Title: [270155] trunk

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 };
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to