The Sound Player


The AudioClip Class

Many of the shortcomings of Applet's play( ) method are remedied by the AudioClip class. AudioClip separates loading from playing and allows looping and termination via the loop( ) and stop( ) methods. Example 7-2 is an updated McDonald applet using AudioClip.

Example 7-2. Applet using the AudioClip class
 import java.awt.*; import javax.swing.*; import java.applet.AudioClip; public class McDonald extends JApplet {   private AudioClip mcdClip;   public void init( )   {  mcdClip = getAudioClip(getCodeBase( ), "mcdonald.mid");  }   public void paint(Graphics g)   {  g.drawString("Old McDonald", 25, 25);  }   public void stop( )   {  mcdClip.stop( ); }   public void start( )   /* A looping play (and a call to play( )) always starts at      the beginning of the clip. */   { mcdClip.loop( );  } } // end of McDonald class 

The clip is loaded with getAudioClip( ) in init( ), causing the applet to suspend until the download is completed. The sound is played repeatedly due to the loop( ) call in start( ), continuing until the applet is removed from the browser (triggering a call to stop( )). If the page is displayed again, start( )'s call to loop( ) will play the music from the beginning.

An application employs AudioClips in just about the same way, except that the clip is loaded with newAudioClip( ) from the Applet class, as shown in the PlaySound application (see Example 7-3).

Example 7-3. Using newAudioClip( ) from an applet
 import java.applet.Applet; import java.applet.AudioClip; public class PlaySound {   public PlaySound(String fnm)   { try {       AudioClip clip = Applet.newAudioClip(                              getClass( ).getResource(fnm) );       clip.play( );  // play the sound once     }     catch (Exception e) {       System.out.println("Problem with " + fnm);     }   }   public static void main(String[] args)   { if (args.length != 1) {       System.out.println("Usage: java PlaySound <sound file>");       System.exit(0);     }     new PlaySound(args[0]);   } } // end of PlaySound class 

Despite AudioClip's simplicity, useful applications and applets can be written with it. One of its great strengths is the large number of file formats that it supports. Another is that multiple AudioClips can be played at the same time.

A drawback of this approach is the suspension caused by calls to getAudioClip( ) and newAudioClip( ). Sun's Java Sound tutorial suggests threads as a solution: the tutorial's SoundApplet and SoundApplication examples fire off a separate thread to load the audio, allowing the main program to continue. Another answer is to download the sound resources with the code, wrapped together in a JAR file, making the subsequent loading a local, fast operation.

A stubborn problem with AudioClip is the lack of information about when a piece of audio finishes. This knowledge can be useful in games since linking events to the end of an audio commentary or music clip is common. A hacky workaround is to call sleep( ) for a period based on the audio file's byte size (which can be obtained via a File object).

A third issue is the lack of low-level access to the sound data (or the audio device it is playing on) to permit runtime effects like volume changing, panning between speakers, and echoing. Related to this is the inability to generate new sounds during execution (i.e., sound and music synthesis) though many early Java texts proudly included variants of the class shown in Example 7-4.

Example 7-4. Using the beep( ) method
 public class Bells {   public static void main(String[] args)   {     // \u0007 is the ASCII bell     System.out.println("BELL 1 \u0007");     try {       Thread.sleep(1000);   // separate the bells     }     catch(InterruptedException e) {}     // ring the bell again, using the Toolkit this time     java.awt.Toolkit.getDefaultToolkit( ).beep( );     System.out.println("BELL 2");     System.out.flush( );   } // end of main( ) } // end of Bells class 

The ASCII character bell works on many platforms, but only Java applications can employ the Toolkit beep( ) method.


What Bells illustrates is the poor low-level access offered by Java. The introduction of the Java Sound API in J2SE 1.3 fixed this weakness.

The examples from this section (McDonald.java, PlaySound.java, and Bells.java) can be found in the SoundExamps/McDonalds/ directory.




Killer Game Programming in Java
Killer Game Programming in Java
ISBN: 0596007302
EAN: 2147483647
Year: 2006
Pages: 340

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