//该类可以实现,任何wav的转化,可以从pcm->adpcm,adpcm->mp3,gsm->mp3,mp3->a率,u率 ,a 率 u率->g729A
TWaveBufConverter = class
private
fphad: HACMDRIVER;
fhadid: HACMDRIVERID;
FMaxFmtSize: DWord;
CurrentFormat: TACMWaveFormat;
NewFormat: TACMWaveFormat;
//转化
fStreamHeaderM: TACMStreamHeader;
fStreamHeader: TACMStreamHeader;
fStreamHandle: HACMStream;
FStreamHandleM: HACMStream;
srcDataBuf: PChar;
mDataBuf: PChar;
DscDataBuf: PChar;
srcBufferSize: DWORD;
mBufferSize: DWORD;
DscBufferSize: DWORD;
//获得指定的一个格式
function FormatSuggest(pFDInfo: pFIND_DRIVER_INFO): Boolean;
public
constructor Create(SrcConverFormat, ConverFormat: Integer);
destructor Destroy; override;
//开始转化
function StartConvert(ConvertSize: Integer): Boolean;
//结束转化
function EndConvert: Boolean;
//开始转化
function RunConvvert(srcBuf: PChar; srcBufSize: Integer; out DrcBuf: PChar; out DrcBufSize: Integer): Boolean;
end;
implementation
uses
DataDefine, g729A;
function FormatCallback(hadid:HACMDRIVERID; pafd: PAcmFormatDetailsA;
dwInstance: DWORD; fdwSupport: DWORD): BOOL; stdcall;
begin
Result := True;
if dwInstance = 1 then
begin
if (pafd^.pwfx^.nChannels = 1) and
(pafd^.pwfx^.nSamplesPerSec = 8000) and
(pafd^.pwfx^.wBitsPerSample = 8) then
begin
Result := False;
end;
end
else if dwInstance = 6 then
begin
if (pafd^.pwfx^.nChannels = 1) and
(pafd^.pwfx^.nSamplesPerSec = 8000) and
(pafd^.pwfx^.nAvgBytesPerSec = 8000) then
begin
Result := False;
end;
end
else if dwInstance = 7 then
begin
if (pafd^.pwfx^.wFormatTag = 7) and
(pafd^.pwfx^.nChannels = 1) and
(pafd^.pwfx^.nSamplesPerSec = 8000) and
(pafd^.pwfx^.nAvgBytesPerSec = 8000) then
begin
Result := False;
end;
end
else if dwInstance = 17 then
begin
if (pafd^.pwfx^.wFormatTag = 17) and
(pafd^.pwfx^.nChannels = 1) and
(pafd^.pwfx^.nSamplesPerSec = 8000) then
begin
Result := False;
end;
end
else if dwInstance = 49 then
begin
if (pafd^.pwfx^.wFormatTag = 49) and
(pafd^.pwfx^.nChannels = 1) and
(pafd^.pwfx^.nSamplesPerSec = 8000) then
begin
Result := False;
end;
end
else if dwInstance = 85 then
begin
if (pafd^.pwfx^.nChannels = 1) and
(pafd^.pwfx^.nSamplesPerSec = 8000) and
(pafd^.pwfx^.nAvgBytesPerSec = 1000) then
begin
Result := False;
end;
end
else if dwInstance = 131 then
begin
if (pafd^.pwfx^.wFormatTag = 131) and
(pafd^.pwfx^.nChannels = 1) then
begin
Result := False;
end;
end;
end;
function DriverCallback(hadif: HACMDRIVERID; dwInstance, fdwSupport: DWORD): BOOL; stdcall;
var
padd: TAcmDriverDetails;
pFIND_DRIVER_INFOTmp: pFIND_DRIVER_INFO;
phad: HACMDRIVER;
AcmFormatDetailsTmp: TAcmFormatDetails;
Res: MMRESULT;
intSize: Integer;
TWAVEFORMATEXTmp: TWAVEFORMATEX;
begin
Result := TRUE;
pFIND_DRIVER_INFOTmp := pFIND_DRIVER_INFO(dwInstance);
padd.cbStruct := SizeOf(TAcmDriverDetails);
acmDriverDetails(hadif, padd, 0);
if ((LowerCase(padd.szShortName) = LowerCase('Lame mp3')) and (pFIND_DRIVER_INFOTmp^.wfx.wFormatTag = 85)) or
((LowerCase(padd.szShortName) = LowerCase('Microsoft IMA ADPCM')) and (pFIND_DRIVER_INFOTmp^.wfx.wFormatTag = 17)) or
((LowerCase(padd.szShortName) = LowerCase('Microsoft GSM 6.10')) and (pFIND_DRIVER_INFOTmp^.wfx.wFormatTag = 49)) or
((LowerCase(padd.szShortName) = LowerCase('Microsoft CCITT G.711')) and (pFIND_DRIVER_INFOTmp^.wfx.wFormatTag = 7)) or
((LowerCase(padd.szShortName) = LowerCase('MS-PCM')) and (pFIND_DRIVER_INFOTmp^.wfx.wFormatTag = 1)) or
((LowerCase(padd.szShortName) = LowerCase('SynWay G.729A ')) and (pFIND_DRIVER_INFOTmp^.wfx.wFormatTag = 131)) then
begin
Res := acmDriverOpen(phad, hadif, 0);
if Res <> 0 then
begin
exit;
end;
acmMetrics(HACMOBJ(phad), ACM_METRIC_MAX_SIZE_FORMAT, intSize);
Fillchar(TWAVEFORMATEXTmp, Sizeof(TWAVEFORMATEX), 0);
TWAVEFORMATEXTmp.cbSize := 0;
TWAVEFORMATEXTmp.wFormatTag := 0;
Fillchar(AcmFormatDetailsTmp, Sizeof(TAcmFormatDetails), 0);
AcmFormatDetailsTmp.cbStruct := SizeOf(TAcmFormatDetails);
AcmFormatDetailsTmp.dwFormatTag := 0;
AcmFormatDetailsTmp.pwfx := @TWAVEFORMATEXTmp;
AcmFormatDetailsTmp.cbwfx := intSize;
Res := acmFormatEnum(phad, AcmFormatDetailsTmp, FormatCallback, Integer(pFIND_DRIVER_INFOTmp^.wfx.wFormatTag), 0);
if Res = 0 then
begin
pFIND_DRIVER_INFOTmp^.hadid := hadif;
Move(AcmFormatDetailsTmp.pwfx^, pFIND_DRIVER_INFOTmp^.wfx, SizeOf(TWAVEFORMATEX));
Result := False;
end;
acmDriverClose(phad, 0);
end;
end;
{ TWaveBufConverter }
constructor TWaveBufConverter.Create(SrcConverFormat, ConverFormat: Integer);
var
WaveFormatTmp: TWAVEFORMATEX;
FIND_DRIVER_INFOTmp: TFIND_DRIVER_INFO;
intLength: Integer;
begin
acmMetrics(nil, ACM_METRIC_MAX_SIZE_FORMAT, FMaxFmtSize);
FillChar(NewFormat.Format, FMaxFmtSize, 0);
FillChar(CurrentFormat.Format, FMaxFmtSize, 0);
case SrcConverFormat of
RecordMode_M: //= 7; //m-率
begin
with WaveFormatTmp do
begin
wFormatTag := 7; { format type }
nChannels := 1; { number of channels (i.e. mono, stereo, etc.) }
nSamplesPerSec := 8000; { sample rate }
nAvgBytesPerSec := 8000; { for buffer estimation }
nBlockAlign := 1; { block size of data }
wBitsPerSample := 8; { number of bits per sample of mono data }
cbSize := 0; { the count in bytes of the size of }
end;
Move(WaveFormatTmp, CurrentFormat.Format, SizeOf(TWAVEFORMATEX));
end;
RecordMode_ADPCM:
begin
with WaveFormatTmp do
begin
wFormatTag := 17; { format type }
nChannels := 1; { number of channels (i.e. mono, stereo, etc.) }
nSamplesPerSec := 8000; { sample rate }
nAvgBytesPerSec := 4055; { for buffer estimation }
nBlockAlign := 256; { block size of data }
wBitsPerSample := 4; { number of bits per sample of mono data }
cbSize := 2; { the count in bytes of the size of }
end;
Move(WaveFormatTmp, CurrentFormat.Format