added everything
This commit is contained in:
parent
cfe6c109f7
commit
8bb1e9e6f2
|
@ -0,0 +1,41 @@
|
||||||
|
h1. "Live Beatbox":http://github.com/rfwatson/live-beatbox
|
||||||
|
|
||||||
|
!http://rfwatson.github.com/images/beatbox.png!
|
||||||
|
|
||||||
|
|
||||||
|
Experimental drum machine which uses vocalization to select synthetic drum hits which best match beat-boxed sound.
|
||||||
|
|
||||||
|
Currently uses a combination of MFCC, SpectralCentroid and ZeroCrossing measurements to analyze and match the timbre of the sounds.
|
||||||
|
|
||||||
|
In super-alpha-beta state! It may or may not work on your setup.
|
||||||
|
|
||||||
|
h2. Requirements
|
||||||
|
|
||||||
|
* "SuperCollider":http://supercollider.sourceforge.net
|
||||||
|
|
||||||
|
* Some sort of external microphone and audio interface. I use an Edirol FA101 when building this. I haven't got it working well with the Mac's internal sound
|
||||||
|
|
||||||
|
* OSX - unless you want to make the GUI stuff cross-platform.
|
||||||
|
|
||||||
|
h2. Keyboard shortcuts
|
||||||
|
|
||||||
|
| @F1@ | Record mode |
|
||||||
|
| @F2@ | Preview recorded sound |
|
||||||
|
| @F3@ | Jamming mode |
|
||||||
|
| @Space@ | Start/stop sequencer |
|
||||||
|
| @Return@ | Add hit to seq (while playing) |
|
||||||
|
| @Backsp.@ | Remove hit (while playing) |
|
||||||
|
| @Up/Down@ | Select channel |
|
||||||
|
| @Left/Rt@ | Crossfader control |
|
||||||
|
|
||||||
|
h2. TODO
|
||||||
|
|
||||||
|
* Add analysis of amplitude envelope, only uses timbral analysis at the moment which while quite good it needs amp.env. comparison to be really intuitive
|
||||||
|
* Add ability to scan and add samples via GUI, from any location
|
||||||
|
* Improve doc
|
||||||
|
* Lots more...
|
||||||
|
|
||||||
|
h2. Contact me
|
||||||
|
|
||||||
|
Via "Github":http://github.com/rfwatson
|
||||||
|
|
Binary file not shown.
|
@ -0,0 +1,11 @@
|
||||||
|
AverageOutput : UGen {
|
||||||
|
*ar {
|
||||||
|
arg in, trig=0.0, mul=1.0, add=0.0;
|
||||||
|
^this.multiNew('audio', in, trig).madd(mul, add);
|
||||||
|
}
|
||||||
|
|
||||||
|
*kr {
|
||||||
|
arg in, trig=0.0, mul=1.0, add=0.0;
|
||||||
|
^this.multiNew('control', in, trig).madd(mul, add);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,101 @@
|
||||||
|
Beat {
|
||||||
|
classvar <maxFrames;
|
||||||
|
var <signal, <nframes, <server, sigbuf, <sample, sampbuf, <path, <features, fftbuf, bus, <nearest, <nearestPath;
|
||||||
|
|
||||||
|
*initClass {
|
||||||
|
maxFrames = 44100; // 1 second of audio, which is more than enough.
|
||||||
|
}
|
||||||
|
|
||||||
|
*newFromSignal { |signal, server, donefunc|
|
||||||
|
^super.new.initFromSignal(signal, server, donefunc);
|
||||||
|
}
|
||||||
|
|
||||||
|
*newFromPath { |path, server, donefunc|
|
||||||
|
^super.new.initFromPath(path, server, donefunc);
|
||||||
|
}
|
||||||
|
|
||||||
|
initFromSignal { |aSignal, aServer, donefunc|
|
||||||
|
signal = aSignal;
|
||||||
|
nframes = signal.size;
|
||||||
|
server = aServer;
|
||||||
|
|
||||||
|
// we always pass in a mono signal so no need to check here
|
||||||
|
sigbuf = Buffer.alloc(server, nframes, 1);
|
||||||
|
sigbuf.loadCollection(signal, action: {
|
||||||
|
donefunc.(this)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
initFromPath { |aPath, aServer, donefunc|
|
||||||
|
var sndfile, rawsignal;
|
||||||
|
path = aPath;
|
||||||
|
server = aServer;
|
||||||
|
sndfile = SoundFile.openRead(path);
|
||||||
|
|
||||||
|
if(sndfile.numFrames > maxFrames) {
|
||||||
|
Error("Sound file too large.").throw;
|
||||||
|
} {
|
||||||
|
rawsignal = Signal.newClear(sndfile.numFrames * sndfile.numChannels);
|
||||||
|
sndfile.readData(rawsignal);
|
||||||
|
|
||||||
|
if(sndfile.numChannels == 1) {
|
||||||
|
signal = rawsignal;
|
||||||
|
} {
|
||||||
|
signal = rawsignal.clump(sndfile.numChannels).flop[0]; // channel 0
|
||||||
|
};
|
||||||
|
|
||||||
|
sigbuf = Buffer.loadCollection(server, signal, 1, action: {
|
||||||
|
donefunc.(this)
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
play { |xfade=0.0, mul=1.0|
|
||||||
|
var synth;
|
||||||
|
|
||||||
|
// why isnt doneAction working for me?
|
||||||
|
synth = Synth(\beatboxplayer, [\bufnum1, sigbuf, \bufnum2, sampbuf, \crossfade, xfade, \mul, mul]);
|
||||||
|
SystemClock.sched(3.0, { synth.free });
|
||||||
|
}
|
||||||
|
|
||||||
|
analyse { |donefunc|
|
||||||
|
var duration, synth;
|
||||||
|
|
||||||
|
duration = sigbuf.numFrames / server.sampleRate;
|
||||||
|
|
||||||
|
bus = Bus.control(server, 22); // 20 MFCCs, 1 Spectral Centroid, 1 ZCR
|
||||||
|
fftbuf = Buffer.alloc(server, 1024, 1);
|
||||||
|
|
||||||
|
server.makeBundle(1.0) {
|
||||||
|
synth = Synth(\beatboxanalyzer, [\bufnum, sigbuf, \fftbuf, fftbuf, \cbus1, bus.index, \cbus2, bus.index + 20, \cbus3, bus.index + 21]);
|
||||||
|
};
|
||||||
|
|
||||||
|
server.makeBundle(1.0 + duration, {
|
||||||
|
bus.getn(22) { |theFeatures|
|
||||||
|
features = theFeatures;
|
||||||
|
donefunc.(this);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// 2 seconds later, free the synth, fft-buffer and the control bus.
|
||||||
|
SystemClock.sched(3.0 + duration) {
|
||||||
|
synth.free;
|
||||||
|
fftbuf.free;
|
||||||
|
bus.free;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
nearest_{ |path|
|
||||||
|
var sndfile, rawsignal, len;
|
||||||
|
|
||||||
|
nearestPath = path;
|
||||||
|
sndfile = SoundFile.openRead(path);
|
||||||
|
rawsignal = Signal.newClear(sndfile.numFrames * sndfile.numChannels);
|
||||||
|
sndfile.readData(rawsignal);
|
||||||
|
sample = rawsignal.clump(2).flop[0];
|
||||||
|
|
||||||
|
sampbuf = Buffer.readChannel(server, path, channels: [0], action: { |buf|
|
||||||
|
sampbuf = buf;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,379 @@
|
||||||
|
BeatBox {
|
||||||
|
var <>basepath;
|
||||||
|
|
||||||
|
var w, <layout, <scope, <server, beats, nchannels, seq, data, recbutton;
|
||||||
|
var onsetListener, statusText, thresholdText, lagText, scope, <lowerStatus;
|
||||||
|
var fftbuf, recbuf, synth, isListening, isRecording, isJamming, recStart;
|
||||||
|
var jambutton;
|
||||||
|
|
||||||
|
*new { |basepath|
|
||||||
|
^super.new.init(basepath);
|
||||||
|
}
|
||||||
|
|
||||||
|
init { |aBasePath|
|
||||||
|
basepath = (aBasePath ? "/l/cm2/coursework/task3") ++ "/";
|
||||||
|
|
||||||
|
w = SCWindow("Beatbox Beta 1", Rect(200, 700, 520, 558), resizable: false);
|
||||||
|
|
||||||
|
// keyboard shorts
|
||||||
|
w.view.keyDownAction_{ |...args|
|
||||||
|
var shift = args[2];
|
||||||
|
var code = args.last;
|
||||||
|
|
||||||
|
code.switch(
|
||||||
|
36, { // enter
|
||||||
|
seq.setCurrentHit;
|
||||||
|
},
|
||||||
|
13, { // backspace
|
||||||
|
seq.clearCurrentHit;
|
||||||
|
},
|
||||||
|
49, {
|
||||||
|
// move to seq
|
||||||
|
seq.mainbutton.value_((seq.mainbutton.value + 1) % 2).doAction;
|
||||||
|
},
|
||||||
|
122, {
|
||||||
|
if(recbutton.enabled) {
|
||||||
|
recbutton.value_((recbutton.value + 1) % 2).doAction;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
120, {
|
||||||
|
this.preview;
|
||||||
|
},
|
||||||
|
99, {
|
||||||
|
if(jambutton.enabled) {
|
||||||
|
jambutton.value_((jambutton.value + 1) % 2).doAction;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
123, {
|
||||||
|
// move to seq
|
||||||
|
if(seq.xfadeval > 0.0) {
|
||||||
|
seq.xfadeslid.value_(seq.xfadeval - 0.1).doAction;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
124, {
|
||||||
|
// move to seq
|
||||||
|
if(seq.xfadeval < 1.0) {
|
||||||
|
seq.xfadeslid.value_(seq.xfadeval + 0.1).doAction;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
126, { // move to seq
|
||||||
|
seq.currentChannel = (seq.currentChannel - 1) % seq.numChannels;
|
||||||
|
seq.selects[seq.currentChannel].value_(1).doAction;
|
||||||
|
},
|
||||||
|
125, { // move to seq
|
||||||
|
seq.currentChannel = (seq.currentChannel + 1) % seq.numChannels;
|
||||||
|
seq.selects[seq.currentChannel].value_(1).doAction;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
layout = FlowLayout(w.view.bounds);
|
||||||
|
w.view.decorator = layout;
|
||||||
|
|
||||||
|
nchannels = 8;
|
||||||
|
|
||||||
|
server = Server.local;
|
||||||
|
server.doWhenBooted {
|
||||||
|
recbuf = Buffer.alloc(server, server.sampleRate);
|
||||||
|
fftbuf = Buffer.alloc(server, 512);
|
||||||
|
};
|
||||||
|
|
||||||
|
isListening = false;
|
||||||
|
isRecording = false;
|
||||||
|
isJamming = false;
|
||||||
|
beats = Array.newClear(nchannels);
|
||||||
|
|
||||||
|
File.use(basepath ++ "data.sc", "r") { |file|
|
||||||
|
data = file.readAllString.interpret;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.initDisplay;
|
||||||
|
}
|
||||||
|
|
||||||
|
initDisplay {
|
||||||
|
recbutton = SCButton(w, Rect(5, 5, 100, 25))
|
||||||
|
.states_([
|
||||||
|
[ "Record (F1)", Color.black, Color.green ],
|
||||||
|
[ "Stop (F1)", Color.white, Color.red ],
|
||||||
|
])
|
||||||
|
.action_{ |button| this.switch(button) }
|
||||||
|
.keyDownAction_{ nil };
|
||||||
|
|
||||||
|
SCButton(w, Rect(5, 5, 100, 25))
|
||||||
|
.states_([
|
||||||
|
[ "Preview (F2)", Color.black, Color.green ],
|
||||||
|
])
|
||||||
|
.action_{ |button| this.preview(button) }
|
||||||
|
.keyDownAction_{ nil };
|
||||||
|
|
||||||
|
jambutton = SCButton(w, Rect(5, 5, 100, 25))
|
||||||
|
.states_([
|
||||||
|
[ "Jam (F3)", Color.black, Color.green ],
|
||||||
|
[ "Stop (F1)", Color.white, Color.red ],
|
||||||
|
])
|
||||||
|
.action_{ |button| this.jam(button.value) }
|
||||||
|
.keyDownAction_{ nil };
|
||||||
|
|
||||||
|
|
||||||
|
layout.nextLine;
|
||||||
|
layout.nextLine;
|
||||||
|
|
||||||
|
SCStaticText(w, Rect(5, 5, 200, 25))
|
||||||
|
.string_("Threshold")
|
||||||
|
.font_(Font("Helvetica-Bold", 12));
|
||||||
|
|
||||||
|
|
||||||
|
SCStaticText(w, Rect(200, 5, 30, 25))
|
||||||
|
.string_("Lag")
|
||||||
|
.font_(Font("Helvetica-Bold", 12));
|
||||||
|
|
||||||
|
layout.nextLine;
|
||||||
|
|
||||||
|
SCSlider(w, Rect(5, 5, 100, 25))
|
||||||
|
.step_(0.1)
|
||||||
|
.value_(0.3)
|
||||||
|
.action_{ |slider|
|
||||||
|
var value = slider.value.clip(0.1, 1.0);
|
||||||
|
synth.set(\threshold, value);
|
||||||
|
thresholdText.string_(value.asString);
|
||||||
|
}
|
||||||
|
.keyDownAction_{ nil };
|
||||||
|
|
||||||
|
thresholdText = SCStaticText(w, Rect(5, 5, 95, 25))
|
||||||
|
.string_("0.3");
|
||||||
|
|
||||||
|
SCSlider(w, Rect(200, 5, 100, 25))
|
||||||
|
.step_(0.05)
|
||||||
|
.value_(0.1)
|
||||||
|
.action_{ |slider|
|
||||||
|
var value = slider.value.clip(0.1, 1.0);
|
||||||
|
synth.set(\lag, value);
|
||||||
|
lagText.string_(value.asString);
|
||||||
|
}
|
||||||
|
.keyDownAction_{ nil };
|
||||||
|
|
||||||
|
lagText = SCStaticText(w, Rect(5, 5, 20, 25))
|
||||||
|
.string_("0.1");
|
||||||
|
|
||||||
|
layout.nextLine;
|
||||||
|
|
||||||
|
statusText = SCStaticText(w, Rect(5, 5, 510, 25))
|
||||||
|
.background_(Color.grey);
|
||||||
|
|
||||||
|
layout.nextLine;
|
||||||
|
|
||||||
|
scope = SCUserView(w, Rect(5, 5, 510, 150))
|
||||||
|
.relativeOrigin_(true)
|
||||||
|
.background_(Color.black)
|
||||||
|
.drawFunc_({ this.drawWaveform });
|
||||||
|
|
||||||
|
layout.nextLine;
|
||||||
|
|
||||||
|
lowerStatus = SCStaticText(w, Rect(5, 5, 510, 25))
|
||||||
|
.background_(Color.grey);
|
||||||
|
|
||||||
|
layout.nextLine;
|
||||||
|
|
||||||
|
seq = Sequencer(w, Rect(5, 5, 510, 300), server, beats, this);
|
||||||
|
|
||||||
|
w.onClose = { scope.free };
|
||||||
|
w.front;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch { |button|
|
||||||
|
if(button.value == 1) {
|
||||||
|
jambutton.enabled = false;
|
||||||
|
this.listen;
|
||||||
|
} {
|
||||||
|
this.silenceDetected;
|
||||||
|
this.ignore;
|
||||||
|
jambutton.enabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
jam { |value| // 0 is on, 1 is off: relates to SCButton value
|
||||||
|
if(value == 1) {
|
||||||
|
recbutton.enabled = false;
|
||||||
|
isJamming = true;
|
||||||
|
if(seq.playing.not) {
|
||||||
|
seq.play
|
||||||
|
};
|
||||||
|
this.listen(amp: 0.0);
|
||||||
|
} {
|
||||||
|
isJamming = false;
|
||||||
|
recbutton.enabled = true;
|
||||||
|
jambutton.value = 0;
|
||||||
|
this.ignore;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
preview {
|
||||||
|
seq.previewCurrentChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
onsetDetected {
|
||||||
|
Post << "Onset!" << $\n;
|
||||||
|
if(isJamming) {
|
||||||
|
{
|
||||||
|
seq.setCurrentHit;
|
||||||
|
}.defer;
|
||||||
|
} {
|
||||||
|
if(isRecording.not) {
|
||||||
|
isRecording = true;
|
||||||
|
synth.set(\t_resetRecord, 1);
|
||||||
|
recStart = SystemClock.seconds;
|
||||||
|
{ statusText.background_(Color.red).stringColor_(Color.white).background_(Color.red).string_("RECORDING") }.defer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
silenceDetected {
|
||||||
|
var dursamps, sndfile, signal, beat;
|
||||||
|
Post << "Silence!" << $\n;
|
||||||
|
|
||||||
|
if(isRecording) {
|
||||||
|
synth.run(false);
|
||||||
|
{
|
||||||
|
statusText.background_(Color.green).stringColor_(Color.black).string_("Analysing...");
|
||||||
|
}.defer;
|
||||||
|
dursamps = ((SystemClock.seconds - recStart) * server.sampleRate).asInteger;
|
||||||
|
recbuf.loadToFloatArray(0, dursamps) { |floatdata|
|
||||||
|
// check received from server OK - sometimes fails
|
||||||
|
if(floatdata.isEmpty.not) {
|
||||||
|
signal = Signal.newFrom(floatdata);
|
||||||
|
signal.normalize;
|
||||||
|
|
||||||
|
beats[seq.currentChannel] = Beat.newFromSignal(signal, server);
|
||||||
|
beats[seq.currentChannel].analyse { |beat|
|
||||||
|
this.findNearest(beat);
|
||||||
|
{
|
||||||
|
// allow new recording to begin only after completely finsihed
|
||||||
|
scope.refresh;
|
||||||
|
isRecording = false;
|
||||||
|
statusText.background_(Color.grey).stringColor_(Color.black).string_("");
|
||||||
|
this.updateLowerStatus;
|
||||||
|
recbutton.value_(0).doAction;
|
||||||
|
}.defer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
listen { |amp=1.0|
|
||||||
|
var msg, action;
|
||||||
|
|
||||||
|
if(isListening.not) { // start listening to input
|
||||||
|
synth = Synth(\beatboxlistener, [\out, 0, \in, 0, \fftbuf, fftbuf, \recbuf, recbuf, \amp, amp]);
|
||||||
|
|
||||||
|
onsetListener = OSCresponderNode(nil, '/tr') { |time, responder, msg|
|
||||||
|
action = msg[3];
|
||||||
|
action.asInteger.switch(
|
||||||
|
1, { this.onsetDetected },
|
||||||
|
2, { this.silenceDetected }
|
||||||
|
);
|
||||||
|
}.add;
|
||||||
|
|
||||||
|
statusText.background_(Color.grey).stringColor_(Color.black).string_("Waiting for input...");
|
||||||
|
isListening = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ignore {
|
||||||
|
if(isListening) {
|
||||||
|
var wasRecording = isRecording;
|
||||||
|
this.silenceDetected;
|
||||||
|
synth.free;
|
||||||
|
onsetListener.remove;
|
||||||
|
|
||||||
|
if(wasRecording) {
|
||||||
|
statusText.background_(Color.green).stringColor_(Color.black).string_("Analysing...");
|
||||||
|
} {
|
||||||
|
statusText.background_(Color.grey).stringColor_(Color.black).string_("");
|
||||||
|
};
|
||||||
|
|
||||||
|
isListening = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO move to Beat.sc
|
||||||
|
findNearest { |beat|
|
||||||
|
var p, total;
|
||||||
|
var nearest = 10e10;
|
||||||
|
var neighbour;
|
||||||
|
|
||||||
|
data.getPairs.clump(2).do { |pair|
|
||||||
|
var fname, features;
|
||||||
|
# fname, features = pair;
|
||||||
|
total = 0.0;
|
||||||
|
features.size.do { |i|
|
||||||
|
p = (beat.features[i] - features[i]).squared;
|
||||||
|
total = total + p;
|
||||||
|
};
|
||||||
|
|
||||||
|
if(total < nearest) {
|
||||||
|
neighbour = fname;
|
||||||
|
nearest = total;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
if(neighbour.isNil) { // FIX sometimes a strange bug causes a lot of nan's to be produced
|
||||||
|
"There was an error analysing this sound. Try another".postln;
|
||||||
|
} {
|
||||||
|
beat.nearest = neighbour;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
refresh {
|
||||||
|
scope.refresh
|
||||||
|
}
|
||||||
|
|
||||||
|
updateLowerStatus {
|
||||||
|
var beat = seq.beats[seq.currentChannel];
|
||||||
|
beat !? {
|
||||||
|
beat.nearestPath !? {
|
||||||
|
lowerStatus.string_(beat.nearestPath.basename);
|
||||||
|
^this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
lowerStatus.string_("");
|
||||||
|
}
|
||||||
|
|
||||||
|
drawWaveform {
|
||||||
|
// why is SCSoundFileView so frustrating?
|
||||||
|
var sig, maximums, x2, y1, y2, p1, p2;
|
||||||
|
var beat = beats[seq.currentChannel];
|
||||||
|
|
||||||
|
beat !? {
|
||||||
|
p1 = 0 @ 75;
|
||||||
|
|
||||||
|
if(beat.sample.notNil) {
|
||||||
|
sig = (beat.sample * (seq.xfadeval)) +.s (beat.signal * (1 - seq.xfadeval));
|
||||||
|
} {
|
||||||
|
sig = beat.signal;
|
||||||
|
};
|
||||||
|
|
||||||
|
maximums = sig.clump(sig.size / 510).collect{ |window|
|
||||||
|
var posmax, negmax;
|
||||||
|
posmax = window.maxItem;
|
||||||
|
negmax = window.minItem;
|
||||||
|
|
||||||
|
if(posmax.abs > negmax.abs)
|
||||||
|
{ posmax } { negmax }
|
||||||
|
};
|
||||||
|
|
||||||
|
Pen.use {
|
||||||
|
Color(0.3, 1, 0.3).set;
|
||||||
|
maximums.do { |max, x1|
|
||||||
|
p2 = x1 @ (75 - (75 * max));
|
||||||
|
Pen.moveTo(p1);
|
||||||
|
Pen.lineTo(p2);
|
||||||
|
Pen.stroke;
|
||||||
|
|
||||||
|
p1 = p2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,237 @@
|
||||||
|
Sequencer {
|
||||||
|
var w, view, channels, buttons, <buttonvals, <selects, indicators, beatbox, routine, tempoBox, startedTime;
|
||||||
|
var <xfadeslid, <xfadeval, <>currentChannel, <beats, server, <mainbutton, <playing;
|
||||||
|
|
||||||
|
*new { |w, bounds, server, beats, beatbox, nchannels=8|
|
||||||
|
^super.new.init(w, bounds, server, beats, beatbox, nchannels);
|
||||||
|
}
|
||||||
|
|
||||||
|
init { |aWindow, bounds, aServer, someBeats, aBeatBox, nchannels|
|
||||||
|
w = aWindow;
|
||||||
|
channels = 0.0 ! 16 ! nchannels;
|
||||||
|
indicators = Array.newClear(16);
|
||||||
|
playing = false;
|
||||||
|
beats = someBeats;
|
||||||
|
server = aServer;
|
||||||
|
beatbox = aBeatBox;
|
||||||
|
buttons = List[] ! nchannels; // the buttons
|
||||||
|
buttonvals = List[] ! nchannels; // mirror image of their values: so I can reach them without {}.defer
|
||||||
|
selects = List[];
|
||||||
|
currentChannel = 0;
|
||||||
|
xfadeval = 0.0;
|
||||||
|
|
||||||
|
this.initDisplay(bounds);
|
||||||
|
this.initRoutine;
|
||||||
|
}
|
||||||
|
|
||||||
|
initRoutine {
|
||||||
|
routine = Routine {
|
||||||
|
var n = 0, hit, mul;
|
||||||
|
|
||||||
|
inf.do {
|
||||||
|
hit = n % 16;
|
||||||
|
|
||||||
|
indicators.do { |light, col|
|
||||||
|
if(col == hit) {
|
||||||
|
{ light.value = 1 }.defer(0.2)
|
||||||
|
} {
|
||||||
|
{ light.value = 0 }.defer(0.2)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
server.bind {
|
||||||
|
channels.size.do { |channel|
|
||||||
|
if(buttonvals[channel][hit] > 0) {
|
||||||
|
buttonvals[channel][hit].switch(
|
||||||
|
1, { mul = 0.3 },
|
||||||
|
2, { mul = 0.7 },
|
||||||
|
3, { mul = 1.0 }
|
||||||
|
);
|
||||||
|
beats[channel].play(xfadeval, mul)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
n = n + 1;
|
||||||
|
(((60 / tempoBox.value)) / 4).wait
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
initDisplay { |bounds|
|
||||||
|
var cbar, tbar;
|
||||||
|
|
||||||
|
view = SCVLayoutView(w, bounds);
|
||||||
|
view.background_(Color.grey);
|
||||||
|
|
||||||
|
cbar = SCHLayoutView(view, Rect(5, 5, 510, 25));
|
||||||
|
|
||||||
|
mainbutton = SCButton(cbar, 100 @ 20)
|
||||||
|
.states_([
|
||||||
|
[ "Play", Color.black, Color.green ],
|
||||||
|
[ "Stop", Color.white, Color.red ]
|
||||||
|
])
|
||||||
|
.action_{ |button|
|
||||||
|
button.value.switch(
|
||||||
|
0, { this.stop },
|
||||||
|
1, { this.play }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.keyDownAction_{ nil };
|
||||||
|
|
||||||
|
SCStaticText(cbar, 30 @ 20)
|
||||||
|
.string_("");
|
||||||
|
|
||||||
|
SCStaticText(cbar, 30 @ 20)
|
||||||
|
.string_("BPM");
|
||||||
|
|
||||||
|
SCSlider(cbar, 60 @ 20)
|
||||||
|
.action_{ |slid|
|
||||||
|
var spec = [80, 180, \linear, 1].asSpec;
|
||||||
|
tempoBox.value = spec.map(slid.value);
|
||||||
|
}
|
||||||
|
.keyDownAction_{ nil }
|
||||||
|
.value_(0.5);
|
||||||
|
|
||||||
|
tempoBox = SCNumberBox(cbar, Rect(5, 5, 60, 20))
|
||||||
|
.value_(130);
|
||||||
|
|
||||||
|
SCStaticText(cbar, 30 @ 20)
|
||||||
|
.string_("");
|
||||||
|
|
||||||
|
SCStaticText(cbar, 42 @ 20)
|
||||||
|
.string_("XFader");
|
||||||
|
|
||||||
|
xfadeslid = SCSlider(cbar, 60 @ 20)
|
||||||
|
.action_{ |slider|
|
||||||
|
xfadeval = slider.value;
|
||||||
|
beatbox.refresh;
|
||||||
|
}
|
||||||
|
.keyDownAction_{ nil };
|
||||||
|
|
||||||
|
tbar = SCHLayoutView(view, Rect(5, 5, 510, 20));
|
||||||
|
|
||||||
|
SCStaticText(tbar, Rect(5, 5, 60, 20));
|
||||||
|
|
||||||
|
16.do { |n|
|
||||||
|
indicators[n] = SCButton(tbar, Rect(5, 5, 20, 20))
|
||||||
|
.states_([
|
||||||
|
[ "", Color.grey, Color.grey ],
|
||||||
|
[ "", Color.black, Color.green ]
|
||||||
|
])
|
||||||
|
.enabled_(false)
|
||||||
|
};
|
||||||
|
|
||||||
|
channels.size.do { |channel|
|
||||||
|
var button;
|
||||||
|
var hbox = SCHLayoutView(view, Rect(5, 5, 380, 20));
|
||||||
|
hbox.background_(Color(0.4, 0.4, 0.4));
|
||||||
|
|
||||||
|
button = SCButton(hbox, Rect(5, 5, 60, 20))
|
||||||
|
.states_([
|
||||||
|
[ "Select", Color.black, Color.grey ],
|
||||||
|
[ "Select", Color.black, Color.yellow ]
|
||||||
|
])
|
||||||
|
.action_{ |thisButton|
|
||||||
|
view.children[2..channels.size+1].do { |hbox, n|
|
||||||
|
var anotherButton = hbox.children.first;
|
||||||
|
if(thisButton == anotherButton) {
|
||||||
|
currentChannel = n;
|
||||||
|
thisButton.value = 1;
|
||||||
|
beatbox.scope.refresh;
|
||||||
|
beatbox.updateLowerStatus;
|
||||||
|
} {
|
||||||
|
anotherButton.value = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.keyDownAction_{ nil };
|
||||||
|
|
||||||
|
if(channel == 0)
|
||||||
|
{ button.value = 1 } { button.value = 0 };
|
||||||
|
|
||||||
|
selects.add(button);
|
||||||
|
|
||||||
|
16.do { |n|
|
||||||
|
var button;
|
||||||
|
button = SCButton(hbox, Rect(5, 5, 20, 20))
|
||||||
|
.states_([
|
||||||
|
[ "", Color.white, Color.grey ],
|
||||||
|
[ "x", Color.black, Color.yellow ],
|
||||||
|
[ "x", Color.black, Color(1.0, 0.55, 0.0) ],
|
||||||
|
[ "X", Color.white, Color.red ]
|
||||||
|
])
|
||||||
|
.action_{ |button|
|
||||||
|
buttonvals[channel][n] = button.value;
|
||||||
|
}
|
||||||
|
.keyDownAction_{ nil };
|
||||||
|
|
||||||
|
buttons[channel].add(button);
|
||||||
|
buttonvals[channel].add(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
play {
|
||||||
|
if(playing.not) {
|
||||||
|
startedTime = SystemClock.seconds;
|
||||||
|
routine.play;
|
||||||
|
playing = true;
|
||||||
|
mainbutton.value = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stop {
|
||||||
|
if(playing) {
|
||||||
|
routine.stop;
|
||||||
|
this.initRoutine;
|
||||||
|
beatbox.jam(0);
|
||||||
|
indicators.do { |light| { light.value = 0 }.defer(0.2) };
|
||||||
|
playing = false;
|
||||||
|
mainbutton.value = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setCurrentHit {
|
||||||
|
var currentHit = this.currentHit;
|
||||||
|
beats[currentChannel].play;
|
||||||
|
buttonvals[currentChannel][currentHit] = 2;
|
||||||
|
buttons[currentChannel][currentHit].value = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
clearCurrentHit {
|
||||||
|
var currentHit = this.currentHit;
|
||||||
|
buttonvals[currentChannel][currentHit] = 0;
|
||||||
|
buttons[currentChannel][currentHit].value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentHit {
|
||||||
|
var durplaying, bardur, sdur, thisbar, currhit;
|
||||||
|
|
||||||
|
if(playing) {
|
||||||
|
durplaying = SystemClock.seconds - startedTime;
|
||||||
|
bardur = (60 / tempoBox.value) * 4;
|
||||||
|
sdur = bardur / 16;
|
||||||
|
thisbar = durplaying % bardur;
|
||||||
|
currhit = ((thisbar / sdur).asInteger - 1) % 16;
|
||||||
|
|
||||||
|
^currhit
|
||||||
|
} {
|
||||||
|
^0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
allButtons {
|
||||||
|
^view.children[1..9].collect{ |hview|
|
||||||
|
hview.children[1..16]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
numChannels {
|
||||||
|
^channels.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
previewCurrentChannel {
|
||||||
|
beats[currentChannel].play(xfadeval, 0.7)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
( "/Developer/Projects/live-beatbox/samples/Closed hat 6.wav": [ 0.028100816532969, 0.20734845101833, 0.44244965910912, 0.19834707677364, 0.29480570554733, 0.21033130586147, 0.19226108491421, 0.16130591928959, 0.20348688960075, 0.16594757139683, 0.20781420171261, 0.20277032256126, 0.24474443495274, 0.21634757518768, 0.25939178466797, 0.24534736573696, 0.28614860773087, 0.24162520468235, 0.26033365726471, 0.24491479992867, 0.96856129169464, 0.81802827119827 ], "/Developer/Projects/live-beatbox/samples/Clap 3.wav": [ 0.68969398736954, -0.1031379699707, -0.010573903098702, 0.0011192427482456, 0.10929827392101, 0.17618775367737, 0.2313070744276, 0.25493428111076, 0.24094235897064, 0.23673513531685, 0.22424203157425, 0.21854357421398, 0.21852107346058, 0.23635332286358, 0.23915708065033, 0.24596996605396, 0.25377571582794, 0.25055998563766, 0.25317540764809, 0.24054843187332, 0.45369762182236, 0.28721743822098 ], "/Developer/Projects/live-beatbox/samples/Open hat 6.wav": [ -0.10418137907982, 0.12545272707939, 0.26413142681122, 0.11792324483395, 0.13093458116055, 0.15442660450935, 0.2201838940382, 0.21260103583336, 0.27931788563728, 0.21682423353195, 0.30024662613869, 0.32407745718956, 0.32413098216057, 0.27243322134018, 0.34235110878944, 0.32974123954773, 0.31098112463951, 0.27653843164444, 0.24456091225147, 0.2412886172533, 1.1818572282791, 0.8577134013176 ], "/Developer/Projects/live-beatbox/samples/Open hat 4.wav": [ -0.44512757658958, -0.28453382849693, 0.019333604723215, -0.1732130497694, 0.029163746163249, 0.01279385201633, 0.095025569200516, 0.067504234611988, 0.16189058125019, 0.19917987287045, 0.24972932040691, 0.22220753133297, 0.26714646816254, 0.2609791457653, 0.25403741002083, 0.27353420853615, 0.29010003805161, 0.22680869698524, 0.19121085107327, 0.24994830787182, 1.1471894979477, 0.90326148271561 ],
|
||||||
|
"/Developer/Projects/live-beatbox/samples/Snare 8.wav": [ 0.48005995154381, 0.058043457567692, 0.45187604427338, 0.2283534258604, 0.40486064553261, 0.26525577902794, 0.32236662507057, 0.24231749773026, 0.29479596018791, 0.24303676187992, 0.25518527626991, 0.19307468831539, 0.23229494690895, 0.19739992916584, 0.23464648425579, 0.20485074818134, 0.21900154650211, 0.21084386110306, 0.22259071469307, 0.21663491427898, 0.59355241060257, 0.50185519456863 ], "/Developer/Projects/live-beatbox/samples/Closed hat 1.wav": [ 0.062044788151979, 0.1052081361413, 0.4205387532711, 0.20742812752724, 0.35730031132698, 0.2454069852829, 0.27549934387207, 0.25356411933899, 0.33766117691994, 0.21182133257389, 0.3126594722271, 0.2204102575779, 0.23577497899532, 0.28142130374908, 0.27484825253487, 0.20640909671783, 0.33941233158112, 0.18872247636318, 0.28233349323273, 0.28189796209335, 0.93620014190674, 0.77957373857498 ], "/Developer/Projects/live-beatbox/samples/Kick d.wav": [ 1.4694187641144, 0.67598873376846, 0.55756497383118, 0.41486153006554, 0.41115987300873, 0.33388984203339, 0.32402813434601, 0.27600729465485, 0.30255457758904, 0.27113127708435, 0.27435728907585, 0.24311591684818, 0.25029489398003, 0.24023097753525, 0.2524850666523, 0.24844248592854, 0.24629904329777, 0.25076055526733, 0.24851040542126, 0.23607671260834, 0.048439539968967, 0.0095306942239404 ], "/Developer/Projects/live-beatbox/samples/Open hat 5.wav": [ -0.2410766929388, -0.035868398845196, 0.28107652068138, 0.067077621817589, 0.20943081378937, 0.19142307341099, 0.2358707934618, 0.17827734351158, 0.1976870149374, 0.23997999727726, 0.29167410731316, 0.27388048171997, 0.26068586111069, 0.28834983706474, 0.26689144968987, 0.25419098138809, 0.26368796825409, 0.30371418595314, 0.26542043685913, 0.19742566347122, 1.1515715122223, 0.89676320552826 ], "/Developer/Projects/live-beatbox/samples/snare 2.wav": [ 0.23288822174072, 0.16889598965645, 0.26748639345169, 0.28498288989067, 0.24526613950729, 0.25464102625847, 0.25208041071892, 0.25892278552055, 0.20539751648903, 0.2151442617178, 0.22292718291283, 0.19789381325245, 0.20437158644199, 0.19868516921997, 0.21727727353573, 0.20834235846996, 0.23634694516659, 0.24443908035755, 0.25261974334717, 0.24812336266041, 1.0816323757172, 0.77368497848511 ],
|
||||||
|
"/Developer/Projects/live-beatbox/samples/Snare 7.wav": [ 0.09044323861599, 0.16288183629513, 0.40270894765854, 0.19544792175293, 0.39212024211884, 0.25524243712425, 0.25996765494347, 0.18911173939705, 0.1760091483593, 0.18137215077877, 0.20859894156456, 0.19736552238464, 0.20673575997353, 0.21071603894234, 0.21623130142689, 0.21338751912117, 0.21975739300251, 0.22306030988693, 0.22703586518764, 0.23083430528641, 0.92165344953537, 0.83659398555756 ], "/Developer/Projects/live-beatbox/samples/RIDE 3.wav": [ -0.071648597717285, 0.0553621314466, 0.36981308460236, 0.15631999075413, 0.24372327327728, 0.23463135957718, 0.24096707999706, 0.3165086209774, 0.24067643284798, 0.22424438595772, 0.24786140024662, 0.30708941817284, 0.27702814340591, 0.27915367484093, 0.31422239542007, 0.28455889225006, 0.21855114400387, 0.22710810601711, 0.29566925764084, 0.31767588853836, 1.2412390708923, 0.8346706032753 ], "/Developer/Projects/live-beatbox/samples/Kick b.wav": [ 1.0275176763535, 0.42086938023567, 0.47628819942474, 0.35202345252037, 0.38319835066795, 0.32463994622231, 0.32781052589417, 0.29058158397675, 0.31597372889519, 0.28384652733803, 0.26735052466393, 0.24412631988525, 0.27344533801079, 0.24078017473221, 0.25736999511719, 0.24493227899075, 0.24702084064484, 0.25655102729797, 0.24532003700733, 0.24291236698627, 0.5, 0.018167873844504 ], "/Developer/Projects/live-beatbox/samples/Kick f.wav": [ 1.1850464344025, 0.56375002861023, 0.62069565057755, 0.41818651556969, 0.4848268032074, 0.3511588871479, 0.35587561130524, 0.30143275856972, 0.33469501137733, 0.25428041815758, 0.27268934249878, 0.25191819667816, 0.27329647541046, 0.25330182909966, 0.26204028725624, 0.25307887792587, 0.26889654994011, 0.25623142719269, 0.2646167576313, 0.22322624921799, 0.080272883176804, 0.062225174158812 ], "/Developer/Projects/live-beatbox/samples/Jive 1.wav": [ 2.008181810379, 0.1114629805088, -0.19041830301285, 0.17800055444241, 0.10522022843361, 0.10384325683117, 0.091366000473499, 0.18637864291668, 0.15609197318554, 0.218904286623, 0.15681007504463, 0.23575966060162, 0.21251802146435, 0.24058331549168, 0.23506790399551, 0.27995800971985, 0.23713010549545, 0.27074864506721, 0.25944158434868, 0.2561457157135, 0.2696832716465, 0.15137416124344 ],
|
||||||
|
"/Developer/Projects/live-beatbox/samples/Dang.wav": [ 1.3726348876953, -0.12131077051163, 0.33612629771233, -0.0073578511364758, 0.4443356692791, 0.060378164052963, 0.16375541687012, 0.17800076305866, 0.26725167036057, 0.16094505786896, 0.30799224972725, 0.21561317145824, 0.24000510573387, 0.12743046879768, 0.23220203816891, 0.24272820353508, 0.30206876993179, 0.25479578971863, 0.30772313475609, 0.21098980307579, 0.21562270820141, 0.19006127119064 ], "/Developer/Projects/live-beatbox/samples/Kick h.wav": [ 0.94912803173065, 0.47477921843529, 0.47514694929123, 0.39133659005165, 0.37936681509018, 0.33316299319267, 0.34080484509468, 0.31337457895279, 0.30304673314095, 0.28494390845299, 0.29126861691475, 0.28071278333664, 0.26825761795044, 0.25835114717484, 0.26706477999687, 0.26147267222404, 0.25467404723167, 0.25114393234253, 0.25055089592934, 0.24970503151417, 0.5, 0.0071526719257236 ], "/Developer/Projects/live-beatbox/samples/Clap 7.wav": [ 0.45760855078697, -0.53774011135101, 0.11809688061476, -0.022978089749813, 0.28350520133972, 0.25455424189568, 0.32863521575928, 0.24806566536427, 0.2637283205986, 0.22635988891125, 0.22288265824318, 0.22947107255459, 0.21795237064362, 0.22538688778877, 0.21112777292728, 0.24360074102879, 0.2526421546936, 0.2450682669878, 0.23174214363098, 0.23427757620811, 0.5, 0.38377928733826 ], "/Developer/Projects/live-beatbox/samples/Kick g.wav": [ 0.77546149492264, 0.25903755426407, 0.43933844566345, 0.31100153923035, 0.36109203100204, 0.31638413667679, 0.30694463849068, 0.28719618916512, 0.2780165374279, 0.28012502193451, 0.26964429020882, 0.27232471108437, 0.25955757498741, 0.25745919346809, 0.26201918721199, 0.25883275270462, 0.26024949550629, 0.25421079993248, 0.2531750202179, 0.25156399607658, 0.5, 0.014633702114224 ], "/Developer/Projects/live-beatbox/samples/Reverse Kickverb 1.wav": [ 0.65726900100708, 0.2196581363678, 0.46005126833916, 0.33910647034645, 0.39426189661026, 0.3887896835804, 0.48469299077988, 0.30275547504425, 0.3670559823513, 0.31545257568359, 0.33550706505775, 0.21714062988758, 0.23645380139351, 0.22909854352474, 0.25922292470932, 0.26951062679291, 0.22685568034649, 0.25833064317703, 0.23572447896004, 0.25781145691872, 0.41389018297195, 0.41833674907684 ],
|
||||||
|
"/Developer/Projects/live-beatbox/samples/Closed hat 7.wav": [ -0.24332734942436, -0.19322003424168, 0.11073984950781, -0.036541625857353, 0.16119985282421, 0.078292816877365, 0.17915719747543, 0.088216088712215, 0.16625311970711, 0.13215026259422, 0.18953235447407, 0.14608120918274, 0.17454707622528, 0.19149056077003, 0.18912726640701, 0.20503352582455, 0.21757933497429, 0.22102501988411, 0.18678431212902, 0.1575553715229, 0.82220542430878, 0.83023869991302 ], "/Developer/Projects/live-beatbox/samples/snare 3.wav": [ 0.010340093635023, 0.26783630251884, 0.46705850958824, 0.077159933745861, 0.29836475849152, 0.19020067155361, 0.2185792028904, 0.18547111749649, 0.18239812552929, 0.14637440443039, 0.14732220768929, 0.16217519342899, 0.17602598667145, 0.16259501874447, 0.17616434395313, 0.18828554451466, 0.18788261711597, 0.19264253973961, 0.19720312952995, 0.19981990754604, 1.0201820135117, 0.91014039516449 ], "/Developer/Projects/live-beatbox/samples/Open hat 2.wav": [ -0.034306570887566, -0.025015247985721, 0.043670170009136, 0.18788066506386, 0.25913843512535, 0.25933668017387, 0.34453058242798, 0.24959759414196, 0.28827533125877, 0.29399245977402, 0.33879417181015, 0.3397359251976, 0.27718633413315, 0.24628461897373, 0.24696044623852, 0.25910675525665, 0.23674920201302, 0.28290963172913, 0.26674449443817, 0.29088559746742, 1.0992873907089, 0.75664979219437 ], "/Developer/Projects/live-beatbox/samples/Open hat 7.wav": [ -0.065972350537777, -0.047986380755901, 0.25927954912186, 0.24974997341633, 0.33265352249146, 0.31632879376411, 0.31878867745399, 0.24471218883991, 0.26005679368973, 0.26852366328239, 0.34280428290367, 0.27297979593277, 0.28097099065781, 0.26964583992958, 0.26762807369232, 0.24684555828571, 0.30079361796379, 0.3047471344471, 0.22172579169273, 0.1891892105341, 0.97126388549805, 0.71091687679291 ], "/Developer/Projects/live-beatbox/samples/Kick 10.wav": [ 1.0290342569351, 0.52106761932373, 0.4798122048378, 0.40940818190575, 0.34327286481857, 0.34119325876236, 0.30624306201935, 0.30112782120705, 0.29277807474136, 0.28743726015091, 0.26574268937111, 0.26841932535172, 0.25287494063377, 0.25602960586548, 0.25086104869843, 0.26419657468796, 0.24690487980843, 0.258620262146, 0.24924497306347, 0.24921731650829, 0.5, 0.021645735949278 ],
|
||||||
|
"/Developer/Projects/live-beatbox/samples/Kick 9.wav": [ 0.91486287117004, 0.50329053401947, 0.53434139490128, 0.43013602495193, 0.39190992712975, 0.35855367779732, 0.3406754732132, 0.3098658323288, 0.31276261806488, 0.25969594717026, 0.26555797457695, 0.27105391025543, 0.26375368237495, 0.25955957174301, 0.24891266226768, 0.25785031914711, 0.23536555469036, 0.26002407073975, 0.23747043311596, 0.25289025902748, 0.5, 0.028275629505515 ], "/Developer/Projects/live-beatbox/samples/Cybertraffic.wav": [ 0.85925531387329, 0.17685735225677, 0.56030106544495, 0.29923614859581, 0.37516349554062, 0.25706788897514, 0.35793110728264, 0.26919054985046, 0.29908254742622, 0.26757419109344, 0.30571037530899, 0.23897756636143, 0.26983228325844, 0.25159353017807, 0.28809693455696, 0.25563251972198, 0.30014634132385, 0.25844004750252, 0.22838726639748, 0.21548092365265, 0.35042345523834, 0.34315386414528 ], "/Developer/Projects/live-beatbox/samples/Woosh.wav": [ 1.007453918457, 0.42520293593407, 0.55425077676773, 0.0073907384648919, 0.47816756367683, 0.20854979753494, 0.26529437303543, 0.27382108569145, 0.25220638513565, 0.14099989831448, 0.32786285877228, 0.15587821602821, 0.29569259285927, 0.17399077117443, 0.31752371788025, 0.16004726290703, 0.30391189455986, 0.18779745697975, 0.28517481684685, 0.19686424732208, 0.35602983832359, 0.45979124307632 ], "/Developer/Projects/live-beatbox/samples/Open hat 3.wav": [ -0.18806827068329, -0.00079264352098107, 0.31595858931541, 0.092756599187851, 0.25084030628204, 0.21592333912849, 0.26540276408195, 0.19380535185337, 0.25293180346489, 0.27491039037704, 0.32317113876343, 0.27470606565475, 0.28405353426933, 0.29907646775246, 0.27724125981331, 0.2689326107502, 0.30329623818398, 0.3080695271492, 0.22824014723301, 0.20424315333366, 1.1381356716156, 0.88983279466629 ], "/Developer/Projects/live-beatbox/samples/Closed hat 3.wav": [ -0.28816375136375, -0.13784410059452, 0.31698474287987, 0.25378674268723, 0.29153180122375, 0.21960514783859, 0.33303824067116, 0.29769653081894, 0.26781690120697, 0.23649933934212, 0.29384699463844, 0.26055938005447, 0.25487524271011, 0.24171581864357, 0.2319603562355, 0.23127561807632, 0.25001472234726, 0.25035083293915, 0.24250701069832, 0.23738117516041, 0.94486618041992, 0.73061567544937 ],
|
||||||
|
"/Developer/Projects/live-beatbox/samples/Kick 1.wav": [ 0.91588175296783, 0.45428588986397, 0.58496528863907, 0.37314572930336, 0.43883562088013, 0.34101384878159, 0.35809069871902, 0.31187471747398, 0.29064503312111, 0.27320289611816, 0.27221542596817, 0.26456612348557, 0.27674540877342, 0.26659473776817, 0.26472440361977, 0.26809406280518, 0.2760956287384, 0.24874351918697, 0.25621056556702, 0.23885579407215, 0.5, 0.017491262406111 ], "/Developer/Projects/live-beatbox/samples/Jive 3.wav": [ 2.2372143268585, -0.024090813472867, -0.31805682182312, 0.16341361403465, 0.082020059227943, 0.023007264360785, 0.18150432407856, 0.24999004602432, 0.1153752207756, 0.1944026350975, 0.23748798668385, 0.21152111887932, 0.17090894281864, 0.26320824027061, 0.23613372445107, 0.24748049676418, 0.2459375411272, 0.27975836396217, 0.24011984467506, 0.25249254703522, 0.27104198932648, 0.14754858613014 ], "/Developer/Projects/live-beatbox/samples/Kick a.wav": [ 1.1005251407623, 0.29586187005043, 0.57041263580322, 0.50809097290039, 0.40964633226395, 0.40783306956291, 0.35798427462578, 0.34668016433716, 0.30565163493156, 0.30940017104149, 0.2526627779007, 0.26721423864365, 0.23252418637276, 0.24234329164028, 0.23594723641872, 0.23505254089832, 0.24642345309258, 0.23845611512661, 0.24567161500454, 0.25639548897743, 0.10753717273474, 0.052953895181417 ], "/Developer/Projects/live-beatbox/samples/Kick 4.wav": [ 0.93611294031143, 0.25800436735153, 0.5811305642128, 0.34725385904312, 0.49174624681473, 0.36284822225571, 0.33105072379112, 0.31319147348404, 0.28728953003883, 0.27400785684586, 0.27199250459671, 0.2534915804863, 0.24526245892048, 0.22176134586334, 0.24928249418736, 0.2540597319603, 0.24614335596561, 0.24308599531651, 0.24642080068588, 0.22563152015209, 0.209263920784, 0.23855546116829 ], "/Developer/Projects/live-beatbox/samples/Clap 8.wav": [ 0.60428720712662, 0.053041979670525, 0.36905217170715, 0.15040497481823, 0.28244566917419, 0.2944687306881, 0.23870798945427, 0.23898273706436, 0.19173449277878, 0.14166882634163, 0.15116521716118, 0.19989791512489, 0.19289819896221, 0.20128247141838, 0.21126517653465, 0.21161749958992, 0.21415655314922, 0.18606813251972, 0.19433003664017, 0.19657017290592, 0.57824128866196, 0.50658804178238 ],
|
||||||
|
"/Developer/Projects/live-beatbox/samples/Kick i.wav": [ 1.2660367488861, 0.72230404615402, 0.39479839801788, 0.45937439799309, 0.44627648591995, 0.48469826579094, 0.41922482848167, 0.38191515207291, 0.31499260663986, 0.2971103489399, 0.2607139647007, 0.26749032735825, 0.26705753803253, 0.26931434869766, 0.26219287514687, 0.2657016813755, 0.25427350401878, 0.24527046084404, 0.24137346446514, 0.24400290846825, 0.060839485377073, 0.012823117896914 ], "/Developer/Projects/live-beatbox/samples/Kick j.wav": [ 0.66568666696548, 0.3877287209034, 0.72663903236389, 0.33814695477486, 0.4586991071701, 0.32867577672005, 0.39185512065887, 0.30321332812309, 0.34862568974495, 0.28302523493767, 0.33535400032997, 0.27233931422234, 0.28381314873695, 0.25223881006241, 0.28536349534988, 0.26062855124474, 0.25366026163101, 0.22903640568256, 0.26199051737785, 0.26285922527313, 0.25105962157249, 0.25947561860085 ], "/Developer/Projects/live-beatbox/samples/snare 1.wav": [ 0.18251430988312, 0.23462139070034, 0.52651435136795, 0.26855412125587, 0.41172385215759, 0.23681636154652, 0.28830567002296, 0.2267539203167, 0.20542639493942, 0.19373570382595, 0.18983379006386, 0.1831424087286, 0.19364219903946, 0.1918915361166, 0.2182579934597, 0.2308054715395, 0.23444300889969, 0.2395131289959, 0.24769546091557, 0.25882142782211, 0.91999870538712, 0.74711364507675 ], "/Developer/Projects/live-beatbox/samples/Clap 1.wav": [ 0.72256773710251, 0.004198984708637, 0.0069205807521939, 0.057040087878704, 0.18090313673019, 0.28535178303719, 0.34019842743874, 0.33379846811295, 0.33037883043289, 0.30148312449455, 0.29975843429565, 0.28523281216621, 0.28533810377121, 0.28715687990189, 0.30975842475891, 0.3136482834816, 0.30015376210213, 0.3000565469265, 0.29190695285797, 0.28178691864014, 0.44229477643967, 0.22089773416519 ], "/Developer/Projects/live-beatbox/samples/Kick c.wav": [ 0.78290051221848, 0.42011481523514, 0.39649233222008, 0.36926603317261, 0.34262925386429, 0.32996726036072, 0.31573995947838, 0.30807968974113, 0.30669462680817, 0.28580591082573, 0.28369721770287, 0.27740976214409, 0.26322227716446, 0.26025024056435, 0.26295265555382, 0.25613257288933, 0.25432777404785, 0.24833436310291, 0.24755972623825, 0.24598668515682, 0.5, 0.0095669003203511 ],
|
||||||
|
"/Developer/Projects/live-beatbox/samples/Clap 2.wav": [ 0.49899563193321, -0.30962714552879, -0.16894295811653, -0.18331563472748, 0.080371178686619, 0.12191355973482, 0.20887231826782, 0.16864922642708, 0.17281931638718, 0.15626810491085, 0.2069805264473, 0.18230508267879, 0.19472655653954, 0.20361450314522, 0.22917656600475, 0.22764115035534, 0.24265982210636, 0.23105123639107, 0.24881926178932, 0.23226749897003, 0.42349317669868, 0.26700448989868 ], "/Developer/Projects/live-beatbox/samples/Kick e.wav": [ 1.2427742481232, 0.48412781953812, 0.46151006221771, 0.35224568843842, 0.48598083853722, 0.40589734911919, 0.36835569143295, 0.28702196478844, 0.3270283639431, 0.29504770040512, 0.28973612189293, 0.27286118268967, 0.24378871917725, 0.23382867872715, 0.23643144965172, 0.25075927376747, 0.24520194530487, 0.22855411469936, 0.25418031215668, 0.25720977783203, 0.094749562442303, 0.052820481359959 ], "/Developer/Projects/live-beatbox/samples/Closed hat 4.wav": [ -0.025490814819932, 0.21730072796345, 0.31080269813538, 0.073317714035511, 0.17443419992924, 0.17215865850449, 0.18599112331867, 0.1290600001812, 0.1416395008564, 0.17911048233509, 0.16852425038815, 0.16788147389889, 0.15692643821239, 0.18094246089458, 0.18207062780857, 0.18391583859921, 0.19118309020996, 0.18408054113388, 0.18447045981884, 0.18203270435333, 1.0191293954849, 0.93772488832474 ], "/Developer/Projects/live-beatbox/samples/Kick 2.wav": [ 0.8845841884613, 0.25268477201462, 0.5130113363266, 0.30332741141319, 0.4292431473732, 0.33092740178108, 0.39809715747833, 0.29576361179352, 0.28895643353462, 0.27257210016251, 0.26320305466652, 0.23345525562763, 0.24167196452618, 0.24578388035297, 0.23537655174732, 0.26244062185287, 0.23740193247795, 0.2460995465517, 0.24321322143078, 0.23303996026516, 0.28596416115761, 0.30931651592255 ], "/Developer/Projects/live-beatbox/samples/Boosh.wav": [ 0.82914632558823, 0.10062445700169, 0.72980725765228, 0.13170671463013, 0.37320697307587, 0.12884978950024, 0.34461215138435, 0.10162660479546, 0.30351492762566, 0.096267476677895, 0.25027343630791, 0.16578996181488, 0.26388508081436, 0.18736755847931, 0.26469105482101, 0.18993745744228, 0.29747033119202, 0.19093061983585, 0.29271197319031, 0.17798589169979, 0.43806856870651, 0.42755684256554 ],
|
||||||
|
"/Developer/Projects/live-beatbox/samples/Kick 7.wav": [ 1.2825565338135, 0.51177829504013, 0.50188928842545, 0.32276037335396, 0.35196831822395, 0.28597509860992, 0.30678096413612, 0.27806276082993, 0.27261769771576, 0.25930467247963, 0.25348848104477, 0.24722228944302, 0.23828437924385, 0.24415953457355, 0.25925692915916, 0.25468355417252, 0.24741281569004, 0.23701874911785, 0.24644240736961, 0.24456100165844, 0.5, 0.015705352649093 ], "/Developer/Projects/live-beatbox/samples/Kick 8.wav": [ 0.89023840427399, 0.39156287908554, 0.52313667535782, 0.40548461675644, 0.39242249727249, 0.30010604858398, 0.34176275134087, 0.30604696273804, 0.28998252749443, 0.284569054842, 0.27921843528748, 0.27235385775566, 0.27355247735977, 0.24842885136604, 0.26147907972336, 0.26604726910591, 0.25935155153275, 0.25968423485756, 0.25615233182907, 0.24655812978745, 0.5, 0.010069645009935 ], "/Developer/Projects/live-beatbox/samples/Mace.wav": [ 0.68001586198807, -0.08747585862875, 0.20031732320786, 0.45465880632401, 0.24278998374939, 0.15520741045475, 0.39294219017029, 0.31397640705109, 0.23469185829163, 0.29590052366257, 0.29736387729645, 0.30505037307739, 0.26953941583633, 0.28168845176697, 0.24470297992229, 0.26247560977936, 0.23433543741703, 0.20802608132362, 0.23503650724888, 0.26996144652367, 0.5721527338028, 0.4345386326313 ], "/Developer/Projects/live-beatbox/samples/Closed hat 2.wav": [ -0.24041655659676, 0.18434146046638, 0.26875647902489, 0.10452826321125, 0.15270887315273, 0.14445799589157, 0.16138996183872, 0.13709534704685, 0.13576667010784, 0.18001724779606, 0.22938613593578, 0.2194812297821, 0.22518564760685, 0.22839047014713, 0.21999795734882, 0.20800541341305, 0.22956544160843, 0.24266947805882, 0.24234534800053, 0.20933836698532, 1.2266902923584, 0.97205013036728 ], "/Developer/Projects/live-beatbox/samples/Kick 3.wav": [ 1.0011028051376, 0.40234813094139, 0.45889461040497, 0.34455496072769, 0.37960460782051, 0.32668650150299, 0.32158249616623, 0.30030682682991, 0.28383427858353, 0.26678124070168, 0.2560741007328, 0.25409865379333, 0.2597796022892, 0.25882884860039, 0.2586470246315, 0.24702036380768, 0.25080168247223, 0.25776746869087, 0.24555863440037, 0.24333871901035, 0.5, 0.042498268187046 ],
|
||||||
|
"/Developer/Projects/live-beatbox/samples/Closed hat 5.wav": [ -0.14746677875519, 0.20518408715725, 0.31696575880051, 0.087675958871841, 0.20821140706539, 0.17847244441509, 0.18199095129967, 0.14824746549129, 0.16149520874023, 0.17520378530025, 0.18740993738174, 0.18199309706688, 0.16949005424976, 0.17568406462669, 0.19164322316647, 0.2051462829113, 0.20931321382523, 0.22398208081722, 0.22217744588852, 0.21613308787346, 1.2904230356216, 0.96203035116196 ], "/Developer/Projects/live-beatbox/samples/Kick 5.wav": [ 1.3925746679306, 0.33888247609138, 0.5436674952507, 0.34234488010406, 0.40540197491646, 0.37344381213188, 0.36660873889923, 0.31410774588585, 0.29036098718643, 0.27466267347336, 0.26912334561348, 0.25031274557114, 0.25325891375542, 0.25056770443916, 0.24540962278843, 0.25904276967049, 0.25551190972328, 0.25073948502541, 0.24839524924755, 0.25617578625679, 0.081054776906967, 0.033872157335281 ] )
|
|
@ -0,0 +1,45 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
|
<meta http-equiv="Content-Style-Type" content="text/css">
|
||||||
|
<title></title>
|
||||||
|
<meta name="Generator" content="Cocoa HTML Writer">
|
||||||
|
<meta name="CocoaVersion" content="949.35">
|
||||||
|
<style type="text/css">
|
||||||
|
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Helvetica}
|
||||||
|
p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px}
|
||||||
|
p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica}
|
||||||
|
p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Helvetica}
|
||||||
|
p.p5 {margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Helvetica}
|
||||||
|
p.p6 {margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Helvetica; min-height: 16.0px}
|
||||||
|
p.p7 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; min-height: 12.0px}
|
||||||
|
p.p8 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 9.0px Monaco; color: #a02411}
|
||||||
|
p.p9 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco}
|
||||||
|
span.s1 {text-decoration: underline}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p class="p1"><b>AverageOutput</b></p>
|
||||||
|
<p class="p2"><br></p>
|
||||||
|
<p class="p3">The mean average output since the last received trigger.</p>
|
||||||
|
<p class="p2"><br></p>
|
||||||
|
<p class="p4"><b><span class="s1">Class methods</span></b></p>
|
||||||
|
<p class="p2"><br></p>
|
||||||
|
<p class="p5"><b>*ar(in, trig, mul, add)</b></p>
|
||||||
|
<p class="p5"><b>*kr(in, trig, mul, add)</b></p>
|
||||||
|
<p class="p6"><b></b><br></p>
|
||||||
|
<p class="p6"><b></b><br></p>
|
||||||
|
<p class="p3"><b>in - </b>input signal.</p>
|
||||||
|
<p class="p2"><br></p>
|
||||||
|
<p class="p3"><b>trig</b> -<span class="Apple-converted-space"> </span>if changes from <= 0 to > 0, resets average and count to zero.</p>
|
||||||
|
<p class="p2"><br></p>
|
||||||
|
<p class="p2"><br></p>
|
||||||
|
<p class="p3"><i>Examples</i></p>
|
||||||
|
<p class="p7"><br></p>
|
||||||
|
<p class="p8">// sine oscillator, average slowly settles to zero</p>
|
||||||
|
<p class="p9">a = { AverageOutput.ar(SinOsc.ar(10000)).poll }.play;</p>
|
||||||
|
<p class="p7"><br></p>
|
||||||
|
<p class="p9">a.free;</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
Binary file not shown.
|
@ -0,0 +1,5 @@
|
||||||
|
(
|
||||||
|
Server.local.doWhenBooted {
|
||||||
|
BeatBox(Document.current.dir);
|
||||||
|
};
|
||||||
|
)
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,40 @@
|
||||||
|
// This is the script I used to batch analyse a directory of audio samples.
|
||||||
|
|
||||||
|
// It scans a directory, analyses each suitable audio
|
||||||
|
// sample found and stores the results in the environment variable
|
||||||
|
// ~output.
|
||||||
|
|
||||||
|
// This output should be saved in a file called "data.sc" in the root directory.
|
||||||
|
|
||||||
|
// At present sound samples are limited to 1 second in length..
|
||||||
|
|
||||||
|
|
||||||
|
// TODO improve this system!
|
||||||
|
|
||||||
|
|
||||||
|
(
|
||||||
|
var maxFrames = 44100;
|
||||||
|
var path = Document.current.dir ++ "/samples/".standardizePath; // edit to your path
|
||||||
|
var files = (path ++ "*.wav").pathMatch;
|
||||||
|
~output = ();
|
||||||
|
|
||||||
|
Routine {
|
||||||
|
files.do { |fname|
|
||||||
|
var len;
|
||||||
|
|
||||||
|
try {
|
||||||
|
Post << "Processing " << fname << $\n;
|
||||||
|
|
||||||
|
Beat.newFromPath(fname, s) { |beat|
|
||||||
|
beat.analyse { |beat|
|
||||||
|
~output[fname] = beat.features;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} { |error|
|
||||||
|
error.errorString.postln;
|
||||||
|
};
|
||||||
|
|
||||||
|
1.wait
|
||||||
|
};
|
||||||
|
}.play;
|
||||||
|
)
|
|
@ -0,0 +1 @@
|
||||||
|
the included sounds come from the public domain "Alex Calver Sample Pack"
|
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
SuperCollider real time audio synthesis system
|
||||||
|
Copyright (c) 2002 James McCartney. All rights reserved.
|
||||||
|
http://www.audiosynth.com
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
//ACMC demo UGen
|
||||||
|
|
||||||
|
#include "SC_PlugIn.h"
|
||||||
|
|
||||||
|
static InterfaceTable *ft;
|
||||||
|
|
||||||
|
struct AverageOutput : public Unit {
|
||||||
|
float average, prev_trig;
|
||||||
|
uint32 count;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
void AverageOutput_next(AverageOutput *unit, int inNumSamples);
|
||||||
|
void AverageOutput_Ctor(AverageOutput* unit);
|
||||||
|
void AverageOutput_Dtor(AverageOutput* unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void AverageOutput_Ctor( AverageOutput* unit ) {
|
||||||
|
unit->average = 0.;
|
||||||
|
unit->count = 0;
|
||||||
|
unit->prev_trig = 0.;
|
||||||
|
|
||||||
|
RGen& rgen = *unit->mParent->mRGen;
|
||||||
|
|
||||||
|
SETCALC(AverageOutput_next);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AverageOutput_Dtor(AverageOutput *unit) {
|
||||||
|
// nothing to do here
|
||||||
|
}
|
||||||
|
|
||||||
|
void AverageOutput_next( AverageOutput *unit, int inNumSamples ) {
|
||||||
|
int i;
|
||||||
|
float *in = IN(0);
|
||||||
|
float *out = ZOUT(0);
|
||||||
|
float trig = ZIN0(1);
|
||||||
|
float prev_trig = unit->prev_trig;
|
||||||
|
double average = unit->average;
|
||||||
|
uint32 count = unit->count;
|
||||||
|
|
||||||
|
if(prev_trig <= 0. && trig > 0.) {
|
||||||
|
average = 0.;
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i<inNumSamples; ++i) {
|
||||||
|
average = ((count * average) + *(in+i)) / ++count;
|
||||||
|
ZXP(out) = average;
|
||||||
|
}
|
||||||
|
|
||||||
|
unit->prev_trig = trig;
|
||||||
|
unit->count = count;
|
||||||
|
unit->average = average;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void load(InterfaceTable *inTable) {
|
||||||
|
|
||||||
|
ft = inTable;
|
||||||
|
|
||||||
|
DefineDtorUnit(AverageOutput);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
cp /Applications/SuperCollider3/build/plugins/RFWGens.scx /l/cm2/coursework/task3/plugins
|
|
@ -0,0 +1,47 @@
|
||||||
|
SynthDef(\beatboxlistener) { |out=0, in=0, amp=1.0, threshold=0.3, lag=0.1, t_resetRecord=0.0, fftbuf, recbuf|
|
||||||
|
var input, chain, onsets, peak;
|
||||||
|
|
||||||
|
input = SoundIn.ar(in);
|
||||||
|
chain = FFT(fftbuf, input);
|
||||||
|
onsets = Onsets.kr(chain, threshold, \rcomplex);
|
||||||
|
peak = PeakFollower.ar(input, 0.01).lag(lag);
|
||||||
|
|
||||||
|
RecordBuf.ar(input, bufnum: recbuf, trigger: t_resetRecord);
|
||||||
|
|
||||||
|
SendTrig.kr(onsets, value: 1);
|
||||||
|
SendTrig.ar((peak < 0.0002), value: 2);
|
||||||
|
|
||||||
|
Out.ar(out, input * amp);
|
||||||
|
}.load(s);
|
||||||
|
|
||||||
|
// TODO Envelope recognition? This is pretty good at selecting timbres but often the envelopes
|
||||||
|
// of the two sounds (perceptually just as important??) are very different.
|
||||||
|
SynthDef(\beatboxanalyzer) { |out=0, fftbuf, bufnum, cbus1, cbus2, cbus3, t_reset=0.0|
|
||||||
|
var sig, inbuf, chain, coeffs, centroid, zcr;
|
||||||
|
|
||||||
|
sig = PlayBuf.ar(numChannels: 1, bufnum:bufnum);
|
||||||
|
chain = FFT(fftbuf, sig, wintype: 1); // Hann windowing
|
||||||
|
coeffs = MFCC.kr(chain, 20);
|
||||||
|
centroid = SpecCentroid.kr(chain).linlin(100, 10000, 0, 1.5, \minmax); // perhaps a slight weighting
|
||||||
|
zcr = ZeroCrossing.ar(sig).linlin(100, 10000, 0, 1.5, \minmax); // towards these two
|
||||||
|
|
||||||
|
Out.kr(cbus1, AverageOutput.kr(coeffs, trig: t_reset));
|
||||||
|
Out.kr(cbus2, AverageOutput.kr(centroid, trig: t_reset));
|
||||||
|
Out.kr(cbus3, A2K.kr(AverageOutput.kr(zcr, trig: t_reset)));
|
||||||
|
}.load(s);
|
||||||
|
|
||||||
|
|
||||||
|
SynthDef(\beatboxplayer) { |out=0, bufnum1, bufnum2, crossfade=0.0, mul=1.0|
|
||||||
|
var p1 = PlayBuf.ar(numChannels: 1, loop: 0, bufnum: bufnum1);
|
||||||
|
var p2 = PlayBuf.ar(numChannels: 1, loop: 0, bufnum: bufnum2);
|
||||||
|
var amp1 = 1 - crossfade;
|
||||||
|
var amp2 = crossfade;
|
||||||
|
var dur = BufDur.kr(bufnum1);
|
||||||
|
var env = EnvGen.kr(Env([1,1,0], [dur * 0.9, dur]));
|
||||||
|
|
||||||
|
Out.ar(out,
|
||||||
|
mul * Pan2.ar(
|
||||||
|
(((p1 * 0.5) * (env * amp1)) + ((p2 * 0.5) * (env * amp2)));
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}.load(s);
|
Loading…
Reference in New Issue