diff options
-rw-r--r-- | Alc/ALc.c | 20 | ||||
-rw-r--r-- | Alc/backends/alsa.c | 49 | ||||
-rw-r--r-- | Alc/backends/dsound.c | 53 | ||||
-rw-r--r-- | Alc/backends/loopback.c | 7 | ||||
-rw-r--r-- | Alc/backends/mmdevapi.c | 84 | ||||
-rw-r--r-- | Alc/backends/null.c | 9 | ||||
-rw-r--r-- | Alc/backends/opensl.c | 40 | ||||
-rw-r--r-- | Alc/backends/oss.c | 14 | ||||
-rw-r--r-- | Alc/backends/portaudio.c | 10 | ||||
-rw-r--r-- | Alc/backends/pulseaudio.c | 41 | ||||
-rw-r--r-- | Alc/backends/sndio.c | 10 | ||||
-rw-r--r-- | Alc/backends/solaris.c | 14 | ||||
-rw-r--r-- | Alc/backends/wave.c | 15 | ||||
-rw-r--r-- | Alc/backends/winmm.c | 22 | ||||
-rw-r--r-- | OpenAL32/Include/alMain.h | 2 |
15 files changed, 273 insertions, 117 deletions
@@ -40,7 +40,7 @@ #include "alu.h" -#define EmptyFuncs { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } +#define EmptyFuncs { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } static struct BackendInfo BackendList[] = { #ifdef HAVE_PULSEAUDIO { "pulse", alc_pulse_init, alc_pulse_deinit, alc_pulse_probe, EmptyFuncs }, @@ -1197,8 +1197,6 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) if((device->Flags&DEVICE_RUNNING)) return ALC_NO_ERROR; - LockDevice(device); - oldFreq = device->Frequency; oldChans = device->FmtChans; oldType = device->FmtType; @@ -1211,12 +1209,9 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) device->Frequency, (device->Flags&DEVICE_FREQUENCY_REQUEST)?" (requested)":"", device->UpdateSize, device->NumUpdates); + if(ALCdevice_ResetPlayback(device) == ALC_FALSE) - { - UnlockDevice(device); return ALC_INVALID_DEVICE; - } - device->Flags |= DEVICE_RUNNING; if(device->FmtChans != oldChans && (device->Flags&DEVICE_CHANNELS_REQUEST)) { @@ -1290,6 +1285,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) TRACE("Stereo duplication %s\n", (device->Flags&DEVICE_DUPLICATE_STEREO)?"enabled":"disabled"); oldMode = SetMixerFPUMode(); + LockDevice(device); context = device->ContextList; while(context) { @@ -1304,10 +1300,8 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) if(ALeffectState_DeviceUpdate(slot->EffectState, device) == AL_FALSE) { UnlockUIntMapRead(&context->EffectSlotMap); - RestoreFPUMode(oldMode); UnlockDevice(device); - ALCdevice_StopPlayback(device); - device->Flags &= ~DEVICE_RUNNING; + RestoreFPUMode(oldMode); return ALC_INVALID_DEVICE; } slot->NeedsUpdate = AL_FALSE; @@ -1336,8 +1330,12 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) context = context->next; } - RestoreFPUMode(oldMode); UnlockDevice(device); + RestoreFPUMode(oldMode); + + if(ALCdevice_StartPlayback(device) == ALC_FALSE) + return ALC_INVALID_DEVICE; + device->Flags |= DEVICE_RUNNING; return ALC_NO_ERROR; } diff --git a/Alc/backends/alsa.c b/Alc/backends/alsa.c index a9f34491..fa5ef1a6 100644 --- a/Alc/backends/alsa.c +++ b/Alc/backends/alsa.c @@ -44,6 +44,7 @@ MAKE_FUNC(snd_pcm_bytes_to_frames); MAKE_FUNC(snd_pcm_hw_params_malloc); MAKE_FUNC(snd_pcm_hw_params_free); MAKE_FUNC(snd_pcm_hw_params_any); +MAKE_FUNC(snd_pcm_hw_params_current); MAKE_FUNC(snd_pcm_hw_params_set_access); MAKE_FUNC(snd_pcm_hw_params_set_format); MAKE_FUNC(snd_pcm_hw_params_set_channels); @@ -111,6 +112,7 @@ MAKE_FUNC(snd_card_next); #define snd_pcm_hw_params_malloc psnd_pcm_hw_params_malloc #define snd_pcm_hw_params_free psnd_pcm_hw_params_free #define snd_pcm_hw_params_any psnd_pcm_hw_params_any +#define snd_pcm_hw_params_current psnd_pcm_hw_params_current #define snd_pcm_hw_params_set_access psnd_pcm_hw_params_set_access #define snd_pcm_hw_params_set_format psnd_pcm_hw_params_set_format #define snd_pcm_hw_params_set_channels psnd_pcm_hw_params_set_channels @@ -196,6 +198,7 @@ static ALCboolean alsa_load(void) LOAD_FUNC(snd_pcm_hw_params_malloc); LOAD_FUNC(snd_pcm_hw_params_free); LOAD_FUNC(snd_pcm_hw_params_any); + LOAD_FUNC(snd_pcm_hw_params_current); LOAD_FUNC(snd_pcm_hw_params_set_access); LOAD_FUNC(snd_pcm_hw_params_set_format); LOAD_FUNC(snd_pcm_hw_params_set_channels); @@ -647,7 +650,6 @@ static ALCboolean alsa_reset_playback(ALCdevice *device) int allowmmap; int err; - format = -1; switch(device->FmtType) { @@ -770,23 +772,52 @@ static ALCboolean alsa_reset_playback(ALCdevice *device) snd_pcm_sw_params_free(sp); sp = NULL; + /* Increase periods by one, since the temp buffer counts as an extra + * period */ + if(access == SND_PCM_ACCESS_RW_INTERLEAVED) + device->NumUpdates = periods+1; + else + device->NumUpdates = periods; + device->UpdateSize = periodSizeInFrames; device->Frequency = rate; + SetDefaultChannelOrder(device); - data->size = snd_pcm_frames_to_bytes(data->pcmHandle, periodSizeInFrames); + return ALC_TRUE; + +error: + ERR("%s failed: %s\n", funcerr, snd_strerror(err)); + if(hp) snd_pcm_hw_params_free(hp); + if(sp) snd_pcm_sw_params_free(sp); + return ALC_FALSE; +} + +static ALCboolean alsa_start_playback(ALCdevice *device) +{ + alsa_data *data = (alsa_data*)device->ExtraData; + snd_pcm_hw_params_t *hp = NULL; + snd_pcm_access_t access; + const char *funcerr; + int err; + + snd_pcm_hw_params_malloc(&hp); +#define CHECK(x) if((funcerr=#x),(err=(x)) < 0) goto error + CHECK(snd_pcm_hw_params_current(data->pcmHandle, hp)); + /* retrieve configuration info */ + CHECK(snd_pcm_hw_params_get_access(hp, &access)); +#undef CHECK + snd_pcm_hw_params_free(hp); + hp = NULL; + + data->size = snd_pcm_frames_to_bytes(data->pcmHandle, device->UpdateSize); 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) { ERR("buffer malloc failed\n"); return ALC_FALSE; } - device->UpdateSize = periodSizeInFrames; - device->NumUpdates = periods; data->thread = StartThread(ALSANoMMapProc, device); } else @@ -797,8 +828,6 @@ static ALCboolean alsa_reset_playback(ALCdevice *device) ERR("snd_pcm_prepare(data->pcmHandle) failed: %s\n", snd_strerror(err)); return ALC_FALSE; } - device->UpdateSize = periodSizeInFrames; - device->NumUpdates = periods; data->thread = StartThread(ALSAProc, device); } if(data->thread == NULL) @@ -814,7 +843,6 @@ static ALCboolean alsa_reset_playback(ALCdevice *device) error: ERR("%s failed: %s\n", funcerr, snd_strerror(err)); if(hp) snd_pcm_hw_params_free(hp); - if(sp) snd_pcm_sw_params_free(sp); return ALC_FALSE; } @@ -1186,6 +1214,7 @@ static const BackendFuncs alsa_funcs = { alsa_open_playback, alsa_close_playback, alsa_reset_playback, + alsa_start_playback, alsa_stop_playback, alsa_open_capture, alsa_close_capture, diff --git a/Alc/backends/dsound.c b/Alc/backends/dsound.c index feca3cfa..0eab62a4 100644 --- a/Alc/backends/dsound.c +++ b/Alc/backends/dsound.c @@ -392,6 +392,16 @@ static void DSoundClosePlayback(ALCdevice *device) { DSoundPlaybackData *pData = device->ExtraData; + if(pData->DSnotify) + IDirectSoundNotify_Release(pData->DSnotify); + pData->DSnotify = NULL; + if(pData->DSsbuffer) + IDirectSoundBuffer_Release(pData->DSsbuffer); + pData->DSsbuffer = NULL; + if(pData->DSpbuffer != NULL) + IDirectSoundBuffer_Release(pData->DSpbuffer); + pData->DSpbuffer = NULL; + IDirectSound_Release(pData->lpDS); CloseHandle(pData->hNotifyEvent); free(pData); @@ -408,6 +418,16 @@ static ALCboolean DSoundResetPlayback(ALCdevice *device) memset(&OutputType, 0, sizeof(OutputType)); + if(pData->DSnotify) + IDirectSoundNotify_Release(pData->DSnotify); + pData->DSnotify = NULL; + if(pData->DSsbuffer) + IDirectSoundBuffer_Release(pData->DSsbuffer); + pData->DSsbuffer = NULL; + if(pData->DSpbuffer != NULL) + IDirectSoundBuffer_Release(pData->DSpbuffer); + pData->DSpbuffer = NULL; + switch(device->FmtType) { case DevFmtByte: @@ -578,15 +598,6 @@ retry_open: } } - if(SUCCEEDED(hr)) - { - ResetEvent(pData->hNotifyEvent); - SetDefaultWFXChannelOrder(device); - pData->thread = StartThread(DSoundPlaybackProc, device); - if(pData->thread == NULL) - hr = E_FAIL; - } - if(FAILED(hr)) { if(pData->DSnotify != NULL) @@ -601,6 +612,20 @@ retry_open: return ALC_FALSE; } + ResetEvent(pData->hNotifyEvent); + SetDefaultWFXChannelOrder(device); + + return ALC_TRUE; +} + +static ALCboolean DSoundStartPlayback(ALCdevice *device) +{ + DSoundPlaybackData *pData = (DSoundPlaybackData*)device->ExtraData; + + pData->thread = StartThread(DSoundPlaybackProc, device); + if(pData->thread == NULL) + return ALC_FALSE; + return ALC_TRUE; } @@ -616,14 +641,7 @@ static void DSoundStopPlayback(ALCdevice *device) pData->thread = NULL; pData->killNow = 0; - - IDirectSoundNotify_Release(pData->DSnotify); - pData->DSnotify = NULL; - IDirectSoundBuffer_Release(pData->DSsbuffer); - pData->DSsbuffer = NULL; - if(pData->DSpbuffer != NULL) - IDirectSoundBuffer_Release(pData->DSpbuffer); - pData->DSpbuffer = NULL; + IDirectSoundBuffer_Stop(pData->DSsbuffer); } @@ -918,6 +936,7 @@ static const BackendFuncs DSoundFuncs = { DSoundOpenPlayback, DSoundClosePlayback, DSoundResetPlayback, + DSoundStartPlayback, DSoundStopPlayback, DSoundOpenCapture, DSoundCloseCapture, diff --git a/Alc/backends/loopback.c b/Alc/backends/loopback.c index 8a576361..3726974c 100644 --- a/Alc/backends/loopback.c +++ b/Alc/backends/loopback.c @@ -43,6 +43,12 @@ static ALCboolean loopback_reset_playback(ALCdevice *device) return ALC_TRUE; } +static ALCboolean loopback_start_playback(ALCdevice *device) +{ + return ALC_TRUE; + (void)device; +} + static void loopback_stop_playback(ALCdevice *device) { (void)device; @@ -52,6 +58,7 @@ static const BackendFuncs loopback_funcs = { loopback_open_playback, loopback_close_playback, loopback_reset_playback, + loopback_start_playback, loopback_stop_playback, NULL, NULL, diff --git a/Alc/backends/mmdevapi.c b/Alc/backends/mmdevapi.c index 52b54eb4..ccfb1a44 100644 --- a/Alc/backends/mmdevapi.c +++ b/Alc/backends/mmdevapi.c @@ -90,9 +90,10 @@ typedef struct { #define WM_USER_OpenDevice (WM_USER+0) #define WM_USER_ResetDevice (WM_USER+1) -#define WM_USER_StopDevice (WM_USER+2) -#define WM_USER_CloseDevice (WM_USER+3) -#define WM_USER_Enumerate (WM_USER+4) +#define WM_USER_StartDevice (WM_USER+2) +#define WM_USER_StopDevice (WM_USER+3) +#define WM_USER_CloseDevice (WM_USER+4) +#define WM_USER_Enumerate (WM_USER+5) static HRESULT WaitForResponse(ThreadRequest *req) { @@ -315,7 +316,6 @@ static HRESULT DoReset(ALCdevice *device) REFERENCE_TIME min_per, buf_time; UINT32 buffer_len, min_len; HRESULT hr; - void *ptr; hr = IAudioClient_GetMixFormat(data->client, &wfx); if(FAILED(hr)) @@ -532,32 +532,6 @@ static HRESULT DoReset(ALCdevice *device) ERR("Audio client returned buffer_len < period*2; expect break up\n"); } - ResetEvent(data->hNotifyEvent); - hr = IAudioClient_SetEventHandle(data->client, data->hNotifyEvent); - if(SUCCEEDED(hr)) - hr = IAudioClient_Start(data->client); - if(FAILED(hr)) - { - ERR("Failed to start audio client: 0x%08lx\n", hr); - return hr; - } - - hr = IAudioClient_GetService(data->client, &IID_IAudioRenderClient, &ptr); - if(SUCCEEDED(hr)) - { - data->render = ptr; - data->thread = StartThread(MMDevApiProc, device); - } - if(!data->thread) - { - if(data->render) - IAudioRenderClient_Release(data->render); - data->render = NULL; - IAudioClient_Stop(data->client); - ERR("Failed to start thread\n"); - return E_FAIL; - } - return hr; } @@ -656,6 +630,43 @@ static DWORD CALLBACK MMDevApiMsgProc(void *ptr) SetEvent(req->FinishedEvt); continue; + case WM_USER_StartDevice: + req = (ThreadRequest*)msg.wParam; + device = (ALCdevice*)msg.lParam; + data = device->ExtraData; + + ResetEvent(data->hNotifyEvent); + hr = IAudioClient_SetEventHandle(data->client, data->hNotifyEvent); + if(FAILED(hr)) + ERR("Failed to set event handle: 0x%08lx\n", hr); + else + { + hr = IAudioClient_Start(data->client); + if(FAILED(hr)) + ERR("Failed to start audio client: 0x%08lx\n", hr); + } + + if(SUCCEEDED(hr)) + hr = IAudioClient_GetService(data->client, &IID_IAudioRenderClient, &ptr); + if(SUCCEEDED(hr)) + { + data->render = ptr; + data->thread = StartThread(MMDevApiProc, device); + if(!data->thread) + { + if(data->render) + IAudioRenderClient_Release(data->render); + data->render = NULL; + IAudioClient_Stop(data->client); + ERR("Failed to start thread\n"); + hr = E_FAIL; + } + } + + req->result = hr; + SetEvent(req->FinishedEvt); + continue; + case WM_USER_StopDevice: req = (ThreadRequest*)msg.wParam; device = (ALCdevice*)msg.lParam; @@ -885,6 +896,18 @@ static ALCboolean MMDevApiResetPlayback(ALCdevice *device) return SUCCEEDED(hr) ? ALC_TRUE : ALC_FALSE; } +static ALCboolean MMDevApiStartPlayback(ALCdevice *device) +{ + MMDevApiData *data = device->ExtraData; + ThreadRequest req = { data->MsgEvent, 0 }; + HRESULT hr = E_FAIL; + + if(PostThreadMessage(ThreadID, WM_USER_StartDevice, (WPARAM)&req, (LPARAM)device)) + hr = WaitForResponse(&req); + + return SUCCEEDED(hr) ? ALC_TRUE : ALC_FALSE; +} + static void MMDevApiStopPlayback(ALCdevice *device) { MMDevApiData *data = device->ExtraData; @@ -899,6 +922,7 @@ static const BackendFuncs MMDevApiFuncs = { MMDevApiOpenPlayback, MMDevApiClosePlayback, MMDevApiResetPlayback, + MMDevApiStartPlayback, MMDevApiStopPlayback, NULL, NULL, diff --git a/Alc/backends/null.c b/Alc/backends/null.c index 10068630..8fc60b66 100644 --- a/Alc/backends/null.c +++ b/Alc/backends/null.c @@ -99,9 +99,13 @@ static void null_close_playback(ALCdevice *device) static ALCboolean null_reset_playback(ALCdevice *device) { - null_data *data = (null_data*)device->ExtraData; - SetDefaultWFXChannelOrder(device); + return ALC_TRUE; +} + +static ALCboolean null_start_playback(ALCdevice *device) +{ + null_data *data = (null_data*)device->ExtraData; data->thread = StartThread(NullProc, device); if(data->thread == NULL) @@ -129,6 +133,7 @@ static const BackendFuncs null_funcs = { null_open_playback, null_close_playback, null_reset_playback, + null_start_playback, null_stop_playback, NULL, NULL, diff --git a/Alc/backends/opensl.c b/Alc/backends/opensl.c index 58acc828..5ff60276 100644 --- a/Alc/backends/opensl.c +++ b/Alc/backends/opensl.c @@ -242,6 +242,10 @@ static void opensl_close_playback(ALCdevice *Device) { osl_data *data = Device->ExtraData; + if(data->bufferQueueObject != NULL) + SLObjectItf_Destroy(data->bufferQueueObject); + data->bufferQueueObject = NULL; + SLObjectItf_Destroy(data->outputMix); data->outputMix = NULL; @@ -257,16 +261,13 @@ static ALCboolean opensl_reset_playback(ALCdevice *Device) { osl_data *data = Device->ExtraData; SLDataLocator_AndroidSimpleBufferQueue loc_bufq; - SLAndroidSimpleBufferQueueItf bufferQueue; SLDataLocator_OutputMix loc_outmix; SLDataFormat_PCM format_pcm; SLDataSource audioSrc; SLDataSink audioSnk; - SLPlayItf player; SLInterfaceID id; SLboolean req; SLresult result; - ALuint i; Device->UpdateSize = (ALuint64)Device->UpdateSize * 44100 / Device->Frequency; @@ -303,6 +304,10 @@ static ALCboolean opensl_reset_playback(ALCdevice *Device) audioSnk.pFormat = NULL; + if(data->bufferQueueObject != NULL) + SLObjectItf_Destroy(data->bufferQueueObject); + data->bufferQueueObject = NULL; + result = SLEngineItf_CreateAudioPlayer(data->engine, &data->bufferQueueObject, &audioSrc, &audioSnk, 1, &id, &req); PRINTERR(result, "engine->CreateAudioPlayer"); if(SL_RESULT_SUCCESS == result) @@ -310,11 +315,29 @@ static ALCboolean opensl_reset_playback(ALCdevice *Device) result = SLObjectItf_Realize(data->bufferQueueObject, SL_BOOLEAN_FALSE); PRINTERR(result, "bufferQueue->Realize"); } - if(SL_RESULT_SUCCESS == result) + + if(SL_RESULT_SUCCESS != result) { - result = SLObjectItf_GetInterface(data->bufferQueueObject, SL_IID_BUFFERQUEUE, &bufferQueue); - PRINTERR(result, "bufferQueue->GetInterface"); + if(data->bufferQueueObject != NULL) + SLObjectItf_Destroy(data->bufferQueueObject); + data->bufferQueueObject = NULL; + + return ALC_FALSE; } + + return ALC_TRUE; +} + +static ALCboolean opensl_start_playback(ALCdevice *Device) +{ + osl_data *data = Device->ExtraData; + SLAndroidSimpleBufferQueueItf bufferQueue; + SLPlayItf player; + SLresult result; + ALuint i; + + result = SLObjectItf_GetInterface(data->bufferQueueObject, SL_IID_BUFFERQUEUE, &bufferQueue); + PRINTERR(result, "bufferQueue->GetInterface"); if(SL_RESULT_SUCCESS == result) { result = (*bufferQueue)->RegisterCallback(bufferQueue, opensl_callback, Device); @@ -372,10 +395,6 @@ static void opensl_stop_playback(ALCdevice *Device) { osl_data *data = Device->ExtraData; - if(data->bufferQueueObject != NULL) - SLObjectItf_Destroy(data->bufferQueueObject); - data->bufferQueueObject = NULL; - free(data->buffer); data->buffer = NULL; data->bufferSize = 0; @@ -386,6 +405,7 @@ static const BackendFuncs opensl_funcs = { opensl_open_playback, opensl_close_playback, opensl_reset_playback, + opensl_start_playback, opensl_stop_playback, NULL, NULL, diff --git a/Alc/backends/oss.c b/Alc/backends/oss.c index bd489e3e..a577d8be 100644 --- a/Alc/backends/oss.c +++ b/Alc/backends/oss.c @@ -268,11 +268,18 @@ static ALCboolean oss_reset_playback(ALCdevice *device) device->UpdateSize = info.fragsize / frameSize; device->NumUpdates = info.fragments + 1; - data->data_size = device->UpdateSize * frameSize; - data->mix_data = calloc(1, data->data_size); - SetDefaultChannelOrder(device); + return ALC_TRUE; +} + +static ALCboolean oss_start_playback(ALCdevice *device) +{ + oss_data *data = (oss_data*)device->ExtraData; + + data->data_size = device->UpdateSize * FrameSizeFromDevFmt(device->FmtChans, device->FmtType); + data->mix_data = calloc(1, data->data_size); + data->thread = StartThread(OSSProc, device); if(data->thread == NULL) { @@ -473,6 +480,7 @@ static const BackendFuncs oss_funcs = { oss_open_playback, oss_close_playback, oss_reset_playback, + oss_start_playback, oss_stop_playback, oss_open_capture, oss_close_capture, diff --git a/Alc/backends/portaudio.c b/Alc/backends/portaudio.c index 154b6349..03e54d14 100644 --- a/Alc/backends/portaudio.c +++ b/Alc/backends/portaudio.c @@ -261,12 +261,19 @@ static ALCboolean pa_reset_playback(ALCdevice *device) { pa_data *data = (pa_data*)device->ExtraData; const PaStreamInfo *streamInfo; - PaError err; streamInfo = Pa_GetStreamInfo(data->stream); device->Frequency = streamInfo->sampleRate; device->UpdateSize = data->update_size; + return ALC_TRUE; +} + +static ALCboolean pa_start_playback(ALCdevice *device) +{ + pa_data *data = (pa_data*)device->ExtraData; + PaError err; + err = Pa_StartStream(data->stream); if(err != paNoError) { @@ -409,6 +416,7 @@ static const BackendFuncs pa_funcs = { pa_open_playback, pa_close_playback, pa_reset_playback, + pa_start_playback, pa_stop_playback, pa_open_capture, pa_close_capture, diff --git a/Alc/backends/pulseaudio.c b/Alc/backends/pulseaudio.c index 8fe1118b..78854da7 100644 --- a/Alc/backends/pulseaudio.c +++ b/Alc/backends/pulseaudio.c @@ -873,6 +873,10 @@ static void pulse_close(ALCdevice *device) if(data->stream) { +#if PA_CHECK_VERSION(0,9,15) + if(pa_stream_set_buffer_attr_callback) + pa_stream_set_buffer_attr_callback(data->stream, NULL, NULL); +#endif pa_stream_disconnect(data->stream); pa_stream_unref(data->stream); } @@ -968,6 +972,10 @@ static ALCboolean pulse_reset_playback(ALCdevice *device) if(data->stream) { +#if PA_CHECK_VERSION(0,9,15) + if(pa_stream_set_buffer_attr_callback) + pa_stream_set_buffer_attr_callback(data->stream, NULL, NULL); +#endif pa_stream_disconnect(data->stream); pa_stream_unref(data->stream); data->stream = NULL; @@ -1079,28 +1087,25 @@ static ALCboolean pulse_reset_playback(ALCdevice *device) device->NumUpdates = maxu(device->NumUpdates, 2); device->UpdateSize = data->attr.minreq / pa_frame_size(&data->spec); + pa_threaded_mainloop_unlock(data->loop); + return ALC_TRUE; +} + +static ALCboolean pulse_start_playback(ALCdevice *device) +{ + pulse_data *data = device->ExtraData; + data->thread = StartThread(PulseProc, device); if(!data->thread) - { -#if PA_CHECK_VERSION(0,9,15) - if(pa_stream_set_buffer_attr_callback) - pa_stream_set_buffer_attr_callback(data->stream, NULL, NULL); -#endif - pa_stream_disconnect(data->stream); - pa_stream_unref(data->stream); - data->stream = NULL; - - pa_threaded_mainloop_unlock(data->loop); return ALC_FALSE; - } - pa_threaded_mainloop_unlock(data->loop); return ALC_TRUE; } static void pulse_stop_playback(ALCdevice *device) { pulse_data *data = device->ExtraData; + pa_operation *o; if(!data->stream) return; @@ -1115,13 +1120,10 @@ static void pulse_stop_playback(ALCdevice *device) pa_threaded_mainloop_lock(data->loop); -#if PA_CHECK_VERSION(0,9,15) - if(pa_stream_set_buffer_attr_callback) - pa_stream_set_buffer_attr_callback(data->stream, NULL, NULL); -#endif - pa_stream_disconnect(data->stream); - pa_stream_unref(data->stream); - data->stream = NULL; + o = pa_stream_cork(data->stream, 1, stream_success_callback, device); + while(pa_operation_get_state(o) == PA_OPERATION_RUNNING) + pa_threaded_mainloop_wait(data->loop); + pa_operation_unref(o); pa_threaded_mainloop_unlock(data->loop); } @@ -1352,6 +1354,7 @@ static const BackendFuncs pulse_funcs = { pulse_open_playback, pulse_close_playback, pulse_reset_playback, + pulse_start_playback, pulse_stop_playback, pulse_open_capture, pulse_close_capture, diff --git a/Alc/backends/sndio.c b/Alc/backends/sndio.c index 6be98c2f..fc368951 100644 --- a/Alc/backends/sndio.c +++ b/Alc/backends/sndio.c @@ -280,13 +280,20 @@ static ALCboolean sndio_reset_playback(ALCdevice *device) SetDefaultChannelOrder(device); + return ALC_TRUE; +} + +static ALCboolean sndio_start_playback(ALCdevice *device) +{ + sndio_data *data = device->ExtraData; + if(!sio_start(data->sndHandle)) { ERR("Error starting playback\n"); return ALC_FALSE; } - data->data_size = device->UpdateSize * par.bps * par.pchan; + data->data_size = device->UpdateSize * FrameSizeFromDevFmt(device->FmtChans, device->FmtType); data->mix_data = calloc(1, data->data_size); data->thread = StartThread(sndio_proc, device); @@ -325,6 +332,7 @@ static const BackendFuncs sndio_funcs = { sndio_open_playback, sndio_close_playback, sndio_reset_playback, + sndio_start_playback, sndio_stop_playback, NULL, NULL, diff --git a/Alc/backends/solaris.c b/Alc/backends/solaris.c index bf0f57f5..26d923c7 100644 --- a/Alc/backends/solaris.c +++ b/Alc/backends/solaris.c @@ -193,11 +193,18 @@ static ALCboolean solaris_reset_playback(ALCdevice *device) device->Frequency = info.play.sample_rate; device->UpdateSize = (info.play.buffer_size/device->NumUpdates) + 1; - data->data_size = device->UpdateSize * frameSize; - data->mix_data = calloc(1, data->data_size); - SetDefaultChannelOrder(device); + return ALC_TRUE; +} + +static ALCboolean solaris_start_playback(ALCdevice *device) +{ + solaris_data *data = (solaris_data*)device->ExtraData; + + data->data_size = device->UpdateSize * FrameSizeFromDevFmt(device->FmtChans, device->FmtType); + data->mix_data = calloc(1, data->data_size); + data->thread = StartThread(SolarisProc, device); if(data->thread == NULL) { @@ -233,6 +240,7 @@ static const BackendFuncs solaris_funcs = { solaris_open_playback, solaris_close_playback, solaris_reset_playback, + solaris_start_playback, solaris_stop_playback, NULL, NULL, diff --git a/Alc/backends/wave.c b/Alc/backends/wave.c index ad187896..d9f1fdc7 100644 --- a/Alc/backends/wave.c +++ b/Alc/backends/wave.c @@ -258,10 +258,18 @@ static ALCboolean wave_reset_playback(ALCdevice *device) ERR("Error writing header: %s\n", strerror(errno)); return ALC_FALSE; } - data->DataStart = ftell(data->f); - data->size = device->UpdateSize * channels * bits / 8; + SetDefaultWFXChannelOrder(device); + + return ALC_TRUE; +} + +static ALCboolean wave_start_playback(ALCdevice *device) +{ + wave_data *data = (wave_data*)device->ExtraData; + + data->size = device->UpdateSize * FrameSizeFromDevFmt(device->FmtChans, device->FmtType); data->buffer = malloc(data->size); if(!data->buffer) { @@ -269,8 +277,6 @@ static ALCboolean wave_reset_playback(ALCdevice *device) return ALC_FALSE; } - SetDefaultWFXChannelOrder(device); - data->thread = StartThread(WaveProc, device); if(data->thread == NULL) { @@ -316,6 +322,7 @@ static const BackendFuncs wave_funcs = { wave_open_playback, wave_close_playback, wave_reset_playback, + wave_start_playback, wave_stop_playback, NULL, NULL, diff --git a/Alc/backends/winmm.c b/Alc/backends/winmm.c index 9f2c6316..57d27974 100644 --- a/Alc/backends/winmm.c +++ b/Alc/backends/winmm.c @@ -397,6 +397,21 @@ static void WinMMClosePlayback(ALCdevice *device) static ALCboolean WinMMResetPlayback(ALCdevice *device) { WinMMData *pData = (WinMMData*)device->ExtraData; + + device->UpdateSize = (ALuint)((ALuint64)device->UpdateSize * + pData->Frequency / device->Frequency); + device->UpdateSize = device->UpdateSize*device->NumUpdates / 4; + device->NumUpdates = 4; + device->Frequency = pData->Frequency; + + SetDefaultWFXChannelOrder(device); + + return ALC_TRUE; +} + +static ALCboolean WinMMStartPlayback(ALCdevice *device) +{ + WinMMData *pData = (WinMMData*)device->ExtraData; ALbyte *BufferData; ALint lBufferSize; ALuint i; @@ -405,12 +420,6 @@ static ALCboolean WinMMResetPlayback(ALCdevice *device) if(pData->hWaveThread == NULL) return ALC_FALSE; - device->UpdateSize = (ALuint)((ALuint64)device->UpdateSize * - pData->Frequency / device->Frequency); - device->Frequency = pData->Frequency; - - SetDefaultWFXChannelOrder(device); - pData->lWaveBuffersCommitted = 0; // Create 4 Buffers @@ -689,6 +698,7 @@ static const BackendFuncs WinMMFuncs = { WinMMOpenPlayback, WinMMClosePlayback, WinMMResetPlayback, + WinMMStartPlayback, WinMMStopPlayback, WinMMOpenCapture, WinMMCloseCapture, diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 2fbea8c3..20f6d656 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -449,6 +449,7 @@ typedef struct { ALCenum (*OpenPlayback)(ALCdevice*, const ALCchar*); void (*ClosePlayback)(ALCdevice*); ALCboolean (*ResetPlayback)(ALCdevice*); + ALCboolean (*StartPlayback)(ALCdevice*); void (*StopPlayback)(ALCdevice*); ALCenum (*OpenCapture)(ALCdevice*, const ALCchar*); @@ -630,6 +631,7 @@ struct ALCdevice_struct #define ALCdevice_OpenPlayback(a,b) ((a)->Funcs->OpenPlayback((a), (b))) #define ALCdevice_ClosePlayback(a) ((a)->Funcs->ClosePlayback((a))) #define ALCdevice_ResetPlayback(a) ((a)->Funcs->ResetPlayback((a))) +#define ALCdevice_StartPlayback(a) ((a)->Funcs->StartPlayback((a))) #define ALCdevice_StopPlayback(a) ((a)->Funcs->StopPlayback((a))) #define ALCdevice_OpenCapture(a,b) ((a)->Funcs->OpenCapture((a), (b))) #define ALCdevice_CloseCapture(a) ((a)->Funcs->CloseCapture((a))) |