バイナリの書き込み/読み込みというのはどうすればいいのでしょうか?
実は「MIDIファイルを自分で生産してみよう!」ということを思いついて、
やってみたかったんですが、MIDIファイルの仕組み(ヘッダとか)はわかる...つもりでいるのですが、書き込み/読み込みがどうすればいいのかがわかりません。
テキストファイルはわかるのですが...(^^;
また、書き込み/読み込みというのは
byte型の配列を使ってやるのでしょうか?
それと、ビッグエディアン -> リトルエディアン また、その反対はどうするのでしょうか?
詳しい方、よろしくお願いします。
バイナリの書き込み読み込み
どの程度説明するかわかりませんが、とりあえずざっと書いてみます。
今は、ABではないですが、OS X用のMIDIシーケンサでいいものが見つからないので、作りたいなーとも思っています。
以上簡単な説明なので、分からないところもあるかもしれませんが、その時はまた質問してください。または他のユーザーさんにお願いしたいと思います。
ReadFile()やWriteFile()でOKだと思います。ちなみに、CreateFile() -> ReadFile() Or WriteFile() -> CloseHandle()の流れで使用します。バイナリの書き込み/読み込みというのはどうすればいいのでしょうか?
この辺は、たぶんHIWORD()などでできると思いますが、複雑なものは論理演算(ビット演算)した方がいいかもしれません。それと、ビッグエディアン -> リトルエディアン また、その反対はどうするのでしょうか?
ちなみに、MIDIファイルは私もやろうと思ったことがありますが、その時は構造がうまくつかめなかったので、やりませんでした。実は「MIDIファイルを自分で生産してみよう!」ということを思いついて、
やってみたかったんですが、MIDIファイルの仕組み(ヘッダとか)はわかる...つもりでいるのですが、書き込み/読み込みがどうすればいいのかがわかりません。
今は、ABではないですが、OS X用のMIDIシーケンサでいいものが見つからないので、作りたいなーとも思っています。
以上簡単な説明なので、分からないところもあるかもしれませんが、その時はまた質問してください。または他のユーザーさんにお願いしたいと思います。
エンディアンの変換を行う関数ならWinSockにあります。
正確にはネットワークエンディアン(ビッグエンディアン)とプログラムが動いているコンピュータで使われているホストエンディアンを変換する関数ですけど。
hton?がネットワークエンディアンへの,ntoh?がホストエンディアンへの変換を行います。
正確にはネットワークエンディアン(ビッグエンディアン)とプログラムが動いているコンピュータで使われているホストエンディアンを変換する関数ですけど。
コード: 全て選択
Declare Function htons Lib "ws2_32.dll" (netShort As Word) As Word
Declare Function htonl Lib "ws2_32.dll" (netLong As DWord) As DWord
Declare Function ntohs Lib "ws2_32.dll" (hostShort As Word) As Word
Declare Function ntohl Lib "ws2_32.dll" (hostLong As DWord) As DWord
AB5のCP2以降のIncludeフォルダ内にある、Stringクラスが参考になると思いますが、malloc/calloc/realloc等の関数でバイト数を指定して長大変数を確保し、free関数で変数領域の開放を行う という方法があります。
Website→http://web1.nazca.co.jp/himajinn13sei/top.html
ここ以外の場所では「暇人13世」というHNを主として使用。
に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。
ここ以外の場所では「暇人13世」というHNを主として使用。
に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。
可変長数値というのは、SMF内部構造のページ末尾に書いてあるやつのことですよね?MIDIファイルで一番重要なことですが、
(多分これがリトルエディアンって言われてたと思うのですが、)
可変長数値ってありますよね。
あれってどうやればできるんですか?
ビットシフトという言葉だけは聴いたことがあるのですが、
やり方までは知りません(^^;
とりあえずサンプルとして、配列に格納されている可変長数値のデータを、Long型に変換するものを作ってみました。
ビット演算自体は、オブジェクト指向よりよっぽど具体的な話なので、検索して調べればすぐにわかると思います。ただ、アルゴリズム考えるのがちょっと面倒です。
[ここをクリックすると内容が表示されます]
コード: 全て選択
#console
Dim B[2] As Byte 'サンプルデータ
B[0] = &H92 '10 01 00 10
B[1] = &HB3 '10 11 00 11
B[2] = &H2E '00 10 11 10
Print MakeNumber(B)
Sleep(1000)
Function MakeNumber(b As *Byte) As Long
Dim i As Long
While IsTopStanding(b)
i++
Wend
Dim j As Long
Dim temp As Long
For j = 0 To i - 1
temp = b[j] And &H7F
temp <<= 7*(i - j)
MakeNumber = MakeNumber Or temp
Next
temp = b
MakeNumber = MakeNumber Or temp
End Function
'先頭のビットが1か調べる
Function IsTopStanding(b As Byte) As BOOL
If b And &H80 Then
Return TRUE
Else
Return FALSE
End If
End Function
まず、ビット演算について調べてみてください。wikipediaにも結構詳しく載っています。
ビット演算(wikipedia)
HIBYTEやLOBYTEというのは、16bitを上位,下位の8bitに分断するものです。しかし、MIDIで使われている可変長数値は、HIBYTEなどよりも、もっと細かいビット操作を必要としています。
例えば、上のコードのIsTopStanding()ですが、これは、先頭のbitが1かどうかを返す関数です。先頭の1bitの状態を取得するには、HIBYTEなどでは8bit単位なので無理なのは分かるでしょう。そこで、ビット演算をうまくつかいます。
その前に補足です。条件式ですが、ActiveBasicの場合、条件式の結果が0以外だったら、真と判定されます。
条件式のb And &H80が真だったら、先頭のbitは1になっているというわけですが、具体的には、次のようなビット演算になっています。
and演算をやっていれば分かりますが、and演算の性質は、どちらかの値が0だったら計算結果が0になります。そして、どちらも1だった場合、1になります。andする値が0の場合、その計算結果は必ず0になります。
この性質を利用して、計算します。まず、先頭のビットにand 1することによって、bの値が1だった場合1、0だった場合0となります。1つでもビットが1であれば条件式は真になりますので、他の不要な7bitは、and 0して、全て0にしてしまいます。
こうすることにより、先頭のbitがどうなっているかを、条件式で判断することができます。
こんな感じで、他にも、Orやシフト演算をうまく使い、計算していきます。
最初から複雑な演算は難しいと思いますので、まずは、ビット演算に慣れてみてください。
今日は時間がないので、少し雑な説明になってしまいました。
ビット演算(wikipedia)
HIBYTEやLOBYTEというのは、16bitを上位,下位の8bitに分断するものです。しかし、MIDIで使われている可変長数値は、HIBYTEなどよりも、もっと細かいビット操作を必要としています。
例えば、上のコードのIsTopStanding()ですが、これは、先頭のbitが1かどうかを返す関数です。先頭の1bitの状態を取得するには、HIBYTEなどでは8bit単位なので無理なのは分かるでしょう。そこで、ビット演算をうまくつかいます。
コード: 全て選択
Function IsTopStanding(b As Byte) As BOOL
If b And &H80 Then
Return TRUE
Else
Return FALSE
End If
End Function
条件式のb And &H80が真だったら、先頭のbitは1になっているというわけですが、具体的には、次のようなビット演算になっています。
コード: 全て選択
b = 10110101(2進数)だった場合
&H80は2進数で10000000です。
10110101
and)10000000
-----------------
10000000
コード: 全て選択
0 and 0 = 0
1 and 0 = 0
こうすることにより、先頭のbitがどうなっているかを、条件式で判断することができます。
こんな感じで、他にも、Orやシフト演算をうまく使い、計算していきます。
最初から複雑な演算は難しいと思いますので、まずは、ビット演算に慣れてみてください。
今日は時間がないので、少し雑な説明になってしまいました。