// Local stream methods\r
static void _OnStreamStop(PaWasapiStream *stream);\r
static void _FinishStream(PaWasapiStream *stream);\r
+static void _CleanupStream(PaWasapiStream *stream);\r
\r
// Local statics\r
static volatile BOOL g_WasapiCOMInit = FALSE;\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
+ /*if ((params.sampleFormat == paInt24) && (output == FALSE))\r
+ params.sampleFormat = paFloat32;*/ // <<< The silence was due to missing Int32_To_Int24_Dither implementation\r
\r
MakeWaveFormatFromParams(outWavex, ¶ms, sampleRate);\r
\r
CloseHandle(stream->event[S_INPUT]);\r
CloseHandle(stream->event[S_OUTPUT]);\r
\r
- SAFE_CLOSE(stream->hThread);\r
- SAFE_CLOSE(stream->hThreadStart);\r
- SAFE_CLOSE(stream->hThreadExit);\r
- SAFE_CLOSE(stream->hCloseRequest);\r
- SAFE_CLOSE(stream->hBlockingOpStreamRD);\r
- SAFE_CLOSE(stream->hBlockingOpStreamWR);\r
+ _CleanupStream(stream);\r
\r
free(stream->in.monoBuffer);\r
free(stream->out.monoBuffer);\r
\r
PaUtil_ResetBufferProcessor(&stream->bufferProcessor);\r
\r
+ // Cleanup handles (may be necessary if stream was stopped by itself due to error)\r
+ _CleanupStream(stream);\r
+\r
// Create close event\r
stream->hCloseRequest = CreateEvent(NULL, TRUE, FALSE, NULL);\r
\r
_OnStreamStop(stream);\r
}\r
\r
+ // Cleanup handles\r
+ _CleanupStream(stream);\r
+\r
+ stream->running = FALSE;\r
+}\r
+\r
+// ------------------------------------------------------------------------------------------\r
+static void _CleanupStream(PaWasapiStream *stream)\r
+{\r
// Close thread handles to allow restart\r
SAFE_CLOSE(stream->hThread);\r
SAFE_CLOSE(stream->hThreadStart);\r
SAFE_CLOSE(stream->hCloseRequest);\r
SAFE_CLOSE(stream->hBlockingOpStreamRD);\r
SAFE_CLOSE(stream->hBlockingOpStreamWR);\r
-\r
- stream->running = FALSE;\r
}\r
\r
// ------------------------------------------------------------------------------------------\r
// Process data\r
if (stream->out.monoMixer != NULL)\r
{\r
-#define __DIV_8(v) ((v) >> 3) //!< (v / 8)\r
-\r
// expand buffer (one way only for better performancedue to no calls to realloc)\r
- UINT32 mono_frames_size = frames * __DIV_8(stream->out.wavex.Format.wBitsPerSample);\r
+ UINT32 mono_frames_size = frames * (stream->out.wavex.Format.wBitsPerSample / 8);\r
if (mono_frames_size > stream->out.monoBufferSize)\r
stream->out.monoBuffer = realloc(stream->out.monoBuffer, (stream->out.monoBufferSize = mono_frames_size));\r
\r
\r
// mix 1 to 2 channels\r
stream->out.monoMixer(data, stream->out.monoBuffer, frames);\r
-\r
-#undef __DIV_8\r
}\r
else\r
{\r
// Process data\r
if (stream->in.monoMixer != NULL)\r
{\r
-#define __DIV_8(v) ((v) >> 3) //!< (v / 8)\r
-\r
// expand buffer (one way only for better performancedue to no calls to realloc)\r
- UINT32 mono_frames_size = frames * __DIV_8(stream->in.wavex.Format.wBitsPerSample);\r
+ UINT32 mono_frames_size = frames * (stream->in.wavex.Format.wBitsPerSample / 8);\r
if (mono_frames_size > stream->in.monoBufferSize)\r
stream->in.monoBuffer = realloc(stream->in.monoBuffer, (stream->in.monoBufferSize = mono_frames_size));\r
\r
\r
// process\r
processor[S_INPUT].processor((BYTE *)stream->in.monoBuffer, frames, NULL, 0, processor[S_INPUT].userData);\r
-\r
-#undef __DIV_8\r
}\r
else\r
{\r
// Release buffer\r
if ((hr = IAudioCaptureClient_ReleaseBuffer(stream->cclient, frames)) != S_OK)\r
return LogHostError(hr);\r
+\r
+ break;\r
}\r
\r
return hr;\r
stream->hAvTask = NULL;\r
}\r
\r
+ // Release Render/Capture clients (if Exclusive mode was used it will release devices to other applications)\r
+ SAFE_RELEASE(stream->cclient);\r
+ SAFE_RELEASE(stream->rclient);\r
+\r
// Notify\r
if (stream->streamRepresentation.streamFinishedCallback != NULL)\r
stream->streamRepresentation.streamFinishedCallback(stream->streamRepresentation.userData);\r
// Processing Loop\r
for (;;)\r
{\r
- // 2 sec timeout\r
- dwResult = WaitForMultipleObjects(S_COUNT, stream->event, bWaitAllEvents, 10000);\r
+ // 10 sec timeout (on timeout stream will auto-stop when processed by WAIT_TIMEOUT case)\r
+ dwResult = WaitForMultipleObjects(S_COUNT, stream->event, bWaitAllEvents, 10*1000);\r
\r
// Check for close event (after wait for buffers to avoid any calls to user\r
// callback when hCloseRequest was set)\r
\r
// Input stream\r
case WAIT_OBJECT_0 + S_INPUT: {\r
+\r
if (stream->cclient == NULL)\r
break;\r
+\r
if ((hr = ProcessInputBuffer(stream, processor)) != S_OK)\r
{\r
LogHostError(hr);\r
goto thread_error;\r
}\r
+\r
break; }\r
\r
// Output stream\r
case WAIT_OBJECT_0 + S_OUTPUT: {\r
+\r
if (stream->rclient == NULL)\r
break;\r
+\r
if ((hr = ProcessOutputBuffer(stream, processor, stream->out.framesPerBuffer)) != S_OK)\r
{\r
LogHostError(hr);\r
goto thread_error;\r
}\r
+\r
break; }\r
}\r
}\r
{\r
// Input stream\r
case S_INPUT: {\r
+\r
if (stream->cclient == NULL)\r
break;\r
+\r
if ((hr = ProcessInputBuffer(stream, processor)) != S_OK)\r
{\r
LogHostError(hr);\r
goto thread_error;\r
}\r
+\r
break; }\r
\r
// Output stream\r
// convert output mono\r
if (stream->out.monoMixer)\r
{\r
- #define __DIV_8(v) ((v) >> 3) //!< (v / 8)\r
- UINT32 mono_frames_size = o_processed * __DIV_8(stream->out.wavex.Format.wBitsPerSample);\r
- #undef __DIV_8\r
+ UINT32 mono_frames_size = o_processed * (stream->out.wavex.Format.wBitsPerSample / 8);\r
// expand buffer (one way only for better performance due to no calls to realloc)\r
if (mono_frames_size > stream->out.monoBufferSize)\r
{\r
// convert input mono\r
if (stream->in.monoMixer)\r
{\r
- #define __DIV_8(v) ((v) >> 3) //!< (v / 8)\r
- UINT32 mono_frames_size = i_processed * __DIV_8(stream->in.wavex.Format.wBitsPerSample);\r
- #undef __DIV_8\r
+ UINT32 mono_frames_size = i_processed * (stream->in.wavex.Format.wBitsPerSample / 8);\r
// expand buffer (one way only for better performance due to no calls to realloc)\r
if (mono_frames_size > stream->in.monoBufferSize)\r
{\r
// convert output mono\r
if (stream->out.monoMixer)\r
{\r
- #define __DIV_8(v) ((v) >> 3) //!< (v / 8)\r
- UINT32 mono_frames_size = o_processed * __DIV_8(stream->out.wavex.Format.wBitsPerSample);\r
- #undef __DIV_8\r
+ UINT32 mono_frames_size = o_processed * (stream->out.wavex.Format.wBitsPerSample / 8);\r
// expand buffer (one way only for better performance due to no calls to realloc)\r
if (mono_frames_size > stream->out.monoBufferSize)\r
{\r
// convert input mono\r
if (stream->in.monoMixer)\r
{\r
- #define __DIV_8(v) ((v) >> 3) //!< (v / 8)\r
- UINT32 mono_frames_size = i_processed * __DIV_8(stream->in.wavex.Format.wBitsPerSample);\r
- #undef __DIV_8\r
+ UINT32 mono_frames_size = i_processed * (stream->in.wavex.Format.wBitsPerSample / 8);\r
// expand buffer (one way only for better performance due to no calls to realloc)\r
if (mono_frames_size > stream->in.monoBufferSize)\r
{\r