0
votes

I'm pretty new to the HTML5 audio api: I've read some of the related articles at HTML5 Rocks, but it can be a little tricky flipping between Javascript and Dart at times.

In any case, I've been experimenting with HTML5 Audio in Dart. To produce sound effects for a simple game, I created a class as follows. I created an AudioContext, loaded sound data into SoundBuffers, and when the sound needed to be played, created an AudioBufferSourceNode via which to play the data stored in the buffers:

class Sfx {
  AudioContext audioContext;
  List<Map> soundList;
  int soundFiles;

  Sfx() {
    audioContext = new AudioContext();
    soundList = new List<Map>();
    var soundsToLoad = [
      {"name": "MISSILE", "url": "SFX/missile.wav"},
      {"name": "EXPLOSION", "url": "SFX/explosion.wav"}
    ];
    soundFiles = soundsToLoad.length;

    for (Map sound in soundsToLoad) {
      initSound(sound);
    }
  }

  bool allSoundsLoaded() => (soundFiles == 0);

  void initSound(Map soundMap) {
    HttpRequest req = new HttpRequest();
    req.open('GET', soundMap["url"], true);
    req.responseType = 'arraybuffer';
    req.on.load.add((Event e) {
      audioContext.decodeAudioData(
        req.response,
        (var buffer) {
            // successful decode
            print("...${soundMap["name"]} loaded...");
            soundList.add({"name": soundMap["name"], "buffer": buffer});
            soundFiles--;
        },
        (var error) {
          print("error loading ${soundMap["name"]}");
        }
      );
    });
    req.send();
  }

  void sfx(AudioBuffer buffer) {
    AudioBufferSourceNode source = audioContext.createBufferSource();
    source.connect(audioContext.destination, 0, 0);
    source.buffer = buffer;
    source.start(0);
  }

  void playSound(String sound) {
    for (Map m in soundList) {
      print(m);
      if (m["name"] == sound) {
        sfx(m["buffer"]);
        break;
      }
    }
  }
}

(The sound effects are in a folder "SFX". Now that I look at the code, there are probably a million better ways to organise the data, but that's besides the point right now.) I am able to play sound effects by creating an instance of Sfx and calling the method playSound.

e.g.

#import('dart:html');

#source('sfx.dart');

Sfx sfx;
void main() {
  sfx = new Sfx();
  window.on.keyUp.add((KeyboardEvent keX) {
    sfx.playSound("MISSILE");
  });
}

(Edit: added code to play sound when a key is hit.)

The problem is: although with the dart2js Javascript, the sound effects play as expected in Safari, when they are played in Dartium or (with the dart2js Javascript) in Chrome, they are distorted. (In Firefox, there are even worse problems!)

Is there anything obvious that I have neglected to do or that I need to take into account? Otherwise, are there any references or tutorials, preferably in a Dart context, that might help?

1
The Dart team has a git repo where they are porting the HTML5 Rocks tutorials to Dart. One of them is a port of the Getting Started with the Web Audio API. Not sure if this is what you are after but it is here if you want to see how they are doing it.scribeGriff
Thanks! That sounds like a good starting point. I'll be sure to check it out.Richard Ambler
Just as an update: I took a look at the git repo linked above; the problem seems to lie with the audio file I was using: it was a 32 bit .wav whereas the sound in the example was 16 bit. When I saved my sound files as 16 bit .wav files, they played as expected in both Chrome and Safari...Richard Ambler
Great! I noticed they've rearranged their library a bit for pub so one of the links to the port has changed some. It is now here.scribeGriff

1 Answers

1
votes

thanks for trying Dart!

First off, Firefox doesn't support Web Audio API (yet?) Chrome and Safari support Web Audio API. You can track adoption of Web Audio API here: http://caniuse.com/#feat=audio-api

Second, please try this Web Audio API sample in Dartium: https://github.com/dart-lang/dart-html5-samples/tree/master/web/webaudio/intro You will need to clone the repo first and run it locally. This sample works for me locally.

This sounds more like a bug report. If the sample from dart-html5-samples works for you, but your above code continues to be distorted, please open a bug at http://dartbug.com/new so we can take a look.

One thing to consider is waiting until the specific MISSLE sound is loaded before hooking up the keyUp handler.