From 0b6db5cef648db5a4dba8039fb589cbc215f4b2a Mon Sep 17 00:00:00 2001 From: Sotonye Atemie Date: Sun, 2 Mar 2025 05:19:43 -0500 Subject: [PATCH] Only allow users to select a few standard sample rates --- include/AudioEngine.h | 7 ++-- include/SetupDialog.h | 3 +- src/core/AudioEngine.cpp | 2 +- src/gui/modals/ExportProjectDialog.cpp | 9 ++--- src/gui/modals/SetupDialog.cpp | 46 +++++++++++++++++++------- 5 files changed, 42 insertions(+), 25 deletions(-) diff --git a/include/AudioEngine.h b/include/AudioEngine.h index ae7bc1f754b..20038c1c9db 100644 --- a/include/AudioEngine.h +++ b/include/AudioEngine.h @@ -50,21 +50,18 @@ class MidiClient; class AudioPort; class AudioEngineWorkerThread; - constexpr fpp_t MINIMUM_BUFFER_SIZE = 32; constexpr fpp_t DEFAULT_BUFFER_SIZE = 256; constexpr fpp_t MAXIMUM_BUFFER_SIZE = 4096; -constexpr auto MINIMUM_SAMPLE_RATE = 8000; -constexpr auto MAXIMUM_SAMPLE_RATE = 192000; -constexpr auto DEFAULT_SAMPLE_RATE = 44100; - constexpr int BYTES_PER_SAMPLE = sizeof(sample_t); constexpr int BYTES_PER_INT_SAMPLE = sizeof(int_sample_t); 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 8a7632290e9..13eecf61d82 100644 --- a/include/SetupDialog.h +++ b/include/SetupDialog.h @@ -185,7 +185,8 @@ private slots: QSlider * m_bufferSizeSlider; QLabel * m_bufferSizeLbl; QLabel * m_bufferSizeWarnLbl; - FloatModel m_sampleRateModel; + 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 446ecc89c25..c76ac8073f3 100644 --- a/src/core/AudioEngine.cpp +++ b/src/core/AudioEngine.cpp @@ -74,7 +74,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(), DEFAULT_SAMPLE_RATE)), + 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 1f989841f3b..b4447634a47 100644 --- a/src/gui/modals/ExportProjectDialog.cpp +++ b/src/gui/modals/ExportProjectDialog.cpp @@ -156,17 +156,14 @@ 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}; bool useVariableBitRate = checkBoxVariableBitRate->isChecked(); OutputSettings::BitRateSettings bitRateSettings(bitrates[ bitrateCB->currentIndex() ], useVariableBitRate); - OutputSettings os = OutputSettings( - samplerates[ samplerateCB->currentIndex() ], - bitRateSettings, - static_cast( depthCB->currentIndex() ), - mapToStereoMode(stereoModeComboBox->currentIndex()) ); + OutputSettings os = OutputSettings(SUPPORTED_SAMPLERATES[samplerateCB->currentIndex()], bitRateSettings, + static_cast(depthCB->currentIndex()), + mapToStereoMode(stereoModeComboBox->currentIndex())); if (compressionWidget->isVisible()) { diff --git a/src/gui/modals/SetupDialog.cpp b/src/gui/modals/SetupDialog.cpp index a9600bf8b24..28ef727ddca 100644 --- a/src/gui/modals/SetupDialog.cpp +++ b/src/gui/modals/SetupDialog.cpp @@ -145,8 +145,8 @@ SetupDialog::SetupDialog(ConfigTab tab_to_open) : "app", "nanhandler", "1").toInt()), m_bufferSize(ConfigManager::inst()->value( "audioengine", "framesperaudiobuffer").toInt()), - m_sampleRateModel(ConfigManager::inst()->value("audioengine", "samplerate").toInt(), - MINIMUM_SAMPLE_RATE, MAXIMUM_SAMPLE_RATE), + 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())), @@ -562,21 +562,42 @@ SetupDialog::SetupDialog(ConfigTab tab_to_open) : // useNaNHandler->setChecked(m_NaNHandler); auto sampleRateBox = new QGroupBox{tr("Sample rate"), audio_w}; - auto sampleRateLayout = new QVBoxLayout{sampleRateBox}; - auto sampleRateSubLayout = new QHBoxLayout{}; - auto sampleRateSpinBox = new LcdFloatSpinBox(QString::number(MAXIMUM_SAMPLE_RATE).length(), 2, tr("Sample rate"), sampleRateBox); - sampleRateSpinBox->setModel(&m_sampleRateModel); - - auto sampleRateResetButton = new QPushButton(embed::getIconPixmap("reload"), "", sampleRateSpinBox); + 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); - sampleRateSubLayout->addWidget(sampleRateSpinBox, 1, Qt::AlignLeft); + auto sampleRateSubLayout = new QHBoxLayout{}; + sampleRateSubLayout->addWidget(m_sampleRateSlider); sampleRateSubLayout->addWidget(sampleRateResetButton); + + auto sampleRateLabel = new QLabel{}; + 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)); + + showRestartWarning(); + }; + + connect(m_sampleRateSlider, &QSlider::valueChanged, this, + [setSampleRate](int value) { setSampleRate(SUPPORTED_SAMPLERATES[value]); }); + + connect(sampleRateResetButton, &QPushButton::clicked, this, + [setSampleRate] { setSampleRate(SUPPORTED_SAMPLERATES.front()); }); - connect(&m_sampleRateModel, &FloatModel::dataChanged, this, &SetupDialog::showRestartWarning); - connect(sampleRateResetButton, &QPushButton::clicked, this, [&] { m_sampleRateModel.setValue(DEFAULT_SAMPLE_RATE); }); + setSampleRate(m_sampleRate); // Buffer size group QGroupBox * bufferSizeBox = new QGroupBox(tr("Buffer size"), audio_w); @@ -984,7 +1005,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_sampleRateModel.value())); + ConfigManager::inst()->setValue("audioengine", "samplerate", + QString::number(m_sampleRate)); ConfigManager::inst()->setValue("audioengine", "framesperaudiobuffer", QString::number(m_bufferSize)); ConfigManager::inst()->setValue("audioengine", "mididev",