This example shows how to generate a stereo signal from a multichannel audio signal using matrix encoding, and how to recover the original channels from the stereo mix using matrix decoding. This example illustrates MATLAB® and Simulink® implementations. This example also shows how performance can be improved by using dataflow execution domain.
Matrix decoding is an audio technique that decodes an audio signal with M channels into an audio signal with N channels (N > M) for play back on a system with N speakers. The original audio signal is usually generated using a matrix encoder, which transforms N-channel signals to M-channel signals.
Matrix encoding and decoding enables the same audio content to be played on different systems. For example, a surround sound multichannel signal may be encoded into a stereo signal. The stereo signal may be played back on a stereo system to accommodate settings where a surround sound receiver does not exist, or it may be decoded and played as surround if surround equipment is present .
In this example, we showcase a matrix encoder used to encode a four-channel signal (left, right, center and surround) to a stereo signal. The four original signals are then regenerated using a matrix decoder. This example is a simplified version of the encoding and decoding scheme used in the Dolby Pro Logic system .
The audiomatrixdecoding model implements the audio matrix encoding/decoding example.
The input to the matrix encoder consists of four separate audio channels (center, left, right and surround).
Double-click the Audio Channels subsystem to launch a tuning dialog. The dialog enables you to control the relative power between the right channel and left channel inputs, as well as the power level of the surround channel.
You can also toggle between listening to any of the original, encoded or decoded audio channels by double-clicking the
Audio Player Selector subsystem and selecting the channel of your choice from the dialog drop down menu.
The Matrix Encoder encodes the four input channels into a stereo signal.
Notice that since the input left and right channels only contribute to the output left and right channels, respectively, the output stereo signal conserves the balance between left and right channels.
The surround input channel is passed through a Hilbert transformer, thereby creating a 180 degree phase differential between the surround component feeding the left and right stereo outputs .
You may listen to the encoded left and right stereo signals by double-clicking the Audio Player Selector subsystem and selecting either the 'Encoded Total Left' or 'Encoded Total Right' channels.
The Matrix Decoder extracts the four original channels from the encoded stereo signal.
The lowpass frequencies are first separated using a Linkwitz-Riley cross-over filter. For more information about the implementation of the Linkwitz-Riley filter, refer to Multiband Dynamic Range Compression.
The left and right stereo channels are passed through to the left and right output channels, respectively. Therefore, there is no loss of separation between left and right channels in the output.
The center output channel is equal to the sum of the stereo input signals, thereby cancelling the phase-shifted surround left and right components.
The surround output channel is derived by first taking the difference of the stereo signals. Since the original input center signal contributes equally to both stereo channels, the center channel does not leak into the output surround signal. Moreover, note that the original left and right signals contribute to the output surround channel. The surround signal is delayed by 10 msec to achieve a precedence effect .
You may listen to the decoded surround signal by double-clicking the Audio Player Selector subsystem and selecting one of the decoded signals.
This example can use dataflow execution domain in Simulink to make use of multiple cores on your desktop to improve simulation performance. To learn more about dataflow and how to run Simulink models using multiple threads, see Multicore Execution using Dataflow Domain (DSP System Toolbox).
In Simulink, you specify dataflow as the execution domain for a subsystem by setting the Domain parameter to Dataflow using Property Inspector. Dataflow domains automatically partition your model and simulate the system using multiple threads for better simulation performance. Once you set the Domain parameter to Dataflow, you can use Dataflow Simulation Assistant to analyze your model to get better performance. You can open Dataflow Simulation Assistant by clicking on the Dataflow assistant button below the Automatic frame size calculation parameter in Property Inspector.
In the Dataflow Simulation Assistant, click the Analyze button to start the analysis of the dataflow domain for simulation performance. Once the analysis is finished, the Dataflow Simulation Assistant shows how many threads the dataflow subsystem will use during simulation.
For this model, the assistant shows one thread because the data dependency between blocks prevents them from being executed concurrently. By pipelining the data dependent blocks, the Dataflow Subsystem can increase concurrency for higher data throughput. Dataflow Simulation Assistant shows the recommended number of pipeline delays as Suggested Latency. For this model, the suggested latency is two. Click the Accept button next to Suggested Latency in the Dataflow Simulation Assistant to use the recommended latency for Dataflow Subsystem. Dataflow Simulation Assistant now shows the number of threads as three, meaning that the blocks inside the dataflow subsystem simulate in parallel using three threads.
When latency is increased in the dataflow execution domain to break data dependencies between blocks and create concurrency, that delay needs to be accounted for in other parts of the model. For example, signals that are compared or combined with the signals at the output ports of the Dataflow Subsystem must be delayed to align in time with the signals at the output ports of the Dataflow Subsystem. In this example, the audio signal from the Audio Channels block that goes to the Audio Player Selector must be delayed to align with other signals going into the Audio Player Selector block. To compensate for the latency specified on the dataflow subsystem, use a delay block to delay this signal by two frames. For this signal, the frame length is 1024. A delay value of 2048 is set in the delay block to align the signal from the Audio Channels block and the signal processed through Dataflow Subsystem.
To measure performance improvement gained by using dataflow, compare execution time of the model with and without dataflow. The Audio Device Writer block runs in real time and limits the simulation speed of the model to real time. Comment out the Audio Device Writer block when measuring execution time. On a Windows desktop computer with Intel® Xeon® CPU E5-1650 v3 @ 3.5 GHz 6 Cores 12 Threads processor this model using dataflow domain executes 1.3x times faster compared to original model.
HelperAudioMatrixDecoderSim is the MATLAB function containing the audio matrix decoder example's implementation. It instantiates, initializes and steps through the objects forming the algorithm.
audioMatrixDecoderApp wraps around
HelperAudioMatrixDecoderSim and iteratively calls it.
audioMatrixDecoderApp to run the simulation. Note that the simulation runs until you explicitly stop it.
audioMatrixDecoderApp launches a UI designed to interact with the simulation. Similar to the Simulink version of the example, the UI allows you to tune the relative power between the right channel and left channel inputs, as well as the power level of the surround channel. You can also toggle between listening to any of the original, encoded or decoded audio channels by changing the value of the 'Audio Output' drop-down box in the UI.
There are also three buttons on the UI - the 'Reset' button will reset the simulation internal state to its initial condition and the 'Pause Simulation' button will hold the simulation until you press on it again. The simulation may be terminated by either closing the UI or by clicking on the 'Stop simulation' button.
MATLAB Coder can be used to generate C code for the function
HelperAudioMatrixDecoderSim. In order to generate a MEX-file for your platform, execute the command
HelperMatrixDecodingCodeGeneration from a folder with write permissions.
By calling the wrapper function
'true' as an argument, the generated MEX-file can be used instead of
HelperAudioMatrixDecoderSim for the simulation. In this scenario, the UI is still running inside the MATLAB environment, but the main processing algorithm is being performed by a MEX-file. Performance is improved in this mode without compromising the ability to tune parameters.
 Dolby Pro Logic Surround Decoder: Principles of Operation, Roger Dressler, Dolby Labs