added WAV file volume adjustment (resolves #77)

This commit is contained in:
Thomas Jentzsch 2022-09-03 20:56:38 +02:00
parent d54e7f34fe
commit c7cac63a38
3 changed files with 51 additions and 15 deletions

View File

@ -405,17 +405,13 @@ void SoundSDL2::callback(void* udata, uInt8* stream, int len)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool SoundSDL2::playWav(const char* fileName, uInt32 position, uInt32 length) bool SoundSDL2::playWav(const char* fileName, uInt32 position, uInt32 length)
{ {
// ToDos:
// - volume (requires callback using SDL_MixAudio)
// - (un)mute
SDL_AudioSpec wavSpec;
uInt32 wavLength{0}; uInt32 wavLength{0};
// Stop any playing WAVs // Stop any playing WAVs
stopWav(); stopWav();
// Load WAV file // Load WAV file
SDL_AudioSpec* result = SDL_LoadWAV(fileName, &wavSpec, &myWavBuffer, &wavLength); SDL_AudioSpec* result = SDL_LoadWAV(fileName, &myWavSpec, &myWavBuffer, &wavLength);
if(result == nullptr || position > wavLength) if(result == nullptr || position > wavLength)
return false; return false;
@ -423,18 +419,24 @@ bool SoundSDL2::playWav(const char* fileName, uInt32 position, uInt32 length)
? std::min(length, wavLength - position) ? std::min(length, wavLength - position)
: wavLength; : wavLength;
// Set the callback function
myWavSpec.callback = wavCallback;
myWavSpec.userdata = nullptr;
myWavPos = myWavBuffer + position;
myWavLen = length;
// Open audio device // Open audio device
const char* device = myDeviceId ? myDevices.at(myDeviceId).first.c_str() : nullptr; const char* device = myDeviceId ? myDevices.at(myDeviceId).first.c_str() : nullptr;
myWavDevice = SDL_OpenAudioDevice(device, 0, &wavSpec, nullptr, 0); myWavDevice = SDL_OpenAudioDevice(device, 0, &myWavSpec, nullptr, 0);
if(!myWavDevice) if(!myWavDevice)
return false; return false;
// Play audio // Play audio
int success = SDL_QueueAudio(myWavDevice, myWavBuffer + position, length);
SDL_PauseAudioDevice(myWavDevice, 0); SDL_PauseAudioDevice(myWavDevice, 0);
return success == 0; return true;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -452,7 +454,28 @@ void SoundSDL2::stopWav()
uInt32 SoundSDL2::wavSize() const uInt32 SoundSDL2::wavSize() const
{ {
return myWavBuffer ? SDL_GetQueuedAudioSize(myWavDevice) : 0; return myWavBuffer ? myWavLen /*SDL_GetQueuedAudioSize(myWavDevice)*/ : 0;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void SoundSDL2::wavCallback(void* udata, uInt8* stream, int len)
{
SDL_memset(stream, myWavSpec.silence, len);
if(myWavLen)
{
if(static_cast<uInt32>(len) > myWavLen)
len = myWavLen;
// Mix volume adjusted WAV into silent buffer
SDL_MixAudioFormat(stream, myWavPos, myWavSpec.format, len,
SDL_MIX_MAXVOLUME * myVolumeFactor);
myWavPos += len;
myWavLen -= len;
}
}
float SoundSDL2::myVolumeFactor = 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
#endif // SOUND_SUPPORT #endif // SOUND_SUPPORT

View File

@ -164,7 +164,7 @@ class SoundSDL2 : public Sound
// Current volume as a percentage (0 - 100) // Current volume as a percentage (0 - 100)
uInt32 myVolume{100}; uInt32 myVolume{100};
float myVolumeFactor{0xffff}; static float myVolumeFactor;
// Audio specification structure // Audio specification structure
SDL_AudioSpec myHardwareSpec; SDL_AudioSpec myHardwareSpec;
@ -184,14 +184,20 @@ class SoundSDL2 : public Sound
AudioSettings& myAudioSettings; AudioSettings& myAudioSettings;
// WAV file sound variables
SDL_AudioDeviceID myWavDevice{0}; SDL_AudioDeviceID myWavDevice{0};
uInt8* myWavBuffer{nullptr}; uInt8* myWavBuffer{nullptr};
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
string myAboutString; string myAboutString;
private: private:
// Callback function invoked by the SDL Audio library when it needs data // Callback functions invoked by the SDL Audio library when it needs data
static void callback(void* udata, uInt8* stream, int len); static void callback(void* udata, uInt8* stream, int len);
static void wavCallback(void* udata, uInt8* stream, int len);
// Following constructors and assignment operators not supported // Following constructors and assignment operators not supported
SoundSDL2() = delete; SoundSDL2() = delete;

View File

@ -162,14 +162,17 @@ void KidVid::openSampleFiles()
mySampleFile = myBaseDir + fileNames[i]; mySampleFile = myBaseDir + fileNames[i];
std::ifstream f1, f2; std::ifstream f1, f2;
f1.open(mySampleFile, std::ios::binary); f1.open(mySampleFile);
f2.open(myBaseDir + "KVSHARED.WAV", std::ios::binary); f2.open(myBaseDir + "KVSHARED.WAV");
myFilesFound = f1.is_open() && f2.is_open(); myFilesFound = f1.is_open() && f2.is_open();
#ifdef DEBUG_BUILD
if(myFilesFound) if(myFilesFound)
cerr << "found file: " << fileNames[i] << endl cerr << endl
<< "found file: " << fileNames[i] << endl
<< "found file: " << "KVSHARED.WAV" << endl; << "found file: " << "KVSHARED.WAV" << endl;
#endif
mySongLength = 0; mySongLength = 0;
mySongPointer = firstSongPointer[i]; mySongPointer = firstSongPointer[i];
@ -190,6 +193,10 @@ void KidVid::setNextSong()
// Play the WAV file // Play the WAV file
const string fileName = (temp < 10) ? myBaseDir + "KVSHARED.WAV" : mySampleFile; const string fileName = (temp < 10) ? myBaseDir + "KVSHARED.WAV" : mySampleFile;
mySound.playWav(fileName.c_str(), ourSongStart[temp], mySongLength); mySound.playWav(fileName.c_str(), ourSongStart[temp], mySongLength);
#ifdef DEBUG_BUILD
cerr << fileName << ": " << (ourSongPositions[mySongPointer] & 0x7f) << endl;
#endif
mySongPlaying = myTapeBusy = true; mySongPlaying = myTapeBusy = true;
++mySongPointer; ++mySongPointer;