Halle
Halle

Reputation: 3584

Clipping when converting signed 16-bit PCM samples to unsigned 8-bit PCM samples

I have signed mono 16-bit PCM audio samples stored in a SInt16 buffer and I am trying to convert them to unsigned mono 8-bit PCM samples stored in a UInt8 buffer. I've written the following basically-working code:

for (int i=0; i < numSamples; i++) { 
    SInt8 tempSigned8Bit = signed16BitBuffer[i]/127; // In 2 passes
    unsigned8BitBuffer[i] = tempSigned8Bit + 127;    // for clarity
}

However, I can hear clipping at the maximum amplitudes in the resulting audio, or at least that is my impression of where the distortion is occurring. Is this an artifact of the re-quantization or do I need to include some sort of clamping as described in this question about a similar conversion but without any signedness conversion:

Convert 16 bit pcm to 8 bit

Bitwise optimizations unnecessary but I certainly wouldn't say no to them.

Upvotes: 2

Views: 3022

Answers (1)

Paul R
Paul R

Reputation: 213130

This will fail for large values because you need to divide by 256 not 127. Also the offset needs to be 128, not 127.

for (int i = 0; i < numSamples; i++) { 
    SInt8 tempSigned8Bit = signed16BitBuffer[i] / 256;
    unsigned8BitBuffer[i] = tempSigned8Bit + 128;
}

The conversion for +/- full scale and zero looks like this:

Signed    Divide    Add
16 bit    by 256    128
sample

 32767 ->  127 ->   255    ; Full scale +
     0 ->    0 ->   128    ; 0
-32768 -> -128 ->     0    ; Full scale -

Upvotes: 8

Related Questions