tone.js - no sound when hosted or on mobile preview.

  • so I started messing with tone.js. tonejs.github.io

    i have no idea what I am doing .. just thinking it would be cool to make somesynth in construct with tone.js

    I figured out I can drop tone.js into a script and start messing with the api.

    i put this basic synth together in a few minutes and it works perfect when previewing on desktop

    press the red boxes to make noise....

    drive.google.com/open

    (fyi warning if you click on the tone.js script file it can take about a minute to come to life. it will get there eventually your machine has not crashed.)

    but when hosted or when previewing on mobile there is no sound...

    yamaforce.com/ironpan/open/learntonejs

    is this some audio policy thing ? I tried adding in a construct audio object with a triggered imported audio to get over that but the tone.js synth still wouldn't play...

    anyone got any ideas....?

  • Check the console, when I try the hosted version, I get:

    The AudioContext was not allowed to start. It must be resumed (or created) after a user gesture on the page. goo.gl/7K7WLu

  • A hint here, but you need to tie that to a touch event, which I have not done yet directly in C3 (e.g. it will not work to have a C3 touch event trigger JS in my experience.

    I had a similar experience with requesting device orientation, but I made a ugly workaround which created a big button via JS that I deleted after pressed and device orientation requested (or in your case audio context resumed.)

    stackoverflow.com/questions/50281568/audiocontext-not-allowed-to-start-in-tonejs-chrome

    If you want to see that workaround, check out this: thread:

    construct.net/en/forum/construct-3/plugin-sdk-10/compass-north-sensor-c3-147808

    If you figure out an elegant way, I would be grateful to hear the details, so I could apply it to my device orientation case. Perhaps create a large screen overlay button w/ 1% opacity via JS then destroy it after touch?

  • Lastly, there is a hint in the Tone.js source code and what function to call with your button press / touch:

    ///////////////////////////////////////////////////////////////////////////

    // CONTEXT

    ///////////////////////////////////////////////////////////////////////////

    /**

    * The shared AudioContext

    * @type {Tone.Context}

    * @private

    */

    Tone._audioContext = null;

    /**

    * Most browsers will not play _any_ audio until a user

    * clicks something (like a play button). Invoke this method

    * on a click or keypress event handler to start the audio context.

    * More about the Autoplay policy [here](https://developers.google.com/web/updates/2017/09/autoplay-policy-changes#webaudio)

    * @memberOf Tone

    * @static

    * @return {Promise} This promise is resolved when the audio context is started.

    * @example

    * document.querySelector('#playbutton').addEventListener('click', () => Tone.start())

    */

    Tone.start = function(){

    return Tone.context.resume();

    };

  • Audio restrictions are quite irritating to work around, they were introduced to fight against those websites that autoplay music as soon as you open them. I vaguely recall another hack that existed the prevented tabs from going to background mode by using audio contexts as well, so that might have also been a consideration.

    But yeah easiest way is to have some sort of title screen, with a big "lets play" button or the like, and then create the context in that user gesture.

    Mikal the forum has formatting tools for JS, might make your comment a little more readable.

  • Cheers guys

    & Mikal appreciate that...

    you have confirmed my worst fears..... I cant just lazily use the tone.js api :(

    ...i am going to have to do some hard learning javascript ....

    once (if) I have figured out what to do I will post back.

  • Another gotcha is for touch input you can only start playback in a touch/pointer end/up event, not the start/down event. Basically if you start playback in the first touchend/pointerup/keydown event received, it should unblock audio playback and everything else will work normally after that.

    It's one of those slightly complicated things Construct normally takes care of for you, but you have to handle yourself in script.

  • Thanks to Ashley for pointing out Touch End vs Touch Start, which helped me in my orientation project too! Now I don't have to do that ugly hack.

    So I think you might just need a one time call based on Touch End and then do a simple JS call to: Tone.context.resume(); You can still be lazy :)

    This works for me on mobile:

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • Cheers Ashley cheers Mikal, thanks guys...

    I will check this out on the weekend, (up to my neck in it a work atm cant get no construct lovin' time in). if it works that will be awesome....

    If I get anywhere interesting with this node.js I will upload/post back.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)