[webkit-changes] [WebKit/WebKit] 91ac45: Web audio rendering becomes garbled with switching...

Chris Dumez noreply at github.com
Tue Nov 15 14:59:01 PST 2022


  Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: 91ac45e95dc389df2d0ee9c5b3da6ac4f84d8d88
      https://github.com/WebKit/WebKit/commit/91ac45e95dc389df2d0ee9c5b3da6ac4f84d8d88
  Author: Chris Dumez <cdumez at apple.com>
  Date:   2022-11-15 (Tue, 15 Nov 2022)

  Changed paths:
    M Source/WebCore/platform/audio/mac/AudioSessionMac.h
    M Source/WebCore/platform/audio/mac/AudioSessionMac.mm

  Log Message:
  -----------
  Web audio rendering becomes garbled with switching from speakers to headphones (and vice-versa)
https://bugs.webkit.org/show_bug.cgi?id=241223
rdar://94721398

Reviewed by Jer Noble.

Web Audio requires a rendering quantum of 128. As a result,
MediaSessionManagerCocoa::updateSessionState() always requests a buffer size of
128 if WebAudio is in use, by calling AudioSession::setPreferredBufferSize().

When plugging in the headphones, I noticed that the rendering quantum became
480 instead of 128, which was the cause of the garbled Web Audio rendering.
updateSessionState() was however called when plugging in the headphones and
did try to set the buffer size of 128. However,
AudioSessionMac::setPreferredBufferSize() would return early because
m_bufferSize was already 128. The issue was that m_bufferSize was stale
and causing the call to setPreferredBufferSize(128) to be incorrectly ignored.

Normally, when we initialize m_bufferSize, we set a property listener so that
we can update our cached m_bufferSize whenever the corresponding property on
the audio device changes. However, our listener was set on a particular audio
device. When plugging in the headphone, the default audio device would change
and our listener would still listen for changes on the old device. As a result,
m_bufferSize would not get updated even though the audio device (and thus the
buffer size) would change.

To address the issue, I now register a default audio device listener so that
we get notified whenever the default audio device changes. When it changes,
we do the following:
1. Unregister the property listeners we had on the previous audio device
2. Register the property listeners (the one we had) on the new device
3. If we have cached property values, call the change handler for these
   properties so that our cached values get updated.

Even though the bug was caused by the buffer size not being updated, the
same issue applied to the sample rate and the muted state. I fixed all
3.

* Source/WebCore/platform/audio/mac/AudioSessionMac.h:
* Source/WebCore/platform/audio/mac/AudioSessionMac.mm:
(WebCore::defaultDeviceWithoutCaching):
(WebCore::defaultDeviceTransportIsBluetooth):
(WebCore::AudioSessionMac::removePropertyListenersForDefaultDevice const):
(WebCore::AudioSessionMac::handleDefaultDeviceChange):
(WebCore::AudioSessionMac::defaultOutputDeviceAddress):
(WebCore::AudioSessionMac::addDefaultDeviceObserverIfNeeded const):
(WebCore::AudioSessionMac::nominalSampleRateAddress):
(WebCore::AudioSessionMac::addSampleRateObserverIfNeeded const):
(WebCore::AudioSessionMac::handleSampleRateChange):
(WebCore::AudioSessionMac::handleSampleRateChange const):
(WebCore::AudioSessionMac::bufferSizeAddress):
(WebCore::AudioSessionMac::addBufferSizeObserverIfNeeded const):
(WebCore::AudioSessionMac::handleBufferSizeChange):
(WebCore::AudioSessionMac::handleBufferSizeChange const):
(WebCore::AudioSessionMac::sampleRate const):
(WebCore::AudioSessionMac::sampleRateWithoutCaching const):
(WebCore::AudioSessionMac::bufferSize const):
(WebCore::AudioSessionMac::bufferSizeWithoutCaching const):
(WebCore::AudioSessionMac::defaultDevice const):
(WebCore::AudioSessionMac::setPreferredBufferSize):
(WebCore::AudioSessionMac::muteAddress):
(WebCore::AudioSessionMac::addConfigurationChangeObserver):
(WebCore::AudioSessionMac::removeConfigurationChangeObserver):
(WebCore::AudioSessionMac::addMuteChangeObserverIfNeeded const):
(WebCore::AudioSessionMac::removeMuteChangeObserverIfNeeded const):
(WebCore::defaultDevice): Deleted.
* Source/WebKit/WebProcess/GPU/media/RemoteAudioDestinationProxy.cpp:
(WebKit::RemoteAudioDestinationProxy::connection):

Canonical link: https://commits.webkit.org/256712@main




More information about the webkit-changes mailing list