📄 mmplugin.pas
字号:
end;
{-- TMMVISPlugIn ------------------------------------------------------------}
procedure TMMVISPlugIn.Opened;
begin
if not FOpen then
begin
if pcmIsValidFormat(PWaveFormat) and (PWaveFormat^.wBitsPerSample = 16) then
begin
FBuffer := GlobalAllocMem(3*BufferSize);
FBufferBytes := 0;
FWaveBytesDone:= 0;
FFFTBytesDone := 0;
FReading := False;
FOpen := True;
OpenPlugIn;
if IsLoaded and (FVISPlugIn.Modules[FModuleIdx].ModuleData <> nil) then
with FVISPlugIn.Modules[FModuleIdx].ModuleData^ do
begin
sRate := PWaveFormat^.nSamplesPerSec;
nCh := PWaveFormat^.nChannels;
end;
if assigned(FOnOpen) then FOnOpen(Self);
end;
end;
inherited Opened;
end;
{-- TMMVISPlugIn ------------------------------------------------------------}
procedure TMMVISPlugIn.Closed;
begin
if FOpen then
begin
FDataSection.Enter;
try
FOpen := False;
GlobalFreeMem(Pointer(FBuffer));
finally
FDataSection.Leave;
end;
if assigned(FOnClose) then FOnClose(Self);
end;
inherited Closed;
end;
{-- TMMVISPlugIn ------------------------------------------------------------}
procedure TMMVISPlugIn.Started;
begin
if FOpen and not FStarted then
begin
FStarted := True;
end;
inherited Started;
end;
{-- TMMVISPlugIn ------------------------------------------------------------}
procedure TMMVISPlugIn.Stopped;
begin
if FOpen and FStarted then
begin
FBufferBytes := 0;
FStarted := False;
end;
inherited Stopped;
end;
{-- TMMVISPlugIn ------------------------------------------------------------}
procedure TMMVISPlugIn.Paused;
begin
if FOpen and FStarted and not FPaused then
begin
FBufferBytes := 0;
FPaused := True;
end;
inherited Paused;
end;
{-- TMMVISPlugIn ------------------------------------------------------------}
procedure TMMVISPlugIn.Restarted;
begin
if FOpen and FStarted and FPaused then
begin
FPaused := False;
end;
inherited Restarted;
end;
{-- TMMVISPlugIn ------------------------------------------------------------}
function TMMVISPlugin.GetActive: Boolean;
begin
Result := IsLoaded and FVISPlugIn.Modules[FModuleIdx].Active;
end;
{-- TMMVISPlugIn ------------------------------------------------------------}
function TMMVISPlugin.GetLoaded: Boolean;
begin
Result := (FVISPlugIn <> nil);
end;
{-- TMMVISPlugIn ------------------------------------------------------------}
function TMMVISPlugIn.LoadPlugIn(FileName: TFileName): Boolean;
begin
{$IFDEF _MMDEBUG}
DB_WriteStrLn(0,'Load Module...');
{$ENDIF}
Init;
FFileName := FileName;
ResetEvent(FNotifyEvent);
PostThreadMessage(FPlugInThread.ThreadID,CM_VISPLUGIN_LOAD,0,0);
while (WaitForSingleObject(FNotifyEvent,0) <> WAIT_OBJECT_0) do WinYield(FHandle);
{$IFDEF _MMDEBUG}
DB_WriteStrLn(0,'Module loaded...');
DB_WriteStrLn(0,'----------------');
{$ENDIF}
Result := (FVISPlugIn <> nil);
end;
{-- TMMVISPlugIn ------------------------------------------------------------}
procedure TMMVISPlugIn.OpenPlugIn;
begin
if IsLoaded then
begin
{$IFDEF _MMDEBUG}
DB_WriteStrLn(0,'Open Module...');
{$ENDIF}
ResetEvent(FNotifyEvent);
PostThreadMessage(FPlugInThread.ThreadID,CM_VISPLUGIN_OPEN,0,0);
while (WaitForSingleObject(FNotifyEvent,0) <> WAIT_OBJECT_0) do WinYield(FHandle);
{$IFDEF _MMDEBUG}
DB_WriteStrLn(0,'Module open...');
DB_WriteStrLn(0,'----------------');
{$ENDIF}
end;
end;
{-- TMMVISPlugIn ------------------------------------------------------------}
procedure TMMVISPlugIn.FreePlugIn;
begin
if IsLoaded then
begin
{$IFDEF _MMDEBUG}
DB_WriteStrLn(0,'Free Module...');
{$ENDIF}
ResetEvent(FNotifyEvent);
PostThreadMessage(FPlugInThread.ThreadID,CM_VISPLUGIN_FREE,0,0);
while (WaitForSingleObject(FNotifyEvent,0) <> WAIT_OBJECT_0) do WinYield(FHandle);
{$IFDEF _MMDEBUG}
DB_WriteStrLn(0,'Module free...');
DB_WriteStrLn(0,'----------------');
{$ENDIF}
end;
end;
{-- TMMVISPlugIn ------------------------------------------------------------}
procedure TMMVISPlugIn.SelectModule(idx: integer);
begin
if IsLoaded and (idx < FVISPlugIn.NumModules) then
begin
FModuleIndex := idx;
end
else raise EMMPlugInError.Create('Invalid Module index');
end;
{-- TMMVISPlugIn ------------------------------------------------------------}
function TMMVISPlugIn.GetNumModules: integer;
begin
if IsLoaded then
Result := FVISPlugIn.NumModules
else
Result := 0;
end;
{-- TMMVISPlugIn ------------------------------------------------------------}
procedure TMMVISPlugIn.ConfigModule;
begin
if IsLoaded and (FModuleIdx < FVISPlugIn.NumModules) then
begin
ConfigPlugInVISModule(FVISPlugIn.Modules[FModuleIdx]);
end;
end;
{-- TMMVISPlugIn ------------------------------------------------------------}
procedure TMMVISPlugIn.ActivateModule;
begin
if IsLoaded then
begin
{$IFDEF _MMDEBUG}
DB_WriteStrLn(0,'Activate Module...');
{$ENDIF}
ResetEvent(FNotifyEvent);
PostThreadMessage(FPlugInThread.ThreadID,CM_VISPLUGIN_ACTIVATE, 0, 0);
while (WaitForSingleObject(FNotifyEvent,0) <> WAIT_OBJECT_0) do WinYield(FHandle);
{$IFDEF _MMDEBUG}
DB_WriteStrLn(0,'Module Activated...');
DB_WriteStrLn(0,'----------------');
{$ENDIF}
end;
end;
{-- TMMVISPlugIn ------------------------------------------------------------}
procedure TMMVISPlugIn.CloseModule;
begin
if IsLoaded and (FModuleIdx < FVISPlugIn.NumModules) then
begin
{$IFDEF _MMDEBUG}
DB_WriteStrLn(0,'Close Module...');
{$ENDIF}
ResetEvent(FNotifyEvent);
PostThreadMessage(FPlugInThread.ThreadID,CM_VISPLUGIN_CLOSE, 0, 0);
while (WaitForSingleObject(FNotifyEvent,0) <> WAIT_OBJECT_0) do WinYield(FHandle);
if assigned(FOnPlugInQuit) then FOnPlugInQuit(Self);
{$IFDEF _MMDEBUG}
DB_WriteStrLn(0,'Module closed...');
DB_WriteStrLn(0,'----------------');
{$ENDIF}
end;
end;
{-- TMMVISPlugIn ------------------------------------------------------------}
procedure TMMVISPlugIn.SetEnabled(aValue: Boolean);
begin
if (aValue <> FEnabled) then
begin
FEnabled := aValue;
if (FPlugInThread <> nil) then
PostThreadMessage(FPlugInThread.ThreadID,CM_VISPLUGIN_ENABLE, 0, 0);
end;
end;
{-- TMMVISPlugIn ------------------------------------------------------------}
procedure TMMVISPlugIn.SetPriority(aValue: TThreadPriority);
begin
if (aValue <> FPriority) then
begin
FPriority := aValue;
if (FPlugInThread <> nil) then
begin
FPlugInThread.Priority := FPriority;
end;
end;
end;
{-- TMMVISPlugIn ------------------------------------------------------------}
procedure TMMVISPlugIn.BufferReady(lpwh: PWaveHdr);
var
nBytes,TotalBytes: Longint;
Time: Longint;
begin
if FEnabled and FOpen and (IsLoaded or assigned(FOnData)) then
begin
FDataSection.Enter;
try
TotalBytes := FBufferBytes;
if (PMMWaveHdr(lpwh)^.lpNext = nil) then
begin
if (TotalBytes >= 2*BufferSize) then
begin
GlobalMoveMem((FBuffer+BufferSize)^,FBuffer^,BufferSize);
dec(TotalBytes,BufferSize);
end;
end
else TotalBytes := 0;
nBytes := Min(lpwh^.dwBytesRecorded,BufferSize);
GlobalMoveMem(lpwh^.lpData^,(FBuffer+TotalBytes)^,nBytes);
inc(TotalBytes,nBytes);
if (PMMWaveHdr(lpwh)^.lpNext <> nil) then
begin
nBytes := Min(PMMWaveHdr(lpwh)^.lpNext^.dwBytesRecorded,BufferSize);
GlobalMoveMem(PMMWaveHdr(lpwh)^.lpNext^.lpData^,(FBuffer+TotalBytes)^,nBytes);
inc(TotalBytes,nBytes);
end;
FBufferBytes := TotalBytes;
FWaveBytesDone := 0;
FFFTBytesDone := 0;
finally
FDataSection.Leave;
end;
end;
inherited BufferReady(lpwh);
end;
{-------------------------------------------------------------------------}
procedure TMMVISPlugIn.SyncRender;
begin
FOnData(Self,@FWaveFormData,@FSpectrumData);
end;
{-------------------------------------------------------------------------}
procedure TMMVISPlugIn.Trigger;
begin
if (FRenderEvent <> 0) then
SetEvent(FRenderEvent);
end;
{-------------------------------------------------------------------------}
procedure TMMVISPlugIn.Render(TryOnly: Boolean);
var
i,nCh,nChDst,ch: integer;
lpWaveFormData: PWaveFormData;
lpSpectrumData: PSpectrumData;
lpWaveFormDataShort: PWaveFormDataShort;
lpSpectrumDataShort: PSpectrumDataShort;
pS: PSmallArray;
pF: PFloatArray;
re,im,a2: Float;
fTempL,fTempR: array[0..FFTLen] of Float;
Ready,Fill: Boolean;
InternalMode,DoEnter: Boolean;
begin
try
Ready := False;
Fill := True;
if TryOnly then
begin
DoEnter := FRenderSection.TryEnter;
end
else
begin
FRenderSection.Enter;
DoEnter := True;
end;
if DoEnter then
try
FDataSection.Enter;
try
FReading := True;
if assigned(FOnData) or (IsLoaded and (FVISPlugIn^.Modules[FModuleIdx].ModuleData <> nil)) then
begin
InternalMode := (FVisPlugIn = nil) or (FVISPlugIn^.Modules[FModuleIdx].ModuleData = nil);
lpWaveFormData := @FWaveFormData[0,0];
lpSpectrumData := @FSpectrumData[0,0];
if FOpen and FStarted and not FPaused and (FBuffer <> nil) and (FBufferBytes >= 2*BufferSize) then
begin
nCh := PWaveFormat.nChannels;
if (FBufferBytes-FWaveBytesDone >= 2*nCh*576) then
begin
pS := Pointer(FBuffer+FWaveBytesDone);
for ch := 0 to nCh-1 do
begin
for i := 0 to 576-1 do
lpWaveFormData[ch,i] := pS^[nCh*i];
inc(PChar(pS),2);
end;
if (nCh = 1) then
for i := 0 to 576-1 do
lpWaveFormData[1,i] := lpWaveFormData[0,i];
inc(FWaveBytesDone,2*nCh*576);
end;
if InternalMode then
nChDst := 1
else
nChDst := nCh;
if (FBufferBytes-FFFTBytesDone >= 2*nCh*FFTlen) then
begin
pS := Pointer(FBuffer+FFFTBytesDone);
if not InternalMode then
begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -