jMusic Realtime audio architecture


Below is a diagram that depicts the jMusic real time audio architecture. Notes are contained (or generated by) an RTLine, which is kind of like a real time phrase.  An RTLine has an instrument (strictly an array of several instances of the instrument) with which is renders the notes. The array  of instruments is necessary to deal with polyphony; overlapping notes. A number of RTLines (in an array) are controlled by an RTMixer which combines and synchronises the lines and passes the output to JavaSound audio out.

Instruments are a story to themselves, but briefly, an instrument is a combination (or chain) of AudioObjects. For example a chain might be made up of, an oscillator, a filter, an amplitude envelope, and a delay audio objects. The Instrument class, from which all instruments extend, takes care of pulling samples down the chain while the note duration lasts.

Changes to AudioObjects during processing - for example sweeping the filter cutoff - are managed by passing messages to the actionLines() method in the RTMixer which, in tun, passes the messages to all RTLines and Instruments. It is up to the instrument to pass the message on to the audioObject instance.

This is simply an overview. Other tutorials will deal with more details (and you can always look through the source :).

jMusic RT architecture
Here is an example that uses a sinewave instrument for each (potentially) overlapping note. Each notes needs to have it own jMusic Part because that is the level at which instruments are specified. Notice that for real-time playback you need to add a new instrument for each (potentially) concurrent part, even if they are the same instrument as in this case. Make sure you include the inst directory in your classpath when compiling or running to access the sinewave instrument.

import jm.JMC;
import jm.music.data.*;
import jm.util.View;
import jm.util.Write;
import jm.audio.Instrument;
import jm.util.Play;
public final class SineTest implements JMC {

public static void main(String[] args){
Score s = new Score();
s.setTempo(60);
int numbOfTones = 10;
Instrument[] insts = new Instrument[numbOfTones];





for(int i=0; i<numbOfTones;i++) {
Note n = new Note((int)(Math.random() * 40 + 60),
SEMIBREVE, (int)(Math.random() * 60 + 60));
n.setPan(Math.random());
Phrase phr = new Phrase(n, Math.random() * 10.0);
Part p = new Part("Sine", i);
p.addPhrase(phr);
s.addPart(p);
insts[i] = new SineInst(44100);
}
View.print(s);
Play.audio(s, insts);
}
}




© 2003 Andrew R Brown