Modified code for 25FPS
G0OQK opened this issue · 12 comments
Dear Dirk-Willem,
Thank you for writing the code and providing it for use. I can confirm that it works well for clocks that can be switched to take LTC at 30FPS. Unfortunately I have a clock that will only sync at 25FPS.
I have tried changing the constants 2400 and 4800 in rmt.ino to 2000 and 4000, but while the clock syncs, it also glitches. I’m sure that I should have changed something else as well, as I’m probably overrunning the buffer, but my knowledge is not sufficient to understand what I need to do. If you are able to give me a suggestion as to what needs to be changed for operation at 25FPS, I would be most grateful.
Regards
Nick Garrod
In theory it should be enough to just change the 2400/4800 to 2000 and 4000. How big is the error you get printed on the serial port during startup ?
And do you have a logic analyser (like a https://www.saleae.com or one of the cheap copies) or a second ESP32 available ?
Thank you for the reply. The error on startup is 0.0%. Reported bps is 2000.05. I had already ordered some more ESP32s, but none on hand at present. ESP8266 and Arduinos aplenty though.
I have taken your suggestion and ordered a cheap analyser. What appears on the clock is that it is going to the next second early, for a fraction falling back then changing. I’ve checked the clock with a pre-recorded wav file at 25FPS and it is fine. Obviously the signal out of the esp has faster edges than the wav file, as it has not been through a low pass filter, but I don’t have any problems at 30FPS. As you have said though a logic analyser will show what is happening.
Thank you again. I think our paths crossed at TVC a number of years ago, where I was and still remain a Duty Ops Manager, though these days at W1.
Thanks
Nick.
Did just push a tiny tweak that lets you set the FPS to 25 or 30.
I've not yet had the time to measure it against a stable source to see if it slowly drifts or skips though.
The other option is that we're somehow always a fraction of a 'tick' over (instead of it falling either way); so that after N seconds we are just too much off.
Yup - see below (the timesource is not reliable - but it is soo far off that it is obvious). So either the crystal on this ESP32 is way off - or we're systematically rounding something up or down.
Will investigate if I have some time this weekend.
For 25 FPS:
63.566338250000001,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),?0:21:36.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
64.566522500000005,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),?0:21:37.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
65.566706999999994,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),?0:21:38.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
66.566891499999997,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),?0:21:39.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
67.567076000000000,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),?0:21:40.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
68.567260500000003,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),?0:21:41.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
69.567444750000007,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),?0:21:42.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
70.567629249999996,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),?0:21:43.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
71.567813749999999,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),?0:21:44.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
72.567998250000002,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),?0:21:45.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
73.568182750000005,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),?0:21:46.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
74.568366999999995,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),?0:21:47.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
75.568551499999998,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),?0:21:48.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
76.568736000000001,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),?0:21:49.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
77.568920500000004,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),?0:21:50.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
78.569104999999993,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),?0:21:51.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
79.569289249999997,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),?0:21:52.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
80.569473750000000,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),?0:21:53.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
81.569658250000003,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),?0:21:54.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
82.569842750000007,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),?0:21:55.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
83.570027249999995,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),?0:21:56.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
84.570211749999999,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),?0:21:57.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
85.570396000000002,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),?0:21:58.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
86.570580500000005,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),?0:21:59.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
87.570764999999994,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),?0:22:00.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
88.570949499999998,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),?0:22:01.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
89.571134000000001,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),?0:22:02.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
90.571318250000004,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),?0:22:03.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
91.571502749999993,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),?0:22:04.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
92.571687249999997,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),?0:22:05.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
93.571871750000000,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),?0:22:06.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
94.572056250000003,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),?0:22:07.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
95.572240750000006,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),?0:22:08.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
96.572424999999996,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),?0:22:09.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
97.572609499999999,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),?0:22:10.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
98.572794000000002,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),?0:22:11.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
99.572978500000005,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),?0:22:12.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
65.128652500000001,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),23:06:09.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
66.128851749999995,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),23:06:10.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
67.129051250000003,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),23:06:11.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
68.129250749999997,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),23:06:12.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
69.129450000000006,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),23:06:13.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
70.129649499999999,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),23:06:14.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
71.129848749999994,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),23:06:15.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
72.130048250000002,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),23:06:16.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
73.130247749999995,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),23:06:17.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
74.130447000000004,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),23:06:18.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
75.130646499999997,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),23:06:19.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
76.130846000000005,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),23:06:20.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
77.131045250000000,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),23:06:21.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
78.131244749999993,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),23:06:22.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
79.131444250000001,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),23:06:23.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
80.131643499999996,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),23:06:24.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
81.131843000000003,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),23:06:25.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
82.132042499999997,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),23:06:26.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
83.132241750000006,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),23:06:27.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
84.132441249999999,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),23:06:28.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
85.132640749999993,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),23:06:29.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
86.132840000000002,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),23:06:30.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
87.133039499999995,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),23:06:31.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
88.133239000000003,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),23:06:32.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
89.133438249999998,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),23:06:33.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
90.133637750000005,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),23:06:34.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
91.133837249999999,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),23:06:35.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
92.134036750000007,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),23:06:36.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
93.134236000000001,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),23:06:37.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
94.134435499999995,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),23:06:38.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
95.134635000000003,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),23:06:39.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
96.134834249999997,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),23:06:40.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
97.135033750000005,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),23:06:41.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
98.135233249999999,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),23:06:42.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
99.135432750000007,SMPTE/EBU Timecode (BiPhase Mark 'LTC' 80 bits),23:06:43.00 no-drop no-colour parity-ok User=0-0-0-0-0-0-0-0, groupBits=00, reserved=0
Thank you for continuing to investigate. I’m still awaiting delivery of the logic analyser, for a detailed look at the bitstream. I’ve programmed both a Wemos and a generic ESP32 dev board and had the same results. One thing I have done is plugged the output into an Avitel time code reader at work and according to the Avitel it was still putting out 30 frames per second after having made the changes to the tock values. The Avitel seemed to be dropping a lot of frames. The unmodified code was fine. I noticed a line in the code where it seemed to be resetting the frames to 0 if they were greater than 0x30.
I also note from the standard that the parity correction bit differs between 25 and 30 FPS
I will look at you modified code tomorrow. I’m still working my way through, trying to understand some of the detail of your code. Entirely a lack of detailed knowledge on my part, but a good way to learn.
From Wikipedia
Bits 27, 43, and 59 differ between 25 frame/s time code, and other frame rates (30, 29.97, or 24).[1]:9[2] The bits are:
"Polarity correction bit" (bit 59 at 25 frame/s, bit 27 at other rates): this bit is chosen to provide an even number of 0 bits in the whole frame, including the sync code. (Since the frame is an even number of bits long, this implies an even number of 1 bits, and is thus an even parity bit. Since the sync code includes an odd number of 1 bits, it is an odd parity bit over the data.) This keeps the phase of each frame consistent, so it always starts with a rising edge at the beginning of bit 0. This allows seamless splicing of different time codes, and lets it be more easily read with an oscilloscope.
"Binary group flag" bits BGF0 and BGF2 (bits 27 and 43 at 25 frame/s, bits 43 and 59 at other rates): these indicate the format of the user bits. Both 0 indicates no (or unspecified) format. Only BGF0 set indicates four 8-bit characters (transmitted little-endian). The combinations with BGF2 set are reserved.
I changed the parity bit write in smpte.ino from block 3 to block 7 and your code works at 25fps. I think that was the missing piece of the puzzle.
if (par & 1)
block[7] |= 8; // for 25FPS
Thank you again for writing the code. There are a couple of us at work now using it.
Regards
Nick
That I can’t say, as my 25FPS clock does not show an error on sync loss, it just free runs. I’m at work next weekend, so I can run the output into an Avitel reader, which shows individual frames. For my purposes a short loss of sync is not a problem, as long as the ESP doesn’t output corrupted time.
Assume all is well now. All merged and commited.