0
votes

I have char pAudioBuffer buffer which i got from function ffmpeg:

int len = avcodec_decode_audio3(av_codec_context,
            (int16_t *) pAudioBuffer, &out_size, &packet);

I know that audio format is two bytes per sample, i need to convert every two bytes to short value, i have tried to use code snippet below, but i often got zero instead of short value:

int shortBufIndex = 0;
for (int i = 0; i < (out_size); i += 2) {
    char b1 = pAudioBuffer[i];
    char b2 = pAudioBuffer[i + 1];
    short sample = atoi(&b1) + atoi(&b2);
    shortBuffer[shortBufIndex] = sample;
    shortBufIndex++;
    LOGI("BUFFER_ITEM='%d'", sample);
}

What i'm doing wrong, how to convert every two bytes in char buffer to short and and back.

UPDATE:

system's byte order is LITTLE_ENDIAN i have test it like this: Endianness of Android NDK

How can i convert every two bytes in buffer to sample of short type and back. Please can you provide any code sample.

UPDATE

I have tried to access to short as pairs, here is my fixed code, but it not work, i don't hear any sound:

    int shortBufIndex = 0;
    for (int i = 0; i < (out_size); i += 2) {
        char * byte = (char *) pAudioBuffer[i];
        short * sample = byte;
        shortBuffer[shortBufIndex] = sample;
}

What i'm doing wrong? I need conversion like this: byte array to short array and back again in java but in c.

3
Why don't you just pass shortBuffer instead of pAudiBuffer to the ffmpeg API? - alk
@alk How can i accomplish that, is it simply replace pAudioBuffer with shortBuffer. - testCoder
I have tried to use shortBuffer instead of pAudioBuffer but when i pass it to AudioTrack i hearing some noise, i cannot use that approach. - testCoder
There might be an endian issue here. If the endianess used by ffmpeg and your system differs, you could use ntohs() to convert each element of shortBufferafter it had been filled by the call to avcodec_decode_audio3 like so: size_t size = out_size/2; for (size_t i = 0; i < size; ++i) shortBuffer[i] = ntohs(shortBuffer[i]); - alk
@alk when i try to use ntohs i hearing only noise, but when i use short without ntohs i hearing sometimes noise (periodically). It seems not work. - testCoder

3 Answers

2
votes

The use of atoi() with the address of the variables is entirely mistaken and incorrect. That is for converting the ASCII representation of a value into a number. In your case, you don't really have a buffer of "characters" but rather a buffer of byte values, which under the history of C is commonly implemented with the char type rather than something more recent and definitive such as int8_t.

To convert between a character buffer and a short buffer, you first need to answer the critical question if the encoding of the character buffer is in the system's native endian order, or opposite to it.

If it is in native endian order, then in a language such as C all you have to do is cast the pointer type to a short, and access the data as pairs of bytes.

However, if it is in opposite order, you will have to access the two bytes and combine them (shift + add) in opposite order from usual. There may be macros for doing this which you can use, though doing it by hand has the advantage of making the functionality fully evident.

1
votes

Na. you have to write

short sample = b1<<8|b2;

or, depending of your endian-situation, you have to swap b1 and b2

1
votes
short *pshBuf = (short*)pCharBuf;

It works. I am using the same in my live projects as well.