[alsa-devel] [RFC] Channel mapping API
Takashi Iwai
tiwai at suse.de
Tue Aug 21 14:06:09 CEST 2012
At Tue, 21 Aug 2012 13:24:53 +0200,
David Henningsson wrote:
>
> On 08/21/2012 12:31 PM, Takashi Iwai wrote:
> > Hi,
> >
> > this is a progress report of my longstanding TODO, the channel map API
> > implementation. I'm going to cover this at Plumbers audio uconf, so
> > we can discuss details there, too.
> >
> > The channel mapping API provides a method for user-space to query, get
> > and set the channel map of a PCM stream. It's required for assigning
> > channels properly for multi-channel streams.
> >
> >
> > * KERNEL IMPLEMENTATION
> >
> > In my latest attempt, I implemented with control elements. A control
> > element is created for each PCM substream with the corresponding
> > device and substream index. Then it gives a TLV for querying maps, a
> > read op for obtaining the current map, and optionally a write op for
> > setting the map. The obvious merit by this way is that no extra
> > kernel ABI is required.
> >
> > A couple of new helper functions are provided for assigning standard
> > channel maps. Currently, HD-audio and AC97 drivers has some
> > implementation.
> >
> >
> > * ALSA-LIB IMPLEMENTATION
> >
> > The additional alsa-lib API functions look like:
> >
> > int **snd_pcm_query_chmaps(snd_pcm_t *pcm);
> > int *snd_pcm_get_chmap(snd_pcm_t *pcm);
> > int snd_pcm_set_chmap(snd_pcm_t *pcm, const int *map);
> >
> > snd_pcm_query_chmaps() returns the list of channel maps. A channel
> > map is represented by an integer array, beginning with the channel map
> > type, followed by the number of channels, and the position of each
> > channel, e.g.
> > { SND_CHMAP_FIXED, 4, SND_CHMAP_FL, SND_CHMAP_FR, SND_CHMAP_RL, SND_CHMAP_RR }
> >
> > snd_pcm_get_chmap() returns the currently assigned channel map for the
> > given PCM stream. If the PCM is before prepared, it fills UNKNOWN.
> >
> > When a driver allows user to change the channel map, user can call
> > snd_pcm_set_chmap(). For example, HDMI allows you to choose whether
> > it's 4.0 or 3.1 output.
>
> Interesting. A few thoughts here:
>
> 1) You seem to have invented new constants for different channels
> (SND_CHMAP_FL for "front left" etc). There is already a channel
> enumeration in include/mixer.h, _snd_mixer_selem_channel_id. Is there a
> reason we can't just reuse it for this purpose?
No big reason, but a minor reason would be that UNKNOWN = -1 is
a bit impractical and the mixer id definition lacks some new
positions. And, this is for mixer, and another for PCM, so using
SND_MIXER_* doesn't sound right.
But adjusting to follow the same values won't be a big issue.
Let's see.
> If we can't, we should at least make sure that everywhere we have these
> declarations, they always correspond to the same value and add comments
> that they need to be kept in sync.
>
> 2) a chmap struct would probably be more elegant, something like:
>
> struct snd_chmap {
> int type; /* or snd_pcm_chmap_type? */
> int count;
> int channels[SND_MIXER_SCHN_LAST+1]; /* Or variable length? */
> }
It should be a variable length. It could be with zero-size array,
though:
struct snd_chmap {
int type;
int count;
int channels[0];
};
Though, the type would be used only for queries (see below), so it
should be named like struct snd_chmap_query.
> 3) Can you use snd_pcm_set_chmap before snd_pcm_prepare, and if so, it
> seems a bit strange that snd_pcm_get_chmap does not return what you have
> previously set.
Setting or getting the channel map doesn't work before prepare (or
more specifically hw_params) because the number of channels isn't
determined yet. It's the only reason.
> 4) The question of memory allocation for _get and _query, who is
> supposed to allocate and free the snd_chmap array?
The caller. The helper function snd_pcm_free_chmaps() is provided,
too.
> 5) I'm not sure I'm getting the _VAR and _PAIRED types, even though I
> read the documentation. Is this for the query only? Or if not, what
> would it mean to get/set a channelmap with _VAR type?
Oh sorry, I must correct the description: get_chmap() returns only the
number of channels followed by channel elements. Ditto for
set_chmap(). The type is used only for query.
thanks,
Takashi
More information about the Alsa-devel
mailing list