[vlc-devel] [PATCH 15/16] pulse: handle AUDIO_CHANNELS_TYPE_AMBISONICS
Thomas Guillem
thomas at gllm.fr
Mon Jul 10 15:00:20 CEST 2017
On Fri, Jul 7, 2017, at 17:16, Rémi Denis-Courmont wrote:
> Le 7 juillet 2017 17:03:01 GMT+03:00, Thomas Guillem <thomas at gllm.fr> a écrit :>> ---
>>
>> modules/audio_output/pulse.c | 90 +++++++++++++++++++++++++++++++++++++++++++-
>> >> 1 file changed, 89 insertions(+), 1 deletion(-)
>>
>>
>>
>> diff --git a/modules/audio_output/pulse.c b/modules/audio_output/pulse.c
>> >> index ac1254c8b9..ccec8df8f4 100644
>>
>> --- a/modules/audio_output/pulse.c
>>
>> +++ b/modules/audio_output/pulse.c
>>
>> @@ -74,6 +74,10 @@ struct aout_sys_t
>>
>> pa_stream_flags_t flags_force; /**< Forced flags (stream must be NULL) */
>> >> char *sink_force; /**< Forced sink name (stream must be NULL) */
>> >>
>>
>> + vlc_fourcc_t fourcc;
>>
>> + uint8_t chans_table[AOUT_CHAN_MAX];
>>
>> + uint8_t chans_to_reorder;
>>
>> +
>>
>> struct sink *sinks; /**< Locally-cached list of sinks */
>>
>> };
>>
>>
>>
>> @@ -490,6 +494,11 @@ static void Play(audio_output_t *aout, block_t *block)
>> >> aout_sys_t *sys = aout->sys;
>>
>> pa_stream *s = sys->stream;
>>
>>
>>
>> + if (sys->chans_to_reorder)
>>
>> + aout_ChannelReorder(block->p_buffer, block->i_buffer,
>>
>> + sys->chans_to_reorder, sys->chans_table,
>> >> + sys->fourcc);
>>
>> +
>>
>> const void *ptr = data_convert(&block);
>>
>> if (unlikely(ptr == NULL))
>>
>> return;
>>
>> @@ -687,6 +696,36 @@ static const char *str_map(const char *key, const char *const table[][2],
>> >> return (r != NULL) ? r[1] : NULL;
>>
>> }
>>
>>
>>
>> +static int channel_map_pulse_to_vlc(pa_channel_position_t map)
>>
>> +{
>>
>> + static_assert(AOUT_CHAN_MAX == 9, "Missing channels");
>>
>> +
>>
>> + switch (map)
>>
>> + {
>>
>> + case PA_CHANNEL_POSITION_FRONT_LEFT:
>>
>> + return AOUT_CHAN_LEFT;
>>
>> + case PA_CHANNEL_POSITION_FRONT_RIGHT:
>>
>> + return AOUT_CHAN_RIGHT;
>>
>> + case PA_CHANNEL_POSITION_SIDE_LEFT:
>>
>> + return AOUT_CHAN_MIDDLELEFT;
>>
>> + case PA_CHANNEL_POSITION_SIDE_RIGHT:
>>
>> + return AOUT_CHAN_MIDDLERIGHT;
>>
>> + case PA_CHANNEL_POSITION_REAR_LEFT:
>>
>> + return AOUT_CHAN_REARLEFT;
>>
>> + case PA_CHANNEL_POSITION_REAR_RIGHT:
>>
>> + return AOUT_CHAN_REARRIGHT;
>>
>> + case PA_CHANNEL_POSITION_REAR_CENTER:
>>
>> + return AOUT_CHAN_REARCENTER;
>>
>> + case PA_CHANNEL_POSITION_LFE:
>>
>> + return AOUT_CHAN_LFE;
>>
>> + case PA_CHANNEL_POSITION_MONO:
>>
>> + case PA_CHANNEL_POSITION_FRONT_CENTER:
>>
>> + return AOUT_CHAN_CENTER;
>>
>> + default:
>>
>> + return 0;
>>
>> + }
>>
>> +}
>>
>> +
>>
>> /**
>>
>> * Create a PulseAudio playback stream, a.k.a. a sink input.
>>
>> */
>>
>> @@ -804,6 +843,7 @@ static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt)
>> >>
>>
>> if (encoding != PA_ENCODING_PCM)
>>
>> {
>>
>> + assert(fmt->channels_type == AUDIO_CHANNELS_TYPE_PHYSICAL);
>> >> pa_format_info_set_channels(formatv, ss.channels);
>>
>>
>>
>> /* FIX flags are only permitted for PCM, and there is no way to pass
>> >> @@ -812,7 +852,7 @@ static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt)
>> >> | PA_STREAM_FIX_RATE
>>
>> | PA_STREAM_FIX_CHANNELS);
>>
>> }
>>
>> - else
>>
>> + else if (fmt->channels_type == AUDIO_CHANNELS_TYPE_PHYSICAL)
>> >> {
>>
>> /* Channel mapping (order defined in vlc_aout.h) */
>>
>> struct pa_channel_map map;
>>
>> @@ -861,6 +901,19 @@ static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt)
>> >> pa_format_info_set_channels(formatv, ss.channels);
>>
>> pa_format_info_set_channel_map(formatv, &map);
>>
>> }
>>
>> + else
>>
>> + { /* AUDIO_CHANNELS_TYPE_AMBISONICS */
>>
>> + fmt->channels_type = AUDIO_CHANNELS_TYPE_PHYSICAL;
>>
>> +
>>
>> + /* Use the channel layout of the sink and override the current one.
>> >> + * This new layout be will used to configure the ambisonics filter. */
>> >> + flags |= PA_STREAM_FIX_CHANNELS;
>>
>> +
>>
>> + /* Setup low latency in order to quickly react to ambisonics filters
>> >> + * viewpoint changes. */
>>
>> + flags |= PA_STREAM_ADJUST_LATENCY;
>>
>> + attr.tlength = pa_usec_to_bytes(2 * AOUT_MIN_PREPARE_TIME, &ss);
>> >> + }
>>
>>
>>
>> /* Create a playback stream */
>>
>> pa_proplist *props = pa_proplist_new();
>>
>> @@ -934,9 +987,44 @@ static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt)
>> >> fmt->i_rate = spec->rate;
>>
>> }
>>
>>
>>
>> + if (flags & PA_STREAM_FIX_CHANNELS)
>>
>> + {
>>
>> + const pa_channel_map *map = pa_stream_get_channel_map(s);
>> >> + assert(map != NULL);
>>
>> +
>>
>> + const char *name = pa_channel_map_to_name(map);
>>
>> + msg_Info(aout, "using %s channel map", (name != NULL) ? name : "?");
>> >> +
>>
>> + uint8_t chans_out_count = 0;
>>
>> + uint32_t chans_out[AOUT_CHAN_MAX];
>>
>> + fmt->i_physical_channels = 0;
>>
>> + for (uint8_t i = 0; i < map->channels; ++i)
>>
>> + {
>>
>> + int vlcchan = channel_map_pulse_to_vlc(map->map[i]);
>> >> + if (vlcchan != 0)
>>
>> + {
>>
>> + chans_out[chans_out_count++] = vlcchan;
>>
>> + assert(chans_out_count <= AOUT_CHAN_MAX);
>>
>> + fmt->i_physical_channels |= vlcchan;
>>
>> + }
>>
>> + }
>>
>> + if (chans_out_count != map->channels)
>>
>> + msg_Warn(aout, "%u channels won't be mapped",
>>
>> + map->channels - chans_out_count);
>>
>> + fmt->i_original_channels = fmt->i_physical_channels;
>>
>> + aout_FormatPrepare(fmt);
>>
>> +
>>
>> + sys->chans_to_reorder =
>>
>> + aout_CheckChannelReorder(NULL, chans_out, fmt->i_physical_channels,
>> >> + sys->chans_table);
>>
>> + }
>>
>> + else
>>
>> + sys->chans_to_reorder = 0;
>>
>> +
>>
>> stream_buffer_attr_cb(s, aout);
>>
>> stream_moved_cb(s, aout);
>>
>> pa_threaded_mainloop_unlock(sys->mainloop);
>>
>> + sys->fourcc = fmt->i_format;
>>
>>
>>
>> return VLC_SUCCESS;
>>
>
> Why do you impose the channel order here?!
I use the current channel layout of the pulse stream. The ambisonics renderer need the output channel layout untouched since the rendering algorithm depend of the channel layout.
> --
> Rémi Denis-Courmont
> Typed on an inconvenient virtual keyboard
> _________________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/vlc-devel/attachments/20170710/34e9ab5a/attachment.html>
More information about the vlc-devel
mailing list