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