From af76280e04c3aa9fff2b7c07a4749872699017fa Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sun, 24 Sep 2023 15:30:58 +0200 Subject: [PATCH 1/5] refactor(enginemixer): Rename control to `[App],output_latency_ms` --- src/engine/enginemixer.cpp | 3 ++- src/test/co_dumps/co_dump_inital.csv | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/engine/enginemixer.cpp b/src/engine/enginemixer.cpp index 9d4b7e88730..4a4950da126 100644 --- a/src/engine/enginemixer.cpp +++ b/src/engine/enginemixer.cpp @@ -80,9 +80,10 @@ EngineMixer::EngineMixer( m_pMainSampleRate->set(44100.); // Latency control - m_pMainLatency = new ControlObject(ConfigKey(group, "latency"), + m_pMainLatency = new ControlObject(ConfigKey(kAppGroup, QStringLiteral("output_latency_ms")), true, true); // reported latency (sometimes correct) + m_pMainLatency->addAlias(ConfigKey(kLegacyGroup, QStringLiteral("latency"))); m_pAudioLatencyOverloadCount = new ControlObject( ConfigKey(kAppGroup, QStringLiteral("audio_latency_overload_count"))); m_pAudioLatencyOverloadCount->addAlias(ConfigKey( diff --git a/src/test/co_dumps/co_dump_inital.csv b/src/test/co_dumps/co_dump_inital.csv index c13bae305ff..7253469ac22 100644 --- a/src/test/co_dumps/co_dump_inital.csv +++ b/src/test/co_dumps/co_dump_inital.csv @@ -29,7 +29,7 @@ [EffectRack1_EffectUnit4_Effect4],parameter4_set_default,0 [EffectRack1_EffectUnit2_Effect2],parameter2_link_type,0 [QuickEffectRack1_[Channel3]_Effect1],parameter5_set_zero,0 -[Master],latency,5.80499 +[App],output_latency_ms,5.80499 [Channel4],hotcue_15_enabled,0 [Channel4],hotcue_2_activate,0 [EffectRack1_EffectUnit3_Effect3],parameter4_minus_toggle,0 From 74b44dc715d3e2b38ae36280a43a90dcfb5a273b Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sun, 24 Sep 2023 22:24:55 +0200 Subject: [PATCH 2/5] chore: Use renamed `output_latency_ms` from `[App]` group --- src/preferences/dialog/dlgprefsound.cpp | 2 +- src/soundio/sounddevicenetwork.cpp | 2 +- src/soundio/sounddeviceportaudio.cpp | 4 +++- src/vinylcontrol/vinylcontrolxwax.cpp | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/preferences/dialog/dlgprefsound.cpp b/src/preferences/dialog/dlgprefsound.cpp index 252683e92e9..32a28be8e13 100644 --- a/src/preferences/dialog/dlgprefsound.cpp +++ b/src/preferences/dialog/dlgprefsound.cpp @@ -207,7 +207,7 @@ DlgPrefSound::DlgPrefSound(QWidget* pParent, new ControlProxy(kAppGroup, QStringLiteral("audio_latency_overload_count"), this); m_pAudioLatencyOverloadCount->connectValueChanged(this, &DlgPrefSound::bufferUnderflow); - m_pMainLatency = new ControlProxy("[Master]", "latency", this); + m_pMainLatency = new ControlProxy(kAppGroup, QStringLiteral("output_latency_ms"), this); m_pMainLatency->connectValueChanged(this, &DlgPrefSound::mainLatencyChanged); // TODO: remove this option by automatically disabling/enabling the main mix diff --git a/src/soundio/sounddevicenetwork.cpp b/src/soundio/sounddevicenetwork.cpp index 9f7457dd306..9825743b20a 100644 --- a/src/soundio/sounddevicenetwork.cpp +++ b/src/soundio/sounddevicenetwork.cpp @@ -89,7 +89,7 @@ SoundDeviceStatus SoundDeviceNetwork::open(bool isClkRefDevice, int syncBuffers) // Update the samplerate and latency ControlObjects, which allow the // waveform view to properly correct for the latency. - ControlObject::set(ConfigKey("[Master]", "latency"), + ControlObject::set(ConfigKey(kAppGroup, QStringLiteral("output_latency_ms")), requestedBufferTime.toDoubleMillis()); ControlObject::set(ConfigKey(kAppGroup, QStringLiteral("samplerate")), m_dSampleRate); diff --git a/src/soundio/sounddeviceportaudio.cpp b/src/soundio/sounddeviceportaudio.cpp index 79ac8dda794..f553ac8efdb 100644 --- a/src/soundio/sounddeviceportaudio.cpp +++ b/src/soundio/sounddeviceportaudio.cpp @@ -385,7 +385,9 @@ SoundDeviceStatus SoundDevicePortAudio::open(bool isClkRefDevice, int syncBuffer if (isClkRefDevice) { // Update the samplerate and latency ControlObjects, which allow the // waveform view to properly correct for the latency. - ControlObject::set(ConfigKey("[Master]", "latency"), currentLatencyMSec); + ControlObject::set( + ConfigKey(kAppGroup, QStringLiteral("output_latency_ms")), + currentLatencyMSec); ControlObject::set(ConfigKey(kAppGroup, QStringLiteral("samplerate")), m_dSampleRate); m_invalidTimeInfoCount = 0; m_clkRefTimer.start(); diff --git a/src/vinylcontrol/vinylcontrolxwax.cpp b/src/vinylcontrol/vinylcontrolxwax.cpp index 80dea92cd0e..ffa281ead4a 100644 --- a/src/vinylcontrol/vinylcontrolxwax.cpp +++ b/src/vinylcontrol/vinylcontrolxwax.cpp @@ -128,7 +128,7 @@ VinylControlXwax::VinylControlXwax(UserSettingsPointer pConfig, const QString& g } double latency = ControlObject::get( - ConfigKey("[Master]", "latency")); + ConfigKey(QStringLiteral("[App]"), QStringLiteral("output_latency_ms"))); if (latency <= 0 || latency > 200) { qDebug() << "Failed to get sane latency, assuming 20 as a reasonable value"; latency = 20; From daa5504f6022a61b070448e1404df5ca3b849f81 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sun, 24 Sep 2023 22:28:51 +0200 Subject: [PATCH 3/5] fix(controllers): Fix usage of latency control in Akai LPD8-RK mapping --- res/controllers/Akai-LPD8-RK-scripts.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/controllers/Akai-LPD8-RK-scripts.js b/res/controllers/Akai-LPD8-RK-scripts.js index efee7ca6d2f..30165dbc105 100644 --- a/res/controllers/Akai-LPD8-RK-scripts.js +++ b/res/controllers/Akai-LPD8-RK-scripts.js @@ -493,7 +493,7 @@ LPD8RK.beatjump = function (channel, control, value, status, group) { var numbeats = LPD8RK.beatjumpstep; var backseconds = numbeats*(1/(engine.getValue(group, "bpm")/60)); var backsamples = backseconds*engine.getValue(group, "track_samples")/engine.getValue(group, "duration"); - var newpos = curpos-(backsamples+engine.getValue("Master", "latency")); + var newpos = curpos-(backsamples+engine.getValue("[App]", "output_latency_ms")); if (LPD8RK.debug){print("backseconds: "+backseconds);} if (LPD8RK.debug){print("backsamples: "+backsamples);} From 1248105d22780144fc5caa6d210a94e83b7852c6 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sun, 24 Sep 2023 23:19:18 +0200 Subject: [PATCH 4/5] test(controlobjectaliastest): Add test for `latency` control alias --- src/test/controlobjectaliastest.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/test/controlobjectaliastest.cpp b/src/test/controlobjectaliastest.cpp index 6e1b9be5955..f357ad69537 100644 --- a/src/test/controlobjectaliastest.cpp +++ b/src/test/controlobjectaliastest.cpp @@ -66,6 +66,10 @@ TEST_F(ControlObjectAliasTest, EngineMixer) { auto sampleRateLegacy = ControlProxy(ConfigKey(kLegacyGroup, QStringLiteral("samplerate"))); EXPECT_DOUBLE_EQ(sampleRate.get(), sampleRateLegacy.get()); + auto latency = ControlProxy(ConfigKey(kAppGroup, QStringLiteral("output_latency_ms"))); + auto latencyLegacy = ControlProxy(ConfigKey(kLegacyGroup, QStringLiteral("latency"))); + EXPECT_DOUBLE_EQ(latency.get(), latencyLegacy.get()); + auto audioLatencyUsage = ControlProxy( ConfigKey(kAppGroup, QStringLiteral("audio_latency_usage"))); auto audioLatencyUsageLegacy = ControlProxy( From f85acc5e31d504647781ccd5977d6b0476eea11b Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Fri, 29 Sep 2023 15:46:32 +0200 Subject: [PATCH 5/5] chore: Rename members to match new `output_latency_ms` CO name --- src/engine/enginemixer.cpp | 17 +++++++++-------- src/engine/enginemixer.h | 4 ++-- src/preferences/dialog/dlgprefsound.cpp | 6 +++--- src/preferences/dialog/dlgprefsound.h | 4 ++-- 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/engine/enginemixer.cpp b/src/engine/enginemixer.cpp index 4a4950da126..e4b7ad92434 100644 --- a/src/engine/enginemixer.cpp +++ b/src/engine/enginemixer.cpp @@ -74,16 +74,17 @@ EngineMixer::EngineMixer( m_pWorkerScheduler->start(QThread::HighPriority); // Main sample rate - m_pMainSampleRate = new ControlObject( + m_pSampleRate = new ControlObject( ConfigKey(kAppGroup, QStringLiteral("samplerate")), true, true); - m_pMainSampleRate->addAlias(ConfigKey(group, QStringLiteral("samplerate"))); - m_pMainSampleRate->set(44100.); + m_pSampleRate->addAlias(ConfigKey(group, QStringLiteral("samplerate"))); + m_pSampleRate->set(44100.); // Latency control - m_pMainLatency = new ControlObject(ConfigKey(kAppGroup, QStringLiteral("output_latency_ms")), + m_pOutputLatencyMs = new ControlObject( + ConfigKey(kAppGroup, QStringLiteral("output_latency_ms")), true, true); // reported latency (sometimes correct) - m_pMainLatency->addAlias(ConfigKey(kLegacyGroup, QStringLiteral("latency"))); + m_pOutputLatencyMs->addAlias(ConfigKey(kLegacyGroup, QStringLiteral("latency"))); m_pAudioLatencyOverloadCount = new ControlObject( ConfigKey(kAppGroup, QStringLiteral("audio_latency_overload_count"))); m_pAudioLatencyOverloadCount->addAlias(ConfigKey( @@ -236,8 +237,8 @@ EngineMixer::~EngineMixer() { delete m_pXFaderMode; delete m_pEngineSync; - delete m_pMainSampleRate; - delete m_pMainLatency; + delete m_pSampleRate; + delete m_pOutputLatencyMs; delete m_pAudioLatencyOverloadCount; delete m_pAudioLatencyUsage; delete m_pAudioLatencyOverload; @@ -418,7 +419,7 @@ void EngineMixer::process(const int iBufferSize) { bool boothEnabled = m_pBoothEnabled->toBool(); bool headphoneEnabled = m_pHeadphoneEnabled->toBool(); - m_sampleRate = mixxx::audio::SampleRate::fromDouble(m_pMainSampleRate->get()); + m_sampleRate = mixxx::audio::SampleRate::fromDouble(m_pSampleRate->get()); // TODO: remove assumption of stereo buffer constexpr unsigned int kChannels = 2; const unsigned int iFrames = iBufferSize / kChannels; diff --git a/src/engine/enginemixer.h b/src/engine/enginemixer.h index 0d1d5581024..23d7c95bced 100644 --- a/src/engine/enginemixer.h +++ b/src/engine/enginemixer.h @@ -303,8 +303,8 @@ class EngineMixer : public QObject, public AudioSource { ControlObject* m_pMainGain; ControlObject* m_pBoothGain; ControlObject* m_pHeadGain; - ControlObject* m_pMainSampleRate; - ControlObject* m_pMainLatency; + ControlObject* m_pSampleRate; + ControlObject* m_pOutputLatencyMs; ControlObject* m_pAudioLatencyOverloadCount; ControlObject* m_pAudioLatencyUsage; ControlObject* m_pAudioLatencyOverload; diff --git a/src/preferences/dialog/dlgprefsound.cpp b/src/preferences/dialog/dlgprefsound.cpp index 32a28be8e13..c32b16379a3 100644 --- a/src/preferences/dialog/dlgprefsound.cpp +++ b/src/preferences/dialog/dlgprefsound.cpp @@ -207,8 +207,8 @@ DlgPrefSound::DlgPrefSound(QWidget* pParent, new ControlProxy(kAppGroup, QStringLiteral("audio_latency_overload_count"), this); m_pAudioLatencyOverloadCount->connectValueChanged(this, &DlgPrefSound::bufferUnderflow); - m_pMainLatency = new ControlProxy(kAppGroup, QStringLiteral("output_latency_ms"), this); - m_pMainLatency->connectValueChanged(this, &DlgPrefSound::mainLatencyChanged); + m_pOutputLatencyMs = new ControlProxy(kAppGroup, QStringLiteral("output_latency_ms"), this); + m_pOutputLatencyMs->connectValueChanged(this, &DlgPrefSound::outputLatencyChanged); // TODO: remove this option by automatically disabling/enabling the main mix // when recording, broadcasting, headphone, and main outputs are enabled/disabled @@ -732,7 +732,7 @@ void DlgPrefSound::bufferUnderflow(double count) { update(); } -void DlgPrefSound::mainLatencyChanged(double latency) { +void DlgPrefSound::outputLatencyChanged(double latency) { currentLatency->setText(QString("%1 ms").arg(latency)); update(); } diff --git a/src/preferences/dialog/dlgprefsound.h b/src/preferences/dialog/dlgprefsound.h index 42a3d46109f..797a596e036 100644 --- a/src/preferences/dialog/dlgprefsound.h +++ b/src/preferences/dialog/dlgprefsound.h @@ -48,7 +48,7 @@ class DlgPrefSound : public DlgPreferencePage, public Ui::DlgPrefSoundDlg { void slotApply() override; // called on ok button void slotResetToDefaults() override; void bufferUnderflow(double count); - void mainLatencyChanged(double latency); + void outputLatencyChanged(double latency); void latencyCompensationSpinboxChanged(double value); void mainDelaySpinboxChanged(double value); void headDelaySpinboxChanged(double value); @@ -86,7 +86,7 @@ class DlgPrefSound : public DlgPreferencePage, public Ui::DlgPrefSoundDlg { UserSettingsPointer m_pSettings; SoundManagerConfig m_config; ControlProxy* m_pAudioLatencyOverloadCount; - ControlProxy* m_pMainLatency; + ControlProxy* m_pOutputLatencyMs; ControlProxy* m_pHeadDelay; ControlProxy* m_pMainDelay; ControlProxy* m_pBoothDelay;