SAMP Update + Buffer Allocation Fix
- Updating to the latest version of SAMP (Bank) - Reserving an absurdly high number of buffers for samples
This commit is contained in:
590
Classes/Bank.sc
590
Classes/Bank.sc
@ -3,13 +3,341 @@
|
|||||||
* I have added a method to list the samples in the bank.
|
* I have added a method to list the samples in the bank.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Bank : Singleton {
|
||||||
|
// classvar <>root, <>extensions, <>lazyLoading=true;
|
||||||
|
// var <paths, buffers, <channels, <foundRoot, <foundRootModTime, markersCache, atCache;
|
||||||
|
//
|
||||||
|
// *initClass {
|
||||||
|
// root = "/Users/bubo/.config/livecoding/samples".standardizePath;
|
||||||
|
// extensions = ["wav", "aiff", "aif", "flac", "mp3"];
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// *list {
|
||||||
|
// PathName(Bank.root).entries.do({
|
||||||
|
// arg item; item.folderName.postln;
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// *new {
|
||||||
|
// |path, channels|
|
||||||
|
// ^super.new(path, channels);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// printOn {
|
||||||
|
// |stream|
|
||||||
|
// super.printOn(stream);
|
||||||
|
// stream << "[%]".format(paths.size)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// init {
|
||||||
|
// buffers = [];
|
||||||
|
// ServerQuit.add(this);
|
||||||
|
// ServerBoot.add(this);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// lazyLoading_{
|
||||||
|
//
|
||||||
|
// |lazy|
|
||||||
|
//
|
||||||
|
// if (lazyLoading != lazy) {
|
||||||
|
// lazyLoading = lazy;
|
||||||
|
// this.prUpdateBuffers();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// buffers {
|
||||||
|
// ^paths.size.collect {
|
||||||
|
// |i|
|
||||||
|
// this.bufferAt(i)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// gui {
|
||||||
|
// var view, button, name;
|
||||||
|
//
|
||||||
|
// this.lazyLoading = false;
|
||||||
|
//
|
||||||
|
// view = View().layout_(GridLayout.rows());
|
||||||
|
// paths.do {
|
||||||
|
// |path, i|
|
||||||
|
// name = PathName(path).fileNameWithoutExtension;
|
||||||
|
// view.layout.add(
|
||||||
|
// DragSource()
|
||||||
|
// .object_("%(%)[%]".format(
|
||||||
|
// this.class.name,
|
||||||
|
// channels !? {
|
||||||
|
// "'%', %".format(this.name, channels)
|
||||||
|
// } ?? {
|
||||||
|
// "'%'".format(this.name)
|
||||||
|
// },
|
||||||
|
// name.quote
|
||||||
|
// ))
|
||||||
|
// .string_(name)
|
||||||
|
// .canFocus_(true)
|
||||||
|
// .font_(Font("M+ 2c", 10, false))
|
||||||
|
// .minWidth_(100)
|
||||||
|
// .mouseDownAction_({ |v| if (v.focus) { this.bufferAt(i).play } })
|
||||||
|
// .keyDownAction_({ this.bufferAt(i).play })
|
||||||
|
// .focusGainedAction_({ this.bufferAt(i).play }),
|
||||||
|
// (i / 4).floor,
|
||||||
|
// i % 4
|
||||||
|
// );
|
||||||
|
// };
|
||||||
|
// ScrollView(bounds:500@600).canvas_(view).front;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// set {
|
||||||
|
// |inChannels|
|
||||||
|
// var currentRoot, currentExtensions, foundPaths=[], attempts = List();
|
||||||
|
//
|
||||||
|
// if (channels != inChannels) {
|
||||||
|
// channels = inChannels;
|
||||||
|
// this.clear();
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// if (foundRootModTime.notNil) {
|
||||||
|
// if (File.mtime(foundRoot) == foundRootModTime) {
|
||||||
|
// ^this; // no changes, so early return!
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// currentExtensions = this.class.extensions;
|
||||||
|
// currentRoot = thisProcess.nowExecutingPath;
|
||||||
|
//
|
||||||
|
// if (currentRoot.notNil) {
|
||||||
|
// currentRoot = PathName(currentRoot).parentPath;
|
||||||
|
// foundPaths = Require.resolvePaths(name.asString, currentRoot, currentExtensions, attempts);
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// if (currentRoot.notNil) {
|
||||||
|
// currentRoot = currentRoot +/+ name.asString;
|
||||||
|
// foundPaths = Require.resolvePaths("*", currentRoot, currentExtensions, attempts);
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// if (foundPaths.isEmpty) {
|
||||||
|
// currentRoot = this.class.root;
|
||||||
|
// foundPaths = Require.resolvePaths(name.asString, currentRoot, currentExtensions, attempts);
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// if (foundPaths.isEmpty) {
|
||||||
|
// currentRoot = currentRoot +/+ name.asString;
|
||||||
|
// foundPaths = Require.resolvePaths("*", currentRoot, currentExtensions, attempts);
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// if (foundPaths.isEmpty) {
|
||||||
|
// foundRoot = nil;
|
||||||
|
// foundRootModTime = nil;
|
||||||
|
// "No samples found, attempted paths: ".warn;
|
||||||
|
// attempts.do {
|
||||||
|
// |a|
|
||||||
|
// "\t%.{%}".format(a, currentExtensions.join(",")).warn
|
||||||
|
// };
|
||||||
|
// } {
|
||||||
|
// foundRoot = currentRoot;
|
||||||
|
// foundRootModTime = File.mtime(foundRoot) ?? {0};
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// foundPaths = foundPaths.sort({
|
||||||
|
// |a, b|
|
||||||
|
// var pair;
|
||||||
|
// #a, b = [a, b].collect {
|
||||||
|
// |p|
|
||||||
|
// p = p.toLower;
|
||||||
|
// p = p.split($.).first;
|
||||||
|
// p = p.split($/).reverse;
|
||||||
|
// };
|
||||||
|
// pair = [a, b].flop.detect({
|
||||||
|
// |pair|
|
||||||
|
// pair[0] != pair[1]
|
||||||
|
// });
|
||||||
|
// pair !? {
|
||||||
|
// pair[0] < pair[1]
|
||||||
|
// } ?? { false }
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// if (paths != foundPaths) {
|
||||||
|
// paths = foundPaths;
|
||||||
|
// atCache = ();
|
||||||
|
// this.prUpdateBuffers();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// clear {
|
||||||
|
// paths = [];
|
||||||
|
// atCache = ();
|
||||||
|
// this.prUpdateBuffers()
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// bufferAt {
|
||||||
|
// |index|
|
||||||
|
// ^buffers !? {
|
||||||
|
// buffers[index] ?? {
|
||||||
|
// if (Server.default.serverRunning) {
|
||||||
|
// if (channels.isNil) {
|
||||||
|
// buffers[index] = Buffer.read(Server.default, paths[index])
|
||||||
|
// } {
|
||||||
|
// buffers[index] = Buffer.readChannel(Server.default, paths[index], channels:Array.series(channels));
|
||||||
|
// };
|
||||||
|
// };
|
||||||
|
// buffers[index];
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// at {
|
||||||
|
// |key|
|
||||||
|
// var index;
|
||||||
|
//
|
||||||
|
// if (key.isArray && { key.isString.not }) {
|
||||||
|
// ^key.collect(this.at(_))
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// if (key.isInteger) {
|
||||||
|
// index = key
|
||||||
|
// } {
|
||||||
|
// index = atCache[key.asSymbol];
|
||||||
|
// if (index.isNil) {
|
||||||
|
// index = paths.detectIndex({
|
||||||
|
// |path|
|
||||||
|
// key.asString.toLower.replace("*", ".*").matchRegexp(
|
||||||
|
// path.asString.toLower
|
||||||
|
// );
|
||||||
|
// });
|
||||||
|
// atCache[key.asSymbol] = index;
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// ^this.bufferAt(index);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// markers {
|
||||||
|
// ^markersCache ?? {
|
||||||
|
// markersCache = paths.collect({
|
||||||
|
// |path|
|
||||||
|
// SoundFile(path).extractMarkers
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// wrapAt {
|
||||||
|
// |index|
|
||||||
|
// if (index.isInteger) {
|
||||||
|
// index = index % buffers.size;
|
||||||
|
// };
|
||||||
|
// ^this.at(index);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// do {
|
||||||
|
// |...args|
|
||||||
|
// buffers.size.collect(this.bufferAt(_)).do(*args)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// collect {
|
||||||
|
// |...args|
|
||||||
|
// ^buffers.size.collect(this.bufferAt(_)).collect(*args)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// prUpdateBuffers {
|
||||||
|
// if (Server.default.serverBooting or: {
|
||||||
|
// Server.default.hasBooted && Server.default.serverRunning.not
|
||||||
|
// }) {
|
||||||
|
// Server.default.doWhenBooted {
|
||||||
|
// this.prUpdateBuffers();
|
||||||
|
// };
|
||||||
|
// ^this;
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// if (Server.default.serverRunning.not) {
|
||||||
|
// buffers = [];
|
||||||
|
// } {
|
||||||
|
// if (paths.size > buffers.size) { buffers = buffers.extend(paths.size) };
|
||||||
|
//
|
||||||
|
// paths.do {
|
||||||
|
// |path, i|
|
||||||
|
// var buffer;
|
||||||
|
//
|
||||||
|
// buffer = buffers[i];
|
||||||
|
//
|
||||||
|
// if (path.notNil) {
|
||||||
|
// if (lazyLoading.not) {
|
||||||
|
// this.bufferAt(i)
|
||||||
|
// }
|
||||||
|
// } {
|
||||||
|
// if (buffer.notNil) {
|
||||||
|
// buffer.free;
|
||||||
|
// buffers[i] = buffer = nil;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// buffers.extend(paths.size);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// doOnServerBoot {
|
||||||
|
// if (paths.size > 0) {
|
||||||
|
// buffers = [];
|
||||||
|
// this.prUpdateBuffers();
|
||||||
|
// "***Loaded samples for %***".format(this.asString).postln;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// doOnServerQuit {
|
||||||
|
// buffers = [];
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// pat {
|
||||||
|
// |keyPat|
|
||||||
|
// ^Pindex(Pseq([this], inf), keyPat)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// asBuffer {
|
||||||
|
// ^this.singleSampleWrap(nil)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// asControlInput {
|
||||||
|
// |...args|
|
||||||
|
// ^this.prSingleSampleWrap(\asControlInput, *args)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// play {
|
||||||
|
// |...args|
|
||||||
|
// ^this.prSingleSampleWrap(\play, *args)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// prSingleSampleWrap {
|
||||||
|
// |method ...args|
|
||||||
|
// var buffer;
|
||||||
|
// if (buffers.size == 1) {
|
||||||
|
// buffer = this.bufferAt(0);
|
||||||
|
//
|
||||||
|
// if (method.isNil) {
|
||||||
|
// ^buffer
|
||||||
|
// } {
|
||||||
|
// if (buffer.numFrames.isNil) {
|
||||||
|
// fork {
|
||||||
|
// Server.default.sync;
|
||||||
|
// buffer.performList(method, args)
|
||||||
|
// };
|
||||||
|
// ^nil;
|
||||||
|
// } {
|
||||||
|
// ^buffer.performList(method, args)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// } {
|
||||||
|
// Error("Trying to % a bank with multiple buffers".format(method)).throw;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
Bank : Singleton {
|
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;
|
||||||
|
|
||||||
*initClass {
|
*initClass {
|
||||||
root = "/Users/bubo/.config/livecoding/samples".standardizePath;
|
root = "/Users/bubo/.config/livecoding/samples".standardizePath;
|
||||||
extensions = ["wav", "aiff", "aif", "flac", "mp3"];
|
extensions = ["wav", "aiff", "aif", "flac", "ogg"];
|
||||||
}
|
}
|
||||||
|
|
||||||
*list {
|
*list {
|
||||||
@ -23,6 +351,10 @@ Bank : Singleton {
|
|||||||
^super.new(path, channels);
|
^super.new(path, channels);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size {
|
||||||
|
^paths.size
|
||||||
|
}
|
||||||
|
|
||||||
printOn {
|
printOn {
|
||||||
|stream|
|
|stream|
|
||||||
super.printOn(stream);
|
super.printOn(stream);
|
||||||
@ -30,73 +362,21 @@ Bank : Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
var currentRoot, currentExtensions, foundPaths=[], attempts = List();
|
||||||
|
var fixedName;
|
||||||
|
|
||||||
buffers = [];
|
buffers = [];
|
||||||
ServerQuit.add(this);
|
ServerQuit.add(this);
|
||||||
ServerBoot.add(this);
|
ServerBoot.add(this);
|
||||||
}
|
|
||||||
|
|
||||||
lazyLoading_{
|
fixedName = name.asString
|
||||||
|
.replace("[", "\\[")
|
||||||
|lazy|
|
.replace("]", "\\]")
|
||||||
|
.replace("(", "\\(")
|
||||||
if (lazyLoading != lazy) {
|
.replace(")", "\\)");
|
||||||
lazyLoading = lazy;
|
|
||||||
this.prUpdateBuffers();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buffers {
|
|
||||||
^paths.size.collect {
|
|
||||||
|i|
|
|
||||||
this.bufferAt(i)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gui {
|
|
||||||
var view, button, name;
|
|
||||||
|
|
||||||
this.lazyLoading = false;
|
|
||||||
|
|
||||||
view = View().layout_(GridLayout.rows());
|
|
||||||
paths.do {
|
|
||||||
|path, i|
|
|
||||||
name = PathName(path).fileNameWithoutExtension;
|
|
||||||
view.layout.add(
|
|
||||||
DragSource()
|
|
||||||
.object_("%(%)[%]".format(
|
|
||||||
this.class.name,
|
|
||||||
channels !? {
|
|
||||||
"'%', %".format(this.name, channels)
|
|
||||||
} ?? {
|
|
||||||
"'%'".format(this.name)
|
|
||||||
},
|
|
||||||
name.quote
|
|
||||||
))
|
|
||||||
.string_(name)
|
|
||||||
.canFocus_(true)
|
|
||||||
.font_(Font("M+ 2c", 10, false))
|
|
||||||
.minWidth_(100)
|
|
||||||
.mouseDownAction_({ |v| if (v.focus) { this.bufferAt(i).play } })
|
|
||||||
.keyDownAction_({ this.bufferAt(i).play })
|
|
||||||
.focusGainedAction_({ this.bufferAt(i).play }),
|
|
||||||
(i / 4).floor,
|
|
||||||
i % 4
|
|
||||||
);
|
|
||||||
};
|
|
||||||
ScrollView(bounds:500@600).canvas_(view).front;
|
|
||||||
}
|
|
||||||
|
|
||||||
set {
|
|
||||||
|inChannels|
|
|
||||||
var currentRoot, currentExtensions, foundPaths=[], attempts = List();
|
|
||||||
|
|
||||||
if (channels != inChannels) {
|
|
||||||
channels = inChannels;
|
|
||||||
this.clear();
|
|
||||||
};
|
|
||||||
|
|
||||||
if (foundRootModTime.notNil) {
|
if (foundRootModTime.notNil) {
|
||||||
if (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!
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -104,25 +384,31 @@ Bank : Singleton {
|
|||||||
currentExtensions = this.class.extensions;
|
currentExtensions = this.class.extensions;
|
||||||
currentRoot = thisProcess.nowExecutingPath;
|
currentRoot = thisProcess.nowExecutingPath;
|
||||||
|
|
||||||
|
// Try an absolute path resolve first
|
||||||
|
foundPaths = Require.resolvePaths(fixedName, [], currentExtensions, attempts);
|
||||||
|
if (foundPaths.isEmpty.not) {
|
||||||
|
currentRoot = PathName(fixedName).parentPath;
|
||||||
|
} {
|
||||||
if (currentRoot.notNil) {
|
if (currentRoot.notNil) {
|
||||||
currentRoot = PathName(currentRoot).parentPath;
|
currentRoot = PathName(currentRoot).parentPath;
|
||||||
foundPaths = Require.resolvePaths(name.asString, currentRoot, currentExtensions, attempts);
|
foundPaths = Require.resolvePaths(fixedName, currentRoot, currentExtensions, attempts);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (currentRoot.notNil) {
|
if (foundPaths.isEmpty and: { currentRoot.notNil }) {
|
||||||
currentRoot = currentRoot +/+ name.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(name.asString, currentRoot, currentExtensions, attempts);
|
foundPaths = Require.resolvePaths(fixedName, currentRoot, currentExtensions, attempts);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (foundPaths.isEmpty) {
|
if (foundPaths.isEmpty) {
|
||||||
currentRoot = currentRoot +/+ name.asString;
|
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;
|
||||||
@ -155,40 +441,157 @@ Bank : Singleton {
|
|||||||
} ?? { false }
|
} ?? { false }
|
||||||
});
|
});
|
||||||
|
|
||||||
if (paths != foundPaths) {
|
|
||||||
paths = foundPaths;
|
|
||||||
atCache = ();
|
atCache = ();
|
||||||
|
paths = foundPaths;
|
||||||
|
this.metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
prGetMetadata {
|
||||||
|
^paths.collect {
|
||||||
|
|path|
|
||||||
|
SoundFile.openRead(path) !? {
|
||||||
|
|sf|
|
||||||
|
var e = (
|
||||||
|
sampleRate: sf.sampleRate,
|
||||||
|
numChannels: sf.numChannels,
|
||||||
|
numFrames: sf.numFrames,
|
||||||
|
sampleFormat: sf.sampleFormat,
|
||||||
|
headerFormat: sf.headerFormat,
|
||||||
|
);
|
||||||
|
sf.close;
|
||||||
|
e
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
metadata {
|
||||||
|
|key|
|
||||||
|
metadata = metadata ?? this.prGetMetadata(_);
|
||||||
|
if (key.isNil) {
|
||||||
|
^metadata
|
||||||
|
} {
|
||||||
|
^metadata[this.indexForKey(key)]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lazyLoading_{
|
||||||
|
|lazy|
|
||||||
|
if (lazyLoading != lazy) {
|
||||||
|
lazyLoading = lazy;
|
||||||
this.prUpdateBuffers();
|
this.prUpdateBuffers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buffers {
|
||||||
|
^paths.size.collect {
|
||||||
|
|i|
|
||||||
|
this.bufferAt(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gui {
|
||||||
|
var view, sampleViews, button, name;
|
||||||
|
var playNode;
|
||||||
|
|
||||||
|
this.lazyLoading = false;
|
||||||
|
|
||||||
|
view = View().layout_(GridLayout.rows());
|
||||||
|
paths.do {
|
||||||
|
|path, i|
|
||||||
|
var sampleView;
|
||||||
|
name = PathName(path).fileNameWithoutExtension;
|
||||||
|
view.layout.add(
|
||||||
|
sampleView = DragSource()
|
||||||
|
.object_("%(%)[%]".format(
|
||||||
|
this.class.name,
|
||||||
|
channels !? {
|
||||||
|
"'%', %".format(this.name, channels)
|
||||||
|
} ?? {
|
||||||
|
"'%'".format(this.name)
|
||||||
|
},
|
||||||
|
name.quote
|
||||||
|
))
|
||||||
|
.string_(name)
|
||||||
|
.canFocus_(true)
|
||||||
|
.font_(Font("M+ 2c", 10, false))
|
||||||
|
.minWidth_(100)
|
||||||
|
.mouseDownAction_({
|
||||||
|
|v|
|
||||||
|
if (v.focus) {
|
||||||
|
playNode.free;
|
||||||
|
playNode = this.bufferAt(i).play
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.focusGainedAction_({ this.bufferAt(i).play(mul:[1, 1]) }),
|
||||||
|
(i / 4).floor,
|
||||||
|
i % 4
|
||||||
|
);
|
||||||
|
sampleViews = sampleViews.add(sampleView);
|
||||||
|
};
|
||||||
|
|
||||||
|
view.keyUpAction = {
|
||||||
|
|view, char, modifiers, unicode, keycode, key|
|
||||||
|
switch(
|
||||||
|
keycode.postln,
|
||||||
|
123, {
|
||||||
|
sampleViews[-1 + (sampleViews.detectIndex({ |v| v.hasFocus }) ? 0)].focus
|
||||||
|
},
|
||||||
|
124, {
|
||||||
|
sampleViews[ 1 + (sampleViews.detectIndex({ |v| v.hasFocus }) ? 0)].focus
|
||||||
|
},
|
||||||
|
125, {
|
||||||
|
sampleViews[ 4 + (sampleViews.detectIndex({ |v| v.hasFocus }) ? 0)].focus
|
||||||
|
},
|
||||||
|
126, {
|
||||||
|
sampleViews[-4 + (sampleViews.detectIndex({ |v| v.hasFocus }) ? 0)].focus
|
||||||
|
}
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
ScrollView(bounds:500@600).canvas_(view).front;
|
||||||
|
}
|
||||||
|
|
||||||
|
set {
|
||||||
|
|inChannels|
|
||||||
|
if (channels != inChannels) {
|
||||||
|
channels = inChannels;
|
||||||
|
this.clear();
|
||||||
|
this.prUpdateBuffers();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
clear {
|
clear {
|
||||||
paths = [];
|
paths = [];
|
||||||
atCache = ();
|
atCache = ();
|
||||||
this.prUpdateBuffers()
|
this.prUpdateBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
bufferAt {
|
bufferAt {
|
||||||
|index|
|
|index|
|
||||||
|
var sf;
|
||||||
^buffers !? {
|
^buffers !? {
|
||||||
buffers[index] ?? {
|
buffers[index] ?? {
|
||||||
if (Server.default.serverRunning) {
|
if (Server.default.serverRunning) {
|
||||||
|
buffers = buffers.extend(index + 1, nil);
|
||||||
if (channels.isNil) {
|
if (channels.isNil) {
|
||||||
buffers[index] = Buffer.read(Server.default, paths[index])
|
buffers[index] = Buffer.read(Server.default, paths[index]);
|
||||||
|
buffers[index].numChannels = metadata[index][\numChannels];
|
||||||
|
buffers[index];
|
||||||
} {
|
} {
|
||||||
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];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
at {
|
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(_))
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -207,7 +610,12 @@ Bank : Singleton {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
^this.bufferAt(index);
|
^index
|
||||||
|
}
|
||||||
|
|
||||||
|
at {
|
||||||
|
|key|
|
||||||
|
^this.bufferAt(this.indexForKey(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
markers {
|
markers {
|
||||||
@ -227,15 +635,8 @@ Bank : Singleton {
|
|||||||
^this.at(index);
|
^this.at(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do { |...args| buffers.size.collect(this.bufferAt(_)).do(*args) }
|
||||||
|...args|
|
collect { |...args| ^buffers.size.collect(this.bufferAt(_)).collect(*args) }
|
||||||
buffers.size.collect(this.bufferAt(_)).do(*args)
|
|
||||||
}
|
|
||||||
|
|
||||||
collect {
|
|
||||||
|...args|
|
|
||||||
^buffers.size.collect(this.bufferAt(_)).collect(*args)
|
|
||||||
}
|
|
||||||
|
|
||||||
prUpdateBuffers {
|
prUpdateBuffers {
|
||||||
if (Server.default.serverBooting or: {
|
if (Server.default.serverBooting or: {
|
||||||
@ -270,6 +671,10 @@ Bank : Singleton {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
buffers[paths.size..].do {
|
||||||
|
|b|
|
||||||
|
b.free;
|
||||||
|
};
|
||||||
buffers.extend(paths.size);
|
buffers.extend(paths.size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -291,19 +696,10 @@ Bank : Singleton {
|
|||||||
^Pindex(Pseq([this], inf), keyPat)
|
^Pindex(Pseq([this], inf), keyPat)
|
||||||
}
|
}
|
||||||
|
|
||||||
asBuffer {
|
// Single buffer support
|
||||||
^this.singleSampleWrap(nil)
|
asBuffer { ^this.singleSampleWrap(nil) }
|
||||||
}
|
asControlInput { |...args| ^this.prSingleSampleWrap(\asControlInput, *args) }
|
||||||
|
play { |...args| ^this.prSingleSampleWrap(\play, *args) }
|
||||||
asControlInput {
|
|
||||||
|...args|
|
|
||||||
^this.prSingleSampleWrap(\asControlInput, *args)
|
|
||||||
}
|
|
||||||
|
|
||||||
play {
|
|
||||||
|...args|
|
|
||||||
^this.prSingleSampleWrap(\play, *args)
|
|
||||||
}
|
|
||||||
|
|
||||||
prSingleSampleWrap {
|
prSingleSampleWrap {
|
||||||
|method ...args|
|
|method ...args|
|
||||||
@ -325,7 +721,7 @@ Bank : Singleton {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} {
|
} {
|
||||||
Error("Trying to % a bank with multiple buffers".format(method)).throw;
|
Error("Trying to % a SAMP with multiple buffers".format(method)).throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,7 @@ Boot {
|
|||||||
{
|
{
|
||||||
"-> Booting using default server configuration".postln;
|
"-> Booting using default server configuration".postln;
|
||||||
s = Server.default;
|
s = Server.default;
|
||||||
s.options.numBuffers = 2048 * 512;
|
s.options.numBuffers = (2048 * 2048) * 2; // Some arbitrary number
|
||||||
s.options.memSize = 8192 * 64;
|
s.options.memSize = 8192 * 64;
|
||||||
s.options.numWireBufs = 2048;
|
s.options.numWireBufs = 2048;
|
||||||
s.options.maxNodes = 1024 * 32;
|
s.options.maxNodes = 1024 * 32;
|
||||||
@ -25,6 +25,8 @@ Boot {
|
|||||||
{
|
{
|
||||||
"-> Booting using user server configuration".postln;
|
"-> Booting using user server configuration".postln;
|
||||||
s = Server.default;
|
s = Server.default;
|
||||||
|
// Imposing a very high number of buffers!
|
||||||
|
serverOptions.numBuffers = (2048 * 512) * 2;
|
||||||
s.options = serverOptions;
|
s.options = serverOptions;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -72,7 +74,7 @@ Boot {
|
|||||||
~sp = ~sp ?? 'default';
|
~sp = ~sp ?? 'default';
|
||||||
~nb = ~nb ?? 0;
|
~nb = ~nb ?? 0;
|
||||||
~buf = Bank(~sp)[~nb % Bank(~sp).paths.size];
|
~buf = Bank(~sp)[~nb % Bank(~sp).paths.size];
|
||||||
if (~buf.numChannels == 1) {
|
if (Bank(~sp).metadata[~nb % Bank(~sp).size][\numChannels] == 1) {
|
||||||
~instrument = \player;
|
~instrument = \player;
|
||||||
} {
|
} {
|
||||||
~instrument = \splayer;
|
~instrument = \splayer;
|
||||||
|
|||||||
Reference in New Issue
Block a user