src/multimedia/audio/qaudiooutput_win32_p.cpp
changeset 33 3e2da88830cd
parent 30 5dc02b23752f
equal deleted inserted replaced
30:5dc02b23752f 33:3e2da88830cd
    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;