Skip to content

Instantly share code, notes, and snippets.

@mimetaur
Created February 20, 2019 17:45
Show Gist options
  • Save mimetaur/579070c471f252b524c921dcdef82cd0 to your computer and use it in GitHub Desktop.
Save mimetaur/579070c471f252b524c921dcdef82cd0 to your computer and use it in GitHub Desktop.
Limits of Guitar Study #1: Harmonic Sequences
-- harmonics
engine.name = "Sines"
function init()
root_note = 30
base_freq = midi_to_hz(root_note)
freqs = {}
amps = {}
levels = {}
num_harmonics = 12
release_time = 5
generate_new_random_harmonics()
is_playing = false
note_playing = false
pulse_rate = 0.75
pulse = metro.alloc(play_note, pulse_rate, -1)
is_changing = false
change_rate = 2.0
harmonic_changes = metro.alloc(generate_new_random_harmonics, change_rate, -1)
end
function redraw()
screen.clear()
draw_harmonics()
draw_play_status()
draw_change_status()
screen.update()
end
function draw_harmonics()
screen.move(10, 10)
screen.level(10)
screen.text("Harmonics")
for i = 1, num_harmonics do
screen.move(10 * i, 20)
screen.level(levels[i])
screen.text("#")
end
end
function draw_play_status()
play_level = 2
if is_playing then
play_level = 12
end
screen.move(10, 60)
screen.level(play_level)
screen.text("P")
screen.move(20, 60)
pr = math.ceil(util.linlin(0.25, 2, 1, 10, pulse_rate))
screen.text(pr)
end
function draw_change_status()
change_level = 2
if is_changing then
change_level = 12
end
screen.move(40, 60)
screen.level(change_level)
screen.text("C")
screen.move(50, 60)
cr = math.ceil(util.linlin(0.25, 5, 1, 10, change_rate))
screen.text(cr)
end
function play_note()
if note_playing then
silence_harmonics()
note_playing = false
else
play_harmonics()
note_playing = true
end
end
function key(n, z)
if n == 2 and z == 1 then
if (is_playing == false) then
pulse:start()
is_playing = true
else
is_playing = false
pulse:stop()
silence_harmonics()
end
end
if n == 3 and z == 1 then
if (is_changing) then
harmonic_changes:stop()
is_changing = false
else
harmonic_changes:start()
is_changing = true
end
end
redraw()
end
function enc(n, d)
if (n == 2) then
pr = util.linlin(0, 2, 1, 10, pulse_rate)
pr = util.clamp(pr + d, 1, 10)
pulse_rate = util.linlin(1, 10, 0.25, 2, pr)
pulse.time = pulse_rate
end
if (n == 3) then
cr = util.linlin(0, 5, 1, 10, change_rate)
cr = util.clamp(cr + d, 1, 10)
change_rate = util.linlin(1, 10, 0.25, 5, cr)
harmonic_changes.time = change_rate
end
redraw()
end
function play_harmonics()
local f_debug = "Freqs: "
for i = 1, num_harmonics do
engine.amp_atk(i, 1)
engine.amp(i, amps[i])
engine.hz(i, freqs[i])
f_debug = f_debug .. freqs[i]
end
print(f_debug)
end
function silence_harmonics()
for i = 1, num_harmonics do
engine.amp(i, 0)
end
end
function generate_new_random_harmonics()
for i = 1, num_harmonics do
freqs[i] = base_freq * i
local r = math.random()
amps[i] = util.linexp(0, 1, 0.2, 0.8, r)
-- levels is for visual representation of harmonic strength
levels[i] = math.floor(util.linlin(0, 1, 1, 14, r))
engine.amp_rel(i, release_time)
end
redraw()
end
function midi_to_hz(note)
return (440 / 32) * (2 ^ ((note - 9) / 12))
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment