Audio Compression

A compressor reduces the volume of samples above a specified threshold. It reduces the dynamic range overall and the difference between soft and loud parts of the file. The reduction is specified as a percentage of the value above the threshold. For example, a compression ratio of 4:1 is a reduction of the sample value by one-quarter of the amount above the threshold. If the sample value was 0.6 and the threshold was 0.2 then the compression reduction would be applied to the 0.4 above the threshold which, give a 4:1 ratio would result in a final value of 0.3 (0.2 + 0.1). Because there is always a volume reduction with a compressor it is normal to include a compensating volume gain on all samples.

Read the tutorial on reading and writing audio files for background on some methods used in the program. In this code, Welcome.au is the name of an audio file, you may need to subsitute your own monophonic, 16 bit 44.1k audio file in place of this (A .wav or .aif file can also be read by jMusic).

import jm.util.*;

public final class Compress {   

    public static void main(String[] args){

        float[] data = Read.audio("Welcome.au");
        float threshold = 0.2f;
        float ratio = 2.0f;
        float gain = 2.0f;

        for (int i=0; i< data.length; i++) {
            // positive values
            if(data[i] > threshold) {
                  data[i] = threshold
+(data[i]-threshold) * (1.0f/ratio);
            }
            // negative values
            if(data[i] < -threshold) {
                data[i] = -threshold
+ (data[i]+threshold) * (1.0f/ratio);
            } 
            // apply the gain to all samples            
            data[i] *= gain;
            if (Math.abs(data[i]) > max)
max = Math.abs(data[i]);
        }

        Write.audio(data, "Compressed.aif");
    }
}


Experiment with the ratio, threshold and gain variables to achieve different compression effects. Using a ratio of less than 1:1 will turn the compressor into an expander.

Notice: This compressor is simplified to use linear gain changes in the audio stream and does not take into account the psychoacoustic properties of logarithmic loudness scaling. The compressor audio object in the jm.audio.synth package does.


© 2004 Andrew Brown
jMusic Tutorial Index