Section 10.6. Modern Music Synthesis


[Page 333 (continued)]

10.6. Modern Music Synthesis

Additive synthesis is how early music synthesizers worked. Nowadays, additive synthesis isn't too common because the sounds that it generates aren't natural sounding. Synthesizing from recorded sounds is quite common, but it isn't pure synthesis in the sense of creating sounds out of nothing.

The most common synthesis technique today is probably FM synthesis or frequency modulation synthesis. In FM synthesis, an oscillator (a programmed object that generates a regular series of outputs) controls (modulates) frequencies with other frequencies. The result is a richer sound, less tinny or computer sounding.

Another common technique is subtractive synthesis. In subtractive synthesis, out-and-out noise is used as the input, and then filters are applied to remove unwanted frequencies. The result is, again, a richer sound, though typically not as rich as FM synthesis.

Why would we want to create sounds or music with computers anyway? What's the point when there are lots of great sounds, music, and musicians in the world? The point is that if you want to tell someone else how you got that sound, so that they could replicate the process, or even modify the sound in some way (perhaps making it better), a program is the way to do it. A program succinctly captures and communicates a processhow a sound or piece of music is generated.


[Page 334]

10.6.1. MP3

Nowadays, the most common kind of audio file that you have on your computer is probably an MP3 (or perhaps MP4 or one of its related or descendant file types). MP3 files are sound (and video, in some cases) encodings based on the MPEG-3 standard. They are audio files, but compressed in special ways.

One way in which MP3 files are compressed is called lossless compression. As we know, there are techniques for storing data that use fewer bits. For example, we know that every sample is typically two bytes wide. What if we didn't store every sample, but instead stored the difference from the last sample to the current sample? The difference between samples is usually much smaller than 32,767 to 32,768it might be +/1,000. That takes fewer bits to store.

But MP3 also uses lossy compression. It actually throws away some of the sound information. For example, if there's a really soft sound immediately after or simultaneous with a really loud sound, you won't be able to hear the soft sound. A digital recording keeps all those frequencies. MP3 throws away the ones you can't actually hear.

WAV files are kind of compressed, but not as much as MP3, and they only use lossless techniques. Some WAV files use MP3 compression which makes them really MP3 files. MP3 files tend to be much smaller than the same sound in a WAV format. AIFF files are similar to WAV files.

10.6.2. MIDI

MIDI is the Musical Instrument Digital Interface. It's really a set of agreements between manufacturers of computer music devices (sequencers, synthesizers, drum machines, keyboards, etc.) for how their devices will work together. Using MIDI, you can control various synthesizers and drum machines from different keyboards.

MIDI doesn't really record what something sounds like, instead it encodes how it is played. Literally, MIDI encodes information like "Press the key down on synthesized instrument X at pitch Y" then later "Release the key Y on instrument X." The quality of MIDI sound depends entirely on the synthesizer, the device generating the synthesized instrument.

MIDI files tend to be very small. Instructions like "Play key #42 on track 7" are only some five bytes long. This makes MIDI attractive in comparison with large sound files. MIDI has been particularly popular for karaoke machines.

MIDI has an advantage over MP3 or WAV files in that it can specify a lot of music in very few bytes. But MIDI can't record any particular sound. For example, if you want to record a particular person's style of playing an instrument, or record anyone singing, you don't want to use MIDI. To capture actual sounds, you need to record the actual samples, so you'll need MP3 or WAV.


[Page 335]

Most modern operating systems have pretty good synthesizers built into them. We can actually use them from Java. We have created a class MidiPlayer that has a method playNote that takes as input a note as a number and a duration (how long to play the sound) in milliseconds. The note numbers correspond to keys, not to frequencies. C in the first octave is 1, C# is 2. C in the fourth octave is 60, D is 62, and E is 64. See http://www.harmony-central.com/MIDI/Doc/table2.html for more information on the note numbers. If you don't specify what instrument you want to play the note on it will simulate a piano.

Here's a simple example of playing some MIDI notes from DrJava.

> MidiPlayer player = new MidiPlayer(); > player.playNote(62,250); // d quarter note > player.playNote(60,500); // c half note


The 250 and 500 specify the number of milliseconds to play the note. If you want a measure to take one second (1,000 milliseconds), then a quarter note would be 250 milliseconds and a half note would be 500 milliseconds.

We can write a method to play a song. How about writing a method to play part of Jingle Bells? Here is a method that plays the first four measures from it. Put this in the MidiPlayer class (before the ending curly brace) and compile it.

Program 92. Playing a Song
(This item is displayed on pages 335 - 336 in the print version)

/**  * Method to play the first 4 measures of Jingle Bells  * with each measure taking 1000 milliseconds (1 second)  * this is 2/4 time  */ public void playJingleBells4() {   // measure 1   playNote(52,250); // e eighth note   playNote(60,250); // c eighth note   playNote(58,250); // b flat eighth note   playNote(56,250); // a flat eighth note   // measure 2   playNote(52,500); // e quarter note   rest(250);        // rest   playNote(52,125); // e sixteenth note   playNote(52,125); // e sixteenth note   // measure 3   playNote(52,500); // e eighth note   playNote(60,250); // c eighth note 
[Page 336]
playNote(58,250); // b flat eighth note playNote(56,250); // a flat eighth note // measure 4 playNote(53,1000); // f half note }


This method only plays the first four measures of Jingle Bells. This may not sound like "Jingle Bells" to you since we are using the original version first published in 1,859 by James Pierpont.

To play this using the default piano sounding instrument do the following:

> MidiPlayer player = new MidiPlayer(); > player.playJingleBells4();


You can change the instrument that you want to use to play the notes using the method setInstrument(int num) where the num is a number from 0 to 127 that maps to an instrument. We have created constants for some of the instrument numbers as you can see at the top of the MidiPlayer class definition. To play the first four measures of Jingle Bells on a flute do the following:

> MidiPlayer player = new MidiPlayer(); > player.setInstrument(MidiPlayer.FLUTE); > player.playJingleBells4();


10.6.3. Private Methods

Music often repeats. In Jingle Bells the first verse is played and then the refrain. Next the second verse is played, and then the refrain is played again. The first verse and second verse are a bit different, but many of the measures in the two verses are the same. If we want to write a method that plays the first two verses of Jingle Bells with each verse followed by the refrain, we could put all the measures in it for both verses and the refrains, but then it would be very long (67 measures). Another option is to pull out the measures in the refrain and make a method that just plays the refrain and then call that method from the one that plays Jingle Bells.

Does this new method that plays just the refrain need to be public? If we don't think any other class will need access to the new method we can make it private. Private methods can only be invoked from code in the class that they are declared in. You will get an error if you try to invoke a private method in code that is in another class. Private methods are also called helper methods.

To declare a method to be private, use the keyword private for the visibility. Remember that to declare a method you must specify:

visibility returnType methodName(parameterList)


The following method is a private method that will play the refrain of Jingle Bells.


[Page 337]

Program 93. Playing the Refrain
(This item is displayed on pages 337 - 338 in the print version)

/**  * Method to play refrain of Jingle Bells  */ private void playJingleBellsRefrain() {   // measure 1   playNote(60,250); // c eighth note   playNote(60,250); // c eighth note   playNote(60,500); // c quarter note   // measure 2   playNote(63,250); // e flat eighth note   playNote(63,250); // e flat eighth note   playNote(63,500); // e flat quarter note   // measure 3   playNote(60,250); // c eighth note   playNote(60,250); // c eighth note   playNote(65,375); // f dotted eighth note   playNote(65,125); // f sixteenth note   // measure 4   playNote(64,1000); // e half note   // measure 5   playNote(65,250); // f eighth note   playNote(61,250); // d flat eighth note   playNote(56,250); // a flat eighth note   playNote(64,250); // f eighth note   // measure 6   playNote(63,250); // e flat eighth note   playNote(60,250); // c eighth note   playNote(56,250); // a flat eighth note   playNote(56,125); // a flat sixteenth note   playNote(58,125); // b flat sixteenth note   // measure 7   playNote(60,250); // c eighth note   playNote(58,250); // b flat eighth note   playNote(56,250); // a flat eighth note   playNote(58,250); // b flat eighth note   // measure 8   playNote(60,1000); // c half note   // measure 9   playNote(60,250); // c eighth note   playNote(60,250); // c eighth note   playNote(60,500); // c quarter note 
[Page 338]
// measure 10 playNote(63,250); // e flat eighth note playNote(63,250); // e flat eighth note playNote(63,500); // e flat quarter note // measure 11 playNote(60,250); // c eighth note playNote(60,250); // c eighth note playNote(65,250); // f eighth note playNote(65,250); // f eighth note // measure 12 playNote(64,1000); // e half note // measure 13 playNote(53,250); // f eighth note playNote(61,250); // d flat eighth note playNote(60,250); // c eighth note playNote(58,250); // b flat eighth note // measure 14 playNote(56,250); // a flat eighth note playNote(63,250); // e flat eighth note playNote(62,250); // d eighth note playNote(63,125); // e flat sixteenth note playNote(63,125); // e flat sixteenth note // measure 16 playNote(65,250); // f eighth note playNote(63,250); // e flat eighth note playNote(61,250); // d flat eighth note playNote(58,250); // b flat eighth note // measure 17 playNote(56,500); // a flat quarter note rest(500); // rest }


Assume that we have written the methods that play the two verses as private methods. Here is a method that will play the first two verses of Jingle Bells with each verse followed by the refrain.

Program 94. Playing Jingle Bells
(This item is displayed on pages 338 - 339 in the print version)

/**  * Method to play Jingle Bells  */ public void playJingleBells() {   // play verse 1   playJingleBellsV1(); 
[Page 339]
// play refrain playJingleBellsRefrain(); // play verse 2 playJingleBellsV2(); // play refrain playJingleBellsRefrain(); }


The advantage to breaking methods into smaller reusable methods is that if there is a mistake in one of the smaller methods it is easier to find and fix. If we had created one very long method with all the measures in it, we probably would have copied and pasted the measures in the refrain. If we had to fix notes in the refrain, we would have to fix them in both copies of it. By pulling out repeated code, we have only one copy of it to fix and check for errors.



Introduction to Computing & Programming Algebra in Java(c) A Multimedia Approach
Introduction to Computing & Programming Algebra in Java(c) A Multimedia Approach
ISBN: N/A
EAN: N/A
Year: 2007
Pages: 191

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net