CSCI 136
Fundamentals of Computer Science II
Spring 2015

Montana Tech
Computer Science & Software Engineering



WAV Audio Player

You will be creating a Java GUI application that loads WAV format audio files. The application displays a waveform visual display of the audio and allows the user to playback the audio.

Part 1: Creating the GUI. Stub code and support files for this assignment are in wavplayer.zip. Your first job is to create the GUI application and arrange all your widgets. This can be done by adding code to WavPlayer.java. The panel containing the waveform will be blank until you add code to WavPanel.java in the next part. Here is a screenshot of what the interface should look like both with and without a valid loaded audio file:

    
You will need to use a combination of layout managers and panels to achieve the above design. You may want to consult the MultiButtonsBox and BouncingBall examples. The waveform area will be the subclass of JPanel implemented in WavPanel.java. The other widgets rows will need to be grouped in there own JPanel objects.

Part 1 requirements: Part 2: Loading and drawing the waveform. Users type the filename of their desired audio file in the text field and then hit enter or click the Load button. We assume the audio file given is a 44.1kHz, 16-bit, signed WAV file. You should use StdAudio.read() to read the file into the double [] sample array in WavPanel.java.

Each audio sample is a double value between -1.0 and +1.0. Draw a line at each x-coordinate with a height that is proportional to the absolute value of the audio sample value. So for example, if a sample was 1.0, it would be a blue line going from the bottom of the panel to the top. A sample value of 0.0 would be a dot in the middle of the panel. The audio will contain many more samples than the number of pixels of width of your panel. Thus for each x-coordinate, you will need to map it to a much bigger index into the sample array. You can simply use one audio sample to determine the waveform height at a given x-coordinate. You do NOT need to do anything fancier (such as taking an average).

Part 2 requirements: Part 3: Playing the audio. Allow the user to play a valid loaded audio file by hitting the Play button. During playback, a red line will scroll from left to right through the waveform display in synchronization with the currently playing audio sample. You can play an individual audio sample using StdAudio.play(double). During playback, the only widget that can be used is the Stop button. If the Stop button is hit, playback immediately stops and the red line disappears.

In an event listener such as the one for your Play button, no changes to other widgets (such as your waveform canvas) will be visible until after the listener finishes. Thus you simply cannot loop over all the samples and call repaint() repeatedly on your waveform canvas in the Play button handler. You will need to spin up a worker thread to do this. You'll need to be careful so the worker thread can respond to a request to stop playback via the Stop button.

Part 3 requirements:
My program crashes if the user attempts to load an invalid file. Is that okay? No. The StdAudio read method throws a RuntimeException if it fails to load a file. You need to catch this exception and return false from your load method.

My text field is super tall and looks silly. How do I prevent that? For a widget in a BoxLayout, you can specify a maximum size using the setMaximumSize method.

How do I make a file load when they hit enter in the text field? Similar to a button, you can add an action listener to your JTextField widget.

How can a method in WavPanel determine the height or width of the panel in pixels? Since WavPanel extends JPanel, it has methods such as getWidth() and getHeight().


Extra credit. Add additional features to the program such as:
  • Start with the Load button disabled. Only enable the button once they type a filename that is a file that exists (but may not necessarily be valid).
  • If a command-line argument is given, pre-populate the text field with that value and attempt to load the waveform.
  • Allow users to use their mouse to highlight a portion of the waveform by holding down the button and dragging left or right. If such a portion is highlighted, make Play only play that section. If the user single clicks in the waveform area without dragging, reset to playing the whole waveform.
  • Add a checkbox that causes the playback to be done in reverse.
  • Add a slider widget that adjusts the gain on the audio, causing a multiplicative increase or decrease in sample values. Update the waveform display live as the user drags around the slider.
  • Create a label that displays the sample value and time offset of the user's current mouse x-position in the waveform.

Submission. Submit your programs WavPlayer.java and WavPanel.java using Moodle. Be sure each submitted source file has the required header with your name, username, and a description of the program. For extra-credit, please submit a single zip file containing all your programs/graphics/sounds via the special Assignment #7 extra-credit drop box.

Page last updated: April 08, 2015