001package bradleyross.music.imported;
002import java.util.List;
003import java.util.ArrayList;
004
005import javax.sound.midi.InvalidMidiDataException;
006import javax.sound.midi.MidiDevice;
007// import javax.sound.midi.MidiMessage;
008import javax.sound.midi.MidiSystem;
009import javax.sound.midi.MidiUnavailableException;
010import javax.sound.midi.Receiver;
011import javax.sound.midi.ShortMessage;
012import javax.sound.midi.Synthesizer;
013// import javax.sound.midi.Transmitter;
014
015/**
016 * Plays musical notes on first synthesizer it finds.
017 * 
018 * <p>This program is based loosely on SynthNote which can be found 
019 *    at<a href="http://www.jsresources.org/examples/SynthNote.java.html"
020 *    target="_blank">
021 *    http://www.jsresources.org/examples/SynthNote.java.html</a>.
022 *    However, it has been heavily modified to reduce the need on
023 *    third-party libraries and to make it more understandable.</p>
024 * @author bradleyross
025 *
026 */
027public class SynthNote implements Runnable {
028        List<MidiDevice> devices = new ArrayList<MidiDevice>();
029        MidiDevice.Info[] infos = null; 
030        Synthesizer synthesizer = null;
031        Receiver receiver = null;
032        int PROGRAM_CHANGE = 192;
033        int NOTE_ON = 144;
034        int NOTE_OFF = 128;
035        public void run() {
036                try {
037                        infos = MidiSystem.getMidiDeviceInfo();
038                        for (MidiDevice.Info item : infos) {
039                                MidiDevice device = MidiSystem.getMidiDevice(item);
040                                devices.add(device);
041                                if (synthesizer == null) { 
042                                        if (!Synthesizer.class.isAssignableFrom(device.getClass())) {
043                                                continue;
044                                        }
045                                        if (device.getMaxReceivers() == 0) { continue; }
046                                        synthesizer = (Synthesizer) device;
047                                        synthesizer.open();
048                                        receiver = synthesizer.getReceiver();
049                                }
050                        }
051                        if (synthesizer == null) {
052                                System.out.println("Unable to find synthesizer - aborting");
053                                return;
054                        }
055                        System.out.println("Setting instrument to church organ");
056                        ShortMessage message1 = new ShortMessage(PROGRAM_CHANGE, 20, 100);
057                        System.out.println("Sending first note -  note 96");
058                        receiver.send(message1, -1l);
059                        ShortMessage message2 = new ShortMessage(NOTE_ON, 96, 100);
060                        receiver.send(message2, -1l);
061                        try {
062                                Thread.sleep(1000);
063                        } catch (InterruptedException ex) {
064                                ex.printStackTrace();
065                        }
066                        ShortMessage message3 = new ShortMessage(NOTE_OFF, 96, 0);
067                        receiver.send(message3, -1);
068                        System.out.println("Second note");
069                        sendNote(32, 2000);
070                        System.out.println("Third note");
071                        sendNote(44, 2000);
072                        System.out.println("Fourth note");
073                        sendNote(56, 2000);
074                        for (int i = 0; i < 7; i++) {
075                                int note = 56 + 12*i;
076                                if (note > 127) {
077                                        break;
078                                }
079                                System.out.println("New note: " + Integer.toString(note));
080                                sendNote(56 + 12*i, 1000);
081                        }
082                        sendChord(56, 2000);
083                        synthesizer.close();
084
085                } catch (MidiUnavailableException ex) {
086                        ex.printStackTrace();
087                } catch (InvalidMidiDataException ex) {
088                        ex.printStackTrace();
089                }
090        }
091        /**
092         * Play a note
093         * @param note note to be played
094         * @param length length of note in milliseconds
095         * @throws MidiUnavailableException
096         * @throws InvalidMidiDataException
097         */
098        protected void sendNote (int note, int length ) 
099                        throws MidiUnavailableException, InvalidMidiDataException {
100                ShortMessage message1 = new ShortMessage(NOTE_ON,note, 100);
101                receiver.send(message1, -1);
102                try {
103                        Thread.sleep(length);
104                } catch (InterruptedException ex) {
105                        ex.printStackTrace();
106                }
107                ShortMessage message2 = new ShortMessage(NOTE_OFF, note, 100);
108                receiver.send(message2, -1);
109                
110        }
111        /**
112         * Send a chord.
113         * @param note  base note
114         * @param length length of chord in milliseconds
115         * @throws MidiUnavailableException
116         * @throws InvalidMidiDataException
117         */
118        
119        protected void sendChord(int note, int length) 
120        throws MidiUnavailableException, InvalidMidiDataException {
121                receiver.send(new ShortMessage(NOTE_ON, note, 110), -1);
122                receiver.send(new ShortMessage(NOTE_ON, note + 12, 110), -1);
123                receiver.send(new ShortMessage(NOTE_ON, note + 24, 110), -1);
124                try {
125                        Thread.sleep(length);
126                } catch (InterruptedException ex) {
127                        ex.printStackTrace();
128                }
129                receiver.send(new ShortMessage(NOTE_OFF, note, 110), -1);
130                receiver.send(new ShortMessage(NOTE_OFF, note + 12, 110), -1);
131                receiver.send(new ShortMessage(NOTE_OFF, note + 24, 110), -1);
132        }
133        /**
134         * Test driver.
135         * @param args not used
136         */
137        public static void main(String[] args) {
138                SynthNote instance = new SynthNote();
139                instance.run();
140        }
141
142}