From 9859f3d9162c3ebcb434456aae05e15383a25181 Mon Sep 17 00:00:00 2001 From: Owen Williams Date: Tue, 26 Aug 2014 20:08:07 -0400 Subject: [PATCH 1/3] When disabling keylock, explicitly reset musical pitch. Also reset pitch when a new track is loaded. Fixes lp#1361355 --- src/engine/enginebuffer.cpp | 10 ++++++++++ src/engine/enginebuffer.h | 3 +++ 2 files changed, 13 insertions(+) diff --git a/src/engine/enginebuffer.cpp b/src/engine/enginebuffer.cpp index e7a0bdf9601..1c15b11cf94 100644 --- a/src/engine/enginebuffer.cpp +++ b/src/engine/enginebuffer.cpp @@ -84,6 +84,7 @@ EngineBuffer::EngineBuffer(const char* _group, ConfigObject* _confi m_dSlipRate(1.0), m_bSlipEnabled(false), m_bSlipToggled(false), + m_bWasKeylocked(false), m_pRepeat(NULL), m_startButton(NULL), m_endButton(NULL), @@ -257,6 +258,7 @@ EngineBuffer::EngineBuffer(const char* _group, ConfigObject* _confi m_pKeyControl = new KeyControl(_group, _config); addControl(m_pKeyControl); + m_pPitchControl = new ControlObjectSlave(m_group, "pitch", this); // Create the clock controller m_pClockControl = new ClockControl(_group, _config); @@ -526,6 +528,8 @@ void EngineBuffer::slotTrackLoaded(TrackPointer pTrack, m_file_length_old = iTrackNumSamples; m_pTrackSamples->set(iTrackNumSamples); m_pTrackSampleRate->set(iTrackSampleRate); + // Reset the pitch value for the new track. + m_pPitchControl->set(0.0); m_pause.unlock(); // All EngineControls are connected directly @@ -743,6 +747,11 @@ void EngineBuffer::process(CSAMPLE* pOutput, const int iBufferSize) bool is_scratching = false; bool keylock_enabled = m_pKeylock->get() > 0; + // If keylock was on, and the user disabled it, also reset the pitch. + if (m_bWasKeylocked && !keylock_enabled) { + m_pPitchControl->set(0.0); + } + // speed is the percentage change in player speed. Depending on whether // keylock is enabled, this is applied to either the rate or the tempo. double speed = m_pRateControl->calculateRate( @@ -815,6 +824,7 @@ void EngineBuffer::process(CSAMPLE* pOutput, const int iBufferSize) m_baserate_old = baserate; m_speed_old = speed; m_pitch_old = pitch; + m_bWasKeylocked = keylock_enabled; // The way we treat rate inside of EngineBuffer is actually a // description of "sample consumption rate" or percentage of samples diff --git a/src/engine/enginebuffer.h b/src/engine/enginebuffer.h index d0d2a0da7be..31dab691f52 100644 --- a/src/engine/enginebuffer.h +++ b/src/engine/enginebuffer.h @@ -307,6 +307,8 @@ class EngineBuffer : public EngineObject { bool m_bSlipEnabled; bool m_bSlipToggled; + bool m_bWasKeylocked; + ControlObject* m_pTrackSamples; ControlObject* m_pTrackSampleRate; @@ -328,6 +330,7 @@ class EngineBuffer : public EngineObject { ControlPotmeter* m_playposSlider; ControlObjectSlave* m_pSampleRate; ControlObjectSlave* m_pKeylockEngine; + ControlObjectSlave* m_pPitchControl; ControlPushButton* m_pKeylock; QScopedPointer m_pPassthroughEnabled; From eeb1faaeb18c3d25b0b354b12a01566afda89388 Mon Sep 17 00:00:00 2001 From: Owen Williams Date: Wed, 3 Sep 2014 22:49:59 -0400 Subject: [PATCH 2/3] Add tests for musical pitch reset. --- src/test/enginebuffertest.cpp | 41 +++++++++++++++++++++++++++++++++++ src/test/enginesynctest.cpp | 1 - 2 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 src/test/enginebuffertest.cpp diff --git a/src/test/enginebuffertest.cpp b/src/test/enginebuffertest.cpp new file mode 100644 index 00000000000..632ac820b55 --- /dev/null +++ b/src/test/enginebuffertest.cpp @@ -0,0 +1,41 @@ +// Tests for enginebuffer.cpp + +#include +#include + +#include + +#include "configobject.h" +#include "controlobject.h" +#include "test/mockedenginebackendtest.h" +#include "test/mixxxtest.h" + + +class EngineBufferTest : public MockedEngineBackendTest { +}; + +TEST_F(EngineBufferTest, DisableKeylockResetsPitch) { + // To prevent one-slider users from getting stuck on a key, unsetting + // keylock resets the musical pitch. + ControlObject::getControl(ConfigKey(m_sGroup1, "file_bpm"))->set(128.0); + ControlObject::getControl(ConfigKey(m_sGroup1, "keylock"))->set(1.0); + ControlObject::getControl(ConfigKey(m_sGroup1, "pitch"))->set(0.5); + ProcessBuffer(); + + ControlObject::getControl(ConfigKey(m_sGroup1, "keylock"))->set(0.0); + // We require a buffer process to see that the keylock state has changed. + ProcessBuffer(); + ASSERT_EQ(0.0, ControlObject::getControl(ConfigKey(m_sGroup1, "pitch"))->get()); +} + +TEST_F(EngineBufferTest, TrackLoadResetsPitch) { + // When a new track is loaded, the pitch value should be reset. + ControlObject::getControl(ConfigKey(m_sGroup1, "file_bpm"))->set(128.0); + qDebug() << "set pitch!!!!"; + ControlObject::getControl(ConfigKey(m_sGroup1, "pitch"))->set(0.5); + ProcessBuffer(); + ASSERT_EQ(0.5, ControlObject::getControl(ConfigKey(m_sGroup1, "pitch"))->get()); + + m_pChannel1->getEngineBuffer()->loadFakeTrack(); + ASSERT_EQ(0.0, ControlObject::getControl(ConfigKey(m_sGroup1, "pitch"))->get()); +} diff --git a/src/test/enginesynctest.cpp b/src/test/enginesynctest.cpp index bac6ab06d17..9870977bb9f 100644 --- a/src/test/enginesynctest.cpp +++ b/src/test/enginesynctest.cpp @@ -1,5 +1,4 @@ // Tests for Master Sync. -// There are no tests for actual deck playback, since I don't know how to mock that out yet. // The following manual tests should probably be performed: // * Quantize mode nudges tracks in sync, whether internal or deck master. // * Flinging tracks with the waveform should work. From 70e9c95c2dc681fabf0e2c768e7ec8b229d62661 Mon Sep 17 00:00:00 2001 From: Owen Williams Date: Wed, 3 Sep 2014 22:50:37 -0400 Subject: [PATCH 3/3] cruft debug comment --- src/test/enginebuffertest.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/enginebuffertest.cpp b/src/test/enginebuffertest.cpp index 632ac820b55..55d45deaf13 100644 --- a/src/test/enginebuffertest.cpp +++ b/src/test/enginebuffertest.cpp @@ -31,7 +31,6 @@ TEST_F(EngineBufferTest, DisableKeylockResetsPitch) { TEST_F(EngineBufferTest, TrackLoadResetsPitch) { // When a new track is loaded, the pitch value should be reset. ControlObject::getControl(ConfigKey(m_sGroup1, "file_bpm"))->set(128.0); - qDebug() << "set pitch!!!!"; ControlObject::getControl(ConfigKey(m_sGroup1, "pitch"))->set(0.5); ProcessBuffer(); ASSERT_EQ(0.5, ControlObject::getControl(ConfigKey(m_sGroup1, "pitch"))->get());