mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-05 18:01:34 +00:00
dmusic: Implement downloading wave to port.
This commit is contained in:
parent
f54b0a5a9b
commit
d32fb707ad
5 changed files with 100 additions and 3 deletions
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue