サンプリングレート変換

今回はサンプリングレート変換です。でも簡単なプログラムなので、もしかしたらピッチが変わるかもしれません。
このプログラムは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)