📄 mmplugin.pas
字号:
Result := (FDSPPlugIn <> nil);
end;
{-- TMMDSPPlugin ------------------------------------------------------------}
function TMMDSPPlugin.GetActive: Boolean;
begin
Result := IsLoaded and FDSPPlugIn.Modules[FModuleIdx].Active;
end;
{-- TMMDSPPlugin ------------------------------------------------------------}
function TMMDSPPlugin.LoadPlugIn(FileName: TFileName): Boolean;
begin
FDataSection.Enter;
try
FreePlugIn;
FDSPPlugIn := ReadPlugInDSP(FileName);
finally
FDataSection.Leave;
Result := (FDSPPlugIn <> nil);
end;
end;
{-- TMMDSPPlugin ------------------------------------------------------------}
procedure TMMDSPPlugin.OpenPlugInEx(Owner: THandle);
begin
if IsLoaded and not FDSPPlugIn.Open then
begin
FDataSection.Enter;
try
if not OpenPlugInDSP(FDSPPlugIn,Owner) then
raise EMMPlugInError.Create('Unable to open Module');
finally
FDataSection.Leave;
end;
end;
end;
{-- TMMDSPPlugin ------------------------------------------------------------}
procedure TMMDSPPlugin.OpenPlugIn;
var
Hwnd: Thandle;
begin
{$IFDEF BUILD_ACTIVEX}
Hwnd := ParentWindow;
{$ELSE}
Hwnd := GetParentForm(TControl(Self.Owner)).Handle;
{$ENDIF}
OpenPlugInEx(Hwnd);
end;
{-- TMMDSPPlugin ------------------------------------------------------------}
procedure TMMDSPPlugin.FreePlugIn;
begin
FDataSection.Enter;
try
FreePlugInDSP(FDSPPlugIn);
finally
FDataSection.Leave;
end;
end;
{-- TMMDSPPlugin ------------------------------------------------------------}
procedure TMMDSPPlugIn.SelectModule(idx: integer);
begin
if IsLoaded and (idx < FDSPPlugIn.NumModules) then
begin
FModuleIdx := idx;
end
else raise EMMPlugInError.Create('Invalid Module index');
end;
{-- TMMDSPPlugin ------------------------------------------------------------}
function TMMDSPPlugIn.GetNumModules: integer;
begin
if IsLoaded then
Result := FDSPPlugIn.NumModules
else
Result := 0;
end;
{-- TMMDSPPlugin ------------------------------------------------------------}
procedure TMMDSPPlugIn.ConfigModule;
begin
if IsLoaded and (FModuleIdx < FDSPPlugIn.NumModules) then
begin
ConfigPlugInDSPModule(FDSPPlugIn.Modules[FModuleIdx]);
end;
end;
{-- TMMDSPPlugin ------------------------------------------------------------}
procedure TMMDSPPlugin.ActivateModule;
begin
if IsLoaded and (FModuleIdx < FDSPPlugIn.NumModules) then
begin
FDataSection.Enter;
try
OpenPlugIn;
if not InitPlugInDSPModule(FDSPPlugIn.Modules[FModuleIdx], PWaveFormat, BufferSize) then
raise EMMPlugInError.Create('Unable to initialise Module');
ResetModule;
finally
FDataSection.Leave;
end;
end;
end;
{-- TMMDSPPlugin ------------------------------------------------------------}
procedure TMMDSPPlugin.ResetModule;
begin
if IsLoaded and (FModuleIdx < FDSPPlugIn.NumModules) and IsActive then
begin
FDataSection.Enter;
try
FWaveHdr.wh.dwBytesRecorded := 0;
FWaveHdr.LoopRec.dwLooping := False;
FBytesRead := 0;
FDone := False;
if not RestartPlugInDSPModule(FDSPPlugIn.Modules[FModuleIdx], PWaveFormat, BufferSize) then
raise EMMPlugInError.Create('Unable to restart Module');
finally
FDataSection.Leave;
end;
end;
end;
{-- TMMDSPPlugin ------------------------------------------------------------}
procedure TMMDSPPlugin.CloseModule;
begin
if IsLoaded and (FModuleIdx < FDSPPlugIn.NumModules) then
begin
FDataSection.Enter;
try
QuitPlugInDSPModule(FDSPPlugIn.Modules[FModuleIdx]);
finally
FDataSection.Leave;
end;
end;
end;
{-- TMMDSPPlugin ------------------------------------------------------------}
procedure TMMDSPPlugIn.ReadFromInput(lpwh: PWaveHdr; var MoreBuffers: Boolean);
label _Again;
var
nRead,nDstBytes,nSrcBytes,n: Longint;
begin
lpwh^.dwBytesRecorded := 0;
if (Input <> nil) then
with FWaveHdr.wh do
begin
nDstBytes := lpwh^.dwBufferlength;
nRead := 0;
_Again:
nSrcBytes := dwBytesRecorded - FBytesRead;
if (nSrcBytes > 0) then
begin
n := Min(nSrcBytes,nDstBytes);
Move((FWaveHdr.wh.lpData+FBytesRead)^,(lpwh^.lpData+nRead)^,n);
dec(nDstBytes,n);
inc(FBytesRead,n);
inc(nRead,n);
end;
{ do we need more data ? }
if (nDstBytes > 0) and not FDone then
begin
while not FDone do
begin
dwBytesRecorded := 0;
if FWaveHdr.LoopRec.dwLooping then
begin
PMMWaveHdr(lpwh)^.LoopRec.dwLooping := True;
PMMWaveHdr(lpwh)^.LoopRec.dwLoopTmpCnt := FWaveHdr.LoopRec.dwLoopTmpCnt;
FWaveHdr.LoopRec.dwLooping := False;
end;
FWaveHdr.LoopRec.dwLoop := PMMWaveHdr(lpwh)^.LoopRec.dwLoop;
if FWaveHdr.LoopRec.dwLoop then
begin
FWaveHdr.LoopRec.dwLoopCnt := PMMWaveHdr(lpwh)^.LoopRec.dwLoopCnt;
FWaveHdr.LoopRec.dwLoopTmpCnt := PMMWaveHdr(lpwh)^.LoopRec.dwLoopTmpCnt;
FWaveHdr.LoopRec.dwLooping := False;
end;
Set8087CW(Default8087CW);
asm
wait
end;
FMoreBuffers := False;
inherited BufferLoad(@FWaveHdr,FMoreBuffers);
if not FMoreBuffers or (dwBytesRecorded <= 0) then FDone := True;
if (dwBytesRecorded > 0) then
begin
dwBytesRecorded := ModifySamplesPlugInDSP(FDSPPlugIn.Modules[FModuleIdx],
Pointer(lpData),
dwBytesRecorded,
PWaveFormat);
end;
FBytesRead := 0;
if (dwBytesRecorded > 0) then goto _Again;
end;
end;
MoreBuffers := FMoreBuffers or (dwBytesRecorded-FBytesRead > 0);
lpwh^.dwBytesRecorded := nRead;
end;
end;
{-- TMMDSPPlugin ------------------------------------------------------------}
procedure TMMDSPPlugin.BufferLoad(lpwh: PWaveHdr; var MoreBuffers: Boolean);
begin
FDataSection.Enter;
try
if Enabled and FOpen and IsLoaded then
begin
ReadFromInput(lpwh,MoreBuffers);
end
else inherited BufferLoad(lpwh, MoreBuffers);
finally
FDataSection.Leave;
end;
end;
{-- TMMDSPPlugin ------------------------------------------------------------}
procedure TMMDSPPlugin.BufferReady(lpwh: PWaveHdr);
begin
FDataSection.Enter;
try
if Enabled and FOpen and IsLoaded then
begin
lpwh.dwBytesRecorded := ModifySamplesPlugInDSP(FDSPPlugIn.Modules[FModuleIdx],
Pointer(lpwh.lpData),
lpwh.dwBytesRecorded,
PWaveFormat);
end;
finally
FDataSection.Leave;
end;
inherited BufferReady(lpwh);
end;
{== TMMVISPlugIn ============================================================}
constructor TMMVISPlugIn.Create(aOwner: TComponent);
begin
inherited Create(aOwner);
FHandle := 0;
FPlugInThread:= nil;
FEnabled := True;
FOpen := False;
FStarted := False;
FModuleIdx := 0;
FModuleIndex := 0;
FVISPlugIn := nil;
FInterval := -1;
FBuffer := nil;
FBufferBytes := 0;
FPriority := tpNormal;
FOnData := nil;
FDataSection := TMMCriticalSection.Create;
FRenderSection:= TMMCriticalSection.Create;
if not (csDesigning in ComponentState) then
begin
FHandle := GetParentForm(TControl(Self.Owner)).Handle;
end;
end;
{-- TMMVISPlugIn ------------------------------------------------------------}
destructor TMMVISPlugIn.Destroy;
begin
FOnPlugInActivate := nil;
FOnPlugInQuit := nil;
if (FNotifyHandle <> 0) then
begin
SetCallback(FVISPlugIn,nil,0);
FreePlugIn;
DoneThread;
DoneRealFFT(FpFFT);
GlobalFreeMem(Pointer(FWinBuf));
DeallocateHwnd(FNotifyHandle);
FNotifyHandle := 0;
end;
FDataSection.Free;
FRenderSection.Free;
inherited Destroy;
end;
{-- TMMVISPlugIn ------------------------------------------------------------}
procedure TMMVISPlugIn.ChangeDesigning(aValue: Boolean);
begin
inherited ChangeDesigning(aValue);
if not (csDesigning in ComponentState) then
begin
{$IFDEF BUILD_ACTIVEX}
FHandle := ParentWindow;
{$ELSE}
FHandle := GetParentForm(TControl(Self.Owner)).Handle;
{$ENDIF}
end;
end;
{-- TMMVISPlugIn ------------------------------------------------------------}
procedure TMMVISPlugIn.Init;
begin
if (FNotifyHandle = 0) then
begin
FNotifyHandle := AllocateHwnd(NotifyHandler);
FpFFT := InitRealFFT(Trunc(Log2(FFTLen)));
FWinBuf := GlobalAllocMem(FFTLen * sizeOf(Integer));
GenWindowTableInt(FWinBuf,1,Trunc(Log2(FFTLen)));
InitThread;
end;
end;
{-- TMMVISPlugIn ------------------------------------------------------------}
procedure TMMVISPlugIn.InitThread;
begin
{ create event objects }
FGeneralEvent := CreateEvent(nil, False, False, nil);
FCloseEvent := CreateEvent(nil, False, False, nil);
FNotifyEvent := CreateEvent(nil, False, False, nil);
FRenderEvent := CreateEvent(nil, False, False, nil);
{ create the output thread }
FPlugInThread := TMMPlugInThread.CreateSuspended(Self);
if (FPlugInThread = nil) then
raise EMMPlugInError.Create(LoadResStr(IDS_THREADERROR));
FPluginThread.FreeOnTerminate := True;
FPlugInThread.Resume;
{ Wait for it to start... }
if WaitForSingleObject(FGeneralEvent, TIMEOUT) <> WAIT_OBJECT_0 then
raise EMMPlugInError.Create(LoadResStr(IDS_THREADERROR));
end;
{-- TMMVISPlugIn ------------------------------------------------------------}
procedure TMMVISPlugIn.DoneThread;
begin
if (FGeneralEvent <> 0) then
begin
{ Force the output thread to close... }
SetEvent(FCloseEvent);
{ ...and wait for it to die }
WaitForSingleObject(FGeneralEvent, TIMEOUT);
{ release events }
CloseHandle(FGeneralEvent);
CloseHandle(FCloseEvent);
CloseHandle(FNotifyEvent);
CloseHandle(FRenderEvent);
FGeneralEvent := 0;
FCloseEvent := 0;
FNotifyEvent := 0;
FRenderEvent := 0;
end;
end;
{-- TMMVISPlugIn ------------------------------------------------------------}
procedure TMMVISPlugIn.SetOnData(Event: TMMVISPlugInDataEvent);
begin
FOnData := Event;
if assigned(FOnData) and (FPlugInThread <> nil) then
PostThreadMessage(FPlugInThread.ThreadID,CM_VISPLUGIN_ENABLE, 0, 0);
end;
{-- TMMVISPlugIn ------------------------------------------------------------}
procedure TMMVISPlugIn.SetPWaveFormat(aValue: PWaveFormatEx);
begin
if (aValue <> nil) then
begin
if not pcmIsValidFormat(aValue) or (aValue.wBitsPerSample <> 16) then
raise EMMPluginError.Create(LoadResStr(IDS_INVALIDFORMAT));
end;
inherited SetPWaveFormat(aValue);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -