aboutsummaryrefslogtreecommitdiffstats
path: root/Alc/wave.c
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2009-08-13 12:28:46 -0700
committerChris Robinson <[email protected]>2009-08-13 12:28:46 -0700
commit243939f94f26b1840255590b2454e931374de73f (patch)
tree2739c389486d703c5d31ab262aecb1be02d11b5c /Alc/wave.c
parent739385bd89c4eaae662ee1e017f74ba0da31f350 (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.c85
1 files changed, 62 insertions, 23 deletions
diff --git a/Alc/wave.c b/Alc/wave.c
index cba9fb13..a21bbc15 100644
--- a/Alc/wave.c
+++ b/Alc/wave.c
@@ -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,