16 bit PCM Audio Sounds Like Bit Crushing I'm developing an Android app which uses USB soundcard for input and output. The audio processes are in the native (C++) side.

The device's bit resolution is 16. I get the audio stream from the device as unsigned char* and have to convert them to float between -1.0f and +1.0f to process.

I do the conversion but it sounds like bit crushing effect if I increase the volume of input.

Here is what I do when converting:

For Input Conversion:

/*** buffer is an array of float ***/
/*** temp_buffer_in is the buffer coming from the device ***/

float divider = (float) std::pow(2, (BIT_RESOLUTION_IN - 1));
int BYTE_RESOLUTION_IN = BIT_RESOLUTION_IN / (sizeof(char) * 8);
int bytes = buffer_size * BYTE_RESOLUTION_IN; //Buffer size in bytes

for (i = 0, j = 0; i &lt; bytes; i += BYTE_RESOLUTION_IN, j++) {

    UnionInteger16 union_int; // Union structure below
    union_int.i = 0;

    for (int k = 0; k &lt; BYTE_RESOLUTION_IN; k++) {
            union_int.c[k] = temp_buffer_in[i + k];
    }

    buffer[j] = (float) union_int.i;

    buffer[j] = buffer[j] / divider;
}


For Output Conversion:

/*** temp_buffer_out is the buffer sent to the device ***/

float multiplier = (float) std::pow(2, (BIT_RESOLUTION_OUT - 1));
int BYTE_RESOLUTION_OUT = BIT_RESOLUTION_OUT / (sizeof(char) * 8);
int bytes = buffer_size * BYTE_RESOLUTION_OUT;

for (i = 0, j = 0; i &lt; bytes; i += BYTE_RESOLUTION_OUT, j++) {

    if (buffer[j] &gt;= 0) {
        buffer[j] = buffer[j] * (multiplier - 1.0f);
    } else {
        buffer[j] = buffer[j] * multiplier;
    }


    UnionInteger16 union_int; // Union structure below
    union_int.i = (int16_t) buffer[j];

    for (int k = 0; k &lt; BYTE_RESOLUTION_OUT; k++) {
        temp_buffer_out[i + k] = union_int.c[k];
    }
}


I use Union for converting unsigned chars to int16_t and then to float. Here is the union structure:

union UnionInteger16 {
    int16_t i;
    uint8_t c[2];
};


Everything looks fine in the code but as I mentioned, the audio sounds like bit crushing when the input volume is increased and when the volume is decreased, the audio starts to disappear. I think I lost the dynamic range of the audio.

Sorry for the long question. I would be grateful if you help me. Thanks in advance.
In case anyone has the same problem, I want to tell that the above code works really well. My problem about the distortion of audio caused by wrong buffer size. 

But while searching for a solution, I figured out that everyone says that using union may cause undefined behaviour in different CPU structures. It is said to use bitshift operations instead. So I decided to change the code for conversion as below:

Input Conversion

int16_t sample = 0;
    for (int k = 0; k &lt; BYTE_RESOLUTION_IN; k++) {
    sample |= input_buffer[i + k] &lt;&lt; (k * 8);
}


Output Conversion

int16_t sample_int16 = (int16_t) temp;
    for (int k = 0; k &lt; BYTE_RESOLUTION_OUT; k++) {
    output_buffer[i + k] = (sample_int16 &gt;&gt; (k * 8)) &amp; 0xFF;
}


And this conversion is made for Little-Endian system. If you have Big-Endian system, you have to change the k value properly.

Have a nice day