export class Mixer { inputs : { [ id ] : Input ; } = { } ; pcm : { [ id ] : Buffer ; } = { } ; onData : ( buf : Buffer ) => void = ( ) => { } ; constructor ( private args ) { } input ( ) { const input = new Input ( this ) ; this . inputs [ input . id ] = input ; return input ; } mixing ( ) { if ( Object . keys ( this . pcm ) . length === Object . keys ( this . inputs ) . length ) { const inputs = Object . values ( this . pcm ) ; const base = inputs . shift ( ) ; this . pcm = { } ; const res = inputs . reduce ( ( acc , cur ) => { const next = acc . map ( ( v , i ) => this . mix ( v , cur [ i ] ) ) ; return next ; } , [ ... ( base || [ ] ) ] ) ; this . onData ( Buffer . from ( res ) ) ; } } private mix ( a , b ) { const res = a + b ; const max = 1 << ( this . args . bit - 1 ) ; if ( max < res ) { return max ; } else if ( 0 > res ) { return res ; } return res ; } } export class Input { id = Math . random ( ) . toString ( ) ; constructor ( private mixer ) { } write ( buf ) { this . mixer . pcm [ this . id ] = buf ; this . mixer . mixing ( ) ; } remove ( ) { delete this . mixer . inputs [ this . id ] ; delete this . mixer . pcm [ this . id ] ; } }