There is an experience about sharing how to make a converter between mono channel and stereo channel.
To implement a channel converter is quite easy. The critical part of this kind of converter is to transform the input data as interleaving to output. Let us look the following diagrams that might be helpful.
For example, we get an original input data like table 1.
Seq. (input)
|
0
|
1
|
2
|
3
|
|
0xaa
|
0xbb
|
0xcc
|
0xdd
|
Table 1. The original input data
And what we want to do is to duplicate the same data interleavely to another one. That will make the left channel and the right channel has the same data as table 1, such like table 2 and table 3.
Seq. (left)
|
0
|
1
|
2
|
3
|
Data
|
0xaa
|
0xbb
|
0xcc
|
0xdd
|
Table 2. The left output data
Seq.
(right)
|
0
|
1
|
2
|
3
|
Data
|
0xaa
|
0xbb
|
0xcc
|
0xdd
|
Table 3. The right output data
Thus, the output data will be like table 4.
Seq. (output)
|
0 (L)
|
0 (R)
|
1 (L)
|
1 (R)
|
2 (L)
|
2 (R)
|
3 (L)
|
3 (R)
|
|
0xaa
|
0xaa
|
0xbb
|
0xbb
|
0xcc
|
0xcc
|
0xdd
|
0xdd
|
Table 4. The stereo data come from table 1
There is a sample code just for reference:
int converter(int8_t *input_data, size_t size)
{
int8_t *output_data = (int8_t)malloc(sizeof(int8_t)* size * 2);
int i = 0, pos = 0;
for(i; i < size; i++){
memcpy(output_data[pos], input_data[i], 1);
memcpy(output_data[pos + 1
], input_data[i], 1);
pos += 2;
}
}
However, the format what you are processing is important too. The above one is only for a 8-bits and little-significant(LS) format. If some people who just apply the above sample codec into a 16-bits and LS format, they will find the left data and the right data are totally different. The output is like table 5.
Seq. (output)
|
0 (L)
|
0 (R)
|
1 (L)
|
1 (R)
|
Data
|
0xaaaa
|
0xbbbb
|
0xcccc
|
0xdddd
|
Table 5. The output data with wrong format (8-bits LS into 16-bits LS)
In this case, there is a result that I record it before and the result showed as figure 1.
Figure 1. The output data with wrong format (8-bits LS into 16-bits LS)
Therefore it needs another version for 16-bits LS and it will looks like as following.
int converter(int8_t *input_data, size_t size)
{
int8_t *output_data = (int8_t)malloc(sizeof(int8_t)* size * 2);
int i = 0, pos = 0;
for(i; i < size; i++){
memcpy(output_data[pos], input_data[i], 2);
memcpy(output_data[pos + 2
], input_data[i], 2);
pos += 4;
}
}
Finally we will get the result as table 6.
Seq. (output)
|
0 (L)
|
0 (R)
|
1 (L)
|
1 (R)
|
Data
|
0xaabb
|
0xaabb
|
0xccdd
|
0xccdd
|
Table 6. The output data of 16-bits LS.
This skill is useful when it need to stream a voice data from a Bluetooth module to an audio codec while playing Hand-Free profile (HFP). In an automotive software system, sometimes our company will offer customers software solution for applying acoustic echo cancellation (AEC). In that situation, the streaming of voice is controlled by CPU and it will make decision how to transfer audio data between a Bluetooth module and an audio-codec. Mostly, a Bluetooth module only support mono channel but an audio-codec need stereo data.
Figure 2. Architecture of automotive audio components
O.T.