2013年6月2日 星期日

An Implementation of Channel Converter (from mono to stereo)

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
Data
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)
Data
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.

沒有留言:

張貼留言