> Audio > Synthesis > jMusic Instrument Architecture | |||||
jMusic Instrument ArchitectureThis tutorial reveals how a jMusic instrument class is structured. jMusic instruments are used to render jMusic scores as audio files (or as real time audio output). Instruments are made up from audio objects (not unlike unit generators in Csound or audio objects in Max/MSP) arranged in a hierarchial structure called a chain. Typically the audio chain is a linear arrangement of audio objects, as in the class below, but more complex hierarchies of audio objects can be constructed to produce more complex timbres. Hear the result of this tutorial's music below. Gongs.mp3[492K] View / Download source - Instrument source code View / Download source - Composition source code Let's have a closer look.
Instrument class overview jMusic instruments, such as the SimpleSineInst above, extend the Instrument class. public final class SimpleSineInst extends jm.audio.Instrument{ This provides them with significant functionality and means that the
instrument classes you create need only pay attention to the Class variables for sample rate and number of channels can be decalred with constant values or assigned with values from constructors. private int sampleRate; private int channels; In the SimpleSineInst they are assigned from the constructor. public SimpleSineInst(int sampleRate){ this.sampleRate = sampleRate; this.channels = 1; } jMusic instruments can be rendered at any sample rate. Having the rate
passed in the constructor provides the chance to determine the quality
The createChain() method The heart of the Instrument classes is the creatChain() method. public void createChain(){ WaveTable wt = new WaveTable(this, this.sampleRate, Oscillator.getSineWave(this.sampleRate), 1); Envelope env = new Envelope(wt, new EnvPoint[] { new EnvPoint((float)0.0, (float)0.0), new EnvPoint((float)1.0, (float)0.1), new EnvPoint((float)0.0, (float)1.0) }); SampleOut sout = new SampleOut( env, "jmusic.tmp"); } The createChain() method in the SimpleSineInst class (shown above) has a chain of three audio objects, Wavetable, Envelope, and SampleOut. An audio object's position in the chain is indicated by the first constructor
argument; the preceeding audio object is passed as the firt argument. Audio objects There are many audio objects provided with jMusic and you are encouraged to write your own. Some of the audio objects are: Wavetable, Envelope, Volume, Panner, SampleIn, SampleOut, Filter, Add, Splitter, and WhiteNoise. For a complete list see the jMusic documentation, or look in the jm/audio/synth directory of the jMusic source tree. All audio objects take one or more arguments, the first of which is by convention the preceeding audio object in the chain, the other arguments vary depending upon the funtion of theaudio object class - check the documentation for details. Constructing new Audio Objects is beyond the scope of this tutorial and is covered elsewhere. Sample stream The hierarchial arrangment of objects is necessary because the Instrument
is essentailly a class to generate and/or processes samples.
To visualise this imagine that the SimpleSineInst generates a raw sione
wave in the wt object, then each sample amplitude is adjusted according
One important, but counter intuitive, aspect of the sample progression
through the chain is that the last object in the chain is the first
object to be executed. in theory, one sample at a time could be passed down the chain but
this would be quite inefficient. Gong Example The code below uses multiple notes played by sine waves to create a gong-like timbre.
The SimpleSineInst is used by this example. Instrument sine = new SimpleSineInst(sampleRate); This is the only instrument required for this piece, so it is passed as an argument to the Write.au() method to render the score as a file named Gongs.au using the line; Write.au(score, "Gongs.au", sine); You might like to experiment with editing the instrument by changing the envelope point values to change the charracteristic of the gong sound.
|
|||||