Skip to content

Commit 47c299c

Browse files
rbernonjulliard
authored andcommitted
dmime/tests: Test sequence track and DMUS_NOTE_PMSG.
1 parent c04e686 commit 47c299c

File tree

1 file changed

+261
-0
lines changed

1 file changed

+261
-0
lines changed

dlls/dmime/tests/dmime.c

+261
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,81 @@ static void load_resource(const WCHAR *name, WCHAR *filename)
7777
CloseHandle(file);
7878
}
7979

80+
static void stream_begin_chunk(IStream *stream, const char type[5], ULARGE_INTEGER *offset)
81+
{
82+
static const LARGE_INTEGER zero = {0};
83+
HRESULT hr;
84+
hr = IStream_Write(stream, type, 4, NULL);
85+
ok(hr == S_OK, "got %#lx\n", hr);
86+
hr = IStream_Seek(stream, zero, STREAM_SEEK_CUR, offset);
87+
ok(hr == S_OK, "got %#lx\n", hr);
88+
hr = IStream_Write(stream, "\0\0\0\0", 4, NULL);
89+
ok(hr == S_OK, "got %#lx\n", hr);
90+
}
91+
92+
static void stream_end_chunk(IStream *stream, ULARGE_INTEGER *offset)
93+
{
94+
static const LARGE_INTEGER zero = {0};
95+
ULARGE_INTEGER position;
96+
HRESULT hr;
97+
UINT size;
98+
hr = IStream_Seek(stream, zero, STREAM_SEEK_CUR, &position);
99+
ok(hr == S_OK, "got %#lx\n", hr);
100+
hr = IStream_Seek(stream, *(LARGE_INTEGER *)offset, STREAM_SEEK_SET, NULL);
101+
ok(hr == S_OK, "got %#lx\n", hr);
102+
size = position.QuadPart - offset->QuadPart - 4;
103+
hr = IStream_Write(stream, &size, 4, NULL);
104+
ok(hr == S_OK, "got %#lx\n", hr);
105+
hr = IStream_Seek(stream, *(LARGE_INTEGER *)&position, STREAM_SEEK_SET, NULL);
106+
ok(hr == S_OK, "got %#lx\n", hr);
107+
hr = IStream_Write(stream, &zero, (position.QuadPart & 1), NULL);
108+
ok(hr == S_OK, "got %#lx\n", hr);
109+
}
110+
111+
#define CHUNK_BEGIN(stream, type) \
112+
do { \
113+
ULARGE_INTEGER __off; \
114+
IStream *__stream = (stream); \
115+
stream_begin_chunk(stream, type, &__off); \
116+
do
117+
118+
#define CHUNK_RIFF(stream, form) \
119+
do { \
120+
ULARGE_INTEGER __off; \
121+
IStream *__stream = (stream); \
122+
stream_begin_chunk(stream, "RIFF", &__off); \
123+
IStream_Write(stream, form, 4, NULL); \
124+
do
125+
126+
#define CHUNK_LIST(stream, form) \
127+
do { \
128+
ULARGE_INTEGER __off; \
129+
IStream *__stream = (stream); \
130+
stream_begin_chunk(stream, "LIST", &__off); \
131+
IStream_Write(stream, form, 4, NULL); \
132+
do
133+
134+
#define CHUNK_END \
135+
while (0); \
136+
stream_end_chunk(__stream, &__off); \
137+
} while (0)
138+
139+
#define CHUNK_DATA(stream, type, data) \
140+
CHUNK_BEGIN(stream, type) \
141+
{ \
142+
IStream_Write((stream), &(data), sizeof(data), NULL); \
143+
} \
144+
CHUNK_END
145+
146+
#define CHUNK_ARRAY(stream, type, items) \
147+
CHUNK_BEGIN(stream, type) \
148+
{ \
149+
UINT __size = sizeof(*(items)); \
150+
IStream_Write((stream), &__size, 4, NULL); \
151+
IStream_Write((stream), &(items), sizeof(items), NULL); \
152+
} \
153+
CHUNK_END
154+
80155
struct test_tool
81156
{
82157
IDirectMusicTool IDirectMusicTool_iface;
@@ -2411,6 +2486,191 @@ static void test_wave_pmsg(void)
24112486
IDirectMusicTool_Release(tool);
24122487
}
24132488

2489+
#define check_dmus_note_pmsg(a, b, c, d, e, f) check_dmus_note_pmsg_(__LINE__, a, b, c, d, e, f)
2490+
static void check_dmus_note_pmsg_(int line, DMUS_NOTE_PMSG *msg, MUSIC_TIME time, UINT chan,
2491+
UINT duration, UINT key, UINT vel)
2492+
{
2493+
ok_(__FILE__, line)(msg->dwSize == sizeof(*msg), "got dwSize %lu\n", msg->dwSize);
2494+
ok_(__FILE__, line)(!!msg->rtTime, "got rtTime %I64u\n", msg->rtTime);
2495+
ok_(__FILE__, line)(abs(msg->mtTime - time) < 10, "got mtTime %lu\n", msg->mtTime);
2496+
ok_(__FILE__, line)(msg->dwPChannel == chan, "got dwPChannel %lu\n", msg->dwPChannel);
2497+
ok_(__FILE__, line)(!!msg->dwVirtualTrackID, "got dwVirtualTrackID %lu\n", msg->dwVirtualTrackID);
2498+
ok_(__FILE__, line)(msg->dwType == DMUS_PMSGT_NOTE, "got %#lx\n", msg->dwType);
2499+
ok_(__FILE__, line)(!msg->dwVoiceID, "got dwVoiceID %lu\n", msg->dwVoiceID);
2500+
ok_(__FILE__, line)(msg->dwGroupID == 1, "got dwGroupID %lu\n", msg->dwGroupID);
2501+
ok_(__FILE__, line)(!msg->punkUser, "got punkUser %p\n", msg->punkUser);
2502+
ok_(__FILE__, line)(msg->mtDuration == duration, "got mtDuration %lu\n", msg->mtDuration);
2503+
ok_(__FILE__, line)(msg->wMusicValue == key, "got wMusicValue %u\n", msg->wMusicValue);
2504+
ok_(__FILE__, line)(!msg->wMeasure, "got wMeasure %u\n", msg->wMeasure);
2505+
/* FIXME: ok_(__FILE__, line)(!msg->nOffset, "got nOffset %u\n", msg->nOffset); */
2506+
/* FIXME: ok_(__FILE__, line)(!msg->bBeat, "got bBeat %u\n", msg->bBeat); */
2507+
/* FIXME: ok_(__FILE__, line)(!msg->bGrid, "got bGrid %u\n", msg->bGrid); */
2508+
ok_(__FILE__, line)(msg->bVelocity == vel, "got bVelocity %u\n", msg->bVelocity);
2509+
ok_(__FILE__, line)(msg->bFlags == 1, "got bFlags %#x\n", msg->bFlags);
2510+
ok_(__FILE__, line)(!msg->bTimeRange, "got bTimeRange %u\n", msg->bTimeRange);
2511+
ok_(__FILE__, line)(!msg->bDurRange, "got bDurRange %u\n", msg->bDurRange);
2512+
ok_(__FILE__, line)(!msg->bVelRange, "got bVelRange %u\n", msg->bVelRange);
2513+
ok_(__FILE__, line)(!msg->bPlayModeFlags, "got bPlayModeFlags %#x\n", msg->bPlayModeFlags);
2514+
ok_(__FILE__, line)(!msg->bSubChordLevel, "got bSubChordLevel %u\n", msg->bSubChordLevel);
2515+
ok_(__FILE__, line)(msg->bMidiValue == key, "got bMidiValue %u\n", msg->bMidiValue);
2516+
ok_(__FILE__, line)(!msg->cTranspose, "got cTranspose %u\n", msg->cTranspose);
2517+
}
2518+
2519+
static void test_sequence_track(void)
2520+
{
2521+
static const DWORD message_types[] =
2522+
{
2523+
DMUS_PMSGT_MIDI,
2524+
DMUS_PMSGT_NOTE,
2525+
DMUS_PMSGT_CURVE,
2526+
DMUS_PMSGT_DIRTY,
2527+
};
2528+
static const LARGE_INTEGER zero = {0};
2529+
IDirectMusicPerformance *performance;
2530+
IDirectMusicSegment *segment;
2531+
IDirectMusicGraph *graph;
2532+
IDirectMusicTrack *track;
2533+
IPersistStream *persist;
2534+
IDirectMusicTool *tool;
2535+
DMUS_NOTE_PMSG *note;
2536+
IStream *stream;
2537+
DMUS_PMSG *msg;
2538+
HRESULT hr;
2539+
DWORD ret;
2540+
2541+
hr = test_tool_create(message_types, ARRAY_SIZE(message_types), &tool);
2542+
ok(hr == S_OK, "got %#lx\n", hr);
2543+
2544+
hr = CoCreateInstance(&CLSID_DirectMusicPerformance, NULL, CLSCTX_INPROC_SERVER,
2545+
&IID_IDirectMusicPerformance, (void **)&performance);
2546+
ok(hr == S_OK, "got %#lx\n", hr);
2547+
2548+
hr = CoCreateInstance(&CLSID_DirectMusicGraph, NULL, CLSCTX_INPROC_SERVER,
2549+
&IID_IDirectMusicGraph, (void **)&graph);
2550+
ok(hr == S_OK, "got %#lx\n", hr);
2551+
hr = IDirectMusicGraph_InsertTool(graph, (IDirectMusicTool *)tool, NULL, 0, -1);
2552+
ok(hr == S_OK, "got %#lx\n", hr);
2553+
hr = IDirectMusicPerformance_SetGraph(performance, graph);
2554+
ok(hr == S_OK, "got %#lx\n", hr);
2555+
IDirectMusicGraph_Release(graph);
2556+
2557+
2558+
/* create a segment and load a simple RIFF stream */
2559+
2560+
hr = CoCreateInstance(&CLSID_DirectMusicSegment, NULL, CLSCTX_INPROC_SERVER,
2561+
&IID_IDirectMusicSegment, (void **)&segment);
2562+
ok(hr == S_OK, "got %#lx\n", hr);
2563+
2564+
hr = IDirectMusicSegment_QueryInterface(segment, &IID_IPersistStream, (void **)&persist);
2565+
ok(hr == S_OK, "got %#lx\n", hr);
2566+
hr = CreateStreamOnHGlobal(0, TRUE, &stream);
2567+
ok(hr == S_OK, "got %#lx\n", hr);
2568+
2569+
CHUNK_RIFF(stream, "DMSG")
2570+
{
2571+
/* set a non-zero segment length, or nothing will be played */
2572+
DMUS_IO_SEGMENT_HEADER head = {.mtLength = 2000};
2573+
CHUNK_DATA(stream, "segh", head);
2574+
CHUNK_DATA(stream, "guid", CLSID_DirectMusicSegment);
2575+
}
2576+
CHUNK_END;
2577+
2578+
hr = IStream_Seek(stream, zero, 0, NULL);
2579+
ok(hr == S_OK, "got %#lx\n", hr);
2580+
hr = IPersistStream_Load(persist, stream);
2581+
ok(hr == S_OK, "got %#lx\n", hr);
2582+
IPersistStream_Release(persist);
2583+
IStream_Release(stream);
2584+
2585+
2586+
/* add a sequence track to our segment */
2587+
2588+
hr = CoCreateInstance(&CLSID_DirectMusicSeqTrack, NULL, CLSCTX_INPROC_SERVER,
2589+
&IID_IDirectMusicTrack, (void **)&track);
2590+
ok(hr == S_OK, "got %#lx\n", hr);
2591+
2592+
hr = IDirectMusicSegment_QueryInterface(track, &IID_IPersistStream, (void **)&persist);
2593+
ok(hr == S_OK, "got %#lx\n", hr);
2594+
hr = CreateStreamOnHGlobal(0, TRUE, &stream);
2595+
ok(hr == S_OK, "got %#lx\n", hr);
2596+
2597+
CHUNK_BEGIN(stream, "seqt")
2598+
{
2599+
DMUS_IO_SEQ_ITEM items[] =
2600+
{
2601+
{.mtTime = 0, .mtDuration = 500, .dwPChannel = 0, .bStatus = 0x90, .bByte1 = 60, .bByte2 = 120},
2602+
{.mtTime = 1000, .mtDuration = 200, .dwPChannel = 1, .bStatus = 0x90, .bByte1 = 50, .bByte2 = 100},
2603+
};
2604+
CHUNK_ARRAY(stream, "evtl", items);
2605+
}
2606+
CHUNK_END;
2607+
2608+
hr = IStream_Seek(stream, zero, 0, NULL);
2609+
ok(hr == S_OK, "got %#lx\n", hr);
2610+
hr = IPersistStream_Load(persist, stream);
2611+
ok(hr == S_OK, "got %#lx\n", hr);
2612+
IPersistStream_Release(persist);
2613+
IStream_Release(stream);
2614+
2615+
hr = IDirectMusicSegment_InsertTrack(segment, (IDirectMusicTrack *)track, 1);
2616+
ok(hr == S_OK, "got %#lx\n", hr);
2617+
IDirectMusicTrack_Release(track);
2618+
2619+
2620+
/* now play the segment, and check produced messages */
2621+
2622+
hr = IDirectMusicPerformance_Init(performance, NULL, 0, 0);
2623+
ok(hr == S_OK, "got %#lx\n", hr);
2624+
2625+
hr = IDirectMusicPerformance_PlaySegment(performance, segment, 0x800, 0, NULL);
2626+
ok(hr == S_OK, "got %#lx\n", hr);
2627+
2628+
ret = test_tool_wait_message(tool, 500, &msg);
2629+
todo_wine ok(!ret, "got %#lx\n", ret);
2630+
if (!ret)
2631+
{
2632+
ok(msg->dwType == DMUS_PMSGT_DIRTY, "got %#lx\n", msg->dwType);
2633+
hr = IDirectMusicPerformance_FreePMsg(performance, msg);
2634+
ok(hr == S_OK, "got %#lx\n", hr);
2635+
}
2636+
2637+
ret = test_tool_wait_message(tool, 500, (DMUS_PMSG **)&note);
2638+
todo_wine ok(!ret, "got %#lx\n", ret);
2639+
if (!ret)
2640+
{
2641+
check_dmus_note_pmsg(note, 0, 0, 500, 60, 120);
2642+
hr = IDirectMusicPerformance_FreePMsg(performance, (DMUS_PMSG *)note);
2643+
ok(hr == S_OK, "got %#lx\n", hr);
2644+
}
2645+
2646+
ret = test_tool_wait_message(tool, 500, (DMUS_PMSG **)&note);
2647+
todo_wine ok(!ret, "got %#lx\n", ret);
2648+
if (!ret)
2649+
{
2650+
check_dmus_note_pmsg(note, 1000, 1, 200, 50, 100);
2651+
hr = IDirectMusicPerformance_FreePMsg(performance, (DMUS_PMSG *)note);
2652+
ok(hr == S_OK, "got %#lx\n", hr);
2653+
}
2654+
2655+
ret = test_tool_wait_message(tool, 500, &msg);
2656+
todo_wine ok(!ret, "got %#lx\n", ret);
2657+
if (!ret)
2658+
{
2659+
ok(msg->dwType == DMUS_PMSGT_DIRTY, "got %#lx\n", msg->dwType);
2660+
hr = IDirectMusicPerformance_FreePMsg(performance, msg);
2661+
ok(hr == S_OK, "got %#lx\n", hr);
2662+
}
2663+
2664+
IDirectMusicSegment_Release(segment);
2665+
2666+
2667+
hr = IDirectMusicPerformance_CloseDown(performance);
2668+
ok(hr == S_OK, "got %#lx\n", hr);
2669+
2670+
IDirectMusicPerformance_Release(performance);
2671+
IDirectMusicTool_Release(tool);
2672+
}
2673+
24142674
START_TEST(dmime)
24152675
{
24162676
CoInitialize(NULL);
@@ -2440,6 +2700,7 @@ START_TEST(dmime)
24402700
test_performance_pmsg();
24412701
test_notification_pmsg();
24422702
test_wave_pmsg();
2703+
test_sequence_track();
24432704

24442705
CoUninitialize();
24452706
}

0 commit comments

Comments
 (0)