All of lore.kernel.org
 help / color / mirror / Atom feed
From: Markus Armbruster <armbru@redhat.com>
To: "Zoltán Kővágó" <dirty.ice.hu@gmail.com>
Cc: qemu-devel@nongnu.org, Gerd Hoffmann <kraxel@redhat.com>
Subject: Re: [PATCH v4 21/24] paaudio: channel-map option
Date: Wed, 25 Sep 2019 14:17:15 +0200	[thread overview]
Message-ID: <87impgy3hw.fsf@dusky.pond.sub.org> (raw)
In-Reply-To: <55ea6ac9-9651-e322-fd84-22b4bedb3a93@gmail.com> (=?utf-8?B?IlpvbHTDoW4JS8WRdsOhZ8OzIidz?= message of "Tue, 24 Sep 2019 02:43:32 +0200")

"Zoltán Kővágó" <dirty.ice.hu@gmail.com> writes:

> On 2019-09-23 15:12, Markus Armbruster wrote:
>> "Kővágó, Zoltán" <dirty.ice.hu@gmail.com> writes:
>>
>>> Add an option to change the channel map used by pulseaudio.  If not
>>> specified, falls back to an OSS compatible channel map.
>>>
>>> Signed-off-by: Kővágó, Zoltán <DirtY.iCE.hu@gmail.com>
>>> ---
>>>   audio/paaudio.c | 18 ++++++++++++++----
>>>   qapi/audio.json |  7 +++++--
>>>   qemu-options.hx |  9 +++++++++
>>>   3 files changed, 28 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/audio/paaudio.c b/audio/paaudio.c
>>> index d195b1caa8..20402b0718 100644
>>> --- a/audio/paaudio.c
>>> +++ b/audio/paaudio.c
>>> @@ -338,17 +338,27 @@ static pa_stream *qpa_simple_new (
>>>           pa_stream_direction_t dir,
>>>           const char *dev,
>>>           const pa_sample_spec *ss,
>>> -        const pa_channel_map *map,
>>> +        const char *map,
>>>           const pa_buffer_attr *attr,
>>>           int *rerror)
>>>   {
>>>       int r;
>>>       pa_stream *stream;
>>>       pa_stream_flags_t flags;
>>> +    pa_channel_map pa_map;
>>>         pa_threaded_mainloop_lock(c->mainloop);
>>>   -    stream = pa_stream_new(c->context, name, ss, map);
>>> +    if (map && !pa_channel_map_parse(&pa_map, map)) {
>>> +        dolog("Invalid channel map specified: '%s'\n", map);
>>> +        map = NULL;
>>> +    }
>>> +    if (!map) {
>>> +        pa_channel_map_init_extend(&pa_map, ss->channels,
>>> +                                   PA_CHANNEL_MAP_OSS);
>>> +    }
>>> +
>>> +    stream = pa_stream_new(c->context, name, ss, &pa_map);
>>>       if (!stream) {
>>>           goto fail;
>>>       }
>>> @@ -421,7 +431,7 @@ static int qpa_init_out(HWVoiceOut *hw, struct audsettings *as,
>>>           PA_STREAM_PLAYBACK,
>>>           ppdo->has_name ? ppdo->name : NULL,
>>>           &ss,
>>> -        NULL,                   /* channel map */
>>> +        ppdo->has_channel_map ? ppdo->channel_map : NULL,
>>>           &ba,                    /* buffering attributes */
>>>           &error
>>>           );
>>> @@ -470,7 +480,7 @@ static int qpa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
>>>           PA_STREAM_RECORD,
>>>           ppdo->has_name ? ppdo->name : NULL,
>>>           &ss,
>>> -        NULL,                   /* channel map */
>>> +        ppdo->has_channel_map ? ppdo->channel_map : NULL,
>>>           &ba,                    /* buffering attributes */
>>>           &error
>>>           );
>>> diff --git a/qapi/audio.json b/qapi/audio.json
>>> index 0535eff794..07003808cb 100644
>>> --- a/qapi/audio.json
>>> +++ b/qapi/audio.json
>>> @@ -214,13 +214,16 @@
>>>   # @latency: latency you want PulseAudio to achieve in microseconds
>>>   #           (default 15000)
>>>   #
>>> +# @channel-map: channel map to use (default: OSS compatible map, since: 4.2)
>>> +#
>>>   # Since: 4.0
>>>   ##
>>>   { 'struct': 'AudiodevPaPerDirectionOptions',
>>>     'base': 'AudiodevPerDirectionOptions',
>>>     'data': {
>>> -    '*name': 'str',
>>> -    '*latency': 'uint32' } }
>>> +    '*name':        'str',
>>> +    '*latency':     'uint32',
>>> +    '*channel-map': 'str' } }
>>>     ##
>>>   # @AudiodevPaOptions:
>>> diff --git a/qemu-options.hx b/qemu-options.hx
>>> index 395427422a..f3bc342f98 100644
>>> --- a/qemu-options.hx
>>> +++ b/qemu-options.hx
>>> @@ -471,6 +471,7 @@ DEF("audiodev", HAS_ARG, QEMU_OPTION_audiodev,
>>>       "-audiodev pa,id=id[,prop[=value][,...]]\n"
>>>       "                server= PulseAudio server address\n"
>>>       "                in|out.name= source/sink device name\n"
>>> +    "                in|out.channel-map= channel map to use\n"
>>>   #endif
>>>   #ifdef CONFIG_AUDIO_SDL
>>>       "-audiodev sdl,id=id[,prop[=value][,...]]\n"
>>> @@ -636,6 +637,14 @@ Sets the PulseAudio @var{server} to connect to.
>>>   @item in|out.name=@var{sink}
>>>   Use the specified source/sink for recording/playback.
>>>   +@item in|out.channel-map=@var{map}
>>> +Use the specified channel map.  The default is an OSS compatible
>>> +channel map.  Do not forget to escape commas inside the map:
>>
>> Awkward.
>>
>>> +
>>> +@example
>>> +-audiodev pa,id=example,sink.channel-map=front-left,,front-right
>>> +@end example
>>
>> Makes me realize new AudiodevPaPerDirectionOptions member @channel-map
>> is a list encoded in a string.  QAPI heavily frowns upon encoding stuff
>> in strings.  Any reason why you can't (or don't want to) make it
>> ['str']?
>
> Hmm, I don't think it's used too frequently on structs parsed by qapi
> opts visitor. What would be the command line format in that case?
> Something like this?
>
> -audiodev
> pa,id=example,sink.channel-map=front-left,sink.channel-map=front-right

Let's talk concepts before details.  I'll get back to this below.

> I think it's simply a string because while conceptually it's a string,
> we don't try to interpret it, we just pass the string to
> pa_channel_map_parse.  Of course we could take a list and instead
> either rebuild the string or reimplement half of pa_channel_map_parse
> by manually calling pa_channel_position_from_string.

Precedence: BlockdevOptionsRbd member @auth-client-required.  Under the
hood, this is Ceph configuration option auth-client-required.
Semantically a list of well-known values.  rados_conf_set() takes it
encoded in a string.  We could have plumbed that straight through QAPI
by making @auth-client-required a 'str'.  Instead, we made it
['RbdAuthMode'].  rbd.c has to encode the list in a string for
rados_conf_set().

Why did we bother?  Besides the dogmatic reason "do not encode stuff in
strings in QAPI", there's a pragmatic one: introspection.
@auth-client-required's type ['RbdAuthMode'] tells exactly what the
acceptable values are.  If Ceph ever grows another mode, QEMU support
for it will be visible in introspection: enum RbdAuthMode will have
another value.

Baking the acceptable modes into QEMU means new modes need a QEMU update
to work.  New modes that just work without a QEMU update feel unlikely.
If we're wrong, and a QEMU update is impractical, you can still work
around the limitation with a Ceph configuration file.

Which of these considerations other than "do not encode in strings"
apply to PA I can't say.

Let's turn the question around: is there any reason to break the "do not
encode in strings" rule other than "it saves a few lines of code"?

> Oh now that I looked again at the pulseaudio docs, channel-map doesn't
> have to be a list, it can be also a "well-known mapping name".

Unambiguous because the well-known mapping names are not valid channel
position list members.

Semantially, this is a disjoint union of well-known mapping names and
channel position lists.

The tools QAPI provides for disjoint unions are union and alternate
types.  In this case, an alternate of 'str' and ['str'] would do.
Well-known mapping names use the 'str' branch, channel position lists
the ['str'] branch.

>>
>>> +
>>>   @end table
>>>     @item -audiodev
>>> sdl,id=@var{id}[,@var{prop}[=@var{value}][,...]]

I promised you to get back to command line syntax.

The opts visitor uses repeated keys for lists, just like you guessed.
It supports only a subset of the QAPI types, and has weird magic for
integer lists.

-audiodev actually uses the QObject input visitor, which is more general
and somewhat less magical.  Its CLI syntax for lists is even wordier,
though.  I'd expect something like

    -audiodev pa,id=example,sink.channel-map.0=front-left,sink.channel-map.1=front-right

Aside: CLI QAPIfication will have to find a way to accomodate the opts
visitor's syntax and quirks, or break compatibility.


  reply	other threads:[~2019-09-25 12:19 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-19 21:24 [PATCH v4 00/24] Audio: Mixeng-free 5.1/7.1 audio support Kővágó, Zoltán
2019-09-19 21:24 ` [PATCH v4 01/24] audio: api for mixeng code free backends Kővágó, Zoltán
2019-09-19 21:24 ` [PATCH v4 02/24] alsaaudio: port to the new audio backend api Kővágó, Zoltán
2019-09-19 21:24 ` [PATCH v4 03/24] coreaudio: " Kővágó, Zoltán
2019-09-19 21:24 ` [PATCH v4 04/24] dsoundaudio: " Kővágó, Zoltán
2019-09-19 21:24 ` [PATCH v4 05/24] noaudio: " Kővágó, Zoltán
2019-09-19 21:24 ` [PATCH v4 06/24] ossaudio: " Kővágó, Zoltán
2019-09-19 21:24 ` [PATCH v4 07/24] paaudio: " Kővágó, Zoltán
2019-09-19 21:24 ` [PATCH v4 08/24] sdlaudio: " Kővágó, Zoltán
2019-09-19 21:24 ` [PATCH v4 10/24] wavaudio: " Kővágó, Zoltán
2019-09-19 21:24 ` [PATCH v4 11/24] audio: remove remains of the old " Kővágó, Zoltán
2019-09-19 21:24 ` [PATCH v4 12/24] audio: unify input and output mixeng buffer management Kővágó, Zoltán
2019-09-19 21:24 ` [PATCH v4 13/24] audio: common rate control code for timer based outputs Kővágó, Zoltán
2019-09-19 21:24 ` [PATCH v4 14/24] audio: split ctl_* functions into enable_* and volume_* Kővágó, Zoltán
2019-09-19 21:24 ` [PATCH v4 15/24] audio: add mixing-engine option (documentation) Kővágó, Zoltán
2019-09-23 13:08   ` Markus Armbruster
2019-09-24  0:21     ` Zoltán Kővágó
2019-09-25  9:49       ` Markus Armbruster
2019-09-29 19:07         ` Zoltán Kővágó
2019-10-01  6:23           ` Markus Armbruster
2019-10-03 23:27             ` Zoltán Kővágó
2019-10-07  8:21               ` Markus Armbruster
2019-09-19 21:24 ` [PATCH v4 16/24] audio: make mixeng optional Kővágó, Zoltán
2019-09-19 21:24 ` [PATCH v4 18/24] audio: support more than two channels in volume setting Kővágó, Zoltán
2019-09-19 21:24 ` [PATCH v4 19/24] audio: replace shift in audio_pcm_info with bytes_per_frame Kővágó, Zoltán
2019-09-19 21:24 ` [PATCH v4 20/24] audio: basic support for multichannel audio Kővágó, Zoltán
2019-09-19 21:24 ` [PATCH v4 21/24] paaudio: channel-map option Kővágó, Zoltán
2019-09-23 13:12   ` Markus Armbruster
2019-09-24  0:43     ` Zoltán Kővágó
2019-09-25 12:17       ` Markus Armbruster [this message]
2019-09-25 14:13         ` Gerd Hoffmann
2019-09-29 18:13           ` Zoltán Kővágó
2019-09-30  6:36             ` Gerd Hoffmann
2019-09-19 21:24 ` [PATCH v4 22/24] usb-audio: do not count on avail bytes actually available Kővágó, Zoltán
2019-09-19 21:24 ` [PATCH v4 24/24] usbaudio: change playback counters to 64 bit Kővágó, Zoltán

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87impgy3hw.fsf@dusky.pond.sub.org \
    --to=armbru@redhat.com \
    --cc=dirty.ice.hu@gmail.com \
    --cc=kraxel@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.