I have a USB soundcard attached to my RPi. I used the command

sudo modprobe snd_pcm_oss

which created /dev/dsp and /dev/dsp1. /dsp corresponds to the internal soundcard whereas /dsp1 corresponds to the outer devie.

When I type in:

sudo cat sample.wav > /dev/dsp1

all I get is glitchy and extremely distorted sound. The same goes to when I cat the sound sample into the internal soundcard.

The conventional method works just fine (for external device):

sudo aplay -D plughw:1 sample.wav 

OR (for internal device):

sudo aplay sample.wav

Why am I getting distorted sound when I pipe my sound files through /dev/dsp or /dev/dsp1?

I've tried both 16-bit PCM and 32-bit float, but both of them result in distorted sound.

  • Just so you know, /dev/dsp is OSS and deprecated. It should still work if it's present, though. One thing you could try is a signal generator. Try looking for the siggen package. This will help you figure out what kind of "glitches" we're dealing with. Btw, what is your operating system? Raspbian? – appas Jun 17 '15 at 0:21
  • @appas I'm using a Raspbian. – stock username Jun 22 '15 at 0:33

You are getting a distorted sound because the default settings for the old /dev/dsp* devices are 8 bit, 8 kHz sample rate, mono. To change this one must use ioctl() calls but of course if you use the '>' shell redirect doesn't happen.

So what happens if you pipe in a 16 bit wav? The device will read in one byte at a time, but its input contains 2 bytes per sample. The 16 bits are spread over 2 bytes, one for the upper 8 bits and one for the lower 8 bits.

Example: a sine wave in 8 bits may produce the following sequence of values:

0 64 110 127 110 63 0 -64 -110 -127 -110 -63 0

This is one full cycle; the values go up and down smoothly.

The same sine in 16 bits has the following values:

0 16384 28377 32767 28377 16383 0 -16384 -28377 -32767 -28377 -16383 0

Again, going up and down smoothly. But what happens if we split the 16 bits into 2 8 bit quantities?

0 0 0 64 -39 111 -1 128 -39 111 -1 64 0 0 0 -64 39 -111 1 -128 39 -111 1 -64 0 0

Suddenly it becomes a chaotic sequence of values, and that is what you are hearing: noise.

So how do you fix this? You can try to convert the sample with sox, but of course that will severely downgrade the quality (I mean, 8 bits at 8 kHz is telephone quality...). So the best way, as you already discovered, is using aplay; it will set the device to the proper settings. If you want to play something from your own program, you must set the proper bit size, sample rate, number of channels etc. etc. using ioctl() calls. Search for 'oss ioctl'.


echo {0 64 110 127 110 63 0 -64 -110 -127 -110 -63 0} | sudo cat > /dev/dsp seemed to produce one sound will this work for piping that data. I actually got sound on my ubuntu machine so that was cool.

I really dont know what putting sudo cat vs. removing it does. I was just trying to ensure root priv without using su command. Is it supposed to sound like a brief tap on microphone or is that the sound from pop/click starting aplay.

So with the 16 bit sound it was big endian? The data 64bit flag on the second value became 64X16 for the 4 bit shift? Or 8 bit shift x 255?

In little endian 16 bit should still be 64? If you swap the lower and upper 8bits the sound will definitely be distorted.

  • I cannot understand what you're saying at all. Was this intended as an answer or a comment or a new question? – Brick Oct 29 '18 at 15:47
  • I was testing the answer and learning that the sound is stored in different ways some of them involve swapping the byte order I also learned that you need to enable the bell sounds in your terminal preferences. – openInvent Nov 6 '18 at 22:50

Your Answer

