MIDetector
MIDetector is a Supercollider library, is a easy to use library for sending musical information to other applications via OSC messages.
Current detectors are implemented based on existing UGENS (Supercollider Plugins) and some mathematical functions from mathlibs
Convenience, Musical Information, send musical information to other applications in real time.
- Amplitude
- Pitch
- Tarini
- Onsets
- FFTSubbandPower
The library is maintained by Benajamin Sanchez Lengeling on github and some help by Thomas Sanchez Lengeling
Tutorial
Once installed the library into Supercollider you are ready to start detection musical information!.
First boot up the server and run a simple MIDectector, just to make sure that the installation worked.
s.boot;
(
a=MIDetectorManager.new(net:NetAddr("127.0.0.1",32000));
)
This simple detector sends the information to a local host a.k.a your computer with a port number 32000.
So lest start en detection some more useful things, like Pitch, Onsets and amplitude.
(
a=MIDetectorManager.new(net:NetAddr("127.0.0.1",32000));
a.addDetector("Pitch");
a.addDetector("Onset",[tol,0.3]);
a.addDetector("Amp");
)
- Pitch, Detection Pitch of the sound
- Onset, With a initial Threshold of 0.3, change this values to sensitivity of the Onsets
- Amplitude, Detection Amplitude.
If you want to detect Power Bands, you can just add it in the MIDetector, just like the Pitch, Onset and Amp examples.
a.addDetector("Power",[nbands,64]);
Try the detection with the following sounds.
x={Decay2.ar(Impulse.ar(2),0.01,0.2)*SinOsc.ar(LFNoise0.kr(2).range(20,10000).poll)}.play
//Or your mouse
x={Decay2.ar(Impulse.ar(2),0.01,0.2)*SinOsc.ar(MouseX.kr(20,10000,1).poll)}.play
//White noise
x={WhiteNoise.ar}.play
//Kill it!
x.free
Processing Example
Processing code to receive and parse messages.
The processing example uses the library oscP5, it can be installed on processing using the Library Manager or manual installation.
For example, if you use the following MIDectector configuration, you are going to receive in processing 4 different types of information pitch, onset, amplitude and power bands.
(
a=MIDetectorManager.new(net:NetAddr("127.0.0.1",32000));
a.addDetector("Pitch");
a.addDetector("Onset",[tol,0.3]);
a.addDetector("Amp");
a.addDetector("Power",[nbands,64]);
)
Base on this configuration, in processing you plug OSC functions that will receive that musical information, you can do this for all the Detectors.
oscP5.plug(this, "ampResponse", "/amp");
oscP5.plug(this, "onsetResponse", "/onset");
oscP5.plug(this, "pitchResponse", "/pitch");
oscP5.plug(this, "powerResponse", "/power");
Complete Example in processing.
import java.nio.*;
import oscP5.*;
import netP5.*;
OscP5 oscP5;
NetAddress myRemoteLocation;
boolean printOSCMessage = true;
void setup(){
size(100,100);
oscSetup();
background(0);
}
void draw() {
}
void oscSetup(){
oscP5 = new OscP5(this, 32000);
oscP5.plug(this, "ampResponse", "/amp");
oscP5.plug(this, "onsetResponse", "/onset");
oscP5.plug(this, "pitchResponse", "/pitch");
oscP5.plug(this, "powerResponse", "/power");
}
/* Osc events reciever for not plugged messages */
void oscEvent(OscMessage theOscMessage) {
/* print the address pattern and the typetag of the received OscMessage */
if (printOSCMessage && theOscMessage.isPlugged() == false) {
print("### received an osc message.");
print(" addrpattern: " + theOscMessage.addrPattern());
println(" typetag: " + theOscMessage.typetag());
theOscMessage.printData();
}
}
/* Pluggable functions */
public void ampResponse(int id, float amp) {
if (printOSCMessage)println("Amp:" + id + " " + amp);
}
public void onsetResponse(int id) {
if (printOSCMessage)println("Onset:" + id);
}
public void pitchResponse(int id, float pitch) {
if (printOSCMessage)println("Pitch:" + id + " " + pitch);
}
public void powerResponse(int id, int nbands,byte[] data){
if (printOSCMessage)println("Power:" + id + " " + nbands);
//Parse bytes to floats
int offset=data.length-nbands*4;
ByteBuffer buffer = ByteBuffer.allocate(nbands*4);
buffer.put(data,0,4);
buffer.put(data,4+offset,4*(nbands-1)); //skip padding
println("[");
for(int i=0; i < nbands; i++){
print(buffer.getFloat(i*4)+",");
}
println("]");
}