type XAudioBufferOptions = { numberOfChannels ? : number ; length : number ; sampleRate : number ; } ; /**
 * An implementation of AudioBuffer as seen in the Web Audio API. The
 * AudioBuffer in Web Audio is tied to the browser, and only recently it became
 * possible to instantiate an AudioBuffer without a Web Audio Context. This
 * implementation allows for a fully WebAudio-free player, while still allowing
 * for easy interop with the Web Audio API when needed when still in a browser
 * environment.
 *
 * Originally from https://github.com/audiojs/audio-buffer/, MIT Licensed.
 * Converted to TS.
 * https://github.com/audiojs/audio-buffer/blob/master/LICENSE
 */ export class XAudioBuffer { sampleRate : number ; length : number ; duration : number ; numberOfChannels : number ; protected _data : Float32Array ; protected _channelData : Float32Array [ ] ; constructor ( options ) { this . sampleRate = options . sampleRate ; this . length = Math . floor ( options . length ) ; this . numberOfChannels = options . numberOfChannels ? options . numberOfChannels : 1 ; this . duration = this . length / this . sampleRate ; this . _data = new Float32Array ( this . length * this . numberOfChannels ) ; this . _channelData = [ ] ; for ( let c = 0 ; c < this . numberOfChannels ; c ++ ) { this . _channelData . push ( this . _data . subarray ( c * this . length , ( c + 1 ) * this . length ) ) ; } } /**
     * Create a new XAudioBuffer by copying data from an existing AudioBuffer.
     */ static fromAudioBuffer ( ab ) { const x = new XAudioBuffer ( { numberOfChannels : ab . numberOfChannels , sampleRate : ab . sampleRate , length : ab . length } ) ; for ( let i = 0 ; i < ab . numberOfChannels ; i ++ ) { x . copyToChannel ( ab . getChannelData ( i ) , i , 0 ) ; } return x ; } /**
     * Return data associated with the channel.
     */ getChannelData ( channel ) { if ( channel >= this . numberOfChannels || channel < 0 || channel == null ) { throw Error ( 'Cannot getChannelData: channel number (' + channel + ') exceeds number of channels (' + this . numberOfChannels + ')' ) ; } return this . _channelData [ channel ] ; } /**
     * Place data to the destination buffer, starting from the position
     */ copyFromChannel ( destination , channelNumber , startInChannel = 0 ) { const data = this . _channelData [ channelNumber ] ; for ( let i = startInChannel , j = 0 ; i < this . length && j < destination . length ; i ++ , j ++ ) { destination [ j ] = data [ i ] ; } } /**
     * Place data from the source to the channel, starting (in self) from the position
     */ copyToChannel ( source , channelNumber , startInChannel = 0 ) { const data = this . _channelData [ channelNumber ] ; for ( let i = startInChannel , j = 0 ; i < this . length && j < source . length ; i ++ , j ++ ) { data [ i ] = source [ j ] ; } } }