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

📄 mmplugin.pas

📁 一套及时通讯的原码
💻 PAS
📖 第 1 页 / 共 4 页
字号:
                        for ch := 0 to nCh-1 do
                        begin
                           if ch = 0 then
                              pF := @fTempL
                           else
                              pF := @fTempR;

                           for i := 0 to FFTLen-1 do
                               pF[i] := MulDiv32(pS^[nCh*i],FWinBuf^[i],32768);

                           inc(PChar(pS),2);
                        end;
                     end
                     else
                     begin
                        pF := @fTempL;
                        for i := 0 to FFTLen-1 do
                            pF[i] := MulDiv32((pS^[nCh*i]+pS^[nCh*i+1])div 2,FWinBuf^[i],32768);
                     end;

                     FReading := False;

                     for ch := 0 to nChDst-1 do
                     begin
                        if ch = 0 then
                           pF := @fTempL
                        else
                           pF := @fTempR;

                        { calc the FFT }
                        DoRealFFT(FpFFT,pF,1);

                        for i := 0 to FFTLen div 2-1 do
                        begin
                           { Compute the magnitude }
                           re := pF[i+i]/(FFTLen div 2);
                           im := pF[i+i+1]/(FFTLen div 2);
                           a2 := re*re+im*im;

                           { Watch for possible overflow }
                           if a2 < 0 then a2 := 0;
                           lpSpectrumData[ch,i] := Round(sqrt(a2)*16);
                        end;
                     end;

                     if (nCh = 1) then
                         for i := 0 to FFTLen div 2-1 do
                             lpSpectrumData[1,i] := lpSpectrumData[0,i];

                     inc(FFFTBytesDone,2*nCh*(FFTLen div 2));
                  end;

                  Fill := False;
               end;

               if Fill then
               begin
                  GlobalFillMem(lpWaveFormData^,sizeOf(lpWaveFormData^),0);
                  GlobalFillMem(lpSpectrumData^,sizeOf(lpSpectrumData^),0);
               end;

               Ready := True;
            end;

         finally
            FReading := False;
            FDataSection.Leave;
         end;

         if Ready then
         begin
            if not TryOnly and assigned(FOnData) then
               GlobalSynchronize(SyncRender);

            if not InternalMode and IsLoaded and
               (FVISPlugIn^.Modules[FModuleIdx].ModuleData <> nil) and
               (FVISPlugIn^.Modules[FModuleIdx].Active) then
            begin
               lpWaveFormDataShort := @FVISPlugIn^.Modules[FModuleIdx].ModuleData.WaveFormData[0,0];
               lpSpectrumDataShort := @FVISPlugIn^.Modules[FModuleIdx].ModuleData.SpectrumData[0,0];
               for i := 0 to 576-1 do
               begin
                  lpWaveFormDataShort[0,i] := lpWaveFormData[0,i] div 256;
                  lpWaveFormDataShort[1,i] := lpWaveFormData[1,i] div 256;
                  lpSpectrumDataShort[0,i] := lpSpectrumData[0,i] div 256;
                  lpSpectrumDataShort[1,i] := lpSpectrumData[1,i] div 256;
               end;

               if not RenderPlugInVISModule(FVISPlugIn.Modules[FModuleIdx]) then
                  ClosePlugInVIS(FVISPlugIn);
            end;
         end;

      finally
         FRenderSection.Leave;
      end;

   except
      // no exception here please...
   end;
end;

{-------------------------------------------------------------------------}
procedure TMMVISPlugIn.NotifyHandler(Var Msg: TMessage );
begin
  with Msg do
  try
     if (wParam = Longint(Self)) then
     case Msg of
       CM_VISPLUGIN_ONACTIVATE:
       begin
          if assigned(FOnPlugInActivate) then
             FOnPlugInActivate(Self);
       end;
       CM_VISPLUGIN_ONCLOSE:
       begin
          if assigned(FOnPlugInQuit) then
             FOnPlugInQuit(Self);
       end;
     end;
  except
     Application.HandleException(Self);
  end;
end;

{-------------------------------------------------------------------------}
procedure PlugInCallBack(User: Longint; aAction: TPlugInCBAction); stdcall;
begin
   with TMMVISPlugIn(User) do
   begin
      if not (csDestroying in ComponentState) then
      case aAction of
         paActivate: if assigned(FOnPlugInActivate) then
                        PostMessage(TMMVISPlugIn(User).FNotifyHandle,CM_VISPLUGIN_ONACTIVATE,User,0);
             paQuit: if assigned(FOnPlugInQuit) then
                        PostMessage(TMMVISPlugIn(User).FNotifyHandle,CM_VISPLUGIN_ONCLOSE,User,0);
      end;
   end;
end;

{-------------------------------------------------------------------------}
procedure TMMPlugInThread.SetFPU;
var
  Flags: Word;
begin
   asm
      mov    ax, $133F
      mov    Flags, ax
      fldcw  Flags
      fwait
   end;
end;

{-------------------------------------------------------------------------}
procedure TMMPlugInThread.RestoreFPU;
var
  Flags: Word;
begin
   asm
      mov    ax, $1332
      mov    Flags, ax
      fldcw  Flags
      fwait
   end;
end;

{-------------------------------------------------------------------------}
procedure TMMPlugInThread.Execute;
{- Wait for and process messages }
var
   Res  : DWORD;
   Msg  : TMsg;
   Time : integer;
   Handles: array[0..2] of THandle;

begin
   with TMMVISPlugIn(Owner) do
   try
      Self.Priority := FPriority;

      Handles[0] := FCloseEvent;
      Handles[1] := FRenderEvent;

      { make sure we have a message queue... }
      PeekMessage(Msg, 0, 0, 0, PM_NOREMOVE);

      { Ready to go, set the output event }
      SetEvent(FGeneralEvent);

      while not Terminated do
      begin
         try
            if not PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then
            begin
               if FEnabled and assigned(Input) and
                  (assigned(FOnData) or ((FVISPlugIn <> nil) and (FVISPlugIn.Modules[FModuleIdx].Active))) then
               begin
                  if (FInterval >= 0) or (FVISPlugIn = nil) or not FVISPlugIn.Modules[FModuleIdx].Active then
                  begin
                     if assigned(FOnData) and (FVISPlugIn = nil) and (FInterval < 0) then
                         Time := 25
                     else
                         Time := Interval;
                  end
                  else
                      Time := FVISPlugIn.Modules[FModuleIdx].ModuleData.delayMs;

                  if (Time < 0) then Time  := 0;
                  if (Time > 50) then Time := 20;
               end
               else
                   Time := INFINITE;

               Res := MsgWaitForMultipleObjects(2, Handles, False, Time, QS_ALLINPUT);
               case Res of
                  WAIT_FAILED:       { Wait failed. Should not happen. }
                  begin
                     Continue;
                  end;
                  WAIT_TIMEOUT,       { TimeOut. Render a Frame. }
                  WAIT_OBJECT_0+1:    { Render Event received.      }
                  begin
                     Render(False);
                     Continue;
                  end;
                  WAIT_OBJECT_0:     { CloseEvent signaled!            }
                  begin
                     { Finished here, okay to close }
                     {$IFDEF _MMDEBUG}
                     DB_WriteStrLn(0,'Terminate received...');
                     {$ENDIF}
                     exit;
                  end;
                  WAIT_OBJECT_0+2:    { New message was received.      }
                  begin
                     { Get the message that woke us up by looping again.}
                     Continue;
                  end;
               end;
            end;

            { Process the message. }
            with msg do
            begin
               if ((Message >= CM_VISPLUGIN_ENABLE) and (Message <= CM_VISPLUGIN_CLOSE)) or
                   (Message = WM_QUIT) then
               begin
                  FDataSection.Enter;
                  try
                     case Message of
                       WM_QUIT:
                       begin
                          {$IFDEF _MMDEBUG}
                          DB_WriteStrLn(0,'WM_QUIT received...');
                          {$ENDIF}

                          if IsLoaded and FVISPlugIn.Modules[FModuleIdx].Active then
                          begin
                             ClosePlugInVIS(FVISPlugIn);

                            {$IFDEF _MMDEBUG}
                            DB_WriteStrLn(0,'Module closed...');
                            DB_WriteStrLn(0,'----------------');
                            {$ENDIF}
                          end;
                       end;
                       CM_VISPLUGIN_ENABLE:
                       begin
                          {$IFDEF _MMDEBUG}
                          DB_WriteStrLn(0,'Enabled received...');
                          {$ENDIF}

                          // Do nothing...
                       end;
                       CM_VISPLUGIN_LOAD:
                       try
                          {$IFDEF _MMDEBUG}
                          DB_WriteStrLn(0,'Load received...');
                          {$ENDIF}
                          FreePlugInVIS(FVISPlugIn);
                          FVISPlugIn := ReadPlugInVIS(FFileName);
                       finally
                          {$IFDEF _MMDEBUG}
                          DB_WriteStrLn(0,'Setting Event!');
                          {$ENDIF}
                          SetEvent(FNotifyEvent);
                       end;

                       CM_VISPLUGIN_OPEN:
                       try
                          {$IFDEF _MMDEBUG}
                          DB_WriteStrLn(0,'Open received...');
                          {$ENDIF}
                          if not OpenPlugInVIS(FVISPlugIn,FHandle) then
                             raise EMMPlugInError.Create('Unable to open Module');

                          SetCallback(FVISPlugIn,PlugInCallBack,Longint(Self.Owner));

                       finally
                          {$IFDEF _MMDEBUG}
                          DB_WriteStrLn(0,'Setting Event!');
                          {$ENDIF}
                          SetEvent(FNotifyEvent);
                       end;

                       CM_VISPLUGIN_FREE:
                       try
                          {$IFDEF _MMDEBUG}
                          DB_WriteStrLn(0,'Free received...');
                          {$ENDIF}
                          FreePlugInVIS(FVISPlugIn);

                       finally
                          {$IFDEF _MMDEBUG}
                          DB_WriteStrLn(0,'Setting Event!');
                          {$ENDIF}
                          SetEvent(FNotifyEvent);
                       end;

                       CM_VISPLUGIN_ACTIVATE:
                       try
                          {$IFDEF _MMDEBUG}
                          DB_WriteStrLn(0,'Activate Received...');
                          {$ENDIF}
                          if (FModuleIndex <> FModuleIdx) then
                              QuitPlugInVISModule(FVISPlugIn.Modules[FModuleIdx]);

                          FModuleIdx := FModuleIndex;

                          SetFPU;

                          if not OpenPlugInVIS(FVISPlugIn,FHandle) then
                             QuitPlugInVISModule(FVISPlugIn.Modules[FModuleIdx])
                          else if not InitPlugInVISModule(FVISPlugIn.Modules[FModuleIdx], PWaveFormat) then
                             QuitPlugInVISModule(FVISPlugIn.Modules[FModuleIdx]);

                       finally
                          {$IFDEF _MMDEBUG}
                          DB_WriteStrLn(0,'Setting Event!');
                          {$ENDIF}
                          SetEvent(FNotifyEvent);
                       end;

                       CM_VISPLUGIN_CLOSE:
                       try
                          {$IFDEF _MMDEBUG}
                          DB_WriteStrLn(0,'Close received...');
                          {$ENDIF}
                          QuitPlugInVISModule(FVISPlugIn.Modules[FModuleIdx]);

                       finally
                          {$IFDEF _MMDEBUG}
                          DB_WriteStrLn(0,'Setting Event!');
                          {$ENDIF}
                          SetEvent(FNotifyEvent);
                       end;
                     end;

                  finally
                     FDataSection.Leave;
                     Msg.Message := 0;
                  end;
               end
               else
               begin
                  {$IFDEF _MMDEBUG}
                  DB_WriteStrLn(0,'Message: '+IntToStr(Msg.Message));
                  {$ENDIF}

                  { Unknown message received }
                  TranslateMessage(Msg);
                  DispatchMessage(Msg);
               end;
            end;

         except
            Application.HandleException(nil);
         end;
      end;

   finally
     SetEvent(FGeneralEvent);
     {$IFDEF _MMDEBUG}
     DB_WriteStrLn(0,'Thread terminated.');
     {$ENDIF}
   end;
end;

end.

⌨️ 快捷键说明

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