Christian Costa : dmusic: Implement SynthPortImpl_IDirectMusicPort_DownloadInstrument.

Alexandre Julliard julliard at winehq.org
Mon Dec 24 14:03:04 CST 2012


Module: wine
Branch: master
Commit: c6694e6dec9c9010d10ed7fe37526218b3a99302
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=c6694e6dec9c9010d10ed7fe37526218b3a99302

Author: Christian Costa <titan.costa at 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;
 }




More information about the wine-cvs mailing list