exokitxr / exokit

Native VR/AR/XR engine for JavaScript 🦖
MIT License
994 stars 117 forks source link

Web Audio - AudioBuffer playbackRate setValueAtTime #678

Open sidequestlegend opened 5 years ago

sidequestlegend commented 5 years ago

Looks like the native audio is missing the playbackRate AudioParam property on the AudioBuffer source. It is used internally by THREE.Audio for starting playback and also setting the playback rate.

Here's a repro: node . https://seemly-decimal.glitch.me/ I did override the play method in THREE.Audio as a work around and removed the playbackRate line and it worked just fine which means this could just be an empty stub if we dont want implement playback rate right now.

THREE.Audio.prototype.play = function () {
    if ( this.isPlaying === true ) {
        console.warn( 'THREE.Audio: Audio is already playing.' );
        return;
    }
    if ( this.hasPlaybackControl === false ) {
        console.warn( 'THREE.Audio: this Audio has no playback control.' );
        return;
    }
    var source = this.context.createBufferSource();
    source.buffer = this.buffer;
    source.loop = this.loop;
    source.onended = this.onEnded.bind( this );

    //- commented out this line source.playbackRate.setValueAtTime( this.playbackRate, this.startTime );

    this.startTime = this.context.currentTime;
    source.start( this.startTime, this.offset );
    this.isPlaying = true;
    this.source = source;
    return this.connect();
}

More Info: https://github.com/mrdoob/three.js/blob/master/src/audio/Audio.js#L101

https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/playbackRate

TypeError: Cannot read property 'setValueAtTime' of undefined
    at PositionalAudio.play (https://aframe.io/releases/0.8.0/aframe.js:43857:24)
    at https://aframe.io/releases/0.8.0/aframe.js:70936:15
    at Array.forEach (<anonymous>)
    at NewComponent.playSound (https://aframe.io/releases/0.8.0/aframe.js:70934:24)
    at NewComponent.bound [as playSound] (https://aframe.io/releases/0.8.0/aframe.js:79999:17)
    at https://aframe.io/releases/0.8.0/aframe.js:70825:57
    at https://aframe.io/releases/0.8.0/aframe.js:43443:6
    at process.nextTick (C:\workspace\TheExpanse1\exokit\src\core.js:1920:17)
    at process._tickCallback (internal/process/next_tick.js:61:11)

On a separate positive note, the current audio is broken in aframe and three.js in that is is quite choppy or distorted or something, however this only affects the main stream browsers as the audio is perfectly smooth in exokit! Yay!

avaer commented 5 years ago

Apparently LabSound supports this; it's just not bound from the Exokit side.

sidequestlegend commented 5 years ago

A few more to add here - AudioBufferSourceNode.loop seems to be ignored

PannerNode.coneInnerAngle, PannerNode.coneOuterAngle, and PannerNode.coneOuterGain seem to prevent the audio playback.

I have updated the repro to add the loop property. Of the above the only one that's important to me ATM is the loop property.

avaer commented 5 years ago

AudioBuffer has longstanding bugs with loading/ending. I never tackled this myself, but see https://github.com/webmixedreality/exokit/issues/174 and the trail of issues.

Therefore adding loop is probably more than just adding a property, and an entirely different (known) issue.

avaer commented 5 years ago

There is also the detune property missing:

TypeError: Cannot read property 'setTargetAtTime' of undefined at ou.setPlaybackRate (/main.e61dc335221d7c8bd14b.bundle.js:2:1375999) at ou.play (/main.e61dc335221d7c8bd14b.bundle.js:2:1374375) at n.playSound (/main.e61dc335221d7c8bd14b.bundle.js:2:1704964) at n.setAccelerationInput (/main.e61dc335221d7c8bd14b.bundle.js:2:2544141) at HTMLElement.emit (events.js:188:13) at HTMLElement.EventEmitter.emit (domain.js:441:20) at HTMLElement._emit (/home/arpu/Downloads/exokit-linux-bin (1)/lib/exokit/src/Event.js:60:40) at _emit (/home/arpu/Downloads/exokit-linux-bin (1)/lib/exokit/src/Event.js:38:14) at _recurse (/home/arpu/Downloads/exokit-linux-bin (1)/lib/exokit/src/Event.js:46:7) at _recurse (/home/arpu/Downloads/exokit-linux-bin (1)/lib/exokit/src/Event.js:53:9)

avaer commented 5 years ago

The place to add these properties is about here: https://github.com/exokitxr/exokit/blob/master/deps/exokit-bindings/webaudiocontext/src/AudioBuffer.cpp#L190