Pages: 1 2 3 [4]   Go Down
Author Topic: 'midi in" project....  (Read 13463 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 1
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hi there,
I'm using a 2nd order filter
r = 47k
2r = 100k
c = 22nF
1/2c = 100nF
cheers,
Fedde
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 2
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I`m fairly new to Arduino programming, but I`m getting there. I have so far tried all of the midi-in programs on this thread, but what I really want to do is get the Arduino to play a simple square wave, for every note sent via MIDI.
I originally thought of using joshatkins MIDI to CV/gate converter, to control an external oscillator, but surely the Arduino should be able to generate simple tones. Does anyone know how to go about modifying the CV/ate converter code to do this?
Quote
/* MIDI to CV/Gate converter

Error in HZ due to 256-bit resolution of PWM (f_desired - f_synthesized)
------------------------------------------------------------------------
        0  A0
   0.0988  A#0
  -0.2105  B0
  -0.1113  C1
        0  C#1
   0.1245  D1
  -0.2652  D#1
  -0.1402  E1
        0  F1
   0.1569  F#1
  -0.3341  G1
  -0.1767  G#1
        0  A1
   0.1977
  -0.4210
  -0.2226
        0
   0.2490
  -0.5304
  -0.2805
        0
   0.3138
  -0.6682
  -0.3534
        0  A2
   0.3953
  -0.8419
  -0.4452
        0
   0.4981
  -1.0607
  -0.5610
        0
   0.6275
  -1.3365
  -0.7068
        0  A3
   0.7906
  -1.6838
  -0.8905
        0
   0.9961
  -2.1215
  -1.1219
        0
   1.2550
  -2.6729
  -1.4135
        0  A4
   1.5812
  -3.3676
  -1.7809
        0
   1.9922
  -4.2430
  -2.2438
        0
   2.5101
  -5.3458
  -2.8270
        0  A5
*/

int gatePin = 4;
int cvPin = 5;
int statusLED = 13;
int midiEnable = 2;
byte notes[] = {0,4,9,13,17,21,26,30,34,38,43,47,
   51,55,60,64,68,72,77,81,85,89,94,98,
   102,106,111,115,119,123,128,132,136,140,145,149,
   153,157,162,166,170,174,179,183,187,191,196,200,
   204,208,213,217,221,225,230,234,238,242,247,251,255};
int tempo = 1;

void setup() {
 pinMode(gatePin, OUTPUT);
 pinMode(cvPin, OUTPUT);
 pinMode(statusLED, OUTPUT);
 pinMode(midiEnable, OUTPUT);
 Serial.begin(31250);
 digitalWrite(midiEnable, HIGH);
}

void loop() {
 readMIDI();
}


// play a note out to cv
void note(byte note, byte velocity) {
 analogWrite(cvPin, notes[note-9]);
 if(velocity == 0) {
   digitalWrite(gatePin, LOW);
 } else {
   digitalWrite(gatePin, HIGH);
 }
}

void blink(int repeat) {
 for(int i=0; i<repeat; i++) {
   digitalWrite(statusLED, HIGH);
   delay(5);
   digitalWrite(statusLED, LOW);
   delay(1);
 }
}

void readMIDI() {
 byte incomingMessage[] = {0,0,0};
 byte incomingByte = 0;
 
 if(Serial.available() > 0) {
   incomingByte = Serial.read();
   delay(3);  // not sure why i need to delay here, but doesn't work w/o it
   if(incomingByte >= 240) {
     readSystem(incomingByte);
   } else {
     incomingMessage[0] = incomingByte;
   }
   if(Serial.available() > 0) {
     incomingByte = Serial.read();
     if(incomingByte >= 240) {
       readSystem(incomingByte);
     } else {
       incomingMessage[1] = incomingByte;
     }
     if(Serial.available() > 0) {
       incomingByte = Serial.read();
       if(incomingByte >= 240) {
         readSystem(incomingByte);
       } else {
         incomingMessage[2] = incomingByte;
       }
     }
   }
 }
 
 processMIDI(incomingMessage);
}

void readSystem(byte incomingByte) {
 byte incomingMessage[] = {0,0,0};
 
 // read in the system message
 incomingMessage[0] = incomingByte;
 if(Serial.available() > 0) {
   incomingMessage[1] = Serial.read();
   if(Serial.available() > 0) {
     incomingMessage[2] = Serial.read();
   }
 }
 
 processMIDI(incomingMessage);
}

void processMIDI(byte incomingMessage[]) {
 switch(incomingMessage[0]) {
   case B10010000:  // Note on, channel 1
     note(incomingMessage[1], incomingMessage[2]);
     break;
   case B10000000:  // Note off, channel 1
     note(incomingMessage[1], 0);
     break;
   case B11111000:  // Time code
     tempo++;
     if(tempo == 24) {
       blink(1);
       tempo = 0;
     }
     break;
 }
}
Thanks

Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 75
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

wow, for a  bare bones midi2cv is half bad!  To reduce the glide or portamento between notes I replaced the  470uf cap in the rc filter with a 47 and 22uf.   It was the lowest I could go without audibly impacting the cv out.  The only bugs/problems Ive encountered are:  Occasionally I will get a stuck note and when two  keys are pressed it cancels the "note on" command. Anyone else experiencing this?
    I have a r2r dac that I have been trying to use, with no luck.  Its a AD7528 , from this pic based midi to cv I tried to make:, http://www.emusic-diy.org/Schematics/Misc/MidiCv?action=AttachFile&do=get&target=MIDITOCV.GIF      and      http://www.emusic-diy.org/Schematics/Misc/MidiCv
even though the pic loaded properly, I could never get it working, even the gate. ?anyway...)  I also have some dac0800's
Im still not sure how to change the code of the midi2cv   to accommodate a dac or resistor bridge.  The pin configs and labeling  of the different  dacs already posted about seem to vary so much that I cant seem to figure much out by looking at other examples.    any thought or does anyone know of a real simple interfacing tutorial?
« Last Edit: February 22, 2010, 09:32:00 pm by Charbot » Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 75
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The keyboard glitches were with my keyboard.  If anyone else is experiencing similar problems, try turnig off the internal clock in your synth.

I have been trying to modify this sketch by adding an additional cv out  that works just like the pitch but coresponds to the mod wheel or an other assigned control and is used to modulate the filter, LFO or whatever on a Modular synth.  
Here is what i have:
Code:
int gatePin = 4;
int cvPin = 5;
int modwheel = 3; // **declare mod wheel pin  

int statusLED = 13;
int midiEnable = 2;
byte notes[] = {0,4,9,13,17,21,26,30,34,38,43,47,
  51,55,60,64,68,72,77,81,85,89,94,98,
  102,106,111,115,119,123,128,132,136,140,145,149,
  153,157,162,166,170,174,179,183,187,191,196,200,
  204,208,213,217,221,225,230,234,238,242,247,251,255};

byte mods[] = {0,4,9,13,17,21,26,30,34,38,43,47,       //**modulation steps
  51,55,60,64,68,72,77,81,85,89,94,98,
  102,106,111,115,119,123,128,132,136,140,145,149,
  153,157,162,166,170,174,179,183,187,191,196,200,
  204,208,213,217,221,225,230,234,238,242,247,251,255};

 

int tempo = 1;

void setup() {
pinMode(gatePin, OUTPUT);
pinMode(cvPin, OUTPUT);
pinMode(modwheel, OUTPUT);   //** mod wheel as output
pinMode(statusLED, OUTPUT);
pinMode(midiEnable, OUTPUT);
Serial.begin(31250);
digitalWrite(midiEnable, HIGH);
}

void loop() {
readMIDI();
}


// play a note out to cv
void note(byte note, byte velocity){
analogWrite(cvPin, notes[note-9]);
if(velocity == 0) {
  digitalWrite(gatePin, LOW);
} else {
  digitalWrite(gatePin, HIGH);
}
}

void mod (byte mod, byte velocity) {  //** modulate function
analogWrite(modwheel, mods[mod-9]);   //** modulate function
}

void blink(int repeat) {
for(int i=0; i<repeat; i++) {
  digitalWrite(statusLED, HIGH);
  delay(5);
  digitalWrite(statusLED, LOW);
  delay(1);
}
}

void readMIDI() {
byte incomingMessage[] = {0,0,0};
byte incomingByte = 0;

if(Serial.available() > 0) {
  incomingByte = Serial.read();
  delay(3);  
  if(incomingByte >= 240) {
    readSystem(incomingByte);
  } else {
    incomingMessage[0] = incomingByte;
  }
  if(Serial.available() > 0) {
    incomingByte = Serial.read();
    if(incomingByte >= 240) {
      readSystem(incomingByte);
    } else {
      incomingMessage[1] = incomingByte;
    }
    if(Serial.available() > 0) {
      incomingByte = Serial.read();
      if(incomingByte >= 240) {
        readSystem(incomingByte);
      } else {
        incomingMessage[2] = incomingByte;
      }
    }
  }
}

processMIDI(incomingMessage);
}

void readSystem(byte incomingByte) {
byte incomingMessage[] = {0,0,0};


incomingMessage[0] = incomingByte;
if(Serial.available() > 0) {
  incomingMessage[1] = Serial.read();
  if(Serial.available() > 0) {
    incomingMessage[2] = Serial.read();
  }
}

processMIDI(incomingMessage);
}

void processMIDI(byte incomingMessage[]) {
switch(incomingMessage[0]) {
  case B10010000:  // Note on, channel 1
    note(incomingMessage[1], incomingMessage[2]);
    break;
  case B10000000:  // Note off, channel 1
    note(incomingMessage[1], 0);
    break;
   case B00100001:  //**mod wheel
     mod (incomingMessage[1], incomingMessage[2]);
     break;
  
  case B11111000:  // Time code
    tempo++;
    if(tempo == 24) {
      blink(1);
      tempo = 0;
    }
    break;
}
}
My Additions are noted with **.     So as you can see... not very original.   Its really just a guess.  I am trying to copy the pitch cv  functons  but have it correspond to the mod wheel.  I was thinking that I only have to add a few  lines to the MIDI processing to read the mod wheel and then another, above,  to calculate the modulation steps and send  pulses out.
Is the the correct approach?
  It doesent seem to work, but there could be any number of problems. I thought that the mod" void mod" commands should have been with void note, but it wouldnt let be declare another variable (byte mod) in the scope.   Also I am not sure if I have the right mod wheel message listed in the MIDI processing.    01 is the Mod wheel for midi in, but is different for out... or (more likely) am I totally wrong and need to take another approach
Logged

0
Offline Offline
Full Member
***
Karma: 0
Posts: 111
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I looked at this, but I can't read code before I've had my coffee.  Are you using running status here?  That is the trick for things like mod wheels; you send the complete MIDI command only once, and then just keep updating the status byte.
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 75
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks nomuse.....     Sorry, total novice here.  Running status? ... Im not sure what that is exactly,  but I dont think Im doing it.        So in the case of this code, where should the running status line appear and do you have an example?  

« Last Edit: February 24, 2010, 06:28:21 pm by Charbot » Logged

0
Offline Offline
Full Member
***
Karma: 0
Posts: 111
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Here's the clearest explanation I was able to find in a quick search:

http://www.csie.ntu.edu.tw/~r92092/ref/midi/midi_messages.html
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 75
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks.   I found that one too.   So I get  get what running status is but not how to do it.  This is a little confusing because the sketch Im starting with list binary values and most of the  other midi progams and tutorials use hexadecimal.  Can I use both?   ....I guess Ill keep searching. 
« Last Edit: February 24, 2010, 07:41:57 pm by Charbot » Logged

Pages: 1 2 3 [4]   Go Up
Jump to: