来自 http://www.rediware.com/programming/vb/vbrecwav/vbrecordwav.htm 的方法,经过修改简化
使用VB录音,修改音频参数:
RetLng = mciSendString("Set Wave Time Format ms", "", 0, 0) RetLng = mciSendString("Set Wave Format tag pcm", "", 0, 0) RetLng = mciSendString("Set Wave Channels 1", "", 0, 0) RetLng = mciSendString("Set Wave Samplespersec 16000", "", 0, 0) RetLng = mciSendString("Set Wave BitsperSample 8", "", 0, 0)
之后保存,发现wmp无法播放。原来是mcisendstring的bug所在。
这是mci保存的音频数据,可以发现,地址1C、1D、1E上的值 002B11 就是11025,是默认的参数。但是录音音频已经改变了。所以wmp无法识别。
现在来修改:
反向:003E80,就是前面设置的参数:16000*1*8/8,samplespersec*bitspersample*channels/8 。
这样就改好了。当然可以直接在vb里改:
Public Sub FixWaveFile() '录音后的修正 Dim IndexNum As Integer Dim Offset As Long Dim FileName As String IndexNum = FreeFile FileName = App.Path & "\GoogleASR.wav" Open FileName For Binary Access Write As #IndexNum Offset = 29 Put #IndexNum, Offset, &H80 Offset = 30 Put #IndexNum, Offset, &H3E Offset = 31 Put #IndexNum, Offset, &H0 Close #1 End Sub
看一下,的确能播放了。
---------------------------------------
更新:其实修改后的wav还有错误,看一下文件大小,如果是奇数字节的,还要进一步修改,只需在文件末尾添加一个空字节,并将文件头的SIZE调整为 文件大小-8 就可以了。
#include <stdio.h> #include <conio.h> typedef unsigned char byte; int main() { long len; long a; FILE *fp = fopen("1.wav", "rb+"); fseek(fp, 0, SEEK_END); len = ftell(fp); fseek(fp, 4, SEEK_SET); a = len - 7; fputc((byte)a, fp); fputc((byte(a>>8)),fp); fseek(fp, 0, SEEK_END); fputc(0, fp); fclose(fp); getch(); return 0; }
经过测试,发现未修改文件大小的wav用flac.exe -8 --sample-rate=16000 1.wav显示error,而修改后的wav被正常转换。
-----------------------
还有一点要注意,Block Align也要修改成匹配的形式,大小为:bitspersample*channels/8。