diff options
-rw-r--r-- | Alc/ALc.c | 16 | ||||
-rw-r--r-- | Alc/alsa.c | 42 | ||||
-rw-r--r-- | Alc/dsound.c | 13 | ||||
-rw-r--r-- | Alc/oss.c | 13 | ||||
-rw-r--r-- | Alc/portaudio.c | 6 | ||||
-rw-r--r-- | Alc/pulseaudio.c | 8 | ||||
-rw-r--r-- | Alc/solaris.c | 4 | ||||
-rw-r--r-- | Alc/wave.c | 2 | ||||
-rw-r--r-- | Alc/winmm.c | 3 | ||||
-rw-r--r-- | OpenAL32/Include/alMain.h | 2 | ||||
-rw-r--r-- | alsoftrc.sample | 34 |
11 files changed, 72 insertions, 71 deletions
@@ -614,7 +614,8 @@ ALCAPI ALCdevice* ALCAPIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, AL pDevice->Frequency = frequency; pDevice->Format = format; - pDevice->BufferSize = SampleSize; + pDevice->UpdateSize = SampleSize; + pDevice->NumUpdates = 1; SuspendContext(NULL); for(i = 0;BackendList[i].Init;i++) @@ -1481,9 +1482,16 @@ ALCAPI ALCdevice* ALCAPIENTRY alcOpenDevice(const ALCchar *deviceName) fmt = GetConfigValue(NULL, "format", "AL_FORMAT_STEREO16"); device->Format = GetFormatFromString(fmt); - device->BufferSize = GetConfigValueInt(NULL, "refresh", 4096); - if((ALint)device->BufferSize <= 0) - device->BufferSize = 4096; + device->NumUpdates = GetConfigValueInt(NULL, "periods", 4); + if(device->NumUpdates < 2) + device->NumUpdates = 4; + + i = GetConfigValueInt(NULL, "refresh", 4096); + if(i <= 0) i = 4096; + + device->UpdateSize = GetConfigValueInt(NULL, "period_size", i/device->NumUpdates); + if(device->UpdateSize <= 0) + device->UpdateSize = i/device->NumUpdates; device->MaxNoOfSources = GetConfigValueInt(NULL, "sources", 256); if((ALint)device->MaxNoOfSources <= 0) @@ -69,10 +69,12 @@ MAKE_FUNC(snd_pcm_hw_params_set_periods_near); MAKE_FUNC(snd_pcm_hw_params_set_rate_near); MAKE_FUNC(snd_pcm_hw_params_set_rate); MAKE_FUNC(snd_pcm_hw_params_set_buffer_size_near); +MAKE_FUNC(snd_pcm_hw_params_set_period_size_near); MAKE_FUNC(snd_pcm_hw_params_set_buffer_size_min); MAKE_FUNC(snd_pcm_hw_params_get_buffer_size); MAKE_FUNC(snd_pcm_hw_params_get_period_size); MAKE_FUNC(snd_pcm_hw_params_get_access); +MAKE_FUNC(snd_pcm_hw_params_get_periods); MAKE_FUNC(snd_pcm_hw_params); MAKE_FUNC(snd_pcm_sw_params_malloc); MAKE_FUNC(snd_pcm_sw_params_current); @@ -411,7 +413,7 @@ static void alsa_close_playback(ALCdevice *device) static ALCboolean alsa_reset_playback(ALCdevice *device) { alsa_data *data = (alsa_data*)device->ExtraData; - snd_pcm_uframes_t bufferSizeInFrames; + snd_pcm_uframes_t periodSizeInFrames; snd_pcm_sw_params_t *sp = NULL; snd_pcm_hw_params_t *p = NULL; snd_pcm_access_t access; @@ -439,8 +441,8 @@ static ALCboolean alsa_reset_playback(ALCdevice *device) } allowmmap = GetConfigValueBool("alsa", "mmap", 1); - periods = GetConfigValueInt("alsa", "periods", 0); - bufferSizeInFrames = device->BufferSize; + periods = GetConfigValueInt("alsa", "periods", device->NumUpdates); + periodSizeInFrames = device->UpdateSize; rate = device->Frequency; err = NULL; @@ -451,6 +453,7 @@ static ALCboolean alsa_reset_playback(ALCdevice *device) /* set interleaved access */ if(err == NULL && (!allowmmap || (i=psnd_pcm_hw_params_set_access(data->pcmHandle, p, SND_PCM_ACCESS_MMAP_INTERLEAVED)) < 0)) { + if(periods > 2) periods--; if((i=psnd_pcm_hw_params_set_access(data->pcmHandle, p, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) err = "set access"; } @@ -466,16 +469,18 @@ static ALCboolean alsa_reset_playback(ALCdevice *device) /* set rate (implicitly constrains period/buffer parameters) */ if(err == NULL && (i=psnd_pcm_hw_params_set_rate_near(data->pcmHandle, p, &rate, NULL)) < 0) err = "set rate near"; - /* set buffer size in frame units (implicitly sets period size/bytes/time and buffer time/bytes) */ - if(err == NULL && (i=psnd_pcm_hw_params_set_buffer_size_near(data->pcmHandle, p, &bufferSizeInFrames)) < 0) - err = "set buffer size near"; + /* set period size in frame units (implicitly sets buffer size/bytes/time and period time/bytes) */ + if(err == NULL && (i=psnd_pcm_hw_params_set_period_size_near(data->pcmHandle, p, &periodSizeInFrames, NULL)) < 0) + err = "set period size near"; /* install and prepare hardware configuration */ if(err == NULL && (i=psnd_pcm_hw_params(data->pcmHandle, p)) < 0) err = "set params"; if(err == NULL && (i=psnd_pcm_hw_params_get_access(p, &access)) < 0) err = "get access"; - if(err == NULL && (i=psnd_pcm_hw_params_get_period_size(p, &bufferSizeInFrames, NULL)) < 0) + if(err == NULL && (i=psnd_pcm_hw_params_get_period_size(p, &periodSizeInFrames, NULL)) < 0) err = "get period size"; + if(err == NULL && (i=psnd_pcm_hw_params_get_periods(p, &periods, NULL)) < 0) + err = "get periods"; if(err != NULL) { AL_PRINT("%s failed: %s\n", err, psnd_strerror(i)); @@ -490,7 +495,7 @@ static ALCboolean alsa_reset_playback(ALCdevice *device) if((i=psnd_pcm_sw_params_current(data->pcmHandle, sp)) != 0) err = "sw current"; - if(err == NULL && (i=psnd_pcm_sw_params_set_avail_min(data->pcmHandle, sp, bufferSizeInFrames)) != 0) + if(err == NULL && (i=psnd_pcm_sw_params_set_avail_min(data->pcmHandle, sp, periodSizeInFrames)) != 0) err = "sw set avail min"; if(err == NULL && (i=psnd_pcm_sw_params(data->pcmHandle, sp)) != 0) err = "sw set params"; @@ -503,15 +508,19 @@ static ALCboolean alsa_reset_playback(ALCdevice *device) psnd_pcm_sw_params_free(sp); - data->size = psnd_pcm_frames_to_bytes(data->pcmHandle, bufferSizeInFrames); + data->size = psnd_pcm_frames_to_bytes(data->pcmHandle, periodSizeInFrames); if(access == SND_PCM_ACCESS_RW_INTERLEAVED) { + /* Increase periods by one, since the temp buffer counts as an extra + * period */ + periods++; data->buffer = malloc(data->size); if(!data->buffer) { AL_PRINT("buffer malloc failed\n"); return ALC_FALSE; } + data->thread = StartThread(ALSANoMMapProc, device); } else { @@ -523,12 +532,8 @@ static ALCboolean alsa_reset_playback(ALCdevice *device) data->buffer = NULL; return ALC_FALSE; } - } - - if(access == SND_PCM_ACCESS_RW_INTERLEAVED) - data->thread = StartThread(ALSANoMMapProc, device); - else data->thread = StartThread(ALSAProc, device); + } if(data->thread == NULL) { AL_PRINT("Could not create playback thread\n"); @@ -537,7 +542,8 @@ static ALCboolean alsa_reset_playback(ALCdevice *device) return ALC_FALSE; } - device->UpdateSize = bufferSizeInFrames; + device->UpdateSize = periodSizeInFrames; + device->NumUpdates = periods; device->Frequency = rate; return ALC_TRUE; @@ -631,7 +637,7 @@ open_alsa: } err = NULL; - bufferSizeInFrames = pDevice->BufferSize; + bufferSizeInFrames = pDevice->UpdateSize * pDevice->NumUpdates; psnd_pcm_hw_params_malloc(&p); if((i=psnd_pcm_hw_params_any(data->pcmHandle, p)) < 0) @@ -677,7 +683,7 @@ open_alsa: frameSize = aluChannelsFromFormat(pDevice->Format); frameSize *= aluBytesFromFormat(pDevice->Format); - data->ring = CreateRingBuffer(frameSize, pDevice->BufferSize); + data->ring = CreateRingBuffer(frameSize, bufferSizeInFrames); if(!data->ring) { AL_PRINT("ring buffer create failed\n"); @@ -815,9 +821,11 @@ LOAD_FUNC(snd_pcm_hw_params_set_rate_near); LOAD_FUNC(snd_pcm_hw_params_set_rate); LOAD_FUNC(snd_pcm_hw_params_set_buffer_size_near); LOAD_FUNC(snd_pcm_hw_params_set_buffer_size_min); +LOAD_FUNC(snd_pcm_hw_params_set_period_size_near); LOAD_FUNC(snd_pcm_hw_params_get_buffer_size); LOAD_FUNC(snd_pcm_hw_params_get_period_size); LOAD_FUNC(snd_pcm_hw_params_get_access); +LOAD_FUNC(snd_pcm_hw_params_get_periods); LOAD_FUNC(snd_pcm_hw_params); LOAD_FUNC(snd_pcm_sw_params_malloc); LOAD_FUNC(snd_pcm_sw_params_current); diff --git a/Alc/dsound.c b/Alc/dsound.c index e4436258..959f55d2 100644 --- a/Alc/dsound.c +++ b/Alc/dsound.c @@ -51,8 +51,6 @@ static void *ds_handle; static HRESULT (WINAPI *pDirectSoundCreate)(LPCGUID pcGuidDevice, LPDIRECTSOUND *ppDS, LPUNKNOWN pUnkOuter); static HRESULT (WINAPI *pDirectSoundEnumerateA)(LPDSENUMCALLBACKA pDSEnumCallback, LPVOID pContext); -// Since DSound doesn't report the fragment size, emulate it -static int num_frags; typedef struct { // DirectSound Playback Device @@ -98,10 +96,10 @@ static ALuint DSoundProc(ALvoid *ptr) aluHandleDisconnect(pDevice); return 1; } - FragSize = DSBCaps.dwBufferBytes / num_frags; FrameSize = aluChannelsFromFormat(pDevice->Format) * aluBytesFromFormat(pDevice->Format); + FragSize = pDevice->UpdateSize * FrameSize; IDirectSoundBuffer_GetCurrentPosition(pData->DSsbuffer, &LastCursor, NULL); while(!pData->killNow) @@ -344,10 +342,13 @@ static ALCboolean DSoundResetPlayback(ALCdevice *device) if(SUCCEEDED(hr)) { + DWORD num_frags = GetConfigValueInt("dsound", "periods", device->NumUpdates); + if(num_frags < 2) num_frags = 2; + memset(&DSBDescription,0,sizeof(DSBUFFERDESC)); DSBDescription.dwSize=sizeof(DSBUFFERDESC); DSBDescription.dwFlags=DSBCAPS_GLOBALFOCUS|DSBCAPS_GETCURRENTPOSITION2; - DSBDescription.dwBufferBytes=(device->BufferSize/num_frags) * num_frags * frameSize; + DSBDescription.dwBufferBytes=device->UpdateSize * device->NumUpdates * frameSize; DSBDescription.lpwfxFormat=&OutputType.Format; hr = IDirectSound_CreateSoundBuffer(pData->lpDS, &DSBDescription, &pData->DSsbuffer, NULL); } @@ -375,7 +376,6 @@ static ALCboolean DSoundResetPlayback(ALCdevice *device) } device->Format = format; - device->UpdateSize = device->BufferSize/num_frags; return ALC_TRUE; } @@ -505,9 +505,6 @@ void alcDSoundInit(BackendFuncs *FuncList) LOAD_FUNC(DirectSoundCreate); LOAD_FUNC(DirectSoundEnumerateA); #undef LOAD_FUNC - - num_frags = GetConfigValueInt("dsound", "periods", 4); - if(num_frags < 2) num_frags = 2; } void alcDSoundDeinit(void) @@ -221,18 +221,19 @@ static ALCboolean oss_reset_playback(ALCdevice *device) AL_PRINT("Unknown format?! %x\n", device->Format); } - periods = GetConfigValueInt("oss", "periods", 4); - if((int)periods <= 0) + periods = GetConfigValueInt("oss", "periods", device->NumUpdates); + if((int)periods < 2) periods = 4; numChannels = aluChannelsFromFormat(device->Format); frameSize = numChannels * aluBytesFromFormat(device->Format); ossSpeed = device->Frequency; - log2FragmentSize = log2i(device->BufferSize * frameSize / periods); + log2FragmentSize = log2i(device->UpdateSize * frameSize); /* according to the OSS spec, 16 bytes are the minimum */ if (log2FragmentSize < 4) log2FragmentSize = 4; + if(periods > 2) periods--; numFragmentsLogSize = (periods << 16) | log2FragmentSize; #define ok(func, str) (i=(func),((i<0)?(err=(str)),0:1)) @@ -262,6 +263,7 @@ static ALCboolean oss_reset_playback(ALCdevice *device) device->Frequency = ossSpeed; device->UpdateSize = info.fragsize / frameSize; + device->NumUpdates = info.fragments + 1; data->data_size = device->UpdateSize * frameSize; data->mix_data = calloc(1, data->data_size); @@ -343,7 +345,8 @@ static ALCboolean oss_open_capture(ALCdevice *device, const ALCchar *deviceName) numChannels = aluChannelsFromFormat(device->Format); frameSize = numChannels * aluBytesFromFormat(device->Format); ossSpeed = device->Frequency; - log2FragmentSize = log2i(device->BufferSize * frameSize / periods); + log2FragmentSize = log2i(device->UpdateSize * device->NumUpdates * + frameSize / periods); /* according to the OSS spec, 16 bytes are the minimum */ if (log2FragmentSize < 4) @@ -381,7 +384,7 @@ static ALCboolean oss_open_capture(ALCdevice *device, const ALCchar *deviceName) return ALC_FALSE; } - data->ring = CreateRingBuffer(frameSize, device->BufferSize); + data->ring = CreateRingBuffer(frameSize, device->UpdateSize * device->NumUpdates); if(!data->ring) { AL_PRINT("ring buffer create failed\n"); diff --git a/Alc/portaudio.c b/Alc/portaudio.c index 50039286..e7330999 100644 --- a/Alc/portaudio.c +++ b/Alc/portaudio.c @@ -90,7 +90,7 @@ static ALCboolean pa_open_playback(ALCdevice *device, const ALCchar *deviceName) outParams.device = GetConfigValueInt("port", "device", -1); if(outParams.device < 0) outParams.device = pPa_GetDefaultOutputDevice(); - outParams.suggestedLatency = (float)device->BufferSize / + outParams.suggestedLatency = (device->UpdateSize*device->NumUpdates) / (float)device->Frequency; outParams.hostApiSpecificStreamInfo = NULL; @@ -116,8 +116,7 @@ static ALCboolean pa_open_playback(ALCdevice *device, const ALCchar *deviceName) outParams.channelCount = aluChannelsFromFormat(device->Format); err = pPa_OpenStream(&data->stream, NULL, &outParams, device->Frequency, - device->BufferSize/periods, paNoFlag, - pa_callback, device); + device->UpdateSize, paNoFlag, pa_callback, device); if(err != paNoError) { AL_PRINT("Pa_OpenStream() returned an error: %s\n", pPa_GetErrorText(err)); @@ -138,7 +137,6 @@ static ALCboolean pa_open_playback(ALCdevice *device, const ALCchar *deviceName) } device->szDeviceName = strdup(deviceName); - device->UpdateSize = device->BufferSize/periods; device->Frequency = streamInfo->sampleRate; return ALC_TRUE; } diff --git a/Alc/pulseaudio.c b/Alc/pulseaudio.c index c5453344..53e864b2 100644 --- a/Alc/pulseaudio.c +++ b/Alc/pulseaudio.c @@ -342,17 +342,13 @@ static ALCboolean pulse_reset_playback(ALCdevice *device) //{{{ ppa_threaded_mainloop_lock(data->loop); - data->samples = device->BufferSize; data->frame_size = aluBytesFromFormat(device->Format) * aluChannelsFromFormat(device->Format); - - device->UpdateSize = device->BufferSize / 4; - data->attr.minreq = -1; data->attr.prebuf = -1; data->attr.maxlength = -1; data->attr.fragsize = data->frame_size * device->UpdateSize; - data->attr.tlength = data->attr.fragsize * 4; + data->attr.tlength = data->attr.fragsize * device->NumUpdates; data->stream_name = "Playback Stream"; data->spec.rate = device->Frequency; @@ -464,7 +460,7 @@ static ALCboolean pulse_open_capture(ALCdevice *device, const ALCchar *device_na data = device->ExtraData; ppa_threaded_mainloop_lock(data->loop); - data->samples = device->BufferSize; + data->samples = device->UpdateSize * device->NumUpdates; data->frame_size = aluBytesFromFormat(device->Format) * aluChannelsFromFormat(device->Format); diff --git a/Alc/solaris.c b/Alc/solaris.c index 5cc9e201..58d6e081 100644 --- a/Alc/solaris.c +++ b/Alc/solaris.c @@ -167,7 +167,7 @@ static ALCboolean solaris_reset_playback(ALCdevice *device) info.play.channels = numChannels; frameSize = numChannels * aluBytesFromFormat(device->Format); - info.play.buffer_size = device->BufferSize * frameSize; + info.play.buffer_size = device->UpdateSize*device->NumUpdates * frameSize; if(ioctl(data->fd, AUDIO_SETINFO, &info) < 0) { @@ -189,7 +189,7 @@ static ALCboolean solaris_reset_playback(ALCdevice *device) } device->Frequency = info.play.sample_rate; - device->UpdateSize = info.play.buffer_size / 4; + device->UpdateSize = (info.play.buffer_size/device->NumUpdates) + 1; data->data_size = device->UpdateSize * frameSize; data->mix_data = calloc(1, data->data_size); @@ -219,8 +219,6 @@ static ALCboolean wave_reset_playback(ALCdevice *device) data->DataStart = ftell(data->f); - device->UpdateSize = device->BufferSize / 4; - data->size = device->UpdateSize * channels * bits / 8; data->buffer = malloc(data->size); if(!data->buffer) diff --git a/Alc/winmm.c b/Alc/winmm.c index e2a4a7b9..5ecf471f 100644 --- a/Alc/winmm.c +++ b/Alc/winmm.c @@ -229,7 +229,8 @@ static ALCboolean WinMMOpenCapture(ALCdevice *pDevice, const ALCchar *deviceName goto failure; // Allocate circular memory buffer for the captured audio - pData->ulCapturedDataSize = pDevice->BufferSize * wfexCaptureFormat.nBlockAlign; + pData->ulCapturedDataSize = pDevice->UpdateSize*pDevice->NumUpdates * + wfexCaptureFormat.nBlockAlign; // Make sure circular buffer is at least 100ms in size (and an exact multiple of // the block alignment diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index a7fdb6ee..a334fabd 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -210,7 +210,7 @@ struct ALCdevice_struct ALuint Frequency; ALuint UpdateSize; - ALuint BufferSize; + ALuint NumUpdates; ALenum Format; ALCchar *szDeviceName; diff --git a/alsoftrc.sample b/alsoftrc.sample index 45d5ba07..83795f34 100644 --- a/alsoftrc.sample +++ b/alsoftrc.sample @@ -52,10 +52,17 @@ # Sets the output frequency. #frequency = 44100 -## refresh: -# Sets the buffer size, in frames. Note that the actual granularity may or may -# not be less than this. -#refresh = 4096 +## period_size: +# Sets the update period size, in frames. This is the number of frames needed +# for each mixing update. If the deprecated 'refresh' option is specified and +# this isn't, the value will be calculated as size = refresh/periods. +#period_size = 1024 + +## periods: +# Sets the number of update periods. Higher values create a larger mix ahead, +# which helps protect against skips when the CPU is under load, but increases +# the delay between a sound getting mixed and being heard. +#periods = 4 ## sources: # Sets the maximum number of allocatable sources. Lower values may help for @@ -136,11 +143,6 @@ # Sets the device name for the default playback device. #device = default -## periods: -# Sets the number of update buffers for playback. A value of 0 means auto- -# select. -#periods = 0 - ## capture: # Sets the device name for the default capture device. #capture = default @@ -161,10 +163,6 @@ # Sets the device name for OSS output. #device = /dev/dsp -## periods: -# Sets the number of update buffers. -#periods = 4 - ## capture: # Sets the device name for OSS capture. #capture = /dev/dsp @@ -178,13 +176,11 @@ # Sets the device name for Solaris output. #device = /dev/audio +## ## DirectSound backend stuff +## [dsound] -## periods: -# Sets the number of updates for the output buffer. -#periods = 4 - ## ## Windows Multimedia backend stuff ## @@ -200,10 +196,6 @@ # given by PortAudio itself. #device = -1 -## periods: -# Sets the number of update buffers. -#periods = 4 - ## ## PulseAudio backend stuff ## |