Free forever·no account, no tracking, no third-party requests ·open data, free API
showstack / learn / timecode
Stage 4 of 7 · The system2 of 3 in this stage14 min read

What is actually in a timecode frame

LTC and MTC both carry hours, minutes, seconds and frames, and they carry them completely differently — one as an audio waveform, one as four bits at a time down a slow serial wire. Here is what the bits are, why drop frame drops nothing, and how to read a MIDI stream in hex.

LTC

Eighty bits, of which twenty-six are the time

Linear timecode is exactly 80 bits per frame, repeated every frame forever. At 30 fps that is 2400 bits per second, which is the whole design constraint: it has to fit down an analogue audio track, so it has to sound like audio and survive everything that happens to audio.

Of those 80 bits, 26 are the time. The rest is 32 user bits — free space, often carrying a date or a reel number and very often carrying nothing — six flag bits, and a 16-bit sync word. Two of the flags are named and useful: bit 10 says whether this is drop frame, bit 11 is the colour frame flag. The other four carry binary group flags and a polarity correction bit whose assignment differs between 25 and 30 frame systems and between revisions of SMPTE 12M, so they are left unlabelled here rather than asserted.

The time is stored as BCD: binary-coded decimal, each decimal digit in its own little field, least significant bit first. That is why the field widths look arbitrary until you think about what each digit has to count to. Frame tens only ever reaches 2, so it gets two bits. Second tens reaches 5, so it gets three. Hour tens reaches 2, so two bits again. And it is why you can read the digits straight out of a bit dump without dividing anything.

time (26 bits) user bits (32) flags (6) sync word (16)
rule
The sync word is 0011111111111101, and its twelve consecutive ones cannot occur anywhere else in the frame. That is how a reader finds the frame boundary — and because the word is not a palindrome, whether it arrives forwards or backwards also tells the reader which way the tape is moving.

Why it sounds like that

Biphase mark, and reading tape backwards

LTC is encoded biphase mark, which is the reason a timecode track sounds like an angry fax machine and the reason it works at all.

The rule is two lines long. There is a transition at every bit boundary, always. A one gets one extra transition in the middle of the bit; a zero does not. Everything useful follows: the guaranteed boundary transition is a clock, so no separate clock line is needed. There is no DC component, so it passes through the transformers and capacitors in an audio path. Inverting the whole signal changes nothing, so a swapped pair does not matter. And a one is always twice the frequency of a zero, so the decoder works over a wide range of speeds — which is what lets an editor read timecode while shuttling at a third of play speed, or backwards.

This is the same family of ideas as every other self-clocking line code. How a one gets down a wire has the wider set; LTC is the one that had to survive being recorded on quarter-inch tape.

MTC

The same time, four bits at a time

MIDI runs at 31 250 baud, which by modern standards is nothing. Sending a whole timecode value every frame as a system exclusive message would eat a significant slice of the wire, so MTC does something else: it sends quarter-frame messages, two bytes each, four times per frame.

Each quarter frame is F1 followed by one byte packing a piece index and four bits of data: 0nnn dddd. Eight pieces make one complete timecode value, and eight pieces at four per frame takes two frames.

That is the fact everybody trips over, and it is arithmetic rather than folklore: a running MTC receiver is always two frames behind the transmitter, because the value only completes two frames after it started arriving. A receiver that does not add the offset back is quietly two frames out on every cue, which at 25 fps is 80 milliseconds — well inside the range where an audience notices a light that is late for a hit.

It is also why MTC has a separate full-frame message, a system exclusive carrying the whole value at once, used for locating while the transport is stopped. Nothing is running, so there is nothing to be two frames behind of.

Drop frame

It drops numbers, not frames

This is the most misunderstood thing in the whole subject, and the name is entirely to blame. Drop frame drops no frames. Every frame that was shot is still there. What gets dropped is labels.

The problem it solves: NTSC colour does not run at 30 frames per second, it runs at 30000/1001, which is 29.97. Timecode counts in whole frames, so if you count 30 frames to the second, your counter runs slightly fast compared with the clock on the wall. Over an hour it gains about 108 frames — 3.6 seconds. For a broadcaster billing by the second, that is intolerable.

So drop-frame timecode skips two frame numbers, 00 and 01, at the start of every minute, except every tenth minute. There are 60 minutes in an hour and six of them are tenth minutes, so 54 minutes lose two numbers each: 54 × 2 = 108. Which is the drift, near enough — the true figure is 107.89, so the correction itself is slightly over and drop frame gains about a frame every ten hours. Nobody cares at show length, and the picture is untouched either way: nothing was dropped, the numbering just skips.

Which means 00:01:00:00 and 00:01:00:01 are not timecodes at all in drop frame. They do not exist. A system that lets you type one is not validating, and a system that reports one is lying.

rule
Non-drop counts every frame and does not match the clock. Drop frame matches the clock and skips numbers. Neither loses a single frame of picture.

When the code stops

Freewheel, jam sync, and what a device does with silence

Timecode arrives as a continuous stream, and on a real show it will be interrupted — a cable pulled, a deck stopped, a player reaching the end of a file. What happens next is a setting, and it is the setting people discover by having the show do the wrong thing.

Freewheel is how many frames a reader will keep counting after the incoming code disappears, using its own clock, before it declares the code lost. A short freewheel means a momentary dropout stops the show; a long one means the show carries on for a second or two into a genuine failure. The right value is a judgement about which mistake is cheaper on that particular job, and the default is almost never it.

Jam sync is the same idea taken further. A device jams to incoming code — matches its internal generator to what it is receiving — and then keeps generating, in step, indefinitely, whether the incoming code continues or not. There are two flavours and confusing them is the classic fault. Continuous jam keeps correcting to the incoming code as long as it is there, so it tracks and it stays honest. One-time jam takes the value once, at the moment it is armed, and then free-runs on its own crystal for the rest of the day. One-time is what you want on a camera that must keep sensible code after it is unplugged from the master; it is emphatically not what you want on a device you assumed was following the master, because from the moment it jammed it has been drifting.

Which is why the useful discipline is to know, for every device in the chain, whether it is reading, freewheeling, or generating. Two devices generating look identical to two devices reading, right up until they disagree, and a rig with an accidental second master drifts apart at a rate nobody notices in rehearsal and everybody notices on the third night.

MIDI in hex

One bit does all the framing

A MIDI stream has no packet header, no length field and no checksum. It has one rule instead, and it is enough: a status byte has its top bit set — 0x80 to 0xFF — and a data byte does not, 0x00 to 0x7F. Everything else falls out of that. A receiver that joins a stream mid-message throws bytes away until it sees one with the high bit set, and it is back in sync.

For channel messages the byte splits in two: the high nibble is the command, the low nibble is the channel. The channel is zero-based on the wire and displayed one-based by nearly every piece of software, which is the off-by-one every MIDI person meets exactly once. So 90 is Note On on channel 1, 9F is Note On on channel 16, and B0 07 64 is controller 7 — volume — set to 100 on channel 1.

Then running status, which is the compression that makes MIDI dumps look confusing. If the status byte would repeat, it can simply be left out and only the data bytes sent. That is why a busy stream has long runs with no status byte in sight. And it is why Note On with velocity 0 exists as a way of saying Note Off: it means an entire passage of notes going down and coming up can share one 9n status byte instead of alternating between two.

ByteMessageData bytes
8nNote Offnote, velocity
9nNote On — velocity 0 means offnote, velocity
AnPoly aftertouchnote, pressure
BnControl changecontroller, value
CnProgram changeprogram
DnChannel aftertouchpressure
EnPitch bend — 14 bits, LSB firstLSB, MSB
F0 … F7System exclusive, runs until F7any length
F1MTC quarter framepiece and nibble
F2Song position — 14 bits, LSB firstLSB, MSB
F8 FA FB FCClock, start, continue, stopnone

Fourteen bits

Why pitch bend arrives backwards

Seven bits per data byte is 128 steps, which is fine for a velocity and hopeless for a pitch bend. So the values that need more precision are sent as two data bytes, seven bits each, giving 14 bits and 16384 steps — and they are sent least significant byte first.

The reassembly is one line: value = (MSB << 7) | LSB. Pitch bend centre is 8192, which on the wire is En 00 40 — LSB zero, MSB 0x40. Reading those two bytes in the order they appear and expecting a number is how people end up convinced their bender is broken.

The same shape appears in Song Position Pointer, in the 14-bit control change pairs (controller n and controller n+32), and in almost everything MIDI does when seven bits is not enough. When something MIDI reads backwards, this is usually why.

Show control

MSC is a system exclusive with a cue number in it

MIDI Show Control is one message shape: F0 7F <device> 02 <format> <command> <data> F7. It is the oldest reliable way to make one GO button fire lighting, sound and machinery at once.

Three details cause nearly all the trouble. Device ID 7F is all-call, so a receiver left at 127 acts on every message on the network whether it was meant for it or not. Command format is a category rather than an address — 01 is Lighting (General), 02 is Moving Lights — and a receiver only acts on the formats it is set to accept, so a format mismatch is the single most common cause of “MSC is doing nothing”. And the cue data is ASCII digits, not binary, with 0x00 bytes separating cue number, cue list and cue path.

So F0 7F 7F 02 01 01 31 00 F7 is: all-call, lighting, GO, cue “1”. The 31 is the ASCII character 1, not the number 0x31. Paste it into the decoder and it will say so.

The last detail is the one that bites in a show: MSC is one-directional and has no state. Nothing acknowledges. A receiver that missed a GO stays where it was, and the sender reports a perfectly successful cue.

Where this goes next

The calculators on this page

The MIDI hex decoder parses a pasted stream, including running status, quarter frames and MSC. Timecode converts between rates and validates drop-frame times — it will refuse 00:01:00:00, because that is not a time. How a one gets down a wire has the wider family of line codes that biphase mark belongs to, and how it all runs together covers what happens when several systems assume a shared clock rather than agreeing one.

Check yourself

6 questions on the mechanism rather than the trivia. Nothing is scored and you can answer again — the explanation under a wrong answer is the point of it.

  1. 1An LTC frame is 80 bits. How many of them are the actual time?

  2. 2Why can an editor read LTC while shuttling a tape backwards?

  3. 3Your MTC-triggered cues are consistently two frames late. What is happening?

  4. 4Drop-frame timecode. What exactly gets dropped?

  5. 5You are reading a MIDI stream and see the bytes 90 3C 7F 3E 7F. How many messages is that?

  6. 6Pitch bend centre arrives as E0 00 40. Why is the small byte first?

Answers are kept in this browser on this device. Nothing is sent anywhere.

You can now answer
  • What is in an LTC frame?
  • Why is MTC two frames late?
  • How do I read MIDI hex?
Kept in this browser on this device. Nothing is sent anywhere.

Where to go next

These pages are a chain rather than a library — the next one along usually answers the question this one raised.