1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-05-01 16:19:43 +02:00
audacity/lib-src/portaudio-v19/wasapi-loopback.patch

139 lines
5.6 KiB
Diff

diff -wruN portaudio/src/hostapi/wasapi/pa_win_wasapi.c portaudio-v19/src/hostapi/wasapi/pa_win_wasapi.c
--- portaudio/src/hostapi/wasapi/pa_win_wasapi.c 2012-06-29 06:44:12.000000000 -0500
+++ portaudio-v19/src/hostapi/wasapi/pa_win_wasapi.c 2012-12-31 14:46:16.533923600 -0600
@@ -1052,6 +1055,8 @@
HRESULT hr = S_OK;
IMMDeviceCollection* pEndPoints = NULL;
UINT i;
+ UINT renderCount;
+ UINT devIndex;
if (!SetupAVRT())
{
@@ -1148,6 +1153,19 @@
}
}
+ hr = IMMDeviceEnumerator_EnumAudioEndpoints(paWasapi->enumerator, eRender, DEVICE_STATE_ACTIVE, &pEndPoints);
+ // We need to set the result to a value otherwise we will return paNoError
+ // [IF_FAILED_JUMP(hResult, error);]
+ IF_FAILED_INTERNAL_ERROR_JUMP(hr, result, error);
+
+ hr = IMMDeviceCollection_GetCount(pEndPoints, &renderCount);
+ // We need to set the result to a value otherwise we will return paNoError
+ // [IF_FAILED_JUMP(hResult, error);]
+ IF_FAILED_INTERNAL_ERROR_JUMP(hr, result, error);
+
+ SAFE_RELEASE(pEndPoints);
+ pEndPoints = NULL;
+
hr = IMMDeviceEnumerator_EnumAudioEndpoints(paWasapi->enumerator, eAll, DEVICE_STATE_ACTIVE, &pEndPoints);
// We need to set the result to a value otherwise we will return paNoError
// [IF_FAILED_JUMP(hResult, error);]
@@ -1158,6 +1176,8 @@
// [IF_FAILED_JUMP(hResult, error);]
IF_FAILED_INTERNAL_ERROR_JUMP(hr, result, error);
+ paWasapi->deviceCount += renderCount;
+
paWasapi->devInfo = (PaWasapiDeviceInfo *)PaUtil_AllocateMemory(sizeof(PaWasapiDeviceInfo) * paWasapi->deviceCount);
for (i = 0; i < paWasapi->deviceCount; ++i)
memset(&paWasapi->devInfo[i], 0, sizeof(PaWasapiDeviceInfo));
@@ -1181,7 +1201,7 @@
goto error;
}
- for (i = 0; i < paWasapi->deviceCount; ++i)
+ for (devIndex = 0, i = 0; i < paWasapi->deviceCount; ++i, ++devIndex)
{
DWORD state = 0;
PaDeviceInfo *deviceInfo = &deviceInfoArray[i];
@@ -1191,7 +1211,7 @@
PA_DEBUG(("WASAPI: device idx: %02d\n", i));
PA_DEBUG(("WASAPI: ---------------\n"));
- hr = IMMDeviceCollection_Item(pEndPoints, i, &paWasapi->devInfo[i].device);
+ hr = IMMDeviceCollection_Item(pEndPoints, devIndex, &paWasapi->devInfo[i].device);
// We need to set the result to a value otherwise we will return paNoError
// [IF_FAILED_JUMP(hResult, error);]
IF_FAILED_INTERNAL_ERROR_JUMP(hr, result, error);
@@ -1373,6 +1393,41 @@
(*hostApi)->deviceInfos[i] = deviceInfo;
++(*hostApi)->info.deviceCount;
+
+ if (paWasapi->devInfo[i].flow == eRender)
+ {
+ char *deviceName;
+ UINT deviceNameLen;
+
+ memcpy(&deviceInfoArray[i + 1], deviceInfo, sizeof(*deviceInfo));
+ memcpy(&paWasapi->devInfo[i + 1], &paWasapi->devInfo[i], sizeof(*paWasapi->devInfo));
+
+ i++;
+ deviceInfo = &deviceInfoArray[i];
+
+ deviceInfo->maxInputChannels = deviceInfo->maxOutputChannels;
+ deviceInfo->defaultHighInputLatency = deviceInfo->defaultHighOutputLatency;
+ deviceInfo->defaultLowInputLatency = deviceInfo->defaultLowOutputLatency;
+ deviceInfo->maxOutputChannels = 0;
+ deviceInfo->defaultHighOutputLatency = 0;
+ deviceInfo->defaultLowOutputLatency = 0;
+ PA_DEBUG(("WASAPI:%d| def.SR[%d] max.CH[%d] latency{hi[%f] lo[%f]}\n", i, (UINT32)deviceInfo->defaultSampleRate,
+ deviceInfo->maxInputChannels, (float)deviceInfo->defaultHighInputLatency, (float)deviceInfo->defaultLowInputLatency));
+
+ IMMDevice_AddRef(paWasapi->devInfo[i].device);
+
+ deviceName = (char *)PaUtil_GroupAllocateMemory(paWasapi->allocations, MAX_STR_LEN + 1);
+ if (deviceName == NULL)
+ {
+ result = paInsufficientMemory;
+ goto error;
+ }
+ _snprintf(deviceName, MAX_STR_LEN-1, "%s (loopback)", deviceInfo->name);
+ deviceInfo->name = deviceName;
+
+ (*hostApi)->deviceInfos[i] = deviceInfo;
+ ++(*hostApi)->info.deviceCount;
+ }
}
}
@@ -2170,7 +2225,7 @@
}*/
// select mixer
- pSub->monoMixer = _GetMonoToStereoMixer(WaveToPaFormat(&pSub->wavex), (pInfo->flow == eRender ? MIX_DIR__1TO2 : MIX_DIR__2TO1_L));
+ pSub->monoMixer = _GetMonoToStereoMixer(WaveToPaFormat(&pSub->wavex), (output ? MIX_DIR__1TO2 : MIX_DIR__2TO1_L));
if (pSub->monoMixer == NULL)
{
(*pa_error) = paInvalidChannelCount;
@@ -2423,7 +2478,7 @@
}*/
// Select mixer
- pSub->monoMixer = _GetMonoToStereoMixer(WaveToPaFormat(&pSub->wavex), (pInfo->flow == eRender ? MIX_DIR__1TO2 : MIX_DIR__2TO1_L));
+ pSub->monoMixer = _GetMonoToStereoMixer(WaveToPaFormat(&pSub->wavex), (output ? MIX_DIR__1TO2 : MIX_DIR__2TO1_L));
if (pSub->monoMixer == NULL)
{
(*pa_error) = paInvalidChannelCount;
@@ -2728,6 +2786,9 @@
if (fullDuplex)
stream->in.streamFlags = 0; // polling interface is implemented for full-duplex mode also
+ if (info->flow == eRender)
+ stream->in.streamFlags |= AUDCLNT_STREAMFLAGS_LOOPBACK;
+
// Fill parameters for Audio Client creation
stream->in.params.device_info = info;
stream->in.params.stream_params = (*inputParameters);
@@ -3411,7 +3474,7 @@
// ------------------------------------------------------------------------------------------
static PaError IsStreamStopped( PaStream *s )
{
- return !((PaWasapiStream *)s)->running;
+ return ((PaWasapiStream *)s)->stopped;
}
// ------------------------------------------------------------------------------------------