diff --git a/algos/demux/demux.rst b/algos/demux/demux.rst new file mode 100644 index 00000000..d0962617 --- /dev/null +++ b/algos/demux/demux.rst @@ -0,0 +1,138 @@ +.. _demux: + +Multiplexer/Demultiplexer +######################## + +Introduction +************ + +Multiplexer/demultiplexer component copies its input audio channels +into output audio channels according to specific routing +matrix. Multiplexer has multiple input audio streams and a single +audio output stream. Demultiplexer has a single input stream and +multiple output streams. In SOF codebase multiplexer and demultiplexer +are implemented in a single component as the operations and +configurations are overlapping heavily. + +.. figure:: images/muxdemux.png + + Multiplexer has exactly 1 output stream and demultiplexer has exactly + 1 input stream. + +Configuration +============= + +Component configuration defines how audio channels are copied from +input to output stream. As ASoC/SOF audio stream can have up to 8 +audio channels, a stream-to-stream specific 8 x 8 routing matrix +defines the channel mapping from input to output. Because every stream +is fully configurable we have a matrix for all multiplexer input +streams or all demultiplexer output streams. 8 x 8 binary matrix takes up +to 64 bits and is controlled with eight unsigned char values. + +.. figure:: images/mux.png + + Example of multiplexer configuration matrices with 2 input streams. + In this artificial Mux example Input stream 1’s channel 1 is copied + to both output channels, Input stream 2’s single channel is copied + also to output channel 1. + +.. figure:: images/demux.png + + Example of demultiplexer configuration matrices with 2 output streams. + In this artificial demux example input stream’s channel 1 is copied to + all output streams channels (1 channel to 4 identical channels in 2 + output streams) + +Using a routing matrix means also that this component can leave out +channels or mix multiple channels into one. + +Topology +======== + +Previous figures show that the routing matrix is difficult to +parametrize to be easily understandable. As it is sent to firmware +with 64 bits, it is quite tedious to easily see from hexadecimal or +integer values the binary routings. SOF topology m4 macros have helpers +to "visualize" the matrix for easier configuration. + +Example from pipe-volume-demux-playback.m4 shows how to define 2 +routing matrices and a demux component: + +.. code-block:: m4 + + # pipeline_id, channels, matrix_rows + define(matrix1, `ROUTE_MATRIX(PIPELINE_ID, 2, + `BITS_TO_BYTE(1, 0, 0 ,0 ,0 ,0 ,0 ,0)', + `BITS_TO_BYTE(0, 1, 0 ,0 ,0 ,0 ,0 ,0)', + `BITS_TO_BYTE(0, 0, 1 ,0 ,0 ,0 ,0 ,0)', + `BITS_TO_BYTE(0, 0, 0 ,1 ,0 ,0 ,0 ,0)', + `BITS_TO_BYTE(0, 0, 0 ,0 ,1 ,0 ,0 ,0)', + `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,1 ,0 ,0)', + `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,1 ,0)', + `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,0 ,1)')') + + # pipeline_id, channels, matrix_rows + define(matrix2, `ROUTE_MATRIX(5, 2, + `BITS_TO_BYTE(1, 0, 0 ,0 ,0 ,0 ,0 ,0)', + `BITS_TO_BYTE(0, 1, 0 ,0 ,0 ,0 ,0 ,0)', + `BITS_TO_BYTE(0, 0, 1 ,0 ,0 ,0 ,0 ,0)', + `BITS_TO_BYTE(0, 0, 0 ,1 ,0 ,0 ,0 ,0)', + `BITS_TO_BYTE(0, 0, 0 ,0 ,1 ,0 ,0 ,0)', + `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,1 ,0 ,0)', + `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,1 ,0)', + `BITS_TO_BYTE(0, 0, 0 ,0 ,0 ,0 ,0 ,1)')') + + # frame_format, num_channels, num_streams, route_matrix + MUXDEMUX_CONFIG(demux_priv, 2, 2, 2, LIST(` ', `matrix1,', `matrix2')) + + # demux Bytes control with max value of 255 + C_CONTROLBYTES(DEMUX, PIPELINE_ID, + CONTROLBYTES_OPS(bytes, 258 binds the mixer control to bytes get/put handlers, 258, 258), + CONTROLBYTES_EXTOPS(258 binds the mixer control to bytes get/put handlers, 258, 258), + , , , + CONTROLBYTES_MAX(, 304), + , + demux_priv) + + # Mux 0 has 2 sink and source periods. + W_MUXDEMUX(0, 1, PIPELINE_FORMAT, 2, 2, LIST(` ', "DEMUX")) + +In the above example you can see that the routing matrices have only +"diagonal" 1's, which means that input stream's channels +are copied to corresponding output streams channels. + +ALSA control +============ + +Multiplexer configuration is loaded in kernel/firmware boot as part of ALSA +binary control in topology, but can be also controlled through ALSA +controls. The quite complex binary control blob can be created with +a generic python tool: + +.. code-block:: python + + python sof_gen_blob.py -a 3 14 0 -t 18 -m 3H I 1B 8B 3B I 1B 8B 3B -v "2 2 2" "1" "2" "1 2 4 8 16 32 64 128" "0 0 0" "5" "1" "1 1 4 8 16 32 64 128" "0 0 0" + +Producing following output: + +.. code-block:: m4 + + sof m4 and ALSA conf format: + ` bytes "0x53,0x4f,0x46,0x00,0x12,0x00,0x00,0x00,0x3c,' + ` 0x00,0x00,0x00,0x00,0xe0,0x00,0x03,0x00,' + ` 0x00,0x00,0x00,0x02,0x00,0x02,0x00,0x02,' + ` 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x02,' + ` 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,' + ` 0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x01,' + ` 0x01,0x01,0x04,0x08,0x10,0x20,0x40,0x80,' + ` 0x00,0x00,0x00,' + + sof ctl tool format: + (4607827, 18, 60, 50388992, 0, 2, 2, 2, 1, 2, 1, 2, 4, 8, 16, 32, 64, 128, 0, 0, 0, 5, 1, 1, 1, 4, 8, 16, 32, 64, 128, 0, 0, 0) + +The sof-ctl tool can be then used to set the parameters through ALSA control: + +.. code-block:: bash + + sof-ctl -Dhw:0 -n 22 -s demux_coeffs.txt diff --git a/algos/demux/images/demux.png b/algos/demux/images/demux.png new file mode 100644 index 00000000..3d87dc79 Binary files /dev/null and b/algos/demux/images/demux.png differ diff --git a/algos/demux/images/mux.png b/algos/demux/images/mux.png new file mode 100644 index 00000000..65df01bd Binary files /dev/null and b/algos/demux/images/mux.png differ diff --git a/algos/demux/images/muxdemux.png b/algos/demux/images/muxdemux.png new file mode 100644 index 00000000..ea4b96a3 Binary files /dev/null and b/algos/demux/images/muxdemux.png differ