ReactOS 0.4.17-dev-966-gf06eace
instrument.c
Go to the documentation of this file.
1/*
2 * IDirectMusicInstrument Implementation
3 *
4 * Copyright (C) 2003-2004 Rok Mandeljc
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#include "dmusic_private.h"
22#include "soundfont.h"
23#include "dls2.h"
24
26
27static const GUID IID_IDirectMusicInstrumentPRIVATE = { 0xbcb20080, 0xa40c, 0x11d1, { 0x86, 0xbc, 0x00, 0xc0, 0x4f, 0xbf, 0x8f, 0xef } };
28
29#define CONN_SRC_CC2 0x0082
30#define CONN_SRC_RPN0 0x0100
31
32#define CONN_TRN_BIPOLAR (1<<4)
33#define CONN_TRN_INVERT (1<<5)
34
35#define CONN_TRANSFORM(src, ctrl, dst) (((src) & 0x3f) << 10) | (((ctrl) & 0x3f) << 4) | ((dst) & 0xf)
36
38{
39 struct list entry;
42};
43
44#ifdef __REACTOS__
45C_ASSERT(sizeof(struct articulation) == offsetof(struct articulation, connections));
46#else
47C_ASSERT(sizeof(struct articulation) == offsetof(struct articulation, connections[0]));
48#endif
49
50struct region
51{
52 struct list entry;
59};
60
61static void region_destroy(struct region *region)
62{
64
66 {
69 }
70
71 free(region);
72}
73
75{
76 IDirectMusicInstrument IDirectMusicInstrument_iface;
77 IDirectMusicDownloadedInstrument IDirectMusicDownloadedInstrument_iface;
79
81 IDirectMusicDownload *download;
84 struct list regions;
85};
86
87static inline struct instrument *impl_from_IDirectMusicInstrument(IDirectMusicInstrument *iface)
88{
90}
91
93{
94 TRACE("(%p)->(%s, %p)\n", iface, debugstr_dmguid(riid), ret_iface);
95
97 IsEqualIID(riid, &IID_IDirectMusicInstrument))
98 {
99 *ret_iface = iface;
101 return S_OK;
102 }
104 {
105 /* it seems to me that this interface is only basic IUnknown, without any
106 * other inherited functions... *sigh* this is the worst scenario, since it means
107 * that whoever calls it knows the layout of original implementation table and therefore
108 * tries to get data by direct access... expect crashes
109 */
110 FIXME("*sigh*... requested private/unspecified interface\n");
111
112 *ret_iface = iface;
114 return S_OK;
115 }
116
117 WARN("(%p)->(%s, %p): not found\n", iface, debugstr_dmguid(riid), ret_iface);
118
119 return E_NOINTERFACE;
120}
121
123{
126
127 TRACE("(%p): new ref = %lu\n", iface, ref);
128
129 return ref;
130}
131
133{
136
137 TRACE("(%p): new ref = %lu\n", iface, ref);
138
139 if (!ref)
140 {
141 struct articulation *articulation, *next_articulation;
142 struct region *region, *next_region;
143
144 LIST_FOR_EACH_ENTRY_SAFE(articulation, next_articulation, &This->articulations, struct articulation, entry)
145 {
148 }
149
150 LIST_FOR_EACH_ENTRY_SAFE(region, next_region, &This->regions, struct region, entry)
151 {
154 }
155
157 free(This);
158 }
159
160 return ref;
161}
162
164{
166
167 TRACE("(%p)->(%p)\n", This, pdwPatch);
168
169 *pdwPatch = MIDILOCALE2Patch(&This->header.Locale);
170
171 return S_OK;
172}
173
175{
177
178 TRACE("(%p, %ld): stub\n", This, dwPatch);
179
180 Patch2MIDILOCALE(dwPatch, &This->header.Locale);
181
182 return S_OK;
183}
184
185static const IDirectMusicInstrumentVtbl instrument_vtbl =
186{
192};
193
194static inline struct instrument* impl_from_IDirectMusicDownloadedInstrument(IDirectMusicDownloadedInstrument *iface)
195{
197}
198
199static HRESULT WINAPI downloaded_instrument_QueryInterface(IDirectMusicDownloadedInstrument *iface, REFIID riid, VOID **ret_iface)
200{
201 TRACE("(%p, %s, %p)\n", iface, debugstr_dmguid(riid), ret_iface);
202
203 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDirectMusicDownloadedInstrument))
204 {
206 *ret_iface = iface;
207 return S_OK;
208 }
209
210 WARN("(%p, %s, %p): not found\n", iface, debugstr_dmguid(riid), ret_iface);
211
212 return E_NOINTERFACE;
213}
214
215static ULONG WINAPI downloaded_instrument_AddRef(IDirectMusicDownloadedInstrument *iface)
216{
218 return IDirectMusicInstrument_AddRef(&This->IDirectMusicInstrument_iface);
219}
220
221static ULONG WINAPI downloaded_instrument_Release(IDirectMusicDownloadedInstrument *iface)
222{
224 return IDirectMusicInstrument_Release(&This->IDirectMusicInstrument_iface);
225}
226
227static const IDirectMusicDownloadedInstrumentVtbl downloaded_instrument_vtbl =
228{
232};
233
234static HRESULT instrument_create(struct collection *collection, IDirectMusicInstrument **ret_iface)
235{
236 struct instrument *instrument;
237
238 *ret_iface = NULL;
239 if (!(instrument = calloc(1, sizeof(*instrument)))) return E_OUTOFMEMORY;
242 instrument->ref = 1;
246
247 TRACE("Created DirectMusicInstrument %p\n", instrument);
249 return S_OK;
250}
251
253 struct list *articulations)
254{
257 HRESULT hr;
258 UINT size;
259
260 if (chunk->size < sizeof(list)) return E_INVALIDARG;
261 if (FAILED(hr = stream_read(stream, &list, sizeof(list)))) return hr;
262 if (chunk->size != list.cbSize + sizeof(CONNECTION) * list.cConnections) return E_INVALIDARG;
263 if (list.cbSize != sizeof(list)) return E_INVALIDARG;
264
265 size = offsetof(struct articulation, connections[list.cConnections]);
266 if (!(articulation = malloc(size))) return E_OUTOFMEMORY;
268
269 size = sizeof(CONNECTION) * list.cConnections;
271 else list_add_tail(articulations, &articulation->entry);
272
273 return hr;
274}
275
277 struct list *articulations)
278{
279 struct chunk_entry chunk = {.parent = parent};
280 HRESULT hr;
281
282 while ((hr = stream_next_chunk(stream, &chunk)) == S_OK)
283 {
284 switch (MAKE_IDTYPE(chunk.id, chunk.type))
285 {
286 case FOURCC_ART1:
287 hr = parse_art1_chunk(This, stream, &chunk, articulations);
288 break;
289
290 default:
291 FIXME("Ignoring chunk %s %s\n", debugstr_fourcc(chunk.id), debugstr_fourcc(chunk.type));
292 break;
293 }
294
295 if (FAILED(hr)) break;
296 }
297
298 return hr;
299}
300
302{
303 struct chunk_entry chunk = {.parent = parent};
304 struct region *region;
305 HRESULT hr;
306
307 if (!(region = malloc(sizeof(*region)))) return E_OUTOFMEMORY;
309
310 while ((hr = stream_next_chunk(stream, &chunk)) == S_OK)
311 {
312 switch (MAKE_IDTYPE(chunk.id, chunk.type))
313 {
314 case FOURCC_RGNH:
316 break;
317
318 case FOURCC_WSMP:
319 if (chunk.size < sizeof(region->wave_sample)) hr = E_INVALIDARG;
322 {
323 if (region->wave_sample.cSampleLoops > 1) FIXME("More than one wave loop is not implemented\n");
324 if (chunk.size != sizeof(WSMPL) + region->wave_sample.cSampleLoops * sizeof(WLOOP)) hr = E_INVALIDARG;
325 else hr = stream_read(stream, &region->wave_loop, sizeof(region->wave_loop));
326 }
327 break;
328
329 case FOURCC_WLNK:
331 break;
332
335 break;
336
337 default:
338 FIXME("Ignoring chunk %s %s\n", debugstr_fourcc(chunk.id), debugstr_fourcc(chunk.type));
339 break;
340 }
341
342 if (FAILED(hr)) break;
343 }
344
346 else list_add_tail(&This->regions, &region->entry);
347
348 return hr;
349}
350
352{
353 struct chunk_entry chunk = {.parent = parent};
354 HRESULT hr;
355
356 while ((hr = stream_next_chunk(stream, &chunk)) == S_OK)
357 {
358 switch (MAKE_IDTYPE(chunk.id, chunk.type))
359 {
362 break;
363
364 default:
365 FIXME("Ignoring chunk %s %s\n", debugstr_fourcc(chunk.id), debugstr_fourcc(chunk.type));
366 break;
367 }
368
369 if (FAILED(hr)) break;
370 }
371
372 return hr;
373}
374
377{
378 struct chunk_entry chunk = {.parent = parent};
379 HRESULT hr;
380
383 return hr;
384
385 while ((hr = stream_next_chunk(stream, &chunk)) == S_OK)
386 {
387 switch (MAKE_IDTYPE(chunk.id, chunk.type))
388 {
389 case FOURCC_INSH:
390 hr = stream_chunk_get_data(stream, &chunk, &This->header, sizeof(This->header));
391 break;
392
393 case FOURCC_DLID:
395 /* already parsed by dmobj_parsedescriptor */
396 break;
397
400 break;
401
403 hr = parse_lart_list(This, stream, &chunk, &This->articulations);
404 break;
405
406 default:
407 FIXME("Ignoring chunk %s %s\n", debugstr_fourcc(chunk.id), debugstr_fourcc(chunk.type));
408 break;
409 }
410
411 if (FAILED(hr)) break;
412 }
413
414 return hr;
415}
416
418 struct collection *collection, DMUS_OBJECTDESC *desc, IDirectMusicInstrument **ret_iface)
419{
420 IDirectMusicInstrument *iface;
421 struct instrument *This;
422 HRESULT hr;
423
424 TRACE("(%p, %p, %p, %p, %p)\n", stream, parent, collection, desc, ret_iface);
425
426 if (FAILED(hr = instrument_create(collection, &iface))) return hr;
428
430 {
433 }
434
435 if (TRACE_ON(dmusic))
436 {
437 struct region *region;
438 UINT i;
439
440 TRACE("Created DirectMusicInstrument %p\n", This);
441 TRACE(" - header:\n");
442 TRACE(" - regions: %ld\n", This->header.cRegions);
443 TRACE(" - locale: {bank: %#lx, instrument: %#lx} (patch %#lx)\n",
444 This->header.Locale.ulBank, This->header.Locale.ulInstrument,
445 MIDILOCALE2Patch(&This->header.Locale));
446 if (desc->dwValidData & DMUS_OBJ_OBJECT) TRACE(" - guid: %s\n", debugstr_dmguid(&desc->guidObject));
447 if (desc->dwValidData & DMUS_OBJ_NAME) TRACE(" - name: %s\n", debugstr_w(desc->wszName));
448
449 TRACE(" - regions:\n");
450 LIST_FOR_EACH_ENTRY(region, &This->regions, struct region, entry)
451 {
452 TRACE(" - region:\n");
453 TRACE(" - header: {key: %u - %u, vel: %u - %u, options: %#x, group: %#x}\n",
457 TRACE(" - wave_link: {options: %#x, group: %u, channel: %lu, index: %lu}\n",
460 TRACE(" - wave_sample: {size: %lu, unity_note: %u, fine_tune: %d, attenuation: %ld, options: %#lx, loops: %lu}\n",
464 for (i = 0; i < region->wave_sample.cSampleLoops; i++)
465 TRACE(" - wave_loop[%u]: {size: %lu, type: %lu, start: %lu, length: %lu}\n", i,
468 }
469 }
470
471 *ret_iface = iface;
472 return S_OK;
473}
474
476{
478};
479
481{
482 .amount =
483 {
484 [SF_GEN_INITIAL_FILTER_FC] = {.value = 13500},
485 [SF_GEN_DELAY_MOD_LFO] = {.value = -12000},
486 [SF_GEN_DELAY_VIB_LFO] = {.value = -12000},
487 [SF_GEN_DELAY_MOD_ENV] = {.value = -12000},
488 [SF_GEN_ATTACK_MOD_ENV] = {.value = -12000},
489 [SF_GEN_HOLD_MOD_ENV] = {.value = -12000},
490 [SF_GEN_DECAY_MOD_ENV] = {.value = -12000},
491 [SF_GEN_RELEASE_MOD_ENV] = {.value = -12000},
492 [SF_GEN_DELAY_VOL_ENV] = {.value = -12000},
493 [SF_GEN_ATTACK_VOL_ENV] = {.value = -12000},
494 [SF_GEN_HOLD_VOL_ENV] = {.value = -12000},
495 [SF_GEN_DECAY_VOL_ENV] = {.value = -12000},
496 [SF_GEN_RELEASE_VOL_ENV] = {.value = -12000},
497 [SF_GEN_KEY_RANGE] = {.range = {.low = 0, .high = 127}},
498 [SF_GEN_VEL_RANGE] = {.range = {.low = 0, .high = 127}},
499 [SF_GEN_KEYNUM] = {.value = -1},
500 [SF_GEN_VELOCITY] = {.value = -1},
501 [SF_GEN_SCALE_TUNING] = {.value = 100},
502 [SF_GEN_OVERRIDING_ROOT_KEY] = {.value = -1},
503 }
504};
505
507 struct sf_generators *preset_generators, struct sf_generators *generators)
508{
509 struct sf_bag *bag = (preset_generators ? soundfont->ibag : soundfont->pbag) + index;
510 struct sf_gen *gen, *gens = preset_generators ? soundfont->igen : soundfont->pgen;
511
512 for (gen = gens + bag->gen_ndx; gen < gens + (bag + 1)->gen_ndx; gen++)
513 {
514 switch (gen->oper)
515 {
523 case SF_GEN_KEYNUM:
524 case SF_GEN_VELOCITY:
529 if (preset_generators) generators->amount[gen->oper] = gen->amount;
530 else WARN("Ignoring invalid preset generator %s\n", debugstr_sf_gen(gen));
531 break;
532
534 if (!preset_generators) generators->amount[gen->oper] = gen->amount;
535 else WARN("Ignoring invalid instrument generator %s\n", debugstr_sf_gen(gen));
536 /* should always be the last generator */
537 return FALSE;
538
539 case SF_GEN_SAMPLE_ID:
540 if (preset_generators) generators->amount[gen->oper] = gen->amount;
541 else WARN("Ignoring invalid preset generator %s\n", debugstr_sf_gen(gen));
542 /* should always be the last generator */
543 return FALSE;
544
545 default:
546 generators->amount[gen->oper] = gen->amount;
547 if (preset_generators) generators->amount[gen->oper].value += preset_generators->amount[gen->oper].value;
548 break;
549 }
550 }
551
552 return TRUE;
553}
554
556 struct sf_generators *generators)
557{
558 UINT start_loop, end_loop, unity_note, sample_index = generators->amount[SF_GEN_SAMPLE_ID].value;
559 struct sf_sample *sample = soundfont->shdr + sample_index;
560 struct region *region;
561
562 if (!(region = calloc(1, sizeof(*region)))) return E_OUTOFMEMORY;
564
569
570 region->wave_link.ulTableIndex = sample_index;
571
572 unity_note = generators->amount[SF_GEN_OVERRIDING_ROOT_KEY].value;
573 if (unity_note == -1) unity_note = sample->original_key;
574 region->wave_sample.usUnityNote = unity_note;
576 region->wave_sample.lAttenuation = sample->correction;
577
578 start_loop = generators->amount[SF_GEN_STARTLOOP_ADDRS_OFFSET].value;
579 end_loop = generators->amount[SF_GEN_ENDLOOP_ADDRS_OFFSET].value;
580 if (start_loop || end_loop)
581 {
584 region->wave_loop.ulStart = start_loop;
585 region->wave_loop.ulLength = end_loop - start_loop;
586 }
587
588 list_add_tail(&This->regions, &region->entry);
589 This->header.cRegions++;
590 return S_OK;
591}
592
594 UINT index, struct sf_generators *preset_generators)
595{
596 struct sf_generators global_generators = SF_DEFAULT_GENERATORS;
598 UINT i = instrument->bag_ndx;
599 HRESULT hr = S_OK;
600
601 for (i = instrument->bag_ndx; SUCCEEDED(hr) && i < (instrument + 1)->bag_ndx; i++)
602 {
603 struct sf_generators generators = global_generators;
604
605 if (parse_soundfont_generators(soundfont, i, preset_generators, &generators))
606 {
607 if (i > instrument->bag_ndx)
608 WARN("Ignoring instrument zone without a sample id\n");
609 else
610 global_generators = generators;
611 continue;
612 }
613
615 }
616
617 return hr;
618}
619
621 struct collection *collection, DMUS_OBJECTDESC *desc, IDirectMusicInstrument **ret_iface)
622{
623 struct sf_preset *preset = soundfont->phdr + index;
624 struct sf_generators global_generators = {0};
625 IDirectMusicInstrument *iface;
626 struct instrument *This;
627 HRESULT hr;
628 UINT i;
629
630 TRACE("(%p, %u, %p, %p, %p)\n", soundfont, index, collection, desc, ret_iface);
631
632 if (FAILED(hr = instrument_create(collection, &iface))) return hr;
634
635 This->header.Locale.ulBank = (preset->bank & 0x7f) | ((preset->bank << 1) & 0x7f00);
636 This->header.Locale.ulInstrument = preset->preset;
637 MultiByteToWideChar(CP_ACP, 0, preset->name, strlen(preset->name) + 1,
638 desc->wszName, sizeof(desc->wszName));
639
640 for (i = preset->bag_ndx; SUCCEEDED(hr) && i < (preset + 1)->bag_ndx; i++)
641 {
642 struct sf_generators generators = global_generators;
644
645 if (parse_soundfont_generators(soundfont, i, NULL, &generators))
646 {
647 if (i > preset->bag_ndx)
648 WARN("Ignoring preset zone without an instrument\n");
649 else
650 global_generators = generators;
651 continue;
652 }
653
656 }
657
658 if (FAILED(hr))
659 {
661 return hr;
662 }
663
664 if (TRACE_ON(dmusic))
665 {
666 struct region *region;
667 UINT i;
668
669 TRACE("Created DirectMusicInstrument %p\n", This);
670 TRACE(" - header:\n");
671 TRACE(" - regions: %ld\n", This->header.cRegions);
672 TRACE(" - locale: {bank: %#lx, instrument: %#lx} (patch %#lx)\n",
673 This->header.Locale.ulBank, This->header.Locale.ulInstrument,
674 MIDILOCALE2Patch(&This->header.Locale));
675 if (desc->dwValidData & DMUS_OBJ_OBJECT) TRACE(" - guid: %s\n", debugstr_dmguid(&desc->guidObject));
676 if (desc->dwValidData & DMUS_OBJ_NAME) TRACE(" - name: %s\n", debugstr_w(desc->wszName));
677
678 TRACE(" - regions:\n");
679 LIST_FOR_EACH_ENTRY(region, &This->regions, struct region, entry)
680 {
681 TRACE(" - region:\n");
682 TRACE(" - header: {key: %u - %u, vel: %u - %u, options: %#x, group: %#x}\n",
686 TRACE(" - wave_link: {options: %#x, group: %u, channel: %lu, index: %lu}\n",
689 TRACE(" - wave_sample: {size: %lu, unity_note: %u, fine_tune: %d, attenuation: %ld, options: %#lx, loops: %lu}\n",
693 for (i = 0; i < region->wave_sample.cSampleLoops; i++)
694 TRACE(" - wave_loop[%u]: {size: %lu, type: %lu, start: %lu, length: %lu}\n", i,
697 }
698 }
699
700 *ret_iface = iface;
701 return S_OK;
702}
703
706{
707 DMUS_ARTICULATION2 *dmus_articulation2 = NULL;
710 UINT size;
711
712 LIST_FOR_EACH_ENTRY(articulation, articulations, struct articulation, entry)
713 {
714 if (dmus_articulation2) dmus_articulation2->ulNextArtIdx = index;
715 else *first = index;
716
717 offsets[index++] = sizeof(DMUS_DOWNLOADINFO) + *ptr - (BYTE *)offsets;
718 dmus_articulation2 = (DMUS_ARTICULATION2 *)*ptr;
719 (*ptr) += sizeof(DMUS_ARTICULATION2);
720
721 dmus_articulation2->ulArtIdx = index;
722 dmus_articulation2->ulFirstExtCkIdx = 0;
723 dmus_articulation2->ulNextArtIdx = 0;
724
726 offsets[index++] = sizeof(DMUS_DOWNLOADINFO) + *ptr - (BYTE *)offsets;
727 list = (CONNECTIONLIST *)*ptr;
728 (*ptr) += sizeof(CONNECTIONLIST) + size;
729
732 }
733
734 *end = index;
735}
736
738{
741};
742
743#ifdef __REACTOS__
744/* MSVC does not fold offsetof() with a subscript into a constant expression
745 in C (C2057). Element zero lives at the array base, so naming the member
746 alone is the same value and is constant for both compilers. */
747C_ASSERT(sizeof(struct download_buffer) == offsetof(struct download_buffer, offsets));
748#else
750#endif
751
752HRESULT instrument_download_to_port(IDirectMusicInstrument *iface, IDirectMusicPortDownload *port,
753 IDirectMusicDownloadedInstrument **downloaded)
754{
757 struct download_buffer *buffer;
758 IDirectMusicDownload *download;
759 DWORD size, offset_count;
760 struct region *region;
761 IDirectMusicObject *wave;
762 HRESULT hr;
763
764 if (This->download) goto done;
765
766 size = sizeof(DMUS_DOWNLOADINFO);
767 size += sizeof(ULONG) + sizeof(DMUS_INSTRUMENT);
768 offset_count = 1;
769
770 LIST_FOR_EACH_ENTRY(articulation, &This->articulations, struct articulation, entry)
771 {
772 size += sizeof(ULONG) + sizeof(DMUS_ARTICULATION2);
773 size += sizeof(ULONG) + sizeof(CONNECTIONLIST);
775 offset_count += 2;
776 }
777
778 LIST_FOR_EACH_ENTRY(region, &This->regions, struct region, entry)
779 {
780 size += sizeof(ULONG) + sizeof(DMUS_REGION);
781 offset_count++;
782
784 {
785 size += sizeof(ULONG) + sizeof(DMUS_ARTICULATION2);
786 size += sizeof(ULONG) + sizeof(CONNECTIONLIST);
788 offset_count += 2;
789 }
790 }
791
793
796 {
797 BYTE *ptr = (BYTE *)&buffer->offsets[offset_count];
798 DMUS_INSTRUMENT *dmus_instrument;
799 DMUS_REGION *dmus_region = NULL;
800 UINT index = 0;
801
802 buffer->info.dwDLType = DMUS_DOWNLOADINFO_INSTRUMENT2;
803 buffer->info.dwNumOffsetTableEntries = offset_count;
804 buffer->info.cbSize = size;
805
806 buffer->offsets[index++] = ptr - (BYTE *)buffer;
807 dmus_instrument = (DMUS_INSTRUMENT *)ptr;
808 ptr += sizeof(DMUS_INSTRUMENT);
809
810 dmus_instrument->ulPatch = MIDILOCALE2Patch(&This->header.Locale);
811 dmus_instrument->ulFirstRegionIdx = 0;
812 dmus_instrument->ulCopyrightIdx = 0;
813 dmus_instrument->ulGlobalArtIdx = 0;
814
815 write_articulation_download(&This->articulations, buffer->offsets, &ptr, index,
816 &dmus_instrument->ulGlobalArtIdx, &index);
817
818 LIST_FOR_EACH_ENTRY(region, &This->regions, struct region, entry)
819 {
820 if (dmus_region) dmus_region->ulNextRegionIdx = index;
821 else dmus_instrument->ulFirstRegionIdx = index;
822
823 buffer->offsets[index++] = ptr - (BYTE *)buffer;
824 dmus_region = (DMUS_REGION *)ptr;
825 ptr += sizeof(DMUS_REGION);
826
827 dmus_region->RangeKey = region->header.RangeKey;
828 dmus_region->RangeVelocity = region->header.RangeVelocity;
829 dmus_region->fusOptions = region->header.fusOptions;
830 dmus_region->usKeyGroup = region->header.usKeyGroup;
831 dmus_region->ulRegionArtIdx = 0;
832 dmus_region->ulNextRegionIdx = 0;
833 dmus_region->ulFirstExtCkIdx = 0;
834 dmus_region->WaveLink = region->wave_link;
835 dmus_region->WSMP = region->wave_sample;
836 dmus_region->WLOOP[0] = region->wave_loop;
837
839 {
840 hr = wave_download_to_port(wave, port, &dmus_region->WaveLink.ulTableIndex);
842 }
843 if (FAILED(hr)) goto failed;
844
846 &dmus_region->ulRegionArtIdx, &index);
847 }
848
850 }
851
852 This->download = download;
853
854done:
855 *downloaded = &This->IDirectMusicDownloadedInstrument_iface;
857 return S_OK;
858
859failed:
860 WARN("Failed to download instrument to port, hr %#lx\n", hr);
862 return hr;
863}
864
865HRESULT instrument_unload_from_port(IDirectMusicDownloadedInstrument *iface, IDirectMusicPortDownload *port)
866{
868 struct download_buffer *buffer;
869 DWORD size;
870 HRESULT hr;
871
872 if (!This->download) return DMUS_E_NOT_DOWNLOADED_TO_PORT;
873
875 WARN("Failed to unload instrument download buffer, hr %#lx\n", hr);
876 else if (SUCCEEDED(hr = IDirectMusicDownload_GetBuffer(This->download, (void **)&buffer, &size)))
877 {
878 IDirectMusicDownload *wave_download;
880 BYTE *ptr = (BYTE *)buffer;
882 UINT index;
883
884 instrument = (DMUS_INSTRUMENT *)(ptr + buffer->offsets[0]);
885 for (index = instrument->ulFirstRegionIdx; index; index = region->ulNextRegionIdx)
886 {
887 region = (DMUS_REGION *)(ptr + buffer->offsets[index]);
888
889 if (FAILED(hr = IDirectMusicPortDownload_GetBuffer(port, region->WaveLink.ulTableIndex, &wave_download)))
890 WARN("Failed to get wave download with id %#lx, hr %#lx\n", region->WaveLink.ulTableIndex, hr);
891 else
892 {
893 if (FAILED(hr = IDirectMusicPortDownload_Unload(port, wave_download)))
894 WARN("Failed to unload wave download buffer, hr %#lx\n", hr);
895 IDirectMusicDownload_Release(wave_download);
896 }
897 }
898 }
899
901 This->download = NULL;
902
903 return hr;
904}
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define index(s, c)
Definition: various.h:29
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
static void list_init(struct list_entry *head)
Definition: list.h:51
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
const GUID IID_IUnknown
Definition: list.h:39
HRESULT collection_get_wave(struct collection *collection, DWORD index, IDirectMusicObject **out)
Definition: collection.c:81
void collection_internal_addref(struct collection *collection)
Definition: collection.c:66
void collection_internal_release(struct collection *collection)
Definition: collection.c:72
static const WCHAR connections[]
Definition: connections.c:41
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
HRESULT hr
Definition: delayimp.cpp:582
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define CP_ACP
Definition: compat.h:109
#define TRACE_ON(x)
Definition: compat.h:75
#define MultiByteToWideChar
Definition: compat.h:110
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1597
USHORT port
Definition: uri.c:210
#define FOURCC_RGN
Definition: dls1.h:44
#define FOURCC_WSMP
Definition: dls1.h:49
#define FOURCC_LART
Definition: dls1.h:46
#define FOURCC_LRGN
Definition: dls1.h:43
#define FOURCC_DLID
Definition: dls1.h:34
struct _CONNECTION CONNECTION
#define FOURCC_RGNH
Definition: dls1.h:45
#define FOURCC_INSH
Definition: dls1.h:42
#define FOURCC_ART1
Definition: dls1.h:47
#define FOURCC_WLNK
Definition: dls1.h:48
struct _CONNECTIONLIST CONNECTIONLIST
#define DMUS_DOWNLOADINFO_INSTRUMENT2
Definition: dmdls.h:8
struct _DMUS_DOWNLOADINFO DMUS_DOWNLOADINFO
struct _DMUS_REGION DMUS_REGION
struct _DMUS_ARTICULATION2 DMUS_ARTICULATION2
struct _DMUS_INSTRUMENT DMUS_INSTRUMENT
#define DMUS_E_UNSUPPORTED_STREAM
Definition: dmerror.h:100
#define DMUS_E_NOT_DOWNLOADED_TO_PORT
Definition: dmerror.h:68
HRESULT stream_chunk_get_data(IStream *stream, const struct chunk_entry *chunk, void *data, ULONG size)
Definition: dmobject.c:417
HRESULT stream_next_chunk(IStream *stream, struct chunk_entry *chunk)
Definition: dmobject.c:360
HRESULT dmobj_parsedescriptor(IStream *stream, const struct chunk_entry *riff, DMUS_OBJECTDESC *desc, DWORD supported)
Definition: dmobject.c:591
const char * debugstr_dmguid(const GUID *id)
Definition: dmobject.c:36
static HRESULT stream_reset_chunk_data(IStream *stream, const struct chunk_entry *chunk)
Definition: dmobject.h:50
#define DMUS_OBJ_NAME_INFO
Definition: dmobject.h:97
#define MAKE_IDTYPE(id, type)
Definition: dmobject.h:33
#define DMUS_OBJ_GUID_DLID
Definition: dmobject.h:98
void Patch2MIDILOCALE(DWORD dwPatch, LPMIDILOCALE pLocale)
Definition: dmusic_main.c:160
DWORD MIDILOCALE2Patch(const MIDILOCALE *pLocale)
Definition: dmusic_main.c:150
HRESULT wave_download_to_port(IDirectMusicObject *iface, IDirectMusicPortDownload *port, DWORD *id)
Definition: wave.c:437
#define IDirectMusicDownload_Release(p)
Definition: dmusicc.h:604
#define IDirectMusicPortDownload_GetDLId(p, a, b)
Definition: dmusicc.h:638
#define IDirectMusicPortDownload_GetBuffer(p, a, b)
Definition: dmusicc.h:636
#define IDirectMusicPortDownload_Download(p, a)
Definition: dmusicc.h:640
#define IDirectMusicPortDownload_Unload(p, a)
Definition: dmusicc.h:641
#define IDirectMusicInstrument_AddRef(p)
Definition: dmusicc.h:526
#define IDirectMusicDownload_GetBuffer(p, a, b)
Definition: dmusicc.h:606
#define IDirectMusicPortDownload_AllocateBuffer(p, a, b)
Definition: dmusicc.h:637
#define IDirectMusicDownloadedInstrument_AddRef(p)
Definition: dmusicc.h:551
struct IDirectMusicInstrument * LPDIRECTMUSICINSTRUMENT
Definition: dmusicc.h:100
#define IDirectMusicInstrument_Release(p)
Definition: dmusicc.h:527
#define DMUS_FOURCC_INFO_LIST
Definition: dmusicf.h:43
#define IDirectMusicObject_Release(p)
Definition: dmusici.h:844
#define DMUS_OBJ_NAME
Definition: dmusici.h:267
#define DMUS_OBJ_OBJECT
Definition: dmusici.h:265
r parent
Definition: btrfs.c:3010
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
static const FxOffsetAndName offsets[]
GLuint GLuint end
Definition: gl.h:1545
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLuint index
Definition: glext.h:6031
const GLint * first
Definition: glext.h:5794
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned int UINT
Definition: sysinfo.c:13
REFIID riid
Definition: atlbase.h:39
static const IDirectMusicDownloadedInstrumentVtbl downloaded_instrument_vtbl
Definition: instrument.c:227
static HRESULT instrument_create(struct collection *collection, IDirectMusicInstrument **ret_iface)
Definition: instrument.c:234
HRESULT instrument_unload_from_port(IDirectMusicDownloadedInstrument *iface, IDirectMusicPortDownload *port)
Definition: instrument.c:865
static ULONG WINAPI downloaded_instrument_AddRef(IDirectMusicDownloadedInstrument *iface)
Definition: instrument.c:215
static BOOL parse_soundfont_generators(struct soundfont *soundfont, UINT index, struct sf_generators *preset_generators, struct sf_generators *generators)
Definition: instrument.c:506
static HRESULT WINAPI instrument_GetPatch(LPDIRECTMUSICINSTRUMENT iface, DWORD *pdwPatch)
Definition: instrument.c:163
static const struct sf_generators SF_DEFAULT_GENERATORS
Definition: instrument.c:480
static struct instrument * impl_from_IDirectMusicInstrument(IDirectMusicInstrument *iface)
Definition: instrument.c:87
static HRESULT WINAPI downloaded_instrument_QueryInterface(IDirectMusicDownloadedInstrument *iface, REFIID riid, VOID **ret_iface)
Definition: instrument.c:199
static HRESULT parse_lrgn_list(struct instrument *This, IStream *stream, struct chunk_entry *parent)
Definition: instrument.c:351
static HRESULT instrument_add_soundfont_instrument(struct instrument *This, struct soundfont *soundfont, UINT index, struct sf_generators *preset_generators)
Definition: instrument.c:593
static struct instrument * impl_from_IDirectMusicDownloadedInstrument(IDirectMusicDownloadedInstrument *iface)
Definition: instrument.c:194
static void write_articulation_download(struct list *articulations, ULONG *offsets, BYTE **ptr, UINT index, DWORD *first, UINT *end)
Definition: instrument.c:704
static ULONG WINAPI instrument_AddRef(LPDIRECTMUSICINSTRUMENT iface)
Definition: instrument.c:122
static ULONG WINAPI instrument_Release(LPDIRECTMUSICINSTRUMENT iface)
Definition: instrument.c:132
HRESULT instrument_download_to_port(IDirectMusicInstrument *iface, IDirectMusicPortDownload *port, IDirectMusicDownloadedInstrument **downloaded)
Definition: instrument.c:752
static ULONG WINAPI downloaded_instrument_Release(IDirectMusicDownloadedInstrument *iface)
Definition: instrument.c:221
static HRESULT WINAPI instrument_SetPatch(LPDIRECTMUSICINSTRUMENT iface, DWORD dwPatch)
Definition: instrument.c:174
static void region_destroy(struct region *region)
Definition: instrument.c:61
static HRESULT instrument_add_soundfont_region(struct instrument *This, struct soundfont *soundfont, struct sf_generators *generators)
Definition: instrument.c:555
static HRESULT parse_rgn_chunk(struct instrument *This, IStream *stream, struct chunk_entry *parent)
Definition: instrument.c:301
static const GUID IID_IDirectMusicInstrumentPRIVATE
Definition: instrument.c:27
static const IDirectMusicInstrumentVtbl instrument_vtbl
Definition: instrument.c:185
static HRESULT parse_lart_list(struct instrument *This, IStream *stream, struct chunk_entry *parent, struct list *articulations)
Definition: instrument.c:276
static HRESULT parse_ins_chunk(struct instrument *This, IStream *stream, struct chunk_entry *parent, DMUS_OBJECTDESC *desc)
Definition: instrument.c:375
static HRESULT WINAPI instrument_QueryInterface(LPDIRECTMUSICINSTRUMENT iface, REFIID riid, LPVOID *ret_iface)
Definition: instrument.c:92
HRESULT instrument_create_from_chunk(IStream *stream, struct chunk_entry *parent, struct collection *collection, DMUS_OBJECTDESC *desc, IDirectMusicInstrument **ret_iface)
Definition: instrument.c:417
HRESULT instrument_create_from_soundfont(struct soundfont *soundfont, UINT index, struct collection *collection, DMUS_OBJECTDESC *desc, IDirectMusicInstrument **ret_iface)
Definition: instrument.c:620
static HRESULT parse_art1_chunk(struct instrument *This, IStream *stream, struct chunk_entry *chunk, struct list *articulations)
Definition: instrument.c:252
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
#define C_ASSERT(e)
Definition: intsafe.h:73
uint32_t entry
Definition: isohybrid.c:63
#define debugstr_w
Definition: kernel32.h:32
if(dx< 0)
Definition: linetemp.h:194
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define FOURCC_LIST
Definition: mmsystem.h:565
static PVOID ptr
Definition: dispmode.c:27
D3D11_SHADER_VARIABLE_DESC desc
Definition: reflection.c:1683
static int stream_read
Definition: htmldoc.c:205
long LONG
Definition: pedump.c:60
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define REFIID
Definition: guiddef.h:118
static unsigned __int64 next
Definition: rand_nt.c:6
#define calloc
Definition: rosglue.h:14
#define list
Definition: rosglue.h:35
#define offsetof(TYPE, MEMBER)
static __inline const char * debugstr_fourcc(unsigned int cc)
Definition: debug.h:397
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:236
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:242
#define TRACE(s)
Definition: solgame.cpp:4
static const char * debugstr_sf_gen(struct sf_gen *gen)
Definition: soundfont.h:266
@ SF_GEN_STARTLOOP_ADDRS_OFFSET
Definition: soundfont.h:62
@ SF_GEN_RELEASE_VOL_ENV
Definition: soundfont.h:96
@ SF_GEN_STARTLOOP_ADDRS_COARSE_OFFSET
Definition: soundfont.h:103
@ SF_GEN_KEYNUM
Definition: soundfont.h:104
@ SF_GEN_SAMPLE_MODES
Definition: soundfont.h:112
@ SF_GEN_ENDLOOP_ADDRS_OFFSET
Definition: soundfont.h:63
@ SF_GEN_DELAY_VOL_ENV
Definition: soundfont.h:91
@ SF_GEN_KEY_RANGE
Definition: soundfont.h:101
@ SF_GEN_START_ADDRS_COARSE_OFFSET
Definition: soundfont.h:64
@ SF_GEN_DELAY_VIB_LFO
Definition: soundfont.h:81
@ SF_GEN_INITIAL_FILTER_FC
Definition: soundfont.h:68
@ SF_GEN_DELAY_MOD_LFO
Definition: soundfont.h:79
@ SF_GEN_END_ADDRS_COARSE_OFFSET
Definition: soundfont.h:72
@ SF_GEN_HOLD_MOD_ENV
Definition: soundfont.h:85
@ SF_GEN_SAMPLE_ID
Definition: soundfont.h:111
@ SF_GEN_SCALE_TUNING
Definition: soundfont.h:114
@ SF_GEN_ATTACK_MOD_ENV
Definition: soundfont.h:84
@ SF_GEN_OVERRIDING_ROOT_KEY
Definition: soundfont.h:116
@ SF_GEN_START_ADDRS_OFFSET
Definition: soundfont.h:60
@ SF_GEN_VELOCITY
Definition: soundfont.h:105
@ SF_GEN_DELAY_MOD_ENV
Definition: soundfont.h:83
@ SF_GEN_VEL_RANGE
Definition: soundfont.h:102
@ SF_GEN_DECAY_VOL_ENV
Definition: soundfont.h:94
@ SF_GEN_END_ADDRS_OFFSET
Definition: soundfont.h:61
@ SF_GEN_FINE_TUNE
Definition: soundfont.h:110
@ SF_GEN_HOLD_VOL_ENV
Definition: soundfont.h:93
@ SF_GEN_DECAY_MOD_ENV
Definition: soundfont.h:86
@ SF_GEN_ATTACK_VOL_ENV
Definition: soundfont.h:92
@ SF_GEN_END_OPER
Definition: soundfont.h:118
@ SF_GEN_ENDLOOP_ADDRS_COARSE_OFFSET
Definition: soundfont.h:108
@ SF_GEN_EXCLUSIVE_CLASS
Definition: soundfont.h:115
@ SF_GEN_INSTRUMENT
Definition: soundfont.h:99
@ SF_GEN_RELEASE_MOD_ENV
Definition: soundfont.h:88
ULONG cConnections
Definition: dls1.h:73
ULONG ulFirstExtCkIdx
Definition: dmdls.h:147
ULONG ulNextArtIdx
Definition: dmdls.h:148
USHORT usKeyGroup
Definition: dls1.h:128
RGNRANGE RangeVelocity
Definition: dls1.h:126
USHORT fusOptions
Definition: dls1.h:127
RGNRANGE RangeKey
Definition: dls1.h:125
USHORT usHigh
Definition: dls1.h:120
USHORT usLow
Definition: dls1.h:119
Definition: dls1.h:132
ULONG cbSize
Definition: dls1.h:133
ULONG ulLength
Definition: dls1.h:136
ULONG ulType
Definition: dls1.h:134
ULONG ulStart
Definition: dls1.h:135
Definition: dls1.h:140
LONG lAttenuation
Definition: dls1.h:144
SHORT sFineTune
Definition: dls1.h:143
ULONG fulOptions
Definition: dls1.h:145
ULONG cSampleLoops
Definition: dls1.h:146
ULONG cbSize
Definition: dls1.h:141
USHORT usUnityNote
Definition: dls1.h:142
struct list entry
Definition: instrument.c:39
CONNECTION connections[]
Definition: instrument.c:41
CONNECTIONLIST list
Definition: instrument.c:40
Definition: dmobject.h:26
uint16_t size
Definition: btrfs_drv.h:563
ULONG offsets[]
Definition: instrument.c:740
DMUS_DOWNLOADINFO info
Definition: instrument.c:739
IDirectMusicInstrument IDirectMusicInstrument_iface
Definition: instrument.c:76
struct list regions
Definition: instrument.c:84
INSTHEADER header
Definition: instrument.c:80
IDirectMusicDownloadedInstrument IDirectMusicDownloadedInstrument_iface
Definition: instrument.c:77
IDirectMusicDownload * download
Definition: instrument.c:81
struct list articulations
Definition: instrument.c:83
struct collection * collection
Definition: instrument.c:82
LONG ref
Definition: instrument.c:78
Definition: send.c:48
WAVELINK wave_link
Definition: instrument.c:55
RGNHEADER header
Definition: instrument.c:54
WSMPL wave_sample
Definition: instrument.c:56
struct list entry
Definition: instrument.c:52
BOOL loop_present
Definition: instrument.c:58
WLOOP wave_loop
Definition: instrument.c:57
struct list articulations
Definition: instrument.c:53
Definition: wave.c:25
WORD gen_ndx
Definition: soundfont.h:235
union sf_amount amount
Definition: soundfont.h:261
sf_generator oper
Definition: soundfont.h:260
union sf_amount amount[SF_GEN_END_OPER]
Definition: instrument.c:477
WORD bank
Definition: soundfont.h:224
char name[20]
Definition: soundfont.h:222
WORD bag_ndx
Definition: soundfont.h:225
WORD preset
Definition: soundfont.h:223
struct sf_gen * igen
Definition: soundfont.h:318
struct sf_gen * pgen
Definition: soundfont.h:312
struct sf_instrument * inst
Definition: soundfont.h:315
struct sf_bag * ibag
Definition: soundfont.h:316
struct sf_preset * phdr
Definition: soundfont.h:309
struct sf_bag * pbag
Definition: soundfont.h:310
struct sf_sample * shdr
Definition: soundfont.h:321
Definition: parse.h:23
Definition: wave.c:37
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
WORD value
Definition: soundfont.h:40
struct sf_range range
Definition: soundfont.h:39
#define WINAPI
Definition: msvc.h:6
#define E_NOINTERFACE
Definition: winerror.h:3479
unsigned char BYTE
Definition: xxhash.c:193