sound.dart 4.65 KB
Newer Older
1
part of flutter_sprites;
2

3
/// An audio asset loaded by the SoundEffectPlayer.
4
class SoundEffect {
5
  SoundEffect(this._soundId);
6

7
  int _soundId;
8 9
}

10
/// A sound being played by the SoundEffectPlayer.
11
class SoundEffectStream {
12 13 14 15 16 17 18 19 20 21 22 23
  SoundEffectStream(SoundEffectPlayer player, int streamId, {
    double leftVolume,
    double rightVolume,
    double pitch
  }) {
    _player = player;
    _streamId = streamId;
    _paused = false;
    _leftVolume = leftVolume;
    _rightVolume = rightVolume;
    _pitch = pitch;
  }
24

25 26
  SoundEffectPlayer _player;
  int _streamId;
27

28
  SoundPoolProxy get _soundPool => _player._soundPool;
29

30 31 32
  void stop() {
    _soundPool.ptr.stop(_streamId);
  }
33

34 35 36 37 38 39 40 41
  bool get paused => _paused;
  bool _paused;
  void set paused(bool value) {
    _paused = value;
    if (_paused) {
      _soundPool.ptr.pause(_streamId);
    } else {
      _soundPool.ptr.resume(_streamId);
42 43 44
    }
  }

45 46 47 48 49
  double get leftVolume => _leftVolume;
  double _leftVolume;
  void set leftVolume(double value) {
    _leftVolume = value;
    _soundPool.ptr.setVolume(_streamId, <double>[_leftVolume, _rightVolume]);
50 51
  }

52 53 54 55 56 57
  double get rightVolume => _rightVolume;
  double _rightVolume;
  void set rightVolume(double value) {
    _rightVolume = value;
    _soundPool.ptr.setVolume(_streamId, <double>[_leftVolume, _rightVolume]);
  }
58

59 60 61 62 63 64 65
  double get pitch => _pitch;
  double _pitch;
  void set pitch(double value) {
    _pitch = value;
    _soundPool.ptr.setRate(_streamId, _pitch);
  }
}
66

67 68 69
class SoundEffectPlayer {
  SoundEffectPlayer(int maxStreams) {
    MediaServiceProxy mediaService = new MediaServiceProxy.unbound();
70
    shell.connectToService("mojo:media_service", mediaService);
71 72
    _soundPool = new SoundPoolProxy.unbound();
    mediaService.ptr.createSoundPool(_soundPool, maxStreams);
73 74
  }

75 76 77
  SoundPoolProxy _soundPool;
  bool _paused;
  int _nextStreamId = 0;
78

79 80 81 82
  Future<SoundEffect> load(MojoDataPipeConsumer data) async {
    SoundPoolLoadResponseParams result = await _soundPool.ptr.load(data);
    if (result.success)
      return new SoundEffect(result.soundId);
83

84 85
    throw new Exception('Unable to load sound');
  }
86

87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
  Future<SoundEffectStream> play(SoundEffect sound, {
    double leftVolume: 1.0,
    double rightVolume: 1.0,
    bool loop: false,
    double pitch: 1.0
  }) async {
    int streamId = _nextStreamId++;
    SoundPoolPlayResponseParams result = await _soundPool.ptr.play(
      sound._soundId, streamId, <double>[leftVolume, rightVolume], loop, pitch
    );

    if (result.success) {
      return new SoundEffectStream(this, streamId,
        leftVolume: leftVolume,
        rightVolume: rightVolume,
        pitch: pitch
      );
104 105
    }

106
    throw new Exception('Unable to play sound');
107 108
  }

109
  bool get paused => _paused;
110

111 112 113 114 115 116
  void set paused(bool value) {
    _paused = value;
    if (_paused) {
      _soundPool.ptr.pauseAll();
    } else {
      _soundPool.ptr.resumeAll();
117 118 119
    }
  }
}
120

Hixie's avatar
Hixie committed
121 122
typedef void SoundTrackCallback(SoundTrack soundTrack);
typedef void SoundTrackBufferingCallback(SoundTrack soundTrack, int index);
123 124 125 126 127 128 129 130 131

class SoundTrack {
  MediaPlayerProxy _player;

  SoundTrackCallback onSoundComplete;
  SoundTrackCallback onSeekComplete;
  SoundTrackBufferingCallback onBufferingUpdate;
  bool loop;
  double time;
132
  double volume;
133 134 135 136 137 138 139
}

SoundTrackPlayer _sharedSoundTrackPlayer;

class SoundTrackPlayer {
  SoundTrackPlayer() {
    _mediaService = new MediaServiceProxy.unbound();
140
    shell.connectToService("mojo:media_service", _mediaService);
141 142 143 144
  }

  MediaServiceProxy _mediaService;

Ian Hickson's avatar
Ian Hickson committed
145 146 147 148 149 150
  Set<SoundTrack> _soundTracks = new HashSet<SoundTrack>();

  static SoundTrackPlayer sharedInstance() {
    return _sharedSoundTrackPlayer ??= new SoundTrackPlayer();
  }

151
  Future<SoundTrack> load(Future<MojoDataPipeConsumer> pipe) async {
152 153 154 155 156
    // Create media player
    SoundTrack soundTrack = new SoundTrack();
    soundTrack._player = new MediaPlayerProxy.unbound();
    _mediaService.ptr.createPlayer(soundTrack._player);

157
    await soundTrack._player.ptr.prepare(await pipe);
158 159 160 161 162 163 164 165
    return soundTrack;
  }

  void unload(SoundTrack soundTrack) {
    stop(soundTrack);
    _soundTracks.remove(soundTrack);
  }

166 167 168 169 170 171 172
  void play(SoundTrack soundTrack, {
    bool loop: false,
    double volume: 1.0,
    double startTime: 0.0
  }) {
    soundTrack._player.ptr.setLooping(loop);
    soundTrack._player.ptr.setVolume(volume);
173 174
    soundTrack._player.ptr.seekTo((startTime * 1000.0).toInt());
    soundTrack._player.ptr.start();
175
    _soundTracks.add(soundTrack);
176 177 178 179 180 181
  }

  void stop(SoundTrack track) {
    track._player.ptr.pause();
  }

182 183
  void pauseAll() {
    for (SoundTrack soundTrack in _soundTracks)
184
      soundTrack._player.ptr.pause();
185 186 187 188 189
  }

  void resumeAll() {
    for (SoundTrack soundTrack in _soundTracks)
      soundTrack._player.ptr.start();
190 191
  }
}