まずMIDIの構造から説明しますね。
MIDIは23バイトのヘッダーが有って、その後ろにID3v2みたいな感じで著作権情報、トラック名が記録されています。
ではMIDIのヘッダーを。
MIDIのヘッダー |
"MThd"(4バイト) |
ヘッダーの長さ(4バイト) |
MIDIフォーマット(2バイト) |
トラックナンバー(2バイト) |
4分音符の分解率(2バイト) |
"MTrk"(4バイト) |
トラックの長さ(5バイト) |
ヘッダーから得られる情報は見てみると分かると思いますが、MIDIフォーマット、トラックナンバー、分解率、トラックの長さだけです。これだけの情報じゃぁ味気ないですよね。そこでこの後ろについてくるやつから情報を得ます。
じゃあ、どんな感じに記録されているのか?ってのを書きますね。
(正確な名前を知らないんでここではID3v2と同様にフレームと呼びます。知ってる方は教えてくださいm(_
_)m)
フレームヘッダー |
内容 |
FF 01 nn |
テキスト |
FF 02 nn |
著作権関連 |
FF 03 nn |
トラック名 |
nnってのは内容の長さです。あと、もちろんフレームヘッダーは16進数表記ですよ。メモ帳なんかで開いて、そんなもんネーぞコラー!!なんて言わないで下さいね(笑)
FF が始まりの印みたいな物で、次にある01、02、03ってのが識別用のやつです。04や05等他の数にもそれぞれ意味があるようですが、私は知りません。知ってる方教えて〜
これは可変長ですからヘッダーのときみたいにユーザー定義型作ってポンッとは行きません。まぁnnっていう内容の長さを記録してくれてるやつがありますから、それにしたがって読み込んでいけばOKです。ここで注意しなくてはならないのが、nnはフレームヘッダーの長さを含んでいません。だから次のフレームを読みに行くときにはフレームヘッダーの長さの+3ってのが有るってことを忘れないで下さいね。
それじゃーお約束のコードを(笑)
(それにしても俺の説明って短い&分かりにくなぁ。だからソース乗っけてるんだけどねぇ。分かりやすい文書く練習しなきゃ・・・)
'MIDIのヘッダー
Private Type tagMIDIHeader
MThd As String *4
HeaderLength(3) As Byte
MIDIFormat(1) As Byte
TrackCount(1) As Byte
TCount(1) As Byte
MTrk As String *4
TrackLength(4) As Byte
End Type
'MIDIの情報を得る
Private Function GetMIDIInfo(FileName As String) As String
Dim MIDIHeader As tagMIDIHeader
Dim Title As String
Dim Copyright As String
Dim Text As String
Dim DateType(2) As Byte
Dim StrtPos As Integer ´フレームの始まりの場所
Dim FN As Long
On Error Resume Next
FN = FreeFile
Open FileName For Binary As FN
'ファイルが異常
If LOF(FN) <= 20 Then
GetMIDIInfo = ""
Close
Exit Function
End If
Get FN, , MIDIHeader
'MIDIではないとき
If MIDIHeader.MThd = "MThd" Then
GetMIDIInfo = ""
Close
Exit Function
End If
'23バイトがヘッダーでその直後からフレームが始まるので
Get FN, 24, DateType
StrtPos = 24
'フレームヘッダーがある限りループ
Do While DateType(0) = &HFF
Select Case DateType(1)
Case &H1
If Text = "" Then
Text = Space$(DateType(2))
Get FN, StrtPos + 3, Text
'↑この+3はフレームヘッダーの分
End If
Case &H2
If Copyright = "" Then
Copyright = Space$(DateType(2))
Get FN, StrtPos + 3, Copyright
End If
Case &H3
If Title = "" Then
Title = Space$(DateType(2))
Get FN, StrtPos + 3, Title
End If
End Select
StrtPos = StrtPos + DateType(2) + 4
'↑この+4はフレームヘッダーの分の3と、次の始まりの位置は
'今のデーターの長さ+位置+1なので
Get FN, StrtPos, DateType
Loop
Close
GetMIDIInfo = "タイトル :" & Title & vbCrLf
& _
"著作権 :" & Copyright & vbCrLf & _
"その他 :" & Text & vbCrLf & _
"フォーマット :" & CStr(MIDIHeader.FileFormat(0) * &HFF + _
MIDIHeader.FileFormat(1)) & vbCrLf & _
"トラック数 :" & CStr(MIDIHeader.TrackCount(0) * &HFF + _
MIDIHeader.TrackCount(1)) & vbCrLf & _
"分解率 :" & CStr(MIDIHeader.TCount(0) * &HFF + _
MIDIHeader.TCount(1)) & vbCrLf
'トラックの長さも取得できてるはずなんだけど、どうもイマイチ自分の計算じゃ
'合ってない気がする。
'どんな風に記録されているか知っている方がいたら、教えてくれると嬉しいです。
End Function |
|