audio MIDI Music Algorithms Interfaces Programming Acoustics Context
> Audio > Musical Data > Realtime audio in jMusic    
 
   

Realtime audio in jMusic

This tutorial provides an introduction to real time audio with jMusic. When producing audio in realtime, data is played back as soon as it's created.
Usually data is not stored as a file so no record of the music in maintained. Realtime playback can go on forever and is not limited by file size.
The complexity of the realtime audio production is limited by processing capacity, however, and so the number of parts and the sofistication of the
audio processing varies from computer to computer.

The architecture of realtime audio in jMusic varies considerably from rendered audio in that the audio engine deals directly with notes, and they need
not be encapsulated insdie phrases, parts, or a score. The composition can be generated in realtime also, note-by-note.
This opens up new opportunities for interactive music. For realtime audio, notes are generated within an RTLine object. This class is conceptually not dissimilar to a phrase for realtime.

The tutorial is in two parts. First, the RTTest class is presented which sets up the instruments and the RTline. Second, the RealtimeMelody class is presented. This class is an extension of the RTLine class. Each realtime piece must create extensions of the RTLine class of each musical line (phrase).
the RTTest class has the main() method.

Here is the source for these two files:

RTTest source.

RealtimeMelody source.

in addition you will need the RTPluckInst class availible from the jMusic instruments page, or directly from here:

RTPluckInst source.

Lets have a closer look at the RTTest class

import jm.JMC;
import jm.audio.RTMixer;
import jm.audio.Instrument;
import jm.music.rt.RTLine;

As well as the familiar JMC class, we import a number of jMusic audio classes. The RTLine class is in the jm.music package because of its similarity to the other music data classes (Note, phrase, score etc.).

public class RTTest implements JMC{
public static void main(String[] args){
int sampleRate = 44100;
int channels = 1;
double controlRate = 0.1;
int bufferSize = (int)((sampleRate*channels)*controlRate);

The class is short and so all the workings are in the main method.

The first four lines of the main(0 method set up the audio specifications for the music. The samplerate in this case is the same as CD quality audio, it will produce a monophonic audio stream, the control rate specifies how frequenctly adjustments to the sound are calculated (shorter = more precission), and the buffer size is calulated from those previous settings. The buffer size is the amount of sample data computed at a time - it effects the latency of the audio system. In practice it is good to have as small a control rate as possible to minimise the buffer size.

        Instrument inst = new RTPluckInst(sampleRate);

Instrument[] insts = new Instrument[] {inst};

RTLine[] rtlines = {new RealtimeMelody(insts, controlRate, bufferSize)};

RTMixer rtm = new RTMixer(rtlines, bufferSize,
sampleRate, channels, controlRate);
rtm.begin();
}

}

An instrument to use for the music is decalred - the RTPluckInst. We only have one line in this piece so one instrument will suffice. realtime instruments in jMusic are slightly different from rendered instruments in that they don't write a file to disk. it is usually better to have specific realtime and non-realtime versions of an instrument.

The instrument is added to an instrument array. This seems superfluous when we only have one instrument, but in cases where there are several this makes more sense.

An array of RTLines is decalared. in this case it only contains one line and uses our RealtimeMelosy class (see below). Notice that the RTLine takes the instruments, controlrate, and buffersize as arguments.

Each jMusic realtime audio piece has an RTMixer object. Its function is to combine all of the RTLines together and send the mix to the audio output.
The processing is begun by calling the begin() method of the RTMixer object.


Now let's look at the note generation class - what are we going to play with this RTPluckInst?

import jm.music.rt.*;
import jm.audio.*;
import jm.music.data.*;

public class RealtimeMelody extends RTLine {

public RealtimeMelody(Instrument[] inst, double controlRate, int bufferSize) {
super(inst, controlRate, bufferSize);
}

// required method overrided
public Note getNote() {
return new Note((int)(Math.random() * 60 + 30), 0.25,
(int)(Math.random() * 100 + 27));
}

The RealtimeMelody class has the job of providing notes as the music proceeds. It gets much of its functionality by extending the RTLine class. Each realtime audio program in jMusic must contain one or more classes that extend the RTLine class in this way.

The class imports the appropriate jMusic packages.

There are two clasess that are critical, the constructor and the getNote() method.

The constructor takes the necessary arguments allowing the appropriate audio data to be calulated. these are passed to the super class - RTLine - for use.

The getNote() method simply generates one note. When this has been rendered the method will be called again, and so on, until we quit the application.
In this case a semiquaver of random pitch and dynamic is produced each time the method is called. Simplistic, but effective.
You can put any compositional logic you want in this method - or have it call a method in another class -
so long as the result is the next note to be played back.

 

jMusic Australia Council Queensland University of Technology Sitemap Contact Home Home http://www.qut.com http://explodingart.com/jmusic http://www.ozco.gov.au

Digital Instrument making Home