forked from drahosj/MoppyLive
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMoppySequencer.java
101 lines (82 loc) · 3.04 KB
/
MoppySequencer.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package moppylive;
import gnu.io.NoSuchPortException;
import gnu.io.PortInUseException;
import gnu.io.UnsupportedCommOperationException;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.MetaEventListener;
import javax.sound.midi.MetaMessage;
import javax.sound.midi.MidiMessage;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.Receiver;
import javax.sound.midi.Sequence;
import javax.sound.midi.Sequencer;
/**
*
* @author Sammy1Am
*/
public class MoppySequencer implements MetaEventListener{
MoppyBridge mb;
MoppyPlayer mp;
Sequencer sequencer;
ArrayList<MoppyStatusConsumer> listeners = new ArrayList<MoppyStatusConsumer>(1);
public MoppySequencer(String comPort) throws NoSuchPortException, PortInUseException, UnsupportedCommOperationException, IOException, MidiUnavailableException {
mb = new MoppyBridge(comPort); //Create MoppyBridge on the COM port with the Arduino
mp = new MoppyPlayer(mb);
mb.resetDrives();
sequencer = MidiSystem.getSequencer(false);
sequencer.open();
sequencer.getTransmitter().setReceiver(mp); // Set MoppyPlayer as a receiver.
sequencer.addMetaEventListener(this);
}
public void loadFile(String filePath) throws InvalidMidiDataException, IOException, MidiUnavailableException {
sequencer.stop();
Sequence sequence = MidiSystem.getSequence(new File(filePath));
sequencer.setSequence(sequence);
System.out.println("Loaded sequence with "+(sequence.getTracks().length-1)+" MIDI channels.");
}
public void startSequencer(){
sequencer.start();
}
public void stopSequencer(){
if (sequencer.isOpen()){
sequencer.stop();
}
mb.resetDrives();
}
public void setTempo(float newTempo){
sequencer.setTempoInBPM(newTempo);
}
public void addListener(MoppyStatusConsumer newListener){
listeners.add(newListener);
}
public void removeListener(MoppyStatusConsumer oldListener){
listeners.remove(oldListener);
}
public void closeSequencer(){
stopSequencer();
sequencer.close();
mp.close();
}
public void meta(MetaMessage meta) {
if (meta.getType() == 81){
int uSecondsPerQN = 0;
uSecondsPerQN |= meta.getData()[0] & 0xFF;
uSecondsPerQN <<= 8;
uSecondsPerQN |= meta.getData()[1] & 0xFF;
uSecondsPerQN <<= 8;
uSecondsPerQN |= meta.getData()[2] & 0xFF;
int newTempo = 60000000/uSecondsPerQN;
sequencer.setTempoInBPM(newTempo);
for (MoppyStatusConsumer c : listeners){
c.tempoChanged(newTempo);
}
System.out.println("Tempo changed to: " + newTempo);
}
}
}