fixing some of the current issues with pat

This commit is contained in:
2024-05-14 15:21:50 +02:00
parent 6f61558ffb
commit 74642bd1f4
6 changed files with 151 additions and 73 deletions

View File

@@ -2,7 +2,7 @@ Bank : Singleton {
classvar <>root, <>extensions, <>lazyLoading=true; classvar <>root, <>extensions, <>lazyLoading=true;
var <paths, buffers, <channels, <foundRoot, <foundRootModTime, markersCache, atCache; var <paths, buffers, <channels, <foundRoot, <foundRootModTime, markersCache, atCache;
var metadata; var metadata;
*initClass { *initClass {
root = "/Users/bubo/.config/livecoding/samples".standardizePath; root = "/Users/bubo/.config/livecoding/samples".standardizePath;
extensions = ["wav", "aiff", "aif", "flac", "ogg"]; extensions = ["wav", "aiff", "aif", "flac", "ogg"];
@@ -13,45 +13,56 @@ Bank : Singleton {
arg item; item.folderName.postln; arg item; item.folderName.postln;
}) })
} }
*contains {
arg sample;
var folderNames = PathName(Bank.root).entries.collect({
arg item;
if (item.folderName == sample) {
^true
}
});
^false;
}
*new { *new {
|path, channels| |path, channels|
^super.new(path, channels); ^super.new(path, channels);
} }
size { size {
^paths.size ^paths.size
} }
printOn { printOn {
|stream| |stream|
super.printOn(stream); super.printOn(stream);
stream << "[%]".format(paths.size) stream << "[%]".format(paths.size)
} }
init { init {
var currentRoot, currentExtensions, foundPaths=[], attempts = List(); var currentRoot, currentExtensions, foundPaths=[], attempts = List();
var fixedName; var fixedName;
buffers = []; buffers = [];
ServerQuit.add(this); ServerQuit.add(this);
ServerBoot.add(this); ServerBoot.add(this);
fixedName = name.asString fixedName = name.asString
.replace("[", "\\[") .replace("[", "\\[")
.replace("]", "\\]") .replace("]", "\\]")
.replace("(", "\\(") .replace("(", "\\(")
.replace(")", "\\)"); .replace(")", "\\)");
if (foundRootModTime.notNil) { if (foundRootModTime.notNil) {
if (foundRoot.notNil and: { File.exists(foundRoot) } and: { File.mtime(foundRoot) == foundRootModTime }) { if (foundRoot.notNil and: { File.exists(foundRoot) } and: { File.mtime(foundRoot) == foundRootModTime }) {
^this; // no changes, so early return! ^this; // no changes, so early return!
} }
}; };
currentExtensions = this.class.extensions; currentExtensions = this.class.extensions;
currentRoot = thisProcess.nowExecutingPath; currentRoot = thisProcess.nowExecutingPath;
// Try an absolute path resolve first // Try an absolute path resolve first
foundPaths = Require.resolvePaths(fixedName, [], currentExtensions, attempts); foundPaths = Require.resolvePaths(fixedName, [], currentExtensions, attempts);
if (foundPaths.isEmpty.not) { if (foundPaths.isEmpty.not) {
@@ -61,23 +72,23 @@ Bank : Singleton {
currentRoot = PathName(currentRoot).parentPath; currentRoot = PathName(currentRoot).parentPath;
foundPaths = Require.resolvePaths(fixedName, currentRoot, currentExtensions, attempts); foundPaths = Require.resolvePaths(fixedName, currentRoot, currentExtensions, attempts);
}; };
if (foundPaths.isEmpty and: { currentRoot.notNil }) { if (foundPaths.isEmpty and: { currentRoot.notNil }) {
currentRoot = currentRoot +/+ fixedName.asString; currentRoot = currentRoot +/+ fixedName.asString;
foundPaths = Require.resolvePaths("*", currentRoot, currentExtensions, attempts); foundPaths = Require.resolvePaths("*", currentRoot, currentExtensions, attempts);
}; };
if (foundPaths.isEmpty) { if (foundPaths.isEmpty) {
currentRoot = this.class.root; currentRoot = this.class.root;
foundPaths = Require.resolvePaths(fixedName, currentRoot, currentExtensions, attempts); foundPaths = Require.resolvePaths(fixedName, currentRoot, currentExtensions, attempts);
}; };
if (foundPaths.isEmpty) { if (foundPaths.isEmpty) {
currentRoot = currentRoot +/+ fixedName; currentRoot = currentRoot +/+ fixedName;
foundPaths = Require.resolvePaths("*", currentRoot, currentExtensions, attempts); foundPaths = Require.resolvePaths("*", currentRoot, currentExtensions, attempts);
}; };
}; };
if (foundPaths.isEmpty) { if (foundPaths.isEmpty) {
foundRoot = nil; foundRoot = nil;
foundRootModTime = nil; foundRootModTime = nil;
@@ -90,7 +101,7 @@ Bank : Singleton {
foundRoot = currentRoot; foundRoot = currentRoot;
foundRootModTime = File.mtime(foundRoot) ?? {0}; foundRootModTime = File.mtime(foundRoot) ?? {0};
}; };
foundPaths = foundPaths.sort({ foundPaths = foundPaths.sort({
|a, b| |a, b|
var pair; var pair;
@@ -108,12 +119,12 @@ Bank : Singleton {
pair[0] < pair[1] pair[0] < pair[1]
} ?? { false } } ?? { false }
}); });
atCache = (); atCache = ();
paths = foundPaths; paths = foundPaths;
this.metadata; this.metadata;
} }
prGetMetadata { prGetMetadata {
^paths.collect { ^paths.collect {
|path| |path|
@@ -131,7 +142,7 @@ Bank : Singleton {
}; };
} }
} }
metadata { metadata {
|key| |key|
metadata = metadata ?? this.prGetMetadata(_); metadata = metadata ?? this.prGetMetadata(_);
@@ -141,7 +152,7 @@ Bank : Singleton {
^metadata[this.indexForKey(key)] ^metadata[this.indexForKey(key)]
} }
} }
lazyLoading_{ lazyLoading_{
|lazy| |lazy|
if (lazyLoading != lazy) { if (lazyLoading != lazy) {
@@ -149,20 +160,20 @@ Bank : Singleton {
this.prUpdateBuffers(); this.prUpdateBuffers();
} }
} }
buffers { buffers {
^paths.size.collect { ^paths.size.collect {
|i| |i|
this.bufferAt(i) this.bufferAt(i)
} }
} }
gui { gui {
var view, sampleViews, button, name; var view, sampleViews, button, name;
var playNode; var playNode;
this.lazyLoading = false; this.lazyLoading = false;
view = View().layout_(GridLayout.rows()); view = View().layout_(GridLayout.rows());
paths.do { paths.do {
|path, i| |path, i|
@@ -196,7 +207,7 @@ Bank : Singleton {
); );
sampleViews = sampleViews.add(sampleView); sampleViews = sampleViews.add(sampleView);
}; };
view.keyUpAction = { view.keyUpAction = {
|view, char, modifiers, unicode, keycode, key| |view, char, modifiers, unicode, keycode, key|
switch( switch(
@@ -215,10 +226,10 @@ Bank : Singleton {
} }
) )
}; };
ScrollView(bounds:500@600).canvas_(view).front; ScrollView(bounds:500@600).canvas_(view).front;
} }
set { set {
|inChannels| |inChannels|
if (channels != inChannels) { if (channels != inChannels) {
@@ -227,13 +238,13 @@ Bank : Singleton {
this.prUpdateBuffers(); this.prUpdateBuffers();
}; };
} }
clear { clear {
paths = []; paths = [];
atCache = (); atCache = ();
this.prUpdateBuffers(); this.prUpdateBuffers();
} }
bufferAt { bufferAt {
|index| |index|
var sf; var sf;
@@ -249,20 +260,20 @@ Bank : Singleton {
buffers[index] = Buffer.readChannel(Server.default, paths[index], channels:Array.series(channels)); buffers[index] = Buffer.readChannel(Server.default, paths[index], channels:Array.series(channels));
}; };
}; };
buffers[index]; buffers[index];
} }
} }
} }
indexForKey { indexForKey {
|key| |key|
var index; var index;
if (key.isArray && key.isString.not) { if (key.isArray && key.isString.not) {
^key.collect(this.at(_)) ^key.collect(this.at(_))
}; };
if (key.isInteger) { if (key.isInteger) {
index = key index = key
} { } {
@@ -277,15 +288,15 @@ Bank : Singleton {
atCache[key.asSymbol] = index; atCache[key.asSymbol] = index;
} }
}; };
^index ^index
} }
at { at {
|key| |key|
^this.bufferAt(this.indexForKey(key)); ^this.bufferAt(this.indexForKey(key));
} }
markers { markers {
^markersCache ?? { ^markersCache ?? {
markersCache = paths.collect({ markersCache = paths.collect({
@@ -294,7 +305,7 @@ Bank : Singleton {
}) })
} }
} }
wrapAt { wrapAt {
|index| |index|
if (index.isInteger) { if (index.isInteger) {
@@ -302,10 +313,10 @@ Bank : Singleton {
}; };
^this.at(index); ^this.at(index);
} }
do { |...args| buffers.size.collect(this.bufferAt(_)).do(*args) } do { |...args| buffers.size.collect(this.bufferAt(_)).do(*args) }
collect { |...args| ^buffers.size.collect(this.bufferAt(_)).collect(*args) } collect { |...args| ^buffers.size.collect(this.bufferAt(_)).collect(*args) }
prUpdateBuffers { prUpdateBuffers {
if (Server.default.serverBooting or: { if (Server.default.serverBooting or: {
Server.default.hasBooted && Server.default.serverRunning.not Server.default.hasBooted && Server.default.serverRunning.not
@@ -315,18 +326,18 @@ Bank : Singleton {
}; };
^this; ^this;
}; };
if (Server.default.serverRunning.not) { if (Server.default.serverRunning.not) {
buffers = []; buffers = [];
} { } {
if (paths.size > buffers.size) { buffers = buffers.extend(paths.size) }; if (paths.size > buffers.size) { buffers = buffers.extend(paths.size) };
paths.do { paths.do {
|path, i| |path, i|
var buffer; var buffer;
buffer = buffers[i]; buffer = buffers[i];
if (path.notNil) { if (path.notNil) {
if (lazyLoading.not) { if (lazyLoading.not) {
this.bufferAt(i) this.bufferAt(i)
@@ -338,7 +349,7 @@ Bank : Singleton {
} }
} }
}; };
buffers[paths.size..].do { buffers[paths.size..].do {
|b| |b|
b.free; b.free;
@@ -346,7 +357,7 @@ Bank : Singleton {
buffers.extend(paths.size); buffers.extend(paths.size);
} }
} }
doOnServerBoot { doOnServerBoot {
if (paths.size > 0) { if (paths.size > 0) {
buffers = []; buffers = [];
@@ -354,27 +365,27 @@ Bank : Singleton {
"***Loaded samples for %***".format(this.asString).postln; "***Loaded samples for %***".format(this.asString).postln;
} }
} }
doOnServerQuit { doOnServerQuit {
buffers = []; buffers = [];
} }
pat { pat {
|keyPat| |keyPat|
^Pindex(Pseq([this], inf), keyPat) ^Pindex(Pseq([this], inf), keyPat)
} }
// Single buffer support // Single buffer support
asBuffer { ^this.singleSampleWrap(nil) } asBuffer { ^this.singleSampleWrap(nil) }
asControlInput { |...args| ^this.prSingleSampleWrap(\asControlInput, *args) } asControlInput { |...args| ^this.prSingleSampleWrap(\asControlInput, *args) }
play { |...args| ^this.prSingleSampleWrap(\play, *args) } play { |...args| ^this.prSingleSampleWrap(\play, *args) }
prSingleSampleWrap { prSingleSampleWrap {
|method ...args| |method ...args|
var buffer; var buffer;
if (buffers.size == 1) { if (buffers.size == 1) {
buffer = this.bufferAt(0); buffer = this.bufferAt(0);
if (method.isNil) { if (method.isNil) {
^buffer ^buffer
} { } {

View File

@@ -95,6 +95,10 @@ Boot {
Event.addEventType(\buboLoopEvent, { Event.addEventType(\buboLoopEvent, {
arg server; arg server;
[~sp, ~nb].postln;
~sp = BuboUtils.cleanSampleName(~sp);
~nb = BuboUtils.cleanSampleIndex(~nb);
[~sp, ~nb].postln;
if (~sp.notNil && ~nb.notNil, { if (~sp.notNil && ~nb.notNil, {
~sp = ~sp ?? 'default'; ~sp = ~sp ?? 'default';
~nb = ~nb ?? 0; ~nb = ~nb ?? 0;
@@ -111,18 +115,21 @@ Boot {
Event.addEventType(\buboEvent, { Event.addEventType(\buboEvent, {
arg server; arg server;
~sp = BuboUtils.cleanSampleName(~sp);
~nb = BuboUtils.cleanSampleIndex(~nb);
if (~sp.notNil && ~nb.notNil, { if (~sp.notNil && ~nb.notNil, {
~sp = ~sp ?? 'default'; if (~sp != "", {
~nb = ~nb ?? 0; ~buf = Bank(~sp)[~nb % Bank(~sp).paths.size];
~buf = Bank(~sp)[~nb % Bank(~sp).paths.size]; if (Bank(~sp).metadata[~nb % Bank(~sp).size][\numChannels] == 1) {
if (Bank(~sp).metadata[~nb % Bank(~sp).size][\numChannels] == 1) { ~instrument = \player;
~instrument = \player; } {
} { ~instrument = \splayer;
~instrument = \splayer; };
}; })
}); });
~type = \note; ~type = \note;
currentEnvironment.play; currentEnvironment.play;
}); });
} }
} }

View File

@@ -12,6 +12,20 @@ BuboUtils {
) )
} }
*cleanSampleName {
arg str;
if (str == nil, { ^nil });
^str.asList.collect({
|char|
if (char.isAlpha, char, "")
}).join
}
*cleanSampleIndex {
arg number;
if (number.isKindOf(Number), { ^number }, { ^0 });
}
*banner { *banner {
var banner = "┳┓ ┓ ┳┓ ┓ ┳┓\n" var banner = "┳┓ ┓ ┳┓ ┓ ┳┓\n"
"┣┫┓┏┣┓┏┓┣┫┓┏┣┓┏┓ ┣┫┏┓┏┓╋\n" "┣┫┓┏┣┓┏┓┣┫┓┏┣┓┏┓ ┣┫┏┓┏┓╋\n"
@@ -39,4 +53,3 @@ BuboUtils {
}); });
} }
} }

View File

@@ -19,7 +19,7 @@ d.list = { arg obj; obj.keys.do({arg i; i.postln}); };
trigger: 1, startPos:startPos, trigger: 1, startPos:startPos,
loop:\loop.kr(0), doneAction: 2); loop:\loop.kr(0), doneAction: 2);
sig = sig * \amp.kr(-6).dbamp; sig = sig * \amp.kr(-6).dbamp;
sig = Pan2.ar(sig * env, \pan.kr(0)); sig = Pan2.ar(sig * env, \pan.kr(0.0));
OffsetOut.ar(out, sig) OffsetOut.ar(out, sig)
}).add; }).add;
d.player = z; d.player = z;
@@ -47,7 +47,7 @@ d.list = { arg obj; obj.keys.do({arg i; i.postln}); };
trigger: 1, startPos:startPos, trigger: 1, startPos:startPos,
loop:\loop.kr(0), doneAction: 2); loop:\loop.kr(0), doneAction: 2);
sig = sig * \amp.kr(-6).dbamp; sig = sig * \amp.kr(-6).dbamp;
sig = Pan2.ar(sig * env, \pan.kr(0)); sig = Pan2.ar(sig * env, \pan.kr(0.0));
OffsetOut.ar(out, sig) OffsetOut.ar(out, sig)
}).add; }).add;
d.splayer = z; d.splayer = z;

View File

@@ -54,9 +54,9 @@ EventShortener {
if (type !== 'midi', { if (type !== 'midi', {
if (pattern.includes('i') || pattern.includes('instrument') == false, { if (pattern.includes('i') || pattern.includes('instrument') == false, {
new_pattern = new_pattern ++ [ new_pattern = new_pattern ++ [
sp: Pfunc { |e| e.str ? "kick" }, sp: Pfunc { |e| e.str ? 'default' },
nb: Pfunc { |e| e.num ? 0 }, nb: Pfunc(\num),
instrument: Pfunc { |e| e.str.isNil && e.num.isNil ? "default" }, instrument: 'default',
fast: 1, fast: 1,
]; ];
}); });

View File

@@ -6,16 +6,16 @@
// BUG: Evalue moi // BUG: Evalue moi
m = MIDIOut.newByName("MIDI", "Bus 1"); m = MIDIOut.newByName("MIDI", "Bus 1");
// NOTE: Pattern rythmique de base
( (
~test => [ sp: "kick", nb: 0]; ~test => [ sp: "kick", nb: 0 ];
~test.play; ~test.play;
) )
// NOTE: Pattern avec Pmini ~test.source.patternpairs
( (
~test => [ pat: "kick:4 snare:3" ]; ~fun => [ pat: "kick:4 snare:3" ];
~test.play; ~fun.play;
) )
// NOTE: Pattern sans numéro maintenant ! // NOTE: Pattern sans numéro maintenant !
@@ -40,8 +40,6 @@ Sweep.help
sound sound
}); });
~rhythm.play; ~rhythm.play;
)
~basse => [ ~basse => [
pat: "0(5,8)/2", pat: "0(5,8)/2",
i: "kraut", i: "kraut",
@@ -156,15 +154,32 @@ m = MIDIOut.newByName("MIDI", "Bus 1");
( (
~ground => [pat: "[kick:2(5,16)/16, fgood:11/2]", release: 4, quant: 4]; ~ground => [
pat: "[kick:2(5,16)/16, cgood:11/2 lgood:13]*2",
release: [4, 2, 1].pseq(inf),
quant: 4,
// test: Pfunc { |e| e.postln; },
// finish: { currentEnvironment.keysValuesDo {
// |key, val|
// "%: %".format(key, val).postln}
// },
];
~ground.play;
)
(
~snare => [pat: "[~ snare]/16", release: 4, quant: 4]; ~snare => [pat: "[~ snare]/16", release: 4, quant: 4];
~snare.fx1(0.7, {arg in; MiVerb.ar(in, time: 0.7)}); ~snare.fx1(0.7, {arg in; MiVerb.ar(in, time: 0.7)});
~snare.play;
)
(
~hat => [pat: "[sound:2|hat:5] hat:2 hat:3!2", release: 1/32, ~hat => [pat: "[sound:2|hat:5] hat:2 hat:3!2", release: 1/32,
amp: [0.0,-12.0].pwhite(inf), quant: 4 amp: [0.0,-12.0].pwhite(inf), quant: 4
]; ];
~hat.play; ~hat.play;
~snare.play; )
~ground.play;
~vorb => [ ~vorb => [
instrument: 'kraut', instrument: 'kraut',
octave: 4, octave: 4,
@@ -190,3 +205,35 @@ m = MIDIOut.newByName("MIDI", "Bus 1");
}); });
~apply.play; ~apply.play;
) )
Bank("default")[0].play
// NOTE: absolute crash (attention !)
(
~other => [
sp: "synthi", nb: 2,
release: 1/4, rate: 0.75,
pan: [0.0, 1.0].pwhite,
];
~other.mold(2);
~other.play;
)
// Faire le point sur la situation : qu'est-ce qui marche et ne marche pas ?
// NOTE: Pattern le plus basique
~a => [sp: "kick", nb: 4];
~a.play;
~a.clear;
// NOTE: Pattern avec Pmini
~a => [pat: "[kick hat snare hat]/2"];
~a.play;
~a.clear;
// NOTE: pattern de base, sample mal formée
// WARNING: le crash se produit ici !
~a => [sp: "kick:2", nb: 4];
~a.play;