Change Audio class to optionally use SDL's internal audio stream.
Close #2215.
This commit is contained in:
parent
136b84e351
commit
7b4dab3783
@ -87,12 +87,7 @@ bool Audio::SetMode(int bufferLengthMSec, int mixRate, bool stereo, bool interpo
|
||||
|
||||
desired.freq = mixRate;
|
||||
|
||||
// The concept behind the emscripten audio port is to treat it as 16 bit until the final accumulation form the clip buffer
|
||||
#ifdef __EMSCRIPTEN__
|
||||
desired.format = AUDIO_F32LSB;
|
||||
#else
|
||||
desired.format = AUDIO_S16;
|
||||
#endif
|
||||
desired.channels = (Uint8)(stereo ? 2 : 1);
|
||||
desired.callback = SDLAudioCallback;
|
||||
desired.userdata = this;
|
||||
@ -103,30 +98,22 @@ bool Audio::SetMode(int bufferLengthMSec, int mixRate, bool stereo, bool interpo
|
||||
if (Abs((int)desired.samples / 2 - bufferSamples) < Abs((int)desired.samples - bufferSamples))
|
||||
desired.samples /= 2;
|
||||
|
||||
deviceID_ = SDL_OpenAudioDevice(nullptr, SDL_FALSE, &desired, &obtained, SDL_AUDIO_ALLOW_ANY_CHANGE);
|
||||
// Intentionally disallow format change so that the obtained format will always be the desired format, even though that format
|
||||
// is not matching the device format, however in doing it will enable the SDL's internal audio stream with audio conversion
|
||||
deviceID_ = SDL_OpenAudioDevice(nullptr, SDL_FALSE, &desired, &obtained, SDL_AUDIO_ALLOW_ANY_CHANGE&~SDL_AUDIO_ALLOW_FORMAT_CHANGE);
|
||||
if (!deviceID_)
|
||||
{
|
||||
URHO3D_LOGERROR("Could not initialize audio output");
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
if (obtained.format != AUDIO_F32LSB && obtained.format != AUDIO_F32MSB && obtained.format != AUDIO_F32SYS)
|
||||
{
|
||||
URHO3D_LOGERROR("Could not initialize audio output, 32-bit float buffer format not supported");
|
||||
SDL_CloseAudioDevice(deviceID_);
|
||||
deviceID_ = 0;
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
if (obtained.format != AUDIO_S16SYS && obtained.format != AUDIO_S16LSB && obtained.format != AUDIO_S16MSB)
|
||||
if (obtained.format != AUDIO_S16)
|
||||
{
|
||||
URHO3D_LOGERROR("Could not initialize audio output, 16-bit buffer format not supported");
|
||||
SDL_CloseAudioDevice(deviceID_);
|
||||
deviceID_ = 0;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
stereo_ = obtained.channels == 2;
|
||||
sampleSize_ = (unsigned)(stereo_ ? sizeof(int) : sizeof(short));
|
||||
@ -274,7 +261,7 @@ void SDLAudioCallback(void* userdata, Uint8* stream, int len)
|
||||
auto* audio = static_cast<Audio*>(userdata);
|
||||
{
|
||||
MutexLock Lock(audio->GetMutex());
|
||||
audio->MixOutput(stream, len / audio->GetSampleSize() / Audio::SAMPLE_SIZE_MUL);
|
||||
audio->MixOutput(stream, len / audio->GetSampleSize());
|
||||
}
|
||||
}
|
||||
|
||||
@ -282,7 +269,7 @@ void Audio::MixOutput(void* dest, unsigned samples)
|
||||
{
|
||||
if (!playing_ || !clipBuffer_)
|
||||
{
|
||||
memset(dest, 0, samples * sampleSize_ * SAMPLE_SIZE_MUL);
|
||||
memset(dest, 0, samples * sampleSize_);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -313,17 +300,11 @@ void Audio::MixOutput(void* dest, unsigned samples)
|
||||
source->Mix(clipPtr, workSamples, mixRate_, stereo_, interpolation_);
|
||||
}
|
||||
// Copy output from clip buffer to destination
|
||||
#ifdef __EMSCRIPTEN__
|
||||
float* destPtr = (float*)dest;
|
||||
while (clipSamples--)
|
||||
*destPtr++ = (float)Clamp(*clipPtr++, -32768, 32767) / 32768.0f;
|
||||
#else
|
||||
auto* destPtr = (short*)dest;
|
||||
while (clipSamples--)
|
||||
*destPtr++ = (short)Clamp(*clipPtr++, -32768, 32767);
|
||||
#endif
|
||||
samples -= workSamples;
|
||||
((unsigned char*&)dest) += sampleSize_ * SAMPLE_SIZE_MUL * workSamples;
|
||||
((unsigned char*&)dest) += sampleSize_ * workSamples;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -115,12 +115,6 @@ public:
|
||||
/// Mix sound sources into the buffer.
|
||||
void MixOutput(void* dest, unsigned samples);
|
||||
|
||||
/// Final multiplier for audio byte conversion.
|
||||
#ifdef __EMSCRIPTEN__
|
||||
static const int SAMPLE_SIZE_MUL = 2;
|
||||
#else
|
||||
static const int SAMPLE_SIZE_MUL = 1;
|
||||
#endif
|
||||
private:
|
||||
/// Handle render update event.
|
||||
void HandleRenderUpdate(StringHash eventType, VariantMap& eventData);
|
||||
|
Loading…
Reference in New Issue
Block a user