2 * Copyright (c) 2015 Andrew Eikum for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "wine/test.h"
26 #include "xaudio2fx.h"
33 static HRESULT (WINAPI
*pXAudio2Create
)(IXAudio2
**, UINT32
, XAUDIO2_PROCESSOR
) = NULL
;
34 static HRESULT (WINAPI
*pCreateAudioVolumeMeter
)(IUnknown
**) = NULL
;
36 #define XA2CALL_0(method) if(xaudio27) hr = IXAudio27_##method((IXAudio27*)xa); else hr = IXAudio2_##method(xa);
37 #define XA2CALL_0V(method) if(xaudio27) IXAudio27_##method((IXAudio27*)xa); else IXAudio2_##method(xa);
38 #define XA2CALL_V(method, ...) if(xaudio27) IXAudio27_##method((IXAudio27*)xa, __VA_ARGS__); else IXAudio2_##method(xa, __VA_ARGS__);
39 #define XA2CALL(method, ...) if(xaudio27) hr = IXAudio27_##method((IXAudio27*)xa, __VA_ARGS__); else hr = IXAudio2_##method(xa, __VA_ARGS__);
41 static void fill_buf(float *buf
, WAVEFORMATEX
*fmt
, DWORD hz
, DWORD len_frames
)
43 if(winetest_interactive
){
45 for(offs
= 0; offs
< len_frames
; ++offs
)
46 for(c
= 0; c
< fmt
->nChannels
; ++c
)
47 buf
[offs
* fmt
->nChannels
+ c
] = sinf(offs
* hz
* 2 * M_PI
/ fmt
->nSamplesPerSec
);
49 memset(buf
, 0, sizeof(float) * len_frames
* fmt
->nChannels
);
52 static struct _cb_state
{
53 BOOL start_called
, end_called
;
54 } ecb_state
, src1_state
, src2_state
;
56 static int pass_state
= 0;
57 static BOOL buffers_called
= FALSE
;
59 static void WINAPI
ECB_OnProcessingPassStart(IXAudio2EngineCallback
*This
)
61 ok(!xaudio27
|| pass_state
== 0, "Callbacks called out of order: %u\n", pass_state
);
65 static void WINAPI
ECB_OnProcessingPassEnd(IXAudio2EngineCallback
*This
)
67 ok(!xaudio27
|| pass_state
== (buffers_called
? 7 : 5), "Callbacks called out of order: %u\n", pass_state
);
69 buffers_called
= FALSE
;
72 static void WINAPI
ECB_OnCriticalError(IXAudio2EngineCallback
*This
, HRESULT Error
)
74 ok(0, "Unexpected OnCriticalError\n");
77 static const IXAudio2EngineCallbackVtbl ecb_vtbl
= {
78 ECB_OnProcessingPassStart
,
79 ECB_OnProcessingPassEnd
,
83 static IXAudio2EngineCallback ecb
= { &ecb_vtbl
};
85 static IXAudio2VoiceCallback vcb1
;
86 static IXAudio2VoiceCallback vcb2
;
88 static void WINAPI
VCB_OnVoiceProcessingPassStart(IXAudio2VoiceCallback
*This
,
92 ok(!xaudio27
|| pass_state
== (buffers_called
? 4 : 3), "Callbacks called out of order: %u\n", pass_state
);
95 ok(!xaudio27
|| pass_state
== 1, "Callbacks called out of order: %u\n", pass_state
);
100 static void WINAPI
VCB_OnVoiceProcessingPassEnd(IXAudio2VoiceCallback
*This
)
103 ok(!xaudio27
|| pass_state
== (buffers_called
? 6 : 4), "Callbacks called out of order: %u\n", pass_state
);
106 ok(!xaudio27
|| pass_state
== (buffers_called
? 3 : 2), "Callbacks called out of order: %u\n", pass_state
);
111 static void WINAPI
VCB_OnStreamEnd(IXAudio2VoiceCallback
*This
)
113 ok(0, "Unexpected OnStreamEnd\n");
116 static void WINAPI
VCB_OnBufferStart(IXAudio2VoiceCallback
*This
,
117 void *pBufferContext
)
120 ok(!xaudio27
|| pass_state
== 5, "Callbacks called out of order: %u\n", pass_state
);
123 ok(!xaudio27
|| pass_state
== 2, "Callbacks called out of order: %u\n", pass_state
);
125 buffers_called
= TRUE
;
129 static void WINAPI
VCB_OnBufferEnd(IXAudio2VoiceCallback
*This
,
130 void *pBufferContext
)
133 ok(!xaudio27
|| pass_state
== 5, "Callbacks called out of order: %u\n", pass_state
);
136 ok(!xaudio27
|| pass_state
== 2, "Callbacks called out of order: %u\n", pass_state
);
138 buffers_called
= TRUE
;
142 static void WINAPI
VCB_OnLoopEnd(IXAudio2VoiceCallback
*This
,
143 void *pBufferContext
)
145 ok(0, "Unexpected OnLoopEnd\n");
148 static void WINAPI
VCB_OnVoiceError(IXAudio2VoiceCallback
*This
,
149 void *pBuffercontext
, HRESULT Error
)
151 ok(0, "Unexpected OnVoiceError\n");
154 static const IXAudio2VoiceCallbackVtbl vcb_vtbl
= {
155 VCB_OnVoiceProcessingPassStart
,
156 VCB_OnVoiceProcessingPassEnd
,
164 static IXAudio2VoiceCallback vcb1
= { &vcb_vtbl
};
165 static IXAudio2VoiceCallback vcb2
= { &vcb_vtbl
};
167 static void test_simple_streaming(IXAudio2
*xa
)
170 IXAudio2MasteringVoice
*master
;
171 IXAudio2SourceVoice
*src
, *src2
;
174 XAUDIO2_BUFFER buf
, buf2
;
175 XAUDIO2_VOICE_STATE state
;
176 XAUDIO2_EFFECT_DESCRIPTOR effect
;
177 XAUDIO2_EFFECT_CHAIN chain
;
180 memset(&ecb_state
, 0, sizeof(ecb_state
));
181 memset(&src1_state
, 0, sizeof(src1_state
));
182 memset(&src2_state
, 0, sizeof(src2_state
));
184 XA2CALL_0V(StopEngine
);
186 /* Tests show in native XA2.8, ECB is called from a mixer thread, but VCBs
187 * may be called from other threads in any order. So we can't rely on any
188 * sequencing between VCB calls.
190 * XA2.7 does all mixing from a single thread, so call sequence can be
192 XA2CALL(RegisterForCallbacks
, &ecb
);
193 ok(hr
== S_OK
, "RegisterForCallbacks failed: %08x\n", hr
);
196 hr
= IXAudio27_CreateMasteringVoice((IXAudio27
*)xa
, &master
, 2, 44100, 0, 0, NULL
);
198 hr
= IXAudio2_CreateMasteringVoice(xa
, &master
, 2, 44100, 0, NULL
, NULL
, AudioCategory_GameEffects
);
199 ok(hr
== S_OK
, "CreateMasteringVoice failed: %08x\n", hr
);
203 IXAudio2MasteringVoice_GetChannelMask(master
, &chmask
);
204 ok(chmask
== (SPEAKER_FRONT_LEFT
| SPEAKER_FRONT_RIGHT
), "Got unexpected channel mask: 0x%x\n", chmask
);
207 /* create first source voice */
208 fmt
.wFormatTag
= WAVE_FORMAT_IEEE_FLOAT
;
210 fmt
.nSamplesPerSec
= 44100;
211 fmt
.wBitsPerSample
= 32;
212 fmt
.nBlockAlign
= fmt
.nChannels
* fmt
.wBitsPerSample
/ 8;
213 fmt
.nAvgBytesPerSec
= fmt
.nSamplesPerSec
* fmt
.nBlockAlign
;
216 XA2CALL(CreateSourceVoice
, &src
, &fmt
, 0, 1.f
, &vcb1
, NULL
, NULL
);
217 ok(hr
== S_OK
, "CreateSourceVoice failed: %08x\n", hr
);
220 XAUDIO27_VOICE_DETAILS details
;
221 IXAudio27SourceVoice_GetVoiceDetails((IXAudio27SourceVoice
*)src
, &details
);
222 ok(details
.CreationFlags
== 0, "Got wrong flags: 0x%x\n", details
.CreationFlags
);
223 ok(details
.InputChannels
== 2, "Got wrong channel count: 0x%x\n", details
.InputChannels
);
224 ok(details
.InputSampleRate
== 44100, "Got wrong sample rate: 0x%x\n", details
.InputSampleRate
);
226 XAUDIO2_VOICE_DETAILS details
;
227 IXAudio2SourceVoice_GetVoiceDetails(src
, &details
);
228 ok(details
.CreationFlags
== 0, "Got wrong creation flags: 0x%x\n", details
.CreationFlags
);
229 ok(details
.ActiveFlags
== 0, "Got wrong active flags: 0x%x\n", details
.CreationFlags
);
230 ok(details
.InputChannels
== 2, "Got wrong channel count: 0x%x\n", details
.InputChannels
);
231 ok(details
.InputSampleRate
== 44100, "Got wrong sample rate: 0x%x\n", details
.InputSampleRate
);
234 memset(&buf
, 0, sizeof(buf
));
235 buf
.AudioBytes
= 22050 * fmt
.nBlockAlign
;
236 buf
.pAudioData
= HeapAlloc(GetProcessHeap(), 0, buf
.AudioBytes
);
237 fill_buf((float*)buf
.pAudioData
, &fmt
, 440, 22050);
239 hr
= IXAudio2SourceVoice_SubmitSourceBuffer(src
, &buf
, NULL
);
240 ok(hr
== S_OK
, "SubmitSourceBuffer failed: %08x\n", hr
);
242 hr
= IXAudio2SourceVoice_Start(src
, 0, XAUDIO2_COMMIT_NOW
);
243 ok(hr
== S_OK
, "Start failed: %08x\n", hr
);
245 /* create second source voice */
246 XA2CALL(CreateSourceVoice
, &src2
, &fmt
, 0, 1.f
, &vcb2
, NULL
, NULL
);
247 ok(hr
== S_OK
, "CreateSourceVoice failed: %08x\n", hr
);
250 XAUDIO27_VOICE_DETAILS details
;
251 IXAudio27SourceVoice_GetVoiceDetails((IXAudio27SourceVoice
*)src2
, &details
);
252 ok(details
.CreationFlags
== 0, "Got wrong flags: 0x%x\n", details
.CreationFlags
);
253 ok(details
.InputChannels
== 2, "Got wrong channel count: 0x%x\n", details
.InputChannels
);
254 ok(details
.InputSampleRate
== 44100, "Got wrong sample rate: 0x%x\n", details
.InputSampleRate
);
256 XAUDIO2_VOICE_DETAILS details
;
257 IXAudio2SourceVoice_GetVoiceDetails(src2
, &details
);
258 ok(details
.CreationFlags
== 0, "Got wrong creation flags: 0x%x\n", details
.CreationFlags
);
259 ok(details
.ActiveFlags
== 0, "Got wrong active flags: 0x%x\n", details
.CreationFlags
);
260 ok(details
.InputChannels
== 2, "Got wrong channel count: 0x%x\n", details
.InputChannels
);
261 ok(details
.InputSampleRate
== 44100, "Got wrong sample rate: 0x%x\n", details
.InputSampleRate
);
264 memset(&buf2
, 0, sizeof(buf2
));
265 buf2
.AudioBytes
= 22050 * fmt
.nBlockAlign
;
266 buf2
.pAudioData
= HeapAlloc(GetProcessHeap(), 0, buf2
.AudioBytes
);
267 fill_buf((float*)buf2
.pAudioData
, &fmt
, 220, 22050);
269 hr
= IXAudio2SourceVoice_SubmitSourceBuffer(src2
, &buf2
, NULL
);
270 ok(hr
== S_OK
, "SubmitSourceBuffer failed: %08x\n", hr
);
272 hr
= IXAudio2SourceVoice_Start(src2
, 0, XAUDIO2_COMMIT_NOW
);
273 ok(hr
== S_OK
, "Start failed: %08x\n", hr
);
275 XA2CALL_0(StartEngine
);
276 ok(hr
== S_OK
, "StartEngine failed: %08x\n", hr
);
278 /* hook up volume meter */
282 hr
= CoCreateInstance(&CLSID_AudioVolumeMeter27
, NULL
,
283 CLSCTX_INPROC_SERVER
, &IID_IUnknown
, (void**)&vumeter
);
284 ok(hr
== S_OK
, "CoCreateInstance(AudioVolumeMeter) failed: %08x\n", hr
);
286 hr
= IUnknown_QueryInterface(vumeter
, &IID_IXAPO27
, (void**)&xapo
);
287 ok(hr
== S_OK
, "Couldn't get IXAPO27 interface: %08x\n", hr
);
293 hr
= pCreateAudioVolumeMeter(&vumeter
);
294 ok(hr
== S_OK
, "CreateAudioVolumeMeter failed: %08x\n", hr
);
296 hr
= IUnknown_QueryInterface(vumeter
, &IID_IXAPO
, (void**)&xapo
);
297 ok(hr
== S_OK
, "Couldn't get IXAPO interface: %08x\n", hr
);
302 effect
.InitialState
= TRUE
;
303 effect
.OutputChannels
= 2;
304 effect
.pEffect
= vumeter
;
306 chain
.EffectCount
= 1;
307 chain
.pEffectDescriptors
= &effect
;
309 hr
= IXAudio2MasteringVoice_SetEffectChain(master
, &chain
);
310 ok(hr
== S_OK
, "SetEffectchain failed: %08x\n", hr
);
312 IUnknown_Release(vumeter
);
316 IXAudio27SourceVoice_GetState((IXAudio27SourceVoice
*)src
, &state
);
318 IXAudio2SourceVoice_GetState(src
, &state
, 0);
319 if(state
.SamplesPlayed
>= 22050)
324 ok(state
.SamplesPlayed
== 22050, "Got wrong samples played\n");
326 HeapFree(GetProcessHeap(), 0, (void*)buf
.pAudioData
);
327 HeapFree(GetProcessHeap(), 0, (void*)buf2
.pAudioData
);
330 IXAudio27SourceVoice_DestroyVoice((IXAudio27SourceVoice
*)src
);
331 IXAudio27SourceVoice_DestroyVoice((IXAudio27SourceVoice
*)src2
);
333 IXAudio2SourceVoice_DestroyVoice(src
);
334 IXAudio2SourceVoice_DestroyVoice(src2
);
336 IXAudio2MasteringVoice_DestroyVoice(master
);
338 XA2CALL_V(UnregisterForCallbacks
, &ecb
);
341 static void WINAPI
vcb_buf_OnVoiceProcessingPassStart(IXAudio2VoiceCallback
*This
,
342 UINT32 BytesRequired
)
346 static void WINAPI
vcb_buf_OnVoiceProcessingPassEnd(IXAudio2VoiceCallback
*This
)
350 static void WINAPI
vcb_buf_OnStreamEnd(IXAudio2VoiceCallback
*This
)
352 ok(0, "Unexpected OnStreamEnd\n");
355 struct vcb_buf_testdata
{
357 IXAudio2SourceVoice
*src
;
360 static int obs_calls
= 0;
361 static int obe_calls
= 0;
363 static void WINAPI
vcb_buf_OnBufferStart(IXAudio2VoiceCallback
*This
,
364 void *pBufferContext
)
366 struct vcb_buf_testdata
*data
= pBufferContext
;
367 XAUDIO2_VOICE_STATE state
;
369 ok(data
->idx
== obs_calls
, "Buffer callback out of order: %u\n", data
->idx
);
372 IXAudio27SourceVoice_GetState((IXAudio27SourceVoice
*)data
->src
, &state
);
374 IXAudio2SourceVoice_GetState(data
->src
, &state
, 0);
376 ok(state
.BuffersQueued
== 5 - obs_calls
, "Got wrong number of buffers remaining: %u\n", state
.BuffersQueued
);
377 ok(state
.pCurrentBufferContext
== pBufferContext
, "Got wrong buffer from GetState\n");
382 static void WINAPI
vcb_buf_OnBufferEnd(IXAudio2VoiceCallback
*This
,
383 void *pBufferContext
)
385 struct vcb_buf_testdata
*data
= pBufferContext
;
386 XAUDIO2_VOICE_STATE state
;
388 ok(data
->idx
== obe_calls
, "Buffer callback out of order: %u\n", data
->idx
);
391 IXAudio27SourceVoice_GetState((IXAudio27SourceVoice
*)data
->src
, &state
);
393 IXAudio2SourceVoice_GetState(data
->src
, &state
, 0);
395 ok(state
.BuffersQueued
== 5 - obe_calls
- 1, "Got wrong number of buffers remaining: %u\n", state
.BuffersQueued
);
396 if(state
.BuffersQueued
== 0)
397 ok(state
.pCurrentBufferContext
== NULL
, "Got wrong buffer from GetState: %p\n", state
.pCurrentBufferContext
);
399 ok(state
.pCurrentBufferContext
== data
+ 1, "Got wrong buffer from GetState: %p\n", state
.pCurrentBufferContext
);
404 static void WINAPI
vcb_buf_OnLoopEnd(IXAudio2VoiceCallback
*This
,
405 void *pBufferContext
)
407 ok(0, "Unexpected OnLoopEnd\n");
410 static void WINAPI
vcb_buf_OnVoiceError(IXAudio2VoiceCallback
*This
,
411 void *pBuffercontext
, HRESULT Error
)
413 ok(0, "Unexpected OnVoiceError\n");
416 static const IXAudio2VoiceCallbackVtbl vcb_buf_vtbl
= {
417 vcb_buf_OnVoiceProcessingPassStart
,
418 vcb_buf_OnVoiceProcessingPassEnd
,
420 vcb_buf_OnBufferStart
,
426 static IXAudio2VoiceCallback vcb_buf
= { &vcb_buf_vtbl
};
428 static int nloopends
= 0;
429 static int nstreamends
= 0;
431 static void WINAPI
loop_buf_OnStreamEnd(IXAudio2VoiceCallback
*This
)
436 static void WINAPI
loop_buf_OnBufferStart(IXAudio2VoiceCallback
*This
,
437 void *pBufferContext
)
441 static void WINAPI
loop_buf_OnBufferEnd(IXAudio2VoiceCallback
*This
,
442 void *pBufferContext
)
446 static void WINAPI
loop_buf_OnLoopEnd(IXAudio2VoiceCallback
*This
,
447 void *pBufferContext
)
452 static void WINAPI
loop_buf_OnVoiceError(IXAudio2VoiceCallback
*This
,
453 void *pBuffercontext
, HRESULT Error
)
457 static const IXAudio2VoiceCallbackVtbl loop_buf_vtbl
= {
458 vcb_buf_OnVoiceProcessingPassStart
,
459 vcb_buf_OnVoiceProcessingPassEnd
,
460 loop_buf_OnStreamEnd
,
461 loop_buf_OnBufferStart
,
462 loop_buf_OnBufferEnd
,
464 loop_buf_OnVoiceError
467 static IXAudio2VoiceCallback loop_buf
= { &loop_buf_vtbl
};
469 static void test_buffer_callbacks(IXAudio2
*xa
)
472 IXAudio2MasteringVoice
*master
;
473 IXAudio2SourceVoice
*src
;
476 XAUDIO2_VOICE_STATE state
;
477 struct vcb_buf_testdata testdata
[5];
483 XA2CALL_0V(StopEngine
);
486 hr
= IXAudio27_CreateMasteringVoice((IXAudio27
*)xa
, &master
, 2, 44100, 0, 0, NULL
);
488 hr
= IXAudio2_CreateMasteringVoice(xa
, &master
, 2, 44100, 0, NULL
, NULL
, AudioCategory_GameEffects
);
489 ok(hr
== S_OK
, "CreateMasteringVoice failed: %08x\n", hr
);
491 /* test OnBufferStart/End callbacks */
492 fmt
.wFormatTag
= WAVE_FORMAT_IEEE_FLOAT
;
494 fmt
.nSamplesPerSec
= 44100;
495 fmt
.wBitsPerSample
= 32;
496 fmt
.nBlockAlign
= fmt
.nChannels
* fmt
.wBitsPerSample
/ 8;
497 fmt
.nAvgBytesPerSec
= fmt
.nSamplesPerSec
* fmt
.nBlockAlign
;
500 XA2CALL(CreateSourceVoice
, &src
, &fmt
, 0, 1.f
, &vcb_buf
, NULL
, NULL
);
501 ok(hr
== S_OK
, "CreateSourceVoice failed: %08x\n", hr
);
503 memset(&buf
, 0, sizeof(buf
));
504 buf
.AudioBytes
= 4410 * fmt
.nBlockAlign
;
505 buf
.pAudioData
= HeapAlloc(GetProcessHeap(), 0, buf
.AudioBytes
);
506 fill_buf((float*)buf
.pAudioData
, &fmt
, 440, 4410);
508 /* submit same buffer fragment 5 times */
509 for(i
= 0; i
< 5; ++i
){
511 testdata
[i
].src
= src
;
512 buf
.pContext
= &testdata
[i
];
514 hr
= IXAudio2SourceVoice_SubmitSourceBuffer(src
, &buf
, NULL
);
515 ok(hr
== S_OK
, "SubmitSourceBuffer failed: %08x\n", hr
);
518 hr
= IXAudio2SourceVoice_Start(src
, 0, XAUDIO2_COMMIT_NOW
);
519 ok(hr
== S_OK
, "Start failed: %08x\n", hr
);
522 XA2CALL_0(StartEngine
);
523 ok(hr
== S_OK
, "StartEngine failed: %08x\n", hr
);
526 hr
= IXAudio27SourceVoice_SetSourceSampleRate((IXAudio27SourceVoice
*)src
, 48000);
527 ok(hr
== S_OK
, "SetSourceSampleRate failed: %08x\n", hr
);
529 hr
= IXAudio2SourceVoice_SetSourceSampleRate(src
, 48000);
530 ok(hr
== XAUDIO2_E_INVALID_CALL
, "SetSourceSampleRate should have failed: %08x\n", hr
);
535 IXAudio27SourceVoice_GetState((IXAudio27SourceVoice
*)src
, &state
);
537 IXAudio2SourceVoice_GetState(src
, &state
, 0);
538 if(state
.SamplesPlayed
>= 4410 * 5)
543 ok(state
.SamplesPlayed
== 4410 * 5, "Got wrong samples played\n");
546 IXAudio27SourceVoice_DestroyVoice((IXAudio27SourceVoice
*)src
);
548 IXAudio2SourceVoice_DestroyVoice(src
);
551 /* test OnStreamEnd callback */
552 XA2CALL(CreateSourceVoice
, &src
, &fmt
, 0, 1.f
, &loop_buf
, NULL
, NULL
);
553 ok(hr
== S_OK
, "CreateSourceVoice failed: %08x\n", hr
);
555 buf
.Flags
= XAUDIO2_END_OF_STREAM
;
557 hr
= IXAudio2SourceVoice_SubmitSourceBuffer(src
, &buf
, NULL
);
558 ok(hr
== S_OK
, "SubmitSourceBuffer failed: %08x\n", hr
);
560 hr
= IXAudio2SourceVoice_Start(src
, 0, XAUDIO2_COMMIT_NOW
);
561 ok(hr
== S_OK
, "Start failed: %08x\n", hr
);
564 while(nstreamends
== 0 && timeout
< 1000){
569 ok(nstreamends
== 1, "Got wrong number of OnStreamEnd calls: %u\n", nstreamends
);
571 /* xaudio resets SamplesPlayed after processing an end-of-stream buffer */
573 IXAudio27SourceVoice_GetState((IXAudio27SourceVoice
*)src
, &state
);
575 IXAudio2SourceVoice_GetState(src
, &state
, 0);
576 ok(state
.SamplesPlayed
== 0, "Got wrong samples played\n");
579 IXAudio27SourceVoice_DestroyVoice((IXAudio27SourceVoice
*)src
);
581 IXAudio2SourceVoice_DestroyVoice(src
);
584 IXAudio2MasteringVoice_DestroyVoice(master
);
586 HeapFree(GetProcessHeap(), 0, (void*)buf
.pAudioData
);
589 static UINT32
play_to_completion(IXAudio2SourceVoice
*src
, UINT32 max_samples
)
591 XAUDIO2_VOICE_STATE state
;
596 hr
= IXAudio2SourceVoice_Start(src
, 0, XAUDIO2_COMMIT_NOW
);
597 ok(hr
== S_OK
, "Start failed: %08x\n", hr
);
601 IXAudio27SourceVoice_GetState((IXAudio27SourceVoice
*)src
, &state
);
603 IXAudio2SourceVoice_GetState(src
, &state
, 0);
604 if(state
.BuffersQueued
== 0)
606 if(state
.SamplesPlayed
>= max_samples
){
608 IXAudio27SourceVoice_ExitLoop((IXAudio27SourceVoice
*)src
, XAUDIO2_COMMIT_NOW
);
610 IXAudio2SourceVoice_ExitLoop(src
, XAUDIO2_COMMIT_NOW
);
615 hr
= IXAudio2SourceVoice_Stop(src
, 0, XAUDIO2_COMMIT_NOW
);
616 ok(hr
== S_OK
, "Start failed: %08x\n", hr
);
618 return state
.SamplesPlayed
;
621 static void test_looping(IXAudio2
*xa
)
624 IXAudio2MasteringVoice
*master
;
625 IXAudio2SourceVoice
*src
;
628 UINT32 played
, running_total
= 0;
630 XA2CALL_0V(StopEngine
);
633 hr
= IXAudio27_CreateMasteringVoice((IXAudio27
*)xa
, &master
, 2, 44100, 0, 0, NULL
);
635 hr
= IXAudio2_CreateMasteringVoice(xa
, &master
, 2, 44100, 0, NULL
, NULL
, AudioCategory_GameEffects
);
636 ok(hr
== S_OK
, "CreateMasteringVoice failed: %08x\n", hr
);
639 fmt
.wFormatTag
= WAVE_FORMAT_IEEE_FLOAT
;
641 fmt
.nSamplesPerSec
= 44100;
642 fmt
.wBitsPerSample
= 32;
643 fmt
.nBlockAlign
= fmt
.nChannels
* fmt
.wBitsPerSample
/ 8;
644 fmt
.nAvgBytesPerSec
= fmt
.nSamplesPerSec
* fmt
.nBlockAlign
;
647 XA2CALL(CreateSourceVoice
, &src
, &fmt
, 0, 1.f
, &loop_buf
, NULL
, NULL
);
648 ok(hr
== S_OK
, "CreateSourceVoice failed: %08x\n", hr
);
650 memset(&buf
, 0, sizeof(buf
));
652 buf
.AudioBytes
= 44100 * fmt
.nBlockAlign
;
653 buf
.pAudioData
= HeapAlloc(GetProcessHeap(), 0, buf
.AudioBytes
);
654 fill_buf((float*)buf
.pAudioData
, &fmt
, 440, 44100);
656 XA2CALL_0(StartEngine
);
657 ok(hr
== S_OK
, "StartEngine failed: %08x\n", hr
);
659 /* play from middle to end */
660 buf
.PlayBegin
= 22050;
666 hr
= IXAudio2SourceVoice_SubmitSourceBuffer(src
, &buf
, NULL
);
667 ok(hr
== S_OK
, "SubmitSourceBuffer failed: %08x\n", hr
);
669 played
= play_to_completion(src
, -1);
670 ok(played
- running_total
== 22050, "Got wrong samples played: %u\n", played
- running_total
);
671 running_total
= played
;
672 ok(nloopends
== 0, "Got wrong OnLoopEnd calls: %u\n", nloopends
);
674 /* play 4410 samples from middle */
675 buf
.PlayBegin
= 22050;
676 buf
.PlayLength
= 4410;
681 hr
= IXAudio2SourceVoice_SubmitSourceBuffer(src
, &buf
, NULL
);
682 ok(hr
== S_OK
, "SubmitSourceBuffer failed: %08x\n", hr
);
684 played
= play_to_completion(src
, -1);
685 ok(played
- running_total
== 4410, "Got wrong samples played: %u\n", played
- running_total
);
686 running_total
= played
;
687 ok(nloopends
== 0, "Got wrong OnLoopEnd calls: %u\n", nloopends
);
689 /* loop 4410 samples in middle */
692 buf
.LoopBegin
= 22050;
693 buf
.LoopLength
= 4410;
696 hr
= IXAudio2SourceVoice_SubmitSourceBuffer(src
, &buf
, NULL
);
697 ok(hr
== S_OK
, "SubmitSourceBuffer failed: %08x\n", hr
);
699 played
= play_to_completion(src
, -1);
700 ok(played
- running_total
== 44100 + 4410, "Got wrong samples played: %u\n", played
- running_total
);
701 running_total
= played
;
702 ok(nloopends
== 1, "Got wrong OnLoopEnd calls: %u\n", nloopends
);
704 /* play last half, then loop the whole buffer */
705 buf
.PlayBegin
= 22050;
711 hr
= IXAudio2SourceVoice_SubmitSourceBuffer(src
, &buf
, NULL
);
712 ok(hr
== S_OK
, "SubmitSourceBuffer failed: %08x\n", hr
);
714 played
= play_to_completion(src
, -1);
715 ok(played
- running_total
== 22050 + 44100, "Got wrong samples played: %u\n", played
- running_total
);
716 running_total
= played
;
717 ok(nloopends
== 1, "Got wrong OnLoopEnd calls: %u\n", nloopends
);
719 /* play short segment from middle, loop to the beginning, and end at PlayEnd */
720 buf
.PlayBegin
= 22050;
721 buf
.PlayLength
= 4410;
726 hr
= IXAudio2SourceVoice_SubmitSourceBuffer(src
, &buf
, NULL
);
727 ok(hr
== S_OK
, "SubmitSourceBuffer failed: %08x\n", hr
);
729 played
= play_to_completion(src
, -1);
730 ok(played
- running_total
== 4410 + (22050 + 4410), "Got wrong samples played: %u\n", played
- running_total
);
731 running_total
= played
;
732 ok(nloopends
== 1, "Got wrong OnLoopEnd calls: %u\n", nloopends
);
734 /* invalid: LoopEnd must be <= PlayEnd
735 * xaudio27: play until LoopEnd, loop to beginning, play until PlayEnd */
736 buf
.PlayBegin
= 22050;
737 buf
.PlayLength
= 4410;
739 buf
.LoopLength
= 22050 + 4410 * 2;
742 hr
= IXAudio2SourceVoice_SubmitSourceBuffer(src
, &buf
, NULL
);
744 ok(hr
== S_OK
, "SubmitSourceBuffer failed: %08x\n", hr
);
746 played
= play_to_completion(src
, -1);
747 ok(played
- running_total
== 4410 + (22050 + 4410 * 2), "Got wrong samples played: %u\n", played
- running_total
);
748 running_total
= played
;
749 ok(nloopends
== 1, "Got wrong OnLoopEnd calls: %u\n", nloopends
);
751 ok(hr
== XAUDIO2_E_INVALID_CALL
, "SubmitSourceBuffer should have failed: %08x\n", hr
);
753 /* invalid: LoopEnd must be within play range
754 * xaudio27: plays only play range */
755 buf
.PlayBegin
= 22050;
756 buf
.PlayLength
= 0; /* == until end of buffer */
758 buf
.LoopLength
= 22050;
761 hr
= IXAudio2SourceVoice_SubmitSourceBuffer(src
, &buf
, NULL
);
763 ok(hr
== S_OK
, "SubmitSourceBuffer failed: %08x\n", hr
);
765 played
= play_to_completion(src
, -1);
766 ok(played
- running_total
== 22050, "Got wrong samples played: %u\n", played
- running_total
);
767 running_total
= played
;
768 ok(nloopends
== 0, "Got wrong OnLoopEnd calls: %u\n", nloopends
);
770 ok(hr
== XAUDIO2_E_INVALID_CALL
, "SubmitSourceBuffer should have failed: %08x\n", hr
);
772 /* invalid: LoopBegin must be before PlayEnd
773 * xaudio27: crashes */
776 buf
.PlayLength
= 4410;
777 buf
.LoopBegin
= 22050;
778 buf
.LoopLength
= 4410;
781 hr
= IXAudio2SourceVoice_SubmitSourceBuffer(src
, &buf
, NULL
);
782 ok(hr
== XAUDIO2_E_INVALID_CALL
, "SubmitSourceBuffer should have failed: %08x\n", hr
);
785 /* infinite looping buffer */
786 buf
.PlayBegin
= 22050;
792 hr
= IXAudio2SourceVoice_SubmitSourceBuffer(src
, &buf
, NULL
);
793 ok(hr
== S_OK
, "SubmitSourceBuffer failed: %08x\n", hr
);
795 played
= play_to_completion(src
, running_total
+ 88200);
796 ok(played
- running_total
== 22050 + 44100 * 2, "Got wrong samples played: %u\n", played
- running_total
);
797 ok(nloopends
== (played
- running_total
) / 88200 + 1, "Got wrong OnLoopEnd calls: %u\n", nloopends
);
798 running_total
= played
;
801 IXAudio27SourceVoice_DestroyVoice((IXAudio27SourceVoice
*)src
);
803 IXAudio2SourceVoice_DestroyVoice(src
);
804 IXAudio2MasteringVoice_DestroyVoice(master
);
805 HeapFree(GetProcessHeap(), 0, (void*)buf
.pAudioData
);
808 static void test_submix(IXAudio2
*xa
)
811 IXAudio2MasteringVoice
*master
;
812 IXAudio2SubmixVoice
*sub
;
814 XA2CALL_0V(StopEngine
);
817 hr
= IXAudio27_CreateMasteringVoice((IXAudio27
*)xa
, &master
, 2, 44100, 0, 0, NULL
);
819 hr
= IXAudio2_CreateMasteringVoice(xa
, &master
, 2, 44100, 0, NULL
, NULL
, AudioCategory_GameEffects
);
820 ok(hr
== S_OK
, "CreateMasteringVoice failed: %08x\n", hr
);
822 XA2CALL(CreateSubmixVoice
, &sub
, 2, 44100, 0, 0, NULL
, NULL
);
823 ok(hr
== S_OK
, "CreateSubmixVoice failed: %08x\n", hr
);
826 XAUDIO27_VOICE_DETAILS details
;
827 IXAudio27SubmixVoice_GetVoiceDetails((IXAudio27SubmixVoice
*)sub
, &details
);
828 ok(details
.CreationFlags
== 0, "Got wrong flags: 0x%x\n", details
.CreationFlags
);
829 ok(details
.InputChannels
== 2, "Got wrong channel count: 0x%x\n", details
.InputChannels
);
830 ok(details
.InputSampleRate
== 44100, "Got wrong sample rate: 0x%x\n", details
.InputSampleRate
);
832 XAUDIO2_VOICE_DETAILS details
;
833 IXAudio2SubmixVoice_GetVoiceDetails(sub
, &details
);
834 ok(details
.CreationFlags
== 0, "Got wrong creation flags: 0x%x\n", details
.CreationFlags
);
835 ok(details
.ActiveFlags
== 0, "Got wrong active flags: 0x%x\n", details
.CreationFlags
);
836 ok(details
.InputChannels
== 2, "Got wrong channel count: 0x%x\n", details
.InputChannels
);
837 ok(details
.InputSampleRate
== 44100, "Got wrong sample rate: 0x%x\n", details
.InputSampleRate
);
840 IXAudio2SubmixVoice_DestroyVoice(sub
);
841 IXAudio2MasteringVoice_DestroyVoice(master
);
844 static void test_flush(IXAudio2
*xa
)
847 IXAudio2MasteringVoice
*master
;
848 IXAudio2SourceVoice
*src
;
851 XAUDIO2_VOICE_STATE state
;
853 XA2CALL_0V(StopEngine
);
856 hr
= IXAudio27_CreateMasteringVoice((IXAudio27
*)xa
, &master
, 2, 44100, 0, 0, NULL
);
858 hr
= IXAudio2_CreateMasteringVoice(xa
, &master
, 2, 44100, 0, NULL
, NULL
, AudioCategory_GameEffects
);
859 ok(hr
== S_OK
, "CreateMasteringVoice failed: %08x\n", hr
);
861 fmt
.wFormatTag
= WAVE_FORMAT_IEEE_FLOAT
;
863 fmt
.nSamplesPerSec
= 44100;
864 fmt
.wBitsPerSample
= 32;
865 fmt
.nBlockAlign
= fmt
.nChannels
* fmt
.wBitsPerSample
/ 8;
866 fmt
.nAvgBytesPerSec
= fmt
.nSamplesPerSec
* fmt
.nBlockAlign
;
869 XA2CALL(CreateSourceVoice
, &src
, &fmt
, 0, 1.f
, NULL
, NULL
, NULL
);
870 ok(hr
== S_OK
, "CreateSourceVoice failed: %08x\n", hr
);
872 memset(&buf
, 0, sizeof(buf
));
873 buf
.AudioBytes
= 22050 * fmt
.nBlockAlign
;
874 buf
.pAudioData
= HeapAlloc(GetProcessHeap(), 0, buf
.AudioBytes
);
875 fill_buf((float*)buf
.pAudioData
, &fmt
, 440, 22050);
877 hr
= IXAudio2SourceVoice_SubmitSourceBuffer(src
, &buf
, NULL
);
878 ok(hr
== S_OK
, "SubmitSourceBuffer failed: %08x\n", hr
);
880 hr
= IXAudio2SourceVoice_Start(src
, 0, XAUDIO2_COMMIT_NOW
);
881 ok(hr
== S_OK
, "Start failed: %08x\n", hr
);
883 XA2CALL_0(StartEngine
);
884 ok(hr
== S_OK
, "StartEngine failed: %08x\n", hr
);
888 IXAudio27SourceVoice_GetState((IXAudio27SourceVoice
*)src
, &state
);
890 IXAudio2SourceVoice_GetState(src
, &state
, 0);
891 if(state
.SamplesPlayed
>= 2205)
896 hr
= IXAudio2SourceVoice_Stop(src
, 0, XAUDIO2_COMMIT_NOW
);
897 ok(hr
== S_OK
, "Stop failed: %08x\n", hr
);
899 hr
= IXAudio2SourceVoice_FlushSourceBuffers(src
);
900 ok(hr
== S_OK
, "FlushSourceBuffers failed: %08x\n", hr
);
902 hr
= IXAudio2SourceVoice_Start(src
, 0, XAUDIO2_COMMIT_NOW
);
903 ok(hr
== S_OK
, "Start failed: %08x\n", hr
);
907 hr
= IXAudio2SourceVoice_SubmitSourceBuffer(src
, &buf
, NULL
);
908 ok(hr
== S_OK
, "SubmitSourceBuffer failed: %08x\n", hr
);
911 IXAudio27SourceVoice_DestroyVoice((IXAudio27SourceVoice
*)src
);
913 IXAudio2SourceVoice_DestroyVoice(src
);
915 IXAudio2MasteringVoice_DestroyVoice(master
);
917 HeapFree(GetProcessHeap(), 0, (void*)buf
.pAudioData
);
920 static UINT32
test_DeviceDetails(IXAudio27
*xa
)
923 XAUDIO2_DEVICE_DETAILS dd
;
926 hr
= IXAudio27_GetDeviceCount(xa
, &count
);
927 ok(hr
== S_OK
, "GetDeviceCount failed: %08x\n", hr
);
932 for(i
= 0; i
< count
; ++i
){
933 hr
= IXAudio27_GetDeviceDetails(xa
, i
, &dd
);
934 ok(hr
== S_OK
, "GetDeviceDetails failed: %08x\n", hr
);
937 ok(dd
.Role
== GlobalDefaultDevice
, "Got wrong role for index 0: 0x%x\n", dd
.Role
);
939 ok(dd
.Role
== NotDefaultDevice
, "Got wrong role for index %u: 0x%x\n", i
, dd
.Role
);
945 static void test_xapo_creation_legacy(const char *module
, unsigned int version
)
953 HRESULT (CDECL
*pCreateFX
)(REFCLSID
,IUnknown
**) = NULL
;
955 /* CLSIDs are the same across all versions */
956 static const GUID
*const_clsids
[] = {
958 &CLSID_FXMasteringLimiter27
,
961 /* older versions of xapofx actually have support for new clsids */
963 &CLSID_FXMasteringLimiter
,
968 /* different CLSID for each version */
969 static const GUID
*avm_clsids
[] = {
970 &CLSID_AudioVolumeMeter20
,
971 &CLSID_AudioVolumeMeter21
,
972 &CLSID_AudioVolumeMeter22
,
973 &CLSID_AudioVolumeMeter23
,
974 &CLSID_AudioVolumeMeter24
,
975 &CLSID_AudioVolumeMeter25
,
976 &CLSID_AudioVolumeMeter26
,
977 &CLSID_AudioVolumeMeter27
980 static const GUID
*ar_clsids
[] = {
981 &CLSID_AudioReverb20
,
982 &CLSID_AudioReverb21
,
983 &CLSID_AudioReverb22
,
984 &CLSID_AudioReverb23
,
985 &CLSID_AudioReverb24
,
986 &CLSID_AudioReverb25
,
987 &CLSID_AudioReverb26
,
991 xapofxdll
= LoadLibraryA(module
);
993 pCreateFX
= (void*)GetProcAddress(xapofxdll
, "CreateFX");
994 ok(pCreateFX
!= NULL
, "%s did not have CreateFX?\n", module
);
996 FreeLibrary(xapofxdll
);
1000 win_skip("Couldn't load %s\n", module
);
1004 for(i
= 0; i
< ARRAY_SIZE(const_clsids
); ++i
){
1005 hr
= pCreateFX(const_clsids
[i
], &fx_unk
);
1006 ok(hr
== S_OK
, "%s: CreateFX(%s) failed: %08x\n", module
, wine_dbgstr_guid(const_clsids
[i
]), hr
);
1009 hr
= IUnknown_QueryInterface(fx_unk
, &IID_IXAPO27
, (void**)&xapo
);
1010 ok(hr
== S_OK
, "Couldn't get IXAPO27 interface: %08x\n", hr
);
1012 IXAPO_Release(xapo
);
1013 rc
= IUnknown_Release(fx_unk
);
1014 ok(rc
== 0, "XAPO via CreateFX should have been released, got refcount: %u\n", rc
);
1017 hr
= CoCreateInstance(const_clsids
[i
], NULL
, CLSCTX_INPROC_SERVER
,
1018 &IID_IUnknown
, (void**)&fx_unk
);
1019 ok(hr
== REGDB_E_CLASSNOTREG
, "CoCreateInstance should have failed: %08x\n", hr
);
1021 IUnknown_Release(fx_unk
);
1024 hr
= pCreateFX(avm_clsids
[version
- 20], &fx_unk
);
1025 ok(hr
== S_OK
, "%s: CreateFX(%s) failed: %08x\n", module
, wine_dbgstr_guid(avm_clsids
[version
- 20]), hr
);
1028 hr
= IUnknown_QueryInterface(fx_unk
, &IID_IXAPO27
, (void**)&xapo
);
1029 ok(hr
== S_OK
, "Couldn't get IXAPO27 interface: %08x\n", hr
);
1031 IXAPO_Release(xapo
);
1032 rc
= IUnknown_Release(fx_unk
);
1033 ok(rc
== 0, "AudioVolumeMeter via CreateFX should have been released, got refcount: %u\n", rc
);
1036 hr
= pCreateFX(ar_clsids
[version
- 20], &fx_unk
);
1037 ok(hr
== S_OK
, "%s: CreateFX(%s) failed: %08x\n", module
, wine_dbgstr_guid(ar_clsids
[version
- 20]), hr
);
1040 hr
= IUnknown_QueryInterface(fx_unk
, &IID_IXAPO27
, (void**)&xapo
);
1041 ok(hr
== S_OK
, "Couldn't get IXAPO27 interface: %08x\n", hr
);
1043 IXAPO_Release(xapo
);
1044 rc
= IUnknown_Release(fx_unk
);
1045 ok(rc
== 0, "AudioReverb via CreateFX should have been released, got refcount: %u\n", rc
);
1048 FreeLibrary(xapofxdll
);
1051 static void test_xapo_creation_modern(const char *module
)
1059 HRESULT (CDECL
*pCreateFX
)(REFCLSID
,IUnknown
**,void*,UINT32
) = NULL
;
1060 HRESULT (WINAPI
*pCAVM
)(IUnknown
**) = NULL
;
1061 HRESULT (WINAPI
*pCAR
)(IUnknown
**) = NULL
;
1063 /* CLSIDs are the same across all versions */
1064 static const GUID
*const_clsids
[] = {
1066 &CLSID_FXMasteringLimiter27
,
1070 &CLSID_FXMasteringLimiter
,
1076 xaudio2dll
= LoadLibraryA(module
);
1078 pCreateFX
= (void*)GetProcAddress(xaudio2dll
, "CreateFX");
1079 ok(pCreateFX
!= NULL
, "%s did not have CreateFX?\n", module
);
1081 FreeLibrary(xaudio2dll
);
1085 win_skip("Couldn't load %s\n", module
);
1089 for(i
= 0; i
< ARRAY_SIZE(const_clsids
); ++i
){
1090 hr
= pCreateFX(const_clsids
[i
], &fx_unk
, NULL
, 0);
1091 ok(hr
== S_OK
, "%s: CreateFX(%s) failed: %08x\n", module
, wine_dbgstr_guid(const_clsids
[i
]), hr
);
1094 hr
= IUnknown_QueryInterface(fx_unk
, &IID_IXAPO
, (void**)&xapo
);
1095 ok(hr
== S_OK
, "Couldn't get IXAPO interface: %08x\n", hr
);
1097 IXAPO_Release(xapo
);
1098 rc
= IUnknown_Release(fx_unk
);
1099 ok(rc
== 0, "XAPO via CreateFX should have been released, got refcount: %u\n", rc
);
1102 hr
= CoCreateInstance(const_clsids
[i
], NULL
, CLSCTX_INPROC_SERVER
,
1103 &IID_IUnknown
, (void**)&fx_unk
);
1104 ok(hr
== REGDB_E_CLASSNOTREG
, "CoCreateInstance should have failed: %08x\n", hr
);
1106 IUnknown_Release(fx_unk
);
1109 /* test legacy CLSID */
1110 hr
= pCreateFX(&CLSID_AudioVolumeMeter27
, &fx_unk
, NULL
, 0);
1111 ok(hr
== S_OK
, "%s: CreateFX(CLSID_AudioVolumeMeter) failed: %08x\n", module
, hr
);
1114 hr
= IUnknown_QueryInterface(fx_unk
, &IID_IXAPO
, (void**)&xapo
);
1115 ok(hr
== S_OK
, "Couldn't get IXAPO interface: %08x\n", hr
);
1117 IXAPO_Release(xapo
);
1118 rc
= IUnknown_Release(fx_unk
);
1119 ok(rc
== 0, "XAPO via legacy CreateFX should have been released, got refcount: %u\n", rc
);
1122 pCAVM
= (void*)GetProcAddress(xaudio2dll
, "CreateAudioVolumeMeter");
1123 ok(pCAVM
!= NULL
, "%s did not have CreateAudioVolumeMeter?\n", module
);
1125 hr
= pCAVM(&fx_unk
);
1126 ok(hr
== S_OK
, "CreateAudioVolumeMeter failed: %08x\n", hr
);
1129 hr
= IUnknown_QueryInterface(fx_unk
, &IID_IXAPO
, (void**)&xapo
);
1130 ok(hr
== S_OK
, "Couldn't get IXAPO interface: %08x\n", hr
);
1132 IXAPO_Release(xapo
);
1133 rc
= IUnknown_Release(fx_unk
);
1134 ok(rc
== 0, "XAPO via CreateAudioVolumeMeter should have been released, got refcount: %u\n", rc
);
1137 pCAR
= (void*)GetProcAddress(xaudio2dll
, "CreateAudioReverb");
1138 ok(pCAR
!= NULL
, "%s did not have CreateAudioReverb?\n", module
);
1141 ok(hr
== S_OK
, "CreateAudioReverb failed: %08x\n", hr
);
1144 hr
= IUnknown_QueryInterface(fx_unk
, &IID_IXAPO
, (void**)&xapo
);
1145 ok(hr
== S_OK
, "Couldn't get IXAPO interface: %08x\n", hr
);
1147 IXAPO_Release(xapo
);
1148 rc
= IUnknown_Release(fx_unk
);
1149 ok(rc
== 0, "XAPO via CreateAudioReverb should have been released, got refcount: %u\n", rc
);
1152 FreeLibrary(xaudio2dll
);
1155 static void test_xapo_creation(void)
1157 test_xapo_creation_legacy("xapofx1_1.dll", 22);
1158 test_xapo_creation_legacy("xapofx1_2.dll", 23);
1159 test_xapo_creation_legacy("xapofx1_3.dll", 24);
1160 test_xapo_creation_legacy("xapofx1_3.dll", 25);
1161 test_xapo_creation_legacy("xapofx1_4.dll", 26);
1162 test_xapo_creation_legacy("xapofx1_5.dll", 27);
1163 test_xapo_creation_modern("xaudio2_8.dll");
1166 static void test_setchannelvolumes(IXAudio2
*xa
)
1169 IXAudio2MasteringVoice
*master
;
1170 IXAudio2SourceVoice
*src_2ch
, *src_8ch
;
1171 WAVEFORMATEX fmt_2ch
, fmt_8ch
;
1172 float volumes
[] = {0.1f
, 0.2f
, 0.3f
, 0.4f
, 0.5f
, 0.6f
, 0.7f
, 0.8f
};
1175 hr
= IXAudio27_CreateMasteringVoice((IXAudio27
*)xa
, &master
, 8, 44100, 0, 0, NULL
);
1177 hr
= IXAudio2_CreateMasteringVoice(xa
, &master
, 8, 44100, 0, NULL
, NULL
, AudioCategory_GameEffects
);
1178 ok(hr
== S_OK
, "CreateMasteringVoice failed: %08x\n", hr
);
1180 fmt_2ch
.wFormatTag
= WAVE_FORMAT_IEEE_FLOAT
;
1181 fmt_2ch
.nChannels
= 2;
1182 fmt_2ch
.nSamplesPerSec
= 44100;
1183 fmt_2ch
.wBitsPerSample
= 32;
1184 fmt_2ch
.nBlockAlign
= fmt_2ch
.nChannels
* fmt_2ch
.wBitsPerSample
/ 8;
1185 fmt_2ch
.nAvgBytesPerSec
= fmt_2ch
.nSamplesPerSec
* fmt_2ch
.nBlockAlign
;
1188 fmt_8ch
.wFormatTag
= WAVE_FORMAT_IEEE_FLOAT
;
1189 fmt_8ch
.nChannels
= 8;
1190 fmt_8ch
.nSamplesPerSec
= 44100;
1191 fmt_8ch
.wBitsPerSample
= 32;
1192 fmt_8ch
.nBlockAlign
= fmt_8ch
.nChannels
* fmt_8ch
.wBitsPerSample
/ 8;
1193 fmt_8ch
.nAvgBytesPerSec
= fmt_8ch
.nSamplesPerSec
* fmt_8ch
.nBlockAlign
;
1196 XA2CALL(CreateSourceVoice
, &src_2ch
, &fmt_2ch
, 0, 1.f
, NULL
, NULL
, NULL
);
1197 ok(hr
== S_OK
, "CreateSourceVoice failed: %08x\n", hr
);
1199 XA2CALL(CreateSourceVoice
, &src_8ch
, &fmt_8ch
, 0, 1.f
, NULL
, NULL
, NULL
);
1200 ok(hr
== S_OK
, "CreateSourceVoice failed: %08x\n", hr
);
1202 hr
= IXAudio2SourceVoice_SetChannelVolumes(src_2ch
, 2, volumes
, XAUDIO2_COMMIT_NOW
);
1203 ok(hr
== S_OK
, "SetChannelVolumes failed: %08x\n", hr
);
1205 hr
= IXAudio2SourceVoice_SetChannelVolumes(src_8ch
, 8, volumes
, XAUDIO2_COMMIT_NOW
);
1206 ok(hr
== S_OK
, "SetChannelVolumes failed: %08x\n", hr
);
1209 /* XAudio 2.7 doesn't check the number of channels */
1210 hr
= IXAudio2SourceVoice_SetChannelVolumes(src_8ch
, 2, volumes
, XAUDIO2_COMMIT_NOW
);
1211 ok(hr
== S_OK
, "SetChannelVolumes failed: %08x\n", hr
);
1213 /* the number of channels must be the same as the number of channels on the source voice */
1214 hr
= IXAudio2SourceVoice_SetChannelVolumes(src_8ch
, 2, volumes
, XAUDIO2_COMMIT_NOW
);
1215 ok(hr
== XAUDIO2_E_INVALID_CALL
, "SetChannelVolumes should have failed: %08x\n", hr
);
1217 hr
= IXAudio2SourceVoice_SetChannelVolumes(src_2ch
, 8, volumes
, XAUDIO2_COMMIT_NOW
);
1218 ok(hr
== XAUDIO2_E_INVALID_CALL
, "SetChannelVolumes should have failed: %08x\n", hr
);
1220 /* volumes must not be NULL, XAudio 2.7 doesn't check this */
1221 hr
= IXAudio2SourceVoice_SetChannelVolumes(src_2ch
, 2, NULL
, XAUDIO2_COMMIT_NOW
);
1222 ok(hr
== XAUDIO2_E_INVALID_CALL
, "SetChannelVolumes should have failed: %08x\n", hr
);
1226 IXAudio27SourceVoice_DestroyVoice((IXAudio27SourceVoice
*)src_2ch
);
1227 IXAudio27SourceVoice_DestroyVoice((IXAudio27SourceVoice
*)src_8ch
);
1229 IXAudio2SourceVoice_DestroyVoice(src_2ch
);
1230 IXAudio2SourceVoice_DestroyVoice(src_8ch
);
1233 IXAudio2MasteringVoice_DestroyVoice(master
);
1236 static UINT32
check_has_devices(IXAudio2
*xa
)
1239 IXAudio2MasteringVoice
*master
;
1241 hr
= IXAudio2_CreateMasteringVoice(xa
, &master
, 2, 44100, 0, NULL
, NULL
, AudioCategory_GameEffects
);
1245 IXAudio2MasteringVoice_DestroyVoice(master
);
1253 IXAudio27
*xa27
= NULL
;
1254 IXAudio2
*xa
= NULL
;
1261 xa28dll
= LoadLibraryA("xaudio2_8.dll");
1263 pXAudio2Create
= (void*)GetProcAddress(xa28dll
, "XAudio2Create");
1264 pCreateAudioVolumeMeter
= (void*)GetProcAddress(xa28dll
, "CreateAudioVolumeMeter");
1267 test_xapo_creation();
1269 /* XAudio 2.7 (Jun 2010 DirectX) */
1270 hr
= CoCreateInstance(&CLSID_XAudio27
, NULL
, CLSCTX_INPROC_SERVER
,
1271 &IID_IXAudio27
, (void**)&xa27
);
1275 hr
= IXAudio27_QueryInterface(xa27
, &IID_IXAudio28
, (void**) &xa
);
1276 ok(hr
!= S_OK
, "QueryInterface with IID_IXAudio28 on IXAudio27 object returned success. Expected to fail\n");
1278 hr
= IXAudio27_Initialize(xa27
, 0, XAUDIO2_ANY_PROCESSOR
);
1279 ok(hr
== S_OK
, "Initialize failed: %08x\n", hr
);
1281 has_devices
= test_DeviceDetails(xa27
);
1283 test_simple_streaming((IXAudio2
*)xa27
);
1284 test_buffer_callbacks((IXAudio2
*)xa27
);
1285 test_looping((IXAudio2
*)xa27
);
1286 test_submix((IXAudio2
*)xa27
);
1287 test_flush((IXAudio2
*)xa27
);
1288 test_setchannelvolumes((IXAudio2
*)xa27
);
1290 skip("No audio devices available\n");
1292 rc
= IXAudio27_Release(xa27
);
1293 ok(rc
== 0, "IXAudio2.7 object should have been released, got refcount %u\n", rc
);
1295 win_skip("XAudio 2.7 not available\n");
1297 /* XAudio 2.8 (Win8+) */
1301 hr
= pXAudio2Create(&xa
, 0, XAUDIO2_DEFAULT_PROCESSOR
);
1302 ok(hr
== S_OK
, "XAudio2Create failed: %08x\n", hr
);
1304 hr
= IXAudio2_QueryInterface(xa
, &IID_IXAudio27
, (void**)&xa27
);
1305 ok(hr
== E_NOINTERFACE
, "XA28 object should support IXAudio27, gave: %08x\n", hr
);
1307 has_devices
= check_has_devices(xa
);
1309 test_simple_streaming(xa
);
1310 test_buffer_callbacks(xa
);
1314 test_setchannelvolumes(xa
);
1316 skip("No audio devices available\n");
1318 rc
= IXAudio2_Release(xa
);
1319 ok(rc
== 0, "IXAudio2 object should have been released, got refcount %u\n", rc
);
1321 win_skip("XAudio 2.8 not available\n");