genish.js
Version:
95 lines (72 loc) • 3.35 kB
JavaScript
combFilter = function( _input, combLength, damping=.5*.4, feedbackCoeff=.84 ) {
let lastSample = ssd(),
readWriteIdx = counter( 1,0,combLength ),
combBuffer = data( combLength ),
out = peek( combBuffer, readWriteIdx, { interp:'none', mode:'samples' }),
storeInput = memo( add( mul( out, sub( 1, damping)), mul( lastSample.out, damping ) ) )
lastSample.in( storeInput )
poke( combBuffer, add( _input, mul( storeInput, feedbackCoeff ) ), readWriteIdx )
return out
}
// constructor for schroeder allpass filters
allPass = function( _input, length=500, feedback=.5 ) {
let index = counter( 1,0,length ),
buffer = data( length ),
bufferSample = peek( buffer, index, { interp:'none', mode:'samples' }),
out = memo( add( mul( -1, _input), bufferSample ) )
poke( buffer, add( _input, mul( bufferSample, feedback ) ), index )
return out
}
// tuning settings for schroeder / moorer model
tuning = {
combCount: 8,
combTuning: [ 1116, 1188, 1277, 1356, 1422, 1491, 1557, 1617 ],
allPassCount: 4,
allPassTuning: [ 225, 556, 441, 341 ],
allPassFeedback: 0.5,
fixedGain: 0.015,
scaleDamping: 0.4,
scaleRoom: 0.28,
offsetRoom: 0.7,
}
combs = []
signalData = data( './resources/audiofiles/dead-presidents.wav' ).then( ()=> {
// parameters for external manipulation (via gui)
let wet = param( 'wet',.55 ), dry = param( 'dry',.5 ),
roomSize = param( 'roomSize',75 ), bandwidth = param( 'bandwidth', .5 ),
early = param( 'early', .25 ), revtime = param( 'revtime', 11 )
in1 = in2 = peek( signalData, accum( 1,0, { max:signalData.buffer.length } ), { interp:'none', mode:'samples' } )
attenuatedSignal = memo( mul( in1, .707 ) )
// in1 * samplerate / 340
roomSizeCoeff = memo( div( mul( roomSize, gen.samplerate ), 340 ) )
// input damper
damperHistory = ssd()
damper = mix( attenuatedSignal, damperHistory.out, sub( 1, bandwidth ) )
damperHistory.in( damper )
prediffuseHistory = ssd()
prediffuseTime = mul( roomSizeCoeff, .110732 )
prediffuseDelay = delay( prediffuseHistory.out, prediffuseTime, { size: 6000 })
dampMinusDiffuse = sub( damper, mul( prediffuseDelay, .75 ) )
prediffuseHistory.in( dampMinusDiffuse )
prediffusePlusDamping = add( prediffuseDelay, mul( dampMinusDiffuse, .75 ) )
tap1Time = memo( add( mul( roomSizeCoeff, .41 ), 5 ) )
tap2Time = memo( add( mul( roomSizeCoeff, .3 ), 5 ) )
tap3Time = memo( add( mul( roomSizeCoeff, .155 ), 5 ) )
tap4Time = add( roomSizeCoeff, 5 )
multitap = delay(
prediffusePlusDamping,
tap1Time, tap2Time, tap3Time, tap4Time,
{ size: 48000, interp:'linear' }
)
//play( add( ...multitap.outputs ) )
// pow( pow( 10,-60/20 ), 1. / ( in1*samplerate ) )
tapCoeff = memo( pow( pow( 10,-60/20 ), div(1., mul( revtime, gen.samplerate) ) ) )
tap1 = mul( early, mul( multitap.outputs[0], pow( tapCoeff, tap1Time ) ) )
tap2 = mul( early, mul( multitap.outputs[1], pow( tapCoeff, tap2Time ) ) )
tap3 = mul( early, mul( multitap.outputs[2], pow( tapCoeff, tap3Time ) ) )
tap4 = mul( early, mul( multitap.outputs[3], pow( tapCoeff, tap4Time ) ) )
tapsL = add( tap1, tap3 )
tapsR = add( tap2, tap4 )
tapOutput = sub( tapsL, tapsR )
cb = play( tapOutput )
})