|   
         Overtones and Harmonics 
      
      All partials identified by Fourier analysis (a decomposition 
        of sounds into thier sine wave components) are referred to as overtones. 
         
        The overtones that have a frequency at a simple multiple of the fundamental 
        (2:1, 3:1, 6:1 etc.) are referred to as harmonics,  
        and create 'nice' musical sounds. 
        Inharmonic overtones (frequencies not at simple multiples) create more 
        clangerous timbres, such as bells and other percussion sounds.  
        In this example, inharmonic overtones are used to create a timpani-like 
        sound. 
      Heres the audio file: 
       
      TimpaniTest.au [1377k] 
       
      Heres the code: 
       
      View / Download source 
        - Instrument source code 
      View / Download source 
        - Composition source code 
      Instrument class overview 
           
      
        
           
             import jm.audio.io.*; import jm.audio.synth.*; import jm.music.data.Note; import jm.audio.Instrument;
  
public final class TimpaniInst extends Instrument{
	
	private int overtones = 5;
	
	private double[] freqVals = {1.0, 1.42, 1.53, 1.77, 1.94};
	
	private double[] volVals = {1.0, 0.8, 0.7, 0.6, 0.5};
	
	private double[][] points = new double[overtones][8];
	private double[] pointArray1 = {0.0, 0.0, 0.002, 1.0, 0.3, 0.3, 1.0, 0.0};
	private double[] pointArray2 = {0.0, 0.0, 0.05, 1.0, 0.2, 0.4, 1.0, 0.0};
	private double[] pointArray3 = {0.0, 0.0, 0.1, 1.0, 0.4, 0.3, 1.0, 0.0};
	
	
	private float pan;
	
	private int sampleRate;
	
	private Oscillator[] osc;
	
	private Envelope[] env;
	
	private Volume[] vol;	
	
	public TimpaniInst(int sampleRate){
		this.sampleRate = sampleRate;
		
		points[0] = pointArray1;
		points[1] = pointArray2;
		points[2] = pointArray3;
		points[3] = pointArray2;
		points[4] = pointArray3;
	}
	
	public void createChain(){
		
		osc = new Oscillator[overtones];
		env = new Envelope[overtones];
		vol = new Volume[overtones];
		for(int i=0;i&t;overtones; i++){
			osc[i] = new Oscillator(this, Oscillator.SINE_WAVE,
                            this.sampleRate, 2);
			osc[i].setFrqRatio((float)freqVals[i]); 
			env[i] = new Envelope(osc[i], points[i]);
			vol[i] = new Volume(env[i], (float)volVals[i]);
		}
		
		Add add = new Add(vol);
		StereoPan span = new StereoPan(add);
		SampleOut sout = new SampleOut(span);
	}
}
               | 
           
        
       
         
      Importantly, the oscillators are set to frequency ratios of 
        the fundamental that are not simple multiples. 
        The specific rations are speciefied in this line: 
          private double[] freqVals = {1.0, 
        1.42, 1.53, 1.77, 1.94}; 
       
      As well, each overtone can have a different amplitude envelope creating 
        a dynamic timbre that changes over time.  
        For example, the envelope points of the fundamental is specified in this 
        line: 
       
          private double[] pointArray1 = 
        {0.0, 0.0, 0.002, 1.0, 0.3, 0.3, 1.0, 0.0}; 
       
      One convient coding 'trick' in the createChain() method is to use a for-loop 
        to create the chain for each overtone, then add them together after that. 
         
        This saves some repetition of similar code. Here is the relevant for loop: 
          for(int i=0;i<overtones;i++){ 
                    
        osc[i] = new Oscillator(this, Oscillator.SINE_WAVE, 
                                    
        this.sampleRate, 2); 
                    
        osc[i].setFrqRatio((float)freqVals[i]); 
                    
        env[i] = new Envelope(osc[i], points[i]); 
                    
        vol[i] = new Volume(env[i], (float)volVals[i]); 
                } 
       
       
        Musical Example 
      
        
           
             import jm.JMC; import jm.music.data.*; import jm.audio.*; import jm.util.*;
  public final class TimpaniTest implements JMC{ 	public static void main(String[] args){ 		Score score = new Score("JMDemo - Audio test"); 		Part part = new Part("wave", 0); 		Phrase phr = new Phrase(0.0); 		int sampleRate = 44100; 		Instrument inst = new TimpaniInst(sampleRate); 		for (int i=0; i<8; i++ ) { 			Note note = new Note(C3 - i, 1.0); 			phr.addNote(note); 		} 		part.addPhrase(phr); 		score.addPart(part); 		Write.au(score, "TimpaniTest.au", inst); 	} }  
             | 
           
        
       
          This test code creates a descending chromatic run 
        of eight notes in a low register, as would be typical of a timpani pitch. 
       
        Easy variation of the Additive 
      Synthesis instrument The lines of code below can be 
        substituted in the Timpani instrument to create a mellow bell-like tone, 
        not unlike a vibraphone. 
          private int overtones = 3; 
             private double[] freqVals 
        = {1.0, 2.7, 6.75}; 
            private double[] volVals = {1.0, 0.77, 
        0.7}; 
       
       View / Download source - 
        Instrument source code 
         
      This shows how simply a different timbre can be created 
        with additive synthesis by changing overtone values. 
       
         
       
       |