Background
As a terminal junkie, I've started messing around with a combination of mpd (Music Player Daemon) and a player, ncmpcpp (NCurses Media Player Client C++).
I installed these via Homebrew - a simple brew install mpd ncmpcpp
. A bit of configuration later, and the apps are running quite nicely. The effect is actually rather impressive:
The problem I run into is when I want to run mpd
automatically instead of having it launch in my terminal. It comes with a launchd
plist, so I install that, and it appears to work - The problem is that whatever I'm playing, be that an MP3, streaming audio from a server, or whatever, the audio stutters every 5 seconds
This absolutely does not happen when mpd
is invoked directly from the command line, only when it's fired off via launchd.
Here's what the plist looks like:
<!--homebrew.mxcl.mpd.plist-->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>KeepAlive</key>
<true/>
<key>Label</key>
<string>homebrew.mxcl.mpd</string>
<key>ProcessType</key>
<string>Interactive</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/opt/mpd/bin/mpd</string>
<string>--no-daemon</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>WorkingDirectory</key>
<string>/usr/local</string>
</dict>
The ProcessType interactive
was added by me in an attempt to force launchd to give the daemon higher priority, to no effect.
Debugging?
If we dtruss
the process, there is a huge blast of identical gettimeofday
messages correlated with every stutter. It looks like this:
gettimeofday(0x10A03FD40, 0x0, 0x1000) = 1428698761 0
Things I've already eliminated
- CPU / Disk IO
The system is relatively quiet - during the stutters, mpd is not even on the top 25 for memory or CPU usage, and load is well below 1.0
- Incorrect environment causing bad config settings to be loaded
My mpd config is the one being loaded from ~/.mpdconf
- same as it is when I run it by hand.
This appears to be a symptom of the way launchd chooses to handle the process.
The ultimate question
Why is the daemon so misbehaved when run under launchd, but not when run via terminal?
Bonus question:
What about the way launchd kicks off processes could be making this behavior manifest?