CS 161 Homework 6 - Guitar Player

Due Fri Nov 01 at 11:59pm

Overview

In this assignment, you will be able to apply your programming skills to the domain of digital audio. Specifically, you will be writing a program to simulate the plucking of a guitar string, creating an application that lets the user create synthesized music by hitting keys on the (computer) keyboard and see a visualization of that music. An example video can be seen below:

This assignment should be completed individually.

Objectives

Necessary Files

You will need a copy of the Hwk6.zip file. The BlueJ project in this file contains a number of classes for you to use.

The zip file also contains the README.txt that you will need to fill out and turn in along with your assignment.

Remember to extract the files from the zip folder before proceeding!

Digital Audio (A Rough Overview)

Digital audio is a complex topic; for this assignment we will be considering it from a very simple and specific point of view. I have placed a short (5-page) simple excerpt from an introductory text on Moodle; I recommend you read through that for an introduction.

The basic idea behind digital audio is the concept that sound waves can be represented mathematically as complex trigometic functions that indicate the amount of "energy" at any particular time. Different properteis of this trig function correspond to differnet properties of the sound. For example, the frequency of the function (how close each "hill" is to the previous) is related to the pitch of the audio (how 'high' the note sounds), while the amplitude of the function (how "high" each hill is) relates to the volume of the sound.

Because sound is continuous but computers work with integers (discrete values), we end up sampling the audio lots and lots of times in order to get a pretty good guess of what the curve looks like. CD quality audio samples the curve 44,100 times per second (measured in what is called hertz (Hz)--1Hz means 1 time per second, 10Hz means 10 times per second, etc). So this means that we'll represent 1 second of audio on a CD with 44,100 numbers--each number representing the sound you can hear for a particular 1/44,100 of a second.

In order to play audio through Java, we represent a "sound" as a collection of numbers (samples) between -1 and 1. You can almost think of each sample as representing a sound that is 1/44,100th of a second long, Since we will have a lot of these samples, we will store them in an array of doubles (a double[]). We can tell Java to either play a single sample (and just tell it to do that over and over), or to play an entire array of samples.

Strumming a Guitar

When a guitar string is plucked, the string vibrates and creates sound. The length of the string determines its fundamental frequency of vibration. In this assignment, you will 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,100) divided by the fundamental frequency (rounding the quotient up to the nearest integer).

Why it works

Bonus confusing fun fact! From a mathematical physics viewpoint, the Karplus-Strong algorithm approximately solves the 1D wave equation which describes the transverse motion of the string as a function of time.

Assignment Details

Implementing this program is less complicated than it may sound (though not simplistic). For this assignment, you will be creating two new classes: GuitarString, which is a "model" or "object" class that represents a single string of a Guitar; and GuitarPlayer, which is a "main" class that lets you interact with keyboard input to strum the strings.

Be sure and name the classes as specified in this write-up!

GuitarString

The first class you'll need to make is the GuitarString class. It will have the following API (method signatures):

public class GuitarString
------------------------------------------------------------------------------------------------------------------------
    GuitarString(double frequency)  // create a guitar string of the given frequency, using a sampling rate of 44,100
    GuitarString(double[] init)     // create a guitar string whose size and initial values are given by the array
    void pluck()                    // set the buffer to white noise
    double sample()                 // return the current sample
    void update()                   // apply the Karplus-Strong update and advance the simulation one time step

Further details are below:

GuitarPlayer

Once your GuitarString is working, you can write the rest of the program. Create a new GuitarPlayer class that is similar to the provided GuitarHeroLite, but supports a total of 37 notes on the chromatic scale from 110Hz to 880Hz. Your music keyboard should map to the computer keyboard after the following diagram:

Visualization

Finally, you should add functionality to your GuitarPlayer class so that it displays a visual representation of the audio. You can get access to the IOFrame's Graphics2D object by calling the getGraphics2D() method. You can then draw on this frame during the while loop, making your drawing depending on the samples produced. Your basic drawing should be a wave form that looks like

but changes over time (as in the above video).

Helpful Advice: Iterative Development

As always, you should work to complete this assignment iteratively---you should build a small piece, test that it works, and then move on to the next bit. Below is a suggested order of steps, as well as good deadlines for getting each step working (if you haven't figure something out by the listed date, definitely ask for help!!):

  1. GuitarString class: Mon 10/28
  2. GuitarPlayer plays 37 String guitar: Wed 10/30
  3. Visualization functionality: Fri 11/01

Extensions

Here are some possible next steps. It is possible to earn up to 10 points of extra credit on this assignment.

Submitting Your Assignment

Grading

This assignment will be graded on approximately the following criteria: