New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 792629 link

Starred by 2 users

Issue metadata

Status: WontFix
Owner: ----
Closed: Jan 18
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Windows
Pri: 3
Type: Bug



Sign in to add a comment

WASAPIAudioOutputStream doesn't work correctly when requested buffer is larger than device period

Project Member Reported by sergeyu@chromium.org, Dec 6 2017

Issue description

1. 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.

 
Components: -Blink>Media>Audio Internals>Media>Audio
Cc: henrika@chromium.org
I believe it should be failing initialization if not configured for exclusive mode.
Cc: olka@chromium.org
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
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.
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.
Owner: dalecur...@chromium.org
Status: Assigned (was: Untriaged)
audio related bug, give to dale to start with.
Owner: ----
Status: Available (was: Assigned)
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 :)
Project Member

Comment 9 by sheriffbot@chromium.org, Jan 18 (4 days ago)

Labels: Hotlist-Recharge-Cold
Status: Untriaged (was: Available)
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

Comment 10 by dalecur...@chromium.org, Jan 18 (4 days ago)

Status: WontFix (was: Untriaged)
No current need to fix, so closing.

Sign in to add a comment