WASAPIAudioOutputStream doesn't work correctly when requested buffer is larger than device period |
|||||||
Issue description1. Create PCM_LOW_LATENCY audio output stream on Windows with frames_per_buffer = sample_rate / 10 (100ms). 2. Observe that the stream never calls OnMoreData(). The problem is that WASAPIAudioOutputStream::RenderAudioFromSource() will not call OnMoreData() if endpoint_buffer_size_frames_ < packet_size_frames_. I think the correct behavior in that case would be to call OnMoreData() once and chop it into multiple smaller buffers. Alternatively, if this configuration is not supported then WASAPIAudioOutputStream should fail initialization.
,
Dec 7 2017
I believe it should be failing initialization if not configured for exclusive mode.
,
Dec 8 2017
Is exclusive mode used or not? AFAIK, only then will the buffer scheme not allow the condition in 1 [1]. But I might be missing something. You can also try out the WASAPIAudioOutputStreamTest unittest since it contains some tests with different buffersize in combination with exclusive mode. [2] FYI, exclusive has always been behind a flag and should be seen as experimental. [1] https://cs.chromium.org/chromium/src/media/audio/win/audio_low_latency_output_win.cc?sq=package:chromium&l=215 [2] https://cs.chromium.org/chromium/src/media/audio/win/audio_low_latency_output_win_unittest.cc?sq=package:chromium&l=451
,
Dec 8 2017
No, I see it in shared mode. WASAPIAudioOutputStream::RenderAudioFromSource() contains the following code
if (share_mode_ == AUDCLNT_SHAREMODE_SHARED) {
hr = audio_client_->GetCurrentPadding(&num_queued_frames);
num_available_frames =
endpoint_buffer_size_frames_ - num_queued_frames;
if (FAILED(hr)) { ... }
} else {
....
}
if (num_available_frames < packet_size_frames_)
return true;
When the stream is initialized with sample_rate=48kHz, frames_per_buffer=4800 I see endpoint_buffer_size_frames_=480, packet_size_frames_=4800. So when this function is called num_available_frames<=480 (I assume that it's always 480 because GetCurrentPadding() is expected to return 0, but I didn't verify it) and so num_available_frames<packet_size_frames_ condition is always true, i.e. RenderAudioFromSource() just returns without calling OnMoreData().
In exclusive mode this case is handled correctly: initialization fails because frames_per_buffer is different from device period. In shared mode initialization succeeds, but the stream doesn't render any sound.
You can reproduce it with AudioOutputTest.Play200HzTone test from patchset 3 in https://chromium-review.googlesource.com/c/chromium/src/+/809540. In patchset 4 I removed the line that sets frames_per_buffer, so the version I landed passes now.
,
Dec 11 2017
I am unable to provide comments on the exact details since it was long time since I worked with this particular code and much has probably changed since. Also, I don't have access to a Windows platform for development right now. Some more generic comments are that the low-latency WASAPI implementation was initially not written to be as flexible in terms of selection of buffer size and sample rate as the old Wave-based version. You could write tests like in #4 using PCM_LINEAR (<=> Wave implementation), but for PCM_LOW_LATENCY the selected sample rate was used and the buffer size is then given by https://cs.chromium.org/chromium/src/media/audio/win/core_audio_util_win.cc?q=GetPreferredAudioParameters&sq=package:chromium&l=750 and it was usually ~10ms (depending om sample rate). Dale then added sample rate conversion and extra buffer handling and FIFOs to deal with situations where the client needed other than e.g. 48k and 10ms. It is not clear to me what drives the need for being able to run a test like AudioOutputTest.Play200HzTone in Patchset #2 and why using the preferred buffer size is no longer sufficient.
,
Jan 2 2018
audio related bug, give to dale to start with.
,
Jan 8 2018
,
Jan 18 2018
Sorry for the noise, but is exclusive mode still a thing? I mean does the flag still works? Since quite some time ago I found passing the flag still resamples sounds of different sample rates to system default. Multiple tabs can also play sounds simultaneously which is not an exclusive thing, so I thought the flag is somehow deprecated or broken. Is it not the case? That you in fact changed the exclusive path to do resampling as well? Thank you in advance for replying so you don't get extra mail :)
,
Jan 18
(4 days ago)
This issue has been Available for over a year. If it's no longer important or seems unlikely to be fixed, please consider closing it out. If it is important, please re-triage the issue. Sorry for the inconvenience if the bug really should have been left as Available. For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
,
Jan 18
(4 days ago)
No current need to fix, so closing. |
|||||||
►
Sign in to add a comment |
|||||||
Comment 1 by mlamouri@chromium.org
, Dec 7 2017