-- midi fm rhodes -- -- key 2: play a C4 engine.name = "Rhodes" local MusicUtil = require "musicutil" local ControlSpec = require "controlspec" local _dirname function dir(f) if not _dirname then source = string.gsub(debug.getinfo(1,'S').source, "@", "") _dirname = string.gsub(source, "[^/.]+.lua", "") end return _dirname.."/"..f end function redraw(level) screen.clear(); screen.display_png(dir("rhodes.png"), 0, 0); -- draw the jewel light level meter -- do this here so it won't overdraw the screen screen.circle(104, 32, 6) screen.level(math.floor(level or 0)) screen.fill() screen.circle(104, 32, 6) screen.level(15) screen.stroke() screen.update() end function init () local mod_wheel_controls = 2 local base_mod_index = 0.1 local base_trem_speed = 2.0 local base_trem_depth = 0.1 local operator_mix = 0.2 local m = nil local midi_event = function (a) b = midi.to_msg(a) if b.type == "note_on" then engine.note_on(b.note, b.vel or 60) elseif b.type == "note_off" then engine.note_off(b.note) end -- mod wheel if b.type == "cc" and b.ch == 1 then if mod_wheel_controls == 1 then engine.set_mod_index(base_mod_index + (b.val / 127) * (1.0 - base_mod_index)) elseif mod_wheel_controls == 2 then engine.set_lfo_speed(base_trem_speed + (b.val / 127) * (60.0 - base_trem_speed)) elseif mod_wheel_controls == 3 then engine.set_lfo_depth(base_trem_depth + (b.val / 127) * (1.0 - base_trem_depth)) end end end -- midi settings params:add({ type = "option", id = "mod_controls", name = "Mod Wheel", default = mod_wheel_controls, options={"Mod Index", "Tremolo Speed", "Tremolo Depth"}, action = function(value) do mod_wheel_controls = value; engine.set_mod_index(base_mod_index); engine.set_lfo_speed(base_trem_speed); engine.set_lfo_depth(base_trem_depth); end end}) params:add({ type = "control", id = "midi_in_vport", name = "Midi In", default=60, controlspec = ControlSpec.new(1, 4, 'lin', 1, 1), action = function(value) -- clear the old connection if m then m.event = nil end m = midi.connect(value) m.event = midi_event end}) params:add_separator() -- modulation settings params:add({ type = "control", id = "base_mod_index", name = "Mod Index", controlspec = ControlSpec.new(0.0, 100.0, 'lin', 0.5, base_mod_index * 100.0, "%"), action = function(value) do base_mod_index = value/100.0; engine.set_mod_index(value/100.0); end end}) params:add({ type = "control", id = "operator_mix", name = "Operator Mix", controlspec = ControlSpec.new(0.0, 100.0, 'lin', 0.1, operator_mix * 100.0, "%"), action = function(value) do operator_mix = value/100.0; engine.set_mix(value/100.0); end end}) params:add_separator() -- tremolo params:add({ type = "control", id = "base_trem_speed", name = "Tremolo Speed", controlspec = ControlSpec.new(0.001, 60.0, 'lin', 0.1, base_trem_speed, "hz"), action = function(value) do base_trem_speed = value; engine.set_lfo_speed(value); end end}) params:add({ type = "control", id = "base_trem_depth", name = "Tremolo Depth", controlspec = ControlSpec.new(0.00, 100.0, 'lin', 0.1, base_trem_depth * 100.0, "%"), action = function(value) do base_trem_depth = value/100.0; engine.set_lfo_depth(value/100.00); end end}) params:default() redraw() -- set a poll to draw the jewel light level meter p = poll.set("amp_out_l") p.callback = function (val) -- log this so it trails off naturally level = math.log(10 * val + 1) * 15; -- actually draw it in redraw, so it won't -- draw over the menu redraw(level) end p.time = 0.025 p:start() end function key (n, x) if n == 2 and x == 1 then engine.note_on(60, 50) elseif n == 2 and x == 0 then engine.note_off(60) end end -- Local Variables: -- compile-command: "make upload" -- End: