Module: wine Branch: master Commit: c6694e6dec9c9010d10ed7fe37526218b3a99302 URL: http://source.winehq.org/git/wine.git/?a=commit;h=c6694e6dec9c9010d10ed7fe37...
Author: Christian Costa titan.costa@gmail.com Date: Mon Dec 24 09:46:18 2012 +0100
dmusic: Implement SynthPortImpl_IDirectMusicPort_DownloadInstrument.
---
dlls/dmusic/dmusic_private.h | 2 + dlls/dmusic/port.c | 108 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 105 insertions(+), 5 deletions(-)
diff --git a/dlls/dmusic/dmusic_private.h b/dlls/dmusic/dmusic_private.h index 1872177..286b48b 100644 --- a/dlls/dmusic/dmusic_private.h +++ b/dlls/dmusic/dmusic_private.h @@ -140,6 +140,8 @@ struct IDirectMusicDownloadedInstrumentImpl { LONG ref;
/* IDirectMusicDownloadedInstrumentImpl fields */ + BOOL downloaded; + void *data; };
/***************************************************************************** diff --git a/dlls/dmusic/port.c b/dlls/dmusic/port.c index eb139ca..55d0dad 100644 --- a/dlls/dmusic/port.c +++ b/dlls/dmusic/port.c @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#include <assert.h> #include "dmusic_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(dmusic); @@ -82,7 +83,10 @@ static ULONG WINAPI IDirectMusicDownloadedInstrumentImpl_Release(LPDIRECTMUSICDO TRACE("(%p)->(): new ref = %u\n", iface, ref);
if (!ref) + { + HeapFree(GetProcessHeap(), 0, This->data); HeapFree(GetProcessHeap(), 0, This); + }
DMUSIC_UnlockModule();
@@ -95,11 +99,20 @@ static const IDirectMusicDownloadedInstrumentVtbl DirectMusicDownloadedInstrumen IDirectMusicDownloadedInstrumentImpl_Release };
+static inline IDirectMusicDownloadedInstrumentImpl* unsafe_impl_from_IDirectMusicDownloadedInstrument(IDirectMusicDownloadedInstrument *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == &DirectMusicDownloadedInstrument_Vtbl); + + return impl_from_IDirectMusicDownloadedInstrument(iface); +} + HRESULT DMUSIC_CreateDirectMusicDownloadedInstrumentImpl(IDirectMusicDownloadedInstrument **instrument) { IDirectMusicDownloadedInstrumentImpl *object;
- object = HeapAlloc(GetProcessHeap(), 0, sizeof(*object)); + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); if (!object) { *instrument = NULL; @@ -227,20 +240,105 @@ static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_Read(LPDIRECTMUSICPORT ifac static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_DownloadInstrument(LPDIRECTMUSICPORT iface, IDirectMusicInstrument* instrument, IDirectMusicDownloadedInstrument** downloaded_instrument, DMUS_NOTERANGE* note_ranges, DWORD num_note_ranges) { SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface); - - FIXME("(%p/%p)->(%p, %p, %p, %d): stub\n", iface, This, instrument, downloaded_instrument, note_ranges, num_note_ranges); + IDirectMusicInstrumentImpl *instrument_object; + HRESULT ret; + BOOL free; + HANDLE download; + DMUS_DOWNLOADINFO *info; + DMUS_OFFSETTABLE *offset_table; + DMUS_INSTRUMENT *instrument_info; + BYTE *data; + ULONG offset; + ULONG nb_regions; + ULONG size; + int i; + + TRACE("(%p/%p)->(%p, %p, %p, %d)\n", iface, This, instrument, downloaded_instrument, note_ranges, num_note_ranges);
if (!instrument || !downloaded_instrument || (num_note_ranges && !note_ranges)) return E_POINTER;
- return DMUSIC_CreateDirectMusicDownloadedInstrumentImpl(downloaded_instrument); + instrument_object = impl_from_IDirectMusicInstrument(instrument); + + nb_regions = instrument_object->header.cRegions; + size = sizeof(DMUS_DOWNLOADINFO) + sizeof(ULONG) * (1 + nb_regions) + sizeof(DMUS_INSTRUMENT) + sizeof(DMUS_REGION) * nb_regions; + + data = (BYTE*)HeapAlloc(GetProcessHeap(), 0, size); + if (!data) + return E_OUTOFMEMORY; + + info = (DMUS_DOWNLOADINFO*)data; + offset_table = (DMUS_OFFSETTABLE*)(data + sizeof(DMUS_DOWNLOADINFO)); + offset = sizeof(DMUS_DOWNLOADINFO) + sizeof(ULONG) * (1 + nb_regions); + + info->dwDLType = DMUS_DOWNLOADINFO_INSTRUMENT2; + info->dwDLId = 0; + info->dwNumOffsetTableEntries = 1 + instrument_object->header.cRegions; + info->cbSize = size; + + offset_table->ulOffsetTable[0] = offset; + instrument_info = (DMUS_INSTRUMENT*)(data + offset); + offset += sizeof(DMUS_INSTRUMENT); + instrument_info->ulPatch = MIDILOCALE2Patch(&instrument_object->header.Locale); + instrument_info->ulFirstRegionIdx = 1; + instrument_info->ulGlobalArtIdx = 0; /* FIXME */ + instrument_info->ulFirstExtCkIdx = 0; /* FIXME */ + instrument_info->ulCopyrightIdx = 0; /* FIXME */ + instrument_info->ulFlags = 0; /* FIXME */ + + for (i = 0; i < nb_regions; i++) + { + DMUS_REGION *region = (DMUS_REGION*)(data + offset); + + offset_table->ulOffsetTable[1 + i] = offset; + offset += sizeof(DMUS_REGION); + region->RangeKey = instrument_object->regions[i].header.RangeKey; + region->RangeVelocity = instrument_object->regions[i].header.RangeVelocity; + region->fusOptions = instrument_object->regions[i].header.fusOptions; + region->usKeyGroup = instrument_object->regions[i].header.usKeyGroup; + region->ulRegionArtIdx = 0; /* FIXME */ + region->ulNextRegionIdx = i != (nb_regions - 1) ? (i + 2) : 0; + region->ulFirstExtCkIdx = 0; /* FIXME */ + region->WaveLink = instrument_object->regions[i].wave_link; + region->WSMP = instrument_object->regions[i].wave_sample; + region->WLOOP[0] = instrument_object->regions[i].wave_loop; + } + + ret = IDirectMusicSynth8_Download(This->synth, &download, (VOID*)data, &free); + + if (SUCCEEDED(ret)) + ret = DMUSIC_CreateDirectMusicDownloadedInstrumentImpl(downloaded_instrument); + + if (SUCCEEDED(ret)) + { + IDirectMusicDownloadedInstrumentImpl *downloaded_object = impl_from_IDirectMusicDownloadedInstrument(*downloaded_instrument); + + downloaded_object->data = data; + downloaded_object->downloaded = TRUE; + } + + *downloaded_instrument = NULL; + HeapFree(GetProcessHeap(), 0, data); + + return E_FAIL; }
static HRESULT WINAPI SynthPortImpl_IDirectMusicPort_UnloadInstrument(LPDIRECTMUSICPORT iface, IDirectMusicDownloadedInstrument *downloaded_instrument) { SynthPortImpl *This = impl_from_SynthPortImpl_IDirectMusicPort(iface); + IDirectMusicDownloadedInstrumentImpl *downloaded_object = unsafe_impl_from_IDirectMusicDownloadedInstrument(downloaded_instrument); + + TRACE("(%p/%p)->(%p)\n", iface, This, downloaded_instrument); + + if (!downloaded_instrument) + return E_POINTER; + + if (!downloaded_object->downloaded) + return DMUS_E_NOT_DOWNLOADED_TO_PORT;
- FIXME("(%p/%p)->(%p): stub\n", iface, This, downloaded_instrument); + HeapFree(GetProcessHeap(), 0, downloaded_object->data); + downloaded_object->data = NULL; + downloaded_object->downloaded = FALSE;
return S_OK; }