Recently I have been exploring the enchanted /dev folder. I want to write some random data to an audio device in order to generate some noise.
I am using ALSA.
So I instruct cat to pipe some random data to the playback file in the /dev folder…
cat file-of-random-data > /dev/snd/pcmC0D0p
then I recieve what seems to be an error from cat
cat: write error: File descriptor in bad state
How can I fix this so I can hear some delicious static play from my sound card?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
I think the reason this isn’t working for you is because that interface has been deprecated. You normally can’t write audio using /dev/dsp
anymore, at least without being tricky.
There is a program that will accomplish this for you on your system: padsp
.
This will map the /dev/audio
or /dev/dsp
file to the new Audio Server system.
Fire up the terminal and get into root mode with sudo su
.
Then, I’m going to cat /dev/urandom
and pipe the output into padsp
and use the tee
command to send the data to /dev/audio
. You’ll get a ton of garbage in your terminal, so you may want to redirect to /dev/null
.
Once you’re in superuser, try this command:
cat /dev/urandom | padsp tee /dev/audio > /dev/null
You may even want to try with other devices, like your mouse: Use: /dev/psaux
, for instance or the usb driver. You can even run your memory through it:
/dev/mem
Hope this clarifies why it wasn’t working before.
Personally, I found the mouse and memory to be way more interesting than playing random static!
Method 2
cat /dev/urandom | aplay
is the command that needs to be typed. If you aren’t in “audio” group, you could prefix aplay with sudo. This also doesn’t interfere with any daemons (I was running pulseaudio
while this command was active and correctly heard the “noise”.
EDIT (Aug 6, 2019): In an older version of the command I also had a padsp tee
thing between the cat
and aplay
. Now that I’m actually working in the field I realise that it made absolutely no sense. Also, I know the updated command (the one visible now at the beginning of this answer) works because I use it several times a day at work.
Method 3
Try /dev/audio or one of the other devices under /dev/snd. Not all of them are audio data sinks, you might have caught a mixer, microphone, or something
Method 4
Is a sound daemon (e.g. pulseaudio
) holding a lock on the device? I think you can find out if anything else has a handle on it via lsof
.
Method 5
update (2020-12-25): I created a shell script for forwarding data from stdin to stdout which set up stdout if it is a PCM file. Check out https://github.com/pasqualirb/pcmsh.
TL;DR: The device’s parameters must be set before reading or writing data to it.
Step by step:
-
Open the PCM device. E.g.:
fd = open("/dev/snd/pcmC0D0p", O_RDWR)
. After open, PCM is inOPEN
state. -
Set parameters with
ioctl(fd, SNDRV_PCM_IOCTL_HW_PARAMS, (struct snd_pcm_hw_params*) p)
. The hardware parameters structure has masks (each bit is a value) and intervals ([minimum, maximum] range). The parameters that are not being set must be passed filled (all bits/values set for masks; full range for intervals). After setting hardware parameters, PCM is inSETUP
state. See pcm_set_config() of TinyALSA for code.Setting
ACCESS
,FORMAT
,RATE
,CHANNELS
,PERIOD_SIZE
andPERIODS
is sufficient. The other parameters are variants of these, exceptBUFFER_SIZE
that in some devices may be set to a non multiple ofPERIOD_SIZE
. -
Call
ioctl(fd, SNDRV_PCM_IOCTL_PREPARE)
to prepare device and ALSA runtime variables. After this, the PCM is inPREPARED
state. - Start reading (capture) or writing (playback).
A minimal application for reading or writing to a PCM device will have most of its code around hardware parameters manipulation.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0