gibberish-dsp
Version:
Gibberish is designed to be an optimized API for audio synthesis using per-sample techniques.
146 lines (117 loc) • 4.28 kB
JavaScript
let Gibberish = null
const __ugen = function( __Gibberish ) {
if( __Gibberish !== undefined && Gibberish == null ) Gibberish = __Gibberish
const replace = obj => {
if( typeof obj === 'object' ) {
if( obj.id !== undefined ) {
return processor.ugens.get( obj.id )
}
}
return obj
}
const ugen = {
__Gibberish:Gibberish,
free:function() {
Gibberish.genish.gen.free( this.graph )
},
print:function() {
console.log( this.callback.toString() )
},
connect:function( target, level=1 ) {
if( this.connected === undefined ) this.connected = []
//let input = level === 1 ? this : Gibberish.binops.Mul( this, level )
let input = this
if( target === undefined || target === null ) target = Gibberish.output
// XXX I forgot, where is __addInput found? Can we control the
// level of the input?
if( typeof target.__addInput == 'function' ) {
target.__addInput( input )
} else if( target.sum && target.sum.inputs ) {
target.sum.inputs.push( input )
} else if( target.inputs ) {
const idx = target.inputs.indexOf( input )
// if no connection exists...
if( idx === -1 ) {
target.inputs.unshift( input, level, input.isStereo )
}else{
// ... otherwise update the connection's level, which is stored
// one index higher in the input list.
target.inputs[ idx + 1 ] = level
}
} else {
target.input = input
target.inputGain = level
}
Gibberish.dirty( target )
this.connected.push([ target, input, level ])
return this
},
disconnect:function( target ) {
if( target === undefined ){
if( Array.isArray( this.connected ) ) {
for( let connection of this.connected ) {
if( connection[0].disconnectUgen !== undefined ) {
connection[0].disconnectUgen( connection[1] )
}else if( connection[0].input === this ) {
connection[0].input = 0
}
}
this.connected.length = 0
}
}else{
const connection = this.connected.find( v => v[0] === target )
// if target is a bus...
if( target.disconnectUgen !== undefined ) {
if( connection !== undefined ) {
target.disconnectUgen( connection[1] )
}
}else{
// must be an effect, set input to 0
target.input = 0
}
const targetIdx = this.connected.indexOf( connection )
if( targetIdx !== -1 ) {
this.connected.splice( targetIdx, 1 )
}
}
},
chain:function( target, level=1 ) {
this.connect( target,level )
return target
},
__redoGraph:function() {
let isStereo = this.isStereo
this.__createGraph()
this.callback = Gibberish.genish.gen.createCallback( this.graph, Gibberish.memory, false, true )
this.inputNames = new Set( Gibberish.genish.gen.parameters )
this.callback.ugenName = this.ugenName
Gibberish.dirty( this )
// if channel count has changed after recompiling graph...
if( isStereo !== this.isStereo ) {
// check for any connections before iterating...
if( this.connected === undefined ) return
// loop through all busses the ugen is connected to
for( let connection of this.connected ) {
// set the dirty flag of the bus
Gibberish.dirty( connection[ 0 ] )
// check for inputs array, which indicates connection is to a bus
if( connection[0].inputs !== undefined ) {
// find the input in the busses 'inputs' array
const inputIdx = connection[ 0 ].inputs.indexOf( connection[ 1 ] )
// assumiing it is found...
if( inputIdx !== -1 ) {
// change stereo field
connection[ 0 ].inputs[ inputIdx + 2 ] = this.isStereo
}
}else if( connection[0].input !== undefined ) {
if( connection[0].__redoGraph !== undefined ) {
connection[0].__redoGraph()
}
}
}
}
},
}
return ugen
}
module.exports = __ugen