Diff
Modified: trunk/LayoutTests/ChangeLog (270154 => 270155)
--- trunk/LayoutTests/ChangeLog 2020-11-21 23:03:28 UTC (rev 270154)
+++ trunk/LayoutTests/ChangeLog 2020-11-22 03:03:46 UTC (rev 270155)
@@ -1,3 +1,16 @@
+2020-11-21 Chris Dumez <[email protected]>
+
+ Unreviewed, reverting r270141.
+
+ Caused assertions on bots
+
+ Reverted changeset:
+
+ "Poor resampling quality when using AudioContext sampleRate
+ parameter"
+ https://bugs.webkit.org/show_bug.cgi?id=219201
+ https://trac.webkit.org/changeset/270141
+
2020-11-21 Antti Koivisto <[email protected]>
[LFC][Integration] Remove ensureLineBoxes call from RenderedPosition constructor
Deleted: trunk/LayoutTests/webaudio/audiocontext-large-samplerate-expected.txt (270154 => 270155)
--- trunk/LayoutTests/webaudio/audiocontext-large-samplerate-expected.txt 2020-11-21 23:03:28 UTC (rev 270154)
+++ trunk/LayoutTests/webaudio/audiocontext-large-samplerate-expected.txt 2020-11-22 03:03:46 UTC (rev 270155)
@@ -1,11 +0,0 @@
-Tests that we do not crash when using a very large sample rate
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS context.sampleRate is 384000
-PASS context.state is "running"
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
Deleted: trunk/LayoutTests/webaudio/audiocontext-large-samplerate.html (270154 => 270155)
--- trunk/LayoutTests/webaudio/audiocontext-large-samplerate.html 2020-11-21 23:03:28 UTC (rev 270154)
+++ trunk/LayoutTests/webaudio/audiocontext-large-samplerate.html 2020-11-22 03:03:46 UTC (rev 270155)
@@ -1,22 +0,0 @@
-<!DOCTYPE html>
-<html>
-<script src=""
-<body>
-<script>
-description("Tests that we do not crash when using a very large sample rate");
-jsTestIsAsync = true;
-
-context = new AudioContext({ sampleRate: 384000 });
-shouldBe("context.sampleRate", "384000");
-
-node = new ConstantSourceNode(context, { offset: 0.5 });
-node.connect(context.destination);
-node.start();
-
-setTimeout(() => {
- shouldBeEqualToString("context.state", "running");
- finishJSTest();
-}, 100);
-</script>
-</body>
-</html>
Deleted: trunk/LayoutTests/webaudio/audiocontext-low-samplerate-expected.txt (270154 => 270155)
--- trunk/LayoutTests/webaudio/audiocontext-low-samplerate-expected.txt 2020-11-21 23:03:28 UTC (rev 270154)
+++ trunk/LayoutTests/webaudio/audiocontext-low-samplerate-expected.txt 2020-11-22 03:03:46 UTC (rev 270155)
@@ -1,11 +0,0 @@
-Tests that we do not crash when using a very low sample rate
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS context.sampleRate is 3000
-PASS context.state is "running"
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
Deleted: trunk/LayoutTests/webaudio/audiocontext-low-samplerate.html (270154 => 270155)
--- trunk/LayoutTests/webaudio/audiocontext-low-samplerate.html 2020-11-21 23:03:28 UTC (rev 270154)
+++ trunk/LayoutTests/webaudio/audiocontext-low-samplerate.html 2020-11-22 03:03:46 UTC (rev 270155)
@@ -1,22 +0,0 @@
-<!DOCTYPE html>
-<html>
-<script src=""
-<body>
-<script>
-description("Tests that we do not crash when using a very low sample rate");
-jsTestIsAsync = true;
-
-context = new AudioContext({ sampleRate: 3000 });
-shouldBe("context.sampleRate", "3000");
-
-node = new ConstantSourceNode(context, { offset: 0.5 });
-node.connect(context.destination);
-node.start();
-
-setTimeout(() => {
- shouldBeEqualToString("context.state", "running");
- finishJSTest();
-}, 100);
-</script>
-</body>
-</html>
Modified: trunk/Source/WebCore/ChangeLog (270154 => 270155)
--- trunk/Source/WebCore/ChangeLog 2020-11-21 23:03:28 UTC (rev 270154)
+++ trunk/Source/WebCore/ChangeLog 2020-11-22 03:03:46 UTC (rev 270155)
@@ -1,3 +1,16 @@
+2020-11-21 Chris Dumez <[email protected]>
+
+ Unreviewed, reverting r270141.
+
+ Caused assertions on bots
+
+ Reverted changeset:
+
+ "Poor resampling quality when using AudioContext sampleRate
+ parameter"
+ https://bugs.webkit.org/show_bug.cgi?id=219201
+ https://trac.webkit.org/changeset/270141
+
2020-11-21 Andres Gonzalez <[email protected]>
AccessibilityObject::FocusedUIElement should not call AXObjectCache::focusedUIElementForPage that can return an isolated object.
Modified: trunk/Source/WebCore/platform/audio/MultiChannelResampler.cpp (270154 => 270155)
--- trunk/Source/WebCore/platform/audio/MultiChannelResampler.cpp 2020-11-21 23:03:28 UTC (rev 270154)
+++ trunk/Source/WebCore/platform/audio/MultiChannelResampler.cpp 2020-11-22 03:03:46 UTC (rev 270155)
@@ -33,34 +33,30 @@
#include "MultiChannelResampler.h"
#include "AudioBus.h"
-#include "AudioUtilities.h"
namespace WebCore {
// ChannelProvider provides a single channel of audio data (one channel at a time) for each channel
// of data provided to us in a multi-channel provider.
-class MultiChannelResampler::ChannelProvider {
+class MultiChannelResampler::ChannelProvider : public AudioSourceProvider {
WTF_MAKE_FAST_ALLOCATED;
public:
explicit ChannelProvider(unsigned numberOfChannels)
- : m_multiChannelBus(AudioBus::create(numberOfChannels, AudioUtilities::renderQuantumSize))
+ : m_numberOfChannels(numberOfChannels)
{
}
void setProvider(AudioSourceProvider* multiChannelProvider)
{
+ m_currentChannel = 0;
+ m_framesToProcess = 0;
m_multiChannelProvider = multiChannelProvider;
}
// provideInput() will be called once for each channel, starting with the first channel.
// Each time it's called, it will provide the next channel of data.
- void provideInputForChannel(AudioBus* bus, size_t framesToProcess, unsigned channelIndex)
+ void provideInput(AudioBus* bus, size_t framesToProcess) override
{
- ASSERT(channelIndex < m_multiChannelBus->numberOfChannels());
- ASSERT(framesToProcess <= AudioUtilities::renderQuantumSize);
- if (framesToProcess > AudioUtilities::renderQuantumSize)
- return;
-
bool isBusGood = bus && bus->numberOfChannels() == 1;
ASSERT(isBusGood);
if (!isBusGood)
@@ -68,24 +64,31 @@
// Get the data from the multi-channel provider when the first channel asks for it.
// For subsequent channels, we can just dish out the channel data from that (stored in m_multiChannelBus).
- if (!channelIndex) {
+ if (!m_currentChannel) {
m_framesToProcess = framesToProcess;
+ m_multiChannelBus = AudioBus::create(m_numberOfChannels, framesToProcess);
m_multiChannelProvider->provideInput(m_multiChannelBus.get(), framesToProcess);
}
// All channels must ask for the same amount. This should always be the case, but let's just make sure.
- bool isGood = framesToProcess == m_framesToProcess;
+ bool isGood = m_multiChannelBus.get() && framesToProcess == m_framesToProcess;
ASSERT(isGood);
if (!isGood)
return;
// Copy the channel data from what we received from m_multiChannelProvider.
- memcpy(bus->channel(0)->mutableData(), m_multiChannelBus->channel(channelIndex)->data(), sizeof(float) * framesToProcess);
+ ASSERT(m_currentChannel <= m_numberOfChannels);
+ if (m_currentChannel < m_numberOfChannels) {
+ memcpy(bus->channel(0)->mutableData(), m_multiChannelBus->channel(m_currentChannel)->data(), sizeof(float) * framesToProcess);
+ ++m_currentChannel;
+ }
}
private:
AudioSourceProvider* m_multiChannelProvider { nullptr };
RefPtr<AudioBus> m_multiChannelBus;
+ unsigned m_numberOfChannels { 0 };
+ unsigned m_currentChannel { 0 };
size_t m_framesToProcess { 0 }; // Used to verify that all channels ask for the same amount.
};
@@ -109,25 +112,14 @@
// channelProvider wraps the original multi-channel provider and dishes out one channel at a time.
m_channelProvider->setProvider(provider);
- // We need to ensure that SincResampler only calls provideInput() once for each channel or it will confuse the logic
- // inside ChannelProvider. To ensure this, we chunk the number of requested frames into SincResampler::chunkSize()
- // sized chunks. SincResampler guarantees it will only call provideInput() once once we resample this way.
- m_outputFramesReady = 0;
- while (m_outputFramesReady < framesToProcess) {
- size_t chunkSize = m_kernels[0]->chunkSize();
- size_t framesThisTime = std::min(framesToProcess - m_outputFramesReady, chunkSize);
-
- for (unsigned channelIndex = 0; channelIndex < m_numberOfChannels; ++channelIndex) {
- ASSERT(chunkSize == m_kernels[channelIndex]->chunkSize());
- bool wasProvideInputCalled = false;
- m_kernels[channelIndex]->process(destination->channel(channelIndex)->mutableData() + m_outputFramesReady, framesThisTime, [this, channelIndex, &wasProvideInputCalled](AudioBus* bus, size_t framesToProcess) {
- ASSERT_WITH_MESSAGE(!wasProvideInputCalled, "provideInputForChannel should only be called once");
- wasProvideInputCalled = true;
- m_channelProvider->provideInputForChannel(bus, framesToProcess, channelIndex);
- });
- }
-
- m_outputFramesReady += framesThisTime;
+ for (unsigned channelIndex = 0; channelIndex < m_numberOfChannels; ++channelIndex) {
+ // Depending on the sample-rate scale factor, and the internal buffering used in a SincResampler
+ // kernel, this call to process() will only sometimes call provideInput() on the channelProvider.
+ // However, if it calls provideInput() for the first channel, then it will call it for the remaining
+ // channels, since they all buffer in the same way and are processing the same number of frames.
+ m_kernels[channelIndex]->process(m_channelProvider.get(),
+ destination->channel(channelIndex)->mutableData(),
+ framesToProcess);
}
m_channelProvider->setProvider(nullptr);
Modified: trunk/Source/WebCore/platform/audio/MultiChannelResampler.h (270154 => 270155)
--- trunk/Source/WebCore/platform/audio/MultiChannelResampler.h 2020-11-21 23:03:28 UTC (rev 270154)
+++ trunk/Source/WebCore/platform/audio/MultiChannelResampler.h 2020-11-22 03:03:46 UTC (rev 270155)
@@ -59,7 +59,6 @@
class ChannelProvider;
std::unique_ptr<ChannelProvider> m_channelProvider;
- size_t m_outputFramesReady { 0 };
};
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/audio/SincResampler.cpp (270154 => 270155)
--- trunk/Source/WebCore/platform/audio/SincResampler.cpp 2020-11-21 23:03:28 UTC (rev 270154)
+++ trunk/Source/WebCore/platform/audio/SincResampler.cpp 2020-11-22 03:03:46 UTC (rev 270155)
@@ -115,11 +115,6 @@
constexpr unsigned kernelSize { 32 };
constexpr unsigned numberOfKernelOffsets { 32 };
-static size_t calculateChunkSize(unsigned blockSize, double scaleFactor)
-{
- return blockSize / scaleFactor;
-}
-
SincResampler::SincResampler(double scaleFactor, Optional<unsigned> requestFrames)
: m_scaleFactor(scaleFactor)
, m_kernelStorage(kernelSize * (numberOfKernelOffsets + 1))
@@ -142,7 +137,6 @@
m_r3 = m_r0 + m_requestFrames - kernelSize;
m_r4 = m_r0 + m_requestFrames - kernelSize / 2;
m_blockSize = m_r4 - m_r2;
- m_chunkSize = calculateChunkSize(m_blockSize, m_scaleFactor);
// m_r1 at the beginning of the buffer.
ASSERT(m_r1 == m_inputBuffer.data());
@@ -193,10 +187,10 @@
}
}
-void SincResampler::consumeSource(float* buffer, unsigned numberOfSourceFrames, const Function<void(AudioBus* bus, size_t framesToProcess)>& provideInput)
+void SincResampler::consumeSource(float* buffer, unsigned numberOfSourceFrames)
{
- ASSERT(provideInput);
- if (!provideInput)
+ ASSERT(m_sourceProvider);
+ if (!m_sourceProvider)
return;
// Wrap the provided buffer by an AudioBus for use by the source provider.
@@ -206,14 +200,14 @@
// FIXME: Find a way to make the following const-correct:
m_internalBus->setChannelMemory(0, buffer, numberOfSourceFrames);
- provideInput(m_internalBus.get(), numberOfSourceFrames);
+ m_sourceProvider->provideInput(m_internalBus.get(), numberOfSourceFrames);
}
namespace {
-// BufferSourceProvider is an audio source provider wrapping an in-memory buffer.
+// BufferSourceProvider is an AudioSourceProvider wrapping an in-memory buffer.
-class BufferSourceProvider {
+class BufferSourceProvider : public AudioSourceProvider {
public:
explicit BufferSourceProvider(const float* source, size_t numberOfSourceFrames)
: m_source(source)
@@ -222,7 +216,7 @@
}
// Consumes samples from the in-memory buffer.
- void provideInput(AudioBus* bus, size_t framesToProcess)
+ void provideInput(AudioBus* bus, size_t framesToProcess) override
{
ASSERT(m_source && bus);
if (!m_source || !bus)
@@ -259,9 +253,7 @@
while (remaining) {
unsigned framesThisTime = std::min(remaining, m_requestFrames);
- process(destination, framesThisTime, [&sourceProvider](AudioBus* bus, size_t framesToProcess) {
- sourceProvider.provideInput(bus, framesToProcess);
- });
+ process(&sourceProvider, destination, framesThisTime);
destination += framesThisTime;
remaining -= framesThisTime;
@@ -268,11 +260,13 @@
}
}
-void SincResampler::process(float* destination, size_t framesToProcess, const Function<void(AudioBus* bus, size_t framesToProcess)>& provideInput)
+void SincResampler::process(AudioSourceProvider* sourceProvider, float* destination, size_t framesToProcess)
{
- ASSERT(provideInput);
- if (!provideInput)
+ ASSERT(sourceProvider);
+ if (!sourceProvider)
return;
+
+ m_sourceProvider = sourceProvider;
unsigned numberOfDestinationFrames = framesToProcess;
@@ -279,7 +273,7 @@
// Step (1)
// Prime the input buffer at the start of the input stream.
if (!m_isBufferPrimed) {
- consumeSource(m_r0, m_requestFrames, provideInput);
+ consumeSource(m_r0, m_requestFrames);
m_isBufferPrimed = true;
}
@@ -527,7 +521,7 @@
// Step (5)
// Refresh the buffer with more input.
- consumeSource(m_r0, m_requestFrames, provideInput);
+ consumeSource(m_r0, m_requestFrames);
}
}
Modified: trunk/Source/WebCore/platform/audio/SincResampler.h (270154 => 270155)
--- trunk/Source/WebCore/platform/audio/SincResampler.h 2020-11-21 23:03:28 UTC (rev 270154)
+++ trunk/Source/WebCore/platform/audio/SincResampler.h 2020-11-22 03:03:46 UTC (rev 270155)
@@ -45,17 +45,15 @@
// requestFrames controls the size in frames of the buffer requested by each provideInput() call.
SincResampler(double scaleFactor, Optional<unsigned> requestFrames = WTF::nullopt);
- size_t chunkSize() const { return m_chunkSize; }
-
// Processes numberOfSourceFrames from source to produce numberOfSourceFrames / scaleFactor frames in destination.
void process(const float* source, float* destination, unsigned numberOfSourceFrames);
- // Process with provideInput callback function for streaming applications.
- void process(float* destination, size_t framesToProcess, const Function<void(AudioBus* bus, size_t framesToProcess)>& provideInput);
+ // Process with input source callback function for streaming applications.
+ void process(AudioSourceProvider*, float* destination, size_t framesToProcess);
protected:
void initializeKernel();
- void consumeSource(float* buffer, unsigned numberOfSourceFrames, const Function<void(AudioBus* bus, size_t framesToProcess)>& provideInput);
+ void consumeSource(float* buffer, unsigned numberOfSourceFrames);
void updateRegions(bool isSecondLoad);
double m_scaleFactor;
@@ -74,8 +72,6 @@
// The number of source frames processed per pass.
unsigned m_blockSize { 0 };
- size_t m_chunkSize { 0 };
-
// Source is copied into this buffer for each processing pass.
AudioFloatArray m_inputBuffer;
@@ -89,6 +85,9 @@
const float* m_source { nullptr };
unsigned m_sourceFramesAvailable { 0 };
+
+ // m_sourceProvider is used to provide the audio input stream to the resampler.
+ AudioSourceProvider* m_sourceProvider { nullptr };
// The buffer is primed once at the very beginning of processing.
bool m_isBufferPrimed { false };