diff --git a/content/media/AudioNodeEngine.cpp b/content/media/AudioNodeEngine.cpp index 15bfcbceb6c..6d4f3f36e7b 100644 --- a/content/media/AudioNodeEngine.cpp +++ b/content/media/AudioNodeEngine.cpp @@ -56,9 +56,9 @@ AudioBlockAddChannelWithScale(const float aInput[WEBAUDIO_BLOCK_SIZE], } void -AudioBlockCopyChannelWithScale(const float aInput[WEBAUDIO_BLOCK_SIZE], +AudioBlockCopyChannelWithScale(const float* aInput, float aScale, - float aOutput[WEBAUDIO_BLOCK_SIZE]) + float* aOutput) { if (aScale == 1.0f) { memcpy(aOutput, aInput, WEBAUDIO_BLOCK_SIZE*sizeof(float)); diff --git a/content/media/AudioNodeEngine.h b/content/media/AudioNodeEngine.h index 768f5354d51..2e4eae0393a 100644 --- a/content/media/AudioNodeEngine.h +++ b/content/media/AudioNodeEngine.h @@ -100,10 +100,12 @@ void AudioBlockAddChannelWithScale(const float aInput[WEBAUDIO_BLOCK_SIZE], /** * Pointwise copy-scaled operation. aScale == 1.0f should be optimized. + * + * Buffer size is implicitly assumed to be WEBAUDIO_BLOCK_SIZE. */ -void AudioBlockCopyChannelWithScale(const float aInput[WEBAUDIO_BLOCK_SIZE], +void AudioBlockCopyChannelWithScale(const float* aInput, float aScale, - float aOutput[WEBAUDIO_BLOCK_SIZE]); + float* aOutput); /** * Vector copy-scaled operation. diff --git a/content/media/webaudio/DelayNode.cpp b/content/media/webaudio/DelayNode.cpp index 223f2002e71..4cc30dc2f4c 100644 --- a/content/media/webaudio/DelayNode.cpp +++ b/content/media/webaudio/DelayNode.cpp @@ -200,7 +200,7 @@ public: // Write the input sample to the correct location in our buffer if (input) { - buffer[writeIndex] = input[i]; + buffer[writeIndex] = input[i] * aInput.mVolume; } // Now, determine the correct read position. We adjust the read position to be diff --git a/content/media/webaudio/ScriptProcessorNode.cpp b/content/media/webaudio/ScriptProcessorNode.cpp index 33552bbcb83..1c85d8958af 100644 --- a/content/media/webaudio/ScriptProcessorNode.cpp +++ b/content/media/webaudio/ScriptProcessorNode.cpp @@ -201,9 +201,10 @@ public: aInput.GetDuration()); } else { mSeenNonSilenceInput = true; - PodCopy(mInputChannels[i] + mInputWriteIndex, - static_cast(aInput.mChannelData[i]), - aInput.GetDuration()); + MOZ_ASSERT(aInput.GetDuration() == WEBAUDIO_BLOCK_SIZE, "sanity check"); + AudioBlockCopyChannelWithScale(static_cast(aInput.mChannelData[i]), + aInput.mVolume, + mInputChannels[i] + mInputWriteIndex); } } mInputWriteIndex += aInput.GetDuration(); diff --git a/content/media/webaudio/test/Makefile.in b/content/media/webaudio/test/Makefile.in index 9dfb35a504a..5b192eb66fe 100644 --- a/content/media/webaudio/test/Makefile.in +++ b/content/media/webaudio/test/Makefile.in @@ -29,6 +29,7 @@ MOCHITEST_FILES := \ test_biquadFilterNode.html \ test_currentTime.html \ test_delayNode.html \ + test_delayNodeWithGain.html \ test_decodeAudioData.html \ test_dynamicsCompressorNode.html \ test_gainNode.html \ diff --git a/content/media/webaudio/test/test_delayNode.html b/content/media/webaudio/test/test_delayNode.html index 4f2139fca6f..736b007b814 100644 --- a/content/media/webaudio/test/test_delayNode.html +++ b/content/media/webaudio/test/test_delayNode.html @@ -19,6 +19,10 @@ addLoadEvent(function() { for (var i = 0; i < 2048; ++i) { buffer.getChannelData(0)[i] = Math.sin(440 * 2 * Math.PI * i / context.sampleRate); } + var expectedBuffer = context.createBuffer(1, 2048 * 2, context.sampleRate); + for (var i = 2048; i < 2048 * 2; ++i) { + expectedBuffer.getChannelData(0)[i] = buffer.getChannelData(0)[i - 2048]; + } var destination = context.destination; @@ -32,7 +36,9 @@ addLoadEvent(function() { source.buffer = buffer; source.connect(delay); - delay.connect(destination); + var sp = context.createScriptProcessor(2048 * 2, 1); + delay.connect(sp); + sp.connect(destination); ok(delay.delayTime, "The audioparam member must exist"); is(delay.delayTime.value, 0, "Correct initial value"); @@ -62,15 +68,19 @@ addLoadEvent(function() { }, DOMException.NOT_SUPPORTED_ERR); context.createDelay(1); // should not throw + // Delay the source stream by 2048 frames + delay.delayTime.value = 2048 / context.sampleRate; + source.start(0); - SimpleTest.executeSoon(function() { - source.stop(0); - source.disconnect(); - delay.disconnect(); + sp.onaudioprocess = function(e) { + is(e.inputBuffer.numberOfChannels, 1, "Correct input channel count"); + compareBuffers(e.inputBuffer.getChannelData(0), expectedBuffer.getChannelData(0)); + + sp.onaudioprocess = null; SpecialPowers.clearUserPref("media.webaudio.enabled"); SimpleTest.finish(); - }); + }; }); diff --git a/content/media/webaudio/test/test_delayNodeWithGain.html b/content/media/webaudio/test/test_delayNodeWithGain.html new file mode 100644 index 00000000000..9ae2a616639 --- /dev/null +++ b/content/media/webaudio/test/test_delayNodeWithGain.html @@ -0,0 +1,62 @@ + + + + Test DelayNode with a GainNode + + + + +
+
+
+
+ + diff --git a/content/media/webaudio/test/test_gainNode.html b/content/media/webaudio/test/test_gainNode.html index bdecacf6612..c772811ce11 100644 --- a/content/media/webaudio/test/test_gainNode.html +++ b/content/media/webaudio/test/test_gainNode.html @@ -3,6 +3,7 @@ Test GainNode + @@ -18,6 +19,10 @@ addLoadEvent(function() { for (var i = 0; i < 2048; ++i) { buffer.getChannelData(0)[i] = Math.sin(440 * 2 * Math.PI * i / context.sampleRate); } + var expectedBuffer = context.createBuffer(1, 2048, context.sampleRate); + for (var i = 0; i < 2048; ++i) { + expectedBuffer.getChannelData(0)[i] = buffer.getChannelData(0)[i] / 2; + } var destination = context.destination; @@ -31,7 +36,9 @@ addLoadEvent(function() { source.buffer = buffer; source.connect(gain); - gain.connect(destination); + var sp = context.createScriptProcessor(2048, 1); + gain.connect(sp); + sp.connect(destination); ok(gain.gain, "The audioparam member must exist"); is(gain.gain.value, 1.0, "Correct initial value"); @@ -41,14 +48,15 @@ addLoadEvent(function() { is(gain.gain.defaultValue, 1.0, "Correct default value"); source.start(0); - SimpleTest.executeSoon(function() { - source.stop(0); - source.disconnect(); - gain.disconnect(); + sp.onaudioprocess = function(e) { + is(e.inputBuffer.numberOfChannels, 1, "Correct input channel count"); + compareBuffers(e.inputBuffer.getChannelData(0), expectedBuffer.getChannelData(0)); + + sp.onaudioprocess = null; SpecialPowers.clearUserPref("media.webaudio.enabled"); SimpleTest.finish(); - }); + }; }); diff --git a/content/media/webaudio/test/webaudio.js b/content/media/webaudio/test/webaudio.js index 22c9b95f471..fb42a455b66 100644 --- a/content/media/webaudio/test/webaudio.js +++ b/content/media/webaudio/test/webaudio.js @@ -24,7 +24,7 @@ function expectTypeError(func) { } function fuzzyCompare(a, b) { - return Math.abs(a - b) < 1e-5; + return Math.abs(a - b) < 5e-5; } function compareBuffers(buf1, buf2,