Skip to content

Instantly share code, notes, and snippets.

@charlieroberts
Created March 29, 2018 14:03
Show Gist options
  • Select an option

  • Save charlieroberts/799b8cd210407099d3752c1b41b8042c to your computer and use it in GitHub Desktop.

Select an option

Save charlieroberts/799b8cd210407099d3752c1b41b8042c to your computer and use it in GitHub Desktop.
web audio API FM echoes with reverb
window.onload = function() {
const gui = new dat.GUI()
const ctx = new AudioContext()
const delayLine = ctx.createDelay()
delayLine.delayTime.value = .25
const delayGain = ctx.createGain()
delayGain.gain.value = .65
delayLine.connect( ctx.destination )
delayLine.connect( delayGain )
delayGain.connect( delayLine )
const reverb = ctx.createConvolver()
reverb.connect( ctx.destination )
const reverbInput = ctx.createGain()
reverbInput.gain.value = 1
reverbInput.connect( reverb )
const glock = { cmRatio:3.5307, index: 1, attack:.001, decay:1 }
fetch( './impulses/largeBrightPlate.wav' ).then(
response => response.arrayBuffer()
).then( audioData => {
ctx.decodeAudioData( audioData, buffer => {
reverb.buffer = buffer
const notes = [ 220, 440, 880, 1760 ]
let noteCount = 0
setInterval( ()=> {
playNote(
notes[noteCount++ % notes.length],
glock.cmRatio, glock.index, glock.attack, glock.decay
)
}, 500 )
})
})
const props = {
get 'delay time'() { return delayLine.delayTime.value },
set 'delay time'( v ) { delayLine.delayTime.value = v },
get feedback() { return delayGain.gain.value },
set feedback( v ) { delayGain.gain.value = v },
get 'reverb amount'() { return reverbInput.gain.value },
set 'reverb amount'( v ) { reverbInput.gain.value = v }
}
gui.add( props, 'delay time', .0001, .5 )
gui.add( props, 'feedback', .0, .99 )
gui.add( props, 'reverb amount', 0, 2 )
const playNote = function( frequency, cmRatio, index, attack, decay ) {
const carrier = ctx.createOscillator()
carrier.frequency.value = frequency
const mod = ctx.createOscillator()
mod.frequency.value = frequency * cmRatio
const modGain = ctx.createGain()
modGain.gain.value = frequency * index
mod.connect( modGain )
modGain.connect( carrier.frequency )
const envelope = ctx.createGain()
carrier.connect( envelope )
envelope.connect( ctx.destination )
envelope.connect( delayLine )
envelope.connect( reverbInput )
envelope.gain.value = 0
envelope.gain.linearRampToValueAtTime( .15, ctx.currentTime + attack )
envelope.gain.linearRampToValueAtTime( 0, ctx.currentTime + attack + decay )
mod.start()
carrier.start()
carrier.stop( ctx.currentTime + attack + decay )
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment