2011-07-30 13 views
1

Java에서 MIDI 파일 판독기를 작성하고 있습니다 (주로 운동으로, 아마도 javax.sound.midi 라이브러리가 없으므로 Android 프로젝트에서 사용하기 위해). 나는 this 사양을 따릅니다.알 수없는 MIDI 이벤트 디코딩

필자의 프로젝트에서는 실제 세부 내용이 이벤트별로 진행되므로 사양 세부 사항을 잘 구현했습니다. 파일에 InputStream이 열리고 동일한 객체가 전달되어 다양한 이벤트 객체를 구문 분석하여 이벤트가 자체 파싱되면 스트림이 다음 이벤트에 배치됩니다. 이것은 모두 훌륭하게 작동합니다.

첫 번째 테스트 파일은 단순히 소나 8에 생성 된 빈 데이터 트랙이있는 템포 맵입니다. 템포 트랙은 완벽하게 파싱됩니다. 빈 트랙은 청크 식별자와 트랙 이름 뒤에 다음과 같은 데이터가 있습니다

00 B0 07 47 00 0A 40 00 FF 2F 00

첫 번째 바이트가 성공적으로 구문 분석됩니다. 00 채널 0, 07 = 메인 볼륨 조절, 다음 바이트는 저를 혼동 (71)

47 = 볼륨 값에 0, B0 = 컨트롤러 이벤트의 델타 시간을 =. 00 0A 40 가장 일반적인 경우는 값이 64 인 Pan 이벤트입니다. 0A은 볼륨 이벤트와 마찬가지로 B0 앞에 오는 것으로 예상되는 Controller 이벤트 유형입니다. 그러나 알려진 이벤트 식별자 바이트가 없기 때문에 독자가이 이벤트를 구문 분석하지 못합니다.

그래서 내 질문에 이러한 이벤트 유형을 어떻게 설명 할 수 있을까요? 이 파일 형식에서 문자열을 컨트롤러 이벤트와 함께 사용하면 하나의 B0 식별자와 함께 사용할 수 있습니까? 또한 파일에 식별 할 수없는 이벤트 유형이있는 경우 이벤트가 무엇인지 알지 못하면 얼마나 많은 데이터를 건너 뛸 수 있는지 알 수있는 방법이 있습니까? 알려지지 않은 이벤트를 건너 뛰고 내 독자가 실패하지 않도록하고 싶습니다. 그러나 이벤트를 식별 할 수 없으면 어떻게 건너 뛸 지 잘 모릅니다. 이 특별한 경우에 대한 통찰력을 원할 것입니다.

+0

비어 있지 않은 데이터 트랙 (실제 음표가있는 트랙)을보고 약간의 통찰력을 얻었습니다. 내가 많은 Note-On 이벤트 (0x9)를 기대하는 동안, 나는 트랙에서 모든 노트가 뒤 따르는 하나의 Note-On 이벤트를 본다. 흥미로운 점은 Note-Off 이벤트가 없다는 것입니다. 노트가 종료되어야하는 velocity 0의 Note-On 이벤트가 있습니다. 그래서 이벤트 식별자는 다음 이벤트를 식별 할뿐만 아니라 다른 이벤트 식별자가 발견 될 때까지 해당 유형의 이벤트로 이벤트 식별자를 따르는 모든 바이트를 식별한다고 믿게되었습니다. 나는 이것에 대한 확인이나 추가 설명을 여전히 감사 할 것입니다. – LeffelMania

+0

[midi 파일 구문 분석, 인식 할 수없는 이벤트 유형]의 가능한 복제본 (http://stackoverflow.com/questions/7719366/midi-file-parsing-unrecognised-event-type) – Arhad

답변

3

실행 상태라고합니다. MIDI 사양의 일부입니다. 당신이하는 일은 정확히 옳은 일입니다. 미안하지만 MIDI 데이터 스트림을 리버스 엔지니어링하여 알아 내야했습니다.Here is a longer explanation of running status.

그리고 예, 속도 0 인 Note On 이벤트는 음표 꺼짐입니다. 실제 노트 오프 이벤트는 연관된 벨로 시티를 가지고 있지만 거의 노트 오프 속도를 구현하는 장치가 거의 없기 때문에 노트 온을 제로 속도로 보는 것이 훨씬 더 일반적입니다.

+0

이것은 훨씬 더 구체화 된 사양입니다. . 많은 분들께 감사드립니다. – LeffelMania

+0

대단히 반갑습니다. MIDI의 새벽에 많은 MIDI 관련 프로그래밍을 수행 했으므로 사용자가 올 수있는 질문을 게시하십시오. – SSteve

0

아무도 유사한 문제로이 문제가 발생하면 제 질문에 대한 답변을 드리겠습니다. (그러나 그럴 가능성은 낮습니다.)

위의 코멘트가 보류 중입니다. 첫 번째로 식별 된 이벤트를 읽은 후 후속 이벤트에 이벤트 ID가 없으면 이전 이벤트와 동일한 유형의 이벤트로 처리 할 수 ​​있습니다. 그래서 내 예제에서

:

00 B0 07 47 00 0A 40 00 FF 2F 00

은 하나의 이벤트 식별자가있는 경우에도 두 개의 연속 컨트롤러 이벤트로 해석 될 수있다. 따라서 이것은 실제로 볼륨 이벤트 07이고 Pan 이벤트 0A 다음에 트랙 끝의 이벤트 FF 2F 00이 뒤 따른다.

내 코드의 솔루션은 마지막 식별자를 기억하고 스트림의 다음 바이트가 유효한 식별자가 아닌 경우 다음 바이트 청크가 이전 이벤트와 동일한 유형의 이벤트로 해석됩니다 . 이해가되고, 더 중요한 것은 내 독자가 성공적으로 완료된 것 같습니다.