Created
June 1, 2012 03:34
-
-
Save bokmann/2848498 to your computer and use it in GitHub Desktop.
FM Synthesis with portaudio and ruby noise
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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