tags:

views:

344

answers:

1

Why do i get distorted output if I convert a wav file using libsox to:

&in->encoding.encoding = SOX_ENCODING_UNSIGNED;
&in->encoding.bits_per_sample = 8;

using the above code?

The input file has bits_per_sample = 16.

A: 

So you're saying that you tell SOX to read a 16 bit sample WAV file as an 8 bit sample file? Knowing nothing about SOX, I would expect it to read each 16 bit sample as two 8 bit samples... the high order byte and the low order byte like this: ...HLHLHLHLHL...

For simplicity, we'll call high order byte samples 'A' samples. 'A' samples carry the original sound with less dynamic range, because the low order byte with the extra precision has been chopped off.

We'll call the low order byte samples "B samples." These will be roughly random and encode noise.

So, as a result we'll have the original sound, the 'A' samples, shifted down in frequency by a half. This is because there's a 'B' sample between every 'A' sample which halves the rate of the 'A' samples. The 'B' samples add noise to the original sound. So we'll have the original sound, shifted down by a half, with noise.

Is that what you're hearing?

Edit Guest commented that the goal is to downconvert a WAV to 8 bit audio. Reading the manpage for SoX, it looks like SoX always uses 32 bit audio in memory as a result of sox_read(). Passing it a format will only make it attempt to read from that format.

To downconvert in memory, use SOX_SAMPLE_TO_SIGNED_8BIT or SOX_SAMPLE_TO_UNSIGNED_8BIT from sox.h, ie:

sox_format_t ft = sox_open_read("/file/blah.wav", NULL, NULL);
if( ft ) {
    sox_ssample_t buffer[100];
    sox_size_t amt = sox_read(ft, buffer, sizeof(buffer));
    char 8bitsample = SOX_SAMPLE_TO_SIGNED_8BIT(buffer[0], ft->clips);
}

to output a downconverted file, use the 8 bit format when writing instead of when reading.

Paul
i want to convert it to 8 bits per sample. how do i do that?