Created
August 11, 2021 19:43
-
-
Save cfdrake/a0312eaff1d892d745aedb14a846888e to your computer and use it in GitHub Desktop.
wrms + passersby
This file contains hidden or 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
-- | |
-- wrms/lite | |
-- | |
-- simple stereo delay & looper | |
-- | |
-- version 2.0.0 @andrew | |
-- https://norns.community/ | |
-- authors/andrew/ | |
-- wrms#wrmslite | |
-- | |
-- E1 changes which page | |
-- is displayed. pages contain | |
-- controls, mapped to the | |
-- lower keys and encoders. | |
-- the location of the control | |
-- (left, right, center) | |
-- shows which wrm will be | |
-- affected. | |
-- | |
-- wrm 1 (on the left) is a delay | |
-- & wrm 2 (on the right) is a | |
-- live looper. feed the wrms | |
-- some audio to begin exploring! | |
-- tap K3 once to begin | |
-- recording a loop, then again | |
-- to begin playback. | |
-- | |
-- for documentation of each | |
-- control, head to: | |
-- https://norns.community/ | |
-- authors/andrew/ | |
-- wrms#wrmslite | |
local MusicUtil = require "musicutil" | |
local Passersby = include("passersby/lib/passersby_engine") | |
engine.name = "Passersby" | |
function r() norns.script.load(norns.script.state) end | |
--external libs | |
include 'wrms/lib/nest/core' | |
include 'wrms/lib/nest/norns' | |
include 'wrms/lib/nest/txt' | |
cartographer, Slice = include 'wrms/lib/cartographer/cartographer' | |
crowify = include 'wrms/lib/crowify/lib/crowify' .new(0.01) | |
cs = require 'controlspec' | |
wrms = include 'wrms/lib/globals' --saving, loading, values, etc | |
sc, reg = include 'wrms/lib/softcut' --softcut utilities | |
wrms.gfx = include 'wrms/lib/graphics' --graphics & animations | |
include 'wrms/lib/params' --create params | |
local x, y = wrms.pos.x, wrms.pos.y | |
local _rec = function(i) | |
return _txt.key.toggle { | |
n = 2, x = x[i][1], y = y.key, | |
label = 'rec', edge = 'falling', | |
v = function() return params:get('rec '..i) end, | |
action = function(s, v, t) | |
if t < 0.5 then params:set('rec '..i, v) | |
else params:delta('clear '..i, 1) end | |
end | |
} | |
end | |
local _trans = function(i, o) | |
return _txt.key.trigger { | |
label = { '<<', '>>' }, | |
edge = 'falling', | |
blinktime = 0.2, | |
n = { 2, 3 }, | |
y = y.key, x = { { x[i][1] }, { x[i][2] } }, | |
action = function(s, v, t, d, add, rem, l) | |
s.blinktime = sc.slew(i, t[add]) / 2 | |
if #l == 2 then | |
params:set('dir '..i, params:get('dir '..i)==1 and 2 or 1) | |
else | |
params:delta('oct '..i, add==2 and 1 or -1) | |
end | |
end | |
} :merge(o) | |
end | |
--the wrmslite template | |
wrms_ = nest_ { | |
gfx = _screen { | |
redraw = wrms.gfx.draw | |
}, | |
tab = _txt.enc.option { | |
n = 1, x = x.tab, y = y.tab, sens = 0.5, align = sh and 'right' or 'left', margin = 2, | |
flow = 'y', options = { 1, 2, 3 }, | |
lvl = { 4, 15 } | |
}, | |
pages = nest_ { | |
[1] = nest_ { | |
v = _txt.enc.control { | |
n = 2, x = x[1][1], y = y.enc, | |
} :param('vol 1'), | |
l = _txt.enc.number { | |
min = 0, max = math.huge, inc = 0.01, | |
n = 3, x = x[1][2], y = y.enc, step = 1/100/100/100, | |
value = function() return reg.play:get_length(1) end, | |
sens = function(s) | |
return sc.punch_in[sc.buf[1]].big and ( | |
s.p_.v <= 0.00019 and 1/100/100 or s.p_.v <= 0.019 and 1/100 or 1 | |
) or 1 | |
end, | |
action = function(s, v) | |
reg.play:set_length(1, v) | |
if v > 0 and not sc.punch_in[sc.buf[1]].recorded then | |
params:set('rec 1', 1, true) | |
sc.punch_in:manual(1) | |
end | |
sc.punch_in:big(1, v) | |
sc.fade(1, v) | |
sc.punch_in:untap(1) | |
end | |
}, | |
rec = _rec(2) | |
}, | |
[2] = nest_ { | |
old = nest_(2):each(function(i) | |
return _txt.enc.control { | |
n = i + 1, x = x[i][1], y = y.enc, label = 'old' | |
} :param('old '..i) | |
end), | |
rec = _rec(2) | |
}, | |
[3] = nest_ { | |
bnd = _txt.enc.control { | |
n = 2, x = x[1][1], y = y.enc, label = 'bnd', | |
min = -1, max = 1, | |
action = function(s, v) | |
sc.ratemx[1].bnd = v + 1 | |
sc.ratemx:update(1) | |
end | |
}, | |
wgl = _txt.enc.control { | |
n = 3, x = x[1.5], y = y.enc | |
} :param('wgl'), | |
trans = _trans(2, {}) | |
} | |
} :each(function(k, v) | |
v.enabled = function(s) return wrms_.tab.options[wrms_.tab.v//1] == k end | |
end) | |
} :connect { screen = screen, enc = enc, key = key } | |
function init() | |
params:set('>', 0) | |
params:set('<', 1) | |
params:set('input routing', 2) | |
wrms.setup() | |
params:read() | |
wrms.load() | |
params:bang() | |
wrms_:init() | |
pb_init() | |
end | |
local function note_on(note_num, vel) | |
engine.noteOn(note_num, MusicUtil.note_num_to_freq(note_num), vel) | |
table.insert(active_notes, note_num) | |
input_indicator_active = true | |
screen_dirty = true | |
end | |
local function note_off(note_num) | |
engine.noteOff(note_num) | |
for i = #active_notes, 1, -1 do | |
if active_notes[i] == note_num then | |
table.remove(active_notes, i) | |
end | |
end | |
if #active_notes == 0 then | |
input_indicator_active = false | |
screen_dirty = true | |
end | |
end | |
local function set_pitch_bend(bend_st) | |
engine.pitchBendAll(MusicUtil.interval_to_ratio(bend_st)) | |
end | |
local function set_channel_pressure(pressure) | |
engine.pressureAll(pressure) | |
end | |
local function set_channel_timbre(value) | |
engine.timbreAll(value) | |
timbre = value * 0.5 | |
wave_folds.dirty = true | |
end | |
local function midi_event(data) | |
local msg = midi.to_msg(data) | |
local channel_param = params:get("midi_channel") | |
if channel_param == 1 or (channel_param > 1 and msg.ch == channel_param - 1) then | |
-- Note on | |
if msg.type == "note_on" then | |
note_on(msg.note, msg.vel / 127) | |
-- Note off | |
elseif msg.type == "note_off" then | |
note_off(msg.note) | |
-- Pitch bend | |
elseif msg.type == "pitchbend" then | |
local bend_st = (util.round(msg.val / 2)) / 8192 * 2 -1 -- Convert to -1 to 1 | |
set_pitch_bend(bend_st * params:get("bend_range")) | |
-- Pressure | |
elseif msg.type == "channel_pressure" or msg.type == "key_pressure" then | |
set_channel_pressure(msg.val / 127) | |
end | |
end | |
end | |
function pb_init() | |
midi_in_device = midi.connect(1) | |
midi_in_device.event = midi_event | |
params:add_separator("Passersby") | |
Passersby.add_params() | |
end | |
function cleanup() | |
-- wrms.save() | |
params:write() | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment