001package headfirst.combined.djview;
002
003import java.util.ArrayList;
004
005import javax.sound.midi.MetaEventListener;
006import javax.sound.midi.MetaMessage;
007import javax.sound.midi.MidiEvent;
008import javax.sound.midi.MidiSystem;
009import javax.sound.midi.Sequence;
010import javax.sound.midi.Sequencer;
011import javax.sound.midi.ShortMessage;
012import javax.sound.midi.Track;
013
014public class BeatModel implements BeatModelInterface, MetaEventListener {
015        Sequencer sequencer;
016        ArrayList<BeatObserver> beatObservers = new ArrayList<BeatObserver>();
017        ArrayList<BPMObserver> bpmObservers = new ArrayList<BPMObserver>();
018        int bpm = 90;
019        Sequence sequence;
020        Track track;
021
022        public void initialize() {
023                setUpMidi();
024                buildTrackAndStart();
025        }
026
027        public void on() {
028                sequencer.start();
029                setBPM(90);
030        }
031
032        public void off() {
033                setBPM(0);
034                sequencer.stop();
035        }
036
037        public void setBPM(int bpm) {
038                this.bpm = bpm;
039                sequencer.setTempoInBPM(getBPM());
040                notifyBPMObservers();
041        }
042
043        public int getBPM() {
044                return bpm;
045        }
046
047        void beatEvent() {
048                notifyBeatObservers();
049        }
050
051
052        public void registerObserver(BeatObserver o) {
053                beatObservers.add(o);
054        }
055
056        public void notifyBeatObservers() {
057                for(int i = 0; i < beatObservers.size(); i++) {
058                        BeatObserver observer = beatObservers.get(i);
059                        observer.updateBeat();
060                }
061        }
062
063        public void registerObserver(BPMObserver o) {
064                bpmObservers.add(o);
065        }
066
067        public void notifyBPMObservers() {
068                for(int i = 0; i < bpmObservers.size(); i++) {
069                        BPMObserver observer = bpmObservers.get(i);
070                        observer.updateBPM();
071                }
072        }
073
074
075        public void removeObserver(BeatObserver o) {
076                int i = beatObservers.indexOf(o);
077                if (i >= 0) {
078                        beatObservers.remove(i);
079                }
080        }
081
082
083
084        public void removeObserver(BPMObserver o) {
085                int i = bpmObservers.indexOf(o);
086                if (i >= 0) {
087                        bpmObservers.remove(i);
088                }
089        }
090
091
092        public void meta(MetaMessage message) {
093                if (message.getType() == 47) {
094                        beatEvent();
095                        sequencer.start();
096                        setBPM(getBPM());
097                }
098        }
099
100        public void setUpMidi() {
101                try {
102                        sequencer = MidiSystem.getSequencer();
103                        sequencer.open();
104                        sequencer.addMetaEventListener(this);
105                        sequence = new Sequence(Sequence.PPQ,4);
106                        track = sequence.createTrack();
107                        sequencer.setTempoInBPM(getBPM());
108                } catch(Exception e) {
109                        e.printStackTrace();
110                }
111        }
112
113        public void buildTrackAndStart() {
114                int[] trackList = {35, 0, 46, 0};
115
116                sequence.deleteTrack(null);
117                track = sequence.createTrack();
118
119                makeTracks(trackList);
120                track.add(makeEvent(192,9,1,0,4));
121                try {
122                        sequencer.setSequence(sequence);
123                } catch(Exception e) {
124                        e.printStackTrace();
125                }
126        }
127
128        public void makeTracks(int[] list) {
129
130                for (int i = 0; i < list.length; i++) {
131                        int key = list[i];
132
133                        if (key != 0) {
134                                track.add(makeEvent(144,9,key, 100, i));
135                                track.add(makeEvent(128,9,key, 100, i+1));
136                        }
137                }
138        }
139
140        public  MidiEvent makeEvent(int comd, int chan, int one, int two, int tick) {
141                MidiEvent event = null;
142                try {
143                        ShortMessage a = new ShortMessage();
144                        a.setMessage(comd, chan, one, two);
145                        event = new MidiEvent(a, tick);
146
147                } catch(Exception e) {
148                        e.printStackTrace();
149                }
150                return event;
151        }
152}