import { Filter } from '../filters/Filter' ; import { IMedia } from '../interfaces/IMedia' ; import { LoadedCallback , Sound } from '../Sound' ; import { WebAudioContext } from './WebAudioContext' ; import { WebAudioInstance } from './WebAudioInstance' ; import { WebAudioNodes } from './WebAudioNodes' ; memberof class WebAudioMedia implements IMedia { readonly public parent : Sound ; readonly public source : ArrayBuffer | AudioBuffer ; /** Instance of the chain builder. */ private _nodes : WebAudioNodes ; /** Instance of the source node. */ private _source : AudioBufferSourceNode ; param parent public init ( parent ) { this . parent = parent ; this . _nodes = new WebAudioNodes ( this . context ) ; this . _source = this . _nodes . bufferSource ; this . source = parent . options . source as ArrayBuffer | AudioBuffer ; } /** Destructor, safer to use `SoundLibrary.remove(alias)` to remove this sound. */ public destroy ( ) { this . parent = null ; this . _nodes . destroy ( ) ; this . _nodes = null ; try { this . _source . buffer = null ; } catch ( err ) { console . warn ( 'Failed to set AudioBufferSourceNode.buffer to null:' , err ) ; } this . _source = null ; this . source = null ; } public create ( ) { return new WebAudioInstance ( this ) ; } public get context ( ) : WebAudioContext { return this . parent . context as WebAudioContext ; } public get isPlayable ( ) : boolean { return ! ! this . _source && ! ! this . _source . buffer ; } public get filters ( ) : Filter [ ] { return this . _nodes . filters ; } public set filters ( filters ) { this . _nodes . filters = filters ; } public get duration ( ) : number { console . assert ( this . isPlayable , 'Sound not yet playable, no duration' ) ; return this . _source . buffer . duration ; } /** Gets and sets the buffer. */ public get buffer ( ) : AudioBuffer { return this . _source . buffer ; } public set buffer ( buffer ) { this . _source . buffer = buffer ; } /** Get the current chained nodes object */ public get nodes ( ) : WebAudioNodes { return this . _nodes ; } public load ( callback ? ) { if ( this . source ) { this . _decode ( this . source , callback ) ; } else if ( this . parent . url ) { this . _loadUrl ( callback ) ; } else if ( callback ) { callback ( new Error ( 'sound.url or sound.source must be set' ) ) ; } else { console . error ( 'sound.url or sound.source must be set' ) ; } } /** Loads a sound using XHMLHttpRequest object. */ private _loadUrl ( callback ? ) { const request = new XMLHttpRequest ( ) ; const url = this . parent . url ; request . open ( 'GET' , url , true ) ; request . responseType = 'arraybuffer' ; request . onload = ( ) => { this . source = request . response as ArrayBuffer ; this . _decode ( request . response , callback ) ; } ; request . send ( ) ; } param arrayBuffer param { Function } callback private _decode ( arrayBuffer , callback ? ) { const audioBufferReadyFn = ( err , buffer ) => { if ( err ) { if ( callback ) { callback ( err ) ; } } else { this . parent . isLoaded = true ; this . buffer = buffer ; const instance = this . parent . autoPlayStart ( ) ; if ( callback ) { callback ( null , this . parent , instance ) ; } } } ; if ( arrayBuffer instanceof AudioBuffer ) { audioBufferReadyFn ( null , arrayBuffer ) ; } else { const context = this . parent . context as WebAudioContext ; context . decode ( arrayBuffer , audioBufferReadyFn ) ; } } } export { WebAudioMedia } ;