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

📄 mmacmsup.pas

📁 一套及时通讯的原码
💻 PAS
📖 第 1 页 / 共 3 页
字号:
{========================================================================}
{=                (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;

⌨️ 快捷键说明

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