https://www.youtube.com/watch?v=s8nFqwOho-s http://mercury.sexy/hg_sdf/
-
first synthetic instrument
- additive synthesis, like the Hammond organ (b3)
- transmitted music over phone lines
- early Musak
- Mark I: 7 Tons
- Mark II: 200 Tons
- $200,000 in 1906 (close to 5 million today)
- 36 note per octave keyboard (Cahill liked just intonation)
-
Other important digital musical instruments
- Theremin
- Buchla vs. Moog
- West Coast vs East Coast
- Wendy Carlos
- Switched on Bach
- Scores for Tron, A Clockwork Orange, The Shining
- Start from waveform rich in overtones / harmonics
- Emphasize / De-emphasize various frequencies
- We do this via "filters"
- Filters are typically high-pass, low-pass, bandpass, or notch
- Filters also have a Q, or "quality" control, that can emphasize the
cutoff frequency
- On some synthesizers this was called resonance.
- We do this via "filters"
An enveloped oscillator with frequency assigned to mouse control:
<!doctype html>
<html lang='en'>
<body></body>
<script src='./tonal.min.js'></script>
<script>
window.onload = function() {
const scale = Tonal.Scale.notes( 'c4', 'minor' )
const ctx = new AudioContext()
const playNote = function( frequency, amp, attack, decay ) {
const osc = ctx.createOscillator()
osc.type = 'sawtooth'
osc.frequency.value = frequency
const gainNode = ctx.createGain()
gainNode.gain.setValueAtTime( 0, ctx.currentTime )
gainNode.gain.linearRampToValueAtTime( amp, ctx.currentTime + attack )
gainNode.gain.linearRampToValueAtTime( 0, ctx.currentTime + attack + decay )
osc.connect( gainNode )
gainNode.connect( ctx.destination )
osc.start()
osc.stop( ctx.currentTime + attack + decay )
}
window.onclick = evt => {
//const freq = 100 + (evt.clientY / window.innerHeight) * 1000
const idx = Math.floor( evt.clientY / window.innerHeight * scale.length )
const freq = Tonal.freq( scale[ idx ] )
playNote( freq, evt.clientX / window.innerWidth, .001, .15 )
}
}
</script>
</html>ctx = new AudioContext()
playNote = function( frequency, amp, attack, decay, cutoff, Q ) {
var osc = ctx.createOscillator()
osc.type = 'sawtooth'
osc.frequency.value = frequency
// create gain node to control amplitude
var gainNode = ctx.createGain()
gainNode.gain.setValueAtTime( 0, ctx.currentTime )
gainNode.gain.linearRampToValueAtTime( amp, ctx.currentTime + attack )
gainNode.gain.linearRampToValueAtTime( 0, ctx.currentTime + attack + decay )
var filter = ctx.createBiquadFilter()
filter.type = 'lowpass'
filter.frequency.value = cutoff
filter.Q.value = Q
osc.connect( gainNode )
gainNode.connect( filter )
filter.connect( ctx.destination )
osc.start()
osc.stop( ctx.currentTime + attack + decay )
}
// 220 Hz, .5 amplitude
// 1 second attack, 1 second decay
playNote( 220, .5, 1, 1, 800, 10 )ctx = new AudioContext()
playNote = function( frequency, amp, attack, decay, cutoff, Q ) {
var osc = ctx.createOscillator()
osc.type = 'sawtooth'
osc.frequency.value = frequency
// create gain node to control amplitude
var gainNode = ctx.createGain()
gainNode.gain.setValueAtTime( 0, ctx.currentTime )
gainNode.gain.linearRampToValueAtTime( amp, ctx.currentTime + attack )
gainNode.gain.linearRampToValueAtTime( 0, ctx.currentTime + attack + decay )
var filter = ctx.createBiquadFilter()
filter.type = 'lowpass'
filter.frequency.value = 50
filter.frequency.linearRampToValueAtTime( cutoff, ctx.currentTime + attack )
filter.frequency.linearRampToValueAtTime( 50, ctx.currentTime + attack + decay )
filter.Q.value = Q
osc.connect( gainNode )
gainNode.connect( filter )
filter.connect( ctx.destination )
osc.start()
osc.stop( ctx.currentTime + attack + decay )
}
playNote( 220, .5, .001, .5, 1500, 10 )