[pulseaudio-discuss] PulseAudio and AC3 passthrough

Tanu Kaskinen tanuk at iki.fi
Tue Jun 15 11:12:45 PDT 2010

On Mon, 2010-06-14 at 16:03 -0500, pl bossart wrote:
> > Do you plan to do it (the formatting) inside or outside libpulse?
> Outside (like in gstreamer/xine)

Maybe it would make sense to provide a helper function for converting
AC3 frames into spdif data blocks? That would ensure that the spdif data
buffer is layed out exactly as Pulseaudio wants.

> > Sink inputs would get a new flag: PA_SINK_INPUT_NONPCM. The flag would
> > mean that no automatic conversion may be done before passing the stream
> > data to the sink, and also that the sink must know what it's doing (=
> > understand the non-PCM semantics) if it wants to modify the stream data
> > in any way. For example, module-combine doesn't understand any other
> > data types than PCM, so module-combine couldn't accept AC3 streams. If
> > there was "module-combine-ac3" that would decode the stream, or use
> > magic to resample the raw AC3 data, then that would be fine.
> Yes the NON_PCM flag is needed.
> > Sinks would get a new function: pa_sink_accept_input(pa_sink *s,
> > pa_sink_input *si). The function would check whether the sink input is
> > suitable for that sink. It would be called inside
> > pa_sink_input_may_move_to() and inside pa_sink_input_put(), or if making
> > _put() a failable function is not acceptable, then whenever anyone wants
> > to call _put(), he must first call _accept_input().
> Yes as well. There are some issues though. On most systems,there's a
> separate device for digital outputs which isn't loaded by PulseAudio
> by default (only loads the first device). My s/pdif output is usable
> with hw:0,1 (although using hw:0,0 seems to work for PCM but not
> compressed, go figure).

Pulseaudio doesn't use hw:x style device identifiers, except when
nothing else works. Alsa provides the hw:spdif device alias, which
Pulseaudio should be able to use reliably to obtain access to the spdif

> > Sink implementers could provide a callback that would be called inside
> > pa_sink_accept_input(). By default inputs with the _NONPCM flag would be
> > rejected, but the ALSA sink and module-combine-ac3 would accept also
> > _NONPCM inputs if the sample format happened to be PA_SAMPLE_AC3 (for
> > ALSA sinks, of course only if the sink's sample format would also be
> >
> > So, I'd introduce a new sample format: PA_SAMPLE_AC3.
> No for this one. You need to keep the PCM format (frequency, # of
> bits) to allow for conversions between bytes/ms.

But AC3 is compressed. What sample rate, sample format and number of
channels would you use to get the correct bytes-ms conversion? The real
value for sample rate is usually 48 kHz, for sample format it's s24le(?)
and for number of channels it's 6. From that you can derive bitrate of
6.912 Mbps, but since the stream is compressed, the actual bitrate is
lower (3.072 Mbps), so you can't use those "real" values in the bytes-ms
conversion. If you mark the sample format to be PA_SAMPLE_AC3, you can
use that information to calculate the correct bitrate at given sample
rate (am I right in that the bitrate doesn't vary depending on the
number of channels?)

> > Preventing mixing would be achieved by the fact that either sinks only
> > accept one AC3 stream at a time, or they don't use pa_sink_render(), but
> > do the mixing themselves if they somehow can handle that. I think
> > pa_sink_render() should be safe for the ALSA sink to use as long as
> > there's only one input and the sample rates match[1]. (I assume AC3
> > streams always have six channels. If that's not the case, then there are
> > more complications.)
> I didn't think of this one. Essentially you rely on the sink to
> perform this exclusion. Why not?
> > Avoiding applying sw volume could be done by introducing another sink
> > input flag: PA_SINK_INPUT_NO_VOLUME and making sure that such sink
> > inputs are initialized with PA_VOLUME_NORM. pa_sink_input_set_volume()
> > would contain an assertion making sure that it's not called for inputs
> > with that flag. That would mean that all the places that call
> > pa_sink_input_set_volume() would need to be adapted. The detail that
> > even while conceptually the sink input wouldn't have volume,
> > initializing the volume to PA_VOLUME_NORM would probably save us from
> > touching pa_sink_render() code.
> I will have to look into this one. I have no idea what PA_VOLUME_NORM means.

PA_VOLUME_NORM is just a constant defining the 100% aka 0dB volume, i.e.
no amplification or attenuation.

> > Similar flag would be needed for sinks too, and similar modifications to
> > the places that call pa_sink_set_volume().
> >
> > I think that covers the most important pieces. The lack of volume would
> > need to be communicated to clients somehow (with sink and stream flags
> > probably). But old clients wouldn't understand that anyway - when a
> > client tries to set the volume of a sink or stream without volume, then
> > just make the operation fail, or make the operation a no-op.
> >
> > [1] Is it a problem that a sink can't reconfigure its sample rate at
> > runtime? According to Wikipedia, an AC3 stream's sample rate can be
> > either 32 kHz, 44.1 kHz or 48 kHz. It would seem to me that the sink
> > should reinitialize its sample rate whenever a new AC3 stream is
> > connected to it, otherwise the user can play only those files that have
> > the right sample rate.
> Yes you need the ability to change frequencies (although in 99% of the
> cases it's going to be 48kHz since it works better with video).
> But since mixing isn't possible, there's no problem with dynamic
> configuration. You can only play one stream at a time, and you can set
> the sink frequency to be equal to the stream frequency.

I guess stuff doesn't break too horribly if you silently reopen the alsa
device whenever a new stream is connected, but that's not very clean
solution. At least that would mean that clients that use the sink sample
rate information for something would have wrong information, because the
sample rate change doesn't (at least currently) generate any event to

Another possibility would be to generate separate card profiles for each
of the sample rates. However, I don't think it makes conceptual sense to
have separate profiles (and thus sinks) just for different sample rates.

I think I would solve this by making it "officially" possible for any
sink to change the sample rate dynamically at runtime, so that clients
get proper notifications etc. I would make changing the sample rate
possible only when the sink is idle - changing the sample rate at
arbitrary time would probably introduce a lot of complexity that,
however, wouldn't be needed for anything in practice.

What plans do you have about the UI in general? What configuration, if
any, the user has to do before playing back an AC3 file?

Tanu Kaskinen

More information about the pulseaudio-discuss mailing list