Java Reference
In-Depth Information
The constructor then initializes a normalization array named normArray . This is an array of double values
used to normalize the magnitude values that are later computed for each equalizer band's frequency range. The
normalization factor attempts to compensate for the fact that the bandwidth doubles in each successive equalizer
band, but we still want to display all of them on the same scale in our SpectrumBar controls.
The final piece of initialization code called from our constructor is the createBucketCounts method. This
method's job is to figure out how many spectrum bands fall within each of our equalizer bands. It creates “buckets”
into which we can later sum the magnitudes of each of the spectrum bands, thus easily figuring out to which equalizer
band they correspond. The bucket counts are stored in an int array that is the same length as the SpectrumBar array;
that is, one bucket for each SpectrumBar .
To begin the bucket calculation, we assume that the spectrum data will cover frequencies of up to 22.05 kHz,
which is a good assumption for music. Spoken audio (voices only) will typically cover a much smaller range of
frequencies, but the spectrum data provided by the media engine will cover all 22.05 kHz. We divide this maximum
frequency by the number of audio spectrum bands to yield the bandwidth of each band. Half of the bandwidth gives
us the center frequency of the first band. We then proceed to set the initial values of the variables used inside the for
loop. These are set such that the first time through the loop, the value of currentSpectrumFreq (which was initialized
to the center frequency of the first spectrum band) is greater than the currentCutoff frequency (which was initialized
to zero) thus triggering a recalculation of our loop variables. We do this so that we don't have to treat the first iteration
of the loop differently than the following iterations.
After the first iteration, the loop variables are all set up as expected and the count of the first bucket is
incremented. The loop then proceeds to check the center frequency of each spectrum band. If it is greater than the
cutoff frequency of the current equalizer band, the bucket index is incremented and the bucket corresponding to the
next equalizer frequency begins to be incremented. When finished, we have an array that tells us how many spectrum
bands are contained in each equalizer band.
This bucket array allows us to sum the magnitudes of each spectrum band quickly and assign them to the correct
equalizer band during the listener's spectrumDataUpdate method. This optimization is a good idea because the
spectrumDataUpdate takes place 10 times per second. The code for the listener's spectrumDataUpdate method is
shown in Listing 9-26.
Listing 9-26. SpectrumListener 's spectrumDataUpdate Method
@Override
public void spectrumDataUpdate(double timestamp, double duration,
float[] magnitudes, float[] phases) {
int index = 0;
int bucketIndex = 0;
int currentBucketCount = 0;
double sum = 0.0;
while (index < magnitudes.length) {
sum += magnitudes[index] - minValue;
++currentBucketCount;
if (currentBucketCount >=spectrumBucketCounts[bucketIndex]) {
bars[bucketIndex].setValue(sum / norms[bucketIndex]);
currentBucketCount = 0;
sum = 0.0;
++bucketIndex;
}
++index;
}
}
 
Search WWH ::




Custom Search