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}