mirror of https://github.com/stella-emu/stella.git
added WAV file volume adjustment (resolves #77)
This commit is contained in:
parent
d54e7f34fe
commit
c7cac63a38
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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];
|
||||||
|
@ -185,11 +188,15 @@ void KidVid::setNextSong()
|
||||||
myBeep = (ourSongPositions[mySongPointer] & 0x80) == 0;
|
myBeep = (ourSongPositions[mySongPointer] & 0x80) == 0;
|
||||||
|
|
||||||
const uInt8 temp = ourSongPositions[mySongPointer] & 0x7f;
|
const uInt8 temp = ourSongPositions[mySongPointer] & 0x7f;
|
||||||
mySongLength = ourSongStart[temp+1] - ourSongStart[temp];
|
mySongLength = ourSongStart[temp + 1] - ourSongStart[temp];
|
||||||
|
|
||||||
// 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;
|
||||||
|
|
Loading…
Reference in New Issue