~mixxxdevelopers/mixxx/engine-control-refactor

« back to all changes in this revision

Viewing changes to mixxx/src/engine/loopingcontrol.cpp

  • Committer: RJ Ryan
  • Date: 2013-06-04 00:41:29 UTC
  • mfrom: (2890.22.101 mixxx)
  • Revision ID: rryan@mixxx.org-20130604004129-8jjxkicsb3givu4a
MergingĀ fromĀ lp:mixxx.

Show diffs side-by-side

added added

removed removed

Lines of Context:
37
37
    CallbackControlManager* pCallbackControlManager =
38
38
            pEngineState->getControlManager();
39
39
 
40
 
    //Create loop-in, loop-out, and reloop/exit ControlObjects
 
40
    //Create loop-in, loop-out, loop-exit, and reloop/exit controls.
41
41
    m_pLoopInButton = pCallbackControlManager->addControl(
42
42
        new ControlPushButton(ConfigKey(_group, "loop_in")), 1);
 
43
 
43
44
    connect(m_pLoopInButton, SIGNAL(valueChanged(double)),
44
45
            this, SLOT(slotLoopIn(double)),
45
46
            Qt::DirectConnection);
52
53
            Qt::DirectConnection);
53
54
    m_pLoopOutButton->set(0);
54
55
 
 
56
    m_pLoopExitButton = pCallbackControlManager->addControl(
 
57
        new ControlPushButton(ConfigKey(_group, "loop_exit")), 1);
 
58
    connect(m_pLoopExitButton, SIGNAL(valueChanged(double)),
 
59
            this, SLOT(slotLoopExit(double)),
 
60
            Qt::DirectConnection);
 
61
    m_pLoopExitButton->set(0);
 
62
 
55
63
    m_pReloopExitButton = pCallbackControlManager->addControl(
56
64
        new ControlPushButton(ConfigKey(_group, "reloop_exit")), 1);
57
65
    connect(m_pReloopExitButton, SIGNAL(valueChanged(double)),
59
67
            Qt::DirectConnection);
60
68
    m_pReloopExitButton->set(0);
61
69
 
62
 
 
63
70
    m_pCOLoopEnabled = pCallbackControlManager->addControl(
64
71
        new ControlObject(ConfigKey(_group, "loop_enabled")), 1);
65
72
    m_pCOLoopEnabled->set(0.0f);
134
141
LoopingControl::~LoopingControl() {
135
142
    delete m_pLoopOutButton;
136
143
    delete m_pLoopInButton;
 
144
    delete m_pLoopExitButton;
137
145
    delete m_pReloopExitButton;
138
146
    delete m_pCOLoopEnabled;
139
147
    delete m_pCOLoopStartPosition;
157
165
 
158
166
    // Abandon loops that are too short of extend beyond the end of the file.
159
167
    if (loop_length < MINIMUM_AUDIBLE_LOOP_SIZE ||
160
 
        m_iLoopStartSample + loop_length > m_pTrackSamples->get()) {
 
168
        m_iLoopStartSample + loop_length > samples) {
161
169
        return;
162
170
    }
163
171
 
233
241
                               const double currentSample,
234
242
                               const double totalSamples,
235
243
                               const int iBufferSize) {
 
244
    Q_UNUSED(totalSamples);
 
245
    Q_UNUSED(iBufferSize);
236
246
    m_iCurrentSample = currentSample;
237
247
    if (!even(m_iCurrentSample))
238
248
        m_iCurrentSample--;
243
253
    if(m_bLoopingEnabled &&
244
254
       m_iLoopStartSample != kNoTrigger &&
245
255
       m_iLoopEndSample != kNoTrigger) {
246
 
        bool outsideLoop = ((!reverse && currentSample > m_iLoopEndSample) ||
247
 
                            (reverse && currentSample < m_iLoopStartSample));
 
256
        bool outsideLoop = currentSample >= m_iLoopEndSample ||
 
257
                currentSample <= m_iLoopStartSample;
248
258
        if (outsideLoop) {
249
259
            retval = reverse ? m_iLoopEndSample : m_iLoopStartSample;
250
260
        }
257
267
                                   const double currentSample,
258
268
                                   const double totalSamples,
259
269
                                   const int iBufferSize) {
 
270
    Q_UNUSED(currentSample);
 
271
    Q_UNUSED(totalSamples);
 
272
    Q_UNUSED(iBufferSize);
260
273
    bool bReverse = dRate < 0;
261
274
 
262
275
    if(m_bLoopingEnabled) {
272
285
                                  const double currentSample,
273
286
                                  const double totalSamples,
274
287
                                  const int iBufferSize) {
 
288
    Q_UNUSED(currentSample);
 
289
    Q_UNUSED(totalSamples);
 
290
    Q_UNUSED(iBufferSize);
275
291
    bool bReverse = dRate < 0;
276
292
 
277
293
    if(m_bLoopingEnabled) {
410
426
    }
411
427
}
412
428
 
 
429
void LoopingControl::slotLoopExit(double val) {
 
430
    if (!m_pTrack) {
 
431
        return;
 
432
    }
 
433
    if (val) {
 
434
        // If we're looping, stop looping
 
435
        if (m_bLoopingEnabled) {
 
436
            setLoopingEnabled(false);
 
437
        }
 
438
    }
 
439
}
 
440
 
413
441
void LoopingControl::slotReloopExit(double val) {
414
442
    if (!m_pTrack) {
415
443
        return;
440
468
        newpos--;
441
469
    }
442
470
 
 
471
 
 
472
    if (m_iLoopStartSample == newpos) {
 
473
        //nothing to do
 
474
        return;
 
475
    }
 
476
 
443
477
    clearActiveBeatLoop();
444
478
 
445
479
    if (pos == -1.0f) {
467
501
        newpos--;
468
502
    }
469
503
 
 
504
    if (m_iLoopEndSample == newpos) {
 
505
        //nothing to do
 
506
        return;
 
507
    }
 
508
 
470
509
    // Reject if the loop-in is not set, or if the new position is before the
471
510
    // start point (but not -1).
472
511
    if (m_iLoopStartSample == -1 ||
519
558
}
520
559
 
521
560
void LoopingControl::trackUnloaded(TrackPointer pTrack) {
 
561
    Q_UNUSED(pTrack);
522
562
    if (m_pTrack) {
523
563
        m_pTrackWatcher->unwatchTrack(m_pTrack);
524
564
    }
559
599
}
560
600
 
561
601
void LoopingControl::slotBeatLoopDeactivate(BeatLoopingControl* pBeatLoopControl) {
562
 
    slotReloopExit(1);
 
602
    Q_UNUSED(pBeatLoopControl);
 
603
    setLoopingEnabled(false);
563
604
}
564
605
 
565
606
void LoopingControl::slotBeatLoopDeactivateRoll(BeatLoopingControl* pBeatLoopControl) {
566
 
    slotReloopExit(1);
 
607
    Q_UNUSED(pBeatLoopControl);
 
608
    setLoopingEnabled(false);
567
609
    m_pSlipEnabled->set(0);
568
610
}
569
611
 
575
617
}
576
618
 
577
619
void LoopingControl::slotBeatLoop(double beats, bool keepStartPoint) {
578
 
    if (!m_pTrack) {
 
620
    int samples = m_pTrackSamples->get();
 
621
    if (!m_pTrack || samples == 0) {
 
622
        clearActiveBeatLoop();
 
623
        return;
 
624
    }
 
625
 
 
626
 
 
627
    if (!m_pBeats) {
 
628
        clearActiveBeatLoop();
 
629
        return;
 
630
    }
 
631
 
 
632
    // For now we do not handle negative beatloops.
 
633
    if (beats < 0) {
 
634
        clearActiveBeatLoop();
579
635
        return;
580
636
    }
581
637
 
583
639
    // fine.
584
640
    foreach (BeatLoopingControl* pBeatLoopControl, m_beatLoops) {
585
641
        if (pBeatLoopControl->getSize() == beats) {
586
 
            if (m_pActiveBeatLoop &&
587
 
                m_pActiveBeatLoop != pBeatLoopControl) {
588
 
                m_pActiveBeatLoop->deactivate();
 
642
            if (m_pActiveBeatLoop != pBeatLoopControl) {
 
643
                if (m_pActiveBeatLoop) {
 
644
                    m_pActiveBeatLoop->deactivate();
 
645
                }
 
646
                m_pActiveBeatLoop = pBeatLoopControl;
589
647
            }
590
 
            m_pActiveBeatLoop = pBeatLoopControl;
591
648
            pBeatLoopControl->activate();
 
649
            break;
592
650
        }
593
651
    }
594
652
 
595
653
    // give loop_in and loop_out defaults so we can detect problems
596
654
    int loop_in = -1;
597
655
    int loop_out = -1;
598
 
    int samples = m_pTrackSamples->get();
599
 
 
600
 
    if (!m_pBeats) {
601
 
        clearActiveBeatLoop();
602
 
        return;
603
 
    }
604
 
 
605
 
    // For now we do not handle negative beatloops.
606
 
    if (beats < 0) {
607
 
        clearActiveBeatLoop();
608
 
        return;
609
 
    }
610
656
 
611
657
    // For positive numbers we start from the current position/closest beat and
612
658
    // create the loop around X beats from there.
614
660
        if (keepStartPoint) {
615
661
            loop_in = m_iLoopStartSample;
616
662
        } else {
617
 
            // loop_in is set to the closest beat if quantize is on
618
 
            double currentClosestBeat =
619
 
                    floorf(m_pBeats->findClosestBeat(getCurrentSample()));
620
 
            loop_in = (m_pQuantizeEnabled->get() > 0.0 && currentClosestBeat != -1) ?
621
 
                    currentClosestBeat : floorf(getCurrentSample());
 
663
            // loop_in is set to the previous beat if quantize is on.  The
 
664
            // closest beat might be ahead of play position which would cause a seek.
 
665
            // TODO: If in reverse, should probably choose nextBeat.
 
666
            double prevBeat =
 
667
                    floorf(m_pBeats->findPrevBeat(getCurrentSample()));
 
668
            loop_in = (m_pQuantizeEnabled->get() > 0.0 && prevBeat != -1) ?
 
669
                    prevBeat : floorf(getCurrentSample());
622
670
            if (!even(loop_in)) {
623
671
                loop_in--;
624
672
            }
726
774
}
727
775
 
728
776
void BeatLoopingControl::deactivate() {
729
 
    m_bActive = false;
730
 
    m_pEnabled->set(0);
731
 
    m_pLegacy->set(0);
 
777
    if (m_bActive) {
 
778
        m_bActive = false;
 
779
        m_pEnabled->set(0);
 
780
        m_pLegacy->set(0);
 
781
    }
732
782
}
733
783
 
734
784
void BeatLoopingControl::activate() {
735
 
    m_bActive = true;
736
 
    m_pEnabled->set(1);
737
 
    m_pLegacy->set(1);
 
785
    if (!m_bActive) {
 
786
        m_bActive = true;
 
787
        m_pEnabled->set(1);
 
788
        m_pLegacy->set(1);
 
789
    }
738
790
}
739
791
 
740
792
void BeatLoopingControl::slotLegacy(double v) {
782
834
    key.item = ctrlName.arg(num);
783
835
    return key;
784
836
}
785