Additive Synthesis

jMusic can be used to create instruments with all manner of synthesis systems. One of the easiest to understand is additive synthesis, where multiple sine waves of different frequencies are summed.

The final Audio file will sound like this: AddSynthTest.au [1774kb ]

Click here to view source for AddSynthInt.java

Lets have a closer look

There is a constructor that just takes the sampleRate and provides defaults for all other settings. This provides a tone similar to the one in the audio example above. To use it create an instrument like this:

Instrument inst = new AddSynthInst(44100);

Next, let's look at the constructor which sets up all the variables such as frequencies and amplitudes.

	public AddSynthInst(int sampleRate, float[] overtoneRatios,
float[] overtoneVolumes, double[][] envPointArray){

this.overtoneRatios = overtoneRatios;
this.overtoneVolumes = overtoneVolumes;

double[][] tempPoints = new double[envPointArray.length][];

for (int i=0; i<envPointArray.length; i++) {
tempPoints[i] = envPoints;
}
allEnvPoints = tempPoints;

this.sampleRate = sampleRate;
}


The constructor above takes a series of arrays for the frequency, volume and envelope of each harmonic. Make sure when using this constructor that the number of values in each array match (i.e., five values in each array if you want five harmonics).



The audio object organisation shown in the flow chart above is depicted in jMusic code below, taken from the AddSynthInst class. This shows the inner workings of the class. The for loop allows the instrument to support any number of overtones, specified by the number of elements in the arrays passed to the constructor.

	public void createChain(){
Envelope[] env = new Envelope[overtoneRatios.length];
Volume[] vol = new Volume[overtoneRatios.length];
Oscillator[] osc = new Oscillator[overtoneRatios.length];

for(int i=0;i<overtoneRatios.length;i++){
osc[i] = new Oscillator(this, Oscillator.SINE_WAVE,
this.sampleRate,2);
osc[i].setFrqRatio(overtoneRatios[i]);
env[i] = new Envelope(osc[i], allEnvPoints[i]);
vol[i] = new Volume(env[i], overtoneVolumes[i]);
}

Add add = new Add(vol);
StereoPan span = new StereoPan(add);
SampleOut sout = new SampleOut(span);
}




Now let's look at a class that uses the additive synthesis instrument.

Click here to view source.

import jm.JMC;
import jm.util.*;
import jm.music.data.*;
import jm.midi.*;

import jm.audio.synth.*;
import jm.audio.Instrument;

import java.io.File;


public final class AddSynthTest implements JMC{
public static void main(String[] args){
Score s = new Score("Additive synthesis test");
Part p = new Part("Flute", 0);
Phrase phr = new Phrase();
//create the test note/score and display it
for(int i=0;i<6;i++) {
Note n = new Note(A2+i*6, 0.5*(i+1));
phr.addNote(n);
}
p.addPhrase(phr);
s.addPart(p);

//create the instrument
AddSynthInst inst = new AddSynthInst(44100);
Instrument[] ensemble = {inst};

// write out the files
Write.au(s, "AddSynthTest.au",ensemble);
}
}

Try modifying this class to create a more interesting sound by using the alternate constructor that takes arrays of values.