UNPKG

genish.js

Version:
187 lines (144 loc) 6.9 kB
/* Gigaverb ported from Gen example by thecharlie 5/18/16 ... and it's probably not quite right. */ signalData = data( './resources/audiofiles/dead-presidents.wav' ).then( ()=> { 'use jsdsp' // parameters for external manipulation (via gui) let dry = param( 'dry', 1 ), roomSize = param( 'roomSize', 75 ), // .1 - 300 bandwidth = param( 'inputBandwidth', .5 ),// 0 - 1 early = param( 'earlyReflections',.25 ),// 0 - 1 revtime = param( 'reverbTime', 11 ), // min 0.1 - Inf damping = param( 'damping', .7 ), // 0 - 1 tail = param( 'tailLevel',.25 ), // 0 - 1 ggG spread = param( 'spread', 23 ), // 0 - 100 in1 = peek( signalData, accum( 1,0, { max:signalData.buffer.length } ), { interp:'none', mode:'samples' } ) attenuatedSignal = memo( in1 * .707 ) // in1 * samplerate / 340 roomSizeCoeff = memo( ( roomSize * gen.samplerate ) / 340 ) // input damper damperHistory = ssd() damper = mix( attenuatedSignal, damperHistory.out, 1 - bandwidth ) damperHistory.in( damper ) prediffuseHistory = ssd() prediffuseTime = roomSizeCoeff * .110732 prediffuseDelay = delay( prediffuseHistory.out, prediffuseTime, { size: 6000 }) dampMinusDiffuse = damper - ( prediffuseDelay * .75 ) prediffuseHistory.in( dampMinusDiffuse ) prediffusePlusDamping = prediffuseDelay + dampMinusDiffuse * .75 tap1Time = memo( ( roomSizeCoeff * .41 ) + 5 ) tap2Time = memo( ( roomSizeCoeff * .3 ) + 5 ) tap3Time = memo( ( roomSizeCoeff * .155 ) + 5 ) tap4Time = roomSizeCoeff + 5 multitap = delay( prediffusePlusDamping, [tap1Time, tap2Time, tap3Time, tap4Time], { size: 48000, interp:'linear' } ) // pow( pow( 10,-60/20 ), 1. / ( in1*samplerate ) ) revtimeCoeff = memo( ( 10 ^ -3 ) ^ ( 1 / ( revtime * gen.samplerate) ) ) taps = [ memo( early * ( multitap.outputs[0] * ( revtimeCoeff ^ tap1Time ) ) ), memo( early * ( multitap.outputs[1] * ( revtimeCoeff ^ tap2Time ) ) ), memo( early * ( multitap.outputs[2] * ( revtimeCoeff ^ tap3Time ) ) ), memo( early * ( multitap.outputs[3] * ( revtimeCoeff ^ tap4Time ) ) ) ] tapsL = taps[0] + taps[2] tapsR = taps[1] + taps[3] tapOutput = tapsL - tapsR //play( tapOutput ) }) // ************* Feedback Delay Network ************* fdnCoeffs = [ 1, .81649, .7071, .63245 ] delayLines = [] for( let i = 0; i < 4; i++ ) { let dlHistory, delayTimeCoeff, dl, feedbackInput, feedbackHistory, feedbackMix, terminal, output dlHistory = ssd() delayTimeCoeff = memo( roomSizeCoeff * fdnCoeffs[i] ) dl = delay( dlHistory.out, delayTimeCoeff, { size:48000 } ) feedbackInput = dl * ( -1 * ( revtimeCoeff ^ delayTimeCoeff) ) feedbackHistory = ssd(), feedbackMix = mix( feedbackInput, feedbackHistory.out, damping ) feedbackHistory.in( feedbackMix ) terminal = i < 2 ? sub() : add() output = i !== 2 ? terminal * .5 : ( 0 - terminal ) * .5 dlHistory.in( output + taps[i] ) delayLines.push({ terminal, output, feedbackMix }) } // *************** hook the network up ***************** delayLines[0].positive = delayLines[0].feedbackMix + delayLines[1].feedbackMix delayLines[0].negative = delayLines[0].feedbackMix - delayLines[1].feedbackMix // must wait for delay line 2 to connect terminal delayLines[1].terminal.inputs[0] = delayLines[0].negative // STILL MUST DO OTHER INPUT TO DL[2].NEGATIVE delayLines[2].positive = delayLines[2].feedbackMix + delayLines[3].feedbackMix delayLines[2].negative = delayLines[2].feedbackMix - delayLines[3].feedbackMix delayLines[2].terminal.inputs = [ delayLines[0].negative, delayLines[2].negative ] delayLines[0].terminal.inputs = [ delayLines[0].positive, delayLines[2].positive ] // now that delayLine[2] has been made, connect delayLine[1] to it delayLines[1].terminal.inputs[1] = delayLines[2].negative delayLines[3].terminal.inputs = [ delayLines[2].positive, delayLines[0].positive ] fdnL = ( delayLines[0].output * tail ) + ( delayLines[2].output * tail ) fdnR = ( delayLines[1].output * tail ) + ( delayLines[3].output * tail ) fdnOut = fdnL - fdnR fdnPlusDiffuse = fdnOut + tapOutput diffusionRoomSizeCoeff = memo( floor( roomSizeCoeff * .000527 ) ) leftDiffusionHead = in1 + fdnPlusDiffuse rightDiffusionHead = in1 + fdnPlusDiffuse chain1Head = memo( .125541 * spread ) delayOffset1 = 159 + chain1Head diff1History = ssd() delay1 = delay( diff1History.out, delayOffset1 * diffusionRoomSizeCoeff, { size: 5000 } ) diff1 = leftDiffusionHead - ( delay1 * .75 ) diff1History.in( diff1 ) chain1Out = ( diff1 * .75 ) + delay1 chain2Head = memo( .376623 * spread ) delayOffset2 = 931 + chain2Head delayOffset2_a = delayOffset2 - ( chain1Head + 369 ) delayOffset2_b = 1341 - delayOffset2 diff2History = ssd() delay2 = delay( diff2History.out, delayOffset2_a * diffusionRoomSizeCoeff, { size: 15000 } ) diff2 = chain1Out - ( delay2 *.625 ) diff2History.in( diff2 ) chain2Out = ( diff2 * .625 ) + delay2 delayOffset3 = delayOffset2_b * diffusionRoomSizeCoeff diff3History = ssd() delay3 = delay( diff3History.out, delayOffset3, { size: 10000 } ) diff3 = chain2Out - ( delay3 * .625 ) diff3History.in( diff3 ) chain3Out = ( diff3 * .625 ) + delay3 chain1RHead = memo( -.568366 * spread ) delayOffset1R = 159 + chain1RHead diff1RHistory = ssd() delay1R = delay( diff1RHistory.out, delayOffset1R * diffusionRoomSizeCoeff, { size: 7000 } ) diff1R = leftDiffusionHead - ( delay1R * .75 ) diff1RHistory.in( diff1R ) chain1ROut = ( diff1R * .75 ) + delay1R chain2RHead = memo( -.380445 * spread ) delayOffset2R = 931 + chain2RHead delayOffset2R_a = delayOffset2R - ( chain1RHead + 369 ) delayOffset2R_b = 1341 - delayOffset2R diff2RHistory = ssd() delay2R = delay( diff2RHistory.out, delayOffset2R_a * diffusionRoomSizeCoeff , { size: 16000 } ) diff2R = chain1ROut - ( delay2R * .625 ) diff2RHistory.in( diff2R ) chain2ROut = ( diff2R * .625 ) + delay2R delayOffset3R = delayOffset2R_b * diffusionRoomSizeCoeff diff3RHistory = ssd() delay3R = delay( diff3RHistory.out, delayOffset3R, { size: 12000 } ) diff3R = chain2ROut - ( delay3R * .625 ) diff3RHistory.in( diff3R ) chain3ROut = ( diff3R * .625 ) + delay3R chainL = chain3Out + in1 * dry chainR = chain3ROut + in1 * dry cb = play( [chainL, chainR] ) gui = new dat.GUI() gui.add( cb, 'roomSize', .1, 300 ) gui.add( cb, 'reverbTime', .1, 1000 ) gui.add( cb, 'spread', 0, 100 ) gui.add( cb, 'inputBandwidth', 0, 1 ) gui.add( cb, 'damping', 0, 1 ) gui.add( cb, 'dry', 0, 1 ) gui.add( cb, 'earlyReflections', 0, 1 ) gui.add( cb, 'tailLevel', 0, 1 ) })