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.
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.
- Not compensating the two frames. Every MTC receiver is two frames behind. If your cues land late by exactly two frames, this is why, and the fix is an offset, not a nudge.
- Expecting the rate immediately. The frame rate rides in piece 7, the last one. A receiver does not know what rate it is being sent until a whole sequence has arrived.
- Using MTC to locate. Quarter frames only make sense running. Locating while stopped is what the full-frame message is for.
- Running MTC down a busy MIDI cable. Four messages a frame is eight bytes a frame, every frame, forever — on a wire that carries about 3125 bytes a second in total. Give it its own port.
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.
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.
- Every generator in the building drifts. Crystals differ by parts per million, which is frames per hour. Jammed at lunch is not still in sync at curtain.
- One-time jam is silent about having stopped listening. The display still shows plausible timecode, which is the whole problem.
- Freewheel hides a real fault for exactly as long as it is set to. If code failures need to be visible, set it short and let it fail loudly.
- Jamming to a stopped deck captures a stopped number. Arm the jam while the master is actually running, not while it is parked at the top.
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.
| Byte | Message | Data bytes |
|---|---|---|
| 8n | Note Off | note, velocity |
| 9n | Note On — velocity 0 means off | note, velocity |
| An | Poly aftertouch | note, pressure |
| Bn | Control change | controller, value |
| Cn | Program change | program |
| Dn | Channel aftertouch | pressure |
| En | Pitch bend — 14 bits, LSB first | LSB, MSB |
| F0 … F7 | System exclusive, runs until F7 | any length |
| F1 | MTC quarter frame | piece and nibble |
| F2 | Song position — 14 bits, LSB first | LSB, MSB |
| F8 FA FB FC | Clock, start, continue, stop | none |
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.
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.
-
1An LTC frame is 80 bits. How many of them are the actual time?
-
The time takes far less than that. Most of the frame is other things.
-
Right. 26 bits of time, 32 user bits, six flag bits and a 16-bit sync word. Storing each decimal digit separately is why the field widths look odd — frame tens only has to count to 2, so it gets two bits.
-
The user bits are 32; the time is smaller than that, because BCD digits that only count to 2 or 5 do not need four bits each.
-
The last 16 bits are the sync word, not a checksum. LTC has no checksum at all.
-
-
2Why can an editor read LTC while shuttling a tape backwards?
-
Right. A transition at every bit boundary provides the clock at any speed, and because the sync word reads differently backwards, the reader can tell not only where the frame starts but which direction it is arriving.
-
It is transmitted once. The properties that make it reversible are in the encoding.
-
It may, but LTC does not need to be told — the sync word answers it.
-
No buffering is needed. The encoding itself is direction-tolerant.
-
-
3Your MTC-triggered cues are consistently two frames late. What is happening?
-
A rate mismatch gives drift that grows, not a constant two-frame offset.
-
Dropped messages give erratic behaviour. A consistent two-frame offset is the design working as specified.
-
MIDI propagation is microseconds. Two frames is 80 ms at 25 fps — four orders of magnitude out.
-
Right, and it is arithmetic rather than a fault. MTC sends four bits at a time, four times per frame, and a complete value only exists two frames after it started. The fix is an offset in the receiver, not a nudge on each cue.
-
-
4Drop-frame timecode. What exactly gets dropped?
-
That would lose 3600 frames an hour, over thirty times too many.
-
This is the belief the name creates, and it is why people are afraid of drop frame. No picture is lost at any point.
-
Right. 00 and 01 are skipped at the start of every minute except every tenth. That is 108 numbers an hour, which is very close to the 107.89 frames a 30 fps counter gains over real 29.97 time. Every frame that was shot is still there.
-
It genuinely changes the count. 00:01:00:00 does not exist in drop frame, and a system that accepts it is not validating.
-
-
5You are reading a MIDI stream and see the bytes 90 3C 7F 3E 7F. How many messages is that?
-
Note On takes exactly two data bytes. A third would have to belong to something else.
-
Right. 3E and 7F have their top bits clear, so they are data bytes, and with no new status byte they inherit the last one. That is running status, and it is why busy MIDI dumps have long stretches with no status byte visible.
-
It is not malformed — omitting a repeated status byte is the specified behaviour, not an error.
-
It can. The high bit of each byte says everything needed to parse it, which is the whole framing mechanism.
-
-
6Pitch bend centre arrives as E0 00 40. Why is the small byte first?
-
Right. Seven bits per data byte gives 128 steps, which is useless for a bend, so the value is split across two bytes least significant first. 00 then 40 reassembles to 8192, which is centre.
-
That is the shape of a control change. Pitch bend has its own status byte and both data bytes are parts of one number.
-
It is specified, and it is the same on every compliant device.
-
MIDI is not consistently one endianness; this is a specific convention for multi-byte values, and status and data bytes have no endianness at all.
-
Answers are kept in this browser on this device. Nothing is sent anywhere.
- What is in an LTC frame?
- Why is MTC two frames late?
- How do I read MIDI hex?
Where to go next
These pages are a chain rather than a library — the next one along usually answers the question this one raised.