fix incorrect buffer free (now handled by ALBuffer); work in progress

This was SVN commit r1172.
This commit is contained in:
janwas 2004-09-19 19:29:03 +00:00
parent 85cf439f62
commit ae2d42bbad

View File

@ -57,8 +57,12 @@ struct Sound
uint flags;
ALuint al_source;
// list of all sounds
Sound* next;
// handle to this Sound, so that it can close itself
Handle hs;
// if stream:
Handle hf;
ALenum al_format;
@ -212,8 +216,12 @@ cassert(sizeof(WavFormatChunk) == 16);
#pragma pack(pop)
static int wav_detect(Handle hf, ALenum* al_format, ALsizei* al_sample_rate)
// output parameters zeroed on failure.
static int wav_detect_format(Handle hf, ALenum* al_format, ALsizei* al_sample_rate)
{
*al_format = 0;
*al_sample_rate = 0;
int ret = -1;
WavFormatChunk* fmt = 0;
@ -278,51 +286,6 @@ fail:
}
// output parameters zeroed on failure.
static int detect_audio_fmt(Handle hf, ALenum* al_format, ALsizei* al_sample_rate)
{
*al_format = 0;
*al_sample_rate = 0;
const char* fn = h_filename(hf);
if(!fn)
return -1;
char* ext = strrchr(fn, '.');
if(!ext)
return -1;
// OGG (data will be passed directly to OpenAL)
if(!stricmp(ext, ".ogg"))
{
if(!ogg_supported)
return -1;
*al_format = AL_FORMAT_VORBIS_EXT;
*al_sample_rate = 1;
return 0;
}
// WAV
else if(!stricmp(ext, ".wav"))
return wav_detect(hf, al_format, al_sample_rate);
// not WAV either => unknown
else
return -1;
}
///////////////////////////////////////////////////////////////////////////////
//
@ -363,19 +326,52 @@ static int ALBuffer_reload(ALBuffer* b, const char* fn, Handle)
hf = vfs_open(fn);
CHECK_ERR(hf);
// detect sound file format and seek to audio data
//
// detect sound format (by checking file extension)
//
ALenum al_format;
ALsizei al_sample_rate;
int err = detect_audio_fmt(hf, &al_format, &al_sample_rate);
char* ext = strrchr(fn, '.');
// .. OGG (data will be passed directly to OpenAL)
if(ext && !stricmp(ext, ".ogg"))
{
if(!ogg_supported)
{
ret = -1;
goto fail;
}
al_format = AL_FORMAT_VORBIS_EXT;
al_sample_rate = 1;
}
// .. WAV (read format from header and seek to audio data)
else if(ext && !stricmp(ext, ".wav"))
{
int err = wav_detect_format(hf, &al_format, &al_sample_rate);
if(err < 0)
{
ret = err;
goto fail;
}
}
// .. unknown extension
else
{
ret = -1;
goto fail;
}
// alloc temp buffer that will hold waveform data until OpenAL latches
// it below. note: we don't know how much has already been read by
// detect_audio_fmt; we allocate enough for the entire file.
//
// allocate buffer for audio data
//
// note: freed after openal latches its contents in al_create_buffer.
// we don't know how much has already been read by wav_detect_format;
// allocate enough for the entire file.
ssize_t file_size = vfs_size(hf);
if(file_size < 0)
{
@ -399,7 +395,7 @@ static int ALBuffer_reload(ALBuffer* b, const char* fn, Handle)
goto fail;
}
b->al_buffer = al_create_buffer(file, file_size, al_format, al_sample_rate);
b->al_buffer = al_create_buffer(file, bytes_read, al_format, al_sample_rate);
ret = 0;
fail:
@ -635,30 +631,21 @@ static void Sound_dtor(Sound* s)
{
sounds_remove(s);
vfs_close(s->hf);
albuffer_free(s->hb);
alDeleteSources(1, &s->al_source);
check();
// move to sounddatasource
vfs_close(s->hf);
albuffer_free(s->hb);
}
static int Sound_reload(Sound* s, const char* fn, Handle)
static int Sound_reload(Sound* s, const char* fn, Handle hs)
{
// always add; if this fails, dtor is called, which removes from list
sounds_add(s);
// decide if it'll be streamed or loaded into memory
struct stat stat_buf;
CHECK_ERR(vfs_stat(fn, &stat_buf));
off_t file_size = stat_buf.st_size;
// big enough to warrant streaming
if(file_size > CLIP_MAX_SIZE)
s->flags = SF_STREAMING;
// TODO: let caller decide as well
s->hs = hs;
alGenSources(1, &s->al_source);
check();
@ -674,12 +661,30 @@ static int Sound_reload(Sound* s, const char* fn, Handle)
check();
// decide if it'll be streamed or loaded into memory
struct stat stat_buf;
CHECK_ERR(vfs_stat(fn, &stat_buf));
off_t file_size = stat_buf.st_size;
// big enough to warrant streaming
if(file_size > CLIP_MAX_SIZE)
s->flags = SF_STREAMING;
// TODO: let caller decide as well
if(s->flags & SF_STREAMING)
{
s->hf = vfs_open(fn);
CHECK_ERR(s->hf);
CHECK_ERR(detect_audio_fmt(s->hf, &s->al_format, &s->al_sample_rate));
// CHECK_ERR(detect_audio_fmt(s->hf, &s->al_format, &s->al_sample_rate));
for(int i = 0; i < MAX_IOS; i++)
CHECK_ERR(io_issue(s, s->hf));
@ -701,7 +706,7 @@ static int Sound_reload(Sound* s, const char* fn, Handle)
Handle sound_open(const char* const fn)
{
snd_init();
return h_alloc(H_Sound, fn);
return h_alloc(H_Sound, fn, RES_NO_CACHE);
}
@ -739,6 +744,19 @@ static int sound_update(Sound* s)
alGetSourcei(s->al_source, AL_BUFFERS_PROCESSED, &num_finished_buffers);
check();
if(!(s->flags & SF_STREAMING) && num_finished_buffers == 1)
{
ALuint al_buffer;
alSourceUnqueueBuffers(s->al_source, 1, &al_buffer);
check();
alSourceStop(s->al_source);
check();
sound_free(s->hs);
}
if(s->flags & SF_STREAMING)
for(int i = 0; i < num_finished_buffers; i++)
{
ALuint al_buffer;