17 unsigned wantedFreq,
unsigned wantedSamples)
21 SDL_AudioSpec desired;
22 desired.freq = wantedFreq;
25 desired.format = AUDIO_F32SYS;
26 desired.callback = audioCallbackHelper;
27 desired.userdata =
this;
29 SDL_AudioSpec obtained;
30 deviceID = SDL_OpenAudioDevice(
nullptr, SDL_FALSE, &desired, &obtained,
31 SDL_AUDIO_ALLOW_FREQUENCY_CHANGE);
33 throw MSXException(
"Unable to open SDL audio: ", SDL_GetError());
36 frequency = obtained.freq;
37 fragmentSize = obtained.samples;
39 mixBufferSize = 3 * (obtained.size /
sizeof(float)) + 2;
40 mixBuffer.
resize(mixBufferSize);
46 SDL_CloseAudioDevice(deviceID);
49 void SDLSoundDriver::reInit()
51 SDL_LockAudioDevice(deviceID);
54 SDL_UnlockAudioDevice(deviceID);
61 SDL_PauseAudioDevice(deviceID, 1);
70 SDL_PauseAudioDevice(deviceID, 0);
84 void SDLSoundDriver::audioCallbackHelper(
void* userdata, uint8_t* strm,
int len)
86 assert((len & 7) == 0);
88 audioCallback(
reinterpret_cast<float*
>(strm), len /
sizeof(float));
91 unsigned SDLSoundDriver::getBufferFilled()
const
93 int result = writeIdx - readIdx;
94 if (result < 0) result += mixBufferSize;
95 assert((0 <= result) && (
unsigned(result) < mixBufferSize));
99 unsigned SDLSoundDriver::getBufferFree()
const
105 int result = mixBufferSize - 2 - getBufferFilled();
106 assert((0 <= result) && (
unsigned(result) < mixBufferSize));
110 void SDLSoundDriver::audioCallback(
float* stream,
unsigned len)
112 assert((len & 1) == 0);
113 unsigned available = getBufferFilled();
114 unsigned num =
std::min(len, available);
115 if ((readIdx + num) < mixBufferSize) {
116 memcpy(stream, &mixBuffer[readIdx], num *
sizeof(
float));
119 unsigned len1 = mixBufferSize - readIdx;
120 memcpy(stream, &mixBuffer[readIdx], len1 *
sizeof(
float));
121 unsigned len2 = num - len1;
122 memcpy(&stream[len1], &mixBuffer[0], len2 *
sizeof(
float));
125 int missing = len - available;
128 memset(&stream[available], 0, missing *
sizeof(
float));
134 SDL_LockAudioDevice(deviceID);
136 unsigned free = getBufferFree();
139 if (board && !board->getMSXMixer().isSynchronousMode() &&
142 SDL_UnlockAudioDevice(deviceID);
144 SDL_LockAudioDevice(deviceID);
145 board->getRealTime().resync();
146 free = getBufferFree();
147 }
while (len > free);
154 if ((writeIdx + len) < mixBufferSize) {
155 memcpy(&mixBuffer[writeIdx], buffer, len *
sizeof(
float));
158 unsigned len1 = mixBufferSize - writeIdx;
159 memcpy(&mixBuffer[writeIdx], buffer, len1 *
sizeof(
float));
160 unsigned len2 = len - len1;
161 memcpy(&mixBuffer[0], &buffer[len1], len2 *
sizeof(
float));
165 SDL_UnlockAudioDevice(deviceID);