Sequencing
From Bennet
I'm using SuperCollider to implement the sequencer, but also looking at chuck because it looks juicy;).
There is still very much to do, but the major goals are achieved. The code needs cleanup and more generalizing.
This is how it works:
The client is using timestamped OSC messages, sent a little time before the event is scheduled to happen. This ensures exact timing and gives the synth server some time to set up the graph.
Each event reads from a bus when it's scheduled to trigger a synthesis network in the synth server. The value on this bus is exported from SuperCollider and may be set via MIDI/OSC.
Each synthesis graph on the server has its parameters exported as well, and may be realtime manipulated over MIDI/OSC.
In its most basic form, you're able to switch patterns (beats) on exact end of beat. This means you can change the drum loop or any part of the arrangement at any time. Each event object is also a separate instance, which means you can manipulate each event individually. You can use samples if you prefer, but I'm trying to do everything in synthesis, which I haven't actually to a pleasing state.
I've also started to look at using SuperCollider with Scheme
More to come..
Visit the project page to download the latest code:
//boot server
s.options.numControlBusChannels_(60000)
s=Server.local.boot;
(
~synth_variable_bus_array=Array.fill(48000,{Bus.control(s,1)}).reshape(4,4,10,15,20);
(//fundamental_frequency
//~synth_variable_bus_array[0][1][0][0][0].set(34.48818);
~synth_variable_bus_array[0][1][0][0][0].set(70);
~synth_variable_bus_array[0][1][0][0][0].get({arg value;a=value;(a).postln;});
~synth_variable_bus_array[0][1][0][0][1].set(74);
~synth_variable_bus_array[0][1][0][0][2].set(35);
~synth_variable_bus_array[0][1][0][0][3].set(35);
~synth_variable_bus_array[0][1][0][0][4].set(35);
~synth_variable_bus_array[0][1][0][0][5].set(35);
~synth_variable_bus_array[0][1][0][0][6].set(35);
~synth_variable_bus_array[0][1][0][0][7].set(35);
~synth_variable_bus_array[0][1][0][0][8].set(35);
~synth_variable_bus_array[0][1][0][0][9].set(35);
)
(//percussive_envelope_time0
~synth_variable_bus_array[0][1][1][0][0].set(0.002);
~synth_variable_bus_array[0][1][1][0][0].get({arg value;a=value;(a).postln;});
~synth_variable_bus_array[0][1][1][0][1].set(0.002);
~synth_variable_bus_array[0][1][1][0][2].set(0.002);
~synth_variable_bus_array[0][1][1][0][3].set(0.002);
~synth_variable_bus_array[0][1][1][0][4].set(0.002);
~synth_variable_bus_array[0][1][1][0][5].set(0.002);
~synth_variable_bus_array[0][1][1][0][6].set(0.002);
~synth_variable_bus_array[0][1][1][0][7].set(0.002);
~synth_variable_bus_array[0][1][1][0][8].set(0.002);
~synth_variable_bus_array[0][1][1][0][9].set(0.002);
)
(//percussive_envelope_time1 (global)
~synth_variable_bus_array[0][1][1][1][0].set(0.0015);
//percussive_envelope_time2 (global)
~synth_variable_bus_array[0][1][1][2][0].set(0.1);
//accent_envelope_0
~synth_variable_bus_array[0][1][2][0][0].set(0.005);
//accent_envelope_1
~synth_variable_bus_array[0][1][2][1][0].set(0.05);
//accent_envelope_2
~synth_variable_bus_array[0][1][2][2][0].set(0.07);
//gain_array_gain_0
~synth_variable_bus_array[0][1][3][0][0].set(0.95);
//gain_array_gain_1
~synth_variable_bus_array[0][1][3][1][0].set(0.24);
//gain_array_gain_2
~synth_variable_bus_array[0][1][3][2][0].set(0.75);
//gain_array_gain_3
~synth_variable_bus_array[0][1][3][3][0].set(0.6);
//gain_array_gain_4
~synth_variable_bus_array[0][1][3][4][0].set(0.55);
//gain_array_gain_5
~synth_variable_bus_array[0][1][3][5][0].set(0.5);
)
(//pitch array
~synth_variable_bus_array[0][1][4][0][0].set(0.007);
~synth_variable_bus_array[0][1][4][1][0].set(0.006);
~synth_variable_bus_array[0][1][4][2][0].set(0.009);
~synth_variable_bus_array[0][1][4][3][0].set(0.003);
~synth_variable_bus_array[0][1][4][4][0].set(0.002);
~synth_variable_bus_array[0][1][4][5][0].set(0.006);
)
(//
~synth_variable_bus_array[0][1][1][7][0].set(0.9);
~synth_variable_bus_array[0][1][1][8][0].set(0.24);
~synth_variable_bus_array[0][1][1][9][0].set(0.75);
~synth_variable_bus_array[0][1][1][10][0].set(0.6);
~synth_variable_bus_array[0][1][1][11][0].set(0.55);
~synth_variable_bus_array[0][1][1][12][0].set(0.5);
)
(//sett første til 0.6 eller 0.9 for en phat stomping bass
~synth_variable_bus_array[0][1][1][0][0].set(0.002);//perc_env0 (0.002)
~synth_variable_bus_array[0][1][1][1][0].set(0.0035);//perc_env1
~synth_variable_bus_array[0][1][1][2][0].set(0.004);//perc_env2
~synth_variable_bus_array[0][1][1][3][0].set(0.0021);//acc_env0
~synth_variable_bus_array[0][1][1][4][0].set(0.0024);//acc_env1
~synth_variable_bus_array[0][1][1][5][0].set(0.02);//acc_env2
)
//NO USE//15.do({|i| ~synth_variable_bus_array[0][i+1] = 1.3});
//fill-it -- ~synth_variable_bus_array[2][0][1][0][(0..15)].do({|n|n.set(0.045);});
//test
//~synth_variable_bus_array[2][0][1][0][0].get({arg value;a=value;(a).postln;});
//~synth_variable_bus_array[2][0][1][0][1].get({arg value;a=value;(a).postln;});
~constant_bus_array=Array.fill(20,{Bus.control(s,1)});
~constant_bus_array[0].set(0.045);//minimum gain for 2000
~constant_bus_array[1].set(1.6);
(
~synth_variable_bus_array[2][0][1][0][0].set(0.025);
~synth_variable_bus_array[2][0][1][0][1].set(0.025*~the_golden_ratio);
~synth_variable_bus_array[2][0][1][0][2].set(0.025);
~synth_variable_bus_array[2][0][1][0][3].set(0.025*~the_golden_ratio);
~synth_variable_bus_array[2][0][1][0][4].set(0.025);
~synth_variable_bus_array[2][0][1][0][5].set(0.025*~the_golden_ratio);
~synth_variable_bus_array[2][0][1][0][6].set(0.025);
~synth_variable_bus_array[2][0][1][0][7].set(0.025*~the_golden_ratio);
~synth_variable_bus_array[2][0][1][0][8].set(0.025);
~synth_variable_bus_array[2][0][1][0][9].set(0.025*~the_golden_ratio);
~synth_variable_bus_array[2][0][1][0][10].set(0.025);
~synth_variable_bus_array[2][0][1][0][11].set(0.025*~the_golden_ratio);
~synth_variable_bus_array[2][0][1][0][12].set(0.025);
~synth_variable_bus_array[2][0][1][0][13].set(0.025*~the_golden_ratio);
~synth_variable_bus_array[2][0][1][0][14].set(0.025);
~synth_variable_bus_array[2][0][1][0][15].set(0.025*~the_golden_ratio);
)
(
~groove_coefficient=0.007;
~foo_event_array=Array.fill(20,{Array.newClear(20)});
~foo_event_array=[0.0,0.5,2.0,2.5,4.0,4.48,5.89,6.0,6.538,7.38];
//~foo_event_array=[0.0,0.5,2.0,2.5,4.0,4.5,6.0,6.5,7.5]+~groove_coefficient;
~foo_event_array[0]=0.0;
//post values
(
~foo_event_array[0].postln;
~foo_event_array[1].postln;
~foo_event_array[2].postln;
~foo_event_array[3].postln;
~foo_event_array[4].postln;
~foo_event_array[5].postln;
~foo_event_array[6].postln;
~foo_event_array[7].postln;
)
//session_uno
// 0.0039370078740157
// 0.50629921259843
// 2.0125984251969
// 2.4952755905512
// 4.0173228346457
// 4.4913385826772
// 5.940157480315
// 6.0637795275591
// 6.0637795275591
~bar_event_array=Array.fill(20,{Array.newClear(20)});
~bar_event_array=[0.97,3.02,5.0,7.02];
//~bar_event_array=[1.0,3.0,5.0,7.0]-~groove_coefficient;
~bat_event_array=Array.fill(20,{Array.newClear(20)});
~bat_event_array=
[
0.0+~groove_coefficient,
0.5-~groove_coefficient,
1.0+~groove_coefficient,
1.5-~groove_coefficient,
2.0+~groove_coefficient,
2.5-~groove_coefficient,
3.0+~groove_coefficient,
3.5-~groove_coefficient,
4.0+~groove_coefficient,
4.5-~groove_coefficient,
5.0+~groove_coefficient,
5.5-~groove_coefficient,
6.0+~groove_coefficient,
6.5-~groove_coefficient,
7.0+~groove_coefficient,
7.5-~groove_coefficient
];
~the_golden_ratio=(1+sqrt(5))/2;
~fundamental_slap_frequency=~fundamental_punch_frequency*~the_golden_ratio;
//~instance_array=Array.fill(20,{Array.newClear(20)});
~instance_array=Array.fill(20,{Array.fill(20, Array.fill(20,Array.newClear(20)))});
~synthesis_network_array=Array.fill(50,{Array.fill(50,{Array.newClear(50)})});
~synthesis_network_array[0][9][34]=\brave_blue_world;
~synthesis_network_array[0][9][35]=\soldier_of_b0rkness;
~synthesis_network_array[0][9][40]=\chloe_lection;
~synthesis_network_array[0][9][42]=\ventrical_entity;
~synthesis_network_array[0][9][43]=\nostril_damus;
)
~task_array=Array.fill(20,{Array.newClear(20)});
~task_array[0][0]=\foo0_task;
~task_array[0][1]=\foo1_task;
~task_array[1][0]=\bar0_task;
~task_array[2][0]=\bat0_task;
~task_array[2][1]=\hukarz0_task;
// \bat2_task
// \bat2_taskold
// \bat3_task
// \hukarz1_task
// \baz1_task
// \boo1_task
// \gazonk1_task
// \quux1_task
// \xyzzy1_task
// \shme1_task
//for the busless one
~variable_array=Array.fill(20,{Array.newClear(20)});
~variable_array[0][0]=40;
~variable_array[1][0]=0.2;
(
Tdef(
~task_array[0][0],
{
var clock_beat_start;
loop
{
clock_beat_start=thisThread.clock.beats;
s.makeBundle
(
0.25,
{
//1-0.15
~instance_array[0][0][0][x]=Synth(~synthesis_network_array[0][9][34]);
//~instance_array[0][x].map(\initial_frequency,~synth_variable_bus_array[0][x].index);
//~instance_array[0][x].map(\decay,~synth_variable_bus_array[1][x].index);
//m.noteOn(1,1,60);
}
);
(clock_beat_start+8.0-thisThread.clock.beats).wait;
}
})
)
(
Tdef(
~task_array[0][1],
{
var clock_beat_start,clock_beat_round_up;
loop
{
clock_beat_start=thisThread.clock.beats;
clock_beat_round_up=thisThread.clock.beats.roundUp(1);
x=0;
~foo_event_array[(0..9)].do
(
{
|elem,n|
thisThread.clock.schedAbs
(
clock_beat_round_up+elem,
{
s.makeBundle
(
0.25,
{
~instance_array[0][1][0][x]=Synth(~synthesis_network_array[0][9][35]);
~instance_array[0][1][0][x].map(\fundamental_frequency,~synth_variable_bus_array[0][1][0][0][0].index);
~instance_array[0][1][0][x].map(\percussive_envelope_time0,~synth_variable_bus_array[0][1][1][0][0].index);
~instance_array[0][1][0][x].map(\percussive_envelope_time1,~synth_variable_bus_array[0][1][1][1][0].index);
~instance_array[0][1][0][x].map(\percussive_envelope_time2,~synth_variable_bus_array[0][1][1][2][0].index);
~instance_array[0][1][0][x].map(\accent_envelope_time0,~synth_variable_bus_array[0][1][2][0][0].index);
~instance_array[0][1][0][x].map(\accent_envelope_time1,~synth_variable_bus_array[0][1][2][1][0].index);
~instance_array[0][1][0][x].map(\accent_envelope_time2,~synth_variable_bus_array[0][1][2][2][0].index);
~instance_array[0][1][0][x].map(\gain_array_gain0,~synth_variable_bus_array[0][1][3][0][0].index);
~instance_array[0][1][0][x].map(\gain_array_gain1,~synth_variable_bus_array[0][1][3][1][0].index);
~instance_array[0][1][0][x].map(\gain_array_gain2,~synth_variable_bus_array[0][1][3][2][0].index);
~instance_array[0][1][0][x].map(\gain_array_gain3,~synth_variable_bus_array[0][1][3][3][0].index);
~instance_array[0][1][0][x].map(\gain_array_gain4,~synth_variable_bus_array[0][1][3][4][0].index);
~instance_array[0][1][0][x].map(\gain_array_gain5,~synth_variable_bus_array[0][1][3][5][0].index);
~instance_array[0][1][0][x].map(\pitch_array_dur0,~synth_variable_bus_array[0][1][4][0][0].index);
~instance_array[0][1][0][x].map(\pitch_array_dur1,~synth_variable_bus_array[0][1][4][1][0].index);
~instance_array[0][1][0][x].map(\pitch_array_dur2,~synth_variable_bus_array[0][1][4][2][0].index);
~instance_array[0][1][0][x].map(\pitch_array_dur3,~synth_variable_bus_array[0][1][4][3][0].index);
~instance_array[0][1][0][x].map(\pitch_array_dur4,~synth_variable_bus_array[0][1][4][4][0].index);
~instance_array[0][1][0][x].map(\pitch_array_dur5,~synth_variable_bus_array[0][1][4][5][0].index);
//m.noteOn(1,1,60);
//x.postln;
x=x+1;
}
);
}
);
}
);
(clock_beat_start+8.0-thisThread.clock.beats).wait;
}
}
)
)
(
Tdef(
~task_array[1][0],
{
var clock_beat_start,clock_beat_round_up;
loop
{
clock_beat_start=thisThread.clock.beats;
clock_beat_round_up=thisThread.clock.beats.roundUp(1);
y=0;
~bar_event_array[(0..3)].do
(
{
|elem,n|
thisThread.clock.schedAbs
(
clock_beat_round_up+elem,
{
s.makeBundle
(
0.25,
{
~instance_array[1][0][0][x]=Synth(~synthesis_network_array[0][9][40]);
//~instance_array[1][x].map(\initial_frequency,~synth_variable_bus_array[0][x].index);
//~instance_array[1][x].map(\decay,~synth_variable_bus_array[1][x].index);
//m.noteOn(1,1,60);
//x.postln;
y=y+1;
}
);
}
);
}
);
(clock_beat_start+8.0-thisThread.clock.beats).wait;
}
}
)
)
(
Tdef(
~task_array[2][0],
{
var clock_beat_start,clock_beat_round_up;
loop
{
clock_beat_start=thisThread.clock.beats;
clock_beat_round_up=thisThread.clock.beats.roundUp(1);
w=0;
~bat_event_array[(0..15)].do
(
{
|elem,n|
thisThread.clock.schedAbs
(
clock_beat_round_up+elem,
{
s.makeBundle
(
0.25,
{
~instance_array[2][0][0][w]=Synth(~synthesis_network_array[0][9][42]);
~instance_array[2][0][0][w].map(\amp,~synth_variable_bus_array[2][0][0][w].index);
//m.noteOn(1,1,60);
//w.postln;
w=w+1;
}
);
}
);
}
);
(clock_beat_start+8.0-thisThread.clock.beats).wait;
}
}
)
)
////////////////////////No buses allowed
(
Tdef(
~task_array[2][1],
{
var clock_beat_start,clock_beat_round_up;
loop
{
clock_beat_start=thisThread.clock.beats;
clock_beat_round_up=thisThread.clock.beats.roundUp(1);
x=0;
~foo_event_array[(0..9)].do
(
{
|elem,n|
thisThread.clock.schedAbs
(
clock_beat_round_up+elem,
{
s.makeBundle
(
0.25,
{
~instance_array[0][1][0][x]=Synth(~synthesis_network_array[0][9][35],
[
"fundamental_frequency",~variable_array[0][0],
"decay",~variable_array[1][0];
]
);
//~instance_array[0][1][0][x].map(\initial_frequency,~synth_variable_bus_array[0][1][0][x].index);
//~instance_array[0][1][0][x].map(\decay,~synth_variable_bus_array[0][1][1][x].index);
//t=~instance_array[0][1][0][x];
//~instance_array[0][1][0][x].set("initial_frequency",~variable_array[0][0];
//t.set("initial_frequency",~variable_array[0][0];
//m.noteOn(1,1,60);
//x.postln;
x=x+1;
}
);
}
);
}
);
(clock_beat_start+8.0-thisThread.clock.beats).wait;
}
}
)
)
(
//OSC sendbundle
s.sendBundle(nil,
//["/s_new","soldier_of_b0rkness",2000,1,0,\fundamental_frequency,323],
["/s_new","soldier_of_b0rkness",2000,1,0],
["/n_setn",2000,"fundamental_frequency",1001],
["/n_setn",2000,"membrane_mode_array",6,1,1.593,2.135,2.295,2.917,3.598],
["/n_setn",2000,"gain_array",6,0.95,0.85,0.7,0.45,0.25,0.25]
);
)

