MMACMSup.pas
上传用户:hylc_2004
上传日期:2014-01-23
资源大小:46800k
文件大小:36k
- {========================================================================}
- {= (c) 1995-98 SwiftSoft Ronald Dittrich =}
- {========================================================================}
- {= All Rights Reserved =}
- {========================================================================}
- {= D 01099 Dresden = Fax.: +49(0)351-8037944 =}
- {= Loewenstr.7a = info@swiftsoft.de =}
- {========================================================================}
- {= Actual versions on http://www.swiftsoft.de/index.html =}
- {========================================================================}
- {= This code is for reference purposes only and may not be copied or =}
- {= distributed in any format electronic or otherwise except one copy =}
- {= for backup purposes. =}
- {= =}
- {= No Delphi Component Kit or Component individually or in a collection=}
- {= subclassed or otherwise from the code in this unit, or associated =}
- {= .pas, .dfm, .dcu, .asm or .obj files may be sold or distributed =}
- {= without express permission from SwiftSoft. =}
- {= =}
- {= For more licence informations please refer to the associated =}
- {= HelpFile. =}
- {========================================================================}
- {= $Date: 27.01.99 - 02:33:52 $ =}
- {========================================================================}
- unit MMACMSup;
- {$I COMPILER.INC}
- interface
- uses
- {$IFDEF WIN32}
- Windows,
- {$ELSE}
- WinTypes,
- WinProcs,
- {$ENDIF}
- SysUtils,
- Classes,
- Forms,
- MMSystem,
- MMUtils,
- MMRegs,
- MMPCMSup,
- MMACM
- {$IFDEF USEWAVEMPEG}
- ,L3DecDLL,
- L2DecDLL
- {$ENDIF}
- ;
- type
- PACMStream = ^TACMStream;
- TACMStream = packed record
- lpSrcBuffer : PChar;
- lpDstBuffer : PChar;
- dwSrcBufferSize: Longint;
- dwDstBufferSize: Longint;
- dwRemaining : Longint;
- acmStream : THACMSTREAM;
- acmStreamHeader: TACMStreamHeader;
- end;
- PACMConvert = ^TACMConvert;
- TACMConvert = packed record
- lpSrcBuffer : PChar;
- lpDstBuffer : PChar;
- dwSrcBufferSize : Longint;
- dwDstBufferSize : Longint;
- dwBytesConverted : Longint;
- dwBytesRead : Longint;
- bPending : Boolean;
- bQueued : Boolean;
- bFreeSrcBuffer : Boolean;
- Streams : TList;
- {$IFDEF USEWAVEMPEG}
- lpDecBuffer : array[0..16384-1] of Byte;
- bUseL3Decoder : Boolean;
- pL3DLL : THandle;
- bUseL2Decoder : Boolean;
- pL2DLL : PL2DLL;
- DataSection : TRTLCriticalSection;
- {$ENDIF}
- end;
- { a set of low level conversion routines to convert Formats }
- function acmMustConvert(pwfxSrc,pwfxDst: PWaveFormatEx): Boolean;
- function acmQueryConvert(pwfxSrc,pwfxDst: PWaveFormatEx; RealTime: Boolean): Boolean;
- function acmSuggestPCMFormat(pwfxSrc: PWaveFormatEx): TWaveFormatEx;
- function acmSuggestPCMFormatEx(pwfxSrc: PWaveFormatEx; Bits,Channels,SampleRate: Longint): TWaveFormatEx;
- function acmSizeOutputData(pwfxSrc,pwfxDst: PWaveFormatEx; SrcBufSize: Longint): Longint;
- function acmBeginConvert(pwfxSrc,pwfxDst: PWaveFormatEx;
- SrcBuffer: PChar; SrcBufSize: Longint; RealTime: Boolean): PACMConvert;
- function acmDoConvert(pConvert: PACMConvert; SrcBufSize: Longint): Longint;
- function acmFlushConvert(pConvert: PACMConvert): Boolean;
- function acmEndConvert(pConvert: PACMConvert; SrcBufSize: Longint): Longint;
- procedure acmDoneConvert(var pConvert: PACMConvert);
- implementation
- {------------------------------------------------------------------------}
- function acmMustConvert(pwfxSrc,pwfxDst: PWaveFormatEx): Boolean;
- begin
- Result := ((pwfxSrc <> nil) and (pwfxDst <> nil)) and
- ((pwfxSrc^.wFormatTag <> pwfxDst^.wFormatTag) or
- (pwfxSrc^.wBitsPerSample <> pwfxDst^.wBitsPerSample) or
- (pwfxSrc^.nChannels <> pwfxDst^.nChannels) or
- (pwfxSrc^.nSamplesPerSec <> pwfxDst^.nSamplesPerSec));
- end;
- {------------------------------------------------------------------------}
- function acmSuggestPCMFormat(pwfxSrc: PWaveFormatEx): TWaveFormatEx;
- var
- Ready: Boolean;
- dwSuggest: Longint;
- wfx: TWaveFormatEx;
- begin
- if (pwfxSrc^.wFormatTag <> WAVE_FORMAT_PCM) then
- begin
- Ready := False;
- try
- FillChar(Result,sizeOf(Result),0);
- FillChar(wfx, sizeOf(wfx),0);
- wfx.wFormatTag := WAVE_FORMAT_PCM;
- dwSuggest := ACM_FORMATSUGGESTF_WFORMATTAG;
- { 'suggest' a PCM format' }
- if acmFormatSuggest(0, pwfxSrc, @wfx, SizeOf(wfx), dwSuggest) <> 0 then
- exit;
- if acmStreamOpen(nil, 0, pwfxSrc, @wfx, nil, 0, 0, ACM_STREAMOPENF_QUERY) <> 0 then
- exit;
- Ready := True;
- Result := wfx;
- finally
- {$IFDEF USEWAVEMPEG}
- if not Ready then
- begin
- if (pwfxSrc.wFormatTag = WAVE_FORMAT_MPEG) or
- (pwfxSrc.wFormatTag = WAVE_FORMAT_MPEG_LAYER3) then
- begin
- pcmBuildWaveHeader(@wfx,16,pwfxSrc.nChannels,pwfxSrc.nSamplesPerSec);
- Result := wfx;
- end;
- end;
- {$ENDIF}
- end;
- end
- else Result := pwfxSrc^;
- end;
- {------------------------------------------------------------------------}
- function acmSuggestPCMFormatEx(pwfxSrc: PWaveFormatEx; Bits,Channels,SampleRate: Longint): TWaveFormatEx;
- var
- Ready: Boolean;
- dwSuggest: Longint;
- wfx: TWaveFormatEx;
- begin
- Result := pwfxSrc^;
- if (pwfxSrc^.wFormatTag <> WAVE_FORMAT_PCM) or
- ((Bits > 0) and (pwfxSrc^.wBitsPerSample <> Bits)) or
- ((Channels > 0) and (pwfxSrc^.nChannels <> Channels)) or
- ((SampleRate > 0) and (pwfxSrc^.nSamplesPerSec <> SampleRate)) then
- begin
- Ready := False;
- try
- wfx.wFormatTag := WAVE_FORMAT_PCM;
- dwSuggest := ACM_FORMATSUGGESTF_WFORMATTAG;
- if (Bits > 0) then
- begin
- wfx.wBitsPerSample := Bits;
- dwSuggest := ACM_FORMATSUGGESTF_WBITSPERSAMPLE;
- end;
- if (Channels > 0) then
- begin
- wfx.nChannels := Channels;
- dwSuggest := ACM_FORMATSUGGESTF_NCHANNELS;
- end;
- if (SampleRate > 0) then
- begin
- wfx.nSamplesPerSec := SampleRate;
- dwSuggest := ACM_FORMATSUGGESTF_NSAMPLESPERSEC;
- end;
- { 'suggest' a PCM format' }
- if acmFormatSuggest(0, pwfxSrc, @wfx, SizeOf(wfx), dwSuggest) <> 0 then
- exit;
- if acmStreamOpen(nil, 0, pwfxSrc, @wfx, nil, 0, 0, ACM_STREAMOPENF_QUERY) <> 0 then
- exit;
- Ready := True;
- Result := wfx;
- finally
- {$IFDEF USEWAVEMPEG}
- if not Ready then
- begin
- if (pwfxSrc.wFormatTag = WAVE_FORMAT_MPEG) or
- (pwfxSrc.wFormatTag = WAVE_FORMAT_MPEG_LAYER3) then
- begin
- pcmBuildWaveHeader(@wfx,Bits,Channels,SampleRate);
- end;
- end;
- {$ENDIF}
- end;
- end;
- end;
- {------------------------------------------------------------------------}
- function acmQueryConvert(pwfxSrc,pwfxDst: PWaveFormatEx; RealTime: Boolean): Boolean;
- Label Ready;
- var
- Buf: array[0..1024] of Char;
- pwfx: PWaveFormatEx;
- dwSuggest,dwFlags: Longint;
- begin
- Result := False;
- if acmDLLLoaded and (HiWord(acmGetVersion) >= $0200) and
- (pwfxSrc <> nil) and (pwfxSrc <> nil) then
- begin
- if acmMustConvert(pwfxSrc,pwfxDst) then
- begin
- dwFlags := ACM_STREAMOPENF_QUERY;
- if not RealTime then dwFlags := dwFlags or ACM_STREAMOPENF_NONREALTIME;
- if (acmStreamOpen(nil, 0, pwfxSrc, pwfxDst, nil, 0, 0, dwFlags) = 0) then
- begin
- Result := True;
- exit;
- end
- {$IFDEF USEWAVEMPEG}
- else if ((pwfxSrc.wFormatTag = WAVE_FORMAT_MPEG) or
- (pwfxSrc.wFormatTag = WAVE_FORMAT_MPEG_LAYER3)) and
- (pwfxDst.wFormatTag = WAVE_FORMAT_PCM) then
- begin
- if (pwfxSrc^.nSamplesPerSec = pwfxDst.nSamplesPerSec) and
- (pwfxSrc^.nChannels = pwfxDst.nChannels) then
- begin
- Result := True;
- exit;
- end;
- end
- {$ENDIF};
- pwfx := Pointer(@Buf);
- FillChar(pwfx^, sizeOf(pwfx^), 0);
- if (pwfxSrc^.wFormatTag <> WAVE_FORMAT_PCM) then
- begin
- pwfx^.wFormatTag := WAVE_FORMAT_PCM;
- pwfx^.nChannels := pwfxDst^.nChannels;
- pwfx^.nSamplesPerSec := pwfxDst^.nSamplesPerSec;
- dwSuggest := ACM_FORMATSUGGESTF_WFORMATTAG or
- ACM_FORMATSUGGESTF_NCHANNELS or
- ACM_FORMATSUGGESTF_NSAMPLESPERSEC;
- { 'suggest' a format' }
- if acmFormatSuggest(0, pwfxSrc, pwfx, SizeOf(Buf), dwSuggest) = 0 then
- goto ready;
- dwSuggest := ACM_FORMATSUGGESTF_WFORMATTAG;
- { 'suggest' a format' }
- if acmFormatSuggest(0, pwfxSrc, pwfx, SizeOf(Buf), dwSuggest) = 0 then
- goto ready;
- end
- else if (pwfxSrc^.nChannels <> pwfxDst^.nChannels) or
- (pwfxSrc^.nSamplesPerSec <> pwfxDst^.nSamplesPerSec) then
- begin
- pwfx^.nChannels := pwfxDst^.nChannels;
- pwfx^.nSamplesPerSec := pwfxDst^.nSamplesPerSec;
- dwSuggest := ACM_FORMATSUGGESTF_NCHANNELS or
- ACM_FORMATSUGGESTF_NSAMPLESPERSEC;
- { 'suggest' a format' }
- if acmFormatSuggest(0, pwfxSrc, pwfx, SizeOf(Buf), dwSuggest) = 0 then
- begin
- if (acmStreamOpen(nil, 0, pwfx, pwfxDst, nil, 0, 0, dwFlags) = 0) then
- goto ready;
- if (pwfx^.wBitsperSample = 16) then
- pwfx^.wBitsPerSample := 8
- else
- pwfx^.wBitsPerSample := 16;
- dwSuggest := dwSuggest or ACM_FORMATSUGGESTF_WBITSPERSAMPLE;
- if acmFormatSuggest(0, pwfxSrc, pwfx, SizeOf(Buf), dwSuggest) = 0 then
- goto ready;
- end;
- end;
- exit;
- Ready:
- if (acmStreamOpen(nil, 0, pwfxSrc, pwfx, nil, 0, 0, dwFlags) <> 0) then
- exit;
- if acmMustConvert(pwfx,pwfxDst) then
- Result := acmQueryConvert(pwfx,pwfxDst,RealTime)
- else
- Result := True;
- end
- else Result := True;
- end;
- end;
- {-------------------------------------------------------------------------}
- function acmSizeOutputData(pwfxSrc,pwfxDst: PWaveFormatEx; SrcBufSize: Longint): Longint;
- var
- Ready: Boolean;
- ACMStream: THACMSTREAM;
- begin
- Result := -1;
- if (pwfxSrc <> nil) and (pwfxDst <> nil) then
- begin
- Ready := False;
- try
- if acmStreamOpen(@ACMStream, 0, pwfxSrc, pwfxDst, nil, 0, 0, 0) <> 0 then
- exit;
- try
- if acmStreamSize(ACMStream, SrcBufSize, Result, ACM_STREAMSIZEF_SOURCE) <> 0 then
- exit;
- Ready := True;
- finally
- acmStreamClose(ACMStream, 0);
- end;
- finally
- {$IFDEF USEWAVEMPEG}
- if not Ready and ((pwfxSrc.wFormatTag = WAVE_FORMAT_MPEG) or
- (pwfxSrc.wFormatTag = WAVE_FORMAT_MPEG_LAYER3)) then
- begin
- Result := ((SrcBufSize*pwfxDst^.nAvgBytesPerSec) div pwfxSrc^.nAvgBytesPerSec)+4096;
- end;
- {$ENDIF}
- end;
- end;
- end;
- {------------------------------------------------------------------------}
- function acmInitConvert(lpACMConvert: PACMConvert; pwfxSrc,pwfxDst: PWaveFormatEx; RealTime: Boolean): Boolean;
- Label Ready;
- var
- Buf: array[0..1024] of Char;
- pwfx: PWaveFormatEx;
- dwSuggest,dwFlags: Longint;
- bFreeSrc: Boolean;
- function SetupConvert(pwfxSrc, pwfxDst: PWaveFormatEx; UseMpeg: Boolean): Boolean;
- var
- Stream: PACMStream;
- dwOpenFlags: Longint;
- begin
- Result := False;
- if not UseMpeg then
- begin
- Stream := GlobalAllocMem(sizeOf(TACMStream));
- with Stream^ do
- try
- dwOpenFlags := 0;
- if not RealTime then dwOpenFlags := ACM_STREAMOPENF_NONREALTIME;
- if acmStreamOpen(@acmStream, 0, pwfxSrc, pwfxDst, nil, 0, 0, dwOpenFlags) <> 0 then
- exit;
- if (lpACMConvert^.lpDstBuffer <> nil) then
- begin
- dwSrcBufferSize:= lpACMConvert^.dwDstBufferSize;
- lpSrcBuffer := lpACMConvert^.lpDstBuffer;
- bFreeSrc := False;
- end
- else
- begin
- if (lpACMConvert^.lpSrcBuffer = nil) then
- begin
- dwSrcBufferSize:= 4*lpACMConvert^.dwSrcBufferSize;
- lpSrcBuffer := GlobalAllocMem(dwSrcBufferSize);
- bFreeSrc := True;
- lpACMConvert^.bFreeSrcBuffer := True;
- end
- else
- begin
- dwSrcBufferSize:= lpACMConvert^.dwSrcBufferSize;
- lpSrcBuffer := lpACMConvert^.lpSrcBuffer;
- bFreeSrc := False;
- end;
- end;
- if acmStreamSize(acmStream, dwSrcBufferSize, dwDstBufferSize, ACM_STREAMSIZEF_SOURCE) <> 0 then
- exit;
- lpDstBuffer := GlobalAllocMem(dwDstBufferSize);
- { setup the first stream header structure }
- with acmStreamHeader do
- begin
- cbStruct := sizeof(TACMStreamHeader);
- fdwStatus := 0;
- dwUser := 0;
- pbSrc := lpSrcBuffer;
- cbSrcLength := dwSrcBufferSize;
- cbSrcLengthUsed := 0;
- dwSrcUser := dwSrcBufferSize;
- pbDst := lpDstBuffer;
- cbDstLength := dwDstBufferSize;
- cbDstLengthUsed := 0;
- dwDstUser := dwDstBufferSize;
- end;
- dwRemaining := 0;
- if acmStreamPrepareHeader(acmStream, @acmStreamHeader, 0) <> 0 then
- exit;
- lpACMConvert^.lpDstBuffer := lpDstBuffer;
- lpACMConvert^.dwDstBufferSize := dwDstBufferSize;
- lpACMConvert^.Streams.Add(Stream);
- Result := True;
- finally
- if not Result then
- begin
- acmStreamUnprepareHeader(acmStream, @acmStreamHeader, 0);
- acmStreamClose(acmStream, 0);
- if bFreeSrc then GlobalFreeMem(Pointer(lpSrcBuffer));
- GlobalFreeMem(Pointer(lpDstBuffer));
- GlobalFreeMem(Pointer(Stream));
- end;
- end;
- end
- {$IFDEF USEWAVEMPEG}
- else
- with lpACMConvert^ do
- begin
- try
- if (pwfxSrc.wFormatTag = WAVE_FORMAT_MPEG_LAYER3) then
- begin
- bUseL3Decoder := True;
- pL3DLL := mp3DecInit;
- if (pL3DLL = 0) then exit;
- dwDstBufferSize := 2*((dwSrcBufferSize*pwfxDst^.nAvgBytesPerSec) div pwfxSrc^.nAvgBytesPerSec);
- lpDstBuffer := GlobalAllocMem(dwDstBufferSize);
- if mp3DecOpenEx(pL3DLL,@lpDecBuffer,sizeOf(lpDecBuffer),0,0,0,False) <> 0 then
- begin
- Result := False;
- exit;
- end;
- { create critical section object }
- FillChar(DataSection, SizeOf(DataSection), 0);
- InitializeCriticalSection(DataSection);
- end
- else
- begin
- bUseL2Decoder := True;
- pL2DLL := CreateL2DLLInstance;
- if (pL2DLL = nil) then exit;
- dwDstBufferSize := ((dwSrcBufferSize*pwfxDst^.nAvgBytesPerSec) div pwfxSrc^.nAvgBytesPerSec)+4096;
- lpDstBuffer := GlobalAllocMem(dwDstBufferSize);
- if (pL2DLL.mpegOpen('external://', 0, 0,0, 0) <> 0) then
- begin
- Result := False;
- exit;
- end;
- pL2DLL.mpegCommand(0, MP3_KEY, 0, 0, MP3_KEY_STR);
- { create critical section object }
- FillChar(DataSection, SizeOf(DataSection), 0);
- InitializeCriticalSection(DataSection);
- end;
- Result := True;
- finally
- if not Result then
- begin
- if (pL3DLL <> 0) then
- begin
- mp3DecClose(pL3DLL);
- mp3DecDone(pL3DLL);
- pL3DLL := 0;
- GlobalFreeMem(Pointer(lpDstBuffer));
- end;
- if (pl2DLL <> nil) then
- begin
- pL2DLL.mpegClose;
- FreeL2DLLInstance(pL2DLL);
- pL2DLL := nil;
- GlobalFreeMem(Pointer(lpDstBuffer));
- end;
- end;
- end;
- end
- {$ENDIF};
- end;
- begin
- Result := False;
- if acmDLLLoaded and (HiWord(acmGetVersion) >= $0200) and
- (pwfxSrc <> nil) and (pwfxSrc <> nil) then
- begin
- if acmMustConvert(pwfxSrc,pwfxDst) then
- begin
- dwFlags := ACM_STREAMOPENF_QUERY;
- if not RealTime then dwFlags := dwFlags or ACM_STREAMOPENF_NONREALTIME;
- {$IFDEF USEWAVEMPEG}
- if ((pwfxSrc.wFormatTag = WAVE_FORMAT_MPEG) or
- (pwfxSrc.wFormatTag = WAVE_FORMAT_MPEG_LAYER3)) and
- (pwfxDst.wFormatTag = WAVE_FORMAT_PCM) then
- begin
- if (pwfxSrc^.nSamplesPerSec = pwfxDst.nSamplesPerSec) and
- (pwfxSrc^.nChannels = pwfxDst.nChannels) then
- begin
- Result := SetupConvert(pwfxSrc,pwfxDst,True);
- exit;
- end;
- end
- {$ENDIF};
- if (acmStreamOpen(nil, 0, pwfxSrc, pwfxDst, nil, 0, 0, dwFlags) = 0) then
- begin
- Result := SetupConvert(pwfxSrc,pwfxDst,False);
- exit;
- end;
- pwfx := Pointer(@Buf);
- FillChar(pwfx^, sizeOf(pwfx^), 0);
- if (pwfxSrc^.wFormatTag <> WAVE_FORMAT_PCM) then
- begin
- pwfx^.wFormatTag := WAVE_FORMAT_PCM;
- pwfx^.nChannels := pwfxDst^.nChannels;
- pwfx^.nSamplesPerSec := pwfxDst^.nSamplesPerSec;
- dwSuggest := ACM_FORMATSUGGESTF_WFORMATTAG or
- ACM_FORMATSUGGESTF_NCHANNELS or
- ACM_FORMATSUGGESTF_NSAMPLESPERSEC;
- { 'suggest' a format' }
- if acmFormatSuggest(0, pwfxSrc, pwfx, sizeOf(Buf), dwSuggest) = 0 then
- goto ready;
- dwSuggest := ACM_FORMATSUGGESTF_WFORMATTAG;
- { 'suggest' a format' }
- if acmFormatSuggest(0, pwfxSrc, pwfx, sizeOf(Buf), dwSuggest) = 0 then
- goto ready;
- end
- else if (pwfxSrc^.nChannels <> pwfxDst^.nChannels) or
- (pwfxSrc^.nSamplesPerSec <> pwfxDst^.nSamplesPerSec) then
- begin
- pwfx^.nChannels := pwfxDst^.nChannels;
- pwfx^.nSamplesPerSec := pwfxDst^.nSamplesPerSec;
- dwSuggest := ACM_FORMATSUGGESTF_NCHANNELS or
- ACM_FORMATSUGGESTF_NSAMPLESPERSEC;
- { 'suggest' a format' }
- if acmFormatSuggest(0, pwfxSrc, pwfx, SizeOf(Buf), dwSuggest) = 0 then
- begin
- if (acmStreamOpen(nil, 0, pwfx, pwfxDst, nil, 0, 0, dwFlags) = 0) then
- goto ready;
- if (pwfx^.wBitsperSample = 16) then
- pwfx^.wBitsPerSample := 8
- else
- pwfx^.wBitsPerSample := 16;
- dwSuggest := dwSuggest or ACM_FORMATSUGGESTF_WBITSPERSAMPLE;
- if acmFormatSuggest(0, pwfxSrc, pwfx, sizeOf(Buf), dwSuggest) = 0 then
- goto ready;
- end;
- end;
- exit;
- Ready:
- if (acmStreamOpen(nil, 0, pwfxSrc, pwfx, nil, 0, 0, dwFlags) <> 0) then
- exit;
- Result := SetupConvert(pwfxSrc,pwfx,False);
- if Result and acmMustConvert(pwfx,pwfxDst) then
- Result := acmInitConvert(lpACMConvert,pwfx,pwfxDst,RealTime);
- end;
- end;
- end;
- {-------------------------------------------------------------------------}
- function acmBeginConvert(pwfxSrc,pwfxDst: PWaveFormatEx;
- SrcBuffer: PChar; SrcBufSize: Longint;
- RealTime: Boolean): PACMConvert;
- begin
- if acmDLLLoaded and (HiWord(acmGetVersion) >= $0200) and
- (pwfxSrc <> nil) and (pwfxDst <> nil) then
- begin
- Result := GlobalAllocMem(sizeOf(TACMConvert));
- with Result^ do
- begin
- Streams := TList.Create;
- lpSrcBuffer := SrcBuffer;
- dwSrcBufferSize := (SrcBufSize div pwfxSrc^.nBlockAlign)*pwfxSrc^.nBlockAlign;
- lpDstBuffer := nil;
- dwDstBufferSize := 0;
- bPending := False;
- bQueued := False;
- bFreeSrcBuffer := False;
- if not acmInitConvert(Result, pwfxSrc, pwfxDst, RealTime) then
- begin
- acmDoneConvert(Result);
- exit;
- end;
- {$IFDEF USEWAVEMPEG}
- if (lpSrcBuffer = nil) then
- begin
- lpSrcBuffer := GlobalAllocMem(dwSrcBufferSize);
- bFreeSrcBuffer := True;
- end;
- {$ELSE}
- if (Streams.Count > 0) then
- lpSrcBuffer := PACMStream(Streams[0])^.lpSrcBuffer;
- {$ENDIF}
- end;
- end;
- end;
- {-------------------------------------------------------------------------}
- function acmDoConvert(pConvert: PACMConvert; SrcBufSize: Longint): Longint;
- var
- i: integer;
- nConvert: Longint;
- {$IFDEF USEWAVEMPEG}
- info: Tmpgainfo;
- Res,nRead,nFree,nFill,nBytes: DWORD;
- TryCount: Longint;
- {$ENDIF}
- begin
- Result := -1;
- if (pConvert <> nil) then
- with pConvert^ do
- begin
- nConvert := 0;
- {$IFDEF USEWAVEMPEG}
- if not bUseL3Decoder and not bUseL2Decoder then
- {$ENDIF}
- begin
- nConvert := Min(SrcBufSize,dwSrcBufferSize);
- bPending := False;
- bQueued := False;
- for i := 0 to Streams.Count-1 do
- with PACMStream(Streams[i])^,PACMStream(Streams[i])^.acmStreamHeader do
- begin
- if (dwRemaining > 0) then
- begin
- { copy the reamaining bytes to the start }
- GlobalMoveMem(pbSrc^,(pbSrc+dwRemaining)^,nConvert);
- GlobalMoveMem(((pbSrc+dwSrcUser)-dwRemaining)^,pbSrc^,dwRemaining);
- cbSrcLength := nConvert+dwRemaining;
- end
- else cbSrcLength := nConvert;
- if acmStreamConvert(acmStream, @acmStreamHeader,
- ACM_STREAMCONVERTF_BLOCKALIGN) = 0 then
- begin
- { wait until the converting is done }
- while (fdwStatus and ACMSTREAMHEADER_STATUSF_DONE = 0) do;
- nConvert := cbDstLengthUsed;
- dwRemaining := cbSrcLength-cbSrcLengthUsed;
- if (dwRemaining > 0) then
- begin
- { move the remaining bytes to the end of the buffer }
- GlobalMoveMem((pbSrc+cbSrcLengthUsed)^,(pbSrc+dwSrcUser-dwRemaining)^,dwRemaining);
- bPending := True;
- end
- else
- begin
- if (nConvert = 0) and (cbSrcLengthUsed > 0) then
- bQueued := True;
- end;
- end
- else exit;
- end;
- end
- {$IFDEF USEWAVEMPEG}
- else if bUseL3Decoder then
- begin
- EnterCriticalSection(DataSection);
- try
- nBytes := SrcBufSize;
- mp3DecGetInputFree(pL3DLL, @nFree);
- mp3DecFill(pL3DLL,lpSrcBuffer, Min(nBytes,nFree), @nFill);
- dec(nBytes,nFill);
- nConvert := 0;
- nRead := 0;
- bQueued := True;
- TryCount := 0;
- while True do
- begin
- inc(TryCount);
- Res := mp3DecDecode(pL3DLL, (lpDstBuffer+nConvert), dwDstBufferSize-nConvert, @nRead, @info);
- case Res of
- MPGA_WARNING_SYNCEOF: break;
- MPGA_WARNING_SYNCNEEDDATA: begin
- if (nBytes > 0) then
- begin
- mp3DecGetInputFree(pL3DLL, @nFree);
- mp3DecFill(pL3DLL,lpSrcBuffer+(SrcBufSize-nBytes), Min(nBytes,nFree), @nFill);
- dec(nBytes,nFill);
- end
- else break;
- end;
- MPGA_WARNING_SYNCSEARCH: begin
- if (nConvert > 0) then
- break
- else
- begin
- if (TryCount > 100) then exit;
- continue;
- end;
- end;
- MPGA_WARNING_SYNCLOST: continue;
- MPGA_OK: begin
- inc(nConvert,nRead);
- end;
- else break;
- end;
- end;
- finally
- if (nBytes > 0) then
- begin
- mp3DecGetInputFree(pL3DLL, @nFree);
- mp3DecFill(pL3DLL,lpSrcBuffer+(SrcBufSize-nBytes), Min(nBytes,nFree), @nFill);
- dec(nBytes,nFill);
- end;
- LeaveCriticalSection(DataSection);
- end;
- end
- else if bUseL2Decoder then
- begin
- EnterCriticalSection(DataSection);
- try
- pL2DLL.mpegCommand(0,CMD_EXTERNALIO_FILL,integer(lpSrcBuffer),SrcBufSize,@nRead);
- nConvert := 0;
- nRead := 0;
- bQueued := True;
- TryCount := 0;
- while True do
- begin
- inc(TryCount);
- Res := pL2DLL.mpegGetFrame((lpDstBuffer+nConvert), @nRead, @info);
- case Res of
- MPGA_WARNING_SYNCEOF: break;
- MPGA_WARNING_SYNCNEEDDATA: begin
- break;
- end;
- MPGA_WARNING_SYNCSEARCH: begin
- if (nConvert > 0) then
- break
- else
- begin
- if (TryCount > 100) then exit;
- continue;
- end;
- end;
- MPGA_WARNING_SYNCLOST: continue;
- MPGA_OK: begin
- inc(nConvert,nRead);
- end;
- else break;
- end;
- Sleep(1);
- end;
- finally
- LeaveCriticalSection(DataSection);
- end;
- end
- {$ENDIF};
- Result := nConvert;
- dwBytesConverted := nConvert;
- dwBytesRead := 0;
- end;
- end;
- {-------------------------------------------------------------------------}
- function acmFlushConvert(pConvert: PACMConvert): Boolean;
- var
- i: integer;
- begin
- Result := False;
- if (pConvert <> nil) then
- with pConvert^ do
- begin
- dwBytesRead := dwBytesConverted;
- bPending := False;
- bQueued := False;
- {$IFDEF USEWAVEMPEG}
- if not bUseL3Decoder and not bUseL2Decoder then
- {$ENDIF}
- begin
- for i := 0 to Streams.Count-1 do
- with PACMStream(Streams[i])^,PACMStream(Streams[i])^.acmStreamHeader do
- begin
- dwRemaining := 0;
- cbSrcLength := 0;
- acmStreamConvert(acmStream, @acmStreamHeader,
- ACM_STREAMCONVERTF_START or ACM_STREAMCONVERTF_END);
- end;
- Result := True;
- end
- {$IFDEF USEWAVEMPEG}
- else if bUseL3Decoder then
- begin
- if (pL3DLL <> 0) then
- begin
- EnterCriticalSection(DataSection);
- try
- if (mp3DecReset(pL3DLL, 0) <> 0) then
- begin
- Result := False;
- exit;
- end;
- Result := True;
- finally
- LeaveCriticalSection(DataSection);
- end;
- end;
- end
- else if bUseL2Decoder then
- begin
- if (pL2DLL <> nil) then
- begin
- EnterCriticalSection(DataSection);
- try
- pL2DLL.mpegClose;
- if (pL2DLL.mpegOpen('external://', 0, 0,0, 0) <> 0) then
- begin
- Result := False;
- exit;
- end;
- pL2DLL.mpegCommand(0, MP3_KEY, 0, 0, MP3_KEY_STR);
- Result := True;
- finally
- LeaveCriticalSection(DataSection);
- end;
- end;
- end
- {$ENDIF};
- end;
- end;
- {-------------------------------------------------------------------------}
- function acmEndConvert(pConvert: PACMConvert; SrcBufSize: Longint): Longint;
- var
- i: integer;
- nConvert: Longint;
- {$IFDEF USEWAVEMPEG}
- info: Tmpgainfo;
- Res,nRead: DWORD;
- {$ENDIF}
- begin
- Result := -1;
- if (pConvert <> nil) then
- with pConvert^ do
- begin
- nConvert := 0;
- {$IFDEF USEWAVEMPEG}
- if not bUseL3Decoder and not bUseL2Decoder then
- {$ENDIF}
- begin
- nConvert := Min(SrcBufSize,dwSrcBufferSize);
- bPending := False;
- for i := 0 to Streams.Count-1 do
- with PACMStream(Streams[i])^,PACMStream(Streams[i])^.acmStreamHeader do
- begin
- if (dwRemaining > 0) then
- begin
- { copy the reamaining bytes to the start }
- GlobalMoveMem(pbSrc^,(pbSrc+dwRemaining)^,nConvert);
- GlobalMoveMem(((pbSrc+dwSrcUser)-dwRemaining)^,pbSrc^,dwRemaining);
- cbSrcLength := nConvert+dwRemaining;
- end
- else cbSrcLength := nConvert;
- if acmStreamConvert(acmStream, @acmStreamHeader,
- ACM_STREAMCONVERTF_END) = 0 then
- begin
- { wait until the converting is done }
- while (fdwStatus and ACMSTREAMHEADER_STATUSF_DONE = 0) do;
- nConvert := cbDstLengthUsed;
- dwRemaining := cbSrcLength-cbSrcLengthUsed;
- if (dwRemaining > 0) then
- begin
- { move the remaining bytes to the end of the buffer }
- GlobalMoveMem((pbSrc+cbSrcLengthUsed)^,(pbSrc+dwSrcUser-dwRemaining)^,dwRemaining);
- bPending := True;
- end;
- end
- else exit;
- end;
- end
- {$IFDEF USEWAVEMPEG}
- else if bUseL3Decoder then
- begin
- EnterCriticalSection(DataSection);
- try
- mp3DecSetInputEof(pL3DLL);
- nConvert := 0;
- nRead := 0;
- while True do
- begin
- Res := mp3DecDecode(pL3DLL, (lpDstBuffer+nConvert), dwDstBufferSize-nConvert, @nRead, @info);
- if (Res <> MPGA_OK) then break;
- inc(nConvert,nRead);
- end;
- finally
- LeaveCriticalSection(DataSection);
- end;
- end
- else if bUseL2Decoder then
- begin
- EnterCriticalSection(DataSection);
- try
- pL2DLL.mpegCommand(0,CMD_EXTERNALIO_SETEOF,0,0,nil);
- nConvert := 0;
- nRead := 0;
- while True do
- begin
- Res := pL2DLL.mpegGetFrame((lpDstBuffer+nConvert), @nRead, @info);
- if (Res <> MPGA_OK) then break;
- inc(nConvert,nRead);
- end;
- finally
- LeaveCriticalSection(DataSection);
- end;
- end;
- {$ENDIF};
- Result := nConvert;
- dwBytesConverted := nConvert;
- dwBytesRead := 0;
- end;
- end;
- {-------------------------------------------------------------------------}
- procedure acmDoneConvert(var pConvert: PACMConvert);
- var
- i: integer;
- p: Pointer;
- begin
- if (pConvert <> nil) then
- with pConvert^ do
- begin
- {$IFDEF USEWAVEMPEG}
- if not bUseL3Decoder and not bUseL2Decoder then
- {$ENDIF}
- begin
- for i := Streams.Count-1 downto 0 do
- with PACMStream(Streams[i])^,PACMStream(Streams[i])^.acmStreamHeader do
- begin
- if (fdwStatus and ACMSTREAMHEADER_STATUSF_PREPARED <> 0) then
- begin
- cbSrcLength := dwSrcUser;
- cbDstLength := dwDstUser;
- acmStreamUnprepareHeader(acmStream, @acmStreamHeader, 0);
- acmStreamClose(acmStream, 0);
- end;
- GlobalFreeMem(Pointer(lpDstBuffer));
- p := Streams[i];
- Streams.Delete(i);
- GlobalFreeMem(p);
- end;
- Streams.Free;
- end
- {$IFDEF USEWAVEMPEG}
- else if bUseL3Decoder then
- begin
- if (pL3DLL <> 0) then
- begin
- EnterCriticalSection(DataSection);
- try
- mp3DecClose(pL3DLL);
- mp3DecDone(pL3DLL);
- pL3DLL := 0;
- GlobalFreeMem(Pointer(lpDstBuffer));
- finally
- LeaveCriticalSection(DataSection);
- DeleteCriticalSection(DataSection);
- end;
- end;
- end
- else if bUseL2Decoder then
- begin
- if (pL2DLL <> nil) then
- begin
- EnterCriticalSection(DataSection);
- try
- pL2DLL.mpegClose;
- FreeL2DLLInstance(pL2DLL);
- pL2DLL := nil;
- GlobalFreeMem(Pointer(lpDstBuffer));
- finally
- LeaveCriticalSection(DataSection);
- DeleteCriticalSection(DataSection);
- end;
- end;
- end
- {$ENDIF};
- if bFreeSrcBuffer then GlobalFreeMem(Pointer(pConvert^.lpSrcBuffer));
- end;
- GlobalFreeMem(Pointer(pConvert));
- end;
- end.