From 077366f34b93ed738595d10cae31aecd08eff5a4 Mon Sep 17 00:00:00 2001 From: Thomas Jentzsch Date: Wed, 14 Sep 2022 13:39:24 +0200 Subject: [PATCH 1/8] fixed Sound muting for WAV files --- src/common/SoundSDL2.cxx | 32 +++++++++++++++++++++++--------- src/common/SoundSDL2.hxx | 5 ++++- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/common/SoundSDL2.cxx b/src/common/SoundSDL2.cxx index 37e658f20..1c894e924 100644 --- a/src/common/SoundSDL2.cxx +++ b/src/common/SoundSDL2.cxx @@ -64,6 +64,8 @@ SoundSDL2::SoundSDL2(OSystem& osystem, AudioSettings& audioSettings) return; SoundSDL2::mute(true); + myMuteState = !audioSettings.enabled(); + myWavVolumeFactor = myMuteState ? 0 : myVolumeFactor; Logger::debug("SoundSDL2::SoundSDL2 initialized"); } @@ -151,6 +153,10 @@ void SoundSDL2::setEnabled(bool enable) if(myAudioQueue) myAudioQueue->ignoreOverflows(!enable); + // Set new mute state and resulting WAV data volume + myMuteState = !enable; + myWavVolumeFactor = myMuteState ? 0 : myVolumeFactor; + Logger::debug(enable ? "SoundSDL2::setEnabled(true)" : "SoundSDL2::setEnabled(false)"); } @@ -195,7 +201,7 @@ void SoundSDL2::open(shared_ptr audioQueue, Logger::info(myAboutString); // And start the SDL sound subsystem ... - mute(false); + mute(false && myMuteState); Logger::debug("SoundSDL2::open finished"); } @@ -203,11 +209,11 @@ void SoundSDL2::open(shared_ptr audioQueue, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void SoundSDL2::close() { - stopWav(); if(!myIsInitializedFlag) return; - mute(true); + // Mute and remember current mute state for 'open()' + myMuteState = mute(true); if(myAudioQueue) myAudioQueue->closeSink(myCurrentFragment); @@ -235,6 +241,13 @@ bool SoundSDL2::toggleMute() setEnabled(enabled); myOSystem.console().initializeAudio(); + // Adjust TIA sound to new mute state + myMuteState = !enabled; + mute(myMuteState); + // Make sure the current WAV file continues playing if it got stopped by 'mute()' + if(myWavDevice) + SDL_PauseAudioDevice(myWavDevice, 0); + string message = "Sound "; message += enabled ? "unmuted" : "muted"; @@ -253,6 +266,7 @@ void SoundSDL2::setVolume(uInt32 percent) SDL_LockAudioDevice(myDevice); myVolumeFactor = static_cast(percent) / 100.F; + myWavVolumeFactor = myAudioSettings.enabled() ? myVolumeFactor : 0; SDL_UnlockAudioDevice(myDevice); } } @@ -263,16 +277,15 @@ void SoundSDL2::adjustVolume(int direction) Int32 percent = myVolume; percent = BSPF::clamp(percent + direction * 2, 0, 100); - setVolume(percent); - // Enable audio if it is currently disabled const bool enabled = myAudioSettings.enabled(); - if(percent > 0 && !enabled) + if(percent > 0 && direction && !enabled) { setEnabled(true); myOSystem.console().initializeAudio(); } + setVolume(percent); // Now show an onscreen message ostringstream strval; @@ -418,6 +431,7 @@ bool SoundSDL2::playWav(const string& fileName, const uInt32 position, // Set the callback function myWavSpec.callback = wavCallback; myWavSpec.userdata = nullptr; + //myWavSpec.samples = 4096; // decrease for smaller samples; } if(position > myWavLength) return false; @@ -472,16 +486,16 @@ void SoundSDL2::wavCallback(void* udata, uInt8* stream, int len) if(static_cast(len) > myWavLen) len = myWavLen; - // Mix volume adjusted WAV into silent buffer + // Mix volume adjusted WAV data into silent buffer SDL_MixAudioFormat(stream, myWavPos, myWavSpec.format, len, - SDL_MIX_MAXVOLUME * myVolumeFactor); + SDL_MIX_MAXVOLUME * myWavVolumeFactor); myWavPos += len; myWavLen -= len; } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -float SoundSDL2::myVolumeFactor = 0xffff; +float SoundSDL2::myWavVolumeFactor = 0xffff; SDL_AudioSpec SoundSDL2::myWavSpec; // audio output format uInt8* SoundSDL2::myWavPos = nullptr; // pointer to the audio buffer to be played uInt32 SoundSDL2::myWavLen = 0; // remaining length of the sample we have to play diff --git a/src/common/SoundSDL2.hxx b/src/common/SoundSDL2.hxx index 60868b2f9..e5fd57fb6 100644 --- a/src/common/SoundSDL2.hxx +++ b/src/common/SoundSDL2.hxx @@ -165,7 +165,9 @@ class SoundSDL2 : public Sound // Current volume as a percentage (0 - 100) uInt32 myVolume{100}; - static float myVolumeFactor; + float myVolumeFactor{0xffff}; + // Current mute state, used to control WAV file sound + bool myMuteState{false}; // Audio specification structure SDL_AudioSpec myHardwareSpec; @@ -191,6 +193,7 @@ class SoundSDL2 : public Sound SDL_AudioDeviceID myWavDevice{0}; uInt8* myWavBuffer{nullptr}; + static float myWavVolumeFactor; static SDL_AudioSpec myWavSpec; // audio output format static uInt8* myWavPos; // pointer to the audio buffer to be played static uInt32 myWavLen; // remaining length of the sample we have to play From af5272cff460a732aba1b276f3da3b5bf6886041 Mon Sep 17 00:00:00 2001 From: Thomas Jentzsch Date: Wed, 14 Sep 2022 17:38:47 +0200 Subject: [PATCH 2/8] fixed interrupted WAV continuing to play at restart --- src/common/SoundSDL2.cxx | 19 +++++++++++++++++++ src/common/SoundSDL2.hxx | 5 +++++ src/emucore/Console.cxx | 1 + 3 files changed, 25 insertions(+) diff --git a/src/common/SoundSDL2.cxx b/src/common/SoundSDL2.cxx index 1c894e924..61647f39f 100644 --- a/src/common/SoundSDL2.cxx +++ b/src/common/SoundSDL2.cxx @@ -441,7 +441,26 @@ bool SoundSDL2::playWav(const string& fileName, const uInt32 position, myWavLen = length ? std::min(length, myWavLength - position) : myWavLength; +#ifndef RESAMPLE_WAV myWavPos = myWavBuffer + position; +#else + SDL_free(myCvt.buf); + + //const double speed = BSPF::clamp(262 * 60 * 2. / myEmulationTiming->audioSampleRate(), 0.5, 2.0); + const double speed = 262 * 60 * 2. / myEmulationTiming->audioSampleRate(); + + SDL_BuildAudioCVT(&myCvt, myWavSpec.format, myWavSpec.channels, myWavSpec.freq, + myWavSpec.format, myWavSpec.channels, myWavSpec.freq * speed); + SDL_assert(myCvt.needed); // Obviously, this one is always needed. + myCvt.len = myWavLen * myWavSpec.channels; // Mono 8 bit sample frames + myCvt.buf = (uInt8*)SDL_malloc(myCvt.len * myCvt.len_mult * 2); // Double buffer size to avoid memory access exception + // Read original data into conversion buffer + SDL_memcpy(myCvt.buf, myWavBuffer + position, myCvt.len); + SDL_ConvertAudio(&myCvt); + + myWavPos = myCvt.buf; + myWavLen = myCvt.len_cvt; +#endif // Open audio device if(!myWavDevice) diff --git a/src/common/SoundSDL2.hxx b/src/common/SoundSDL2.hxx index e5fd57fb6..7b5bdf673 100644 --- a/src/common/SoundSDL2.hxx +++ b/src/common/SoundSDL2.hxx @@ -20,6 +20,8 @@ #ifndef SOUND_SDL2_HXX #define SOUND_SDL2_HXX +//#define RESAMPLE_WAV + class OSystem; class AudioQueue; class EmulationTiming; @@ -192,6 +194,9 @@ class SoundSDL2 : public Sound uInt32 myWavLength{0}; SDL_AudioDeviceID myWavDevice{0}; uInt8* myWavBuffer{nullptr}; +#ifdef RESAMPLE_WAV + SDL_AudioCVT myCvt{0}; +#endif static float myWavVolumeFactor; static SDL_AudioSpec myWavSpec; // audio output format diff --git a/src/emucore/Console.cxx b/src/emucore/Console.cxx index e0af1daf8..8b0615fc6 100644 --- a/src/emucore/Console.cxx +++ b/src/emucore/Console.cxx @@ -253,6 +253,7 @@ Console::~Console() // Close audio to prevent invalid access to myConsoleTiming from the audio // callback myOSystem.sound().close(); + myOSystem.sound().stopWav(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 37f8a5595fdb0f75cb2cf041729d9a8da2572ed1 Mon Sep 17 00:00:00 2001 From: Thomas Jentzsch Date: Wed, 14 Sep 2022 19:34:30 +0200 Subject: [PATCH 3/8] removed debug code and cast warning --- src/common/SoundSDL2.cxx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/common/SoundSDL2.cxx b/src/common/SoundSDL2.cxx index 61647f39f..89ae72e7d 100644 --- a/src/common/SoundSDL2.cxx +++ b/src/common/SoundSDL2.cxx @@ -201,7 +201,7 @@ void SoundSDL2::open(shared_ptr audioQueue, Logger::info(myAboutString); // And start the SDL sound subsystem ... - mute(false && myMuteState); + mute(myMuteState); Logger::debug("SoundSDL2::open finished"); } @@ -284,6 +284,8 @@ void SoundSDL2::adjustVolume(int direction) { setEnabled(true); myOSystem.console().initializeAudio(); + myMuteState = false; + mute(false); } setVolume(percent); @@ -453,7 +455,7 @@ bool SoundSDL2::playWav(const string& fileName, const uInt32 position, myWavSpec.format, myWavSpec.channels, myWavSpec.freq * speed); SDL_assert(myCvt.needed); // Obviously, this one is always needed. myCvt.len = myWavLen * myWavSpec.channels; // Mono 8 bit sample frames - myCvt.buf = (uInt8*)SDL_malloc(myCvt.len * myCvt.len_mult * 2); // Double buffer size to avoid memory access exception + myCvt.buf = static_cast(SDL_malloc(myCvt.len * myCvt.len_mult * 2)); // Double buffer size to avoid memory access exception // Read original data into conversion buffer SDL_memcpy(myCvt.buf, myWavBuffer + position, myCvt.len); SDL_ConvertAudio(&myCvt); From 26d6f0db696c8d5ba30d91539485860942a29df3 Mon Sep 17 00:00:00 2001 From: Thomas Jentzsch Date: Thu, 15 Sep 2022 15:21:10 +0200 Subject: [PATCH 4/8] added on-the-fly WAV resampling (disabled, causes echo) --- src/common/SoundSDL2.cxx | 45 +++++++++++++++++++++++++++++++++++----- src/common/SoundSDL2.hxx | 6 +++++- 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/src/common/SoundSDL2.cxx b/src/common/SoundSDL2.cxx index 89ae72e7d..43354beb2 100644 --- a/src/common/SoundSDL2.cxx +++ b/src/common/SoundSDL2.cxx @@ -175,6 +175,9 @@ void SoundSDL2::open(shared_ptr audioQueue, openDevice(); myEmulationTiming = emulationTiming; +#ifdef RESAMPLE_WAV_CB + myWavSpeed = 262 * 60 * 2. / myEmulationTiming->audioSampleRate(); +#endif Logger::debug("SoundSDL2::open started ..."); mute(true); @@ -504,12 +507,41 @@ void SoundSDL2::wavCallback(void* udata, uInt8* stream, int len) SDL_memset(stream, myWavSpec.silence, len); if(myWavLen) { - if(static_cast(len) > myWavLen) - len = myWavLen; +#ifdef RESAMPLE_WAV_CB + if(myWavSpeed != 1.0) + { + int newLen = std::round(len / myWavSpeed); + const int newFreq = std::round(static_cast(myWavSpec.freq) * len / newLen); - // Mix volume adjusted WAV data into silent buffer - SDL_MixAudioFormat(stream, myWavPos, myWavSpec.format, len, - SDL_MIX_MAXVOLUME * myWavVolumeFactor); + if(static_cast(newLen) > myWavLen) + newLen = myWavLen; + + SDL_AudioCVT cvt; + SDL_BuildAudioCVT(&cvt, myWavSpec.format, myWavSpec.channels, myWavSpec.freq, + myWavSpec.format, myWavSpec.channels, newFreq); + SDL_assert(cvt.needed); // Obviously, this one is always needed. + cvt.len = newLen * myWavSpec.channels; // Mono 8 bit sample frames + cvt.buf = static_cast(SDL_malloc(cvt.len * cvt.len_mult * 2)); // Double buffer size to avoid memory access exception + // Read original data into conversion buffer + SDL_memcpy(cvt.buf, myWavPos, cvt.len); + SDL_ConvertAudio(&cvt); + // Mix volume adjusted WAV data into silent buffer + SDL_MixAudioFormat(stream, cvt.buf, myWavSpec.format, cvt.len_cvt, + SDL_MIX_MAXVOLUME * myWavVolumeFactor); + SDL_free(cvt.buf); + + cerr << cvt.len_cvt << " "; + } + else +#endif + { + if(static_cast(len) > myWavLen) + len = myWavLen; + + // Mix volume adjusted WAV data into silent buffer + SDL_MixAudioFormat(stream, myWavPos, myWavSpec.format, len, + SDL_MIX_MAXVOLUME * myWavVolumeFactor); + } myWavPos += len; myWavLen -= len; } @@ -520,5 +552,8 @@ float SoundSDL2::myWavVolumeFactor = 0xffff; SDL_AudioSpec SoundSDL2::myWavSpec; // audio output format uInt8* SoundSDL2::myWavPos = nullptr; // pointer to the audio buffer to be played uInt32 SoundSDL2::myWavLen = 0; // remaining length of the sample we have to play +#ifdef RESAMPLE_WAV_CB +double SoundSDL2::myWavSpeed = 1.0; +#endif #endif // SOUND_SUPPORT diff --git a/src/common/SoundSDL2.hxx b/src/common/SoundSDL2.hxx index 7b5bdf673..c42238113 100644 --- a/src/common/SoundSDL2.hxx +++ b/src/common/SoundSDL2.hxx @@ -20,7 +20,8 @@ #ifndef SOUND_SDL2_HXX #define SOUND_SDL2_HXX -//#define RESAMPLE_WAV +//#define RESAMPLE_WAV // does not adjust to speed immediately +//#define RESAMPLE_WAV_CB // causes echo in in-the-fly resampling class OSystem; class AudioQueue; @@ -197,6 +198,9 @@ class SoundSDL2 : public Sound #ifdef RESAMPLE_WAV SDL_AudioCVT myCvt{0}; #endif +#ifdef RESAMPLE_WAV_CB + static double myWavSpeed; +#endif static float myWavVolumeFactor; static SDL_AudioSpec myWavSpec; // audio output format From ce684daacc92a6db29aae2dfaf36d97b20ce16cc Mon Sep 17 00:00:00 2001 From: Thomas Jentzsch Date: Thu, 15 Sep 2022 18:34:37 +0200 Subject: [PATCH 5/8] fixed WAV echo problem and enabled on-the-fly resampling --- src/common/SoundSDL2.cxx | 39 +++++++++++---------------------------- src/common/SoundSDL2.hxx | 6 +----- 2 files changed, 12 insertions(+), 33 deletions(-) diff --git a/src/common/SoundSDL2.cxx b/src/common/SoundSDL2.cxx index 43354beb2..03045a3f7 100644 --- a/src/common/SoundSDL2.cxx +++ b/src/common/SoundSDL2.cxx @@ -175,7 +175,7 @@ void SoundSDL2::open(shared_ptr audioQueue, openDevice(); myEmulationTiming = emulationTiming; -#ifdef RESAMPLE_WAV_CB +#ifdef RESAMPLE_WAV myWavSpeed = 262 * 60 * 2. / myEmulationTiming->audioSampleRate(); #endif @@ -446,26 +446,7 @@ bool SoundSDL2::playWav(const string& fileName, const uInt32 position, myWavLen = length ? std::min(length, myWavLength - position) : myWavLength; -#ifndef RESAMPLE_WAV myWavPos = myWavBuffer + position; -#else - SDL_free(myCvt.buf); - - //const double speed = BSPF::clamp(262 * 60 * 2. / myEmulationTiming->audioSampleRate(), 0.5, 2.0); - const double speed = 262 * 60 * 2. / myEmulationTiming->audioSampleRate(); - - SDL_BuildAudioCVT(&myCvt, myWavSpec.format, myWavSpec.channels, myWavSpec.freq, - myWavSpec.format, myWavSpec.channels, myWavSpec.freq * speed); - SDL_assert(myCvt.needed); // Obviously, this one is always needed. - myCvt.len = myWavLen * myWavSpec.channels; // Mono 8 bit sample frames - myCvt.buf = static_cast(SDL_malloc(myCvt.len * myCvt.len_mult * 2)); // Double buffer size to avoid memory access exception - // Read original data into conversion buffer - SDL_memcpy(myCvt.buf, myWavBuffer + position, myCvt.len); - SDL_ConvertAudio(&myCvt); - - myWavPos = myCvt.buf; - myWavLen = myCvt.len_cvt; -#endif // Open audio device if(!myWavDevice) @@ -507,21 +488,23 @@ void SoundSDL2::wavCallback(void* udata, uInt8* stream, int len) SDL_memset(stream, myWavSpec.silence, len); if(myWavLen) { -#ifdef RESAMPLE_WAV_CB +#ifdef RESAMPLE_WAV if(myWavSpeed != 1.0) { - int newLen = std::round(len / myWavSpeed); - const int newFreq = std::round(static_cast(myWavSpec.freq) * len / newLen); + const int origLen = len; - if(static_cast(newLen) > myWavLen) - newLen = myWavLen; + len = std::round(len / myWavSpeed); + const int newFreq = std::round(static_cast(myWavSpec.freq) * origLen / len); + + if(static_cast(len) > myWavLen) + len = myWavLen; SDL_AudioCVT cvt; SDL_BuildAudioCVT(&cvt, myWavSpec.format, myWavSpec.channels, myWavSpec.freq, myWavSpec.format, myWavSpec.channels, newFreq); SDL_assert(cvt.needed); // Obviously, this one is always needed. - cvt.len = newLen * myWavSpec.channels; // Mono 8 bit sample frames - cvt.buf = static_cast(SDL_malloc(cvt.len * cvt.len_mult * 2)); // Double buffer size to avoid memory access exception + cvt.len = len * myWavSpec.channels; // Mono 8 bit sample frames + cvt.buf = static_cast(SDL_malloc(cvt.len * cvt.len_mult)); // Read original data into conversion buffer SDL_memcpy(cvt.buf, myWavPos, cvt.len); SDL_ConvertAudio(&cvt); @@ -552,7 +535,7 @@ float SoundSDL2::myWavVolumeFactor = 0xffff; SDL_AudioSpec SoundSDL2::myWavSpec; // audio output format uInt8* SoundSDL2::myWavPos = nullptr; // pointer to the audio buffer to be played uInt32 SoundSDL2::myWavLen = 0; // remaining length of the sample we have to play -#ifdef RESAMPLE_WAV_CB +#ifdef RESAMPLE_WAV double SoundSDL2::myWavSpeed = 1.0; #endif diff --git a/src/common/SoundSDL2.hxx b/src/common/SoundSDL2.hxx index c42238113..bc2270f7c 100644 --- a/src/common/SoundSDL2.hxx +++ b/src/common/SoundSDL2.hxx @@ -20,8 +20,7 @@ #ifndef SOUND_SDL2_HXX #define SOUND_SDL2_HXX -//#define RESAMPLE_WAV // does not adjust to speed immediately -//#define RESAMPLE_WAV_CB // causes echo in in-the-fly resampling +#define RESAMPLE_WAV class OSystem; class AudioQueue; @@ -196,9 +195,6 @@ class SoundSDL2 : public Sound SDL_AudioDeviceID myWavDevice{0}; uInt8* myWavBuffer{nullptr}; #ifdef RESAMPLE_WAV - SDL_AudioCVT myCvt{0}; -#endif -#ifdef RESAMPLE_WAV_CB static double myWavSpeed; #endif From d0c94e5e14b1f64b1969ba0bd095dd3078bed705 Mon Sep 17 00:00:00 2001 From: Thomas Jentzsch Date: Fri, 16 Sep 2022 15:18:24 +0200 Subject: [PATCH 6/8] eliminated frequent memory allocation while playing WAV files --- src/common/SoundSDL2.cxx | 23 ++++++++++++++++++----- src/common/SoundSDL2.hxx | 2 ++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/common/SoundSDL2.cxx b/src/common/SoundSDL2.cxx index 03045a3f7..f00c5b4b5 100644 --- a/src/common/SoundSDL2.cxx +++ b/src/common/SoundSDL2.cxx @@ -474,6 +474,12 @@ void SoundSDL2::stopWav() SDL_FreeWAV(myWavBuffer); myWavBuffer = nullptr; } + if(myWavCvtBuffer) + { + SDL_free(myWavCvtBuffer); + myWavCvtBuffer = nullptr; + myWavCvtBufferSize = 0; + } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -492,7 +498,6 @@ void SoundSDL2::wavCallback(void* udata, uInt8* stream, int len) if(myWavSpeed != 1.0) { const int origLen = len; - len = std::round(len / myWavSpeed); const int newFreq = std::round(static_cast(myWavSpec.freq) * origLen / len); @@ -504,16 +509,22 @@ void SoundSDL2::wavCallback(void* udata, uInt8* stream, int len) myWavSpec.format, myWavSpec.channels, newFreq); SDL_assert(cvt.needed); // Obviously, this one is always needed. cvt.len = len * myWavSpec.channels; // Mono 8 bit sample frames - cvt.buf = static_cast(SDL_malloc(cvt.len * cvt.len_mult)); + + if(!myWavCvtBuffer || myWavCvtBufferSize < static_cast(cvt.len * cvt.len_mult)) + { + if(myWavCvtBuffer) + SDL_free(myWavCvtBuffer); + myWavCvtBufferSize = cvt.len * cvt.len_mult; + myWavCvtBuffer = static_cast(SDL_malloc(myWavCvtBufferSize)); + } + //cvt.buf = static_cast(SDL_malloc(cvt.len * cvt.len_mult)); + cvt.buf = myWavCvtBuffer; // Read original data into conversion buffer SDL_memcpy(cvt.buf, myWavPos, cvt.len); SDL_ConvertAudio(&cvt); // Mix volume adjusted WAV data into silent buffer SDL_MixAudioFormat(stream, cvt.buf, myWavSpec.format, cvt.len_cvt, SDL_MIX_MAXVOLUME * myWavVolumeFactor); - SDL_free(cvt.buf); - - cerr << cvt.len_cvt << " "; } else #endif @@ -537,6 +548,8 @@ uInt8* SoundSDL2::myWavPos = nullptr; // pointer to the audio buffer to be playe uInt32 SoundSDL2::myWavLen = 0; // remaining length of the sample we have to play #ifdef RESAMPLE_WAV double SoundSDL2::myWavSpeed = 1.0; +uInt8* SoundSDL2::myWavCvtBuffer = nullptr; +uInt32 SoundSDL2::myWavCvtBufferSize = 0; #endif #endif // SOUND_SUPPORT diff --git a/src/common/SoundSDL2.hxx b/src/common/SoundSDL2.hxx index bc2270f7c..affcb889d 100644 --- a/src/common/SoundSDL2.hxx +++ b/src/common/SoundSDL2.hxx @@ -196,6 +196,8 @@ class SoundSDL2 : public Sound uInt8* myWavBuffer{nullptr}; #ifdef RESAMPLE_WAV static double myWavSpeed; + static uInt8* myWavCvtBuffer; + static uInt32 myWavCvtBufferSize; #endif static float myWavVolumeFactor; From b927f214f31ac5cfd34a64fdcd406db161b78d85 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sun, 18 Sep 2022 16:56:57 -0230 Subject: [PATCH 7/8] Use unique_ptr instead of C-style allocations. --- src/common/SoundSDL2.cxx | 16 +++++++--------- src/common/SoundSDL2.hxx | 2 +- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/common/SoundSDL2.cxx b/src/common/SoundSDL2.cxx index f00c5b4b5..f44760de6 100644 --- a/src/common/SoundSDL2.cxx +++ b/src/common/SoundSDL2.cxx @@ -476,8 +476,7 @@ void SoundSDL2::stopWav() } if(myWavCvtBuffer) { - SDL_free(myWavCvtBuffer); - myWavCvtBuffer = nullptr; + myWavCvtBuffer.reset(); myWavCvtBufferSize = 0; } } @@ -510,15 +509,14 @@ void SoundSDL2::wavCallback(void* udata, uInt8* stream, int len) SDL_assert(cvt.needed); // Obviously, this one is always needed. cvt.len = len * myWavSpec.channels; // Mono 8 bit sample frames - if(!myWavCvtBuffer || myWavCvtBufferSize < static_cast(cvt.len * cvt.len_mult)) + if(!myWavCvtBuffer || + myWavCvtBufferSize < static_cast(cvt.len * cvt.len_mult)) { - if(myWavCvtBuffer) - SDL_free(myWavCvtBuffer); myWavCvtBufferSize = cvt.len * cvt.len_mult; - myWavCvtBuffer = static_cast(SDL_malloc(myWavCvtBufferSize)); + myWavCvtBuffer = make_unique(myWavCvtBufferSize); } - //cvt.buf = static_cast(SDL_malloc(cvt.len * cvt.len_mult)); - cvt.buf = myWavCvtBuffer; + cvt.buf = myWavCvtBuffer.get(); + // Read original data into conversion buffer SDL_memcpy(cvt.buf, myWavPos, cvt.len); SDL_ConvertAudio(&cvt); @@ -548,7 +546,7 @@ uInt8* SoundSDL2::myWavPos = nullptr; // pointer to the audio buffer to be playe uInt32 SoundSDL2::myWavLen = 0; // remaining length of the sample we have to play #ifdef RESAMPLE_WAV double SoundSDL2::myWavSpeed = 1.0; -uInt8* SoundSDL2::myWavCvtBuffer = nullptr; +unique_ptr SoundSDL2::myWavCvtBuffer = nullptr; uInt32 SoundSDL2::myWavCvtBufferSize = 0; #endif diff --git a/src/common/SoundSDL2.hxx b/src/common/SoundSDL2.hxx index affcb889d..0e6531d46 100644 --- a/src/common/SoundSDL2.hxx +++ b/src/common/SoundSDL2.hxx @@ -196,7 +196,7 @@ class SoundSDL2 : public Sound uInt8* myWavBuffer{nullptr}; #ifdef RESAMPLE_WAV static double myWavSpeed; - static uInt8* myWavCvtBuffer; + static unique_ptr myWavCvtBuffer; static uInt32 myWavCvtBufferSize; #endif From f98fef11db0cedf89410b14b87475c0cce41d384 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Mon, 19 Sep 2022 01:33:36 -0230 Subject: [PATCH 8/8] Fixed crash in resampling WAV playing; forgot to create an array. Make WAV resampling default behaviour. --- src/common/SoundSDL2.cxx | 13 ++++--------- src/common/SoundSDL2.hxx | 10 +++------- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/src/common/SoundSDL2.cxx b/src/common/SoundSDL2.cxx index f44760de6..e9cede687 100644 --- a/src/common/SoundSDL2.cxx +++ b/src/common/SoundSDL2.cxx @@ -175,9 +175,7 @@ void SoundSDL2::open(shared_ptr audioQueue, openDevice(); myEmulationTiming = emulationTiming; -#ifdef RESAMPLE_WAV myWavSpeed = 262 * 60 * 2. / myEmulationTiming->audioSampleRate(); -#endif Logger::debug("SoundSDL2::open started ..."); mute(true); @@ -493,12 +491,12 @@ void SoundSDL2::wavCallback(void* udata, uInt8* stream, int len) SDL_memset(stream, myWavSpec.silence, len); if(myWavLen) { -#ifdef RESAMPLE_WAV if(myWavSpeed != 1.0) { const int origLen = len; len = std::round(len / myWavSpeed); - const int newFreq = std::round(static_cast(myWavSpec.freq) * origLen / len); + const int newFreq = + std::round(static_cast(myWavSpec.freq) * origLen / len); if(static_cast(len) > myWavLen) len = myWavLen; @@ -513,7 +511,7 @@ void SoundSDL2::wavCallback(void* udata, uInt8* stream, int len) myWavCvtBufferSize < static_cast(cvt.len * cvt.len_mult)) { myWavCvtBufferSize = cvt.len * cvt.len_mult; - myWavCvtBuffer = make_unique(myWavCvtBufferSize); + myWavCvtBuffer = make_unique(myWavCvtBufferSize); } cvt.buf = myWavCvtBuffer.get(); @@ -525,7 +523,6 @@ void SoundSDL2::wavCallback(void* udata, uInt8* stream, int len) SDL_MIX_MAXVOLUME * myWavVolumeFactor); } else -#endif { if(static_cast(len) > myWavLen) len = myWavLen; @@ -544,10 +541,8 @@ float SoundSDL2::myWavVolumeFactor = 0xffff; SDL_AudioSpec SoundSDL2::myWavSpec; // audio output format uInt8* SoundSDL2::myWavPos = nullptr; // pointer to the audio buffer to be played uInt32 SoundSDL2::myWavLen = 0; // remaining length of the sample we have to play -#ifdef RESAMPLE_WAV double SoundSDL2::myWavSpeed = 1.0; -unique_ptr SoundSDL2::myWavCvtBuffer = nullptr; +unique_ptr SoundSDL2::myWavCvtBuffer; uInt32 SoundSDL2::myWavCvtBufferSize = 0; -#endif #endif // SOUND_SUPPORT diff --git a/src/common/SoundSDL2.hxx b/src/common/SoundSDL2.hxx index 0e6531d46..ce398d4b5 100644 --- a/src/common/SoundSDL2.hxx +++ b/src/common/SoundSDL2.hxx @@ -20,8 +20,6 @@ #ifndef SOUND_SDL2_HXX #define SOUND_SDL2_HXX -#define RESAMPLE_WAV - class OSystem; class AudioQueue; class EmulationTiming; @@ -194,12 +192,10 @@ class SoundSDL2 : public Sound uInt32 myWavLength{0}; SDL_AudioDeviceID myWavDevice{0}; uInt8* myWavBuffer{nullptr}; -#ifdef RESAMPLE_WAV - static double myWavSpeed; - static unique_ptr myWavCvtBuffer; - static uInt32 myWavCvtBufferSize; -#endif + static double myWavSpeed; + static unique_ptr myWavCvtBuffer; + static uInt32 myWavCvtBufferSize; static float myWavVolumeFactor; static SDL_AudioSpec myWavSpec; // audio output format static uInt8* myWavPos; // pointer to the audio buffer to be played