📄 mmplugin.pas
字号:
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 + -