From: Yuxuan Shui yshui@codeweavers.com
So that instrument downloading etc. could work. --- dlls/dmime/Makefile.in | 1 + dlls/dmime/midi.c | 73 ++++++++++++++++++++++++++++++++++++++++++ dlls/dmime/segment.c | 2 ++ dlls/dmusic/band.c | 16 +++++++++ dlls/dmusic/band.h | 1 + 5 files changed, 93 insertions(+)
diff --git a/dlls/dmime/Makefile.in b/dlls/dmime/Makefile.in index f8f622f8f3d..0f7b7db609e 100644 --- a/dlls/dmime/Makefile.in +++ b/dlls/dmime/Makefile.in @@ -4,6 +4,7 @@ PARENTSRC = ../dmusic
SOURCES = \ audiopath.c \ + band.c \ dmime.idl \ dmime_main.c \ dmobject.c \ diff --git a/dlls/dmime/midi.c b/dlls/dmime/midi.c index a0eed2f0d3b..670d85deb4e 100644 --- a/dlls/dmime/midi.c +++ b/dlls/dmime/midi.c @@ -17,6 +17,7 @@ */
#include "dmime_private.h" +#include "band.h"
WINE_DEFAULT_DEBUG_CHANNEL(dmime);
@@ -662,15 +663,87 @@ struct midi_parser { IStream *stream; DWORD division; + BOOL bandtrack_created; WORD number_of_tracks, current_track; };
+static HRESULT create_midi_bandtrack(IStream *stream, IDirectMusicTrack **track) +{ + DMUS_OBJECTDESC default_desc = + { + .dwSize = sizeof(DMUS_OBJECTDESC), + .dwValidData = DMUS_OBJ_OBJECT | DMUS_OBJ_CLASS, + .guidClass = CLSID_DirectMusicCollection, + .guidObject = GUID_DefaultGMCollection, + }; + HRESULT hr; + int i; + IDirectMusicTrack *bandtrack = NULL; + IDirectMusicBand *band = NULL; + IDirectMusicCollection *collection = NULL; + DMUS_BAND_PARAM bandparam; + + hr = stream_get_object(stream, &default_desc, &IID_IDirectMusicCollection, + (void **)&collection); + if (FAILED(hr)) + WARN("Failed to load default collection from loader, hr %#lx\n", hr); + + hr = CoCreateInstance(&CLSID_DirectMusicBandTrack, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectMusicTrack, (void **)&bandtrack); + if (FAILED(hr)) + return hr; + + hr = create_dmband(&IID_IDirectMusicBand, (void **)&band); + if (FAILED(hr)) + goto out; + for (i = 0; i < 128; i++) + { + hr = band_add_instrument(band, i, 0); + if (FAILED(hr)) + break; + } + if (FAILED(hr)) + goto out; + if (collection) + { + hr = band_connect_to_collection(band, collection); + if (FAILED(hr)) + WARN("Failed to connect band to default collection, hr %#lx\n", hr); + } + + bandparam.mtTimePhysical = 0; + bandparam.pBand = band; + hr = IDirectMusicTrack_SetParam(bandtrack, &GUID_BandParam, 0, &bandparam); + if (FAILED(hr)) + goto out; + + *track = bandtrack; + IDirectMusicTrack_AddRef(bandtrack); + +out: + IDirectMusicTrack_Release(bandtrack); + if (collection) + IDirectMusicCollection_Release(collection); + if (band) + IDirectMusicBand_Release(band); + return hr; +} + + HRESULT midi_parser_next_track(struct midi_parser *parser, IDirectMusicTrack **out_track, MUSIC_TIME *out_length) { IPersistStream *pstream; HRESULT hr; MUSIC_TIME midi_length;
+ if (!parser->bandtrack_created) + { + hr = create_midi_bandtrack(parser->stream, out_track); + if (FAILED(hr)) return hr; + parser->bandtrack_created = TRUE; + *out_length = 0; + return S_OK; + } + if (parser->current_track >= parser->number_of_tracks) return S_FALSE;
hr = create_midiseqtrack(&IID_IPersistStream, (void **)&pstream, parser->division); diff --git a/dlls/dmime/segment.c b/dlls/dmime/segment.c index c37e76b91cb..49e11cc77e5 100644 --- a/dlls/dmime/segment.c +++ b/dlls/dmime/segment.c @@ -17,7 +17,9 @@ * License along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ + #include "dmime_private.h" +#include "band.h"
#ifdef WORDS_BIGENDIAN #define GET_BE_WORD(x) (x) diff --git a/dlls/dmusic/band.c b/dlls/dmusic/band.c index 2fdee5701b4..e5aebc0e46b 100644 --- a/dlls/dmusic/band.c +++ b/dlls/dmusic/band.c @@ -496,6 +496,22 @@ HRESULT band_connect_to_collection(IDirectMusicBand *iface, IDirectMusicCollecti return S_OK; }
+HRESULT band_add_instrument(IDirectMusicBand *iface, DWORD patch, DWORD pchannel) +{ + struct band *This = impl_from_IDirectMusicBand(iface); + struct instrument_entry *entry; + + TRACE("%p, %lu, %lu\n", iface, patch, pchannel); + if (!(entry = calloc(1, sizeof(*entry)))) + return E_OUTOFMEMORY; + + entry->instrument.dwPatch = patch; + entry->instrument.dwPChannel = pchannel; + + list_add_tail(&This->instruments, &entry->entry); + return S_OK; +} + HRESULT band_send_messages(IDirectMusicBand *iface, IDirectMusicPerformance *performance, IDirectMusicGraph *graph, MUSIC_TIME time, DWORD track_id) { diff --git a/dlls/dmusic/band.h b/dlls/dmusic/band.h index 660f208f34a..91c8fcb9c23 100644 --- a/dlls/dmusic/band.h +++ b/dlls/dmusic/band.h @@ -26,5 +26,6 @@ extern HRESULT create_dmband(REFIID riid, void **ret_iface); extern HRESULT band_connect_to_collection(IDirectMusicBand *iface, IDirectMusicCollection *collection); extern HRESULT band_send_messages(IDirectMusicBand *iface, IDirectMusicPerformance *performance, IDirectMusicGraph *graph, MUSIC_TIME time, DWORD track_id); +HRESULT band_add_instrument(IDirectMusicBand *iface, DWORD patch, DWORD pchannel);
#endif