サンプリングレート変換
今回はサンプリングレート変換です。でも簡単なプログラムなので、もしかしたらピッチが変わるかもしれません。
このプログラムはmp3のプリエコーを隠すのが目的です。だからデータの間引きは出来ますが、補間はできません。そういったことが必要であれば、
SoundEngineなど専用の波形編集ソフトを使うと良いでしょう。
wavファイルはtest.wavで、16bit2ch専用です。出力はtest2.wavです。サンプリングレートを半分にします。
'レート変換-半分にする-
#console
#include<vcrt71.sbp>
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
Dim wh As WAVEHEADER
Dim ifp As *FILE , ofp As *FILE
Dim pcm As *Long ,buf As *Long
Dim n As Long , siz As Long
Dim shz As Long , dhz As Long
Dim rate As double
Sub Err(m As *Byte)
printf(Ex"エラー:%s\n" , m)
exit(0)
End Sub
ifp = fopen("test.wav" , "rb")
If ifp = NULL Then Err("入力ファイル開けん")
ofp = fopen("test2.wav" , "wb")
If ofp = NULL Then Err("出力ファイル開けん")
fread(VarPtr(wh) , sizeof(WAVEHEADER) , 1 , ifp)
'レートを設定する
shz = wh.nSamplesPerSec
dhz = wh.nSamplesPerSec / 2
rate = dhz / shz
pcm = malloc(wh.pcmbytes)
buf = malloc(wh.pcmbytes * rate + 1)'+1は四捨五入対策
fread(pcm , 1 , wh.pcmbytes , ifp)
printf(Ex"%dHz -> %dHz %3.3f\n" , shz , dhz , rate)
printf(Ex"サイズ\nbytes=%d\n" , wh.bytes )
'データを間引く
For n=0 To wh.pcmbytes / 4
buf[n*rate] = pcm[n]
Next
'ヘッダ書き換え
wh.nSamplesPerSec = dhz
wh.nAvgBytesPerSec = wh.nSamplesPerSec * wh.nBlockAlign
wh.pcmbytes = wh.pcmbytes * rate + 1
wh.bytes = wh.pcmbytes + 44-8
'カキコ
fwrite(VarPtr(wh) , sizeof(WAVEHEADER) , 1 , ofp)
fwrite(buf , 1 , wh.pcmbytes , ofp)
'開放
free(buf)
free(pcm)
fclose(ifp)
fclose(ofp)
exit(0)