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

📄 vismain.pas

📁 啊看见电脑哦啊师父破案对方;啊老大你发;dfadsdsfadfd发
💻 PAS
📖 第 1 页 / 共 2 页
字号:
unit VisMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, ComCtrls, StdCtrls, Mask, ToolEdit, Registry,
  WinampVisBase, ImgList, Spin, RXShell;

type
  TVisPlugInBuf = record
    DLLName : string;
    DLLHandle : THandle;
    Header : PwinampVisHeader;
    Count : integer;
    Modules : array of PwinampVisModule;
    Enables : array of Boolean;
  end;
  TVisPlugInList=array of TVisPlugInBuf;

  TMainForm = class(TForm)
    TreeView1: TTreeView;
    Panel1: TPanel;
    Label1: TLabel;
    DirectoryEdit1: TDirectoryEdit;
    CheckBox1: TCheckBox;
    Button1: TButton;
    ImageList: TImageList;
    Label2: TLabel;
    SpinEdit1: TSpinEdit;
    RxTrayIcon1: TRxTrayIcon;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure TreeView1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure TreeView1AdvancedCustomDrawItem(Sender: TCustomTreeView;
      Node: TTreeNode; State: TCustomDrawState; Stage: TCustomDrawStage;
      var PaintImages, DefaultDraw: Boolean);
    procedure TreeView1CustomDrawItem(Sender: TCustomTreeView;
      Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
    procedure TreeView1DblClick(Sender: TObject);
    procedure DirectoryEdit1Change(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure RxTrayIcon1Click(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure SpinEdit1Change(Sender: TObject);
    procedure CheckBox1Click(Sender: TObject);
  private
    { Private declarations }
    FReg : TRegistry;
    FRenderThread : TThread;
    procedure SearchPlugIn;
    function  IndexofVisPlugInList(DLLName: string): integer;
    function  AddVisPlugInList(DLLName: string): integer;
    function  IsPlugInFile(Name: string): Boolean;
    procedure TestVisParent(Node: TTreeNode; index: integer);
    procedure EnabledVisPlugIn(DLLName: string; Index: integer; Flag: Boolean);
    procedure ShowPlugInError;
    procedure SetupVisPlugIn(DLLName: string; Index: integer);
    procedure FreeVisPlugIn;
    procedure SaveVisPlugIn(sName: string);
    procedure LoadVisPlugIn(sName: string);
  public
    { Public declarations }
    procedure AddSoundData(samples : PByte;numsamples,bps,nch,srate : integer);
  end;

  TRenderThread = class(TThread)
  private
    { Private declarations }
    FOldClock : DWORD;
    FAudioBuffer : array of Byte;
    FSampleRate : integer;
    FSampleMul : integer;
    FSampleLen : integer;
    FSampleCh : integer;
    FSampleBps : integer;
    frequency : array[0..1,0..1024-1] of Byte;
    waveform : array[0..1,0..1024-1] of Byte;
    FReal,FImag : array[0..1024-1] of Double;
    procedure UpdateSoundData(pSample: pByte; len, bps, nch, srate: integer);
    procedure AnalySampleData(samples: pByte; numsamples, bps, nch: integer);
    procedure GetSpectrum(var wave, freq: array of Byte);
  protected
    procedure Execute; override;
  end;


var
  MainForm: TMainForm;
  FFrameRate : integer;
  FVisPlugInList : TVisPlugInList;
  FUsePlugIn : Boolean;
  FIsTrayIcon : Boolean;

const
  sRegistryKey = '\Software\ChangwonUniv\KMP\Visualization';
  sPluginPath = 'PluginPath';
  sVisPlugKey = 'VisPlugInKey';
  sBaseVisPreset = 'BaseVisPreset';
  sUsePlugIn = 'UsePlugIn';
  sFrameRate = 'FrameRate';
  sIsTrayIcon = 'IsTrayIcon';

  cDataLen = 1024;

implementation

{$R *.dfm}


{ TRenderThread }


procedure TRenderThread.AnalySampleData(samples: pByte; numsamples, bps, nch : integer);
var
 pw : pSmallInt;
 pb : pByte;
 i,num : integer;
begin
 if numsamples>cDataLen then num:=cDataLen
 else num:=numsamples;
 if bps=8 then begin
   pb:=pByte(samples);
   if nch=1 then begin
     for i:=0 to num-1 do begin
       waveform[0][i]:=pb^;
       inc(pb);
     end;
   end
   else if nch=2 then begin
     for i:=0 to num-1 do begin
       waveform[0][i]:=pb^;
       inc(pb);
       waveform[1][i]:=pb^;
       inc(pb);
     end;;
   end;
 end
 else if bps=16 then begin
   pw:=pSmallInt(samples);
   if nch=1 then begin
     for i:=0 to num-1 do begin
       waveform[0][i]:=((pw^) div 256)+128;
       inc(pw);
     end;
   end
   else if nch=2 then begin
     for i:=0 to num-1 do begin
       waveform[0][i]:=((pw^) div 256)+128;
       inc(pw);
       waveform[1][i]:=((pw^) div 256)+128;
       inc(pw);
     end;
   end;
 end;
end;

procedure TRenderThread.GetSpectrum(var wave,freq : array of Byte);
var
 i,j,m,mmax,istep,aa,bb : integer;
 c,s,treal,timag : double;
 theta : double;
begin
 for i:=0 to cDataLen-1 do begin
   FReal[i]:=wave[i];
   FImag[i]:=0.0;
 end;
 j:=1;
 for i:=1 to cDataLen do begin
   if(i<j) then begin
     aa:=j-1;
     bb:=i-1;
     treal:=FReal[aa];
     FReal[aa]:=FReal[bb];
     FReal[bb]:=treal;
   end;
   m:=cDataLen div 2;
   while(j>m) do begin
     j:=j-m;
     m:=(m+1) div 2;
   end;
   j:=j+m;
 end;

 mmax:=1;
 while(cDataLen>mmax) do begin
   istep:=2*mmax;
   for m:=1 to mmax do begin
     theta:=PI*(m-1)/mmax;
     c:=cos(theta);
     s:=sin(theta);
     i:=m;
     while i<=cDataLen do begin
       j:=i+mmax;
       aa:=j-1;
       bb:=i-1;
       treal:=FReal[aa]*c-FImag[aa]*s;
       timag:=FImag[aa]*c+FReal[aa]*s;
       FReal[aa]:=FReal[bb]-treal;
       FImag[aa]:=FImag[bb]-timag;
       FReal[bb]:=FReal[bb]+treal;
       FImag[bb]:=FImag[bb]+timag;
       i:=i+istep;
     end;
   end;
   mmax:=istep;
 end;
 for i:=0 to cDataLen-1 do begin
   freq[i]:=Trunc(sqrt(FReal[i]*FReal[i]+FImag[i]*FImag[i])) shr 3;
 end;
end;

procedure TRenderThread.Execute;
var
 pp,i,j : integer;
 np : DWORD;
begin
 FreeOnTerminate:=False;
 FOldClock:=0;
 while not(Terminated) do begin
   np:=GetTickCount;
   if FAudioBuffer<>nil then begin
     if FOldClock=0 then pp:=0
     else pp:=(np-FOldClock);
     pp:=pp*FSampleRate*FSampleMul div 1000;
     if pp>FSampleLen*2 then pp:=FSampleLen*2;
     if (pp and $03)<>0 then pp:=(pp shr 2) shl 2;
     AnalySampleData(@FAudioBuffer[pp],FSampleLen,FSampleBps,FSampleCh);
     GetSpectrum(waveform[0],frequency[0]);
     if FSampleCh=2 then GetSpectrum(waveform[1],frequency[1]);
     for i:=0 to Length(FVisPlugInList)-1 do begin
       for j:=0 to FVisPlugInList[i].Count-1 do begin
         if FVisPlugInList[i].Enables[j] then begin
           Move(waveform[0],FVisPlugInList[i].Modules[j]^.waveformData[0],576);
           if FSampleCh=2 then Move(waveform[1],FVisPlugInList[i].Modules[j]^.waveformData[1],576);
           FVisPlugInList[i].Modules[j]^.sRate:=FSampleRate;
           FVisPlugInList[i].Modules[j]^.nCh:=FSampleCh;
           FVisPlugInList[i].Modules[j]^.spectrumNch:=FSampleCh;
           FVisPlugInList[i].Modules[j]^.waveformNch:=FSampleCh;
           FVisPlugInList[i].Modules[j]^.Render(FVisPlugInList[i].Modules[j]);
         end;
       end;
     end;
   end;
   Sleep(FFrameRate);
 end;
end;

procedure TRenderThread.UpdateSoundData(pSample: pByte; len, bps, nch, srate: integer);
begin
 FSampleRate:=srate;
 FSampleMul:=(nch*bps div 8);
 FSampleLen:=len;
 FSampleCh:=nch;
 FSampleBps:=bps;
 if Length(FAudioBuffer)<len*4 then SetLength(FAudioBuffer,len*4);
 Move(FAudioBuffer[len],FAudioBuffer[len shl 1],len);
 Move(FAudioBuffer[0],FAudioBuffer[len],len);
 Move(pSample^,FAudioBuffer[0],len);
 FOldClock:=GetTickCount;
end;

{ TMainForm }

procedure TMainForm.AddSoundData(samples: PByte; numsamples, bps, nch, srate: integer);
begin
 if FRenderThread<>nil then TRenderThread(FRenderThread).UpdateSoundData(samples,numsamples,bps,nch,srate);
end;

procedure TMainForm.FormCreate(Sender: TObject);
begin
 FReg:=TRegistry.Create;
 FReg.RootKey:=HKEY_CURRENT_USER;
 if FReg.OpenKey(sRegistryKey,True) then begin
   if FReg.ValueExists(sPluginPath) then DirectoryEdit1.Text:=FReg.ReadString(sPluginPath);
   if DirectoryEdit1.Text='' then DirectoryEdit1.Text:=ExtractFilePath(Application.ExeName)+'PlugIns';
   if FReg.ValueExists(sUsePlugIn) then FUsePlugIn:=FReg.ReadBool(sUsePlugIn)
   else FUsePlugIn:=True;
   if FReg.ValueExists(sIsTrayIcon) then FIsTrayIcon:=FReg.ReadBool(sIsTrayIcon)
   else FIsTrayIcon:=True;
   if FReg.ValueExists(sFrameRate) then FFrameRate:=FReg.ReadInteger(sFrameRate)
   else FFrameRate:=15;
   CheckBox1.Checked:=FUsePlugIn;
   SpinEdit1.Value:=FFrameRate;
   if FIsTrayIcon then RxTrayIcon1.Active:=True
   else Show;
   FReg.CloseKey;
 end;
 FRenderThread:=TRenderThread.Create(False);
 LoadVisPlugIn(sBaseVisPreset);
 SearchPlugIn;
end;

procedure TMainForm.FormDestroy(Sender: TObject);
begin
 if FReg.OpenKey(sRegistryKey,True) then begin
   FReg.WriteString(sPluginPath,DirectoryEdit1.Text);
   FReg.WriteBool(sUsePlugIn,FUsePlugIn);
   FReg.WriteBool(sIsTrayIcon,RxTrayIcon1.Active);
   FReg.WriteInteger(sFrameRate,FFrameRate);
   FReg.CloseKey;
 end;
 FRenderThread.Terminate;
 FRenderThread.WaitFor;
 FRenderThread.Free;
 SaveVisPlugIn(sBaseVisPreset);
 FreeVisPlugIn;
 FReg.Free;
end;

function TMainForm.IndexofVisPlugInList(DLLName: string): integer;
var
 i : integer;
begin
 Result:=-1;
 for i:=0 to Length(FVisPlugInList)-1 do begin
   if UpperCase(FVisPlugInList[i].DLLName)=UpperCase(DLLName) then begin
     result:=i;
     break;
   end;
 end;
end;

function TMainForm.AddVisPlugInList(DLLName: string): integer;
var
 i,jj : integer;
 Func : function : PwinampVisHeader; cdecl;
 DSPMod : PwinampVisModule;
begin
 Result:=IndexofVisPlugInList(DLLName);
 if Result>=0 then exit;
 SetLength(FVisPlugInList,Length(FVisPlugInList)+1);
 jj:=Length(FVisPlugInList)-1;
 FVisPlugInList[jj].DLLName:=DLLName;
 FVisPlugInList[jj].DLLHandle:=SafeLoadLibrary(pchar(DLLName));
 Func:=GetProcAddress(FVisPlugInList[Length(FVisPlugInList)-1].DLLHandle,'winampVisGetHeader');
 if Assigned(Func) then begin
   FVisPlugInList[jj].Header:=Func;
   FVisPlugInList[jj].Count:=0;
   FVisPlugInList[jj].Modules:=nil;
   FVisPlugInList[jj].Enables:=nil;
   i:=0;
   while True do begin
     DSPMod:=Func^.getModule(i);
     if DSPMod=nil then break;
     DSPMod^.hwndParent:=Handle;
     DSPMod^.hDllInstance:=FVisPlugInList[jj].DLLHandle;
     SetLength(FVisPlugInList[jj].Modules,Length(FVisPlugInList[jj].Modules)+1);
     SetLength(FVisPlugInList[jj].Enables,Length(FVisPlugInList[jj].Enables)+1);
     FVisPlugInList[jj].Modules[Length(FVisPlugInList[jj].Modules)-1]:=DSPMod;
     FVisPlugInList[jj].Enables[Length(FVisPlugInList[jj].Enables)-1]:=False;
     FVisPlugInList[jj].Count:=Length(FVisPlugInList[jj].Enables);
     inc(i);
   end;
 end;
 Result:=jj;
end;

function TMainForm.IsPlugInFile(Name: string): Boolean;
var
 DLLHandle : THandle;
 p : Pointer;
begin
 DLLHandle:=LoadLibrary(pchar(Name));
 p:=GetProcAddress(DLLHandle,'winampVisGetHeader');

⌨️ 快捷键说明

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