Audio output on RS-232

I made a little program to play audio out of the serial port of my computer.

http://vivara.net/software/ttyplay/

A blurry picture of the serial connections

The Linux desktop is complete, now that this application is released…

Laptop playing music!

Notice the image is blurry because of huge quantities of bass produced. (Actually, the sound is barely audible.)

How does it work?

First, the audio is resampled to the baudrate of the serial port.

Look over here for a description of the RS-232 waveform. Good hardware can send bytes “back-to-back”. Two of the bits are determined by the protocol: the Start bit and the Stop bit. I can control the other 8 bits coming out of the serial port.

Sigma-Delta modulation is a way to encode an analog signal into a binary bitstream.

Sigma Delta modulation

(This image is from http://www.numerix-dsp.com/appsnotes/APR8-sigma-delta.pdf)

To make the serial port play music, I added a block after the one-bit quantizer to account for start and stop bits. This block is still inside the feedback loop, and reduces the audible effect of the start and stop bits.

See the README for more implementation detail.

Links:

Mega Nerd, home of libsndfile and libsamplerate, which are both used by this project.

Roman Black’s one bit sound on a PIC. I do not see the modulation details on his page. Some of the analysis on this page appears to be incorrect, or uses nonstandard terminology.

Linux Gazette article on sound from the parallel port.

17 Comments »

  1. Steve said,

    October 24, 2005 at 6:58 pm

    TH Lee is heard saying, after trying your code, “The smell so bad.”

    Why don’t you try compressing the audio before you send it out the serial port. That will save time. I suggest a compression algorithm that will compress it down to 1 bit, indicating that it exists. That should suffice for most audiophiles.

    I think, for your next trick, you should hook up a modem and send the audio over a phone line.

  2. justin said,

    October 25, 2005 at 11:13 am

    This brings me back to the TRS-80 days where games produces sound, including occasionally digitized voice, through a cassette port which had only a single bit as well. out $FF,0 or out $FF,1 (scary that I remember that).

  3. lentilwallop said,

    October 26, 2005 at 10:58 am

    There used to be a Z-Shell program for the Ti-85 that did essentially this. The bottom port (1/8″) of the Ti-85 is a Serial Connection.

  4. Gabriele said,

    October 27, 2005 at 7:00 pm

    Back to my old Sinclair ZX Spectrum… Few assembly instructions to RECord and PLAY a 1bit audio stream… It sounded terribly (and quickly filled out 48KBytes of RAM), but was very exciting!

  5. BjornW said,

    October 29, 2005 at 6:04 am

    I was reading hackaday.com and I came across your project. I was wondering if it would be possible to create a simple music generator out of a 486 wih Debian and the serial port as output. So I’ working on it now. If you have any ideas about it, feel free to email me.

  6. Robert said,

    November 1, 2005 at 7:36 pm

    I saw this page and just HAD to try it. It was working great. I was playing “Usage of the word fuck” out of it to some headphones and although it contained a lot of noise, it was surprisingly good and wasn’t tinny like I had expected. All of a sudden, however, it stopped working. I just could not get it to work again. I tried to connect to a modem using cu and minicom, both froze… While bashing ^D, all of a sudden… *BEEP* bye bye 78 days uptime on my FreeBSD (yes FYI after a slight change in the Makefile it works fine under FreeBSD) box along with a handful of irritated users (including myself), who were using it at the time for IRC being booted off. Shit. The box (http://home.m33p.be/)is back up fine but the serial controller is now dead! The smell coming from the box confirms this – although I’ve yet to find the source, there’s no visable damage. Luckily it’s only a Celeron 300 machine and I was due to put it back to its original PIII 500 form with a different motherboard soon.

    A word of warning to anyone doing this: if possible use resistors/diodes to protect the controller otherwise the same may happen to you!

  7. Robert said,

    November 1, 2005 at 9:12 pm

    Following on from my previous post: The tape drive (an old Trakker 250 via floppy connection) nearly caught fire and I had to throw it in water to cool down. It hissed as it boiled the water on contact! I now have a very painful burn on the end of my finger from yanking the drive out after realising the source of the burning smell. Not sure if it’s related to motherboard damage from playing with the serial port or pure coincidence.

  8. Mark said,

    November 1, 2005 at 9:44 pm

    Sorry about your serial port. What kind of headphones were you driving?

    I wonder if the serial port is integrated with the floppy controller on that motherboard? I guess it’s too late to do a ‘lspci’ (or the BSD equivalent) to see what chips are being used.

  9. Robert said,

    November 2, 2005 at 6:12 am

    The headphones were some cheap folding ones but I was combining left and right together. You can see the output of pciconf here: http://home.m33p.be/~robert/pciconf

    The parallel port is working fine as I have a thermal printer attached to it spewing out selected output from syslogd.

  10. ian king said,

    November 9, 2005 at 10:16 am

    this is so cool i tryed to do this earlier and i blowed out my rs232 controler thanks fo the design

  11. Elektrojänis said,

    January 14, 2006 at 2:51 pm

    Hmmm… Maybe you should use an amplifier between the serial port and the speaker/headphones. Serial port’s are probably not be designed to drive low impedance loads. If you are clever you could work the amplifier in high efficiency class D.

  12. Liam said,

    January 18, 2006 at 9:34 am

    ^^^^ Agreed with Elektrojänis

    Even most soundcards have difficulty adequately driving a pair of headphones. It’s not so bad when connected to the input on an amplifier as the load effectively—>infinity. So effectively, the card will ‘see’ a huge load. The effect is particularly noticable in the bass tones, they litereally drop out when the load is too heavy (i.e. the cutoff increases). I’d assume the same for the serial port. In fact, if you’ve joined both headphones in dual-mono (parallel) then you’ll be dropping the impedence even more = more instantanious current = smoke your gear.

  13. BCP said,

    September 16, 2006 at 12:57 pm

    RS232 ports are designed with a current limit (12-20mA) in mind and will survive a direct short circuit…a better way to do this of course is a “covox device” which is a resistor DAC on the parallel port. Either way, its probably only usefull to do this is embedded devices/routers/etc for warning tones and such.

  14. bkizzy said,

    October 31, 2009 at 1:24 am

    Howdy! Nice work. I am built a microphone that connects to serial, but I can’t seem to get the data to be sound. How do I do that? Any tips would be greatly appreciated.

  15. Vladislav30 said,

    March 15, 2010 at 10:22 am

    Советую подписку на РСС поставить на видном месте! Читателей будет больше! Особенно на таком блоге, как у вас! Пробовала – у меня на 50% больше посетителей стало!

  16. Vladislav65 said,

    March 23, 2010 at 5:25 pm

    Я писал что-то подобное, но у Вас тема более глубого раскрыта

  17. Vladislav67 said,

    March 24, 2010 at 10:10 am

    Это должно быть в цитатнике

RSS feed for comments on this post · TrackBack URL

Leave a Comment