JDK 1.2 breaks the Java sound barrier

Learn how to implement JDK 1.2’s high-quality sound

Earlier versions of the JDK produced audio through an applet or an application in .au format only, which provided support for 8,000 Hz mono 8-bit mu-Law-encoded audio clips. That fairly substandard sound format severely restricted Java in providing professional audio qualities. The recent release of JDK 1.2 has remedied that problem, as it now offers support for almost all available audio formats. The new sound engine supports the following audio file formats:

  • MIDI (type 0 and type 1): the Musical Instrument Digital Interface, a digital format for musical instruments
  • RMF: the Rich Music Format, an audio file format from Beatnik for online playback with the Beatnik Player plug-in
  • WAVE: the Microsoft Windows audio file format
  • AIFF: the Audi Interchange File Format, used specifically with Mac or SGI computers
  • AU: the Sun audio file format

Both applications and applets support those audio file formats.

Play an audio file through an applet

To play an audio file through an applet, you must complete the following steps:

  • Obtain the audio clip from the specified URL
  • Instantiate the AudioClip object
  • Play, stop, or loop the audio file in response to certain actions or events occurring within the applet

The most flexible method is to load an object that implements the AudioClip interface and then invoke the object’s play(), stop(), or loop() methods. You can load the audio file from the specified URL at the init() method of the applet. The following code snippet loads a particular audio file from a specified URL:

AudioClip clip=getAudioClip(getCodeBase(),"sample.wav");

Replace getCodeBase() with getDocumentBase(), if the location of the audio file so demands. For a recapitulation, the getCodeBase() method returns the URL of the loading applet, and getDocumentBase() returns the URL of the HTML file containing the applet.

Here, the URL from which to load the applet is the same as the URL of the applet itself, specified through the getCodeBase() statement. You can specify any other URL for the audio file (note that an applet, by its restriction, can only read files from the server that hosts it). The sound file shown below features a .wav extension, but files can be in any format supported by JDK 1.2.

You can play, stop, or loop the clip object with the following instructions:

    clip.play(); 
    clip.stop(); 
    clip.loop(); 

The full code

Here I present the full Java code that declares the Play, Stop, and Loop buttons and their corresponding actions:

import java.applet.*; 
import java.awt.*; 
public class audioApplet extends Applet { 
    //declaring the buttons to control the audio 
    Button playButton; 
    Button stopButton; 
    Button loopButton; 
    //declaring the audio clip 
    AudioClip clip; 
public void init() 
{ 
    //initializing the Buttons 
    playButton=new Button("Play"); 
    stopButton=new Button("Stop"); 
    loopButton=new Button("Loop"); 
    //adding ActionListeners to the Buttons 
    playButton.addActionListener(new ButtonResponser()); 
    stopButton.addActionListener(new ButtonResponser()); 
    loopButton.addActionListener(new ButtonResponser()); 
    //Adding the Buttons to the Applet 
    add(playButton); 
    add(stopButton); 
    add(loopButton); 
    //initializing the audio clip 
    clip=getAudioClip(getCodeBase(),"sample.wav"); 
} 
public void stop() 
{ 
    clip.stop(); 
} 
public void destroy() 
{ 
    clip.stop(); 
} 
//The ButtonResponser handles the events generated through the Buttons 
    class ButtonResponser implements ActionListener 
    { 
        public void actionPerformed(ActionEvent e) 
        { 
            String action=e.getActionCommand();
            if(action.equals("Play")) 
                clip.play(); 
            else if(action.equals("Stop")) 
                clip.stop(); 
            else if(action.equals("Loop")) 
                clip.loop(); 
            } 
    }//end of ButtonResponder Class 
}//end of audioApplet class 

Run the applet

Although the above code is simple and no expert coding is required to play the new audio format, no present version of any browser directly supports the JDK 1.2 applet rendering. For that purpose, you need to install the JDK 1.2 Plug-in in the user system. You can download that information free from Resources.

Once you install the plug-in, the browser can interpret the JDK 1.2 applets. However, you will need to alter the HTML file that invokes the applet. The .class file compiled with JDK 1.2 compiler cannot be rendered under the ordinary <APPLET> tag. Though JDK 1.2 is installed, because we are using a plug-in, the <APPLET> tag renders only the JDK 1.0 or JDK 1.1 applets. The browser continues to directly render and interpret an <APPLET>, according to the browser’s default supported JVM. However, for our purposes, the browser needs to implement Sun’s JVM 1.2. To access the JVM 1.2, you will need to use the <OBJECT> or <EMBED> tags, depending on the browser you are using. I will explain the procedures for each.

Netscape 4.0 (Windows 95, NT 4.0, 98, Solaris)

To use the plug-in with Netscape 4.0, let us assume that one original applet in JDK 1.0 or JDK 1.1 took the HTML file in the following format:

    <HTML> 
    <BODY> 
    <APPLET CODE="abc.class" WIDTH=100 HEIGHT=100> 
    <PARAM NAME="fig1" VALUE="sample1.jpg"> 
    </APPLET> 
    </BODY> 
    </HTML> 

If compiled with the JDK 1.2 compiler, an HTML page should render the above .class file, with the <APPLET> tag dropped as follows:

    <EMBED type="application/x-java-applet;version=1.2"  WIDTH="100" HEIGHT="100" CODE="abc.class" 
      PLUGINSPAGE=" 
    </EMBED> 

The type attribute in the <EMBED> tag identifies the type of the Java executable. When Navigator understands that type attribute, it comes to know how to initialize the Java executable.

The CODE attribute identifies the applet. If the plug-in isn’t already installed in the browser, the PLUGINSPAGE attribute tells the browser where to find it for download. The value of PLUGINSPAGE should always point to the page indicated in the above example.

Internet Explorer 4.0 (Windows 95, NT 4.0, 98)

To use the plug-in with Internet Explorer, the following <OBJECT> tag should replace the original <APPLET> tag.

    <OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" 
      width="100" height="100" 
    codebase="" 
    <PARAM NAME="code" VALUE="abc.class"> 
    <PARAM NAME="type" VALUE="application/x-java-applet;version=1.2"> 
    </OBJECT> 

The classid in the <OBJECT> tag identifies the plug-in itself. That identifier should remain the same for all HTML pages irrespective of the applet you use. The codebase attribute typically points to the page from which to download the plug-in if it’s not in the system. That attribute in the <OBJECT> tag typically matches with the PLUGINSPAGE attribute in the <EMBED> tag.

Combine the two methods

Although you must use two different approaches for interpreting the applet through each browser’s HTML page, that does not mean that you have to implement two different pages targeted at two different browsers. Write a single HTML page so that any browser can interpret it:

    <OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" 
         width="100" height="100"               codebase=" 
     <PARAM NAME="code" VALUE="abc.class"> 
     <PARAM NAME="type" VALUE="application/x-java-applet;version=1.2">  
     <COMMENT> 
         <EMBED type="application/x-java-applet;version=1.2" width="100" 
            height="100"  code="abc.class" 
            pluginspage=" 
         </COMMENT> 
    </EMBED> 
     </OBJECT> 

The <OBJECT> tag is a special tag interpreted only by Internet Explorer; it ignores the content within the <COMMENT> tag. Internet Explorer loads and interprets only the portion marked in red above.

Similarly, Netscape does not understand the <OBJECT> or the <COMMENT> tags. Therefore, it only interprets the portion within the <EMBED> tag. The above example demonstrates the only method that creates a common HTML page for both browsers to interpret and load the plug-in and run the JDK 1.2 applet.

Scripting the applet

Typically, many applications require you to establish a communication channel between a scripting language — either VBScript or JavaScript — and the applet. I will discuss here the issues involved in scripting with JavaScript.

With earlier versions of JDK, where we could use the <APPLET> tag, the communication mechanism was straightforward. You could implement either the applets[] array of the JavaScript or the name of the applet loaded in the page. In a nutshell, the mechanism appeared like this:

    document.appletname.appletMethod().
    or
     document.applets[index].appletMethod() 
    ** index starting from 0.

In order to allow the JavaScript to access some of the methods and variables of the applet, they must be declared public. In addition, the applet must be loaded before it can be accessed.

Those requirements still exist in the JDK 1.2 environment. But because we can no longer use the <APPLET> tag, we can no longer access appletname or the applets[] array in JavaScript. Unfortunately, Netscape doesn’t provide a scripting mechanism. However, we can complete scripting with Internet Explorer. The following section discusses some issues regarding the scripting mechanism with that browser.

Scripting with Internet Explorer

To access the applet, we basically need to identify it. We complete that task through the ID attribute of the <OBJECT> tag. In the value of the <OBJECT> attribute, assign a name to the loading applet. Follow the same methods as in earlier versions of the JDK. I offer a complete example with the following code:

    <OBJECT  ID="myApplet" classid="clasid:8AD9C840-044E-11D1-B3E9-00805F499D93" 
      width="100" height="100" 
    codebase="" 
    <PARAM NAME="code" VALUE="abc.class"> 
    <PARAM NAME="type" VALUE="application/x-java-applet;version=1.2"> 
    </OBJECT> 

That simple code is sufficient to establish the communication you need. However, in some particular cases, problems occur when loading the applet because the JVM is not able to properly detect the codebase of the applet. I suggest also specifying the codebase parameter inside the <OBJECT> tag. Let us assume that an applet resides in the directory c:progra FilesmyPrograms; we then add the codebase parameter as follows:

    <OBJECT  ID="myApplet" classid="clasid:8AD9C840-044E-11D1-B3E9-00805F499D93" 
      width="100" height="100" 
    codebase="" 
    <PARAM NAME="code" VALUE="abc.class"> 
    <PARAM NAME="type" VALUE="application/x-java-applet;version=1.2"> 
    <PARAM NAME="codebase" VALUE="c:progra FilesmyPrograms"> 
    </OBJECT> 

That simple trick will ensure that the applet as well as the communication works perfectly. Now you can call the applet through JavaScript in the following way:

    document.myApplet.appletMethod() 

As we are not implementing the <APPLET> tag, note that the applets[] array will not work.

Conclusion

The topics covered here present a guideline for using the recently improved audio formats within the premise of Java. You can use those techniques, which establish a communication link between JavaScript and applets, where a fancy GUI could be avoided. The recent version 1.3 of Java 2 features more control over the audio capabilities such as audio mixing, audio capture, MIDI sequencing, and MIDI synthesis in a framework that promotes extensibility and flexibility, but those subjects take us beyond the scope of this article.

Samudra Gupta works as a system executive in
VJIL Consulting in India. Gupta has been extensively involved in
experimenting with Java along with different multimedia products.
Gupta is presently involved in extending and integrating Java
support for Macromedia products such as Flash and Director.

Source: www.infoworld.com