mirror of
https://github.com/fabiangreffrath/woof.git
synced 2025-09-23 03:52:12 -04:00
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
This commit is contained in:
parent
dd536bff1b
commit
639069d399
@ -147,15 +147,13 @@ static void FillBuffer(uint8_t *buffer, unsigned int nsamples)
|
|||||||
|
|
||||||
// Callback function to fill a new sound buffer:
|
// 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;
|
unsigned int filled;
|
||||||
uint8_t *buffer = stream;
|
|
||||||
|
|
||||||
// Repeatedly call the OPL emulator update function until the buffer is
|
// Repeatedly call the OPL emulator update function until the buffer is
|
||||||
// full.
|
// full.
|
||||||
filled = 0;
|
filled = 0;
|
||||||
buffer_samples = len / 4;
|
|
||||||
|
|
||||||
while (filled < buffer_samples)
|
while (filled < buffer_samples)
|
||||||
{
|
{
|
||||||
@ -196,7 +194,8 @@ static int OPL_Callback(byte *stream, int len)
|
|||||||
|
|
||||||
AdvanceTime(nsamples);
|
AdvanceTime(nsamples);
|
||||||
}
|
}
|
||||||
return len;
|
|
||||||
|
return buffer_samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OPL_SDL_Shutdown(void)
|
static void OPL_SDL_Shutdown(void)
|
||||||
|
@ -52,18 +52,18 @@ static fluid_player_t *player = NULL;
|
|||||||
static char **soundfonts;
|
static char **soundfonts;
|
||||||
static int soundfonts_num;
|
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;
|
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)
|
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
|
// Load SNDFONT lump
|
||||||
|
@ -28,10 +28,10 @@
|
|||||||
#include "i_sound.h"
|
#include "i_sound.h"
|
||||||
|
|
||||||
// Define the number of buffers and buffer size (in milliseconds) to use. 4
|
// 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
|
// buffers with 4096 samples each gives a nice per-chunk size, and lets the
|
||||||
// queue last for almost one second at 44.1khz.
|
// queue last for about half second at 44.1khz.
|
||||||
#define NUM_BUFFERS 4
|
#define NUM_BUFFERS 4
|
||||||
#define BUFFER_SAMPLES 8192
|
#define BUFFER_SAMPLES 4096
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -44,6 +44,7 @@ typedef struct
|
|||||||
// The format of the output stream
|
// The format of the output stream
|
||||||
ALenum format;
|
ALenum format;
|
||||||
ALsizei freq;
|
ALsizei freq;
|
||||||
|
ALsizei frame_size;
|
||||||
} stream_player_t;
|
} stream_player_t;
|
||||||
|
|
||||||
static stream_player_t player;
|
static stream_player_t player;
|
||||||
@ -69,6 +70,7 @@ static boolean UpdatePlayer(void)
|
|||||||
// Unqueue and handle each processed buffer
|
// Unqueue and handle each processed buffer
|
||||||
while (processed > 0)
|
while (processed > 0)
|
||||||
{
|
{
|
||||||
|
uint32_t frames;
|
||||||
ALuint bufid;
|
ALuint bufid;
|
||||||
ALsizei size;
|
ALsizei size;
|
||||||
|
|
||||||
@ -79,14 +81,16 @@ static boolean UpdatePlayer(void)
|
|||||||
// the source.
|
// the source.
|
||||||
if (callback)
|
if (callback)
|
||||||
{
|
{
|
||||||
size = callback(player.data, BUFFER_SAMPLES);
|
frames = callback(player.data, BUFFER_SAMPLES);
|
||||||
}
|
}
|
||||||
else
|
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);
|
alBufferData(bufid, player.format, player.data, size, player.freq);
|
||||||
alSourceQueueBuffers(player.source, 1, &bufid);
|
alSourceQueueBuffers(player.source, 1, &bufid);
|
||||||
}
|
}
|
||||||
@ -124,7 +128,7 @@ static boolean StartPlayer(void)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
player.data = malloc(BUFFER_SAMPLES);
|
player.data = malloc(BUFFER_SAMPLES * player.frame_size);
|
||||||
|
|
||||||
// Rewind the source position and clear the buffer queue.
|
// Rewind the source position and clear the buffer queue.
|
||||||
alSourceRewind(player.source);
|
alSourceRewind(player.source);
|
||||||
@ -133,23 +137,26 @@ static boolean StartPlayer(void)
|
|||||||
// Fill the buffer queue
|
// Fill the buffer queue
|
||||||
for (i = 0; i < NUM_BUFFERS; i++)
|
for (i = 0; i < NUM_BUFFERS; i++)
|
||||||
{
|
{
|
||||||
|
uint32_t frames;
|
||||||
ALsizei size;
|
ALsizei size;
|
||||||
|
|
||||||
// Get some data to give it to the buffer
|
// Get some data to give it to the buffer
|
||||||
if (callback)
|
if (callback)
|
||||||
{
|
{
|
||||||
size = callback(player.data, BUFFER_SAMPLES);
|
frames = callback(player.data, BUFFER_SAMPLES);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
size = I_SND_FillStream(player.data, BUFFER_SAMPLES);
|
frames = I_SND_FillStream(player.data, BUFFER_SAMPLES);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size < 1)
|
if (frames < 1)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
alBufferData(player.buffers[i], player.format, player.data,
|
size = frames * player.frame_size;
|
||||||
size, player.freq);
|
|
||||||
|
alBufferData(player.buffers[i], player.format, player.data, size,
|
||||||
|
player.freq);
|
||||||
}
|
}
|
||||||
if (alGetError() != AL_NO_ERROR)
|
if (alGetError() != AL_NO_ERROR)
|
||||||
{
|
{
|
||||||
@ -267,7 +274,11 @@ static void I_OAL_ShutdownMusic(void)
|
|||||||
|
|
||||||
static void *I_OAL_RegisterSong(void *data, int len)
|
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;
|
return NULL;
|
||||||
|
|
||||||
StartPlayer();
|
StartPlayer();
|
||||||
@ -294,6 +305,7 @@ void I_OAL_HookMusic(callback_func_t callback_func)
|
|||||||
|
|
||||||
player.format = AL_FORMAT_STEREO16;
|
player.format = AL_FORMAT_STEREO16;
|
||||||
player.freq = SND_SAMPLERATE;
|
player.freq = SND_SAMPLERATE;
|
||||||
|
player.frame_size = 2 * sizeof(short);
|
||||||
|
|
||||||
I_OAL_SetGain(1.0f);
|
I_OAL_SetGain(1.0f);
|
||||||
StartPlayer();
|
StartPlayer();
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
#include "doomtype.h"
|
#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_HookMusic(callback_func_t callback_func);
|
||||||
void I_OAL_SetGain(float gain);
|
void I_OAL_SetGain(float gain);
|
||||||
|
@ -198,7 +198,7 @@ typedef struct
|
|||||||
|
|
||||||
sample_format_t sample_format;
|
sample_format_t sample_format;
|
||||||
ALenum format;
|
ALenum format;
|
||||||
ALint byteblockalign;
|
ALint frame_size;
|
||||||
} sndfile_t;
|
} sndfile_t;
|
||||||
|
|
||||||
static void CloseFile(sndfile_t *file)
|
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;
|
sample_format_t sample_format;
|
||||||
ALenum format;
|
ALenum format;
|
||||||
ALint byteblockalign;
|
ALint frame_size;
|
||||||
|
|
||||||
file->sfdata.data = data;
|
file->sfdata.data = data;
|
||||||
file->sfdata.length = size;
|
file->sfdata.length = size;
|
||||||
@ -262,15 +262,15 @@ static boolean OpenFile(sndfile_t *file, void *data, sf_count_t size)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
byteblockalign = 1;
|
frame_size = 1;
|
||||||
|
|
||||||
if (sample_format == Int16)
|
if (sample_format == Int16)
|
||||||
{
|
{
|
||||||
byteblockalign = file->sfinfo.channels * 2;
|
frame_size = file->sfinfo.channels * 2;
|
||||||
}
|
}
|
||||||
else if (sample_format == Float)
|
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.
|
// 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->sample_format = sample_format;
|
||||||
file->format = format;
|
file->format = format;
|
||||||
file->byteblockalign = byteblockalign;
|
file->frame_size = frame_size;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -318,7 +318,7 @@ boolean I_SND_LoadFile(void *data, ALenum *format, byte **wavdata,
|
|||||||
return false;
|
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)
|
if (file.sample_format == Int16)
|
||||||
{
|
{
|
||||||
@ -341,7 +341,7 @@ boolean I_SND_LoadFile(void *data, ALenum *format, byte **wavdata,
|
|||||||
|
|
||||||
*wavdata = local_wavdata;
|
*wavdata = local_wavdata;
|
||||||
*format = file.format;
|
*format = file.format;
|
||||||
*size = num_frames * file.byteblockalign / file.sfinfo.channels;
|
*size = num_frames * file.frame_size / file.sfinfo.channels;
|
||||||
*freq = file.sfinfo.samplerate;
|
*freq = file.sfinfo.samplerate;
|
||||||
|
|
||||||
CloseFile(&file);
|
CloseFile(&file);
|
||||||
@ -352,7 +352,8 @@ boolean I_SND_LoadFile(void *data, ALenum *format, byte **wavdata,
|
|||||||
static sndfile_t stream;
|
static sndfile_t stream;
|
||||||
static boolean looping;
|
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)
|
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;
|
*format = stream.format;
|
||||||
*freq = stream.sfinfo.samplerate;
|
*freq = stream.sfinfo.samplerate;
|
||||||
|
*frame_size = stream.frame_size;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -370,10 +372,9 @@ void I_SND_SetLooping(boolean on)
|
|||||||
looping = 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 num_frames = 0;
|
||||||
sf_count_t frames = size / stream.byteblockalign;
|
|
||||||
|
|
||||||
if (stream.sample_format == Int16)
|
if (stream.sample_format == Int16)
|
||||||
{
|
{
|
||||||
@ -389,7 +390,7 @@ int I_SND_FillStream(byte *data, ALsizei size)
|
|||||||
sf_seek(stream.sndfile, 0, SEEK_SET);
|
sf_seek(stream.sndfile, 0, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (num_frames * stream.byteblockalign);
|
return num_frames;
|
||||||
}
|
}
|
||||||
|
|
||||||
void I_SND_CloseStream(void)
|
void I_SND_CloseStream(void)
|
||||||
|
@ -25,9 +25,10 @@
|
|||||||
boolean I_SND_LoadFile(void *data, ALenum *format, byte **wavdata,
|
boolean I_SND_LoadFile(void *data, ALenum *format, byte **wavdata,
|
||||||
ALsizei *size, ALsizei *freq);
|
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);
|
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);
|
void I_SND_CloseStream(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user