From 639069d399c5446cf7c83ed5160a7e1e2cfbc686 Mon Sep 17 00:00:00 2001 From: Roman Fomin Date: Wed, 5 Apr 2023 12:46:56 +0700 Subject: [PATCH] OAL stream: actually use buffer samples instead of buffer size This was the idea from the beginning. Also reduce the buffer length to about half a second. * cosmetic changes --- opl/opl_sdl.c | 9 ++++----- src/i_flmusic.c | 8 ++++---- src/i_oalmusic.c | 38 +++++++++++++++++++++++++------------- src/i_oalmusic.h | 2 +- src/i_sndfile.c | 25 +++++++++++++------------ src/i_sndfile.h | 5 +++-- 6 files changed, 50 insertions(+), 37 deletions(-) diff --git a/opl/opl_sdl.c b/opl/opl_sdl.c index af9355b5..300b62c9 100644 --- a/opl/opl_sdl.c +++ b/opl/opl_sdl.c @@ -147,15 +147,13 @@ static void FillBuffer(uint8_t *buffer, unsigned int nsamples) // Callback function to fill a new sound buffer: -static int OPL_Callback(byte *stream, int len) +static uint32_t OPL_Callback(byte *buffer, uint32_t buffer_samples) { - unsigned int filled, buffer_samples; - uint8_t *buffer = stream; + unsigned int filled; // Repeatedly call the OPL emulator update function until the buffer is // full. filled = 0; - buffer_samples = len / 4; while (filled < buffer_samples) { @@ -196,7 +194,8 @@ static int OPL_Callback(byte *stream, int len) AdvanceTime(nsamples); } - return len; + + return buffer_samples; } static void OPL_SDL_Shutdown(void) diff --git a/src/i_flmusic.c b/src/i_flmusic.c index de0032cb..74c0530a 100644 --- a/src/i_flmusic.c +++ b/src/i_flmusic.c @@ -52,18 +52,18 @@ static fluid_player_t *player = NULL; static char **soundfonts; static int soundfonts_num; -static int FL_Callback(byte *stream, int len) +static uint32_t FL_Callback(byte *buffer, uint32_t buffer_samples) { int result; - result = fluid_synth_write_s16(synth, len / 4, stream, 0, 2, stream, 1, 2); + result = fluid_synth_write_s16(synth, buffer_samples, buffer, 0, 2, buffer, 1, 2); if (result != FLUID_OK) { - fprintf(stderr, "Error generating FluidSynth audio\n"); + fprintf(stderr, "FL_Callback: Error generating FluidSynth audio\n"); } - return len; + return buffer_samples; } // Load SNDFONT lump diff --git a/src/i_oalmusic.c b/src/i_oalmusic.c index b84bb433..81b8d7d2 100644 --- a/src/i_oalmusic.c +++ b/src/i_oalmusic.c @@ -28,10 +28,10 @@ #include "i_sound.h" // Define the number of buffers and buffer size (in milliseconds) to use. 4 -// buffers with 8192 samples each gives a nice per-chunk size, and lets the -// queue last for almost one second at 44.1khz. +// buffers with 4096 samples each gives a nice per-chunk size, and lets the +// queue last for about half second at 44.1khz. #define NUM_BUFFERS 4 -#define BUFFER_SAMPLES 8192 +#define BUFFER_SAMPLES 4096 typedef struct { @@ -44,6 +44,7 @@ typedef struct // The format of the output stream ALenum format; ALsizei freq; + ALsizei frame_size; } stream_player_t; static stream_player_t player; @@ -69,6 +70,7 @@ static boolean UpdatePlayer(void) // Unqueue and handle each processed buffer while (processed > 0) { + uint32_t frames; ALuint bufid; ALsizei size; @@ -79,14 +81,16 @@ static boolean UpdatePlayer(void) // the source. if (callback) { - size = callback(player.data, BUFFER_SAMPLES); + frames = callback(player.data, BUFFER_SAMPLES); } else { - size = I_SND_FillStream(player.data, BUFFER_SAMPLES); + frames = I_SND_FillStream(player.data, BUFFER_SAMPLES); } - if (size > 0) + + if (frames > 0) { + size = frames * player.frame_size; alBufferData(bufid, player.format, player.data, size, player.freq); alSourceQueueBuffers(player.source, 1, &bufid); } @@ -124,7 +128,7 @@ static boolean StartPlayer(void) { int i; - player.data = malloc(BUFFER_SAMPLES); + player.data = malloc(BUFFER_SAMPLES * player.frame_size); // Rewind the source position and clear the buffer queue. alSourceRewind(player.source); @@ -133,23 +137,26 @@ static boolean StartPlayer(void) // Fill the buffer queue for (i = 0; i < NUM_BUFFERS; i++) { + uint32_t frames; ALsizei size; // Get some data to give it to the buffer if (callback) { - size = callback(player.data, BUFFER_SAMPLES); + frames = callback(player.data, BUFFER_SAMPLES); } else { - size = I_SND_FillStream(player.data, BUFFER_SAMPLES); + frames = I_SND_FillStream(player.data, BUFFER_SAMPLES); } - if (size < 1) + if (frames < 1) break; - alBufferData(player.buffers[i], player.format, player.data, - size, player.freq); + size = frames * player.frame_size; + + alBufferData(player.buffers[i], player.format, player.data, size, + player.freq); } if (alGetError() != AL_NO_ERROR) { @@ -267,7 +274,11 @@ static void I_OAL_ShutdownMusic(void) static void *I_OAL_RegisterSong(void *data, int len) { - if (I_SND_OpenStream(data, len, &player.format, &player.freq) == false) + boolean result; + + result = I_SND_OpenStream(data, len, &player.format, &player.freq, + &player.frame_size); + if (!result) return NULL; StartPlayer(); @@ -294,6 +305,7 @@ void I_OAL_HookMusic(callback_func_t callback_func) player.format = AL_FORMAT_STEREO16; player.freq = SND_SAMPLERATE; + player.frame_size = 2 * sizeof(short); I_OAL_SetGain(1.0f); StartPlayer(); diff --git a/src/i_oalmusic.h b/src/i_oalmusic.h index 8e1f56f9..e9fc9e00 100644 --- a/src/i_oalmusic.h +++ b/src/i_oalmusic.h @@ -19,7 +19,7 @@ #include "doomtype.h" -typedef int (*callback_func_t)(byte *data, int size); +typedef uint32_t (*callback_func_t)(byte *buffer, uint32_t buffer_samples); void I_OAL_HookMusic(callback_func_t callback_func); void I_OAL_SetGain(float gain); diff --git a/src/i_sndfile.c b/src/i_sndfile.c index 008de5d7..0d6a999d 100644 --- a/src/i_sndfile.c +++ b/src/i_sndfile.c @@ -198,7 +198,7 @@ typedef struct sample_format_t sample_format; ALenum format; - ALint byteblockalign; + ALint frame_size; } sndfile_t; static void CloseFile(sndfile_t *file) @@ -214,7 +214,7 @@ static boolean OpenFile(sndfile_t *file, void *data, sf_count_t size) { sample_format_t sample_format; ALenum format; - ALint byteblockalign; + ALint frame_size; file->sfdata.data = data; file->sfdata.length = size; @@ -262,15 +262,15 @@ static boolean OpenFile(sndfile_t *file, void *data, sf_count_t size) break; } - byteblockalign = 1; + frame_size = 1; if (sample_format == Int16) { - byteblockalign = file->sfinfo.channels * 2; + frame_size = file->sfinfo.channels * 2; } else if (sample_format == Float) { - byteblockalign = file->sfinfo.channels * 4; + frame_size = file->sfinfo.channels * 4; } // Figure out the OpenAL format from the file and desired sample type. @@ -301,7 +301,7 @@ static boolean OpenFile(sndfile_t *file, void *data, sf_count_t size) file->sample_format = sample_format; file->format = format; - file->byteblockalign = byteblockalign; + file->frame_size = frame_size; return true; } @@ -318,7 +318,7 @@ boolean I_SND_LoadFile(void *data, ALenum *format, byte **wavdata, return false; } - local_wavdata = malloc(file.sfinfo.frames * file.byteblockalign / file.sfinfo.channels); + local_wavdata = malloc(file.sfinfo.frames * file.frame_size / file.sfinfo.channels); if (file.sample_format == Int16) { @@ -341,7 +341,7 @@ boolean I_SND_LoadFile(void *data, ALenum *format, byte **wavdata, *wavdata = local_wavdata; *format = file.format; - *size = num_frames * file.byteblockalign / file.sfinfo.channels; + *size = num_frames * file.frame_size / file.sfinfo.channels; *freq = file.sfinfo.samplerate; CloseFile(&file); @@ -352,7 +352,8 @@ boolean I_SND_LoadFile(void *data, ALenum *format, byte **wavdata, static sndfile_t stream; static boolean looping; -boolean I_SND_OpenStream(void *data, ALsizei size, ALenum *format, ALsizei *freq) +boolean I_SND_OpenStream(void *data, ALsizei size, ALenum *format, + ALsizei *freq, ALsizei *frame_size) { if (OpenFile(&stream, data, size) == false) { @@ -361,6 +362,7 @@ boolean I_SND_OpenStream(void *data, ALsizei size, ALenum *format, ALsizei *freq *format = stream.format; *freq = stream.sfinfo.samplerate; + *frame_size = stream.frame_size; return true; } @@ -370,10 +372,9 @@ void I_SND_SetLooping(boolean on) looping = on; } -int I_SND_FillStream(byte *data, ALsizei size) +uint32_t I_SND_FillStream(byte *data, uint32_t frames) { sf_count_t num_frames = 0; - sf_count_t frames = size / stream.byteblockalign; if (stream.sample_format == Int16) { @@ -389,7 +390,7 @@ int I_SND_FillStream(byte *data, ALsizei size) sf_seek(stream.sndfile, 0, SEEK_SET); } - return (num_frames * stream.byteblockalign); + return num_frames; } void I_SND_CloseStream(void) diff --git a/src/i_sndfile.h b/src/i_sndfile.h index aa464ce5..0f40990f 100644 --- a/src/i_sndfile.h +++ b/src/i_sndfile.h @@ -25,9 +25,10 @@ boolean I_SND_LoadFile(void *data, ALenum *format, byte **wavdata, ALsizei *size, ALsizei *freq); -boolean I_SND_OpenStream(void *data, ALsizei size, ALenum *format, ALsizei *freq); +boolean I_SND_OpenStream(void *data, ALsizei size, ALenum *format, + ALsizei *freq, ALsizei *frame_size); void I_SND_SetLooping(boolean on); -int I_SND_FillStream(byte *data, ALsizei size); +uint32_t I_SND_FillStream(byte *data, uint32_t frames); void I_SND_CloseStream(void); #endif