diff options
author | Chris Robinson <[email protected]> | 2009-08-13 12:28:46 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2009-08-13 12:28:46 -0700 |
commit | 243939f94f26b1840255590b2454e931374de73f (patch) | |
tree | 2739c389486d703c5d31ab262aecb1be02d11b5c /Alc/wave.c | |
parent | 739385bd89c4eaae662ee1e017f74ba0da31f350 (diff) |
Allow delaying playback start until context creation, and don't use UpdateSize to store the buffer size
This will make it possible to support the context attributes (frequency,
refresh, etc) for some backends
Diffstat (limited to 'Alc/wave.c')
-rw-r--r-- | Alc/wave.c | 85 |
1 files changed, 62 insertions, 23 deletions
@@ -67,7 +67,7 @@ static ALuint WaveProc(ALvoid *ptr) now = timeGetTime(); avail = (now-last) * pDevice->Frequency / 1000; - if(avail < pDevice->UpdateSize/4) + if(avail < pDevice->UpdateSize) { Sleep(1); continue; @@ -109,10 +109,7 @@ static ALuint WaveProc(ALvoid *ptr) static ALCboolean wave_open_playback(ALCdevice *device, const ALCchar *deviceName) { wave_data *data; - ALuint channels; - ALuint bits; const char *fname; - int i; fname = GetConfigValue("wave", "file", ""); if(!fname[0]) @@ -137,6 +134,54 @@ static ALCboolean wave_open_playback(ALCdevice *device, const ALCchar *deviceNam return ALC_FALSE; } + device->ExtraData = data; + return ALC_TRUE; +} + +static void wave_close_playback(ALCdevice *device) +{ + wave_data *data = (wave_data*)device->ExtraData; + ALuint dataLen; + long size; + + data->killNow = 1; + StopThread(data->thread); + + size = ftell(data->f); + if(size > 0) + { + dataLen = size - data->DataStart; + if(fseek(data->f, data->DataStart-4, SEEK_SET) == 0) + { + fputc(dataLen&0xff, data->f); // 'data' header len + fputc((dataLen>>8)&0xff, data->f); + fputc((dataLen>>16)&0xff, data->f); + fputc((dataLen>>24)&0xff, data->f); + } + if(fseek(data->f, 4, SEEK_SET) == 0) + { + size -= 8; + fputc(size&0xff, data->f); // 'WAVE' header len + fputc((size>>8)&0xff, data->f); + fputc((size>>16)&0xff, data->f); + fputc((size>>24)&0xff, data->f); + } + } + + fclose(data->f); + free(data); + device->ExtraData = NULL; +} + +static ALCboolean wave_start_context(ALCdevice *device, ALCcontext *Context) +{ + wave_data *data = (wave_data*)device->ExtraData; + ALuint channels, bits, i; + (void)Context; + + fseek(data->f, 0, SEEK_SET); + clearerr(data->f); + bits = aluBytesFromFormat(device->Format) * 8; channels = aluChannelsFromFormat(device->Format); switch(bits) @@ -146,16 +191,12 @@ static ALCboolean wave_open_playback(ALCdevice *device, const ALCchar *deviceNam if(channels == 0) { AL_PRINT("Unknown format?! %x\n", device->Format); - fclose(data->f); - free(data); return ALC_FALSE; } break; default: AL_PRINT("Unknown format?! %x\n", device->Format); - fclose(data->f); - free(data); return ALC_FALSE; } @@ -206,47 +247,48 @@ static ALCboolean wave_open_playback(ALCdevice *device, const ALCchar *deviceNam if(ferror(data->f)) { AL_PRINT("Error writing header: %s\n", strerror(errno)); - fclose(data->f); - free(data); return ALC_FALSE; } data->DataStart = ftell(data->f); - device->UpdateSize = max(device->UpdateSize, 2048); + device->UpdateSize = max(device->BufferSize/4, 2048); data->size = device->UpdateSize; data->buffer = malloc(data->size * channels * bits / 8); if(!data->buffer) { AL_PRINT("buffer malloc failed\n"); - fclose(data->f); - free(data); return ALC_FALSE; } - device->ExtraData = data; data->thread = StartThread(WaveProc, device); if(data->thread == NULL) { - device->ExtraData = NULL; - fclose(data->f); free(data->buffer); - free(data); + data->buffer = NULL; return ALC_FALSE; } return ALC_TRUE; } -static void wave_close_playback(ALCdevice *device) +static void wave_stop_context(ALCdevice *device, ALCcontext *Context) { wave_data *data = (wave_data*)device->ExtraData; ALuint dataLen; long size; + (void)Context; + + if(!data->thread) + return; data->killNow = 1; StopThread(data->thread); + data->thread = NULL; + + free(data->buffer); + data->buffer = NULL; size = ftell(data->f); if(size > 0) @@ -268,11 +310,6 @@ static void wave_close_playback(ALCdevice *device) fputc((size>>24)&0xff, data->f); } } - - fclose(data->f); - free(data->buffer); - free(data); - device->ExtraData = NULL; } @@ -318,6 +355,8 @@ static ALCuint wave_available_samples(ALCdevice *pDevice) BackendFuncs wave_funcs = { wave_open_playback, wave_close_playback, + wave_start_context, + wave_stop_context, wave_open_capture, wave_close_capture, wave_start_capture, |