live-beatbox/synthdefs.sc

48 lines
1.8 KiB
Python

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);