]> Repos - portaudio/commitdiff
wasapi: allow mono input/output streams be created when Blocking interface is used...
authordmitrykos <dmitrykos@0f58301d-fd10-0410-b4af-bbb618454e57>
Mon, 3 Jan 2011 18:33:32 +0000 (18:33 +0000)
committerdmitrykos <dmitrykos@0f58301d-fd10-0410-b4af-bbb618454e57>
Mon, 3 Jan 2011 18:33:32 +0000 (18:33 +0000)
src/hostapi/wasapi/pa_win_wasapi.c

index cbd9dee44905a7811ccf09140da503872947092f..bf70d91b173f4be672fdb0f413d3c727aa53aa41 100644 (file)
@@ -376,6 +376,21 @@ typedef struct
 }\r
 PaWasapiHostApiRepresentation;\r
 \r
+// ------------------------------------------------------------------------------------------\r
+/* PaWasapiAudioClientParams - audio client parameters */\r
+typedef struct PaWasapiAudioClientParams\r
+{\r
+       PaWasapiDeviceInfo *device_info;\r
+       PaStreamParameters  stream_params;\r
+       PaWasapiStreamInfo  wasapi_params;\r
+       UINT32              frames_per_buffer;\r
+       double              sample_rate;\r
+       BOOL                blocking;\r
+       BOOL                full_duplex;\r
+       BOOL                wow64_workaround;\r
+}\r
+PaWasapiAudioClientParams;\r
+\r
 // ------------------------------------------------------------------------------------------\r
 /* PaWasapiStream - a stream data structure specifically for this implementation */\r
 typedef struct PaWasapiSubStream\r
@@ -390,6 +405,7 @@ typedef struct PaWasapiSubStream
        AUDCLNT_SHAREMODE    shareMode;\r
        UINT32               streamFlags; // AUDCLNT_STREAMFLAGS_EVENTCALLBACK, ...\r
        UINT32               flags;\r
+       PaWasapiAudioClientParams params; //!< parameters\r
 \r
        // Buffers\r
        UINT32               buffers;                   //!< number of buffers used (from host side)\r
@@ -849,7 +865,7 @@ typedef enum EMixerDir { MIX_DIR__1TO2, MIX_DIR__2TO1, MIX_DIR__2TO1_L } EMixerD
        }\r
 \r
 // ------------------------------------------------------------------------------------------\r
-#define _WASAPI_MONO_TO_STEREO_MIXER_2_TO_1(TYPE)\\r
+#define _WASAPI_MONO_TO_STEREO_MIXER_2_TO_1_FLT32(TYPE)\\r
        TYPE * __restrict to   = (TYPE *)__to;\\r
        TYPE * __restrict from = (TYPE *)__from;\\r
        TYPE * __restrict end  = to + count;\\r
@@ -859,6 +875,28 @@ typedef enum EMixerDir { MIX_DIR__1TO2, MIX_DIR__2TO1, MIX_DIR__2TO1_L } EMixerD
                from += 2;\\r
        }\r
 \r
+// ------------------------------------------------------------------------------------------\r
+#define _WASAPI_MONO_TO_STEREO_MIXER_2_TO_1_INT32(TYPE)\\r
+       TYPE * __restrict to   = (TYPE *)__to;\\r
+       TYPE * __restrict from = (TYPE *)__from;\\r
+       TYPE * __restrict end  = to + count;\\r
+       while (to != end)\\r
+       {\\r
+               *to ++ = (TYPE)(((INT32)from[0] + (INT32)from[1]) >> 1);\\r
+               from += 2;\\r
+       }\r
+\r
+// ------------------------------------------------------------------------------------------\r
+#define _WASAPI_MONO_TO_STEREO_MIXER_2_TO_1_INT64(TYPE)\\r
+       TYPE * __restrict to   = (TYPE *)__to;\\r
+       TYPE * __restrict from = (TYPE *)__from;\\r
+       TYPE * __restrict end  = to + count;\\r
+       while (to != end)\\r
+       {\\r
+               *to ++ = (TYPE)(((INT64)from[0] + (INT64)from[1]) >> 1);\\r
+               from += 2;\\r
+       }\r
+\r
 // ------------------------------------------------------------------------------------------\r
 #define _WASAPI_MONO_TO_STEREO_MIXER_2_TO_1_L(TYPE)\\r
        TYPE * __restrict to   = (TYPE *)__to;\\r
@@ -878,11 +916,11 @@ static void _MixMonoToStereo_1TO2_32(void *__to, void *__from, UINT32 count) { _
 static void _MixMonoToStereo_1TO2_32f(void *__to, void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_1_TO_2(float); }\r
 \r
 // ------------------------------------------------------------------------------------------\r
-static void _MixMonoToStereo_2TO1_8(void *__to, void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_2_TO_1(BYTE); }\r
-static void _MixMonoToStereo_2TO1_16(void *__to, void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_2_TO_1(short); }\r
-static void _MixMonoToStereo_2TO1_24(void *__to, void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_2_TO_1(int); /* !!! int24 data is contained in 32-bit containers*/ }\r
-static void _MixMonoToStereo_2TO1_32(void *__to, void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_2_TO_1(int); }\r
-static void _MixMonoToStereo_2TO1_32f(void *__to, void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_2_TO_1(float); }\r
+static void _MixMonoToStereo_2TO1_8(void *__to, void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_2_TO_1_INT32(BYTE); }\r
+static void _MixMonoToStereo_2TO1_16(void *__to, void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_2_TO_1_INT32(short); }\r
+static void _MixMonoToStereo_2TO1_24(void *__to, void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_2_TO_1_INT32(int); /* !!! int24 data is contained in 32-bit containers*/ }\r
+static void _MixMonoToStereo_2TO1_32(void *__to, void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_2_TO_1_INT64(int); }\r
+static void _MixMonoToStereo_2TO1_32f(void *__to, void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_2_TO_1_FLT32(float); }\r
 \r
 // ------------------------------------------------------------------------------------------\r
 static void _MixMonoToStereo_2TO1_8_L(void *__to, void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_2_TO_1_L(BYTE); }\r
@@ -1985,15 +2023,22 @@ static void _CalculateAlignedPeriod(PaWasapiSubStream *pSub, UINT32 *nFramesPerL
 }\r
 \r
 // ------------------------------------------------------------------------------------------\r
-static HRESULT CreateAudioClient(PaWasapiStream *pStream, PaWasapiSubStream *pSub,\r
-       PaWasapiDeviceInfo *pInfo, const PaStreamParameters *params, UINT32 framesPerLatency,\r
-       double sampleRate, BOOL blocking, BOOL output, BOOL fullDuplex, PaError *pa_error)\r
+static HRESULT CreateAudioClient(PaWasapiStream *pStream, PaWasapiSubStream *pSub, BOOL output, PaError *pa_error)\r
 {\r
        PaError error;\r
     HRESULT hr;\r
+\r
+       const PaWasapiDeviceInfo *pInfo  = pSub->params.device_info;\r
+       const PaStreamParameters *params = &pSub->params.stream_params;\r
+       UINT32 framesPerLatency          = pSub->params.frames_per_buffer;\r
+       double sampleRate                = pSub->params.sample_rate;\r
+       BOOL blocking                    = pSub->params.blocking;\r
+       BOOL fullDuplex                  = pSub->params.full_duplex;\r
+\r
        const UINT32 userFramesPerBuffer = framesPerLatency;\r
     IAudioClient *audioClient       = NULL;\r
 \r
+\r
        // Validate parameters\r
     if (!pSub || !pInfo || !params)\r
         return E_POINTER;\r
@@ -2021,11 +2066,11 @@ static HRESULT CreateAudioClient(PaWasapiStream *pStream, PaWasapiSubStream *pSu
        // Check for Mono <<>> Stereo workaround\r
        if ((params->channelCount == 1) && (pSub->wavex.Format.nChannels == 2))\r
        {\r
-               if (blocking)\r
+               /*if (blocking)\r
                {\r
                        LogHostError(hr = AUDCLNT_E_UNSUPPORTED_FORMAT);\r
                        goto done; // fail, blocking mode not supported\r
-               }\r
+               }*/\r
 \r
                // select mixer\r
                pSub->monoMixer = _GetMonoToStereoMixer(WaveToPaFormat(&pSub->wavex), (pInfo->flow == eRender ? MIX_DIR__1TO2 : MIX_DIR__2TO1_L));\r
@@ -2260,11 +2305,11 @@ static HRESULT CreateAudioClient(PaWasapiStream *pStream, PaWasapiSubStream *pSu
                // Check for Mono >> Stereo workaround\r
                if ((params->channelCount == 1) && (pSub->wavex.Format.nChannels == 2))\r
                {\r
-                       if (blocking)\r
+                       /*if (blocking)\r
                        {\r
                                LogHostError(hr = AUDCLNT_E_UNSUPPORTED_FORMAT);\r
                                goto done; // fail, blocking mode not supported\r
-                       }\r
+                       }*/\r
 \r
                        // Select mixer\r
                        pSub->monoMixer = _GetMonoToStereoMixer(WaveToPaFormat(&pSub->wavex), (pInfo->flow == eRender ? MIX_DIR__1TO2 : MIX_DIR__2TO1_L));\r
@@ -2316,6 +2361,150 @@ done:
     return hr;\r
 }\r
 \r
+// ------------------------------------------------------------------------------------------\r
+static PaError ActivateAudioClientOutput(PaWasapiStream *stream)\r
+{\r
+       HRESULT hr;\r
+       PaError result;\r
+\r
+       UINT32 maxBufferSize   = 0;\r
+       PaTime buffer_latency  = 0;\r
+       UINT32 framesPerBuffer = stream->out.params.frames_per_buffer;\r
+\r
+       // Create Audio client\r
+       hr = CreateAudioClient(stream, &stream->out, TRUE, &result);\r
+    if (hr != S_OK)\r
+       {\r
+               LogPaError(result = paInvalidDevice);\r
+               goto error;\r
+    }\r
+       LogWAVEFORMATEXTENSIBLE(&stream->out.wavex);\r
+\r
+       // Activate volume\r
+       stream->outVol = NULL;\r
+    /*hr = info->device->Activate(\r
+        __uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, NULL,\r
+        (void**)&stream->outVol);\r
+    if (hr != S_OK)\r
+        return paInvalidDevice;*/\r
+\r
+    // Get max possible buffer size to check if it is not less than that we request\r
+    hr = IAudioClient_GetBufferSize(stream->out.client, &maxBufferSize);\r
+    if (hr != S_OK)\r
+       {\r
+               LogHostError(hr);\r
+               LogPaError(result = paInvalidDevice);\r
+               goto error;\r
+       }\r
+\r
+    // Correct buffer to max size if it maxed out result of GetBufferSize\r
+       stream->out.bufferSize = maxBufferSize;\r
+\r
+       // Get interface latency (actually uneeded as we calculate latency from the size\r
+       // of maxBufferSize).\r
+    hr = IAudioClient_GetStreamLatency(stream->out.client, &stream->out.device_latency);\r
+    if (hr != S_OK)\r
+       {\r
+               LogHostError(hr);\r
+               LogPaError(result = paInvalidDevice);\r
+               goto error;\r
+       }\r
+       //stream->out.latency_seconds = nano100ToSeconds(stream->out.device_latency);\r
+\r
+    // Number of frames that are required at each period\r
+       stream->out.framesPerHostCallback = maxBufferSize;\r
+\r
+       // Calculate frames per single buffer, if buffers > 1 then always framesPerBuffer\r
+       stream->out.framesPerBuffer =\r
+               (stream->out.userBufferAndHostMatch ? stream->out.framesPerHostCallback : framesPerBuffer);\r
+\r
+       // Calculate buffer latency\r
+       buffer_latency = (PaTime)maxBufferSize / stream->out.wavex.Format.nSamplesPerSec;\r
+\r
+       // Append buffer latency to interface latency in shared mode (see GetStreamLatency notes)\r
+       stream->out.latency_seconds = buffer_latency;\r
+\r
+       PRINT(("WASAPI::OpenStream(output): framesPerUser[ %d ] framesPerHost[ %d ] latency[ %.02fms ] exclusive[ %s ] wow64_fix[ %s ] mode[ %s ]\n", (UINT32)framesPerBuffer, (UINT32)stream->out.framesPerHostCallback, (float)(stream->out.latency_seconds*1000.0f), (stream->out.shareMode == AUDCLNT_SHAREMODE_EXCLUSIVE ? "YES" : "NO"), (stream->out.params.wow64_workaround ? "YES" : "NO"), (stream->out.streamFlags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK ? "EVENT" : "POLL")));\r
+\r
+       return paNoError;\r
+\r
+error:\r
+\r
+       return result;\r
+}\r
+\r
+// ------------------------------------------------------------------------------------------\r
+static PaError ActivateAudioClientInput(PaWasapiStream *stream)\r
+{\r
+       HRESULT hr;\r
+       PaError result;\r
+\r
+       UINT32 maxBufferSize   = 0;\r
+       PaTime buffer_latency  = 0;\r
+       UINT32 framesPerBuffer = stream->out.params.frames_per_buffer;\r
+\r
+       // Create Audio client\r
+       hr = CreateAudioClient(stream, &stream->in, FALSE, &result);\r
+    if (hr != S_OK)\r
+       {\r
+               LogPaError(result = paInvalidDevice);\r
+               goto error;\r
+    }\r
+       LogWAVEFORMATEXTENSIBLE(&stream->in.wavex);\r
+\r
+       // Create volume mgr\r
+       stream->inVol = NULL;\r
+    /*hr = info->device->Activate(\r
+        __uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, NULL,\r
+        (void**)&stream->inVol);\r
+    if (hr != S_OK)\r
+        return paInvalidDevice;*/\r
+\r
+    // Get max possible buffer size to check if it is not less than that we request\r
+    hr = IAudioClient_GetBufferSize(stream->in.client, &maxBufferSize);\r
+    if (hr != S_OK)\r
+       {\r
+               LogHostError(hr);\r
+               LogPaError(result = paInvalidDevice);\r
+               goto error;\r
+       }\r
+\r
+    // Correct buffer to max size if it maxed out result of GetBufferSize\r
+       stream->in.bufferSize = maxBufferSize;\r
+\r
+       // Get interface latency (actually uneeded as we calculate latency from the size\r
+       // of maxBufferSize).\r
+    hr = IAudioClient_GetStreamLatency(stream->in.client, &stream->in.device_latency);\r
+    if (hr != S_OK)\r
+       {\r
+               LogHostError(hr);\r
+               LogPaError(result = paInvalidDevice);\r
+               goto error;\r
+       }\r
+       //stream->in.latency_seconds = nano100ToSeconds(stream->in.device_latency);\r
+\r
+    // Number of frames that are required at each period\r
+       stream->in.framesPerHostCallback = maxBufferSize;\r
+\r
+       // Calculate frames per single buffer, if buffers > 1 then always framesPerBuffer\r
+       stream->in.framesPerBuffer =\r
+               (stream->in.userBufferAndHostMatch ? stream->in.framesPerHostCallback : framesPerBuffer);\r
+\r
+       // Calculate buffer latency\r
+       buffer_latency = (PaTime)maxBufferSize / stream->in.wavex.Format.nSamplesPerSec;\r
+\r
+       // Append buffer latency to interface latency in shared mode (see GetStreamLatency notes)\r
+       stream->in.latency_seconds = buffer_latency;\r
+\r
+       PRINT(("WASAPI::OpenStream(input): framesPerUser[ %d ] framesPerHost[ %d ] latency[ %.02fms ] exclusive[ %s ] wow64_fix[ %s ] mode[ %s ]\n", (UINT32)framesPerBuffer, (UINT32)stream->in.framesPerHostCallback, (float)(stream->in.latency_seconds*1000.0f), (stream->in.shareMode == AUDCLNT_SHAREMODE_EXCLUSIVE ? "YES" : "NO"), (stream->in.params.wow64_workaround ? "YES" : "NO"), (stream->in.streamFlags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK ? "EVENT" : "POLL")));\r
+\r
+       return paNoError;\r
+\r
+error:\r
+\r
+       return result;\r
+}\r
+\r
 // ------------------------------------------------------------------------------------------\r
 static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,\r
                            PaStream** s,\r
@@ -2336,8 +2525,6 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
     PaSampleFormat hostInputSampleFormat, hostOutputSampleFormat;\r
        PaWasapiStreamInfo *inputStreamInfo = NULL, *outputStreamInfo = NULL;\r
        PaWasapiDeviceInfo *info = NULL;\r
-       UINT32 maxBufferSize;\r
-       PaTime buffer_latency;\r
        ULONG framesPerHostCallback;\r
        PaUtilHostBufferSizeMode bufferMode;\r
        const BOOL fullDuplex = ((inputParameters != NULL) && (outputParameters != NULL));\r
@@ -2424,27 +2611,31 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
                if (fullDuplex)\r
                        stream->in.streamFlags = 0; // polling interface is implemented for full-duplex mode also\r
 \r
-               // Create Audio client\r
-               hr = CreateAudioClient(stream, &stream->in, info, inputParameters, framesPerBuffer/*framesPerLatency*/,\r
-                       sampleRate, (streamCallback == NULL), FALSE, fullDuplex, &result);\r
+               // Fill parameters for Audio Client creation\r
+               stream->in.params.device_info       = info;\r
+               stream->in.params.stream_params     = (*inputParameters);\r
+               if (inputStreamInfo != NULL)\r
+               {\r
+                       stream->in.params.wasapi_params = (*inputStreamInfo);\r
+                       stream->in.params.stream_params.hostApiSpecificStreamInfo = &stream->in.params.wasapi_params;\r
+               }\r
+               stream->in.params.frames_per_buffer = framesPerBuffer;\r
+               stream->in.params.sample_rate       = sampleRate;\r
+               stream->in.params.blocking          = (streamCallback == NULL);\r
+               stream->in.params.full_duplex       = fullDuplex;\r
+               stream->in.params.wow64_workaround  = paWasapi->useWOW64Workaround;\r
+\r
+               // Create and activate audio client\r
+               hr = ActivateAudioClientInput(stream);\r
         if (hr != S_OK)\r
                {\r
                        LogPaError(result = paInvalidDevice);\r
                        goto error;\r
         }\r
-               LogWAVEFORMATEXTENSIBLE(&stream->in.wavex);\r
 \r
                // Get closest format\r
         hostInputSampleFormat = PaUtil_SelectClosestAvailableFormat( WaveToPaFormat(&stream->in.wavex), inputSampleFormat );\r
 \r
-               // Create volume mgr\r
-               stream->inVol = NULL;\r
-        /*hr = info->device->Activate(\r
-            __uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, NULL,\r
-            (void**)&stream->inVol);\r
-        if (hr != S_OK)\r
-            return paInvalidDevice;*/\r
-\r
         // Set user-side custom host processor\r
         if ((inputStreamInfo != NULL) &&\r
             (inputStreamInfo->flags & paWinWasapiRedirectHostProcessor))\r
@@ -2452,44 +2643,6 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
             stream->hostProcessOverrideInput.processor = inputStreamInfo->hostProcessorInput;\r
             stream->hostProcessOverrideInput.userData = userData;\r
         }\r
-\r
-        // Get max possible buffer size to check if it is not less than that we request\r
-        hr = IAudioClient_GetBufferSize(stream->in.client, &maxBufferSize);\r
-        if (hr != S_OK)\r
-               {\r
-                       LogHostError(hr);\r
-                       LogPaError(result = paInvalidDevice);\r
-                       goto error;\r
-               }\r
-\r
-        // Correct buffer to max size if it maxed out result of GetBufferSize\r
-               stream->in.bufferSize = maxBufferSize;\r
-\r
-               // Get interface latency (actually uneeded as we calculate latency from the size\r
-               // of maxBufferSize).\r
-        hr = IAudioClient_GetStreamLatency(stream->in.client, &stream->in.device_latency);\r
-        if (hr != S_OK)\r
-               {\r
-                       LogHostError(hr);\r
-                       LogPaError(result = paInvalidDevice);\r
-                       goto error;\r
-               }\r
-               //stream->in.latency_seconds = nano100ToSeconds(stream->in.device_latency);\r
-\r
-        // Number of frames that are required at each period\r
-               stream->in.framesPerHostCallback = maxBufferSize;\r
-\r
-               // Calculate frames per single buffer, if buffers > 1 then always framesPerBuffer\r
-               stream->in.framesPerBuffer =\r
-                       (stream->in.userBufferAndHostMatch ? stream->in.framesPerHostCallback : framesPerBuffer);\r
-\r
-               // Calculate buffer latency\r
-               buffer_latency = (PaTime)maxBufferSize / stream->in.wavex.Format.nSamplesPerSec;\r
-\r
-               // Append buffer latency to interface latency in shared mode (see GetStreamLatency notes)\r
-               stream->in.latency_seconds += buffer_latency;\r
-\r
-               PRINT(("WASAPI::OpenStream(input): framesPerUser[ %d ] framesPerHost[ %d ] latency[ %.02fms ] exclusive[ %s ] wow64_fix[ %s ] mode[ %s ]\n", (UINT32)framesPerBuffer, (UINT32)stream->in.framesPerHostCallback, (float)(stream->in.latency_seconds*1000.0f), (stream->in.shareMode == AUDCLNT_SHAREMODE_EXCLUSIVE ? "YES" : "NO"), (paWasapi->useWOW64Workaround ? "YES" : "NO"), (stream->in.streamFlags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK ? "EVENT" : "POLL")));\r
        }\r
     else\r
     {\r
@@ -2538,72 +2691,38 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
                if (fullDuplex)\r
                        stream->out.streamFlags = 0; // polling interface is implemented for full-duplex mode also\r
 \r
-               // Create Audio client\r
-               hr = CreateAudioClient(stream, &stream->out, info, outputParameters, framesPerBuffer/*framesPerLatency*/,\r
-                       sampleRate, (streamCallback == NULL), TRUE, fullDuplex, &result);\r
+               // Fill parameters for Audio Client creation\r
+               stream->out.params.device_info       = info;\r
+               stream->out.params.stream_params     = (*outputParameters);\r
+               if (inputStreamInfo != NULL)\r
+               {\r
+                       stream->out.params.wasapi_params = (*outputStreamInfo);\r
+                       stream->out.params.stream_params.hostApiSpecificStreamInfo = &stream->out.params.wasapi_params;\r
+               }\r
+               stream->out.params.frames_per_buffer = framesPerBuffer;\r
+               stream->out.params.sample_rate       = sampleRate;\r
+               stream->out.params.blocking          = (streamCallback == NULL);\r
+               stream->out.params.full_duplex       = fullDuplex;\r
+               stream->out.params.wow64_workaround  = paWasapi->useWOW64Workaround;\r
+\r
+               // Create and activate audio client\r
+               hr = ActivateAudioClientOutput(stream);\r
         if (hr != S_OK)\r
                {\r
                        LogPaError(result = paInvalidDevice);\r
                        goto error;\r
         }\r
-               LogWAVEFORMATEXTENSIBLE(&stream->out.wavex);\r
 \r
-        // Get closest format\r
+               // Get closest format\r
         hostOutputSampleFormat = PaUtil_SelectClosestAvailableFormat( WaveToPaFormat(&stream->out.wavex), outputSampleFormat );\r
 \r
-               // Activate volume\r
-               stream->outVol = NULL;\r
-        /*hr = info->device->Activate(\r
-            __uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, NULL,\r
-            (void**)&stream->outVol);\r
-        if (hr != S_OK)\r
-            return paInvalidDevice;*/\r
-\r
-       // Set user-side custom host processor\r
+        // Set user-side custom host processor\r
         if ((outputStreamInfo != NULL) &&\r
             (outputStreamInfo->flags & paWinWasapiRedirectHostProcessor))\r
         {\r
             stream->hostProcessOverrideOutput.processor = outputStreamInfo->hostProcessorOutput;\r
             stream->hostProcessOverrideOutput.userData = userData;\r
         }\r
-\r
-        // Get max possible buffer size to check if it is not less than that we request\r
-        hr = IAudioClient_GetBufferSize(stream->out.client, &maxBufferSize);\r
-        if (hr != S_OK)\r
-               {\r
-                       LogHostError(hr);\r
-                       LogPaError(result = paInvalidDevice);\r
-                       goto error;\r
-               }\r
-\r
-        // Correct buffer to max size if it maxed out result of GetBufferSize\r
-               stream->out.bufferSize = maxBufferSize;\r
-\r
-               // Get interface latency (actually uneeded as we calculate latency from the size\r
-               // of maxBufferSize).\r
-        hr = IAudioClient_GetStreamLatency(stream->out.client, &stream->out.device_latency);\r
-        if (hr != S_OK)\r
-               {\r
-                       LogHostError(hr);\r
-                       LogPaError(result = paInvalidDevice);\r
-                       goto error;\r
-               }\r
-               //stream->out.latency_seconds = nano100ToSeconds(stream->out.device_latency);\r
-\r
-        // Number of frames that are required at each period\r
-               stream->out.framesPerHostCallback = maxBufferSize;\r
-\r
-               // Calculate frames per single buffer, if buffers > 1 then always framesPerBuffer\r
-               stream->out.framesPerBuffer =\r
-                       (stream->out.userBufferAndHostMatch ? stream->out.framesPerHostCallback : framesPerBuffer);\r
-\r
-               // Calculate buffer latency\r
-               buffer_latency = (PaTime)maxBufferSize / stream->out.wavex.Format.nSamplesPerSec;\r
-\r
-               // Append buffer latency to interface latency in shared mode (see GetStreamLatency notes)\r
-               stream->out.latency_seconds += buffer_latency;\r
-\r
-               PRINT(("WASAPI::OpenStream(output): framesPerUser[ %d ] framesPerHost[ %d ] latency[ %.02fms ] exclusive[ %s ] wow64_fix[ %s ] mode[ %s ]\n", (UINT32)framesPerBuffer, (UINT32)stream->out.framesPerHostCallback, (float)(stream->out.latency_seconds*1000.0f), (stream->out.shareMode == AUDCLNT_SHAREMODE_EXCLUSIVE ? "YES" : "NO"), (paWasapi->useWOW64Workaround ? "YES" : "NO"), (stream->out.streamFlags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK ? "EVENT" : "POLL")));\r
        }\r
     else\r
     {\r
@@ -4138,7 +4257,7 @@ PA_THREAD_FUNC ProcThreadPoll(void *param)
                }\r
 \r
                // Setup thread sleep scheduler\r
-               ThreadIdleScheduler_Setup(&scheduler, 1, sleep_ms/* microseconds here actually */);\r
+               ThreadIdleScheduler_Setup(&scheduler, 1, sleep_ms/* microseconds here */);\r
                sleep_ms = 0;\r
        }\r
 \r
@@ -4549,12 +4668,12 @@ thread_end:
        // Process stop\r
        _OnStreamStop(stream);\r
 \r
-       // Notify: thread exited\r
-       SetEvent(stream->hThreadExit);\r
-\r
        // Notify: not running\r
        stream->running = FALSE;\r
 \r
+       // Notify: thread exited\r
+       SetEvent(stream->hThreadExit);\r
+\r
        return 0;\r
 \r
 thread_error:\r