public
Created

FM Synthesis with portaudio and ruby noise

  • Download Gist
ruby-noise-addendum.rm
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
# 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)),
])
)

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.