Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 10 of 10

Thread: Midi clock signals

  1. #1
    Junior Member
    Join Date
    Oct 2014
    Posts
    5

    Midi clock signals

    Hello. First I want to say cheers for a great product. And also I hope I am writing in the right place. I was looking at a way of syncing my gameboy with music production software through midi. I am not sure if I am missing something but it seems not possible to read all bytes of the midi message. From what I can see the first byte is hidden by the usbMIDI.getType() function and usbMIDI.getChannel(). Is there a simple way of getting around this? Is there a way of hacking the source of the midi library?

    I hope I am just being stupid here.. Also I am using teensy 2.0 if that makes any difference.

    Thanks

    ERik

  2. #2
    Member
    Join Date
    Nov 2012
    Location
    Olympia, WA
    Posts
    56
    OK you are in the right place, BUT have to clarify a bit your exact layout and what you want it to do if you want specific help. Also at least give us a little source code (see message IN RED above).

    BUT FIRST I would direct your attention to a post on the amazing Little Scale blog.

    http://little-scale.blogspot.com/201...nc-for-16.html <--has code, circuits

    Is that what you are looking for, or is it perhaps what you are working from?

    Hope that helps.

  3. #3
    Junior Member
    Join Date
    Oct 2014
    Posts
    5
    Sorry. I guess I wasn't clear enough. I am using teensy 2.0 in usb midi mode. A midi message normally consist of three bytes. From what I can see I can read the second and the third byte with usbMIDI.getData1() and usbMIDI.getData2(). But there seems to be no way of reading the first byte of the midi message. The only way to access parts of the first byte is through usbMIDI.getType() and usbMIDI.getChannel(). But these preset types does not cover the standard for midi clock signals.

    Hope that clears it up.

    [EDIT]I don't know if there is another documentation but I was using this page as information, https://www.pjrc.com/teensy/td_midi.html.[/EDIT]

    Thanks

    ERik
    Last edited by humbleTUNE; 10-26-2014 at 04:14 PM.

  4. #4
    Junior Member
    Join Date
    Oct 2014
    Posts
    5
    Ok, I found the source now inside the arduino folders. So that should mean that I can hack the usbMidi library.

    Cheers.

    ERik

  5. #5
    Member
    Join Date
    Nov 2012
    Location
    Olympia, WA
    Posts
    56
    Quote Originally Posted by humbleTUNE View Post
    Sorry. I guess I wasn't clear enough. I am using teensy 2.0 in usb midi mode. A midi message normally consist of three bytes. From what I can see I can read the second and the third byte with usbMIDI.getData1() and usbMIDI.getData2(). But there seems to be no way of reading the first byte of the midi message. The only way to access parts of the first byte is through usbMIDI.getType() and usbMIDI.getChannel(). But these preset types does not cover the standard for midi clock signals.

    Hope that clears it up.

    [EDIT]I don't know if there is another documentation but I was using this page as information, https://www.pjrc.com/teensy/td_midi.html.[/EDIT]
    You are right, that page does not mention clock. It can be a little confusing with THREE official arduino MIDI library versions, all kinds of hacked versions out there, and USB thrown in the mix.

    I don't know what the current status is, but if you look at the page I pointed you to, it says, "If you would like to edit the source code, you need to update the Teensyduino core to include MIDI Beat Clock messages. See here for more information."

    Where here is:
    http://little-scale.blogspot.com/201...midi-beat.html

    Give that a shot? There's code to blink an LED in time with MIDI clock, so modifying and testing this simple case should take less time than lunch.

  6. #6
    Junior Member
    Join Date
    Oct 2014
    Posts
    5
    Thanks. I think I will hack the library. I mean I can already read the type of the clock message (as type 8), just not differentiate between the different clock messages. With this cheat just classing everything which is not one of the 7 defined types, as a clock tick, the gameboy syncs fine already. It is just not very neat.

    Thanks

    ERik

  7. #7
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,115
    Quote Originally Posted by humbleTUNE View Post
    Thanks. I think I will hack the library. I mean I can already read the type of the clock message (as type 8), just not differentiate between the different clock messages.
    Let me know what you come up with?

    The functions available today are a hybrid of the MIDI v2.6 library from Francois Best and callbacks from another MIDI library, but without C++ subclassing, which were later adopted into MIDI v3.2.

    Perhaps more functions should be added for Teensyduino 1.21 or later? I'm certainly willing to add more... it's simply not been a high priority because most projects have only needed the basic functions. If possible, I'd like to keep Teensyduino's USB MIDI functions similar to Francois's MIDI library, which is now at version 4.2.

  8. #8
    Junior Member
    Join Date
    Oct 2014
    Posts
    5
    Hi Paul. I think you are right that midi clock is not the most common of midi messages. I definitely do not use them everyday anyway. I didn't look that far into the source files but instead used the little scale implementation linked by drjohn. It seems very good to me. It properly implements a callback function for the clock messages which gives me the byte I wanted to read.

    Cheers guy for the help. Really appreciate it.

    ERik

  9. #9
    Junior Member
    Join Date
    Apr 2013
    Posts
    4
    Looking at the code on github the functionality has apparently been added: https://github.com/PaulStoffregen/co...RealTimeSystem, but it would be great to update the documentation (I spent quite some time looking for this and assumed I would have to hack the library).

    It's true that midi clock messages are not the most commonly used ones, but they do open up quite a few possibilities. I have a foot controller powered by a teensy 2.0 that I use to control a sequencer on my computer while playing with my band on stage. Having a led light up with the tempo directly on the controller makes it possible to not always have the drummer (with the in-ear click) give the tempo at the beginning of a song. I'm also building a synth with the audio board, it would be very nice to have an arpeggiator that is synchronised with the rest.

    Thank you for all these cool tools, it's amazing what they enable!

  10. #10
    Junior Member
    Join Date
    Oct 2012
    Posts
    16

    USBMIDI Clock slave (fixed) Pass Realtime byte to usbMIDI.getData1()

    I would like to chime in on the USB MIDI Clock issue. I have to say they are a very important part of MIDI.
    I use them every day and whenever I use MIDI.
    Drum machines, Arpeggiators and sequencers all use them. Not all will slave. Teensy will!

    I have been patching teensyduino with the following in cores/teensy3/usb_midi.c

    Code:
    if (type1 == 0x0F) {
    		// TODO: does this need to be a full MIDI parser?
    		// What software actually uses this message type in practice?
    		if (usb_midi_msg_sysex_len > 0) {
    			// From David Sorlien, dsorlien at gmail.com, http://axe4live.wordpress.com
    			// OSX sometimes uses Single Byte Unparsed to
    			// send bytes in the middle of a SYSEX message.
    			sysex_byte(n >> 8);
    		} else {
    			// From Sebastian Tomczak, seb.tomczak at gmail.com
    			// http://little-scale.blogspot.com/2011/08/usb-midi-game-boy-sync-for-16.html
    			usb_midi_msg_type = 8;
    			if (usb_midi_handleRealTimeSystem)
                    (*usb_midi_handleRealTimeSystem)(n >> 8);
                //goto return_message;
                // From viclabs 3/12/2016 Pass Realtime byte back to usbMIDI.getData1();
                usb_midi_msg_channel = ch;
                usb_midi_msg_data1 = (n >> 8);
                return 1;
    	}
    }
    I have only changed from the viclabs comment.
    Use like this

    Code:
      if (usbMIDI.read()) {
        type = usbMIDI.getType();
        d1 = usbMIDI.getData1();
        d2 = usbMIDI.getData2();
        dd = d1 + (d2 << 8);
        chnl = usbMIDI.getChannel();
    
        switch (type) {
          case 1:
            midiA.sendNoteOn(d1, d2, chnl);
            break;
          case 0:
            midiA.sendNoteOff(d1, d2, chnl);
            break;
          case 2:
            midiA.sendPolyPressure(d1, d2, chnl);
            break;
          case 3:
             midiA.sendControlChange(d1, d2, chnl);
            break;
          case 4:
            midiA.sendProgramChange(dd, chnl);
            break;
          case 5:
            midiA.sendAfterTouch(dd, chnl);
            break;
          case 6:
            midiA.sendPitchBend(dd, chnl);
            break;
          case 7:
             byte *  mySysExArray;
            mySysExArray = usbMIDI.getSysExArray();
            break;
          case 8:
            midiA.sendRealTime((midi::MidiType)d1);
            if (hasDinSync) {
              switch (d1) {
                case START:
                  midiA.sendRealTime(midi::Start);
                  break;
                case STOP:
                  midiA.sendRealTime(midi::Stop);
                  break;
                case CONTINUE:
                  midiA.sendRealTime(midi::Continue);
                  break;
                case CLOCK:
                  midiA.sendRealTime(midi::Clock);
              }
            }
            break;
          default:
            break;
        }
      }
    I also found that to be quick enough for the clock it pays to not use callbacks.

    This will enable the teensy to follow USBMIDI clock.
    I use it to drive a TR-909, Quicksilver Devilfish, and TB-303.
    Din Sync, MIDI Clock and USBMIDI Clock out all from Teensy LC which is a USBMIDI Clock Slave.

    I could use some direction about the right way to do this change via github. I have never done a pull request before but would be keen to know the right way to go about merging fixes so they get to the whole community. Apologies if there is already a post with this question.

    Just post here is you need this for Teensy 2. The same change needs to be put in a different folder in cores, maybe with a different name from memory. I have got it working and will post on request.

    Hope this helps

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •