Dynamic Instrument Parameters
        This tutorial shows how audio objects can 
          have variations built into them.
        Hear the result of this tutorial's music 
          below.
        Gongs3.mp3 [416K]
        View 
          / Download source - Instrument 
          class
        View / Download 
          source - Composition class
        Lets have a closer look.  
        
  
        
           
             import jm.audio.io.*;
import jm.audio.synth.*;
import jm.music.data.Note;
import jm.audio.AudioObject;
 
 
 
 
public final class VaryDecaySineInst extends jm.audio.Instrument{
	
	
	
	
	private EnvPoint[] pointArray = new EnvPoint[10];
	
	private int channels;
	
	private int sampleRate;
 
	
	
	
	
	 
	 
	
	 */
	public VaryDecaySineInst(int sampleRate){
	    this(sampleRate, 2);
	}
	
	 
	 
	 
     
	public VaryDecaySineInst(int sampleRate, int channels){
		this.sampleRate = sampleRate;
		this.channels = channels;
		EnvPoint[] tempArray = {
			new EnvPoint((float)0.0, (float)0.0),
			new EnvPoint((float)1.0, (float)0.001),
			new EnvPoint((float)0.5, (float)0.1),
			new EnvPoint((float)0.05, (float)(Math.random() * 0.4 + 0.3)),
			new EnvPoint((float)0.0, (float)(Math.random() * 0.3 + 0.7))
		};
		pointArray = tempArray;
	}
 
	
	
	
	   
	
	 *
	 
	
	public void createChain(){
		WaveTable wt = new WaveTable(this, this.sampleRate, 
				Oscillator.getSineWave(this.sampleRate), channels);
		Envelope env = new Envelope(wt, pointArray);
		Volume vol = new Volume(env,(float)1.0);
		StereoPan span = new StereoPan(vol);
		SampleOut sout = new SampleOut(span);
	}	
} 
             | 
          
        
        
        Dynamic Envelope Change
        The dynamic part of this instrument is in 
          the declaration of envelope points. 
        		EnvPoint[] tempArray = {
			new EnvPoint((float)0.0, (float)0.0),
			new EnvPoint((float)1.0, (float)0.001),
			new EnvPoint((float)0.5, (float)0.1),
			new EnvPoint((float)0.05, (float)(Math.random() * 0.4 + 0.3)),
			new EnvPoint((float)0.0, (float)(Math.random() * 0.3 + 0.7))
		};
        Notice that the last two EnvPoint's and have a randomised value, this 
          will be calculated when the instrument is constructed. 
          Therefore each instance of the instrument will be slightly different.
          We use this characteristic in the following piece to create an additive 
          timbre where each partial has a slightly different envelope
          and so the timbre changes over the duration of each note. 
        Compositional Example
        This composition extends the Gong concept of the previous two tutorials. 
          the pitch of notes is used to determine the overtone series for each 
          gong.
          There is plenty of randomness in both the setting of the fundamental 
          pitch, the overtone intervals, and overtone loudness - thus some gong 
          sounds 
          will be more convincing than others.
        The score creates 5 gong tones (chords) each 
          with 8 partials (parts). This imbedded loop struture takes up most of 
          the code.
        		Instrument[] ensemble = new Instrument[partCounter];
		
		for (int k = 0; k < partCounter; k++) {
			ensemble[k] = new VaryDecaySineInst(sampleRate);
		}
        The VaryDecayinstrument described earlier is used for each part. In 
          order to minimise code repetition the instrument array is created in 
          a loop which
          declares an instrument each iteration. 
          We are using multiple instances of the same instrument (rather than 
          just one) because the envelopes of each instance will vary thus giving 
          us
          a dynamic timbrel result.
        
        
           
             import jm.music.data.*;
import jm.music.tools.*;
import jm.JMC;
import jm.audio.*;
import jm.util.*;
 
 
public class Gongs3 implements JMC {
	
	public static void main(String[] args) {
		new Gongs3();
	}
	
	public Gongs3() {		
		
		Score score = new Score("Gongs 3");
		int partCounter = 0;
		double startTime = 0.0;
		
		for (int j = 0; j < 5; j++) {
			startTime = score.getEndTime();
			int fundPitch = (int)(Math.random() * 12 + C2);
			int pitch = 60;
			double length = Math.random() * 10.0 + 4.0;
			
			for (int i = 0; i < 8; i++) {
				Part p = new Part("Part" + partCounter, partCounter);
				partCounter ++;
				Phrase phrase = new Phrase(startTime);
				if (i == 0 ) { 
					pitch = fundPitch;
					phrase.addNote(new Note(pitch, length + 2.0, 
						127 + C2 - pitch - (int) (Math.random() * 20)));
				} else { 
					pitch = (int)(Math.random() * 16 + fundPitch + 8);
					phrase.addNote(new Note(pitch, length, 
						127 + C2 - pitch - (int) (Math.random() * 20)));
				}
				p.addPhrase(phrase);
				score.addPart(p);
			}
		}
		
		View.show(score);
		
		
		int sampleRate = 11000;
		
		Instrument[] ensemble = new Instrument[partCounter];
		
		for (int k = 0; k < partCounter; k++) {
			ensemble[k] = new VaryDecaySineInst(sampleRate);
		}
			
		
		Write.au(score, "Gongs3.au", ensemble);
	}
} 
               |