import { TimeInstant } from '../time' ; import { GainNode as GGainNode } from 'nf-grapher' ; import { ScoreAudioParam } from '../params/ScoreAudioParam' ; import { SPNode } from './SPNode' ; import { SPNodeFactory } from './SPNodeFactory' ; import { CommandsMutation , applyMutationToParam } from '../Mutations' ; import { debug as Debug } from 'debug' ; import { XAudioBuffer } from '../XAudioBuffer' ; const DBG_STR = 'nf:gainnode' ; const dbg = Debug ( DBG_STR ) ; export class SPGainNode extends SPNode { protected gainParam = new ScoreAudioParam ( 1 ) ; async nodeDidMount ( ) { this . gainParam . applyScoreCommands ( this . node . params ! . gain ) ; } feed ( renderTime , buffers , sampleCount ) { const seconds = renderTime . asSeconds ( ) ; dbg ( '%s feed @ %f' , this . node . id , seconds ) ; const ancestorBuffers = [ ] ; SPNodeFactory . feed ( this . ancestors , renderTime , ancestorBuffers , sampleCount ) ; for ( let buffer of ancestorBuffers ) { const incr = 1 / buffer . sampleRate ; for ( let c = 0 ; c < buffer . numberOfChannels ; c ++ ) { const chan = buffer . getChannelData ( c ) ; for ( let i = 0 ; i < chan . length ; i ++ ) { const sampleTime = seconds + incr * i ; const pvalue = this . gainParam . getValueAtTime ( sampleTime ) ; chan [ i ] *= pvalue ; } } } for ( let buffer of ancestorBuffers ) { buffers . push ( buffer ) ; } } acceptCommandsEffect ( effect ) { const node = GGainNode . from ( this . node ) ; const { paramName } = effect ; if ( ! Object . keys ( node . getParams ( ) ) . includes ( paramName ) ) { throw new Error ( `GainNode does not contain param with name: ${ paramName }` ) ; } return applyMutationToParam ( effect , this . gainParam , this . node . params ! . gain ) ; } }