HSP | waveファイルの再生を地道な方法でやってみる
HSP | waveファイルの再生を地道な方法でやってみる
// 準備
#include "winmm.as"
#define CALLBACK_FUNCTION 0x30000
#define CALLBACK_NULL 0
#define CALLBACK_WINDOW 0x10000
#define WHDR_BEGINLOOP 4
#define WHDR_ENDLOOP 8// 読み込み
filename="aiueo.wav" // WAVEファイルのあるパス指定
exist filename
wavedatasize=strsize
if wavedatasize=-1 : end
sdim data,wavedatasize
bload filename,data// ヘッダー解析
sdim PCMWAVEFORMAT,16
sdim wavedata
chunk=""
chunk_length=0
chunk_type=""
index=0
repeat
lpoke chunk,0,lpeek(data,index)
switch chunk
case "RIFF"
index+4
;chunk_length=lpeek(data,index) ; 本当はこのサイズだけ解析、とするべきだが、どうせ最後までRIFFのデータなんだからいいんじゃね?的なノリ
index+4
lpoke chunk_type,0,lpeek(data,index)
index+4
repeat
lpoke chunk,0,lpeek(data,index)
switch chunk
case "LIST"
index+4
chunk_length=lpeek(data,index)
index+4
;lpoke chunk_type,0,lpeek(data,index)
index+4
;LISTチャンクのデータ抜き出し
index+chunk_length
swbreak
case "fmt "
index+4
chunk_length=lpeek(data,index)
index+4
memexpand PCMWAVEFORMAT,chunk_length
memcpy PCMWAVEFORMAT,data,chunk_length,0,index
index+chunk_length
swbreak
case "data"
index+4
chunk_length=lpeek(data,index)
index+4
memexpand wavedata,chunk_length
memcpy wavedata,data,chunk_length,0,index
index+chunk_length
swbreak
swend
if index>wavedatasize-8 : break
loop
swbreak
swend
if index>wavedatasize-8 : break
loop// 再生には必要ないが、PCMWAVEFORMAT構造体解析
wpoke formatType,0,wpeek(PCMWAVEFORMAT,0)
wpoke channels,0,wpeek(PCMWAVEFORMAT,2)
lpoke samplingRate,0,lpeek(PCMWAVEFORMAT,4)
lpoke meanDataTransferRate,0,lpeek(PCMWAVEFORMAT,8)
wpoke blocAlign,0,wpeek(PCMWAVEFORMAT,12)
wpoke bit,0,wpeek(PCMWAVEFORMAT,14)// blocAlign=channels*1(2) // 16bitなら2、8bitなら1
// meanDataTransferRate=samplingRate*blocAlign// 変数
sdim WAVEFORMATEX,18
memcpy WAVEFORMATEX,PCMWAVEFORMAT,16,0,0
;wpoke WAVEFORMATEX,0,formatType
;wpoke WAVEFORMATEX,2,channels
;lpoke WAVEFORMATEX,4,samplingRate
;lpoke WAVEFORMATEX,8,samplingRate*2
;wpoke WAVEFORMATEX,12,blocAlign
;wpoke WAVEFORMATEX,14,bitsdim WAVEHDR,32
lpoke WAVEHDR,0,varptr(wavedata)
lpoke WAVEHDR,4,wavedatasize
lpoke WAVEHDR,16,WHDR_BEGINLOOP | WHDR_ENDLOOP
lpoke WAVEHDR,20,1sdim MMTIME,16
lpoke MMTIME,0,1dim phwo,1024
// メイン
waveOutOpen varptr(phwo),-1,varptr(WAVEFORMATEX),0,0,CALLBACK_NULL
waveOutPrepareHeader phwo(0),varptr(WAVEHDR),32
waveOutWrite phwo(0),varptr(WAVEHDR),32
*lp
redraw 0
waveOutGetPosition phwo(0),varptr(MMTIME),16
color 255,255,255 : boxf
color
pos 0,0 : mes ""+(lpeek(MMTIME,4)/meanDataTransferRate)+"."+((lpeek(MMTIME,4)\meanDataTransferRate)*1000/meanDataTransferRate)+"秒"
redraw
await 50
goto *lp
*exit
waveOutReset phwo(0)
waveOutUnprepareHeader phwo(0),varptr(WAVEHDR),32
waveOutClose phwo(0)
end
phwoだけだったら普通に配列にして、代入させる (?) 時には4バイトずれたところに書き込みさせる、とすればいいですが、WAVEFORMATEXやWAVEHDRは一工夫しないと…。
ケルパニさん、こんばんは
なんだか分からない文字の羅列
凄すぎます…
理解不能で涙
だけどリスペクトのナイス押しちゃっていいですか?
> †Chacottさん
ありがとうございます!! 大歓迎です!! (^^
本当は一般向きの記事も書きたいんですけど、今ちょっと訳あって更新できないんです (><
ごめんなさい!!
ありがとうございます!
では今後はすべて
「なんだか凄いからリスペクトのNICE!」
押しに来ますねヾ(。◕‿◕。)