2 * Unit test suite for IDirectMusicPerformance
4 * Copyright 2010 Austin Lund
6 * This library 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.
11 * This library 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.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 #include <wine/test.h>
31 DEFINE_GUID(GUID_NULL
,0,0,0,0,0,0,0,0,0,0,0);
32 DEFINE_GUID(GUID_Bunk
,0xFFFFFFFF,0xFFFF,0xFFFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF);
34 static void create_performance(IDirectMusicPerformance8
**performance
, IDirectMusic
**dmusic
,
35 IDirectSound
**dsound
, BOOL set_cooplevel
)
39 hr
= CoCreateInstance(&CLSID_DirectMusicPerformance
, NULL
, CLSCTX_INPROC_SERVER
,
40 &IID_IDirectMusicPerformance8
, (void **)performance
);
41 ok(hr
== S_OK
, "DirectMusicPerformance create failed: %#lx\n", hr
);
43 hr
= CoCreateInstance(&CLSID_DirectMusic
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectMusic8
,
45 ok(hr
== S_OK
, "DirectMusic create failed: %#lx\n", hr
);
48 hr
= DirectSoundCreate8(NULL
, (IDirectSound8
**)dsound
, NULL
);
49 ok(hr
== S_OK
, "DirectSoundCreate failed: %#lx\n", hr
);
51 hr
= IDirectSound_SetCooperativeLevel(*dsound
, GetForegroundWindow(), DSSCL_PRIORITY
);
52 ok(hr
== S_OK
, "SetCooperativeLevel failed: %#lx\n", hr
);
57 static void destroy_performance(IDirectMusicPerformance8
*performance
, IDirectMusic
*dmusic
,
62 hr
= IDirectMusicPerformance8_CloseDown(performance
);
63 ok(hr
== S_OK
, "CloseDown failed: %#lx\n", hr
);
64 IDirectMusicPerformance8_Release(performance
);
66 IDirectMusic_Release(dmusic
);
68 IDirectSound_Release(dsound
);
71 static ULONG
get_refcount(void *iface
)
73 IUnknown
*unknown
= iface
;
74 IUnknown_AddRef(unknown
);
75 return IUnknown_Release(unknown
);
78 static HRESULT
test_InitAudio(void)
80 IDirectMusicPerformance8
*performance
;
83 IDirectMusicPort
*port
;
84 IDirectMusicAudioPath
*path
;
89 hr
= CoCreateInstance(&CLSID_DirectMusicPerformance
, NULL
, CLSCTX_INPROC_SERVER
,
90 &IID_IDirectMusicPerformance8
, (void **)&performance
);
92 skip("Cannot create DirectMusicPerformance object (%lx)\n", hr
);
98 hr
= IDirectMusicPerformance8_InitAudio(performance
, NULL
, &dsound
, NULL
,
99 DMUS_APATH_SHARED_STEREOPLUSREVERB
, 128, DMUS_AUDIOF_ALL
, NULL
);
101 IDirectMusicPerformance8_Release(performance
);
105 hr
= IDirectMusicPerformance8_PChannelInfo(performance
, 128, &port
, NULL
, NULL
);
106 ok(hr
== E_INVALIDARG
, "PChannelInfo failed, got %#lx\n", hr
);
107 hr
= IDirectMusicPerformance8_PChannelInfo(performance
, 127, &port
, NULL
, NULL
);
108 ok(hr
== S_OK
, "PChannelInfo failed, got %#lx\n", hr
);
109 IDirectMusicPort_Release(port
);
111 hr
= IDirectMusicPerformance8_PChannelInfo(performance
, 0, &port
, NULL
, NULL
);
112 ok(hr
== S_OK
, "PChannelInfo failed, got %#lx\n", hr
);
113 ok(port
!= NULL
, "IDirectMusicPort not set\n");
114 hr
= IDirectMusicPerformance8_AssignPChannel(performance
, 0, port
, 0, 0);
115 todo_wine
ok(hr
== DMUS_E_AUDIOPATHS_IN_USE
, "AssignPChannel failed (%#lx)\n", hr
);
116 hr
= IDirectMusicPerformance8_AssignPChannelBlock(performance
, 0, port
, 0);
117 todo_wine
ok(hr
== DMUS_E_AUDIOPATHS_IN_USE
, "AssignPChannelBlock failed (%#lx)\n", hr
);
118 IDirectMusicPort_Release(port
);
120 hr
= IDirectMusicPerformance8_GetDefaultAudioPath(performance
, &path
);
121 ok(hr
== S_OK
, "Failed to call GetDefaultAudioPath (%lx)\n", hr
);
123 IDirectMusicAudioPath_Release(path
);
125 hr
= IDirectMusicPerformance8_CloseDown(performance
);
126 ok(hr
== S_OK
, "Failed to call CloseDown (%lx)\n", hr
);
128 IDirectMusicPerformance8_Release(performance
);
130 /* Auto generated dmusic and dsound */
131 create_performance(&performance
, NULL
, NULL
, FALSE
);
132 hr
= IDirectMusicPerformance8_InitAudio(performance
, NULL
, NULL
, NULL
, 0, 64, 0, NULL
);
133 ok(hr
== S_OK
, "InitAudio failed: %#lx\n", hr
);
134 hr
= IDirectMusicPerformance8_PChannelInfo(performance
, 0, &port
, NULL
, NULL
);
135 ok(hr
== E_INVALIDARG
, "PChannelInfo failed, got %#lx\n", hr
);
136 destroy_performance(performance
, NULL
, NULL
);
138 /* Refcounts for auto generated dmusic and dsound */
139 create_performance(&performance
, NULL
, NULL
, FALSE
);
142 hr
= IDirectMusicPerformance8_InitAudio(performance
, &dmusic
, &dsound
, NULL
, 0, 64, 0, NULL
);
143 ok(hr
== S_OK
, "InitAudio failed: %#lx\n", hr
);
144 ref
= get_refcount(dsound
);
145 ok(ref
== 3, "dsound ref count got %ld expected 3\n", ref
);
146 ref
= get_refcount(dmusic
);
147 ok(ref
== 2, "dmusic ref count got %ld expected 2\n", ref
);
148 destroy_performance(performance
, NULL
, NULL
);
150 /* dsound without SetCooperativeLevel() */
151 create_performance(&performance
, NULL
, &dsound
, FALSE
);
152 hr
= IDirectMusicPerformance8_InitAudio(performance
, NULL
, &dsound
, NULL
, 0, 0, 0, NULL
);
153 todo_wine
ok(hr
== DSERR_PRIOLEVELNEEDED
, "InitAudio failed: %#lx\n", hr
);
154 destroy_performance(performance
, NULL
, dsound
);
156 /* Using the wrong CLSID_DirectSound */
157 create_performance(&performance
, NULL
, NULL
, FALSE
);
158 hr
= DirectSoundCreate(NULL
, &dsound
, NULL
);
159 ok(hr
== S_OK
, "DirectSoundCreate failed: %#lx\n", hr
);
160 hr
= IDirectMusicPerformance8_InitAudio(performance
, NULL
, &dsound
, NULL
, 0, 0, 0, NULL
);
161 todo_wine
ok(hr
== E_NOINTERFACE
, "InitAudio failed: %#lx\n", hr
);
162 destroy_performance(performance
, NULL
, dsound
);
164 /* Init() works with just a CLSID_DirectSound */
165 create_performance(&performance
, NULL
, NULL
, FALSE
);
166 hr
= DirectSoundCreate(NULL
, &dsound
, NULL
);
167 ok(hr
== S_OK
, "DirectSoundCreate failed: %#lx\n", hr
);
168 hr
= IDirectSound_SetCooperativeLevel(dsound
, GetForegroundWindow(), DSSCL_PRIORITY
);
169 ok(hr
== S_OK
, "SetCooperativeLevel failed: %#lx\n", hr
);
170 hr
= IDirectMusicPerformance8_Init(performance
, NULL
, dsound
, NULL
);
171 ok(hr
== S_OK
, "Init failed: %#lx\n", hr
);
172 destroy_performance(performance
, NULL
, dsound
);
174 /* Init() followed by InitAudio() */
175 create_performance(&performance
, NULL
, &dsound
, TRUE
);
176 hr
= IDirectMusicPerformance8_Init(performance
, NULL
, dsound
, NULL
);
177 ok(hr
== S_OK
, "Init failed: %#lx\n", hr
);
178 hr
= IDirectMusicPerformance8_InitAudio(performance
, NULL
, &dsound
, NULL
, 0, 0, 0, NULL
);
179 ok(hr
== DMUS_E_ALREADY_INITED
, "InitAudio failed: %#lx\n", hr
);
180 destroy_performance(performance
, NULL
, dsound
);
182 /* Provided dmusic and dsound */
183 create_performance(&performance
, &dmusic
, &dsound
, TRUE
);
184 hr
= IDirectMusicPerformance8_InitAudio(performance
, &dmusic
, &dsound
, NULL
, 0, 64, 0, NULL
);
185 ok(hr
== S_OK
, "InitAudio failed: %#lx\n", hr
);
186 ref
= get_refcount(dsound
);
187 todo_wine
ok(ref
== 2, "dsound ref count got %ld expected 2\n", ref
);
188 ref
= get_refcount(dmusic
);
189 ok(ref
== 2, "dmusic ref count got %ld expected 2\n", ref
);
190 destroy_performance(performance
, dmusic
, dsound
);
192 /* Provided dmusic initialized with SetDirectSound */
193 create_performance(&performance
, &dmusic
, &dsound
, TRUE
);
194 hr
= IDirectMusic_SetDirectSound(dmusic
, dsound
, NULL
);
195 ok(hr
== S_OK
, "SetDirectSound failed: %#lx\n", hr
);
196 ref
= get_refcount(dsound
);
197 ok(ref
== 2, "dsound ref count got %ld expected 2\n", ref
);
198 hr
= IDirectMusicPerformance8_InitAudio(performance
, &dmusic
, NULL
, NULL
, 0, 64, 0, NULL
);
199 ok(hr
== S_OK
, "InitAudio failed: %#lx\n", hr
);
200 ref
= get_refcount(dsound
);
201 todo_wine
ok(ref
== 2, "dsound ref count got %ld expected 2\n", ref
);
202 ref
= get_refcount(dmusic
);
203 ok(ref
== 2, "dmusic ref count got %ld expected 2\n", ref
);
204 destroy_performance(performance
, dmusic
, dsound
);
206 /* Provided dmusic and dsound, dmusic initialized with SetDirectSound */
207 create_performance(&performance
, &dmusic
, &dsound
, TRUE
);
208 hr
= IDirectMusic_SetDirectSound(dmusic
, dsound
, NULL
);
209 ok(hr
== S_OK
, "SetDirectSound failed: %#lx\n", hr
);
210 ref
= get_refcount(dsound
);
211 ok(ref
== 2, "dsound ref count got %ld expected 2\n", ref
);
212 hr
= IDirectMusicPerformance8_InitAudio(performance
, &dmusic
, &dsound
, NULL
, 0, 64, 0, NULL
);
213 ok(hr
== S_OK
, "InitAudio failed: %#lx\n", hr
);
214 ref
= get_refcount(dsound
);
215 ok(ref
== 3, "dsound ref count got %ld expected 3\n", ref
);
216 ref
= get_refcount(dmusic
);
217 ok(ref
== 2, "dmusic ref count got %ld expected 2\n", ref
);
218 destroy_performance(performance
, dmusic
, dsound
);
220 /* InitAudio with perf channel count not a multiple of 16 rounds up */
221 create_performance(&performance
, NULL
, NULL
, TRUE
);
222 hr
= IDirectMusicPerformance8_InitAudio(performance
, NULL
, NULL
, NULL
,
223 DMUS_APATH_SHARED_STEREOPLUSREVERB
, 29, DMUS_AUDIOF_ALL
, NULL
);
224 ok(hr
== S_OK
, "InitAudio failed: %#lx\n", hr
);
225 hr
= IDirectMusicPerformance8_PChannelInfo(performance
, 31, &port
, &group
, &channel
);
226 ok(hr
== S_OK
&& group
== 2 && channel
== 15,
227 "PChannelInfo failed, got %#lx, %lu, %lu\n", hr
, group
, channel
);
228 hr
= IDirectMusicPerformance8_PChannelInfo(performance
, 32, &port
, NULL
, NULL
);
229 ok(hr
== E_INVALIDARG
, "PChannelInfo failed, got %#lx\n", hr
);
230 destroy_performance(performance
, NULL
, NULL
);
235 static void test_createport(void)
237 IDirectMusicPerformance8
*perf
;
238 IDirectMusic
*music
= NULL
;
239 IDirectMusicPort
*port
= NULL
;
240 DMUS_PORTCAPS portcaps
;
241 DMUS_PORTPARAMS portparams
;
245 hr
= CoCreateInstance(&CLSID_DirectMusicPerformance
, NULL
,
246 CLSCTX_INPROC_SERVER
, &IID_IDirectMusicPerformance8
, (void**)&perf
);
247 ok(hr
== S_OK
, "CoCreateInstance failed: %#lx\n", hr
);
249 hr
= IDirectMusicPerformance8_Init(perf
, &music
, NULL
, NULL
);
250 ok(hr
== S_OK
, "Init failed: %#lx\n", hr
);
251 ok(music
!= NULL
, "Didn't get IDirectMusic pointer\n");
255 portcaps
.dwSize
= sizeof(portcaps
);
257 hr
= IDirectMusic_EnumPort(music
, i
, &portcaps
);
258 ok(hr
== S_OK
|| hr
== S_FALSE
|| (i
== 0 && hr
== E_INVALIDARG
), "EnumPort failed: %#lx\n", hr
);
262 ok(portcaps
.dwSize
== sizeof(portcaps
), "Got unexpected portcaps struct size: %lu\n", portcaps
.dwSize
);
263 trace("portcaps(%lu).dwFlags: %#lx\n", i
, portcaps
.dwFlags
);
264 trace("portcaps(%lu).guidPort: %s\n", i
, wine_dbgstr_guid(&portcaps
.guidPort
));
265 trace("portcaps(%lu).dwClass: %#lx\n", i
, portcaps
.dwClass
);
266 trace("portcaps(%lu).dwType: %#lx\n", i
, portcaps
.dwType
);
267 trace("portcaps(%lu).dwMemorySize: %#lx\n", i
, portcaps
.dwMemorySize
);
268 trace("portcaps(%lu).dwMaxChannelGroups: %lu\n", i
, portcaps
.dwMaxChannelGroups
);
269 trace("portcaps(%lu).dwMaxVoices: %lu\n", i
, portcaps
.dwMaxVoices
);
270 trace("portcaps(%lu).dwMaxAudioChannels: %lu\n", i
, portcaps
.dwMaxAudioChannels
);
271 trace("portcaps(%lu).dwEffectFlags: %#lx\n", i
, portcaps
.dwEffectFlags
);
272 trace("portcaps(%lu).wszDescription: %s\n", i
, wine_dbgstr_w(portcaps
.wszDescription
));
278 win_skip("No ports available, skipping tests\n");
282 portparams
.dwSize
= sizeof(portparams
);
284 /* dwValidParams == 0 -> S_OK, filled struct */
285 portparams
.dwValidParams
= 0;
286 hr
= IDirectMusic_CreatePort(music
, &CLSID_DirectMusicSynth
, &portparams
, &port
, NULL
);
287 ok(hr
== S_OK
, "CreatePort failed: %#lx\n", hr
);
288 ok(port
!= NULL
, "Didn't get IDirectMusicPort pointer\n");
289 ok(portparams
.dwValidParams
, "portparams struct was not filled in\n");
290 IDirectMusicPort_Release(port
);
293 /* dwValidParams != 0, invalid param -> S_FALSE, filled struct */
294 portparams
.dwValidParams
= DMUS_PORTPARAMS_CHANNELGROUPS
;
295 portparams
.dwChannelGroups
= 0;
296 hr
= IDirectMusic_CreatePort(music
, &CLSID_DirectMusicSynth
, &portparams
, &port
, NULL
);
297 todo_wine
ok(hr
== S_FALSE
, "CreatePort failed: %#lx\n", hr
);
298 ok(port
!= NULL
, "Didn't get IDirectMusicPort pointer\n");
299 ok(portparams
.dwValidParams
, "portparams struct was not filled in\n");
300 IDirectMusicPort_Release(port
);
303 /* dwValidParams != 0, valid params -> S_OK */
304 hr
= IDirectMusic_CreatePort(music
, &CLSID_DirectMusicSynth
, &portparams
, &port
, NULL
);
305 ok(hr
== S_OK
, "CreatePort failed: %#lx\n", hr
);
306 ok(port
!= NULL
, "Didn't get IDirectMusicPort pointer\n");
307 IDirectMusicPort_Release(port
);
310 /* GUID_NULL succeeds */
311 portparams
.dwValidParams
= 0;
312 hr
= IDirectMusic_CreatePort(music
, &GUID_NULL
, &portparams
, &port
, NULL
);
313 ok(hr
== S_OK
, "CreatePort failed: %#lx\n", hr
);
314 ok(port
!= NULL
, "Didn't get IDirectMusicPort pointer\n");
315 ok(portparams
.dwValidParams
, "portparams struct was not filled in\n");
316 IDirectMusicPort_Release(port
);
319 /* null GUID fails */
320 portparams
.dwValidParams
= 0;
321 hr
= IDirectMusic_CreatePort(music
, NULL
, &portparams
, &port
, NULL
);
322 ok(hr
== E_POINTER
, "CreatePort failed: %#lx\n", hr
);
323 ok(port
== NULL
, "Get IDirectMusicPort pointer? %p\n", port
);
324 ok(portparams
.dwValidParams
== 0, "portparams struct was filled in?\n");
326 /* garbage GUID fails */
327 portparams
.dwValidParams
= 0;
328 hr
= IDirectMusic_CreatePort(music
, &GUID_Bunk
, &portparams
, &port
, NULL
);
329 ok(hr
== E_NOINTERFACE
, "CreatePort failed: %#lx\n", hr
);
330 ok(port
== NULL
, "Get IDirectMusicPort pointer? %p\n", port
);
331 ok(portparams
.dwValidParams
== 0, "portparams struct was filled in?\n");
333 hr
= IDirectMusicPerformance8_CloseDown(perf
);
334 ok(hr
== S_OK
, "CloseDown failed: %#lx\n", hr
);
336 IDirectMusic_Release(music
);
337 IDirectMusicPerformance_Release(perf
);
340 static void test_pchannel(void)
342 IDirectMusicPerformance8
*perf
;
343 IDirectMusicPort
*port
= NULL
, *port2
;
344 DWORD channel
, group
;
348 create_performance(&perf
, NULL
, NULL
, TRUE
);
349 hr
= IDirectMusicPerformance8_Init(perf
, NULL
, NULL
, NULL
);
350 ok(hr
== S_OK
, "Init failed: %#lx\n", hr
);
351 hr
= IDirectMusicPerformance8_PChannelInfo(perf
, 0, &port
, NULL
, NULL
);
352 ok(hr
== E_INVALIDARG
&& !port
, "PChannelInfo failed, got %#lx, %p\n", hr
, port
);
354 /* Add default port. Sets PChannels 0-15 to the corresponding channels in group 1 */
355 hr
= IDirectMusicPerformance8_AddPort(perf
, NULL
);
356 ok(hr
== S_OK
, "AddPort of default port failed: %#lx\n", hr
);
357 hr
= IDirectMusicPerformance8_PChannelInfo(perf
, 0, NULL
, NULL
, NULL
);
358 ok(hr
== S_OK
, "PChannelInfo failed, got %#lx\n", hr
);
359 hr
= IDirectMusicPerformance8_PChannelInfo(perf
, 0, &port
, NULL
, NULL
);
360 ok(hr
== S_OK
&& port
, "PChannelInfo failed, got %#lx, %p\n", hr
, port
);
361 for (i
= 1; i
< 16; i
++) {
362 hr
= IDirectMusicPerformance8_PChannelInfo(perf
, i
, &port2
, &group
, &channel
);
363 ok(hr
== S_OK
&& port
== port2
&& group
== 1 && channel
== i
,
364 "PChannelInfo failed, got %#lx, %p, %lu, %lu\n", hr
, port2
, group
, channel
);
365 IDirectMusicPort_Release(port2
);
368 /* Unset PChannels fail to retrieve */
369 hr
= IDirectMusicPerformance8_PChannelInfo(perf
, 16, &port2
, NULL
, NULL
);
370 ok(hr
== E_INVALIDARG
, "PChannelInfo failed, got %#lx, %p\n", hr
, port
);
371 hr
= IDirectMusicPerformance8_PChannelInfo(perf
, MAXDWORD
- 16, &port2
, NULL
, NULL
);
372 ok(hr
== E_INVALIDARG
, "PChannelInfo failed, got %#lx, %p\n", hr
, port
);
374 /* Channel group 0 can be set just fine */
375 hr
= IDirectMusicPerformance8_AssignPChannel(perf
, 0, port
, 0, 0);
376 ok(hr
== S_OK
, "AssignPChannel failed, got %#lx\n", hr
);
377 hr
= IDirectMusicPerformance8_AssignPChannelBlock(perf
, 0, port
, 0);
378 ok(hr
== S_OK
, "AssignPChannelBlock failed, got %#lx\n", hr
);
379 for (i
= 1; i
< 16; i
++) {
380 hr
= IDirectMusicPerformance8_PChannelInfo(perf
, i
, &port2
, &group
, &channel
);
381 ok(hr
== S_OK
&& port
== port2
&& group
== 0 && channel
== i
,
382 "PChannelInfo failed, got %#lx, %p, %lu, %lu\n", hr
, port2
, group
, channel
);
383 IDirectMusicPort_Release(port2
);
386 /* Last PChannel Block can be set only individually but not read */
387 hr
= IDirectMusicPerformance8_AssignPChannel(perf
, MAXDWORD
, port
, 0, 3);
388 ok(hr
== S_OK
, "AssignPChannel failed, got %#lx\n", hr
);
389 port2
= (IDirectMusicPort
*)0xdeadbeef;
390 hr
= IDirectMusicPerformance8_PChannelInfo(perf
, MAXDWORD
, &port2
, NULL
, NULL
);
391 todo_wine
ok(hr
== E_INVALIDARG
&& port2
== (IDirectMusicPort
*)0xdeadbeef,
392 "PChannelInfo failed, got %#lx, %p\n", hr
, port2
);
393 hr
= IDirectMusicPerformance8_AssignPChannelBlock(perf
, MAXDWORD
, port
, 0);
394 ok(hr
== E_INVALIDARG
, "AssignPChannelBlock failed, got %#lx\n", hr
);
395 hr
= IDirectMusicPerformance8_AssignPChannelBlock(perf
, MAXDWORD
/ 16, port
, 1);
396 todo_wine
ok(hr
== E_INVALIDARG
, "AssignPChannelBlock failed, got %#lx\n", hr
);
397 for (i
= MAXDWORD
- 15; i
< MAXDWORD
; i
++) {
398 hr
= IDirectMusicPerformance8_AssignPChannel(perf
, i
, port
, 0, 0);
399 ok(hr
== S_OK
, "AssignPChannel failed, got %#lx\n", hr
);
400 hr
= IDirectMusicPerformance8_PChannelInfo(perf
, i
, &port2
, NULL
, NULL
);
401 todo_wine
ok(hr
== E_INVALIDARG
&& port2
== (IDirectMusicPort
*)0xdeadbeef,
402 "PChannelInfo failed, got %#lx, %p\n", hr
, port2
);
405 /* Second to last PChannel Block can be set only individually and read */
406 hr
= IDirectMusicPerformance8_AssignPChannelBlock(perf
, MAXDWORD
/ 16 - 1, port
, 1);
407 todo_wine
ok(hr
== E_INVALIDARG
, "AssignPChannelBlock failed, got %#lx\n", hr
);
408 for (i
= MAXDWORD
- 31; i
< MAXDWORD
- 15; i
++) {
409 hr
= IDirectMusicPerformance8_AssignPChannel(perf
, i
, port
, 1, 7);
410 ok(hr
== S_OK
, "AssignPChannel failed, got %#lx\n", hr
);
411 hr
= IDirectMusicPerformance8_PChannelInfo(perf
, i
, &port2
, &group
, &channel
);
412 ok(hr
== S_OK
&& port2
== port
&& group
== 1 && channel
== 7,
413 "PChannelInfo failed, got %#lx, %p, %lu, %lu\n", hr
, port2
, group
, channel
);
414 IDirectMusicPort_Release(port2
);
417 /* Third to last PChannel Block behaves normal */
418 hr
= IDirectMusicPerformance8_AssignPChannelBlock(perf
, MAXDWORD
/ 16 - 2, port
, 0);
419 ok(hr
== S_OK
, "AssignPChannelBlock failed, got %#lx\n", hr
);
420 for (i
= MAXDWORD
- 47; i
< MAXDWORD
- 31; i
++) {
421 hr
= IDirectMusicPerformance8_PChannelInfo(perf
, i
, &port2
, &group
, &channel
);
422 ok(hr
== S_OK
&& port2
== port
&& group
== 0 && channel
== i
% 16,
423 "PChannelInfo failed, got %#lx, %p, %lu, %lu\n", hr
, port2
, group
, channel
);
424 IDirectMusicPort_Release(port2
);
427 /* One PChannel set in a Block, rest is initialized too */
428 hr
= IDirectMusicPerformance8_AssignPChannel(perf
, 4711, port
, 1, 13);
429 ok(hr
== S_OK
, "AssignPChannel failed, got %#lx\n", hr
);
430 hr
= IDirectMusicPerformance8_PChannelInfo(perf
, 4711, &port2
, &group
, &channel
);
431 ok(hr
== S_OK
&& port2
== port
&& group
== 1 && channel
== 13,
432 "PChannelInfo failed, got %#lx, %p, %lu, %lu\n", hr
, port2
, group
, channel
);
433 IDirectMusicPort_Release(port2
);
434 group
= channel
= 0xdeadbeef;
435 hr
= IDirectMusicPerformance8_PChannelInfo(perf
, 4712, &port2
, &group
, &channel
);
436 ok(hr
== S_OK
&& port2
== port
&& group
== 0 && channel
== 8,
437 "PChannelInfo failed, got %#lx, %p, %lu, %lu\n", hr
, port2
, group
, channel
);
438 IDirectMusicPort_Release(port2
);
439 group
= channel
= 0xdeadbeef;
440 hr
= IDirectMusicPerformance8_PChannelInfo(perf
, 4719, &port2
, &group
, &channel
);
441 ok(hr
== S_OK
&& port2
== port
&& group
== 0 && channel
== 15,
442 "PChannelInfo failed, got %#lx, %p, %lu, %lu\n", hr
, port2
, group
, channel
);
443 IDirectMusicPort_Release(port2
);
445 IDirectMusicPort_Release(port
);
446 destroy_performance(perf
, NULL
, NULL
);
449 static void test_COM(void)
451 IDirectMusicPerformance
*dmp
= (IDirectMusicPerformance
*)0xdeadbeef;
452 IDirectMusicPerformance
*dmp2
;
453 IDirectMusicPerformance8
*dmp8
;
457 /* COM aggregation */
458 hr
= CoCreateInstance(&CLSID_DirectMusicPerformance
, (IUnknown
*)0xdeadbeef, CLSCTX_INPROC_SERVER
,
459 &IID_IUnknown
, (void**)&dmp
);
460 ok(hr
== CLASS_E_NOAGGREGATION
,
461 "DirectMusicPerformance create failed: %#lx, expected CLASS_E_NOAGGREGATION\n", hr
);
462 ok(!dmp
, "dmp = %p\n", dmp
);
465 hr
= CoCreateInstance(&CLSID_DirectMusicPerformance
, NULL
, CLSCTX_INPROC_SERVER
,
466 &IID_IDirectMusicObject
, (void**)&dmp
);
467 ok(hr
== E_NOINTERFACE
, "DirectMusicPerformance create failed: %#lx, expected E_NOINTERFACE\n", hr
);
470 hr
= CoCreateInstance(&CLSID_DirectMusicPerformance
, NULL
, CLSCTX_INPROC_SERVER
,
471 &IID_IDirectMusicPerformance
, (void**)&dmp
);
472 ok(hr
== S_OK
, "DirectMusicPerformance create failed: %#lx, expected S_OK\n", hr
);
473 refcount
= IDirectMusicPerformance_AddRef(dmp
);
474 ok (refcount
== 2, "refcount == %lu, expected 2\n", refcount
);
475 hr
= IDirectMusicPerformance_QueryInterface(dmp
, &IID_IDirectMusicPerformance2
, (void**)&dmp2
);
476 ok(hr
== S_OK
, "QueryInterface for IID_IDirectMusicPerformance2 failed: %#lx\n", hr
);
477 IDirectMusicPerformance_AddRef(dmp
);
478 refcount
= IDirectMusicPerformance_Release(dmp
);
479 ok (refcount
== 3, "refcount == %lu, expected 3\n", refcount
);
480 hr
= IDirectMusicPerformance_QueryInterface(dmp
, &IID_IDirectMusicPerformance8
, (void**)&dmp8
);
481 ok(hr
== S_OK
, "QueryInterface for IID_IDirectMusicPerformance8 failed: %#lx\n", hr
);
482 refcount
= IDirectMusicPerformance_Release(dmp
);
483 ok (refcount
== 3, "refcount == %lu, expected 3\n", refcount
);
484 refcount
= IDirectMusicPerformance8_Release(dmp8
);
485 ok (refcount
== 2, "refcount == %lu, expected 2\n", refcount
);
486 refcount
= IDirectMusicPerformance_Release(dmp2
);
487 ok (refcount
== 1, "refcount == %lu, expected 1\n", refcount
);
488 refcount
= IDirectMusicPerformance_Release(dmp
);
489 ok (refcount
== 0, "refcount == %lu, expected 0\n", refcount
);
492 static void test_notification_type(void)
494 static unsigned char rifffile
[8+4+8+16+8+256] = "RIFF\x24\x01\x00\x00WAVE" /* header: 4 ("WAVE") + (8 + 16) (format segment) + (8 + 256) (data segment) = 0x124 */
495 "fmt \x10\x00\x00\x00\x01\x00\x20\x00\xAC\x44\x00\x00\x10\xB1\x02\x00\x04\x00\x10\x00" /* format segment: PCM, 2 chan, 44100 Hz, 16 bits */
496 "data\x00\x01\x00\x00"; /* 256 byte data segment (silence) */
498 IDirectMusicPerformance8
*perf
;
499 IDirectMusic
*music
= NULL
;
500 IDirectMusicSegment8
*prime_segment8
;
501 IDirectMusicSegment8
*segment8
= NULL
;
502 IDirectMusicLoader8
*loader
;
503 IDirectMusicAudioPath8
*path
;
504 IDirectMusicSegmentState
*state
;
505 IDirectSound
*dsound
= NULL
;
509 DMUS_NOTIFICATION_PMSG
*msg
;
510 BOOL found_end
= FALSE
;
511 DMUS_OBJECTDESC desc
= {0};
513 hr
= CoCreateInstance(&CLSID_DirectMusicPerformance
, NULL
,
514 CLSCTX_INPROC_SERVER
, &IID_IDirectMusicPerformance8
, (void**)&perf
);
515 ok(hr
== S_OK
, "CoCreateInstance failed: %#lx\n", hr
);
517 hr
= IDirectMusicPerformance8_InitAudio(perf
, &music
, &dsound
, NULL
, DMUS_APATH_DYNAMIC_STEREO
, 64, DMUS_AUDIOF_ALL
, NULL
);
518 ok(music
!= NULL
, "Didn't get IDirectMusic pointer\n");
519 ok(dsound
!= NULL
, "Didn't get IDirectSound pointer\n");
521 hr
= CoCreateInstance(&CLSID_DirectMusicLoader
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectMusicLoader8
, (void**)&loader
);
522 ok(hr
== S_OK
, "CoCreateInstance failed: %#lx\n", hr
);
524 messages
= CreateEventA( NULL
, FALSE
, FALSE
, NULL
);
526 hr
= IDirectMusicPerformance8_AddNotificationType(perf
, &GUID_NOTIFICATION_SEGMENT
);
527 ok(hr
== S_OK
, "Failed: %#lx\n", hr
);
529 hr
= IDirectMusicPerformance8_SetNotificationHandle(perf
, messages
, 0);
530 ok(hr
== S_OK
, "Failed: %#lx\n", hr
);
532 hr
= IDirectMusicPerformance8_GetDefaultAudioPath(perf
, &path
);
533 ok(hr
== S_OK
, "Failed: %#lx\n", hr
);
534 ok(path
!= NULL
, "Didn't get IDirectMusicAudioPath pointer\n");
536 desc
.dwSize
= sizeof(DMUS_OBJECTDESC
);
537 desc
.dwValidData
= DMUS_OBJ_CLASS
| DMUS_OBJ_MEMORY
;
538 desc
.guidClass
= CLSID_DirectMusicSegment
;
539 desc
.pbMemData
= rifffile
;
540 desc
.llMemLength
= sizeof(rifffile
);
541 hr
= IDirectMusicLoader8_GetObject(loader
, &desc
, &IID_IDirectMusicSegment8
, (void**)&prime_segment8
);
542 ok(hr
== S_OK
, "Failed: %#lx\n", hr
);
543 ok(prime_segment8
!= NULL
, "Didn't get IDirectMusicSegment pointer\n");
545 hr
= IDirectMusicSegment8_Download(prime_segment8
, (IUnknown
*)path
);
546 ok(hr
== S_OK
, "Download failed: %#lx\n", hr
);
548 hr
= IDirectMusicPerformance8_PlaySegmentEx(perf
, (IUnknown
*)prime_segment8
,
549 NULL
, NULL
, DMUS_SEGF_SECONDARY
, 0, &state
, NULL
, (IUnknown
*)path
);
550 ok(hr
== S_OK
, "PlaySegmentEx failed: %#lx\n", hr
);
551 ok(state
!= NULL
, "Didn't get IDirectMusicSegmentState pointer\n");
554 result
= WaitForSingleObject(messages
, 500);
555 todo_wine
ok(result
== WAIT_OBJECT_0
, "Failed: %ld\n", result
);
556 if (result
!= WAIT_OBJECT_0
)
560 hr
= IDirectMusicPerformance8_GetNotificationPMsg(perf
, &msg
);
561 ok(hr
== S_OK
, "Failed: %#lx\n", hr
);
562 ok(msg
!= NULL
, "Unexpected NULL pointer\n");
563 if (FAILED(hr
) || !msg
)
566 trace("Notification: %ld\n", msg
->dwNotificationOption
);
568 if (msg
->dwNotificationOption
== DMUS_NOTIFICATION_SEGEND
||
569 msg
->dwNotificationOption
== DMUS_NOTIFICATION_SEGALMOSTEND
) {
570 ok(msg
->punkUser
!= NULL
, "Unexpected NULL pointer\n");
572 IDirectMusicSegmentState8
*segmentstate
;
573 IDirectMusicSegment
*segment
;
575 hr
= IUnknown_QueryInterface(msg
->punkUser
, &IID_IDirectMusicSegmentState8
, (void**)&segmentstate
);
576 ok(hr
== S_OK
, "Failed: %#lx\n", hr
);
578 hr
= IDirectMusicSegmentState8_GetSegment(segmentstate
, &segment
);
579 ok(hr
== S_OK
, "Failed: %#lx\n", hr
);
581 IDirectMusicSegmentState8_Release(segmentstate
);
585 hr
= IDirectMusicSegment_QueryInterface(segment
, &IID_IDirectMusicSegment8
, (void**)&segment8
);
586 ok(hr
== S_OK
, "Failed: %#lx\n", hr
);
590 IDirectMusicSegment_Release(segment
);
591 IDirectMusicSegmentState8_Release(segmentstate
);
595 IDirectMusicPerformance8_FreePMsg(perf
, (DMUS_PMSG
*)msg
);
597 todo_wine
ok(prime_segment8
== segment8
, "Wrong end segment\n");
598 todo_wine
ok(found_end
, "Didn't receive DMUS_NOTIFICATION_SEGEND message\n");
600 CloseHandle(messages
);
603 IDirectMusicSegment8_Release(segment8
);
604 IDirectSound_Release(dsound
);
605 IDirectMusicSegmentState_Release(state
);
606 IDirectMusicAudioPath_Release(path
);
607 IDirectMusicLoader8_Release(loader
);
608 IDirectMusic_Release(music
);
609 IDirectMusicPerformance8_Release(perf
);
612 static void test_performance_graph(void)
615 IDirectMusicPerformance8
*perf
;
616 IDirectMusicGraph
*graph
= NULL
, *graph2
;
618 create_performance(&perf
, NULL
, NULL
, FALSE
);
619 hr
= IDirectMusicPerformance8_Init(perf
, NULL
, NULL
, NULL
);
620 ok(hr
== S_OK
, "Init failed: %#lx\n", hr
);
622 hr
= IDirectMusicPerformance8_GetGraph(perf
, NULL
);
623 ok(hr
== E_POINTER
, "Failed: %#lx\n", hr
);
625 hr
= IDirectMusicPerformance8_GetGraph(perf
, &graph2
);
626 ok(hr
== DMUS_E_NOT_FOUND
, "Failed: %#lx\n", hr
);
627 ok(graph2
== NULL
, "unexpected pointer.\n");
629 hr
= IDirectMusicPerformance8_QueryInterface(perf
, &IID_IDirectMusicGraph
, (void**)&graph
);
630 todo_wine
ok(hr
== S_OK
, "Failed: %#lx\n", hr
);
633 IDirectMusicGraph_Release(graph
);
634 destroy_performance(perf
, NULL
, NULL
);
637 START_TEST( performance
)
641 hr
= CoInitialize(NULL
);
643 skip("Cannot initialize COM (%lx)\n", hr
);
647 hr
= test_InitAudio();
649 skip("InitAudio failed (%lx)\n", hr
);
656 test_notification_type();
657 test_performance_graph();