Skip to content
Permalink
Browse files
Audio pitch changes on enabling / disabling the mic capture
https://bugs.webkit.org/show_bug.cgi?id=243651
rdar://problem/98655838

Reviewed by Eric Carlson.

When starting microphone capture, we stop the track remote IO unit and use the VPIO unit.
Previously we were stopping the remote IO unit when asking the VPIO unit to start.
The VPIO unit may take some time to start and audio to be rendered will start to be buffered.
We are getting rid of this buffering by speeding up a bit playback, leading to higher pitch.

To prevent this buffering, we are no longer stopping the remote IO unit when starting the VPIO unit.
Instead, we wait for the first speaker callback to ask the remote IO unit to stop after hopping to main thread.

* Source/WebCore/platform/mediastream/mac/BaseAudioSharedUnit.h:
* Source/WebCore/platform/mediastream/mac/CoreAudioSharedUnit.cpp:
(WebCore::CoreAudioSharedUnit::provideSpeakerData):
(WebCore::CoreAudioSharedUnit::startInternal):
* Source/WebCore/platform/mediastream/mac/CoreAudioSharedUnit.h:

Canonical link: https://commits.webkit.org/253673@main
  • Loading branch information
youennf committed Aug 23, 2022
1 parent 115d929 commit 65ae54bdedbb604855de7306576ed9572dd7bfe3
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 7 deletions.
@@ -42,7 +42,7 @@ class CaptureDevice;
class CoreAudioCaptureSource;
class PlatformAudioData;

class BaseAudioSharedUnit : public CanMakeWeakPtr<BaseAudioSharedUnit> {
class BaseAudioSharedUnit : public CanMakeWeakPtr<BaseAudioSharedUnit, WeakPtrFactoryInitialization::Eager> {
public:
BaseAudioSharedUnit();
virtual ~BaseAudioSharedUnit() = default;
@@ -391,7 +391,19 @@ void CoreAudioSharedUnit::checkTimestamps(const AudioTimeStamp& timeStamp, doubl

OSStatus CoreAudioSharedUnit::provideSpeakerData(AudioUnitRenderActionFlags& flags, const AudioTimeStamp& timeStamp, UInt32 /*inBusNumber*/, UInt32 inNumberFrames, AudioBufferList& ioData)
{
if (m_isReconfiguring || !m_speakerSamplesProducerLock.tryLock()) {
if (m_isReconfiguring || m_shouldNotifySpeakerSamplesProducer || !m_hasNotifiedSpeakerSamplesProducer || !m_speakerSamplesProducerLock.tryLock()) {
if (m_shouldNotifySpeakerSamplesProducer) {
m_shouldNotifySpeakerSamplesProducer = false;
callOnMainThread([this, weakThis = WeakPtr { *this }] {
if (!weakThis)
return;
m_hasNotifiedSpeakerSamplesProducer = true;
Locker locker { m_speakerSamplesProducerLock };
if (m_speakerSamplesProducer)
m_speakerSamplesProducer->captureUnitIsStarting();
});
}

AudioSampleBufferList::zeroABL(ioData, static_cast<size_t>(inNumberFrames * m_speakerProcFormat.bytesPerFrame()));
flags = kAudioUnitRenderAction_OutputIsSilence;
return noErr;
@@ -528,11 +540,8 @@ OSStatus CoreAudioSharedUnit::startInternal()

unduck();

{
Locker locker { m_speakerSamplesProducerLock };
if (m_speakerSamplesProducer)
m_speakerSamplesProducer->captureUnitIsStarting();
}
m_shouldNotifySpeakerSamplesProducer = true;
m_hasNotifiedSpeakerSamplesProducer = false;

if (auto err = m_ioUnit->start()) {
{
@@ -147,6 +147,8 @@ class CoreAudioSharedUnit final : public BaseAudioSharedUnit {

bool m_shouldUpdateMicrophoneSampleBufferSize { false };
bool m_isReconfiguring { false };
bool m_shouldNotifySpeakerSamplesProducer { false };
bool m_hasNotifiedSpeakerSamplesProducer { false };
mutable Lock m_speakerSamplesProducerLock;
CoreAudioSpeakerSamplesProducer* m_speakerSamplesProducer WTF_GUARDED_BY_LOCK(m_speakerSamplesProducerLock) { nullptr };
};

0 comments on commit 65ae54b

Please sign in to comment.