Big Buck Bunny from DAT Tape |
I wrote a small tool called datvideo that allows storing arbitrary binary data on the tape. This tool is used to grab raw audio binary data from a sound card, search for frames of binary data, decode them and emit them into another file. This can be assembled into a pipeline to feed video data into a player such as mplayer. How cool is that?
Sony DTC-690, below Marantz Blu-Ray, AV Receiver and New-Old-Stock DAT Tapes |
What is DAT?
DAT Tapes - Smaller than a cassette |
Arbitrary Binary Data on a DAT Tape
The DAT tape decks include a digital input and output. These take the sample data provided to them and commit it directly to tape. This is great for audio because you can make a perfect copy of any input source. I had the idea that any arbitrary data could be fed into the digital input. It doesn't necessarily need to be real audio sample data.
Before spending any time on this project, I worked out the data rate of the tape to make sure I could do something meaningful with it. The calculation is quite simple:
Networking
In order to store arbitrary binary data on the tape, I would need a way to synchronize the receiver with the data on the tape. There could be some audio data, followed by a binary blob, followed by more audio data. The receiver does not know when it will receive a specific type of data, so a system must be devised to signal to the receiver that some binary data has begun. It would also be nice to have some error handling in the form of a CRC. Though it is unlikely that the hardware will introduce errors in the data, it is possible that something in the audio path could introduce some unexpected behavior (some gain on the signal, or the like).
I opted to use the frame format specified by RFC-1662 which is commonly used in PPP (point-to-point) networking. The nice thing about this format is that it is easy to implement, has some error handling and can easily mix in with other forms of data thanks to the escaping feature. More details can be found in the specification.
Audio Hardware
I used a cheap USB sound card to send/receive data to/from the DAT deck. The sound card that I selected has S/PDIF inputs and outputs. I will use a TOSLINK cable to connect this sound card to the DAT deck.
When the binary data stored on the tape is played back, it sounds like noise and pins the level meter. It is interesting when music is interrupted with binary data and the music resumes.
Level Meters during Data Playback |
In order to test all of this, I created a loopback on the sound card so that I could avoid using the tape deck during development.
I wrote a tool called datvideo that helps with this project. It has two modes: encode and decode. The encode mode takes an input file and generates a raw "audio" file that is intended to be recorded to the tape. The decode mode takes captured raw "audio" data and extracts data from the RFC-1662 frames. The tool can be configured to read/write from files or stdin/stdout. This makes it convenient for setting up a pipeline to read/write the tapes with. Here is the help output with a description of all command line flags that can be passed to the tool.
[andrew@andrew-laptop build]$ ./src/datvideo --help USAGE: ./src/datvideo {-e|-d} [-n <byte count="">] [-s <byte count="">] [-o <path>] [-i <path>] [--] [--version] [-h] Where: -e, --encode (OR required) Put the tool in encode mode. -- OR -- -d, --decode (OR required) Put the tool in decode mode. -n <byte count="">, --buffer_size <byte count=""> The amount of data to buffer before writing to the out file. This is useful for streaming operations to ensure that there is always data available to read for the client without blocking. -s <byte count="">, --chunk_size <byte count=""> The size of chunks to split the file into. This is useful for streaming operations, like audio/video. -o <path>, --output_file <path> The output file to use for the current operation. Do not specify for stdout. -i <path>, --input_file <path> The input file to use for the current operation. Do not specify for stdin. --, --ignore_rest Ignores the rest of the labeled arguments following this flag. --version Displays version information and exits. -h, --help Displays usage information and exits. A tool for storing binary data on DAT tapes.
The following commands generate a tape image and decode a captured tape image, respectively. This encodes a photo from a local car meet that I atteded recently. These commands can be chained together with aplay and arecord. More details on that next.
[andrew@andrew-laptop build]$ ./src/datvideo --encode \ -i car_meet_1.jpeg -o car_meet_1.bin [andrew@andrew-laptop build]$ ./src/datvideo --decode \ -i car_meet_1.raw -o car_meet_1.jpeg
Raw Audio Hardware Access
Linux comes with a rich set of tools for working with audio. This demo requires the lowest level of access to the hardware, playing back and recording raw files. The aplay and arecord commands from the ALSA project allow exactly this. First, I will list out the sinks and sources. This can be done for both aplay and arecord.
# List out available audio sinks and sources [andrew@andrew-laptop ~]$ aplay -l **** List of PLAYBACK Hardware Devices **** card 0: HDMI [HDA Intel HDMI], device 3: HDMI 0 [HDMI 0] Subdevices: 1/1 Subdevice #0: subdevice #0 card 0: HDMI [HDA Intel HDMI], device 7: HDMI 1 [HDMI 1] Subdevices: 1/1 Subdevice #0: subdevice #0 card 0: HDMI [HDA Intel HDMI], device 8: HDMI 2 [HDMI 2] Subdevices: 1/1 Subdevice #0: subdevice #0 card 0: HDMI [HDA Intel HDMI], device 9: HDMI 3 [HDMI 3] Subdevices: 1/1 Subdevice #0: subdevice #0 card 0: HDMI [HDA Intel HDMI], device 10: HDMI 4 [HDMI 4] Subdevices: 1/1 Subdevice #0: subdevice #0 card 1: PCH [HDA Intel PCH], device 0: ALC3232 Analog [ALC3232 Analog] Subdevices: 1/1 Subdevice #0: subdevice #0 card 2: Device [USB Sound Device], device 0: USB Audio [USB Audio] Subdevices: 0/1 Subdevice #0: subdevice #0
This allows me to determine that the hardware address of my USB sound card is "hw:2,0". It is also worth noting that I changed the default input and outputs in the pavucontrol app to S/PDIF in and out.
Minting a Tape
With all of this knowledge in hand, let's chain it together to allow video streaming from the tape deck and USB sound card. I decided to use Big Buck Bunny as a test, which is common when dealing with media and decoders/encoders.
So first, let's grab Big Buck Bunny from Renderfarming. I like the1080p, 60fps version for the buttery smooth visuals :]. The video is roughly 10 minutes long which means the file needs to be around 110MB to achieve real-time playback from the tape. The file is overweight at 356MB which means that some transcoding is needed to trim it down. I noticed that there is an extra audio track. That can be stripped out too.
Big Buck Bunny - Short Film from the Blender Project |
# Strip the AC3 audio track. MP3 is smaller. [andrew@andrew-laptop Downloads]$ ffmpeg \ -i bbb_sunflower_1080p_60fps_normal.mp4 -map 0:0 -map 0:1 \ -acodec copy -vcodec copy bbb_sunflower_1080p_60fps_normal_one_audio.mp4 # Transcode to h265 with CRF 30. This yeilds a ~100MB file. andrew-desktop:Downloads andrew$ ffmpeg \ -i bbb_sunflower_1080p_60fps_normal_one_audio.mp4 -acodec copy \ -vcodec libx265 -crf 30 bbb_sunflower_1080p_60fps_normal_one_audio_h265.mp4
I used my Mac Pro for the heavy h265 transcoding so that my tiny ThinkPad T440s didn't have to work too hard and to speed up the operation.
Once the file was transcoded into a file of suitable size, it was placed into MPEG-TS frames. MPEG-TS is typically used for DVB systems where interruptions in the stream may happen due to interference. Once the MPEG-TS stream was ready, the file was encoded with datvideo.
Once the file was transcoded into a file of suitable size, it was placed into MPEG-TS frames. MPEG-TS is typically used for DVB systems where interruptions in the stream may happen due to interference. Once the MPEG-TS stream was ready, the file was encoded with datvideo.
# Change the transport to MPEG-TS [andrew@andrew-laptop Downloads]$ ffmpeg \ -i bbb_sunflower_1080p_60fps_normal_one_audio_h265.mp4 \ -f mpegts -vcodec copy -acodec copy \ bbb_sunflower_1080p_60fps_normal_one_audio_h265.ts # Encode the MPEG-TS to a tape image. Use 188 byte frames, which # happens to be the same as the MPEG-TS frame size ;) [andrew@andrew-laptop build]$ ./src/datvideo --encode \ -i ~/Downloads/bbb_sunflower_1080p_60fps_normal_one_audio_h265.ts \ --chunk_size 188 -o big_buck_bunny.binNow that the image is ready, it is time to burn it to tape. First, the DAT deck is put into record mode. The DAT deck can be recording before starting to burn the image thanks to the RFC-1662 framing that allows detecting the start of binary data anywhere on the tape. The following aplay command is used to play the raw file to tape without modification.
# Play the track out to the DAT deck [andrew@andrew-laptop build]$ aplay --format=S16_LE --device=hw:2,0 \ --channels=2 --rate=48000 --file-type=raw big_buck_bunny.binNow that the MPEG transport stream has been recorded to tape, it can be played back, decoded with datvideo and played back with VLC.
# Record from the DAT deck, piping into datvideo # and decoding to a file 'bbb.ts' [andrew@andrew-laptop build]$ arecord --format=S16_LE \ --device=hw:2,0 --channels=2 --rate=48000 \ --file-type=raw | ./src/datvideo --decode -o bbb.ts # Open the file for playback with VLC [andrew@andrew-laptop build]$ vlc bbb.tsLet the file bbb.ts buffer for a few seconds and then it can be opened with VLC for playback. It is a pretty crude setup, but it works surprisingly well.
Weekend Projects :] |
Closing Remarks
This was fun. I like doing quirky things with technology. I learned a few new things that I can probably use in my day-to-day work which is always nice. I probably won't go out and convert all of my favorite movies to DAT format, but this was certainly a nice way to spend a rainy weekend.
I hope you enjoyed my zany use of technology and perhaps are inspired to do something yourself. I know one idea that comes to mind is TCP/IP over TOSLINK optical audio cables via the datvideo tool shown above. It should work rather well.
Comments always welcome. Thanks for reading!
No comments :
Post a Comment
Note: Only a member of this blog may post a comment.