Clarifying the OpenAL loop

because it isn't as clear as it can be
This commit is contained in:
John Peterson 2013-06-09 09:43:27 +02:00
parent 3ddd24872b
commit adb83cfabe
2 changed files with 108 additions and 113 deletions

View File

@ -124,6 +124,15 @@ void OpenALStream::SoundLoop()
{ {
Common::SetCurrentThreadName("Audio thread - openal"); Common::SetCurrentThreadName("Audio thread - openal");
bool surround_capable = Core::g_CoreStartupParameter.bDPL2Decoder;
#if defined(__APPLE__)
bool float32_capable = false;
// OSX does not have the alext AL_FORMAT_51CHN32 yet.
surround_capable = false;
#else
bool float32_capable = true;
#endif
u32 ulFrequency = m_mixer->GetSampleRate(); u32 ulFrequency = m_mixer->GetSampleRate();
numBuffers = Core::g_CoreStartupParameter.iLatency + 2; // OpenAL requires a minimum of two buffers numBuffers = Core::g_CoreStartupParameter.iLatency + 2; // OpenAL requires a minimum of two buffers
@ -136,16 +145,14 @@ void OpenALStream::SoundLoop()
alGenSources(1, &uiSource); alGenSources(1, &uiSource);
// Short Silence // Short Silence
memset(sampleBuffer, 0, OAL_MAX_SAMPLES * SIZE_FLOAT * SURROUND_CHANNELS * numBuffers); memset(sampleBuffer, 0, OAL_MAX_SAMPLES * numBuffers * FRAME_SURROUND_FLOAT);
memset(realtimeBuffer, 0, OAL_MAX_SAMPLES * 4); memset(realtimeBuffer, 0, OAL_MAX_SAMPLES * FRAME_STEREO_SHORT);
for (int i = 0; i < numBuffers; i++) for (int i = 0; i < numBuffers; i++)
{ {
#if !defined(__APPLE__) if (surround_capable)
if (Core::g_CoreStartupParameter.bDPL2Decoder) alBufferData(uiBuffers[i], AL_FORMAT_51CHN32, sampleBuffer, 4 * FRAME_SURROUND_FLOAT, ulFrequency);
alBufferData(uiBuffers[i], AL_FORMAT_51CHN32, sampleBuffer, 4 * SIZE_FLOAT * SURROUND_CHANNELS, ulFrequency);
else else
#endif alBufferData(uiBuffers[i], AL_FORMAT_STEREO16, realtimeBuffer, 4 * FRAME_STEREO_SHORT, ulFrequency);
alBufferData(uiBuffers[i], AL_FORMAT_STEREO16, realtimeBuffer, 4 * 2 * 2, ulFrequency);
} }
alSourceQueueBuffers(uiSource, numBuffers, uiBuffers); alSourceQueueBuffers(uiSource, numBuffers, uiBuffers);
alSourcePlay(uiSource); alSourcePlay(uiSource);
@ -170,13 +177,6 @@ void OpenALStream::SoundLoop()
soundTouch.setSetting(SETTING_SEEKWINDOW_MS, 28); soundTouch.setSetting(SETTING_SEEKWINDOW_MS, 28);
soundTouch.setSetting(SETTING_OVERLAP_MS, 12); soundTouch.setSetting(SETTING_OVERLAP_MS, 12);
bool surround_capable = Core::g_CoreStartupParameter.bDPL2Decoder;
#if defined(__APPLE__)
bool float32_capable = false;
#else
bool float32_capable = true;
#endif
while (!threadData) while (!threadData)
{ {
// num_samples_to_render in this update - depends on SystemTimers::AUDIO_DMA_PERIOD. // num_samples_to_render in this update - depends on SystemTimers::AUDIO_DMA_PERIOD.
@ -193,12 +193,9 @@ void OpenALStream::SoundLoop()
numSamples = m_mixer->Mix(realtimeBuffer, numSamples); numSamples = m_mixer->Mix(realtimeBuffer, numSamples);
// Convert the samples from short to float // Convert the samples from short to float
float dest[OAL_MAX_SAMPLES * 2 * 2 * OAL_MAX_BUFFERS]; float dest[OAL_MAX_SAMPLES * STEREO_CHANNELS];
for (u32 i = 0; i < numSamples; ++i) for (u32 i = 0; i < numSamples * STEREO_CHANNELS; ++i)
{ dest[i] = (float)realtimeBuffer[i] / (1 << 16);
dest[i * 2 + 0] = (float)realtimeBuffer[i * 2 + 0] / (1 << 16);
dest[i * 2 + 1] = (float)realtimeBuffer[i * 2 + 1] / (1 << 16);
}
soundTouch.putSamples(dest, numSamples); soundTouch.putSamples(dest, numSamples);
@ -230,10 +227,11 @@ void OpenALStream::SoundLoop()
} }
} }
unsigned int nSamples = soundTouch.receiveSamples(sampleBuffer, OAL_MAX_SAMPLES * SIZE_FLOAT * OAL_MAX_BUFFERS); unsigned int nSamples = soundTouch.receiveSamples(sampleBuffer, OAL_MAX_SAMPLES * numBuffers);
if (nSamples < minSamples)
continue;
if (nSamples > minSamples)
{
// Remove the Buffer from the Queue. (uiBuffer contains the Buffer ID for the unqueued Buffer) // Remove the Buffer from the Queue. (uiBuffer contains the Buffer ID for the unqueued Buffer)
if (iBuffersFilled == 0) if (iBuffersFilled == 0)
{ {
@ -244,16 +242,12 @@ void OpenALStream::SoundLoop()
ERROR_LOG(AUDIO, "Error unqueuing buffers: %08x", err); ERROR_LOG(AUDIO, "Error unqueuing buffers: %08x", err);
} }
} }
#if defined(__APPLE__)
// OSX does not have the alext AL_FORMAT_51CHN32 yet.
surround_capable = false;
#else
if (surround_capable) if (surround_capable)
{ {
float dpl2[OAL_MAX_SAMPLES * SIZE_FLOAT * SURROUND_CHANNELS * OAL_MAX_BUFFERS]; float dpl2[OAL_MAX_SAMPLES * OAL_MAX_BUFFERS * SURROUND_CHANNELS];
dpl2decode(sampleBuffer, nSamples, dpl2); dpl2decode(sampleBuffer, nSamples, dpl2);
alBufferData(uiBufferTemp[iBuffersFilled], AL_FORMAT_51CHN32, dpl2, nSamples * FRAME_SURROUND_FLOAT, ulFrequency);
alBufferData(uiBufferTemp[iBuffersFilled], AL_FORMAT_51CHN32, dpl2, nSamples * SIZE_FLOAT * SURROUND_CHANNELS, ulFrequency);
ALenum err = alGetError(); ALenum err = alGetError();
if (err == AL_INVALID_ENUM) if (err == AL_INVALID_ENUM)
{ {
@ -266,13 +260,12 @@ void OpenALStream::SoundLoop()
ERROR_LOG(AUDIO, "Error occurred while buffering data: %08x", err); ERROR_LOG(AUDIO, "Error occurred while buffering data: %08x", err);
} }
} }
#endif
if (!surround_capable) else
{ {
#if !defined(__APPLE__)
if (float32_capable) if (float32_capable)
{ {
alBufferData(uiBufferTemp[iBuffersFilled], AL_FORMAT_STEREO_FLOAT32, sampleBuffer, nSamples * 4 * 2, ulFrequency); alBufferData(uiBufferTemp[iBuffersFilled], AL_FORMAT_STEREO_FLOAT32, sampleBuffer, nSamples * FRAME_STEREO_FLOAT, ulFrequency);
ALenum err = alGetError(); ALenum err = alGetError();
if (err == AL_INVALID_ENUM) if (err == AL_INVALID_ENUM)
{ {
@ -283,17 +276,15 @@ void OpenALStream::SoundLoop()
ERROR_LOG(AUDIO, "Error occurred while buffering float32 data: %08x", err); ERROR_LOG(AUDIO, "Error occurred while buffering float32 data: %08x", err);
} }
} }
#endif
if (!float32_capable) else
{ {
// Convert the samples from float to short // Convert the samples from float to short
short stereo[OAL_MAX_SAMPLES * 2 * 2 * OAL_MAX_BUFFERS]; short stereo[OAL_MAX_SAMPLES * STEREO_CHANNELS * OAL_MAX_BUFFERS];
for (u32 i = 0; i < nSamples; ++i) for (u32 i = 0; i < nSamples * STEREO_CHANNELS; ++i)
{ stereo[i] = (short)((float)sampleBuffer[i] * (1 << 16));
stereo[i * 2 + 0] = (short)((float)sampleBuffer[i * 2 + 0] * (1 << 16));
stereo[i * 2 + 1] = (short)((float)sampleBuffer[i * 2 + 1] * (1 << 16)); alBufferData(uiBufferTemp[iBuffersFilled], AL_FORMAT_STEREO16, stereo, nSamples * FRAME_STEREO_SHORT, ulFrequency);
}
alBufferData(uiBufferTemp[iBuffersFilled], AL_FORMAT_STEREO16, stereo, nSamples * 2 * 2, ulFrequency);
} }
} }
@ -327,7 +318,6 @@ void OpenALStream::SoundLoop()
} }
} }
} }
}
else else
{ {
soundSyncEvent.Wait(); soundSyncEvent.Wait();

View File

@ -33,8 +33,13 @@
#define SFX_MAX_SOURCE 1 #define SFX_MAX_SOURCE 1
#define OAL_MAX_BUFFERS 32 #define OAL_MAX_BUFFERS 32
#define OAL_MAX_SAMPLES 256 #define OAL_MAX_SAMPLES 256
#define STEREO_CHANNELS 2
#define SURROUND_CHANNELS 6 // number of channels in surround mode #define SURROUND_CHANNELS 6 // number of channels in surround mode
#define SIZE_SHORT 2
#define SIZE_FLOAT 4 // size of a float in bytes #define SIZE_FLOAT 4 // size of a float in bytes
#define FRAME_STEREO_SHORT STEREO_CHANNELS * SIZE_SHORT
#define FRAME_STEREO_FLOAT STEREO_CHANNELS * SIZE_FLOAT
#define FRAME_SURROUND_FLOAT SURROUND_CHANNELS * SIZE_FLOAT
#endif #endif
class OpenALStream: public SoundStream class OpenALStream: public SoundStream
@ -61,8 +66,8 @@ private:
std::thread thread; std::thread thread;
Common::Event soundSyncEvent; Common::Event soundSyncEvent;
short realtimeBuffer[OAL_MAX_SAMPLES * 2]; short realtimeBuffer[OAL_MAX_SAMPLES * STEREO_CHANNELS];
soundtouch::SAMPLETYPE sampleBuffer[OAL_MAX_SAMPLES * SIZE_FLOAT * SURROUND_CHANNELS * OAL_MAX_BUFFERS]; soundtouch::SAMPLETYPE sampleBuffer[OAL_MAX_SAMPLES * SURROUND_CHANNELS * OAL_MAX_BUFFERS];
ALuint uiBuffers[OAL_MAX_BUFFERS]; ALuint uiBuffers[OAL_MAX_BUFFERS];
ALuint uiSource; ALuint uiSource;
ALfloat fVolume; ALfloat fVolume;