From 1d5f2c005078963ca8abdc5a7ef1be18eef602c2 Mon Sep 17 00:00:00 2001 From: Sotonye Atemie Date: Tue, 25 Mar 2025 16:27:00 -0400 Subject: [PATCH] Add ability to change sample rate in the settings menu (#7719) Add a slider in the audio settings menu to allow users to select a few standard sample rates, those being 44100, 48000, 88200, 96000, and 192000. --- include/AudioEngine.h | 3 +- include/SetupDialog.h | 2 ++ src/core/AudioEngine.cpp | 2 +- src/gui/modals/ExportProjectDialog.cpp | 13 +++++--- src/gui/modals/SetupDialog.cpp | 43 ++++++++++++++++++++++++++ src/gui/modals/export_project.ui | 28 +---------------- 6 files changed, 58 insertions(+), 33 deletions(-) diff --git a/include/AudioEngine.h b/include/AudioEngine.h index 20579f54d..49b511a17 100644 --- a/include/AudioEngine.h +++ b/include/AudioEngine.h @@ -50,7 +50,6 @@ class MidiClient; class AudioBusHandle; class AudioEngineWorkerThread; - constexpr fpp_t MINIMUM_BUFFER_SIZE = 32; constexpr fpp_t DEFAULT_BUFFER_SIZE = 256; constexpr fpp_t MAXIMUM_BUFFER_SIZE = 4096; @@ -61,6 +60,8 @@ constexpr int BYTES_PER_FRAME = sizeof(SampleFrame); constexpr float OUTPUT_SAMPLE_MULTIPLIER = 32767.0f; +constexpr auto SUPPORTED_SAMPLERATES = std::array{44100, 48000, 88200, 96000, 192000}; + class LMMS_EXPORT AudioEngine : public QObject { Q_OBJECT diff --git a/include/SetupDialog.h b/include/SetupDialog.h index f544b8977..c314ff42d 100644 --- a/include/SetupDialog.h +++ b/include/SetupDialog.h @@ -182,6 +182,8 @@ private: QSlider * m_bufferSizeSlider; QLabel * m_bufferSizeLbl; QLabel * m_bufferSizeWarnLbl; + int m_sampleRate; + QSlider* m_sampleRateSlider; // MIDI settings widgets. QComboBox * m_midiInterfaces; diff --git a/src/core/AudioEngine.cpp b/src/core/AudioEngine.cpp index 3eb604fc8..99db26d5f 100644 --- a/src/core/AudioEngine.cpp +++ b/src/core/AudioEngine.cpp @@ -73,7 +73,7 @@ static thread_local bool s_renderingThread = false; AudioEngine::AudioEngine( bool renderOnly ) : m_renderOnly( renderOnly ), m_framesPerPeriod( DEFAULT_BUFFER_SIZE ), - m_baseSampleRate(std::max(ConfigManager::inst()->value("audioengine", "samplerate").toInt(), 44100)), + m_baseSampleRate(std::max(ConfigManager::inst()->value("audioengine", "samplerate").toInt(), SUPPORTED_SAMPLERATES.front())), m_inputBufferRead( 0 ), m_inputBufferWrite( 1 ), m_outputBufferRead(nullptr), diff --git a/src/gui/modals/ExportProjectDialog.cpp b/src/gui/modals/ExportProjectDialog.cpp index 016ed447b..01d7c23b0 100644 --- a/src/gui/modals/ExportProjectDialog.cpp +++ b/src/gui/modals/ExportProjectDialog.cpp @@ -98,6 +98,14 @@ ExportProjectDialog::ExportProjectDialog( const QString & _file_name, compressionWidget->setVisible(false); #endif + for (const auto sampleRate : SUPPORTED_SAMPLERATES) + { + samplerateCB->addItem(tr("%1 Hz").arg(sampleRate), sampleRate); + } + + const auto currentIndex = std::max(0, samplerateCB->findData(Engine::audioEngine()->outputSampleRate())); + samplerateCB->setCurrentIndex(currentIndex); + connect( startButton, SIGNAL(clicked()), this, SLOT(startBtnClicked())); } @@ -156,12 +164,9 @@ void ExportProjectDialog::startExport() { auto qs = AudioEngine::qualitySettings( static_cast(interpolationCB->currentIndex())); - const auto samplerates = std::array{44100, 48000, 88200, 96000, 192000}; const auto bitrates = std::array{64, 128, 160, 192, 256, 320}; - const auto bitrate = bitrates[bitrateCB->currentIndex()]; - - OutputSettings os = OutputSettings(samplerates[samplerateCB->currentIndex()], bitrate, + OutputSettings os = OutputSettings(samplerateCB->currentData().toInt(), bitrates[bitrateCB->currentIndex()], static_cast(depthCB->currentIndex()), mapToStereoMode(stereoModeComboBox->currentIndex())); diff --git a/src/gui/modals/SetupDialog.cpp b/src/gui/modals/SetupDialog.cpp index eb65e2a2c..4ea0d4ddd 100644 --- a/src/gui/modals/SetupDialog.cpp +++ b/src/gui/modals/SetupDialog.cpp @@ -143,6 +143,8 @@ SetupDialog::SetupDialog(ConfigTab tab_to_open) : "app", "nanhandler", "1").toInt()), m_bufferSize(ConfigManager::inst()->value( "audioengine", "framesperaudiobuffer").toInt()), + m_sampleRate(ConfigManager::inst()->value( + "audioengine", "samplerate").toInt()), m_midiAutoQuantize(ConfigManager::inst()->value( "midi", "autoquantize", "0").toInt() != 0), m_workingDir(QDir::toNativeSeparators(ConfigManager::inst()->workingDir())), @@ -557,6 +559,44 @@ SetupDialog::SetupDialog(ConfigTab tab_to_open) : // audio_layout->addWidget(useNaNHandler); // useNaNHandler->setChecked(m_NaNHandler); + auto sampleRateBox = new QGroupBox{tr("Sample rate"), audio_w}; + + m_sampleRateSlider = new QSlider{Qt::Horizontal}; + m_sampleRateSlider->setRange(0, SUPPORTED_SAMPLERATES.size() - 1); + m_sampleRateSlider->setTickPosition(QSlider::TicksBelow); + + auto sampleRateResetButton = new QPushButton{embed::getIconPixmap("reload"), ""}; + sampleRateResetButton->setFixedSize(32, 32); + + auto sampleRateSubLayout = new QHBoxLayout{}; + sampleRateSubLayout->addWidget(m_sampleRateSlider); + sampleRateSubLayout->addWidget(sampleRateResetButton); + + auto sampleRateLabel = new QLabel{sampleRateBox}; + auto sampleRateLayout = new QVBoxLayout{sampleRateBox}; + sampleRateLayout->addLayout(sampleRateSubLayout); + sampleRateLayout->addWidget(sampleRateLabel); + + auto setSampleRate = [this, sampleRateLabel](int sampleRate) + { + const auto it = std::find(SUPPORTED_SAMPLERATES.begin(), SUPPORTED_SAMPLERATES.end(), sampleRate); + const auto index = it == SUPPORTED_SAMPLERATES.end() ? 0 : std::distance(SUPPORTED_SAMPLERATES.begin(), it); + + m_sampleRate = SUPPORTED_SAMPLERATES[index]; + m_sampleRateSlider->setValue(index); + sampleRateLabel->setText(tr("Sample rate: %1").arg(m_sampleRate)); + }; + + setSampleRate(m_sampleRate); + + connect(m_sampleRateSlider, &QSlider::valueChanged, this, &SetupDialog::showRestartWarning); + + connect(m_sampleRateSlider, &QSlider::valueChanged, this, + [setSampleRate](int value) { setSampleRate(SUPPORTED_SAMPLERATES[value]); }); + + connect(sampleRateResetButton, &QPushButton::clicked, this, + [setSampleRate] { setSampleRate(SUPPORTED_SAMPLERATES.front()); }); + // Buffer size group QGroupBox * bufferSizeBox = new QGroupBox(tr("Buffer size"), audio_w); QVBoxLayout * bufferSizeLayout = new QVBoxLayout(bufferSizeBox); @@ -598,6 +638,7 @@ SetupDialog::SetupDialog(ConfigTab tab_to_open) : // Audio layout ordering. audio_layout->addWidget(audioInterfaceBox); audio_layout->addWidget(as_w); + audio_layout->addWidget(sampleRateBox); audio_layout->addWidget(bufferSizeBox); audio_layout->addStretch(); @@ -962,6 +1003,8 @@ void SetupDialog::accept() m_audioIfaceNames[m_audioInterfaces->currentText()]); ConfigManager::inst()->setValue("app", "nanhandler", QString::number(m_NaNHandler)); + ConfigManager::inst()->setValue("audioengine", "samplerate", + QString::number(m_sampleRate)); ConfigManager::inst()->setValue("audioengine", "framesperaudiobuffer", QString::number(m_bufferSize)); ConfigManager::inst()->setValue("audioengine", "mididev", diff --git a/src/gui/modals/export_project.ui b/src/gui/modals/export_project.ui index b047bec08..2a923021f 100644 --- a/src/gui/modals/export_project.ui +++ b/src/gui/modals/export_project.ui @@ -122,33 +122,7 @@ - - - - 44100 Hz - - - - - 48000 Hz - - - - - 88200 Hz - - - - - 96000 Hz - - - - - 192000 Hz - - - +