<< Chapter < Page Chapter >> Page >

The audio output can be thought of as an audio representation of a graph of the input data with three zero values prepended onto the front toestablish the pitch for a y value of zero. Other than those three pulses, each output pulse represents one point on the graph. That is, each output pulse representsthe value of y for a given value of x for the function being evaluated.

The beginning of the method named getMelody is shown in Listing 12 .

You have seen code like this in many previous modules, so no explanation beyond the embedded comments should be needed for this code.

Listing 12 . Beginning of the method named getMelody.
byte[] getMelody(){//Set channels to 2 for stereo overriding the default value of 1. audioParams.channels = 2;//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;//Declare variables used to control the output volume on the left and// right speaker channels. These values will be used to cause pulses // representing the data values to progress uniformly from the left// speaker to the right speaker in proportion to the value of x. double gain = 0.0;double leftGain = 0.0; double rightGain = 0.0;//Declare a variable that is used to control the frequency of each pulse. double freq = 0.0;//Set the length of each pulse in seconds and in samples. The user // specifies the output rate in pulses per second as a command-line// parameter. The pulse length in seconds is the reciprocal of that value. double pulseLengthInSec = 1/Double.parseDouble(args[1]);//in seconds int pulseLengthInSamples = (int)(pulseLengthInSec*audioParams.sampleRate);//Create an output array of sufficient size to contain the audio data.melody = new byte[(int)(inputData.length * pulseLengthInSamples *bytesPerSampPerChan * audioParams.channels)]; System.out.println("melody.length = " + melody.length);//Prepare a ByteBuffer for usebyteBuffer = ByteBuffer.wrap(melody);

Determine the frequency and data ranges

Later on, in order to map the data values into frequencies and make maximum use of the available audio dynamic range from 220 Hz to 1760 Hz, we will need toknow the frequency range and the data range.

The first statement in Listing 13 computes the frequency range. I could have taken care of this back in Listing 9 where the high and low frequency limits were established but I overlooked it at that point.

The code beginning with the second statement determines the minimum and maximum data values.This can only be determined after the actual data values have been read from the input file. These values will be used to bias and scale the data so as to make maximum use of the availableaudio dynamic range.

Listing 13 . Determine the frequency and data ranges.
double freqRange = highFreq - lowFreq;double highData = Double.MIN_VALUE; double lowData = Double.MAX_VALUE;//Skip first three values which are always zero. for(int cnt = 3;cnt<inputData.length;cnt++){ if (inputData[cnt]>highData){ highData = inputData[cnt]; }//end ifif(inputData[cnt]<lowData){ lowData = inputData[cnt]; }//end if}//end for loop double dataRange = highData - lowData;

Get Jobilize Job Search Mobile App in your pocket Now!

Get it on Google Play Download on the App Store Now




Source:  OpenStax, Accessible objected-oriented programming concepts for blind students using java. OpenStax CNX. Sep 01, 2014 Download for free at https://legacy.cnx.org/content/col11349/1.17
Google Play and the Google Play logo are trademarks of Google Inc.

Notification Switch

Would you like to follow the 'Accessible objected-oriented programming concepts for blind students using java' conversation and receive update notifications?

Ask