diff --git a/src/common/AudioSettings.cxx b/src/common/AudioSettings.cxx index bdc2e2ead..94c740b26 100644 --- a/src/common/AudioSettings.cxx +++ b/src/common/AudioSettings.cxx @@ -41,9 +41,16 @@ namespace { } } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +AudioSettings::AudioSettings() + : mySettings(), + myIsPersistent(false) +{} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AudioSettings::AudioSettings(Settings* settings) - : mySettings(settings) + : mySettings(settings), + myIsPersistent(true) { setPreset(normalizedPreset(mySettings->getInt(SETTING_PRESET))); } @@ -81,10 +88,10 @@ void AudioSettings::normalize(Settings& settings) } int settingBufferSize = settings.getInt(SETTING_BUFFER_SIZE); - if (settingBufferSize < 0 || settingBufferSize > 20) settings.setValue(SETTING_BUFFER_SIZE, DEFAULT_BUFFER_SIZE); + if (settingBufferSize < 0 || settingBufferSize > MAX_BUFFER_SIZE) settings.setValue(SETTING_BUFFER_SIZE, DEFAULT_BUFFER_SIZE); int settingHeadroom = settings.getInt(SETTING_HEADROOM); - if (settingHeadroom < 0 || settingHeadroom > 20) settings.setValue(SETTING_HEADROOM, DEFAULT_HEADROOM); + if (settingHeadroom < 0 || settingHeadroom > MAX_HEADROOM) settings.setValue(SETTING_HEADROOM, DEFAULT_HEADROOM); int settingResamplingQuality = settings.getInt(SETTING_RESAMPLING_QUALITY); ResamplingQuality resamplingQuality = normalizeResamplingQuality(settingResamplingQuality); @@ -198,12 +205,14 @@ void AudioSettings::setPreset(AudioSettings::Preset preset) throw runtime_error("invalid preset"); } - mySettings->setValue(SETTING_PRESET, static_cast(myPreset)); + if (myIsPersistent) mySettings->setValue(SETTING_PRESET, static_cast(myPreset)); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void AudioSettings::setSampleRate(uInt32 sampleRate) { + if (!myIsPersistent) return; + mySettings->setValue(SETTING_SAMPLE_RATE, sampleRate); normalize(*mySettings); } @@ -211,6 +220,8 @@ void AudioSettings::setSampleRate(uInt32 sampleRate) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void AudioSettings::setFragmentSize(uInt32 fragmentSize) { + if (!myIsPersistent) return; + mySettings->setValue(SETTING_FRAGMENT_SIZE, fragmentSize); normalize(*mySettings); } @@ -218,6 +229,8 @@ void AudioSettings::setFragmentSize(uInt32 fragmentSize) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void AudioSettings::setBufferSize(uInt32 bufferSize) { + if (!myIsPersistent) return; + mySettings->setValue(SETTING_BUFFER_SIZE, bufferSize); normalize(*mySettings); } @@ -225,6 +238,8 @@ void AudioSettings::setBufferSize(uInt32 bufferSize) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void AudioSettings::setHeadroom(uInt32 headroom) { + if (!myIsPersistent) return; + mySettings->setValue(SETTING_HEADROOM, headroom); normalize(*mySettings); } @@ -232,6 +247,8 @@ void AudioSettings::setHeadroom(uInt32 headroom) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void AudioSettings::setResamplingQuality(AudioSettings::ResamplingQuality resamplingQuality) { + if (!myIsPersistent) return; + mySettings->setValue(SETTING_RESAMPLING_QUALITY, static_cast(resamplingQuality)); normalize(*mySettings); } @@ -239,6 +256,8 @@ void AudioSettings::setResamplingQuality(AudioSettings::ResamplingQuality resamp // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void AudioSettings::setVolume(uInt32 volume) { + if (!myIsPersistent) return; + mySettings->setValue(SETTING_VOLUME, volume); normalize(*mySettings); } @@ -246,9 +265,17 @@ void AudioSettings::setVolume(uInt32 volume) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void AudioSettings::setEnabled(bool isEnabled) { + if (!myIsPersistent) return; + mySettings->setValue(SETTING_ENABLED, isEnabled); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void AudioSettings::setPersistent(bool isPersistent) +{ + myIsPersistent = isPersistent; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool AudioSettings::customSettings() const { @@ -258,5 +285,7 @@ bool AudioSettings::customSettings() const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void AudioSettings::updatePresetFromSettings() { + if (!myIsPersistent) return; + setPreset(normalizedPreset(mySettings->getInt(SETTING_PRESET))); } diff --git a/src/common/AudioSettings.hxx b/src/common/AudioSettings.hxx index 3435a344d..61b66ffb2 100644 --- a/src/common/AudioSettings.hxx +++ b/src/common/AudioSettings.hxx @@ -58,9 +58,12 @@ class AudioSettings static constexpr uInt32 DEFAULT_VOLUME = 80; static constexpr bool DEFAULT_ENABLED = true; + static constexpr int MAX_BUFFER_SIZE = 10; + static constexpr int MAX_HEADROOM = 10; + public: - AudioSettings() = default; + AudioSettings(); AudioSettings(Settings* mySettings); @@ -100,6 +103,8 @@ class AudioSettings void setEnabled(bool isEnabled); + void setPersistent(bool isPersistent); + private: bool customSettings() const; @@ -117,6 +122,8 @@ class AudioSettings uInt32 myPresetBufferSize; uInt32 myPresetHeadroom; ResamplingQuality myPresetResamplingQuality; + + bool myIsPersistent; }; #endif // AUDIO_PARAMTERS_HXX diff --git a/src/emucore/OSystem.hxx b/src/emucore/OSystem.hxx index 981f3c729..d52956fae 100644 --- a/src/emucore/OSystem.hxx +++ b/src/emucore/OSystem.hxx @@ -126,6 +126,11 @@ class OSystem Console& console() const { return *myConsole; } bool hasConsole() const; + /** + Get the audio settings ovject. + */ + AudioSettings& audioSettings() { return myAudioSettings; } + /** Get the serial port of the system. diff --git a/src/gui/AudioDialog.cxx b/src/gui/AudioDialog.cxx index cf5773bd3..0a3b22aba 100644 --- a/src/gui/AudioDialog.cxx +++ b/src/gui/AudioDialog.cxx @@ -29,6 +29,7 @@ #include "Settings.hxx" #include "Sound.hxx" #include "Widget.hxx" +#include "AudioSettings.hxx" #include "AudioDialog.hxx" @@ -50,7 +51,7 @@ AudioDialog::AudioDialog(OSystem& osystem, DialogContainer& parent, VariantList items; // Set real dimensions - _w = 35 * fontWidth + HBORDER * 2; + _w = 45 * fontWidth + HBORDER * 2; _h = 11 * (lineHeight + 4) + VBORDER + _th; xpos = HBORDER; ypos = VBORDER + _th; @@ -71,12 +72,13 @@ AudioDialog::AudioDialog(OSystem& osystem, DialogContainer& parent, ypos += lineHeight + 4; // - VarList::push_back(items, "Minimal Lag", "minlag"); - VarList::push_back(items, "Balanced", "balanced"); - VarList::push_back(items, "Max. Quality", "maxquality"); - VarList::push_back(items, "Custom", "Custom"); + VarList::push_back(items, "Low quality, medium lag", static_cast(AudioSettings::Preset::lowQualityMediumLag)); + VarList::push_back(items, "High quality, medium lag", static_cast(AudioSettings::Preset::highQualityMediumLag)); + VarList::push_back(items, "High quality, low lag", static_cast(AudioSettings::Preset::highQualityLowLag)); + VarList::push_back(items, "Ultra quality, minimal lag", static_cast(AudioSettings::Preset::veryHighQualityVeryLowLag)); + VarList::push_back(items, "Custom", static_cast(AudioSettings::Preset::custom)); myModePopup = new PopUpWidget(this, font, xpos, ypos, - font.getStringWidth("Max. Quality"), lineHeight, + font.getStringWidth("Ultry quality, minimal lag "), lineHeight, items, "Mode (*) ", 0, kModeChanged); wid.push_back(myModePopup); ypos += lineHeight + 4; @@ -84,35 +86,34 @@ AudioDialog::AudioDialog(OSystem& osystem, DialogContainer& parent, // Fragment size items.clear(); - VarList::push_back(items, "128 bytes", "128"); - VarList::push_back(items, "256 bytes", "256"); - VarList::push_back(items, "512 bytes", "512"); - VarList::push_back(items, "1 KB", "1024"); - VarList::push_back(items, "2 KB", "2048"); - VarList::push_back(items, "4 KB", "4096"); + VarList::push_back(items, "128 bytes", 128); + VarList::push_back(items, "256 bytes", 256); + VarList::push_back(items, "512 bytes", 512); + VarList::push_back(items, "1 KB", 1024); + VarList::push_back(items, "2 KB", 2048); + VarList::push_back(items, "4 KB", 4096); myFragsizePopup = new PopUpWidget(this, font, xpos, ypos, pwidth, lineHeight, - items, "Sample size (*) ", lwidth); + items, "Fragment size (*) ", lwidth); wid.push_back(myFragsizePopup); ypos += lineHeight + 4; // Output frequency items.clear(); - VarList::push_back(items, "44100 Hz", "44100"); - VarList::push_back(items, "48000 Hz", "48000"); - VarList::push_back(items, "96000 Hz", "96000"); + VarList::push_back(items, "44100 Hz", 44100); + VarList::push_back(items, "48000 Hz", 48000); + VarList::push_back(items, "96000 Hz", 96000); myFreqPopup = new PopUpWidget(this, font, xpos, ypos, pwidth, lineHeight, - items, "Frequency (*) ", lwidth); + items, "Sample rate (*) ", lwidth); wid.push_back(myFreqPopup); ypos += lineHeight + 4; - // Resampling quality items.clear(); - VarList::push_back(items, "Low", "low"); - VarList::push_back(items, "Medium", "medium"); - VarList::push_back(items, "High", "high"); + VarList::push_back(items, "Low", static_cast(AudioSettings::ResamplingQuality::nearestNeightbour)); + VarList::push_back(items, "High", static_cast(AudioSettings::ResamplingQuality::lanczos_2)); + VarList::push_back(items, "Ultra", static_cast(AudioSettings::ResamplingQuality::lanczos_3)); myResamplingPopup = new PopUpWidget(this, font, xpos, ypos, pwidth, lineHeight, items, "Resampling quality ", lwidth); @@ -121,15 +122,15 @@ AudioDialog::AudioDialog(OSystem& osystem, DialogContainer& parent, // Param 1 myHeadroomSlider = new SliderWidget(this, font, xpos, ypos, - "Headroom "); - myHeadroomSlider->setMinValue(1); myHeadroomSlider->setMaxValue(10); + "Headroom ", 0, 0, 2 * fontWidth); + myHeadroomSlider->setMinValue(1); myHeadroomSlider->setMaxValue(AudioSettings::MAX_HEADROOM); wid.push_back(myHeadroomSlider); ypos += lineHeight + 4; // Param 2 myBufferSizeSlider = new SliderWidget(this, font, xpos, ypos, - "Buffer size "); - myBufferSizeSlider->setMinValue(1); myBufferSizeSlider->setMaxValue(10); + "Buffer size ", 0, 0, 2 * fontWidth); + myBufferSizeSlider->setMinValue(1); myBufferSizeSlider->setMaxValue(AudioSettings::MAX_BUFFER_SIZE); wid.push_back(myBufferSizeSlider); // Add message concerning usage @@ -148,41 +149,69 @@ AudioDialog::AudioDialog(OSystem& osystem, DialogContainer& parent, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void AudioDialog::loadConfig() { + AudioSettings& audioSettings = instance().audioSettings(); + // Volume - myVolumeSlider->setValue(instance().settings().getInt("volume")); - - // Fragsize - myFragsizePopup->setSelected(instance().settings().getString("fragsize"), "512"); - - // Output frequency - myFreqPopup->setSelected(instance().settings().getString("freq"), "31400"); + myVolumeSlider->setValue(audioSettings.volume()); // Enable sound - bool b = instance().settings().getBool("sound"); - mySoundEnableCheckbox->setState(b); + mySoundEnableCheckbox->setState(audioSettings.enabled()); + + // Preset / mode + myModePopup->setSelected(static_cast(audioSettings.preset())); + + updatePresetSettings(instance().audioSettings()); // Make sure that mutually-exclusive items are not enabled at the same time - handleSoundEnableChange(b); + handleSoundEnableChange(audioSettings.enabled()); + handleModeChange(audioSettings.enabled()); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void AudioDialog::updatePresetSettings(AudioSettings& audioSettings) +{ + // Fragsize + myFragsizePopup->setSelected(audioSettings.fragmentSize()); + + // Output frequency + myFreqPopup->setSelected(audioSettings.sampleRate()); + + // Headroom + myHeadroomSlider->setValue(audioSettings.headroom()); + + // Buffer size + myBufferSizeSlider->setValue(audioSettings.bufferSize()); + + // Resampling quality + myResamplingPopup->setSelected(static_cast(audioSettings.resamplingQuality())); +} + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void AudioDialog::saveConfig() { - Settings& settings = instance().settings(); + AudioSettings audioSettings = instance().audioSettings(); // Volume - settings.setValue("volume", myVolumeSlider->getValue()); + audioSettings.setVolume(myVolumeSlider->getValue()); instance().sound().setVolume(myVolumeSlider->getValue()); - // Fragsize - settings.setValue("fragsize", myFragsizePopup->getSelectedTag().toString()); - - // Output frequency - settings.setValue("freq", myFreqPopup->getSelectedTag().toString()); - - // Enable/disable sound (requires a restart to take effect) + audioSettings.setEnabled(mySoundEnableCheckbox->getState()); instance().sound().setEnabled(mySoundEnableCheckbox->getState()); + AudioSettings::Preset preset = static_cast(myModePopup->getSelectedTag().toInt()); + audioSettings.setPreset(preset); + + if (preset == AudioSettings::Preset::custom) { + + // Fragsize + audioSettings.setFragmentSize(myFragsizePopup->getSelectedTag().toInt()); + audioSettings.setSampleRate(myFreqPopup->getSelectedTag().toInt()); + audioSettings.setHeadroom(myHeadroomSlider->getValue()); + audioSettings.setBufferSize(myBufferSizeSlider->getValue()); + audioSettings.setResamplingQuality(static_cast(myResamplingPopup->getSelectedTag().toInt())); + } + // Only force a re-initialization when necessary, since it can // be a time-consuming operation if(instance().hasConsole()) @@ -216,7 +245,17 @@ void AudioDialog::handleSoundEnableChange(bool active) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void AudioDialog::handleModeChange(bool active) { - bool userMode = active && "Custom" == myModePopup->getSelectedName(); + AudioSettings::Preset preset = static_cast(myModePopup->getSelectedTag().toInt()); + + AudioSettings audioSettings = instance().audioSettings(); + audioSettings.setPersistent(false); + audioSettings.setPreset(preset); + + (cout << "Preset: " << static_cast(preset) << std::endl).flush(); + + updatePresetSettings(audioSettings); + + bool userMode = active && preset == AudioSettings::Preset::custom; myFragsizePopup->setEnabled(userMode); myFreqPopup->setEnabled(userMode); diff --git a/src/gui/AudioDialog.hxx b/src/gui/AudioDialog.hxx index 91ff75df6..94e2666aa 100644 --- a/src/gui/AudioDialog.hxx +++ b/src/gui/AudioDialog.hxx @@ -26,6 +26,7 @@ class SliderWidget; class StaticTextWidget; class CheckboxWidget; class OSystem; +class AudioSettings; #include "bspf.hxx" @@ -59,6 +60,10 @@ class AudioDialog : public Dialog SliderWidget* myHeadroomSlider; SliderWidget* myBufferSizeSlider; + private: + + void updatePresetSettings(AudioSettings&); + private: // Following constructors and assignment operators not supported AudioDialog() = delete;