From 042ec206e729f46c2d11e5c55a76b5f5cf68cea6 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sat, 5 Jan 2008 05:03:31 -0800 Subject: Disable fast float-to-int hack. Even with precautions, it's giving problems. Not worth it since I don't quite understand how it works, or know if there's even a benefit. --- Alc/ALu.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Alc/ALu.c b/Alc/ALu.c index 0b668b65..f4524d71 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -151,12 +151,14 @@ __inline ALuint aluChannelsFromFormat(ALenum format) static __inline ALint aluF2L(ALfloat Value) { +#if 0 if(sizeof(ALint) == 4 && sizeof(double) == 8) { double temp; temp = Value + (((65536.0*65536.0*16.0)+(65536.0*65536.0*8.0))*65536.0); return *((ALint*)&temp); } +#endif return (ALint)Value; } -- cgit v1.2.3 From 017fc933074947b9f8dd85d9582030fe4ce367ea Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sat, 5 Jan 2008 05:33:54 -0800 Subject: Some non-mmap ALSA fixes --- Alc/alsa.c | 61 +++++++++++++++++++++---------------------------------------- 1 file changed, 21 insertions(+), 40 deletions(-) diff --git a/Alc/alsa.c b/Alc/alsa.c index bef6ac99..91a4543d 100644 --- a/Alc/alsa.c +++ b/Alc/alsa.c @@ -222,30 +222,9 @@ static ALuint ALSANoMMapProc(ALvoid *ptr) alsa_data *data = (alsa_data*)pDevice->ExtraData; snd_pcm_sframes_t avail; char *WritePtr; - int err; while(!data->killNow) { - snd_pcm_state_t state = psnd_pcm_state(data->pcmHandle); - if(state == SND_PCM_STATE_XRUN) - { - err = xrun_recovery(data->pcmHandle, -EPIPE); - if (err < 0) - { - AL_PRINT("XRUN recovery failed: %s\n", psnd_strerror(err)); - break; - } - } - else if (state == SND_PCM_STATE_SUSPENDED) - { - err = xrun_recovery(data->pcmHandle, -ESTRPIPE); - if (err < 0) - { - AL_PRINT("SUSPEND recovery failed: %s\n", psnd_strerror(err)); - break; - } - } - SuspendContext(NULL); aluMixData(pDevice->Context, data->buffer, data->size, pDevice->Format); ProcessContext(NULL); @@ -425,7 +404,7 @@ open_alsa: if(!(ok(psnd_pcm_hw_params_any(data->pcmHandle, p), "any") && /* set interleaved access */ (ok(psnd_pcm_hw_params_set_access(data->pcmHandle, p, SND_PCM_ACCESS_MMAP_INTERLEAVED), "set access") || - ok(psnd_pcm_hw_params_set_access(data->pcmHandle, p, SND_PCM_ACCESS_RW_INTERLEAVED), "set access"))&& + ok(psnd_pcm_hw_params_set_access(data->pcmHandle, p, SND_PCM_ACCESS_RW_INTERLEAVED), "set access")) && /* set format (implicitly sets sample bits) */ ok(psnd_pcm_hw_params_set_format(data->pcmHandle, p, data->format), "set format") && /* set channels (implicitly sets frame bits) */ @@ -461,16 +440,6 @@ open_alsa: device->MaxNoOfSources = 256; device->UpdateFreq = bufferSizeInFrames; - i = psnd_pcm_prepare(data->pcmHandle); - if(i < 0) - { - AL_PRINT("prepare error: %s\n", psnd_strerror(i)); - psnd_pcm_close(data->pcmHandle); - free(data->buffer); - free(data); - return ALC_FALSE; - } - data->size = psnd_pcm_frames_to_bytes(data->pcmHandle, bufferSizeInFrames); if(access == SND_PCM_ACCESS_RW_INTERLEAVED) { @@ -484,16 +453,28 @@ open_alsa: } } else + { + i = psnd_pcm_prepare(data->pcmHandle); + if(i < 0) + { + AL_PRINT("prepare error: %s\n", psnd_strerror(i)); + psnd_pcm_close(data->pcmHandle); + free(data->buffer); + free(data); + return ALC_FALSE; + } + fill_silence(data->pcmHandle, data->format, device->Channels); - i = psnd_pcm_start(data->pcmHandle); - if(i < 0) - { - AL_PRINT("start error: %s\n", psnd_strerror(i)); - psnd_pcm_close(data->pcmHandle); - free(data->buffer); - free(data); - return ALC_FALSE; + i = psnd_pcm_start(data->pcmHandle); + if(i < 0) + { + AL_PRINT("start error: %s\n", psnd_strerror(i)); + psnd_pcm_close(data->pcmHandle); + free(data->buffer); + free(data); + return ALC_FALSE; + } } device->ExtraData = data; -- cgit v1.2.3 From dd60366aecf6721775eba007465f78c36e17dd5c Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 6 Jan 2008 00:18:06 -0800 Subject: Fix the buffer size so ALSA doesn't multiply by the number of periods --- Alc/alsa.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Alc/alsa.c b/Alc/alsa.c index 91a4543d..7b8d4dfa 100644 --- a/Alc/alsa.c +++ b/Alc/alsa.c @@ -396,7 +396,7 @@ open_alsa: periods = GetConfigValueInt("alsa", "periods", 4); if((int)periods <= 0) periods = 4; - bufferSizeInFrames = device->UpdateFreq; + bufferSizeInFrames = device->UpdateFreq / periods; psnd_pcm_hw_params_malloc(&p); #define ok(func, str) (i=(func),((i<0)?(err=(str)),0:1)) @@ -438,9 +438,9 @@ open_alsa: psnd_pcm_hw_params_free(p); device->MaxNoOfSources = 256; - device->UpdateFreq = bufferSizeInFrames; + device->UpdateFreq = bufferSizeInFrames * periods; - data->size = psnd_pcm_frames_to_bytes(data->pcmHandle, bufferSizeInFrames); + data->size = psnd_pcm_frames_to_bytes(data->pcmHandle, device->UpdateFreq); if(access == SND_PCM_ACCESS_RW_INTERLEAVED) { data->buffer = malloc(data->size); @@ -512,7 +512,7 @@ static ALCboolean alsa_open_capture(ALCdevice *pDevice, const ALCchar *deviceNam snd_pcm_format_t alsaFormat; snd_pcm_hw_params_t *p; unsigned int periods = 4; - snd_pcm_uframes_t bufferSizeInFrames = SampleSize; + snd_pcm_uframes_t bufferSizeInFrames; alsa_data *data; char driver[64]; char *err; @@ -575,6 +575,8 @@ open_alsa: AL_PRINT("Unknown format?! %x\n", format); } + bufferSizeInFrames = SampleSize / periods; + psnd_pcm_hw_params_malloc(&p); #define ok(func, str) (i=(func),((i<0)?(err=(str)),0:1)) /* start with the largest configuration space possible */ -- cgit v1.2.3 From da3b27048886add6fb3101cf34f8b8ab165d51f7 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 6 Jan 2008 00:19:28 -0800 Subject: Make OSS's update size dynamic --- Alc/oss.c | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/Alc/oss.c b/Alc/oss.c index a5c2fef4..6229fc09 100644 --- a/Alc/oss.c +++ b/Alc/oss.c @@ -78,31 +78,35 @@ static ALuint OSSProc(ALvoid *ptr) { ALCdevice *pDevice = (ALCdevice*)ptr; oss_data *data = (oss_data*)pDevice->ExtraData; - int remaining; + int remaining = 0; int wrote; while(!data->killNow) { - SuspendContext(NULL); - aluMixData(pDevice->Context,data->mix_data,data->data_size,pDevice->Format); - ProcessContext(NULL); + int len = data->data_size - remaining; - remaining = data->data_size; - while(remaining > 0) + if(len > 0) + { + SuspendContext(NULL); + aluMixData(pDevice->Context, data->mix_data+remaining, len, pDevice->Format); + ProcessContext(NULL); + } + + remaining += len; + wrote = write(data->fd, data->mix_data, remaining); + if(wrote < 0) + { + AL_PRINT("write failed: %s\n", strerror(errno)); + remaining = 0; + } + else if(wrote > 0) { - wrote = write(data->fd, data->mix_data+data->data_size-remaining, remaining); - if(wrote < 0) - { - AL_PRINT("write failed: %s\n", strerror(errno)); - break; - } - if(wrote == 0) - { - usleep(1000); - continue; - } remaining -= wrote; + if(remaining > 0) + memmove(data->mix_data, data->mix_data+wrote, remaining); } + else + usleep(1000); } return 0; -- cgit v1.2.3 From 8553fb9e30f79052e56986689256acd8f3517309 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 6 Jan 2008 01:14:09 -0800 Subject: ALC_REFRESH is the number of updates per second --- Alc/ALc.c | 2 +- Alc/alsa.c | 2 +- Alc/dsound.c | 4 ++-- Alc/oss.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Alc/ALc.c b/Alc/ALc.c index 1a66dc2a..ab05d7b3 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -707,7 +707,7 @@ ALCAPI ALCvoid ALCAPIENTRY alcGetIntegerv(ALCdevice *device,ALCenum param,ALsize data[i++] = device->Frequency; data[i++] = ALC_REFRESH; - data[i++] = device->UpdateFreq; + data[i++] = device->Frequency / device->UpdateFreq; data[i++] = ALC_SYNC; data[i++] = ALC_FALSE; diff --git a/Alc/alsa.c b/Alc/alsa.c index 7b8d4dfa..ea6ab2ea 100644 --- a/Alc/alsa.c +++ b/Alc/alsa.c @@ -438,7 +438,7 @@ open_alsa: psnd_pcm_hw_params_free(p); device->MaxNoOfSources = 256; - device->UpdateFreq = bufferSizeInFrames * periods; + device->UpdateFreq = bufferSizeInFrames; data->size = psnd_pcm_frames_to_bytes(data->pcmHandle, device->UpdateFreq); if(access == SND_PCM_ACCESS_RW_INTERLEAVED) diff --git a/Alc/dsound.c b/Alc/dsound.c index 90a422a2..ddedaf21 100644 --- a/Alc/dsound.c +++ b/Alc/dsound.c @@ -60,7 +60,7 @@ static void CALLBACK DirectSoundProc(UINT uID,UINT uReserved,DWORD_PTR dwUser,DW (void)dwReserved1; (void)dwReserved2; - BufSize = pDevice->UpdateFreq * pDevice->FrameSize; + BufSize = pDevice->UpdateFreq * 2 * pDevice->FrameSize; // Get current play and write cursors IDirectSoundBuffer_GetCurrentPosition(pData->DSsbuffer,&PlayCursor,&WriteCursor); @@ -169,7 +169,7 @@ static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceNam memset(&DSBDescription,0,sizeof(DSBUFFERDESC)); DSBDescription.dwSize=sizeof(DSBUFFERDESC); DSBDescription.dwFlags=DSBCAPS_GLOBALFOCUS|DSBCAPS_GETCURRENTPOSITION2; - DSBDescription.dwBufferBytes=device->UpdateFreq * device->FrameSize; + DSBDescription.dwBufferBytes=device->UpdateFreq * 2 * device->FrameSize; DSBDescription.lpwfxFormat=&OutputType; hr = IDirectSound_CreateSoundBuffer(pData->lpDS, &DSBDescription, &pData->DSsbuffer, NULL); } diff --git a/Alc/oss.c b/Alc/oss.c index 6229fc09..483f2247 100644 --- a/Alc/oss.c +++ b/Alc/oss.c @@ -406,7 +406,7 @@ static ALCboolean oss_open_capture(ALCdevice *device, const ALCchar *deviceName, device->UpdateFreq = info.fragsize / device->FrameSize; - data->data_size = device->UpdateFreq * device->FrameSize; + data->data_size = device->UpdateFreq * device->FrameSize * info.fragments; data->mix_data = calloc(1, data->data_size); device->ExtraData = data; -- cgit v1.2.3 From 298f6f440ae87373d92b2e392f0cc7780453d144 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 6 Jan 2008 01:15:44 -0800 Subject: Add missing header include --- OpenAL32/alBuffer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/OpenAL32/alBuffer.c b/OpenAL32/alBuffer.c index 2bcb6562..1ea54fce 100644 --- a/OpenAL32/alBuffer.c +++ b/OpenAL32/alBuffer.c @@ -22,6 +22,7 @@ #include #include +#include #include "alMain.h" #include "AL/al.h" #include "AL/alc.h" -- cgit v1.2.3 From 1178e900eb8e1f1dfb4757df19b55234d7d9e29e Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 6 Jan 2008 01:27:26 -0800 Subject: Don't allow 0 periods --- Alc/oss.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Alc/oss.c b/Alc/oss.c index 483f2247..26be11d7 100644 --- a/Alc/oss.c +++ b/Alc/oss.c @@ -194,7 +194,7 @@ static ALCboolean oss_open_playback(ALCdevice *device, const ALCchar *deviceName } periods = GetConfigValueInt("oss", "periods", 4); - if((int)periods < 0) + if((int)periods <= 0) periods = 4; numChannels = device->Channels; ossSpeed = device->Frequency; -- cgit v1.2.3 From 90d825e7f8f0c5bafcba07be4fc4493d973df0e4 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 6 Jan 2008 03:36:01 -0800 Subject: Fix lone ALC_REFRESH query case --- Alc/ALc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Alc/ALc.c b/Alc/ALc.c index ab05d7b3..1e4bca01 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -742,7 +742,7 @@ ALCAPI ALCvoid ALCAPIENTRY alcGetIntegerv(ALCdevice *device,ALCenum param,ALsize else if(!size) SetALCError(ALC_INVALID_VALUE); else - *data = device->UpdateFreq; + *data = device->Frequency / device->UpdateFreq; break; case ALC_SYNC: -- cgit v1.2.3 From f8acdc9497ee9fe9e437b0ab79f43e4b73bda4bb Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 6 Jan 2008 04:35:53 -0800 Subject: Release 1.1.93 --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dc73a4bf..a35c5dea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,8 +28,8 @@ OPTION(WERROR "Treat compile warnings as errors" OFF) SET(LIB_MAJOR_VERSION "1") -SET(LIB_MINOR_VERSION "0") -SET(LIB_BUILD_VERSION "38") +SET(LIB_MINOR_VERSION "1") +SET(LIB_BUILD_VERSION "93") SET(LIB_VERSION "${LIB_MAJOR_VERSION}.${LIB_MINOR_VERSION}.${LIB_BUILD_VERSION}") -- cgit v1.2.3 From 9c97f07ec9e5e72a8bfebffe05b7de5ce439d7f6 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 7 Jan 2008 00:26:10 -0800 Subject: Remove unneeded silence field --- Alc/oss.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Alc/oss.c b/Alc/oss.c index 26be11d7..77fe4192 100644 --- a/Alc/oss.c +++ b/Alc/oss.c @@ -55,7 +55,6 @@ typedef struct { ALubyte *mix_data; int data_size; - int silence; RingBuffer *ring; int doCapture; @@ -181,11 +180,9 @@ static ALCboolean oss_open_playback(ALCdevice *device, const ALCchar *deviceName switch(aluBytesFromFormat(device->Format)) { case 1: - data->silence = 0x80; ossFormat = AFMT_U8; break; case 2: - data->silence = 0; ossFormat = AFMT_S16_NE; break; default: @@ -311,11 +308,9 @@ static ALCboolean oss_open_capture(ALCdevice *device, const ALCchar *deviceName, switch(aluBytesFromFormat(format)) { case 1: - data->silence = 0x80; ossFormat = AFMT_U8; break; case 2: - data->silence = 0; ossFormat = AFMT_S16_NE; break; default: -- cgit v1.2.3 From 1e3ad2f9ce9dcb95c76ab1e16a317d50657bba09 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 8 Jan 2008 07:09:25 -0800 Subject: Use a more reliable thread loop for DSound, instead of a Win32 timer Also use a simpler method for calculating the read/write location --- Alc/dsound.c | 132 +++++++++++++++++++++++++++++------------------------------ 1 file changed, 64 insertions(+), 68 deletions(-) diff --git a/Alc/dsound.c b/Alc/dsound.c index ddedaf21..d2708f0a 100644 --- a/Alc/dsound.c +++ b/Alc/dsound.c @@ -36,71 +36,74 @@ typedef struct { LPDIRECTSOUND lpDS; LPDIRECTSOUNDBUFFER DSpbuffer; LPDIRECTSOUNDBUFFER DSsbuffer; - MMRESULT ulDSTimerID; - DWORD OldWriteCursor; + + int killNow; + ALvoid *thread; } DSoundData; static ALCchar *DeviceList[16]; -static void CALLBACK DirectSoundProc(UINT uID,UINT uReserved,DWORD_PTR dwUser,DWORD_PTR dwReserved1,DWORD_PTR dwReserved2) -{ - ALCdevice *pDevice = (ALCdevice *)dwUser; - DSoundData *pData = pDevice->ExtraData; - DWORD PlayCursor,WriteCursor; - BYTE *WritePtr1,*WritePtr2; - DWORD WriteCnt1,WriteCnt2; - WAVEFORMATEX OutputType; - DWORD BytesPlayed; - DWORD BufSize; - HRESULT DSRes; - (void)uID; - (void)uReserved; - (void)dwReserved1; - (void)dwReserved2; +static ALuint DSoundProc(ALvoid *ptr) +{ + ALCdevice *pDevice = (ALCdevice*)ptr; + DSoundData *pData = (DSoundData*)pDevice->ExtraData; + DWORD LastCursor = 0; + DWORD PlayCursor; + VOID *WritePtr; + DWORD WriteCnt; + DWORD avail; + HRESULT err; + + while(!pData->killNow) + { + // Get current play and write cursors + IDirectSoundBuffer_GetCurrentPosition(pData->DSsbuffer, &PlayCursor, NULL); + avail = (PlayCursor-LastCursor) % (pDevice->UpdateFreq*pDevice->FrameSize); - BufSize = pDevice->UpdateFreq * 2 * pDevice->FrameSize; + if(avail == 0) + { + Sleep(1); + continue; + } - // Get current play and write cursors - IDirectSoundBuffer_GetCurrentPosition(pData->DSsbuffer,&PlayCursor,&WriteCursor); - if (!pData->OldWriteCursor) pData->OldWriteCursor=WriteCursor-PlayCursor; + // Lock output buffer + WriteCnt = 0; + err = IDirectSoundBuffer_Lock(pData->DSsbuffer, LastCursor, avail, &WritePtr, &WriteCnt, NULL, NULL, 0); - // Get the output format and figure the number of bytes played (block aligned) - IDirectSoundBuffer_GetFormat(pData->DSsbuffer,&OutputType,sizeof(WAVEFORMATEX),NULL); - BytesPlayed=((((WriteCursorOldWriteCursor)?(BufSize+WriteCursor-pData->OldWriteCursor):(WriteCursor-pData->OldWriteCursor))/OutputType.nBlockAlign)*OutputType.nBlockAlign); + // If the buffer is lost, restore it, play and lock + if(err == DSERR_BUFFERLOST) + { + err = IDirectSoundBuffer_Restore(pData->DSsbuffer); + if(SUCCEEDED(err)) + err = IDirectSoundBuffer_Play(pData->DSsbuffer, 0, 0, DSBPLAY_LOOPING); + if(SUCCEEDED(err)) + err = IDirectSoundBuffer_Lock(pData->DSsbuffer, LastCursor, avail, (LPVOID*)&WritePtr, &WriteCnt, NULL, NULL, 0); + } - // Lock output buffer started at 40msec in front of the old write cursor (15msec in front of the actual write cursor) - DSRes=IDirectSoundBuffer_Lock(pData->DSsbuffer,(pData->OldWriteCursor+(OutputType.nSamplesPerSec/25)*OutputType.nBlockAlign)%BufSize,BytesPlayed,(LPVOID*)&WritePtr1,&WriteCnt1,(LPVOID*)&WritePtr2,&WriteCnt2,0); + // Successfully locked the output buffer + if(SUCCEEDED(err)) + { + // If we have an active context, mix data directly into output buffer otherwise fill with silence + SuspendContext(NULL); + aluMixData(pDevice->Context, WritePtr, WriteCnt, pDevice->Format); + ProcessContext(NULL); - // If the buffer is lost, restore it, play and lock - if (DSRes==DSERR_BUFFERLOST) - { - IDirectSoundBuffer_Restore(pData->DSsbuffer); - IDirectSoundBuffer_Play(pData->DSsbuffer,0,0,DSBPLAY_LOOPING); - DSRes=IDirectSoundBuffer_Lock(pData->DSsbuffer,(pData->OldWriteCursor+(OutputType.nSamplesPerSec/25)*OutputType.nBlockAlign)%BufSize,BytesPlayed,(LPVOID*)&WritePtr1,&WriteCnt1,(LPVOID*)&WritePtr2,&WriteCnt2,0); - } + // Unlock output buffer only when successfully locked + IDirectSoundBuffer_Unlock(pData->DSsbuffer, WritePtr, WriteCnt, NULL, 0); + } + else + AL_PRINT("Buffer lock error: %#lx\n", err); - // Successfully locked the output buffer - if (DSRes==DS_OK) - { - // If we have an active context, mix data directly into output buffer otherwise fill with silence - SuspendContext(NULL); - if (WritePtr1) - aluMixData(pDevice->Context, WritePtr1, WriteCnt1, pDevice->Format); - if (WritePtr2) - aluMixData(pDevice->Context, WritePtr2, WriteCnt2, pDevice->Format); - ProcessContext(NULL); - - // Unlock output buffer only when successfully locked - IDirectSoundBuffer_Unlock(pData->DSsbuffer,WritePtr1,WriteCnt1,WritePtr2,WriteCnt2); + // Update old write cursor location + LastCursor += WriteCnt; + LastCursor %= pDevice->UpdateFreq*pDevice->FrameSize; } - // Update old write cursor location - pData->OldWriteCursor=((pData->OldWriteCursor+BytesPlayed)%BufSize); + return 0; } - static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceName) { DSBUFFERDESC DSBDescription; @@ -169,7 +172,7 @@ static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceNam memset(&DSBDescription,0,sizeof(DSBUFFERDESC)); DSBDescription.dwSize=sizeof(DSBUFFERDESC); DSBDescription.dwFlags=DSBCAPS_GLOBALFOCUS|DSBCAPS_GETCURRENTPOSITION2; - DSBDescription.dwBufferBytes=device->UpdateFreq * 2 * device->FrameSize; + DSBDescription.dwBufferBytes=device->UpdateFreq * device->FrameSize; DSBDescription.lpwfxFormat=&OutputType; hr = IDirectSound_CreateSoundBuffer(pData->lpDS, &DSBDescription, &pData->DSsbuffer, NULL); } @@ -177,6 +180,13 @@ static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceNam if(SUCCEEDED(hr)) hr = IDirectSoundBuffer_Play(pData->DSsbuffer, 0, 0, DSBPLAY_LOOPING); + device->MaxNoOfSources = 256; + device->ExtraData = pData; + + pData->thread = StartThread(DSoundProc, device); + if(!pData->thread) + hr = E_FAIL; + if(FAILED(hr)) { if (pData->DSsbuffer) @@ -190,10 +200,6 @@ static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceNam return ALC_FALSE; } - pData->ulDSTimerID = timeSetEvent(25, 0, (LPTIMECALLBACK)DirectSoundProc, (DWORD)device, (UINT)TIME_CALLBACK_FUNCTION|TIME_PERIODIC); - device->MaxNoOfSources = 256; - - device->ExtraData = pData; return ALC_TRUE; } @@ -201,26 +207,16 @@ static void DSoundClosePlayback(ALCdevice *device) { DSoundData *pData = device->ExtraData; - // Stop and release the DS timer - if (pData->ulDSTimerID) - timeKillEvent(pData->ulDSTimerID); + pData->killNow = 1; + StopThread(pData->thread); - // Wait ... just in case any timer events happen - Sleep(100); - - SuspendContext(NULL); - - if (pData->DSsbuffer) - IDirectSoundBuffer_Release(pData->DSsbuffer); - if (pData->DSpbuffer) - IDirectSoundBuffer_Release(pData->DSpbuffer); + IDirectSoundBuffer_Release(pData->DSsbuffer); + IDirectSoundBuffer_Release(pData->DSpbuffer); IDirectSound_Release(pData->lpDS); //Deinit COM CoUninitialize(); - ProcessContext(NULL); - free(pData); device->ExtraData = NULL; } -- cgit v1.2.3 From bc56c00a9a99ccbf2523ecb5f25a0e14922aed56 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 10 Jan 2008 08:24:23 -0800 Subject: Allow querying of ALC_MONO_SOURCES and ALC_STEREO_SOURCES Based on a patch by Xavier Bouchoux --- Alc/ALc.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Alc/ALc.c b/Alc/ALc.c index 1e4bca01..d33390f7 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -754,6 +754,24 @@ ALCAPI ALCvoid ALCAPIENTRY alcGetIntegerv(ALCdevice *device,ALCenum param,ALsize *data = ALC_FALSE; break; + case ALC_MONO_SOURCES: + if(!device || !device->Context) + SetALCError(ALC_INVALID_DEVICE); + else if (size != 1) + SetALCError(ALC_INVALID_VALUE); + else + *data = device->Context->lNumMonoSources; + break; + + case ALC_STEREO_SOURCES: + if(!device || !device->Context) + SetALCError(ALC_INVALID_DEVICE); + else if (size != 1) + SetALCError(ALC_INVALID_VALUE); + else + *data = device->Context->lNumStereoSources; + break; + default: SetALCError(ALC_INVALID_ENUM); break; -- cgit v1.2.3 From a97ecb8690c64a6007ad3f0e983cb8ef67b47795 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 11 Jan 2008 06:01:51 -0800 Subject: Add a timing wrapper, using gettimeofday --- CMakeLists.txt | 5 +++++ OpenAL32/Include/alMain.h | 16 ++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index a35c5dea..86fc4fd1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -132,6 +132,11 @@ ENDIF() # Check if we have Windows headers CHECK_INCLUDE_FILE(windows.h HAVE_WINDOWS_H) IF(NOT "${HAVE_WINDOWS_H}") + CHECK_FUNCTION_EXISTS(gettimeofday HAVE_GETTIMEOFDAY) + IF(NOT "${HAVE_GETTIMEOFDAY}") + MESSAGE(FATAL_ERROR "No timing function found!") + ENDIF() + # We need pthreads outside of Windows CHECK_INCLUDE_FILE(pthread.h HAVE_PTHREAD_H) IF(NOT "${HAVE_PTHREAD_H}") diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index d8611a71..adf3f2c3 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -13,6 +13,7 @@ #include #include +#include #define IsBadWritePtr(a,b) (0) @@ -52,6 +53,21 @@ static inline void DeleteCriticalSection(CRITICAL_SECTION *cs) assert(ret == 0); } +/* NOTE: This wrapper isn't quite accurate as it returns an ALuint, as opposed + * to the expected DWORD. Both are defined as unsigned 32-bit types, however. + * Additionally, Win32 is supposed to measure the time since Windows started, + * as opposed to the actual time. */ +static inline ALuint timeGetTime(void) +{ + struct timeval tv; + int ret; + + ret = gettimeofday(&tv, NULL); + assert(ret == 0); + + return tv.tv_usec/1000 + tv.tv_sec*1000; +} + #define min(x,y) (((x)<(y))?(x):(y)) #define max(x,y) (((x)>(y))?(x):(y)) #endif -- cgit v1.2.3 From 2a5a5b5c1b97cfe66149bd77b4402e80f69c37c1 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 11 Jan 2008 06:54:09 -0800 Subject: Add Sleep wrapper --- CMakeLists.txt | 5 +++++ OpenAL32/Include/alMain.h | 1 + 2 files changed, 6 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 86fc4fd1..32f717a2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -137,6 +137,11 @@ IF(NOT "${HAVE_WINDOWS_H}") MESSAGE(FATAL_ERROR "No timing function found!") ENDIF() + CHECK_FUNCTION_EXISTS(usleep HAVE_USLEEP) + IF(NOT "${HAVE_USLEEP}") + MESSAGE(FATAL_ERROR "No sleep function found!") + ENDIF() + # We need pthreads outside of Windows CHECK_INCLUDE_FILE(pthread.h HAVE_PTHREAD_H) IF(NOT "${HAVE_PTHREAD_H}") diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index adf3f2c3..113101e4 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -68,6 +68,7 @@ static inline ALuint timeGetTime(void) return tv.tv_usec/1000 + tv.tv_sec*1000; } +#define Sleep(x) ((void)usleep((unsigned int)x*1000)) #define min(x,y) (((x)<(y))?(x):(y)) #define max(x,y) (((x)>(y))?(x):(y)) #endif -- cgit v1.2.3 From e1d0ad749bd5772d968aa8b5ed600dee905310a4 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 11 Jan 2008 08:15:44 -0800 Subject: Use nanosleep instead of usleep So not to rely on the non-standard unistd.h header --- CMakeLists.txt | 4 ++-- OpenAL32/Include/alMain.h | 12 +++++++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 32f717a2..4955d250 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -137,8 +137,8 @@ IF(NOT "${HAVE_WINDOWS_H}") MESSAGE(FATAL_ERROR "No timing function found!") ENDIF() - CHECK_FUNCTION_EXISTS(usleep HAVE_USLEEP) - IF(NOT "${HAVE_USLEEP}") + CHECK_FUNCTION_EXISTS(nanosleep HAVE_NANOSLEEP) + IF(NOT "${HAVE_NANOSLEEP}") MESSAGE(FATAL_ERROR "No sleep function found!") ENDIF() diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 113101e4..c238a3a9 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -14,6 +14,8 @@ #include #include #include +#include +#include #define IsBadWritePtr(a,b) (0) @@ -68,7 +70,15 @@ static inline ALuint timeGetTime(void) return tv.tv_usec/1000 + tv.tv_sec*1000; } -#define Sleep(x) ((void)usleep((unsigned int)x*1000)) +static inline void Sleep(ALuint t) +{ + struct timespec tv, rem; + tv.tv_nsec = (t*1000000)%1000000000; + tv.tv_sec = t/1000; + + while(nanosleep(&tv, &rem) == -1 && errno == EINTR) + tv = rem; +} #define min(x,y) (((x)<(y))?(x):(y)) #define max(x,y) (((x)>(y))?(x):(y)) #endif -- cgit v1.2.3 From f10408739e22cea6b3c52b8a9f6e36792c33d855 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 11 Jan 2008 09:32:22 -0800 Subject: Add a wave file writing backend --- Alc/ALc.c | 2 + Alc/wave.c | 335 ++++++++++++++++++++++++++++++++++++++++++++++ CMakeLists.txt | 4 + OpenAL32/Include/alMain.h | 1 + openalrc.sample | 8 +- 5 files changed, 349 insertions(+), 1 deletion(-) create mode 100644 Alc/wave.c diff --git a/Alc/ALc.c b/Alc/ALc.c index d33390f7..0ec42533 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -61,6 +61,8 @@ struct { { "winmm", alcWinMMInit, EmptyFuncs }, #endif + { "wave", alc_wave_init, EmptyFuncs }, + { NULL, NULL, EmptyFuncs } }; #undef EmptyFuncs diff --git a/Alc/wave.c b/Alc/wave.c new file mode 100644 index 00000000..3de7ea80 --- /dev/null +++ b/Alc/wave.c @@ -0,0 +1,335 @@ +/** + * OpenAL cross platform audio library + * Copyright (C) 1999-2007 by authors. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + +#include "config.h" + +#include +#include +#include +#include "alMain.h" +#include "AL/al.h" +#include "AL/alc.h" + + +typedef struct { + FILE *f; + long DataStart; + + ALvoid *buffer; + ALuint size; + + int killNow; + ALvoid *thread; +} wave_data; + + +static ALCchar *waveDevice; + + +static ALuint WaveProc(ALvoid *ptr) +{ + ALCdevice *pDevice = (ALCdevice*)ptr; + wave_data *data = (wave_data*)pDevice->ExtraData; + ALuint frameSize; + ALuint now, last; + size_t WriteCnt; + ALuint avail; + union { + short s; + char b[sizeof(short)]; + } uSB; + + uSB.s = 1; + frameSize = aluBytesFromFormat(pDevice->Format) * + aluChannelsFromFormat(pDevice->Format); + + last = timeGetTime(); + while(!data->killNow) + { + now = timeGetTime(); + + avail = (now-last) * pDevice->Frequency / 1000; + if(avail < pDevice->UpdateFreq/4) + { + Sleep(1); + continue; + } + + while(avail > 0) + { + SuspendContext(NULL); + WriteCnt = min(data->size, avail); + aluMixData(pDevice->Context, data->buffer, WriteCnt * frameSize, + pDevice->Format); + ProcessContext(NULL); + + if(uSB.b[0] != 1 && aluBytesFromFormat(pDevice->Format) > 1) + { + ALubyte *bytes = data->buffer; + ALuint i; + + for(i = 0;i < WriteCnt*frameSize;i++) + fputc(bytes[i^1], data->f); + } + else + fwrite(data->buffer, frameSize, WriteCnt, data->f); + if(ferror(data->f)) + { + AL_PRINT("Error writing to file\n"); + data->killNow = 1; + break; + } + + avail -= WriteCnt; + } + last = now; + } + + return 0; +} + +static ALCboolean wave_open_playback(ALCdevice *device, const ALCchar *deviceName) +{ + wave_data *data; + ALuint channels; + ALuint bits; + char fname[64]; + int i; + + strncpy(fname, GetConfigValue("wave", "file", ""), sizeof(fname)-1); + fname[sizeof(fname)-1] = 0; + if(!fname[0]) + return ALC_FALSE; + + if(deviceName) + { + if(strcmp(deviceName, waveDevice) != 0) + return ALC_FALSE; + device->szDeviceName = waveDevice; + } + else + device->szDeviceName = waveDevice; + + data = (wave_data*)calloc(1, sizeof(wave_data)); + + data->f = fopen(fname, "wb"); + if(!data->f) + { + free(data); + AL_PRINT("Could not open file '%s': %s\n", fname, strerror(errno)); + return ALC_FALSE; + } + + bits = aluBytesFromFormat(device->Format) * 8; + channels = aluChannelsFromFormat(device->Format); + switch(bits) + { + case 8: + case 16: + 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; + } + + fprintf(data->f, "RIFF"); + fputc(0, data->f); // 'RIFF' header len; filled in at close + fputc(0, data->f); + fputc(0, data->f); + fputc(0, data->f); + + fprintf(data->f, "WAVE"); + + fprintf(data->f, "fmt "); + fputc(16, data->f); // 'fmt ' header len; 16 bytes for PCM + fputc(0, data->f); + fputc(0, data->f); + fputc(0, data->f); + // 16-bit val, format type id (PCM: 1) + fputc(1, data->f); + fputc(0, data->f); + // 16-bit val, channel count + fputc(channels&0xff, data->f); + fputc((channels>>8)&0xff, data->f); + // 32-bit val, frequency + fputc(device->Frequency&0xff, data->f); + fputc((device->Frequency>>8)&0xff, data->f); + fputc((device->Frequency>>16)&0xff, data->f); + fputc((device->Frequency>>24)&0xff, data->f); + // 32-bit val, bytes per second + i = device->Frequency * channels * bits / 8; + fputc(i&0xff, data->f); + fputc((i>>8)&0xff, data->f); + fputc((i>>16)&0xff, data->f); + fputc((i>>24)&0xff, data->f); + // 16-bit val, frame size + i = channels * bits / 8; + fputc(i&0xff, data->f); + fputc((i>>8)&0xff, data->f); + // 16-bit val, bits per sample + fputc(bits&0xff, data->f); + fputc((bits>>8)&0xff, data->f); + + fprintf(data->f, "data"); + fputc(0, data->f); // 'data' header len; filled in at close + fputc(0, data->f); + fputc(0, data->f); + fputc(0, data->f); + + data->DataStart = ftell(data->f); + if(data->DataStart == -1 || ferror(data->f)) + { + AL_PRINT("Error writing header: %s\n", strerror(errno)); + fclose(data->f); + free(data); + return ALC_FALSE; + } + + device->MaxNoOfSources = 256; + device->UpdateFreq = max(device->UpdateFreq, 2048); + + data->size = device->UpdateFreq; + 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); + return ALC_FALSE; + } + + 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->buffer); + free(data); + device->ExtraData = NULL; +} + + +static ALCboolean wave_open_capture(ALCdevice *pDevice, const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei SampleSize) +{ + (void)pDevice; + (void)deviceName; + (void)frequency; + (void)format; + (void)SampleSize; + return ALC_FALSE; +} + +static void wave_close_capture(ALCdevice *pDevice) +{ + (void)pDevice; +} + +static void wave_start_capture(ALCdevice *pDevice) +{ + (void)pDevice; +} + +static void wave_stop_capture(ALCdevice *pDevice) +{ + (void)pDevice; +} + +static void wave_capture_samples(ALCdevice *pDevice, ALCvoid *pBuffer, ALCuint lSamples) +{ + (void)pDevice; + (void)pBuffer; + (void)lSamples; +} + +static ALCuint wave_available_samples(ALCdevice *pDevice) +{ + (void)pDevice; + return 0; +} + + +BackendFuncs wave_funcs = { + wave_open_playback, + wave_close_playback, + wave_open_capture, + wave_close_capture, + wave_start_capture, + wave_stop_capture, + wave_capture_samples, + wave_available_samples +}; + +void alc_wave_init(BackendFuncs *func_list) +{ + *func_list = wave_funcs; + + waveDevice = AppendDeviceList("Wave File Writer"); + AppendAllDeviceList(waveDevice); +} diff --git a/CMakeLists.txt b/CMakeLists.txt index 4955d250..ee2cc94e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -190,6 +190,7 @@ SET(ALC_OBJS Alc/ALc.c Alc/alcRing.c Alc/alcThread.c Alc/bs2b.c + Alc/wave.c ) SET(BACKENDS "") @@ -263,6 +264,9 @@ IF("${HAVE_WINDOWS_H}") ENDIF() ENDIF() +# This is always available +SET(BACKENDS ${BACKENDS} WaveFile) + # End configuration CONFIGURE_FILE( "${OpenAL_SOURCE_DIR}/config.h.in" diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index c238a3a9..840c6993 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -149,6 +149,7 @@ void alc_alsa_init(BackendFuncs *func_list); void alc_oss_init(BackendFuncs *func_list); void alcDSoundInit(BackendFuncs *func_list); void alcWinMMInit(BackendFuncs *FuncList); +void alc_wave_init(BackendFuncs *func_list); struct ALCdevice_struct diff --git a/openalrc.sample b/openalrc.sample index 0e378a84..37325d14 100644 --- a/openalrc.sample +++ b/openalrc.sample @@ -44,7 +44,7 @@ drivers = # Sets the backend driver list order, comma-seperated. Unknown # backends and duplicated names are ignored, and unlisted backends # won't be considered for use. An empty list means the default. # Default is: - # alsa,oss,dsound,winmm + # alsa,oss,dsound,winmm,wave [alsa] # ALSA backend stuff device = default # Sets the device name for the default playback device. @@ -67,3 +67,9 @@ capture = /dev/dsp # Sets the device name for OSS capture. Default is /dev/dsp [winmm] # Windows Multimedia backend stuff # Nothing yet... + +[wave] # Wave File Writer stuff +file = # Sets the filename of the wave file to write to. An empty name + # prevents the backend from opening, even when explicitly requested. + # THIS WILL OVERWRITE EXISTING FILES WITHOUT QUESTION! + # Default is empty -- cgit v1.2.3 From 40241b4e970c451f37f805c0611e7b9d62b6ba30 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 11 Jan 2008 13:00:30 -0800 Subject: Don't attempt to open ALSA playback/capture if it didn't load --- Alc/alsa.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Alc/alsa.c b/Alc/alsa.c index ea6ab2ea..f8cb17f7 100644 --- a/Alc/alsa.c +++ b/Alc/alsa.c @@ -325,6 +325,9 @@ static ALCboolean alsa_open_playback(ALCdevice *device, const ALCchar *deviceNam char *err; int i; + if(!alsa_handle) + return ALC_FALSE; + strncpy(driver, GetConfigValue("alsa", "device", "default"), sizeof(driver)-1); driver[sizeof(driver)-1] = 0; if(deviceName) @@ -518,6 +521,9 @@ static ALCboolean alsa_open_capture(ALCdevice *pDevice, const ALCchar *deviceNam char *err; int i; + if(!alsa_handle) + return ALC_FALSE; + strncpy(driver, GetConfigValue("alsa", "capture", "default"), sizeof(driver)-1); driver[sizeof(driver)-1] = 0; if(deviceName) @@ -758,7 +764,7 @@ void alc_alsa_init(BackendFuncs *func_list) } while(0) #else str = NULL; - alsa_handle = NULL; + alsa_handle = 0xDEADBEEF; #define LOAD_FUNC(f) p##f = f #endif -- cgit v1.2.3 From f8089d20262681542dd214da130f4462d6a9eb8b Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 11 Jan 2008 13:23:37 -0800 Subject: Don't double-close a handle on error --- Alc/alsa.c | 1 - 1 file changed, 1 deletion(-) diff --git a/Alc/alsa.c b/Alc/alsa.c index f8cb17f7..926ca354 100644 --- a/Alc/alsa.c +++ b/Alc/alsa.c @@ -899,7 +899,6 @@ next_card: } if (err >= 0 && (err = psnd_ctl_card_info(handle, info)) < 0) { AL_PRINT("control hardware info (%i): %s\n", card, psnd_strerror(err)); - psnd_ctl_close(handle); } else if (err >= 0 && card < MAX_DEVICES-1) { -- cgit v1.2.3 From aa453b4e9e325df3debd65f0d965e8b2b5eb53e3 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 11 Jan 2008 14:55:35 -0800 Subject: Use Sleep instead of usleep --- Alc/alsa.c | 8 ++++---- Alc/oss.c | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Alc/alsa.c b/Alc/alsa.c index 926ca354..e76b8504 100644 --- a/Alc/alsa.c +++ b/Alc/alsa.c @@ -116,7 +116,7 @@ static int xrun_recovery(snd_pcm_t *handle, int err) else if (err == -ESTRPIPE) { while ((err = psnd_pcm_resume(handle)) == -EAGAIN) - usleep(1); /* wait until the suspend flag is released */ + Sleep(1); /* wait until the suspend flag is released */ if (err < 0) { err = psnd_pcm_prepare(handle); @@ -177,7 +177,7 @@ static ALuint ALSAProc(ALvoid *ptr) // make sure there's frames to process if(avail == 0) { - usleep(1000); + Sleep(1); continue; } @@ -367,7 +367,7 @@ open_alsa: i = psnd_pcm_open(&data->pcmHandle, driver, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); if(i < 0) { - usleep(200000); + Sleep(200); i = psnd_pcm_open(&data->pcmHandle, driver, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); } if(i >= 0) @@ -552,7 +552,7 @@ open_alsa: i = psnd_pcm_open(&data->pcmHandle, driver, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK); if(i < 0) { - usleep(200000); + Sleep(200); i = psnd_pcm_open(&data->pcmHandle, driver, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK); } if(i >= 0) diff --git a/Alc/oss.c b/Alc/oss.c index 77fe4192..299146b2 100644 --- a/Alc/oss.c +++ b/Alc/oss.c @@ -105,7 +105,7 @@ static ALuint OSSProc(ALvoid *ptr) memmove(data->mix_data, data->mix_data+wrote, remaining); } else - usleep(1000); + Sleep(1); } return 0; @@ -131,7 +131,7 @@ static ALuint OSSCaptureProc(ALvoid *ptr) } if(amt == 0) { - usleep(1000); + Sleep(1); continue; } if(data->doCapture) -- cgit v1.2.3 From 893ecf1af2ba7a31d83c85e4bb081dae1911fa3b Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 11 Jan 2008 15:18:26 -0800 Subject: Fix the Wave Writer's reliance on ftell So output can work on FIFOs --- Alc/wave.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Alc/wave.c b/Alc/wave.c index 3de7ea80..e08b0bc1 100644 --- a/Alc/wave.c +++ b/Alc/wave.c @@ -203,8 +203,7 @@ static ALCboolean wave_open_playback(ALCdevice *device, const ALCchar *deviceNam fputc(0, data->f); fputc(0, data->f); - data->DataStart = ftell(data->f); - if(data->DataStart == -1 || ferror(data->f)) + if(ferror(data->f)) { AL_PRINT("Error writing header: %s\n", strerror(errno)); fclose(data->f); @@ -212,6 +211,8 @@ static ALCboolean wave_open_playback(ALCdevice *device, const ALCchar *deviceNam return ALC_FALSE; } + data->DataStart = ftell(data->f); + device->MaxNoOfSources = 256; device->UpdateFreq = max(device->UpdateFreq, 2048); -- cgit v1.2.3 From 978764cb6b84d78187badf9d8d5b7177d047654f Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 11 Jan 2008 15:27:56 -0800 Subject: Don't limit output wave filename size --- Alc/wave.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Alc/wave.c b/Alc/wave.c index e08b0bc1..de4c87db 100644 --- a/Alc/wave.c +++ b/Alc/wave.c @@ -110,11 +110,10 @@ static ALCboolean wave_open_playback(ALCdevice *device, const ALCchar *deviceNam wave_data *data; ALuint channels; ALuint bits; - char fname[64]; + const char *fname; int i; - strncpy(fname, GetConfigValue("wave", "file", ""), sizeof(fname)-1); - fname[sizeof(fname)-1] = 0; + fname = GetConfigValue("wave", "file", ""); if(!fname[0]) return ALC_FALSE; -- cgit v1.2.3