Jazz-Soft.net
We make it sound!
Home » Documentation » JZZ.js » JZZ.SMPTE

JZZ.SMPTE

JZZ.SMPTE is a helper class to simplify the work with the MIDI Time Code (MTC).

It takes care of frame-drops, generating and reading the full-frame sysex messages, generating and reading the quarter-frame MIDI messages in forvard and reverse directions.

Construction

JZZ.SMPTE() constructor works with or without the new keyword.

It takes a comma-separated list or an array of the following parameters: type, hour, minute, second, frame, quarter, where

type - SMPTE type (frames per second); can be 24 (24 fps, default), 25 (25 fps), 30 (30 fps), or 29.97 (30 fps, drop-frame).

hour, minute, second, frame - time from hours to fractions of second; omitted parameters will be set to zero.

quarter - the frame quarter number; from 0 (default) to 7 sic!. Used to generate the quarter-frame MIDI Time Code messages.

Constructor can also take another JZZ.SMPTE object to create its copy.

Example

// the following code creates 4 identical SMPTE objects: 07:40:00:00, 30 fps, drop-frame
var smpte0 = new JZZ.SMPTE(29.97, 7, 40);       // using the "new" keyword
var smpte1 = JZZ.SMPTE(29.97, 7, 40);           // not using the "new" keyword
var smpte2 = JZZ.SMPTE([29.97, 7, 40]);         // take an array as the argument
var smpte3 = JZZ.SMPTE(smpte1);                 // take another object as the argument

toString()

toString() return a string in the form hh:mm:ss:ff.

NOTE: in most JavaScript realizations, console.log() does not automatically call this function.

Data access

isFullFrame() - return true if it's a beginning of a new SMPTE frame, or false otherwise. A useful check if you want to emit a SMPTE clock event.

getType(), getHour(), getMinute(), getSecond(), getFrame(), getQuarter() - return the object's type, hour, minute, second, frame, quarter respectively.

setType(tt), setHour(hh), setMinute(mm), setSecond(ss), setFrame(ff), setQuarter(qq) - set the object's type, hour, minute, second, frame, quarter.

reset(...) - takes exactly the same parameters as the constructor above and sets all object fields accordingly.

incrFrame() - increase the time by one SMPTE frame.

decrFrame() - decrease the time by one SMPTE frame.

incrQF() - increase the time by a quarter-frame.

decrQF() - decrease the time by a quarter-frame.

Functions set***(), reset(), incr***(), decr***() return this, and, therefore, can be chained, e.g.: smpte.reset().setSecond(5).incrQF();.

Generating the MIDI Time Code (MTC) messages

The following JZZ.MIDI helpers produce MTC-related MIDI messages from a JZZ.SMPTE input:

JZZ.MIDI.mtc(smpte) creates a quarter-frame MIDI message.

JZZ.MIDI.sxFullFrame(smpte) creates a full-frame MIDI SysEx message. (Make sure the SysEx messages are enabled!)

Reading the MIDI Time Code messages

read(msg) - read the quarter-frame or full-frame message and update the object accordingly. Returns true if that was a MIDI Time Code message, or false otherwise.

Example

This example demonstrates how the slave clock picks up the current time from the master clock.

var master = JZZ.SMPTE();                // master clock
var slave = JZZ.SMPTE();                 // slave clock
var sender = JZZ.Widget();               // sending port
var receiver = JZZ.Widget();             // receiving port
receiver._receive = function(msg) {
  if (slave.read(msg))                   // print and consume the MTC messages
    console.log(master.toString(), ' ==> ', msg.toString(), ' ==> ', slave.toString());
  else _emit(msg);                       // forward all other MIDI messages
};
sender.connect(receiver);
master.reset(24, 7, 39, 59);             // 7:40 it arrives...
for (var n = 0; n < 25; n++) {
  sender.mtc(master);
  master.incrQF();
}

It takes the full cycle of eight quarter-frames to get the clocks synchronized:

07:39:59:00  ==>  f1 00 -- MIDI Time Code  ==>  00:00:00:00
07:39:59:00  ==>  f1 10 -- MIDI Time Code  ==>  00:00:00:00
07:39:59:00  ==>  f1 2b -- MIDI Time Code  ==>  00:00:00:00
07:39:59:00  ==>  f1 33 -- MIDI Time Code  ==>  00:00:00:00
07:39:59:01  ==>  f1 47 -- MIDI Time Code  ==>  00:00:00:01
07:39:59:01  ==>  f1 52 -- MIDI Time Code  ==>  00:00:00:01
07:39:59:01  ==>  f1 67 -- MIDI Time Code  ==>  00:00:00:01
07:39:59:01  ==>  f1 70 -- MIDI Time Code  ==>  00:00:00:01
07:39:59:02  ==>  f1 02 -- MIDI Time Code  ==>  07:39:59:02
07:39:59:02  ==>  f1 10 -- MIDI Time Code  ==>  07:39:59:02
07:39:59:02  ==>  f1 2b -- MIDI Time Code  ==>  07:39:59:02
07:39:59:02  ==>  f1 33 -- MIDI Time Code  ==>  07:39:59:02
07:39:59:03  ==>  f1 47 -- MIDI Time Code  ==>  07:39:59:03
07:39:59:03  ==>  f1 52 -- MIDI Time Code  ==>  07:39:59:03
07:39:59:03  ==>  f1 67 -- MIDI Time Code  ==>  07:39:59:03
07:39:59:03  ==>  f1 70 -- MIDI Time Code  ==>  07:39:59:03
07:39:59:04  ==>  f1 04 -- MIDI Time Code  ==>  07:39:59:04
07:39:59:04  ==>  f1 10 -- MIDI Time Code  ==>  07:39:59:04
07:39:59:04  ==>  f1 2b -- MIDI Time Code  ==>  07:39:59:04
07:39:59:04  ==>  f1 33 -- MIDI Time Code  ==>  07:39:59:04
07:39:59:05  ==>  f1 47 -- MIDI Time Code  ==>  07:39:59:05
07:39:59:05  ==>  f1 52 -- MIDI Time Code  ==>  07:39:59:05
07:39:59:05  ==>  f1 67 -- MIDI Time Code  ==>  07:39:59:05
07:39:59:05  ==>  f1 70 -- MIDI Time Code  ==>  07:39:59:05
07:39:59:06  ==>  f1 06 -- MIDI Time Code  ==>  07:39:59:06

NOTE: sender and receiver in the above example are used just for illustration.

Instead of sender.mtc(master);, one could equally well write receiver.mtc(master); or slave.read(JZZ.MIDI.mtc(master));.

See also