8.4. Normalizing SoundsIf you think about it, it seems strange that the last two methods work! We can just multiply these numbers representing a soundand the sound seems (essentially) the same to our ears just louder? The way we experience a sound depends less on the specific numbers than on the relationship between them. Remember that the overall shape of the sound waveform is dependent on many samples. In general, if we multiply all the samples by the same multiplier, we only effect our sense of volume (intensity), not the sound itself. (We'll work to change the sound itself in future sections.) A common operation that people want to do with sounds is to make them as LOUD AS POSSIBLE. That's called normalizing. It's not really hard to do, but it takes more lines of code than we've used previously and a few more variables, but we can do it. Here's the algorithm, in English, that we need to tell the computer to do.
Here's a program to normalize sounds. Program 69. Normalize the Sound to a Maximum Amplitude |
/** * Method to normalize (make as loud as possible) a sound. */ public void normalize() { int largest = 0; int maxIndex = 0; SoundSample[] sampleArray = this.getSamples(); SoundSample sample = null; int value = 0; // loop comparing the absolute value of the current value // to the current largest for (int i = 0; i < sampleArray.length; i++) { sample = sampleArray[i]; value = Math.abs(sample.getValue()); if (value > largest) |
There are several notational items to note about this program.
There is more than one loop in this method. That is okay. We can even use the same variable i in each loop. Since the variable is declared in the initialization area of the for loop, it is only known in that loop. So, when we declare i again in the second loop it is seen as a new variable and not an attempt to declare the same variable more than once.
There are System.out.println() statements in there! These statements can be really useful. First, they give you some feedback that the program is runninga useful thing in long-running programs. Second, they show you what it's finding, which can be interesting. Third, it's a terrific testing method and a way to debug your programs. Let's imagine that the printout showed that the multiplier was less than 1.0. We know that that kind of multiplier decreases volume. You should suspect that something went wrong.
Here's how to run this program:
> Sound s = new Sound(FileChooser.getMediaPath("preamble.wav")); > s.explore(); > s.normalize(); The largest value was 10216 at index 179377 The multiplier is 3.207419733750979 > s.play(); > s.explore();
Exciting, huh? Obviously, the interesting part is hearing the much louder volume, which is awfully hard to do in a book. So please try it now if you haven't yet. But you can see from Figure 8.19 that the values have increased.
Earlier, we talked about clipping, what happens when the normal curves of the sound are broken by the limitations of the sample size. One way of generating clipping is to keep increasing the volume. Another way is to explicitly force clipping.
What if you only had the largest and smallest possible sample values? What if all positive values (including zero), were the maximum value (32,767) and all negative values were the minimum value (32,768)? Try this program, particularly on sounds with words in them.
/** * Method to set all the sample values to the * maximum positive value if they were positive * (including 0) and the minimum negative * value if they were negative. */ public void forceToExtremes() { SoundSample[] sampleArray = this.getSamples(); SoundSample sample = null; // loop through the sample values for (int i = 0; i < sampleArray.length; i++) { // get the current sample sample = sampleArray[i]; |
Here's how to run this program:
> Sound s = new Sound(FileChooser.getMediaPath("preamble.wav")); > s.play(); > s.explore(); > s.forceToExtremes(); > s.play(); > s.explore();
Look at Figure 8.20 and see that all the values have been set to extremes. When you play the sound back, you'll hear a bunch of awful noises. That's clipping. The really amazing thing is that you can still make out the words in sounds that you manipulate with this method. Our ability to decipher words from noise is incredibly powerful.