HSPでMIDI扱えるサンプル作ってたりする
HSPでMIDI扱えるサンプル作ってたりする
昨日の夜作成始めたんですけど、まだ完成していません…。
とりあえずMIDIのフォーマットは検索して調べました。
MIDIにかぎらずよくあるファイル (? WAVEとか) は次のようにすれば行けそうです。
最初4バイトを取り出す
→これからチャンクタイプを調べる
→次の4バイトを数値として取っておく
→その次の部分からさっきの数値byte分とっておく
次の4バイトを取り出す
→これからチャンクタイプを… (繰り返し)
必ずチャンクタイプ・データ長で8バイトなので、調べるところのインデックスが「全体のサイズー8バイト」より大きくなったら解析終了、みたいな。
existでファイルサイズで変数初期化してそこに読み込んで
repeat loop でlpeekして調べて超えたらbreakして
それ終わったらそれぞれのデータを…。
という感じ。
ただし、WAVEデータ (のように、メモリに数字ぶち込んだみたいなデータ、逆ワード式) と違って、データ長のデータが、ワード式で入ってやがるのでlpeekするととんでもない数値が出てしまいます。
これ用にモジュール作ったので記事の最後見てください。
もう演奏データ抜き出しまで行けたのであとは演奏データ解析するところだけなんですが、ちょっと面倒くさくて…。
まず、それぞれのイベントの位置とかのデータが可変長数値なんです。これもモジュールに含めました。
それだけならいいんですが、MIDIイベント、SysExイベント、メタイベントでそれぞれ違うし…。
でもまあ明日にはできると思います。
モジュール
#module "kerupanium"
#defcfunc cvnum var _p1,int _p2,int _p3
// 変換された数値=cvnum(変数,インデックス,データ長)
s=0
s2=0
repeat _p3
s2=peek(_p1,_p2+cnt)
s=s*256+s2
loop
return s
#defcfunc cvnum2 var _p1,int _p2,var _p3
// 変換された数値=cvnum2(変数,インデックス,結果入れる変数)
s=0
s2=0
repeat 5
s2=peek(_p1,_p2+cnt)
s=s*128+s2
if s2>=128 : s-128 : else : _p3=cnt+1 : break
loop
return s
#global
cvnum がワード式用の関数で
cvnum2 が可変長数値用の関数です。
cvnum は、指定した変数の指定したインデックスの所から指定したデータ長分の所をワード式として、数値を返します。もし4バイトより大きい数値指定したら場合によってはオーバーフローになるだろうしHSPは32ビットだから4バイト超えるのはおかしい。
cvnum2 は、指定した変数の指定したインデックスの所からどこまでが数値のデータかを調べ、数値を返し、そのデータ長を結果入れる変数に返します。結果入れる変数には1~45の数値が返る (はず) です。
それでは。
↓あなたのクリックでやる気アップするかも
いろいろ補足
>結果入れる変数には1~4の数値が返る (はず) です。
1~5の数値でした。すいません。
普通にやったら4バイトになるところを7ビットづつやっているために32ビットは5バイト行っちゃうことを忘れていました…。
あと、作ろうとしているものはMIDI→MMLまたはMML→MIDIです。(MMLというのは一般的なMMLではなくFlMML)
音を鳴らそうとしているわけではありません。鳴らしたいだけなら関数 (HSPだと命令) 使うだけで一発だし…。
いろいろ書き忘れていてすいません。
よく作れるなwww
結構手さぐりで作ってます。
MIDIのデータのことは初めて扱うし、可変長数値なんて知らなかったし…。
検索とカンでなんとかここまでできました。
勘www
>
HSP自体は慣れてるんでけっこうカンで行けます。
HSPに似たようなプログラミング言語も調べればカンで行けるけどC言語は無理でした…。
>
わかりました。登録しました。