ttymidi - software for MIDI-through-USB for Linux

Shameless plug. I just wrote this. I thought some of you might need it. Let me know how it works for you.

Wow, that looks awesome.

One silly question: how do you provide a MIDI input to other programs on the computer? That is, what does it mean to define a MIDI endpoint (if that's the right terminology)? Or, rather, what's ALSA MIDI?

Also, I added a link to ttymidi to the MIDI section of communication section of the interfacing with hardware page on the playground. There's a link there for a similar program for the Mac.

Yes, it's ALSA MIDI, so it will work with all major programs. The page I linked has some more info about how it works and such.

I'm glad you liked it :slight_smile:

Great, I was looking for something like that for a while now.

I'll give it a try.

Nicolas

Oh, now I understand your question. Well, ALSA is the most-used Linux sound system. Even when you use JACK or whatever, the MIDI part is generally still handled by ALSA. So this means that most Linux MIDI-compatible programs will be interfaceable with ttymidi.

Awesome.

I tried it (ubuntu FF) .
Great !!!

FYI (and future release) : I noticed a tipo in the README/COMPILE (not a big deal)
You mean apt-get install libasound2-dev when you say apt-get install libasound-dev

Thank U for that (including the doc)

Did you try it in real time with a master midi keyboard ?

Nicolas

Thanks for catching that typo. I'll fix the file in a bit.

Did you try it in real time with a master midi keyboard ?

I used it in real time before, but not with a master midi keyboard.

Hi! I’ve recently seen this project and i think it’s awesome. I post here because I have some problems with ttymidi.

I’ve done some changes to ardumidi_test.pde to check how other instruments sound (apart from piano):

/*
  This file is public domain. Use it as you like.
*/

#include <ardumidi.h>

int ledPin = 13;
int note_on = 0;
byte [glow]count[/glow] = 0;

void setup()
{
  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);
}

void loop()
{
  if (!note_on)
  {
    [glow]midi_program_change(0, count);    //Change instrument
    count++;                                     //in each note[/glow]
      // play a Cminor chord on channel 0, at maximum volume (127)
    midi_note_on(0, MIDI_C, 127);
    midi_note_on(0, MIDI_E + MIDI_FLAT + MIDI_OCTAVE, 127);
    midi_note_on(0, MIDI_G + MIDI_OCTAVE, 127);

      // The MIDI_* macros were created to make your life easier, but you
      // don't have to use them. You may enter numbers instead if you know
      // what you're doing.

    note_on = 1;
    digitalWrite(ledPin, HIGH);
  }

  else
  {
      // stop the Cminor chord
    midi_note_off(0, MIDI_C, 127);
    midi_note_off(0, MIDI_E + MIDI_FLAT + MIDI_OCTAVE, 127);
    midi_note_off(0, MIDI_G + MIDI_OCTAVE, 127);

    note_on = 0;
    digitalWrite(ledPin, LOW);
  }
  
  delay(500);
}

Then I use ttymidi and timidity as shown in your web, but I only hear some instruments, not all. Some of them don’t work, like 116 and 117 (and many others). I don’t know if i’m doing something bad or is a problem of the program, but cheking instruments one by one gives me the same result.

I’m using arduino-0012 in a kubuntu 8.10.

Thank you very much for your help, and excuse me for my english, i’m kind of a rookie :-[

I forgot that to compile the sketchbook, i had to fix some problems with stdlib.h as shown in the first reply to this topic: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1222985221/2

I don't know if it could be a problem

Here is a quick sketch I did that makes your Danger Shield into a musical instrument… sort of… it’s about as useful as a thermin for making music Button 1 on the Danger shield starts the note slider 3 is the value of the note musical note slider 2 to is velocity of note slider 1 is pitch bend not really working as intended but hey this sketch is quick dirty… please improve on it if you have any good ideas on how to make the danger shield into a better musical instrument… :wink:
the next sketch I’m going to attempt with ttymidi is to use the danger shield as a midi control surface for SooperLooper see if we can get some Monome like functionality out of the Danger Shield :sunglasses: I have a idea about using one of the Danger shield buttons as a mode selector and using the 7seg led display to feedback what mode we are in kinda like the Korg Kaossilator that way where not stuck with changing just three control values with the sliders then maybe using the knock sensor to tap in Tempo BPM & leds above knock sensor to flash back playback BPM does this sound useful at all??? or are all you guys happy with the sound slider example using the buzzer? ;D

// Danger Board v1.0 ttymidi MIDI-through-USB for 
// linux using the Danger Shield v1.0
// By: Brian Lightfoot (brianlightfoot@gmail.com)
// More info: http://make.nycresistor.com/ds-1.0 
// http://www.varal.org/ttymidi/

//our setup stuff
#include "_init.h"
//ttymidi include
#include <ardumidi.h>

void setup()
{
  ds_init();
}
// setup our varables here 
int note_on = 0;
int slider1_value = 0;
byte slider2_value = 0;
byte slider3_value = 0;
boolean button1_state = false;
boolean button2_state = false;
boolean button3_state = false;
boolean last_button1_state = false;
boolean last_button2_state = false;
boolean last_button3_state = false;

void loop()
{
   //read all our slider values & button states.
  slider1_value = analogRead(SLIDER1_PIN) * 17;
  slider2_value = analogRead(SLIDER2_PIN) / 8;
  slider3_value = analogRead(SLIDER3_PIN) / 8;
  button1_state = digitalRead(BUTTON1_PIN);
  button2_state = digitalRead(BUTTON2_PIN);
  button3_state = digitalRead(BUTTON3_PIN);

  //Play note if button is pressed slider3 is value of note slider to is velocity of note 
  if (button1_state && !last_button1_state)
  {
    delay(100);
    midi_note_on(0, slider3_value, slider2_value);
    note_on = 1;

    
  }
  // turn of note if slider3 was moved must hold button down and sweep slider3 back across 
  // to turn note off 
  else if (button2_state && !last_button2_state) 
  {
    // turn off notes when slider pot is in same position or when sweeped back 
    //across value need to change this.... to somthing more functional
    midi_note_off(0, slider3_value, slider2_value);
    note_on = 0;
  }


  //write values directly to our leds for led brightness.
  midi_pitch_bend(0, slider1_value);
  analogWrite(SLIDER1_LED_PIN, slider1_value);
  analogWrite(SLIDER2_LED_PIN, slider2_value);
  analogWrite(SLIDER3_LED_PIN, slider3_value);
}

Here is a posting of more unfinished but working code of a Danger Shield midi control surface for Linux that I’m making using ttymidi. Was changing pitch & other effect values in TerminatorX I was also scratching loops with the sliders… Feedback would be great… :smiley:

// Danger Board v1.0 ttymidi MIDI-through-USB for 
// linux using the Danger Shield v1.0
// By: Brian Lightfoot (brianlightfoot@gmail.com)
// More info: http://make.nycresistor.com/ds-1.0 
// http://www.varal.org/ttymidi/

//our setup stuff
#include "_init.h"
//ttymidi include
#include <ardumidi.h>

void setup()
{
  ds_init();
}
// setup our varables here 
int modecount = 0;
int note_on = 0;
int seg = 255;
int slider1_value = 0;
byte slider2_value = 0;
byte slider3_value = 0;
boolean button1_state = false;
boolean button2_state = false;
boolean button3_state = false;
boolean last_button1_state = false;
boolean last_button2_state = false;
boolean last_button3_state = false;

void loop()
{
  //in this while loop we have instrument mode
  while(modecount == 0) 
{
  // Show mode on 7-segment
  // change this to usefull output in the future int seg above is value 
  digitalWrite(LATCH_PIN, 0);
  shiftOut(DATA_PIN, CLOCK_PIN, LSBFIRST, seg);
  digitalWrite(LATCH_PIN, 1);
  
  //read all our slider values & button states.
  slider1_value = analogRead(SLIDER1_PIN) * 17;
  slider2_value = analogRead(SLIDER2_PIN) / 8;
  slider3_value = analogRead(SLIDER3_PIN) / 8;
  button1_state = digitalRead(BUTTON1_PIN);
  button2_state = digitalRead(BUTTON2_PIN);
  button3_state = digitalRead(BUTTON3_PIN);

  //Play note if button is pressed slider3 is value of note slider to is velocity of note 
  if (button1_state && !last_button1_state)
  {
    delay(100);
    midi_note_on(0, slider3_value, slider2_value);
    note_on = 1;
  }
  
  // turn of note if slider3 was moved must hold button down and sweep slider3 back across 
  // to turn note off 
  if (button2_state && !last_button2_state) 
  {
    // turn off notes when slider pot is in same position or when sweeped back 
    //across value need to change this.... to somthing more functional   
    midi_note_off(0, slider3_value, slider2_value);
    note_on = 0;
  }
  //Change the mode if button 3 pressed break the while loop 
  if (button3_state && !last_button3_state)
  {
  modecount++;
  }

  //write values directly to our leds for led brightness.
  analogWrite(SLIDER1_LED_PIN, slider1_value);
  analogWrite(SLIDER2_LED_PIN, slider2_value);
  analogWrite(SLIDER3_LED_PIN, slider3_value);
}
  
  // this while loop is controller mode 
  while(modecount == 1) {
  
  //read all our slider values & button states.
  slider1_value = analogRead(SLIDER1_PIN) * 17;
  slider2_value = analogRead(SLIDER2_PIN) / 8;
  slider3_value = analogRead(SLIDER3_PIN) / 8;
  button1_state = digitalRead(BUTTON1_PIN);
  button2_state = digitalRead(BUTTON2_PIN);
  button3_state = digitalRead(BUTTON3_PIN);
  
  seg = 254;
  digitalWrite(LATCH_PIN, 0);
  shiftOut(DATA_PIN, CLOCK_PIN, LSBFIRST, slider3_value);
  digitalWrite(LATCH_PIN, 1);
  
  if (button1_state && !last_button1_state)
  //slider 3 controls the byte for what controller is used this is going to change to a button press in the near future just testing code here :D
  //slider 2 controls the value of the control used 
  {
    midi_controller_change(0, slider3_value, slider2_value);
    note_on = 1;
  }
  
  //Change the mode if button 3 pressed break the while loop 
  if (button3_state && !last_button3_state)
  {
  modecount--;
  }
  analogWrite(SLIDER1_LED_PIN, slider1_value);
  analogWrite(SLIDER2_LED_PIN, slider2_value);
  analogWrite(SLIDER3_LED_PIN, slider3_value);

}
 
}

Iam also have problem whwn make compiling in terminal
p:/home/inot/Dokumen/ttymidi# # list available MIDI output clients
root@inot-desktop:/home/inot/Dokumen/ttymidi# aconnect -o
client 14: 'Midi Through' [type=kernel]
0 'Midi Through Port-0'
client 16: 'Ensoniq AudioPCI' [type=kernel]
0 'ES1371 '
client 128: 'TiMidity' [type=user]
0 'TiMidity port 0 '
1 'TiMidity port 1 '
2 'TiMidity port 2 '
3 'TiMidity port 3 '
client 129: 'TiMidity' [type=user]
0 'TiMidity port 0 '
1 'TiMidity port 1 '
2 'TiMidity port 2 '
3 'TiMidity port 3 '
client 130: 'TiMidity' [type=user]
0 'TiMidity port 0 '
1 'TiMidity port 1 '
2 'TiMidity port 2 '
3 'TiMidity port 3 '
client 136: 'TiMidity' [type=user]
0 'TiMidity port 0 '
1 'TiMidity port 1 '
2 'TiMidity port 2 '
3 'TiMidity port 3 '

bolloyo: strange... I will check it out and get back to you.

tony: that's not how you compile it. As described in the file called README, you should compile with

gcc ttymidi.c -o ttymidi -lasound

So, I went on and made a project page at launchpad. You can post bugs there from now on.

https://launchpad.net/ttymidi

Hello, well, I tried reporting a bug on launchpad, but I’m getting “ttymidi doesn’t use launchpad as it’s bug tracker”, so in the meanwhile I’ll report here.

I had ttymidi working ok some months ago on my laptop with Ubuntu + arduino. Now I moved to Archlinux and I’m getting strange behaviour. The ardumidi_test the other day worked sometimes yes others no, today I can’t get it at all working. It’s strange: it compiles, it uploads, and the led blinks correctly (If I change the delay time I see the led blinking accordingly).
Then I run from the source ttymidi directory:
./ttymidi -s /dev/ttyUSB0
and then I connect, in Qjackctl, the out of ttymidi to amSynth. As said, sometimes it will work and I’ll here the sound, others it just won’t. All the times the synth is working correctly, I’m testing it with vkeybd (a virtual keyboard program).

This is really strange and I am sorry/frustrated I can’t get any more details. Could I get some significant output of ttymidi?

Could this somehow be related to udev? (Just guessing)

Also, this may be known and not related to my problem, I noticed that while ttymidi is running, I get an avrdude error if I try uploading another sketch on arduino; I have first to quit ttymidi.

Renato

Hi Nareto. I have fixed the problem with Launchpad. Thanks for reporting it. Now, about your problem:

  1. Try installing the default ardumidi sketch, then running ttymidi with your usual settings (something like ttymidi -s /dev/ttyUSB0 -b 115200) and also add the -v argument for verbose output. This should print something like:

$ ttymidi -s /dev/ttyUSB0 -b 115200 -v
0x90 Note on 000 060 127
0x90 Note on 000 075 127
0x90 Note on 000 079 127
0x80 Note off 000 060 127
0x80 Note off 000 075 127
0x80 Note off 000 079 127
0x90 Note on 000 060 127
0x90 Note on 000 075 127
0x90 Note on 000 079 127
...etc...

If you don't see this, then there's a bug either in the arduino code or in serial part of ttymidi. (This could also mean there's a problem with your arduino or serial port.) So let me know if you don't see the output above so I can run some more tests.

  1. If you see the messages above, then there could be a bug in the midi part of ttymidi, or maybe something wrong with your setup. Try this:
  • download and run the program called "QSynth". This is the only program I know of that reports when it receives midi input, so this is what I use to debug.
  • Connect QSynth to ttymidi (either using qjackctl or whatever other method you prefer).
  • The black orb icon next to the plus sign at the bottom of QSynth should start blinking, indicating that it is receiving midi messages from ttymidi.

If you see the blinking, then ttymidi is working properly and the problem is somewhere else. Otherwise, make sure other midi programs are communicating correctly by connecting them to QSynth and verifying that the orb blinks for them.

Also, only now did I get around to checking bolloyo's bug report (from earlier in the thread).

@bolloyo
All programs (instruments) work fine on my side. I just tested them.

Hello tvst. I'm not getting that output at point 1. I compiled the ardumidi_test.pde file present in the sources, uploaded it on the arduino and ran exactly
./ttymidi -s /dev/ttyUSB0 -b 115200 -v
and I'm getting no output at all. I tried it on different usb ports on the pc, same result.
I have to admit I don't quite know what the baud rate is, but I could have messed with that with other sketches... Anyways to my understanding the ardumidi_test.pde is setting the baud rate to 115200 so: 1 that should override previous settings on the arduino and 2 the -b 115200 option in the command should be right..

If it is the Arduino having some part damaged, how could I find out? Thanks for the help

Try this:

  1. Run the Arduino programmer app on the PC
  2. Install the default Ardumidi sketch
  3. Click on the "serial monitor" icon
  4. Do you see some crazy characters coming in at the bottom of the window? (seeing crazy characters is the correct behavior, since the Ardumidi sketch sends out binary numbers that do not translate to ASCII letters or numbers.)

A few other things, just to clarify:

In your previous message you said "If I change the delay time I see the led blinking accordingly". What does that mean? The LEDs should blink once per second using the default Arduino sketch. No changes should be necessary. The LED labeled "TX" always blinks whenever some data is transmitted to the PC.

Can you tell me which Arduino you're using? Is it Diecimila, or some Arduino-compatible clone? Maybe it doesn't support 115200 baudrate?