1
0
forked from 0ad/0ad

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;
}
///////////////////////////////////////////////////////////////////////////////
//
@ -360,51 +323,84 @@ static int ALBuffer_reload(ALBuffer* b, const char* fn, Handle)
{
hf = vfs_open(fn);
CHECK_ERR(hf);
hf = vfs_open(fn);
CHECK_ERR(hf);
// detect sound file format and seek to audio data
ALenum al_format;
ALsizei al_sample_rate;
int err = detect_audio_fmt(hf, &al_format, &al_sample_rate);
//
// detect sound format (by checking file extension)
//
ALenum al_format;
ALsizei 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.
ssize_t file_size = vfs_size(hf);
if(file_size < 0)
{
ret = file_size;
goto fail;
}
void* file = malloc(file_size); // freed soon after
if(!file)
{
ret = ERR_NO_MEM;
goto fail;
}
// read from file. note: don't use vfs_load - detect_audio_fmt
// has seeked to the actual audio data in the file.
void* dst = file; // for vfs_io
ssize_t bytes_read = vfs_io(hf, file_size, &dst);
if(bytes_read < 0)
{
ret = bytes_read;
goto fail;
}
//
// allocate buffer for audio data
//
b->al_buffer = al_create_buffer(file, file_size, al_format, al_sample_rate);
// 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)
{
ret = file_size;
goto fail;
}
void* file = malloc(file_size); // freed soon after
if(!file)
{
ret = ERR_NO_MEM;
goto fail;
}
ret = 0;
// read from file. note: don't use vfs_load - detect_audio_fmt
// has seeked to the actual audio data in the file.
void* dst = file; // for vfs_io
ssize_t bytes_read = vfs_io(hf, file_size, &dst);
if(bytes_read < 0)
{
ret = bytes_read;
goto fail;
}
b->al_buffer = al_create_buffer(file, bytes_read, al_format, al_sample_rate);
ret = 0;
fail:
free(file);
vfs_close(hf);
free(file);
vfs_close(hf);
}
@ -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,16 +744,29 @@ static int sound_update(Sound* s)
alGetSourcei(s->al_source, AL_BUFFERS_PROCESSED, &num_finished_buffers);
check();
for(int i = 0; i < num_finished_buffers; i++)
if(!(s->flags & SF_STREAMING) && num_finished_buffers == 1)
{
ALuint al_buffer;
alSourceUnqueueBuffers(s->al_source, 1, &al_buffer);
alDeleteBuffers(1, &al_buffer);
check();
CHECK_ERR(io_issue(s, s->hf));
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;
alSourceUnqueueBuffers(s->al_source, 1, &al_buffer);
alDeleteBuffers(1, &al_buffer);
check();
CHECK_ERR(io_issue(s, s->hf));
}
return 0;
}