First mockup of audio looper (==)
I am trying to add an audio looper to play breakbeats. It works .. meh for now but I'm sure that it'll slowly get better!
This commit is contained in:
@ -51,22 +51,22 @@ Boot {
|
||||
|
||||
// Post actions: installing behavior after server boot
|
||||
Server.default.waitForBoot({
|
||||
d = ();
|
||||
// Exceptional Dual Sardine Boot
|
||||
d.dirt = SuperDirt(2, s);
|
||||
d.dirt.fileExtensions = ["wav","aif","aiff","aifc","mp3"];
|
||||
d.dirt.loadSoundFiles("/Users/bubo/Library/Application\ Support/Sardine/SON/*");
|
||||
d.dirt.loadSoundFiles("/Users/bubo/.config/livecoding/samples/*");
|
||||
d.dirt.doNotReadYet = true;
|
||||
d.dirt.start(57120, [ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22]);
|
||||
(
|
||||
d.d1 = d.dirt.orbits[0]; d.d2 = d.dirt.orbits[1]; d.d3 = d.dirt.orbits[2];
|
||||
d.d4 = d.dirt.orbits[3]; d.d5 = d.dirt.orbits[4]; d.d6 = d.dirt.orbits[5];
|
||||
d.d7 = d.dirt.orbits[6]; d.d8 = d.dirt.orbits[7]; d.d9 = d.dirt.orbits[8];
|
||||
d.d10 = d.dirt.orbits[9]; d.d11 = d.dirt.orbits[10]; d.d12 = d.dirt.orbits[11];
|
||||
);
|
||||
d.dirt.soundLibrary.addMIDI(\midi, MIDIOut.newByName("MIDI", "Bus 1"));
|
||||
d.dirt.soundLibrary.addMIDI(\midi2, MIDIOut.newByName("MIDI", "Bus 2"));
|
||||
// d = ();
|
||||
// // Exceptional Dual Sardine Boot
|
||||
// d.dirt = SuperDirt(2, s);
|
||||
// d.dirt.fileExtensions = ["wav","aif","aiff","aifc","mp3"];
|
||||
// d.dirt.loadSoundFiles("/Users/bubo/Library/Application\ Support/Sardine/SON/*");
|
||||
// d.dirt.loadSoundFiles("/Users/bubo/.config/livecoding/samples/*");
|
||||
// d.dirt.doNotReadYet = true;
|
||||
// d.dirt.start(57120, [ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22]);
|
||||
// (
|
||||
// d.d1 = d.dirt.orbits[0]; d.d2 = d.dirt.orbits[1]; d.d3 = d.dirt.orbits[2];
|
||||
// d.d4 = d.dirt.orbits[3]; d.d5 = d.dirt.orbits[4]; d.d6 = d.dirt.orbits[5];
|
||||
// d.d7 = d.dirt.orbits[6]; d.d8 = d.dirt.orbits[7]; d.d9 = d.dirt.orbits[8];
|
||||
// d.d10 = d.dirt.orbits[9]; d.d11 = d.dirt.orbits[10]; d.d12 = d.dirt.orbits[11];
|
||||
// );
|
||||
// d.dirt.soundLibrary.addMIDI(\midi, MIDIOut.newByName("MIDI", "Bus 1"));
|
||||
// d.dirt.soundLibrary.addMIDI(\midi2, MIDIOut.newByName("MIDI", "Bus 2"));
|
||||
s.latency = 0.3;
|
||||
|
||||
// Resume normal boot sequence
|
||||
@ -92,8 +92,26 @@ Boot {
|
||||
Server.default.avgCPU.round(2),
|
||||
Server.default.peakCPU.round(2)), 40)
|
||||
}, Server.default);
|
||||
|
||||
// This custom event is used for audio looping
|
||||
Event.addEventType(\buboLoopEvent, {
|
||||
arg server;
|
||||
if (~sp.notNil && ~nb.notNil, {
|
||||
~sp = ~sp ?? 'default';
|
||||
~nb = ~nb ?? 0;
|
||||
~buf = Bank(~sp)[~nb % Bank(~sp).paths.size];
|
||||
if (Bank(~sp).metadata[~nb % Bank(~sp).size][\numChannels] == 1) {
|
||||
~instrument = \looperMono;
|
||||
} {
|
||||
~instrument = \looperStereo;
|
||||
};
|
||||
});
|
||||
~type = \note;
|
||||
currentEnvironment.play;
|
||||
});
|
||||
|
||||
// This custom event makes it easier to play samples
|
||||
Event.addEventType(\buboEvent, {
|
||||
// This is a custom event that makes it easier to play samples
|
||||
arg server;
|
||||
if (~sp.notNil && ~nb.notNil, {
|
||||
~sp = ~sp ?? 'default';
|
||||
|
||||
@ -40,34 +40,59 @@
|
||||
/* Syntax for sending MIDI messages */
|
||||
>> {
|
||||
arg pattern;
|
||||
var quant = this.getQuantFromPattern(pattern);
|
||||
var fade = this.getFadeFromPattern(pattern);
|
||||
pattern = EventShortener.findShortcuts(pattern);
|
||||
pattern = pattern ++ [type: 'midi'];
|
||||
this[0] = Pbind(*pattern);
|
||||
this.quant = 4; this.fadeTime = 0.01;
|
||||
this.quant = quant;
|
||||
this.fadeTime = fade;
|
||||
this.play;
|
||||
^this
|
||||
}
|
||||
|
||||
/* Player-like syntax sugar */
|
||||
/* Player syntax sugar */
|
||||
=> {
|
||||
arg pattern;
|
||||
var quant = this.getQuantFromPattern(pattern);
|
||||
var fade = this.getFadeFromPattern(pattern);
|
||||
pattern = EventShortener.findShortcuts(pattern);
|
||||
pattern = pattern ++ [\type, \buboEvent];
|
||||
this[0] = Pbind(*pattern);
|
||||
this.quant = 4; this.fadeTime = 0.01;
|
||||
this.quant = quant;
|
||||
this.fadeTime = fade;
|
||||
this.play;
|
||||
^this
|
||||
}
|
||||
|
||||
/* FIX: Completely broken. What is the event type
|
||||
* BuboEvent should fall back to after tweaking
|
||||
* the pattern to my liking?
|
||||
*/
|
||||
/* Audio Looper (sample playback) */
|
||||
== {
|
||||
arg pattern;
|
||||
var quant = this.getQuantFromPattern(pattern);
|
||||
var fade = this.getFadeFromPattern(pattern);
|
||||
pattern = EventShortener.findShortcuts(pattern);
|
||||
pattern = pattern ++ [\type, \buboLoopEvent];
|
||||
pattern = pattern ++ [\legato, 1];
|
||||
pattern = pattern ++ [
|
||||
\time, Pkey(\dur) / Pfunc { currentEnvironment.clock.tempo }
|
||||
];
|
||||
this[0] = Pbind(*pattern);
|
||||
this.quant = quant;
|
||||
this.fadeTime = fade;
|
||||
this.play;
|
||||
^this
|
||||
}
|
||||
|
||||
/* FIX: Rewrite this part, slightly broken */
|
||||
-> {
|
||||
arg pattern;
|
||||
var quant = this.getQuantFromPattern(pattern);
|
||||
var fade = this.getFadeFromPattern(pattern);
|
||||
pattern = EventShortener.findShortcuts(pattern);
|
||||
// pattern = pattern ++ [\type, \buboMonoEvent];
|
||||
this[0] = Pmono(*pattern);
|
||||
this.quant = 4;
|
||||
this.fadeTime = 0.01;
|
||||
this.quant = quant;
|
||||
this.fadeTime = fade;
|
||||
this.play;
|
||||
}
|
||||
|
||||
f {
|
||||
@ -96,4 +121,24 @@
|
||||
^this
|
||||
}
|
||||
|
||||
getQuantFromPattern {
|
||||
arg pattern; var quant;
|
||||
var quantIndex = pattern.indexOf('quant');
|
||||
if (quantIndex.notNil) {
|
||||
^pattern[quantIndex + 1]
|
||||
} {
|
||||
^0
|
||||
}
|
||||
}
|
||||
|
||||
getFadeFromPattern {
|
||||
arg pattern; var fade;
|
||||
var fadeIndex = pattern.indexOf('fade');
|
||||
if (fadeIndex.notNil) {
|
||||
^pattern[fadeIndex + 1]
|
||||
} {
|
||||
^0.01
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -7,3 +7,6 @@ c = currentEnvironment.clock;
|
||||
// Space for loading custom SynthDefs
|
||||
"Loading SynthDefs...".postln;
|
||||
"Synthdefs.scd".loadRelative;
|
||||
|
||||
// Debug during development
|
||||
// OSCFunc.trace(true);
|
||||
|
||||
@ -53,6 +53,55 @@ d.list = { arg obj; obj.keys.do({arg i; i.postln}); };
|
||||
d.splayer = z;
|
||||
);
|
||||
|
||||
|
||||
(
|
||||
/* Crafted with some help from Bruno Gola */
|
||||
z = SynthDef(\looperMono,
|
||||
{
|
||||
arg out;
|
||||
var sig, env, index;
|
||||
index = Select.kr(\direction.kr(1) > 0, [\index.kr(0) + 1, \index.kr]);
|
||||
sig = PlayBuf.ar(
|
||||
1,
|
||||
\buf.kr(0),
|
||||
(BufRateScale.kr(\buf.kr) * (BufSamples.kr(\buf.kr)
|
||||
/ \slices.kr(1) / BufSampleRate.kr(\buf.kr)) / \time.kr * \direction.kr) / 2,
|
||||
1, BufSamples.kr(\buf.kr) * (index / \slices.kr), doneAction: 0
|
||||
);
|
||||
env = EnvGen.ar(
|
||||
Env.asr(0.01, 1, 0.01), \gate.kr(1), doneAction: 2
|
||||
);
|
||||
sig = sig * env;
|
||||
sig = sig * \amp.kr(-6.dbamp);
|
||||
OffsetOut.ar(out,Pan2.ar(sig,\pan.kr(0)));
|
||||
}).add;
|
||||
d.looperMono = z;
|
||||
);
|
||||
|
||||
(
|
||||
/* Crafted with some help from Bruno Gola */
|
||||
z = SynthDef(\looperStereo,
|
||||
{
|
||||
arg out;
|
||||
var sig, env, index;
|
||||
index = Select.kr(\direction.kr(1) > 0, [\index.kr(0) + 1, \index.kr]);
|
||||
sig = PlayBuf.ar(
|
||||
2,
|
||||
\buf.kr(0),
|
||||
(BufRateScale.kr(\buf.kr) * (BufSamples.kr(\buf.kr)
|
||||
/ \slices.kr(1) / BufSampleRate.kr(\buf.kr)) / \time.kr * \direction.kr) / 2,
|
||||
1, BufSamples.kr(\buf.kr) * (index / \slices.kr), doneAction: 0
|
||||
);
|
||||
env = EnvGen.ar(
|
||||
Env.asr(0.01, 1, 0.01), \gate.kr(1), doneAction: 2
|
||||
);
|
||||
sig = sig * env;
|
||||
sig = sig * \amp.kr(-6.dbamp);
|
||||
OffsetOut.ar(out,Pan2.ar(sig,\pan.kr(0)));
|
||||
}).add;
|
||||
d.looperStereo = z;
|
||||
);
|
||||
|
||||
(
|
||||
z = SynthDef(\sinfb, {
|
||||
arg out;
|
||||
|
||||
33
test_breakbeat.scd
Normal file
33
test_breakbeat.scd
Normal file
@ -0,0 +1,33 @@
|
||||
~a => [sp: ["kick", \].pseq(inf), nb: 0, db: 0];
|
||||
|
||||
~a.play;
|
||||
|
||||
~a.clear;
|
||||
|
||||
Scope()
|
||||
|
||||
(
|
||||
var sampleStr = "kick:2(1) snare:4(1/4) . hihat:1(1/8) .";
|
||||
a = { |sampleStr, defaultRestDuration = 1.0|
|
||||
var pattern = "(\\w+):(\\d+)\\(([\\d/]+)\\)|\\.";
|
||||
var matches = sampleStr.findAllRegexp(pattern);
|
||||
matches.collect { |match|
|
||||
if(match.size == 1) {
|
||||
[ 'sp': 'rest', 'nb': 0, 'dur': defaultRestDuration ]
|
||||
} {
|
||||
var sampleName = match[0];
|
||||
var sampleNumber = match[1].asInteger;
|
||||
var duration = match[2];
|
||||
var durationValue;
|
||||
if(duration.contains("/")) {
|
||||
var nums = duration.split("/");
|
||||
durationValue = nums[0].asInteger / nums[1].asInteger;
|
||||
} {
|
||||
durationValue = duration.asFloat;
|
||||
};
|
||||
[ 'sp': sampleName, 'nb': sampleNumber, 'dur': durationValue ]
|
||||
}
|
||||
}
|
||||
};
|
||||
a.value(sampleStr);
|
||||
)
|
||||
Reference in New Issue
Block a user