import { XAudioBuffer } from './XAudioBuffer' ; export function mixdown ( dest , buffers ) { if ( buffers . length === 0 ) { return dest ; } for ( let i = 0 ; i < buffers . length ; i ++ ) { const buffer = buffers [ i ] ; for ( let c = 0 ; c < dest . numberOfChannels ; c ++ ) { const sourceIdx = c < buffer . numberOfChannels ? c : 0 ; const sourceChan = buffer . getChannelData ( sourceIdx ) ; const destChan = dest . getChannelData ( c ) ; for ( let s = 0 ; s < sourceChan . length ; s ++ ) { destChan [ s ] = destChan [ s ] + sourceChan [ s ] ; } } } return dest ; } export function mixdownToAudioBuffer ( dest , buffers ) { return mixdown ( dest as XAudioBuffer , buffers ) ; } /**
 * Copy the src to the dst. If the src has fewer channels than the dst, the
 * last src channel is used. If the dst has fewer channels than the src,
 * the other src channels are not used.
 */ export function copy ( dst , src , startInDestination , boundsCheck = true ) { if ( boundsCheck && dst . length - startInDestination < src . length ) { throw new Error ( 'InvalidSourceSize: The Source must fit within destination.' ) ; } for ( let i = 0 ; i < dst . numberOfChannels ; i ++ ) { if ( i < src . numberOfChannels ) { dst . copyToChannel ( src . getChannelData ( i ) , i , startInDestination ) ; } else { dst . copyToChannel ( src . getChannelData ( src . numberOfChannels - 1 ) , i , startInDestination ) ; } } return dst ; } export function zeroOut ( dest ) { for ( let i = 0 ; i < dest . numberOfChannels ; i ++ ) { const destChan = dest . getChannelData ( i ) ; for ( let s = 0 ; s < destChan . length ; s ++ ) { destChan [ s ] = 0 ; } } return dest ; } export function asInterleaved ( ab ) { const channels = ab . numberOfChannels ; const output = new Float32Array ( channels * ab . length ) ; for ( let i = 0 ; i < ab . length ; i ++ ) { for ( let c = 0 ; c < channels ; c ++ ) { const chan = ab . getChannelData ( c ) ; output [ i * channels + c ] = chan [ i ] ; } } return output ; } export function asPlanar ( buffer , sampleRate , channels = 2 ) { const channelLength = Math . floor ( buffer . length / channels ) ; const output = new XAudioBuffer ( { numberOfChannels : channels , length : channelLength , sampleRate : sampleRate } ) ; for ( let c = 0 ; c < channels ; c ++ ) { const chan = output . getChannelData ( c ) ; for ( let i = 0 ; i < channelLength ; i ++ ) { chan [ i ] = buffer [ i * channels + c ] ; } } return output ; } function getTargetValueAtTime ( t , v0 , v1 , t0 , timeConstant ) { if ( t <= t0 ) { return v0 ; } return v1 + ( v0 - v1 ) * Math . exp ( ( t0 - t ) / timeConstant ) ; } export function applyFadeIn ( buffer ) { const t0 = 0 ; const v0 = 0 ; const v1 = 1 ; const constant = buffer . length / 10 ; for ( let i = 0 ; i < buffer . numberOfChannels ; i ++ ) { const chan = buffer . getChannelData ( i ) ; for ( let j = 0 ; j < chan . length ; j ++ ) { const v = getTargetValueAtTime ( j , v0 , v1 , t0 , constant ) ; chan [ j ] = chan [ j ] * v ; } } return buffer ; } export function applyFadeOut ( buffer ) { const t0 = 0 ; const v0 = 1 ; const v1 = 0 ; const constant = buffer . length / 4 ; for ( let i = 0 ; i < buffer . numberOfChannels ; i ++ ) { const chan = buffer . getChannelData ( i ) ; for ( let j = 0 ; j < chan . length ; j ++ ) { const v = getTargetValueAtTime ( j , v0 , v1 , t0 , constant ) ; chan [ j ] = chan [ j ] * v ; } } return buffer ; }