Skip to content

Instantly share code, notes, and snippets.

@catfact
Last active December 7, 2019 22:26
Show Gist options
  • Select an option

  • Save catfact/954e5658fa010269793e5f8dd5960ab8 to your computer and use it in GitHub Desktop.

Select an option

Save catfact/954e5658fa010269793e5f8dd5960ab8 to your computer and use it in GitHub Desktop.
norns hackalong drumf
local ControlSpec = require "controlspec"
local specs = {}
specs.pitch_base = ControlSpec.new(10, 20000, "exp", 0, 55, "Hz")
specs.pitch_env_ratio = ControlSpec.new(0, 8, "lin", 0, 1)
specs.fm_ratio = ControlSpec.new(0.01, 10, "lin", 0, 1.5)
specs.fm_mod = ControlSpec.new(0, 20, "lin", 0, 0)
specs.noise_rate = ControlSpec.new(10, 20000, "exp", 0, 10, "hz")
specs.noise_shape = ControlSpec.new(0, 2, "lin", 0, 0)
specs.osc_level = ControlSpec.new(0, 1, "lin", 0, 1)
specs.noise_level = ControlSpec.new(0, 1, "lin", 0, 1)
specs.noise_amp_env_atk = ControlSpec.new(0.001, 8, "exp", 0, 0.001, "s")
specs.noise_amp_env_sus = ControlSpec.new(0.0001, 8, "exp", 0, 0.001, "s")
specs.noise_amp_env_rel = ControlSpec.new(0.001, 8, "exp", 0, 0.001, "s")
specs.osc_amp_env_atk = ControlSpec.new(0.001, 8, "exp", 0, 0.1, "s")
specs.osc_amp_env_sus = ControlSpec.new(0.0001, 8, "exp", 0, 0.001, "s")
specs.osc_amp_env_rel = ControlSpec.new(0.001, 8, "exp", 0, 0.1, "s")
specs.pitch_env_atk = ControlSpec.new(0.001, 8, "exp", 0, 0.001, "s")
specs.pitch_env_sus = ControlSpec.new(0.001, 8, "exp", 0, 0.001, "s")
specs.pitch_env_rel = ControlSpec.new(0.001, 8, "exp", 0, 0.1, "s")
specs.fc_env_atk = ControlSpec.new(0.001, 8, "exp", 0, 0.001, "s")
specs.fc_env_sus = ControlSpec.new(0.0001, 8, "exp", 0, 0.001, "s")
specs.fc_env_rel = ControlSpec.new(0.001, 8, "exp", 0, 0.1, "s")
specs.fc_env_ratio = ControlSpec.new(0, 8, "lin", 0, 1)
specs.fc_base = ControlSpec.new(10, 20000, "exp", 0, 10, "hz")
specs.filter_gain = ControlSpec.new(0, 10, 'lin', 0, 1)
local NUM_VOICES = 4
local command_names = {
"pitch_base",
"pitch_env_ratio",
"fm_ratio",
"fm_mod",
"noise_rate",
"noise_shape",
"osc_level",
"noise_level",
"noise_amp_env_atk",
"noise_amp_env_sus",
"noise_amp_env_rel",
"osc_amp_env_atk",
"osc_amp_env_sus",
"osc_amp_env_rel",
"pitch_env_atk",
"pitch_env_sus",
"pitch_env_rel",
"fc_env_atk",
"fc_env_sus",
"fc_env_rel",
"fc_env_ratio",
"fc_base",
"filter_gain"
}
local NUM_COMMANDS = #command_names
local function add_params()
local com_name
local param_name
local action_fn
local spec
for voice=1,NUM_VOICES do
for com_idx=1, NUM_COMMANDS do
com_name = command_names[com_idx]
param_name = ""..voice.."_"..com_name
action_fn = function(value)
engine[com_name](voice, value)
end
spec = specs[com_name]
print('adding parameter; com name: ' .. com_name .. '; param name: ' ..param_name)
params:add{
type='control',
controlspec=spec,
id=param_name,
name=param_name,
action=action_fn
}
end
end
end
Drumf = {}
Drumf.specs = specs
Drumf.add_params = add_params
Drumf.NUM_COMMANDS = NUM_COMMANDS
return Drumf
--- hello drumf
--- BADD
--- it overwrites the 'engine' global!!
--- engine = 'Drumf'
-- GOOD
-- set the 'name' field in the engine global
engine.name = 'Drumf'
local drumf = include('drumf.lua')
function init()
engine.list_commands()
drumf.add_params()
end
-- trigger drums with keys 2, 3
function key(n,z)
if n > 1 then
if z == 1 then
engine.trig(n-1)
end
end
end
-- change filter envelope amount with encoders 2 and 3
function enc(n, d)
if n == 2 then
params:delta("1_fc_env_ratio", d)
end
if n == 3 then
params:delta("2_fc_env_ratio", d)
end
end
function redraw()
screen.clear()
screen.move(1, 10)
screen.text("drumf")
screen.update()
end
Engine_Drumf : CroneEngine {
classvar <numVoices = 4;
var <trig_bus;
var <drum_synth;
var <drum_def;
*new { arg context, doneCallback;
^super.new(context, doneCallback);
}
alloc {
var synth_param_names;
var s = context.server;
Routine {
// make a synthdef
drum_def = SynthDef.new(\better_drumf, {
arg out=0, trig_bus, amp=0.25,
pitch_base=55,
fm_ratio=2.0, fm_mod=2.0, noise_rate=10000,
noise_shape=0,
osc_level = 1.0,
noise_level = 1.0,
noise_amp_env_atk=0.01,
noise_amp_env_sus=0.1,
noise_amp_env_rel=0.2,
osc_amp_env_atk=0.01,
osc_amp_env_sus=0.1,
osc_amp_env_rel=0.2,
pitch_env_atk=0.01,
pitch_env_sus=0.0,
pitch_env_rel=0.3,
pitch_env_ratio=2,
fc_env_atk=0.01,
fc_env_sus=0.0,
fc_env_rel=0.3,
fc_env_ratio=2,
fc_base = 1000,
filter_gain=1;
/*
gain_env_atk=0.01,
gain_env_sus=0.0,
gain_env_rel=0.3;*/
var gate, snd, osc, noise,
noise_amp, osc_amp, pitch,
noise_amp_env, osc_amp_env, pitch_env, fc_env, fc;
gate = InTrig.kr(trig_bus);
noise_amp_env = Env.linen(noise_amp_env_atk, noise_amp_env_sus, noise_amp_env_rel);
osc_amp_env = Env.linen(osc_amp_env_atk, osc_amp_env_sus, osc_amp_env_rel);
pitch_env = Env.linen(pitch_env_atk, pitch_env_sus, pitch_env_rel);
fc_env = Env.linen(fc_env_atk, fc_env_sus, fc_env_rel);
pitch = pitch_base * (1.0 + (pitch_env_ratio * EnvGen.ar(pitch_env, gate)));
noise_amp = EnvGen.ar(noise_amp_env, gate);
osc_amp = EnvGen.ar(osc_amp_env, gate);
fc = fc_base * (1.0 + (fc_env_ratio * EnvGen.ar(fc_env, gate)));
osc = SinOsc.ar(pitch, SinOsc.ar(pitch * fm_ratio) * fm_mod).distort;
osc = osc * osc_amp * osc_level;
noise = SelectX.ar(noise_shape, [
LFNoise0.ar(noise_rate),
LFNoise1.ar(noise_rate),
LFNoise2.ar(noise_rate)
]);
noise = noise * noise_amp * noise_level;
snd = osc + noise;
snd = MoogFF.ar(snd, fc, filter_gain);
Out.ar(out, snd*amp);
}).send(s);
// send to the server
drum_def.send(s);
// make a control bus for triggers
trig_bus = Array.fill(numVoices, {
Bus.control(s)
});
s.sync;
// make a synth lookin at the bus
drum_synth = Array.fill(numVoices, {
arg i;
Synth.new(\better_drumf, [\trig_bus, trig_bus[i].index], s);
});
}.play;
this.addCommand("trig", "i", {
arg msg;
var i = msg[1];
postln(msg);
trig_bus[i].set(1.0);
});
synth_param_names = [
\pitch_base,
\pitch_env_ratio,
\fm_ratio,
\fm_mod,
\noise_rate,
\noise_shape,
\osc_level ,
\noise_level ,
\noise_amp_env_atk,
\noise_amp_env_sus,
\noise_amp_env_rel,
\osc_amp_env_atk,
\osc_amp_env_sus,
\osc_amp_env_rel,
\pitch_env_atk,
\pitch_env_sus,
\pitch_env_rel,
\fc_env_atk,
\fc_env_sus,
\fc_env_rel,
\fc_env_ratio,
\fc_base,
\filter_gain
];
synth_param_names.do({ arg name;
this.addCommand(name, "if", {
arg msg;
var idx, value;
postln(msg);
idx = msg[1] - 1;
if((idx > 0) && (idx < numVoices), {
value = msg[2];
drum_synth[idx].set(name, value);
});
});
});
}
}
@catfact
Copy link
Author

catfact commented Sep 28, 2019

install:

dust/code/drumf/drumf.lua
dust/code/drumf/lib/drumf_params.lua
dust/code/drumf/lib/Engine_Drumf.lua

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment