Releases Blog Info RSS Soundcloud Facebook Twitter Spotify Last.fm iTunes Amazon MP3

MicroBrute Patch - Too Much Sauce

Notes: LFO split to Pitch and Filter using a headphone splitter. Env and LFO can combine to provide a delay effect. Best played using an internal or external sequencer so the LFO is synced.

MicroBrute Patch - West Coast Alarm

Notes: High, whiny, glide-y. Reverb and Delay from Guitar Rig.

MicroBrute Patch - Canadian Excitebike

Notes: Bass/lead with unstable pitch. Sounds kinda like a Nintendo motorcycle. Reverb and Delay from Guitar Rig / Reflektor.

MicroBrute Patch - BeetleBass

Notes: Synthbass patch. During the demo I swept the mod wheel and cutoff.

MicroBrute Patch - DistHarpsiOrgan

Notes: This patch ended up somewhere between a distorted organ, a synthbass and some tone that reminded me of a harpsichord. Despite the arpeggios of the demo this patch can work well with long sustained notes. I manually swept the Env Amt during the recording.

MicroBrute Patch - SquareKick

Notes: This was my first attempt to get something like a kick drum out of the MicroBrute. In software my approach has been to have individual envelopes for amplitude and pitch. Since the MicroBrute only has one envelope I have turned on the LFO retrigger thru the MicroBrute Connection software. By having the LFO retrigger on each note we are able to use it as a simple envelope. Modify the LFO Amount and Rate to change the shape of the pitch envelope. Other useful parameters for this patch are Decay, Mod Wheel and Glide.

Analog Excursions

Recently I acquired an Arturia Microbrute. Despite how long I have been creating music and the numerous pieces of gear I have owned this is my first analog synth. Since I am planning this as the first step in a small eurorack modular setup I figured I would start documenting some of my experiments and failures here. Expect more on this soon.

rePatcher to Reaktor

In a previous post I introduced my interface to translate the Open Music Labs rePatcher hardware’s serial data into OSC messages. I have also written a macro for Reaktor that allows you to access the knobs and patchbay.

The macro can be download from the Reaktor User Library.

The macro has 6 In and Out ports that correspond to the Ins and Outs on the hardware. The final 6 outputs send the value of the hardware knobs scaled to a value between 0 and 1.

Before you can use this macro you must enable OSC Receive under the the File -> Osc Settings menu.

rePatcher to OSC shortcut

Yesterday I posted about my rePatcher to OSC interface written in Processing. I’ve been finding it very useful but I was annoyed by the fact that I had to open processing IDE and run the code every time. I wanted it to behave a bit more like a traditional program.

I tried to export the program as an app but for whatever reason the export was not working correctly. I decided to do a quick hack as a workaround. This applies to windows only although I am sure a similar process could be done on Mac and Linux.

Within the directory you installed processing to there is a file called processing-java.exe. This is the file that you send command line parameters to instead of processing itself. We will be passing this the command to run your script without running the Processing IDE. The output directory is where the temporary files it generates will be stored. I would suggest using a location within your sketch folder.

  1. Right-click on your desktop and pick New -> Shortcut
  2. When prompted for a location use the following. Change thedirectory path to point to your processing-java.exe and change the input and output paths to point to valid locations. "C:\Program Files (x86)\processing-2.0.1\processing-java.exe" —run —sketch=c:\repatcher_osc —output=c:\repatcher_osc\output —force
  3. From within the shortcut properties choose Run: Minimized. This will cause the console window that is generated by the shortcut to be minimized on launch and help reduce screen clutter. You can close this console window any time it is launched, it will not affect the app.

rePatcher to OSC

As soon as I saw the announcement of rePatcher I was interested. It seemed like a very affordable way to add some physical control over your code. I am personally not a big fan of PD or Max so I decided to interface it to Supercollider and Reaktor instead. I quickly realized that the windows implementation of the Serial class in Supercollider did not work and Reaktor did not support serial communication at all. Both languages have very good support for OSC so I decided to write a small processing app to translate the serial info from the rePatcher into OSC.

Download the rePatcher Arduino code from the Open Music Labs Wiki and delete the following line before loading the code to your arduino:
while (Serial.read() != 0xab); // wait for turn on signal
In the PD patch that Open Music Labs provided they had a functionality where you could start and stop the rePatcher serial stream. It was not a bad idea but without a hardware button for the function it just seems like an extra step in trying to get the rePatcher set up properly.

From within your Processing IDE you will need to install the ControlP5 and OscP5 libraries. Once they have been installed properly you can run the following code from the IDE. The window will ask you for the COM port your arduino is connected to as well as the IP and port you wish to send OSC data on. Once you are satisfied with the settings hit the TX button and leave the window running. If you need to change these settings simply close the window and restart the program.

The knobs will send a message in the format of /repatcher/knobN where N is a number between 0 and 5 representing the current knob. The knobs will send a single argument of a float between 0 and 1 for the current value.

The patchbay will send a message in the format of /repatcher/outputN where N is a number between 0 and 5 representing the current output. The patchbay will send six integers with a value of 0 or 1 to represent which inputs are patched to the current output.

In the future I will post about how to read the generated OSC inside of Reaktor.

import oscP5.*;
import netP5.*;
import controlP5.*;
import processing.serial.*;

final int MESSAGE_STOP = 0xba;
final int MESSAGE_START = 0xab;
final int MESSAGE_BUFFERSTART = 0xc0;

//System
PApplet app = this;
Serial myPort;
OscP5 oscP5;
NetAddress myRemoteLocation;

//GUI
ControlP5 cp5;
Toggle transmitToggle;
DropdownList serialPortList;
Textfield ip;
Textfield ip_port;

void setup(){
  //Setup display
  size(190, 70);
  smooth();
  noStroke();
  cp5 = new ControlP5(this);
  transmitToggle = createTransmitToggle();
  serialPortList = createSerialPortList();
  ip = cp5.addTextfield("IP").setPosition(70, 10).setSize(50, 15).setText("127.0.0.1");
  ip_port = cp5.addTextfield("IP_Port").setPosition(70, 40).setSize(50, 15).setText("12000");
  oscP5 = new OscP5(this,12001);
}

void draw(){
  background(100);
 
  if (transmitToggle.getState()){
    //Read and process the buffer as long as the TX button is pressed
    readBuffer();
  };
  
}

Toggle createTransmitToggle(){
  Toggle transmitToggle;
  CallbackListener toggleCallback = new CallbackListener() {
    public void controlEvent(CallbackEvent theEvent) {
      if (theEvent.getAction()==ControlP5.ACTION_PRESSED) {connectSerialPort();}
    }
  };
  transmitToggle = cp5.addToggle("TX")
    .setPosition(130,10)
    .setSize(45,45)
    .addCallback(toggleCallback)
  ;
  return transmitToggle;
}

DropdownList createSerialPortList(){
  DropdownList serialPortList = cp5.addDropdownList("Port")
    .setPosition(10,22)
    .setSize(50,60)
    .addItems(Serial.list())
    .setValue(0);
  ;
  return serialPortList;
}

void connectSerialPort(){
  if (myPort == null){
    //If the serial port is not connected then connect it.  
    myPort = new Serial(app, Serial.list()[(int)serialPortList.getValue()], 38400);
    serialPortList.disableCollapse();
    
    //Connect port for OSC data
    ip.setLock(true);
    ip_port.setLock(true);
    myRemoteLocation = new NetAddress(ip.getText(),int(ip_port.getText()));
    
    //Lock all controls
    transmitToggle.setLock(true);
  }
}

void readBuffer(){
  //If the buffer is empty then bail out
  if (myPort.available() == 0) {return;}
  
  //Read all incoming serial data.  When we find the start of a buffer we grab the next 18 characters and process them.
  byte[] buffer = new byte[18];
  char inByte = myPort.readChar();
  if (inByte == MESSAGE_BUFFERSTART) {
    myPort.readBytes(buffer);
    myPort.clear(); //Data is coming in so fast we need to clear the pipe to avoid serious lag
    readKnobs(buffer);
    readPatchBay(buffer);
  };
}

void readKnobs(byte[] buffer){
  //Parse knob data out of the buffer and pass it to the repatcherControls object  
  for(int i = 0; i < 12; i = i+2){
    int knobNumber = 5 - (i / 2);  //Knobs are packed in the buffer in reverse order, this flips the numbering
    float knobInValue = (buffer[i+1] << 7) | buffer[i];
    float knobMapValue = map(knobInValue, 0, 1024, 0, 1);
    OscMessage myMessage = new OscMessage("/repatcher/knob" + knobNumber);
    myMessage.add(knobMapValue);
    oscP5.send(myMessage, myRemoteLocation); 
  };
}

void readPatchBay(byte[] buffer){
  //Parse patchbay data out of the buffer and pass it to the repatcherControls object
  for(int i = 12; i < 18; i++){
    int outPin = 5 - (i - 12);
    OscMessage myMessage = new OscMessage("/repatcher/output" + outPin);
    if ((buffer[i] & 32) == 32) {myMessage.add(1);} else {myMessage.add(0);};
    if ((buffer[i] & 16) == 16) {myMessage.add(1);} else {myMessage.add(0);};
    if ((buffer[i] &  8) ==  8) {myMessage.add(1);} else {myMessage.add(0);};
    if ((buffer[i] &  4) ==  4) {myMessage.add(1);} else {myMessage.add(0);};
    if ((buffer[i] &  2) ==  2) {myMessage.add(1);} else {myMessage.add(0);};
    if ((buffer[i] &  1) ==  1) {myMessage.add(1);} else {myMessage.add(0);};
    oscP5.send(myMessage, myRemoteLocation); 
  };
}