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 :).
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); }
}
|
|