hoch / canopy

Web Audio API programming/debugging suite
http://hoch.github.io/canopy/
MIT License
72 stars 7 forks source link

No waveform rendered when using async calls in code #89

Open chrislo opened 5 years ago

chrislo commented 5 years ago

When I type the following code in Canopy:

async function fetchData() {
  const response    = await fetch('https://www.webaudioweekly.com/audio/1.wav');
  const arrayBuffer = await response.arrayBuffer();
  const audioBuffer = await context.decodeAudioData(arrayBuffer);

  return audioBuffer;
};

fetchData().then((audioBuffer) => {
  const bufferSource = context.createBufferSource();

  bufferSource.buffer = audioBuffer;
  bufferSource.connect(context.destination);

  bufferSource.start();
});

and hit the run button, no audio is played and no waveform is rendered. If I define context = new AudioContext(); in a JavaScript developer console and run the same code, I hear the audio as expected. This problem occurs in both FF65 and Chrome 72 (tested on OS X).

Discussing this with @hoch and @rtoy in the web audio slack channel, we think that the wrapping function may not work with async calls.

@rtoy suggested one approach might be to have a function that needs explicity calling from user code to start the rendering.

haywirez commented 4 years ago

🤔 could be done by hacking var footer = `` to start rendering after some manual trigger event

https://github.com/hoch/canopy/blob/b2345f83014dc42c8af991f4f534adc67c909085/docs/spiral-elements/spiral-coder/code-renderer.js#L19

haywirez commented 4 years ago

This works in my fork:

    var footer = setting.async
      ? "\ncontext.renderAsync = () => context.startRendering().then(this._handleCompletion.bind(this));\n"
      : "\ncontext.startRendering().then(this._handleCompletion.bind(this));\n";
haywirez commented 4 years ago

I'm happy to make a pull request, just wondering what approach would be preferred.

hoch commented 4 years ago

The patch makes sense. I'll merge the PR if you can submit one. Thanks @haywirez!

haywirez commented 4 years ago

Still haven't got around to finalize the PR 😞 But my latest thinking is perhaps a quick check on the submitted code string (in editor text field) — if it contains a render() somewhere, then trigger the completion manually, otherwise call startRendering() at the end. Would be a better user experience as no explicit settings would be needed.