1 package camidion.chordhelper.mididevice;
\r
3 import java.util.List;
\r
4 import java.util.Vector;
\r
6 import javax.sound.midi.MidiDevice;
\r
7 import javax.sound.midi.MidiSystem;
\r
8 import javax.sound.midi.MidiUnavailableException;
\r
9 import javax.sound.midi.Sequencer;
\r
10 import javax.sound.midi.Synthesizer;
\r
12 import camidion.chordhelper.ChordHelperApplet;
\r
13 import camidion.chordhelper.midieditor.MidiEditor;
\r
18 public class MidiDeviceModelList extends Vector<MidiConnecterListModel> {
\r
22 public MidiEditor editorDialog;
\r
26 private MidiConnecterListModel editorDialogModel;
\r
30 private MidiConnecterListModel synthModel;
\r
34 private MidiConnecterListModel firstMidiOutModel;
\r
36 * MIDIデバイスモデルリストを生成します。
\r
37 * @param vmdList 仮想MIDIデバイスのリスト
\r
39 public MidiDeviceModelList(List<VirtualMidiDevice> vmdList) {
\r
40 MidiDevice.Info[] devInfos = MidiSystem.getMidiDeviceInfo();
\r
41 MidiConnecterListModel guiModels[] = new MidiConnecterListModel[vmdList.size()];
\r
42 MidiConnecterListModel firstMidiInModel = null;
\r
43 for( int i=0; i<vmdList.size(); i++ )
\r
44 guiModels[i] = addMidiDevice(vmdList.get(i));
\r
45 Sequencer sequencer;
\r
47 sequencer = MidiSystem.getSequencer(false);
\r
48 sequencerModel = (MidiSequencerModel)addMidiDevice(sequencer);
\r
49 } catch( MidiUnavailableException e ) {
\r
51 ChordHelperApplet.VersionInfo.NAME +
\r
52 " : MIDI sequencer unavailable"
\r
54 e.printStackTrace();
\r
56 editorDialog = new MidiEditor(sequencerModel);
\r
57 editorDialogModel = addMidiDevice(editorDialog.getVirtualMidiDevice());
\r
58 for( MidiDevice.Info info : devInfos ) {
\r
61 device = MidiSystem.getMidiDevice(info);
\r
62 } catch( MidiUnavailableException e ) {
\r
63 e.printStackTrace(); continue;
\r
65 if( device instanceof Sequencer ) continue;
\r
66 if( device instanceof Synthesizer ) {
\r
68 synthModel = addMidiDevice(MidiSystem.getSynthesizer());
\r
69 } catch( MidiUnavailableException e ) {
\r
71 ChordHelperApplet.VersionInfo.NAME +
\r
72 " : Java internal MIDI synthesizer unavailable"
\r
74 e.printStackTrace();
\r
78 MidiConnecterListModel m = addMidiDevice(device);
\r
79 if( m.rxSupported() && firstMidiOutModel == null )
\r
80 firstMidiOutModel = m;
\r
81 if( m.txSupported() && firstMidiInModel == null )
\r
82 firstMidiInModel = m;
\r
85 // NOTE: 必ず MIDI OUT Rx デバイスを先に開くこと。
\r
87 // そうすれば、後から開いた MIDI IN Tx デバイスからの
\r
88 // タイムスタンプのほうが「若く」なる。これにより、
\r
89 // 先に開かれ「少し歳を食った」Rx デバイスは
\r
90 // 「信号が遅れてやってきた」と認識するので、
\r
91 // 遅れを取り戻そうとして即座に音を出してくれる。
\r
93 // 開く順序が逆になると「進みすぎるから遅らせよう」として
\r
94 // 無用なレイテンシーが発生する原因になる。
\r
96 MidiConnecterListModel openModels[] = {
\r
103 for( MidiConnecterListModel m : openModels ) {
\r
104 if( m != null ) m.openDevice();
\r
106 for( MidiConnecterListModel m : guiModels ) {
\r
109 } catch( MidiUnavailableException ex ) {
\r
110 ex.printStackTrace();
\r
114 for( MidiConnecterListModel mtx : guiModels ) {
\r
115 for( MidiConnecterListModel mrx : guiModels )
\r
116 mtx.connectToReceiverOf(mrx);
\r
117 mtx.connectToReceiverOf(sequencerModel);
\r
118 mtx.connectToReceiverOf(synthModel);
\r
119 mtx.connectToReceiverOf(firstMidiOutModel);
\r
121 if( firstMidiInModel != null ) {
\r
122 for( MidiConnecterListModel m : guiModels )
\r
123 firstMidiInModel.connectToReceiverOf(m);
\r
124 firstMidiInModel.connectToReceiverOf(sequencerModel);
\r
125 firstMidiInModel.connectToReceiverOf(synthModel);
\r
126 firstMidiInModel.connectToReceiverOf(firstMidiOutModel);
\r
128 if( sequencerModel != null ) {
\r
129 for( MidiConnecterListModel m : guiModels )
\r
130 sequencerModel.connectToReceiverOf(m);
\r
131 sequencerModel.connectToReceiverOf(synthModel);
\r
132 sequencerModel.connectToReceiverOf(firstMidiOutModel);
\r
134 if( editorDialogModel != null ) {
\r
135 editorDialogModel.connectToReceiverOf(synthModel);
\r
136 editorDialogModel.connectToReceiverOf(firstMidiOutModel);
\r
140 * このデバイスモデルリストに登録されたMIDIシーケンサーモデルを返します。
\r
141 * @return MIDIシーケンサーモデル
\r
143 public MidiSequencerModel getSequencerModel() { return sequencerModel; }
\r
144 private MidiSequencerModel sequencerModel;
\r
146 * 指定のMIDIデバイスからMIDIデバイスモデルを生成して追加します。
\r
147 * @param device MIDIデバイス
\r
148 * @return 生成されたMIDIデバイスモデル
\r
150 private MidiConnecterListModel addMidiDevice(MidiDevice device) {
\r
151 MidiConnecterListModel m;
\r
152 if( device instanceof Sequencer )
\r
153 m = new MidiSequencerModel(this,(Sequencer)device,this);
\r
155 m = new MidiConnecterListModel(device,this);
\r