From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dmusic/dmusic_private.h | 43 +-------- dlls/dmusic/instrument.c | 174 +++++++++++++++++++++++++++++++++++ dlls/dmusic/port.c | 172 +--------------------------------- 3 files changed, 180 insertions(+), 209 deletions(-)
diff --git a/dlls/dmusic/dmusic_private.h b/dlls/dmusic/dmusic_private.h index 31ff63a954d..2d195574b89 100644 --- a/dlls/dmusic/dmusic_private.h +++ b/dlls/dmusic/dmusic_private.h @@ -48,7 +48,6 @@ */ typedef struct IDirectMusic8Impl IDirectMusic8Impl; typedef struct IDirectMusicBufferImpl IDirectMusicBufferImpl; -typedef struct IDirectMusicDownloadedInstrumentImpl IDirectMusicDownloadedInstrumentImpl; typedef struct IReferenceClockImpl IReferenceClockImpl;
/***************************************************************************** @@ -73,16 +72,6 @@ typedef struct port_info { ULONG device; } port_info;
-struct region -{ - struct list entry; - RGNHEADER header; - WAVELINK wave_link; - WSMPL wave_sample; - WLOOP wave_loop; - BOOL loop_present; -}; - /***************************************************************************** * ClassFactory */ @@ -99,6 +88,9 @@ extern HRESULT download_create(DWORD size, IDirectMusicDownload **ret_iface);
extern HRESULT instrument_create_from_chunk(IStream *stream, struct chunk_entry *parent, DMUS_OBJECTDESC *desc, IDirectMusicInstrument **ret_iface); +extern HRESULT instrument_download_to_port(IDirectMusicInstrument *iface, IDirectMusicPortDownload *port, + IDirectMusicDownloadedInstrument **downloaded); +extern HRESULT instrument_unload_from_port(IDirectMusicDownloadedInstrument *iface, IDirectMusicPortDownload *port);
/***************************************************************************** * IDirectMusic8Impl implementation structure @@ -130,19 +122,6 @@ struct IDirectMusicBufferImpl { REFERENCE_TIME start_time; };
-/***************************************************************************** - * IDirectMusicDownloadedInstrumentImpl implementation structure - */ -struct IDirectMusicDownloadedInstrumentImpl { - /* IUnknown fields */ - IDirectMusicDownloadedInstrument IDirectMusicDownloadedInstrument_iface; - LONG ref; - - /* IDirectMusicDownloadedInstrumentImpl fields */ - BOOL downloaded; - void *data; -}; - /** Internal factory */ extern HRESULT synth_port_create(IDirectMusic8Impl *parent, DMUS_PORTPARAMS *port_params, DMUS_PORTCAPS *port_caps, IDirectMusicPort **port); @@ -168,22 +147,6 @@ typedef struct _DMUS_PRIVATE_POOLCUE { struct list entry; /* for listing elements */ } DMUS_PRIVATE_POOLCUE, *LPDMUS_PRIVATE_POOLCUE;
-struct instrument -{ - IDirectMusicInstrument IDirectMusicInstrument_iface; - LONG ref; - - INSTHEADER header; - - struct list articulations; - struct list regions; -}; - -static inline struct instrument *impl_from_IDirectMusicInstrument(IDirectMusicInstrument *iface) -{ - return CONTAINING_RECORD(iface, struct instrument, IDirectMusicInstrument_iface); -} - /***************************************************************************** * Misc. */ diff --git a/dlls/dmusic/instrument.c b/dlls/dmusic/instrument.c index 025bba940e5..24b3c0305f8 100644 --- a/dlls/dmusic/instrument.c +++ b/dlls/dmusic/instrument.c @@ -33,6 +33,33 @@ struct articulation
C_ASSERT(sizeof(struct articulation) == offsetof(struct articulation, connections[0]));
+struct region +{ + struct list entry; + RGNHEADER header; + WAVELINK wave_link; + WSMPL wave_sample; + WLOOP wave_loop; + BOOL loop_present; +}; + +struct instrument +{ + IDirectMusicInstrument IDirectMusicInstrument_iface; + IDirectMusicDownloadedInstrument IDirectMusicDownloadedInstrument_iface; + LONG ref; + + INSTHEADER header; + IDirectMusicDownload *download; + struct list articulations; + struct list regions; +}; + +static inline struct instrument *impl_from_IDirectMusicInstrument(IDirectMusicInstrument *iface) +{ + return CONTAINING_RECORD(iface, struct instrument, IDirectMusicInstrument_iface); +} + static HRESULT WINAPI instrument_QueryInterface(LPDIRECTMUSICINSTRUMENT iface, REFIID riid, LPVOID *ret_iface) { TRACE("(%p)->(%s, %p)\n", iface, debugstr_dmguid(riid), ret_iface); @@ -134,6 +161,46 @@ static const IDirectMusicInstrumentVtbl instrument_vtbl = instrument_SetPatch, };
+static inline struct instrument* impl_from_IDirectMusicDownloadedInstrument(IDirectMusicDownloadedInstrument *iface) +{ + return CONTAINING_RECORD(iface, struct instrument, IDirectMusicDownloadedInstrument_iface); +} + +static HRESULT WINAPI downloaded_instrument_QueryInterface(IDirectMusicDownloadedInstrument *iface, REFIID riid, VOID **ret_iface) +{ + TRACE("(%p, %s, %p)\n", iface, debugstr_dmguid(riid), ret_iface); + + if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDirectMusicDownloadedInstrument)) + { + IDirectMusicDownloadedInstrument_AddRef(iface); + *ret_iface = iface; + return S_OK; + } + + WARN("(%p, %s, %p): not found\n", iface, debugstr_dmguid(riid), ret_iface); + + return E_NOINTERFACE; +} + +static ULONG WINAPI downloaded_instrument_AddRef(IDirectMusicDownloadedInstrument *iface) +{ + struct instrument *This = impl_from_IDirectMusicDownloadedInstrument(iface); + return IDirectMusicInstrument_AddRef(&This->IDirectMusicInstrument_iface); +} + +static ULONG WINAPI downloaded_instrument_Release(IDirectMusicDownloadedInstrument *iface) +{ + struct instrument *This = impl_from_IDirectMusicDownloadedInstrument(iface); + return IDirectMusicInstrument_Release(&This->IDirectMusicInstrument_iface); +} + +static const IDirectMusicDownloadedInstrumentVtbl downloaded_instrument_vtbl = +{ + downloaded_instrument_QueryInterface, + downloaded_instrument_AddRef, + downloaded_instrument_Release, +}; + static HRESULT instrument_create(IDirectMusicInstrument **ret_iface) { struct instrument *instrument; @@ -141,6 +208,7 @@ static HRESULT instrument_create(IDirectMusicInstrument **ret_iface) *ret_iface = NULL; if (!(instrument = calloc(1, sizeof(*instrument)))) return E_OUTOFMEMORY; instrument->IDirectMusicInstrument_iface.lpVtbl = &instrument_vtbl; + instrument->IDirectMusicDownloadedInstrument_iface.lpVtbl = &downloaded_instrument_vtbl; instrument->ref = 1; list_init(&instrument->articulations); list_init(&instrument->regions); @@ -365,3 +433,109 @@ HRESULT instrument_create_from_chunk(IStream *stream, struct chunk_entry *parent *ret_iface = iface; return S_OK; } + +struct download_buffer +{ + DMUS_DOWNLOADINFO info; + ULONG offsets[]; +}; + +C_ASSERT(sizeof(struct download_buffer) == offsetof(struct download_buffer, offsets[0])); + +HRESULT instrument_download_to_port(IDirectMusicInstrument *iface, IDirectMusicPortDownload *port, + IDirectMusicDownloadedInstrument **downloaded) +{ + struct instrument *This = impl_from_IDirectMusicInstrument(iface); + struct download_buffer *buffer; + IDirectMusicDownload *download; + DWORD size, offset_count; + struct region *region; + HRESULT hr; + + if (This->download) goto done; + + size = sizeof(DMUS_DOWNLOADINFO); + size += sizeof(ULONG) + sizeof(DMUS_INSTRUMENT); + offset_count = 1; + + LIST_FOR_EACH_ENTRY(region, &This->regions, struct region, entry) + { + size += sizeof(ULONG) + sizeof(DMUS_REGION); + offset_count++; + } + + 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))) + { + BYTE *ptr = (BYTE *)&buffer->offsets[offset_count]; + DMUS_INSTRUMENT *dmus_instrument; + DMUS_REGION *dmus_region = NULL; + UINT index = 0; + + buffer->info.dwDLType = DMUS_DOWNLOADINFO_INSTRUMENT2; + buffer->info.dwNumOffsetTableEntries = offset_count; + buffer->info.cbSize = size; + + buffer->offsets[index++] = ptr - (BYTE *)buffer; + dmus_instrument = (DMUS_INSTRUMENT *)ptr; + ptr += sizeof(DMUS_INSTRUMENT); + + dmus_instrument->ulPatch = MIDILOCALE2Patch(&This->header.Locale); + dmus_instrument->ulFirstRegionIdx = 0; + dmus_instrument->ulCopyrightIdx = 0; + dmus_instrument->ulGlobalArtIdx = 0; + + LIST_FOR_EACH_ENTRY(region, &This->regions, struct region, entry) + { + if (dmus_region) dmus_region->ulNextRegionIdx = index; + else dmus_instrument->ulFirstRegionIdx = index; + + buffer->offsets[index++] = ptr - (BYTE *)buffer; + dmus_region = (DMUS_REGION *)ptr; + ptr += sizeof(DMUS_REGION); + + dmus_region->RangeKey = region->header.RangeKey; + dmus_region->RangeVelocity = region->header.RangeVelocity; + dmus_region->fusOptions = region->header.fusOptions; + dmus_region->usKeyGroup = region->header.usKeyGroup; + dmus_region->ulRegionArtIdx = 0; + dmus_region->ulNextRegionIdx = 0; + dmus_region->ulFirstExtCkIdx = 0; + dmus_region->WaveLink = region->wave_link; + dmus_region->WSMP = region->wave_sample; + dmus_region->WLOOP[0] = region->wave_loop; + } + + if (FAILED(hr = IDirectMusicPortDownload_Download(port, download))) goto failed; + } + + This->download = download; + +done: + *downloaded = &This->IDirectMusicDownloadedInstrument_iface; + IDirectMusicDownloadedInstrument_AddRef(*downloaded); + return S_OK; + +failed: + WARN("Failed to download instrument to port, hr %#lx\n", hr); + IDirectMusicDownload_Release(download); + return hr; +} + +HRESULT instrument_unload_from_port(IDirectMusicDownloadedInstrument *iface, IDirectMusicPortDownload *port) +{ + struct instrument *This = impl_from_IDirectMusicDownloadedInstrument(iface); + 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); + + IDirectMusicDownload_Release(This->download); + This->download = NULL; + + return hr; +} diff --git a/dlls/dmusic/port.c b/dlls/dmusic/port.c index 675cf05a003..b23a3f5d4dd 100644 --- a/dlls/dmusic/port.c +++ b/dlls/dmusic/port.c @@ -52,11 +52,6 @@ struct synth_port { DWORD next_dlid; };
-static inline IDirectMusicDownloadedInstrumentImpl* impl_from_IDirectMusicDownloadedInstrument(IDirectMusicDownloadedInstrument *iface) -{ - return CONTAINING_RECORD(iface, IDirectMusicDownloadedInstrumentImpl, IDirectMusicDownloadedInstrument_iface); -} - static inline struct synth_port *synth_from_IDirectMusicPort(IDirectMusicPort *iface) { return CONTAINING_RECORD(iface, struct synth_port, IDirectMusicPort_iface); @@ -77,83 +72,6 @@ static inline struct synth_port *synth_from_IKsControl(IKsControl *iface) return CONTAINING_RECORD(iface, struct synth_port, IKsControl_iface); }
-/* IDirectMusicDownloadedInstrument IUnknown part follows: */ -static HRESULT WINAPI IDirectMusicDownloadedInstrumentImpl_QueryInterface(IDirectMusicDownloadedInstrument *iface, REFIID riid, VOID **ret_iface) -{ - TRACE("(%p, %s, %p)\n", iface, debugstr_dmguid(riid), ret_iface); - - if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDirectMusicDownloadedInstrument)) - { - IDirectMusicDownloadedInstrument_AddRef(iface); - *ret_iface = iface; - return S_OK; - } - - WARN("(%p, %s, %p): not found\n", iface, debugstr_dmguid(riid), ret_iface); - - return E_NOINTERFACE; -} - -static ULONG WINAPI IDirectMusicDownloadedInstrumentImpl_AddRef(LPDIRECTMUSICDOWNLOADEDINSTRUMENT iface) -{ - IDirectMusicDownloadedInstrumentImpl *This = impl_from_IDirectMusicDownloadedInstrument(iface); - ULONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p): new ref = %lu\n", iface, ref); - - return ref; -} - -static ULONG WINAPI IDirectMusicDownloadedInstrumentImpl_Release(LPDIRECTMUSICDOWNLOADEDINSTRUMENT iface) -{ - IDirectMusicDownloadedInstrumentImpl *This = impl_from_IDirectMusicDownloadedInstrument(iface); - ULONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p): new ref = %lu\n", iface, ref); - - if (!ref) - { - free(This->data); - free(This); - } - - return ref; -} - -static const IDirectMusicDownloadedInstrumentVtbl DirectMusicDownloadedInstrument_Vtbl = { - IDirectMusicDownloadedInstrumentImpl_QueryInterface, - IDirectMusicDownloadedInstrumentImpl_AddRef, - 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); -} - -static HRESULT DMUSIC_CreateDirectMusicDownloadedInstrumentImpl(IDirectMusicDownloadedInstrument **instrument) -{ - IDirectMusicDownloadedInstrumentImpl *object; - - object = calloc(1, sizeof(*object)); - if (!object) - { - *instrument = NULL; - return E_OUTOFMEMORY; - } - - object->IDirectMusicDownloadedInstrument_iface.lpVtbl = &DirectMusicDownloadedInstrument_Vtbl; - object->ref = 1; - - *instrument = &object->IDirectMusicDownloadedInstrument_iface; - - return S_OK; -} - static HRESULT WINAPI synth_port_QueryInterface(IDirectMusicPort *iface, REFIID riid, void **ret_iface) { struct synth_port *This = synth_from_IDirectMusicPort(iface); @@ -265,110 +183,26 @@ static HRESULT WINAPI synth_port_DownloadInstrument(IDirectMusicPort *iface, IDi IDirectMusicDownloadedInstrument **downloaded_instrument, DMUS_NOTERANGE *note_ranges, DWORD num_note_ranges) { struct synth_port *This = synth_from_IDirectMusicPort(iface); - struct instrument *instrument_object; - struct region *instrument_region; - HRESULT ret; - BOOL on_heap; - HANDLE download; - DMUS_DOWNLOADINFO *info; - DMUS_OFFSETTABLE *offset_table; - DMUS_INSTRUMENT *instrument_info; - BYTE *data; - ULONG offset; - ULONG nb_regions; - ULONG size; - ULONG i;
TRACE("(%p, %p, %p, %p, %ld)\n", iface, instrument, downloaded_instrument, note_ranges, num_note_ranges);
if (!instrument || !downloaded_instrument || (num_note_ranges && !note_ranges)) return E_POINTER;
- 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 = malloc(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 */ - - i = 0; - LIST_FOR_EACH_ENTRY(instrument_region, &instrument_object->regions, struct region, entry) - { - DMUS_REGION *region = (DMUS_REGION*)(data + offset); - - offset_table->ulOffsetTable[1 + i] = offset; - offset += sizeof(DMUS_REGION); - region->RangeKey = instrument_region->header.RangeKey; - region->RangeVelocity = instrument_region->header.RangeVelocity; - region->fusOptions = instrument_region->header.fusOptions; - region->usKeyGroup = instrument_region->header.usKeyGroup; - region->ulRegionArtIdx = 0; /* FIXME */ - region->ulNextRegionIdx = i != (nb_regions - 1) ? (i + 2) : 0; - region->ulFirstExtCkIdx = 0; /* FIXME */ - region->WaveLink = instrument_region->wave_link; - region->WSMP = instrument_region->wave_sample; - region->WLOOP[0] = instrument_region->wave_loop; - i++; - } - - ret = IDirectMusicSynth8_Download(This->synth, &download, (void*)data, &on_heap); - - 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; - free(data); - - return E_FAIL; + return instrument_download_to_port(instrument, &This->IDirectMusicPortDownload_iface, downloaded_instrument); }
static HRESULT WINAPI synth_port_UnloadInstrument(IDirectMusicPort *iface, IDirectMusicDownloadedInstrument *downloaded_instrument) { - IDirectMusicDownloadedInstrumentImpl *downloaded_object = unsafe_impl_from_IDirectMusicDownloadedInstrument(downloaded_instrument); + struct synth_port *This = synth_from_IDirectMusicPort(iface);
TRACE("(%p, %p)\n", iface, downloaded_instrument);
if (!downloaded_instrument) return E_POINTER;
- if (!downloaded_object->downloaded) - return DMUS_E_NOT_DOWNLOADED_TO_PORT; - - free(downloaded_object->data); - downloaded_object->data = NULL; - downloaded_object->downloaded = FALSE; - - return S_OK; + return instrument_unload_from_port(downloaded_instrument, &This->IDirectMusicPortDownload_iface); }
static HRESULT WINAPI synth_port_GetLatencyClock(IDirectMusicPort *iface, IReferenceClock **clock)