I guys,
I’m moving my first steps into live coding thanks to the beautiful Sean Cotterill tutorials and now I would like my set to send some information via OSC to an external piece of software in order for it to create live visuals.
Some month ago I’ve written a SynthDef and some functions to send machine listening data (like amplitude, centroid, chromas and more) via OSC.
Here’s the code:
(
s.waitForBoot({
// this is the address of the OSC application
// which will receive machine listening data from SC
~data_analyzer = NetAddr("127.0.0.1", 15100);
~bool_sendOSC = True;
~fftWidth = 2048;
~rate = 1;
~pitchExecFreq = 10;
~b = Bus.audio(s, 2);
s.sync;
// Synth Definitions
SynthDef(\features_onset, {
| in=0, rate=1 |
var sig, fft, amplitude;
var loud, flat, centroid;
var freq, hasFreq, chroma;
var ph, onset;
sig = In.ar(in, 2);
amplitude = Amplitude.kr(sig);
fft = FFT(LocalBuf(~fftWidth), sig);
loud = Loudness.kr(fft);
# freq, hasFreq = Pitch.kr(sig, execFreq:~pitchExecFreq);
flat = SpecFlatness.kr(fft);
chroma = Chromagram.kr(fft, ~fftWidth, /*tuningbase:55.0,*/ integrationflag:0, perframenormalize:1);
centroid = SpecCentroid.kr(fft);
onset = Onsets.kr(fft, threshold:0.3, odftype:'magsum');
SendTrig.kr(onset, id:0);
SendReply.kr(Impulse.kr(rate),'/tr',
[
loud, flat, centroid
],
replyID:1);
SendReply.kr(hasFreq * Impulse.kr(~pitchExecFreq),'/tr',
[
hasFreq, freq,
chroma[0], chroma[1], chroma[2], chroma[3],
chroma[4], chroma[5], chroma[6], chroma[7],
chroma[8], chroma[9], chroma[10], chroma[11],
],
replyID:2);
}).add;
s.sync;
// OSC functions
o = OSCFunc({
|msg, time, addr, recvPort|
var data, elapsed;
//[time, msg].postln;
switch( msg[2],
0, {
// ONSETS ID
if( ~bool_sendOSC == True , {
~data_analyzer.sendMsg("/debug/onset", 1);
~data_analyzer.sendMsg("/debug/onset", 0);
});
},
1, {
// FEATURES ID
data = msg[3..];
if( ~bool_sendOSC == True , {
~data_analyzer.sendMsg("/debug/loud", data[0]);
~data_analyzer.sendMsg("/debug/flat", data[1]);
~data_analyzer.sendMsg("/debug/centroid", data[2]);
});
},
2, {
// PITCH FEATURES ID
data = msg[3..];
if( ~bool_sendOSC == True , {
~sendDataViaOsc.value(data);
});
},
{
"default".postln;
}
);
},'/tr', s.addr);
s.sync;
// some utility functions
~sendDataViaOsc = {
|data|
~data_analyzer.sendMsg("/debug/hasFreq", data[0]);
~data_analyzer.sendMsg("/debug/freq", data[1]);
// chroma data
~data_analyzer.sendMsg("/debug/C", data[2] );
~data_analyzer.sendMsg("/debug/C#", data[3] );
~data_analyzer.sendMsg("/debug/D", data[4] );
~data_analyzer.sendMsg("/debug/D#", data[5] );
~data_analyzer.sendMsg("/debug/E", data[6] );
~data_analyzer.sendMsg("/debug/F", data[7] );
~data_analyzer.sendMsg("/debug/F#", data[8]);
~data_analyzer.sendMsg("/debug/G", data[9]);
~data_analyzer.sendMsg("/debug/G#", data[10]);
~data_analyzer.sendMsg("/debug/A", data[11]);
~data_analyzer.sendMsg("/debug/A#", data[12]);
~data_analyzer.sendMsg("/debug/B", data[13]);
};
s.sync;
// let's start!
~feature_onset = Synth(\features_onset, [\in, ~b, \rate, ~rate]);
});
)
I would like to use it but I don’t know how.
As you can see the synth must be fed with some audio input.
Is there a way the synth can be fed by ProxySpace audio output?
Should it be the right strategy to get what I want?
Do somebody have some experience with this topic?
maybe is there some Quark I should use instead?
Thank you in advance for your help!