转自它处Delphi 实现MP3互相转换 WAV (无需任何第三方dll)function acmDriverEnumCallback(hadid: HACMDRIVERID;
dwInstance: DWORD;
fdwSupport: DWORD): BOOL;
stdcall;var driver : HACMDRIVER;
details : TACMDRIVERDETAILS;
i : integer;
fmtDetails : TACMFORMATTAGDETAILS;
begin
if (fdwSupport and ACMDRIVERDETAILS_SUPPORTF_CODEC) <> 0 then
begin
details.cbStruct := sizeof(TACMDRIVERDETAILS);
acmDriverDetails(hadid, details, 0);
acmDriverOpen(driver, hadid, 0);
for i := 0 to details.cFormatTags - 1do
begin
ZeroMemory(@fmtDetails, sizeof(fmtDetails));
fmtDetails.cbStruct := sizeof(TACMFORMATTAGDETAILS);
fmtDetails.dwFormatTagIndex := i;
acmFormatTagDetails(driver, fmtDetails, ACM_FORMATTAGDETAILSF_INDEX);
if (fmtDetails.dwFormatTag = WAVE_FORMAT_MPEGLAYER3) then
inc(g_mp3Drivers);
end;
acmDriverClose(driver, 0);
end;
Result := true;
end;
function ConverMP3ToRaw(Mp3FileName: pChar;
const Channels, SamplesPerSec, BitsPerSample: Integer): Boolean;
stdcall;var mmr : MMRESULT;
maxFormatSize : DWORD;
waveFormat : PWAVEFORMATEX;
mp3format : PMPEGLAYER3WAVEFORMAT;
g_mp3stream : HACMSTREAM;
fpIn, fpOut : Integer;
rawbufsize : Cardinal;
mp3buf, rawbuf : PBYTE;
mp3streamHead : TACMSTREAMHEADER;
count : Cardinal;
RawFileName : string;
begin
Result := False;
acmDriverEnum(acmDriverEnumCallback, 0, 0);
// try to find an MP3 codec if (g_mp3Drivers = 0) then
Exit;
maxFormatSize := 0;
// find the biggest format size acmMetrics(nil, ACM_METRIC_MAX_SIZE_FORMAT, maxFormatSize);
waveFormat := PWAVEFORMATEX(Pointer(LocalAlloc(LPTR, maxFormatSize)));
// define desired output format waveFormat^.wFormatTag := WAVE_FORMAT_PCM;
if Channels = 1 then
waveFormat^.nChannels := 1;
if Channels = 2 then
waveFormat^.nChannels := 2;
waveFormat^.nSamplesPerSec := SamplesPerSec;
// 44.1kHz waveFormat^.wBitsPerSample := BitsPerSample;
// 16 bits waveFormat^.nBlockAlign := waveFormat^.nChannels * waveFormat^.wBitsperSample div 8;
// 4;
// 4 bytes of data at a time are useful (1 sample) waveFormat^.nAvgBytesPerSec := waveFormat^.nBlockAlign * SamplesPerSec;
// byte-rate waveFormat^.cbSize := 0;
// no more data to follow mp3format := PMPEGLAYER3WAVEFORMAT(Pointer(LocalAlloc(LPTR, maxFormatSize)));
// define MP3 input format mp3format^.wfx.cbSize := MPEGLAYER3_WFX_EXTRA_BYTES;
mp3format^.wfx.wFormatTag := WAVE_FORMAT_MPEGLAYER3;
mp3format^.wfx.nChannels := 2;
mp3format^.wfx.nAvgBytesPerSec := 128 * (1024 div 8);
// not really used but must be one of 64, 96, 112, 128, 160kbps mp3format^.wfx.wBitsPerSample := 0;
// MUST BE ZERO mp3format^.wfx.nBlockAlign := 1;
// MUST BE ONE mp3format^.wfx.nSamplesPerSec := 44100;
// 44.1kHz mp3format^.fdwFlags := MPEGLAYER3_FLAG_PADDING_OFF;
mp3format^.nBlockSize := MP3_BLOCK_SIZE;
// voodoo value #1 mp3format^.nFramesPerBlock := 1;
// MUST BE ONE mp3format^.nCodecDelay := 1393;
// voodoo value #2 mp3format^.wID := MPEGLAYER3_ID_MPEG;
g_mp3stream := nil;
mmr := acmStreamOpen(g_mp3stream, // open an ACM conversion stream nil, // querying all ACM drivers TWAVEFORMATEX(Pointer(mp3format)^), //TWAVEFORMATEX(Pointer(LongInt(@mp3format))), // converting from MP3 waveFormat^, // to WAV nil, // with no filter 0, // or async callbacks 0, // (and no data for the callback) 0 // and no flags );
LocalFree(LongInt(mp3format));
LocalFree(LongInt(waveFormat));
if mmr <> 0 then
Exit;
// MP3 stream converter opened correctly // now, let‘s open a file, read in a bunch of MP3 data, and convert it! // open file fpIn := FileOpen(MP3FileName, fmOpenRead);
if (fpIn = 0) then
Exit;
// find out how big the decompressed buffer will be rawbufsize := 0;
acmStreamSize(g_mp3stream, MP3_BLOCK_SIZE, rawbufsize, ACM_STREAMSIZEF_SOURCE);
// allocate our I/O buffers mp3Buf := PByte(LocalAlloc(LPTR, MP3_BLOCK_SIZE));
rawbuf := pByte(LocalAlloc(LPTR, rawbufsize));
// prepare the decoder ZeroMemory(@mp3streamHead, sizeof(TACMSTREAMHEADER));
mp3streamHead.cbStruct := sizeof(TACMSTREAMHEADER);
mp3streamHead.pbSrc := mp3buf;
mp3streamHead.cbSrcLength := MP3_BLOCK_SIZE;
mp3streamHead.pbDst := rawbuf;
mp3streamHead.cbDstLength := rawbufsize;
acmStreamPrepareHeader(g_mp3stream, mp3streamHead, 0);
// let‘s dump this data off to disk (for debug checking!) RawFileName := ChangeFileExt(MP3FileName, ‘.raw‘);
fpOut := FileCreate(RawFileName);
if (fpOut = 0) then
Exit;
FileSeek(fpIn, 0, 0);
while Truedo
begin
//suck in some MP3 data Count := FileRead(fpIn, mp3buf^, MP3_BLOCK_SIZE);
if (Count <> MP3_BLOCK_SIZE) then
break;
// convert the data mmr := acmStreamConvert(g_mp3stream, mp3streamHead, ACM_STREAMCONVERTF_BLOCKALIGN);
if mmr <> 0 then
begin
MessageBox(0, ‘输入参数错误。请检查你的输入参数。‘, ‘系统提示: ‘, 64);
Exit;
end;
//write the decoded PCM to disk Count := FileWrite(fpOut, rawbuf^, mp3streamHead.cbDstLengthUsed);
if Count <> mp3streamHead.cbDstLengthUsed then
begin
MessageBox(0, ‘输入参数错误。请检查你的输入参数。‘, ‘系统提示: ‘, 64);
Exit;
end;
end;
;// clean up after yourself like a good little boy FileClose(fpIn);
FileClose(fpOut);
acmStreamUnprepareHeader(g_mp3stream, mp3streamHead, 0);
LocalFree(LongInt(rawbuf));
LocalFree(LongInt(mp3buf));
acmStreamClose(g_mp3stream, 0);
Result := True;
end;
ConverMP3ToRaw函数是将MP3转换成RAW(RIFF格式),添加WAV文件头就是WAV文件了。