Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Hah. I had a similar moment of enlightenment with FreeBSD when somebody explained that you can just cat a wav file into /dev/audio (or /dev/dsp? forget the exact name). And that you can produce white noise by catting /dev/random to the same destination. With no barrier to the sound card like that, I was free to experiment with programming dfferent noise algorithms and figuring out how digital audio works. I eventually did things the proper way with OSS and finally sndio on OpenBSD, but direct, universal interfaces like files invite that initial exploration and help you get things done quick and easy.

netcat is also a secret weapon around the house. My girlfriend runs macOS, but it's way more reliable to just nc files to each other over wifi than deal with all the cloud and airdropping bullshit.



When I was first learning Linux many years ago a friend and I got intoxicated and catted /dev/hda into /dev/dsp. It was all basically static with sometimes very structured patterns that we would try to guess as to what filetype was producing them. He had download and forgotten about a long uncompressed audio recording of a piano performance on his drive that suddenly started breaking through the static in chunks of varying length. We came to the conclusion that this was probably just what the kernel source sounded like.


mplayer -demuxer rawaudio -rawaudio rate=48000 -format s16le -af volume=-20 /dev/sda

Warning, headphone users: may hurt your ears. Trust me on the volume lowering.

With 16 bit samples and (default) two channels, you can recognizeably hear small integer values in your left ear. :)


I remember when I discovered that while in engineering school. I would try to pipe all kinds of files to see which ones had interesting acoustic signatures. I remember .iso files to be particularly interesting.


for i in $(seq 1 10); do seq -120 1 120; seq 120 1 -120; done | aplay

It's for you.


Good skills.

It has never occurred to me to do that but it is actually quite an obvious thing to do when you "know" that everything is a file.

Any idea what the visual equivalent would be?


If you've got a framebuffer console, I think you can cat to /dev/fb ... Although pixels are less friendly than audio, it's kind of helpful for identifying patterns if you preprocess so everything is shades of one color, or a byte -> color map anyway.


Plan9's /dev/draw.


ffmpeg can point directly to the webcam under /dev/.


> Any idea what the visual equivalent would be?

Perhaps:

head -c800 /dev/urandom > /dev/tty

Or:

mplayer -demuxer rawvideo -rawvideo w=80:h=60 /dev/urandom


> mplayer -demuxer rawvideo -rawvideo w=80:h=60 /dev/urandom

Change that to w=720 h=576 (for pal countries) and you can relive the glory days of analog TV static. Except not - mey memory seems to tell me it's more colourful. I guess it's to do with the limited chroma resolution in pal?


As far as I understand/remember it:

Analog color television color information is sent "out of band" from the point of view of black-and-white television (as a sideband frequency, with neat analog trickery to cancel out its effect on main signal). Color TV is backwards compatible. It's unlikely that random input happens to look like meaningful properly encoded color information, so television static is largely black and white.


You can reduce the saturation as desired (0.6 below):

mplayer -vf eq2=1:1:0:0.6 -demuxer rawvideo -rawvideo pal /dev/urandom


The secret of *nix that people don't like accepting is the file approach is often the right approach.

Consider lowly embedded linux. You COULD dig down deep into the documentation of which register, which interrupt, which special memory address needs to be written to interact with the right ports on a embedded linux board. All while adding a bunch of safeguards and checks to make sure "Only you are doing this".

Or, as if often the case, you can simply find the right /dev/xxxx device and read from it or write to it.

9 times out of 10, you'd not suffer any negative consequences from using the /dev/xxx system as intended and you get the bonus ability of being able to interact with the outside world using programming languages other than C.


The file approach ignores anything that exists (at least in part) in the time domain.

Audio files are (for me) the canonical example. A text file has no inherent bit-rate. An audio file being handled without knowledge of (even just) its sample rate has its semantics distorted or destroyed.

There's an awful lot of things you can do with the file approach, and I love it. Cross into the time domain and try to retain the same approach, and I say you're making a serious mistake.

What's worse is when the actual programming APIs (as opposed to just redirecting stdout to /dev/dsp) also fail to model the time aspect, and encourage programmers to think that you can just shovel data at a device without any consequences for your software's properties (like latency).


Many character devices do in fact have a bitrate.


It's mostly syntactic though, not semantic.


I don't think this has anything to do with the file approach per se, just with using an interface at a higher abstraction level.


My favorite version of this is reading from /dev/dsp will capture audio from the mic. I would cat this audio to /dev/dsp on another host over ssh in the school lab.


You used to be able to do that on Linux when its sound system was OSS ("Open Sound System", not "Open Source Software"), the same as FreeBSD uses today (I believe Linux still has an OSS compat layer). A long time ago the project lead was employed by a company to write support for some newer sound hardware, and decided to make those changes proprietary. The Linux folks decided to do something completely different, and we got ALSA, while some BSD folks decided to fork the last fully open source version of OSS and continue developing it.

The irony, of course, is that the proprietary version of OSS failed, and it ended up going open source again.


The difference is that on Linux, only one process can open /dev/dsp, which is why you need shims like aoss or padsp to run older games or other audio-programs without stopping all other sound sources / your sound server.

IMO, /dev/dsp was the right approach and should have been extended instead of being replaced with entirely different interfaces.


ALSA has compat modules for OSS.


I remember back when ALSA was a hot new thing on Linux, and it kinda sorta solved the "only one app can play things at the same time" problem that existed with the traditional OSS.

Meanwhile, OSS on FreeBSD just worked.


Rinse & repeat when every desktop environment brought their own audio daemons, then later PulseAudio and now PipeWire.

I still roll my eyes and I don’t get surprised every couple of years when somebody releases a yet another Linux audio daemon.

Maybe it’s some kind of Linux tradition.

At least PipeWire is saner compared to PulseAudio.


> every couple of years when somebody releases a yet another Linux audio daemon.

You seem to be stuck in, oh, maybe 2008.

There hasn't been "yet another Linux audio daemon" in more than a decade. JACK came along in the early 2000's (I wrote it), and PulseAudio in 2004 or thereabouts. All that nonsense with esd, artsd etc. was over because the aughts were over.


You seem to have missed pipewire.

While it supports the same APIs as Pulseaudio, it's still a new audio (and video) daemon.


The GP is about pipewire, and was complaining that it's "just another linux audio daemon". I concluded that it wasn't necessary to mention it in the context of my comment.


Thank You For JACK.

Even though i don't do audio on Linux.


artsd.... now that's a name I haven't heard in a long time!


My problem is that all of these are incompatible. Woe be to whomever has an OSS app, an ALSA app, a JACK app, and a PulseAudio app, all of which want to run at the same time.

I don't get why this was never fixed at the kernel level. You have onions of layers.


PipeWire solves this problem. It provides ALSA, JACK, and PulseAudio emulation (no one has actually used OSS on Linux in decades).

It is the audio solution for Linux.

PipeWire does video too, and when combined with a compatible Wayland compositor, serves as a replacement for remote X11.


Replace "PipeWire" with "PulseAudio" and hey look it's 2010 all over again.

Don't worry, THIS time we got right FOR SURE.


PulseAudio never intended to replace Jack. And in fact, that's one of its biggest failings.

FWIW, I have recently switched from PulseAudio to PipeWire. I remembered how rough the switch from plain ALSA to PulseAudio was, and thus was utterly baffled how smooth the transition to PipeWire is. I just uninstalled PulseAudio, installed PipeWire, rebooted, and everything just worked, down to the Bluetooth headset that I never quite got to work well with PulseAudio.


.... Wait a minute. You got a bluetooth headset working reliably with Linux? Tell me more...


Yeah, I had the same experience. With PipeWire it (mostly) just works, and reliably. The only thing I'm missing is always presenting the microphone as an usable device and only switching codecs/profile when the microphone is being used.


Since I switched to pipewire, my audio is crackling every time the cpu is loaded (a ryzen 7...) not even jack was struggling with that on this machine


Double check that you're running PipeWire with rtkit (this is the default with PulseAudio, AFAIK it is not the default yet on PipeWire).

It is really important to run a sound daemon with realtime privileges. This is the only way to ensure no cracks.


Thanks I'll check that


Pipewire is not finished at this point. It is being deployed "early" by some distros, apparently in the belief that it will help find bugs and help them being fixed.


> At least PipeWire is saner compared to PulseAudio.

In what way?


Pipewire implements both ALSA psuedo-devices, the JACK API and the PulseAudio API. You only need a single daemon to address all possible audio I/O needs, something that PulseAudio could not do.


That doesn't sound like a recipe for sanity.


My experience with pipewire is it works better than pulseaudio, is faster, has lower latency, and fewer bugs. And it gets better all the time!


What I don't like is that audio systems on Linux are too complicated. For example, all that ALSA needs to do is to provide exclusive access to a device (only one program at a time) and send samples into it unmodified (no bit depth change, no resampling, no mixing, no volume adjustment etc). But open source developers cannot do such a simple thing. They added thousands of unnesessary features, hundreds config options and turned ALSA into a monster. When it should be just a dumb backend for PulseAudio.


It didn't, though, initially. On hardware that supported multiple streams, it worked (assuming the driver for that hardware knew how to do it), but for hardware that didn't, you had to use the ALSA dmix plugin, which for the longest time wasn't enabled by default because it was the cause of some audio artifacts.


dmix is what I meant. But you had to use ALSA to use dmix, so in practice, it was the biggest reason to switch for most.


OSS got that ability decades ago, yet we still have ALSA and then the others :(


OSS did not have the ability when it was removed from the kernel and replaced by ALSA, which did have that ability already.

There were (and are) many problems with the OSS API, a number of which continue to exist in the ALSA API too.

All serious audio APIs (plugins, or native audio I/O) use a pull model at the bottom of the stack, so that i/o is driven by the hardware. You can layer a push model (where software does blocking read/write calls whenever it wants) on top of that, but not the other way around.

And yes, OSS and ALSA both implement select/poll etc. for audio devices, but do not enforce the use of this model, resulting in the 2000s being filled with Linux (and *BSD) apps that couldn't function correctly without oodles of buffering.


I remember the mixer interface (channel volumes, mute states, routing matrix) was far superior with ALSA.

I used a script to toggle the SPDIF output stream of my Soundblaster Live to get track marks on the Mini Disc player recording the output.


At some point you may get bitten by just nc’ing files around as tcp checksums alone are not that great. A lot of transfers or large files will at some point introduce errors. This is where an application layer error check may be desirable.


Is that really the case? (I mean i know in theory, but in practise does it matter?). Its not like http has its own checksum, and i've never had problems downloading over http (yes https does have better checksums, but i suspect it would just fail and not auto retry, which has never happened to me)


I've always verified the checksums of files transmitted via netcat and occasionally I have had different checksums. It's rare, and only on gigabyte+ files, but it has happened.


You should just use rsync - its been the best tool for transfering files between UNIXoids for the last 15-20 years for me and comes preinstalled with most distros (even macOS). It will take care of transferring only the required parts, and if you supply -c (slow!) it will even perform checksumming on both ends to assert files were correctly transferred and are bit-identical.


I was primarily using Android's busybox netcat, but I agree; there's always a better tool.


TCP checksums aren't that great, but you've usually also got lower layer CRCs which are much better. Though you can still get tripped up by misbehaving network hardware that corrupts a packet and then masks it by recomputing the CRC as the packet goes out again.


> My girlfriend runs macOS, but it's way more reliable to just nc files to each other over wifi than deal with all the cloud and airdropping bullshit.

I'd never though of that, so simple!

    # On the receiver
    nc -l 9000 > output.file

    # On the sender
    nc 172.17.0.7 9000 < input.file
My only issue is that it seems to hang after it's done. What am I missing?


Probably something about EOL, end-of-feed, CRLF-translation or something similar?

Netcat has plenty of (confusing) options, but there's usually a solution.


It also depends on which netcat you use. I usually use ncat (which comes with nmap) with the following invocations, and that never gave me any encoding/EOF/CRLF trouble:

  # on sender
  ncat --send-only --listen 12345 < file.zip
  # then, on receiver
  ncat --recv-only 1.2.3.4 12345 > file.zip


Yeah I did this at work recently with netcat. Our file sharing "solution" wasn't going to work so I just thought to try it for the hell of it.

I also setup a horrible video chat in bash using just vlc and netcat. Audio works better like this


I remember back in the day when I had some old HP behemoth my dad's office was throwing out... a 4100 or something like that.

I never bothered with a printing system.. I'd just cat a ps file to /dev/lp0


Is this a Linux feature or FreeBSD magic, as like the article seems to credit it?


> Is this a Linux feature or FreeBSD magic, as like the article seems to credit it?

Being able to just send wave data to the audio device "file" is pretty common on most systems that smell like Unix.

The netcat trickery from the article works on any platforms where netcat is available, what file formats are specifically supported varies by printer. Most will take text and Postscript (though some famous printers like the LaserJet 4 still had PS as an optional addon), anything more complicated is implementation-specific.


It's Unix magic remembered in the FreeBSD Handbook.


How do the device files know what format the audio data is in?


It doesn't, it just plays the data as PCM and with whatever sample format and sample rate it is currently configured for.


I'd guess the device files just pass through the binary data to the hardware, and then it's up to the audio device/driver what their defaults are (probably PCM 16-bit 44.1khz)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: