Devious Fish
pianod2 music server
profile for Perette at Stack Overflow, Q&A for professional and enthusiast programmers

Some pianod Uses

Home Automation

The X10 daemon I use (a customized version of Anya Turnquist’s exTENd) can be set up to invoke an arbitrary command in response to an X10 event. I imagine most home automation systems have similar facilities.

I use invokable shell script (using the #!/bin/ksh syntax; see exec(2) if you’re unfamilar with UNIX’s #!) that issues piano commands in to control pianod in response to clicks X10 controllers through the house. Shell scripts make great “impedance matching” tools to get different utilities to work together. If you’re not acquainted, I recommend taking some time to familiarize yourself with (in order of preference) ksh(1)1, bash(1), or sh(1). Don’t waste time on csh(1) and variants; they don’t have functions and csh programming is considered hazardous.

Shared Music Server with Autotuning

pianod implements an algorithm to select stations best compatible with the current listeners. It can determine who is listening in 2 ways:

Each user indicates whether they like, hate, or are neutral about each station. Whenever the listener list changes, pianod adjusts the stations to the current listeners, prefering:

If no agreeable stations are found, or there are no listeners, pianod provides silence.

Automixing

A nice feature of Pandora is the wide selection of music it offers. It makes it easy to define collections of different genres and styles, then blend them based on your mood with the shufffle (formerly the QuickMix). However, there are times it would be nice to preprogram the mood—for example, “setting a mood”.

You might want the evening to start with some nice classical piano for dinner, change to something a little more romantic later in the evening, and finally switch over to your love goove as the night heats up. A mixplan is a declarative program that describes how you want the music to mix:

# My Romantic Evening mixplan
now piano concerti
18:00 start // start playing
20:00 jazz fusion
21:00 barry white radio
// Justify My Love Radio refers to the song on Madonna's
// "Erotica" song
22:00 justify my love radio + yes radio
00:00 stop

The format is simply a time (or “now”) followed by a list of patterns that will match station names. Comments are allowed in shell (#) and C++ (//) form.

The runmix script included in the contrib directory is used to run mixplans. The format is:

runmix [-n] <mixfile>

The -n option causes the mixplan to be validated without scheduling/execution.

A mixplan is valid if every station pattern (not line) matches 1 or more station. Patterns matching 2 or more stations are reported, but considered valid.

If a mixplan is valid, at(1) is used to change the mix at the requested times. Note on OS X, at must be manually enabled. See atrun(8) for instructions.

Blending Automixes

The automix sample above is a start, but the transitions may be a bit harsh. After sketeching out what I want to achieve, I find it pleasing to add steps in between to make the transition more gradual:

# My Romantic Evening mixplan
now piano concerti
18:00 start // start playing
19:00 piano concerti + light jazz
19:20 light jazz
19:40 light jazz + jazz fusion
20:00 jazz fusion
21:00 jazz fusion + funk radio // Trying the transition via funk
21:20 funk radio + yes radio 
21:40 yes radio
// Justify My Love Radio refers to the song on Madonna's
// "Erotica" song
22:00 justify my love radio + yes radio
00:00 stop

Now that the music is planned, there’s just getting some candles, preparing a nice meal, and finding a date!


  1. I prefer ksh because when dealing with pipelines, the current process performs the tail of the pipe, which is usually What You Want (i.e., collecting some output for further manipulation). However, this diverges from the original sh(1) behavior in which the current process performs the front of the pipe (which requires redirecting output into a temporary file, then extracting it without using a pipe before further processing).  ↩︎