AudioClip class
An AudioClip stores sound data. To play an AudioClip, see AudioSource, AudioMusic, and AudioManager.
class AudioClip { static const SFXR_PREFIX = "sfxr:"; final AudioManager _manager; String _name; String _url; set url(String u) => _url = u; String get url => _url; AudioBuffer _buffer; bool _hasError = false; String _errorString = ''; bool _isReadyToPlay = false; bool _urlAbsolute = false; AudioClip._internal(this._manager, this._name, this._url); AudioClip.external(this._manager, this._name, this._url) { _urlAbsolute = true; } void _empty() { _isReadyToPlay = false; _buffer = null; } Map toJson() { // Serialize buffer contents as well. return { "_url":_url, "_name": _name, }; } AudioClip fromMap(Map map) { _url = map['_url']; _name = map['_name']; return this; } /** Does the clip have an error? */ bool get hasError => _hasError; /** Human readable error */ String get errorString => _errorString; /** Clear any error. */ void clearError() { _hasError = false; _errorString = 'OK'; } void _setError(String error) { _hasError = true; _errorString = error; } void _onDecode(AudioBuffer buffer, Completer<AudioClip> completer) { if (buffer == null) { _setError('Error decoding buffer.'); completer.complete(this); return; } clearError(); _buffer = buffer; _isReadyToPlay = true; completer.complete(this); } void _onRequestSuccess(HttpRequest request, Completer<AudioClip> completer) { var response = request.response; _manager._context.decodeAudioData(response, (b) => _onDecode(b, completer), (b) => _onDecode(b, completer)); } void _onRequestError(HttpRequest request, Completer<AudioClip> completer) { _setError('Error fetching data'); completer.complete(this); } /** Fetch and decode the clip's [url] into the clip buffer. * Returns a [Future<AudioClip>] which completes to *this*. * [hasError] and [errorString] will indicate and explain respetively * any load errors. */ Future<AudioClip> load() { if (url == null) { _setError('No URL set.'); return new Future<AudioClip>.value(this); } _empty(); if (url.startsWith(SFXR_PREFIX)) { return new Future<AudioClip>.delayed(new Duration(milliseconds: 1), (){ _buffer = SfxrSynth.toAudioBuffer(_manager._context, url.substring(SFXR_PREFIX.length)); _isReadyToPlay = true; return this; }); } var request = new HttpRequest(); var completer = new Completer<AudioClip>(); if (_urlAbsolute) { request.open('GET', url); } else { request.open('GET', '${_manager.baseURL}/$url'); } request.responseType = 'arraybuffer'; request.onLoad.listen((e) => _onRequestSuccess(request, completer)); request.onError.listen((e) => _onRequestError(request, completer)); request.onAbort.listen((e) => _onRequestError(request, completer)); request.send(); return completer.future; } /** Make an empty clip buffer with [numberOfSampleFrames] in * each [numberOfChannels]. The buffer plays at a rate of [sampleRate]. * The duration (in seconds) of the buffer is equal to: * numberOfSampleFrames / sampleRate */ void makeBuffer(num numberOfSampleFrames, num numberOfChannels, num sampleRate) { _buffer = _manager._context.createBuffer(numberOfChannels, numberOfChannels, sampleRate); _isReadyToPlay = true; } /** Return the sample frames array for [channel]. Assuming a stereo setup, * the left and right speakers are mapped to channel 0 and 1 respectively. */ Float32List getSampleFramesForChannel(num channel) { if (_buffer == null) { return null; } return _buffer.getChannelData(channel); } /** Number of clip channels. */ num get numberOfChannels { if (_buffer == null) { return 0; } return _buffer.numberOfChannels; } /** Length of clip in seconds. */ num get length { if (_buffer == null) { return 0; } return _buffer.duration; } /** Length of clip in samples. */ num get samples { if (_buffer == null) { return 0; } return _buffer.length; } /** Samples per second. */ num get frequency { if (_buffer == null) { return 0; } return _buffer.sampleRate; } /** Is the clip ready to be played? */ bool get isReadyToPlay => _isReadyToPlay; }
Static Properties
const SFXR_PREFIX #
static const SFXR_PREFIX = "sfxr:"
Constructors
new AudioClip.external(AudioManager _manager, String _name, String _url) #
AudioClip.external(this._manager, this._name, this._url) { _urlAbsolute = true; }
Properties
final num frequency #
Samples per second.
num get frequency { if (_buffer == null) { return 0; } return _buffer.sampleRate; }
final bool isReadyToPlay #
Is the clip ready to be played?
bool get isReadyToPlay => _isReadyToPlay;
final num length #
Length of clip in seconds.
num get length { if (_buffer == null) { return 0; } return _buffer.duration; }
final num numberOfChannels #
Number of clip channels.
num get numberOfChannels { if (_buffer == null) { return 0; } return _buffer.numberOfChannels; }
Methods
void clearError() #
Clear any error.
void clearError() { _hasError = false; _errorString = 'OK'; }
AudioClip fromMap(Map map) #
AudioClip fromMap(Map map) { _url = map['_url']; _name = map['_name']; return this; }
Float32List getSampleFramesForChannel(num channel) #
Return the sample frames array for channel. Assuming a stereo setup, the left and right speakers are mapped to channel 0 and 1 respectively.
Float32List getSampleFramesForChannel(num channel) { if (_buffer == null) { return null; } return _buffer.getChannelData(channel); }
Future<AudioClip> load() #
Fetch and decode the clip's url into the clip buffer.
Returns a [Future
Future<AudioClip> load() { if (url == null) { _setError('No URL set.'); return new Future<AudioClip>.value(this); } _empty(); if (url.startsWith(SFXR_PREFIX)) { return new Future<AudioClip>.delayed(new Duration(milliseconds: 1), (){ _buffer = SfxrSynth.toAudioBuffer(_manager._context, url.substring(SFXR_PREFIX.length)); _isReadyToPlay = true; return this; }); } var request = new HttpRequest(); var completer = new Completer<AudioClip>(); if (_urlAbsolute) { request.open('GET', url); } else { request.open('GET', '${_manager.baseURL}/$url'); } request.responseType = 'arraybuffer'; request.onLoad.listen((e) => _onRequestSuccess(request, completer)); request.onError.listen((e) => _onRequestError(request, completer)); request.onAbort.listen((e) => _onRequestError(request, completer)); request.send(); return completer.future; }
void makeBuffer(num numberOfSampleFrames, num numberOfChannels, num sampleRate) #
Make an empty clip buffer with numberOfSampleFrames in each numberOfChannels. The buffer plays at a rate of sampleRate. The duration (in seconds) of the buffer is equal to: numberOfSampleFrames / sampleRate
void makeBuffer(num numberOfSampleFrames, num numberOfChannels, num sampleRate) { _buffer = _manager._context.createBuffer(numberOfChannels, numberOfChannels, sampleRate); _isReadyToPlay = true; }