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.
|