Teensy 3.1 read Midi from Ableton/have metronome click

Status
Not open for further replies.

321lupo

Active member
Hey everybody!
I am currently working on a midi controller using a teensy 3.1 as teensyduino an accelerometer, an infrared sensors and different LEDs that I want to have light up simultaneously with the midi message coming from ableton live. I have installed a midi send channel in live and am already successfully reading midi messages with the USB.midi PrintIncoming example from the library:

Code:
int ledPin = 13;

void OnNoteOn(byte channel, byte note, byte velocity)
{digitalWrite(ledPin, HIGH);}

void OnNoteOff(byte channel, byte note, byte velocity)
{digitalWrite(ledPin, LOW);}

void setup()
{
  pinMode(ledPin, OUTPUT);
  usbMIDI.setHandleNoteOff(OnNoteOff);
  usbMIDI.setHandleNoteOn(OnNoteOn) ;
  digitalWrite(ledPin, HIGH);
  digitalWrite(ledPin, LOW);
}

void loop()
{
  usbMIDI.read();
}

This seems to work so far, however, is it possible to directly access the click function (the metronome) in ableton?
and to change the bpm variable through the teensy?

i already tried out this: http://little-scale.blogspot.de/2011/08/how-to-deal-with-real-time-midi-beat.html
but so far I have not managed to get it to work..
Is there an updated midi-library for the teensy, which includes a direct midi clock connection?

thank you in advance, all the best!
 
Did you click sync in ableton's midi tab? I'm pretty sure midi sync messages are not sent if only set to track or remote. Also once sync is setup a new button with EXT pops up top left of the main ableton window that turns on and off external sync.
 
Last edited:
hey, yeah it's synced :) what i am wondering is how can i read/write the clock/bpm/metronome variable in teensyduino to be able to change the speed
from the midi controller that i am building? thx forthe quick response btw!

maybe to clarify, on the pjrc page i have only found these readable variables:
usbMIDI.setHandleNoteOff(OnNoteOff)
usbMIDI.setHandleNoteOn(OnNoteOn)
usbMIDI.setHandleVelocityChange(OnVelocityChange)
usbMIDI.setHandleControlChange(OnControlChange)
usbMIDI.setHandleProgramChange(OnProgramChange)
usbMIDI.setHandleAfterTouch(OnAfterTouch)
usbMIDI.setHandlePitchChange(OnPitchChange

would the bpm be simply a control change???
i know i can change it by assigning a midi variable to it, but how can i read the bpm clock or value to make sure that for example a delay between to midion/offs is a 1/4, 1/8 of the ableton bpm?
 
Last edited:
If you send midi sync messages to ableton, it will only use that data to adjust your ableton tempo if the EXT button is visble and enabled in top left. The usb midi library doesn't seem to have tempo change built in, fortunately midi messages are pretty basic and easy to work with in their raw form.

Code:
  while (usbMIDI.read()) {
  }
usbMIDI.getType()
The types are: 0 = Note Off, 1 = Note On, 2 = Velocity Change, 3 = Control Change, 4 = Program Change, 5 = After Touch, 6 = Pitch Bend, 7 = System Exclusive
  usbMIDI.getData1()
  usbMIDI.getData2()
The actual message data can be accessed with getData1 and getData2.
  usbMIDI.getSysExArray()

You'll want to read(), then manually parse the data with getData1() or getData2(), or maybe getType() returns something useful. If you still have trouble I can figure it out for real later today. I believe the standard is 24 messages per quarter note of tempo, so 110bpm would be 110*4*24= 10560 messages per minute or a 176 per second, meaning sending a clock sync message every 5.68ms you would have to consistently send out for ableton to hold 110bpm with external sync enabled. It's a constant feed, it isn't a number you can just tell it to hold on to.

something like
Code:
while (usbMIDI.read()){
 Serial.println(usbMIDI.getData1() + " , " + usbMIDI.getData2());
}
should show you what the message looks like when ableton sends a clock update to your teensy, to do it the other way around just send that same message from the teensy to ableton. I think usbMIDI.sendSysEx(length, array) will work for sending your midi message without tagging it with the wrong type but I could be wrong and we just need a sendRawMessage or sendClockUpdate added to the library.

A great bit of functionality to add to the usbMidi library would be to be able to just set a tempo and sendSync on/off and the it would take care of sending that message all the time for you. I could hack it in but probably not up to the standards of the lib.

A quick hack to make it work would be to use sendPitchbend() because of it's higher resolution and then midi map tempo to it in ableton.
 
Last edited:
hey! i tried out to plug in the code but haven't been able to receive any useful data in the serial monitor, only

Code:
þC°@þC°@þCÀ@
þC°@þC°@þCÀ@
þC°@þC°@þCÀ@
þC°@þC°@þCÀ@
þC°@þC°@þCÀ@
þC°@þC°@þCÀ@

i am still able to receive midi messages from ableton, but only those that i specifically route over the midi tracks to teensy.. no luck with reading/writing the data.
you are right, i could just map it to a pitch or control. i just tried that and it works ok, only problem is the translation of 0-127 values to bpm, but even that can be figured out. however, in the long run this will not be sufficient control i think, since i still cannot read out the bpm, so that, should i use another midi input to change it, the teensy wouldnt be able to follow, etc. also, i dont think it is the most elegant solution for the long term to work around the clock problem instead of addressing it directly. i just started working with arduino a few months ago, so i basically still do not have a clue.. :D but for anybody at pjrc, wouldn't it be good to add clocking to the midi library? from what i can tell many people are buying the teensy specifically to use it as a midi controller, often with ableton, traktor or other programs in which bpm clocking is crucial. though the current library is amazing, maybe it could use another basic usage line? Midi.clockingOn(BPM), for example? this would be so useful to musicians like me who know little about coding!

in any case, ohnoitsanija, thank you very much for your help so far!
 
Normal control change messages are 0-127. Pitch bend messages are 0-16383. To scale your value, use map(value, lowBound, highBound, 0, 16383). As far as your garbage serial data, it could either an incorrect baud rate or you need to typecast the variable getData returns like int(usbMIDI.getData1()) . I'm going to start playing around with getting it to work for real through the usbMidi lib, I've done it before just not on usb.

Code:
elapsedMillis sincePrint;

void setup() {
  Serial.begin(115200);
}

void loop() {
 if (usbMIDI.read())
 {
   Serial.println(10000/(sincePrint*4));
   sincePrint = 0;
 } 
}
Ableton has to be configured to send midi sync to teensy's midi output for this to work.

A very crude hack, but is currently works for picking up ableton's midi sync message and converting it to the current bpm and sending it out serial. This is backwards of what you want but in the right direction. My attempts at using getData1, getData2, and getType were fruitless, I'll have to edit the lib to do any better. I scoured the internets for anyone who has ever sent midi sync out usb on a teensy and I don't think it's ever been done? I couldn't get it to work, help anyone?
 
Last edited:
Status
Not open for further replies.
Back
Top