Skip to content

Instantly share code, notes, and snippets.

@bokmann
Created June 1, 2012 03:34
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save bokmann/2848498 to your computer and use it in GitHub Desktop.
FM Synthesis with portaudio and ruby noise
# FM Synthesis code I wrote whole dorking out with
# https://github.com/awwaiid/ruby-noise
# first, lets define some variables we can use
harmonic_ratio = 1.5 # overtones involving the perfect 5th
#harmonic_ratio = 1.33 # overtones involving the perfect 4th
#harmonic_ratio = 1.25 # overtones involving the major 3rd
#harmonic_ratio = 1.2 # overtones involving the minor 3rd
# harmonic ratios close to these values introduce a wobble
# characteristic of analog synthesizers. Diverge much
# and they begin to sound metallic.
#the 12th root of 2 doesn't get nearly the respect as pi, e or i, but wait till
# you see what it does...
halfstep = 1.059#46309
# an arbitrary number that is used in fm synthesis
harmonic_strength = 1000
# the note 'A'. I think 44 is the one below middle C...
a = 440
# The frequency Modulation Equation:
# http://cnx.org/content/m15482/latest/
# y(t)= sin(2 * pi * carrier_frequency + modulation_index * sin(2 * pi * modulation_frequency t))
# Note that this is just one among many. The Yamaha DX7 synthesizer has 32
# variations of this that involve up to 6 sine wave generators.
def fm(carrier_freq, modulation_index, modulation_freq)
carrier_freq = genize carrier_freq
modulation_index = genize modulation_index
modulator = sine(modulation_freq)
sine(lambda {carrier_freq.call + (modulation_index.call * modulator.call)})
end
# uncomment and play with values for the harmonic strength and ratio.
# play (
# fm(a, harmonic_strength, a * harmonic_ratio)
# )
#
# ahh, the power of envelopes. In this case, we also envelope the harmonic strength.
# play(
# envelope(fm(note, envelope(harmonic_strength,1,0,3), a * harmonic_ratio), 0.1, 3, 0.4),
# )
# and now your $3000 computer can imitate a used 1980's era synthesizer
def glass_violin(note)
harmonic_ratio = 1.5
harmonic_strength = 1000
envelope(fm(note, envelope(harmonic_strength,0.5,0,1), note * harmonic_ratio), 0.1, 1, 0.4)
end
#huh? wha? Where'd those notes come from?
play(
seq([
glass_violin(a * (halfstep ** 0)),
glass_violin(a * (halfstep ** 2)),
glass_violin(a * (halfstep ** 4)),
glass_violin(a * (halfstep ** 5)),
glass_violin(a * (halfstep ** 7)),
glass_violin(a * (halfstep ** 9)),
glass_violin(a * (halfstep ** 11)),
glass_violin(a * (halfstep ** 12)),
])
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment