[pulseaudio-discuss] RFC: New volume functionality for PulseAudio
Tanu Kaskinen
tanu.kaskinen at linux.intel.com
Fri Sep 12 04:43:15 PDT 2014
On Fri, 2014-09-12 at 08:35 +0200, David Henningsson wrote:
>
> On 2014-09-11 21:56, Tanu Kaskinen wrote:
> > How do you suggest pa_context_set_control_volume() to work?
> > pa_tagstruct_put_bvolume(t, &bvolume, channels) doesn't work as well as
> > I imagined it to work, because the channels parameter is unknown.
> >
> > My proposal is (still) to add a channels field to pa_bvolume, but there
> > are other ways too. The application could pass the number of channels
> > explicitly to pa_context_set_control_volume(), or the application could
> > pass the whole pa_control_volume_data object. libpulse could also
> > somehow cache the channel count when the application queries the volume
> > control info.
>
> Hmm. I'm leaning towards either of the two later ones. Probably the most
> flexible one would be to pass the whole pa_control_volume_data object.
> Then the user would essentially do:
>
> pa_context_get_control_volume(/*...*/, &control_volume_data);
What does this function do? There's no precedent for this kind of thing
in the introspection API. I'd expect the application to get the volume
data from a control info callback.
> pa_move_balance_to_the_left(&control_volume_data.volume,
> &control_volume_data.caps);
>
> pa_context_put_control_volume(/*...*/, &control_volume_data);
>
> Now that leaves the question of pa_move_balance_to_the_left (the name is
> just an example) should take a pa_control_volume_data or one bvolume and
> one bvolume_caps. The reason to split them up would be that then the
> bvolume_caps could be a const pointer and the bvolume be a non-const
> pointer, but maybe it's overkill and pa_move_balance_to_the_left could
> just use the entire pa_control_volume_data pointer instead.
You missed the part where you free the volume data. You can't allocate
the volume data from the stack, unless you also want to add this macro
and the pa_control_volume_data_size() function:
#define pa_control_volume_data_alloca() ((pa_control_volume_data *) alloca(pa_control_volume_data_size()))
By the way, alloca() is not in the POSIX standard. I'm not sure if
that's a problem regarding using it in the public API.
Here are two functions that do the same thing. The first version is what
I think you meant in your proposal, and the second is my proposal. Your
proposal has the disadvantage that the volume data has to be freed after
use, but my proposal has the (unexpected) disadvantage that it needs one
more variable to avoid excessive casting from the void data pointer to
pa_control_volume_data. I'll implement the first version, unless you
change your mind.
/*** first version, pa_bvolume without channels field ***/
static void get_control_info_cb(pa_context *context,
const pa_control_info *info,
int is_last, void *userdata) {
App *app = userdata;
pa_control_volume_data *data;
if (is_last < 0)
abort();
if (is_last > 0)
return;
if (info->type != PA_CONTROL_TYPE_VOLUME)
abort();
data = pa_control_volume_data_copy(info->data);
pa_control_volume_data_move_to_the_left(data);
o = pa_context_set_control_volume_by_index(context, info->index, data,
NULL, NULL);
if (!o)
abort();
pa_operation_unref(o);
pa_control_volume_data_free(data);
}
/*** second version, pa_bvolume with channels field ***/
static void get_control_info_cb(pa_context *context,
const pa_control_info *info,
int is_last, void *userdata) {
App *app = userdata;
pa_control_volume_data *data;
pa_bvolume bvolume;
if (is_last < 0)
abort();
if (is_last > 0)
return;
if (info->type != PA_CONTROL_TYPE_VOLUME)
abort();
data = info->data;
bvolume = data->volume;
pa_bvolume_move_to_the_left(&bvolume, &data->caps.channel_map);
o = pa_context_set_control_volume_by_index(context, info->index, &bvolume,
NULL, NULL);
if (!o)
abort();
pa_operation_unref(o);
}
--
Tanu
More information about the pulseaudio-discuss
mailing list