From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=9027 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=34751 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45135 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48220 --- dlls/dmime/Makefile.in | 3 +- dlls/dmime/audiopath.c | 1 - dlls/dmime/dmime_main.c | 1 - dlls/dmime/dmime_private.h | 5 ++ dlls/dmime/graph.c | 1 - dlls/dmime/lyricstrack.c | 1 - dlls/dmime/markertrack.c | 1 - dlls/dmime/paramcontroltrack.c | 1 - dlls/dmime/performance.c | 1 - dlls/dmime/segment.c | 112 +++++++++++++-------------------- dlls/dmime/segmentstate.c | 1 - dlls/dmime/segtriggertrack.c | 1 - dlls/dmime/seqtrack.c | 1 - dlls/dmime/sysextrack.c | 1 - dlls/dmime/tempotrack.c | 1 - dlls/dmime/tests/dmime.c | 2 +- dlls/dmime/timesigtrack.c | 1 - dlls/dmime/wavetrack.c | 43 +++++++++++-- dlls/dmusic/dmusic_private.h | 1 + dlls/dmusic/wave.c | 7 +++ 20 files changed, 96 insertions(+), 90 deletions(-)
diff --git a/dlls/dmime/Makefile.in b/dlls/dmime/Makefile.in index ef4d0b9bee4..c60eb04d106 100644 --- a/dlls/dmime/Makefile.in +++ b/dlls/dmime/Makefile.in @@ -18,7 +18,8 @@ C_SRCS = \ sysextrack.c \ tempotrack.c \ timesigtrack.c \ - wavetrack.c + wavetrack.c \ + wave.c
IDL_SRCS = dmime.idl
diff --git a/dlls/dmime/audiopath.c b/dlls/dmime/audiopath.c index aef48a5d2db..3310624eb00 100644 --- a/dlls/dmime/audiopath.c +++ b/dlls/dmime/audiopath.c @@ -18,7 +18,6 @@ */
#include "dmime_private.h" -#include "dmobject.h"
WINE_DEFAULT_DEBUG_CHANNEL(dmime);
diff --git a/dlls/dmime/dmime_main.c b/dlls/dmime/dmime_main.c index c0aa4e31cfb..89e70bcd1bd 100644 --- a/dlls/dmime/dmime_main.c +++ b/dlls/dmime/dmime_main.c @@ -34,7 +34,6 @@ #include "dmusici.h"
#include "dmime_private.h" -#include "dmobject.h"
WINE_DEFAULT_DEBUG_CHANNEL(dmime);
diff --git a/dlls/dmime/dmime_private.h b/dlls/dmime/dmime_private.h index e67797def30..3a9e8d547c1 100644 --- a/dlls/dmime/dmime_private.h +++ b/dlls/dmime/dmime_private.h @@ -42,6 +42,8 @@ #include "dmusics.h" #include "dmusicc.h"
+#include "dmusic_private.h" + /***************************************************************************** * Interfaces */ @@ -75,6 +77,9 @@ extern HRESULT segment_state_create(IDirectMusicSegment *segment, MUSIC_TIME sta extern HRESULT segment_state_play(IDirectMusicSegmentState *iface, IDirectMusicPerformance *performance); extern HRESULT segment_state_end_play(IDirectMusicSegmentState *iface);
+extern HRESULT wave_track_create_from_chunk(IStream *stream, struct chunk_entry *parent, + IDirectMusicTrack8 **ret_iface); + /***************************************************************************** * Auxiliary definitions */ diff --git a/dlls/dmime/graph.c b/dlls/dmime/graph.c index d8f6bb88701..e0aa94833ae 100644 --- a/dlls/dmime/graph.c +++ b/dlls/dmime/graph.c @@ -18,7 +18,6 @@ */
#include "dmime_private.h" -#include "dmobject.h"
WINE_DEFAULT_DEBUG_CHANNEL(dmime);
diff --git a/dlls/dmime/lyricstrack.c b/dlls/dmime/lyricstrack.c index a1b299e9a7c..f7da1132867 100644 --- a/dlls/dmime/lyricstrack.c +++ b/dlls/dmime/lyricstrack.c @@ -18,7 +18,6 @@ */
#include "dmime_private.h" -#include "dmobject.h"
WINE_DEFAULT_DEBUG_CHANNEL(dmime);
diff --git a/dlls/dmime/markertrack.c b/dlls/dmime/markertrack.c index 460e708bc5d..8d36a4cdd01 100644 --- a/dlls/dmime/markertrack.c +++ b/dlls/dmime/markertrack.c @@ -18,7 +18,6 @@ */
#include "dmime_private.h" -#include "dmobject.h"
WINE_DEFAULT_DEBUG_CHANNEL(dmime);
diff --git a/dlls/dmime/paramcontroltrack.c b/dlls/dmime/paramcontroltrack.c index 9d32484bfd7..4abcf614c3a 100644 --- a/dlls/dmime/paramcontroltrack.c +++ b/dlls/dmime/paramcontroltrack.c @@ -18,7 +18,6 @@ */
#include "dmime_private.h" -#include "dmobject.h"
WINE_DEFAULT_DEBUG_CHANNEL(dmime);
diff --git a/dlls/dmime/performance.c b/dlls/dmime/performance.c index 7d077db16cb..327f7d88c3b 100644 --- a/dlls/dmime/performance.c +++ b/dlls/dmime/performance.c @@ -20,7 +20,6 @@
#include "dmime_private.h" #include "wine/rbtree.h" -#include "dmobject.h"
WINE_DEFAULT_DEBUG_CHANNEL(dmime);
diff --git a/dlls/dmime/segment.c b/dlls/dmime/segment.c index af7729f34b9..fc277ba73f9 100644 --- a/dlls/dmime/segment.c +++ b/dlls/dmime/segment.c @@ -19,7 +19,6 @@ */
#include "dmime_private.h" -#include "dmobject.h"
WINE_DEFAULT_DEBUG_CHANNEL(dmime);
@@ -742,13 +741,17 @@ static inline void dump_segment_header(DMUS_IO_SEGMENT_HEADER *h, DWORD size) } }
-static HRESULT parse_segment_form(struct segment *This, IStream *stream, const struct chunk_entry *riff) +static HRESULT parse_dmsg_chunk(struct segment *This, IStream *stream, const struct chunk_entry *riff) { struct chunk_entry chunk = {.parent = riff}; HRESULT hr;
TRACE("Parsing segment form in %p: %s\n", stream, debugstr_chunk(riff));
+ if (FAILED(hr = dmobj_parsedescriptor(stream, riff, &This->dmobj.desc, DMUS_OBJ_NAME | DMUS_OBJ_CATEGORY)) + || FAILED(hr = stream_reset_chunk_data(stream, riff))) + return hr; + while ((hr = stream_next_chunk(stream, &chunk)) == S_OK) { switch (chunk.id) { case DMUS_FOURCC_SEGMENT_CHUNK: @@ -787,89 +790,58 @@ static inline struct segment *impl_from_IPersistStream(IPersistStream *iface) return CONTAINING_RECORD(iface, struct segment, dmobj.IPersistStream_iface); }
-static HRESULT parse_wave_form(struct segment *This, IStream *stream, const struct chunk_entry *riff) +static HRESULT WINAPI segment_persist_stream_Load(IPersistStream *iface, IStream *stream) { + struct segment *This = impl_from_IPersistStream(iface); + struct chunk_entry chunk = {0}; HRESULT hr; - struct chunk_entry chunk = {.parent = riff};
- TRACE("Parsing segment wave in %p: %s\n", stream, debugstr_chunk(riff)); + TRACE("(%p, %p): Loading\n", This, stream);
- while ((hr = stream_next_chunk(stream, &chunk)) == S_OK) { - switch (chunk.id) { - case mmioFOURCC('f','m','t',' '): { - if (FAILED(hr = stream_chunk_get_data(stream, &chunk, &This->wave_format, - sizeof(This->wave_format))) ) - return hr; - TRACE("Wave Format tag %d\n", This->wave_format.wf.wFormatTag); - break; - } - case mmioFOURCC('d','a','t','a'): { - TRACE("Wave Data size %lu\n", chunk.size); - if (This->wave_data) - ERR("Multiple data streams detected\n"); - This->wave_data = malloc(chunk.size); - This->data_size = chunk.size; - if (!This->wave_data) - return E_OUTOFMEMORY; - if (FAILED(hr = stream_chunk_get_data(stream, &chunk, This->wave_data, chunk.size))) - return hr; - break; - } - case FOURCC_LIST: { - FIXME("Skipping LIST tag\n"); - break; - } - case mmioFOURCC('I','S','F','T'): { - FIXME("Skipping ISFT tag\n"); - break; - } - case mmioFOURCC('f','a','c','t'): { - FIXME("Skipping fact tag\n"); - break; - } - } - } + if (!stream) return E_POINTER;
- return SUCCEEDED(hr) ? S_OK : hr; -} + if ((hr = stream_get_chunk(stream, &chunk)) == S_OK) + { + switch (MAKE_IDTYPE(chunk.id, chunk.type)) + { + case MAKE_IDTYPE(FOURCC_RIFF, DMUS_FOURCC_SEGMENT_FORM): + hr = parse_dmsg_chunk(This, stream, &chunk); + break;
-static HRESULT WINAPI segment_persist_stream_Load(IPersistStream *iface, IStream *stream) -{ - struct segment *This = impl_from_IPersistStream(iface); - struct chunk_entry riff = {0}; - HRESULT hr; + case mmioFOURCC('M','T','h','d'): + FIXME("MIDI file loading not supported\n"); + break;
- TRACE("(%p, %p): Loading\n", This, stream); + case MAKE_IDTYPE(FOURCC_RIFF, mmioFOURCC('W','A','V','E')): + { + IDirectMusicTrack8 *track; + HRESULT hr;
- if (!stream) - return E_POINTER; + TRACE("Loading segment %p from wave file\n", This);
- if (stream_get_chunk(stream, &riff) != S_OK || - (riff.id != FOURCC_RIFF && riff.id != mmioFOURCC('M','T','h','d'))) - return DMUS_E_UNSUPPORTED_STREAM; - stream_reset_chunk_start(stream, &riff); + This->header.mtLength = 1; + if (FAILED(hr = wave_track_create_from_chunk(stream, &chunk, &track))) break; + hr = segment_append_track(This, (IDirectMusicTrack *)track, 1, 0); + break; + }
- if (riff.id == mmioFOURCC('M','T','h','d')) { - FIXME("MIDI file loading not supported\n"); - return S_OK; + default: + WARN("Invalid segment chunk %s %s\n", debugstr_fourcc(chunk.id), debugstr_fourcc(chunk.type)); + hr = DMUS_E_UNSUPPORTED_STREAM; + break; + } }
- hr = IDirectMusicObject_ParseDescriptor(&This->dmobj.IDirectMusicObject_iface, stream, - &This->dmobj.desc); if (FAILED(hr)) - return hr; - stream_reset_chunk_data(stream, &riff); - - if (riff.type == DMUS_FOURCC_SEGMENT_FORM) - hr = parse_segment_form(This, stream, &riff); - else if(riff.type == mmioFOURCC('W','A','V','E')) - hr = parse_wave_form(This, stream, &riff); - else { - FIXME("Unknown type %s\n", debugstr_chunk(&riff)); - hr = S_OK; + { + WARN("Failed to load segment from stream %p, hr %#lx\n", stream, hr); + return DMUS_E_UNSUPPORTED_STREAM; }
- return hr; + This->dmobj.desc.guidClass = CLSID_DirectMusicSegment; + This->dmobj.desc.dwValidData |= DMUS_OBJ_CLASS; + + return S_OK; }
static const IPersistStreamVtbl segment_persist_stream_vtbl = diff --git a/dlls/dmime/segmentstate.c b/dlls/dmime/segmentstate.c index de47d85e9b8..1cb9daac69a 100644 --- a/dlls/dmime/segmentstate.c +++ b/dlls/dmime/segmentstate.c @@ -17,7 +17,6 @@ */
#include "dmime_private.h" -#include "dmobject.h"
WINE_DEFAULT_DEBUG_CHANNEL(dmime);
diff --git a/dlls/dmime/segtriggertrack.c b/dlls/dmime/segtriggertrack.c index dc29ede4963..3f8e628b259 100644 --- a/dlls/dmime/segtriggertrack.c +++ b/dlls/dmime/segtriggertrack.c @@ -19,7 +19,6 @@ */
#include "dmime_private.h" -#include "dmobject.h"
WINE_DEFAULT_DEBUG_CHANNEL(dmime);
diff --git a/dlls/dmime/seqtrack.c b/dlls/dmime/seqtrack.c index ae2f002da92..21b78ff26cd 100644 --- a/dlls/dmime/seqtrack.c +++ b/dlls/dmime/seqtrack.c @@ -17,7 +17,6 @@ */
#include "dmime_private.h" -#include "dmobject.h"
WINE_DEFAULT_DEBUG_CHANNEL(dmime);
diff --git a/dlls/dmime/sysextrack.c b/dlls/dmime/sysextrack.c index f9c71abf08a..2c55d0dbe07 100644 --- a/dlls/dmime/sysextrack.c +++ b/dlls/dmime/sysextrack.c @@ -18,7 +18,6 @@ */
#include "dmime_private.h" -#include "dmobject.h"
WINE_DEFAULT_DEBUG_CHANNEL(dmime);
diff --git a/dlls/dmime/tempotrack.c b/dlls/dmime/tempotrack.c index 6704448b71e..07f410118fe 100644 --- a/dlls/dmime/tempotrack.c +++ b/dlls/dmime/tempotrack.c @@ -19,7 +19,6 @@ */
#include "dmime_private.h" -#include "dmobject.h"
WINE_DEFAULT_DEBUG_CHANNEL(dmime); WINE_DECLARE_DEBUG_CHANNEL(dmfile); diff --git a/dlls/dmime/tests/dmime.c b/dlls/dmime/tests/dmime.c index cb35ef64ead..8468ee50dda 100644 --- a/dlls/dmime/tests/dmime.c +++ b/dlls/dmime/tests/dmime.c @@ -3279,7 +3279,7 @@ static void test_wave_pmsg(void) length = 0xdeadbeef; hr = IDirectMusicSegment_GetLength(segment, &length); ok(hr == S_OK, "got %#lx\n", hr); - todo_wine ok(length == 1, "got %lu\n", length); + ok(length == 1, "got %lu\n", length);
/* without Download, no DMUS_PMSGT_WAVE is sent */ diff --git a/dlls/dmime/timesigtrack.c b/dlls/dmime/timesigtrack.c index e98807b7503..0ebf5e4256e 100644 --- a/dlls/dmime/timesigtrack.c +++ b/dlls/dmime/timesigtrack.c @@ -18,7 +18,6 @@ */
#include "dmime_private.h" -#include "dmobject.h"
WINE_DEFAULT_DEBUG_CHANNEL(dmime);
diff --git a/dlls/dmime/wavetrack.c b/dlls/dmime/wavetrack.c index 279cfb5c768..aa53fdfdffd 100644 --- a/dlls/dmime/wavetrack.c +++ b/dlls/dmime/wavetrack.c @@ -17,14 +17,13 @@ */
#include "dmime_private.h" -#include "dmobject.h"
WINE_DEFAULT_DEBUG_CHANNEL(dmime);
struct wave_item { struct list entry; DMUS_IO_WAVE_ITEM_HEADER header; - IDirectMusicObject *object; + IUnknown *object; };
struct wave_part { @@ -101,8 +100,7 @@ static ULONG WINAPI wave_track_Release(IDirectMusicTrack8 *iface) list_remove(&part->entry); LIST_FOR_EACH_ENTRY_SAFE(item, item2, &part->items, struct wave_item, entry) { list_remove(&item->entry); - if (item->object) - IDirectMusicObject_Release(item->object); + if (item->object) IUnknown_Release(item->object); free(item); } free(part); @@ -356,7 +354,7 @@ static HRESULT parse_wave_item(struct wave_part *part, IStream *stream, struct c hr = DMUS_E_UNSUPPORTED_STREAM; goto error; } - if (FAILED(hr = dmobj_parsereference(stream, &chunk, &item->object))) + if (FAILED(hr = dmobj_parsereference(stream, &chunk, (IDirectMusicObject **)&item->object))) goto error;
list_add_tail(&part->items, &item->entry); @@ -485,3 +483,38 @@ HRESULT create_dmwavetrack(REFIID lpcGUID, void **ppobj)
return hr; } + +HRESULT wave_track_create_from_chunk(IStream *stream, struct chunk_entry *parent, + IDirectMusicTrack8 **ret_iface) +{ + IDirectMusicTrack8 *iface; + struct wave_track *This; + struct wave_item *item; + struct wave_part *part; + HRESULT hr; + + if (FAILED(hr = create_dmwavetrack(&IID_IDirectMusicTrack8, (void **)&iface))) return hr; + This = impl_from_IDirectMusicTrack8(iface); + + if (!(part = calloc(1, sizeof(*part)))) + { + IDirectMusicTrack8_Release(iface); + return E_OUTOFMEMORY; + } + list_init(&part->items); + list_add_tail(&This->parts, &part->entry); + + if (!(item = calloc(1, sizeof(*item))) + || FAILED(hr = wave_create_from_chunk(stream, parent, &item->object))) + { + IDirectMusicTrack8_Release(iface); + free(item); + return hr; + } + if (FAILED(hr = wave_get_duration(item->object, &item->header.rtDuration))) + WARN("Failed to get wave duration, hr %#lx\n", hr); + list_add_tail(&part->items, &item->entry); + + *ret_iface = iface; + return S_OK; +} diff --git a/dlls/dmusic/dmusic_private.h b/dlls/dmusic/dmusic_private.h index 2317ffa57c6..0125634f7d6 100644 --- a/dlls/dmusic/dmusic_private.h +++ b/dlls/dmusic/dmusic_private.h @@ -103,6 +103,7 @@ extern HRESULT instrument_unload_from_port(IDirectMusicDownloadedInstrument *ifa extern HRESULT wave_create_from_soundfont(struct soundfont *soundfont, UINT index, IUnknown **out); 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); +extern HRESULT wave_get_duration(IUnknown *iface, REFERENCE_TIME *duration);
/***************************************************************************** * IDirectMusic8Impl implementation structure diff --git a/dlls/dmusic/wave.c b/dlls/dmusic/wave.c index 40a8c9e129f..2f5e1409106 100644 --- a/dlls/dmusic/wave.c +++ b/dlls/dmusic/wave.c @@ -338,3 +338,10 @@ HRESULT wave_download_to_port(IUnknown *iface, IDirectMusicPortDownload *port, D IDirectMusicDownload_Release(download); return hr; } + +HRESULT wave_get_duration(IUnknown *iface, REFERENCE_TIME *duration) +{ + struct wave *This = impl_from_IUnknown(iface); + *duration = (REFERENCE_TIME)This->data_size * 10000000 / This->format->nAvgBytesPerSec; + return S_OK; +}