audio MIDI Music Algorithms Interfaces Programming Acoustics Context
> Audio > Synthesis > Audio Objects    
 
   

Audio Objects

This tutorial provides details some of the jMusic audio objects and has a class that uses three different instruments.

Hear the result of this tutorial's music below.

Arps.mp3 [200K]

View / Download source - Instrument source code

View / Download source - Composition source code

Let's have a closer look the heart of the simplest of rendering instruments in jMusic.

 
	public void createChain(){
		WaveTable wt = new WaveTable(this, this.sampleRate, 
			Oscillator.getSineWave(this.sampleRate), channels);
		SampleOut sout = new SampleOut(span);
	}	

 

The arrangement of audio classes is pictured below.
Notice that your instrument classes draw upon a number of audio object classes, most extending the AudioObject class itself.

Class Heirarchy

Wavetable class

Inside the WaveTable class we can see that there is a constructor (shown below) that takes four arguments,
an audio instrument, the current sample rate, an array of floating point values to be used as the lookup table,
and the number of channels for this instrument.

	/**
	 * This constructor sets this wavetable up as a generator
	 * object meaning that it will pass sample information 
	 * down the chain based on its wave table data.
	 * @param sampleRate the sampling rate
	 * @param waveTable the wave table data
	 * @param channels the number of channels to use
	 */
	public WaveTable(Instrument inst, int sampleRate, 
				float[] waveTable, int channels){
		super(inst, sampleRate, "[WaveTable]");
		this.waveTable = waveTable;
		this.channels = channels;
	}		

In the instruments shown thus far, these arguments have been filled by the following line inside the createChain() method.

		WaveTable wt = new WaveTable(this, 
						this.sampleRate, 
						Oscillator.getSineWave(this.sampleRate), 
						channels);

Each wavetable instance takes an array of floats that describe the wave table data.
Often this data is one cycle of a waveform provided by the Oscillator class.
The timbral information is provided by the Oscillator class that, in this case, returns a single cycle of sine wave floating point
values to be used as a wave table.

Oscillator class

The oscillator class has a number of methods to generate wavetable data. The sine wave generating method is shown below.

public final class Oscillator{
	/**
	 * Static function returning a sineWave created from
	 * from a certain number of samples.
	 * @param numOfSamples the number of samples to create
	 * @return an array containing the sinewaves sample data
	 */
	public static float[] getSineWave(int numOfSamples){
		float[] sampleArray = new float[numOfSamples]; 
		float increment = (float)(Math.PI*2) / (float)numOfSamples;
		float x = (float)0.0;
		for(int i=0;i<numOfSamples;i++){
			sampleArray[i] = (float)((float)Math.sin(x+(
				(float)2.0*(float)Math.PI)));
			x += increment;
		}
		return sampleArray;
	}

There are methods to generate the following wave tables and you can always add others that you might want to include.

SquareWave, PulseWave, SawTooth, and TriangleWave.

SampleOut class

The sampleout class constructor takes the previous audio object in the chain as its only argument.

		SampleOut sout = new SampleOut(span);

Arpeggio composition

This program creates a three part score from a four note cell. Each subsequent layer is both higher and faster than the one below it, and a different instrument is assigned to each part so that each has its own timbre. The dynamic of each note is set randomly within a specified range and the panning position is set to a specific location for two of the parts and at random for the third. The three phrases, once constructed, are modified in various ways-In particular there is considerable use of volume fading in and out, and the highest part has the note order randomised using the Mod.shuffle() method.

import jm.music.data.*;
import jm.music.tools.*;
import jm.JMC;
import jm.audio.*;
import jm.util.*;
 
public class Arps implements JMC {
	
	public static void main(String[] args) {
		new Arps();
	}
	
	public Arps() {		
		// musical score construction
		int[] pitches = {60, 67, 72, 74};
		Phrase phrase1 = new Phrase();
		Phrase phrase2 = new Phrase();
		Phrase phrase3 = new Phrase();
		Part part1 = new Part("One", 0);
		Part part2 = new Part("Two", 1);
		Part part3 = new Part("Three", 2);
		
		// make arpeggios
		int loop = pitches.length;
		for (int i = 0; i < loop * 4; i++) {
			for (int j = 0; j < loop; j++) {
				for (int k = 0; k < loop; k++) {
					Note n3 = new Note(pitches[k] + 24, 
							0.0625, 
							(int)(Math.random() * 60 + 20));
					n3.setPan(Math.random());
					phrase3.addNote(n3);
				}
				Note n = new Note(pitches[j], 
							SEMI_QUAVER, 
							(int)(Math.random() * 40 + 80));
				n.setPan(0.2);
				phrase1.addNote(n);
			}
			Note n2 = new Note(pitches[i % pitches.length] - 24, 
							CROTCHET, 
							(int)(Math.random() * 40 + 40));
			n2.setPan(0.8);
			phrase2.addNote(n2);
		}
 
		// modify the phrases
		Mod.cycle(phrase3, pitches.length * 4.0 + 9.0);
		Mod.shuffle(phrase3);
		Mod.fadeOut(phrase3, 9.0);
		Mod.fadeIn(phrase1, 16);
		Mod.fadeOut(phrase2, 8);
		
		// add phrases to their parts
		part1.addPhrase(phrase1);
		part2.addPhrase(phrase2);
		part3.addPhrase(phrase3);
 
		// add parts to the score		
		Score score = new Score(part1);
		score.addPart(part2);
		score.addPart(part3);
		
		// display the score
		View.show(score);
		
		// instrument declaration
		int sampleRate = 22000;
		Instrument saw = new SawtoothInst(sampleRate);
		Instrument tri = new TriangleInst(sampleRate);
		Instrument sin = new SineInst(sampleRate);
		Instrument[] ensemble = {tri, saw, sin};
		
		// render
		Write.au(score, "Arps.au", ensemble);
	}
}

Enjoy.

 

 

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