Section 9.1. Manipulating Different Sections of a Sound Differently

9.1. Manipulating Different Sections of a Sound Differently

Manipulating all of the samples in a sound in the same way can be useful, but really interesting effects come from chopping up sounds and manipulating them differentially: Some words this way, other sounds that way. How would you do that? We need to be able to loop through portions of the sample, without walking through the whole thing. This turns out to be an easy thing to do, but we need to manipulate samples somewhat differently (e.g., we have to use our for loop in a slightly different way).

Recall that each sample has an index number, and that we can get each individual sample value with getSampleValue(int index) (with an index number as input). We can set any sample with setSampleValue(int index, int value) (with inputs of an index number, and a new value). That's how we can manipulate samples without using getSamples() and SoundSample objects. But we still don't want to have to write code like:

[Page 294]

sound.setSampleValue(0,12); sound.setSampleValue(1,28);

Not for tens of thousands of samples! So we will continue to use a for loop. However, if we are not processing the entire sound in the same way, the index value that we start at won't necessarily be 0, and the last index value won't necessarily be the length of the sound minus 1.

What if we want to increase the sound for the first half of the sound, then decrease it in the second half. How could we do that? First we will need to calculate the halfway point. We can determine that by dividing the length of the sound by 2. Since the length and 2 are both integers, the result will also be an integer, so no casting is needed (any values after the decimal point will be thrown away). We will need two loops. One loop will start at the beginning of sound (0) and loop till the halfway point. The second loop will start at the halfway point and loop to the end of the sound (length 1).

Program 71. Increase the Volume then Decrease

(This item is displayed on pages 294 - 295 in the print version)

/** * Method to increase the first half of the sound * (double it) and then decrease the * second half (half it). */ public void increaseAndDecrease() { int half = this.getLength() / 2; int value = 0; // loop through the first half of the soundfor (int i = 0; i < half; i++) { // get the current value value = this.getSampleValueAt(i); // set the value to 2x the originalthis.setSampleValueAt(i,value * 2); } // loop through the second half of the soundfor (int i = half; i <this.getLength(); i++) { // get the current value value = this.getSampleValueAt(i);

[Page 295]

// set the value to half the originalthis.setSampleValueAt(i,(int) (value * 0.5)); } }

There are two loops in increaseAndDecrease(), each of which deals with one half of the sound.

The first loop deals with the samples from 0 to halfway through the sound. Those samples all get multiplied by 2, to double their amplitude.

The second loop goes from halfway through to the end of the sound. Here, we multiply each sample by 0.5 thus decreasing the sound by 50%.

Another Way of Writing Array References

It's worth pointing out that in many languages, square brackets ([ ]) are standard notations for manipulating arrays. It works that way in Java. For any array, array[index] returns the index-th element in the array. The number inside the square brackets is always an index variable, but it's sometimes referred to as a subscript, because of the way that mathematicians refer to the i-th element of a, e.g., ai.