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