1 package camidion.chordhelper.mididevice;
4 import java.util.Vector;
6 import javax.sound.midi.MidiDevice;
7 import javax.sound.midi.MidiSystem;
8 import javax.sound.midi.MidiUnavailableException;
9 import javax.sound.midi.Sequencer;
10 import javax.sound.midi.Synthesizer;
12 import camidion.chordhelper.ChordHelperApplet;
13 import camidion.chordhelper.midieditor.MidiSequenceEditor;
18 public class MidiDeviceModelList extends Vector<MidiConnecterListModel> {
22 public MidiSequenceEditor editorDialog;
26 private MidiConnecterListModel editorDialogModel;
30 private MidiConnecterListModel synthModel;
34 private MidiConnecterListModel firstMidiOutModel;
36 * MIDIデバイスモデルリストを生成します。
37 * @param guiVirtualDeviceList GUI仮想MIDIデバイスのリスト
39 public MidiDeviceModelList(List<VirtualMidiDevice> guiVirtualDeviceList) {
40 MidiDevice.Info[] deviceInfos = MidiSystem.getMidiDeviceInfo();
41 MidiConnecterListModel guiModels[] = new MidiConnecterListModel[guiVirtualDeviceList.size()];
42 MidiConnecterListModel firstMidiInModel = null;
44 // GUI仮想MIDIデバイスリストの構築
45 for( int i=0; i<guiVirtualDeviceList.size(); i++ )
46 guiModels[i] = addMidiDevice(guiVirtualDeviceList.get(i));
51 sequencer = MidiSystem.getSequencer(false);
52 sequencerModel = (MidiSequencerModel)addMidiDevice(sequencer);
53 } catch( MidiUnavailableException e ) {
54 System.out.println(ChordHelperApplet.VersionInfo.NAME +" : MIDI sequencer unavailable");
58 editorDialog = new MidiSequenceEditor(sequencerModel);
59 editorDialogModel = addMidiDevice(editorDialog.getVirtualMidiDevice());
60 for( MidiDevice.Info info : deviceInfos ) {
64 device = MidiSystem.getMidiDevice(info);
65 } catch( MidiUnavailableException e ) {
66 e.printStackTrace(); continue;
68 // シーケンサの場合はすでに取得済みなのでスキップ
69 if( device instanceof Sequencer ) continue;
72 if( device instanceof Synthesizer ) {
74 synthModel = addMidiDevice(MidiSystem.getSynthesizer());
75 } catch( MidiUnavailableException e ) {
76 System.out.println(ChordHelperApplet.VersionInfo.NAME +
77 " : Java internal MIDI synthesizer unavailable");
82 // MIDIデバイスを追加し、最初のエントリを覚えておく
83 MidiConnecterListModel m = addMidiDevice(device);
84 if( m.rxSupported() && firstMidiOutModel == null ) firstMidiOutModel = m;
85 if( m.txSupported() && firstMidiInModel == null ) firstMidiInModel = m;
88 // NOTE: 必ず MIDI OUT Rx デバイスを先に開くこと。
90 // そうすれば、後から開いた MIDI IN Tx デバイスからの
91 // タイムスタンプのほうが「若く」なる。これにより、
92 // 先に開かれ「少し歳を食った」Rx デバイスは
93 // 「信号が遅れてやってきた」と認識するので、
94 // 遅れを取り戻そうとして即座に音を出してくれる。
96 // 開く順序が逆になると「進みすぎるから遅らせよう」として
97 // 無用なレイテンシーが発生する原因になる。
99 MidiConnecterListModel openModels[] = {
106 for( MidiConnecterListModel m : openModels ) if( m != null ) m.openDevice();
107 for( MidiConnecterListModel m : guiModels ) m.openDevice();
108 } catch( MidiUnavailableException ex ) {
109 ex.printStackTrace();
113 for( MidiConnecterListModel mtx : guiModels ) {
114 for( MidiConnecterListModel mrx : guiModels ) mtx.connectToReceiverOf(mrx);
115 mtx.connectToReceiverOf(sequencerModel);
116 mtx.connectToReceiverOf(synthModel);
117 mtx.connectToReceiverOf(firstMidiOutModel);
119 if( firstMidiInModel != null ) {
120 for( MidiConnecterListModel m : guiModels ) firstMidiInModel.connectToReceiverOf(m);
121 firstMidiInModel.connectToReceiverOf(sequencerModel);
122 firstMidiInModel.connectToReceiverOf(synthModel);
123 firstMidiInModel.connectToReceiverOf(firstMidiOutModel);
125 if( sequencerModel != null ) {
126 for( MidiConnecterListModel m : guiModels ) sequencerModel.connectToReceiverOf(m);
127 sequencerModel.connectToReceiverOf(synthModel);
128 sequencerModel.connectToReceiverOf(firstMidiOutModel);
130 if( editorDialogModel != null ) {
131 editorDialogModel.connectToReceiverOf(synthModel);
132 editorDialogModel.connectToReceiverOf(firstMidiOutModel);
136 * このデバイスモデルリストに登録されたMIDIシーケンサーモデルを返します。
137 * @return MIDIシーケンサーモデル
139 public MidiSequencerModel getSequencerModel() { return sequencerModel; }
140 private MidiSequencerModel sequencerModel;
142 * 指定のMIDIデバイスからMIDIデバイスモデルを生成して追加します。
143 * @param device MIDIデバイス
144 * @return 生成されたMIDIデバイスモデル
146 private MidiConnecterListModel addMidiDevice(MidiDevice device) {
147 MidiConnecterListModel m;
148 if( device instanceof Sequencer )
149 m = new MidiSequencerModel(this,(Sequencer)device,this);
151 m = new MidiConnecterListModel(device,this);