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.
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.
Thus, the output data will be like table 4.
There is a sample code just for reference:
Therefore it needs another version for 16-bits LS and it will looks like as following.
Finally we will get the result as table 6.
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.
Table 1. The original input data
Seq. (input) 0 1 2 3 Data 0xaa 0xbb 0xcc 0xdd
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.
Table 2. The left output data
Seq. (left) 0 1 2 3 Data 0xaa 0xbb 0xcc 0xdd
Table 3. The right output data
Seq.(right) 0 1 2 3 Data 0xaa 0xbb 0xcc 0xdd
Thus, the output data will be like table 4.
Table 4. The stereo data come from table 1
Seq. (output) 0 (L) 0 (R) 1 (L) 1 (R) 2 (L) 2 (R) 3 (L) 3 (R) Data 0xaa 0xaa 0xbb 0xbb 0xcc 0xcc 0xdd 0xdd
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.In this case, there is a result that I record it before and the result showed as figure 1.Table 5. The output data with wrong format (8-bits LS into 16-bits LS)
Seq. (output) 0 (L) 0 (R) 1 (L) 1 (R) Data 0xaaaa 0xbbbb 0xcccc 0xdddd
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.
Table 6. The output data of 16-bits LS.
Seq. (output) 0 (L) 0 (R) 1 (L) 1 (R) Data 0xaabb 0xaabb 0xccdd 0xccdd
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.
沒有留言:
張貼留言