=== modified file 'mixxx/res/skins/LateNight1280x800-WXGA/skin.xml' --- mixxx/res/skins/LateNight1280x800-WXGA/skin.xml 2012-05-31 20:28:19 +0000 +++ mixxx/res/skins/LateNight1280x800-WXGA/skin.xml 2012-06-02 19:53:01 +0000 @@ -4215,6 +4215,7 @@ 2 true + true 0 btn_beatloop1_0125.png @@ -4233,6 +4234,11 @@ true + [Channel1],beatlooproll_0.125_activate + true + RightButton + + [Channel1],beatloop_0.125_enabled false @@ -4242,6 +4248,7 @@ 2 true + true 0 btn_beatloop1_0250.png @@ -4269,6 +4276,7 @@ 2 true + true 0 btn_beatloop1_0500.png @@ -4287,6 +4295,11 @@ true + [Channel1],beatlooproll_0.5_activate + true + RightButton + + [Channel1],beatloop_0.5_enabled false @@ -4296,6 +4309,7 @@ 2 true + true 0 btn_beatloop1_1.png @@ -4314,6 +4328,11 @@ true + [Channel1],beatlooproll_1_activate + true + RightButton + + [Channel1],beatloop_1_enabled false @@ -4323,6 +4342,7 @@ 2 true + true 0 btn_beatloop1_2.png @@ -4341,6 +4361,11 @@ true + [Channel1],beatlooproll_2_activate + true + RightButton + + [Channel1],beatloop_2_enabled false @@ -4350,6 +4375,7 @@ 2 true + true 0 btn_beatloop1_4.png @@ -4368,6 +4394,11 @@ true + [Channel1],beatlooproll_4_activate + true + RightButton + + [Channel1],beatloop_4_enabled false @@ -4377,6 +4408,7 @@ 2 true + true 0 btn_beatloop1_8.png @@ -4395,6 +4427,11 @@ true + [Channel1],beatlooproll_8_activate + true + RightButton + + [Channel1],beatloop_8_enabled false @@ -4404,6 +4441,7 @@ 2 true + true 0 btn_beatloop1_16.png @@ -4422,6 +4460,11 @@ true + [Channel1],beatlooproll_16_activate + true + RightButton + + [Channel1],beatloop_16_enabled false @@ -5164,6 +5207,7 @@ 2 true + true 0 btn_beatloop2_0125.png @@ -5182,6 +5226,11 @@ true + [Channel2],beatlooproll_0.125_activate + true + RightButton + + [Channel2],beatloop_0.125_enabled false @@ -5191,6 +5240,7 @@ 2 true + true 0 btn_beatloop2_0250.png @@ -5218,6 +5268,7 @@ 2 true + true 0 btn_beatloop2_0500.png @@ -5236,6 +5287,11 @@ true + [Channel2],beatlooproll_0.5_activate + true + RightButton + + [Channel2],beatloop_0.5_enabled false @@ -5245,6 +5301,7 @@ 2 true + true 0 btn_beatloop2_1.png @@ -5263,6 +5320,11 @@ true + [Channel2],beatlooproll_1_activate + true + RightButton + + [Channel2],beatloop_1_enabled false @@ -5272,6 +5334,7 @@ 2 true + true 0 btn_beatloop2_2.png @@ -5290,6 +5353,11 @@ true + [Channel2],beatlooproll_2_activate + true + RightButton + + [Channel2],beatloop_2_enabled false @@ -5299,6 +5367,7 @@ 2 true + true 0 btn_beatloop2_4.png @@ -5317,6 +5386,11 @@ true + [Channel2],beatlooproll_4_activate + true + RightButton + + [Channel2],beatloop_4_enabled false @@ -5326,6 +5400,7 @@ 2 true + true 0 btn_beatloop2_8.png @@ -5344,6 +5419,11 @@ true + [Channel2],beatlooproll_8_activate + true + RightButton + + [Channel2],beatloop_8_enabled false @@ -5353,6 +5433,7 @@ 2 true + true 0 btn_beatloop2_16.png @@ -5371,6 +5452,11 @@ true + [Channel2],beatlooproll_16_activate + true + RightButton + + [Channel2],beatloop_16_enabled false === modified file 'mixxx/src/engine/enginebuffer.cpp' --- mixxx/src/engine/enginebuffer.cpp 2012-05-05 02:36:53 +0000 +++ mixxx/src/engine/enginebuffer.cpp 2012-06-02 19:54:22 +0000 @@ -150,6 +150,15 @@ connect(endButton, SIGNAL(valueChanged(double)), this, SLOT(slotControlEnd(double)), Qt::DirectConnection); + + m_pSlipButton = new ControlPushButton(ConfigKey(group, "slip_enabled")); + m_pSlipButton->setButtonMode(ControlPushButton::TOGGLE); + connect(m_pSlipButton, SIGNAL(valueChanged(double)), + this, SLOT(slotControlSlip(double)), + Qt::DirectConnection); + connect(m_pSlipButton, SIGNAL(valueChangedFromEngine(double)), + this, SLOT(slotControlSlip(double)), + Qt::DirectConnection); // Actual rate (used in visuals, not for control) rateEngine = new ControlObject(ConfigKey(group, "rateEngine")); @@ -178,7 +187,7 @@ m_pRepeat = new ControlPushButton(ConfigKey(group, "repeat")); m_pRepeat->setButtonMode(ControlPushButton::TOGGLE); - + #ifdef __VINYLCONTROL__ //a midi knob to tweak the vinyl pitch for decks with crappy sliders m_pVinylPitchTweakKnob = new ControlPotmeter(ConfigKey(_group, "vinylpitchtweak"), -0.005, 0.005); @@ -512,6 +521,27 @@ } } +void EngineBuffer::slotControlSlip(double v) +{ + bool enabled = v > 0.0; + if (enabled == m_bSlipEnabled) { + return; + } + + m_bSlipEnabled = enabled; + + if (enabled) { + m_dSlipPosition = filepos_play; + m_dSlipRate = rate_old; + } + else + { + //TODO(owen) assuming that looping will get cancelled properly + slotControlSeekAbs(m_dSlipPosition); + } +} + + void EngineBuffer::process(const CSAMPLE *, const CSAMPLE * pOut, const int iBufferSize) { Q_ASSERT(even(iBufferSize)); @@ -544,6 +574,12 @@ &is_scratching); //qDebug() << "rate" << rate << " paused" << paused; + + // Update the slipped position + if (m_bSlipEnabled) { + m_dSlipPosition += static_cast(iBufferSize) * m_dSlipRate; + } + // Scratching always disables keylock because keylock sounds terrible // when not going at a constant rate. === modified file 'mixxx/src/engine/enginebuffer.h' --- mixxx/src/engine/enginebuffer.h 2012-05-10 00:21:25 +0000 +++ mixxx/src/engine/enginebuffer.h 2012-06-02 19:55:09 +0000 @@ -131,6 +131,7 @@ void slotControlEnd(double); void slotControlSeek(double); void slotControlSeekAbs(double); + void slotControlSlip(double); // Request that the EngineBuffer load a track. Since the process is // asynchronous, EngineBuffer will emit a trackLoaded signal when the load @@ -206,11 +207,19 @@ /** Used in update of playpos slider */ int m_iSamplesCalculated; int m_iUiSlowTick; - + + /** The location where the track would have been had slip not been engaged */ + double m_dSlipPosition; + /** Saved value of rate for slip mode */ + double m_dSlipRate; + /** Slip Status */ + bool m_bSlipEnabled; + ControlObject* m_pTrackSamples; ControlObject* m_pTrackSampleRate; ControlPushButton *playButton, *buttonBeatSync, *playStartButton, *stopStartButton, *stopButton, *playSyncButton; + ControlPushButton *m_pSlipButton; ControlObjectThreadMain *playButtonCOT, *playStartButtonCOT, *stopStartButtonCOT, *m_pTrackEndCOT, *stopButtonCOT; ControlObject *fwdButton, *backButton; === modified file 'mixxx/src/engine/loopingcontrol.cpp' --- mixxx/src/engine/loopingcontrol.cpp 2012-05-05 02:36:01 +0000 +++ mixxx/src/engine/loopingcontrol.cpp 2012-06-02 19:57:06 +0000 @@ -68,6 +68,7 @@ m_pNextBeat = ControlObject::getControl(ConfigKey(_group, "beat_next")); m_pClosestBeat = ControlObject::getControl(ConfigKey(_group, "beat_closest")); m_pTrackSamples = ControlObject::getControl(ConfigKey(_group,"track_samples")); + m_pSlipEnabled = ControlObject::getControl(ConfigKey(_group,"slip_enabled")); // Connect beatloop, which can flexibly handle different values. // Using this CO directly is meant to be used internally and by scripts, @@ -84,9 +85,15 @@ connect(pBeatLoop, SIGNAL(activateBeatLoop(BeatLoopingControl*)), this, SLOT(slotBeatLoopActivate(BeatLoopingControl*)), Qt::DirectConnection); + connect(pBeatLoop, SIGNAL(activateBeatLoopRoll(BeatLoopingControl*)), + this, SLOT(slotBeatLoopActivateRoll(BeatLoopingControl*)), + Qt::DirectConnection); connect(pBeatLoop, SIGNAL(deactivateBeatLoop(BeatLoopingControl*)), this, SLOT(slotBeatLoopDeactivate(BeatLoopingControl*)), Qt::DirectConnection); + connect(pBeatLoop, SIGNAL(deactivateBeatLoopRoll(BeatLoopingControl*)), + this, SLOT(slotBeatLoopDeactivateRoll(BeatLoopingControl*)), + Qt::DirectConnection); m_beatLoops.append(pBeatLoop); } @@ -520,10 +527,25 @@ beatLoopAlreadyActive && m_bLoopingEnabled); } +void LoopingControl::slotBeatLoopActivateRoll(BeatLoopingControl* pBeatLoopControl) { + if (!m_pTrack) { + return; + } + + //Disregard existing loops + m_pSlipEnabled->set(1); + slotBeatLoop(pBeatLoopControl->getSize(), false); +} + void LoopingControl::slotBeatLoopDeactivate(BeatLoopingControl* pBeatLoopControl) { slotReloopExit(1); } +void LoopingControl::slotBeatLoopDeactivateRoll(BeatLoopingControl* pBeatLoopControl) { + slotReloopExit(1); + m_pSlipEnabled->set(0); +} + void LoopingControl::clearActiveBeatLoop() { if (m_pActiveBeatLoop != NULL) { m_pActiveBeatLoop->deactivate(); @@ -654,6 +676,13 @@ connect(m_pToggle, SIGNAL(valueChanged(double)), this, SLOT(slotToggle(double)), Qt::DirectConnection); + + // A push-button which activates rolling beatloops + m_pActivateRoll = new ControlPushButton( + keyForControl(pGroup, "beatlooproll_%1_activate", size)); + connect(m_pActivateRoll, SIGNAL(valueChanged(double)), + this, SLOT(slotActivateRoll(double)), + Qt::DirectConnection); // An indicator control which is 1 if the beatloop is enabled and 0 if not. m_pEnabled = new ControlObject( @@ -696,6 +725,15 @@ emit(activateBeatLoop(this)); } +void BeatLoopingControl::slotActivateRoll(double v) { + //qDebug() << "slotActivateRoll" << m_dBeatLoopSize << "v" << v; + if (v > 0) { + emit(activateBeatLoopRoll(this)); + } else { + emit(deactivateBeatLoopRoll(this)); + } +} + void BeatLoopingControl::slotToggle(double v) { //qDebug() << "slotToggle" << m_dBeatLoopSize << "v" << v; if (!v) { === modified file 'mixxx/src/engine/loopingcontrol.h' --- mixxx/src/engine/loopingcontrol.h 2011-12-22 08:17:26 +0000 +++ mixxx/src/engine/loopingcontrol.h 2012-06-02 19:31:52 +0000 @@ -67,7 +67,9 @@ // beatslicing effect. void slotBeatLoop(double loopSize, bool keepStartPoint=false); void slotBeatLoopActivate(BeatLoopingControl* pBeatLoopControl); + void slotBeatLoopActivateRoll(BeatLoopingControl* pBeatLoopControl); void slotBeatLoopDeactivate(BeatLoopingControl* pBeatLoopControl); + void slotBeatLoopDeactivateRoll(BeatLoopingControl* pBeatLoopControl); void slotLoopScale(double); void slotLoopDouble(double); @@ -86,6 +88,7 @@ ControlObject* m_pCOLoopScale; ControlPushButton* m_pLoopHalveButton; ControlPushButton* m_pLoopDoubleButton; + ControlObject* m_pSlipEnabled; bool m_bLoopingEnabled; int m_iLoopEndSample; @@ -124,11 +127,14 @@ public slots: void slotLegacy(double value); void slotActivate(double value); + void slotActivateRoll(double value); void slotToggle(double value); signals: void activateBeatLoop(BeatLoopingControl*); void deactivateBeatLoop(BeatLoopingControl*); + void activateBeatLoopRoll(BeatLoopingControl*); + void deactivateBeatLoopRoll(BeatLoopingControl*); private: // Used simply to generate the beatloop_%SIZE and beatseek_%SIZE CO @@ -138,6 +144,7 @@ bool m_bActive; ControlPushButton* m_pLegacy; ControlPushButton* m_pActivate; + ControlPushButton* m_pActivateRoll; ControlPushButton* m_pToggle; ControlObject* m_pEnabled; };