added WAV file volume adjustment (resolves #77)

This commit is contained in:
Thomas Jentzsch 2022-09-03 20:56:38 +02:00
parent 1c38d3e57a
commit 21f3b319c2
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)
{
// ToDos:
// - volume (requires callback using SDL_MixAudio)
// - (un)mute
SDL_AudioSpec wavSpec;
uInt32 wavLength{0};
// Stop any playing WAVs
stopWav();
// 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)
return false;
@ -423,18 +419,24 @@ bool SoundSDL2::playWav(const char* fileName, uInt32 position, uInt32 length)
? std::min(length, wavLength - position)
: wavLength;
// Set the callback function
myWavSpec.callback = wavCallback;
myWavSpec.userdata = nullptr;
myWavPos = myWavBuffer + position;
myWavLen = length;
// Open audio device
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)
return false;
// Play audio
int success = SDL_QueueAudio(myWavDevice, myWavBuffer + position, length);
SDL_PauseAudioDevice(myWavDevice, 0);
return success == 0;
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -452,7 +454,28 @@ void SoundSDL2::stopWav()
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

View File

@ -164,7 +164,7 @@ class SoundSDL2 : public Sound
// Current volume as a percentage (0 - 100)
uInt32 myVolume{100};
float myVolumeFactor{0xffff};
static float myVolumeFactor;
// Audio specification structure
SDL_AudioSpec myHardwareSpec;
@ -184,14 +184,20 @@ class SoundSDL2 : public Sound
AudioSettings& myAudioSettings;
// WAV file sound variables
SDL_AudioDeviceID myWavDevice{0};
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;
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 wavCallback(void* udata, uInt8* stream, int len);
// Following constructors and assignment operators not supported
SoundSDL2() = delete;

View File

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