49 // |
49 // |
50 // We mean it. |
50 // We mean it. |
51 // |
51 // |
52 |
52 |
53 #include "qaudiooutput_win32_p.h" |
53 #include "qaudiooutput_win32_p.h" |
|
54 |
|
55 #ifndef SPEAKER_FRONT_LEFT |
|
56 #define SPEAKER_FRONT_LEFT 0x00000001 |
|
57 #define SPEAKER_FRONT_RIGHT 0x00000002 |
|
58 #define SPEAKER_FRONT_CENTER 0x00000004 |
|
59 #define SPEAKER_LOW_FREQUENCY 0x00000008 |
|
60 #define SPEAKER_BACK_LEFT 0x00000010 |
|
61 #define SPEAKER_BACK_RIGHT 0x00000020 |
|
62 #define SPEAKER_FRONT_LEFT_OF_CENTER 0x00000040 |
|
63 #define SPEAKER_FRONT_RIGHT_OF_CENTER 0x00000080 |
|
64 #define SPEAKER_BACK_CENTER 0x00000100 |
|
65 #define SPEAKER_SIDE_LEFT 0x00000200 |
|
66 #define SPEAKER_SIDE_RIGHT 0x00000400 |
|
67 #define SPEAKER_TOP_CENTER 0x00000800 |
|
68 #define SPEAKER_TOP_FRONT_LEFT 0x00001000 |
|
69 #define SPEAKER_TOP_FRONT_CENTER 0x00002000 |
|
70 #define SPEAKER_TOP_FRONT_RIGHT 0x00004000 |
|
71 #define SPEAKER_TOP_BACK_LEFT 0x00008000 |
|
72 #define SPEAKER_TOP_BACK_CENTER 0x00010000 |
|
73 #define SPEAKER_TOP_BACK_RIGHT 0x00020000 |
|
74 #define SPEAKER_RESERVED 0x7FFC0000 |
|
75 #define SPEAKER_ALL 0x80000000 |
|
76 #endif |
|
77 |
|
78 #ifndef _WAVEFORMATEXTENSIBLE_ |
|
79 |
|
80 #define _WAVEFORMATEXTENSIBLE_ |
|
81 typedef struct |
|
82 { |
|
83 WAVEFORMATEX Format; // Base WAVEFORMATEX data |
|
84 union |
|
85 { |
|
86 WORD wValidBitsPerSample; // Valid bits in each sample container |
|
87 WORD wSamplesPerBlock; // Samples per block of audio data; valid |
|
88 // if wBitsPerSample=0 (but rarely used). |
|
89 WORD wReserved; // Zero if neither case above applies. |
|
90 } Samples; |
|
91 DWORD dwChannelMask; // Positions of the audio channels |
|
92 GUID SubFormat; // Format identifier GUID |
|
93 } WAVEFORMATEXTENSIBLE, *PWAVEFORMATEXTENSIBLE, *LPPWAVEFORMATEXTENSIBLE; |
|
94 typedef const WAVEFORMATEXTENSIBLE* LPCWAVEFORMATEXTENSIBLE; |
|
95 |
|
96 #endif |
|
97 |
|
98 #if !defined(WAVE_FORMAT_EXTENSIBLE) |
|
99 #define WAVE_FORMAT_EXTENSIBLE 0xFFFE |
|
100 #endif |
54 |
101 |
55 //#define DEBUG_AUDIO 1 |
102 //#define DEBUG_AUDIO 1 |
56 |
103 |
57 QT_BEGIN_NAMESPACE |
104 QT_BEGIN_NAMESPACE |
58 |
105 |
144 |
191 |
145 int count = buffer_size/period_size; |
192 int count = buffer_size/period_size; |
146 |
193 |
147 for(int i = 0; i < count; i++) { |
194 for(int i = 0; i < count; i++) { |
148 waveOutUnprepareHeader(hWaveOut,blocks, sizeof(WAVEHDR)); |
195 waveOutUnprepareHeader(hWaveOut,blocks, sizeof(WAVEHDR)); |
149 blocks+=sizeof(WAVEHDR); |
196 blocks++; |
150 } |
197 } |
151 HeapFree(GetProcessHeap(), 0, blockArray); |
198 HeapFree(GetProcessHeap(), 0, blockArray); |
152 } |
199 } |
153 |
200 |
154 QAudioFormat QAudioOutputPrivate::format() const |
201 QAudioFormat QAudioOutputPrivate::format() const |
256 break; |
303 break; |
257 } |
304 } |
258 } |
305 } |
259 } |
306 } |
260 |
307 |
261 if(waveOutOpen(&hWaveOut, devId, &wfx, |
308 if ( settings.channels() <= 2) { |
262 (DWORD_PTR)&waveOutProc, |
309 if(waveOutOpen(&hWaveOut, devId, &wfx, |
263 (DWORD_PTR) this, |
310 (DWORD_PTR)&waveOutProc, |
264 CALLBACK_FUNCTION) != MMSYSERR_NOERROR) { |
311 (DWORD_PTR) this, |
265 errorState = QAudio::OpenError; |
312 CALLBACK_FUNCTION) != MMSYSERR_NOERROR) { |
266 deviceState = QAudio::StoppedState; |
313 errorState = QAudio::OpenError; |
267 emit stateChanged(deviceState); |
314 deviceState = QAudio::StoppedState; |
268 qWarning("QAudioOutput: open error"); |
315 emit stateChanged(deviceState); |
269 return false; |
316 qWarning("QAudioOutput: open error"); |
|
317 return false; |
|
318 } |
|
319 } else { |
|
320 WAVEFORMATEXTENSIBLE wfex; |
|
321 wfex.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; |
|
322 wfex.Format.nChannels = settings.channels(); |
|
323 wfex.Format.wBitsPerSample = settings.sampleSize(); |
|
324 wfex.Format.nSamplesPerSec = settings.frequency(); |
|
325 wfex.Format.nBlockAlign = wfex.Format.nChannels*wfex.Format.wBitsPerSample/8; |
|
326 wfex.Format.nAvgBytesPerSec=wfex.Format.nSamplesPerSec*wfex.Format.nBlockAlign; |
|
327 wfex.Samples.wValidBitsPerSample=wfex.Format.wBitsPerSample; |
|
328 static const GUID _KSDATAFORMAT_SUBTYPE_PCM = { |
|
329 0x00000001, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; |
|
330 wfex.SubFormat=_KSDATAFORMAT_SUBTYPE_PCM; |
|
331 wfex.Format.cbSize=22; |
|
332 |
|
333 wfex.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT; |
|
334 if (settings.channels() >= 4) |
|
335 wfex.dwChannelMask |= SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT; |
|
336 if (settings.channels() >= 6) |
|
337 wfex.dwChannelMask |= SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY; |
|
338 if (settings.channels() == 8) |
|
339 wfex.dwChannelMask |= SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT; |
|
340 |
|
341 if(waveOutOpen(&hWaveOut, devId, &wfex.Format, |
|
342 (DWORD_PTR)&waveOutProc, |
|
343 (DWORD_PTR) this, |
|
344 CALLBACK_FUNCTION) != MMSYSERR_NOERROR) { |
|
345 errorState = QAudio::OpenError; |
|
346 deviceState = QAudio::StoppedState; |
|
347 emit stateChanged(deviceState); |
|
348 qWarning("QAudioOutput: open error"); |
|
349 return false; |
|
350 } |
270 } |
351 } |
271 |
352 |
272 totalTimeValue = 0; |
353 totalTimeValue = 0; |
273 timeStampOpened.restart(); |
354 timeStampOpened.restart(); |
274 elapsedTimeOffset = 0; |
355 elapsedTimeOffset = 0; |