wine-staging/patches/dmime-load-wave/0002-dmime-Implement-IDirectMusicSegment8-Download.patch
2023-09-20 08:16:07 +10:00

151 lines
4.9 KiB
Diff

From cdbd2714d5454e6518b699e3cdbedd3e0a1243c5 Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
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 | 80 +++++++++++++++++++++++++++++++++++++-
3 files changed, 88 insertions(+), 1 deletion(-)
diff --git a/dlls/dmime/dmime_private.h b/dlls/dmime/dmime_private.h
index eacde4b46be..cd34378b66e 100644
--- a/dlls/dmime/dmime_private.h
+++ b/dlls/dmime/dmime_private.h
@@ -70,6 +70,8 @@ extern void set_audiopath_perf_pointer(IDirectMusicAudioPath*,IDirectMusicPerfor
extern void set_audiopath_dsound_buffer(IDirectMusicAudioPath*,IDirectSoundBuffer*);
extern void set_audiopath_primary_dsound_buffer(IDirectMusicAudioPath*,IDirectSoundBuffer*);
+extern IDirectSound *get_dsound_interface(IDirectMusicPerformance8*);
+
/*****************************************************************************
* Auxiliary definitions
*/
diff --git a/dlls/dmime/performance.c b/dlls/dmime/performance.c
index d8624427423..a707de39d50 100644
--- a/dlls/dmime/performance.c
+++ b/dlls/dmime/performance.c
@@ -251,6 +251,13 @@ static inline struct performance *impl_from_IDirectMusicPerformance8(IDirectMusi
return CONTAINING_RECORD(iface, struct performance, IDirectMusicPerformance8_iface);
}
+IDirectSound *get_dsound_interface(IDirectMusicPerformance8* iface)
+{
+ struct performance *This = impl_from_IDirectMusicPerformance8(iface);
+ return This->dsound;
+}
+
+
/* IDirectMusicPerformance8 IUnknown part: */
static HRESULT WINAPI performance_QueryInterface(IDirectMusicPerformance8 *iface, REFIID riid, void **ret_iface)
{
diff --git a/dlls/dmime/segment.c b/dlls/dmime/segment.c
index a72ec786623..ebee90eee92 100644
--- a/dlls/dmime/segment.c
+++ b/dlls/dmime/segment.c
@@ -54,6 +54,7 @@ struct segment
PCMWAVEFORMAT wave_format;
void *wave_data;
int data_size;
+ IDirectSoundBuffer *buffer;
};
static struct segment *segment_create(void);
@@ -114,6 +115,8 @@ static ULONG WINAPI segment_Release(IDirectMusicSegment8 *iface)
track_entry_destroy(entry);
}
+ if (This->buffer)
+ IDirectSoundBuffer_Release(This->buffer);
if (This->wave_data)
free(This->wave_data);
@@ -517,7 +520,82 @@ static HRESULT WINAPI segment_Compose(IDirectMusicSegment8 *iface, MUSIC_TIME mt
static HRESULT WINAPI segment_Download(IDirectMusicSegment8 *iface, IUnknown *pAudioPath)
{
struct segment *This = impl_from_IDirectMusicSegment8(iface);
- FIXME("(%p, %p): stub\n", This, pAudioPath);
+ 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);
+
return S_OK;
}
--
2.40.1