WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch
bug-154538-20160225193212.patch (text/plain), 7.87 KB, created by
Jer Noble
on 2016-02-25 19:32:29 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Jer Noble
Created:
2016-02-25 19:32:29 PST
Size:
7.87 KB
patch
obsolete
>Subversion Revision: 196961 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 218b3e6e50b7060922c8607252662c20b6e82689..b99ef8d222eb89fec44e738bd90a8fadbb974a71 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,27 @@ >+2016-02-25 Jer Noble <jer.noble@apple.com> >+ >+ Web Audio becomes distorted after sample rate changes >+ https://bugs.webkit.org/show_bug.cgi?id=154538 >+ <rdar://problem/24771292> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ When the underlying audio hardware sample rate changes, the AudioUnit render callback will begin asking >+ for fewer or more frames. For example, when the sample rate goes from 44.1kHz to 48kHz, it will ask for >+ 118 samples instead of 128. (And vice-versa, 140 samples instead of 128.) But the Web Audio engine can only >+ really handle requests in multiples of 128 samples. In the case where there are requests for < 128 samples, >+ actually render 128, but save off the unrequested samples in a separate bus. Then fill that bus during the >+ next request. >+ >+ * platform/audio/AudioBus.cpp: >+ (WebCore::AudioBus::copyFromRange): Added utility method. >+ * platform/audio/AudioBus.h: >+ * platform/audio/ios/AudioDestinationIOS.cpp: >+ (WebCore::AudioDestinationIOS::AudioDestinationIOS): Create a "spare" bus. >+ (WebCore::assignAudioBuffersToBus): Moved from inside render. >+ (WebCore::AudioDestinationIOS::render): Save off extra samples to the "spare" bus. >+ * platform/audio/ios/AudioDestinationIOS.h: >+ > 2016-02-19 Jer Noble <jer.noble@apple.com> > > Adopt CachedRawResourceClient::shouldCacheResponse() in MediaResourceLoader and WebCoreNSURLSession >diff --git a/Source/WebCore/platform/audio/AudioBus.cpp b/Source/WebCore/platform/audio/AudioBus.cpp >index faa96170a8c410df8f2dc8e8caf48354760f3b4c..ec02ac48771f860384512e6e782fc2940b9ad6db 100644 >--- a/Source/WebCore/platform/audio/AudioBus.cpp >+++ b/Source/WebCore/platform/audio/AudioBus.cpp >@@ -213,6 +213,33 @@ void AudioBus::scale(float scale) > channel(i)->scale(scale); > } > >+void AudioBus::copyFromRange(const AudioBus& sourceBus, unsigned startFrame, unsigned endFrame) >+{ >+ if (!topologyMatches(sourceBus)) { >+ ASSERT_NOT_REACHED(); >+ zero(); >+ return; >+ } >+ >+ size_t numberOfSourceFrames = sourceBus.length(); >+ bool isRangeSafe = startFrame < endFrame && endFrame <= numberOfSourceFrames; >+ ASSERT(isRangeSafe); >+ if (!isRangeSafe) { >+ zero(); >+ return; >+ } >+ >+ unsigned numberOfChannels = this->numberOfChannels(); >+ ASSERT(numberOfChannels <= MaxBusChannels); >+ if (numberOfChannels > MaxBusChannels) { >+ zero(); >+ return; >+ } >+ >+ for (unsigned i = 0; i < numberOfChannels; ++i) >+ channel(i)->copyFromRange(sourceBus.channel(i), startFrame, endFrame); >+} >+ > void AudioBus::copyFrom(const AudioBus& sourceBus, ChannelInterpretation channelInterpretation) > { > if (&sourceBus == this) >diff --git a/Source/WebCore/platform/audio/AudioBus.h b/Source/WebCore/platform/audio/AudioBus.h >index 8d6839f012110dbfd7c0f501b7d0433e4340640e..4f9b5f55cc843f4ab87de355439f86d9786d16ea 100644 >--- a/Source/WebCore/platform/audio/AudioBus.h >+++ b/Source/WebCore/platform/audio/AudioBus.h >@@ -122,6 +122,9 @@ public: > void reset() { m_isFirstTime = true; } // for de-zippering > > // Copies the samples from the source bus to this one. >+ void copyFromRange(const AudioBus& sourceBus, unsigned startFrame, unsigned endFrame); >+ >+ // Copies the samples from the source bus to this one. > // This is just a simple per-channel copy if the number of channels match, otherwise an up-mix or down-mix is done. > void copyFrom(const AudioBus& sourceBus, ChannelInterpretation = Speakers); > >diff --git a/Source/WebCore/platform/audio/ios/AudioDestinationIOS.cpp b/Source/WebCore/platform/audio/ios/AudioDestinationIOS.cpp >index addb524f017a17ea91211235993220d8c9b1419c..76ce942f1ca632d4e9a6123904778a1ebe585552 100644 >--- a/Source/WebCore/platform/audio/ios/AudioDestinationIOS.cpp >+++ b/Source/WebCore/platform/audio/ios/AudioDestinationIOS.cpp >@@ -101,6 +101,7 @@ AudioDestinationIOS::AudioDestinationIOS(AudioIOCallback& callback, double sampl > : m_outputUnit(0) > , m_callback(callback) > , m_renderBus(AudioBus::create(2, kRenderBufferSize, false)) >+ , m_spareBus(AudioBus::create(2, kRenderBufferSize, true)) > , m_sampleRate(sampleRate) > , m_isPlaying(false) > { >@@ -199,19 +200,46 @@ void AudioDestinationIOS::stop() > setIsPlaying(false); > } > >+static void assignAudioBuffersToBus(AudioBuffer* buffers, AudioBus* bus, UInt32 numberOfBuffers, UInt32 numberOfFrames, UInt32 frameOffset, UInt32 framesThisTime) >+{ >+ for (UInt32 i = 0; i < numberOfBuffers; ++i) { >+ UInt32 bytesPerFrame = buffers[i].mDataByteSize / numberOfFrames; >+ UInt32 byteOffset = frameOffset * bytesPerFrame; >+ float* memory = (float*)((char*)buffers[i].mData + byteOffset); >+ bus->setChannelMemory(i, memory, framesThisTime); >+ } >+} >+ > // Pulls on our provider to get rendered audio stream. > OSStatus AudioDestinationIOS::render(UInt32 numberOfFrames, AudioBufferList* ioData) > { > AudioBuffer* buffers = ioData->mBuffers; >- for (UInt32 frameOffset = 0; frameOffset + kRenderBufferSize <= numberOfFrames; frameOffset += kRenderBufferSize) { >- UInt32 remainingFrames = std::min<UInt32>(kRenderBufferSize, numberOfFrames - frameOffset); >- for (UInt32 i = 0; i < ioData->mNumberBuffers; ++i) { >- UInt32 bytesPerFrame = buffers[i].mDataByteSize / numberOfFrames; >- UInt32 byteOffset = frameOffset * bytesPerFrame; >- float* memory = (float*)((char*)buffers[i].mData + byteOffset); >- m_renderBus->setChannelMemory(i, memory, remainingFrames); >+ UInt32 numberOfBuffers = ioData->mNumberBuffers; >+ UInt32 framesRemaining = numberOfFrames; >+ UInt32 frameOffset = 0; >+ while (framesRemaining > 0) { >+ if (m_firstSpareFrame && m_lastSpareFrame) { >+ ASSERT(m_firstSpareFrame < m_lastSpareFrame); >+ UInt32 framesThisTime = m_lastSpareFrame - m_firstSpareFrame; >+ assignAudioBuffersToBus(buffers, m_renderBus.get(), numberOfBuffers, numberOfFrames, frameOffset, framesThisTime); >+ m_renderBus->copyFromRange(*m_spareBus, m_firstSpareFrame, m_lastSpareFrame); >+ frameOffset += framesThisTime; >+ framesRemaining -= framesThisTime; >+ m_firstSpareFrame = m_lastSpareFrame = 0; > } >- m_callback.render(0, m_renderBus.get(), remainingFrames); >+ >+ UInt32 framesThisTime = std::min<UInt32>(kRenderBufferSize, framesRemaining); >+ assignAudioBuffersToBus(buffers, m_renderBus.get(), numberOfBuffers, numberOfFrames, frameOffset, framesThisTime); >+ >+ if (framesThisTime < kRenderBufferSize) { >+ m_callback.render(0, m_spareBus.get(), kRenderBufferSize); >+ m_renderBus->copyFromRange(*m_spareBus, 0, framesThisTime); >+ m_firstSpareFrame = framesThisTime; >+ m_lastSpareFrame = kRenderBufferSize - 1; >+ } else >+ m_callback.render(0, m_renderBus.get(), framesThisTime); >+ frameOffset += framesThisTime; >+ framesRemaining -= framesThisTime; > } > > return noErr; >diff --git a/Source/WebCore/platform/audio/ios/AudioDestinationIOS.h b/Source/WebCore/platform/audio/ios/AudioDestinationIOS.h >index 812487a33ff0a8c63aea4a0cc7d4789676cfe3a3..1a4598ecb375b11ba2ee11cb6a5ffa58c73ba705 100644 >--- a/Source/WebCore/platform/audio/ios/AudioDestinationIOS.h >+++ b/Source/WebCore/platform/audio/ios/AudioDestinationIOS.h >@@ -65,6 +65,9 @@ private: > AudioUnit m_outputUnit; > AudioIOCallback& m_callback; > RefPtr<AudioBus> m_renderBus; >+ RefPtr<AudioBus> m_spareBus; >+ unsigned m_firstSpareFrame { 0 }; >+ unsigned m_lastSpareFrame { 0 }; > > double m_sampleRate; > bool m_isPlaying;
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
darin
:
review+
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 154538
:
272270
| 272280