COS 126 Plucking a Guitar String |
Programming Assignment Checklist Assignment Page |
Frequently Asked Questions (general) |
What are the goals of this assignment? To learn how to create user-defined data types in Java and to learn about digital audio.
Do I need to follow the prescribed API? Yes, we will be testing the methods in the API directly. If your method has a different signature or does not behave as specified, you will lose a substantial number of points. You may not add public methods to the API; however, you may add private instance variables or methods (which are only accessible in the class in which they are declared).
Frequently Asked Questions (RingBuffer) |
Which instance variables should I use to represent a RingBuffer? There are many viable approaches, including one suggested in the assignment specification. Be sure that your representation allows you to implement each operation efficiently (because the GuitarHero client will call the methods 44,100 times per second).
How do I determine the length of an array? If you're asking this, you probably need to review Section 1.4.
Is the size of a RingBuffer equal to its capacity? No. The size of a RingBuffer is the number of elements currently in it; the capacity of a RingBuffer is its maximum possible size.
Is the size of a RingBuffer equal to the number of its nonzeros elements? No. Some of the elements in the buffer can be zero.
How do I throw a RuntimeException with a custom message? Read the Exceptions paragraph on pp. 465–466 of the textbook.
I get an ArrayOutOfBounds or NullPointerException. What could cause this? Does your constructor correctly initialize all of the instance variables? Did you allocate memory for your array? Did you inadvertently re-declare an instance variable in a method or constructor, thereby shadowing the instance variable with the same name?
I get the following error message on OS X. How can I fix it?
You can ignore it. It is a warning intended for the authors of the Mac OS X Java sound library.This application, or a library it uses, is using the deprecated Carbon Component Manager for hosting Audio Units. Support for this will be removed in a future release.
Frequently Asked Questions (GuitarString) |
When generating random values between −0.5 and +0.5, should I include the two endpoints? The assignment specification does not specify, so you are free to choose whichever convention you find most convenient. In Java, we typically include the left endpoint of an interval and exclude the right endpoint. For example, StdRandom.uniform(-0.5, 0.5) generates a uniformly random value in the interval [−0.5, 0.5) and s.substring(i, j) returns the substring of the string s beginning at index i and ending at index j-1.
How do I round a double up to the nearest int? Use Math.ceil() and cast the result to an integer.
Frequently Asked Questions (GuitarHero) |
Where do I enter keystrokes in GuitarHeroLite and GuitarHero? Be sure that the standard drawing window has focus by clicking in it. Then, type the keystrokes.
When I run from DrJava, even though I have clicked in the standard drawing window, the program seems to ignore my keystrokes. What is wrong? Try clicking on DrJava, then clicking in the standard drawing window, again. If that does not work, close the standard drawing window and run from the Terminal or Command Prompt.
What happens if I call StdAudio.play(x) where x is greater than 1 or less than −1? The value is clipped—it is replaced by the value +1.0 or −1.0, respectively. This is fine and can happen when you play chords.
I get a RuntimeException or an ArrayIndexOutOfBoundsException in GuitarHeroLite before I type any keystrokes. Why? Did you forget to initialize the ring buffer to contain n zeros in your GuitarString constructor?
When I run GuitarHeroLite for the first time, I hear no sound. What am I doing wrong? Make sure you have tested with the main() provided for GuitarString. If that works, it is likely something wrong with pluck() since the main() provided for GuitarString does not test that method. To diagnose the problem, print the values of sample() and check that they become nonzero after you type the lowercase characters 'a' and 'c'.
When I run GuitarHeroLite, I hear static (either just one click, and then silence or continual static). What am I doing wrong? It's likely that pluck() is working, but tic() is not. The best test is to run the main() provided for GuitarString.
How do I use keyboard.indexOf(key)? If keyboard is a String and key is a character, then keyboard.indexOf(key) returns the integer index of the first occurrence of the character key in the string keyboard, or –1 if it does not occur. You can read about it in the String Javadoc page.
Can I hardwire the constants 44,100, 440.0, and 37 in my program? As usual, we may deduct style points for using an unnamed constant, especially if you use it more than once. We recommend using the name SAMPLING_RATE for 44,100 and CONCERT_A for 440.0 and the expression keyboard.length() for 37. You do not need to name all of the constants in the formula 2(i − 24) / 12.
Testing |
Be sure to thoroughly test each piece of your code as you write it. We offer some suggestions below, but these are only partial tests. Write code to test each constructor and each method of each class, especially in RingBuffer.
public static void main(String[] args) { int n = Integer.parseInt(args[0]); RingBuffer buffer = new RingBuffer(n); for (int i = 1; i <= n; i++) { buffer.enqueue(i); } double t = buffer.dequeue(); buffer.enqueue(t); StdOut.println("Size after wrap-around is " + buffer.size()); while (buffer.size() >= 2) { double x = buffer.dequeue(); double y = buffer.dequeue(); buffer.enqueue(x + y); } StdOut.println(buffer.peek()); }
% java-introcs RingBuffer 10 Size after wrap-around is 10 55.0 % java-introcs RingBuffer 100 Size after wrap-around is 100 5050.0
public static void main(String[] args) { double[] samples = { 0.2, 0.4, 0.5, 0.3, -0.2, 0.4, 0.3, 0.0, -0.1, -0.3 }; GuitarString testString = new GuitarString(samples); int m = 25; // 25 tics for (int i = 0; i < m; i++) { double sample = testString.sample(); StdOut.printf("%6d %8.4f\n", i, sample); testString.tic(); } }
% java-introcs GuitarString 0 0.2000 1 0.4000 2 0.5000 3 0.3000 4 -0.2000 5 0.4000 6 0.3000 7 0.0000 8 -0.1000 9 -0.3000 10 0.2988 11 0.4482 12 0.3984 13 0.0498 14 0.0996 15 0.3486 16 0.1494 17 -0.0498 18 -0.1992 19 -0.0006 20 0.3720 21 0.4216 22 0.2232 23 0.0744 24 0.2232
Next, using your implementations of RingBuffer and GuitarString, compile and execute GuitarHeroLite.
What is this familiar melody? (S = space)w q q 8 u 7 y o p p i p z v b z p b n z p n d [ i d z p i p z p i u i i
Here is a round that you can practice with 3 friends:nn//SS/ ..,,mmn //..,,m //..,,m nn//SS/ ..,,mmn
x c v x x c v x v g n v g n nmngv x nmngv x x p x x p x x c v x x c v x v g n v g n nmngv x nmngv x x p x x p x x c v x x c v x v g n v g n nmngv x nmngv x x p x x p x x c v x x c v x v g n v g n nmngv x nmngv x x p x x p x
Possible Progress Steps (RingBuffer) |
These are purely suggestions for how you might make progress. You do not have to follow these steps.
private double[] rb; // items in the buffer private int first; // index for the next dequeue or peek private int last; // index for the next enqueue private int size; // number of items in the buffer
Possible Progress Steps (GuitarString) |
These are purely suggestions for how you might make progress. You do not have to follow these steps.
Possible Progress Steps (GuitarHero) |
These are purely suggestions for how you might make progress. You do not have to follow these steps.
Enrichment |
Here are some concrete ideas for synthesizing other instruments. Some come from the paper of Karplus and Strong.
Here is some cool stuff that is closely related.