static HRESULT DSoundRender_SendSampleData(DSoundRenderImpl* This, const BYTE *data, DWORD size) { HRESULT hr = S_OK; LPBYTE lpbuf1 = NULL; LPBYTE lpbuf2 = NULL; DWORD dwsize1 = 0; DWORD dwsize2 = 0; DWORD size2; DWORD play_pos,buf_free; do { hr = DSoundRender_GetPos(This, &play_pos, NULL); if (hr != DS_OK) { ERR("GetPos returned error: %x\n", hr); break; } if (This->write_pos <= play_pos) buf_free = play_pos-This->write_pos; else buf_free = This->buf_size - This->write_pos + play_pos; /* Wait for enough of the buffer to empty before filling it */ if(buf_free < This->buf_size/4) { Sleep(50); continue; } size2 = min(buf_free, size); hr = IDirectSoundBuffer_Lock(This->dsbuffer, This->write_pos, size2, (LPVOID *)&lpbuf1, &dwsize1, (LPVOID *)&lpbuf2, &dwsize2, 0); if (hr != DS_OK) { ERR("Unable to lock sound buffer! (%x)\n", hr); break; } /* TRACE("write_pos=%d, size=%d, sz1=%d, sz2=%d\n", This->write_pos, size2, dwsize1, dwsize2); */ memcpy(lpbuf1, data, dwsize1); if (dwsize2) memcpy(lpbuf2, data + dwsize1, dwsize2); hr = IDirectSoundBuffer_Unlock(This->dsbuffer, lpbuf1, dwsize1, lpbuf2, dwsize2); if (hr != DS_OK) ERR("Unable to unlock sound buffer! (%x)\n", hr); size -= dwsize1 + dwsize2; data += dwsize1 + dwsize2; This->write_pos += dwsize1 + dwsize2; if (This->write_pos >= This->buf_size) { This->write_pos -= This->buf_size; This->write_loops++; } } while (size && This->state == State_Running); return hr; }
/*** IReferenceClock methods ***/ static HRESULT WINAPI ReferenceClock_GetTime(IReferenceClock *iface, REFERENCE_TIME *pTime) { ICOM_THIS_MULTI(DSoundRenderImpl, IReferenceClock_vtbl, iface); HRESULT hr = E_FAIL; DWORD play_pos; TRACE("(%p/%p)->(%p)\n", This, iface, pTime); if (This->dsbuffer) hr = DSoundRender_GetPos(This, &play_pos, pTime); if (FAILED(hr)) ERR("Could not get reference time (%x)!\n", hr); return hr; }
static HRESULT DSoundRender_SendSampleData(DSoundRenderImpl* This, const BYTE *data, DWORD size) { HRESULT hr = S_OK; LPBYTE lpbuf1 = NULL; LPBYTE lpbuf2 = NULL; DWORD dwsize1 = 0; DWORD dwsize2 = 0; DWORD size2; DWORD play_pos,buf_free; do { hr = DSoundRender_GetPos(This, &play_pos, NULL); if (hr != DS_OK) { ERR("GetPos returned error: %x\n", hr); break; } if (This->write_pos <= play_pos) buf_free = play_pos-This->write_pos; else buf_free = This->buf_size - This->write_pos + play_pos; /* Wait for enough of the buffer to empty before filling it */ if(buf_free < This->buf_size/20) { DWORD ret; This->in_loop = 1; LeaveCriticalSection(&This->filter.csFilter); ret = WaitForSingleObject(This->blocked, 50); if (ret != WAIT_TIMEOUT) ERR("%x\n", ret); EnterCriticalSection(&This->filter.csFilter); This->in_loop = 0; if (This->pInputPin->flushing) return VFW_E_WRONG_STATE; if (This->filter.state == State_Stopped) return VFW_E_WRONG_STATE; continue; } size2 = min(buf_free, size); hr = IDirectSoundBuffer_Lock(This->dsbuffer, This->write_pos, size2, (LPVOID *)&lpbuf1, &dwsize1, (LPVOID *)&lpbuf2, &dwsize2, 0); if (hr != DS_OK) { ERR("Unable to lock sound buffer! (%x)\n", hr); break; } /* TRACE("write_pos=%d, size=%d, sz1=%d, sz2=%d\n", This->write_pos, size2, dwsize1, dwsize2); */ memcpy(lpbuf1, data, dwsize1); if (dwsize2) memcpy(lpbuf2, data + dwsize1, dwsize2); hr = IDirectSoundBuffer_Unlock(This->dsbuffer, lpbuf1, dwsize1, lpbuf2, dwsize2); if (hr != DS_OK) ERR("Unable to unlock sound buffer! (%x)\n", hr); size -= dwsize1 + dwsize2; data += dwsize1 + dwsize2; This->write_pos += dwsize1 + dwsize2; if (This->write_pos >= This->buf_size) { This->write_pos -= This->buf_size; This->write_loops++; } } while (size && This->filter.state == State_Running); return hr; }