# Guitar Hero

Being a client of linear collections to implement interfaces.1

In this assignment, we will write a program to simulate plucking a guitar string using the Karplus–Strong algorithm. This algorithm played a key role in the emergence of electronic sound synthesis.

## Guitars and sound

Before getting started with this assignment, watch the following video from 1:47–6:24 for an introduction to digital audio.

When a guitar string is plucked, the string vibrates and creates sound. The length of the string determines its fundamental frequency of vibration. We model a guitar string by sampling its displacement (a real number between -1/2 and +1/2) at N equally spaced points in time, where N equals the sampling rate (44,100Hz) divided by the fundamental frequency of the string, rounded to the nearest integer. We store these displacement values in a structure that we will refer to as a ring buffer.

Plucking a string moves it and gives it energy. The excitation of the string can contain energy at any frequency. We simulate the excitation by filling the ring buffer with white noise. In other words, we set each of the N sample displacements to a random real number between -1/2 and +1/2.

After the string is plucked, the string vibrates. The pluck causes a displacement which spreads wave-like over time. The Karplus-Strong algorithm simulates this vibration by maintaining a ring buffer of the N samples: for each step the algorithm deletes the first sample from the ring buffer and adds to the end of the ring buffer the average of the first two samples, scaled by an energy decay factor of 0.996.

## GuitarString

Implement a `GuitarString` class that models a vibrating guitar string of a given frequency. `GuitarString` instances will need to keep track of a ring buffer.

Represent the ring buffer as a queue using only a single `LinkedList<E>` Java object declared with the interface type `Queue<E>`. Use only the following `Queue<E>` methods:

• `add`
• `remove`
• `isEmpty`
• `size`
• `peek`

Once the `GuitarString` class has been implemented, run `GuitarHero` using `GuitarLite` and listen to the sound!

### Method summary

`public GuitarString(double frequency)`
Constructs a `GuitarString` of the given frequency. It creates a ring buffer of the desired capacity N (sampling rate divided by frequency, rounded to the nearest integer), and initializes it to represent a guitar string at rest by enqueueing N zeros. The sampling rate is specified by the constant `StdAudio.SAMPLE_RATE`. If the frequency is less than or equal to 0 or if the resulting size of the ring buffer would be less than 2, this method should throw an `IllegalArgumentException`
`public GuitarString(double[] init)`
Constructs a `GuitarString` and initializes the contents of the ring buffer to the values in the array. If the array has fewer than two elements, this constructor should throw an `IllegalArgumentException`. This constructor is used only for testing purposes.
`public void pluck()`
Replaces the N elements in the ring buffer with N random values between -0.5 inclusive and +0.5 exclusive, i.e. `-0.5 <= value < 0.5`. Use the `nextDouble` method in the Java `Random` class to generate random values, not `Math.random`.
`public void tic()`
Apply the Karplus-Strong update once (performing one step) by deleting the sample at the front of the ring buffer and adding to the end of the ring buffer the average of the first two samples multiplied by the energy decay factor (0.996). Use a public constant for the energy decay factor.
`public double sample()`
Returns the current sample (the value at the front of the ring buffer).

### Implementation details

Remember to include this import declaration at the beginning of the class: `import java.util.*;`

A testing program is provided for verifying that `GuitarString` has the basic functionality required. The testing program will not check for correct/efficient use of the queue or exception handling.

Normally, we encourage writing a single constructor and using the `this(...)` notation to have one constructor call another. That won’t be possible for the `GuitarString` class because the two constructors are completely different.

For documenting the `GuitarString` class, it’s difficult to know what constitutes an implementation detail versus what is okay to discuss in client comments. Assume that a client of the `GuitarString` class is familiar with the concept of a ring buffer and the Karplus-Strong algorithm. The fact that we are implementing it as a queue is an implementation detail, so don’t mention it but do discuss the ring buffer itself and the changes that each method makes to the state of the ring buffer. This might include describing the movement of values from the front of the ring buffer to the back of the ring buffer.

## Guitar and GuitarHero

This section describes the important supporting files and how to run the program. There are no deliverables for this section.

In the next part of the assignment, we’ll build on the `GuitarString` class to write a class that keeps track of a musical instrument with multiple strings. There could be many possible guitar objects with different kinds of strings. As a result, we introduce a `Guitar` interface that each guitar object implements.

``````public interface Guitar {
public void playNote(int pitch);
public boolean hasString(char key);
public void pluck(char key);
public double sample();
public void tic();
public int time();
}
``````

The interface allows a client to specify what to play in one of two ways. A client can specify exactly which note to play by calling the `playNote` method passing it a pitch. Pitch is specified as an integer where the value 0 represents concert-A and all other notes are specified relative to concert-A using what is known as a chromatic scale. Not every value of pitch can be played by any given guitar. If it can’t be played, it is ignored.

Additionally, a client can also specify a character that indicates which note to play by calling the `pluck` method. Different guitar objects will have different mappings from characters to notes. The interface includes a method called `hasString` that is paired with pluck that lets a client verify that a particular character has a corresponding string for this guitar. The `pluck` method has a precondition that the key is legal for this guitar.

The `Guitar` interface also has methods for getting the current sound sample (the sum of all samples from the strings of the guitar), to advance the time forward one `tic`, and a method for determining the current time (the number of times `tic` has been called). The sample `GuitarLite` class implements the `Guitar` interface. `GuitarLite` has only two strings: “a” and “c”.

## Guitar37

Implement the `Guitar37` class, which is a 37-string implementation of the `Guitar` interface.

Because the `GuitarLite` class uses just two strings, it stores them as two separate fields. Since our `Guitar37` instrument has 37 strings, use an array of strings instead. Each of the operations defined in the `Guitar` interface needs to be generalized from using two specific strings to using an array of strings. For example, the sample method returns the sum of the current samples. `GuitarLite` does this by adding together two numbers. `Guitar37` will have to use a loop to find the sum of all 37 samples.

Once `Guitar37` has been implemented, change `GuitarHero` to use `Guitar37` instead of `GuitarLite` and play the full instrument!

### Keyboard

The `Guitar37` class has a total of 37 notes on the chromatic scale from 110Hz to 880Hz. Clients can play the guitar by using their computer’s keyboard.

This use of keyboard characters imitates a piano keyboard, making playing songs a little easier for people used to a piano keyboard. The white keys are on the qwerty and zxcv rows while the black keys on the 12345 and asdf rows of the keyboard.

This mapping is stored as the `KEYBOARD` constant at the top of the `Guitar37` class.

``````public static final String KEYBOARD = "q2we4r5ty7u8i9op-[=zxdcfvgbnjmk,.;/' ";
``````

The i-th character of the string corresponds to a frequency of 440 × 2(i - 24) / 12, so that the character “q” is 110Hz, “i” is 220Hz, “v” is 440Hz, and “ “ (space) is 880Hz.

A pitch of 0 is supposed to correspond to concert-A, which corresponds to the character “v” at index 24 in the `KEYBOARD` string. We can convert from a pitch value to an index into the string by adding 24 to the pitch value.

Key“q”“2”“w”“e”“v””/””’”” “
Pitch-24-23-22-210101112

### Implementation details

Note that the `GuitarLite` class is not well documented. Also, it does not handle illegal keys or implement the `time` method. `Guitar37` should include complete comments. The `pluck` method should throw an `IllegalArgumentException` if the key is not one of the 37 keys it is designed to play (as noted above, this differs from the `playNote` method that simply ignores notes it can’t play).

Use the testing program `Test37` in the `test37` folder. To use it, copy the `Guitar37` class to this folder, run it, and then compare against the sample output produced using the Output Comparison Tool.

In terms of external correctness, the `GuitarString` and `Guitar37` classes must provide all of the functionality and satisfy the constraints described above. In terms of style, we will be grading on use of comments, good variable names, consistent indentation and good coding style to implement these operations.

Commenting errors
• Implementation details included in comments for a class or its public methods.
Method errors
Class design errors
Miscellaneous errors

## Reflection

Create a new file `reflection.txt` and write a paragraph-long reflection answering the following questions (along with anything else you find appropriate):

1. What did you learn this week?
2. What did you enjoy in the course this week?
3. What did you find challenging or frustrating this week?
4. What did you find particularly helpful for your learning this week?

## Submission

Submit `GuitarString.java`, `Guitar37.java`, and `reflection.txt` to Grade-It!

1. Kevin Wayne. 2012. Guitar Heroine. http://nifty.stanford.edu/2012/wayne-guitar-heroine/