문제
나는 사용한 Java 프로젝트를 물려 받았습니다 MIDI 데이터를 수신하기위한 오래된 C ++ DLL 컴퓨터에 연결된 피아노에서.
Java는 MIDI 장치에 대한 내장 지원을 받았으므로 레거시 C ++ DLL을 제거하고 Pure Java를 사용하고 싶습니다. Java는 컴퓨터에 연결된 피아노에서 데이터를 수신하는 것을 지원합니까? Google에서 예시를 검색하여 아무 소용이 없었습니다.
해결책
예, Javasound API를 사용하여 MIDI 장치에서 MIDI 데이터를 읽을 수 있습니다.
Jfugue Javasound API를 사용하고 Javasound와의 상호 작용을 단순화하는 데 도움이되는 음악 프로그래밍을위한 Java API입니다. 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();
다른 팁
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를 던질 수 있으며 최종 문서에서 열린 모든 것들에 대한 가까운 방법을 호출해야합니다.
그러나 이것은 코드의 모습의 핵심 일뿐입니다. 그것은 모든 것을 시퀀스에 기록합니다 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"));
}
또한 트랙 클래스 (시퀀스에는 여러 트랙이있을 수 있음)에는 실제 입력 데이터가 포함되어 있으며 GET 메소드로 쉽게 액세스 할 수 있습니다. 트랙 클래스는 중형인으로 구성됩니다. 예를 들어 트랙은 다음과 같습니다.
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...
그리고 모든 미드 디벤트에는 특정 타임 스탬프가 있으며, 이는 미디 진드기로 표현되는 특정 타임 스탬프가 있으므로 초당 진드기 수를 늘리거나 줄여 템포를 쉽게 변경할 수 있습니다.
여기서 가장 어려운 문제는 미드 예의인이 바이트 코드로 표현되므로 참조 바이트 코드 시트를 사용하여 바이트가 어떤 동작을 나타내는 지 알려 주어야합니다. 이것은 당신이 그것을 시작할 것입니다 : http://www.onicos.com/staff/iz/formats/midi-event.html