Win32/WASAPI loopback: can not open stream at mono mode, paInvalidChannelCount
RightFS opened this issue · 19 comments
Describe the bug
Pa_OpenStream()
return paInvalidChannelCount
when open stream at mono mode on a loopback device, but Pa_IsFormatSupported()
report paFormatIsSupported
To Reproduce
Steps to reproduce the behavior. Include code if applicable.
// Open loopback device
int loopback = portaudio::getDefalutLoopback();
if (loopback < 0)
{
std::cout << "Error: No loopback device found" << std::endl;
return false;
}
int sampleRates[] = {8000, 16000, 32000, 44100, 48000};
PaStreamParameters loopbackParameters{};
loopbackParameters.channelCount = 1;
loopbackParameters.device = loopback;
loopbackParameters.sampleFormat = paInt16;
loopbackParameters.suggestedLatency = Pa_GetDeviceInfo(loopbackParameters.device)->defaultLowInputLatency;
loopbackParameters.hostApiSpecificStreamInfo = NULL;
for (int i = 0; i < 5; i++)
{
// Check if the format is supported
PaError err = Pa_IsFormatSupported(&loopbackParameters, NULL, sampleRates[i]);
if (err == paFormatIsSupported)
{
m_nloopbackSampleRate = sampleRates[i];
}
}
err = Pa_OpenStream(&loopbackStream, &loopbackParameters, NULL, m_nloopbackSampleRate, m_frame_size * 2, paClipOff, NULL, NULL);
if (err != paNoError)
{
qDebug() << "Error: sampleRate " << Pa_GetErrorText(err) << m_nloopbackSampleRate;
return false;
}
Desktop (please complete the following information):
- OS: windows 10 22h2
- PortAudio version: stable, nightly snapshot (which?), current (please give date and/or Git hash): current master branch
- If Windows or Linux, which Host API (e.g. WASAPI): WASAPI
@RightFS thank you for reporting the problem. It seems issue may be caused by some undefined behavior of WASAPI. The only place which can potentially return paInvalidChannelCount
in Pa_OpenStream()
is here (line 3342):
portaudio/src/hostapi/wasapi/pa_win_wasapi.c
Lines 3339 to 3345 in daaf637
This behavior is not reproducible on my machine, so your debugging help is needed to find the cause. Would you please put breakpoint on line 3339 and get value of pSub->wavexu.ext
for me.
@RightFS would you please have a look into the issue. It is not reproducible on my side, therefore your participation is needed as long as you can reproduce it on your side and help with debugging.
@dmitrykos do you have a Windows 10 22h2 instance for testing? If not I have it here.
I have Windows 10 Pro 22H2. The problem is not reproducible and probably could be caused by some process memory corruption on user side, so I think if reporter does not reply or assist with debugging this ticket needs to be closed as non reproducible/not confirmed.
Here is fully working example based on reporter's code which anyone can try:
#include <stdio.h>
#include <stdlib.h>
#include "portaudio.h"
#define FRAMES_PER_BUFFER (512)
int main(void)
{
PaError err = paNoError;
PaStream* loopbackStream;
int loopbackSampleRate = 0;
int loopbackDeviceIndex = -1;
PaDeviceInfo *loopbackDevice = NULL;
int sampleRates[] = {8000, 16000, 32000, 44100, 48000};
PaStreamParameters loopbackParameters = {0};
int i;
err = Pa_Initialize();
if (err != paNoError)
goto done;
for (i = Pa_GetDeviceCount() - 1; i >= 0; i--)
{
if ((loopbackDevice = Pa_GetDeviceInfo(i)) != NULL)
{
if (strstr(loopbackDevice->name, "[Loopback]") != NULL)
{
loopbackDeviceIndex = i;
break;
}
}
}
if ((loopbackDevice = Pa_GetDeviceInfo(loopbackDeviceIndex)) == NULL)
{
fprintf(stderr,"Error: Loopback device not found.\n");
goto done;
}
loopbackParameters.channelCount = 1;
loopbackParameters.device = loopbackDeviceIndex;
loopbackParameters.sampleFormat = paInt16;
loopbackParameters.suggestedLatency = Pa_GetDeviceInfo(loopbackParameters.device)->defaultLowInputLatency;
loopbackParameters.hostApiSpecificStreamInfo = NULL;
for (i = 0; i < 5; i++)
{
// Check if the format is supported
err = Pa_IsFormatSupported(&loopbackParameters, NULL, sampleRates[i]);
if (err == paFormatIsSupported)
{
loopbackSampleRate = sampleRates[i];
}
}
err = Pa_OpenStream(&loopbackStream, &loopbackParameters, NULL, loopbackSampleRate, FRAMES_PER_BUFFER, paClipOff, NULL, NULL);
if (err != paNoError)
{
fprintf(stderr,"Error: Failed opening a stream.\n");
goto done;
}
done:
Pa_Terminate();
return err;
}
I can reproduce this with PortAudio 18a606e on Windows 10 Home 22H2 19045.4529. Changed the above program slightly to add some diagnostic: https://gist.github.com/arkadijs/7027bf8aad399f3420406600c73df9e4
Specifying .channelCount = 2
allow Pa_OpenStream()
to succeed.
arkad@Lenovo3050 UCRT64 /c/Users/arkad/Documents/portaudio
$ ./loopback.exe
Device: Windows WDM-KS > Speakers (Nahimic mirroring Wave Speaker) rate:44100
Device: Windows WDM-KS > Headphones (Realtek HD Audio 2nd output) rate:44100
Device: Windows WDM-KS > Zestaw mikrofonów (Realtek HD Audio Mic Array input) rate:44100
Device: Windows WDM-KS > Miks stereo (Realtek HD Audio Stereo input) rate:48000
Device: Windows WDM-KS > Mikrofon (Realtek HD Audio Mic input) rate:44100
Device: Windows WDM-KS > Głośnik PC (Realtek HD Audio output with HAP) rate:44100
Device: Windows WDM-KS > Speakers 2 (Realtek HD Audio output with HAP) rate:44100
Device: Windows WDM-KS > Speakers 1 (Realtek HD Audio output with HAP) rate:48000
Device: Windows WASAPI > Głośniki (Realtek(R) Audio) [Loopback] rate:48000 <=======
Device: Windows WASAPI > Zestaw mikrofonów (Realtek(R) Audio) rate:48000
Device: Windows WASAPI > Głośniki (Realtek(R) Audio) rate:48000
Device: MME > Głośniki (Realtek(R) Audio) rate:44100
Device: MME > Microsoft Sound Mapper - Output rate:44100
Device: MME > Zestaw mikrofonów (Realtek(R) A rate:44100
Device: MME > Microsoft Sound Mapper - Input rate:44100
Error: Failed opening a stream: Invalid device
It's a Ryzen Lenovo laptop.
PortAudio built without DirectSound.
MSYS2 ucrt64 GCC 14.1.
@arkadijs tried your updated code but all is ok for me:
Device: Windows WASAPI > Speakers (Realtek(R) Audio) [Loopback] rate:48000 <=======
Device: Windows WASAPI > Microphone (Realtek(R) Audio) rate:44100
Device: Windows WASAPI > Speakers (Realtek(R) Audio) rate:48000
(process 1480) exited with code 0.
Could you please compile PA with PA_ENABLE_DEBUG_OUTPUT
defined, to see the place of the failure inside PA WASAPI. If you could debug execution by putting breakpoints to all places inside PA WASAPI code where paInvalidDevice
is thrown, it would be even better.
Here is a GDB session, full output https://0x0.st/XmYQ.txt
after paHostApiInitializers[2].
Device: Windows WDM-KS > Speakers (Nahimic mirroring Wave Speaker) rate:44100
Device: Windows WDM-KS > Headphones (Realtek HD Audio 2nd output) rate:44100
Device: Windows WDM-KS > Zestaw mikrofon├│w (Realtek HD Audio Mic Array input) rate:44100
Device: Windows WDM-KS > Miks stereo (Realtek HD Audio Stereo input) rate:48000
Device: Windows WDM-KS > Mikrofon (Realtek HD Audio Mic input) rate:44100
Device: Windows WDM-KS > G┼éo┼Ťnik PC (Realtek HD Audio output with HAP) rate:44100
Device: Windows WDM-KS > Speakers 2 (Realtek HD Audio output with HAP) rate:44100
Device: Windows WDM-KS > Speakers 1 (Realtek HD Audio output with HAP) rate:48000
Device: Windows WASAPI > G┼éo┼Ťniki (Realtek(R) Audio) [Loopback] rate:48000 <=======
Device: Windows WASAPI > Zestaw mikrofon├│w (Realtek(R) Audio) rate:48000
Device: Windows WASAPI > G┼éo┼Ťniki (Realtek(R) Audio) rate:48000
Device: MME > G┼éo┼Ťniki (Realtek(R) Audio) rate:44100
Device: MME > Microsoft Sound Mapper - Output rate:44100
Device: MME > Zestaw mikrofon├│w (Realtek(R) A rate:44100
Device: MME > Microsoft Sound Mapper - Input rate:44100
WASAPI: IAudioClient2 set properties: IsOffload = 0, Category = 0, Options = 0
Thread 1 hit Breakpoint 2, CreateAudioClient (pStream=0x8095e0, pSub=0x809750, output=0, pa_error=0x5ffbe4)
at C:/Users/arkad/Documents/portaudio/portaudio-master/src/hostapi/wasapi/pa_win_wasapi.c:3336
3336 if ((params->channelCount == 1) && (pSub->wavexu.ext.Format.nChannels == 2))
(gdb) n
3349 if ((pSub->shareMode != AUDCLNT_SHAREMODE_EXCLUSIVE) &&
(gdb) p params->channelCount
$3 = 1
(gdb) p pSub->wavexu.ext
$4 = {Format = {wFormatTag = 1, nChannels = 1, nSamplesPerSec = 48000, nAvgBytesPerSec = 96000, nBlockAlign = 2, wBitsPerSample = 16, cbSize = 0}, Samples = {wValidBitsPerSample = 0,
wSamplesPerBlock = 0, wReserved = 0}, dwChannelMask = 0, SubFormat = {Data1 = 0, Data2 = 0, Data3 = 0, Data4 = "\000\000\000\000\000\000\000"}}
(gdb) n
[New Thread 10552.0x2760]
3350 (!pSub->streamFlags || ((pSub->streamFlags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK) == 0)))
(gdb)
3349 if ((pSub->shareMode != AUDCLNT_SHAREMODE_EXCLUSIVE) &&
(gdb)
3350 (!pSub->streamFlags || ((pSub->streamFlags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK) == 0)))
(gdb)
3353 pSub->wavexu.ext.Format.nSamplesPerSec);
(gdb)
3352 framesPerLatency = _CalculateFramesPerHostBuffer(userFramesPerBuffer, params->suggestedLatency,
(gdb)
3381 if (output && fullDuplex)
(gdb)
3385 if (framesPerLatency == 0)
(gdb)
3390 if (!output && (pSub->shareMode == AUDCLNT_SHAREMODE_EXCLUSIVE))
(gdb)
3398 _CalculateAlignedPeriod(pSub, &framesPerLatency, ALIGN_BWD);
(gdb)
3403 if (pSub->shareMode == AUDCLNT_SHAREMODE_SHARED)
(gdb)
[New Thread 10552.0xd9c]
3405 if (pSub->period < pInfo->DefaultDevicePeriod)
(gdb)
3436 if (pSub->shareMode == AUDCLNT_SHAREMODE_EXCLUSIVE)
(gdb)
3469 _CalculatePeriodicity(pSub, output, &eventPeriodicity);
(gdb)
3472 hr = IAudioClient_Initialize(audioClient,
(gdb) s
[New Thread 10552.0x364]
warning: avcore\audiocore\client\audioclient\audioclientcore.cpp(1501)\AUDIOSES.DLL!00007FF94CC27915: (caller: 00007FF94CC04FA5) ReturnHr(1) tid(2c88) 887C0030
3483 if (output && SUCCEEDED(hr) && (pSub->shareMode == AUDCLNT_SHAREMODE_EXCLUSIVE))
(gdb) p hr
$5 = -2004287480
(gdb) p audioClient
$6 = (IAudioClient *) 0x806f10
(gdb) p *audioClient
$7 = {lpVtbl = 0x7ff94ccf0fb8}
(gdb) p *pSub
$8 = {clientParent = 0x0, clientStream = 0x0, clientProc = 0x0, wavexu = {ext = {Format = {wFormatTag = 1, nChannels = 1, nSamplesPerSec = 48000, nAvgBytesPerSec = 96000,
nBlockAlign = 2, wBitsPerSample = 16, cbSize = 0}, Samples = {wValidBitsPerSample = 0, wSamplesPerBlock = 0, wReserved = 0}, dwChannelMask = 0, SubFormat = {Data1 = 0, Data2 = 0,
Data3 = 0, Data4 = "\000\000\000\000\000\000\000"}}, iec61937 = {FormatExt = {Format = {wFormatTag = 1, nChannels = 1, nSamplesPerSec = 48000, nAvgBytesPerSec = 96000,
nBlockAlign = 2, wBitsPerSample = 16, cbSize = 0}, Samples = {wValidBitsPerSample = 0, wSamplesPerBlock = 0, wReserved = 0}, dwChannelMask = 0, SubFormat = {Data1 = 0,
Data2 = 0, Data3 = 0, Data4 = "\000\000\000\000\000\000\000"}}, dwEncodedSamplesPerSec = 0, dwEncodedChannelCount = 0, dwAverageBytesPerSec = 0}}, bufferSize = 0,
deviceLatency = 0, period = 213333, latencySeconds = 0, framesPerHostCallback = 0, shareMode = AUDCLNT_SHAREMODE_SHARED, streamFlags = 131072, flags = 0, params = {
device_info = 0x803840, stream_params = {device = 2, channelCount = 1, sampleFormat = 8, suggestedLatency = 0.0030000000000000001, hostApiSpecificStreamInfo = 0x0}, wasapi_params = {
size = 0, hostApiType = paInDevelopment, version = 0, flags = 0, channelMask = 0, hostProcessorOutput = 0x0, hostProcessorInput = 0x0, threadPriority = eThreadPriorityNone,
streamCategory = eAudioCategoryOther, streamOption = eStreamOptionNone, passthrough = {formatId = ePassthroughFormatPcmIec60958, encodedSamplesPerSec = 0, encodedChannelCount = 0,
averageBytesPerSec = 0}}, frames_per_buffer = 512, sample_rate = 48000, blocking = 1, full_duplex = 0, wow64_workaround = 0}, buffers = 0, framesPerBuffer = 0,
userBufferAndHostMatch = 0, monoBuffer = 0x0, monoBufferSize = 0, monoMixer = 0x0, tailBuffer = 0x0, tailBufferMemory = 0x0}
(gdb) p eventPeriodicity
$9 = 0
(gdb) n
3540 while ((hr == E_OUTOFMEMORY) && (pSub->period > (100 * 10000)))
(gdb)
3577 if ((hr == AUDCLNT_E_BUFFER_SIZE_ERROR) || (hr == AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED))
(gdb)
3609 if (FAILED(hr))
(gdb)
3611 (*pa_error) = paInvalidDevice;
(gdb)
Thread 1 hit Breakpoint 1, CreateAudioClient (pStream=0x8095e0, pSub=0x809750, output=0, pa_error=0x5ffbe4)
at C:/Users/arkad/Documents/portaudio/portaudio-master/src/hostapi/wasapi/pa_win_wasapi.c:3612
3612 LogHostError(hr);
(gdb) n
WASAPI ERROR HRESULT: 0x88890008 : AUDCLNT_E_UNSUPPORTED_FORMAT
[FUNCTION: CreateAudioClient FILE: C:/Users/arkad/Documents/portaudio/portaudio-master/src/hostapi/wasapi/pa_win_wasapi.c {LINE: 3612}]
3613 goto done;
Thank you for the log.
It seems WASAPI driver of your system is malfunctioning (has bug, surprisingly you also have Realtek(R) Audio
):
- it accepts Mono format by
IAudioClient_IsFormatSupported
inGetClosestFormat
- but later it fails in
CreateAudioClient
withIAudioClient_Initialize
Basically it is not PA's issue because IAudioClient_IsFormatSupported
must return closest supported format which guarantees that IAudioClient_Initialize
does not fail. Most probably there is buggy rare version of Realtek driver which is causing it because in most cases it is not a problem.
Could you please show the value of sharedClosestMatch
by setting breakpoint after line 2965 IAudioClient_IsFormatSupported
:
portaudio/src/hostapi/wasapi/pa_win_wasapi.c
Lines 2965 to 2968 in 2f61007
Thank you for the support. Looks like driver issue indeed. I was able to find a workaround though.
For the invalid device
run:
4 times the pointer is set
Thread 1 hit Breakpoint 1, GetClosestFormat (client=0x765050, sampleRate=8000, _params=0x5ffce0, shareMode=AUDCLNT_SHAREMODE_SHARED, outWavexU=0x5ffbe0, output=0)
at C:/Users/arkad/Documents/portaudio/portaudio-master/src/hostapi/wasapi/pa_win_wasapi.c:2965
2965 hr = IAudioClient_IsFormatSupported(client, shareMode, &outWavex->Format, (shareMode == AUDCLNT_SHAREMODE_SHARED ? &sharedClosestMatch : NULL));
(gdb) p sharedClosestMatch
$1 = (WAVEFORMATEX *) 0x0
(gdb) n
2968 if ((hr != S_OK) && (shareMode == AUDCLNT_SHAREMODE_EXCLUSIVE))
(gdb) p sharedClosestMatch
$2 = (WAVEFORMATEX *) 0x763940
(gdb) p *sharedClosestMatch
$3 = {wFormatTag = 65534, nChannels = 2, nSamplesPerSec = 48000, nAvgBytesPerSec = 384000, nBlockAlign = 8, wBitsPerSample = 32, cbSize = 22}
(gdb)
then 2 times sharedClosestMatch
is NULL
Thread 1 hit Breakpoint 1, GetClosestFormat (client=0x76adf0, sampleRate=48000, _params=0x76aaf0, shareMode=AUDCLNT_SHAREMODE_SHARED, outWavexU=0x76aa88, output=0)
at C:/Users/arkad/Documents/portaudio/portaudio-master/src/hostapi/wasapi/pa_win_wasapi.c:2965
2965 hr = IAudioClient_IsFormatSupported(client, shareMode, &outWavex->Format, (shareMode == AUDCLNT_SHAREMODE_SHARED ? &sharedClosestMatch : NULL));
(gdb) n
2968 if ((hr != S_OK) && (shareMode == AUDCLNT_SHAREMODE_EXCLUSIVE))
(gdb) p *sharedClosestMatch
Cannot access memory at address 0x0
(gdb) n
2975 if (hr == S_OK)
(gdb) c
Continuing.
warning: avcore\audiocore\client\audioclient\audioclientcore.cpp(1501)\AUDIOSES.DLL!00007FF94CC27915: (caller: 00007FF94CC04FA5) ReturnHr(1) tid(32d4) 887C0030
WASAPI ERROR HRESULT: 0x88890008 : AUDCLNT_E_UNSUPPORTED_FORMAT
[FUNCTION: CreateAudioClient FILE: C:/Users/arkad/Documents/portaudio/portaudio-master/src/hostapi/wasapi/pa_win_wasapi.c {LINE: 3612}]
WASAPI ERROR PAERROR: -9996 : Invalid device
[FUNCTION: ActivateAudioClient FILE: C:/Users/arkad/Documents/portaudio/portaudio-master/src/hostapi/wasapi/pa_win_wasapi.c {LINE: 3646}]
WASAPI ERROR PAERROR: -9996 : Invalid device
[FUNCTION: OpenStream FILE: C:/Users/arkad/Documents/portaudio/portaudio-master/src/hostapi/wasapi/pa_win_wasapi.c {LINE: 3850}]
G┼éo┼Ťniki (Realtek(R) Audio) [Loopback]: Invalid device
For the good run, sharedClosestMatch
is always set:
Thread 1 hit Breakpoint 1, GetClosestFormat (client=0x7a9450, sampleRate=48000, _params=0x7a9dd0, shareMode=AUDCLNT_SHAREMODE_SHARED, outWavexU=0x7a9d68, output=0)
at C:/Users/arkad/Documents/portaudio/portaudio-master/src/hostapi/wasapi/pa_win_wasapi.c:2965
2965 hr = IAudioClient_IsFormatSupported(client, shareMode, &outWavex->Format, (shareMode == AUDCLNT_SHAREMODE_SHARED ? &sharedClosestMatch : NULL));
(gdb) n
2968 if ((hr != S_OK) && (shareMode == AUDCLNT_SHAREMODE_EXCLUSIVE))
(gdb) p *sharedClosestMatch
$6 = {wFormatTag = 65534, nChannels = 2, nSamplesPerSec = 48000, nAvgBytesPerSec = 384000, nBlockAlign = 8, wBitsPerSample = 32, cbSize = 22}
(gdb) c
Continuing.
wFormatTag =WAVE_FORMAT_EXTENSIBLE
SubFormat =KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
Samples.wValidBitsPerSample =32
dwChannelMask =0x3
nChannels =2
nSamplesPerSec =48000
nAvgBytesPerSec=384000
nBlockAlign =8
wBitsPerSample =32
cbSize =22
WASAPI::OpenStream(input): framesPerUser[ 512 ] framesPerHost[ 1126 ] latency[ 23.46ms ] exclusive[ NO ] wow64_fix[ NO ] mode[ POLL ]
G┼éo┼Ťniki (Realtek(R) Audio) [Loopback]: success
Workaround
Open sound device properties and disable audio enhancements.
Speaker Properties / Additional device properties (to open classic UI) => Advanced => Signal Enhancements => Enable audio enhancements => uncheck.
This must be done per output, even if headphones are attached to the same chip.
FTR, Realtek driver 3/16/2021 6.0.9132.1; PCI id 10EC:0257.
Test program updated to try open all loopback devices.
Great catch!
My Realtek driver version: 19/10/2023, 10.0.19041.3636
. Your is older, so probably Realtek fixed it and thus I do not observe similar behavior. In my case Disable all enhancements
is unchecked but no effect was checked either. I tried activating effects (Bass Boost, Virtual Surround, Loudness Equalization) but it did not change anything - test code worked without an issue.
Microsoft docs specify the following:
For shared mode, if the audio engine supports the caller-specified format, IsFormatSupported sets *ppClosestMatch to NULL and returns S_OK. If the audio engine does not support the caller-specified format but does support a similar format, the method retrieves the similar format through the ppClosestMatch parameter and returns S_FALSE.
So, if hr
is S_OK
and sharedClosestMatch
is NULL then we can't do anything with that. There is another possibility for workaround though:
In shared mode, the audio engine always supports the mix format, which the client can obtain by calling the IAudioClient::GetMixFormat method.
Therefore, workaround could be as follows:
- If
params.channelCount
== 1 andsharedClosestMatch
== NULL andhr
== S_OK then get channel count obtained byIAudioClient::GetMixFormat
and if it is >1 setoutWavex->Format.nChannels
to 2
Shall I open PR for that and you would be able to test the proposed workaround?
I'll be able to test, thanks!
I'm going to send test survey to a few friends, some had this issue.
None of non-Realtek-sound Windows PCs I tried at home have this problem.
Tested the PR, works on my machine (regardless of audio enhancements options enabled or not). Thanks!
This Realtek driver is very odd. Capturing loopback of Speakers works any time. But capturing loopback of Headphones works only if some audio is played - callback not called otherwise, blocking API also doesn't work, changing default sound device makes no difference:
arkad@Lenovo3050 UCRT64 /c/Users/arkad/Documents/portaudio
$ ./loopback.exe
Device: MME > Microsoft Sound Mapper - Input rate:44100
Device: MME > Mikrofon (Realtek(R) Audio) rate:44100
Device: MME > Zestaw mikrofonów (Realtek(R) A rate:44100
Device: MME > Microsoft Sound Mapper - Output rate:44100
Device: MME > Słuchawki (Realtek(R) Audio) rate:44100
Device: MME > Głośniki (Realtek(R) Audio) rate:44100
Device: Windows WASAPI > Głośniki (Realtek(R) Audio) rate:48000
Device: Windows WASAPI > Słuchawki (Realtek(R) Audio) rate:48000
Device: Windows WASAPI > Mikrofon (Realtek(R) Audio) rate:48000
Device: Windows WASAPI > Zestaw mikrofonów (Realtek(R) Audio) rate:48000
Device: Windows WASAPI > Głośniki (Realtek(R) Audio) [Loopback] rate:48000 <=======
Device: Windows WASAPI > Słuchawki (Realtek(R) Audio) [Loopback] rate:48000 <=======
Device: Windows WDM-KS > Speakers 1 (Realtek HD Audio output with HAP) rate:48000
Device: Windows WDM-KS > Speakers 2 (Realtek HD Audio output with HAP) rate:44100
Device: Windows WDM-KS > Głośnik PC (Realtek HD Audio output with HAP) rate:44100
Device: Windows WDM-KS > Mikrofon (Realtek HD Audio Mic input) rate:44100
Device: Windows WDM-KS > Miks stereo (Realtek HD Audio Stereo input) rate:48000
Device: Windows WDM-KS > Zestaw mikrofonów (Realtek HD Audio Mic Array input) rate:44100
Device: Windows WDM-KS > Headphones (Realtek HD Audio 2nd output) rate:44100
Device: Windows WDM-KS > Output (AMD HD Audio HDMI out #0) rate:44100
Device: Windows WDM-KS > Speakers (Nahimic mirroring Wave Speaker) rate:44100
Głośniki (Realtek(R) Audio) [Loopback]: trying callback API...
Głośniki (Realtek(R) Audio) [Loopback]: pushed 512 frames
Głośniki (Realtek(R) Audio) [Loopback]: pushed 512 frames
Głośniki (Realtek(R) Audio) [Loopback]: pushed 512 frames
Głośniki (Realtek(R) Audio) [Loopback]: pushed 512 frames
Głośniki (Realtek(R) Audio) [Loopback]: pushed 512 frames
Głośniki (Realtek(R) Audio) [Loopback]: success
Głośniki (Realtek(R) Audio) [Loopback]: trying blocking API...
Głośniki (Realtek(R) Audio) [Loopback]: read 512 frames
Głośniki (Realtek(R) Audio) [Loopback]: read 512 frames
Głośniki (Realtek(R) Audio) [Loopback]: read 512 frames
Głośniki (Realtek(R) Audio) [Loopback]: read 512 frames
Głośniki (Realtek(R) Audio) [Loopback]: read 512 frames
Głośniki (Realtek(R) Audio) [Loopback]: success
Słuchawki (Realtek(R) Audio) [Loopback]: trying callback API...
Słuchawki (Realtek(R) Audio) [Loopback]: no frames pushed
Słuchawki (Realtek(R) Audio) [Loopback]: trying blocking API...
Słuchawki (Realtek(R) Audio) [Loopback]: read 512 frames <=== unpaused player here
Słuchawki (Realtek(R) Audio) [Loopback]: read 512 frames
Słuchawki (Realtek(R) Audio) [Loopback]: read 512 frames
Słuchawki (Realtek(R) Audio) [Loopback]: read 512 frames
Słuchawki (Realtek(R) Audio) [Loopback]: read 512 frames
Słuchawki (Realtek(R) Audio) [Loopback]: success
Updated sample program here.
Realter driver updated to 7/28/2022 6.0.9389.1 which is latest from Lenovo for this machine.
This Realtek driver is very odd.
What strikes me as especially odd is that WASAPI Loopback is an internal feature of the Windows Audio Engine itself that should have nothing to do with the driver - AFAIK the loopback occurs in audiosrv/audiodg, before the driver even gets involved. I find it surprising that the driver would be a factor in any of this.
This Realtek driver is very odd. Capturing loopback of Speakers works any time. But capturing loopback of Headphones works only if some audio is played - callback not called otherwise, blocking API also doesn't work, changing default sound device makes no difference.
I have also encountered this problem when I use PortAudio capturing loopback for echo cancellation. I have to fill some muted data manually to my buffer by timeline for the alignment between playback out and micphone in. It's too weird...It was supposed to provide a continuous audio stream.
But I've left that job, so I didn't have my test environment ...
Tested the PR, works on my machine (regardless of audio enhancements options enabled or not). Thanks!
@arkadijs Thank you very much for testing and confirming!
I propose to create new issue for capturing loopback of Headphones
to avoid mixing 2 issues in this issue as this one will be closed after PR #934 is approved. Would you please create new issue and re-post there your test code and log, so we could continue there.