Lab5: Orchestra using Inheritance

 

Let's have some fun for this assignment, making music with JFugue. Read all about using JFugue by searching the net, or by reading The Complete Guide to JFugue

To install JFugue for use in this assignment, download JFugue 5.0 from the above website or clicking on this link jfugue-5.0.4.jar. To tell Eclipse how to find this jar, go to Project -> Properties, select Java Build Path, select the Libraries tab, and click the Add External JARs… button. Find jfugue-5.0.4.jar and add it to your project.

From the command line, to compile and run JFugueMusic.java with JFugue, you must use the commands

 

javac -classpath .:jfugue-5.0.4.jar JFugueMusic.java
java -classpath .:jfugue-5.0.4.jar JFugueMusic

Code Requirements

 

You are going to design a number of classes, meaning multiple Java files, for this assignment. The list of required classes and methods are:

  • Orchestra: a group of instruments and methods for dealing with instruments and members of the orchestra and for playing music.
  • Member: represents a member of your orchestra
  • Instrument: represents an instrument in the orchestra. Four classes extend this one to represent these specific instruments:
    • Violin
    • Viola
    • Cello
    • Contrabass

Now the details. Let's start with the Orchestra. This class must contain a collection of instruments as an ArrayList<Instrument> instance variable. Methods that are required are

 

  • public Orchestra(), the no-argument constructor
  • public void addMember(Member member) to add a member
  • public String toString() that returns a String of member
  • public String jfugueString() that returns the JFugue string from all instruments that the orchestra members play using JFugue. The string will be printed a played.
  • public ArrayList<String> whoPlays(String instrumentName) returns an ArrayList<String> containing the names of all members that play the instrument given by instrumentName (The method will be JUnit Tested)
  • public String playedBy(String memberName) returns the name of the instrument played by the member given by memberName (The method will be JUnit Tested)

 

The following method must also be included in Orchestra.

 

public void play() {
     String jfugueString = jfugueString();
     Player player = new Player();
     player.play(jfugueString);
 }

This method requires Orchestra.java to start with the line

 

import org.jfugue.player.Player;

The Instrument class must have instance variables to hold a String of notes, and an int to represent an octave, and it must have at least these methods:

 

  • public Instrument(int octave)
  • public void setNotes(String s)
  • public String getNotes() returns a custom string for the instrument that includes the Voice, Instrument and notes with embedded octaves.
  • public String toString() returns the results of getNotes()

 

The getNotes() method does not just return the stored notes string. It returns a new String constructed from the stored notes for this instrument, with the following modifications.

The int octave is inserted just after each note. For example, the string "C" for octave 4 becomes "C4", and the string "D#" becomes "D#4". If a note has a duration, like "q" for quarter note, "h" for half note, or "w" for whole note, the string "D#w" becomes "D#4w". It is a little tricky inserting the octave value in the correct position.

Each of the classes for the specific instruments, Violin, Viola, Cello and Contrabass, extends the Instrument class. The requirements for these classes is that they implement constructors accepting a String of notes to play and a Member who will play the instrument. Their constructors must explicitly call the super-class constructor with arguments for the notes, the octave, and the member. The octave is an int for the particular instrument which is hardcoded as it is passed into the Instrument constructor from the individual subclass constructor:

 

  • octave is 6 for Violin
  • octave is 5 for Viola
  • octave is 4 for Cello
  • octave is 3 for Contrabass

 

These classes must also implement a String getName() method that returns the name of the instrument, such as "Violin".

The Member class must keep track of the orchestra members name and skill level. Required methods are

 

  • public Member(String name, int level)
  • public void setInstrument(Instrument instrument)
  • public Instrument getInstrument()
  • public void setName(String name)
  • public String getName()
  • public String toString() returns the name and the instrument string

 

That JFugue String

The notes from all instruments must be combined into one string to be played. Each instrument is sequentially assigned a voice as they are combined. The first instrument is voice 0, the second one is voice 1, etc. Skip voice 9, because it is reserved for percussion, and we are not using percussion in this assignment. So, other than 9, voice can be 0 through 15.

The instrument name field is used to specify the instrument. If the ArrayList<Instrument> of instruments has a violin added first with notes "C D" and a cello added second with notes "F G", the resulting JFugue String will be "V0 I[Violin] C6 D6 V1 I[Cello] F3 G3".

Example

Here is an example of a main method, which could be the sole method in your JFugueMusic.java file. However, a second method that creates a new Member given a name and instrument number can also be created. If one command-line argument is provided, and it is the word "play", then the music is actually played. Be sure to use headphones in the lab or turn the volumn way down. If no command line arguments are given, or you change it to something else, like "noplay", then no sound will be played.

The resulting output is shown after the code.

public static void main(String[] args) {

     boolean play = false;
     if (args.length > 0 && args[0].equals("play"))
         play = true;

// TODO: Create a loop that creates an Orchestra, plays the music and asks to try again?

// TODO: Construct an Orchestra

System.out.println("Create an orchestra with no more than 15 instruments.");

// TODO: Create a loop that allows up to 15 members to be created


// TODO: Declare an Orchestra Member reference, String for name
// TODO: an int for instrument number (1-4) and a String for notes.

System.out.print("Enter member name: ");

// TODO: Input the name.


// TODO: Use the number as input and map it to the class.
System.out.print("\t1) Violin\n\t2) Viola\n\t3) Cello\n\t4) Contrabass\nEnter member instrument: ");


// TODO: Read the left-over newline.


System.out.println("Enter notes: ");

// TODO: Read the line of notes.


// TODO: Set the Notes in the member's instrument.


// TODO: Add the member to the orchestra

System.out.print("Another? (y or n): " );
// TODO: Read the character


// TODO: Create the while condition.


// TODO: Print out the jfugueString first, then play it.


System.out.println("Again? (y or n): ");
// TODO: Read the character

// TODO: Create the while condition.

}

Here is the command and the resulting output.

> javac -cp .:jfugue-5.0.4.jar 
> java -cp .:jfugue-5.0.4.jar 

Create an orchestra with no more than 15 instruments.
Enter member name: Julie
1) Violin
2) Viola
3) Cello
4) Contrabass
Enter member instrument: 1
Enter notes:
F# F# G A A G F# E D D E F# F# E E
Another? (y or n): y
Enter member name: Jonathan
1) Violin
2) Viola
3) Cello
4) Contrabass
Enter member instrument: 2
Enter notes:
F# F# G A A G F# E D D E F# F# E E
Another? (y or n): y
Enter member name: Jacob
1) Violin
2) Viola
3) Cello
4) Contrabass
Enter member instrument: 3
Enter notes:
F# F# G A A G F# E D D E F# F# E E
Another? (y or n): n
V0 I[Violin] F#6 F#6 G6 A6 A6 G6 F#6 E6 D6 D6 E6 F#6 F#6 E6 E6 V1 I[Viola] F#6 F#6 G6 A6 A6 G6 F#6 E6 D6 D6 E6 F#6 F#6 E6 E6 V2 I[Cello] F#4 F#4 G4 A4 A4 G4 F#4 E4 D4 D4 E4 F#4 F#4 E4 E4
Again? (y or n): n