Skip to content

Commit b0f4a3c

Browse files
switch movie audio from OpenAL to SDL3
1 parent 74258ba commit b0f4a3c

File tree

4 files changed

+45
-69
lines changed

4 files changed

+45
-69
lines changed

code/cutscene/movie.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,7 @@ void showVideoInfo(const PlayerState& state) {
8080

8181
size_t audio_queue_size = state.decoder->getAudioQueueSize();
8282
if (state.hasAudio) {
83-
ALint queued;
84-
OpenAL_ErrorPrint(alGetSourcei(state.audioSid, AL_BUFFERS_QUEUED, &queued));
85-
audio_queue_size += queued;
83+
audio_queue_size += SDL_GetAudioStreamQueued(state.audioStream);
8684
}
8785

8886
y = print_string(x, y, "Audio Queue size: " SIZE_T_ARG, audio_queue_size);

code/cutscene/player.cpp

Lines changed: 30 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010

1111
#include "osapi/osapi.h"
1212

13-
#include "sound/openal.h"
14-
1513
#include "tracing/tracing.h"
1614

1715
#include "io/key.h"
@@ -25,8 +23,6 @@ using namespace cutscene::player;
2523
namespace {
2624
using namespace cutscene;
2725

28-
const int MAX_AUDIO_BUFFERS = 15;
29-
3026
std::unique_ptr<Decoder> findDecoder(__UNUSED const SCP_string& name, __UNUSED const PlaybackProperties& properties) {
3127
#ifdef WITH_FFMPEG
3228
{
@@ -71,19 +67,23 @@ void audioPlaybackInit(PlayerState* state) {
7167
}
7268
state->hasAudio = true;
7369

74-
OpenAL_ErrorCheck(alGenSources(1, &state->audioSid), return);
75-
OpenAL_ErrorPrint(alSourcef(state->audioSid, AL_GAIN, 1.0f));
76-
77-
state->audioBuffers.clear();
78-
state->audioBuffers.resize(MAX_AUDIO_BUFFERS, 0);
70+
// best guess defaults, might change later
71+
state->audioSpec.channels = 2;
72+
state->audioSpec.format = SDL_AUDIO_S16LE;
73+
state->audioSpec.freq = 48000;
7974

80-
OpenAL_ErrorCheck(alGenBuffers(static_cast<ALsizei>(state->audioBuffers.size()), state->audioBuffers.data()),
81-
return);
75+
state->audioStream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK,
76+
&state->audioSpec,
77+
nullptr, nullptr);
8278

83-
for (auto buffer : state->audioBuffers) {
84-
state->unqueuedAudioBuffers.push(buffer);
79+
if ( !state->audioStream ) {
80+
return;
8581
}
8682

83+
// stream is created in a paused state, so start it playing
84+
// it will just be silent until data is queued
85+
SDL_ResumeAudioStreamDevice(state->audioStream);
86+
8787
state->audioInited = true;
8888
}
8989

@@ -185,76 +185,44 @@ void processSubtitleData(PlayerState* state) {
185185
bool processAudioData(PlayerState* state) {
186186
TRACE_SCOPE(tracing::CutsceneProcessAudioData);
187187

188+
AudioFramePtr audioData;
189+
188190
if (!state->hasAudio) {
189191
if (state->decoder->hasAudio()) {
190192
// Even if we don't play the sound we still need to remove it from the queue
191-
AudioFramePtr audioData;
192193
while (state->decoder->tryPopAudioData(audioData)) {
193194
// Intentionally left empty
194195
}
195196
}
196197
return false;
197198
}
198199

199-
ALint processed = 0;
200-
OpenAL_ErrorCheck(alGetSourcei(state->audioSid, AL_BUFFERS_PROCESSED, &processed), return false);
201-
202-
// First check for free buffers and push them int the audio queue
203-
for (int i = 0; i < processed; ++i) {
204-
ALuint buffer;
205-
OpenAL_ErrorPrint(alSourceUnqueueBuffers(state->audioSid, 1, &buffer));
206-
state->unqueuedAudioBuffers.push(buffer);
207-
}
208-
209-
AudioFramePtr audioData;
210-
211-
while (!state->unqueuedAudioBuffers.empty() && state->decoder->tryPopAudioData(audioData)) {
212-
auto buffer = state->unqueuedAudioBuffers.front();
213-
state->unqueuedAudioBuffers.pop();
214-
215-
ALenum format = (audioData->channels == 2) ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16;
216-
217-
OpenAL_ErrorCheck(alBufferData(buffer,
218-
format,
219-
audioData->audioData.data(),
220-
static_cast<ALsizei>(audioData->audioData.size() * sizeof(short)),
221-
static_cast<ALsizei>(audioData->rate)), return false);
222-
223-
OpenAL_ErrorCheck(alSourceQueueBuffers(state->audioSid, 1, &buffer), return false);
224-
}
225-
226-
ALint status = 0, queued = 0;
227-
OpenAL_ErrorCheck(alGetSourcei(state->audioSid, AL_SOURCE_STATE, &status), return false);
200+
while (state->decoder->tryPopAudioData(audioData)) {
201+
// change audio format if needed (doesn't affect currently queued data)
202+
if ((audioData->channels != state->audioSpec.channels) ||
203+
(audioData->rate != state->audioSpec.freq))
204+
{
205+
state->audioSpec.channels = audioData->channels;
206+
state->audioSpec.freq = audioData->rate;
228207

229-
OpenAL_ErrorCheck(alGetSourcei(state->audioSid, AL_BUFFERS_QUEUED, &queued), return false);
208+
SDL_SetAudioStreamFormat(state->audioStream, &state->audioSpec, nullptr);
209+
}
230210

231-
if ((status != AL_PLAYING) && (queued > 0)) {
232-
OpenAL_ErrorPrint(alSourcePlay(state->audioSid));
211+
// add it to the queue
212+
SDL_PutAudioStreamData(state->audioStream, audioData->audioData.data(),
213+
static_cast<int>(audioData->audioData.size() * sizeof(short)));
233214
}
234215

235-
// Get status again in cause we just started playback
236-
OpenAL_ErrorCheck(alGetSourcei(state->audioSid, AL_SOURCE_STATE, &status), return false);
237-
return status == AL_PLAYING;
216+
return true;
238217
}
239218

240219
void audioPlaybackClose(PlayerState* state) {
241220
if (!state->audioInited) {
242221
return;
243222
}
244223

245-
ALint p = 0;
246-
247-
OpenAL_ErrorPrint(alSourceStop(state->audioSid));
248-
OpenAL_ErrorPrint(alGetSourcei(state->audioSid, AL_BUFFERS_PROCESSED, &p));
249-
OpenAL_ErrorPrint(alSourceUnqueueBuffers(state->audioSid, p, state->audioBuffers.data()));
250-
OpenAL_ErrorPrint(alDeleteSources(1, &state->audioSid));
251-
252-
for (auto buffer : state->audioBuffers) {
253-
// make sure that the buffer is real before trying to delete, it could crash for some otherwise
254-
if ((buffer != 0) && alIsBuffer(buffer)) {
255-
OpenAL_ErrorPrint(alDeleteBuffers(1, &buffer));
256-
}
257-
}
224+
SDL_DestroyAudioStream(state->audioStream);
225+
state->audioStream = nullptr;
258226

259227
state->audioInited = false;
260228
}

code/cutscene/player.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
#include <thread>
66

77
#include "globalincs/pstypes.h"
8-
#include "sound/openal.h"
98

109
#include "Decoder.h"
1110
#include "VideoPresenter.h"
@@ -25,9 +24,8 @@ struct PlayerState {
2524
// Audio state
2625
bool audioInited = false;
2726
bool hasAudio = false;
28-
ALuint audioSid = 0;
29-
SCP_vector<ALuint> audioBuffers;
30-
SCP_queue<ALuint> unqueuedAudioBuffers;
27+
SDL_AudioStream *audioStream = nullptr;
28+
SDL_AudioSpec audioSpec;
3129

3230
// Graphics state following
3331
bool videoInited = false;

code/sound/sound.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,12 @@ int snd_init()
203203

204204
snd_clear();
205205

206+
if ( !SDL_InitSubSystem(SDL_INIT_AUDIO) ) {
207+
nprintf(( "Sound", "SOUND => Fatal error initializing SDL audio!\n" ));
208+
Cmdline_freespace_no_sound = Cmdline_freespace_no_music = 1;
209+
goto Failure;
210+
}
211+
206212
rval = ds_init();
207213

208214
if ( rval != 0 ) {
@@ -221,6 +227,10 @@ int snd_init()
221227
return 1;
222228

223229
Failure:
230+
if (SDL_WasInit(SDL_INIT_AUDIO)) {
231+
SDL_QuitSubSystem(SDL_INIT_AUDIO);
232+
}
233+
224234
// Warning(LOCATION, "Sound system was unable to be initialized. If you continue, sound will be disabled.\n");
225235
nprintf(( "Sound", "SOUND => Audio init unsuccessful, continuing without sound.\n" ));
226236
return 0;
@@ -542,6 +552,8 @@ void snd_close(void)
542552
snd_unload_all(); // free the sound data stored in DirectSound secondary buffers
543553
dscap_close(); // Close DirectSoundCapture
544554
ds_close(); // Close DirectSound off
555+
556+
SDL_QuitSubSystem(SDL_INIT_AUDIO);
545557
}
546558

547559
// ---------------------------------------------------------------------------------------

0 commit comments

Comments
 (0)