CoSc 200 Laboratory #8
Music Studio and Song Player

Objective: To gain experience working with arrays and the model-view-controller pattern.

The Scenario

Consider the Music Studio applet. You can play a note by pressing the mouse button on a key. Notice how the sound starts loud and gradually tapers off. The sound goes away completely when the mouse button is released. If you hold down the shift key while clicking keys, you can have several notes playing simultaneously. Now a release of the shift key will end the sound. The combo box may be used to select different instruments. Try it!

Music Studio

You can start recording what you play by pressing the "Start Recording" button and then stop recording by pressing the "Stop Recording" button. You can then play back the recording by pressing the "Play" button.

Now consider the Song Player applet. Press the "Play" button to hear the first phrase of "Happy Birthday." Each line in the text area can be thought of as a musical instruction. The first line says at 0 milliseconds to make the instrument a piano (the number 0 instrument in the Music Studio combo box). The second line says at 0 milliseconds to play note 60 (middle C, for the musically inclined). The third line says at 450 milliseconds stop playing note 60. At 2950 milliseconds, the instrument is changed to number 50. You can use the instrument combo box in the first applet to see that 50 corresponds to synthesized strings. Note how a chord of three notes is played from 3000 to 3950 milliseconds.

Song Player

Make some changes and play your modified song!

The Design and Implementation

In object-oriented design, the first steps are to identify the classes, methods, and instance variables.

What classes are there? Clearly, there should be the two applet classes MusicStudio and SongPlayer that extend WindowController or JApplet. There should be a class that knows how to synthesize sounds; this will be called the Musician class. The MusicStudio class should have a Keyboard class containing Keys. Since there are differences in how different keys appear, it is reasonable to let Key be an interface that is implemented by five classes: BlackKey, WhiteBothKey, WhiteNoneKey, WhiteBothKey, WhiteLeftKey, and WhiteRightKey.

Both applets create and play back Recordings. What is a Recording? A sequence of timed instructions for a Musician. One such instruction will be called a MusicianEvent. Since there are different types of instructions, it is reasonable to let MusicianEvent be an interface that is implemented by four classes: NoteOn, NoteOff, AllNotesOff, and SetInstrument. In order to play back a recording, it will be necessary to have the instructions executed with appropriate length pauses between each execution. This is analogous to FallingBall, which executed move instructions to a FilledOval with pauses between each move. This motivates defining a Playback class as an extension of ActiveObject.

The MusicStudio and SongPlayer classes can be considered views and controllers for the model Recording class: both "view" a Recording by creating the sounds in the Recording. The two applets differ with how their views create the Recording: The MusicStudio creates the recording based upon mouse and shift key presses, while the SongPlayer class creates the recording based upon typed text.

Of course, there are addition classes that will be used: FilledRect, JButton, JPanel, JTextArea, and Timer. The difference is that we will not have to design and implement these classes.

Now that the classes have been identified, our next step is to identify methods.

For MusicStudio, there needs to be set up and responses to user actions:

For SongPlayer, there needs to be set up and responses to user actions: For Keyboard, there need only be a constructor and one method: For the Key interface and the classes that implement Key, there need only be a constructor and a single method: For Musician, there must be a constructor and several methods: For the MusicianEvent interface and the classes that implement MusicianEvent, there needs to be a constructor, a method to carry out the instruction/event, and an accessor for the time of the instruction/event: For Recording, there should be a constructor and methods to add and access instructions/events:

Finally, Playback should have a constructor and a run method.

The final two steps are to identify instance variables and implement each method. The handout files, available from this zip file or this folder, finish these steps for all but the Keyboard, Recording, and Playback classes. Your goal in this lab is to complete the implementation of these three classes. You will need to make use of arrays in the Keyboard and Recording classes.

Grading Point Allocations

Value Feature
10
Correct implementation of the Keyboard class, including appropriate style and use of arrays.
10
Correct implementation of the Recording and Playback classes, including appropriate style and use of arrays.

Submitting Your Work

As with previous lab assignments, you should submit your ".java" files through Blackboard. This time you will probably have three files to submit. You can either add these files separately before you submit, or you can first zip together these files into a single ".zip" file and submit this single ".zip" file.

Submission Deadline: 3:00pm on Tuesday, March 14. Note that once you submit, it is impossible to submit a revision.

Resubmission and Late Submission Deadline: 3:00pm on Tuesday, March 21. A 5 point penalty will be assessed for a resubmission or late submission.

May your songs and programming be melodious!