Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: 1774dbef65c9c409eb4a1c61b476033c6255e601
      
https://github.com/WebKit/WebKit/commit/1774dbef65c9c409eb4a1c61b476033c6255e601
  Author: Jer Noble <[email protected]>
  Date:   2026-04-03 (Fri, 03 Apr 2026)

  Changed paths:
    M LayoutTests/TestExpectations
    M 
LayoutTests/imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/preserves-pitch-expected.txt
    M LayoutTests/platform/glib/TestExpectations
    M Source/WebCore/Modules/webaudio/MediaElementAudioSourceNode.cpp
    M Source/WebCore/Modules/webaudio/MediaElementAudioSourceNode.h
    M Source/WebCore/PAL/pal/cf/AudioToolboxSoftLink.cpp
    M Source/WebCore/PAL/pal/cf/AudioToolboxSoftLink.h
    M Source/WebCore/SourcesCocoa.txt
    M Source/WebCore/WebCore.xcodeproj/project.pbxproj
    M Source/WebCore/html/HTMLMediaElement.cpp
    M Source/WebCore/platform/audio/cocoa/AudioSampleDataSource.mm
    M Source/WebCore/platform/audio/cocoa/CARingBuffer.cpp
    M Source/WebCore/platform/audio/cocoa/CARingBuffer.h
    A Source/WebCore/platform/audio/cocoa/PitchShiftAudioUnit.h
    A Source/WebCore/platform/audio/cocoa/PitchShiftAudioUnit.mm
    M Source/WebCore/platform/cocoa/NetworkExtensionContentFilter.mm
    M Source/WebCore/platform/cocoa/PowerSourceNotifier.h
    M Source/WebCore/platform/graphics/avfoundation/AudioSourceProviderAVFObjC.h
    M 
Source/WebCore/platform/graphics/avfoundation/AudioSourceProviderAVFObjC.mm
    M 
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h
    M 
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm
    M Source/WebCore/platform/mediastream/WebAudioSourceProvider.h
    M 
Source/WebCore/platform/mediastream/cocoa/MediaStreamTrackAudioSourceProviderCocoa.cpp
    M 
Source/WebCore/platform/mediastream/cocoa/MediaStreamTrackAudioSourceProviderCocoa.h
    M Source/WebCore/platform/mediastream/cocoa/WebAudioSourceProviderCocoa.h
    M Source/WebCore/platform/mediastream/cocoa/WebAudioSourceProviderCocoa.mm
    M Source/WebCore/platform/video-codecs/cocoa/WebRTCVideoDecoderVTB.mm
    M Source/WebKit/GPUProcess/media/RemoteAudioSourceProviderProxy.cpp
    M Source/WebKit/GPUProcess/media/RemoteAudioSourceProviderProxy.h
    M Source/WebKit/GPUProcess/media/RemoteMediaPlayerProxy.cpp
    M Source/WebKit/WebKit.xcodeproj/project.pbxproj
    M Source/WebKit/WebProcess/GPU/GPUProcessConnection.cpp
    M Source/WebKit/WebProcess/GPU/media/RemoteAudioSourceProvider.cpp
    M Source/WebKit/WebProcess/GPU/media/RemoteAudioSourceProvider.h
    M Source/WebKit/WebProcess/GPU/media/RemoteAudioSourceProviderManager.cpp
    M Source/WebKit/WebProcess/GPU/media/RemoteAudioSourceProviderManager.h
    M 
Source/WebKit/WebProcess/GPU/media/RemoteAudioSourceProviderManager.messages.in
    M Tools/TestWebKitAPI/SourcesCocoa.txt
    M Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
    A Tools/TestWebKitAPI/Tests/WebKitCocoa/PitchShiftAudioUnitTests.cpp

  Log Message:
  -----------
  HTMLMediaElement preservesPitch=true does not work when using AudioContext
rdar://173727365
https://bugs.webkit.org/show_bug.cgi?id=311000

Reviewed by Eric Carlson.

Add support for playing HTMLMediaElements at non-1x rates with 
`preservesPitch=true` through
MediaElementSourceNode. Due to the nature of AVAudioMix, this requires pitch 
correction to be
applied after the tap emits audio samples.

When an AVPlayer is configured to use "varispeed" and plays at a rate of (e.g.) 
2x, the tap will
emit 88,200 samples per second for content encoded at 44.1khz. This is 
essentially a sample rate
conversion, and the output can be converted by MultiChannelSampleRateConverter 
to 44.1khz, with the
side effect of pitch shifting upwards by (e.g., again) one octave. To 
counteract this pitch change
and simultaneously resample the content, a new class PitchShiftAudioNode is 
added, which wraps an
AudioUnit provided by CoreAudio. This new class operates very similarly to the
MultiChannelSampleRateConverter, insofar as it uses a callback to request more 
data from the
caller, then writes the output data to a AudioBus provided by the caller.

Two concrete classes were modified to incorporate this new PitchShiftAudioNode: 
AudioSourceProviderAVFObjC
and WebAudioSourceProviderCocoa. These two classes are now very similar, and 
are targets for merging
together in the future. The MultiChannelSampleRateConverter was removed from 
MediaElementSourceNode
and added to those same two classes, to handle the case where the connected 
audio element had
`preservesPitch=false`.

Both playbackRate and preservesPitch were piped through from the GPU process to 
the WebContent
process so that both ends of the audio provider could be configured correctly.

With this change, two subtests in 
imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/preserves-pitch.html
now pass.

Test: Tools/TestWebKitAPI/Tests/WebKitCocoa/PitchShiftAudioUnitTests.cpp

* LayoutTests/TestExpectations:
* 
LayoutTests/imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/preserves-pitch-expected.txt:
* Source/WebCore/Modules/webaudio/MediaElementAudioSourceNode.cpp:
(WebCore::MediaElementAudioSourceNode::MediaElementAudioSourceNode):
(WebCore::MediaElementAudioSourceNode::updateResamplerIfNeeded):
(WebCore::MediaElementAudioSourceNode::setPlaybackRate): Deleted.
* Source/WebCore/Modules/webaudio/MediaElementAudioSourceNode.h:
* Source/WebCore/PAL/pal/cf/AudioToolboxSoftLink.cpp:
* Source/WebCore/PAL/pal/cf/AudioToolboxSoftLink.h:
* Source/WebCore/SourcesCocoa.txt:
* Source/WebCore/WebCore.xcodeproj/project.pbxproj:
* Source/WebCore/html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::mediaPlayerRateChanged):
* Source/WebCore/platform/audio/cocoa/AudioSampleDataSource.mm:
(WebCore::AudioSampleDataSource::pullSamples):
(WebCore::AudioSampleDataSource::pullAvailableSamplesAsChunks):
* Source/WebCore/platform/audio/cocoa/CARingBuffer.cpp:
(WebCore::CARingBuffer::store):
* Source/WebCore/platform/audio/cocoa/CARingBuffer.h:
* Source/WebCore/platform/audio/cocoa/PitchShiftAudioUnit.h: Added.
(WebCore::PitchShiftAudioUnit::rate const):
(WebCore::PitchShiftAudioUnit::pitch const):
* Source/WebCore/platform/audio/cocoa/PitchShiftAudioUnit.mm: Added.
(WebCore::PitchShiftAudioUnit::PitchShiftAudioUnit):
(WebCore::PitchShiftAudioUnit::~PitchShiftAudioUnit):
(WebCore::PitchShiftAudioUnit::setRate):
(WebCore::PitchShiftAudioUnit::setPitch):
(WebCore::PitchShiftAudioUnit::setInputCallback):
(WebCore::PitchShiftAudioUnit::render):
(WebCore::PitchShiftAudioUnit::renderCallback):
* Source/WebCore/platform/cocoa/NetworkExtensionContentFilter.mm:
* Source/WebCore/platform/cocoa/PowerSourceNotifier.h:
* Source/WebCore/platform/graphics/avfoundation/AudioSourceProviderAVFObjC.h:
* Source/WebCore/platform/graphics/avfoundation/AudioSourceProviderAVFObjC.mm:
(WebCore::AudioSourceProviderAVFObjC::provideInput):
(WebCore::AudioSourceProviderAVFObjC::provideInputInternal):
(WebCore::AudioSourceProviderAVFObjC::setPlaybackRate):
(WebCore::AudioSourceProviderAVFObjC::setPreservesPitch):
(WebCore::AudioSourceProviderAVFObjC::prepare):
(WebCore::AudioSourceProviderAVFObjC::unprepare):
(WebCore::AudioSourceProviderAVFObjC::process):
* 
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h:
* 
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
(WebCore::MediaPlayerPrivateAVFoundationObjC::createAVPlayerItem):
(WebCore::MediaPlayerPrivateAVFoundationObjC::setPreservesPitch):
* 
Source/WebCore/platform/mediastream/cocoa/MediaStreamTrackAudioSourceProviderCocoa.cpp:
(WebCore::MediaStreamTrackAudioSourceProviderCocoa::audioSamplesAvailable):
* Source/WebCore/platform/mediastream/cocoa/WebAudioSourceProviderCocoa.h:
* Source/WebCore/platform/mediastream/cocoa/WebAudioSourceProviderCocoa.mm:
(WebCore::WebAudioSourceProviderCocoa::setClient):
(WebCore::WebAudioSourceProviderCocoa::setPlaybackRate):
(WebCore::WebAudioSourceProviderCocoa::setPreservesPitch):
(WebCore::WebAudioSourceProviderCocoa::audioStorageChanged):
(WebCore::WebAudioSourceProviderCocoa::provideInput):
(WebCore::WebAudioSourceProviderCocoa::provideInputInternal):
(WebCore::WebAudioSourceProviderCocoa::prepare):
(WebCore::WebAudioSourceProviderCocoa::receivedNewAudioSamples):
(WebCore::WebAudioSourceProviderCocoa::setNeedsFlush):
* Source/WebCore/platform/video-codecs/cocoa/WebRTCVideoDecoderVTB.mm:
* Source/WebKit/GPUProcess/media/RemoteAudioSourceProviderProxy.cpp:
(WebKit::RemoteAudioSourceProviderProxy::newAudioSamples):
(WebKit::RemoteAudioSourceProviderProxy::setPlaybackRate):
(WebKit::RemoteAudioSourceProviderProxy::setPreservesPitch):
* Source/WebKit/GPUProcess/media/RemoteAudioSourceProviderProxy.h:
* Source/WebKit/GPUProcess/media/RemoteMediaPlayerProxy.cpp:
(WebKit::RemoteMediaPlayerProxy::setPreservesPitch):
(WebKit::RemoteMediaPlayerProxy::mediaPlayerRateChanged):
(WebKit::RemoteMediaPlayerProxy::createAudioSourceProvider):
* Source/WebKit/WebKit.xcodeproj/project.pbxproj:
* Source/WebKit/WebProcess/GPU/GPUProcessConnection.cpp:
(WebKit::GPUProcessConnection::audioSourceProviderManager):
(WebKit::GPUProcessConnection::dispatchMessage):
* Source/WebKit/WebProcess/GPU/media/RemoteAudioSourceProvider.cpp:
(WebKit::RemoteAudioSourceProvider::audioSamplesAvailable):
* Source/WebKit/WebProcess/GPU/media/RemoteAudioSourceProvider.h:
* Source/WebKit/WebProcess/GPU/media/RemoteAudioSourceProviderManager.cpp:
(WebKit::RemoteAudioSourceProviderManager::RemoteAudioSourceProviderManager):
(WebKit::m_queue):
(WebKit::RemoteAudioSourceProviderManager::~RemoteAudioSourceProviderManager):
(WebKit::RemoteAudioSourceProviderManager::stopListeningForIPC):
(WebKit::RemoteAudioSourceProviderManager::addProvider):
(WebKit::RemoteAudioSourceProviderManager::removeProvider):
(WebKit::RemoteAudioSourceProviderManager::providerFor):
(WebKit::RemoteAudioSourceProviderManager::audioStorageChanged):
(WebKit::RemoteAudioSourceProviderManager::setNeedsFlush):
(WebKit::RemoteAudioSourceProviderManager::setPlaybackRate):
(WebKit::RemoteAudioSourceProviderManager::setPreservesPitch):
(WebKit::RemoteAudioSourceProviderManager::setConnection): Deleted.
(WebKit::RemoteAudioSourceProviderManager::audioSamplesAvailable): Deleted.
(WebKit::RemoteAudioSourceProviderManager::RemoteAudio::RemoteAudio): Deleted.
(WebKit::RemoteAudioSourceProviderManager::RemoteAudio::setStorage): Deleted.
(WebKit::RemoteAudioSourceProviderManager::RemoteAudio::audioSamplesAvailable): 
Deleted.
* Source/WebKit/WebProcess/GPU/media/RemoteAudioSourceProviderManager.h:
(WebKit::RemoteAudioSourceProviderManager::create):
* 
Source/WebKit/WebProcess/GPU/media/RemoteAudioSourceProviderManager.messages.in:
* Tools/TestWebKitAPI/Tests/WebKitCocoa/PitchShiftAudioUnitTests.cpp: Added.
(generateSineWave):
(countZeroCrossings):
(audioFormat):
(TEST(PitchShiftAudioUnit, BasicProcessing)):

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



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications

Reply via email to