mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-15 07:28:47 +00:00
sapi: Implement ISpMMSysAudio::Write.
This commit is contained in:
parent
7bced2878a
commit
ef730b6e41
|
@ -400,9 +400,58 @@ static HRESULT WINAPI mmsysaudio_Read(ISpMMSysAudio *iface, void *pv, ULONG cb,
|
|||
|
||||
static HRESULT WINAPI mmsysaudio_Write(ISpMMSysAudio *iface, const void *pv, ULONG cb, ULONG *cb_written)
|
||||
{
|
||||
FIXME("(%p, %p, %lu, %p): stub.\n", iface, pv, cb, cb_written);
|
||||
struct mmaudio *This = impl_from_ISpMMSysAudio(iface);
|
||||
HRESULT hr = S_OK;
|
||||
WAVEHDR *buf;
|
||||
|
||||
return E_NOTIMPL;
|
||||
TRACE("(%p, %p, %lu, %p).\n", iface, pv, cb, cb_written);
|
||||
|
||||
if (This->flow != FLOW_OUT)
|
||||
return STG_E_ACCESSDENIED;
|
||||
|
||||
if (cb_written)
|
||||
*cb_written = 0;
|
||||
|
||||
EnterCriticalSection(&This->cs);
|
||||
|
||||
if (This->state == SPAS_CLOSED || This->state == SPAS_STOP)
|
||||
{
|
||||
LeaveCriticalSection(&This->cs);
|
||||
return SP_AUDIO_STOPPED;
|
||||
}
|
||||
|
||||
if (!(buf = heap_alloc(sizeof(WAVEHDR) + cb)))
|
||||
{
|
||||
LeaveCriticalSection(&This->cs);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
memcpy((char *)(buf + 1), pv, cb);
|
||||
buf->lpData = (char *)(buf + 1);
|
||||
buf->dwBufferLength = cb;
|
||||
buf->dwFlags = 0;
|
||||
|
||||
if (waveOutPrepareHeader(This->hwave.out, buf, sizeof(WAVEHDR)) != MMSYSERR_NOERROR)
|
||||
{
|
||||
LeaveCriticalSection(&This->cs);
|
||||
heap_free(buf);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
waveOutWrite(This->hwave.out, buf, sizeof(WAVEHDR));
|
||||
|
||||
EnterCriticalSection(&This->pending_cs);
|
||||
++This->pending_buf_count;
|
||||
TRACE("pending_buf_count = %Iu\n", This->pending_buf_count);
|
||||
LeaveCriticalSection(&This->pending_cs);
|
||||
|
||||
ResetEvent(This->event);
|
||||
|
||||
LeaveCriticalSection(&This->cs);
|
||||
|
||||
if (cb_written)
|
||||
*cb_written = cb;
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI mmsysaudio_Seek(ISpMMSysAudio *iface, LARGE_INTEGER move, DWORD origin, ULARGE_INTEGER *new_pos)
|
||||
|
|
|
@ -163,7 +163,10 @@ static void test_audio_out(void)
|
|||
ISpMMSysAudio *mmaudio;
|
||||
GUID fmtid;
|
||||
WAVEFORMATEX *wfx = NULL;
|
||||
WAVEFORMATEX wfx2;
|
||||
UINT devid;
|
||||
char *buf = NULL;
|
||||
ULONG written;
|
||||
HRESULT hr;
|
||||
|
||||
if (waveOutGetNumDevs() == 0) {
|
||||
|
@ -182,6 +185,8 @@ static void test_audio_out(void)
|
|||
ok(hr == S_OK, "got %#lx.\n", hr);
|
||||
ok(IsEqualGUID(&fmtid, &SPDFID_WaveFormatEx), "got %s.\n", wine_dbgstr_guid(&fmtid));
|
||||
ok(wfx != NULL, "wfx == NULL.\n");
|
||||
ok(wfx->wFormatTag == WAVE_FORMAT_PCM, "got %u.\n", wfx->wFormatTag);
|
||||
ok(wfx->cbSize == 0, "got %u.\n", wfx->cbSize);
|
||||
|
||||
hr = ISpMMSysAudio_SetFormat(mmaudio, &fmtid, wfx);
|
||||
ok(hr == S_OK, "got %#lx.\n", hr);
|
||||
|
@ -201,10 +206,12 @@ static void test_audio_out(void)
|
|||
hr = ISpMMSysAudio_SetFormat(mmaudio, &fmtid, wfx);
|
||||
ok(hr == S_OK, "got %#lx.\n", hr);
|
||||
|
||||
wfx->nChannels = wfx->nChannels == 1 ? 2 : 1;
|
||||
wfx->nAvgBytesPerSec = wfx->nSamplesPerSec * wfx->nChannels * wfx->wBitsPerSample / 8;
|
||||
wfx->nBlockAlign = wfx->nChannels * wfx->wBitsPerSample / 8;
|
||||
hr = ISpMMSysAudio_SetFormat(mmaudio, &fmtid, wfx);
|
||||
memcpy(&wfx2, wfx, sizeof(wfx2));
|
||||
wfx2.nChannels = wfx->nChannels == 1 ? 2 : 1;
|
||||
wfx2.nAvgBytesPerSec = wfx2.nSamplesPerSec * wfx2.nChannels * wfx2.wBitsPerSample / 8;
|
||||
wfx2.nBlockAlign = wfx2.nChannels * wfx2.wBitsPerSample / 8;
|
||||
|
||||
hr = ISpMMSysAudio_SetFormat(mmaudio, &fmtid, &wfx2);
|
||||
ok(hr == SPERR_DEVICE_BUSY, "got %#lx.\n", hr);
|
||||
|
||||
devid = 0xdeadbeef;
|
||||
|
@ -215,7 +222,47 @@ static void test_audio_out(void)
|
|||
hr = ISpMMSysAudio_SetState(mmaudio, SPAS_CLOSED, 0);
|
||||
ok(hr == S_OK, "got %#lx.\n", hr);
|
||||
|
||||
buf = calloc(1, wfx->nAvgBytesPerSec);
|
||||
ok(buf != NULL, "failed to allocate buffer.\n");
|
||||
|
||||
hr = ISpMMSysAudio_Write(mmaudio, buf, wfx->nAvgBytesPerSec, NULL);
|
||||
ok(hr == SP_AUDIO_STOPPED, "got %#lx.\n", hr);
|
||||
|
||||
hr = ISpMMSysAudio_SetState(mmaudio, SPAS_STOP, 0);
|
||||
todo_wine ok(hr == S_OK, "got %#lx.\n", hr);
|
||||
if (hr == S_OK)
|
||||
{
|
||||
hr = ISpMMSysAudio_Write(mmaudio, buf, wfx->nAvgBytesPerSec, NULL);
|
||||
ok(hr == SP_AUDIO_STOPPED, "got %#lx.\n", hr);
|
||||
}
|
||||
|
||||
hr = ISpMMSysAudio_SetState(mmaudio, SPAS_CLOSED, 0);
|
||||
ok(hr == S_OK, "got %#lx.\n", hr);
|
||||
|
||||
hr = ISpMMSysAudio_SetState(mmaudio, SPAS_RUN, 0);
|
||||
ok(hr == S_OK, "got %#lx.\n", hr);
|
||||
|
||||
hr = ISpMMSysAudio_Write(mmaudio, buf, wfx->nAvgBytesPerSec, NULL);
|
||||
ok(hr == S_OK, "got %#lx.\n", hr);
|
||||
|
||||
Sleep(200);
|
||||
|
||||
hr = ISpMMSysAudio_SetState(mmaudio, SPAS_CLOSED, 0);
|
||||
ok(hr == S_OK, "got %#lx.\n", hr);
|
||||
|
||||
hr = ISpMMSysAudio_SetState(mmaudio, SPAS_RUN, 0);
|
||||
ok(hr == S_OK, "got %#lx.\n", hr);
|
||||
|
||||
written = 0xdeadbeef;
|
||||
hr = ISpMMSysAudio_Write(mmaudio, buf, wfx->nAvgBytesPerSec * 200 / 1000, &written);
|
||||
ok(hr == S_OK, "got %#lx.\n", hr);
|
||||
ok(written == wfx->nAvgBytesPerSec * 200 / 1000, "got %lu.\n", written);
|
||||
|
||||
hr = ISpMMSysAudio_SetState(mmaudio, SPAS_CLOSED, 0);
|
||||
ok(hr == S_OK, "got %#lx.\n", hr);
|
||||
|
||||
CoTaskMemFree(wfx);
|
||||
free(buf);
|
||||
ISpMMSysAudio_Release(mmaudio);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue