converting audioformat 16bit/16kHz <-> 8bit/8kHz

Hi,
we have to convert a 16bit/16kHz audio format into 8bit/8kHz format and reverse.

Changings between 16bit and 8bit seems to be easy but that's not enough, because there is still the kHz count which has to be changed.

Someone of you know a way to do it with C++?
Or is there function library with which the target can be reached?

Thanks for your help.

p.s.: We are working with Fedora9 but I wrote it in this part of the forum, to find a general way
Last edited on
still up to date :/
Audio format 16 kHz has twice as many samples. To perform conversion you just need to take every second sample, and scale it down to 8-bit value.
ok thx, I did it in this way:

- I tock the buffer with 16bit data

--------------------------------------------------------------------------
I........16........I........16........I........16........I........16........I ...
--------------------------------------------------------------------------
......block 1..........block 2...........block 3.........block 4..


- made the average beetween pairs of 2blocks

---------------------------------------
I.......16.......I........16........I ...
---------------------------------------
.(b1 + b2)/2...(b3 + b4)/2..

- and bitshifted it with 8 (tacking just the first 8bits of each block)

-----------------------
I....8...I....8...I ...
-----------------------


We couldn't test it today, but I hope at the beginning of next week we will.
I hope it works and the voice will sound ok.. also without a special lowpass filter or something like that.
I did some tests and have to say it works BUT it's not good for voice.
Many of the spoken words you can't understand clearly in the new format.

I also tryed it with taking each 2nd block instead of making a average - nearly the same result.

I know that it's normal to loose quality with downsampling but in the result it's to much at the moment.

I made a test with a 16kHz/16bit wav-file und converted it into 8kHz/8bit with the standard-audiorecorder of my windows system and it sounds much better.

So how to reach the same result or one which is next to it?
This is sound naturally, and so it can't just be shifted out like data.

First, I'd like to know if you're actually editing the sine waves rather than just trying to edit the file data, or using some other weird form of editing the sounds.
Last edited on
In our project we are receiving a buffer with 128 shorts (128*16bits).
This buffer contains the raw-audiodata with format 16kHz/16bit.
Now we have to change the format into 8kHz/8bit before sending the data to another application.

At the moment I just tryed to make changes in the file data .. taking the 8leading bits of each 2nd sample (each 2nd short with bitshift by 8 to a 8bit-character).
I took the way to take each 2nd sample und divide it with 256.
After the sound was bad I've taken the values of the origin raw-file and the values of the new raw-file and put them into an excel-sheet.
After comparing the charts of both, I recognized that the tops and the lowest point of the waves often were cuted because they have been in the ignored samples.

So I tryed to take each 2nd sample of the origin audio, compared it with the previous and the following sample and took the maximum of this 3 values. For values lower than the half (<128) I did the same with taking the minimum of this 3 values.

Now it sounds much better. I think loosing a bit of quality is normal.
After comparing the charts of both, I recognized that the tops and the lowest point of the waves often were cuted because they have been in the ignored samples.
You mean the low-pass filter?
This is a part from the top of the origin wave:
http://www.imgbox.de/?img=f29865w15.jpg

And this wave show the same part after taking each 2nd sample:
http://www.imgbox.de/?img=x24438q15.jpg
The black signs show where the origin tops are

specally in the second top you can see the difference.

This way the wave looks after my additional changes:
http://www.imgbox.de/?img=t6720d15.jpg

(I don't know how to post a picture so I posted the links)
Resampling is a pretty complicated topic. There are a few different approaches you can take.

Linear Interpolation is pretty decent, usually. In this case, since you're cutting the samplerate clean in half, linear interpolation would have the same effect as taking every other sample from the stream.

You could try to get clever and take the average of the two samples instead of just dropping one of them, but that wouldn't really be any better (still linear interpolation, just shifted a bit).

Other interpolation methods are far more complex (gaussian, cubic, etc -- try looking them up on wikipedia -- although they're not that easy to understand).

You said that linear interpolation sounds bad -- but I can't imagine it would really be that much worse when compared to another program's output. So I kind of have to point out the obvious here. Are you converting between signed and unsigned samples properly? 16-bit audio is typically signed, whereas 8-bit is typically unsigned. If you're just dividing the samples by 256 and not adjusting the sign, it's no wonder everything sounds horrid.

Provided that's the case (16-bit signed to 8-bit unsigned), be sure to flip the high bit after you shift the sample to the right:
1
2
3
4
5
6
unsigned char Make8bit(signed short sample)
{
  sample >>= 8;  // drop the low 8 bits
  sample ^= 0x80;  // toggle the sign bit
  return (sample & 0xFF);
}


But of course... 8KHz (and 8-bit at that) is pretty much always going to sound terrible no matter which way you slice it.

wow nice!

I have a file with raw-data to test the conversion with which I tried your advice.
1
2
3
  sample >>= 8;  // drop the low 8 bits
  sample ^= 0x80;  // toggle the sign bit
  return (sample & 0xFF);

And it sounds very good, also with taking only each 2nd sample. Of course there is a bit quality lost but we can hear the voice clearly.
My fault was (like you thought) that I handled the signed 16bit like unsigned 16bit.

Now I have to check if the data we receive (packages of 128 samples) is also signed 16bit.

Many Thanks!
Topic archived. No new replies allowed.