COS 126
MIDIGuitarHero
|
OPTIONAL: MIDI Keyboards and MIDI Files
Assignment Page
|
Optional Write a program MidiGuitarHero.java that is similar to GuitarHero.java, but works with a with a MIDI keyboard controller keyboard or a MIDI keyboard controller app (running on your smartphone connected to your laptop). (See the bottom of the page for more information about MIDI controllers.)
Briefly, MIDI (Musical Instrument Digital Interface) is a technical standard for digitial music. More details can be found at on the Wikepedia page.
To implement MidiGuitarHero.java, you will need to download the MidiSource.java class. The MidiSource.java class maintains a queue of short MIDI messages. See javax.sound.midi.ShortMessage for details. The basic steps are:
- Create a MidiSource object - either connected to a MIDI keyboard controller or to a MIDI file.
- Start the MidiSource object so it can generate short MIDI messages.
- Access and interpret each short MIDI message generated.
The API for the MidiSource.java class:
public class MidiSource {
public MidiSource(boolean verbose, boolean connectToSynth) // Creates a MidiSource object listens to the first
// found connected Midi input device.
public MidiSource(String filename, boolean verbose, boolean connectToSynth) // Creates a MidiSource object that produces
// Midi messages from a time-stamped Midi file
public void start() // Starts the MidiSource so it can produce messages.
public void close() // Closes the MidiSource.
public boolean isEmpty() // Does the MidiSource have more messages?
public javax.sound.midi.ShortMessage nextMessage() // Returns next short Midi message produced by a MidiSource
public static void main(String[] args) // Demonstrates the MidiSource class - playing from a
// keyboard or a Midi file - using the default Java synthesizer
}
To get started:
- Download and compile MidiSource.java
- Connect your Midi keyboard controller (via USB) to your laptop
- see below for using a smartphone or tablet.
- On the command line terminal, enter the command: java-introcs MidiSource -p
- Press some keys on your MIDI keyboard controller. You should see output similar to:
MidiSource verison .2
DEVICE 0: Gervill, OpenJDK, Software MIDI Synthesizer, Midi device available, Not a MIDI keyboard controller, trying next...
DEVICE 1: Port1, YAMAHA, YAMAHA PSR-1100 Port1, Midi device available, Valid MIDI controller connected.
ShortMessage: Command: NOTE_ON (144) Channel: 0 Number: 77 Velocity: 21
ShortMessage: Command: NOTE_ON (144) Channel: 0 Number: 77 Velocity: 0
Each time you press a key on the MIDI keyboard controller, a MIDI message is produced. The message contains:
- The command type
- The channel
- The data1 value
- The date2 value
For details, see javax.sound.midi.ShortMessage.
- For the most part, you will want to capture messages whose command type is NOTE_ON. The data1 value corresponds to the key number (similar to the index in the String keyboard in
GuitarHero.java and the data2 value corresponds to the velocity of the pressed key. (Some MIDI controllers generate a NOTE_ON and a velocity value of 0 when releasing a key -
you will want to ignore those messages.
- The general form of your code should look like this:
- Create an array of GuitarString objects. The size of the array depends on how many notes you want to be able to produce.
- You must generalize the formula for the frequency of each GuitarString object, i.e., 440 × 2(i − 24) / 12, where i is
the MIDI keyboard controller number for A4 (concert A or 440 Hz).
- Create and start the MidiSource object.
- Similarly to GuitarHeroLite, write a loop that gets the next short Midi message. Interpret the message, and if it's a NOTE_ON with a velocity greater than zero (0),
pluck the appropriate GuitarString object. (Then compute the sum of the samples, play the sum and tic the GuitarString objects.
More options:
- When you execute the command java-introcs MidiSource -p
you experiment with pressing other buttons on your Midi keyboard controller.
By understanding other MIDI codes (e.g., CONTROL_CHANGE), you can use your Midi keyboard controller to change instruments. Of course, you need
to create new music instruments by modifying the Karplus–Strong algorithm.
- The MidiSource class can also generate MIDI messages from MIDI files. You can experiment by downloading chopstik.mid and
executing the command:
java-introcs MidiSource -p chopstik.mid
As you can see, different channels correspond to different instruments. If you have implemenented multiple instruments, you can write an MidiAutoGuitar.java that
plays your instruments from an exisiting MIDI file.
MIDI Controller Keyboard and USB:
- For this exercise, almost any MIDI keyboard controller with a USB interface will suffice (for example, a 25-key MIDI keyboard controller can be purchased on Amazon for about $40).
- Connect the MIDI keyboard to your laptop.
- In the terminal window on Mac laptop, execute the command:
java-introcs MidiSource
- Press the keys on the MIDI Controller app to see the MIDI messages (numbers) generated by each key.
iPhone with iOS 11, Mac OS and USB:
- iPhone: Download/install the MIDI controller app from the Apple App Store
- Connect your iPhone to your Mac laptop using the USB connector.
- On your Mac:
- Start Audio Midi Setup (Applications/Utilities)
- Windows/Show Audio Devices and enable your iPhone
- In the terminal window on your Mac laptop, execute the command:
java-introcs MidiSource
- Start the MIDI controller app
- Press the keys on the MIDI Controller app to see the MIDI messages (numbers) generated by each key.
Android and USB:
- Android smartphone: Download/install/start the MIDI controller app from the Google Play Store
- Connect your Android smartphone to your laptop using the USB connector. Show the notification screen by dragging down from the top of the display.
- Android smartphone: Tap Use device MIDI.
- In the terminal window on your laptop, execute the command:
java-introcs MidiSource
- On the MIDI Controller app, tap Receivers for Keys and select Android USB Peripheral Port.
- Press the keys on the MIDI Controller app to see the MIDI messages (numbers) generated by each key.