Compressors on 16-bit pcm files

VST, AU, AAX, CLAP, etc. Plugin Virtual Effects Discussion
Post Reply New Topic
RELATED
PRODUCTS

Post

Hi,
I have basically finished a multi-track recorder for java, but it has became appearnt that my gain controls do not work like how they should. Here is what I got:

- a 1:1 ratio compressor which processes a 16-bit chunk from 16-bit stereo pcm audio file. The problem is that when I turn the gain down (the volume variable) it starts to produce noticeable static. I need a compressor that does not produce static at low volumes. The variable toModify and toModify2 are two consecutive bytes read straight from a PCM file..
Could anyone point me to any helpers on this specific subject? If you understand java enough (much like c++) and think you know the problem, please let me know. I can't seem to find any information on how to eliminate the static. No matter what I do I can't get it to work.

Thanks in advance

public byte[] getCompressedVolume(byte toModify, byte toModify2){
byte[] arr= new byte[2];
int tmp = (int)toModify << 8;
tmp= (int)((double)tmp * ((double)(volume/MaxVolume)) ) ; //MaxVolume is
//a constant value
arr[0]=(byte)(tmp);
tmp = toModify2;
tmp= (int)((double)tmp *((double)(volume/MaxVolume)) );
arr[1]=(byte)tmp;
return arr;
}

Post

The problem i think is that 16 bit integer isn't enough room to do that kind of calculations in. If you lower the volume you loose bits. Loose enough bits and it starts to sound like crap.

Convert it to 32 bit float, do your calculations,convert back to 16 bit integer.

Post

Java's integer is 32 bit.. more than enough room for 16 bits.. I think there has to be something wrong with the implementation, I just don't know what. Thanks for your response!

Post

Did you implement a threshold, attack and release for this compressor? Because a sudden change of volume will result in static. And reduction of volume should only be applied relative to the threshold...
We are the KVR collective. Resistance is futile. You will be assimilated. Image
My MusicCalc is served over https!!

Post

My response was'nt entirely accurate.
The problem is that your working with integers.
If you lower the volume of a 16 bit integer file you will loose bits. That is probably the static you're experiencing.

For example if you lower the amplitude in half (out=in*0.5)you only have 8 bit representing the waveform.

Post

Just tried the following; it still produces static at low volumes (same as int). Do you think it might be an error with how I apply the compression to each individual byte?
public byte[] getCompressedMasterVolume(byte toModify, byte toModify2){

byte[] arr = new byte[2];
float sample = toModify<<8;
sample = (float)sample* ((float)((float)volume/(float)MaxVolume));
arr[0] = (byte)sample;
sample = toModify2;
sample = (float)sample* ((float)((float)volume/(float)MaxVolume));
arr[1] = (byte) sample;
return arr;

Post

Why are you calling it a compressor? As far as i can see all you're doing is volume changes. And why are you trying to it on 2 bytes at a time ? Any special reason for that?

The problem is still the 16 bit representation which isn't enough.

Post

Okay, I don't know what an attack and release is? Any links on the matter would be much appreciated. I do have a threshold which is represented as a constant MaxVolume=32767 Volume is simply a value between 0 and MaxVolume, which is set by the user based on where they click.

Post

My understanding was that this is a compressor? My bad, sot of new to the audio stuff effects :( all I really want to do is to be able to turn down the voluem from the starting volume->0 without static in the backround.

Post

"For example if you lower the amplitude in half (out=in*0.5)you only have 8 bit representing the waveform."

if you cut the amplitude in half, you have 15 bits representing the signal, not 8. you would need to make a cut of 1/256th in order to get only 8 bits accuracy.

if you simply want to adjust the volume, do this:

volume is 0 ... 32767
signal = (signal * volume) / 32768;

this should compile to a register imul and sar, taking two or three cycles, much better than using float.
Last edited by aciddose on Wed Nov 08, 2006 11:47 am, edited 1 time in total.

Post

aciddose wrote:"For example if you lower the amplitude in half (out=in*0.5)you only have 8 bit representing the waveform."

if you cut the amplitude in half, you have 15 bits representing the signal, not 8. you would need to make a cut of 1/256th in order to get only 8 bits accuracy.
You're absolutley correct sir! I did think and changed to and from a few times and still messed up. :D

Still does'nt change the main problem though.

Post

Awesome that answers my question! I guess I can not reduce the sound of my recorder as far as I wanted without major quality loss.

Post

There only is a rounding error in the least significant bit (representing a loudess of -90dB) so considering "physical" limitations there should be no more quality loss than to be expected. The Windows volume fader does it the same me thinks.

If you've multiplied each sample with the same constant, there should be no static or other audible artefacts louder than -90dB. Maybe it helps to write output PCM of your a WAV file, and compare that to the original. Maybe with visual feedback using an audio editor (zoom in until you can see individual samples) you can see what went wrong.
We are the KVR collective. Resistance is futile. You will be assimilated. Image
My MusicCalc is served over https!!

Post Reply

Return to “Effects”