wavをauに変換する
題名の通りです。wav形式のファイルをau形式にしようという試みです。
auのヘッダはwavよりも20バイト程度小さいので、ディスクスペースにやさしいファイルといえます。
さて問題はエンディアンです。wavファイルは
リトルエンディアン
ですがauは
ビッグエンディアン
です。これを切り替えなければなりません。
'wav2au
#console
#include<vcrt71.sbp>
Const infile = "test.wav"
Const outfile = "test.au"
Type AUHEADER
snd[3] As Byte'".snd"
hdrsiz As DWord'ヘッダサイズ
datsiz As DWord'データのサイズ
fmt As DWord'フォーマット
rate As DWord'サンプリングレート
ch As DWord'チャンネル数
End Type
Type WAVEHEADER
RIFF[3] As Byte'"RIFF"
bytes As DWord'(ファイルのバイト数)-8
WAVE[3] As Byte' "WAVE"
fmt[3] As Byte '"fmt "
siz_wf As DWord'PCMWAVEFORMAT構造体のバイト数=常に16
'PCMWAVEFORMAT構造
wFormatTag As Word 'pcm=1
nChannels As Word 'ch数
nSamplesPerSec As Dword 'サンプリング周波数
nAvgBytesPerSec As DWord
nBlockAlign As Word
wBitsPerSample As Word '量子化数
data[3] As Byte'"data"
pcmbytes As DWord'波形データのバイト数
End Type
'エンディアン変換(4バイト)
Sub swap4(d As BytePtr)
Dim tmp As Byte
tmp = GetByte(d)
SetByte(d , GetByte(d+3))
SetByte(d+3 , tmp)
tmp = GetByte(d+1)
SetByte(d+1 , GetByte(d+2))
SetByte(d+2 , tmp)
End Sub
'エンディアン変換(2バイト)
Sub swap2(d As BytePtr)
Dim tmp As Byte
tmp = GetByte(d)
SetByte(d , GetByte(d+1))
SetByte(d+1 , tmp)
End Sub
Dim wh As WAVEHEADER
Dim ah As AUHEADER
Dim ifp As *FILE
DIm ofp As *FILE
Dim pcm As BytePtr
Dim n As DWord
'ファイルを開く
ifp = fopen("test.wav" , "rb")
if(ifp = NULL) Then exit(0)
ofp = fopen("test.au" , "wb")
if(ofp = NULL) Then exit(0)
fread(VarPtr(wh) , sizeof(WAVEHEADER) , 1 , ifp)
'auヘッダを作ってみる
lstrcpy(ah.snd , ".snd")
ah.hdrsiz = 24
ah.datsiz =wh.pcmbytes
ah.fmt = 3
ah.rate =wh.nSamplesPerSec
ah.ch = wh.nChannels
'ここでエンディアン変換
swap4(VarPtr(ah.hdrsiz))
swap4(VarPtr(ah.datsiz))
swap4(VarPtr(ah.fmt))
swap4(VarPtr(ah.rate))
swap4(VarPtr(ah.ch))
fwrite(VarPtr(ah) , sizeof(AUHEADER) , 1 , ofp)
pcm = malloc(wh.pcmbytes)
fread(pcm , 1 , wh.pcmbytes , ifp)
'pcmのエンディアンを変換
For n=0 To wh.pcmbytes Step 2
swap2(VarPtr(pcm[n]))
Next
fwrite(pcm , 1 , wh.pcmbytes , ofp)
free(pcm)
fclose(ifp)
fclose(ofp)
exit(0)'終わり
入力ファイルはtest.wav、出力はtest.auです。
エンディアン切り替えのうまいプログラムが分からないため、非常に読みにくくなってしまいました。
swap4は4バイトのデータをswap2は2バイトのデータのエンディアンを切り替えます。
auヘッダはコメントがつくようですが省略しています。