From f58dbcdfedf4d5d78d586d54f507c647e58379c8 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Fri, 2 Dec 2022 14:41:30 +1100 Subject: [PATCH] dmime: Implement IDirectMusicSegment8 Download --- dlls/dmime/dmime_private.h | 2 + dlls/dmime/performance.c | 7 +++ dlls/dmime/segment.c | 87 ++++++++++++++++++++++++++++++++++++-- 3 files changed, 93 insertions(+), 3 deletions(-) diff --git a/dlls/dmime/dmime_private.h b/dlls/dmime/dmime_private.h index 4159abffa99..030aab50094 100644 --- a/dlls/dmime/dmime_private.h +++ b/dlls/dmime/dmime_private.h @@ -71,6 +71,8 @@ extern void set_audiopath_perf_pointer(IDirectMusicAudioPath*,IDirectMusicPerfor extern void set_audiopath_dsound_buffer(IDirectMusicAudioPath*,IDirectSoundBuffer*) DECLSPEC_HIDDEN; extern void set_audiopath_primary_dsound_buffer(IDirectMusicAudioPath*,IDirectSoundBuffer*) DECLSPEC_HIDDEN; +extern IDirectSound *get_dsound_interface(IDirectMusicPerformance8*) DECLSPEC_HIDDEN; + /***************************************************************************** * Auxiliary definitions */ diff --git a/dlls/dmime/performance.c b/dlls/dmime/performance.c index d69a27540d6..5578c3e523b 100644 --- a/dlls/dmime/performance.c +++ b/dlls/dmime/performance.c @@ -252,6 +252,13 @@ static inline IDirectMusicPerformance8Impl *impl_from_IDirectMusicPerformance8(I return CONTAINING_RECORD(iface, IDirectMusicPerformance8Impl, IDirectMusicPerformance8_iface); } +IDirectSound *get_dsound_interface(IDirectMusicPerformance8* iface) +{ + IDirectMusicPerformance8Impl *This = impl_from_IDirectMusicPerformance8(iface); + return This->dsound; +} + + /* IDirectMusicPerformance8 IUnknown part: */ static HRESULT WINAPI IDirectMusicPerformance8Impl_QueryInterface(IDirectMusicPerformance8 *iface, REFIID riid, void **ppv) diff --git a/dlls/dmime/segment.c b/dlls/dmime/segment.c index 6bf9f3abf0c..0ea0c15c5e0 100644 --- a/dlls/dmime/segment.c +++ b/dlls/dmime/segment.c @@ -37,6 +37,7 @@ typedef struct IDirectMusicSegment8Impl { PCMWAVEFORMAT wave_format; void *wave_data; int data_size; + IDirectSoundBuffer *buffer; } IDirectMusicSegment8Impl; IDirectMusicSegment8Impl *create_segment(void); @@ -90,6 +91,8 @@ static ULONG WINAPI IDirectMusicSegment8Impl_Release(IDirectMusicSegment8 *iface TRACE("(%p) ref=%ld\n", This, ref); if (!ref) { + if (This->buffer) + IDirectSoundBuffer_Release(This->buffer); if (This->wave_data) free(This->wave_data); @@ -559,9 +562,87 @@ static HRESULT WINAPI IDirectMusicSegment8Impl_Compose(IDirectMusicSegment8 *ifa static HRESULT WINAPI IDirectMusicSegment8Impl_Download(IDirectMusicSegment8 *iface, IUnknown *pAudioPath) { - IDirectMusicSegment8Impl *This = impl_from_IDirectMusicSegment8(iface); - FIXME("(%p, %p): stub\n", This, pAudioPath); - return S_OK; + IDirectMusicSegment8Impl *This = impl_from_IDirectMusicSegment8(iface); + IDirectMusicPerformance8 *perf; + IDirectMusicAudioPath *audio; + IDirectSound *dsound; + HRESULT hr; + DSBUFFERDESC dsbd = {.dwSize = sizeof(dsbd)}; + void *data; + DWORD size; + DWORD buffer = 0; + + TRACE("(%p, %p)\n", This, pAudioPath); + + if (!pAudioPath) + return E_INVALIDARG; + + if (This->buffer) + { + TRACE("Using Cached buffer\n"); + return S_OK; + } + + /* pAudioPath can either be IDirectMusicAudioPath or IDirectMusicPerformance */ + hr = IUnknown_QueryInterface(pAudioPath, &IID_IDirectMusicPerformance8, (void**)&perf); + if (FAILED(hr)) + { + TRACE("Checking for IDirectMusicAudioPath interface\n"); + hr = IUnknown_QueryInterface(pAudioPath, &IID_IDirectMusicAudioPath, (void**)&audio); + if (FAILED(hr)) + { + WARN("Cannot query for IDirectMusicAudioPath\n"); + return E_INVALIDARG; + } + + IDirectMusicAudioPath_GetObjectInPath(audio, DMUS_PCHANNEL_ALL, DMUS_PATH_PERFORMANCE, buffer, &GUID_NULL, + 0, &IID_IDirectMusicPerformance, (void**)&perf); + IDirectMusicAudioPath_Release(audio); + } + + if (!perf) + { + ERR("Failed to get IDirectMusicPerformance interface\n"); + return E_INVALIDARG; + } + + dsound = get_dsound_interface(perf); + if (!dsound) + { + ERR("Failed get_dsound_interface\n"); + return E_INVALIDARG; + } + + if (This->data_size == 0) + { + FIXME("No wave data skipping\n"); + return S_OK; + } + + dsbd.dwBufferBytes = This->data_size; + dsbd.lpwfxFormat = (WAVEFORMATEX*)&This->wave_format; + + hr = IDirectSound_CreateSoundBuffer(dsound, &dsbd, &This->buffer, NULL); + if (FAILED(hr)) + { + ERR("IDirectSound_CreateSoundBuffer failed 0x%08lx\n", hr); + return E_INVALIDARG; + } + + TRACE("CreateSoundBuffer successful\n"); + + hr = IDirectSoundBuffer_Lock(This->buffer, 0, This->data_size, &data, &size, NULL, 0, 0); + TRACE("IDirectSoundBuffer_Lock hr 0x%08lx\n", hr); + + memcpy(data, This->wave_data, This->data_size); + + hr = IDirectSoundBuffer_Unlock(This->buffer, data, This->data_size, NULL, 0); + TRACE("IDirectSoundBuffer_Unlock hr 0x%08lx\n", hr); + + /*hr = IDirectSoundBuffer_Play(This->buffer, 0, 0, 0); + TRACE("IDirectSoundBuffer_Play hr 0x%08lx\n", hr);*/ + + return S_OK; } static HRESULT WINAPI IDirectMusicSegment8Impl_Unload(IDirectMusicSegment8 *iface, -- 2.39.1