dmusic: Implement downloading wave to port.

This commit is contained in:
Rémi Bernon 2023-09-09 14:06:32 +02:00 committed by Alexandre Julliard
parent f54b0a5a9b
commit d32fb707ad
5 changed files with 100 additions and 3 deletions

View file

@ -72,6 +72,27 @@ extern void collection_internal_release(struct collection *collection)
free(collection);
}
extern HRESULT collection_get_wave(struct collection *collection, DWORD index, IUnknown **out)
{
struct wave_entry *wave_entry;
DWORD offset;
if (index >= collection->pool->table.cCues) return E_INVALIDARG;
offset = collection->pool->cues[index].ulOffset;
LIST_FOR_EACH_ENTRY(wave_entry, &collection->waves, struct wave_entry, entry)
{
if (offset == wave_entry->offset)
{
*out = wave_entry->wave;
IUnknown_AddRef(wave_entry->wave);
return S_OK;
}
}
return E_FAIL;
}
static inline struct collection *impl_from_IDirectMusicCollection(IDirectMusicCollection *iface)
{
return CONTAINING_RECORD(iface, struct collection, IDirectMusicCollection_iface);

View file

@ -79,6 +79,7 @@ typedef struct port_info {
struct collection;
extern void collection_internal_addref(struct collection *collection);
extern void collection_internal_release(struct collection *collection);
extern HRESULT collection_get_wave(struct collection *collection, DWORD index, IUnknown **out);
/* CLSID */
extern HRESULT music_create(IUnknown **ret_iface);
@ -97,6 +98,7 @@ extern HRESULT instrument_download_to_port(IDirectMusicInstrument *iface, IDirec
extern HRESULT instrument_unload_from_port(IDirectMusicDownloadedInstrument *iface, IDirectMusicPortDownload *port);
extern HRESULT wave_create_from_chunk(IStream *stream, struct chunk_entry *parent, IUnknown **out);
extern HRESULT wave_download_to_port(IUnknown *iface, IDirectMusicPortDownload *port, DWORD *id);
/*****************************************************************************
* IDirectMusic8Impl implementation structure

View file

@ -453,6 +453,7 @@ HRESULT instrument_download_to_port(IDirectMusicInstrument *iface, IDirectMusicP
IDirectMusicDownload *download;
DWORD size, offset_count;
struct region *region;
IUnknown *wave;
HRESULT hr;
if (This->download) goto done;
@ -509,6 +510,13 @@ HRESULT instrument_download_to_port(IDirectMusicInstrument *iface, IDirectMusicP
dmus_region->WaveLink = region->wave_link;
dmus_region->WSMP = region->wave_sample;
dmus_region->WLOOP[0] = region->wave_loop;
if (SUCCEEDED(hr = collection_get_wave(This->collection, region->wave_link.ulTableIndex, &wave)))
{
hr = wave_download_to_port(wave, port, &dmus_region->WaveLink.ulTableIndex);
IUnknown_Release(wave);
}
if (FAILED(hr)) goto failed;
}
if (FAILED(hr = IDirectMusicPortDownload_Download(port, download))) goto failed;
@ -530,12 +538,37 @@ failed:
HRESULT instrument_unload_from_port(IDirectMusicDownloadedInstrument *iface, IDirectMusicPortDownload *port)
{
struct instrument *This = impl_from_IDirectMusicDownloadedInstrument(iface);
struct download_buffer *buffer;
DWORD size;
HRESULT hr;
if (!This->download) return DMUS_E_NOT_DOWNLOADED_TO_PORT;
if (FAILED(hr = IDirectMusicPortDownload_Unload(port, This->download)))
WARN("Failed to unload instrument download buffer, hr %#lx\n", hr);
else if (SUCCEEDED(hr = IDirectMusicDownload_GetBuffer(This->download, (void **)&buffer, &size)))
{
IDirectMusicDownload *wave_download;
DMUS_INSTRUMENT *instrument;
BYTE *ptr = (BYTE *)buffer;
DMUS_REGION *region;
UINT index;
instrument = (DMUS_INSTRUMENT *)(ptr + buffer->offsets[0]);
for (index = instrument->ulFirstRegionIdx; index; index = region->ulNextRegionIdx)
{
region = (DMUS_REGION *)(ptr + buffer->offsets[index]);
if (FAILED(hr = IDirectMusicPortDownload_GetBuffer(port, region->WaveLink.ulTableIndex, &wave_download)))
WARN("Failed to get wave download with id %#lx, hr %#lx\n", region->WaveLink.ulTableIndex, hr);
else
{
if (FAILED(hr = IDirectMusicPortDownload_Unload(port, wave_download)))
WARN("Failed to unload wave download buffer, hr %#lx\n", hr);
IDirectMusicDownload_Release(wave_download);
}
}
}
IDirectMusicDownload_Release(This->download);
This->download = NULL;

View file

@ -1300,8 +1300,7 @@ static void test_download_instrument(void)
check_interface(instrument, &IID_IDirectMusicDownloadedInstrument, FALSE);
hr = IDirectMusicPort_DownloadInstrument(port, instrument, &downloaded, NULL, 0);
todo_wine ok(hr == S_OK, "got %#lx\n", hr);
if (hr != S_OK) goto skip_tests;
ok(hr == S_OK, "got %#lx\n", hr);
check_interface(downloaded, &IID_IDirectMusicObject, FALSE);
check_interface(downloaded, &IID_IDirectMusicDownload, FALSE);
@ -1313,7 +1312,6 @@ static void test_download_instrument(void)
IDirectMusicInstrument_Release(instrument);
skip_tests:
IDirectMusicCollection_Release(collection);
IDirectMusicPort_Release(port);
IDirectMusic_Release(dmusic);

View file

@ -212,3 +212,46 @@ HRESULT wave_create_from_chunk(IStream *stream, struct chunk_entry *parent, IUnk
*ret_iface = iface;
return S_OK;
}
HRESULT wave_download_to_port(IUnknown *iface, IDirectMusicPortDownload *port, DWORD *id)
{
struct download_buffer
{
DMUS_DOWNLOADINFO info;
ULONG offsets[2];
DMUS_WAVE wave;
DMUS_WAVEDATA data;
} *buffer;
struct wave *This = impl_from_IUnknown(iface);
DWORD size = offsetof(struct download_buffer, data.byData[This->data_size]);
IDirectMusicDownload *download;
HRESULT hr;
if (FAILED(hr = IDirectMusicPortDownload_AllocateBuffer(port, size, &download))) return hr;
if (SUCCEEDED(hr = IDirectMusicDownload_GetBuffer(download, (void **)&buffer, &size))
&& SUCCEEDED(hr = IDirectMusicPortDownload_GetDLId(port, &buffer->info.dwDLId, 1)))
{
buffer->info.dwDLType = DMUS_DOWNLOADINFO_WAVE;
buffer->info.dwNumOffsetTableEntries = 2;
buffer->info.cbSize = size;
buffer->offsets[0] = offsetof(struct download_buffer, wave);
buffer->offsets[1] = offsetof(struct download_buffer, data);
buffer->wave.WaveformatEx = *This->format;
buffer->wave.ulWaveDataIdx = 1;
buffer->wave.ulCopyrightIdx = 0;
buffer->wave.ulFirstExtCkIdx = 0;
buffer->data.cbSize = This->data_size;
memcpy(buffer->data.byData, This->data, This->data_size);
if (SUCCEEDED(hr = IDirectMusicPortDownload_Download(port, download))) *id = buffer->info.dwDLId;
else WARN("Failed to download wave to port, hr %#lx\n", hr);
}
IDirectMusicDownload_Release(download);
return hr;
}