gibberish-dsp
Version:
Gibberish is designed to be an optimized API for audio synthesis using per-sample techniques.
178 lines (140 loc) • 5.42 kB
JavaScript
const g = require( 'genish.js' ),
ugen = require( '../ugen.js' )(),
feedbackOsc = require( './fmfeedbackosc.js' ),
polyBlep = require( './polyblep.dsp.js' )
// __makeOscillator__( type, frequency, antialias ) {
module.exports = function( Gibberish ) {
let Oscillators = {
export( obj ) {
for( let key in Oscillators ) {
if( key !== 'export' ) {
obj[ key ] = Oscillators[ key ]
}
}
},
genish: {
Brown: require( './brownnoise.dsp.js' ),
Pink: require( './pinknoise.dsp.js' )
},
Wavetable: require( './wavetable.js' )( Gibberish ),
Square( inputProps ) {
const sqr = Object.create( ugen )
const props = Object.assign({ antialias:false }, Oscillators.defaults, inputProps )
const osc = Oscillators.factory( 'square', g.in( 'frequency' ), props.antialias )
const graph = g.mul( osc, g.in('gain' ) )
const out = Gibberish.factory( sqr, graph, ['oscillators','square'], props )
return out
},
Triangle( inputProps ) {
const tri= Object.create( ugen )
const props = Object.assign({ antialias:false }, Oscillators.defaults, inputProps )
const osc = Oscillators.factory( 'triangle', g.in( 'frequency' ), props.antialias )
const graph = g.mul( osc, g.in('gain' ) )
const out = Gibberish.factory( tri, graph, ['oscillators','triangle'], props )
return out
},
PWM( inputProps ) {
const pwm = Object.create( ugen )
const props = Object.assign({ antialias:false, pulsewidth:.25 }, Oscillators.defaults, inputProps )
const osc = Oscillators.factory( 'pwm', g.in( 'frequency' ), props.antialias )
const graph = g.mul( osc, g.in('gain' ) )
const out = Gibberish.factory( pwm, graph, ['oscillators','PWM'], props )
return out
},
Sine( inputProps ) {
const sine = Object.create( ugen )
const props = Object.assign({}, Oscillators.defaults, inputProps )
const graph = g.mul( g.cycle( g.in('frequency') ), g.in('gain') )
const out = Gibberish.factory( sine, graph, ['oscillators','sine'], props )
return out
},
Noise( inputProps ) {
const noise = Object.create( ugen )
const props = Object.assign( {}, { gain: 1, color:'white' }, inputProps )
let graph
switch( props.color ) {
case 'brown':
graph = g.mul( Oscillators.genish.Brown(), g.in('gain') )
break;
case 'pink':
graph = g.mul( Oscillators.genish.Pink(), g.in('gain') )
break;
default:
graph = g.mul( g.noise(), g.in('gain') )
break;
}
const out = Gibberish.factory( noise, graph, ['oscillators','noise'], props )
return out
},
Saw( inputProps ) {
const saw = Object.create( ugen )
const props = Object.assign({ antialias:false }, Oscillators.defaults, inputProps )
const osc = Oscillators.factory( 'saw', g.in( 'frequency' ), props.antialias )
const graph = g.mul( osc, g.in('gain' ) )
const out = Gibberish.factory( saw, graph, ['oscillators','saw'], props )
return out
},
ReverseSaw( inputProps ) {
const saw = Object.create( ugen )
const props = Object.assign({ antialias:false }, Oscillators.defaults, inputProps )
const osc = g.sub( 1, Oscillators.factory( 'saw', g.in( 'frequency' ), props.antialias ) )
const graph = g.mul( osc, g.in( 'gain' ) )
const out = Gibberish.factory( saw, graph, ['oscillators','ReverseSaw'], props )
return out
},
factory( type, frequency, antialias=false ) {
let osc
switch( type ) {
case 'pwm':
let pulsewidth = g.in('pulsewidth')
if( antialias == true ) {
osc = feedbackOsc( frequency, 1, pulsewidth, { type:1 })
}else{
let phase = g.phasor( frequency, 0, { min:0 } )
osc = g.lt( phase, pulsewidth )
}
break;
case 'saw':
if( antialias == false ) {
osc = g.phasor( frequency )
}else{
osc = polyBlep( frequency, { type })
}
break;
case 'sine':
osc = g.cycle( frequency )
break;
case 'square':
if( antialias == true ) {
//osc = feedbackOsc( frequency, 1, .5, { type:1 })
osc = polyBlep( frequency, { type })
}else{
osc = g.wavetable( frequency, { buffer:Oscillators.Square.buffer, name:'square' } )
}
break;
case 'triangle':
if( antialias == true ) {
osc = polyBlep( frequency, { type })
}else{
osc = g.wavetable( frequency, { buffer:Oscillators.Triangle.buffer, name:'triangle' } )
}
break;
case 'noise':
osc = g.noise()
break;
}
return osc
}
}
Oscillators.Square.buffer = new Float32Array( 1024 )
for( let i = 1023; i >= 0; i-- ) {
Oscillators.Square.buffer [ i ] = i / 1024 > .5 ? 1 : -1
}
Oscillators.Triangle.buffer = new Float32Array( 1024 )
for( let i = 1024; i--; i = i ) { Oscillators.Triangle.buffer[i] = 1 - 4 * Math.abs(( (i / 1024) + 0.25) % 1 - 0.5); }
Oscillators.defaults = {
frequency: 440,
gain: 1
}
return Oscillators
}