Closed
Bug 1472550
Opened 5 years ago
Closed 5 years ago
Using linearRampToValueAtTime() with PannerNode produces wrong spatial sound
Categories
(Core :: Web Audio, defect, P3)
Tracking
()
RESOLVED
FIXED
mozilla63
Tracking | Status | |
---|---|---|
firefox63 | --- | fixed |
People
(Reporter: michael.herzog, Assigned: padenot)
References
Details
Attachments
(5 files)
59 bytes,
text/x-review-board-request
|
karlt
:
review+
|
Details |
59 bytes,
text/x-review-board-request
|
dminor
:
review+
|
Details |
59 bytes,
text/x-review-board-request
|
karlt
:
review+
|
Details |
59 bytes,
text/x-review-board-request
|
karlt
:
review+
|
Details |
59 bytes,
text/x-review-board-request
|
jya
:
review+
|
Details |
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36 Steps to reproduce: - Go to: https://jsfiddle.net/4yefu08L/3/ - The example shows a dev version of three.js using linearRampToValueAtTime() in order to change the transformation of the PannerNode (see https://github.com/mrdoob/three.js/pull/14393). Actual results: When you move the camera, you hear wrong spatial ping-pong sounds in Firefox on macOS 10.13.5 and Firefox 61. For example, it does not matter how far or close the camera (listener) is to the ping-pong balls, the produces sound is always equal. When using Firefox 60 on Ubuntu 16.04, there is no spatiality at all. Expected results: When you move the camera, you should always hear correct spatial ping-pong sounds.
Reporter | ||
Comment 1•5 years ago
|
||
BTW: The demo does work in Firefox when using PannerNode.setPosition() and PannerNode.setOrientation().
Reporter | ||
Updated•5 years ago
|
Component: Untriaged → Web Audio
Product: Firefox → Core
Assignee | ||
Comment 2•5 years ago
|
||
I need to check if wpt has test for this, and update expectations, or just write one.
Comment hidden (mozreview-request) |
Assignee | ||
Updated•5 years ago
|
Assignee: nobody → padenot
Comment 4•5 years ago
|
||
mozreview-review |
Comment on attachment 8990039 [details] Bug 1472550 - Consistently apply the distance, input and cone gain on all channels when computing the effect of a PannerNode when its AudioParams have been set. https://reviewboard.mozilla.org/r/255066/#review262110 ::: dom/media/webaudio/PannerNode.cpp:611 (Diff revision 1) > distanceGain = ComputeDistanceGain(position); > > // Actually compute the left and right gain. > - float gainL = cos(0.5 * M_PI * normalizedAzimuth) * aInput.mVolume * distanceGain * coneGain; > - float gainR = sin(0.5 * M_PI * normalizedAzimuth) * aInput.mVolume * distanceGain * coneGain; > + float gainL = cos(0.5 * M_PI * normalizedAzimuth); > + float gainR = sin(0.5 * M_PI * normalizedAzimuth); > > alignedComputedGain[counter] = gainL; > alignedComputedGain[WEBAUDIO_BLOCK_SIZE + counter] = gainR; > onLeft[counter] = azimuth <= 0; > } > > - // Apply the gain to the output buffer > + // Apply the panning to the output buffer > ApplyStereoPanning(aInput, aOutput, alignedComputedGain, &alignedComputedGain[WEBAUDIO_BLOCK_SIZE], onLeft); > > + aOutput->mVolume = aInput.mVolume * distanceGain * coneGain; This is better than what was before for StereoToStereo, but it is making distance and cone gains some kind of k-rate. The distance and cone gains are calculated inside the block loop; they should be applied to each sample. MonoToStereo was good and a-rate, but k-rate would be a regression there. The current design would mean building up a gain array, or an array of inputs with the gain applied. The latter approach would have slightly better memory locality if the arrays of input with gain are modified in place to become the output. I haven't checked whether the SIMD functions would handle this appropriately. I wonder how much win there is from the AudioBlockPanStereoToStereo_NEON version with aIsOnTheLeft an array. https://bugzilla.mozilla.org/show_bug.cgi?id=1105513#c5 says 10-20ms change but gives no indication of total time. I wonder how much of that could be reclaimed by making a sample-wise version of AudioBlockPanStereoToStereo() inline. I would have expected the calculation to be faster if performed sample-by-sample than if building arrays of the parameters. With all the trigonometry and conditionals, it's hard to imagine how SIMD makes much difference for the simple algebra.
Attachment #8990039 -
Flags: review?(karlt)
Updated•5 years ago
|
Status: UNCONFIRMED → NEW
Rank: 25
Ever confirmed: true
Priority: -- → P3
Assignee | ||
Comment 5•5 years ago
|
||
Indeed this was incorrect. It's now fixed. I chose to simply make another array and implement a-rate in-place gain (with NEON and SSE variants). I had a look about testing. This is tested in Web platform tests, but the test itself requires AudioListener AudioParams, that we don't have right now. I'm going to write a simple regression test for this as a mochitest, to run on android and exercise the NEON code.
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment 10•5 years ago
|
||
mozreview-review |
Comment on attachment 8990383 [details] Bug 1472550 - Adjust a web platform test slightly to test that the parameter is a-rate. https://reviewboard.mozilla.org/r/255466/#review262416
Attachment #8990383 -
Flags: review?(karlt) → review+
Comment 11•5 years ago
|
||
mozreview-review |
Comment on attachment 8990384 [details] Bug 1472550 - Add a little regression test. https://reviewboard.mozilla.org/r/255468/#review262418
Attachment #8990384 -
Flags: review?(karlt) → review+
Comment 12•5 years ago
|
||
mozreview-review |
Comment on attachment 8990039 [details] Bug 1472550 - Consistently apply the distance, input and cone gain on all channels when computing the effect of a PannerNode when its AudioParams have been set. https://reviewboard.mozilla.org/r/255066/#review262444 ::: dom/media/webaudio/PannerNode.cpp:571 (Diff revision 2) > } else { > orientationZ[0] = mOrientationZ.GetValueAtTime(tick); > } > > + float computedPanning[2*WEBAUDIO_BLOCK_SIZE + 4]; > float computedGain[2*WEBAUDIO_BLOCK_SIZE + 4]; Only one block of of computedGain is used, and so this array can now be smaller. What would be most compact and clearest, I think would be something like float buffer[3*WEB_AUDIO_BLOCK_SIZE+4]; float* alignedPanL = ALIGNED16(buffer); float* alignedPanR = alignedPanL + WEBAUDIO_BLOCK_SIZE; float* alignedGain = alignedPanR + WEBAUDIO_BLOCK_SIZE; ASSERT_ALIGNED16...
Attachment #8990039 -
Flags: review?(karlt) → review+
Updated•5 years ago
|
Attachment #8990382 -
Flags: review?(karlt) → review?(dminor)
Comment 13•5 years ago
|
||
mozreview-review |
Comment on attachment 8990382 [details] Bug 1472550 - Add Audio{Buffer,Block}InPlaceScale that takes an array of gain values, with SSE and NEON variants. https://reviewboard.mozilla.org/r/255464/#review262446 Dan, would you be able to look at this part, please? I'm not so familiar with these.
Comment 14•5 years ago
|
||
mozreview-review |
Comment on attachment 8990382 [details] Bug 1472550 - Add Audio{Buffer,Block}InPlaceScale that takes an array of gain values, with SSE and NEON variants. https://reviewboard.mozilla.org/r/255464/#review262484 ::: dom/media/webaudio/AudioNodeEngineSSE2.cpp:161 (Diff revision 1) > + __m128 vout0, vout1, vout2, vout3, > + vgain0, vgain1, vgain2, vgain3, > + vin0, vin1, vin2, vin3; > + > + ASSERT_ALIGNED16(aBlock); > + ASSERT_MULTIPLE16(aSize); It seems strange to me that the NEON version works with values of aSize that are not a multiple of 16, but the SSE version doesn't. That could lead to surprises in the future. I think it would be best to make them consistent with each other, either by adding this assert to AudioBufferInPlaceScale and the NEON version or dealing with non-multiple of 16 values of aSize here.
Attachment #8990382 -
Flags: review?(dminor) → review+
Assignee | ||
Comment 15•5 years ago
|
||
(In reply to Dan Minor [:dminor] from comment #14) > It seems strange to me that the NEON version works with values of aSize that > are not a multiple of 16, but the SSE version doesn't. > > That could lead to surprises in the future. I think it would be best to make > them consistent with each other, either by adding this assert to > AudioBufferInPlaceScale and the NEON version or dealing with non-multiple of > 16 values of aSize here. I found it weird as well, but decided to copy the current style, and address it in a followup if we felt it was important.
Comment 16•5 years ago
|
||
Just writing down another possible option for this in case we ever want to come back to it, but no need to change things now that we have something working. EqualPowerPanningFunction() could calculate a matrix of gains to map inputs to outputs. For stereo to stereo, that would be four floats per sample instead of three floats and one bool. For mono to stereo, it would be two floats per sample. There would be more multiplications for stereo to stereo, but fewer conditional branches.
Assignee | ||
Comment 17•5 years ago
|
||
https://treeherder.mozilla.org/#/jobs?repo=try&revision=ebac7f8267596f29411b2f89321ef10d8f157b5b
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment 24•5 years ago
|
||
mozreview-review |
Comment on attachment 8991890 [details] Bug 1472550 - Update wpt expectations. https://reviewboard.mozilla.org/r/256806/#review263662
Attachment #8991890 -
Flags: review?(jyavenard) → review+
Comment 25•5 years ago
|
||
Pushed by paul@paul.cx: https://hg.mozilla.org/integration/autoland/rev/bed4190ce013 Add Audio{Buffer,Block}InPlaceScale that takes an array of gain values, with SSE and NEON variants. r=dminor https://hg.mozilla.org/integration/autoland/rev/ab307640537f Consistently apply the distance, input and cone gain on all channels when computing the effect of a PannerNode when its AudioParams have been set. r=karlt https://hg.mozilla.org/integration/autoland/rev/5b8172ac07f6 Adjust a web platform test slightly to test that the parameter is a-rate. r=karlt https://hg.mozilla.org/integration/autoland/rev/70b5a9fca55b Add a little regression test. r=karlt https://hg.mozilla.org/integration/autoland/rev/32557eba9675 Update wpt expectations. r=jya
Created web-platform-tests PR https://github.com/web-platform-tests/wpt/pull/11987 for changes under testing/web-platform/tests
Comment 27•5 years ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/bed4190ce013 https://hg.mozilla.org/mozilla-central/rev/ab307640537f https://hg.mozilla.org/mozilla-central/rev/5b8172ac07f6 https://hg.mozilla.org/mozilla-central/rev/70b5a9fca55b https://hg.mozilla.org/mozilla-central/rev/32557eba9675
Status: NEW → RESOLVED
Closed: 5 years ago
status-firefox63:
--- → fixed
Resolution: --- → FIXED
Target Milestone: --- → mozilla63
Reporter | ||
Comment 28•5 years ago
|
||
I can confirm the three.js demo works now fine with Firefox Nightly. Yay! Thanks for fixing this! :)
Assignee | ||
Comment 29•5 years ago
|
||
Thanks Michael, glad it is working well for three.js. I'm now looking at implementing the AudioParam for the AudioListener.
You need to log in
before you can comment on or make changes to this bug.
Description
•