用Bass库(Bass.dll)写一个音频转换程序

    因工作需要,11k16bit的wav文件要转换成8k8bit的wav,最开始搜索出来的方法是用acm,但是,转出来的效果比用CoolEdit转出来的效果明显差一些,很容易就能听出来。

    无意中找到一个OCX控件,转出来的效果和CoolEdit的比较接近了,但是,这个OCX要注册,不注册只能转5个文件,晕,也太小气了吧?

    仔细看它的目录下,有几个DLL文件,Lame_enc.dll,Wave_Enc.dll,搜索了一下,Wave_Enc.dll没有什么发现,用ExeScope一查,真实文件名应该是Bass.dll,再搜索,就明白原来是比较有名的Bass库了。

    如果仅仅是直接转换为wav的话,用Bass.dll就可以了,但我还需要调整频率等,所以就需要BassMix。

procedure DecodeFile(Src,Dest:string;Freq,Bits,Channel:Integer); //源文件,目的文件,频率,精度,声道 var Chan: DWORD; frq: Single; buf : array [0..1000] of BYTE; BytesRead : integer; Temp : string; I : longint; RecStream : TFileStream; nChannels : Word; // number of channels (i.e. mono, stereo, etc.) nSamplesPerSec : DWORD; // sample rate nAvgBytesPerSec : DWORD; nBlockAlign : Word; wBitsPerSample : Word; // number of bits per sample of mono data ChanInfo: BASS_CHANNELINFO; Mixer:HSTREAM; PercentDone : Integer; begin Result:=False; //设置Mixer重新采样时的效果 BASS_SetConfig(BASS_CONFIG_MIXER_FILTER,50); //从源文件创建流,默认支持wav,mp3 Chan := BASS_StreamCreateFile(False, PChar(Src), 0, 0, BASS_STREAM_DECODE); //取源文件的相关信息 BASS_ChannelGetInfo(Chan, Chaninfo); nChannels := ChanInfo.Chans; if (Chaninfo.flags and BASS_SAMPLE_8BITS > 0) then wBitsPerSample := 8 else wBitsPerSample := 16; nBlockAlign := nChannels * wBitsPerSample div 8; //取频率 BASS_ChannelGetAttribute(Chan, BASS_ATTRIB_FREQ, Frq); nSamplesPerSec := Trunc(Frq); nAvgBytesPerSec := nSamplesPerSec * nBlockAlign; nBlockAlign := Trunc(Channel * Bits /8); nAvgBytesPerSec := nBlockAlign * Freq; RecStream := TFileStream.Create(Dest, fmCreate); // 写目的文件的WAV头格式 Temp := 'RIFF'; RecStream.write(temp[1], length(temp)); Temp := #0#0#0#0; RecStream.write(temp[1], length(temp)); // 文件大小此时未定,转换完成后修改 Temp := 'WAVE'; RecStream.write(temp[1], length(temp)); Temp := 'fmt '; RecStream.write(temp[1], length(temp)); Temp := #$10#0#0#0; RecStream.write(temp[1], length(temp)); // Fixed Temp := #1#0; RecStream.write(temp[1], length(temp)); // PCM format if Channel = 1 then Temp := #1#0 else Temp := #2#0; RecStream.write(temp[1], length(temp)); RecStream.write(Freq, 2); Temp := #0#0; RecStream.write(temp[1], length(temp)); // SampleRate is given as dWord RecStream.write(nAvgBytesPerSec, 4); RecStream.write(nBlockAlign, 2); RecStream.write(Bits, 2); Temp := 'data'; RecStream.write(temp[1],length(temp)); Temp := #0#0#0#0; RecStream.write(temp[1],length(temp)); // 音频数据大小(不包含头文件)此时未定,转换完成后更新 if Bits=8 then //输出目的文件为8bit精度,指定频率与声道 Mixer:=BASS_Mixer_StreamCreate(Freq, Channel, BASS_SAMPLE_8BITS+BASS_MIXER_END+BASS_STREAM_DECODE +BASS_MIXER_FILTER+BASS_MIXER_BUFFER) else//输出目的文件为16bit精度,指定频率与声道 Mixer:=BASS_Mixer_StreamCreate(Freq, Channel, BASS_SAMPLE_FLOAT+BASS_MIXER_END+BASS_STREAM_DECODE +BASS_MIXER_FILTER+BASS_MIXER_BUFFER); //将源音频流加入到Mixer里面,以实现重采样转换 BASS_Mixer_StreamAddChannel(Mixer, Chan, 0); // plug in the source while (BASS_ChannelIsActive(Mixer) > 0) do begin // 循环获取解码及重采样后的音频数据... BytesRead := BASS_ChannelGetData(Mixer, @buf, 1000); RecStream.Write(buf, BytesRead); //完成进度 PercentDone := Trunc((100 * BASS_ChannelGetPosition(Chan, BASS_POS_BYTE)) / BASS_ChannelGetLength(Chan, BASS_POS_BYTE)); end; BASS_StreamFree(Mixer); // free mixer BASS_StreamFree(Chan); // 修改WAV的头的相关数据 // Rewrite some fields of header I := RecStream.Size - 8; // size of file RecStream.Position := 4; RecStream.write(i, 4); I := I - $24; // size of data RecStream.Position := 40; RecStream.write(i, 4); RecStream.Free; end;  

你可能感兴趣的:(用Bass库(Bass.dll)写一个音频转换程序)