arduino_midi_library icon indicating copy to clipboard operation
arduino_midi_library copied to clipboard

sendTimeCodeQuarterFrame() documentation request

Open scottc11 opened this issue 5 years ago • 3 comments

Would someone mind sharing an example on how to use the sendTimeCodeQuarterFrame() function? It is unclear to me what the DataByte parameter should be equal to.

I assumed just calling this function (with no parameters) would send 24 PPQ's but that isn't an option, so instead I passed the MIDI Clock byte 0xF8 and executed the function 24 times???

void setup() {
  // DIGITAL PIN 3 is used for detecting tempo.
  attachInterrupt(digitalPinToInterrupt(3), sendClockPulse, FALLING); // when input goes low, send pulse
}

void sendClockPulse() {
  step += 1;
  if (step % 4 == 1) {
    for (size_t i = 0; i < 24; i++) {
        MIDI.sendTimeCodeQuarterFrame(0xF8);
    }
  }
}

This is indeed sending the MIDI clock code to my external device, but is far from keeping anything in sync as is rather erratic.

scottc11 avatar Mar 11 '19 11:03 scottc11

Here's the part of the MIDI specification that relates to MTC QuarterFrame messages: http://www.somascape.org/midi/tech/spec.html#syscommsgs

If you want to keep things synchronized, you will have to use a timer to keep track of internal time (or use millis), and send either Clock messages or MTC Quarter Frames, depending on whether you just want beat sync or absolute time sync.

franky47 avatar Mar 11 '19 12:03 franky47

Here an example for you

https://github.com/alf45tar/PedalinoMini/blob/master/src/MidiTimeCode.cpp

alf45tar avatar Mar 11 '19 19:03 alf45tar

another Example: based on a timer.... the interesting macros are

#define lo_nibble(b) (byte)(b & 0x0F)
#define hi_nibble(b) (byte)((b & 0xF0) >> 4 )

mtconly.zip

The Basic send is :

void sendMTCQuarterMessage()
{
  byte toSend;
  switch (msgCount)
  {
    case 0:
      toSend = 0x00 | lo_nibble(ff);
      break;
    case 1:
      toSend = 0x10 | hi_nibble(ff);
      break;
    case 2:
      toSend = 0x20 | lo_nibble(ss);
      break;
    case 3:
      toSend = 0x30 | hi_nibble(ss);
      break;
    case 4:
      toSend = 0x40 | lo_nibble(mm);
      break;
    case 5:
      toSend = 0x50 | hi_nibble(mm);
      break;
    case 6:
      toSend = 0x60 | lo_nibble(hh);
      break;
    case 7:
      toSend = 0x72 | hi_nibble(hh);  //defaults to 25 ....
      //toSend = 0x70 | hi_nybble(hh) | 0b00100000;   //would be 24
      break;
  }
  MidiPort.write(0xF1);
  MidiPort.write(toSend);
#ifdef USE_USB
  midiEventPacket_t event = {MIDI_COMMAND_SYSEX_2BYTE, 0xF1, toSend, 0};
  MidiUSB.sendMIDI(event);
  MidiUSB.flush();
#endif

  msgCount++;
  if (msgCount > 7) msgCount = 0;

}

Preroll is a special feature for my beloved Fostex D2424, as it does not "start" at 00:00:00:00 but at 23:59:55:17. so if i'd rewind to 00:00:00:00 it would start playback/record at 00:00:05:00....

mink99 avatar Mar 12 '19 10:03 mink99