MIDIファイルの作り方

タグの編集
投稿者 G  (社会人) 投稿日時 2010/6/4 12:28:36
初心者なのですがピアノのプログラムをつくってみたのですけど…

MIDIで音の出し方は分かったのですが、それをファイルにする方法が全く検討がつかづ、検索してみたのですが、方法は書いてあるのですけど、具体的にどう描けばいいのか分からず困っています


ドレとか2音ぐらいなるファイルを生成できるテストプログラムとかあればいいのですけど
ちなみにVB2008を使っています



投稿者 名前はまだない  (社会人) 投稿日時 2010/6/4 14:15:09
>MIDIで音の出し方は分かったのですが、それをファイルにする方法が全く検討がつかづ、検索してみ>たのですが、方法は書いてあるのですけど、具体的にどう描けばいいのか分からず困っています
コードは書けたのですか?
ご質問は、つくったコードを○○.exeのファイルにするにはどうしたらよいか?
ということでしょうか
投稿者 daive  (社会人) 投稿日時 2010/6/4 14:20:38
検索の仕方だけ、
Google へ行き
まず、
MIDI
で、検索
絞り込は、
半角スペース入力、関連ワード追加
MIDI フォーマット
排除ワードは、 半角スペース入力、- 排除ワード
MIDI フォーマット -サイト
投稿者 nunun  (小学生) 投稿日時 2010/6/4 16:09:05
http://hpcgi1.nifty.com/MADIA/vbnet/wwwlng.cgi?print+201006/10060001.txt
投稿者 (削除されました)  () 投稿日時 2010/6/4 22:03:45
(削除されました)
投稿者 るきお  (社会人) 投稿日時 2010/6/4 22:23:43
簡単なサンプルを作ってみました。
VBのバージョンが書かれていませんでしたがVB2010でよろしかったでしょうか?

長いので分割して投稿します。


Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles Button1.Click

        Dim midi As New MIDIFile
        Dim track As MIDITrack = midi.NewTrack

        '長さをいじるとエラーになることが多いです 
        track.AddNote(Notes.Cs, 3, 120)
        track.AddNote(Notes.E, 3, 120)
        track.AddNote(Notes.A, 3, 120)

        track.AddNote(Notes.Cs, 4, 120)
        track.AddNote(Notes.E, 4, 120)
        track.AddNote(Notes.Fs, 4, 120)

        track.AddNote(Notes.Gs, 4, 120)
        track.AddNote(Notes.Ds, 4, 120)
        track.AddNote(Notes.B, 3, 120)

        track.AddNote(Notes.Gs, 3, 120)
        track.AddNote(Notes.Ds, 3, 120)
        track.AddNote(Notes.B, 2, 120)

        midi.Save("C:\test\test.mid")

    End Sub
End Class

Public Class MIDIFile

    Private ChunkType As New List(Of ByteFrom {&H4D, &H54, &H68, &H64}
    Private DataLength As New List(Of ByteFrom {0, 0, 0, &H6}
    Private FormatType As New List(Of ByteFrom {0, 1}

    ''' <summary> 
    ''' トラック数。テンポトラック合わせて2固定にしています。 
    ''' </summary> 
    Private TrackCount As New List(Of ByteFrom {0, 2}

    ''' <summary>音符の分解能。</summary> 
    Private TimeUnit As New List(Of ByteFrom {1, &H30}

    Public Tracks As New List(Of MIDITrack)

    Public Sub New()
        'まずテンポトラックを無条件に追加。 
        Tracks.Add(New ConductorTrack)
    End Sub

    ''' <summary> 
    ''' 新しいトラックを追加します。 
    ''' 今のところ、トラック数は2固定にしており、1つ目はテンポトラックなので 
    ''' 楽曲用トラックは1つしか作れません。 
    ''' TrackCountを{0, 3}にすればもう1ついけます。 
    ''' 自動的にTrackCountが変わるようにできればベストです。 
    ''' </summary> 
    ''' <returns></returns> 
    ''' <remarks></remarks> 
    Public Function NewTrack() As MIDITrack
        Dim track As New MIDITrack
        Tracks.Add(track)
        Return track
    End Function

    ''' <summary> 
    ''' MIDIファイルを作成します。 
    ''' </summary> 
    Public Sub Save(ByVal fileName As String)

        Dim buffer() As Byte = Me.ToArray
        IO.File.WriteAllBytes(fileName, Buffer)

    End Sub

    ''' <summary> 
    ''' 全データをMIDI形式のバイト型の配列にします。 
    ''' </summary> 
    ''' <returns></returns> 
    ''' <remarks></remarks> 
    Private Function ToArray() As Byte()

        Dim all As New List(Of Byte)
        all.AddRange(ChunkType)
        all.AddRange(DataLength)
        all.AddRange(FormatType)
        all.AddRange(TrackCount)
        all.AddRange(TimeUnit)

        For Each track As MIDITrack In Tracks
            all.AddRange(track.ToList)
        Next
        Return all.ToArray

    End Function


End Class
投稿者 るきお  (社会人) 投稿日時 2010/6/4 22:24:12
続きです。


Public Class MIDITrack

    Protected ChunkType As New List(Of ByteFrom {&H4D, &H54, &H72, &H6B}
    Protected DataLength As New List(Of ByteFrom {0, 0, 0, 0}
    Protected Data As List(Of Byte)
    Protected Footer As New List(Of ByteFrom {0, &HFF, &H2F, 0}

    Public Notes As New List(Of MidiEvent)

    ''' <summary> 
    ''' 音符を追加します。音符は楽譜の先頭から追加していきます。 
    ''' </summary> 
    ''' <param name="note">音階</param> 
    ''' <param name="octave">オクターブ。中央のオクターブは3です。</param> 
    ''' <param name="tick">発音時間。</param> 
    ''' <remarks></remarks> 
    Public Sub AddNote(ByVal note As Notes, ByVal octave As IntegerByVal tick As Integer)
        Dim thisNote As New MidiEvent(note, octave, tick)
        Notes.Add(thisNote)
    End Sub

    ''' <summary> 
    ''' 音符情報をMIDI形式に変換してDataプロパティに格納します。 
    ''' </summary> 
    Protected Overridable Sub GenerateData()

        Const NoteOn As Byte = &H7F
        Const NoteOff As Byte = &H0
        Data = New List(Of Byte)

        For Each note As MidiEvent In Notes
            Data.Add(&H0)   'まずは 0秒後に 
            Data.Add(&H90)  'チャンネル1で 

            Data.Add(note.Note + ((note.Octave - 3) * 12))  'この音階を 
            Data.Add(NoteOn)    'ならし 

            Data.Add(note.Tick) 'Tick時間後に 

            Data.Add(note.Note + ((note.Octave - 3) * 12))  'この音階を 
            Data.Add(NoteOff)   '停止する 
        Next

    End Sub

    ''' <summary> 
    ''' フッター4バイトを含むデータ部の長さを4バイトの領域に記録する。 
    ''' </summary> 
    Private Sub CalculateLength()

        'もっと簡単な方法があると思うが眠たい…。 
        '非効率だがこれでも機能的にはOKなはず。 
        Dim length As Integer = Data.Count + 4

        DataLength(3) = length Mod 256
        length = length >> 8
        DataLength(2) = length Mod 256

        length = length >> 8
        DataLength(1) = length Mod 256

        length = length >> 8
        DataLength(0) = length
    End Sub

    ''' <summary> 
    ''' このトラックが表すすべてのデータをバイト型の配列で表現する。 
    ''' </summary> 
    Public Overridable Function ToList() As List(Of Byte)

        GenerateData()
        calculatelength()

        Dim all As New List(Of Byte)
        all.AddRange(ChunkType)
        all.AddRange(DataLength)
        all.AddRange(Data)
        all.AddRange(Footer)

        Return all
    End Function

End Class

''' <summary> 
''' テンポ調整用トラック。固定で120にしています。 
''' プロパティで可変にするのがよく、さらに任意のタイミングでテンポを切り替えられるようにするとベストです。 
''' </summary> 
Public Class ConductorTrack
    Inherits MIDITrack

    Protected Overrides Sub GenerateData()
        Data = New List(Of ByteFrom {0, &HFF, &H51, 3, 7, &HA1, &H20}
    End Sub
End Class

''' <summary>音符を表します。</summary> 
Public Class MidiEvent
    ''' <summary>音階</summary> 
    Public Note As Notes
    ''' <summary>オクターブ</summary> 
    Public Octave As Integer
    ''' <summary>発音時間(長さ)</summary> 
    Public Tick As Integer

    ''' <summary> 
    ''' 音符を作ります。 
    ''' </summary> 
    ''' <param name="note">音階</param> 
    ''' <param name="octave">オクターブ。中央のオクターブは3です。</param> 
    ''' <param name="tick">発音時間。</param> 
    ''' <remarks></remarks> 
    Public Sub New(ByVal note As Notes, ByVal octave As IntegerByVal tick As Integer)
        Me.Note = note
        Me.Octave = octave
        Me.Tick = tick
    End Sub
End Class

''' <summary>音階を表します。</summary> 
Public Enum Notes As Byte
    ''' <summary>ド</summary> 
    C = &H3C
    ''' <summary>ド#</summary> 
    Cs = &H3D
    ''' <summary>レ</summary> 
    D = &H3E
    ''' <summary>レ#</summary> 
    Ds = &H3F
    ''' <summary>ミ</summary> 
    E = &H40
    ''' <summary>ファ</summary> 
    F = &H41
    ''' <summary>ファ#</summary> 
    Fs = &H42
    ''' <summary>ソ</summary> 
    G = &H43
    ''' <summary>ソ#</summary> 
    Gs = &H44
    ''' <summary>ラ</summary> 
    A = &H45
    ''' <summary>ラ#</summary> 
    [As] = &H46
    ''' <summary>シ</summary> 
    B = &H47
End Enum
投稿者 るきお  (社会人) 投稿日時 2010/6/4 22:30:40
すいません。VBのバージョン書いてありましたね。
2008でしたか…。2008だと一部動かないところがありますがちょっと力尽きましました…。
これを機会に2010にされるのはいかがでしょうか?
http://homepage1.nifty.com/rucio/main/material/VB2010Install.htm

MIDIについては2008にせよ、2010にせよVBにはMIDIを演奏したり、MIDIファイルを作成する機能はありません。
ただし、この場合「機能がない」=「無理」ではなく、すべてのファイルはバイナリ型の配列で表現できることを考えれば、MIDIファイルの仕様さえわかっていれば自分でMIDIファイルの仕様通りのプログラムを書くことでMIDIファイルを生成することができます。

ただ、MIDIファイルの仕様は音楽の知識がないと多少難しく、コンピューターの知識も必要です。またちょっと検索した限りでは仕様書が見つかりませんでした。
今回のサンプルはこのサイトの記述を全面的に参考にしました。
http://www2s.biglobe.ne.jp/~yyagi/material/smfspec.html#tempo

MIDIの仕様を調べ、その通りに自分でプログラムすることになるので難易度としては中級以上です。
でも、面白いネタなんでがんばって少しずつ機能をつけたしていけばしばらくは退屈しないかもしれませんね。
投稿者 G  (社会人) 投稿日時 2010/6/4 23:41:07
>名前はまだない さん

コードはかけていますしビルドの方法もわかってます
タイトルにあるように
MIDI音源をファイルにすることを目標としてるのですが、
MIDIファイルを検索すると構造とかどうなっているかはかかれているのですけど
具体的にどうかけばいいのかが分からなくなっておりました

>daive さん

検索はかけたのですけど、恐らく理解してる人ならばその説明を見れば分かるのでしょうが
いまいちどう書いて良いのかが分からなくなってしまいました
サンプルプログラムを触って構造を調べてやろうとおもったのですけど、いくら検索してもVBでのソースが見つからず
文字で書かれていてもぜんぜん分からなくて
最終的に此処に書き込んだのです^^;

 >nunun さん

リンクを見たのですが
どうも再生方法を指してるように見えます
私の理解が及んでないだけかもしれませんが^^;


>るきお さん


そうですこれです!
こんな感じに書かれてるのですが、断片的だったりでどこをどう直せば動くのかも分からずだったのです
でも2010なんすね^^;
じつは少し2008の本を買ってしまって

しかもキーボードピアノに変えるソースとか
音を押した長さで調整するとことか、自作のスコアに音をテキストに変換して録音するところとか
タイマーを使わない自動演奏機能とかも作っちゃったんで
さすがに作り直しはちょっと無理っぽいです^^;
休みの日にちょこちょこつくってたんで

バージョンが変わるとちょっと困ってしまいます 
微妙にわからないw

分かる範囲で自分でコード直してみます。

また分からなくなったら質問にきます^^;

こないよう努力はしたいですけど

投稿者 るきお  (社会人) 投稿日時 2010/6/4 23:56:19
こんにちは。

2008でできることはすべて2010でもできますし、
2008の本の説明は2010でも同じくらい参考になります。
それに2008で作ったプログラムは2010でも動くのでGさんが2008で作ったプログラムは無駄になりません。多分、1文字の変更もしないで2010で動くと思いますよ。

なので、VB中学校の主催者の私としてはぜひ2010に移行してほしいなぁと思います。

>テキストに変換して録音するところとか
wavファイルができるんですか?
それはすごいですね。どうプログラムしたのですか?
投稿者 G  (社会人) 投稿日時 2010/6/5 00:17:01
いえいえ、ちがいますよw

音楽データを文字に変換してそのデータを音として呼び起こせるようにしたんですよ
私の知識と発想ではそのぐらいが限界でした^^;

キーボードをたたくとそれに対応した音がなると同時にテキストデータとして変換されて
ノートオンとノートオフと何も押されてない時間を正確に記録して擬似的に録音されてる感じにしたんです

そのデータを再生してる状態で音を変えて演奏して同時録音できるようにできないかなとおもってかんがえたんです
いわゆる、一人で全パート演奏機能ですw

実際はたいした機能ではないですよ^^;

2010ですが、いまダウンロードしてみていますw
使えるだろうか^^;
投稿者 YuO  (社会人) 投稿日時 2010/6/5 01:48:48
蛇足ですが……

他のシーケンサ (Windows Media Player, TMIDI, etc.) で再生する必要があるのであれば,SMF対応は必須ですが,
あくまで,「MIDIに関するデータをファイルに保存したい」という点だけで考えた場合,SMFにこだわる必要はありません。
# というか,大抵のシーケンサは独自のファイル形式を持っています。

例えば,SMF上ではFisとGesの違いは保持できませんが,内部的には別のデータとすることができますし,
独自のファイル形式であればそれを区別することもできます。

独自のファイル形式では,必要なものや後々のこともちゃんと考えて作らないと後悔するのは確かですが,
バージョンを気にしないならデータ部分のクラスに<Serializable>をつけて,データクラスをシリアライズしてしまうのが手っ取り早いです。


> 音楽データを文字に変換してそのデータを音として呼び起こせるようにしたんですよ

MML (Music Macro Language) ?

e.g. エリーゼのために 冒頭 (右手)
O5
E16D+ ED+E<B>DC <A8R16CEA B8R16EG+B >C8R16<E>ED+
ED+E<B>DC <A8R16CEA B8R16E>C<B A4E16D+
ED+E<B>DC <A8R16CEA B8R16EG+B >C8R16<E>ED+
ED+E<B>DC <A8R16CEA B8R16E>C<B A8R16B>CD
E8.<G16>FE D8.<F16>ED C8.<E16>DC <B8R16E>ER RE>ERR<D+ ERRD+ED+
ED+E<B>DC <A8R16CEA B8R16EG+B >C8R16<E>ED+
ED+E<B>DC <A8R16CEA B8R16E>C<B A8R16

<がオクターブを上げ,>が下げる処理系用です。

昔はN88Basicなどで使え,Rayのような高性能再生ソフトがあったのでそれなりに知名度があったのですが,最近はMMLなんて知らない人も多いと思います。
MMLの再生ソフトで国内で最大のコンテンツはニコニコ大百科かなぁ……。
ピコカキコ (コメントへの音楽の埋め込み) に使われるのがMMLだったりします。
http://coderepos.org/share/wiki/FlMML/Reference
# ときたまTwitterにMMLっぽい文字列をツィートする人を見かけますが……。
投稿者 Yasty  (社会人) 投稿日時 2010/6/5 17:44:43
> 音楽データを文字に変換してそのデータを音として呼び起こせるようにしたんですよ

よそからD.LoadしたMIDIファイルを文字情報に戻して改変するとしたら、
著作権侵害になるような気がしますけど.....?
投稿者 るきお  (社会人) 投稿日時 2010/6/5 18:20:49
いや、改変したものを配布・上演等しなければ問題なかったと思いますよ。

まぁよそからDLというのは仮定の話なので、今回のGさんはどちらにせよOKですね。。
投稿者 G  (社会人) 投稿日時 2010/6/5 22:08:52
YuO さん

今回はメディアプレイヤーで再生できるものにしようとおもってたので変換を考えたわけで
それをやめてしまうとピアノのように演奏できる~の意味がなくなってしまいます^^;


Yasty さん

なんで著作権侵害の話にw

上に書いてある通り私の作ってるピアノさんは
キーボードをたたくと音が鳴り離すと音が止まる仕組みでつくられてるんですよ
ピアノの演奏がキーボードで出来るプログラムということで

録音ボタンは自分がキーボードで演奏した曲をそのままテキストとして保存してるだけなんで配布は可能ですけど、MIDファイルから録音するわけではないので著作権にはあたらないとおもいます

よそからダウンロードしたMIDというか
MIDファイルからはテキストに変換できないようになってます
独自の保存形式がただテキストなだけですよw

それにそれを言うなら全ての音源変換ソフトは著作権侵害にあたってしまいますよ^^;

著作権のある音楽を違法と分かりつつダウンロードあるいはアップロードなどをした場合著作権法に引っかかるはずですね

 るきおさん
フォロー有難うございます^^

2010にしてもそんなに使い勝手かわりませんねw
2008のコードも今のところ全て有効になってます

いただいたコードいじりながら勉強してるところです

がんばって自分なりのコードにしていこうとおもいます

皆様ありがとうございました!

分からなくなったらまたきます。


投稿者 G  (社会人) 投稿日時 2010/6/5 22:59:24
じっとながめてましたが、2008で使用されてるコードとかは分かるんですが
New List(Of Byte)

とかそのなかに入ってある数字の目的が分からず挫折しそうww

   Dim length As Integer = Data.Count + 4

        DataLength(3) = length Mod 256
        length = length >> 8
        DataLength(2) = length Mod 256

        length = length >> 8
        DataLength(1) = length Mod 256

        length = length >> 8
        DataLength(0) = lengthとかもよくわからない^^;

勉強不足ですね


とりあえず音をどうしてコントロールしてるかは大体分かりましたので今回はファイルの生成のほうについてはこのコードを転用させてもらいます。

理解にはまだまだ時間がかかりそうなので


一つ聞きたいのですがこのMIDは音量を固定してるのですよね?
どこで音量を制御してるのかを教えていただくとたすかります。
投稿者 G  (社会人) 投稿日時 2010/6/5 23:37:13
連続投稿すいません

大変な事態が起こりました…

VB2010で作ってたデータを開いたらMIDIの音が出なくなりました^^;

で元のバージョンで開こうとしたら
開けませんとか^^;


つ、作り直しっすか^^;
投稿者 あにす  (社会人) 投稿日時 2010/6/6 03:06:06
質問の内容とは関係ないのですが、Gさんにはバージョン管理システムの利用をお勧めします。
過去にコードを編集した内容を記録し、必要に応じて比較したり、過去の状態に戻したり出来るものです。
コードが動かなくなった場合も、どの変更が原因なのかを調査するのに大きな助けになります。
投稿者 るきお  (社会人) 投稿日時 2010/6/6 09:59:08
(すごく長く文章を書いてしまいました…)

>VB2010で作ってたデータを開いたらMIDIの音が出なくなりました^^;
他のmidiファイルの音は出ますか?
また、私が投稿した状態のプログラムでは音は出ますか?

私が紹介したのは即席で手作りのプログラムなので、想定外の使用をするとmidiの規格からはずれて演奏できないファイルが生成できる可能性があります。
たとえば、
track.AddNote(Notes.Cs, 3, 120)


track.AddNote(Notes.Cs, 3, 240)

にするともうダメです。
(これの何がダメなのか私にはわかりません。分解能との関係かもしれません。分解能は Private TimeUnit As New List(Of Byte) From {1, &H30}の行の&H30を&H80や&HE0などにするとより高機能になるはずです。)


VB2008とVB2010の問題ではなくMIDI(SMF)規格の問題と思います。

このことや、「数字の目的が分からず挫折しそう」、「どこで音量を制御してるのか」などの質問の趣旨から考えると、VBの知識ではなくMIDI(SMF)の知識が必要と思います。

DataLengthにはSMFの仕様では、データチャンクのヘッダー部に4バイトでフッター部を含むデータの長さをセットすることになっています。
フッター部は4バイト固定です。私のプログラムではデータの長さはData.Countで取得できます。
ですので、Dim length As Integer = Data.Count + 4として、データの長さをLengthにセットしてこれを4バイトの場所に書きだす処理が引用された個所です。

音量の制御方法についてもMIDIの規格ではどこにどのように音量を指定することになっているかをまず調べる必要があります。そのあとでそれをVBでやるにはどうしたらいいかを考えます。
今、MIDI規格での音量の指定方法も判らない状態ではVBでもどうしたらいいかわかりません。

料理に例えるとMIDI規格がクラムチャウダーで、VBが包丁と鍋(料理器具)です。料理器具の知識だけではクラムチャウダーは作れません。まずはクラムチャウダーの作り方を知るか、レシピを入手した後で、では料理器具をどう使えばいいかを考えます。

そして、MIDIの規格は何を見ればわかるのかというと、どこかで仕様書が公開されていると思うのですが、私が英語が苦手なこともあって見つけられていません。

さいわい仕様書そのものではありませんが、サンプル付きで丁寧に解説してくれている日本語のサイトがありましたので私はこのサイトの記述をVB化しました。
http://www2s.biglobe.ne.jp/~yyagi/material/smfspec.html#tempo
検索すれば他にも参考になる資料や仕様書そのものを発見できるかもしれません。
そのために提案されているのがdaiveさんで、daiveさんは「MIDI フォーマット -サイト」で検索することを勧められています。

前にも書きましたが、MIDIの規格を調べながらVBで記述するのはVB中級以上のレベルがいると思います。Gさんは初心者ということですのでかなりハードルが高いです。でも、楽しみながらチャレンジできるネタなので良さそうだなと思っています。

そこで、私が思うにGさんのとるべきスタンスとして2つあると思います。
スタンス1.私が作ったサンプルでできることで満足する。(私以外にもWebで検索すればサンプルを公開している人がいるかもしれません。)
スタンス2.MIDIの規格を調べながら私のサンプルを元に修正・機能追加を行い、Gさんのプログラムを作り上げる。

daiveさんの検索提案に対するGさんの感想としては、
>恐らく理解してる人ならばその説明を見れば分かるのでしょうが
というものでした。私としてはこの感想は共感でき、うなづけるものはあります。(とても難しいから!)
だとするとスタンス1しかありません。

このくらいのジャンルになるとMIDI規格をちゃんと知っていてそれをVB化できて、それを教えてくれる人というのはまずいないと思ってください。MIDI規格をちゃんと知っている人なら多少いると思います。規格さえ理解していればVB化できる人もそこそこいるとは思います。この両方を満たす人はまずいないと思います。
これが日本人の層の薄さで、私はちょっと残念な気はしています。

だから、スタンス2でいくなら、最低でもGさん自身がMIDI規格をちゃんと知ってからVBの質問をするか、VB中級以上になってからMIDIの質問をするかというのが最低ラインになるかなと思います。
投稿者 G  (社会人) 投稿日時 2010/6/6 12:10:06
あにす さん

どんな方法がw

コードを2008にもう一度コピーしなおして
フォームもやりなおしてしまいましたw

今度利用してみようと思いますw

るきおさん

MIDファイルではなく2008で実現できたキーボードをたたくと音が出るというシステムが死んでしまいましたw
 Declare Auto Function midiOutShortMsg Lib "winmm.dll" (ByVal hMidiOut As Int32, ByVal dwMsg As UInt32) As UInt32
    Declare Auto Function midiOutGetNumDevs Lib "winmm.dll" () As Int32
    Declare Auto Function midiOutOpen Lib "winmm.dll" (ByRef hmo As UInt32, ByVal iDeviceIO As Int32, ByVal dwCallback As Int32, ByVal dwCallbackInstance As Int32, ByVal dwFlags As Int32) As UInt32
    Declare Auto Function midiOutReset Lib "winmm.dll" (ByVal hMidiOut As Int32) As Int32
    Declare Auto Function midiOutClose Lib "winmm.dll" (ByVal hMidiOut As UInt32) As Int32

中略

  Private Sub midi_play(ByVal M1 As Integer, ByVal M2 As Integer, ByVal M3 As Integer, ByVal M4 As Integer)
        'M1音質   M2音階 M3オクターブ M4音量
 Dim ret As UInt32
        Dim dwMsg As UInt32
        Try
            midiOutShortMsg(hMidiOut, &HC0 + M1 * 256)
        Catch
              End Try
        Try
            dwMsg = &H3C90 + ((M2 + 12 * M3) * 256) + (M4 * 256 * 256)
            ret = midiOutShortMsg(hMidiOut, dwMsg)
        Catch
                   End Try
    End Sub '音を出す
かなり省きましたが問題は多分この辺だとおもいますが

エラーも出ずよく分からない状況です

オクターブは3を0としてありますのでこういう計算になってます



多分2010との仕様のちがいかなっておもいました


るさおさんのプログラムで作ったファイルは音が出ます


あの後いろいろ考えて

どれが音量でって言うのはわかりましたw

音量が172で維持されてたのでちょっと考えれば分かることでした^^;
すいません


数字の目的が分からなければ10進数にもどして自分のプログラムと照らし合わせれば良いだけの話でしたw

わからなかったところもなんとなくですがわかりました
いじれるほどというわけではないですけど


というわけで二つのバージョンを利用してみようかなとおもいました

2008から2010になるとなぜ出来なくなるのかは正直わかりません
恐らく技術とMIDの構造を完璧に理解してないからどこが悪いのかの判定ができないんだとおもいます

今回は完成させる事を重視して
今までのピアノプログラミングを改造してテキストを一定の場所に保存する機能を作り
2010でいただいたデータを元にテキストを解析してファイル化する能力をつけて
それを2008のピアノから直接起動させる方法を取ってみようかとおもいます
バージョンの違う二つのプログラムをつかって大変醜い状態ですがw


これならいま実現可能だとおもいます。

自分はどっちかというと分からないものでもとりあえず人に習って作ってそれをいじりながら覚えていくタイプだと思うのでとても助かりました
サンプルは私もかなり探したと思うのですが
VBでMIDのファイルを作ってるデータを公開してます
なんてサイトはほとんどなく
ほとんどは現存するMIDのデータを解析して音を鳴らすというものでした

それなら参照からDirectX.AudioVideoPlayback
とかを使えば簡単に再生できてしまうしとおもってしまったので^^;

とりあえずレベルが足りないから無理だといって諦めるのは嫌なんで
基本は完成させてみます

本とかのガイドなしに作るのはこれが実は初めてで
実力的に正直選択ミスだなとは思いましたw

こんなに難しいとはおもわなかった^^;