8

古い C++ dll を使用してコンピューターに接続されたピアノからMIDI データを受信する Java プロジェクトを継承しました。

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

4

2 に答える 2

16

Java による MIDI API (javax.sound.midi.*) だけで録音したい場合、これは非常に簡単に実行できます。これはコピーして貼り付けるコードではありませんが、独自の 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 ステートメントで開いたすべてのものに対して close メソッドを呼び出す必要があります。

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

次に、録音を停止し、シーケンスを 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"));
}

また、Track クラス (シーケンスは複数のトラックを持つことができます) には実際の入力データが含まれており、get メソッドで簡単にアクセスできます。Track クラスは MidiEvents で構成されます。たとえば、トラックは次のとおりです。

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 ティックで表されます。したがって、1 秒あたりのティック数を増減することでテンポを簡単に変更できます。

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

于 2012-11-04T20:15:41.710 に答える
4

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

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

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();
于 2010-01-05T18:57:07.213 に答える