]> Repos - portaudio/commitdiff
wasapi: fixed host-WASAPI related bug when selected 24-bit Input does not produce...
authordmitrykos <dmitrykos@0f58301d-fd10-0410-b4af-bbb618454e57>
Thu, 10 Jun 2010 09:09:19 +0000 (09:09 +0000)
committerdmitrykos <dmitrykos@0f58301d-fd10-0410-b4af-bbb618454e57>
Thu, 10 Jun 2010 09:09:19 +0000 (09:09 +0000)
src/hostapi/wasapi/pa_win_wasapi.c

index eb922bff0e0a3582a4269316767f937e9c66b63b..b0e469e6df9fcc4d787d4c19868d20a4e2adc4ee 100644 (file)
@@ -1650,13 +1650,23 @@ static void wasapiFillWFEXT( WAVEFORMATEXTENSIBLE* pwfext, PaSampleFormat sample
 \r
 // ------------------------------------------------------------------------------------------\r
 static PaError GetClosestFormat(IAudioClient *myClient, double sampleRate,\r
-       const PaStreamParameters *params, AUDCLNT_SHAREMODE shareMode, WAVEFORMATEXTENSIBLE *outWavex)\r
+       const PaStreamParameters *_params, AUDCLNT_SHAREMODE shareMode, WAVEFORMATEXTENSIBLE *outWavex,\r
+       BOOL output)\r
 {\r
-       PaError answer = paInvalidSampleRate;\r
+       PaError answer                   = paInvalidSampleRate;\r
        WAVEFORMATEX *sharedClosestMatch = NULL;\r
-       HRESULT hr = !S_OK;\r
+       HRESULT hr                       = !S_OK;\r
+       PaStreamParameters params       = (*_params);\r
 \r
-    MakeWaveFormatFromParams(outWavex, params, sampleRate);\r
+       /* It was not noticed that 24-bit Input producing no output while device accepts this format.\r
+          To fix this issue let's ask for 32-bits and let PA converters convert host 32-bit data\r
+          to 24-bit for user-space. The bug concerns Vista, if Windows 7 supports 24-bits for Input\r
+          please report to PortAudio developers to exclude Windows 7.\r
+       */\r
+       if ((params.sampleFormat == paInt24) && (output == FALSE))\r
+               params.sampleFormat = paFloat32;\r
+\r
+    MakeWaveFormatFromParams(outWavex, &params, sampleRate);\r
 \r
        hr = IAudioClient_IsFormatSupported(myClient, shareMode, &outWavex->Format, (shareMode == AUDCLNT_SHAREMODE_SHARED ? &sharedClosestMatch : NULL));\r
        if (hr == S_OK)\r
@@ -1686,19 +1696,19 @@ static PaError GetClosestFormat(IAudioClient *myClient, double sampleRate,
                        return paInvalidSampleRate;\r
 \r
                // Validate Channel count\r
-               if ((WORD)params->channelCount != outWavex->Format.nChannels)\r
+               if ((WORD)params.channelCount != outWavex->Format.nChannels)\r
                {\r
                        // If mono, then driver does not support 1 channel, we use internal workaround\r
                        // of tiny software mixing functionality, e.g. we provide to user buffer 1 channel\r
                        // but then mix into 2 for device buffer\r
-                       if ((params->channelCount == 1) && (outWavex->Format.nChannels == 2))\r
+                       if ((params.channelCount == 1) && (outWavex->Format.nChannels == 2))\r
                                return paFormatIsSupported;\r
                        else\r
                                return paInvalidChannelCount;\r
                }\r
 \r
                // Validate Sample format\r
-               if ((bitsPerSample = PaSampleFormatToBitsPerSample(params->sampleFormat)) == 0)\r
+               if ((bitsPerSample = PaSampleFormatToBitsPerSample(params.sampleFormat)) == 0)\r
                        return paSampleFormatNotSupported;\r
 \r
                // Validate Sample format: bit size (WASAPI does not limit 'bit size')\r
@@ -1723,7 +1733,7 @@ static const int BestToWorst[FORMATTESTS] = { paFloat32, paInt24, paInt16 };
                for (i = 0; i < FORMATTESTS; ++i)\r
                {\r
                        WAVEFORMATEXTENSIBLE ext = { 0 };\r
-                       wasapiFillWFEXT(&ext, BestToWorst[i], sampleRate, params->channelCount);\r
+                       wasapiFillWFEXT(&ext, BestToWorst[i], sampleRate, params.channelCount);\r
 \r
                        hr = IAudioClient_IsFormatSupported(myClient, shareMode, &ext.Format, (shareMode == AUDCLNT_SHAREMODE_SHARED ? &sharedClosestMatch : NULL));\r
                        if (hr == S_OK)\r
@@ -1739,10 +1749,10 @@ static const int BestToWorst[FORMATTESTS] = { paFloat32, paInt24, paInt16 };
                        // If mono, then driver does not support 1 channel, we use internal workaround\r
                        // of tiny software mixing functionality, e.g. we provide to user buffer 1 channel\r
                        // but then mix into 2 for device buffer\r
-                       if (params->channelCount == 1)\r
+                       if (params.channelCount == 1)\r
                        {\r
                                WAVEFORMATEXTENSIBLE stereo = { 0 };\r
-                               wasapiFillWFEXT(&stereo, params->sampleFormat, sampleRate, 2);\r
+                               wasapiFillWFEXT(&stereo, params.sampleFormat, sampleRate, 2);\r
 \r
                                hr = IAudioClient_IsFormatSupported(myClient, shareMode, &stereo.Format, (shareMode == AUDCLNT_SHAREMODE_SHARED ? &sharedClosestMatch : NULL));\r
                                if (hr == S_OK)\r
@@ -1869,7 +1879,7 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
                        return paInvalidDevice;\r
                }\r
 \r
-               answer = GetClosestFormat(tmpClient, sampleRate, inputParameters, shareMode, &wavex);\r
+               answer = GetClosestFormat(tmpClient, sampleRate, inputParameters, shareMode, &wavex, FALSE);\r
                SAFE_RELEASE(tmpClient);\r
 \r
                if (answer != paFormatIsSupported)\r
@@ -1895,7 +1905,7 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
                        return paInvalidDevice;\r
                }\r
 \r
-               answer = GetClosestFormat(tmpClient, sampleRate, outputParameters, shareMode, &wavex);\r
+               answer = GetClosestFormat(tmpClient, sampleRate, outputParameters, shareMode, &wavex, TRUE);\r
                SAFE_RELEASE(tmpClient);\r
 \r
                if (answer != paFormatIsSupported)\r
@@ -1908,7 +1918,7 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
 // ------------------------------------------------------------------------------------------\r
 static HRESULT CreateAudioClient(PaWasapiSubStream *pSubStream, PaWasapiDeviceInfo *info,\r
        const PaStreamParameters *params, UINT32 framesPerLatency, double sampleRate, UINT32 streamFlags,\r
-       BOOL blocking, PaError *pa_error)\r
+       BOOL blocking, BOOL output, PaError *pa_error)\r
 {\r
        PaError error;\r
     HRESULT hr                                 = S_OK;\r
@@ -1930,7 +1940,7 @@ static HRESULT CreateAudioClient(PaWasapiSubStream *pSubStream, PaWasapiDeviceIn
        }\r
 \r
        // Get closest format\r
-       if ((error = GetClosestFormat(pAudioClient, sampleRate, params, pSubStream->shareMode, &pSubStream->wavex)) != paFormatIsSupported)\r
+       if ((error = GetClosestFormat(pAudioClient, sampleRate, params, pSubStream->shareMode, &pSubStream->wavex, output)) != paFormatIsSupported)\r
        {\r
                if (pa_error)\r
                        (*pa_error) = error;\r
@@ -2080,7 +2090,7 @@ static const REFERENCE_TIME MAX_BUFFER_POLL_DURATION  = 2000 * 10000;
                }\r
 \r
                // Get closest format\r
-               if ((error = GetClosestFormat(pAudioClient, sampleRate, params, pSubStream->shareMode, &pSubStream->wavex)) != paFormatIsSupported)\r
+               if ((error = GetClosestFormat(pAudioClient, sampleRate, params, pSubStream->shareMode, &pSubStream->wavex, output)) != paFormatIsSupported)\r
                {\r
                        if (pa_error)\r
                                (*pa_error) = error;\r
@@ -2260,7 +2270,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
 \r
                // Create Audio client\r
                hr = CreateAudioClient(&stream->in, info, inputParameters, 0/*framesPerLatency*/,\r
-                       sampleRate, stream->in.streamFlags, (streamCallback == NULL), &result);\r
+                       sampleRate, stream->in.streamFlags, (streamCallback == NULL), FALSE, &result);\r
         if (hr != S_OK)\r
                {\r
             LogHostError(hr);\r
@@ -2374,7 +2384,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
 \r
                // Create Audio client\r
                hr = CreateAudioClient(&stream->out, info, outputParameters, 0/*framesPerLatency*/,\r
-                       sampleRate, stream->out.streamFlags, (streamCallback == NULL), &result);\r
+                       sampleRate, stream->out.streamFlags, (streamCallback == NULL), TRUE, &result);\r
         if (hr != S_OK)\r
                {\r
             LogHostError(hr);\r