From 6ae69b851f214a01ed96669406068b631c4b5be2 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 31 Jul 2011 14:04:44 -0700 Subject: [PATCH] Let stop notifies get triggered when the thread notices the buffer is stopped --- buffer.c | 86 +++++++++++++++------------------------------------------------ primary.c | 47 +++++++++++++++++++--------------- 2 files changed, 47 insertions(+), 86 deletions(-) diff --git a/buffer.c b/buffer.c index 2058205..def6342 100644 --- a/buffer.c +++ b/buffer.c @@ -80,34 +80,6 @@ static const IDirectSound3DBufferVtbl DS8Buffer3d_Vtbl; static const IDirectSoundNotifyVtbl DS8BufferNot_Vtbl; static const IKsPropertySetVtbl DS8BufferProp_Vtbl; -static void trigger_notifies(DS8Buffer *buf, DWORD lastpos, DWORD curpos) -{ - DWORD i; - for(i = 0;i < buf->nnotify;++i) - { - DSBPOSITIONNOTIFY *not = &buf->notify[i]; - HANDLE event = not->hEventNotify; - DWORD ofs = not->dwOffset; - - if(ofs == (DWORD)DSBPN_OFFSETSTOP) - { - SetEvent(event); - continue; - } - - /* Wraparound case */ - if(curpos < lastpos) - { - if(ofs < curpos || ofs >= lastpos) - SetEvent(event); - continue; - } - - /* Normal case */ - if(ofs >= lastpos && ofs < curpos) - SetEvent(event); - } -} static void CALLBACK DS8Buffer_timer(UINT timerID, UINT msg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2) @@ -173,19 +145,6 @@ static void DS8Buffer_addnotify(DS8Buffer *buf) buf->primary->notifies = list; } -static void DS8Buffer_removenotify(DS8Buffer *buf) -{ - DWORD i; - for(i = 0; i < buf->primary->nnotifies; ++i) - { - if(buf == buf->primary->notifies[i]) - { - buf->primary->notifies[i] = - buf->primary->notifies[--buf->primary->nnotifies]; - return; - } - } -} static const char *get_fmtstr_PCM(const DS8Primary *prim, const WAVEFORMATEX *format, WAVEFORMATEXTENSIBLE *out, ALenum *in_chans, ALenum *in_type) { @@ -738,21 +697,29 @@ fail: void DS8Buffer_Destroy(DS8Buffer *This) { + DS8Primary *prim = This->primary; DWORD idx; - TRACE("Destroying %p\n", This); - DS8Buffer_removenotify(This); + TRACE("Destroying %p\n", This); /* Remove from list, if in list */ - for(idx = 0;idx < This->primary->nbuffers;++idx) + for(idx = 0;idx < prim->nnotifies;++idx) { - if(This->primary->buffers[idx] == This) + if(This == prim->notifies[idx]) { - This->primary->buffers[idx] = This->primary->buffers[This->primary->nbuffers-1]; - This->primary->nbuffers--; + prim->notifies[idx] = prim->notifies[--prim->nnotifies]; break; } } + for(idx = 0;idx < prim->nbuffers;++idx) + { + if(prim->buffers[idx] == This) + { + prim->buffers[idx] = prim->buffers[--prim->nbuffers]; + break; + } + } + setALContext(This->ctx); if(This->source) { @@ -762,19 +729,19 @@ void DS8Buffer_Destroy(DS8Buffer *This) alSourcei(This->source, AL_BUFFER, 0); getALError(); - sources = This->primary->sources; - if(This->primary->nsources == This->primary->sizesources) + sources = prim->sources; + if(prim->nsources == prim->sizesources) { - sources = HeapReAlloc(GetProcessHeap(), 0, sources, sizeof(*sources)*(1+This->primary->nsources)); + sources = HeapReAlloc(GetProcessHeap(), 0, sources, sizeof(*sources)*(prim->nsources+1)); if(!sources) alDeleteSources(1, &This->source); else - This->primary->sizesources++; + prim->sizesources++; } if(sources) { - sources[This->primary->nsources++] = This->source; - This->primary->sources = sources; + sources[prim->nsources++] = This->source; + prim->sources = sources; } } HeapFree(GetProcessHeap(), 0, This->notify); @@ -1595,19 +1562,6 @@ static HRESULT WINAPI DS8Buffer_Stop(IDirectSoundBuffer8 *iface) Sleep(1); } while(1); - /* Stopped, remove from notify list */ - if(This->nnotify) - { - HRESULT hr; - DWORD pos = This->lastpos; - hr = IDirectSoundBuffer8_GetCurrentPosition(iface, &pos, NULL); - if(FAILED(hr)) - ERR("Own getcurrentposition failed!\n"); - trigger_notifies(This, This->lastpos, pos); - This->lastpos = pos; - DS8Buffer_removenotify(This); - } - This->isplaying = FALSE; popALContext(); diff --git a/primary.c b/primary.c index 0b21a6f..440c14f 100644 --- a/primary.c +++ b/primary.c @@ -74,7 +74,7 @@ static void AL_APIENTRY wrap_ProcessUpdates(void) { alcProcessContext(alcGetCurrentContext()); } -static void trigger_notifies(DS8Buffer *buf, DWORD lastpos, DWORD curpos) +static void trigger_elapsed_notifies(DS8Buffer *buf, DWORD lastpos, DWORD curpos) { DWORD i; for(i = 0; i < buf->nnotify; ++i) @@ -100,6 +100,17 @@ static void trigger_notifies(DS8Buffer *buf, DWORD lastpos, DWORD curpos) } } +static void trigger_stop_notifies(DS8Buffer *buf) +{ + DWORD i; + for(i = 0; i < buf->nnotify; ++i) + { + DSBPOSITIONNOTIFY *not = &buf->notify[i]; + if(not->dwOffset == (DWORD)DSBPN_OFFSETSTOP) + SetEvent(not->hEventNotify); + } +} + static DWORD CALLBACK ThreadProc(void *dwUser) { DS8Primary *prim = (DS8Primary*)dwUser; @@ -178,27 +189,23 @@ static DWORD CALLBACK ThreadProc(void *dwUser) { DS8Buffer *buf = prim->notifies[i]; IDirectSoundBuffer8 *dsb = &buf->IDirectSoundBuffer8_iface; - DWORD status, curpos; - HRESULT hr; + DWORD status=0, curpos=buf->lastpos; - hr = IDirectSoundBuffer8_GetStatus(dsb, &status); - if(SUCCEEDED(hr)) + IDirectSoundBuffer8_GetStatus(dsb, &status); + IDirectSoundBuffer8_GetCurrentPosition(dsb, &curpos, NULL); + if(buf->lastpos != curpos) { - if(!(status&DSBSTATUS_PLAYING)) - { - /* Stop will remove this buffer from list, - * and put another at the current position - * don't increment i - */ - IDirectSoundBuffer8_Stop(dsb); - continue; - } - hr = IDirectSoundBuffer8_GetCurrentPosition(dsb, &curpos, NULL); - if(SUCCEEDED(hr) && buf->lastpos != curpos) - { - trigger_notifies(buf, buf->lastpos, curpos); - buf->lastpos = curpos; - } + trigger_elapsed_notifies(buf, buf->lastpos, curpos); + buf->lastpos = curpos; + } + if(!(status&DSBSTATUS_PLAYING)) + { + /* Remove this buffer from list and put another at the + * current position; don't increment i + */ + trigger_stop_notifies(buf); + prim->notifies[i] = prim->notifies[--prim->nnotifies]; + continue; } i++; } -- 2.11.4.GIT