aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Baines <cbaines8@gmail.com>2011-09-18 23:13:32 +0100
committerChristopher Baines <cbaines8@gmail.com>2011-09-18 23:13:32 +0100
commitf93d4c5dd61cd3f5d0c09e5c338c636699da24f7 (patch)
treea8ea538f55ad84e394d58d805569c7d72a6cf920
parent7858c366f2de5b03b211df0b3df4fd50f551e622 (diff)
downloadpunchingbag-master.tar
punchingbag-master.tar.gz
New Keyboard using midi, cleaned simple keyboard.HEADmaster
-rw-r--r--PunchingBag/src/uk/ac/open/punchingbag/PunchingBagGUI.java7
-rw-r--r--PunchingBag/src/uk/ac/open/punchingbag/examples/Keyboard.java316
-rw-r--r--PunchingBag/src/uk/ac/open/punchingbag/examples/SimpleKeyboard.java137
3 files changed, 320 insertions, 140 deletions
diff --git a/PunchingBag/src/uk/ac/open/punchingbag/PunchingBagGUI.java b/PunchingBag/src/uk/ac/open/punchingbag/PunchingBagGUI.java
index 7a7010c..f76c033 100644
--- a/PunchingBag/src/uk/ac/open/punchingbag/PunchingBagGUI.java
+++ b/PunchingBag/src/uk/ac/open/punchingbag/PunchingBagGUI.java
@@ -53,6 +53,7 @@ import javax.sound.sampled.UnsupportedAudioFileException;
import javax.sound.sampled.AudioFormat.Encoding;
import javax.sound.sampled.Mixer.Info;
+import uk.ac.open.punchingbag.examples.Keyboard;
import uk.ac.open.punchingbag.examples.SimpleKeyboard;
import PicHelper.ImagePanel;
@@ -64,7 +65,7 @@ public class PunchingBagGUI implements MouseListener, MouseMotionListener,
Debug, Menu
};
- Mode currentMode = Mode.Menu;
+ Mode currentMode = Mode.Debug;
JFrame frame;
@@ -94,7 +95,7 @@ public class PunchingBagGUI implements MouseListener, MouseMotionListener,
public static void main(String[] args) throws InterruptedException {
new PunchingBagGUI();
- new SimpleKeyboard();
+ new Keyboard();
}
PunchingBagGUI() throws InterruptedException {
@@ -146,7 +147,7 @@ public class PunchingBagGUI implements MouseListener, MouseMotionListener,
programOptionsPanel.add(new JButton("Debug"));
frame.add(bagDebugingPanel);
- frame.add(new DisplayPanel(), BorderLayout.CENTER);
+ //frame.add(new DisplayPanel(), BorderLayout.CENTER);
frame.add(programOptionsPanel, BorderLayout.SOUTH);
setMode(currentMode);
diff --git a/PunchingBag/src/uk/ac/open/punchingbag/examples/Keyboard.java b/PunchingBag/src/uk/ac/open/punchingbag/examples/Keyboard.java
new file mode 100644
index 0000000..b502748
--- /dev/null
+++ b/PunchingBag/src/uk/ac/open/punchingbag/examples/Keyboard.java
@@ -0,0 +1,316 @@
+package uk.ac.open.punchingbag.examples;
+
+import java.awt.Color;
+import java.awt.Rectangle;
+import java.io.File;
+import java.io.IOException;
+
+import javax.sound.midi.InvalidMidiDataException;
+import javax.sound.midi.MidiEvent;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Sequence;
+import javax.sound.midi.Sequencer;
+import javax.sound.midi.ShortMessage;
+import javax.sound.midi.Synthesizer;
+import javax.sound.midi.Track;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.UnsupportedAudioFileException;
+
+import uk.ac.open.punchingbag.ButtonListener;
+import uk.ac.open.punchingbag.Contact;
+import uk.ac.open.punchingbag.PunchingBag;
+
+public class Keyboard implements Runnable, ButtonListener {
+
+ Sequence[] notes = new Sequence[20];
+
+ static PunchingBag bag = PunchingBag.getBag();
+ long lastActionTime = System.currentTimeMillis();
+ boolean noising = false;
+
+ public static final int DAMPER_PEDAL = 64;
+
+ public static final int DAMPER_ON = 127;
+
+ public static final int DAMPER_OFF = 0;
+
+ public static final int END_OF_TRACK = 47;
+
+ Sequencer sequencer;
+
+ static final int[] offsets = { // add these amounts to the base value
+ // A B C D E F G
+ -4, -2, 0, 1, 3, 5, 7 };
+
+ public static void main(String[] args) throws InvalidMidiDataException,
+ MidiUnavailableException, IOException {
+
+ try {
+ // bag.connectToArduinos();
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ new SimpleKeyboard();
+
+ }
+
+ public Keyboard() {
+ bag.addButtonListener(this);
+ try {
+ System.out.println("Generating Keys");
+ genKeys();
+ System.out.println("Finished Generating Keys");
+ /*System.out.println("Testing Keys");
+ for (int i=0; i<5; i++) {
+ System.out.println("Playing " + i);
+ playKey(i);
+ System.out.println("Played " + i);
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }*/
+ } catch (InvalidMidiDataException | MidiUnavailableException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ new Thread(this).start();
+ }
+
+ public void buttonPressed(int x, int y) {
+ if (noising = true) {
+ bag.clearLEDs();
+ noising = false;
+ }
+ lastActionTime = System.currentTimeMillis();
+ System.out.println("Button Pressed: " + x + " " + y);
+ bag.fillRect(0, y, 9, 2, Color.red, 500);
+
+ try {
+ playKey(y - 10);
+ } catch (InvalidMidiDataException | MidiUnavailableException
+ | IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ void genKeys() throws InvalidMidiDataException, MidiUnavailableException {
+ for (int key = 0; key < 20; key++) {
+ int instrument = 0;
+
+ // 16 ticks per quarter note.
+ Sequence sequence = new Sequence(Sequence.PPQ, 16);
+
+ // Add the specified notes to the track
+ Track track = sequence.createTrack(); // Begin with a new track
+
+ ShortMessage sm = new ShortMessage();
+ sm.setMessage(ShortMessage.PROGRAM_CHANGE, 0, instrument, 0);
+ track.add(new MidiEvent(sm, 0));
+
+ // These values persist and apply to all notes 'till changed
+ int notelength = 16; // default to quarter notes
+ int velocity = 64; // default to middle volume
+ int basekey = 60; // 60 is middle C. Adjusted up and down by octave
+ boolean sustain = false; // is the sustain pedal depressed?
+ int numnotes = 0; // How many notes in current chord?
+
+ int t = 0; // time in ticks for the composition
+
+ /*
+ * ShortMessage m = new ShortMessage();
+ * m.setMessage(ShortMessage.CONTROL_CHANGE, 0, DAMPER_PEDAL,
+ * sustain ? DAMPER_ON : DAMPER_OFF); track.add(new MidiEvent(m,
+ * t));
+ */
+
+ ShortMessage on = new ShortMessage();
+ on.setMessage(ShortMessage.NOTE_ON, 0, basekey + key, velocity);
+ ShortMessage off = new ShortMessage();
+ off.setMessage(ShortMessage.NOTE_OFF, 0, basekey + key, velocity);
+ track.add(new MidiEvent(on, t));
+ track.add(new MidiEvent(off, t + notelength));
+
+ notes[key] = sequence;
+ }
+
+ // Set up the Sequencer and Synthesizer objects
+ sequencer = MidiSystem.getSequencer();
+ sequencer.open();
+ Synthesizer synthesizer = MidiSystem.getSynthesizer();
+ synthesizer.open();
+ sequencer.getTransmitter().setReceiver(synthesizer.getReceiver());
+ }
+
+ void playKey(int key) throws InvalidMidiDataException,
+ MidiUnavailableException, IOException {
+ int tempo = 120;
+ // Specify the sequence to play, and the tempo to play it at
+ sequencer.setSequence(notes[key + 10]);
+ sequencer.setTempoInBPM(tempo);
+
+ // And start playing now.
+ if (sequencer.isRunning()) {
+ System.out.println("Is Running");
+ sequencer.stop();
+ sequencer.setTickPosition(sequencer.getLoopStartPoint());
+ sequencer.start();
+ } else {
+ System.out.println("Not Running");
+ sequencer.setTickPosition(sequencer.getLoopStartPoint());
+ sequencer.start();
+ }
+
+ }
+
+ @Override
+ public void contact(Contact c) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /*
+ * This method parses the specified char[] of notes into a Track. The
+ * musical notation is the following: A-G: A named note; Add b for flat and
+ * # for sharp. +: Move up one octave. Persists. -: Move down one octave.
+ * Persists. /1: Notes are whole notes. Persists 'till changed /2: Half
+ * notes /4: Quarter notes /n: N can also be, 8, 16, 32, 64. s: Toggle
+ * sustain pedal on or off (initially off) >: Louder. Persists <: Softer.
+ * Persists .: Rest. Length depends on current length setting Space: Play
+ * the previous note or notes; notes not separated by spaces are played at
+ * the same time
+ */
+ public static void addTrack(Sequence s, int instrument, int tempo,
+ char[] notes) throws InvalidMidiDataException {
+ Track track = s.createTrack(); // Begin with a new track
+
+ // Set the instrument on channel 0
+ ShortMessage sm = new ShortMessage();
+ sm.setMessage(ShortMessage.PROGRAM_CHANGE, 0, instrument, 0);
+ track.add(new MidiEvent(sm, 0));
+
+ int n = 0; // current character in notes[] array
+ int t = 0; // time in ticks for the composition
+
+ // These values persist and apply to all notes 'till changed
+ int notelength = 16; // default to quarter notes
+ int velocity = 64; // default to middle volume
+ int basekey = 60; // 60 is middle C. Adjusted up and down by octave
+ boolean sustain = false; // is the sustain pedal depressed?
+ int numnotes = 0; // How many notes in current chord?
+
+ while (n < notes.length) {
+ char c = notes[n++];
+
+ if (c == '+')
+ basekey += 12; // increase octave
+ else if (c == '-')
+ basekey -= 12; // decrease octave
+ else if (c == '>')
+ velocity += 16; // increase volume;
+ else if (c == '<')
+ velocity -= 16; // decrease volume;
+ else if (c == '/') {
+ char d = notes[n++];
+ if (d == '2')
+ notelength = 32; // half note
+ else if (d == '4')
+ notelength = 16; // quarter note
+ else if (d == '8')
+ notelength = 8; // eighth note
+ else if (d == '3' && notes[n++] == '2')
+ notelength = 2;
+ else if (d == '6' && notes[n++] == '4')
+ notelength = 1;
+ else if (d == '1') {
+ if (n < notes.length && notes[n] == '6')
+ notelength = 4; // 1/16th note
+ else
+ notelength = 64; // whole note
+ }
+ } else if (c == 's') {
+ sustain = !sustain;
+ // Change the sustain setting for channel 0
+ ShortMessage m = new ShortMessage();
+ m.setMessage(ShortMessage.CONTROL_CHANGE, 0, DAMPER_PEDAL,
+ sustain ? DAMPER_ON : DAMPER_OFF);
+ track.add(new MidiEvent(m, t));
+ } else if (c >= 'A' && c <= 'G') {
+ int key = basekey + offsets[c - 'A'];
+ if (n < notes.length) {
+ if (notes[n] == 'b') { // flat
+ key--;
+ n++;
+ } else if (notes[n] == '#') { // sharp
+ key++;
+ n++;
+ }
+ }
+
+ addNote(track, t, notelength, key, velocity);
+ numnotes++;
+ } else if (c == ' ') {
+ // Spaces separate groups of notes played at the same time.
+ // But we ignore them unless they follow a note or notes.
+ if (numnotes > 0) {
+ t += notelength;
+ numnotes = 0;
+ }
+ } else if (c == '.') {
+ // Rests are like spaces in that they force any previous
+ // note to be output (since they are never part of chords)
+ if (numnotes > 0) {
+ t += notelength;
+ numnotes = 0;
+ }
+ // Now add additional rest time
+ t += notelength;
+ }
+ }
+ }
+
+ // A convenience method to add a note to the track on channel 0
+ public static void addNote(Track track, int startTick, int tickLength,
+ int key, int velocity) throws InvalidMidiDataException {
+ ShortMessage on = new ShortMessage();
+ on.setMessage(ShortMessage.NOTE_ON, 0, key, velocity);
+ ShortMessage off = new ShortMessage();
+ off.setMessage(ShortMessage.NOTE_OFF, 0, key, velocity);
+ track.add(new MidiEvent(on, startTick));
+ track.add(new MidiEvent(off, startTick + tickLength));
+ }
+
+ @Override
+ public void run() {
+ while (true) {
+ System.out.println("Checking last action time");
+ if ((System.currentTimeMillis() - lastActionTime) > 20000) {
+ System.out.println("Activating Noise");
+ bag.noise(new Rectangle(0, 0, 9, 20));
+
+ noising = true;
+
+ } else {
+ System.out.println("Waiting more");
+ }
+ try {
+ Thread.sleep(10000);
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+
+ }
+ }
+
+ }
+}
diff --git a/PunchingBag/src/uk/ac/open/punchingbag/examples/SimpleKeyboard.java b/PunchingBag/src/uk/ac/open/punchingbag/examples/SimpleKeyboard.java
index 1e791ee..245ed34 100644
--- a/PunchingBag/src/uk/ac/open/punchingbag/examples/SimpleKeyboard.java
+++ b/PunchingBag/src/uk/ac/open/punchingbag/examples/SimpleKeyboard.java
@@ -128,32 +128,6 @@ public class SimpleKeyboard implements ButtonListener, Runnable {
e.printStackTrace();
}
- /*char[] notes = { 'C', 'C' };
-
- String filename = null;
- int instrument = 0;
- int tempo = 120;
-
- // 16 ticks per quarter note.
- Sequence sequence = new Sequence(Sequence.PPQ, 16);
-
- // Add the specified notes to the track
- addTrack(sequence, instrument, tempo, notes);
-
- // Set up the Sequencer and Synthesizer objects
- Sequencer sequencer = MidiSystem.getSequencer();
- sequencer.open();
- Synthesizer synthesizer = MidiSystem.getSynthesizer();
- synthesizer.open();
- sequencer.getTransmitter().setReceiver(synthesizer.getReceiver());
-
- // Specify the sequence to play, and the tempo to play it at
- sequencer.setSequence(sequence);
- sequencer.setTempoInBPM(tempo);
-
- // And start playing now.
- sequencer.start();*/
-
}
@Override
@@ -162,117 +136,6 @@ public class SimpleKeyboard implements ButtonListener, Runnable {
}
- /*
- * This method parses the specified char[] of notes into a Track. The
- * musical notation is the following: A-G: A named note; Add b for flat and
- * # for sharp. +: Move up one octave. Persists. -: Move down one octave.
- * Persists. /1: Notes are whole notes. Persists 'till changed /2: Half
- * notes /4: Quarter notes /n: N can also be, 8, 16, 32, 64. s: Toggle
- * sustain pedal on or off (initially off) >: Louder. Persists <: Softer.
- * Persists .: Rest. Length depends on current length setting Space: Play
- * the previous note or notes; notes not separated by spaces are played at
- * the same time
- */
- public static void addTrack(Sequence s, int instrument, int tempo,
- char[] notes) throws InvalidMidiDataException {
- Track track = s.createTrack(); // Begin with a new track
-
- // Set the instrument on channel 0
- ShortMessage sm = new ShortMessage();
- sm.setMessage(ShortMessage.PROGRAM_CHANGE, 0, instrument, 0);
- track.add(new MidiEvent(sm, 0));
-
- int n = 0; // current character in notes[] array
- int t = 0; // time in ticks for the composition
-
- // These values persist and apply to all notes 'till changed
- int notelength = 16; // default to quarter notes
- int velocity = 64; // default to middle volume
- int basekey = 60; // 60 is middle C. Adjusted up and down by octave
- boolean sustain = false; // is the sustain pedal depressed?
- int numnotes = 0; // How many notes in current chord?
-
- while (n < notes.length) {
- char c = notes[n++];
-
- if (c == '+')
- basekey += 12; // increase octave
- else if (c == '-')
- basekey -= 12; // decrease octave
- else if (c == '>')
- velocity += 16; // increase volume;
- else if (c == '<')
- velocity -= 16; // decrease volume;
- else if (c == '/') {
- char d = notes[n++];
- if (d == '2')
- notelength = 32; // half note
- else if (d == '4')
- notelength = 16; // quarter note
- else if (d == '8')
- notelength = 8; // eighth note
- else if (d == '3' && notes[n++] == '2')
- notelength = 2;
- else if (d == '6' && notes[n++] == '4')
- notelength = 1;
- else if (d == '1') {
- if (n < notes.length && notes[n] == '6')
- notelength = 4; // 1/16th note
- else
- notelength = 64; // whole note
- }
- } else if (c == 's') {
- sustain = !sustain;
- // Change the sustain setting for channel 0
- ShortMessage m = new ShortMessage();
- m.setMessage(ShortMessage.CONTROL_CHANGE, 0, DAMPER_PEDAL,
- sustain ? DAMPER_ON : DAMPER_OFF);
- track.add(new MidiEvent(m, t));
- } else if (c >= 'A' && c <= 'G') {
- int key = basekey + offsets[c - 'A'];
- if (n < notes.length) {
- if (notes[n] == 'b') { // flat
- key--;
- n++;
- } else if (notes[n] == '#') { // sharp
- key++;
- n++;
- }
- }
-
- addNote(track, t, notelength, key, velocity);
- numnotes++;
- } else if (c == ' ') {
- // Spaces separate groups of notes played at the same time.
- // But we ignore them unless they follow a note or notes.
- if (numnotes > 0) {
- t += notelength;
- numnotes = 0;
- }
- } else if (c == '.') {
- // Rests are like spaces in that they force any previous
- // note to be output (since they are never part of chords)
- if (numnotes > 0) {
- t += notelength;
- numnotes = 0;
- }
- // Now add additional rest time
- t += notelength;
- }
- }
- }
-
- // A convenience method to add a note to the track on channel 0
- public static void addNote(Track track, int startTick, int tickLength,
- int key, int velocity) throws InvalidMidiDataException {
- ShortMessage on = new ShortMessage();
- on.setMessage(ShortMessage.NOTE_ON, 0, key, velocity);
- ShortMessage off = new ShortMessage();
- off.setMessage(ShortMessage.NOTE_OFF, 0, key, velocity);
- track.add(new MidiEvent(on, startTick));
- track.add(new MidiEvent(off, startTick + tickLength));
- }
-
@Override
public void run() {
while (true) {