The Adventures of Joshua Judson Rosen
(action man)

[ sections: VisualIDs | art | movies | everything ]

Page 1 of 40  >>

Tuesday, 26 Jul 2011
[@]

01:32: Whole-Home Audio with MPD + PulseAudio

I have a whole-home audio system that I cobbled together out of spare PCs and low-cost, low-power plug-computers running a mostly-stock Debian 6.0 with MPD and PulseAudio, and which works better than any of the prefabricated solutions that I could find. Not only is it better, but it deployed cheaper, and it was actually quicker to build it than it would have been to finish evaluating the canned solutions and buy one. And, since the protocols (and software) in use are all open standards and Open Source, there's no danger of vendor-lock.

This setup uses multicast RTP with latency-matching across all nodes in the network; I have only one `channel' right now (in the radio-tuner or input-switching sense, not in the `mono vs. stereo' sense), but it's possible to define multiple channels (or `sources', in proper home-audio vocabulary) by giving them separate multicast addresses, and then a given receiver can be siwtched to another channel just by changing the multicast address on which that receiver listens.

Because of the latency-matching, multiple receiver-nodes (to the extent that the ear can tell) all have their playback perfectly time-synced such that there's no `echo' or `reverb' effect when standing between two adjacent rooms with separate receivers. I actually compared this against how well two different FM radios in adjacent rooms sync to the same radio station, and the RTP system did better. Really, multicast RTP over ethernet + dynamic resampling-algorithms with latency-analysis on pentium-class CPUs with network time-sync... provides quite a convincing emulation of speaker-wire. Of course, it also provides a lot of dreamy features that speaker-wire... can't even dream about.

That it's MPD-based means that I can have a single playback- and playlist-control server for the entire house, accessible from anywhere on the network; in other words, I have multiple `single points of control': client UIs are available for desktop and laptop computers of all OSes, Android devices, my friends' Apple iThings (which can automagically discover the MPD server via ZeroConf), etc.--there's even an adaptor that enables `dumb phones' with Java ME to control MPD via bluetooth (or Wi-Fi, if they have it).

MPD manages playlists on the server, and can be told by the clients to load them or to create and store new ones--and playlists can include not just any of the tracks stored on the server, but also anything available via an HTTP URL (e.g.: Internet radio, or an audio-file shared by a laptop or other system on the LAN).

Of course, Using MPD also means that I can use all of the tools and plugins that exist for MPD--like last.fm/audioscrobbler support, and my `mpdjay' autojockey script (which elicited such a positive response from my wife--along the lines of `OMG it's so awesome! Can you make me a portable version‽'--that we now both have NanoNote units running a pocket-sized setup similar to this, but without the multicast).

And MPD does gapless playback, and it can use ReplayGain to automatically adjust for differences in overall volume between different tracks or albums--or even do dynamicrange compression when you want background-music in a relatively noisy environment. And, on the subject of volume-control: there's even a central volume-control--so that you can turn the whole house's volume up or down, after you've got the individual output-volumes set relative to each other.

We generally run GMPC or Sonata on our desktop and laptop systems (though I sometimes like ncmpc for its extremem keyboard-friendliness--and it's what I run on my NanoNote..., but that's mostly another story), my wife runs the Remuco JME app on her Nokia (Symbian) phone, we use PMix on our Android tablet, and our iFriends use something called "MPoD", when they're visiting. And there are plenty of other clients available.

How does it all work?

MPD runs on the machine hosting all of the audio-files, which is set-up as an RTP sender--and, in my case, without any local speakers: all of the `actual audio output' is done on `receiver' nodes elsewhere on the network (my MPD server is a noisy old machine that we keep down in the oubliette/basement).

In /etc/mpd.conf, MPD can be told to use PulseAudio for output with a stanza like:

audio_output {
    type            "pulse"
    name            "MPD Stream"
    sink            "rtp"
    description     "what's playing on the stereo"
    mixer_type      "software"
}

... where "rtp" is the name of a sink defined in /etc/pulse/default.pa via:

load-module module-null-sink sink_name=rtp format=s16be channels=2 rate=44100
load-module module-rtp-send source=rtp.monitor

That last line is the one that actually makes the RTP multicasting happen.

Now, keep all of the system clocks tightly synchronised so that PulseAudio can actually determine the network latency (by comparing the source timestamp on the RTP packets to the system time on the receiver), and then it's just a matter of also running Pulseaudio on the other hosts--but with those PulseAudio instances setup as receivers, which can be done in the respective /etc/pulseaudio/default.pa files with...:

load-module module-rtp-recv

... or, if you have a GUI running on the receiver machine(s), you can just toggle-on the `enable Multicast/RTP receiver' setting in paprefs.

Caveats

Actually, it can be a little more complicated, because:

  • PulseAudio defaults to doing something clever that should make playback better but which, as I understand it, tends to trigger bugs in ALSA; so any "load-module module-udev-detect" directives in default.pa may need to be modified to be "load-module module-udev-detect tsched=0" on each host.

  • There were major problems in PulseAudio's latency-matching code that weren't resolved until this past January; so you want PulseAudio 0.9.23 or later, but that didn't actually exist yet when Debian 6.0 was released. I just grabbed src/modules/rtp/module-rtp-recv.c from git and spliced it into the version of PulseAudio that Debian already had (there were a couple of minor wrinkles, there, that I needed to smooth out--nothing hard, though). Figuring out that this module was just buggy and needed to be updated was probably the biggest problem that I ran into.

  • The ARM-based plug-computers that I'm using have no floating-point units, which means that PulseAudio needs a little bit of additional configuration before it will work entirely right on them and produce sound reliably through the USB audio-adaptor.

  • If your RTP-transmitter machine has multiple network interfaces, make sure that you're routing the multicast packets out over the correct one--I did run into that problem!

  • If you're using DHCP, the system may hiccough when the hosts go through DHCP cycles, so you'll want to find a way of setting your network up such that your audio-system doesn't decide to renew its DHCP leases in the middle of a party.

Addenda

I initially installed PTPd for super-accurate clock-sync between hosts, but ntpd should actually provide sufficient precision. You can use PTP to ensure that all of the nodes on a LAN are kept in very tight sync, even if their collective idea of `what time is it?' isn't actually accurate. If your LAN is connected to the Internet, then it's probably sufficient to just use NTP--which will allow your clocks to also be accurate in addition to being reasonably precise.

I also installed rtkit, which PulseAudio can use to get realtime scheduling; in Debian, I had to get this from Wheezy/testing, but it installed fine on 6.0/Squeeze.

Under GNOME on my normal PCs, PulseAudio starts automatically; on the plug-computers, I had to find another way to make PulseAudio run automatically, and the most sensible thing was to hook into Debian's `ifupdown' system by adding `up' and `down' options to the definition of the plug's ethernet interface in /etc/network/interfaces, such that the complete definition of eth0 looks like this:

# The primary network interface
allow-hotplug eth0
iface eth0 inet dhcp
        up su pulse --login --shell /bin/sh \
                    --command 'pulseaudio --exit-idle-time=-1 --daemonize'
        down killall pulseaudio

The day after I got everything working, the hard disk in one of my `speaker-wire emulator' nodes died....

[Reply]


Monday, 30 May 2011
[@]

21:26: What have you tried?

If you've regularly googled for technical stuff as part of your job as a professional hacker over the past decade, you may have noticed the (ever increasing, it seems) number of dumb questions on developer forums--questions where people not only don't RTFM, but aren't even trying to solve it themselves. A friend of mine found himself wading through this when he came across Matt Gemmell's article, `What Have You Tried?'.

It made both of us smile, but I wish it hadn't--I wish it wasn't so right....

I've been periodically trying to reconnect with the Python programming community, over the past few years; I go back to the newsgroup/mailing-list... and, every time, find that a greater and greater share of the traffic is people just wanting someone else to do their homework for them.

Some of them, at least, are quite bluntly honest about it--writing things like, "I don't want to learn how to program or how to write Python, I just want to solve this problem". Some of them aren't. Neither group is really the type I want to hang with, though.

So I find myself drifting further away from the Python community, and thinking that maybe it's just not even a world I want to be part of anymore--I seem to remember a time when most of the people there seemed bright and help-ful, but now they're all so dull and help-less, and most of the ones who have any intent seem to be set on just making rude noises. And I wonder if maybe it's just that I've changed since that time--if maybe I used to be more like the current crowd.

But I'll bet that the crowd has actually changed, too--and that it's largely just the sort of change that comes as a side-effect of popularity.

Back in 2004, Paul Graham wrote `The Python Paradox', which starts out:

In a recent talk I said something that upset a lot of people: that you could get smarter programmers to work on a Python project than you could to work on a Java project.

I didn't mean by this that Java programmers are dumb. I meant that Python programmers are smart. It's a lot of work to learn a new programming language. And people don't learn Python because it will get them a job; they learn it because they genuinely like to program and aren't satisfied with the languages they already know.

Which makes them exactly the kind of programmers companies should want to hire. Hence what, for lack of a better name, I'll call the Python paradox: if a company chooses to write its software in a comparatively esoteric language, they'll be able to hire better programmers, because they'll attract only those who cared enough to learn it.

Seven years later, Python programmers are dumb. What happened? Well, now Python is something that can get you a job--it's actually popular. And so is programming in general--I guess college-bound kids finally got wind of how much some of us get paid, in this field (or something--though I guess they somehow missed the parts about things like 80-hour work-weeks).

I guess it just makes those of us who can actually think and learn and do stuff look better, though....

[Reply]


Wednesday, 15 Dec 2010
[@]

11:52: Linux has won--without needing anyone to notice.

Someone in my local LUG remarked:

So, while I've been slaving away in the world of corporate IT, it appears Linux has quietly won the OS war. I just didn't notice. Linux may already be out-shipping Microsoft Windows.

... noting that it's actually quite difficult, if not impossible, to buy a TV that's not running Linux internally anymore.

Another member further remarked on the general prevalence of Linux in the embedded market--wondering, quasi-ironically, if maybe even his microwave oven might be Linux-based without him knowing. It's actually not beyond the realm of believability--Electrolux does actually have [a fridge that's Linux-based] (http://www.enlightenment.org/?p=news/show&l=en&news_id=26).

Several years ago, I was at the movie-theatre down in Lowell, MA, with a friend who had a thing for photo-booths, when I discovered that the photo-booth there was running Red Hat Linux.

`Embedded Linux' was already pretty pervasive, even at that point-- having worked its way into a lot of types of devices that people don't even expect to be `digital' inside, let alone be `computers': photo-booths, A/V amplifiers and other stereo equipment, batteries, telephones (well before Android), the telephone network....

Now it's also refrigerators, televisions, toys for small children, e-Books, motorcycles, guitars, personal audio-players, video games....

As Mark Weiser wrote in `The computer for the 21st Century':

The most profound technologies are those that disappear. They weave themselves into the fabric of everyday life until they are indistinguishable from it.

They're the things that happen without anyone noticing that they happened--changes that become visible only in retrospective.

And it's by design, actually.

Part of what's going on here is that more and more `mundane' objects are advancing technologically and becoming `smart'; and, when they do, they use Linux--because Linux is the thing that's making that advance possible in the first place. Develop your own thing from scratch? Pay to license something more obscure, and get a smaller talent-pool? Linux is a commodity. You're not supposed to notice when it gets used, just like you're not supposed to notice when 5-volt circuits (with connectors made by... what manufacturer?) get used.

At least, that's my perspective from the inside--that's why my groups have been shipping Linux for the past decade.

The amazing thing is that Linux-uptake just seems to keep accelerating....

[Reply]


Wednesday, 19 May 2010
[@]

01:33: Completely-unmaintained packages that YOU USE...

On Ubuntu, you can get a list of packages that are installed on your system but completely unmaintained by running this command:

dpkg --get-selections | grep '\Winstall' | cut -f1 | xargs apt-cache show | egrep '^Filename: pool/(universe|multiverse)/.*' | sed -re 's:.*/([^_]+)_(.*)_.*:\1:' | less -N

Packages in this list have not had time allocated to them for integration or QA prior to release, and they do not receive regular security-updates or bug-fixes following initial release.

As one moves further off-centre from Ubuntu's primary target-audience, the number of items in that list increases, and which items they are becomes more unsettling.

For example: I prefer to use the official GNOME web-browser, Epiphany--for reasons nicely summarised on Daniel Bo's weblog. Ubuntu shipped no updates for Epiphany during the lifetime of Ubuntu 9.10 (Karmic Koala), despite there having been several provided by Ubuntu's upstream community--with the first update making its way into Debian just 2 weeks after the initial (random?) snapshot was made for Karmic. That's no updates for the GNOME web-browser available through Ubuntu until the next release, 6 months later. If you stick with Ubuntu's Long Term Service (LTS) releases, then you can expect to go 2 years with no updates for this or any other package in the `universe' or `multiverse' sections of Ubuntu.

Having my web-browser, or anything else that faces the network, go without security-updates should be unsettling enough; but there are other items in my list that are even more unsettling: packages like gnutls-bin, which is supposed to be a security tool. And there are enough other `minorly-unsettling' items in my list that the sheer number of them all together is itself unsettling.

A friend was surprised to find that the "OTR" plugin for Pidgin, which he used to keep his IM conversations secure, is in universe-- which, again, means that he cannot expect security updates for it. So much for his secure conversations.

How many items are in your list, and what are they?

[Reply]


Sunday, 14 Feb 2010
[@]

20:51: Love Bug(fix): libvisualid 0.2.1

It's Valentine's Day and libvisualid 0.2.1 is out, to fix some bugs that managed to escape with version 0.2.0; changes include:

  • Automatic complexity-limiting is actually enabled.
  • A divide-by-zero bug affecting the rendering of line-glyphs with exactly one `rib' sub-glyph has been fixed.
  • Under-reporting of the complexity added to Line-glyphs by multiple `ribs' has been fixed.
  • Two issues in the best-common-substring logic used to associate file-names with pre-existing VisualID-glyphs for other, related files have been resolved: memory-leaks have been fixed, and strings that were treated as circular are now treated correctly.
  • The VisualID Explorer now renders glyphs with a fixed 1:1 aspect-ratio, scaled without distortion to fit the available drawing-area.

[Reply]

Page 1 of 40  >>