<< Chapter < Page | Chapter >> Page > |
.....
Listing 6 . The class named AudioGraphSquareWave. |
---|
/*File AudioGraphSquareWave.java
Copyright 2014, R.G.BaldwinRevised 08/19/14
This class can be used to create an 8-second melody consisting of 32 pulsesat different frequencies.
******************************************************************************/import java.io.*;
import java.nio.*;import java.util.*;
public class AudioGraphSquareWave extends AudioSignalGenerator02{public AudioGraphSquareWave(AudioFormatParameters01 audioParams,String[] args,byte[] melody){super(audioParams,args,melody);
}//end constructor//-------------------------------------------------------------------------////This method returns a melody array that will play an 8-second melody
// consisting of 32 pulses at two different frequencies. The two frequencies// are equidistant on either side of middle-C.//The frequency deviation from middle-C versus time is based on a square wave
// function with a frequency of 0.5 Hz. That is, the function// switches between equal positive and negative values once per second
// producing a periodic function where each cycle is two seconds// long.//Each pulse represents one point on
// a graph of the square wave. Pulses with frequencies at or above// middle-C are delivered to the left speaker. Pulses with
// frequencies below middle-C are delivered to the right speaker.// Middle-C is considered to represent the horizontal axis of the
// graph with a value of zero.//The audio output can be thought of as an audio representation of a graph
// of a square wave. Pulses with frequencies above middle-C represent points// on the positive lobe of the square wave. Increasing pitch represents
// increasing amplitude on the graph of the square wave. Pulses with// frequencies below middle-C can be thought of as representing points on
// the negative lobe of the square wave. In this case, decreasing pitch// represents points on the square wave that are further from the horizontal
// axis in the negative direction.//In order to eliminate pops and clicks caused by abrupt frequency changes
// in the audio signal, the amplitude of each pulse is scaled by a// triangular (rooftop) function that has a value that is zero at both ends
// and 1.0 in the center with a linear progression from the center to the// ends in both directions.
//Four complete cycles of the 0.5 Hz square wave are represented by the 32// pulses in the 8-second melody.byte[] getMelody(){//Set channels to 2 for stereo overriding the default value of 1.
audioParams.channels = 2;System.out.println("audioParams.channels = " + audioParams.channels);
//Each channel requires two 8-bit bytes per 16-bit sample.int bytesPerSampPerChan = 2;//Override the default sampleRate of 16000.0F. Allowable sample rates
// are 8000,11025,16000,22050, and 44100 samples per second.audioParams.sampleRate = 8000.0F;// Specify the length of the melody in seconds.
double lengthInSeconds = 8.0;//Set the center frequency.double centerFreq = 261.63;//middle C//Create an output array of sufficient size to contain the melody at
// "sampleRate" samples per second, "bytesPerSampPerChan" bytes per// sample per channel and "channels" channels.
melody = new byte[(int)(lengthInSeconds*audioParams.sampleRate*bytesPerSampPerChan*audioParams.channels)];System.out.println("melody.length = " + melody.length);//Declare variables used to control the output volume on the left and
// right speaker channels.double gain = 0.0;
double leftGain = 0.0;double rightGain = 0.0;
//Declare the initial frequency deviation from center. To represent the// square wave, pulses will be played that are plus and minus this
// amount relative to the center frequency.double deviation = 75;//Specify the number of pulses in one-half cycle of the square wave.
int halfCycle = 4;//Declare a variable that is used to control the frequency of each pulse.double freq = centerFreq + deviation;
//Prepare a ByteBuffer for usebyteBuffer = ByteBuffer.wrap(melody);
//Compute the number of audio samples in the melody.int sampLength = (int)(lengthInSeconds*audioParams.sampleRate);
//Set the length of each pulse in seconds and in samples.double pulseLengthInSec = 0.25;//in seconds
int pulseLengthInSamples = (int)(pulseLengthInSec*audioParams.sampleRate);//Compute the audio sample values and deposit them in the output melody
// array.for(int cnt = 0; cnt<sampLength; cnt++){
//Compute the time in seconds for this sample.double time = cnt/audioParams.sampleRate;if(cnt % (halfCycle * pulseLengthInSamples) == 0){
//Switch to the other side of the center frequency.deviation = -deviation;
freq = centerFreq + deviation;}//end if
//Deposit audio data in the melody for each channel. Scale the amplitude// of each pulse with a triangular scale factor (rooftop shape) to
// minimize the undesirable pops and clicks that occur when there is an// abrupt change in the frequency from one pulse to the next. The
// following gain factor ranges from 0.0 at the ends to 1.0 in the// center of the pulse.
gain = (cnt%pulseLengthInSamples)/(double)pulseLengthInSamples;if(gain>0.5){
//Change to a negative slope.gain = (pulseLengthInSamples -
cnt%pulseLengthInSamples)/(double)pulseLengthInSamples;}//end if//Set the final gain to a value that is compatible with 16-bit audio
// data.gain = 8000*gain;
//Switch the left and right channels on and off depending on the location// of the pulse frequency relative to the center frequency.
if(freq>= centerFreq){
leftGain = gain;rightGain = 0;//switch off the right channel
}else{rightGain = gain;
leftGain = 0;//switch off the left channel}////Compute scaled pulse values and deposit them into the melody.
byteBuffer.putShort((short)(leftGain*Math.sin(2*Math.PI*freq*time)));byteBuffer.putShort((short)(rightGain*Math.sin(2*Math.PI*freq*time)));
}//end for loopreturn melody;}//end method getMelody
//-------------------------------------------------------------------------//}//end class AudioGraphSquareWave
//===========================================================================// |
Notification Switch
Would you like to follow the 'Accessible objected-oriented programming concepts for blind students using java' conversation and receive update notifications?