[pulseaudio-discuss] Shoutcast/Icecast sink for pulseaudio

Sean McNamara smcnam at gmail.com
Thu May 8 10:50:19 PDT 2008


Hi,

There's definitely an appeal to simplicity for being able to declare, in 
default.pa,

load-module module-icecast-sink var1=val1 var2=val2 ...

However, there are already solutions that allow you to take the output 
of PulseAudio and pipe it into an Icecast2 server. Darkice is an 
Icecast2 Source which accepts an input channel from an ALSA device, and 
it happens to work well with the ALSA<->Pulse plugin for libasound2.

In PulseAudio, every sink has a corresponding loopback device, also 
known as a monitor source. By setting your PA server's default input 
sink to the monitor source of the sink producing the desired sound, you 
can pipe any PulseAudio sound to icecast2. By making the sink a null 
sink, you can opt to route audio through PulseAudio to DarkIce without 
needing any sound hardware. In this case, the null sink will not produce 
any sound through PA directly, but as DarkIce monitors the sink, it is 
able to read the data just before PulseAudio discards it.

Having never written a PA module myself, I'm not sure what complexities 
might be encountered by trying to fit an Icecast2 source library into 
the PA framework. If the sink idiom isn't a good fit for some reason, 
you could instead write a general module that accepts a parameter for 
which sink to monitor, then monitors it and streams that using libshout.

You could also not write a module at all, but just a client program 
*similar to* DarkIce, but which speaks the native PA protocol. But by 
the time you do that, you could have just as easily extended DarkIce 
with native PulseAudio support. And DarkIce is sufficiently robust that 
you'd be reinventing many spokes of the wheel.

The UNIX philosopher in me says it's good to maintain separation of 
concerns between Icecast sources (like DarkIce, or better, mpd) and PCM 
sound servers (like PulseAudio). Imagine if we tried to merge the 
concerns of "cp", "mv" and "ls" into a single program: yuck! Another, 
closer analogy would be, trying to implement VNC as an Xorg DDX (a 
display driver extension). Double yuck! PulseAudio is to Icecast2 as 
Xorg is to VNC.

Note: I would *completely* be in favor of implementing a robust 
PulseAudio interface for DarkIce, so we wouldn't have to rely on the 
functioning of the ALSA compatibility layer for this. ALSA<->Pulse is an 
interim solution that could break whenever there are changes to libasound2.

Now just a few inline comments :)

Matthew Patterson wrote:
> Hey everyone,
>
> In my quest to further expand my whole home audio solution I was 
> thinking about the options for piping the music to non pulse supporting 
> devices like my internet tablet and cell phones. Right now I stream to 
> these devices simply by giving them playlists that target my webserver, 
> but I have tried in the past icecast2. This has the added benefit of 
> normalizing the stream bitrate for the lower bandwidth of the cell phone 
> (and is essential now that I am moving to flac as my primary format).
>   
Yeah, native PulseAudio over a network is too much bandwidth for most 
networks, except LANs operating under low load. With Shoutcast/Icecast, 
you lose a little bit of quality, gain a ton of latency, but the 
bandwidth needs are more realistic.
> Has anybody worked on a solution for pulseaudio -> shoutcast/icecast?
Yes, and it doesn't require a single line of code! See the above DarkIce 
explanation.
>  I realize icecast only takes mp3/ogg streams, so the raw pcm data would 
> have to be piped through an encoder on the fly,
True. libshout does not provide encoding facilities. MPD does this very 
well; it can accept a number of input formats, routes them through 
low-level audio libraries (libFLAC, libtheora, libmikmod, libmad, etc) 
and converts them into a format supported by libshout. To interface 
pulse with libshout, you'd only need the ability to convert PCM into 
MP3, and PCM into Ogg/Vorbis, since all PA data is PCM. For format 
conversion, I'd advise against depending on a media framework (Gstreamer 
or Xine or even ffmpeg), since any "good" PA module would ideally be 
integrated to the PA tree... and we don't want PA depending on Gstreamer 
or Xine or ffmpeg.
>  then shipped to the 
> icecast server. I also realize synchronization would be lost, but 
> wouldn't this be a cool addition!
>   
Actually, I'm not sure how you would measure latency, synchronize, or 
implement buffer rewriting with this, if you used a sink module as your 
base. It'd be strange to explain to pulsecore that the libshout send 
buffer is a really huge buffer of non-PCM data which has no 
correspondence to the data PA clients are writing to the sink. How would 
you implement rewinding or hot-swapping?
> Any ideas?
>
> Matt
>   
You're welcome to try the PA module architecture for this; it may turn 
out better than I expect. But if you're just an end user looking for a 
quick fix, go with DarkIce. I can add stuff to the PA wiki about DarkIce 
using ALSA<->Pulse if you like? Let us know if you have trouble with the 
setup.

-Sean




More information about the pulseaudio-discuss mailing list