Monday, April 30, 2012

Loft - The Package

We just finished up a new record today.  Music recorded with our diy modular synths in several cities around the world.

Friday, April 20, 2012

A New Face!


Another panel option for the Voice of Saturn Synth "Red Devil" Euro module.

Thursday, April 12, 2012

Big Muff Mod!


Last week I did a simple Big Muff mod for a client in the band swerve. Its one of the newer, surface mount pcbs, and thus took a little digging around the circuit to find the correct place to implement the noise gate mod described here. Its pretty easy to figure out which transistor is the 2nd gain stage from looking at the stock schematic from general guitar gadgets, then it just took a bit of poking around to find the equivalent to R14, the 100k to ground. I used a 500k linear pot instead of a trim pot, to allow the user to dial the tone in to taste. Its a pretty easy mod, and super useful as are the others on that site. I hope to get a cheap newer big muff in the near future and fully mod it out.

Wednesday, April 4, 2012

Arduino Midi to Trigger interface with random cv output



Today I completed V1.0 of my Arduino Midi - Trigger interface. Its nothing groundbreaking but a very useful module to give you up to 9 trigger outputs, a random cv output, clock input and midi control over all inputs. The inspiration for mine was watching some demo's of the amazing drum dokta module from Din Sync. I picked one of these up and they sound killer but I needed a useful and easy way to trigger the sounds. The module is basically 2 parts. One is a clock divider inspired somewaht by the 4ms module, the other is a simple midi implementation. As it stands, triggers 1-6 as well as the random cv trigger are controlled by midi notes 60-66. This is easily editable in the code and more triggers can be added. Below is a diagram of the connections and the code follows. Hopefully someone will find this useful and help me to improve it!




One other important thing to note, this program uses the Arduino Midi library which can be found here.
Code below:

//////////////////////////////////////////////////////////
#include "MIDI.h"

// Modular utility controller
// Clock divider, random CV generator, Midi to trigger
// Rev 01. 4-2012 Travis Thatcher recompas@gmail.com

// midi values
#define OFF 1
#define ON 2
#define WAIT 3

boolean DEBUG = false; // to turn off all debug print messages

int resetPin = A0; // analog input used for reset button
int resetValue = 0;
int resetStart = 0;
boolean resetState = false;

int pwmPin = 5; // pin to output cv
int sequence[16]; // array to hold sequnce for pwm out
int counter=0; // counter for pwm sequence array

int triggerPins[] = {2, 4, 10, 11, 12, 13}; // trigger pins
int triggers[] = {0, 0, 0, 0, 0, 0}; // hold trigger counts
int triggerDivs[] = {4, 8, 1, 2, 16, 4}; // these set up the clock divisions for eachoutput
int triggerTimes[] = {0, 0, 0, 0, 0, 0}; // hold times for triggers
int triggerStates[] = {LOW, LOW, LOW, LOW, LOW, LOW};
int triggerTime = 1;

int currentTime=0;

byte incomingByte;
byte velocity;
int action = 2; //1 =note off ; 2=note on ; 3= wait


void setup() {

MIDI.begin(2); // i need to use channel 2 since i use the midi thru to send data do my doepfer midi to cv on channel 1
randomSeed(analogRead(0)); // lets get random
// setup output pins
pinMode(pwmPin, OUTPUT);
pinMode(2, OUTPUT);
pinMode(4, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);
resetStart = millis();
shuffle();
if(DEBUG){
Serial.println("hello!");
}
attachInterrupt(1, trigger, RISING);


}

void loop() {
if (MIDI.read()) { // Is there a MIDI message incoming ?
switch(MIDI.getType()) { // Get the type of the message we caught
case NoteOn: { // If it is a note on
playNote(MIDI.getData1());
break;
}

default:
break;
}
}

//Handle reset processing
resetValue = analogRead(resetPin);
currentTime = millis();

if(resetValue >= 200){ // arbitrary, just making sure the button is pushed. anything greater than 100 would probably work

if(resetState == false){
resetState = true;
shuffle();
resetBeat();
resetStart = currentTime;
if(DEBUG){
Serial.println("resetting");
}
}
else if(currentTime - resetStart>=200){
resetState = false;
}
}

// check out the trigger states
for(int i=0; i<6; i++){
if(triggerStates[i]==HIGH){
if(currentTime - triggerTimes[i] > triggerTime){
if(DEBUG){
Serial.println("turning off!");
}
digitalWrite(triggerPins[i], LOW);
triggerStates[i]=LOW;
}
}
}

}

void shuffle(){
for(int i=0; i<16; i++){
sequence[i]=random(0,255);
if(DEBUG){
Serial.println(sequence[i], DEC);
}
}

// reset beats

for(int j=0; j<6; j++){
triggers[j]=0;
digitalWrite(triggerPins[j], LOW);
triggerStates[j]=LOW;
}
trigger();

}

void resetBeat(){
counter=0;
}

void trigger(){
noInterrupts();
if(DEBUG){
Serial.println("triggering");
}

analogWrite(pwmPin, sequence[counter]);
counter++;
if(counter == 16){
counter = 0;
}

//trigger outputs
for(int i=0; i<6; i++){
triggers[i]++;
if(triggerDivs[i]==triggers[i]){
digitalWrite(triggerPins[i], HIGH);
triggerStates[i] = HIGH;
triggerTimes[i] = currentTime;
triggers[i]=0;
}else{

}
interrupts();
}
}

void playNote(byte note){
noInterrupts();
if(DEBUG){
Serial.println(note);
}

// funkee random bits
if(note-60==6){
analogWrite(pwmPin, sequence[counter]);
counter++;
if(counter == 16){
counter = 0;
}
}


// triggers!
for(int i=0; i<6; i++){

if(note-60==i){
digitalWrite(triggerPins[i], HIGH);
triggerStates[i] = HIGH;
triggerTimes[i] = currentTime;
triggers[i]=0;
action = 2;
}else{

}

interrupts();

}
}