MMADCvt.pas
上传用户:hylc_2004
上传日期:2014-01-23
资源大小:46800k
文件大小:15k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1. {========================================================================}
  2. {=                (c) 1995-98 SwiftSoft Ronald Dittrich                 =}
  3. {========================================================================}
  4. {=                          All Rights Reserved                         =}
  5. {========================================================================}
  6. {=  D 01099 Dresden             = Fax.: +49 (0)351-8037944              =}
  7. {=  Loewenstr.7a                = info@swiftsoft.de                     =}
  8. {========================================================================}
  9. {=  Actual versions on http://www.swiftsoft.de/mmtools.html             =}
  10. {========================================================================}
  11. {=  This code is for reference purposes only and may not be copied or   =}
  12. {=  distributed in any format electronic or otherwise except one copy   =}
  13. {=  for backup purposes.                                                =}
  14. {=                                                                      =}
  15. {=  No Delphi Component Kit or Component individually or in a collection=}
  16. {=  subclassed or otherwise from the code in this unit, or associated   =}
  17. {=  .pas, .dfm, .dcu, .asm or .obj files may be sold or distributed     =}
  18. {=  without express permission from SwiftSoft.                          =}
  19. {=                                                                      =}
  20. {=  For more licence informations please refer to the associated        =}
  21. {=  HelpFile.                                                           =}
  22. {========================================================================}
  23. {=  $Date: 09.03.98 - 23:34:41 $                                        =}
  24. {========================================================================}
  25. unit MMADCvt;
  26. {$I COMPILER.INC}
  27. interface
  28. uses
  29.     {$IFDEF WIN32}
  30.     Windows,
  31.     {$ELSE}
  32.     WinTypes,
  33.     WinProcs,
  34.     {$ENDIF}
  35.     SysUtils,
  36.     Classes,
  37.     MMSystem,
  38.     MMUtils,
  39.     MMObj,
  40.     MMDSPObj,
  41.     MMRegs,
  42.     MMWaveIO,
  43.     MMADPCM,
  44.     MMPCMSup,
  45.     MMAntex;
  46. type
  47.    EMMADPCMError = class(Exception);
  48.    {-- TMMADPCMConverter ------------------------------------------------------}
  49.    TMMADPCMConverter = class(TMMDSPComponent)
  50.    private
  51.       FEnabled     : Boolean;
  52.       FOpen        : Boolean;
  53.       FStarted     : Boolean;
  54.       FPSrcFormat  : PWaveFormatEx;
  55.       FPDstFormat  : PWaveFormatEx;
  56.       FCvtFormat   : PWaveFormatEx;
  57.       FPSrcBuffer  : PChar;
  58.       FPDstBuffer  : PChar;
  59.       FSrcBufSize  : Longint;
  60.       FDstBufSize  : Longint;
  61.       FNumConverted: Longint;
  62.       FNumRead     : Longint;
  63.       FMustConvert : Boolean;        { the format must be converted    }
  64.       FCanConvert  : Boolean;        { the format can be converted     }
  65.       FMoreBuffers : Boolean;
  66.       FDone        : Boolean;
  67.       FIsLoading   : Boolean;
  68.       Ftwh         : TMMWaveHdr;
  69.       FBits        : TMMBits;
  70.       FIMAParams   : TIMA_PARAMS;
  71.       procedure SetBits(aValue: TMMBits);
  72.       function  GetCanConvert: Boolean;
  73.       procedure PrepareConversion;
  74.    protected
  75.       procedure SuggestFormat; virtual;
  76.       procedure Loaded; override;
  77.       procedure ChangePWaveFormat(aValue: PWaveFormatEx); override;
  78.       procedure SetPWaveFormat(aValue: PWaveFormatEx); override;
  79.       procedure Opened; override;
  80.       procedure Closed; override;
  81.       procedure Started; override;
  82.       procedure Stopped; override;
  83.       procedure Reseting; override;
  84.       procedure BufferLoad(lpwh: PWaveHdr; var MoreBuffers: Boolean); override;
  85.    public
  86.       constructor Create(aOwner: TComponent); override;
  87.       destructor Destroy; override;
  88.       procedure Open;
  89.       procedure Close;
  90.       procedure Start;
  91.       procedure Stop;
  92.       property CanConvert: Boolean read GetCanConvert;
  93.    published
  94.       property Input;
  95.       property Output;
  96.       property BitLength: TMMBits read FBits write SetBits default b16Bit;
  97.       property Enabled: Boolean read FEnabled write FEnabled default True;
  98.    end;
  99. implementation
  100. const
  101.      LOADSIZE = 4096;
  102. {== TMMADPCMConverter =========================================================}
  103. constructor TMMADPCMConverter.Create(aOwner: TComponent);
  104. begin
  105.    inherited Create(aOwner);
  106.    FEnabled     := True;
  107.    FOpen        := False;
  108.    FStarted     := False;
  109.    FMustConvert := False;
  110.    FCanConvert  := False;
  111.    FPSrcFormat  := nil;
  112.    FPSrcBuffer  := nil;
  113.    FPDstBuffer  := nil;
  114.    FBits        := b16Bit;
  115.    FIsLoading   := True;
  116.    ErrorCode := ComponentRegistered(InitCode, Self, ClassName);
  117.    if (ErrorCode <> 0) then RegisterFailed(InitCode, Self , ClassName);
  118. end;
  119. {-- TMMADPCMConverter ---------------------------------------------------------}
  120. destructor TMMADPCMConverter.Destroy;
  121. begin
  122.    Close;
  123.    GlobalFreeMem(Pointer(FPSrcFormat));
  124.    GlobalFreeMem(Pointer(FPDstFormat));
  125.    GlobalFreeMem(Pointer(FCvtFormat));
  126.    inherited Destroy;
  127. end;
  128. {-- TMMADPCMConverter ---------------------------------------------------------}
  129. procedure TMMADPCMConverter.SetBits(aValue: TMMBits);
  130. begin
  131.    if (aValue <> FBits) then
  132.    begin
  133.       FBits := aValue;
  134.       PrepareConversion;
  135.    end;
  136. end;
  137. {-- TMMADPCMConverter ---------------------------------------------------------}
  138. procedure TMMADPCMConverter.Loaded;
  139. begin
  140.    inherited Loaded;
  141.    FIsLoading := False;
  142.    PrepareConversion;
  143. end;
  144. {-- TMMADPCMConverter ---------------------------------------------------------}
  145. function TMMADPCMConverter.GetCanConvert: Boolean;
  146. begin
  147.    Result := (not FMustConvert) or FCanConvert;
  148. end;
  149. {-- TMMADPCMConverter ---------------------------------------------------------}
  150. procedure TMMADPCMConverter.ChangePWaveFormat(aValue: PWaveFormatEx);
  151. begin
  152.    if (aValue <> FPSrcFormat) then
  153.    begin
  154.       GlobalFreeMem(Pointer(FPSrcFormat));
  155.       FPSrcFormat := wioCopyWaveFormat(aValue);
  156.       PrepareConversion;
  157.    end;
  158. end;
  159. {-- TMMADPCMConverter ---------------------------------------------------------}
  160. procedure TMMADPCMConverter.SetPWaveFormat(aValue: PWaveFormatEx);
  161. begin
  162.    (* TODO: setzen von WaveFormat nicht erlaubt !!! *)
  163. end;
  164. {-- TMMADPCMConverter ---------------------------------------------------------}
  165. procedure TMMADPCMConverter.SuggestFormat;
  166. var
  167.    wfx: TWaveFormatEx;
  168. begin
  169.    GlobalFreeMem(Pointer(FCvtFormat));
  170.    if (FPSrcFormat <> nil) and FEnabled then
  171.    case FPSrcFormat.wFormatTag of
  172.        WAVE_FORMAT_ADPCM:
  173.        begin
  174.           if adpcmBuildFormatHeader(FPSrcFormat, @wfx, (Ord(FBits)+1)*8,-1,-1) then
  175.              FCvtFormat := wioCopyWaveFormat(@wfx);
  176.        end;
  177.        WAVE_FORMAT_MEDIAVISION_ADPCM,
  178.        WAVE_FORMAT_ANTEX_ADPCME,
  179.        WAVE_FORMAT_ADPCME:
  180.        begin
  181.           pcmBuildWaveheader(@wfx,(Ord(FBits)+1)*8,FPSrcFormat^.nChannels,FPSrcFormat.nSamplesPerSec);
  182.           FCvtFormat := wioCopyWaveFormat(@wfx);
  183.         end;
  184.    end;
  185. end;
  186. {-- TMMADPCMConverter ---------------------------------------------------------}
  187. procedure TMMADPCMConverter.PrepareConversion;
  188. begin
  189.    FMustConvert := False;
  190.    FCanConvert := False;
  191.    if (FPSrcFormat <> nil) and FEnabled then
  192.    begin
  193.       if (FPSrcFormat^.wFormatTag <> WAVE_FORMAT_PCM) then
  194.       begin
  195.          FMustConvert := True;
  196.          SuggestFormat;
  197.          if (FCvtFormat <> nil) and (FCvtFormat^.wFormatTag = WAVE_FORMAT_PCM) then
  198.          begin
  199.             FCanConvert := True;
  200.             inherited SetPWaveFormat(FCvtFormat);
  201.             exit;
  202.          end;
  203.       end;
  204.    end;
  205.    inherited SetPWaveFormat(FPSrcFormat);
  206. end;
  207. {-- TMMADPCMConverter ---------------------------------------------------------}
  208. procedure TMMADPCMConverter.Open;
  209. begin
  210.    if not FOpen and FEnabled then
  211.    begin
  212.       if FMustConvert then
  213.       try
  214.          if FCanConvert then
  215.          begin
  216.             FSrcBufSize := LOADSIZE;
  217.             case FPSrcFormat.wFormatTag of
  218.                  WAVE_FORMAT_ADPCM:
  219.                  begin
  220.                     FDstBufSize := PADPCMWaveFormat(FPSrcFormat)^.wSamplesPerBlock * Longint(FCvtFormat^.nBlockAlign);
  221.                     FDstBufSize := FDstBufSize*(FSrcBufSize div FPSrcFormat^.nBlockAlign);
  222.                  end;
  223.                  WAVE_FORMAT_MEDIAVISION_ADPCM,
  224.                  WAVE_FORMAT_ANTEX_ADPCME,
  225.                  WAVE_FORMAT_ADPCME:
  226.                  begin
  227.                     FDstBufSize := 4*FSrcBufSize;
  228.                  end;
  229.             end;
  230.             FPSrcBuffer := GlobalAllocMem(FSrcBufSize);
  231.             FPDstBuffer := GlobalAllocMem(FDstBufSize);
  232.             if (FPSrcBuffer = nil) or (FPDstBuffer = nil) then
  233.             begin
  234.                FCanConvert := False;
  235.                exit;
  236.             end;
  237.          end;
  238.       finally
  239.          if not FCanConvert then
  240.             raise EMMADPCMError.Create('Unable to convert to destination format');
  241.       end;
  242.       FOpen := True;
  243.    end;
  244. end;
  245. {-- TMMADPCMConverter ---------------------------------------------------------}
  246. procedure TMMADPCMConverter.Close;
  247. begin
  248.    if FOpen then
  249.    begin
  250.       Stop;
  251.       FOpen := False;
  252.       GlobalFreeMem(Pointer(FPSrcBuffer));
  253.       GlobalFreeMem(Pointer(FPDstBuffer));
  254.    end;
  255. end;
  256. {-- TMMADPCMConverter ---------------------------------------------------------}
  257. procedure TMMADPCMConverter.Start;
  258. begin
  259.    if FOpen and not FStarted then
  260.    begin
  261.       FStarted := True;
  262.       FMoreBuffers := False;
  263.       FDone := False;
  264.       FNumRead := 0;
  265.       FNumConverted := 0;
  266.       FillChar(FIMAParams,sizeOf(FIMAParams),0);
  267.    end;
  268. end;
  269. {-- TMMADPCMConverter ---------------------------------------------------------}
  270. procedure TMMADPCMConverter.Stop;
  271. begin
  272.    if FStarted then
  273.    begin
  274.       FStarted := False;
  275.       FNumRead := FNumConverted;
  276.    end;
  277. end;
  278. {-- TMMADPCMConverter ---------------------------------------------------------}
  279. procedure TMMADPCMConverter.Opened;
  280. begin
  281.    Open;
  282.    inherited Opened;
  283. end;
  284. {-- TMMADPCMConverter ---------------------------------------------------------}
  285. procedure TMMADPCMConverter.Closed;
  286. begin
  287.    Close;
  288.    inherited Closed;
  289. end;
  290. {-- TMMADPCMConverter ---------------------------------------------------------}
  291. procedure TMMADPCMConverter.Started;
  292. begin
  293.    inherited Started;
  294.    Start;
  295. end;
  296. {-- TMMADPCMConverter ---------------------------------------------------------}
  297. procedure TMMADPCMConverter.Stopped;
  298. begin
  299.    Stop;
  300.    inherited Stopped;
  301. end;
  302. {-- TMMADPCMConverter ---------------------------------------------------------}
  303. procedure TMMADPCMConverter.Reseting;
  304. begin
  305.    inherited Reseting;
  306.    FNumRead := FNumConverted;
  307.    FillChar(FIMAParams,sizeOf(FIMAParams),0);
  308. end;
  309. {-- TMMADPCMConverter ---------------------------------------------------------}
  310. procedure TMMADPCMConverter.BufferLoad(lpwh: PWaveHdr; var MoreBuffers: Boolean);
  311. Label CopyData;
  312. var
  313.    nRead,nBytes: Longint;
  314. begin
  315.    if FOpen and FStarted and FEnabled then
  316.    begin
  317.       { read Data }
  318.       if (Input <> nil) then
  319.       begin
  320.          nBytes := lpwh^.dwBufferLength;
  321.          if FMustConvert and FCanConvert then
  322.          begin
  323. CopyData:
  324.             { get some data from the conversion buffer }
  325.             if (FNumConverted-FNumRead > 0) then
  326.             begin
  327.                nRead := Min(FNumConverted-FNumRead,nBytes);
  328.                GlobalMoveMem((FPDstBuffer+FNumRead)^,(lpwh^.lpData+lpwh^.dwBytesRecorded)^,nRead);
  329.                dec(nBytes,nRead);
  330.                inc(FNumRead,nRead);
  331.                inc(lpwh^.dwBytesRecorded,nRead);
  332.             end;
  333.             if not PMMWaveHdr(lpwh)^.LoopRec.dwLooping then
  334.             begin
  335.                { do we need more data ? }
  336.                if FStarted and (nBytes > 0) then
  337.                begin
  338.                   if not FDone then
  339.                   begin
  340.                      GlobalFillMem(Ftwh,sizeOf(Ftwh),0);
  341.                      Ftwh.wh.lpData := FPSrcBuffer;
  342.                      Ftwh.wh.dwBufferLength := FSrcBufSize;
  343.                      Ftwh.LoopRec := PMMWaveHdr(lpwh)^.LoopRec;
  344.                      FMoreBuffers := False;
  345.                      inherited BufferLoad(@Ftwh,FMoreBuffers);
  346.                      nRead := Ftwh.wh.dwBytesRecorded;
  347.                      PMMWaveHdr(lpwh)^.LoopRec := Ftwh.LoopRec;
  348.                      if not FMoreBuffers or (nRead <= 0) then FDone := True;
  349.                   end
  350.                   else nRead := 0;
  351.                   if (nRead > 0) and FStarted then
  352.                   begin
  353.                      case FPSrcFormat.wFormatTag of
  354.                          WAVE_FORMAT_ADPCM:
  355.                          begin
  356.                             nRead := adpcmDecode4Bit(PADPCMWaveFormat(FPSrcFormat),
  357.                                                      FCvtFormat,
  358.                                                      FPSrcBuffer, FPDstBuffer, nRead);
  359.                          end;
  360.                          WAVE_FORMAT_MEDIAVISION_ADPCM:
  361.                          begin
  362.                             if (FPSrcFormat^.nChannels = 1) then
  363.                                 nRead := wmimatopcm(FPSrcBuffer, FPDstBuffer, nRead, FIMAParams)
  364.                             else if (FPSrcFormat^.nChannels = 2) then
  365.                                 nRead := wsimatopcm(FPSrcBuffer, FPDstBuffer, nRead, FIMAParams)
  366.                             else
  367.                                 nRead := 0;
  368.                             if (FBits = b8Bit) then
  369.                                 nRead := pcmBitsPerSampleAlign(8, FPDstBuffer, 16, FPDstBuffer,nRead);
  370.                          end;
  371.                          WAVE_FORMAT_ANTEX_ADPCME,
  372.                          WAVE_FORMAT_ADPCME:
  373.                          begin
  374.                             if (FPSrcFormat^.nChannels = 1) then
  375.                                 nRead := wmdvitopcm(FPSrcBuffer, FPDstBuffer, nRead, FIMAParams)
  376.                             else if (FPSrcFormat^.nChannels = 2) then
  377.                                 nRead := wsdvitopcm(FPSrcBuffer, FPDstBuffer, nRead, FIMAParams)
  378.                             else
  379.                                 nRead := 0;
  380.                             if (FBits = b8Bit) then
  381.                                 nRead := pcmBitsPerSampleAlign(8, FPDstBuffer, 16, FPDstBuffer,nRead);
  382.                          end;
  383.                      end;
  384.                      if nRead <= 0 then
  385.                      begin
  386.                         if not FDone then
  387.                         begin
  388.                            FCanConvert := False;
  389.                            exit;
  390.                         end;
  391.                      end
  392.                      else if FStarted then
  393.                      begin
  394.                         FNumConverted := nRead;
  395.                         FNumRead      := 0;
  396.                         goto CopyData;
  397.                      end;
  398.                   end;
  399.                end;
  400.             end;
  401.             MoreBuffers := FMoreBuffers or (FNumConverted-FNumRead > 0);
  402.          end
  403.          else inherited BufferLoad(lpwh,MoreBuffers);
  404.       end;
  405.    end
  406.    else inherited BufferLoad(lpwh,MoreBuffers);
  407. end;
  408. end.