Title: [269108] trunk
Revision
269108
Author
[email protected]
Date
2020-10-28 10:40:03 -0700 (Wed, 28 Oct 2020)

Log Message

AudioBuffer channels should be neuterable / detachable
https://bugs.webkit.org/show_bug.cgi?id=218286

Reviewed by Eric Carlson.

LayoutTests/imported/w3c:

Rebaseline WPT test that is now passing. This test is also passing in Firefox. It is crashing in Blink.

* web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/transferred-buffer-output-expected.txt:

Source/WebCore:

AudioBuffer channels should be neuterable / detachable:
- https://webaudio.github.io/web-audio-api/#acquire-the-content

When the one of the channels' buffers gets detached/neutered, the array returned by
getChannelData(0) is neutered and thus has zero length. Internally though, if
channelData() gets called and ANY of the channels' buffers are detached, we return
a new empty array, as per the specification. This makes sure we end up with silence
on all channels when any of the channels gets detached, which is consistent with the
specification and Firefox (Blink seems to crash).

To make the AudioBuffer API less error-prone when used natively, I updated length()
and duration() to return 0 whenever any of the channels is detached. This is safer
since channelData() returns 0-length arrays in this case. The Web API keeps returning
the original values though so they rely on new originalLength() / originalDuration()
getters.

No new tests, rebaselined / updated existing tests.

* Modules/webaudio/AudioBuffer.cpp:
(WebCore::AudioBuffer::create):
(WebCore::AudioBuffer::AudioBuffer):
(WebCore::AudioBuffer::invalidate):
(WebCore::AudioBuffer::channelData):
(WebCore::AudioBuffer::zero):
(WebCore::AudioBuffer::hasDetachedChannelBuffer const):
* Modules/webaudio/AudioBuffer.h:
(WebCore::AudioBuffer::originalLength const):
(WebCore::AudioBuffer::originalDuration const):
(WebCore::AudioBuffer::length const):
(WebCore::AudioBuffer::duration const):
* Modules/webaudio/AudioBuffer.idl:
* Modules/webaudio/ConvolverNode.cpp:
(WebCore::ConvolverNode::setBuffer):
* Modules/webaudio/ScriptProcessorNode.cpp:
(WebCore::ScriptProcessorNode::initialize):

LayoutTests:

* webaudio/audiobuffer-neuter-expected.txt:
* webaudio/audiobuffer-neuter.html:
Extend layout test coverage. I have verified that this new version of the test is fully passing in
Gecko. In Blink, the initial checks all pass but it then crashes during rendering.

* webaudio/resources/audio-testing.js:
(createConstantBuffer):
Improve createConstantBuffer() so that it can construct buffers with multiple channels.

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (269107 => 269108)


--- trunk/LayoutTests/ChangeLog	2020-10-28 17:32:26 UTC (rev 269107)
+++ trunk/LayoutTests/ChangeLog	2020-10-28 17:40:03 UTC (rev 269108)
@@ -1,3 +1,19 @@
+2020-10-28  Chris Dumez  <[email protected]>
+
+        AudioBuffer channels should be neuterable / detachable
+        https://bugs.webkit.org/show_bug.cgi?id=218286
+
+        Reviewed by Eric Carlson.
+
+        * webaudio/audiobuffer-neuter-expected.txt:
+        * webaudio/audiobuffer-neuter.html:
+        Extend layout test coverage. I have verified that this new version of the test is fully passing in
+        Gecko. In Blink, the initial checks all pass but it then crashes during rendering.
+
+        * webaudio/resources/audio-testing.js:
+        (createConstantBuffer):
+        Improve createConstantBuffer() so that it can construct buffers with multiple channels.
+
 2020-10-28  Philippe Normand  <[email protected]>
 
         [GStreamer] Multi-channel (>2) support for the AudioFileReader

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (269107 => 269108)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2020-10-28 17:32:26 UTC (rev 269107)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2020-10-28 17:40:03 UTC (rev 269108)
@@ -1,3 +1,14 @@
+2020-10-28  Chris Dumez  <[email protected]>
+
+        AudioBuffer channels should be neuterable / detachable
+        https://bugs.webkit.org/show_bug.cgi?id=218286
+
+        Reviewed by Eric Carlson.
+
+        Rebaseline WPT test that is now passing. This test is also passing in Firefox. It is crashing in Blink.
+
+        * web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/transferred-buffer-output-expected.txt:
+
 2020-10-27  Chris Dumez  <[email protected]>
 
         AudioBuffer.getChannelData(x) should keep returning the same JS wrapper for a given channel

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/transferred-buffer-output-expected.txt (269107 => 269108)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/transferred-buffer-output-expected.txt	2020-10-28 17:32:26 UTC (rev 269107)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/transferred-buffer-output-expected.txt	2020-10-28 17:40:03 UTC (rev 269108)
@@ -3,20 +3,8 @@
 PASS Executing "Test Convolver with transferred buffer"
 PASS Audit report
 PASS > [Test Convolver with transferred buffer] Output should be all zeroes
-FAIL X Convolver channel 0 output[0:1279]: Expected 0 for all values but found 1280 unexpected values:
-	Index	Actual
-	[0]	1
-	[1]	2
-	[2]	3
-	[3]	4
-	...and 1276 more errors. assert_true: expected true got false
-FAIL X Convolver channel 1 output[0:1279]: Expected 0 for all values but found 1280 unexpected values:
-	Index	Actual
-	[0]	2
-	[1]	4
-	[2]	6
-	[3]	8
-	...and 1276 more errors. assert_true: expected true got false
-FAIL < [Test Convolver with transferred buffer] 2 out of 2 assertions were failed. assert_true: expected true got false
-FAIL # AUDIT TASK RUNNER FINISHED: 1 out of 1 tasks were failed. assert_true: expected true got false
+PASS   Convolver channel 0 output[0:1279] contains only the constant 0.
+PASS   Convolver channel 1 output[0:1279] contains only the constant 0.
+PASS < [Test Convolver with transferred buffer] All assertions passed. (total 2 assertions)
+PASS # AUDIT TASK RUNNER FINISHED: 1 tasks ran successfully.
 

Modified: trunk/LayoutTests/webaudio/audiobuffer-neuter-expected.txt (269107 => 269108)


--- trunk/LayoutTests/webaudio/audiobuffer-neuter-expected.txt	2020-10-28 17:32:26 UTC (rev 269107)
+++ trunk/LayoutTests/webaudio/audiobuffer-neuter-expected.txt	2020-10-28 17:40:03 UTC (rev 269108)
@@ -1,4 +1,11 @@
-Tests that neutered AudioBuffers do not produce garbage
+Tests that neutered AudioBuffers produce silence
+PASS sourceBuffer.length is numberOfFrames
+PASS sourceBuffer.getChannelData(0).length is 0
+PASS sourceBuffer.getChannelData(0) === sourceBuffer.getChannelData(0) is true
+PASS sourceBuffer.getChannelData(0) === originalFirstChannel is true
+PASS sourceBuffer.getChannelData(1).length is numberOfFrames
+PASS sourceBuffer.getChannelData(1) === sourceBuffer.getChannelData(1) is true
+PASS sourceBuffer.getChannelData(1) === originalSecondChannel is true
 PASS Output matches expectations.
 PASS successfullyParsed is true
 

Modified: trunk/LayoutTests/webaudio/audiobuffer-neuter.html (269107 => 269108)


--- trunk/LayoutTests/webaudio/audiobuffer-neuter.html	2020-10-28 17:32:26 UTC (rev 269107)
+++ trunk/LayoutTests/webaudio/audiobuffer-neuter.html	2020-10-28 17:40:03 UTC (rev 269108)
@@ -14,9 +14,11 @@
         {
             jsTestIsAsync = true;
 
-            var numberOfFrames = sampleRate * lengthInSeconds;
-            context = new OfflineAudioContext(1, numberOfFrames, sampleRate);
-            sourceBuffer = createConstantBuffer(context, numberOfFrames, 0.5);
+            numberOfFrames = sampleRate * lengthInSeconds;
+            context = new OfflineAudioContext(2, numberOfFrames, sampleRate);
+            sourceBuffer = createConstantBuffer(context, numberOfFrames, [0.5, 0.25]);
+            originalFirstChannel = sourceBuffer.getChannelData(0);
+            originalSecondChannel = sourceBuffer.getChannelData(1);
             var data = ""
 
             var string = [
@@ -32,6 +34,27 @@
             var worker = new Worker(blobURL);
             worker._onmessage_ = workerReply;
             worker.postMessage(data, [data]);
+
+            // The length of the AudioBuffer should be unchanged, even if some of its audio channels buffers
+            // have been detached.
+            shouldBe("sourceBuffer.length", "numberOfFrames");
+
+            // getChannelData() should return a 0-length array if the channel buffer has been detached.
+            shouldBe("sourceBuffer.getChannelData(0).length", "0");
+            shouldBeTrue("sourceBuffer.getChannelData(0) === sourceBuffer.getChannelData(0)");
+            shouldBeTrue("sourceBuffer.getChannelData(0) === originalFirstChannel");
+
+            // getChannelData() should return accurate channel data for non detached channels.
+            shouldBe("sourceBuffer.getChannelData(1).length", "numberOfFrames");
+            shouldBeTrue("sourceBuffer.getChannelData(1) === sourceBuffer.getChannelData(1)");
+            shouldBeTrue("sourceBuffer.getChannelData(1) === originalSecondChannel");
+            secondChannel = sourceBuffer.getChannelData(1);
+            for (var i = 0; i < numberOfFrames; ++i) {
+                if (secondChannel[i] != 0.25) {
+                    testFailed("Second channel contained unexpected value: " + secondChannel[i]);
+                    break;
+                }
+            }
         }
 
         function workerReply(event) {
@@ -46,15 +69,18 @@
         function finishTest(event) {
             var renderedBuffer = event.renderedBuffer;
             var numberOfFrames = sampleRate * lengthInSeconds;
-            var expectedBuffer = createConstantBuffer(context, numberOfFrames, 0.5);
+            // We expect silence on both channels.
+            var expectedBuffer = createConstantBuffer(context, numberOfFrames, [0, 0]);
 
-            var renderedData = renderedBuffer.getChannelData(0);
-            var expectedData = expectedBuffer.getChannelData(0);
+            for (let channelIndex = 0; channelIndex < 2; channelIndex++) {
+                var renderedData = renderedBuffer.getChannelData(channelIndex);
+                var expectedData = expectedBuffer.getChannelData(channelIndex);
 
-            for (var i = 0; i < numberOfFrames; ++i) {
-                if (expectedData[i] != renderedData[i]) {
-                    testFailed('expected: ' + expectedData[i] + ' actual: ' + renderedData[i]);
-                    finishJSTest();
+                for (var i = 0; i < numberOfFrames; ++i) {
+                    if (expectedData[i] != renderedData[i]) {
+                        testFailed('Channel ' + channelIndex + ' - expected: ' + expectedData[i] + ' actual: ' + renderedData[i]);
+                        finishJSTest();
+                    }
                 }
             }
 
@@ -65,7 +91,7 @@
     </script>
 </head>
 <body _onload_="runTest()">
-    <div>Tests that neutered AudioBuffers do not produce garbage</div>
+    <div>Tests that neutered AudioBuffers produce silence</div>
     <div id="console"></div>
 </body>
 

Modified: trunk/LayoutTests/webaudio/resources/audio-testing.js (269107 => 269108)


--- trunk/LayoutTests/webaudio/resources/audio-testing.js	2020-10-28 17:32:26 UTC (rev 269107)
+++ trunk/LayoutTests/webaudio/resources/audio-testing.js	2020-10-28 17:40:03 UTC (rev 269108)
@@ -129,13 +129,26 @@
 
 // Create a buffer of the given length having a constant value.
 function createConstantBuffer(context, sampleFrameLength, constantValue) {
-    var audioBuffer = context.createBuffer(1, sampleFrameLength, context.sampleRate);
-    var n = audioBuffer.length;
-    var dataL = audioBuffer.getChannelData(0);
+    let channels;
+    let values;
 
-    for (var i = 0; i < n; ++i)
-        dataL[i] = constantValue;
+    if (typeof constantValue === 'number') {
+        channels = 1;
+        values = [constantValue];
+    } else {
+        channels = constantValue.length;
+        values = constantValue;
+    }
 
+    let audioBuffer = context.createBuffer(channels, sampleFrameLength, context.sampleRate);
+    let n = audioBuffer.length;
+
+    for (let c = 0; c < channels; ++c) {
+        let data = ""
+        for (let i = 0; i < n; ++i)
+            data[i] = values[c];
+    }
+
     return audioBuffer;
 }
 

Modified: trunk/Source/WebCore/ChangeLog (269107 => 269108)


--- trunk/Source/WebCore/ChangeLog	2020-10-28 17:32:26 UTC (rev 269107)
+++ trunk/Source/WebCore/ChangeLog	2020-10-28 17:40:03 UTC (rev 269108)
@@ -1,3 +1,46 @@
+2020-10-28  Chris Dumez  <[email protected]>
+
+        AudioBuffer channels should be neuterable / detachable
+        https://bugs.webkit.org/show_bug.cgi?id=218286
+
+        Reviewed by Eric Carlson.
+
+        AudioBuffer channels should be neuterable / detachable:
+        - https://webaudio.github.io/web-audio-api/#acquire-the-content
+
+        When the one of the channels' buffers gets detached/neutered, the array returned by
+        getChannelData(0) is neutered and thus has zero length. Internally though, if
+        channelData() gets called and ANY of the channels' buffers are detached, we return
+        a new empty array, as per the specification. This makes sure we end up with silence
+        on all channels when any of the channels gets detached, which is consistent with the
+        specification and Firefox (Blink seems to crash).
+
+        To make the AudioBuffer API less error-prone when used natively, I updated length()
+        and duration() to return 0 whenever any of the channels is detached. This is safer
+        since channelData() returns 0-length arrays in this case. The Web API keeps returning
+        the original values though so they rely on new originalLength() / originalDuration()
+        getters.
+
+        No new tests, rebaselined / updated existing tests.
+
+        * Modules/webaudio/AudioBuffer.cpp:
+        (WebCore::AudioBuffer::create):
+        (WebCore::AudioBuffer::AudioBuffer):
+        (WebCore::AudioBuffer::invalidate):
+        (WebCore::AudioBuffer::channelData):
+        (WebCore::AudioBuffer::zero):
+        (WebCore::AudioBuffer::hasDetachedChannelBuffer const):
+        * Modules/webaudio/AudioBuffer.h:
+        (WebCore::AudioBuffer::originalLength const):
+        (WebCore::AudioBuffer::originalDuration const):
+        (WebCore::AudioBuffer::length const):
+        (WebCore::AudioBuffer::duration const):
+        * Modules/webaudio/AudioBuffer.idl:
+        * Modules/webaudio/ConvolverNode.cpp:
+        (WebCore::ConvolverNode::setBuffer):
+        * Modules/webaudio/ScriptProcessorNode.cpp:
+        (WebCore::ScriptProcessorNode::initialize):
+
 2020-10-28  Philippe Normand  <[email protected]>
 
         [GStreamer] Multi-channel (>2) support for the AudioFileReader

Modified: trunk/Source/WebCore/Modules/webaudio/AudioBuffer.cpp (269107 => 269108)


--- trunk/Source/WebCore/Modules/webaudio/AudioBuffer.cpp	2020-10-28 17:32:26 UTC (rev 269107)
+++ trunk/Source/WebCore/Modules/webaudio/AudioBuffer.cpp	2020-10-28 17:40:03 UTC (rev 269108)
@@ -40,13 +40,13 @@
 
 namespace WebCore {
 
-RefPtr<AudioBuffer> AudioBuffer::create(unsigned numberOfChannels, size_t numberOfFrames, float sampleRate)
+RefPtr<AudioBuffer> AudioBuffer::create(unsigned numberOfChannels, size_t numberOfFrames, float sampleRate, LegacyPreventNeutering preventNeutering)
 {
     if (!BaseAudioContext::isSupportedSampleRate(sampleRate) || !numberOfChannels || numberOfChannels > AudioContext::maxNumberOfChannels() || !numberOfFrames)
         return nullptr;
 
-    auto buffer = adoptRef(*new AudioBuffer(numberOfChannels, numberOfFrames, sampleRate));
-    if (!buffer->m_length)
+    auto buffer = adoptRef(*new AudioBuffer(numberOfChannels, numberOfFrames, sampleRate, preventNeutering));
+    if (!buffer->originalLength())
         return nullptr;
 
     return buffer;
@@ -67,7 +67,7 @@
         return Exception { NotSupportedError, "Sample rate is not in the supported range."_s };
     
     auto buffer = adoptRef(*new AudioBuffer(options.numberOfChannels, options.length, options.sampleRate));
-    if (!buffer->length())
+    if (!buffer->originalLength())
         return Exception { NotSupportedError, "Channel was not able to be created."_s };
     
     return buffer;
@@ -81,20 +81,22 @@
     return adoptRef(*new AudioBuffer(*bus));
 }
 
-AudioBuffer::AudioBuffer(unsigned numberOfChannels, size_t length, float sampleRate)
+AudioBuffer::AudioBuffer(unsigned numberOfChannels, size_t length, float sampleRate, LegacyPreventNeutering preventNeutering)
     : m_sampleRate(sampleRate)
-    , m_length(length)
+    , m_originalLength(length)
 {
     m_channels.reserveCapacity(numberOfChannels);
 
     for (unsigned i = 0; i < numberOfChannels; ++i) {
-        auto channelDataArray = Float32Array::tryCreate(m_length);
+        auto channelDataArray = Float32Array::tryCreate(m_originalLength);
         if (!channelDataArray) {
             invalidate();
             break;
         }
 
-        channelDataArray->setNeuterable(false);
+        if (preventNeutering == LegacyPreventNeutering::Yes)
+            channelDataArray->setNeuterable(false);
+
         m_channels.append(WTFMove(channelDataArray));
     }
     m_channelWrappers.resize(m_channels.size());
@@ -102,20 +104,19 @@
 
 AudioBuffer::AudioBuffer(AudioBus& bus)
     : m_sampleRate(bus.sampleRate())
-    , m_length(bus.length())
+    , m_originalLength(bus.length())
 {
     // Copy audio data from the bus to the Float32Arrays we manage.
     unsigned numberOfChannels = bus.numberOfChannels();
     m_channels.reserveCapacity(numberOfChannels);
     for (unsigned i = 0; i < numberOfChannels; ++i) {
-        auto channelDataArray = Float32Array::tryCreate(m_length);
+        auto channelDataArray = Float32Array::tryCreate(m_originalLength);
         if (!channelDataArray) {
             invalidate();
             break;
         }
 
-        channelDataArray->setNeuterable(false);
-        channelDataArray->setRange(bus.channel(i)->data(), m_length, 0);
+        channelDataArray->setRange(bus.channel(i)->data(), m_originalLength, 0);
         m_channels.append(WTFMove(channelDataArray));
     }
     m_channelWrappers.resize(m_channels.size());
@@ -124,7 +125,7 @@
 void AudioBuffer::invalidate()
 {
     releaseMemory();
-    m_length = 0;
+    m_originalLength = 0;
 }
 
 void AudioBuffer::releaseMemory()
@@ -159,11 +160,13 @@
         channelWrapper.visit(visitor);
 }
 
-Float32Array* AudioBuffer::channelData(unsigned channelIndex)
+RefPtr<Float32Array> AudioBuffer::channelData(unsigned channelIndex)
 {
     if (channelIndex >= m_channels.size())
         return nullptr;
-    return m_channels[channelIndex].get();
+    if (hasDetachedChannelBuffer())
+        return Float32Array::create(0);
+    return m_channels[channelIndex].copyRef();
 }
 
 ExceptionOr<void> AudioBuffer::copyFromChannel(Ref<Float32Array>&& destination, unsigned channelNumber, unsigned bufferOffset)
@@ -225,7 +228,7 @@
 void AudioBuffer::zero()
 {
     for (auto& channel : m_channels)
-        channel->zeroRange(0, length());
+        channel->zeroFill();
 }
 
 size_t AudioBuffer::memoryCost() const
@@ -242,6 +245,15 @@
     return cost;
 }
 
+bool AudioBuffer::hasDetachedChannelBuffer() const
+{
+    for (auto& channel : m_channels) {
+        if (channel->isNeutered())
+            return true;
+    }
+    return false;
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(WEB_AUDIO)

Modified: trunk/Source/WebCore/Modules/webaudio/AudioBuffer.h (269107 => 269108)


--- trunk/Source/WebCore/Modules/webaudio/AudioBuffer.h	2020-10-28 17:32:26 UTC (rev 269107)
+++ trunk/Source/WebCore/Modules/webaudio/AudioBuffer.h	2020-10-28 17:40:03 UTC (rev 269108)
@@ -41,23 +41,30 @@
 class AudioBus;
 
 class AudioBuffer : public RefCounted<AudioBuffer> {
-public:   
-    static RefPtr<AudioBuffer> create(unsigned numberOfChannels, size_t numberOfFrames, float sampleRate);
+public:
+    enum class LegacyPreventNeutering : bool { No, Yes };
+    static RefPtr<AudioBuffer> create(unsigned numberOfChannels, size_t numberOfFrames, float sampleRate, LegacyPreventNeutering = LegacyPreventNeutering::No);
     static ExceptionOr<Ref<AudioBuffer>> create(const AudioBufferOptions&);
     // Returns nullptr if data is not a valid audio file.
     static RefPtr<AudioBuffer> createFromAudioFileData(const void* data, size_t dataSize, bool mixToMono, float sampleRate);
 
     // Format
-    size_t length() const { return m_length; }
-    double duration() const { return length() / static_cast<double>(sampleRate()); }
+    size_t originalLength() const { return m_originalLength; }
+    double originalDuration() const { return originalLength() / static_cast<double>(sampleRate()); }
     float sampleRate() const { return m_sampleRate; }
 
+    // The following function may start returning 0 if any of the underlying channel buffers gets detached.
+    size_t length() const { return hasDetachedChannelBuffer() ? 0 : m_originalLength; }
+    double duration() const { return length() / static_cast<double>(sampleRate()); }
+
     // Channel data access
     unsigned numberOfChannels() const { return m_channels.size(); }
     ExceptionOr<JSC::JSValue> getChannelData(JSDOMGlobalObject&, unsigned channelIndex);
     ExceptionOr<void> copyFromChannel(Ref<Float32Array>&&, unsigned channelNumber, unsigned bufferOffset);
     ExceptionOr<void> copyToChannel(Ref<Float32Array>&&, unsigned channelNumber, unsigned startInChannel);
-    Float32Array* channelData(unsigned channelIndex);
+
+    // Native channel data access.
+    RefPtr<Float32Array> channelData(unsigned channelIndex);
     void zero();
 
     // Because an AudioBuffer has a _javascript_ wrapper, which will be garbage collected, it may take a while for this object to be deleted.
@@ -70,14 +77,16 @@
     void visitChannelWrappers(JSC::SlotVisitor&);
     
 private:
-    AudioBuffer(unsigned numberOfChannels, size_t length, float sampleRate);
+    AudioBuffer(unsigned numberOfChannels, size_t length, float sampleRate, LegacyPreventNeutering = LegacyPreventNeutering::No);
     explicit AudioBuffer(AudioBus&);
 
     void invalidate();
 
+    bool hasDetachedChannelBuffer() const;
+
     float m_sampleRate;
     mutable Lock m_channelsLock;
-    size_t m_length;
+    size_t m_originalLength;
     Vector<RefPtr<Float32Array>> m_channels;
     Vector<JSValueInWrappedObject> m_channelWrappers;
 };

Modified: trunk/Source/WebCore/Modules/webaudio/AudioBuffer.idl (269107 => 269108)


--- trunk/Source/WebCore/Modules/webaudio/AudioBuffer.idl	2020-10-28 17:32:26 UTC (rev 269107)
+++ trunk/Source/WebCore/Modules/webaudio/AudioBuffer.idl	2020-10-28 17:40:03 UTC (rev 269108)
@@ -35,8 +35,8 @@
     Exposed=Window
 ] interface AudioBuffer {
     [EnabledBySetting=ModernUnprefixedWebAudio] constructor(AudioBufferOptions options);
-    readonly attribute unsigned long length; // in sample-frames
-    readonly attribute double duration; // in seconds
+    [ImplementedAs=originalLength] readonly attribute unsigned long length; // in sample-frames
+    [ImplementedAs=originalDuration] readonly attribute double duration; // in seconds
     readonly attribute float sampleRate; // in sample-frames per second
     readonly attribute unsigned long numberOfChannels;
 

Modified: trunk/Source/WebCore/Modules/webaudio/ConvolverNode.cpp (269107 => 269108)


--- trunk/Source/WebCore/Modules/webaudio/ConvolverNode.cpp	2020-10-28 17:32:26 UTC (rev 269107)
+++ trunk/Source/WebCore/Modules/webaudio/ConvolverNode.cpp	2020-10-28 17:40:03 UTC (rev 269108)
@@ -130,9 +130,6 @@
     if (!isChannelCountGood)
         return Exception { NotSupportedError, "Buffer should have 1, 2 or 4 channels"_s };
 
-    if (!bufferLength)
-        return Exception { NotSupportedError, "Buffer length cannot be 0"_s };
-
     // Wrap the AudioBuffer by an AudioBus. It's an efficient pointer set and not a memcpy().
     // This memory is simply used in the Reverb constructor and no reference to it is kept for later use in that class.
     auto bufferBus = AudioBus::create(numberOfChannels, bufferLength, false);

Modified: trunk/Source/WebCore/Modules/webaudio/ScriptProcessorNode.cpp (269107 => 269108)


--- trunk/Source/WebCore/Modules/webaudio/ScriptProcessorNode.cpp	2020-10-28 17:32:26 UTC (rev 269107)
+++ trunk/Source/WebCore/Modules/webaudio/ScriptProcessorNode.cpp	2020-10-28 17:40:03 UTC (rev 269108)
@@ -90,8 +90,9 @@
     // Create double buffers on both the input and output sides.
     // These AudioBuffers will be directly accessed in the main thread by _javascript_.
     for (unsigned i = 0; i < 2; ++i) {
-        auto inputBuffer = m_numberOfInputChannels ? AudioBuffer::create(m_numberOfInputChannels, bufferSize(), sampleRate) : 0;
-        auto outputBuffer = m_numberOfOutputChannels ? AudioBuffer::create(m_numberOfOutputChannels, bufferSize(), sampleRate) : 0;
+        // We prevent neutering the AudioBuffers here since we pass those to JS and reuse them.
+        auto inputBuffer = m_numberOfInputChannels ? AudioBuffer::create(m_numberOfInputChannels, bufferSize(), sampleRate, AudioBuffer::LegacyPreventNeutering::Yes) : 0;
+        auto outputBuffer = m_numberOfOutputChannels ? AudioBuffer::create(m_numberOfOutputChannels, bufferSize(), sampleRate, AudioBuffer::LegacyPreventNeutering::Yes) : 0;
 
         m_inputBuffers.append(inputBuffer);
         m_outputBuffers.append(outputBuffer);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to