Seeing the audio data    
          
        
        This class prints the sine wave data to the 
          standard output rather than to an audio file.
        View / Download source
       Lets have a closer look. 
        
           
             import jm.music.data.*;
import jm.JMC;
import jm.audio.*;
import jm.util.*;
 
public class WaveformPrintOut implements JMC {
	
	public static void main(String[] args) {
		new WaveformPrintOut();
	}
	
	public WaveformPrintOut() {	        
		Note n = new Note(C4, QUAVER);
		Score score = new Score(new Part(new Phrase(n)));
		
		
		Instrument printout = new PrintSineInst(44100);
 
		
		
		
		
		Write.au(score, "WaveformExample.au", printout);
			
		
	}
}
   | 
          
        
        So what's really going on when an audio file 
        is rendered? 
        
        This tutorial sets out to begin answering that question. The class 
          above prints the sample values out to the screen rather than to a file, 
          
          so you can see what's going on.
        The results of running the program will look 
          similar to:
        0.2359
          0.2167
          0.1986
          ...
          -0.0178
          -0.0438
          ...
        There are a few of important things to notice 
          about the data. 
        
          - The numbers are floating point values. All audio processing in jMusic 
            happens as floating point numbers which ensures
            that the resolution (quality) is extremely high. 
           - The numbers are both positive and negative. The audio values centre 
            around zero with louder values being those most distant from zero. 
          
 - The numbers are close to zero in value. Numbers produced by each 
            note in jMusic are between -1.0 and 1.0 in value and so if three notes 
            play
            at the same time their combined maximum value will be 3.0 or -3.0. 
            Because the largest floating point values in Java can be in the millions 
            
            you can see that there is plenty of head room in the use of floating 
            point values 
            (we can have very dense textures without the risk of distortion from 
            clipping). 
         
        How are these values generated?
        By whatever maths you like; is the short 
          answer. In the case of a sine wave the following code segment does the 
          work.
        		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;
		}
        Notice the use of Math.PI and Math.sin() 
          which are required to get the characteristic wave-like ascending and 
          descending values of the sine wave.
        		float[] sampleArray = new float[numOfSamples]; 
        These values are calculated for a single cycle of the sine wave and 
          stored in an array established by the line of code above. 
          This array is a 'table' of values that is then used to render the notes. 
          
          The use of a table of values is very widely used in digital sound synthesis 
          and commonly referred to as WaveTable synthesis.
        Wavetable Synthesis
        In Java wave tables are usually arrays of values filled with calculated 
          values (as above) or with values from digital recordings of acoustic 
          sounds.
          Wavetables are of a specified length and notes of different lengths 
          and pitches read from the table in different ways. 
          As an oscillator, the wavetable is read over and over from front to 
          back as many times as required (usually hundreds or thousands of times 
          per second).
          In our sine wave example, one cycle of the sine wave is kept in the 
          wavetable so the rendering of the note A4 (frequency 440 hz) requires 
          that the 
          wavetable be read 440 times for every second of sound.
        
          
            
 
          
        
        This diagram shows how a table can be filled 
          with various values and after it is read from beginning to end reading 
          starts again at the beginning.
        More complicated readings of the wave table can be done. For example 
          a section of the wavetable can be looped, rather than the whole table. 
          
          To play the waveform at higher pitches some samples can be skipped - 
          for example reading every second sample will raise the playback pitch 
          an octave.
        Further details 
        For more detailed information on wavetable synthesis read chapter 3 
          of "The Computer Music Tutorial" by Curtis Roads and chapters 
          3 and 4 of "Computer Music" by Dodge and Jerse.