⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mmacmsup.pas

📁 一套及时通讯的原码
💻 PAS
📖 第 1 页 / 共 3 页
字号:

{------------------------------------------------------------------------}
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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -