[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