ReactOS 0.4.17-dev-923-g4c9a150
performance.c
Go to the documentation of this file.
1/* IDirectMusicPerformance Implementation
2 *
3 * Copyright (C) 2003-2004 Rok Mandeljc
4 * Copyright (C) 2003-2004 Raphael Junqueira
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 "dmime_private.h"
22#include "dmusic_midi.h"
23#include "wine/rbtree.h"
24#include <math.h>
25
27
29{
33};
34
35struct channel
36{
39 IDirectMusicPort *port;
40};
41
43{
44 DWORD block_num; /* Block 0 is PChannels 0-15, Block 1 is PChannels 16-31, etc */
45 struct channel channels[16];
47};
48
50{
51 IDirectMusicPerformance8 IDirectMusicPerformance8_iface;
52 IDirectMusicGraph IDirectMusicGraph_iface;
53 IDirectMusicTool IDirectMusicTool_iface;
55 IDirectMusic *dmusic;
56 IDirectSound *dsound;
57 IDirectMusicGraph *pToolGraph;
62 /* performance channels */
64
66 IDirectMusicAudioPath *pDefaultPath;
70
73 CONDITION_VARIABLE cond;
74
77 struct list messages;
78
84
85 IDirectMusicSegment *primary_segment;
86 IDirectMusicSegment *control_segment;
87};
88
89struct message
90{
91 struct list entry;
93};
94
96{
97 return msg ? CONTAINING_RECORD(msg, struct message, msg) : NULL;
98}
99
101{
103 IDirectMusicPerformance *performance = (IDirectMusicPerformance *)&This->IDirectMusicPerformance8_iface;
104 REFERENCE_TIME latency, offset = 0;
105 struct message *message;
106 struct list *ptr;
107
108 if (!(ptr = list_head(&This->messages)))
109 return NULL;
110 message = LIST_ENTRY(ptr, struct message, entry);
111
113 return NULL;
114
115 switch (message->msg.dwFlags & delivery_flags)
116 {
117 default:
118 WARN("No delivery flag found for message %p\n", &message->msg);
119 break;
121 offset = This->dwBumperLength * 10000;
122 /* fallthrough */
124 if (message->msg.rtTime >= offset && message->msg.rtTime - offset >= latency)
125 {
126 *timeout = (message->msg.rtTime - offset - latency) / 10000;
127 return NULL;
128 }
129 break;
130 }
131
132 return message;
133}
134
136{
137 IDirectMusicPerformance *performance = (IDirectMusicPerformance *)&This->IDirectMusicPerformance8_iface;
138 IDirectMusicTool *tool;
139 HRESULT hr;
140
141 if (!(tool = msg->pTool)) tool = &This->IDirectMusicTool_iface;
142
144
146 if (FAILED(hr)) WARN("Failed to process message, hr %#lx\n", hr);
147 return hr;
148}
149
151{
153 struct message *prev;
154 HRESULT hr;
155
156 while ((message->msg.dwFlags & delivery_flags) == DMUS_PMSGF_TOOL_IMMEDIATE)
157 {
159 if (hr != DMUS_S_REQUEUE)
160 return hr;
161 }
162
163 LIST_FOR_EACH_ENTRY_REV(prev, &This->messages, struct message, entry)
164 {
165 if (&prev->entry == &This->messages) break;
166 if (prev->msg.rtTime <= message->msg.rtTime) break;
167 }
168
170
171 return S_OK;
172}
173
175{
176 struct performance *This = args;
177 HRESULT hr;
178
179 TRACE("performance %p message thread\n", This);
180 SetThreadDescription(GetCurrentThread(), L"wine_dmime_message");
181
183
184 while (This->message_thread)
185 {
187 struct message *message;
188
190 {
191 SleepConditionVariableCS(&This->cond, &This->safe, timeout);
192 continue;
193 }
194
197
200 }
201
203
204 TRACE("(%p): Exiting\n", This);
205 return 0;
206}
207
209 DWORD type, IUnknown *object)
210{
211 IDirectMusicPerformance8 *performance = &This->IDirectMusicPerformance8_iface;
212 IDirectMusicGraph *graph = &This->IDirectMusicGraph_iface;
213 DMUS_PMSG *msg;
214 HRESULT hr;
215
217 return hr;
218
219 msg->mtTime = music_time;
220 msg->dwFlags = DMUS_PMSGF_MUSICTIME | flags;
221 msg->dwType = type;
222 if ((msg->punkUser = object)) IUnknown_AddRef(object);
223
227
228 return hr;
229}
230
232 GUID type, DWORD option, IUnknown *object)
233{
234 IDirectMusicPerformance8 *performance = &This->IDirectMusicPerformance8_iface;
235 IDirectMusicGraph *graph = &This->IDirectMusicGraph_iface;
237 HRESULT hr;
238
240 return hr;
241
242 msg->mtTime = music_time;
245 if ((msg->punkUser = object)) IUnknown_AddRef(object);
246 msg->guidNotificationType = type;
247 msg->dwNotificationOption = option;
248
249 /* only stamp the message if notifications are enabled, otherwise send them directly to the output tool */
253
254 return hr;
255}
256
257static int channel_block_compare(const void *key, const struct wine_rb_entry *entry)
258{
259 const struct channel_block *b = WINE_RB_ENTRY_VALUE(entry, const struct channel_block, entry);
260 return *(DWORD *)key - b->block_num;
261}
262
264{
266 UINT i;
267
268 for (i = 0; i < ARRAY_SIZE(block->channels); i++)
269 {
270 struct channel *channel = block->channels + i;
272 }
273
274 free(block);
275}
276
277static struct channel *performance_get_channel(struct performance *This, DWORD channel_num)
278{
279 DWORD block_num = channel_num / 16;
280 struct wine_rb_entry *entry;
281 if (!(entry = wine_rb_get(&This->channel_blocks, &block_num))) return NULL;
282 return WINE_RB_ENTRY_VALUE(entry, struct channel_block, entry)->channels + channel_num % 16;
283}
284
286 IDirectMusicPort *port, DWORD midi_group)
287{
288 struct channel_block *block;
289 struct wine_rb_entry *entry;
290 UINT i;
291
292 if ((entry = wine_rb_get(&This->channel_blocks, &block_num)))
294 else
295 {
296 if (!(block = calloc(1, sizeof(*block)))) return E_OUTOFMEMORY;
297 block->block_num = block_num;
298 wine_rb_put(&This->channel_blocks, &block_num, &block->entry);
299 }
300
301 for (i = 0; i < ARRAY_SIZE(block->channels); ++i)
302 {
303 struct channel *channel = block->channels + i;
308 }
309
310 return S_OK;
311}
312
313static inline struct performance *impl_from_IDirectMusicPerformance8(IDirectMusicPerformance8 *iface)
314{
316}
317
318HRESULT performance_send_segment_start(IDirectMusicPerformance8 *iface, MUSIC_TIME music_time,
319 IDirectMusicSegmentState *state)
320{
322 HRESULT hr;
323
324 if (FAILED(hr = performance_send_notification_pmsg(This, music_time, This->notification_performance,
325 GUID_NOTIFICATION_PERFORMANCE, DMUS_NOTIFICATION_MUSICSTARTED, NULL)))
326 return hr;
327 if (FAILED(hr = performance_send_notification_pmsg(This, music_time, This->notification_segment,
328 GUID_NOTIFICATION_SEGMENT, DMUS_NOTIFICATION_SEGSTART, (IUnknown *)state)))
329 return hr;
332 return hr;
333
334 return S_OK;
335}
336
337HRESULT performance_send_segment_tick(IDirectMusicPerformance8 *iface, MUSIC_TIME music_time,
338 IDirectMusicSegmentState *state)
339{
342 HRESULT hr;
343
345 return hr;
346 if (FAILED(hr = IDirectMusicPerformance8_ReferenceToMusicTime(iface, time + 2000000, &music_time)))
347 return hr;
350 return hr;
351
352 return S_OK;
353}
354
355HRESULT performance_send_segment_end(IDirectMusicPerformance8 *iface, MUSIC_TIME music_time,
356 IDirectMusicSegmentState *state, BOOL abort)
357{
359 HRESULT hr;
360
361 if (!abort)
362 {
363 if (FAILED(hr = performance_send_notification_pmsg(This, music_time - 1450, This->notification_segment,
364 GUID_NOTIFICATION_SEGMENT, DMUS_NOTIFICATION_SEGALMOSTEND, (IUnknown *)state)))
365 return hr;
366 if (FAILED(hr = performance_send_notification_pmsg(This, music_time, This->notification_segment,
367 GUID_NOTIFICATION_SEGMENT, DMUS_NOTIFICATION_SEGEND, (IUnknown *)state)))
368 return hr;
369 }
370
373 return hr;
374 if (FAILED(hr = performance_send_notification_pmsg(This, music_time, This->notification_performance,
375 GUID_NOTIFICATION_PERFORMANCE, DMUS_NOTIFICATION_MUSICSTOPPED, NULL)))
376 return hr;
379 return hr;
380
381 return S_OK;
382}
383
384static void performance_set_primary_segment(struct performance *This, IDirectMusicSegment *segment)
385{
386 if (This->primary_segment) IDirectMusicSegment_Release(This->primary_segment);
387 if ((This->primary_segment = segment)) IDirectMusicSegment_AddRef(This->primary_segment);
388}
389
390static void performance_set_control_segment(struct performance *This, IDirectMusicSegment *segment)
391{
392 if (This->control_segment) IDirectMusicSegment_Release(This->control_segment);
393 if ((This->control_segment = segment)) IDirectMusicSegment_AddRef(This->control_segment);
394}
395
396/* IDirectMusicPerformance8 IUnknown part: */
397static HRESULT WINAPI performance_QueryInterface(IDirectMusicPerformance8 *iface, REFIID riid, void **ret_iface)
398{
400
401 TRACE("(%p, %s, %p)\n", iface, debugstr_dmguid(riid), ret_iface);
402
404 || IsEqualGUID(riid, &IID_IDirectMusicPerformance)
405 || IsEqualGUID(riid, &IID_IDirectMusicPerformance2)
406 || IsEqualGUID(riid, &IID_IDirectMusicPerformance8))
407 {
408 *ret_iface = iface;
409 IUnknown_AddRef(iface);
410 return S_OK;
411 }
412
413 if (IsEqualGUID(riid, &IID_IDirectMusicGraph))
414 {
415 *ret_iface = &This->IDirectMusicGraph_iface;
416 IDirectMusicGraph_AddRef(&This->IDirectMusicGraph_iface);
417 return S_OK;
418 }
419
420 if (IsEqualGUID(riid, &IID_IDirectMusicTool))
421 {
422 *ret_iface = &This->IDirectMusicTool_iface;
423 IDirectMusicTool_AddRef(&This->IDirectMusicTool_iface);
424 return S_OK;
425 }
426
427 *ret_iface = NULL;
428 WARN("(%p, %s, %p): not found\n", iface, debugstr_dmguid(riid), ret_iface);
429 return E_NOINTERFACE;
430}
431
432static ULONG WINAPI performance_AddRef(IDirectMusicPerformance8 *iface)
433{
436
437 TRACE("(%p): ref=%ld\n", This, ref);
438
439 return ref;
440}
441
442static ULONG WINAPI performance_Release(IDirectMusicPerformance8 *iface)
443{
446
447 TRACE("(%p): ref=%ld\n", This, ref);
448
449 if (ref == 0) {
450 wine_rb_destroy(&This->channel_blocks, channel_block_free, NULL);
451 This->safe.DebugInfo->Spare[0] = 0;
453 free(This);
454 }
455
456 return ref;
457}
458
460{
461 IDirectSound *dsound;
462 HRESULT hr;
463
464 if (FAILED(hr = DirectSoundCreate(NULL, &dsound, NULL))) return hr;
465
466 if (!hwnd) hwnd = GetForegroundWindow();
468
469 if (SUCCEEDED(hr)) This->dsound = dsound;
471
472 return hr;
473}
474
476{
477 IDirectMusic *dmusic;
478 HRESULT hr;
479
480 if (FAILED(hr = CoCreateInstance(&CLSID_DirectMusic, NULL, CLSCTX_INPROC_SERVER,
481 &IID_IDirectMusic8, (void **)&dmusic)))
482 return hr;
483
485
486 if (SUCCEEDED(hr)) This->dmusic = dmusic;
488
489 return hr;
490}
491
493 BYTE status, BYTE byte1, BYTE byte2)
494{
495 IDirectMusicPerformance8 *performance = &This->IDirectMusicPerformance8_iface;
496 DMUS_MIDI_PMSG *midi;
497 HRESULT hr;
498
500 (DMUS_PMSG **)&midi)))
501 return hr;
502
503 if (flags & DMUS_PMSGF_REFTIME) midi->rtTime = msg->rtTime;
504 if (flags & DMUS_PMSGF_MUSICTIME) midi->mtTime = msg->mtTime;
505 midi->dwFlags = flags;
506 midi->dwPChannel = msg->dwPChannel;
507 midi->dwVirtualTrackID = msg->dwVirtualTrackID;
508 midi->dwVoiceID = msg->dwVoiceID;
509 midi->dwGroupID = msg->dwGroupID;
510 midi->dwType = DMUS_PMSGT_MIDI;
511 midi->bStatus = status;
512 midi->bByte1 = byte1;
513 midi->bByte2 = byte2;
514
517
518 return hr;
519}
520
521static HRESULT WINAPI performance_Init(IDirectMusicPerformance8 *iface, IDirectMusic **dmusic,
522 IDirectSound *dsound, HWND hwnd)
523{
525 HRESULT hr;
526
527 TRACE("(%p, %p, %p, %p)\n", iface, dmusic, dsound, hwnd);
528
529 if (This->dmusic) return DMUS_E_ALREADY_INITED;
530
531 if ((This->dsound = dsound)) IDirectMusic8_AddRef(This->dsound);
532 else if (FAILED(hr = performance_init_dsound(This, hwnd))) return hr;
533
534 if (dmusic && (This->dmusic = *dmusic)) IDirectMusic_AddRef(This->dmusic);
535 else if (FAILED(hr = performance_init_dmusic(This, This->dsound)))
536 {
538 return hr;
539 }
540
541 if (FAILED(hr = IDirectMusic_GetMasterClock(This->dmusic, NULL, &This->master_clock))
542 || FAILED(hr = IDirectMusicPerformance8_GetTime(iface, &This->init_time, NULL)))
543 {
545 return hr;
546 }
547
548 if (!(This->message_thread = CreateThread(NULL, 0, message_thread_proc, This, 0, NULL)))
549 {
550 ERR("Failed to start performance message thread, error %lu\n", GetLastError());
553 }
554
555 if (dmusic && !*dmusic)
556 {
557 *dmusic = This->dmusic;
559 }
560 return S_OK;
561}
562
563static HRESULT WINAPI performance_PlaySegment(IDirectMusicPerformance8 *iface, IDirectMusicSegment *segment,
564 DWORD segment_flags, INT64 start_time, IDirectMusicSegmentState **ret_state)
565{
567
568 TRACE("(%p, %p, %ld, %I64d, %p)\n", This, segment, segment_flags, start_time, ret_state);
569
571 segment_flags, start_time, ret_state, NULL, NULL);
572}
573
575{
576 struct list entry;
577 IDirectMusicSegmentState *state;
578};
579
581{
582 list_remove(&entry->entry);
584 free(entry);
585}
586
587static void enum_segment_states(struct performance *This, IDirectMusicSegment *segment, struct list *list)
588{
589 struct state_entry *entry;
590 struct message *message;
591
592 LIST_FOR_EACH_ENTRY(message, &This->messages, struct message, entry)
593 {
594 IDirectMusicSegmentState *message_state;
595
598 continue;
599
600 message_state = (IDirectMusicSegmentState *)message->msg.punkUser;
602
603 if (!(entry = malloc(sizeof(*entry)))) return;
604 entry->state = message_state;
606 list_add_tail(list, &entry->entry);
607 }
608}
609
610static BOOL message_needs_flushing(struct message *message, IDirectMusicSegmentState *state)
611{
612 if (!state) return TRUE;
613
614 switch (message->msg.dwType)
615 {
616 case DMUS_PMSGT_MIDI:
617 case DMUS_PMSGT_NOTE:
618 case DMUS_PMSGT_CURVE:
619 case DMUS_PMSGT_PATCH:
620 case DMUS_PMSGT_WAVE:
621 if (!segment_state_has_track(state, message->msg.dwVirtualTrackID)) return FALSE;
622 break;
623
625 {
627 if (!IsEqualGUID(&notif->guidNotificationType, &GUID_NOTIFICATION_SEGMENT)) return FALSE;
628 if ((IDirectMusicSegmentState *)message->msg.punkUser != state) return FALSE;
629 break;
630 }
631
634 if ((IDirectMusicSegmentState *)message->msg.punkUser != state) return FALSE;
635 break;
636
637 default:
638 FIXME("Unhandled message type %#lx\n", message->msg.dwType);
639 break;
640 }
641
642 return TRUE;
643}
644
645static void performance_flush_messages(struct performance *This, IDirectMusicSegmentState *state)
646{
647 IDirectMusicPerformance *iface = (IDirectMusicPerformance *)&This->IDirectMusicPerformance8_iface;
648 struct message *message, *next;
649 HRESULT hr;
650
652 {
653 if (!message_needs_flushing(message, state)) continue;
654
657
659 ERR("Failed to free message %p, hr %#lx\n", message, hr);
660 }
661
662 LIST_FOR_EACH_ENTRY_SAFE(message, next, &This->notifications, struct message, entry)
663 {
664 if (!message_needs_flushing(message, state)) continue;
665
668
670 ERR("Failed to free message %p, hr %#lx\n", message, hr);
671 }
672}
673
674static HRESULT WINAPI performance_Stop(IDirectMusicPerformance8 *iface, IDirectMusicSegment *segment,
675 IDirectMusicSegmentState *state, MUSIC_TIME music_time, DWORD flags)
676{
678 struct list states = LIST_INIT(states);
679 struct state_entry *entry, *next;
680 DMUS_PMSG msg = {.mtTime = -1};
681 HRESULT hr;
682
683 FIXME("(%p, %p, %p, %ld, %ld): semi-stub\n", This, segment, state, music_time, flags);
684
685 if (music_time) FIXME("time parameter %lu not implemented\n", music_time);
686 if (flags != DMUS_SEGF_DEFAULT) FIXME("flags parameter %#lx not implemented\n", flags);
687
688 if (!music_time && FAILED(hr = IDirectMusicPerformance8_GetTime(iface, NULL, &music_time)))
689 return hr;
690
692
693 if (!state)
695 else if ((entry = malloc(sizeof(*entry))))
696 {
697 entry->state = state;
699 list_add_tail(&states, &entry->entry);
700 }
701
702 if (!segment && !state)
704 else LIST_FOR_EACH_ENTRY(entry, &states, struct state_entry, entry)
706
708 {
709 if (FAILED(hr = performance_send_notification_pmsg(This, music_time, This->notification_segment,
710 GUID_NOTIFICATION_SEGMENT, DMUS_NOTIFICATION_SEGABORT, (IUnknown *)entry->state)))
711 ERR("Failed to send DMUS_NOTIFICATION_SEGABORT, hr %#lx\n", hr);
712 if (FAILED(hr = segment_state_stop(entry->state, iface)))
713 ERR("Failed to stop segment state, hr %#lx\n", hr);
714
716 list_remove(&entry->entry);
717 free(entry);
718 }
719
720 if (!state && !segment)
721 {
723 MIDI_SYSTEM_RESET, 0, 0)))
724 ERR("Failed to send MIDI_SYSTEM_RESET message, hr %#lx\n", hr);
725 }
726
728
729 return S_OK;
730}
731
732static HRESULT WINAPI performance_GetSegmentState(IDirectMusicPerformance8 *iface,
733 IDirectMusicSegmentState **state, MUSIC_TIME time)
734{
736 struct list *ptr, states = LIST_INIT(states);
737 struct state_entry *entry, *next;
738 HRESULT hr = S_OK;
739
740 TRACE("(%p, %p, %ld)\n", This, state, time);
741
742 if (!state) return E_POINTER;
743
745
746 enum_segment_states(This, This->primary_segment, &states);
747
748 if (!(ptr = list_head(&states))) hr = DMUS_E_NOT_FOUND;
749 else
750 {
752
753 *state = entry->state;
755
758 }
759
761
762 return hr;
763}
764
765static HRESULT WINAPI performance_SetPrepareTime(IDirectMusicPerformance8 *iface, DWORD dwMilliSeconds)
766{
768
769 TRACE("(%p, %ld)\n", This, dwMilliSeconds);
770 This->dwPrepareTime = dwMilliSeconds;
771 return S_OK;
772}
773
774static HRESULT WINAPI performance_GetPrepareTime(IDirectMusicPerformance8 *iface, DWORD *pdwMilliSeconds)
775{
777
778 TRACE("(%p, %p)\n", This, pdwMilliSeconds);
779 if (NULL == pdwMilliSeconds) {
780 return E_POINTER;
781 }
782 *pdwMilliSeconds = This->dwPrepareTime;
783 return S_OK;
784}
785
786static HRESULT WINAPI performance_SetBumperLength(IDirectMusicPerformance8 *iface, DWORD dwMilliSeconds)
787{
789
790 TRACE("(%p, %ld)\n", This, dwMilliSeconds);
791 This->dwBumperLength = dwMilliSeconds;
792 return S_OK;
793}
794
795static HRESULT WINAPI performance_GetBumperLength(IDirectMusicPerformance8 *iface, DWORD *pdwMilliSeconds)
796{
798
799 TRACE("(%p, %p)\n", This, pdwMilliSeconds);
800 if (NULL == pdwMilliSeconds) {
801 return E_POINTER;
802 }
803 *pdwMilliSeconds = This->dwBumperLength;
804 return S_OK;
805}
806
807static HRESULT WINAPI performance_SendPMsg(IDirectMusicPerformance8 *iface, DMUS_PMSG *msg)
808{
811 struct message *message;
812 HRESULT hr;
813
814 TRACE("(%p, %p)\n", This, msg);
815
817 if (!This->dmusic) return DMUS_E_NO_MASTER_CLOCK;
818 if (!(msg->dwFlags & (DMUS_PMSGF_MUSICTIME | DMUS_PMSGF_REFTIME))) return E_INVALIDARG;
819
821
822 if (!list_empty(&message->entry))
824 else
825 {
826 if (!(msg->dwFlags & delivery_flags)) msg->dwFlags |= DMUS_PMSGF_TOOL_IMMEDIATE;
827 if (!(msg->dwFlags & DMUS_PMSGF_MUSICTIME))
828 {
830 msg->rtTime, &msg->mtTime)))
831 goto done;
832 msg->dwFlags |= DMUS_PMSGF_MUSICTIME;
833 }
834 if (!(msg->dwFlags & DMUS_PMSGF_REFTIME))
835 {
837 msg->mtTime == -1 ? 0 : msg->mtTime, &msg->rtTime)))
838 goto done;
839 msg->dwFlags |= DMUS_PMSGF_REFTIME;
840 }
841
843 }
844
845done:
848
849 return hr;
850}
851
852static HRESULT WINAPI performance_MusicToReferenceTime(IDirectMusicPerformance8 *iface,
853 MUSIC_TIME music_time, REFERENCE_TIME *time)
854{
856 MUSIC_TIME tempo_time, next = 0;
858 double tempo, duration;
859 HRESULT hr;
860
861 TRACE("(%p, %ld, %p)\n", This, music_time, time);
862
863 if (!time) return E_POINTER;
864 *time = 0;
865
866 if (!This->master_clock) return DMUS_E_NO_MASTER_CLOCK;
867
869
870 for (tempo = 120.0, duration = tempo_time = 0; music_time > 0; tempo_time += next)
871 {
872 if (FAILED(hr = IDirectMusicPerformance_GetParam(iface, &GUID_TempoParam, -1, DMUS_SEG_ALLTRACKS,
873 tempo_time, &next, &param)))
874 break;
875
876 if (!next) next = music_time;
877 else next = min(next, music_time);
878
879 if (param.mtTime <= 0) tempo = param.dblTempo;
880 duration += (600000000.0 * next) / (tempo * DMUS_PPQ);
881 music_time -= next;
882 }
883
884 duration += (600000000.0 * music_time) / (tempo * DMUS_PPQ);
885 *time = This->init_time + duration;
886
888
889 return S_OK;
890}
891
892static HRESULT WINAPI performance_ReferenceToMusicTime(IDirectMusicPerformance8 *iface,
893 REFERENCE_TIME time, MUSIC_TIME *music_time)
894{
896 MUSIC_TIME tempo_time, next = 0;
897 double tempo, duration, step;
899 HRESULT hr;
900
901 TRACE("(%p, %I64d, %p)\n", This, time, music_time);
902
903 if (!music_time) return E_POINTER;
904 *music_time = 0;
905
906 if (!This->master_clock) return DMUS_E_NO_MASTER_CLOCK;
907
909
910 duration = time - This->init_time;
911
912 for (tempo = 120.0, tempo_time = 0; duration > 0; tempo_time += next, duration -= step)
913 {
914 if (FAILED(hr = IDirectMusicPerformance_GetParam(iface, &GUID_TempoParam, -1, DMUS_SEG_ALLTRACKS,
915 tempo_time, &next, &param)))
916 break;
917
918 if (param.mtTime <= 0) tempo = param.dblTempo;
919 step = (600000000.0 * next) / (tempo * DMUS_PPQ);
920 if (!next || duration < step) break;
921 *music_time = *music_time + next;
922 }
923
924 *music_time = *music_time + round((duration * tempo * DMUS_PPQ) / 600000000.0);
925
927
928 return S_OK;
929}
930
931static HRESULT WINAPI performance_IsPlaying(IDirectMusicPerformance8 *iface,
932 IDirectMusicSegment *pSegment, IDirectMusicSegmentState *pSegState)
933{
935
936 FIXME("(%p, %p, %p): stub\n", This, pSegment, pSegState);
937 return S_FALSE;
938}
939
940static HRESULT WINAPI performance_GetTime(IDirectMusicPerformance8 *iface, REFERENCE_TIME *time, MUSIC_TIME *music_time)
941{
944 HRESULT hr;
945
946 TRACE("(%p, %p, %p)\n", iface, time, music_time);
947
948 if (!This->master_clock) return DMUS_E_NO_MASTER_CLOCK;
949 if (FAILED(hr = IReferenceClock_GetTime(This->master_clock, &now))) return hr;
950
951 if (time) *time = now;
952 if (music_time) hr = IDirectMusicPerformance8_ReferenceToMusicTime(iface, now, music_time);
953
954 return hr;
955}
956
957static HRESULT WINAPI performance_AllocPMsg(IDirectMusicPerformance8 *iface, ULONG size, DMUS_PMSG **msg)
958{
960 struct message *message;
961
962 TRACE("(%p, %ld, %p)\n", This, size, msg);
963
964 if (!msg) return E_POINTER;
965 if (size < sizeof(DMUS_PMSG)) return E_INVALIDARG;
966
967 if (!(message = calloc(1, size - sizeof(DMUS_PMSG) + sizeof(struct message)))) return E_OUTOFMEMORY;
968 message->msg.dwSize = size;
970 *msg = &message->msg;
971
972 return S_OK;
973}
974
975static HRESULT WINAPI performance_FreePMsg(IDirectMusicPerformance8 *iface, DMUS_PMSG *msg)
976{
978 struct message *message;
979 HRESULT hr;
980
981 TRACE("(%p, %p)\n", This, msg);
982
984
988
989 if (SUCCEEDED(hr))
990 {
991 if (msg->pTool) IDirectMusicTool_Release(msg->pTool);
992 if (msg->pGraph) IDirectMusicGraph_Release(msg->pGraph);
993 if (msg->punkUser) IUnknown_Release(msg->punkUser);
994 free(message);
995 }
996
997 return hr;
998}
999
1000static HRESULT WINAPI performance_GetGraph(IDirectMusicPerformance8 *iface, IDirectMusicGraph **graph)
1001{
1003
1004 TRACE("(%p, %p)\n", This, graph);
1005
1006 if (!graph)
1007 return E_POINTER;
1008
1009 *graph = This->pToolGraph;
1010 if (This->pToolGraph) {
1012 }
1013
1014 return *graph ? S_OK : DMUS_E_NOT_FOUND;
1015}
1016
1017static HRESULT WINAPI performance_SetGraph(IDirectMusicPerformance8 *iface, IDirectMusicGraph *pGraph)
1018{
1020
1021 FIXME("(%p, %p): to check\n", This, pGraph);
1022
1023 if (NULL != This->pToolGraph) {
1024 /* Todo clean buffers and tools before */
1025 IDirectMusicGraph_Release(This->pToolGraph);
1026 }
1027 This->pToolGraph = pGraph;
1028 if (NULL != This->pToolGraph) {
1029 IDirectMusicGraph_AddRef(This->pToolGraph);
1030 }
1031 return S_OK;
1032}
1033
1034static HRESULT WINAPI performance_SetNotificationHandle(IDirectMusicPerformance8 *iface,
1036{
1038
1039 TRACE("(%p, %p, %I64d)\n", This, notification_event, minimum_time);
1040
1041 This->notification_event = notification_event;
1042 if (minimum_time)
1043 This->notification_timeout = minimum_time;
1044 else if (!This->notification_timeout)
1045 This->notification_timeout = 20000000; /* 2 seconds */
1046
1047 return S_OK;
1048}
1049
1050static HRESULT WINAPI performance_GetNotificationPMsg(IDirectMusicPerformance8 *iface,
1051 DMUS_NOTIFICATION_PMSG **ret_msg)
1052{
1054 struct list *entry;
1055
1056 TRACE("(%p, %p)\n", This, ret_msg);
1057
1058 if (!ret_msg) return E_POINTER;
1059
1060 EnterCriticalSection(&This->safe);
1061 if ((entry = list_head(&This->notifications)))
1062 {
1063 struct message *message = LIST_ENTRY(entry, struct message, entry);
1066 *ret_msg = (DMUS_NOTIFICATION_PMSG *)&message->msg;
1067 }
1068 LeaveCriticalSection(&This->safe);
1069
1070 return entry ? S_OK : S_FALSE;
1071}
1072
1073static HRESULT WINAPI performance_AddNotificationType(IDirectMusicPerformance8 *iface, REFGUID type)
1074{
1076 HRESULT hr = S_OK;
1077
1078 FIXME("(%p, %s): stub\n", This, debugstr_dmguid(type));
1079
1080 if (IsEqualGUID(type, &GUID_NOTIFICATION_PERFORMANCE))
1081 {
1082 hr = This->notification_performance ? S_FALSE : S_OK;
1083 This->notification_performance = TRUE;
1084 }
1085 if (IsEqualGUID(type, &GUID_NOTIFICATION_SEGMENT))
1086 {
1087 hr = This->notification_segment ? S_FALSE : S_OK;
1088 This->notification_segment = TRUE;
1089 }
1090
1091 return hr;
1092}
1093
1094static HRESULT WINAPI performance_RemoveNotificationType(IDirectMusicPerformance8 *iface, REFGUID type)
1095{
1097 HRESULT hr = S_FALSE;
1098
1099 FIXME("(%p, %s): stub\n", This, debugstr_dmguid(type));
1100
1101 if (IsEqualGUID(type, &GUID_NOTIFICATION_PERFORMANCE))
1102 {
1103 hr = This->notification_performance ? S_OK : S_FALSE;
1104 This->notification_performance = FALSE;
1105 }
1106 if (IsEqualGUID(type, &GUID_NOTIFICATION_SEGMENT))
1107 {
1108 hr = This->notification_segment ? S_OK : S_FALSE;
1109 This->notification_segment = FALSE;
1110 }
1111
1112 return hr;
1113}
1114
1115static void performance_update_latency_time(struct performance *This, IDirectMusicPort *port,
1116 REFERENCE_TIME *ret_time)
1117{
1118 IDirectMusicPerformance8 *iface = &This->IDirectMusicPerformance8_iface;
1119 REFERENCE_TIME latency_time, current_time;
1120 IReferenceClock *latency_clock;
1121 HRESULT hr;
1122
1123 if (!ret_time) ret_time = &latency_time;
1124 if (SUCCEEDED(hr = IDirectMusicPort_GetLatencyClock(port, &latency_clock)))
1125 {
1126 hr = IReferenceClock_GetTime(latency_clock, ret_time);
1127 if (SUCCEEDED(hr)) hr = IDirectMusicPerformance8_GetTime(iface, &current_time, NULL);
1128 if (SUCCEEDED(hr) && This->latency_offset < (*ret_time - current_time))
1129 {
1130 TRACE("Updating performance %p latency %I64d -> %I64d\n", This,
1131 This->latency_offset, *ret_time - current_time);
1132 This->latency_offset = *ret_time - current_time;
1133 }
1134 IReferenceClock_Release(latency_clock);
1135 }
1136
1137 if (FAILED(hr)) ERR("Failed to update performance %p latency, hr %#lx\n", This, hr);
1138}
1139
1141{
1142 IDirectMusicPort *port;
1143 GUID guid;
1144 unsigned int i;
1145 HRESULT hr;
1146
1148 return hr;
1149
1151 return hr;
1152
1155 {
1157 return hr;
1158 }
1159
1161
1162 for (i = 0; i < params->dwChannelGroups; i++)
1163 {
1164 if (FAILED(hr = channel_block_init(perf, i, port, i + 1)))
1165 ERR("Failed to init channel block, hr %#lx\n", hr);
1166 }
1167
1170 return S_OK;
1171}
1172
1173static HRESULT WINAPI performance_AddPort(IDirectMusicPerformance8 *iface, IDirectMusicPort *port)
1174{
1176
1177 FIXME("(%p, %p): semi-stub\n", This, port);
1178
1179 if (!This->dmusic) return DMUS_E_NOT_INIT;
1180 if (This->audio_paths_enabled) return DMUS_E_AUDIOPATHS_IN_USE;
1181
1182 if (!port) {
1184 .dwSize = sizeof(params),
1185 .dwValidParams = DMUS_PORTPARAMS_CHANNELGROUPS,
1186 .dwChannelGroups = 1
1187 };
1188
1189 return perf_dmport_create(This, &params);
1190 }
1191
1199 return S_OK;
1200}
1201
1202static HRESULT WINAPI performance_RemovePort(IDirectMusicPerformance8 *iface, IDirectMusicPort *pPort)
1203{
1205
1206 if (This->audio_paths_enabled) return DMUS_E_AUDIOPATHS_IN_USE;
1207
1208 FIXME("(%p, %p): stub\n", This, pPort);
1210 return S_OK;
1211}
1212
1213static HRESULT WINAPI performance_AssignPChannelBlock(IDirectMusicPerformance8 *iface,
1214 DWORD block_num, IDirectMusicPort *port, DWORD midi_group)
1215{
1217
1218 FIXME("(%p, %ld, %p, %ld): semi-stub\n", This, block_num, port, midi_group);
1219
1220 if (!port) return E_POINTER;
1221 if (block_num > MAXDWORD / 16) return E_INVALIDARG;
1222 if (This->audio_paths_enabled) return DMUS_E_AUDIOPATHS_IN_USE;
1223
1224 return channel_block_init(This, block_num, port, midi_group);
1225}
1226
1227static HRESULT WINAPI performance_AssignPChannel(IDirectMusicPerformance8 *iface, DWORD channel_num,
1228 IDirectMusicPort *port, DWORD midi_group, DWORD midi_channel)
1229{
1231 struct channel *channel;
1232 HRESULT hr;
1233
1234 FIXME("(%p)->(%ld, %p, %ld, %ld) semi-stub\n", This, channel_num, port, midi_group, midi_channel);
1235
1236 if (!port) return E_POINTER;
1237 if (This->audio_paths_enabled) return DMUS_E_AUDIOPATHS_IN_USE;
1238
1239 if (!(channel = performance_get_channel(This, channel_num)))
1240 {
1242 channel_num / 16, port, 0)))
1243 return hr;
1244 if (!(channel = performance_get_channel(This, channel_num)))
1245 return DMUS_E_NOT_FOUND;
1246 }
1247
1252
1253 return S_OK;
1254}
1255
1256static HRESULT WINAPI performance_PChannelInfo(IDirectMusicPerformance8 *iface, DWORD channel_num,
1257 IDirectMusicPort **port, DWORD *midi_group, DWORD *midi_channel)
1258{
1260 struct channel *channel;
1261
1262 TRACE("(%p)->(%ld, %p, %p, %p)\n", This, channel_num, port, midi_group, midi_channel);
1263
1264 if (!(channel = performance_get_channel(This, channel_num))) return E_INVALIDARG;
1265 if (port)
1266 {
1267 *port = channel->port;
1269 }
1272
1273 return S_OK;
1274}
1275
1276static HRESULT WINAPI performance_DownloadInstrument(IDirectMusicPerformance8 *iface,
1277 IDirectMusicInstrument *instrument, DWORD port_channel,
1278 IDirectMusicDownloadedInstrument **downloaded, DMUS_NOTERANGE *note_ranges,
1279 DWORD note_range_count, IDirectMusicPort **port, DWORD *group, DWORD *music_channel)
1280{
1282 IDirectMusicPort *tmp_port = NULL;
1283 HRESULT hr;
1284
1285 TRACE("(%p, %p, %ld, %p, %p, %ld, %p, %p, %p)\n", This, instrument, port_channel, downloaded,
1286 note_ranges, note_range_count, port, group, music_channel);
1287
1288 if (!port) port = &tmp_port;
1289 if (FAILED(hr = IDirectMusicPerformance_PChannelInfo(iface, port_channel, port, group, music_channel)))
1290 return hr;
1291
1292 hr = IDirectMusicPort_DownloadInstrument(*port, instrument, downloaded, note_ranges, note_range_count);
1293 if (tmp_port) IDirectMusicPort_Release(tmp_port);
1294 return hr;
1295}
1296
1297static HRESULT WINAPI performance_Invalidate(IDirectMusicPerformance8 *iface, MUSIC_TIME mtTime, DWORD dwFlags)
1298{
1300
1301 FIXME("(%p, %ld, %ld): stub\n", This, mtTime, dwFlags);
1302 return S_OK;
1303}
1304
1305static HRESULT WINAPI performance_GetParam(IDirectMusicPerformance8 *iface, REFGUID type,
1306 DWORD group, DWORD index, MUSIC_TIME music_time, MUSIC_TIME *next_time, void *param)
1307{
1309 HRESULT hr;
1310
1311 TRACE("(%p, %s, %ld, %ld, %ld, %p, %p)\n", This, debugstr_dmguid(type), group, index, music_time, next_time, param);
1312
1313 if (next_time) *next_time = 0;
1314
1315 if (!This->control_segment) hr = DMUS_E_NOT_FOUND;
1316 else hr = IDirectMusicSegment_GetParam(This->control_segment, type, group, index, music_time, next_time, param);
1317
1318 if (FAILED(hr))
1319 {
1320 if (!This->primary_segment) hr = DMUS_E_NOT_FOUND;
1321 else hr = IDirectMusicSegment_GetParam(This->primary_segment, type, group, index, music_time, next_time, param);
1322 }
1323
1324 return hr;
1325}
1326
1327static HRESULT WINAPI performance_SetParam(IDirectMusicPerformance8 *iface, REFGUID rguidType,
1328 DWORD dwGroupBits, DWORD dwIndex, MUSIC_TIME mtTime, void *pParam)
1329{
1331
1332 FIXME("(%p, %s, %ld, %ld, %ld, %p): stub\n", This, debugstr_dmguid(rguidType), dwGroupBits, dwIndex, mtTime, pParam);
1333 return S_OK;
1334}
1335
1336static HRESULT WINAPI performance_GetGlobalParam(IDirectMusicPerformance8 *iface, REFGUID rguidType,
1337 void *pParam, DWORD dwSize)
1338{
1340
1341 TRACE("(%p, %s, %p, %ld): stub\n", This, debugstr_dmguid(rguidType), pParam, dwSize);
1342
1343 if (IsEqualGUID (rguidType, &GUID_PerfAutoDownload))
1344 memcpy(pParam, &This->fAutoDownload, sizeof(This->fAutoDownload));
1345 if (IsEqualGUID (rguidType, &GUID_PerfMasterGrooveLevel))
1346 memcpy(pParam, &This->cMasterGrooveLevel, sizeof(This->cMasterGrooveLevel));
1347 if (IsEqualGUID (rguidType, &GUID_PerfMasterTempo))
1348 memcpy(pParam, &This->fMasterTempo, sizeof(This->fMasterTempo));
1349 if (IsEqualGUID (rguidType, &GUID_PerfMasterVolume))
1350 memcpy(pParam, &This->lMasterVolume, sizeof(This->lMasterVolume));
1351
1352 return S_OK;
1353}
1354
1355static HRESULT WINAPI performance_SetGlobalParam(IDirectMusicPerformance8 *iface, REFGUID rguidType,
1356 void *pParam, DWORD dwSize)
1357{
1359
1360 TRACE("(%p, %s, %p, %ld)\n", This, debugstr_dmguid(rguidType), pParam, dwSize);
1361
1362 if (IsEqualGUID (rguidType, &GUID_PerfAutoDownload)) {
1363 memcpy(&This->fAutoDownload, pParam, dwSize);
1364 TRACE("=> AutoDownload set to %d\n", This->fAutoDownload);
1365 }
1366 if (IsEqualGUID (rguidType, &GUID_PerfMasterGrooveLevel)) {
1367 memcpy(&This->cMasterGrooveLevel, pParam, dwSize);
1368 TRACE("=> MasterGrooveLevel set to %i\n", This->cMasterGrooveLevel);
1369 }
1370 if (IsEqualGUID (rguidType, &GUID_PerfMasterTempo)) {
1371 memcpy(&This->fMasterTempo, pParam, dwSize);
1372 TRACE("=> MasterTempo set to %f\n", This->fMasterTempo);
1373 }
1374 if (IsEqualGUID (rguidType, &GUID_PerfMasterVolume)) {
1375 memcpy(&This->lMasterVolume, pParam, dwSize);
1376 TRACE("=> MasterVolume set to %li\n", This->lMasterVolume);
1377 }
1378
1379 return S_OK;
1380}
1381
1382static HRESULT WINAPI performance_GetLatencyTime(IDirectMusicPerformance8 *iface, REFERENCE_TIME *ret_time)
1383{
1385 REFERENCE_TIME current_time;
1386 HRESULT hr;
1387
1388 TRACE("(%p, %p)\n", This, ret_time);
1389
1390 if (SUCCEEDED(hr = IDirectMusicPerformance8_GetTime(iface, &current_time, NULL)))
1391 *ret_time = current_time + This->latency_offset;
1392
1393 return hr;
1394}
1395
1396static HRESULT WINAPI performance_GetQueueTime(IDirectMusicPerformance8 *iface, REFERENCE_TIME *prtTime)
1397
1398{
1400
1401 FIXME("(%p, %p): stub\n", This, prtTime);
1402 return S_OK;
1403}
1404
1405static HRESULT WINAPI performance_AdjustTime(IDirectMusicPerformance8 *iface, REFERENCE_TIME rtAmount)
1406{
1408
1409 FIXME("(%p, 0x%s): stub\n", This, wine_dbgstr_longlong(rtAmount));
1410 return S_OK;
1411}
1412
1413static HRESULT WINAPI performance_CloseDown(IDirectMusicPerformance8 *iface)
1414{
1416 struct list states = LIST_INIT(states);
1417 struct state_entry *entry, *next;
1418 DMUS_PMSG msg = {.mtTime = -1};
1420 HRESULT hr;
1421
1422 FIXME("(%p): semi-stub\n", This);
1423
1424 if ((message_thread = This->message_thread))
1425 {
1426 EnterCriticalSection(&This->safe);
1427 This->message_thread = NULL;
1428 LeaveCriticalSection(&This->safe);
1430
1433 }
1434
1435 This->notification_performance = FALSE;
1436 This->notification_segment = FALSE;
1437
1438 enum_segment_states(This, NULL, &states);
1440
1442 {
1443 if (FAILED(hr = segment_state_end_play(entry->state, iface)))
1444 ERR("Failed to stop segment state, hr %#lx\n", hr);
1445
1447 list_remove(&entry->entry);
1448 free(entry);
1449 }
1450
1452 MIDI_SYSTEM_RESET, 0, 0)))
1453 ERR("Failed to send MIDI_SYSTEM_RESET message, hr %#lx\n", hr);
1454
1457
1458 if (This->master_clock)
1459 {
1460 IReferenceClock_Release(This->master_clock);
1461 This->master_clock = NULL;
1462 }
1463 if (This->dsound) {
1464 IDirectSound_Release(This->dsound);
1465 This->dsound = NULL;
1466 }
1467 if (This->dmusic) {
1469 IDirectMusic8_Release(This->dmusic);
1470 This->dmusic = NULL;
1471 }
1472 This->audio_paths_enabled = FALSE;
1473
1474 return S_OK;
1475}
1476
1477static HRESULT WINAPI performance_GetResolvedTime(IDirectMusicPerformance8 *iface,
1478 REFERENCE_TIME rtTime, REFERENCE_TIME *prtResolved, DWORD dwTimeResolveFlags)
1479{
1481
1482 FIXME("(%p, 0x%s, %p, %ld): stub\n", This, wine_dbgstr_longlong(rtTime),
1483 prtResolved, dwTimeResolveFlags);
1484 return S_OK;
1485}
1486
1487static HRESULT WINAPI performance_MIDIToMusic(IDirectMusicPerformance8 *iface, BYTE bMIDIValue,
1488 DMUS_CHORD_KEY *pChord, BYTE bPlayMode, BYTE bChordLevel, WORD *pwMusicValue)
1489{
1491
1492 FIXME("(%p, %d, %p, %d, %d, %p): stub\n", This, bMIDIValue, pChord, bPlayMode, bChordLevel, pwMusicValue);
1493 return S_OK;
1494}
1495
1496static HRESULT WINAPI performance_MusicToMIDI(IDirectMusicPerformance8 *iface, WORD wMusicValue,
1497 DMUS_CHORD_KEY *pChord, BYTE bPlayMode, BYTE bChordLevel, BYTE *pbMIDIValue)
1498{
1500
1501 FIXME("(%p, %d, %p, %d, %d, %p): stub\n", This, wMusicValue, pChord, bPlayMode, bChordLevel, pbMIDIValue);
1502 return S_OK;
1503}
1504
1505static HRESULT WINAPI performance_TimeToRhythm(IDirectMusicPerformance8 *iface, MUSIC_TIME mtTime,
1506 DMUS_TIMESIGNATURE *pTimeSig, WORD *pwMeasure, BYTE *pbBeat, BYTE *pbGrid, short *pnOffset)
1507{
1509
1510 FIXME("(%p, %ld, %p, %p, %p, %p, %p): stub\n", This, mtTime, pTimeSig, pwMeasure, pbBeat, pbGrid, pnOffset);
1511 return S_OK;
1512}
1513
1514static HRESULT WINAPI performance_RhythmToTime(IDirectMusicPerformance8 *iface, WORD wMeasure,
1515 BYTE bBeat, BYTE bGrid, short nOffset, DMUS_TIMESIGNATURE *pTimeSig, MUSIC_TIME *pmtTime)
1516{
1518
1519 FIXME("(%p, %d, %d, %d, %i, %p, %p): stub\n", This, wMeasure, bBeat, bGrid, nOffset, pTimeSig, pmtTime);
1520 return S_OK;
1521}
1522
1523/* IDirectMusicPerformance8 Interface part follow: */
1524static HRESULT WINAPI performance_InitAudio(IDirectMusicPerformance8 *iface, IDirectMusic **dmusic,
1525 IDirectSound **dsound, HWND hwnd, DWORD default_path_type, DWORD num_channels, DWORD flags,
1527{
1529 HRESULT hr = S_OK;
1530
1531 TRACE("(%p, %p, %p, %p, %lx, %lu, %lx, %p)\n", This, dmusic, dsound, hwnd, default_path_type,
1532 num_channels, flags, params);
1533
1534 if (flags) FIXME("flags parameter not used\n");
1535 if (params) FIXME("params parameter not used\n");
1536
1538 dsound ? *dsound : NULL, hwnd)))
1539 return hr;
1540
1541 This->audio_paths_enabled = TRUE;
1542 if (default_path_type)
1543 {
1544 hr = IDirectMusicPerformance8_CreateStandardAudioPath(iface, default_path_type,
1545 num_channels, FALSE, &This->pDefaultPath);
1546 if (FAILED(hr))
1547 {
1549 return hr;
1550 }
1551 }
1552
1553 if (dsound && !*dsound) {
1554 *dsound = This->dsound;
1556 }
1557 if (dmusic && !*dmusic) {
1558 *dmusic = This->dmusic;
1560 }
1561
1562 return S_OK;
1563}
1564
1565static HRESULT WINAPI performance_PlaySegmentEx(IDirectMusicPerformance8 *iface, IUnknown *source,
1566 WCHAR *segment_name, IUnknown *transition, DWORD segment_flags, INT64 start_time,
1567 IDirectMusicSegmentState **segment_state, IUnknown *from, IUnknown *audio_path)
1568{
1569 BOOL primary = !(segment_flags & DMUS_SEGF_SECONDARY), control = (segment_flags & DMUS_SEGF_CONTROL);
1571 IDirectMusicSegmentState *state;
1572 IDirectMusicSegment *segment;
1573 MUSIC_TIME music_time;
1574 HRESULT hr;
1575
1576 FIXME("(%p, %p, %s, %p, %#lx, %I64d, %p, %p, %p): stub\n", This, source, debugstr_w(segment_name),
1577 transition, segment_flags, start_time, segment_state, from, audio_path);
1578
1579 /* NOTE: The time is in music time unless the DMUS_SEGF_REFTIME flag is set. */
1580 if (segment_flags) FIXME("flags %#lx not implemented\n", segment_flags);
1581 if (start_time) FIXME("start_time %I64d not implemented\n", start_time);
1582
1583 if (FAILED(hr = IUnknown_QueryInterface(source, &IID_IDirectMusicSegment, (void **)&segment)))
1584 return hr;
1585
1586 EnterCriticalSection(&This->safe);
1587
1590
1591 if ((!(music_time = start_time) && FAILED(hr = IDirectMusicPerformance8_GetTime(iface, NULL, &music_time)))
1592 || FAILED(hr = segment_state_create(segment, music_time, iface, &state)))
1593 {
1596 LeaveCriticalSection(&This->safe);
1597
1599 return hr;
1600 }
1601
1602 if (FAILED(hr = segment_state_play(state, iface)))
1603 {
1604 ERR("Failed to play segment state, hr %#lx\n", hr);
1607 }
1608 else if (segment_state)
1609 {
1612 }
1613
1614 LeaveCriticalSection(&This->safe);
1615
1618 return hr;
1619}
1620
1621static HRESULT WINAPI performance_StopEx(IDirectMusicPerformance8 *iface, IUnknown *pObjectToStop,
1622 __int64 i64StopTime, DWORD dwFlags)
1623{
1625
1626 FIXME("(%p, %p, 0x%s, %ld): stub\n", This, pObjectToStop,
1627 wine_dbgstr_longlong(i64StopTime), dwFlags);
1628 return S_OK;
1629}
1630
1631static HRESULT WINAPI performance_ClonePMsg(IDirectMusicPerformance8 *iface, DMUS_PMSG *msg, DMUS_PMSG **clone)
1632{
1634 HRESULT hr;
1635
1636 TRACE("(%p, %p, %p)\n", This, msg, clone);
1637
1638 if (!msg || !clone) return E_POINTER;
1639 if (FAILED(hr = IDirectMusicPerformance8_AllocPMsg(iface, msg->dwSize, clone))) return hr;
1640
1641 memcpy(*clone, msg, msg->dwSize);
1642 if (msg->pTool) IDirectMusicTool_AddRef(msg->pTool);
1643 if (msg->pGraph) IDirectMusicGraph_AddRef(msg->pGraph);
1644 if (msg->punkUser) IUnknown_AddRef(msg->punkUser);
1645
1646 return S_OK;
1647}
1648
1649static HRESULT WINAPI performance_CreateAudioPath(IDirectMusicPerformance8 *iface,
1650 IUnknown *pSourceConfig, BOOL fActivate, IDirectMusicAudioPath **ret_iface)
1651{
1653 IDirectMusicAudioPath *pPath;
1654 IDirectMusicObject *dmo;
1655 IDirectSoundBuffer *buffer, *primary_buffer;
1656 DMUS_OBJECTDESC objDesc;
1657 DMUS_PORTPARAMS8 port_params;
1658 HRESULT hr;
1661
1662 FIXME("(%p, %p, %d, %p): semi-stub\n", This, pSourceConfig, fActivate, ret_iface);
1663
1664 if (!ret_iface || !pSourceConfig) return E_POINTER;
1665 if (!This->audio_paths_enabled) return DMUS_E_AUDIOPATH_INACTIVE;
1666
1667 hr = IUnknown_QueryInterface(pSourceConfig, &IID_IDirectMusicObject, (void **)&dmo);
1668 if (FAILED(hr))
1669 return hr;
1670
1671 hr = IDirectMusicObject_GetDescriptor(dmo, &objDesc);
1673 if (FAILED(hr))
1674 return hr;
1675
1676 if (!IsEqualCLSID(&objDesc.guidClass, &CLSID_DirectMusicAudioPathConfig))
1677 {
1678 ERR("Unexpected object class %s for source config.\n", debugstr_dmguid(&objDesc.guidClass));
1679 return E_INVALIDARG;
1680 }
1681
1682 hr = path_config_get_audio_path_params(pSourceConfig, &format, &desc, &port_params);
1683 if (FAILED(hr))
1684 return hr;
1685
1686 hr = perf_dmport_create(This, &port_params);
1687 if (FAILED(hr))
1688 return hr;
1689
1691 if (FAILED(hr))
1692 return DSERR_BUFFERLOST;
1693
1694 /* Update description for creating primary buffer */
1695 desc.dwFlags |= DSBCAPS_PRIMARYBUFFER;
1696 desc.dwFlags &= ~DSBCAPS_CTRLFX;
1697 desc.dwBufferBytes = 0;
1698 desc.lpwfxFormat = NULL;
1699
1700 hr = IDirectSound_CreateSoundBuffer(This->dsound, &desc, &primary_buffer, NULL);
1701 if (FAILED(hr))
1702 {
1704 return DSERR_BUFFERLOST;
1705 }
1706
1707 create_dmaudiopath(&IID_IDirectMusicAudioPath, (void **)&pPath);
1708 set_audiopath_perf_pointer(pPath, iface);
1710 set_audiopath_primary_dsound_buffer(pPath, primary_buffer);
1711 TRACE(" returning IDirectMusicAudioPath interface at %p.\n", *ret_iface);
1712
1713 *ret_iface = pPath;
1714 return IDirectMusicAudioPath_Activate(*ret_iface, fActivate);
1715}
1716
1717static HRESULT WINAPI performance_CreateStandardAudioPath(IDirectMusicPerformance8 *iface,
1718 DWORD dwType, DWORD pchannel_count, BOOL fActivate, IDirectMusicAudioPath **ret_iface)
1719{
1721 IDirectMusicAudioPath *pPath;
1724 DMUS_PORTPARAMS params = {0};
1725 IDirectSoundBuffer *buffer, *primary_buffer;
1726 HRESULT hr = S_OK;
1727
1728 FIXME("(%p)->(%ld, %ld, %d, %p): semi-stub\n", This, dwType, pchannel_count, fActivate, ret_iface);
1729
1730 if (!ret_iface) return E_POINTER;
1731 if (!This->audio_paths_enabled) return DMUS_E_AUDIOPATH_INACTIVE;
1732
1733 *ret_iface = NULL;
1734
1735 /* Secondary buffer description */
1736 memset(&format, 0, sizeof(format));
1737 format.wFormatTag = WAVE_FORMAT_PCM;
1738 format.nChannels = 1;
1739 format.nSamplesPerSec = 44000;
1740 format.nAvgBytesPerSec = 44000*2;
1741 format.nBlockAlign = 2;
1742 format.wBitsPerSample = 16;
1743 format.cbSize = 0;
1744
1745 memset(&desc, 0, sizeof(desc));
1746 desc.dwSize = sizeof(desc);
1748 desc.dwBufferBytes = DSBSIZE_MIN;
1749 desc.dwReserved = 0;
1750 desc.lpwfxFormat = &format;
1751 desc.guid3DAlgorithm = GUID_NULL;
1752
1753 switch(dwType) {
1756 break;
1759 break;
1761 /* normally we have to create 2 buffers (one for music other for reverb)
1762 * in this case. See msdn
1763 */
1766 format.nChannels = 2;
1767 format.nBlockAlign *= 2;
1768 format.nAvgBytesPerSec *=2;
1769 break;
1770 default:
1771 return E_INVALIDARG;
1772 }
1773
1774 /* Create a port */
1775 params.dwSize = sizeof(params);
1777 params.dwChannelGroups = (pchannel_count + 15) / 16;
1778 params.dwAudioChannels = format.nChannels;
1780 return hr;
1781
1783 if (FAILED(hr))
1784 return DSERR_BUFFERLOST;
1785
1786 /* Update description for creating primary buffer */
1787 desc.dwFlags |= DSBCAPS_PRIMARYBUFFER;
1788 desc.dwFlags &= ~DSBCAPS_CTRLFX;
1789 desc.dwBufferBytes = 0;
1790 desc.lpwfxFormat = NULL;
1791
1792 hr = IDirectSound_CreateSoundBuffer(This->dsound, &desc, &primary_buffer, NULL);
1793 if (FAILED(hr)) {
1795 return DSERR_BUFFERLOST;
1796 }
1797
1798 create_dmaudiopath(&IID_IDirectMusicAudioPath, (void**)&pPath);
1799 set_audiopath_perf_pointer(pPath, iface);
1801 set_audiopath_primary_dsound_buffer(pPath, primary_buffer);
1802
1803 *ret_iface = pPath;
1804 TRACE(" returning IDirectMusicAudioPath interface at %p.\n", *ret_iface);
1805 return IDirectMusicAudioPath_Activate(*ret_iface, fActivate);
1806}
1807
1808static HRESULT WINAPI performance_SetDefaultAudioPath(IDirectMusicPerformance8 *iface, IDirectMusicAudioPath *audio_path)
1809{
1811
1812 FIXME("(%p, %p): semi-stub\n", This, audio_path);
1813
1814 if (!This->audio_paths_enabled) return DMUS_E_AUDIOPATH_INACTIVE;
1815
1816 if (This->pDefaultPath) IDirectMusicAudioPath_Release(This->pDefaultPath);
1817 if ((This->pDefaultPath = audio_path))
1818 {
1819 IDirectMusicAudioPath_AddRef(This->pDefaultPath);
1820 set_audiopath_perf_pointer(This->pDefaultPath, iface);
1821 }
1822
1823 return S_OK;
1824}
1825
1826static HRESULT WINAPI performance_GetDefaultAudioPath(IDirectMusicPerformance8 *iface,
1827 IDirectMusicAudioPath **ret_iface)
1828{
1830
1831 FIXME("(%p, %p): semi-stub (%p)\n", This, ret_iface, This->pDefaultPath);
1832
1833 if (!ret_iface) return E_POINTER;
1834 if (!This->audio_paths_enabled) return DMUS_E_AUDIOPATH_INACTIVE;
1835
1836 if ((*ret_iface = This->pDefaultPath)) IDirectMusicAudioPath_AddRef(*ret_iface);
1837
1838 return S_OK;
1839}
1840
1841static HRESULT WINAPI performance_GetParamEx(IDirectMusicPerformance8 *iface, REFGUID rguidType, DWORD dwTrackID,
1842 DWORD dwGroupBits, DWORD dwIndex, MUSIC_TIME mtTime, MUSIC_TIME *pmtNext, void *pParam)
1843{
1845
1846 FIXME("(%p, %s, %ld, %ld, %ld, %ld, %p, %p): stub\n", This, debugstr_dmguid(rguidType), dwTrackID, dwGroupBits, dwIndex, mtTime, pmtNext, pParam);
1847
1848 return S_OK;
1849}
1850
1851static const IDirectMusicPerformance8Vtbl performance_vtbl =
1852{
1906};
1907
1908static inline struct performance *impl_from_IDirectMusicGraph(IDirectMusicGraph *iface)
1909{
1911}
1912
1913static HRESULT WINAPI performance_graph_QueryInterface(IDirectMusicGraph *iface, REFIID riid, void **ret_iface)
1914{
1916 return IDirectMusicPerformance8_QueryInterface(&This->IDirectMusicPerformance8_iface, riid, ret_iface);
1917}
1918
1919static ULONG WINAPI performance_graph_AddRef(IDirectMusicGraph *iface)
1920{
1922 return IDirectMusicPerformance8_AddRef(&This->IDirectMusicPerformance8_iface);
1923}
1924
1925static ULONG WINAPI performance_graph_Release(IDirectMusicGraph *iface)
1926{
1928 return IDirectMusicPerformance8_Release(&This->IDirectMusicPerformance8_iface);
1929}
1930
1931static HRESULT WINAPI performance_graph_StampPMsg(IDirectMusicGraph *iface, DMUS_PMSG *msg)
1932{
1934 HRESULT hr;
1935
1936 TRACE("(%p, %p)\n", This, msg);
1937
1938 if (!msg) return E_POINTER;
1939
1940 /* FIXME: Implement segment and audio path graphs support */
1941 if (!This->pToolGraph) hr = DMUS_S_LAST_TOOL;
1942 else if (FAILED(hr = IDirectMusicGraph_StampPMsg(This->pToolGraph, msg))) return hr;
1943
1944 if (msg->pGraph)
1945 {
1947 msg->pGraph = NULL;
1948 }
1949
1950 if (hr == DMUS_S_LAST_TOOL)
1951 {
1953 msg->dwFlags &= ~delivery_flags;
1954 msg->dwFlags |= DMUS_PMSGF_TOOL_QUEUE;
1955
1956 if (msg->pTool) IDirectMusicTool_Release(msg->pTool);
1957 msg->pTool = &This->IDirectMusicTool_iface;
1959 return S_OK;
1960 }
1961
1962 if (SUCCEEDED(hr))
1963 {
1964 msg->pGraph = &This->IDirectMusicGraph_iface;
1966 }
1967
1968 return hr;
1969}
1970
1971static HRESULT WINAPI performance_graph_InsertTool(IDirectMusicGraph *iface, IDirectMusicTool *tool,
1972 DWORD *channels, DWORD channels_count, LONG index)
1973{
1975 TRACE("(%p, %p, %p, %lu, %ld)\n", This, tool, channels, channels_count, index);
1976 return E_NOTIMPL;
1977}
1978
1979static HRESULT WINAPI performance_graph_GetTool(IDirectMusicGraph *iface, DWORD index, IDirectMusicTool **tool)
1980{
1982 TRACE("(%p, %lu, %p)\n", This, index, tool);
1983 return E_NOTIMPL;
1984}
1985
1986static HRESULT WINAPI performance_graph_RemoveTool(IDirectMusicGraph *iface, IDirectMusicTool *tool)
1987{
1989 TRACE("(%p, %p)\n", This, tool);
1990 return E_NOTIMPL;
1991}
1992
1993static const IDirectMusicGraphVtbl performance_graph_vtbl =
1994{
2002};
2003
2004static inline struct performance *impl_from_IDirectMusicTool(IDirectMusicTool *iface)
2005{
2007}
2008
2009static HRESULT WINAPI performance_tool_QueryInterface(IDirectMusicTool *iface, REFIID riid, void **ret_iface)
2010{
2012 return IDirectMusicPerformance8_QueryInterface(&This->IDirectMusicPerformance8_iface, riid, ret_iface);
2013}
2014
2015static ULONG WINAPI performance_tool_AddRef(IDirectMusicTool *iface)
2016{
2018 return IDirectMusicPerformance8_AddRef(&This->IDirectMusicPerformance8_iface);
2019}
2020
2021static ULONG WINAPI performance_tool_Release(IDirectMusicTool *iface)
2022{
2024 return IDirectMusicPerformance8_Release(&This->IDirectMusicPerformance8_iface);
2025}
2026
2027static HRESULT WINAPI performance_tool_Init(IDirectMusicTool *iface, IDirectMusicGraph *graph)
2028{
2030 TRACE("(%p, %p)\n", This, graph);
2031 return E_NOTIMPL;
2032}
2033
2035{
2037 TRACE("(%p, %p)\n", This, type);
2039 return S_OK;
2040}
2041
2043{
2045 TRACE("(%p, %p)\n", This, size);
2046 *size = 0;
2047 return S_OK;
2048}
2049
2051{
2053 TRACE("(%p, %p, %lu)\n", This, types, size);
2054 return E_NOTIMPL;
2055}
2056
2057static HRESULT WINAPI performance_tool_ProcessPMsg(IDirectMusicTool *iface,
2058 IDirectMusicPerformance *performance, DMUS_PMSG *msg)
2059{
2062 HRESULT hr;
2063
2064 TRACE("(%p, %p, %p)\n", This, performance, msg);
2065
2066 switch (msg->dwType)
2067 {
2068 case DMUS_PMSGT_MIDI:
2069 {
2070 static const UINT event_size = sizeof(DMUS_EVENTHEADER) + sizeof(DWORD);
2071 DMUS_BUFFERDESC desc = {.dwSize = sizeof(desc), .cbBuffer = 2 * event_size};
2073 REFERENCE_TIME latency_time;
2074 IDirectMusicBuffer *buffer;
2075 IDirectMusicPort *port;
2077 UINT value = 0;
2078
2080 &port, &group, &channel)))
2081 {
2082 WARN("Failed to get message port, hr %#lx\n", hr);
2083 return DMUS_S_FREE;
2084 }
2085 performance_update_latency_time(This, port, &latency_time);
2086
2087 value |= channel;
2088 value |= (UINT)midi->bStatus;
2089 value |= (UINT)midi->bByte1 << 8;
2090 value |= (UINT)midi->bByte2 << 16;
2091
2093 {
2094 if (msg->rtTime == -1) msg->rtTime = latency_time;
2098 }
2099
2101 break;
2102 }
2103
2104 case DMUS_PMSGT_NOTE:
2105 {
2107
2108 msg->mtTime += note->nOffset;
2109
2110 if (note->bFlags & DMUS_NOTEF_NOTEON)
2111 {
2113 MIDI_NOTE_ON, note->bMidiValue, note->bVelocity)))
2114 WARN("Failed to translate message to MIDI, hr %#lx\n", hr);
2115
2116 if (note->mtDuration)
2117 {
2118 msg->mtTime -= note->nOffset;
2119 msg->mtTime += max(1, note->mtDuration - 1);
2121 return hr;
2122 note->bFlags &= ~DMUS_NOTEF_NOTEON;
2123 return DMUS_S_REQUEUE;
2124 }
2125 }
2126
2128 MIDI_NOTE_OFF, note->bMidiValue, 0)))
2129 WARN("Failed to translate message to MIDI, hr %#lx\n", hr);
2130
2131 break;
2132 }
2133
2134 case DMUS_PMSGT_CURVE:
2135 {
2137
2138 msg->mtTime += curve->nOffset;
2139 switch (curve->bType)
2140 {
2143 MIDI_CONTROL_CHANGE, curve->bCCData, curve->nStartValue)))
2144 WARN("Failed to translate message to MIDI, hr %#lx\n", hr);
2145 break;
2151 FIXME("Unhandled curve type %#x\n", curve->bType);
2152 break;
2153 default:
2154 WARN("Invalid curve type %#x\n", curve->bType);
2155 break;
2156 }
2157
2158 break;
2159 }
2160
2161 case DMUS_PMSGT_PATCH:
2162 {
2164
2167 WARN("Failed to translate message to MIDI, hr %#lx\n", hr);
2168
2171 WARN("Failed to translate message to MIDI, hr %#lx\n", hr);
2172
2174 MIDI_PROGRAM_CHANGE, patch->byInstrument, 0)))
2175 WARN("Failed to translate message to MIDI, hr %#lx\n", hr);
2176
2177 break;
2178 }
2179
2181 {
2183 struct message *previous;
2184 BOOL enabled = FALSE;
2185
2186 if (IsEqualGUID(&notif->guidNotificationType, &GUID_NOTIFICATION_PERFORMANCE))
2187 enabled = This->notification_performance;
2188 if (IsEqualGUID(&notif->guidNotificationType, &GUID_NOTIFICATION_SEGMENT))
2189 enabled = This->notification_segment;
2190 if (!enabled) return DMUS_S_FREE;
2191
2192 if (msg->dwFlags & DMUS_PMSGF_TOOL_IMMEDIATE)
2193 {
2194 /* re-send the message for queueing at the expected time */
2195 msg->dwFlags &= ~DMUS_PMSGF_TOOL_IMMEDIATE;
2196 msg->dwFlags |= DMUS_PMSGF_TOOL_ATTIME;
2197
2199 {
2200 ERR("Failed to send notification message, hr %#lx\n", hr);
2201 return DMUS_S_FREE;
2202 }
2203
2204 return S_OK;
2205 }
2206
2207 list_add_tail(&This->notifications, &message->entry);
2208
2209 /* discard old notification messages */
2210 do
2211 {
2212 previous = LIST_ENTRY(list_head(&This->notifications), struct message, entry);
2213 if (This->notification_timeout <= 0) break; /* negative values may be used to keep everything */
2214 if (message->msg.rtTime - previous->msg.rtTime <= This->notification_timeout) break;
2215 list_remove(&previous->entry);
2216 list_init(&previous->entry);
2218
2219 SetEvent(This->notification_event);
2220 return S_OK;
2221 }
2222
2223 case DMUS_PMSGT_WAVE:
2224 if (FAILED(hr = IDirectSoundBuffer_Play((IDirectSoundBuffer *)msg->punkUser, 0, 0, 0)))
2225 WARN("Failed to play wave buffer, hr %#lx\n", hr);
2226 break;
2227
2229 msg->rtTime += 10000000;
2230 msg->dwFlags &= ~DMUS_PMSGF_MUSICTIME;
2231
2232 /* re-send the tick message until segment_state_tick returns S_FALSE */
2233 if (FAILED(hr = segment_state_tick((IDirectMusicSegmentState *)msg->punkUser,
2234 (IDirectMusicPerformance8 *)performance)))
2235 ERR("Failed to tick segment state %p, hr %#lx\n", msg->punkUser, hr);
2236 else if (hr == S_FALSE)
2237 return DMUS_S_FREE; /* done ticking */
2239 ERR("Failed to queue tick for segment state %p, hr %#lx\n", msg->punkUser, hr);
2240
2241 return S_OK;
2242
2244 if (FAILED(hr = segment_state_end_play((IDirectMusicSegmentState *)msg->punkUser,
2245 (IDirectMusicPerformance8 *)performance)))
2246 WARN("Failed to end segment state %p, hr %#lx\n", msg->punkUser, hr);
2247 break;
2248
2249 default:
2250 FIXME("Unhandled message type %#lx\n", msg->dwType);
2251 break;
2252 }
2253
2254 return DMUS_S_FREE;
2255}
2256
2257static HRESULT WINAPI performance_tool_Flush(IDirectMusicTool *iface,
2258 IDirectMusicPerformance *performance, DMUS_PMSG *msg, REFERENCE_TIME time)
2259{
2261 FIXME("(%p, %p, %p, %I64d): stub\n", This, performance, msg, time);
2262 return E_NOTIMPL;
2263}
2264
2265static const IDirectMusicToolVtbl performance_tool_vtbl =
2266{
2276};
2277
2278/* for ClassFactory */
2280{
2281 struct performance *obj;
2282 HRESULT hr;
2283
2284 TRACE("(%s, %p)\n", debugstr_guid(iid), ret_iface);
2285
2286 *ret_iface = NULL;
2287 if (!(obj = calloc(1, sizeof(*obj)))) return E_OUTOFMEMORY;
2288 obj->IDirectMusicPerformance8_iface.lpVtbl = &performance_vtbl;
2289 obj->IDirectMusicGraph_iface.lpVtbl = &performance_graph_vtbl;
2290 obj->IDirectMusicTool_iface.lpVtbl = &performance_tool_vtbl;
2291 obj->ref = 1;
2292
2293 obj->pDefaultPath = NULL;
2295 obj->safe.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": performance->safe");
2296 wine_rb_init(&obj->channel_blocks, channel_block_compare);
2297
2298 list_init(&obj->messages);
2299 list_init(&obj->notifications);
2300
2301 obj->latency_offset = 50;
2302 obj->dwBumperLength = 50; /* 50 ms default */
2303 obj->dwPrepareTime = 1000; /* 1000 ms default */
2304
2305 hr = IDirectMusicPerformance8_QueryInterface(&obj->IDirectMusicPerformance8_iface, iid, ret_iface);
2306 IDirectMusicPerformance_Release(&obj->IDirectMusicPerformance8_iface);
2307 return hr;
2308}
2309
2310static inline struct performance *unsafe_impl_from_IDirectMusicPerformance8(IDirectMusicPerformance8 *iface)
2311{
2312 if (iface->lpVtbl != &performance_vtbl) return NULL;
2314}
2315
2316HRESULT performance_get_dsound(IDirectMusicPerformance8 *iface, IDirectSound **dsound)
2317{
2319 if (!This || !(*dsound = This->dsound)) return E_FAIL;
2321 return S_OK;
2322}
HRESULT WINAPI DECLSPEC_HOTPATCH SetThreadDescription(_In_ HANDLE hThread, _In_ PCWSTR lpThreadDescription)
COMPILER_DEPENDENT_INT64 INT64
Definition: actypes.h:132
static int state
Definition: maze.c:121
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
HRESULT create_dmaudiopath(REFIID riid, void **ppobj)
Definition: audiopath.c:736
void set_audiopath_primary_dsound_buffer(IDirectMusicAudioPath *iface, IDirectSoundBuffer *buffer)
Definition: audiopath.c:88
void set_audiopath_dsound_buffer(IDirectMusicAudioPath *iface, IDirectSoundBuffer *buffer)
Definition: audiopath.c:82
HRESULT path_config_get_audio_path_params(IUnknown *iface, WAVEFORMATEX *format, DSBUFFERDESC *desc, DMUS_PORTPARAMS *params)
Definition: audiopath.c:652
void set_audiopath_perf_pointer(IDirectMusicAudioPath *iface, IDirectMusicPerformance8 *performance)
Definition: audiopath.c:76
unsigned int channels
Definition: audiorecord.c:89
#define msg(x)
Definition: auth_time.c:54
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define WAVE_FORMAT_PCM
Definition: constants.h:425
#define ARRAY_SIZE(A)
Definition: main.h:20
int note(char *format,...)
Definition: util.c:12
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static int list_empty(struct list_entry *head)
Definition: list.h:58
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
#define ERR(fmt,...)
Definition: precomp.h:57
const GUID IID_IUnknown
#define MIDI_NOTE_OFF
Definition: beepmidi.c:61
#define MIDI_CONTROL_CHANGE
Definition: beepmidi.c:63
#define MIDI_NOTE_ON
Definition: beepmidi.c:62
Definition: list.h:39
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
HRESULT hr
Definition: delayimp.cpp:582
HRESULT WINAPI DirectSoundCreate(LPCGUID lpcGUID, LPDIRECTSOUND *ppDS, IUnknown *pUnkOuter)
Definition: directsound.c:494
static HRESULT WINAPI performance_GetQueueTime(IDirectMusicPerformance8 *iface, REFERENCE_TIME *prtTime)
Definition: performance.c:1396
static HRESULT WINAPI performance_GetSegmentState(IDirectMusicPerformance8 *iface, IDirectMusicSegmentState **state, MUSIC_TIME time)
Definition: performance.c:732
static HRESULT WINAPI performance_Init(IDirectMusicPerformance8 *iface, IDirectMusic **dmusic, IDirectSound *dsound, HWND hwnd)
Definition: performance.c:521
static void channel_block_free(struct wine_rb_entry *entry, void *context)
Definition: performance.c:263
static HRESULT WINAPI performance_SendPMsg(IDirectMusicPerformance8 *iface, DMUS_PMSG *msg)
Definition: performance.c:807
static ULONG WINAPI performance_tool_Release(IDirectMusicTool *iface)
Definition: performance.c:2021
static HRESULT WINAPI performance_MusicToReferenceTime(IDirectMusicPerformance8 *iface, MUSIC_TIME music_time, REFERENCE_TIME *time)
Definition: performance.c:852
static HRESULT WINAPI performance_QueryInterface(IDirectMusicPerformance8 *iface, REFIID riid, void **ret_iface)
Definition: performance.c:397
static ULONG WINAPI performance_tool_AddRef(IDirectMusicTool *iface)
Definition: performance.c:2015
static HRESULT WINAPI performance_IsPlaying(IDirectMusicPerformance8 *iface, IDirectMusicSegment *pSegment, IDirectMusicSegmentState *pSegState)
Definition: performance.c:931
static ULONG WINAPI performance_Release(IDirectMusicPerformance8 *iface)
Definition: performance.c:442
static HRESULT channel_block_init(struct performance *This, DWORD block_num, IDirectMusicPort *port, DWORD midi_group)
Definition: performance.c:285
static HRESULT WINAPI performance_AssignPChannel(IDirectMusicPerformance8 *iface, DWORD channel_num, IDirectMusicPort *port, DWORD midi_group, DWORD midi_channel)
Definition: performance.c:1227
static HRESULT WINAPI performance_GetNotificationPMsg(IDirectMusicPerformance8 *iface, DMUS_NOTIFICATION_PMSG **ret_msg)
Definition: performance.c:1050
static HRESULT WINAPI performance_GetGlobalParam(IDirectMusicPerformance8 *iface, REFGUID rguidType, void *pParam, DWORD dwSize)
Definition: performance.c:1336
static HRESULT WINAPI performance_GetParam(IDirectMusicPerformance8 *iface, REFGUID type, DWORD group, DWORD index, MUSIC_TIME music_time, MUSIC_TIME *next_time, void *param)
Definition: performance.c:1305
static DWORD WINAPI message_thread_proc(void *args)
Definition: performance.c:174
static HRESULT WINAPI performance_ClonePMsg(IDirectMusicPerformance8 *iface, DMUS_PMSG *msg, DMUS_PMSG **clone)
Definition: performance.c:1631
static HRESULT WINAPI performance_FreePMsg(IDirectMusicPerformance8 *iface, DMUS_PMSG *msg)
Definition: performance.c:975
HRESULT performance_get_dsound(IDirectMusicPerformance8 *iface, IDirectSound **dsound)
Definition: performance.c:2316
static HRESULT performance_queue_message(struct performance *This, struct message *message)
Definition: performance.c:150
static HRESULT WINAPI performance_DownloadInstrument(IDirectMusicPerformance8 *iface, IDirectMusicInstrument *instrument, DWORD port_channel, IDirectMusicDownloadedInstrument **downloaded, DMUS_NOTERANGE *note_ranges, DWORD note_range_count, IDirectMusicPort **port, DWORD *group, DWORD *music_channel)
Definition: performance.c:1276
dmus_internal_message_type
Definition: performance.c:29
@ DMUS_PMSGT_INTERNAL_SEGMENT_END
Definition: performance.c:31
@ DMUS_PMSGT_INTERNAL_FIRST
Definition: performance.c:30
@ DMUS_PMSGT_INTERNAL_SEGMENT_TICK
Definition: performance.c:32
static HRESULT WINAPI performance_GetLatencyTime(IDirectMusicPerformance8 *iface, REFERENCE_TIME *ret_time)
Definition: performance.c:1382
static HRESULT WINAPI performance_GetBumperLength(IDirectMusicPerformance8 *iface, DWORD *pdwMilliSeconds)
Definition: performance.c:795
static HRESULT WINAPI performance_graph_InsertTool(IDirectMusicGraph *iface, IDirectMusicTool *tool, DWORD *channels, DWORD channels_count, LONG index)
Definition: performance.c:1971
static HRESULT WINAPI performance_AssignPChannelBlock(IDirectMusicPerformance8 *iface, DWORD block_num, IDirectMusicPort *port, DWORD midi_group)
Definition: performance.c:1213
static struct message * message_from_DMUS_PMSG(DMUS_PMSG *msg)
Definition: performance.c:95
static const IDirectMusicGraphVtbl performance_graph_vtbl
Definition: performance.c:1993
static HRESULT WINAPI performance_graph_QueryInterface(IDirectMusicGraph *iface, REFIID riid, void **ret_iface)
Definition: performance.c:1913
static HRESULT WINAPI performance_MIDIToMusic(IDirectMusicPerformance8 *iface, BYTE bMIDIValue, DMUS_CHORD_KEY *pChord, BYTE bPlayMode, BYTE bChordLevel, WORD *pwMusicValue)
Definition: performance.c:1487
static void state_entry_destroy(struct state_entry *entry)
Definition: performance.c:580
static HRESULT WINAPI performance_Stop(IDirectMusicPerformance8 *iface, IDirectMusicSegment *segment, IDirectMusicSegmentState *state, MUSIC_TIME music_time, DWORD flags)
Definition: performance.c:674
static const IDirectMusicPerformance8Vtbl performance_vtbl
Definition: performance.c:1851
static HRESULT WINAPI performance_InitAudio(IDirectMusicPerformance8 *iface, IDirectMusic **dmusic, IDirectSound **dsound, HWND hwnd, DWORD default_path_type, DWORD num_channels, DWORD flags, DMUS_AUDIOPARAMS *params)
Definition: performance.c:1524
static ULONG WINAPI performance_AddRef(IDirectMusicPerformance8 *iface)
Definition: performance.c:432
static HRESULT WINAPI performance_PlaySegmentEx(IDirectMusicPerformance8 *iface, IUnknown *source, WCHAR *segment_name, IUnknown *transition, DWORD segment_flags, INT64 start_time, IDirectMusicSegmentState **segment_state, IUnknown *from, IUnknown *audio_path)
Definition: performance.c:1565
static HRESULT WINAPI performance_PChannelInfo(IDirectMusicPerformance8 *iface, DWORD channel_num, IDirectMusicPort **port, DWORD *midi_group, DWORD *midi_channel)
Definition: performance.c:1256
static HRESULT WINAPI performance_CreateAudioPath(IDirectMusicPerformance8 *iface, IUnknown *pSourceConfig, BOOL fActivate, IDirectMusicAudioPath **ret_iface)
Definition: performance.c:1649
static HRESULT WINAPI performance_GetGraph(IDirectMusicPerformance8 *iface, IDirectMusicGraph **graph)
Definition: performance.c:1000
static HRESULT WINAPI performance_MusicToMIDI(IDirectMusicPerformance8 *iface, WORD wMusicValue, DMUS_CHORD_KEY *pChord, BYTE bPlayMode, BYTE bChordLevel, BYTE *pbMIDIValue)
Definition: performance.c:1496
static HRESULT WINAPI performance_tool_ProcessPMsg(IDirectMusicTool *iface, IDirectMusicPerformance *performance, DMUS_PMSG *msg)
Definition: performance.c:2057
static HRESULT WINAPI performance_SetParam(IDirectMusicPerformance8 *iface, REFGUID rguidType, DWORD dwGroupBits, DWORD dwIndex, MUSIC_TIME mtTime, void *pParam)
Definition: performance.c:1327
static HRESULT WINAPI performance_RemoveNotificationType(IDirectMusicPerformance8 *iface, REFGUID type)
Definition: performance.c:1094
static HRESULT WINAPI performance_tool_GetMediaTypes(IDirectMusicTool *iface, DWORD **types, DWORD size)
Definition: performance.c:2050
HRESULT performance_send_segment_tick(IDirectMusicPerformance8 *iface, MUSIC_TIME music_time, IDirectMusicSegmentState *state)
Definition: performance.c:337
static BOOL message_needs_flushing(struct message *message, IDirectMusicSegmentState *state)
Definition: performance.c:610
HRESULT performance_send_segment_start(IDirectMusicPerformance8 *iface, MUSIC_TIME music_time, IDirectMusicSegmentState *state)
Definition: performance.c:318
static HRESULT WINAPI performance_AddPort(IDirectMusicPerformance8 *iface, IDirectMusicPort *port)
Definition: performance.c:1173
static HRESULT WINAPI performance_tool_GetMsgDeliveryType(IDirectMusicTool *iface, DWORD *type)
Definition: performance.c:2034
static HRESULT WINAPI performance_RemovePort(IDirectMusicPerformance8 *iface, IDirectMusicPort *pPort)
Definition: performance.c:1202
static HRESULT WINAPI performance_AddNotificationType(IDirectMusicPerformance8 *iface, REFGUID type)
Definition: performance.c:1073
static HRESULT WINAPI performance_tool_GetMediaTypeArraySize(IDirectMusicTool *iface, DWORD *size)
Definition: performance.c:2042
static struct performance * unsafe_impl_from_IDirectMusicPerformance8(IDirectMusicPerformance8 *iface)
Definition: performance.c:2310
static HRESULT WINAPI performance_SetNotificationHandle(IDirectMusicPerformance8 *iface, HANDLE notification_event, REFERENCE_TIME minimum_time)
Definition: performance.c:1034
static HRESULT WINAPI performance_graph_StampPMsg(IDirectMusicGraph *iface, DMUS_PMSG *msg)
Definition: performance.c:1931
static struct performance * impl_from_IDirectMusicTool(IDirectMusicTool *iface)
Definition: performance.c:2004
static HRESULT WINAPI performance_GetDefaultAudioPath(IDirectMusicPerformance8 *iface, IDirectMusicAudioPath **ret_iface)
Definition: performance.c:1826
static HRESULT WINAPI performance_SetBumperLength(IDirectMusicPerformance8 *iface, DWORD dwMilliSeconds)
Definition: performance.c:786
static struct channel * performance_get_channel(struct performance *This, DWORD channel_num)
Definition: performance.c:277
static void enum_segment_states(struct performance *This, IDirectMusicSegment *segment, struct list *list)
Definition: performance.c:587
static ULONG WINAPI performance_graph_AddRef(IDirectMusicGraph *iface)
Definition: performance.c:1919
static HRESULT WINAPI performance_TimeToRhythm(IDirectMusicPerformance8 *iface, MUSIC_TIME mtTime, DMUS_TIMESIGNATURE *pTimeSig, WORD *pwMeasure, BYTE *pbBeat, BYTE *pbGrid, short *pnOffset)
Definition: performance.c:1505
static HRESULT WINAPI performance_GetParamEx(IDirectMusicPerformance8 *iface, REFGUID rguidType, DWORD dwTrackID, DWORD dwGroupBits, DWORD dwIndex, MUSIC_TIME mtTime, MUSIC_TIME *pmtNext, void *pParam)
Definition: performance.c:1841
static HRESULT WINAPI performance_SetGraph(IDirectMusicPerformance8 *iface, IDirectMusicGraph *pGraph)
Definition: performance.c:1017
static void performance_set_primary_segment(struct performance *This, IDirectMusicSegment *segment)
Definition: performance.c:384
static HRESULT WINAPI performance_CreateStandardAudioPath(IDirectMusicPerformance8 *iface, DWORD dwType, DWORD pchannel_count, BOOL fActivate, IDirectMusicAudioPath **ret_iface)
Definition: performance.c:1717
static HRESULT WINAPI performance_tool_Init(IDirectMusicTool *iface, IDirectMusicGraph *graph)
Definition: performance.c:2027
static void performance_set_control_segment(struct performance *This, IDirectMusicSegment *segment)
Definition: performance.c:390
static HRESULT WINAPI performance_StopEx(IDirectMusicPerformance8 *iface, IUnknown *pObjectToStop, __int64 i64StopTime, DWORD dwFlags)
Definition: performance.c:1621
static HRESULT performance_init_dmusic(struct performance *This, IDirectSound *dsound)
Definition: performance.c:475
static HRESULT WINAPI performance_GetTime(IDirectMusicPerformance8 *iface, REFERENCE_TIME *time, MUSIC_TIME *music_time)
Definition: performance.c:940
static HRESULT performance_send_midi_pmsg(struct performance *This, DMUS_PMSG *msg, UINT flags, BYTE status, BYTE byte1, BYTE byte2)
Definition: performance.c:492
static struct message * performance_get_message(struct performance *This, DWORD *timeout)
Definition: performance.c:100
static HRESULT performance_send_notification_pmsg(struct performance *This, MUSIC_TIME music_time, BOOL stamp, GUID type, DWORD option, IUnknown *object)
Definition: performance.c:231
static HRESULT WINAPI performance_SetPrepareTime(IDirectMusicPerformance8 *iface, DWORD dwMilliSeconds)
Definition: performance.c:765
static HRESULT WINAPI performance_graph_RemoveTool(IDirectMusicGraph *iface, IDirectMusicTool *tool)
Definition: performance.c:1986
static HRESULT WINAPI performance_tool_Flush(IDirectMusicTool *iface, IDirectMusicPerformance *performance, DMUS_PMSG *msg, REFERENCE_TIME time)
Definition: performance.c:2257
static void performance_update_latency_time(struct performance *This, IDirectMusicPort *port, REFERENCE_TIME *ret_time)
Definition: performance.c:1115
static HRESULT WINAPI performance_ReferenceToMusicTime(IDirectMusicPerformance8 *iface, REFERENCE_TIME time, MUSIC_TIME *music_time)
Definition: performance.c:892
static HRESULT WINAPI performance_SetDefaultAudioPath(IDirectMusicPerformance8 *iface, IDirectMusicAudioPath *audio_path)
Definition: performance.c:1808
static int channel_block_compare(const void *key, const struct wine_rb_entry *entry)
Definition: performance.c:257
static HRESULT WINAPI performance_SetGlobalParam(IDirectMusicPerformance8 *iface, REFGUID rguidType, void *pParam, DWORD dwSize)
Definition: performance.c:1355
static struct performance * impl_from_IDirectMusicPerformance8(IDirectMusicPerformance8 *iface)
Definition: performance.c:313
HRESULT create_dmperformance(REFIID iid, void **ret_iface)
Definition: performance.c:2279
static const IDirectMusicToolVtbl performance_tool_vtbl
Definition: performance.c:2265
static ULONG WINAPI performance_graph_Release(IDirectMusicGraph *iface)
Definition: performance.c:1925
static HRESULT WINAPI performance_Invalidate(IDirectMusicPerformance8 *iface, MUSIC_TIME mtTime, DWORD dwFlags)
Definition: performance.c:1297
static HRESULT WINAPI performance_GetPrepareTime(IDirectMusicPerformance8 *iface, DWORD *pdwMilliSeconds)
Definition: performance.c:774
static HRESULT WINAPI performance_tool_QueryInterface(IDirectMusicTool *iface, REFIID riid, void **ret_iface)
Definition: performance.c:2009
static void performance_flush_messages(struct performance *This, IDirectMusicSegmentState *state)
Definition: performance.c:645
HRESULT performance_send_segment_end(IDirectMusicPerformance8 *iface, MUSIC_TIME music_time, IDirectMusicSegmentState *state, BOOL abort)
Definition: performance.c:355
static HRESULT WINAPI performance_graph_GetTool(IDirectMusicGraph *iface, DWORD index, IDirectMusicTool **tool)
Definition: performance.c:1979
static HRESULT performance_send_pmsg(struct performance *This, MUSIC_TIME music_time, DWORD flags, DWORD type, IUnknown *object)
Definition: performance.c:208
static HRESULT perf_dmport_create(struct performance *perf, DMUS_PORTPARAMS *params)
Definition: performance.c:1140
static HRESULT WINAPI performance_RhythmToTime(IDirectMusicPerformance8 *iface, WORD wMeasure, BYTE bBeat, BYTE bGrid, short nOffset, DMUS_TIMESIGNATURE *pTimeSig, MUSIC_TIME *pmtTime)
Definition: performance.c:1514
static HRESULT WINAPI performance_PlaySegment(IDirectMusicPerformance8 *iface, IDirectMusicSegment *segment, DWORD segment_flags, INT64 start_time, IDirectMusicSegmentState **ret_state)
Definition: performance.c:563
static HRESULT WINAPI performance_GetResolvedTime(IDirectMusicPerformance8 *iface, REFERENCE_TIME rtTime, REFERENCE_TIME *prtResolved, DWORD dwTimeResolveFlags)
Definition: performance.c:1477
static HRESULT WINAPI performance_AllocPMsg(IDirectMusicPerformance8 *iface, ULONG size, DMUS_PMSG **msg)
Definition: performance.c:957
static HRESULT WINAPI performance_CloseDown(IDirectMusicPerformance8 *iface)
Definition: performance.c:1413
static HRESULT performance_init_dsound(struct performance *This, HWND hwnd)
Definition: performance.c:459
static HRESULT WINAPI performance_AdjustTime(IDirectMusicPerformance8 *iface, REFERENCE_TIME rtAmount)
Definition: performance.c:1405
static struct performance * impl_from_IDirectMusicGraph(IDirectMusicGraph *iface)
Definition: performance.c:1908
static HRESULT performance_process_message(struct performance *This, DMUS_PMSG *msg)
Definition: performance.c:135
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static HANDLE message_thread
Definition: filtergraph.c:54
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, IUnknown *outer, DWORD cls_context, REFIID riid, void **obj)
Definition: combase.c:1685
#define CloseHandle
Definition: compat.h:739
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
BOOL WINAPI SleepConditionVariableCS(PCONDITION_VARIABLE ConditionVariable, PCRITICAL_SECTION CriticalSection, DWORD Timeout)
Definition: sync.c:59
BOOL WINAPI InitializeCriticalSectionEx(OUT LPCRITICAL_SECTION lpCriticalSection, IN DWORD dwSpinCount, IN DWORD flags)
Definition: sync.c:107
VOID WINAPI WakeConditionVariable(PCONDITION_VARIABLE ConditionVariable)
Definition: sync.c:98
GUID guid
Definition: version.c:147
#define __int64
Definition: corecrt.h:72
USHORT port
Definition: uri.c:210
#define DMUS_E_CANNOT_FREE
Definition: dmerror.h:129
#define DMUS_E_AUDIOPATH_INACTIVE
Definition: dmerror.h:155
#define DMUS_E_NO_MASTER_CLOCK
Definition: dmerror.h:116
#define DMUS_E_NOT_INIT
Definition: dmerror.h:110
#define DMUS_E_AUDIOPATHS_IN_USE
Definition: dmerror.h:153
#define DMUS_S_LAST_TOOL
Definition: dmerror.h:46
#define DMUS_S_FREE
Definition: dmerror.h:43
#define DMUS_E_ALREADY_INITED
Definition: dmerror.h:101
#define DMUS_E_ALREADY_SENT
Definition: dmerror.h:128
#define DMUS_S_REQUEUE
Definition: dmerror.h:42
#define DMUS_E_NOT_FOUND
Definition: dmerror.h:109
HRESULT segment_state_create(IDirectMusicSegment *segment, MUSIC_TIME start_time, IDirectMusicPerformance8 *performance, IDirectMusicSegmentState **ret_iface)
Definition: segmentstate.c:312
HRESULT segment_state_stop(IDirectMusicSegmentState *iface, IDirectMusicPerformance8 *performance)
Definition: segmentstate.c:502
BOOL segment_state_has_track(IDirectMusicSegmentState *iface, DWORD track_id)
Definition: segmentstate.c:537
HRESULT segment_state_end_play(IDirectMusicSegmentState *iface, IDirectMusicPerformance8 *performance)
Definition: segmentstate.c:512
BOOL segment_state_has_segment(IDirectMusicSegmentState *iface, IDirectMusicSegment *segment)
Definition: segmentstate.c:531
HRESULT segment_state_tick(IDirectMusicSegmentState *iface, IDirectMusicPerformance8 *performance)
Definition: segmentstate.c:493
HRESULT segment_state_play(IDirectMusicSegmentState *iface, IDirectMusicPerformance8 *performance)
Definition: segmentstate.c:472
const char * debugstr_dmguid(const GUID *id)
Definition: dmobject.c:36
#define IDirectMusicTool_ProcessPMsg(p, a, b)
Definition: dmplugin.h:154
#define IDirectMusicTool_AddRef(p)
Definition: dmplugin.h:147
#define IDirectMusicTool_Release(p)
Definition: dmplugin.h:148
LONG MUSIC_TIME
Definition: dmplugin.h:95
struct _DMUS_EVENTHEADER DMUS_EVENTHEADER
@ MIDI_CC_BANK_MSB
Definition: dmusic_midi.h:42
@ MIDI_CC_BANK_LSB
Definition: dmusic_midi.h:43
@ MIDI_SYSTEM_RESET
Definition: dmusic_midi.h:36
#define DMUS_PORTPARAMS_CHANNELGROUPS
Definition: dmusicc.h:206
#define IDirectMusicPort_SetDirectSound(p, a, b)
Definition: dmusicc.h:697
#define IDirectMusicPort_Release(p)
Definition: dmusicc.h:680
#define IDirectMusic_AddRef(p)
Definition: dmusicc.h:398
#define IDirectMusic8_SetDirectSound(p, a, b)
Definition: dmusicc.h:452
#define DMUS_PORTPARAMS_AUDIOCHANNELS
Definition: dmusicc.h:207
#define IDirectMusic8_Release(p)
Definition: dmusicc.h:442
#define IDirectMusicBuffer_PackStructured(p, a, b, c)
Definition: dmusicc.h:493
#define IDirectMusic8_CreatePort(p, a, b, c, d)
Definition: dmusicc.h:446
#define IDirectMusicPort_AddRef(p)
Definition: dmusicc.h:679
#define IDirectMusic_GetMasterClock(p, a, b)
Definition: dmusicc.h:405
#define IDirectMusic_SetDirectSound(p, a, b)
Definition: dmusicc.h:409
#define IDirectMusic8_GetDefaultPort(p, a)
Definition: dmusicc.h:451
#define IDirectMusicPort_PlayBuffer(p, a)
Definition: dmusicc.h:682
#define IDirectMusic_CreateMusicBuffer(p, a, b, c)
Definition: dmusicc.h:402
#define IDirectMusicPort_DownloadInstrument(p, a, b, c, d)
Definition: dmusicc.h:685
#define IDirectMusicPort_Activate(p, a)
Definition: dmusicc.h:694
#define IDirectMusicBuffer_Release(p)
Definition: dmusicc.h:489
#define IDirectMusicPort_GetLatencyClock(p, a)
Definition: dmusicc.h:687
#define IDirectMusic8_AddRef(p)
Definition: dmusicc.h:441
#define IDirectMusicPerformance8_CreateStandardAudioPath(p, a, b, c, d)
Definition: dmusici.h:1443
#define IDirectMusicPerformance8_QueryInterface(p, a, b)
Definition: dmusici.h:1392
#define IDirectMusicPerformance8_ReferenceToMusicTime(p, a, b)
Definition: dmusici.h:1406
@ DMUS_NOTEF_NOTEON
Definition: dmusici.h:516
#define IDirectMusicPerformance_GetParam(p, a, b, c, d, e, f)
Definition: dmusici.h:1309
#define IDirectMusicPerformance8_FreePMsg(p, a)
Definition: dmusici.h:1410
#define IDirectMusicAudioPath_Activate(p, a)
Definition: dmusici.h:1214
#define IDirectMusicObject_Release(p)
Definition: dmusici.h:844
#define DMUS_SEG_ALLTRACKS
Definition: dmusici.h:317
#define DMUS_CURVET_RPNCURVE
Definition: dmusici.h:239
@ DMUS_SEGF_DEFAULT
Definition: dmusici.h:483
@ DMUS_SEGF_CONTROL
Definition: dmusici.h:478
@ DMUS_SEGF_SECONDARY
Definition: dmusici.h:476
#define DMUS_CURVET_CCCURVE
Definition: dmusici.h:236
#define DMUS_NOTIFICATION_MUSICSTOPPED
Definition: dmusici.h:257
@ DMUS_PMSGF_MUSICTIME
Definition: dmusici.h:446
@ DMUS_PMSGF_REFTIME
Definition: dmusici.h:445
@ DMUS_PMSGF_TOOL_ATTIME
Definition: dmusici.h:449
@ DMUS_PMSGF_TOOL_IMMEDIATE
Definition: dmusici.h:447
@ DMUS_PMSGF_TOOL_QUEUE
Definition: dmusici.h:448
#define DMUS_NOTIFICATION_MUSICSTARTED
Definition: dmusici.h:256
#define IDirectMusicPerformance8_AddRef(p)
Definition: dmusici.h:1393
#define IDirectMusicPerformance8_PlaySegmentEx(p, a, b, c, d, e, f, g, h)
Definition: dmusici.h:1439
#define IDirectMusicPerformance8_Release(p)
Definition: dmusici.h:1394
#define IDirectMusicPerformance8_AllocPMsg(p, a, b)
Definition: dmusici.h:1409
#define IDirectMusicPerformance_PChannelInfo(p, a, b, c, d)
Definition: dmusici.h:1306
#define IDirectMusicAudioPath_AddRef(p)
Definition: dmusici.h:1210
#define IDirectMusicPerformance8_Init(p, a, b, c)
Definition: dmusici.h:1396
#define IDirectMusicSegment_Release(p)
Definition: dmusici.h:1008
#define IDirectMusicObject_GetDescriptor(p, a)
Definition: dmusici.h:846
#define IDirectMusicPerformance8_MusicToReferenceTime(p, a, b)
Definition: dmusici.h:1405
#define DMUS_PPQ
Definition: dmusici.h:314
#define DMUS_CURVET_PBCURVE
Definition: dmusici.h:235
#define IDirectMusicSegment_AddRef(p)
Definition: dmusici.h:1007
#define DMUS_NOTIFICATION_SEGEND
Definition: dmusici.h:252
#define IDirectMusicPerformance_SendPMsg(p, a)
Definition: dmusici.h:1289
#define IDirectMusicPerformance8_GetTime(p, a, b)
Definition: dmusici.h:1408
#define DMUS_NOTIFICATION_SEGALMOSTEND
Definition: dmusici.h:253
#define IDirectMusicSegmentState_Release(p)
Definition: dmusici.h:1140
#define IDirectMusicPerformance_GetLatencyTime(p, a)
Definition: dmusici.h:1313
#define IDirectMusicSegmentState_AddRef(p)
Definition: dmusici.h:1139
#define IDirectMusicSegment_GetParam(p, a, b, c, d, e, f)
Definition: dmusici.h:1025
#define DMUS_APATH_DYNAMIC_MONO
Definition: dmusici.h:219
#define IDirectMusicGraph_Release(p)
Definition: dmusici.h:1472
#define DMUS_APATH_DYNAMIC_3D
Definition: dmusici.h:218
#define DMUS_APATH_SHARED_STEREOPLUSREVERB
Definition: dmusici.h:217
#define IDirectMusicPerformance_Release(p)
Definition: dmusici.h:1279
#define DMUS_NOTIFICATION_SEGSTART
Definition: dmusici.h:251
#define DMUS_APATH_DYNAMIC_STEREO
Definition: dmusici.h:220
#define IDirectMusicPerformance8_AssignPChannelBlock(p, a, b, c)
Definition: dmusici.h:1419
#define IDirectMusicPerformance8_SendPMsg(p, a)
Definition: dmusici.h:1404
#define IDirectMusicPerformance_CloseDown(p)
Definition: dmusici.h:1316
#define IDirectMusicAudioPath_Release(p)
Definition: dmusici.h:1211
#define IDirectMusicPerformance_FreePMsg(p, a)
Definition: dmusici.h:1295
#define DMUS_NOTIFICATION_SEGABORT
Definition: dmusici.h:255
#define IDirectMusicGraph_StampPMsg(p, a)
Definition: dmusici.h:1474
#define IDirectMusicGraph_AddRef(p)
Definition: dmusici.h:1471
#define DMUS_CURVET_PATCURVE
Definition: dmusici.h:238
#define DMUS_CURVET_MATCURVE
Definition: dmusici.h:237
#define DMUS_CURVET_NRPNCURVE
Definition: dmusici.h:240
@ DMUS_PMSGT_NOTE
Definition: dmusici.h:457
@ DMUS_PMSGT_CURVE
Definition: dmusici.h:461
@ DMUS_PMSGT_PATCH
Definition: dmusici.h:463
@ DMUS_PMSGT_WAVE
Definition: dmusici.h:468
@ DMUS_PMSGT_MIDI
Definition: dmusici.h:456
@ DMUS_PMSGT_DIRTY
Definition: dmusici.h:467
@ DMUS_PMSGT_NOTIFICATION
Definition: dmusici.h:459
LONGLONG REFERENCE_TIME
Definition: dmusicks.h:9
#define L(x)
Definition: resources.c:13
#define INFINITE
Definition: serial.h:102
#define DSBCAPS_GLOBALFOCUS
Definition: dsound.h:219
#define DSBCAPS_CTRLVOLUME
Definition: dsound.h:213
#define DSBCAPS_MUTE3DATMAXDISTANCE
Definition: dsound.h:221
#define DSBCAPS_CTRLPAN
Definition: dsound.h:212
#define IDirectSound_AddRef(p)
Definition: dsound.h:452
#define DSSCL_PRIORITY
Definition: dsound.h:248
#define DSBCAPS_CTRLFX
Definition: dsound.h:216
#define DSBSIZE_MIN
Definition: dsound.h:224
#define DSBCAPS_CTRLFREQUENCY
Definition: dsound.h:211
#define DSBCAPS_CTRL3D
Definition: dsound.h:210
#define IDirectSoundBuffer_Play(p, a, b, c)
Definition: dsound.h:585
#define IDirectSound_Release(p)
Definition: dsound.h:453
#define IDirectSound_SetCooperativeLevel(p, a, b)
Definition: dsound.h:458
#define IDirectSound_CreateSoundBuffer(p, a, b, c)
Definition: dsound.h:455
#define IDirectSoundBuffer_Release(p)
Definition: dsound.h:574
#define DSERR_BUFFERLOST
Definition: dsound.h:131
#define DSBCAPS_PRIMARYBUFFER
Definition: dsound.h:206
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
time_t now
Definition: finger.c:65
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLenum GLenum GLsizei const GLuint GLboolean enabled
Definition: glext.h:7750
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLintptr offset
Definition: glext.h:5920
GLuint index
Definition: glext.h:6031
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum const GLfloat * params
Definition: glext.h:5645
GLbitfield flags
Definition: glext.h:7161
GLboolean GLuint group
Definition: glext.h:11120
GLfloat param
Definition: glext.h:5796
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
#define abort()
Definition: i386-dis.c:34
REFIID riid
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
uint32_t entry
Definition: isohybrid.c:63
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_w
Definition: kernel32.h:32
#define GUID_NULL
Definition: ks.h:106
if(dx< 0)
Definition: linetemp.h:194
#define MIDI_PROGRAM_CHANGE
Definition: midi.h:20
__u16 time
Definition: mkdosfs.c:8
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static IMMNotificationClient notif
Definition: mmdevenum.c:189
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
static PVOID ptr
Definition: dispmode.c:27
D3D11_SHADER_VARIABLE_DESC desc
Definition: reflection.c:1683
#define min(a, b)
Definition: monoChain.cc:55
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
Definition: netsh.h:141
#define MAXDWORD
short WCHAR
Definition: pedump.c:58
long LONG
Definition: pedump.c:60
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
#define IsEqualCLSID(rclsid1, rclsid2)
Definition: guiddef.h:96
HWND WINAPI GetForegroundWindow(void)
Definition: ntwrapper.h:392
static unsigned __int64 next
Definition: rand_nt.c:6
#define calloc
Definition: rosglue.h:14
#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 LIST_FOR_EACH_ENTRY_REV(elem, list, type, field)
Definition: list.h:260
__WINE_SERVER_LIST_INLINE void list_add_after(struct list *elem, struct list *to_add)
Definition: list.h:80
#define wine_rb_entry
Definition: rbtree.h:404
#define WINE_RB_ENTRY_VALUE
Definition: rbtree.h:414
#define wine_rb_put
Definition: rbtree.h:410
#define wine_rb_tree
Definition: rbtree.h:405
#define wine_rb_init
Definition: rbtree.h:406
#define wine_rb_destroy
Definition: rbtree.h:408
#define wine_rb_get
Definition: rbtree.h:409
#define memset(x, y, z)
Definition: compat.h:39
#define UINT
Definition: utils.c:29
#define args
Definition: format.c:66
#define TRACE(s)
Definition: solgame.cpp:4
CardRegion * from
Definition: spigame.cpp:19
short nStartValue
Definition: dmusici.h:675
DMUS_PMSG_PART BYTE bStatus
Definition: dmusici.h:633
DMUS_PMSG_PART BYTE byInstrument
Definition: dmusici.h:641
Definition: scsiwmi.h:51
Definition: match.c:390
struct wine_rb_entry entry
Definition: performance.c:46
DWORD block_num
Definition: performance.c:44
struct channel channels[16]
Definition: performance.c:45
DWORD midi_channel
Definition: performance.c:38
DWORD midi_group
Definition: performance.c:37
IDirectMusicPort * port
Definition: performance.c:39
Definition: http.c:7252
Definition: dialog.c:52
Definition: graph.c:32
Definition: copy.c:22
Definition: list.h:15
Definition: tftpd.h:60
struct list entry
Definition: performance.c:91
UINT message
Definition: SystemMenu.c:42
DMUS_PMSG msg
Definition: performance.c:92
Definition: getopt.h:109
long lMasterVolume
Definition: performance.c:61
IDirectMusicGraph IDirectMusicGraph_iface
Definition: performance.c:52
HANDLE message_thread
Definition: performance.c:71
REFERENCE_TIME notification_timeout
Definition: performance.c:80
REFERENCE_TIME init_time
Definition: performance.c:76
IDirectMusicPerformance8 IDirectMusicPerformance8_iface
Definition: performance.c:51
DWORD dwPrepareTime
Definition: performance.c:69
IDirectMusicTool IDirectMusicTool_iface
Definition: performance.c:53
IReferenceClock * master_clock
Definition: performance.c:75
DWORD dwBumperLength
Definition: performance.c:68
IDirectMusic * dmusic
Definition: performance.c:55
float fMasterTempo
Definition: performance.c:60
struct list notifications
Definition: performance.c:79
IDirectMusicSegment * control_segment
Definition: performance.c:86
REFERENCE_TIME latency_offset
Definition: performance.c:67
CONDITION_VARIABLE cond
Definition: performance.c:73
IDirectMusicSegment * primary_segment
Definition: performance.c:85
CRITICAL_SECTION safe
Definition: performance.c:72
BOOL audio_paths_enabled
Definition: performance.c:65
HANDLE notification_event
Definition: performance.c:81
BOOL notification_segment
Definition: performance.c:83
IDirectSound * dsound
Definition: performance.c:56
IDirectMusicAudioPath * pDefaultPath
Definition: performance.c:66
BOOL fAutoDownload
Definition: performance.c:58
struct wine_rb_tree channel_blocks
Definition: performance.c:63
BOOL notification_performance
Definition: performance.c:82
char cMasterGrooveLevel
Definition: performance.c:59
IDirectMusicGraph * pToolGraph
Definition: performance.c:57
Definition: send.c:48
Definition: performance.c:575
IDirectMusicSegmentState * state
Definition: performance.c:577
Definition: ps.c:97
Definition: dhcpd.h:248
Definition: cmds.c:130
#define max(a, b)
Definition: svc.c:63
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:669
#define LIST_INIT(head)
Definition: queue.h:197
#define LIST_ENTRY(type)
Definition: queue.h:175
#define DWORD_PTR
Definition: treelist.c:76
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
Definition: pdh_main.c:64
#define round(x)
Definition: opentype.c:47
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
HANDLE WINAPI GetCurrentThread(void)
Definition: proc.c:1195
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:3451
static HRESULT HRESULT_FROM_WIN32(unsigned int x)
Definition: winerror.h:210
#define E_NOINTERFACE
Definition: winerror.h:3479
#define E_POINTER
Definition: winerror.h:3480
#define RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO
Definition: winnt_old.h:1156
static unsigned int block
Definition: xmlmemory.c:101
unsigned char BYTE
Definition: xxhash.c:193