Vintage bits on cassettes

I had contemplated using Compact Cassettes as a cheap, fun and hipstery media for small yet valuable backups. Perhaps it would even be possible using only an ordinary tape recorder. So finally I thought: How hard could it be? Let's give it a try!

Searching led me to a Wikipedia article about the Commodore Datassette. It was a tape format used by the Commodore personal computer. It used two different frequencies to encode ones and zeros, and they were read back by simply detecting zero-crossings. I exploited this invention and modified it a bit by adding start and stop bits and a 50-byte lead-in tone:

The resulting program, ctape, is on GitHub. Please note that this is an art project and unfortunately I can't provide technical support for it, but if you get it working, then great! You will run into some interesting problems. Note: Unfortunately I will not have the time to assist you.

Compact Cassettes sell for 20 cents at flea markets. They come in many colors and capacities. Using the data rate I chose about 1.2 MB fits on a single cassette.

Video proof below!

By the way, I only used text for demonstrational effect. All kinds of data can be saved onto the cassette. A nice way to do this is to use .tar files (which, incindentally, stands for "Tape Archive"!).

Edit: Here's some PNG data:

Update 2/2013: I've improved the modulation scheme since. I added a slight inter-channel delay that alleviates short losses of signal on the tape. There's also a calibration header to account for polarity or stereo reversal.

64 comments:

  1. So, can you store more bytes on an audio CD in data mode, or as an 80 minute .wav file from your program in audio mode? :D

    This is extremely interesting (even more than your dial-up modem poster, imo). Excellent work!

    ReplyDelete
    Replies
    1. Maybe you can store more as audio if you have a ultra-high data rate. Or maybe you store 8 bytes per pulse of data by doing 16 different frequencies and storing that.

      Just an idea, I'd love to try that!

      Delete
  2. Fantastic! I also have a nice tape deck near my PC, thinking about taking this for a spin.
    Love that you're going back and analysing the old data storage/transmission methods, unveiling the ingenuity of the engineers who designed this old technology.

    ReplyDelete
  3. Would be interesting to use all 4 tracks of a cassette at the same time.

    ReplyDelete
  4. It would be cool to start sharing "secure" data this way, to see what people can come up with. This would make software encryption look dumb. Awesome work, btw you should upload more of your work to youtube

    ReplyDelete
  5. Larry: You could do stereo, double sided. Just have to flip the tape over.
    There are 4-track recorders like the little Portastudios, but then you need an audio output on your computer to handle a 4-track sound file

    As for "security", it's "security through obscurity" in this case. There's plenty of sensitive information passed on tape, where the cost of reading it is too high for the average PC user. Here, the reading mechanism is so common that if someone guesses what the tape is, reading it is trivial thanks to miss Oona here :)

    ...it's still loads of fun to do :D
    I've been looking into data storage on VHS after this, it's a LOT more complex due to the way VHS heads read and write in a helical manner, which makes for a superbly dense storage medium but introduces the tracking problem that plagues old VCRs. For analogue video that's not so bad, when you're dealing with data it's a far larger issue.

    ReplyDelete
  6. Using both channels separately would indeed double the capacity! As for security, the data could simply be encrypted before encoding.

    A problem I've noticed is when an old tape has short demagnetized or wrinkled sections and the audio disappears for a split second. The data format needs some redundancy for error protection.

    ReplyDelete
    Replies
    1. The C64 rom version of the tape storage format saved all data twice in a row, the whole program once and then the whole program again.
      Did you use any turbo tape format to speed things up? Your png picture seems to load faster than a load picture on a retro game.

      Delete
    2. It's not a C64 format, so I guess "turbo" is not applicable. I invented my own format.

      Delete
  7. I was running a course with a colleague in the late '80s and we were due to run it just after a holiday time so there was no way of posting the document to him. We had a course plan written in an early word processor - on a machine which could save to cassette. I discovered if you played that cassette down the phone (headphones on the phone mouthpiece) and my colleague recorded it through a microphone at his end and then played his tape into his computer - voila! The text magically reappeared. Way before email. Seemed totally magical at the time and genuinely useful for our planning.

    ReplyDelete
    Replies
    1. They used to broadcast little c64 games on a local radio station here in Sweden back when. The format seems very resilient to noise and such.

      Delete
    2. This reminds me of Operation VULA! "To avoid having to key in the numbers while in a telephone booth the tones could be recorded on a tape recorder at home and then played into the telephone. Similarly, at the receiving end, the tones could be recorded on a tape recorder and then decoded later. Messages could even be sent to an answering machine and picked up from an answering machine if left as the outgoing message." http://www.anc.org.za/show.php?id=4693

      Spying via cassette tape, modem, and PTN. Fascinating read.

      Delete
    3. WOW! A friend and I attempted something similar, back in the early 1980's! We each had Commodore 64's. I didn't waste my money on a "Datasette"... I rolled my own! :) Using a standard, portable tape deck (a halfway decent one for the time) I fed the speaker output into a comparator to create the 5v TTL squarewaves that the C= 64 wanted. It worked PERFECTLY! It even allowed me to load tapes that my brother's Datasette couldn't. :) (The volume control was helpful!)

      OK, so here's how we tried sending a file thru a phone, sans modems! (We didn't own any!) He connected the output of the C= 64 to a circuit which fed the audio into his phone. I used an audio amp from my phone, to feed the audio into my comparator. He typed "SAVE" on his machine, and I typed "LOAD" on mine. It STARTED... but then locked up and crashed my computer. I was able to reset, and "PEEK" inside the cassette buffer. Most of the header data made it, intact! There were a few flipped bits, tho, and I'm sure the computer choked on one of those. We ended up not revisiting this project, and lost contact over 30 years ago. His name was John E. Frank. I wonder if he will ever find this article? ;) Thanks for the memories!

      PS: I have thought about various means to pass data thru narrow audio paths, like the 56K modems could do in a 3Khz bandwidth... but not being a mathematical genius, I never got past the "what if" phase. ;) Saving data on a stereo cassette COULD yield reasonably decent storage capacity.. but the error correction would have to be VERY robust! Now, what with micro SD cards (literally) the size of a fingernail, holding many GIGS of data... why bother with magnetic tape at all? ;)

      Delete
  8. Ye olde computers had so little processing power that they had to resort to simple FSK/PSK at very low bitrates. But what if trellis modulation is used, for example, like in modern modems? Tape is much better than phone line, no line noise, no evil exchange putting sticks in the wheels. Theoretical limit for lower-than-decent tape recorder at 12.5kHz BW with 50dB SNR is about 200kbit/s, 25kB/s, which would make about 135Mb per 90 min if using mono, 270Mb for stereo. Curious! Imagine legible video playback from an audio tape.

    ReplyDelete
    Replies
    1. PXL-2000 used a Compact Cassette as a video cassette.

      Delete
    2. I heard about it before. It's not really very interesting, or rather interesting from the low-end side of things: it did not use any sophisticated data modulation, more like simply ignored the limitations.

      Here we're talking about high-end cassette tape data storage :) Anyway, something to muse about. Wikipedia says that high-density data streamers using regular audio cassete actually existed and stored up to 60MB per tape.

      Delete
    3. Some cassette data recorders (like the DAT?) used helical scanning, IIRC. But it'd be interesting to try and squeeze more data onto it :)

      Delete
    4. In converting existing audio to image, I haven't had any time to sit down and play with it, but you seem magical with the skillz, so here's a suggestion... create the 'image' from the audio by first folding up the 'paper' that the image will be printed upon in the manner used to create different 'snowflakes' by folding and cutting the paper. Once the 'paper' is folded, the same audio can be converted to video, either filling the entire area (like your LP from sound image) or taking sections and creating video. So with a known range of signal values, the 'paper' can transition from 'solid' at one end to 'cut away' at the other. With different types of folding templates, different kaleidoscope effects could be obtained with the same general philosophy. Good Luck!!

      Delete
  9. Way to go! I worked on a similar concept for my undergrad research project in '97-98 using a sound blaster and consumer cassette deck, but I failed mostly due to aiming too high instead of using a simple encoding. I suspected as well that the processors then couldn't deal with the FFT I was using to detect multiple data tracks.

    Also, there was a system out in that time frame that used VHS tapes to store much more data as video thanks in part to the helical scanning method and the larger tape area. The tapes would play in a VCR and had numbers in the upper left corner of the screen to represent the memory page index, so one could use a reference index to "seek", i.e. fast forward, to a specific file.

    ReplyDelete
    Replies
    1. The scheme used here is very simple, so the tape could be read back using only a 1-bit ADC. No signal processing is needed, either.

      Whoa, the visual seek sounds interesting :o

      Delete
  10. I like this idea, very cool indeed. I'd like if you could pack more data using qam64 with LDPC for the forward error correction. even better I wonder how much data you could write on ordinary vhs tapes.

    ReplyDelete
    Replies
    1. The modulation needs to be resistant to FM intermodulation distortion.

      Delete
  11. I've been listening to streaming SILK audio on cassette tapes using Digital Radio Mondiale, an 'effectively' closed-source program that uses QAM and OFDM modem technology to get 13.8 kilobits on one channel of a stereo cassette tape using the JVC TD-V66 3 head deck. I say closed-source because there is no free implementation of carrier recovery using more than 4-PSK in vanilla C programming, even though the patents probably have expired by now. And I live in hick country without a car or credit card so even for MONEY I couldn't buy a book on carrier recovery.

    ReplyDelete
  12. I used to use video to backup data from my Amiga computer back in the day using a product called Video Backup System (http://www.hugolyppens.com/VBS.html). It basically sent a barcode type composite signal to the VCR. Worked great, I'd ended up with some broadcast spec betamax units (with built in time base correctors)...gave my nice clean stable backups.

    ReplyDelete
  13. I've been looking for something like this for a long time. I miss saving my files to cassette tapes, as I used to in the eighties on my Spectrum.
    I can convert text files to 'screeching' sound, I can record it on tape, but when I try to play back the tape and type ./tape-read.rb > FILE nothing happens.
    Can anyone tell me what I am doing wrong? Thanks.
    Gabriel Artigue
    (gabriel dot artigue at gmail dot com)

    ReplyDelete
  14. Try the old KCS08 tool. ftp://ftp.forth.org/pub/forth/compilers/native/dos/DXForth/kcs08.txt

    ReplyDelete
  15. could you do this with a VHS cassette? Or is that too hard

    ReplyDelete
  16. From my understanding, the signal that is written to the tape is an FSK signa, not a 0 crossing encoded signal. So the decoder doesn't detect a 0 crossing, but rather measures the frequency using something like either FM demodulation (each frequency represents a different voltage, which is then quantized into just a 1 or 0 based on an OP-AMP comparator, but if the tone is too weak the signal is rejected as containing no data), or FSK demodulation (2 bandpass filters are used, and whichever contains the strongest signal it is considered to hold the data, one tone representing binary 1 and the other representing 0, and if neither signal is strong enough it is considered that no data is present).

    ReplyDelete
    Replies
    1. Hi! Thanks for the comment. You can read more about the Commodore cassette encoding and decoding here.

      Delete
  17. Maybe instead of using two tones for 0 and 1, use multiple tones at other sets of frequencies.. kinda like the DARC protocol where you could have the RDS and DARC data at the same time.

    ReplyDelete
  18. Very cool. I know nothing about Ruby - was hoping to find a web site / java script page that had a text box and encoded whatever was in the box to audio...

    ReplyDelete
  19. Sadly it seems like this doesn't work with my tape recorder. No matter what I try, I can't get the signal from my tape recorder to return any kind of output when I put it through the tape-read program.

    If you're interested, I could send you a FLAC recording from my tape recorder, maybe it'd help with debugging.

    ReplyDelete
    Replies
    1. Sure, I could take a look at that FLAC. There could be many factors affecting this, this code is mostly just a work of art. As for e5frog's answer below, phase reversal shouldn't be a problem as my format uses a phase calibration header.

      Delete
    2. Cool, I've uploaded it here: https://my.mixtape.moe/secims.flac

      Delete
    3. For some reason tape-read has trouble detecting an adequate number of zero-crossings for the polarity leader.

      I temporarily changed the expected number of repetitions from /(nppp){30}/ to /(nppp){5}/ and got this: https://i.imgur.com/UGuW9lM.jpg.

      Delete
    4. Ah cool, thanks for looking into it.

      Delete
    5. I've had a similar experience. Have a look at my web site: http://gasconheart.sdf.org/tape
      Regards.

      Delete
    6. The existence of the Worldwide Network of Active CTAPE Users always makes me smile :D Let's hope there will be an actively maintained program in the future!

      Delete
  20. @dennacematthews Try to invert the phase, if sound is phase inverted you won't get any data at all as you'll get the wrong zero crossings.
    Not sure how you'd do that, possibly by swapping ground and signal on the wire used for the hookup.
    On programs for actual computers like the C64 there's often a "invert phase" option as sound equipment may cause inverting - which may sound the same but it makes a difference in this case.
    Perhaps you can record you sound file, invert it in a sound program and then try again.

    ReplyDelete
  21. Very cool! What's the bitrate of this in it's current state? Given that you are emulating a HTTP server response directly from the tape by that picture demo, I've imediatelly thought about encoding some music in HE-AACv2 in an enough low bitrate for the tape (24kbps should do it?) and put a Shoutcast compatible HTTP response header in front. After that you could actually stream music into a audio player like Winamp from the tape, the player would believe you are listening to some kind of webradio :) Really cool, i should get a tape deck :D

    ReplyDelete
    Replies
    1. I used a very low bitrate, around 600 bps. At least it's more robust that way. I think it would be realistic to get up to 1200 or maybe even 2400. However, 24 kbps is 40 times higher than 600 bps, so I don't think it would work. Haven't tried though!

      Delete
    2. Googling on the net I've found someone who was recoding a Digital Radio Mondiale AM signal on the tape and playing it back to the decoder software, thinking it's a digital radio transmission: https://www.youtube.com/watch?v=2mseiBwPKvk This way he could listen to a 11.4kbps HE-AAC stream in real time coming from the tape deck. But DRM's modulation is a lot more sophisticated of course.

      Delete
    3. Interesting, I should try it!

      Delete
  22. This could be a neat addition to the 1802 Membership Card by Lee Hart et al...

    ReplyDelete
  23. What about generating and recording, then playing-back, multiple PSK frequencies? (See: http://www.mymorninglight.org/ham/psk.htm )Each signal would carry some small portion of the total data stream, and then you can add as many as will fit the bandwidth. (You should be able to get some pretty robust throughput, figuring you probably have roughly 50Hz to 12Khz on a "cheap" cassette system.) Each stream could also have some kind of error correction. On ham radio, we can have DOZENS of simplex, keyboard-to-keyboard "conversations" going, simultaneously, within a 2.5Khz passband. (They are only 31Hz wide, approx 31 BPS) The mode is called PSK31. The encoding uses 180 degree phase shifts to create the bit patterns. It's quite clever, actually, and scales up nicely. :)

    ReplyDelete
    Replies
    1. Hi, yes, that would be worth trying. I didn't use any of the ham modes because I judged the frequency modulation caused by motor jitter to be too much of a distortion.

      Delete
  24. Hmmm... interesting point, about the motor speed flutter. That WOULD make the decoding a bit trickier. I know that the popular PSK31 software out there will "auto-tune" for frequency drift, but that's usually a steady shift at a fairly slow pace. Motor flutter is rapid. Of course, better quality cassette decks generally have a big enough flywheel to minimize this quite nicely. :) It would, indeed, be interesting to see just how much robust throughput could be achieved with a GOOD deck... stereo, so you can have 100% redundancy! Make the two channels offset by several hundred milliseconds, to compensate for tape damage, etc. A number of possibilities open up, when you allow for a much higher quality deck and tapes. :)

    ReplyDelete
  25. ctape is really cool. I like the sound of the signal it produces, it's got that classic crunchy-noisy data sound to it, kind of like the sound of ZX spectrum tapes.

    Mid last year I made my own store-data-on-tape program, which uses amplitude instead of pitch to store the data. The code is perhaps a bit messy since I only properly started learning to program at the end of 2015, but you might still find it interesting. It's here: https://github.com/TheGoldenManDenis/NutSystem-audio-cassette-data

    ReplyDelete
  26. This really interests me and i'd love to try this out but i'm stuck in a real problem and can't seem to make this work for me. I'm not sure if i'm suppose to use Ruby or I am doing something wrong here. Any help would be fantastic!

    ReplyDelete
  27. I get this error when I try to use the program.

    C:/Users/username/Desktop/ctape-master/tape-write.rb:13:in `popen': No such file or directory - sox -q -t .raw -r 44100 -c 1 -b 16 -e signed-integer - output.wav (Errno::ENOENT)
    from C:/Users/username/Desktop/ctape-master/tape-write.rb:13:in `'

    I'm not sure what it's wanting though it could be that i'm on a windows system. Maybe. I'm at a loss. I hope this helps.

    ReplyDelete
    Replies
    1. Hi, I haven't tested this on a Windows system, but seems like you're missing SoX.

      Delete
    2. Just a thought... perhaps you should move it to a different directory. You might run into "permissions" issues in that directory. Create a new folder from the root, and try installing it there.

      Delete
  28. I have SoX but maybe I installed it wrong? I really am not sure. Also i'm sorry i've been absent for a long while there. Life stuff distracted me from trying this out.

    ReplyDelete
  29. Hi there!

    We spoke briefly on twitter.
    I've been encountering a few errors when attempting to run tape-read.rb.

    It works fine when I use output.wav as the device. However, when using -t alsa hw:0,0, the script runs but does nothing; it only terminates if aborted.

    Manually running the sox command (using the above in place of the device var) gives me an endless string of unicode characters, which quite clearly responds to audio coming in through the device - it lessens from a full page of characters to sparse strings when audio is registering, and goes back to a full page with silence (tape contains two encoded files separated by a few seconds of silence.)

    Audio device and drivers are working correctly; if I open audacity and record from hw0:0 it picks up the audio. Volume is loud enough, no error message received.

    I also noticed that you were utilizing 2</dev/null for your initial video, wondering if there's anything in particular you can say about that, and if there's anything I should do if I modify default device to /dev/null, /dev/stdin, or /dev/dsp.

    Feel free to request any additional information; I have tried this from both Arch and Ubuntu and get the same (lack of) result.

    Let me know, would love to utilize this program for hipsterish backups, as well as see what the potential for glitch art is.

    ReplyDelete
    Replies
    1. Did you try -t alsa default? You seem to have also written the device name differently for input (hw0:0) and output (hw:0,0). The 2>/dev/null means that error stream is ignored.

      I seriously don't recommend this for backups, but it could be fun for art.

      Delete
  30. Hello,this is a really cool project,but i can't get the program running properly,can you make a well explained video that explains how to use the program please? Thank you

    ReplyDelete
    Replies
    1. Hi! Unfortunately I haven't played with this project for years and technical support for it has ceased - I've added a mention of this in the blog post. But I suggest you write one of your own - you'll run into some pretty interesting problems!

      Delete
  31. This project is amazing!

    I found a similar project at http://www.instructables.com/id/Storing-files-on-an-audio-cassette/ but yours can do in 7 minutes in what takes 20 minutes for that one! What is funny is your project can read the .wav files from the other project, but the other project cannot read the .wav files from yours. Crazy stuff.

    I have a small question, I was wondering how you had the cassette as an input device for the tape-read.rb program. I have been using the .wav files as an input source, but I cannot figure out how you used your mic or line-in as a input source.

    Aka, I do want to record from my line-in and then have to save it as a .wav using recording software, and after that using the .wav file as the source in your program. I would like it to read the data as the audio is being received from the line-in (Basically live.).

    Is there a command or did I completely miss part of your instructions?

    Thanks!

    ReplyDelete
    Replies
    1. Did you try the other 'device' parameters in the config file? Especially:

      device: -t alsa default

      Delete
  32. hi i keep getting an error when i try to run it
    "./tape-write.rb:13:in `+': no implicit conversion of nil into String (TypeError)
    from ./tape-write.rb:13:in `'"

    ReplyDelete
    Replies
    1. Hi, unfortunately there is no technical support for this project anymore, and I've added a mention about this in the blog post. If you find a solution, I'd be happy to publish it.

      Delete
    2. Hi all!
      Just found this by accident, but I was looking around the internet to find more people trying this in modern times.
      I myself did some experiments using my tape deck, but without any error correction or anything other fancy stuff.
      I so far got up to 9600 bps on a mono channel and was able to record about 15 minutes of it. I believe after 10 minutes or so there came some Windows "ding" which messed up the rest of the data.
      Have a look at what I did here:
      https://www.youtube.com/watch?v=IJ5VDKV9qbw
      https://www.youtube.com/watch?v=9A1D3Q4va-w
      https://www.youtube.com/watch?v=FkQzJ6LRdTA
      Unfortunately I think my implementation is not that well usuable as I require to make a WAV file and play that and then also record to WAV and decode. Would of course rather have direct output and input from a soundcard.
      My goal would also be to get somewhere in a region where I can have digital music in HE-AACv2 format, or even xHE-AACv2 which I believe sounds quite good at 16kbps and then just play it from the tape deck.
      Anybody here still up for collaborating on this?

      Cheers,
      Berni

      Delete

Please browse through the FAQ first, it might be that your question is already answered.

Spammers have even found comments sections, so this comments section is pre-moderated; it will take some time for the comment to show up.