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

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: 11.04.98 - 04:29:50 $                                        =}
  24. {========================================================================}
  25. unit MMPlgDSP;
  26. {$I COMPILER.INC}
  27. interface
  28. uses
  29.     Windows,
  30.     Messages,
  31.     SysUtils,
  32.     Forms,
  33.     MMUtils,
  34.     MMSystem,
  35.     MMRegs;
  36. const
  37.     DSP_HDRVER       = $10;
  38. type
  39.     TScaleLayer3     = array [0..1 , 0..31 , 0..17] of Single;  (* Layer3 Amplification array *)
  40.     TScaleLayer2     = array [0..1 , 0..31 , 0..35] of Single;  (* Layer2 Amplification array *)
  41.     TShortData       = array [0 .. 20000] of Smallint;          (* Sample array *)
  42.     PShortData       = ^TShortData;                             (* Pointer to Sample-Array *)
  43.     PPlugInDSPModule = ^TPlugInDSPModule;
  44.     TPlugInDSPModule = record          (* PlugIn DSP-module type *)
  45.         Description         : PChar;
  46.         hWNDParent          : HWND;    {parent window (filled in by Application)}
  47.         hDLLInstance        : HINST;   {instance handle to this DLL (filled in by Application)}
  48.         sRate               : integer; {sample rate (filled in by Application)}
  49.         nCh                 : integer; {number of channels (filled in by Application)}
  50.         BlockSize           : Integer; {BlockSize (filled in by Application)}
  51.         Config              : procedure(This_Mod: PPlugInDSPModule); cdecl;
  52.         Init                : function (This_Mod: PPlugInDSPModule): Integer; cdecl;
  53.         Restart             : function (This_Mod: PPlugInDSPModule): Integer; cdecl;
  54.         ModifySamples       : procedure(This_Mod: PPlugInDSPModule; Samples: PShortData); cdecl;
  55.         ModifyLayer3XR      : procedure(This_Mod: PPlugInDSPModule; var Xr: TScaleLayer3); cdecl;
  56.         ModifyLayer2Subband : procedure(This_Mod: PPlugInDSPModule; var Subbands: TScaleLayer2); cdecl;
  57.         Quit                : procedure(This_Mod: PPlugInDSPModule); cdecl;
  58.         UserData            : Pointer;
  59.     end;
  60.     PPlugInDSPModule2 = ^TPlugInDSPModule2;
  61.     TPlugInDSPModule2 = record          (* PlugIn DSP-module type *)
  62.         Description         : PChar;
  63.         hWNDParent          : HWND;    {parent window (filled in by Application)}
  64.         hDLLInstance        : HINST;   {instance handle to this DLL (filled in by Application)}
  65.         Config              : procedure(This_Mod: PPlugInDSPModule2); cdecl;
  66.         Init                : function (This_Mod: PPlugInDSPModule2): Integer; cdecl;
  67.         ModifySamples       : function (This_Mod: PPlugInDSPModule2; Samples: PShortData; nSamples, bps, nch, srate: integer): integer; cdecl;
  68.         Quit                : procedure(This_Mod: PPlugInDSPModule2); cdecl;
  69.         UserData            : Pointer;
  70.     end;
  71.     PPlugInDSPHeader = ^TPlugInDSPheader;
  72.     TPlugInDSPHeader = packed record   (* PlugIn DSP Header *)
  73.         Version             : Integer; (* PlugIn DSP version ID , PlugIn checks this *)
  74.         Description         : PChar;   (* Name of the DSP-plugin *)
  75.         GetModule           : function(Idx: Integer): Pointer; cdecl;
  76.     end;
  77.     PDSPModule       = ^TDSPModule;
  78.     TDSPModule       = packed record
  79.         Description         : string;
  80.         Active              : Boolean;
  81.         ModuleData          : PPlugInDSPModule;
  82.         ModuleData2         : PPlugInDSPModule2;
  83.     end;
  84.     PPlugInDSP       = ^TPlugInDSP;
  85.     TPlugInDSP       = packed record
  86.         DLLName             : string;
  87.         DLLInstance         : THandle;
  88.         Description         : string;
  89.         Modules             : array[0..99] of TDSPModule;
  90.         NumModules          : integer;
  91.         Open                : Boolean;
  92.         Header              : PPlugInDSPHeader;
  93.     end;
  94. function  ReadPlugInDSP(FileName: string): PPlugInDSP;
  95. procedure FreePlugInDSP(var PlugIn: PPlugInDSP);
  96. function  OpenPlugInDSP(PlugIn: PPlugInDSP; ParentWindow: HWND): Boolean;
  97. procedure ClosePlugInDSP(PlugIn: PPlugInDSP);
  98. procedure ConfigPlugInDSPModule(Module: TDSPModule);
  99. function  InitPlugInDSPModule(var Module: TDSPModule; pwfx: PWaveFormatEx; BytesPerBlock: Longint): Boolean;
  100. function  RestartPlugInDSPModule(var Module: TDSPModule; pwfx: PWaveFormatEx; BytesPerBlock: Longint): Boolean;
  101. function  ModifySamplesPlugInDSP(var Module: TDSPModule; Buffer: PSmallint; nBytes: Longint; pwfx: PWaveFormatEx): Longint;
  102. procedure QuitPlugInDSPModule(var Module: TDSPModule);
  103. implementation
  104. type
  105.     TGetHeader           = function : PPlugInDSPHeader; cdecl;
  106.     TGetModule           = function (Which: Integer) : Pointer; cdecl;
  107.     TConfig              = procedure(This_Mod: Pointer); cdecl;
  108.     TInit                = function (This_Mod: Pointer): Integer; cdecl;
  109.     TRestart             = function (This_Mod: Pointer): Integer; cdecl;
  110.     TQuit                = procedure(This_Mod: Pointer); cdecl;
  111.     TModifySamples       = procedure(This_Mod: Pointer; Samples: PShortData); cdecl;
  112.     TModifySamples2      = function (This_Mod: Pointer; Samples: PShortData; nSamples, bps, nch, srate: integer): integer; cdecl;
  113.     TModifyLayer3XR      = procedure(This_Mod: Pointer; var Xr : TscaleLayer3); cdecl;
  114.     TModifyLayer2Subband = procedure(This_Mod: Pointer; var Subbands: TScaleLayer2); cdecl;
  115. {==============================================================================}
  116. function ReadPlugInDSP(FileName: string): PPlugInDSP;
  117. var
  118.    hPlugIn   : THandle;
  119.    EntryPoint: TFarProc;
  120.    GetHeader : TGetHeader;
  121.    GetModule : TGetModule;
  122.    Hdr       : PPlugInDSPHeader;
  123.    Module    : Pointer;
  124.    Ver2      : Boolean;
  125. begin
  126.    Result := nil;
  127.    hPlugIn := LoadLibrary(PChar(FileName));
  128.    if (hPlugIn <> 0) then
  129.    begin
  130.       try
  131.          Ver2 := False;
  132.          EntryPoint := GetProcAddress(hPlugIn, 'winampDSPGetHeader');
  133.          if (EntryPoint = nil) then
  134.              EntryPoint := GetProcAddress(hPlugIn, 'MMPlugInDSPGetHeader');
  135.          if (EntryPoint = nil) then
  136.          begin
  137.             EntryPoint := GetProcAddress(hPlugIn, 'winampDSPGetHeader2');
  138.             if (EntryPoint <> nil) then Ver2 := True;
  139.          end;
  140.          if (EntryPoint <> nil) then
  141.          begin
  142.             @GetHeader := EntryPoint;
  143.             Hdr        := GetHeader; { Get PlugIn-header }
  144.             if (Hdr <> nil) and (Hdr.Version >= DSP_HDRVER) then
  145.             begin
  146.                New(Result);
  147.                with Result^ do
  148.                begin
  149.                   DLLName     := UpperCase(FileName);
  150.                   DLLInstance := 0;
  151.                   Description := StrPas(Hdr.Description);
  152.                   Header      := nil;
  153.                   Open        := False;
  154.                   GetModule   := Hdr^.GetModule;
  155.                   NumModules  := 0;
  156.                   repeat
  157.                      Module := GetModule(NumModules);
  158.                      if (Module <> nil) then
  159.                      begin
  160.                         if Ver2 then
  161.                            Modules[NumModules].Description := StrPas(PPlugInDSPModule2(Module).Description)
  162.                         else
  163.                            Modules[NumModules].Description := StrPas(PPlugInDSPModule(Module).Description);
  164.                         Modules[NumModules].ModuleData  := nil;
  165.                         Modules[NumModules].ModuleData2 := nil;
  166.                         Modules[NumModules].Active      := False;
  167.                         inc(NumModules);
  168.                      end;
  169.                   until (Module = nil) or (NumModules = 100);
  170.                end;
  171.             end;
  172.          end;
  173.       finally
  174.          FreeLibrary(hPlugIn);
  175.       end;
  176.    end;
  177. end;
  178. {==============================================================================}
  179. function OpenPlugInDSP(PlugIn: PPlugInDSP; ParentWindow: HWND): Boolean;
  180. var
  181.    EntryPoint: TFarProc;
  182.    GetHeader : TGetHeader;
  183.    GetModule : TGetModule;
  184.    Hdr       : PPlugInDSPHeader;
  185.    Module    : Pointer;
  186.    Ver2      : Boolean;
  187. begin
  188.    if (PlugIn <> nil) and not PlugIn.Open then
  189.    begin
  190.       PlugIn.DLLInstance := LoadLibrary(PChar(PlugIn.DLLname));
  191.       if (PlugIn.DLLInstance <> 0) then
  192.       begin
  193.          try
  194.             Ver2 := False;
  195.             EntryPoint := GetProcAddress(PlugIn.DLLInstance, 'winampDSPGetHeader');
  196.             if (EntryPoint = nil) then
  197.                 EntryPoint := GetProcAddress(PlugIn.DLLInstance, 'MMPlugInDSPGetHeader');
  198.             if (EntryPoint = nil) then
  199.             begin
  200.                EntryPoint := GetProcAddress(PlugIn.DLLInstance, 'winampDSPGetHeader2');
  201.                if (EntryPoint <> nil) then Ver2 := True;
  202.             end;
  203.             if (EntryPoint <> nil) then
  204.             begin
  205.                @GetHeader := EntryPoint;
  206.                Hdr        := GetHeader; { Get PlugIn-header }
  207.                if (Hdr <> nil) and (Hdr.Version >= DSP_HDRVER) then
  208.                begin
  209.                   with PlugIn^ do
  210.                   begin
  211.                      Header      := Hdr;
  212.                      GetModule   := Header^.GetModule;
  213.                      NumModules  := 0;
  214.                      repeat
  215.                         Module := GetModule(NumModules);
  216.                         if (Module <> nil) then
  217.                         begin
  218.                            if Ver2 then
  219.                            begin
  220.                               PPlugInDSPModule2(Module).HWNDParent   := ParentWindow;
  221.                               PPlugInDSPModule2(Module).hDLLInstance := PlugIn.DLLInstance;
  222.                               Modules[NumModules].ModuleData2 := Module;
  223.                            end
  224.                            else
  225.                            begin
  226.                               PPlugInDSPModule(Module).HWNDParent   := ParentWindow;
  227.                               PPlugInDSPModule(Module).hDLLInstance := PlugIn.DLLInstance;
  228.                               Modules[NumModules].ModuleData := Module;
  229.                            end;
  230.                            Modules[NumModules].Active     := False;
  231.                            inc(NumModules);
  232.                         end;
  233.                      until (Module = nil) or (NumModules = 100);
  234.                   end;
  235.                   PlugIn.Open := True;
  236.                end;
  237.             end;
  238.          finally
  239.             if not PlugIn.Open then
  240.             begin
  241.                FreeLibrary(PlugIn.DLLInstance);
  242.                PlugIn.DLLInstance := 0;
  243.             end;
  244.          end;
  245.       end;
  246.    end;
  247.    Result := (PlugIn <> nil) and PlugIn.Open;
  248. end;
  249. {==============================================================================}
  250. procedure ClosePlugInDSP(PlugIn: PPlugInDSP);
  251. var
  252.    i: integer;
  253. begin
  254.    try
  255.       if (PlugIn <> nil) and PlugIn.Open then
  256.       with PlugIn^ do
  257.       begin
  258.          for i := 0 to NumModules-1 do
  259.          begin
  260.             QuitPlugInDSPModule(Modules[i]);
  261.             Modules[i].ModuleData := nil;
  262.             Modules[i].ModuleData2:= nil;
  263.          end;
  264.          Header := nil;
  265.          PlugIn.Open := False;
  266.          if (DLLInstance <> 0) then
  267.          begin
  268.             FreeLibrary(DLLInstance);
  269.             DLLInstance := 0;
  270.          end;
  271.       end;
  272.    except
  273.       // no exception please !!!
  274.    end;
  275. end;
  276. {==============================================================================}
  277. procedure FreePlugInDSP(var PlugIn: PPlugInDSP);
  278. begin
  279.    try
  280.       if (PlugIn <> nil) then
  281.       begin
  282.          ClosePlugInDSP(PlugIn);
  283.          Dispose(PlugIn);
  284.          PlugIn := nil;
  285.       end;
  286.    except
  287.       // no exception please !!!
  288.    end;
  289. end;
  290. {==============================================================================}
  291. procedure ConfigPlugInDSPModule(Module: TDSPModule);
  292. begin
  293.    try
  294.       if (Module.ModuleData <> nil) then
  295.       begin
  296.          if assigned(Module.ModuleData.Config) then
  297.             Module.ModuleData.Config(Module.ModuleData);
  298.       end
  299.       else if (Module.ModuleData2 <> nil) then
  300.       begin
  301.          if assigned(Module.ModuleData2.Config) then
  302.             Module.ModuleData2.Config(Module.ModuleData2);
  303.       end;
  304.    except
  305.       // no exception please !!!
  306.    end;
  307. end;
  308. {==============================================================================}
  309. function InitPlugInDSPModule(var Module: TDSPModule; pwfx: PWaveFormatEx; BytesPerBlock: Longint): Boolean;
  310. begin
  311.    try
  312.       if not Module.Active and (BytesPerBlock > 0) then
  313.       begin
  314.          if (Module.ModuleData <> nil) then
  315.          begin
  316.             with Module do
  317.             begin
  318.                if (pwfx = nil) then
  319.                begin
  320.                   ModuleData.sRate     := 22050;
  321.                   ModuleData.nCh       := 1;
  322.                end
  323.                else
  324.                begin
  325.                   ModuleData.sRate     := pwfx.nSamplesPerSec;
  326.                   ModuleData.nCh       := pwfx^.nChannels;
  327.                end;
  328.                ModuleData.BlockSize := BytesPerBlock div (2*ModuleData.nCh);
  329.                if assigned(Module.ModuleData.Init) then
  330.                   Active := Module.ModuleData.Init(Module.ModuleData) = 0;
  331.             end;
  332.          end
  333.          else if (Module.ModuleData2 <> nil) then
  334.          begin
  335.             with Module do
  336.             begin
  337.                if assigned(Module.ModuleData2.Init) then
  338.                begin
  339.                   Active := Module.ModuleData2.Init(Module.ModuleData2) = 0;
  340.                end;
  341.             end;
  342.          end;
  343.       end;
  344.       Result := Module.Active;
  345.    except
  346.       Result := False;
  347.       // no exception please !!!
  348.    end;
  349. end;
  350. {==============================================================================}
  351. function RestartPlugInDSPModule(var Module: TDSPModule; pwfx: PWaveFormatEx; BytesPerBlock: Longint): Boolean;
  352. begin
  353.    try
  354.       Result := False;
  355.       if Module.Active and (BytesPerBlock > 0) then
  356.       begin
  357.          if (Module.ModuleData <> nil) then
  358.          begin
  359.             with Module do
  360.             begin
  361.                if (pwfx = nil) then
  362.                begin
  363.                   ModuleData.sRate     := 22050;
  364.                   ModuleData.nCh       := 1;
  365.                end
  366.                else
  367.                begin
  368.                   ModuleData.sRate     := pwfx.nSamplesPerSec;
  369.                   ModuleData.nCh       := pwfx^.nChannels;
  370.                end;
  371.                ModuleData.BlockSize := BytesPerBlock div (2*ModuleData.nCh);
  372.                if assigned(Module.ModuleData.Restart) then
  373.                   Result := Module.ModuleData.Restart(Module.ModuleData) = 0
  374.                else
  375.                   Result := True;
  376.             end;
  377.          end
  378.          else if (Module.ModuleData2 <> nil) then
  379.          begin
  380.             // TODO: ???
  381.             Result := True;
  382.          end;
  383.       end;
  384.    except
  385.       Result := False;
  386.       // no exception please !!!
  387.    end;
  388. end;
  389. {==============================================================================}
  390. function ModifySamplesPlugInDSP(var Module: TDSPModule; Buffer: PSmallint; nBytes: Longint; pwfx: PWaveFormatEx): Longint;
  391. var
  392.    bytesPS: integer;
  393. begin
  394.    Result := 0;
  395.    try
  396.       bytesPS := (pwfx.wBitsPerSample div 8)*pwfx.nChannels;
  397.       if (Module.ModuleData <> nil) then
  398.       begin
  399.          if Module.Active and assigned(Module.ModuleData.ModifySamples) then
  400.          begin
  401.             Module.ModuleData.ModifySamples(Module.ModuleData, Pointer(Buffer));
  402.             Result := nBytes;
  403.          end;
  404.       end
  405.       else if (Module.ModuleData2 <> nil) then
  406.       begin
  407.          if Module.Active and assigned(Module.ModuleData2.ModifySamples) then
  408.          begin
  409.             with pwfx^ do
  410.             Result := Module.ModuleData2.ModifySamples(Module.ModuleData2, Pointer(Buffer),nBytes div bytesPS,wBitsPerSample,nChannels,nSamplesPerSec)*bytesPS;
  411.          end;
  412.       end
  413.    except
  414.       // no exception please !!!
  415.    end;
  416. end;
  417. {==============================================================================}
  418. procedure QuitPlugInDSPModule(var Module: TDSPModule);
  419. begin
  420.    try
  421.       if (Module.ModuleData <> nil) then
  422.       begin
  423.          if Module.Active and assigned(Module.ModuleData.Quit) then
  424.             Module.ModuleData.Quit(Module.ModuleData);
  425.       end
  426.       else if (Module.ModuleData2 <> nil) then
  427.       begin
  428.          if Module.Active and assigned(Module.ModuleData2.Quit) then
  429.             Module.ModuleData2.Quit(Module.ModuleData2);
  430.       end;
  431.       Module.Active := False;
  432.    except
  433.       // no exception please !!!
  434.    end;
  435. end;
  436. end.