Skip to content
This repository
Browse code

first commit with content

  • Loading branch information...
commit d168ea706107a28a0ee3276a5e4022fbdfad374b 0 parents
grirgz authored June 26, 2011
47  crap.sc
... ...
@@ -0,0 +1,47 @@
  1
+s.boot
  2
+s.gui
  3
+s.makeGui
  4
+s.scope
  5
+s.freqscope
  6
+s.class.methods.do(_.postln)
  7
+s.quit
  8
+s.plotTree
  9
+s.meter
  10
+
  11
+(
  12
+~a = Pbind(
  13
+	\freq, Prout({
  14
+			Pseg([3,7,5,1,10],1.7,'linear',inf).embedInStream;	
  15
+		}),
  16
+	\dur, 2,
  17
+	\bla, Pfunc({ arg e; e[\freq].postln; })
  18
+);
  19
+~a.play
  20
+)
  21
+
  22
+(
  23
+~a = Pbind(
  24
+	\freq, Prout({
  25
+			var ti = 1.7, dur = 2;
  26
+			100.do { arg i;
  27
+				(i*(dur/ti)).debug("index");
  28
+				[3,7,5,1,10].blendAt(i*(dur/ti)).yield;
  29
+			};
  30
+		}),
  31
+	\bla, Pfunc({ arg e; e[\freq].postln; })
  32
+);
  33
+~a.play
  34
+)
  35
+(
  36
+~a = Pbind(
  37
+	\freq, Pseq([7,10,2,5],inf),
  38
+	\bla, Pfunc({ arg e; e[\freq].postln })
  39
+);
  40
+~a.play
  41
+)
  42
+(
  43
+~a = Pbind(
  44
+	\freq, Pseq([207,310],inf)
  45
+);
  46
+~a.play
  47
+)
579  editplayer.sc
... ...
@@ -0,0 +1,579 @@
  1
+(
  2
+~make_name_button = { arg parent, label;
  3
+	var bt;
  4
+	bt = GUI.button.new(parent, Rect(50,50,50,50));
  5
+	bt.states = [
  6
+		[ label, Color.black, Color.white],
  7
+		[ label, Color.white, Color.black ],
  8
+	];
  9
+	bt.value = 0;
  10
+	bt;
  11
+};
  12
+
  13
+~make_step_button = { arg parent, label;
  14
+	var bt;
  15
+	bt = GUI.button.new(parent, Rect(50,50,60,50));
  16
+	bt.states = [
  17
+		[ label, Color.black, Color.white],
  18
+		[ label, Color.white, Color.black ],
  19
+	];
  20
+	bt.value = 0;
  21
+	bt;
  22
+};
  23
+
  24
+~make_states = { arg label;
  25
+	var la = label.asFloat.asStringPrec(6);
  26
+	[
  27
+		[ la, Color.black, Color.white],
  28
+		[ la, Color.white, Color.black ],
  29
+	];
  30
+};
  31
+
  32
+~make_val_button = { arg parent, label;
  33
+	var bt;
  34
+	bt = GUI.button.new(parent, Rect(0,0,60,50));
  35
+	bt.states = ~make_states.(label);
  36
+	bt.value = 0;
  37
+	bt;
  38
+};
  39
+
  40
+~change_button_label = { arg button, label;
  41
+	var oldval = button.value;
  42
+	button.states = ~make_states.(label);
  43
+	button.value = oldval;
  44
+	button.refresh;
  45
+	//"boutton changed".debug;
  46
+};
  47
+
  48
+~init_controller = { arg controller, messages;
  49
+	messages.keysValuesDo { arg key, val; controller.put(key, val) };
  50
+};
  51
+
  52
+
  53
+~pretty_print_freq = { arg freq;
  54
+
  55
+
  56
+};
  57
+
  58
+~make_control_view = { arg parent, player, param, midi;
  59
+	var param_messages,
  60
+		midi_messages,
  61
+		row_layout,
  62
+		bloc,
  63
+		midibloc,
  64
+		btl_cells,
  65
+		bt_name,
  66
+		slider,
  67
+		new_cell,
  68
+		width = 1200;
  69
+	var txt_midi_label, txt_midi_val;
  70
+	var sc_param, sc_midi;
  71
+	var max_cells = 8; // FIXME: already defined in editplayer
  72
+	var inrange;
  73
+
  74
+	row_layout = GUI.hLayoutView.new(parent, Rect(0,0,(width+10),60));
  75
+	row_layout.background = Color.rand;
  76
+
  77
+	bt_name = ~make_name_button.(row_layout, param.name);
  78
+
  79
+	bloc = GUI.vLayoutView.new(row_layout, Rect(0,0,150,60));
  80
+	midibloc = GUI.hLayoutView.new(bloc, Rect(0,0,150,30));
  81
+	txt_midi_label = GUI.staticText.new(midibloc, Rect(0,0,75,30));
  82
+	txt_midi_val = GUI.staticText.new(midibloc, Rect(0,0,75,30));
  83
+
  84
+	slider = GUI.slider.new(bloc, Rect(0,0,100,30));
  85
+
  86
+	btl_cells = GUI.hLayoutView.new(row_layout, Rect(0,0,width,30));
  87
+
  88
+	inrange = { arg sel=nil;
  89
+		var start;
  90
+		start = max_cells * player.get_bank.();
  91
+		sel = sel ?? param.get_selected_cell;
  92
+		start.debug("inrange====");
  93
+		sel.debug("inrange");
  94
+		(sel >= start && (sel < (start+max_cells))).debug("inrange");
  95
+		(sel >= start && (sel < (start+max_cells)))
  96
+	};
  97
+
  98
+	param_messages = Dictionary.newFrom((
  99
+		selected: { arg self;
  100
+			bt_name.value = self.selected;
  101
+		},
  102
+
  103
+		selected_cell: { arg self, msg, oldsel;
  104
+			
  105
+			if(oldsel.notNil && inrange.(oldsel), {
  106
+				btl_cells.children[ oldsel % max_cells ].value = 0;
  107
+			});
  108
+			if(inrange.(), {
  109
+				btl_cells.children[ self.get_selected_cell % max_cells ].value = 1;
  110
+			});
  111
+		},
  112
+
  113
+		val: { arg self, msg, cellidx;
  114
+			var newval;
  115
+			self.get_cells[cellidx].debug("val handler: cellidx");
  116
+			newval = self.get_cells[cellidx];
  117
+			~change_button_label.(btl_cells.children[ cellidx % max_cells ], newval);
  118
+			//self.debug("val changed");
  119
+			if(self.classtype == \stepline, { 
  120
+				btl_cells.children[ cellidx % max_cells ].value = newval
  121
+			},{
  122
+				slider.value = self.spec.unmap(newval);
  123
+			});
  124
+			//btl_cells.children[ cellidx ].states.debug("======heeeeerreeeee");
  125
+			//btl_cells.children[ cellidx ] = newval;
  126
+		},
  127
+
  128
+		cells: { arg self; 
  129
+			var cells, bank, start, range, sel;
  130
+			"cells removeAll===================".debug;
  131
+			btl_cells.removeAll;
  132
+			"END cells removeAll===================".debug;
  133
+
  134
+			bank = player.get_bank.();
  135
+
  136
+			cells = self.get_cells.();
  137
+			cells.debug("cellls============");
  138
+			start = max_cells * bank;
  139
+			range = (start..((start+max_cells)-1));
  140
+			range.debug("cells");
  141
+			cells[ start..((start+max_cells)-1) ].debug("cells");
  142
+			cells[ start..((start+max_cells)-1) ].do { arg cell, i;
  143
+				~make_val_button.(btl_cells, cell);
  144
+				if(self.classtype== \stepline, {
  145
+					btl_cells.children[i].value = cell
  146
+				});
  147
+			};
  148
+			if(self.classtype == \control, {
  149
+				sel = self.get_selected_cell;
  150
+				if( sel >= start && (sel < (start+max_cells)), {
  151
+					btl_cells.children[ sel % max_cells ].value = 1;
  152
+				})
  153
+			})
  154
+		},
  155
+
  156
+		kind: { arg self;
  157
+			self.current_kind.debug("make_control_view changed kind");
  158
+			self.get_cells.debug("make_control_view.kind get_cells");
  159
+			self.changed(\cells);	
  160
+		}
  161
+	));
  162
+	midi_messages = Dictionary.newFrom((
  163
+		label: { arg self;
  164
+			txt_midi_label.string = self.label;
  165
+		},
  166
+		midi_val: { arg self;
  167
+			txt_midi_val.string = self.mapped_val;
  168
+		},
  169
+		blocked: { arg self;
  170
+			txt_midi_val.background = if(self.blocked == \not, { Color.green }, { Color.red });
  171
+		},
  172
+		recording: { arg self;
  173
+			txt_midi_label.background = if(self.recording, { Color.red }, { Color.green(alpha:1) });
  174
+		},
  175
+		midi_key: { arg self, msg, key;
  176
+			param_messages.val(param, msg); //TODO
  177
+		}
  178
+			
  179
+
  180
+
  181
+	));
  182
+	
  183
+	sc_param = SimpleController(param);
  184
+	~init_controller.(sc_param, param_messages);
  185
+	param.refresh.();
  186
+
  187
+	if(midi.notNil, {
  188
+		sc_midi = SimpleController(midi);
  189
+		~init_controller.(sc_midi, midi_messages);
  190
+		midi.refresh.();
  191
+	}, {
  192
+		"midi is nil".debug;
  193
+	});
  194
+
  195
+	// remove func
  196
+
  197
+	row_layout.onClose = {
  198
+		param.name.debug("=========== view closed");
  199
+		sc_param.remove;
  200
+		if(midi.notNil, { sc_midi.remove });
  201
+	};
  202
+};
  203
+
  204
+~make_editplayer_view = { arg parent, player, param_order;
  205
+	var midi;
  206
+	var width = 1200;
  207
+	var row_layout;
  208
+
  209
+	row_layout = GUI.vLayoutView.new(parent, Rect(0,0,(width+10),800));
  210
+	row_layout.background = Color.blue;
  211
+
  212
+	~midi_interface.clear_assigned(\slider);
  213
+	~midi_interface.clear_assigned(\knob);
  214
+
  215
+	CCResponder.removeAll; // FIXME: must not remove other useful CC
  216
+
  217
+	param_order.do { arg param_name, i;
  218
+		var param = player.get_arg(param_name);
  219
+		if([\instrument, \type, \out, \agate].includes(param_name), {
  220
+			// skip
  221
+		}, {
  222
+			case
  223
+				{ [\stepline].includes(param_name) } {
  224
+					midi = nil;
  225
+				}
  226
+				{ [\legato, \amp, \dur].includes(param_name)} {
  227
+					midi = ~midi_interface.assign_first(\slider, param);
  228
+				}
  229
+				{ true } {
  230
+					midi = ~midi_interface.assign_first(\knob, param);
  231
+				};
  232
+			param.midi = midi;
  233
+			~make_control_view.(row_layout, player, param, midi);
  234
+		});
  235
+	};
  236
+
  237
+};
  238
+
  239
+~midi_interface = (
  240
+	next_free: (
  241
+		slider: 0,
  242
+		knob: 0
  243
+	),
  244
+	registry: List[],
  245
+
  246
+	cc_val: Dictionary[
  247
+		[\slider, 0] -> 0
  248
+
  249
+	],
  250
+
  251
+	assign_first: { arg self, kind, param;
  252
+		var mc;
  253
+		mc = ~make_midi_control.([kind, self.next_free[kind]], self.cc_val, param);
  254
+		self.registry.add( mc );
  255
+		self.next_free[kind] = self.next_free[kind] + 1;
  256
+		mc;
  257
+	},
  258
+
  259
+	clear_assigned: { arg self, kind;
  260
+		self.next_free[kind] = 0;
  261
+		self.registry.copy.do { arg mc;
  262
+			if(mc.kind == kind, {
  263
+				mc.destroy;
  264
+				self.registry.remove(mc);
  265
+			});
  266
+		};
  267
+	}
  268
+
  269
+);
  270
+
  271
+
  272
+~make_midi_control = { arg ccid, cc_val, param; 
  273
+	var midi;
  274
+	var sc_param;
  275
+	var get_midi_val = { cc_val[ccid] ?? 0.5};
  276
+	var param_val = { param.get_norm_val };
  277
+
  278
+	//param.debug("make_midi_control param");
  279
+
  280
+	midi = (
  281
+		blocked: \not,
  282
+		ccid: nil,
  283
+		midi_val: get_midi_val.(),
  284
+		label: \void,
  285
+		recording: false,
  286
+		mapped_val: { arg self;
  287
+			param.spec.map(get_midi_val.())
  288
+		},
  289
+
  290
+		refresh: { arg self;
  291
+			self.changed(\label);
  292
+			self.changed(\blocked);
  293
+			self.changed(\midi_val);
  294
+		},
  295
+
  296
+		set_value: { arg self, cc_value;
  297
+			cc_val[ccid] = cc_value;
  298
+			self.midi_val = cc_value;
  299
+			self.changed(\midi_val);
  300
+
  301
+			if(self.recording.not, {
  302
+				if(ccid.notNil, {
  303
+					self.unblock_do({
  304
+						param.set_norm_val(cc_value);
  305
+					});
  306
+				}, {
  307
+					param.set_norm_val(cc_value);
  308
+				});
  309
+			});
  310
+		},
  311
+
  312
+		get_midi_val: { arg self; get_midi_val.() },
  313
+
  314
+		unblock_do: { arg self, fun;
  315
+			var cc_value, param_value;
  316
+
  317
+		
  318
+			//param.debug("make_midi_control.unblock_do param");
  319
+			cc_value = get_midi_val.();
  320
+			param_value = param.get_norm_val.();
  321
+
  322
+			switch(self.blocked,
  323
+				\not, fun,
  324
+				\sup, {
  325
+					if( cc_value <= param_value , {
  326
+						self.blocked = \not;
  327
+						self.changed(\blocked);
  328
+						fun.value;
  329
+					});
  330
+				},
  331
+				\inf, {
  332
+					if( cc_value >= param_value , {
  333
+						self.blocked = \not;
  334
+						self.changed(\blocked);
  335
+						fun.value;
  336
+					});
  337
+				}
  338
+			);
  339
+
  340
+		},
  341
+		
  342
+		block: { arg self;
  343
+			var cc_value, param_value;
  344
+
  345
+			cc_value = get_midi_val.();
  346
+			param_value = param.get_norm_val.();
  347
+
  348
+			case 
  349
+				{ cc_value > param_value } {
  350
+					self.blocked = \sup;
  351
+					self.changed(\blocked);
  352
+				}
  353
+				{ cc_value < param_value } {
  354
+					self.blocked = \inf;
  355
+					self.changed(\blocked);
  356
+				}
  357
+				{ true } {
  358
+					self.blocked = \not;
  359
+					self.changed(\blocked);
  360
+				}
  361
+		},
  362
+
  363
+		assign_cc: { arg self, ccid;
  364
+			self.ccid = ccid;
  365
+			 if(ccid.notNil, {
  366
+				self.label = (ccid[0] ++ (ccid[1]+1)).asSymbol;
  367
+				self.changed(\label);
  368
+				self.ccresp = CCResponder({ |src,chan,num,value|
  369
+						//[src,chan,num,value].debug("==============CCResponder");
  370
+						self.set_value(value/127);
  371
+					},
  372
+					nil, // any source
  373
+					nil, // any channel
  374
+					~cakewalk[ccid[0]][ccid[1]], // any CC number
  375
+					nil // any value
  376
+				);
  377
+				}, {
  378
+					"assigning nil ccid".debug("WARNING");
  379
+					"void"
  380
+				});
  381
+
  382
+		},
  383
+
  384
+		destroy: { arg self;
  385
+			self.ccresp.remove;
  386
+		}
  387
+	);
  388
+
  389
+	midi.assign_cc(ccid);
  390
+	midi.block.();
  391
+
  392
+	sc_param = SimpleController(param);
  393
+	sc_param.put(\kind, { arg obj; midi.block.() });
  394
+	sc_param.put(\selected_cell, { arg obj; midi.block.() });
  395
+
  396
+
  397
+	midi;
  398
+
  399
+};
  400
+
  401
+~make_midi_kb_control = { arg player, editplayer;
  402
+	var nonr, noffr, param, destroy, rec;
  403
+	
  404
+	// init
  405
+	NoteOnResponder.removeAll; // TODO: must save others responders ?
  406
+
  407
+	nonr = NoteOnResponder { arg src, chan, num, veloc;
  408
+		param = editplayer.controller.get_selected_param.();
  409
+		param.set_val(num.midicps);
  410
+	};
  411
+
  412
+	rec = CCResponder({ |src,chan,num,value|
  413
+			var param = editplayer.controller.get_selected_param;
  414
+			var stepline = player.get_arg(\stepline);
  415
+			if(param.midi.notNil && param.midi.recording.notNil, {
  416
+				if(param.midi.recording, {
  417
+					param.midi.recording = false;
  418
+					param.midi.changed(\recording);
  419
+					stepline.tick = { "TICK!!!".postln; };
  420
+				}, {
  421
+					param.midi.recording = true;
  422
+					param.midi.changed(\recording);
  423
+					stepline.tick = { arg obj, idx;
  424
+						param.midi.get_midi_val.debug("set TICK");
  425
+						param.seq.set_norm_val(idx, param.midi.get_midi_val);
  426
+					};
  427
+				});
  428
+			});
  429
+		},
  430
+		nil, // any source
  431
+		nil, // any channel
  432
+		~cakewalk.button[7], // record button
  433
+		nil // any value
  434
+	);
  435
+
  436
+	destroy = { 
  437
+		nonr.remove;
  438
+		rec.remove;
  439
+	};
  440
+	destroy;
  441
+
  442
+};
  443
+
  444
+~make_editplayer = { arg player, parent, kb_handler;
  445
+	var ep;
  446
+	"============making editplayer".debug;
  447
+	ep = (
  448
+		model: (
  449
+				param_order: List[\amp, \stepline, \freq, \dur, \legato],
  450
+				max_cells: 8,
  451
+				selected_param: 0
  452
+
  453
+		),
  454
+
  455
+
  456
+		controller: { arg editplayer; (
  457
+
  458
+			get_param_at: { arg self, idx;
  459
+				player.get_arg( editplayer.model.param_order[idx] )
  460
+			},
  461
+
  462
+			get_selected_param: { arg self;
  463
+				self.get_param_at( editplayer.model.selected_param )
  464
+			},
  465
+
  466
+			// control API
  467
+
  468
+			select_param: { arg self, idx;
  469
+				var param;
  470
+				editplayer.model.param_order.debug("editplayer.select_param param_order");
  471
+				if(idx < (editplayer.model.param_order.size), { 
  472
+					param = self.get_param_at(idx);
  473
+					self.get_selected_param.deselect_param.();
  474
+					param.select_param.();
  475
+					editplayer.model.selected_param = idx;
  476
+				}, {
  477
+					idx.debug("selected param out of range");
  478
+				});
  479
+			},
  480
+
  481
+			select_cell: { arg self, idx;
  482
+				var sel;
  483
+				sel = self.get_selected_param.();
  484
+				if( sel.classtype == \stepline, {
  485
+					sel.toggle_cell(idx);
  486
+				}, {
  487
+					sel.select_cell(idx);
  488
+				});
  489
+			},
  490
+
  491
+			set_value: { arg self, val;
  492
+				self.get_selected_param.set_value(val);
  493
+			},
  494
+
  495
+			add_cell_bar: { arg self;
  496
+				var bar_length = 4;
  497
+				var par = self.get_selected_param;
  498
+				var defval = self.get_selected_param.default_val;
  499
+
  500
+				self.get_selected_param.debug("editplayer.controller.add_cell_bar get sel param");
  501
+
  502
+				if(par.classtype == \stepline,{
  503
+					self.get_selected_param.add_cells( par.default_val[..(bar_length-1)]);
  504
+				},{
  505
+					self.get_selected_param.add_cells( par.default_val ! bar_length);
  506
+				});
  507
+			},
  508
+
  509
+			remove_cell_bar: { arg self;
  510
+				var bar_length = 4;
  511
+				self.get_selected_param.remove_cells(bar_length);
  512
+			},
  513
+
  514
+			change_kind: { arg self, kind;
  515
+				var param = self.get_selected_param;
  516
+				if(param.classtype == \control, {
  517
+					self.get_selected_param.change_kind(kind);
  518
+				});
  519
+			};
  520
+
  521
+
  522
+		)},
  523
+
  524
+
  525
+		init: { arg editplayer, player, parent, kb_handler;
  526
+			var param_order = editplayer.model.param_order.dump, selected;
  527
+			"========== init editplayer ============".debug;
  528
+
  529
+			// param order
  530
+
  531
+			param_order.dump.debug("init param_order");
  532
+			player.get_args.do { arg key; if(param_order.includes(key).not, { param_order.add(key) }) };
  533
+			param_order.deepCopy.do { arg key; if(player.get_args.includes(key).not, { param_order.remove(key) }) };
  534
+			param_order.debug("init done param_order");
  535
+			param_order = param_order.reject({ arg x; [\out, \instrument, \type, \gate].includes(x) });
  536
+			param_order.dump.debug("init done2 param_order");
  537
+			editplayer.model.param_order.debug("init abs param_order");
  538
+			editplayer.model.param_order = param_order;
  539
+			editplayer.model.param_order.debug("init abs param_order");
  540
+			editplayer.model.param_order = param_order;
  541
+			editplayer.model.param_order.dump.debug("init abs param_order");
  542
+		
  543
+
  544
+			~make_editplayer_view.(parent, player, param_order);
  545
+
  546
+			// select param
  547
+
  548
+			selected = param_order.do.detectIndex { arg i; player.get_arg(i).selected == 1 };
  549
+			editplayer.controller.select_param(selected ?? 1);
  550
+
  551
+			// midi keys
  552
+
  553
+			~make_midi_kb_control.(player, editplayer);
  554
+
  555
+			// kb shotcuts
  556
+
  557
+			~kbnumline.do { arg kc, i; kb_handler[[0, kc]] = { 
  558
+				editplayer.controller.select_cell((player.get_bank*editplayer.model.max_cells)+i) 
  559
+			} };
  560
+			~kbnumline.do { arg kc, i; kb_handler[[~modifiers.alt, kc]] = { editplayer.controller.select_param(i) } };
  561
+			kb_handler[[~modifiers.alt, ~kbaalphanum["a"]]] = { editplayer.controller.change_kind(\seq) };
  562
+			kb_handler[[~modifiers.alt, ~kbaalphanum["s"]]] = { editplayer.controller.change_kind(\scalar) };
  563
+
  564
+			kb_handler[[0, ~numpad.plus]] = { editplayer.controller.add_cell_bar.() };
  565
+			kb_handler[[~modifiers.ctrl, ~numpad.plus]] = { editplayer.controller.remove_cell_bar.() };
  566
+
  567
+			~kbnumpad.do { arg keycode, idx;
  568
+				kb_handler[[0, keycode]] = { player.set_bank(idx) };
  569
+			};
  570
+
  571
+		}
  572
+	);
  573
+	ep.init(player, parent, kb_handler);
  574
+	ep;
  575
+
  576
+};
  577
+
  578
+)
  579
+
118  keycode.sc
... ...
@@ -0,0 +1,118 @@
  1
+
  2
+// ==========================================
  3
+// input keycode definition
  4
+// ==========================================
  5
+
  6
+~kbpad8x4 = [
  7
+	[ 38, 233, 34, 39, 40, 45, 232, 95 ],
  8
+	[97, 122, 101, 114, 116, 121, 117, 105 ],
  9
+	[113, 115, 100, 102, 103, 104, 106, 107 ],
  10
+	[119, 120, 99, 118, 98, 110, 44, 59 ]
  11
+];
  12
+~kbcalphanum = {
  13
+	var dict = Dictionary.new;
  14
+	//TODO: only for Ctrl (262144) modifier, do others
  15
+	//NOTE: ^W close the window
  16
+	var keycodes = [
  17
+			[ 38, 233, 34, 39, 40, 45, 232, 31, 231, 224, 41, 61 ],
  18
+			[ 1, 26, 5, 18, 20, 25, 21, 9, 15, 16, 36 ],
  19
+			[ 17, 19, 4, 6, 7, 8, 10, 11, 12, 13, 249, 42], 
  20
+			[60, 24, 3, 22, 2, 14, 44, 59, 58, 33]
  21
+	];
  22
+	var alnum = [
  23
+		"1234567890)=",
  24
+		"azertyuiop^$",
  25
+		"qsdfghjklmù*",
  26
+		"<xcvbn,;:!"
  27
+	];
  28
+	keycodes.do { arg row, rowidx;	
  29
+		row.do { arg kc, kcidx;
  30
+			dict[ alnum[rowidx][kcidx].asString ] = kc;
  31
+		};
  32
+	};
  33
+	dict;
  34
+}.value;
  35
+~kbaalphanum = {
  36
+	var dict = Dictionary.new;
  37
+	//NOTE: only for Alt and no modifier
  38
+	var keycodes = [
  39
+			[ 38, 233, 34, 39, 40, 45, 232, 31, 231, 224, 41, 61 ],
  40
+			[97, 122, 101, 114, 116, 121, 117, 105, 111,112, 36 /* ^ not working */, 36 ],
  41
+			[113, 115, 100, 102, 103, 104, 106, 107, 108, 109, 249, 42 ],
  42
+			[60, 119, 120, 99, 118, 98, 110, 44, 59 ]
  43
+	];
  44
+	var alnum = [
  45
+		"1234567890)=",
  46
+		"azertyuiop^$",
  47
+		"qsdfghjklmù*",
  48
+		"<xcvbn,;:!"
  49
+	];
  50
+	keycodes.do { arg row, rowidx;	
  51
+		row.do { arg kc, kcidx;
  52
+			dict[ alnum[rowidx][kcidx].asString ] = kc;
  53
+		};
  54
+	};
  55
+	dict;
  56
+}.value;
  57
+~kb8x2line = [
  58
+	38, 97, 233, 122, 34, 101, 39, 114, 40, 166, 45, 121, 232, 117, 95, 105
  59
+];
  60
+~kbnumline = [
  61
+	38, 233, 34, 39, 40, 45, 232, 95, 231, 224, 41, 61
  62
+];
  63
+~kbnumpad = [
  64
+	48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
  65
+];
  66
+~numpad = (
  67
+	plus: 43,
  68
+	minus: 45
  69
+);
  70
+~modifiers = (
  71
+	fx: 8388608,
  72
+	ctrl: 262144,
  73
+	shift: 131072,
  74
+	alt: 524288
  75
+);
  76
+~kbfx = [
  77
+	// modifiers = 8388608
  78
+	63236, 63237, 63238, 63239, 63240, 63241, 63242, 63243, 63244, 63245, 63246, 63247
  79
+	//49,50,51,52,53,54,55,56,57,58
  80
+];
  81
+~kbarrow = (
  82
+	// modifiers = 8388608
  83
+	left: 63234,
  84
+	right: 63235,
  85
+	up: 63232,
  86
+	down: 63233
  87
+);
  88
+~kbspecial = (
  89
+	delete: 127
  90
+);
  91
+~cakewalk = (
  92
+	\knob: [
  93
+		74, 71, 65, 2, 5, 76, 77, 78, 10
  94
+	],
  95
+	\button: [
  96
+		21, 22, 23, 24, 25, 26, 27, 28
  97
+	],
  98
+	\toggle: [
  99
+		80,81,82,83
  100
+	],
  101
+	\slider: [
  102
+		73, 75, 72, 91, 92, 93, 94, 95, 7
  103
+	]
  104
+);
  105
+~midi = {
  106
+	var dico = Dictionary.new;
  107
+	~cakewalk.collect { arg v, k;
  108
+		"v:".postln;
  109
+		v.postln;
  110
+		"k:".postln;
  111
+		k.postln;
  112
+		v.do { arg raw, i;
  113
+			dico[raw] = [k, i];
  114
+		};
  115
+	};
  116
+	dico;
  117
+}.value;
  118
+
215  live1.sc
... ...
@@ -0,0 +1,215 @@
  1
+s.boot;
  2
+
  3
+
  4
+(
  5
+Document.dir = "/home/ggz/code/sc/";
  6
+)
  7
+
  8
+(
  9
+
  10
+SynthDef(\pgrain, { arg out = 0, freq=800, sustain=0.001, amp=0.5, pan = 0;
  11
+	var window;
  12
+	window = Env.sine(sustain, amp * AmpCompA.kr(freq));
  13
+	Out.ar(out, 
  14
+	Pan2.ar(
  15
+	SinOsc.ar(freq),
  16
+	pan
  17
+	) * EnvGen.ar(window, doneAction:2)
  18
+	)
  19
+}).store;
  20
+
  21
+SynthDef(\noiseGrain, 
  22
+{ arg out = 0, freq=800, sustain=0.001, amp=0.5, pan = 0;
  23
+var window;
  24
+window = Env.perc(0.002, sustain, amp * AmpCompA.kr(freq));
  25
+Out.ar(out, 
  26
+Pan2.ar(
  27
+Ringz.ar(PinkNoise.ar(0.1), freq, 2.6),
  28
+pan
  29
+) * EnvGen.ar(window, doneAction:2)
  30
+)
  31
+}
  32
+).store;
  33
+
  34
+SynthDef(\bubblebub, {	|out=0, t_trig=1, attack=0.01, decay=0.08, pitchcurvelen=0.1, freq=1000, doneAction=2, amp=0.1|
  35
+	var pitch, son;
  36
+	amp   = amp * EnvGen.ar(Env.perc(attack, decay).delay(0.003), t_trig, doneAction: doneAction);
  37
+	pitch = freq * EnvGen.ar(Env.new([0,0,1],[0,1]).exprange(1, 2.718), t_trig, timeScale: pitchcurvelen);
  38
+	son = SinOsc.ar(pitch);
  39
+	// high-pass to remove any lowpitched artifacts, scale amplitude
  40
+	son = HPF.ar(son, 500) * amp * 10;
  41
+	Out.ar(out, son);
  42
+}).store;
  43
+
  44
+SynthDef("tish", { arg freq = 1200, rate = 2;
  45
+
  46
+var osc, trg;
  47
+
  48
+trg = Decay2.ar(Impulse.ar(rate,0,0.3), 0.01, 0.3);
  49
+
  50
+osc = {WhiteNoise.ar(trg)}.dup;
  51
+
  52
+Out.ar(0, osc); // send output to audio bus zero.
  53
+
  54
+}).store;
  55
+
  56
+
  57
+SynthDef(\bass, { |gate = 1, t_trig = 1, freq=100, freqlag = 0.1, ffreq = 1500, rq = 0.1, filtAttack = 0,
  58
+		amp = 1, out = 0|
  59
+	var	sig = Saw.ar(Lag.kr(freq, freqlag) * [1, 1.005]).sum,
  60
+		fenv = EnvGen.kr(Env([0, filtAttack, 0], [0.01, 0.2], -3), t_trig) + 1;
  61
+	sig = RLPF.ar(sig, ffreq * fenv, rq, amp)
  62
+		* EnvGen.kr(Env.adsr(0.01, 0.2, 0.5, 0.08), (gate > 0) - (t_trig > 0), doneAction: 2);
  63
+	Out.ar(out, sig ! 2);
  64
+}, metadata: (specs: (
  65
+	ffreq: \freq,
  66
+	t_trig: ControlSpec(0, 1, \lin, 1, 1, "trig"),
  67
+	freqlag: \delay,
  68
+	filtAttack: \delay
  69
+)) ).store;
  70
+
  71
+)
  72
+
  73
+~get_spec.(\sustain)
  74
+
  75
+(
  76
+
  77
+"seco22.sc".loadDocument;
  78
+
  79
+
  80
+~patlib = [
  81
+
  82
+\bubblebub -> { arg amp=0.1, pitchcurvelen=0.5, type, stepline = #[1,1,0,1], freq = 500;
  83
+	Pbind(
  84
+		\instrument, \bubblebub,
  85
+		\pitchcurvelen, pitchcurvelen,
  86
+		\freq, freq,
  87
+		\stepline, stepline,
  88
+		\amp, amp,
  89
+		\dur, 0.25,
  90
+		\type, type
  91
+	)
  92
+},
  93
+\noiseGrain -> { arg amp=0.1, type, stepline = #[1,1,0,1], freq = 300;
  94
+	Pbind(
  95
+		\instrument, \noiseGrain,
  96
+		\freq, freq,
  97
+		\stepline, stepline,
  98
+		\amp, amp,
  99
+		\dur, 0.5,
  100
+		\type, type
  101
+	)
  102
+},
  103
+\pgrain -> { arg amp=0.1, type, stepline = #[1,1,0,1], freq = 300;
  104
+	Pbind(
  105
+		\instrument, \pgrain,
  106
+		\freq, freq,
  107
+		\stepline, stepline,
  108
+		\amp, amp,
  109
+		\dur, 0.5,
  110
+		\type, type
  111
+	)
  112
+},
  113
+\bass -> { arg amp=0.1, type, ffreq=1500, rq=0.1, stepline = #[1,1,0,1], freq = 300;
  114
+	Pbind(
  115
+		\instrument, \bass,
  116
+		\freq, freq,
  117
+		\ffreq, ffreq,
  118
+		\rq, rq,
  119
+		\stepline, stepline,
  120
+		\amp, amp,
  121
+		\dur, 0.5,
  122
+		\type, type
  123
+	)
  124
+},
  125
+
  126
+];
  127
+
  128
+// TODO: j'ai changé les fonctions de gui pour decaler mais j'ai oublié que fallais decaler uniquement pour \parlive...
  129
+
  130
+~synthlib = [
  131
+\bass -> \bass,
  132
+\pgrain -> \pgrain
  133
+];
  134
+
  135
+~seq = ~mk_sequencer.value;
  136
+~seq.load_patlib( ~synthlib );
  137
+~seq.make_gui;
  138
+)
  139
+
  140
+
  141
+SynthDescLib("pgrain").synthDescs
  142
+SynthDef("pgrain")
  143
+SynthDescLib.global.browse;
  144
+SynthDescLib.global.synthDescs[\pgrain].dump;
  145
+SynthDescLib.synthDescs[\pgrain].dump;
  146
+SynthDescLib.global.synthDescs[\pgrain].controls[0].dump;
  147
+SynthDescLib.global.synthDescs[\pgriain].controls[0].defaultValue;
  148
+SynthDescLib.global.synthDescs[\pgrain].controlNames
  149
+SynthDescLib.global.synthDescs[\basiis].metadata.specs[\t_trig].asSpec
  150
+
  151
+\freq.map
  152
+\plop.isSymbol
  153
+
  154
+~p = EventPatternProxy.new
  155
+~p.source = \pgrain
  156
+~p.play
  157
+
  158
+
  159
+~d = Dictionary[\bla -> 1 , \rah -> 140]
  160
+~d.keys
  161
+
  162
+~li = List.new;
  163
+~d.pairsDo({ arg key, val; ~li.add(key); ~li.add(val)})
  164
+~li
  165
+Pbind(* ~li )
  166
+[bla: 4]
  167
+
  168
+(
  169
+
  170
+// Alternative syntax, using a key/pattern array:
  171
+
  172
+
  173
+Pbind(*[
  174
+
  175
+instrument: \test, 
  176
+
  177
+nharms: Pseq([4, 10, 40], inf), 
  178
+
  179
+dur: Pseq([1, 1, 2, 1]/10, inf), 
  180
+
  181
+#[freq, sustain],  Ptuple([
  182
+
  183
+Pseq( (1..16) * 50, 4), 
  184
+
  185
+Pseq([1/10, 0.5, 1, 2], inf)
  186
+
  187
+]), 
  188
+
  189
+]).play
  190
+
  191
+)
  192
+
  193
+~f = { arg bla=4, raa=5; };
  194
+~f.argNames
  195
+~f.defaultArgs
  196
+
  197
+~a = nil;
  198
+~a = 7;
  199
+~b = ~a ?? 4
  200
+
  201
+(
  202
+var defname = nil, argName=\sustain;
  203
+SynthDescLib.global.synthDescs[defname].notNil and: { SynthDescLib.global.synthDescs[defname].metadata.specs[argName].notNil }
  204
+)
  205
+
  206
+~patlib.writeArchive("plop.txt")
  207
+
  208
+a = Array.fill(100, { 100.rand });
  209
+
  210
+a.writeArchive(PathName.tmp ++ "myArray");
  211
+
  212
+b = Object.readArchive(PathName.tmp ++ "myArray");
  213
+
  214
+a == b // true
  215
+PathName.tmp
210  live2.sc
... ...
@@ -0,0 +1,210 @@
  1
+s.boot;
  2
+
  3
+
  4
+(
  5
+SynthDef("piou", {
  6
+	arg out=0, amp=1, sustain=0.4; //TODO: is an array ok ?
  7
+	var ou;
  8
+	ou = SinOsc.ar(
  9
+		XLine.kr(500, 50, sustain)*SinOsc.kr(9)+1,
  10
+		XLine.kr(000, 10, sustain)
  11
+	) * EnvGen.kr(Env.linen(0.1,0.5,0.1), timeScale:sustain, doneAction:2);
  12
+	Out.ar(out, ou * amp)
  13
+}).store;
  14
+ 
  15
+SynthDef("fm1", {
  16
+	arg out=0, amp=1, gate=1, adsr=#[0.02, 0.2, 0.25, 1, 1, -4], freq=440, modf=9;
  17
+	var ou;
  18
+	ou = SinOsc.ar( SinOsc.kr(modf)+1*freq);
  19
+	ou = ou * EnvGen.kr(Env.adsr(*adsr), gate, doneAction:2);
  20
+	Out.ar(out, ou * amp)
  21
+}).store;
  22
+ 
  23
+SynthDef("fm2", {
  24
+	arg out=0, amp=1, sustain=0.5, freq=500, modf=200, modbpf=900;
  25
+	var ou;
  26
+	ou = SinOsc.ar( SinOsc.kr(modf)+1*freq)
  27
+	* EnvGen.kr(Env.linen(0.1,0.5,0.1), timeScale:sustain, doneAction:2);
  28
+	ou = BPF.ar(ou, SinOsc.kr(SinOsc.kr(1)+1*900)+1*freq);
  29
+	Out.ar(out, ou * amp)
  30
+}).store;
  31
+ 
  32
+SynthDef("shh", {
  33
+	arg out=0, amp=1, sustain=0.5, freq=440, modf=9, noise=0.5;
  34
+	var ou;
  35
+	ou = WhiteNoise.ar(noise);
  36
+	ou = LPF.ar(ou, SinOsc.kr(modf)+1*freq)
  37
+	* EnvGen.kr(Env.perc(0.001,sustain), doneAction:2);
  38
+	Out.ar(out, ou * amp)
  39
+}).store;
  40
+SynthDef("kickTrig1", { arg levK=1, t_trig=0, sustain=0.125, f1=36.7, f2=73.4, amp=1, out=0;
  41
+	var kEnv, ou;
  42
+	var kickEnv;
  43
+	kickEnv = Env.linen(0.001, 1.9, 0.099, 1);
  44
+	kEnv=EnvGen.ar(kickEnv,1, doneAction:2, timeScale: sustain, levelScale: levK);
  45
+	ou =Pan2.ar(Decay2.kr(t_trig, 0.005, 0.45, 
  46
+	FSinOsc.ar(f1, 0.4)+FSinOsc.ar(f2, 0.2)),0);
  47
+ 
  48
+	Out.ar(out, ou * kEnv * amp);
  49
+}).store;
  50
+SynthDef("snTrig1", { arg levSn=1, t_trig=0, sustain=0.125, panPos=0, amp=1,
  51
+	out=0;
  52
+	var snEnv, ou;
  53
+	var snareEnv;
  54
+	snareEnv = Env.linen(0.001, 1.9, 0.099, 1);
  55
+	snEnv=EnvGen.ar(snareEnv,1, doneAction:2, timeScale: sustain, levelScale: levSn);
  56
+	ou =Pan2.ar(Decay2.kr(t_trig, 0.005, 0.25, FSinOsc.ar(38.midicps, 0.3)+ 		BrownNoise.ar(0.4)),panPos);
  57
+ 
  58
+	Out.ar(out, ou*snEnv * amp);
  59
+}).store;
  60
+)
  61
+
  62
+
  63
+(
  64
+
  65
+
  66
+)
  67
+
  68
+(
  69
+
  70
+Document.dir = "/home/ggz/code/sc/";
  71
+"seco22.sc".loadDocument;
  72
+
  73
+
  74
+
  75
+~synthlib = [
  76
+	\piou,
  77
+	\fm1,
  78
+	\fm2,
  79
+	\kickTrig1,
  80
+	\snTrig1
  81
+].collect({ arg i; i -> i });
  82
+
  83
+~seq = ~mk_sequencer.value;
  84
+~seq.load_patlib( ~synthlib );
  85
+~seq.make_gui;
  86
+)
  87
+(
  88
+~seq.save_project("proj1");
  89
+~seq.load_project("proj1");
  90
+
  91
+
  92
+)
  93
+
  94
+"mkdir myproj".unixCmd
  95
+(
  96
+var myPath;
  97
+myPath = PathName.new("./");
  98
+myPath.files.postln;
  99
+)
  100
+
  101
+
  102
+SynthDescLib("pgrain").synthDescs
  103
+SynthDef("pgrain")
  104
+SynthDescLib.global.browse;
  105
+SynthDescLib.global.synthDescs[\pgrain].dump;
  106
+SynthDescLib.synthDescs[\pgrain].dump;
  107
+SynthDescLib.global.synthDescs[\pgrain].controls[0].dump;
  108
+SynthDescLib.global.synthDescs[\pgriain].controls[0].defaultValue;
  109
+SynthDescLib.global.synthDescs[\pgrain].controlNames
  110
+SynthDescLib.global.synthDescs[\basiis].metadata.specs[\t_trig].asSpec
  111
+
  112
+\freq.map
  113
+\plop.isSymbol
  114
+
  115
+~p = EventPatternProxy.new
  116
+~p.source = \pgrain
  117
+~p.play
  118
+
  119
+
  120
+~d = Dictionary[\bla -> 1 , \rah -> 140]
  121
+~d.keys
  122
+
  123
+~li = List.new;
  124
+~d.pairsDo({ arg key, val; ~li.add(key); ~li.add(val)})
  125
+~li
  126
+Pbind(* ~li )
  127
+[bla: 4]
  128
+
  129
+(
  130
+
  131
+// Alternative syntax, using a key/pattern array:
  132
+
  133
+
  134
+Pbind(*[
  135
+
  136
+instrument: \test, 
  137
+
  138
+nharms: Pseq([4, 10, 40], inf), 
  139
+
  140
+dur: Pseq([1, 1, 2, 1]/10, inf), 
  141
+
  142
+#[freq, sustain],  Ptuple([
  143
+
  144
+Pseq( (1..16) * 50, 4), 
  145
+
  146
+Pseq([1/10, 0.5, 1, 2], inf)
  147
+
  148
+]), 
  149
+
  150
+]).play
  151
+
  152
+)
  153
+
  154
+~f = { arg bla=4, raa=5; };
  155
+~f.argNames
  156
+~f.defaultArgs
  157
+
  158
+~a = nil;
  159
+~a = 7;
  160
+~b = ~a ?? 4
  161
+
  162
+(
  163
+var defname = nil, argName=\sustain;
  164
+SynthDescLib.global.synthDescs[defname].notNil and: { SynthDescLib.global.synthDescs[defname].metadata.specs[argName].notNil }
  165
+)
  166
+
  167
+~patlib.writeArchive("plop.txt")
  168
+
  169
+a = Array.fill(100, { 100.rand });
  170
+
  171
+a.writeArchive(PathName.tmp ++ "myArray");
  172
+
  173
+b = Object.readArchive(PathName.tmp ++ "myArray");
  174
+
  175
+a == b // true
  176
+PathName.tmp
  177
+
  178
+
  179
+
  180
+
  181
+(
  182
+SynthDef(\sin, {
  183
+	arg out=0, amp=1, gate=1, freq=440;
  184
+	var ou;
  185
+	var env, envctl;
  186
+
  187
+	env = Env.adsr(0.02, 0.2, 0.25, 0.1, 1, 4);
  188
+	//env = Env.newClear(6);
  189
+
  190
+	envctl = Control.names([\adsr]).kr( env.asArray );
  191
+	ou = SinOsc.ar( freq);
  192
+	ou = ou * EnvGen.kr(envctl, gate, doneAction:2);
  193
+	Out.ar(out, ou * amp)
  194
+}).add;
  195
+)
  196
+
  197
+~p = EventPatternProxy.new;
  198
+(
  199
+
  200
+~p.source = Pbind(
  201
+	\instrument, \sin,
  202
+	\adsr, [ Env.adsr(0.07,0.1, 0.1, 0.9, 0.9, 1).asArray ],
  203
+	\legato, 0.5,
  204
+	\dur, 2
  205
+);
  206
+~p.play
  207
+
  208
+)
  209
+Env.adsr(0.07,0.01, 0.02, 1.701, 1, 1).test(2).plot
  210
+Env.adsr(0.07,0.01, 0.02, 1.701, 1, 1).asArray
324  live3.sc
... ...
@@ -0,0 +1,324 @@
  1
+s.boot;
  2
+
  3
+
  4
+(
  5
+	var punch =	{
  6
+		arg osc, n=10;
  7
+		{
  8
+			arg out=0, amp=1, agate=1, freq=500, sustain=0.2, lpf=120, rq=0.9;
  9
+			var ou, li;
  10
+			li = XLine.kr(freq, 1, sustain);
  11
+			ou = Mix.fill(n, { |i| osc.value(li + (i * 0.1)) });
  12
+			ou = LPF.ar(ou, lpf, rq);
  13
+			ou = ou * EnvGen.kr(Env.perc(0.000001,sustain), doneAction:2 );
  14
+			Out.ar(out, ou * amp * agate);
  15
+		}
  16
+	};
  17
+	SynthDef("punch_saw", punch.value(LFSaw.ar(_))).store;
  18
+	SynthDef("punch_sin", punch.value(SinOsc.ar(_))).store;
  19
+	SynthDef("punch_pulse", punch.value(LFPulse.ar(_))).store;
  20
+	SynthDef("punch_blip", punch.value(Blip.ar(_,9))).store;
  21
+SynthDef("piou", {
  22
+	arg out=0, amp=1, sustain=0.4; //TODO: is an array ok ?
  23
+	var ou;
  24
+	ou = SinOsc.ar(
  25
+		XLine.kr(500, 50, sustain)*SinOsc.kr(9)+1,
  26
+		XLine.kr(000, 10, sustain)
  27
+	) * EnvGen.kr(Env.linen(0.1,0.5,0.1), timeScale:sustain, doneAction:2);
  28
+	Out.ar(out, ou * amp)
  29
+}).store;
  30
+ 
  31
+SynthDef("fm2", {
  32
+	arg out=0, amp=1, sustain=0.5, freq=500, modf=200, modbpf=900;
  33
+	var ou;
  34
+	ou = SinOsc.ar( SinOsc.kr(modf)+1*freq)
  35
+	* EnvGen.kr(Env.linen(0.1,0.5,0.1), timeScale:sustain, doneAction:2);
  36
+	ou = BPF.ar(ou, SinOsc.kr(SinOsc.kr(1)+1*900)+1*freq);
  37
+	Out.ar(out, ou * amp)
  38
+}).store;
  39
+ 
  40
+SynthDef("shh", {
  41
+	arg out=0, amp=1, sustain=0.5, freq=440, modf=9, noise=0.5;
  42
+	var ou;
  43
+	ou = WhiteNoise.ar(noise);
  44
+	ou = LPF.ar(ou, SinOsc.kr(modf)+1*freq)
  45
+	* EnvGen.kr(Env.perc(0.001,sustain), doneAction:2);
  46
+	Out.ar(out, ou * amp)
  47
+}).store;
  48
+SynthDef("kickTrig1", { arg levK=1, t_trig=0, sustain=0.125, f1=36.7, f2=73.4, amp=1, out=0;
  49
+	var kEnv, ou;
  50
+	var kickEnv;
  51
+	kickEnv = Env.linen(0.001, 1.9, 0.099, 1);
  52
+	kEnv=EnvGen.ar(kickEnv,1, doneAction:2, timeScale: sustain, levelScale: levK);
  53
+	ou =Pan2.ar(Decay2.kr(t_trig, 0.005, 0.45, 
  54
+	FSinOsc.ar(f1, 0.4)+FSinOsc.ar(f2, 0.2)),0);
  55
+ 
  56
+	Out.ar(out, ou * kEnv * amp);
  57
+}).store;
  58
+SynthDef("snTrig1", { arg levSn=1, t_trig=0, sustain=0.125, panPos=0, amp=1,
  59
+	out=0;
  60
+	var snEnv, ou;
  61
+	var snareEnv;
  62
+	snareEnv = Env.linen(0.001, 1.9, 0.099, 1);
  63
+	snEnv=EnvGen.ar(snareEnv,1, doneAction:2, timeScale: sustain, levelScale: levSn);
  64
+	ou =Pan2.ar(Decay2.kr(t_trig, 0.005, 0.25, FSinOsc.ar(38.midicps, 0.3)+ 		BrownNoise.ar(0.4)),panPos);
  65
+ 
  66
+	Out.ar(out, ou*snEnv * amp);
  67
+}).store;
  68
+
  69
+
  70
+SynthDef("klankgeo", {
  71
+	arg out=0, amp=1, sustain=3.0, freq=140, at=1.5, rt=1.5, rq=0.5;
  72
+	var ou;
  73
+	ou = Klank.ar(`[Array.geom(10,freq,2), nil, [1, 1, 1, 1]], PinkNoise.ar(0.007));
  74
+	ou = ou * EnvGen.kr(Env.linen(at,1,rt), timeScale:sustain, doneAction:2);
  75
+	ou = BPF.ar(ou, freq, rq);
  76
+	Out.ar(out, ou*amp);
  77
+}).store;
  78
+SynthDef("kick", {
  79
+	arg out=0, amp=1, sustain=0.125, t_trig=1, shift= -550; 
  80
+	var ou, env;
  81
+	ou = SinOsc.ar(600) + SinOsc.ar(500) + BrownNoise.ar(0.51);
  82
+	ou = FreqShift.ar(ou, shift);
  83
+	ou = ou * Decay.kr(t_trig, sustain);
  84
+	env = EnvGen.ar(Env.perc(0.00001,sustain),doneAction:2);