| Both sides previous revisionPrevious revisionNext revision | Previous revision |
| blocks:app-note:ltc_timecode [2025-04-28 11:45] – [Use the timecode in Blocks] fredrik | blocks:app-note:ltc_timecode [2026-10-06 13:55] (current) – admin |
|---|
| ======LTC timecode as sync source====== | ======LTC timecode as sync source====== |
| |
| This application note describes a method to receive analog timecode from an external source. For simplicity we use a USB analog soundcard that we plug in to the blocks server. Such audio interface should be "class compliant" USB-A, that means to special driver is required for the device to operate basic functionality properly. | This application note describes how to receive analog timecode from an external source. A USB analog audio interface plugs in to the Blocks server. The audio interface must be "class compliant" USB-A, that means no custom driver is required for basic functionality. |
| {{:blocks:app-note:ltc_timecode:i_face.jpg?400|}} | {{:blocks:app-note:ltc_timecode:i_face.jpg?400|}} |
| |
| We refer to the analog input on the Blocks server in the article, the application can run on any linux computer, so if your source signal is elsewhere it may make sense to pickup the sync signal with another computer running the LTC_timecode reader software. One way of doing that is to use the blocks server image to create the computer. Disable the blocks service and then follow the instructions in this application not to make this into a LTC timecode reader device. | A separate program is used to receive the timecode. This program is included on our Linux Server Image, and can be found in the "native" directory. It can run on most Intel-based Linux computers. If your timecode signal is far away it could make sense to pick up the signal using another small computer running the timecode reader program. Simply make another computer based on our Linux server image, disable blocks and follow the instructions below to turn this into a LTC timecode reader device, whcih then will be accessed over the network. |
| |
| There are other alternative that sometimes may be more suitable, such as the one shown here: | There are other alternative that sometimes may be more suitable, such as the one made by joananton@joananton.com you can [[https://www.youtube.com/watch?v=VY9kEkZim_k|watch here]], which can be connected through a PIXILAB Player using the timecode driver (then configured as a Serial port bound to the Display Spot running PIXILAB Player software). |
| https://www.youtube.com/watch?v=VY9kEkZim_k made by joananton@joananton.com. This reciever will produce serial data from the LTC timecode and can be connected to any Blocks spot with the same driver used in this article. | |
| |
| ====Setup the timecode reader software==== | ====Configuring the Timecode Reader Software==== |
| Plug in the USB audio device to the blocks server. | Connect the USB audio device to the server. Use a second computer (e.g. any laptop with an analog autio output) to play [[https://int.pixilab.se/outgoing/permanent/wiki/LTC_10mins_30fps_44100x24.wav|some sample LTC timecode]] for testing purposes. Connect a 3.5mm audio cable between the laptop's audio output and the line in/mic input of the analog audio interface connected to the server. |
| Use a second computer to play [[https://int.pixilab.se/outgoing/permanent/wiki/LTC_10mins_30fps_44100x24.wav|some sample LTC timecode]], just for testing purposes. We play the sample audio from a Windows laptops mediaplayer. | |
| Plug an 3.5mm audio cable between the computers audio output with the line in/mic input of the analog audio card of the Blocks server. | ===Find the ALSA Name of the Sound Device=== |
| | You must determine the the operating system's name of the USB inputdevice, as it may have more than one. To do so, open a terminal as the pixi-server user and type: |
| | |
| | <code>arecord -L</code> |
| |
| ===Find out the ALSA name of the sound device=== | |
| To capture the desired device we must figure out the ALSA name of the usb-device. To do so we open the terminal as the pixi-server user and type: | |
| <code>aplay -l</code> | |
| Look for an entry like: | Look for an entry like: |
| <code>plughw:CARD=Device,DEV=0 | <code> |
| | plughw:CARD=Device,DEV=0 |
| USB PnP Sound Device, USB Audio | USB PnP Sound Device, USB Audio |
| Hardware device with all software conversions | Hardware device with all software conversions |
| </code> | </code> |
| |
| The ALSA name is | The name to use then is |
| <code>plughw:CARD=Device,DEV=0</code> | <code>plughw:CARD=Device,DEV=0</code> |
| |
| If you have more than one USB audio device one can expect the next one to be named: | If you have more than one USB audio device one can expect the next audio device to be named: |
| <code>plughw:CARD=Device_1,DEV=0</code> | <code>plughw:CARD=Device_1,DEV=0</code> |
| and so on. | and so on. |
| |
| | ===Echo Test=== |
| | To test if the signal can be received, connect some headphones to the USB card output and make an Echo test: |
| |
| ===Echo test=== | |
| To test if we get any signal one can now plug in headphones in the USB card output and make an Echo test: | |
| <code>arecord -D plughw:CARD=Device,DEV=0 -f cd | aplay</code> | <code>arecord -D plughw:CARD=Device,DEV=0 -f cd | aplay</code> |
| You should hear the incoming timecode in the headphones. | |
| | Make sure to use the name determined above. You should hear the incoming timecode in the headphones. |
| Stop the echo test by hitting ctrl+c. | Stop the echo test by hitting ctrl+c. |
| |
| ===Test run the LTC reader software=== | ===Test the LTC Timecode Reader Program=== |
| Now we can dryrun also the LTC reader software by making it log the time using the -t parameter. | Test the timecode-reader program by using the -t parameter. |
| Change to the directory where the software is stored, on a Blocks server image is is stored in home/blocks/native/ | First change to the directory where the timecode-reader program is stored: |
| |
| <code>cd native</code> | <code>cd native</code> |
| |
| Run the program using the -d parameter to specify device and -t parameter to run in test mode. | Run the program using the -d parameter to specify device and -t parameter to run in test mode. |
| | |
| <code>./timecode-reader -d plughw:CARD=Device,DEV=0 -t</code> | <code>./timecode-reader -d plughw:CARD=Device,DEV=0 -t</code> |
| |
| We should see the time changing as the time source progress in the console output: | We should see the time changing as the time source progress in the console output: |
| | |
| <code>New settings: i/2000/t/25/p/1633/n/1/c/0/w/150/f/2 | <code>New settings: i/2000/t/25/p/1633/n/1/c/0/w/150/f/2 |
| 01:57.11 signal, dbFS: -0.6 | 01:57.11 signal, dbFS: -0.6 |
| |
| In test mode we may also see some error logging while reading the signal. | In test mode we may also see some error logging while reading the signal. |
| | |
| <code>Non contiguos 92925 with lastAccepted 92929 | <code>Non contiguos 92925 with lastAccepted 92929 |
| Minor error ignored. 92926 contiguous with lastReceived 92925</code> | Minor error ignored. 92926 contiguous with lastReceived 92925</code> |
| |
| ====Use the timecode in Blocks==== | Adjust the signal level to minimize errors. |
| There are a few steps to do before we can make use of the incoming analog timesource in blocks. | |
| |
| | ====Using Timecode in Blocks==== |
| | A few additional steps are required to make use of the timecode in blocks. |
| |
| ===Enable the driver=== | ===Enable the Driver=== |
| The driver to handle the timedata from the LTC-reader software is not enabled by default. | The driver to handle the timedata from the LTC-reader software is not enabled by default. |
| To enable the driver you must make sure the driver files exist in the script/driver directory in the PIXILAB-Blocks-root. The TimecodeLTC driver is stored in the script/driver-archive/ directory and needs to be enabled: | To enable the driver, first must make sure the driver files exist in the script/driver directory in the PIXILAB-Blocks-root. The TimecodeLTC driver is stored in the script/driver-archive/ directory and needs to be enabled: |
| |
| Change to the script directory: | Change to the script directory: |
| <code> cd /home/blocks/PIXILAB-Blocks-root/script </code> | <code> cd /home/pixi-server/PIXILAB-Blocks-root/script </code> |
| |
| Move the driver files to the drive directory: | Move the following files from //drivers-archive// to the //drivers// directory (unless already there): |
| <code> mv /driver-archive/TimecodeLTC.ts /driver-archive/TimecodeLTC.ts driver/</code> | |
| |
| Restart the blocks server: | <code> |
| <code>systemctl --user restart blocks.service</code> | mv driver-archive/TimecodeLTC.ts driver/ |
| | mv driver-archive/TimecodeLTC.js driver/ |
| | </code> |
| |
| The driver is now available to use on network devices. | Restart the blocks server to pick up the changes: |
| ===Setup the network device in blocks=== | |
| |
| Under the page Manage/Network we set up a new device and assign the TimecodeLTC driver. | <code>systemctl --user restart blocks</code> |
| | |
| | The driver is now available for use. |
| | |
| | ===Add the Network Device=== |
| | |
| | Under the Manage/Network page in the Blocks editor, add a new device and assign it the TimecodeLTC driver. |
| The port is predefined in the driver to match the default configuration to the Timecode reader on the server. | The port is predefined in the driver to match the default configuration to the Timecode reader on the server. |
| | |
| {{:blocks:app-note:ltc_timecode:timecodeblocksdevice.png?800|}} | {{:blocks:app-note:ltc_timecode:timecodeblocksdevice.png?800|}} |
| |
| ===Configure the driver=== | ===Configure the Driver=== |
| |
| You must configure the driver for the expected timecode type. This can be done with one of the following methods: | Configure the driver with the expected timecode type. This can be done with either of the following methods: |
| |
| A. Set the 'type' property of this Network Device to the expected type. | A. Set the 'type' property of this Network Device to the expected type. |
| B. Set options using JSON data in the "Custom Options" field of the Network Device, like this: {"type": "29.97_drop", "offset": 0.0} Supported type values: "24","25","29.97_drop","29.97_nondrop","30". | B. Set options using JSON data in the "Custom Options" field of the Network Device, like this: {"type": "29.97_drop", "offset": 0.0} Supported type values: "24","25","29.97_drop","29.97_nondrop","30". |
| {{:blocks:app-note:ltc_timecode:driveroptions.png?800|}} | {{:blocks:app-note:ltc_timecode:driveroptions.png?800|}} |
| ===Connect a Blocks timeline to sync with timecode=== | |
| |
| Create a timeline block, it can be left empty for testing purposes. | ===Synchronize a Timeline to the Timecode=== |
| Set the timeline to use External synchronization in the timeline settings. Select your LTCTimecode device as sync source property. | |
| {{:blocks:app-note:ltc_timecode:timeline.png?800|}} | |
| |
| Apply any time offset as required. This timeline is now controlled by the timecode. | Add a Timeline block. Set it to use "External Synchronization" and select your LTCTimecode device as its sync source property. |
| |
| ====Make the Timecode reader autostart==== | {{:blocks:app-note:ltc_timecode:timeline.png?800|}} |
| |
| To make the timecode reader autostart we must perform a few more steps. On a blocks server we have prepared whats called a unit file used by systemd in most linux distros to manage running programs and services. | Apply a time offset, if required. This timeline is now controlled by the timecode. |
| |
| Change to the users unit files directory: | ====Autostarting the Timecode Reader==== |
| | |
| | To make the timecode reader start automatically with the computer, you must perform a few more steps. The Blocks server (based on a recent Linux server image) comes with a "systemd unit" file for managing the timecode-reader program. You must edit this file to make sure it's set correctly for your audio device. Start by navigating to this directory: |
| | |
| <code>cd /home/pixi-server/.config/systemd/user</code> | <code>cd /home/pixi-server/.config/systemd/user</code> |
| |
| Edit the timecode-reader.service.config file. | Edit the timecode-reader.service.config file using the //nano// text editor: |
| <code>nano timecode-reader.service.config</code> | <code>nano timecode-reader.service.config</code> |
| | |
| Edit the TIMECODE_READER_OPTIONS= line to make the software use the wanted device name. | Edit the TIMECODE_READER_OPTIONS= line to make the software use the wanted device name. |
| In my case I set it to: | In my case I set it to: |
| <code>TIMECODE_READER_OPTIONS=-d plughw:CARD=Device,DEV=0</code> | <code>TIMECODE_READER_OPTIONS=-d plughw:CARD=Device,DEV=0</code> |
| |
| Next step is to enable the service at computer startup. | Save the file using Ctrl-O then exit the //nano// editor using Ctrl-X. |
| |
| <code>systemctl --user enable --now timecode-reader.service</code> | Inform Linux that you've canged the configuration file: |
| |
| ====Make multiple Timecode readers autostart==== | <code>systemctl --user daemon-reload</code> |
| |
| | Finally, enable the service to start at computer startup. |
| |
| If we want to read more than one LTC timesource we would typically need to duplicate and change the unit files in order to be able to do so. | <code>systemctl --user enable --now timecode-reader</code> |
| |
| We can rewrite the example unit file into a unit template to do this. | ====Using Multiple Timecode Readers on One Computer==== |
| |
| Rename the unit file like this: | :!: **IMPORTANT:** To use multiple timecode readers on the same computer, make sure you're running version 1.4 or later of the **timecode-reader** program. You can see the version number by the following command on the command line, while logged in as the pixi-server user. If your version is older than 1.4, {{:blocks:app-note:timecode-reader:timecode-reader-1.4.zip|download version 1.4 here}}, unpack the ZIP and replace the **timecode-reader** file in the //native// subdirectory of the home directory. |
| <code>mv timecode-reader.service timecode-reader@.service</code> | |
| |
| Edit the unit template. | <code>~/native/timecode-reader -h</code> |
| | |
| | To read more than one LTC timecode source you could duplicate and modify the unit file, thus creating a separate unit file for this purpose. However, a better solution is to modify the unit file to a //unit template//, as this keeps all the common stuff in one place. Follow this procudure to use that option. |
| | |
| | **1.** Rename the unit file like this: |
| | <code>mv timecode-reader.service timecode-reader@.service</code> |
| |
| | **2.** Edit the unit template. |
| <code>nano timecode-reader@.service</code> | <code>nano timecode-reader@.service</code> |
| |
| Use this unit configuration: | Using this configuration: |
| <code> | <code> |
| [unit] | [unit] |
| </code> | </code> |
| |
| Rename the config: | **3.** Rename the unit's configuration file: |
| <code>mv timecode-reader.service.config timecode-reader.alpha.config</code> | <code>mv timecode-reader.service.config timecode-reader.alpha.config</code> |
| |
| Make as many copies as you want instances: | **4.** Make a copy of that configuration file with a new name: |
| <code>cp timecode-reader.alpha.config timecode-reader.beta.config</code> | <code>cp timecode-reader.alpha.config timecode-reader.beta.config</code> |
| |
| | **5.** Edit the config files, specifying different audio interfaces and different network ports in each instance. |
| | <code>nano timecode-reader.beta.config</code> |
| |
| Edit the config files as in the single instance case above. Make sure to specify a different audio interface anddifferent udp port on all the subsequent instances. | The configuraition file will look something like this (but with your device name and desired port number) |
| <code>nano timecode-reader.service.beta.config</code> | |
| <code> | <code> |
| # Options to pass to the timecode-reader program, e.g., | # Options to pass to the timecode-reader program, e.g., |
| # TIMECODE_READER_OPTIONS=-d "Alsa device name"§ -p "UDP port" | # TIMECODE_READER_OPTIONS=-d "Alsa device name" -p "UDP port" |
| TIMECODE_READER_OPTIONS=-d plughw:CARD=Device_1,DEV=0 -p 1634 | TIMECODE_READER_OPTIONS=-d plughw:CARD=Device_1,DEV=0 -p 1638 |
| </code> | </code> |
| |
| Efter any unit change make sure to reinitizialize systemd daemon: | **6.** Notify systemd of your changes: |
| |
| <code> | <code> |
| systemctl --user daemon-reload </code> | systemctl --user daemon-reload </code> |
| |
| Enable (autostart) and start the two instances | **7.** Finally, enable and start the two instances |
| <code> | <code> |
| systemctl --user enable --now timecode-reader@alpha.service | systemctl --user enable --now timecode-reader@alpha.service |
| systemctl --user enable --now timecode-reader@beta.service | systemctl --user enable --now timecode-reader@beta.service |
| </code> | </code> |