2009-09-28 23 views
7

私はコンピュータに接続されたピアノからan old C++ dll to receive MIDI dataを使ったJavaプロジェクトを継承しました。Java MIDI - ピアノからデータを取得していますか?

JavaにはMIDIデバイスが組み込まれているので、従来のC++のDLLを取り除き、純粋なJavaを使いたいと思っています。 Javaはコンピュータに接続されたピアノからのデータ受信をサポートしていますか?私は役に立たない例をGoogleで検索しました。

答えて

4

はい、JavaSound APIを使用して、MIDIデータをMIDIデバイスから読み取ることができます。

JFugueは、JavaSound APIを使用する音楽プログラミング用のJava APIであり、JavaSoundとのやり取りを簡素化するのに役立ちます。次のようにJFugue 5.xでは、MIDI機器からのMIDIデータの10秒をキャプチャするためのサンプルコードは次のとおりです。

MidiDevice device = /* specify a MIDI device */ 
MusicTransmitterToSequence transmitter = new MusicTransmitterToSequence(device); 
transmitter.listenForMillis(10000); 
Sequence music = transmitter.getSequence(); 

ます。また、起動してデバイスを聞いて停止することができます:

MidiDevice device = /* specify a MIDI device */ 
MusicTransmitterToSequence transmitter = new MusicTransmitterToSequence(device); 
transmitter.startListening(); 
// Do stuff 
transmitter.stopListening(); 
Sequence music = transmitter.getSequence(); 
13

あなたの場合Java(javax.sound.midi。*)でMIDI APIだけで録音したい場合、これは非常に簡単です。これはコピー&ペーストのコードではありませんが、実際には簡単な独自のMIDIレコーダーのプログラミングを開始するのに役立ちます。

まず、入力と出力のMidiDeviceを定義します。したがって、まずIOの可能性のリストを見つけて、MIDI録音と再生のための入力デバイスと出力デバイスを選択できるGUIを作成する必要があります。

Info[] infos = MidiSystem.getMidiDeviceInfo(); 
for(int i=0;i<infos.length;i++) 
{ 
    System.out.println(infos[i].getName() + " - " + infos[i].getDescription()); 
} 

したがって、MIDIデバイスの一覧があります。次に、MIDIデバイスを選択したいとします。たとえば、infos配列のインデックスを選択します。

MidiDevice inputDevice = MidiSystem.getMidiDevice(infos[x]); 
MidiDevice outputDevice = MidiSystem.getMidiDevice(infos[y]); 

また、シーケンサー、トランスミッタ、およびレシーバのいくつかのグローバルを指定することもできます。

Sequencer sequencer = MidiSystem.getSequencer(); 
Transmitter transmitter; 
Receiver receiver; 

ここで、使用したいレコードボタンがあります。

// Open a connection to your input device 
inputDevice.open(); 
// Open a connection to the default sequencer (as specified by MidiSystem) 
sequencer.open(); 
// Get the transmitter class from your input device 
transmitter = inputDevice.getTransmitter(); 
// Get the receiver class from your sequencer 
receiver = sequencer.getReceiver(); 
// Bind the transmitter to the receiver so the receiver gets input from the transmitter 
transmitter.setReceiver(receiver); 

// Create a new sequence 
Sequence seq = new Sequence(Sequence.PPQ, 24); 
// And of course a track to record the input on 
Track currentTrack = seq.createTrack(); 
// Do some sequencer settings 
sequencer.setSequence(seq); 
sequencer.setTickPosition(0); 
sequencer.recordEnable(currentTrack, -1); 
// And start recording 
sequencer.startRecording(); 

を注意してください、このコードはMidiUnavailableExceptionsを投げることができると、あなたがfinally文で開かれたすべてのものに近いのメソッドを呼び出す必要があります。

しかし、これはコードがどのように見えるかの中心にすぎません。方法sequencer.startRecording()を呼び出すとすぐに、シーケンスseqにすべてが記録されます。

次に、録音を停止し、シーケンスをMIDIとしてファイルに保存したり、再生することができます。たとえば、レコードの停止ボタンなどを押すと、コードになる可能性があります。

// Stop recording 
if(sequencer.isRecording()) 
{ 
    // Tell sequencer to stop recording 
    sequencer.stopRecording(); 

    // Retrieve the sequence containing the stuff you played on the MIDI instrument 
    Sequence tmp = sequencer.getSequence(); 

    // Save to file 
    MidiSystem.write(tmp, 0, new File("MyMidiFile.mid")); 
} 

また、トラッククラスは、(シーケンスが複数のトラックを持つことができます)あなたはgetメソッドにより、容易にアクセスすることができ、実際の入力データを、含まれています。 Trackクラスは、MidiEventで構成されています。

MidiEvent 0: The C key is pressed 
MidiEvent 1: The D key is pressed 
MidiEvent 2: The C key of MidiEvent 0 is released 
MidiEvent 3: The sustain pedal is pressed 
etc... 

、すべてのMidiEventをMIDIティックで特定のタイムスタンプを、持っている、ので、あなたは簡単に毎秒チック数を増加または減少させることにより、テンポを変更することができます。たとえば、トラックがあります。

ここで最も難しい問題は、MidiEventがバイトコードで表現されているため、バイトがどのような動作を表しているかを示す参照バイトコードシートを使用する必要があることです。これで、あなたはそれを始めるはずです:http://www.onicos.com/staff/iz/formats/midi-event.html

+0

また、Trackクラスを使用するコードを提供できますか?ありがとう。 –

+1

@AliSharabiani 'Track'を' List 'と見ることができます。これ以上のことはありません([javax.sound.midi.Track]のこのOracle Javaドキュメントも参照してください)(https://docs.oracle.com/javase/7/docs/api/javax/sound/midi/Track。 html)。 – Yeti

関連する問題