TOP > カテゴリ > フォーマット変換 >

MIDIファイルを作成する(Visual Basic)

楽器、音符を指定してテキストボックスに「ドレミファソラシド」を入力するとMIDIファイルを作成する事ができるサンプルプログラムです。Visual Basic版のサンプルは簡易版ですがMIDIファイルフォーマットの勉強として少しは参考になるかと思います。

サンプルの画面

サンプルプログラムの実行画面です。

[form1.frm]

'リハビリプロジェクト NO.1 「ミニミニMIDIコンパイラ - VB版」

Option Explicit

Dim DataCode(10000) As Byte '演奏データ とりあえず10kまで
Dim CodeCount As Integer

                      
Private Sub AllClear_Click()
 
 '初期化
  Call ZeroMemory(DataCode(0), 10000)
  CodeCount = 0
  Text1.Text = ""
  Combo1.ListIndex = 0
  
End Sub


Private Sub Command2_Click(Index As Integer)
    
  '文字列書きこみ
  Text1.Text = Text1.Text + Command2(Index).Caption
      
  '演奏データの取得
  '(音階については「ノートナンバー 一覧表」を参照)
  Select Case Index
    Case 0
         DataCode(CodeCount) = &H3C 'ド
    Case 1
         DataCode(CodeCount) = &H3E 'レ
    Case 2
         DataCode(CodeCount) = &H40 'ミ
    Case 3
         DataCode(CodeCount) = &H41 'ファ
    Case 4
         DataCode(CodeCount) = &H43 'ソ
    Case 5
         DataCode(CodeCount) = &H45 'ラ
    Case 6
         DataCode(CodeCount) = &H47 'シ
    Case 7
         DataCode(CodeCount) = &H48 'ド↑
  End Select

  'インクリメント
  CodeCount = CodeCount + 1
  
End Sub


Private Sub CreateMidi_Click()

Dim hFile As Long
Dim FileSize, work As Long
Dim i, j As Long

Dim Instrument  As Integer '楽器
Dim Versity As Byte        'べロシティ(音の強さ)
Dim NoteNumber As Byte     'ノートナンバー(音階)
Dim SetTemp As Byte        'テンポ

Dim MIDIData() As Byte     'MIDIデータ

Dim SMFTRACKCHUNCK As TSMFTRACKCHUNCK
Dim SMFHEDAER      As TSMFHEDAER


'ゼロクリア
Call ZeroMemory(SMFTRACKCHUNCK, Len(SMFTRACKCHUNCK))
Call ZeroMemory(SMFHEDAER, Len(SMFHEDAER))

'ファイル作成
hFile = CreateFile(Text2.Text, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL Or FILE_FLAG_WRITE_THROUGH, 0)

If hFile > 0 Then

     'テンポの設定
     
        '0.125秒(16分音符)
        If Option1(0).Value Then
         SetTemp = &H4
        
        '0.25秒(8分音符)
        ElseIf Option1(1).Value Then
         SetTemp = &H8
        
        '0.5秒(4分音符)
        ElseIf Option1(2).Value Then
         SetTemp = &H10
        
        '1秒(2分音符)
        ElseIf Option1(3).Value Then
         SetTemp = &H20
        Else
        '2秒(全音符)
         SetTemp = &H40
        End If
        
      '楽器の選択(0-127)
         
         '0は   AcousticGrandPiano
         '127は Gunshot
          Instrument = &HC0 Or (Combo1.ListIndex * &H100)
                      
      '音の強さ(0-127)
          
          Versity = 127
                      
      'SMFヘッダーの準備
          
          SMFHEDAER.ChunckType = &H6468544D         'SMFのID
          SMFHEDAER.DataLength = IntelOder_DWord(6) 'データの長さ
          SMFHEDAER.Format = IntelOder_Word(1)      'フォーマット
          SMFHEDAER.TrackCount = IntelOder_Word(1)  'トラック数
          SMFHEDAER.TimeType = &H1000               '時間単位
                                      
      'SMFチャンク準備
          
          SMFTRACKCHUNCK.ChunckType = &H6B72544D    'SMFトラックチャンクのID
          SMFTRACKCHUNCK.DataLength = 0             'これ以後のデータの長さ
                     
      '構造体の書きこみ
          
          Call WriteFile(hFile, SMFHEDAER, 14, work, 0)
          Call WriteFile(hFile, SMFTRACKCHUNCK, 8, work, 0)
      
      '楽器の書き込み
          
          Call WriteFile(hFile, xZero, 1, work, 0)
          Call WriteFile(hFile, Instrument, 2, work, 0)
          Call WriteFile(hFile, xZero, 1, work, 0)


      '主要データの書きこみ
      
         ReDim MIDIData(CodeCount * 8)
         Call ZeroMemory(MIDIData(0), CodeCount * 8)
         j = 0

         '音声データの書きこみ
         For i = 0 To CodeCount - 1 Step 1
              NoteNumber = DataCode(i)
                            
              'ノートオンメッセージの書き込み
              MIDIData(j) = xNoteOn
               j = j + 1
              MIDIData(j) = NoteNumber
               j = j + 1
              MIDIData(j) = Versity
               j = j + 1
              MIDIData(j) = SetTemp
               j = j + 1
                    
             'ノートオフメッセージの書き込み
              MIDIData(j) = xNoteOff
               j = j + 1
              MIDIData(j) = NoteNumber
               j = j + 1
              MIDIData(j) = Versity
               j = j + 1
                        
             '最後でなかったら
              If (i <> CodeCount) Then
                 MIDIData(j) = xZero
                 j = j + 1
              Else
                 MIDIData(j) = SetTemp
                 j = j + 1
              End If
         Next i
         
         Call WriteFile(hFile, MIDIData(0), j, work, 0)
           
      
       '終了サインを書きこむ
       
        Call WriteFile(hFile, xMax, 1, work, 0)
        Call WriteFile(hFile, xEnd, 2, work, 0)

       'データサイズの書きこみ
       
        FileSize = GetFileSize(hFile, 0) - 22
        Call SetFilePointer(hFile, 18, 0, FILE_BEGIN)
        Call WriteFile(hFile, IntelOder_DWord(FileSize), 4, work, 0)
        
        CloseHandle (hFile)
Else
 Call MessageBox(Form1.hwnd, "ファイルが作成出来ません。", "エラー", MB_ICONSTOP)
 
End If
End Sub

Private Sub Form_Load()

Dim Buffer As String


   'テキストボックスを編集できないようにする。
   Call SendMessage(Text1.hwnd, EM_SETREADONLY, -1, 0)
   Call SendMessage(Text2.hwnd, EM_SETREADONLY, -1, 0)
   
   CodeCount = 0
   Combo1.ListIndex = 0
   
   
   'バッファを確保
   Buffer = String(MAX_PATH, Chr(0))

   '保存先パスを決定
   Call GetCurrentDirectory(MAX_PATH, Buffer)
   Text2.Text = Buffer
   Text2.Text = Text2.Text + "\test.mid"
   

End Sub

サンプルプログラム一式のダウンロード

create_midi_vb.zip 24.7 KB (25,319 バイト)

注意事項

このサンプルは約15年前に作成した「いにしえ」の産物です。予めご了承下さい。





関連記事



公開日:2015年02月19日
記事NO:00245