📄 mmconect.pas
字号:
FStepTime := Trunc(FStepTime*FIndexMeter/FDstWaveFormat^.nAvgBytesPerSec);
if (TimeGetExactTime-FBufTime < FStepTime) then TimeOK := False;
end;
if TimeOK then
begin
inc(DataPtr,FIndexMeter);
inc(FIndexMeter,Size);
if (DataPtr + Size <= FDstData + FRealBufferSize) then
begin
{ paint the meter. }
if assigned(FMeter1) then FMeter1.RefreshPCMData(DataPtr);
if assigned(FMeter2) then FMeter2.RefreshPCMData(DataPtr);
inc(FMeterRefresh);
end
else FRefreshMeter := False;
end;
end;
if FRefreshScope then
begin
Size := 0;
Offset := -1;
DataPtr := FDstData;
TimeOK := True;
if assigned(FOscope2) then
begin
Size := FOscope2.BytesPerScope;
Scope := FOscope2;
end;
if assigned(FOscope1) then
begin
Size := Max(Size,FOscope1.BytesPerScope);
Scope := FOscope1;
end;
inc(DataPtr, FIndexScope);
if (FTriggerMode <> tmNone) and not FPaused then
begin
Offset := pcmFindZeroCross(FDstWaveFormat, DataPtr,
FRealBufferSize-FIndexScope,
0, Byte(FTriggerMode), FTriggerLevel);
end;
if FSynchronize then
begin
FStepTime := 1000000;
FStepTime := Trunc(FStepTime*FIndexScope/FDstWaveFormat^.nAvgBytesPerSec);
if (TimeGetExactTime-FBufTime < FStepTime) then TimeOK := False;
end;
if TimeOK then
with Scope do
begin
if (Offset > 0) then
begin
inc(FIndexScope,Offset);
inc(DataPtr, Offset);
end;
if Scroll and Accelerate then
inc(FIndexScope, FFTLength div 4 * (Ord(BitLength)+1)*(Ord(Mode)+1))
else
inc(FIndexScope, Size);
if (DataPtr + Size <= FDstData + FRealBufferSize) then
begin
{ paint the scope. }
if assigned(FOscope1) then FOscope1.RefreshPCMData(DataPtr);
if assigned(FOscope2) then FOscope2.RefreshPCMData(DataPtr);
inc(FOscopeRefresh);
end
else FRefreshScope := False;
end;
end;
if FRefreshLight then
begin
Size := 0;
DataPtr := FDstData;
TimeOK := True;
if assigned(FLight1) then Size := FLight1.BytesPerLight;
if assigned(FLight2) then Size := Max(Size,FLight2.BytesPerLight);
if FSynchronize then
begin
FStepTime := 1000000;
FStepTime := Trunc(FStepTime*FIndexLight/FDstWaveFormat^.nAvgBytesPerSec);
if (TimeGetExactTime-FBufTime < FStepTime) then TimeOK := False;
end;
if TimeOK then
begin
inc(DataPtr,FIndexLight);
inc(FIndexLight,Size);
if (DataPtr + Size <= FDstData + FRealBufferSize) then
begin
{ paint the light. }
if assigned(FLight1) then FLight1.RefreshPCMData(DataPtr);
if assigned(FLight2) then FLight2.RefreshPCMData(DataPtr);
inc(FLightRefresh);
end
else FRefreshLight := False;
end;
end;
if FRefreshSpectrum then
begin
Size := 0;
DataPtr := FDstData;
TimeOK := True;
if assigned(FSpectrum1) then Size := FSpectrum1.BytesPerSpectrum;
if assigned(FSpectrum2) then Size := Max(Size,FSpectrum2.BytesPerSpectrum);
if assigned(FSpectrum3) then Size := Max(Size,FSpectrum3.BytesPerSpectrum);
if assigned(FSpectrum4) then Size := Max(Size,FSpectrum4.BytesPerSpectrum);
if FSynchronize then
begin
FStepTime := 1000000;
FStepTime := Trunc(FStepTime*FIndexSpectrum/FDstWaveFormat^.nAvgBytesPerSec);
if (TimeGetExactTime-FBufTime < FStepTime) then TimeOK := False;
end;
if TimeOK then
begin
inc(DataPtr,FIndexSpectrum);
inc(FIndexSpectrum,Size);
if (DataPtr + Size <= FDstData + FRealBufferSize) then
begin
{ paint the spectrum. }
if assigned(FSpectrum1) then FSpectrum1.RefreshPCMData(DataPtr);
if assigned(FSpectrum2) then FSpectrum2.RefreshPCMData(DataPtr);
if assigned(FSpectrum3) then FSpectrum3.RefreshPCMData(DataPtr);
if assigned(FSpectrum4) then FSpectrum4.RefreshPCMData(DataPtr);
inc(FSpectrumRefresh);
end
else
begin
FRefreshSpectrum := False;
end;
end;
end;
if FRefreshSpectrogram then
begin
Size := 0;
Size2:= 0;
DataPtr := nil;
DataPtr2 := nil;
TimeOK := False;
Time2OK := False;
if assigned(FSpectrogram1) then
with FSpectrogram1 do
begin
DataPtr := FDstData;
Size := BytesPerSpectrogram;
if FSynchronize then
begin
FStepTime := 1000000;
FStepTime := Trunc(FStepTime*FIndexSpectrogram1/FDstWaveFormat^.nAvgBytesPerSec);
if (TimeGetExactTime-FBufTime >= FStepTime) then TimeOK := True;
end
else TimeOK := True;
if TimeOK then
begin
inc(DataPtr,FIndexSpectrogram1);
if Accelerate then
inc(FIndexSpectrogram1, Size div 4)
else
inc(FIndexSpectrogram1, Size);
end;
end;
if assigned(FSpectrogram2) then
with FSpectrogram2 do
begin
DataPtr2 := FDstData;
Size2 := BytesPerSpectrogram;
if FSynchronize then
begin
FStepTime := 1000000;
FStepTime := Trunc(FStepTime*FIndexSpectrogram2/FDstWaveFormat^.nAvgBytesPerSec);
if (TimeGetExactTime-FBufTime >= FStepTime) then Time2OK := True;
end
else Time2OK := True;
if Time2OK then
begin
inc(DataPtr2,FIndexSpectrogram2);
if Accelerate then
inc(FIndexSpectrogram2, Size div 4)
else
inc(FIndexSpectrogram2, Size2);
end;
end;
if TimeOK or Time2OK then
begin
if ((DataPtr <> nil) and (DataPtr + Size <= FDstData + FRealBufferSize)) or
((DataPtr2 <> nil) and (DataPtr2 + Size2 <= FDstData + FRealBufferSize)) then
begin
{ paint the spectrogram. }
if assigned(FSpectrogram1) and TimeOK and
(DataPtr + Size <= FDstData + FRealBufferSize) then
FSpectrogram1.RefreshPCMData(DataPtr);
if assigned(FSpectrogram2) and Time2OK and
(DataPtr2 + Size2 <= FDstData + FRealBufferSize) then
FSpectrogram2.RefreshPCMData(DataPtr2);
inc(FSpectrogramRefresh);
end
else FRefreshSpectrogram := False;
end;
end;
{$ENDIF}
{$IFDEF WIN32}
finally
LeaveCriticalSection(FDataSection);
end;
{$ENDIF}
if assigned(FOnTrigger) then FOnTrigger(Self);
end;
end;
{-- TMMConnector --------------------------------------------------------}
procedure TMMConnector.NewBuffer(lpData: PChar; dwLength: DWORD);
begin
if FEnabled and not FPaused and (FIsPCMFormat or FCanConvert) then
begin
if (lpData <> nil) then
begin
FBufTime := TimeGetExactTime;
{$IFDEF WIN32}
EnterCriticalSection(FDataSection);
try
{$ENDIF}
FRealBufferSize := Min(dwLength,BufferSize);
GlobalMoveMem(lpData^,FSrcData^,FRealBufferSize);
{ if we have a compressed format try to convert the format }
if not FIsPCMFormat and FCanConvert then
begin
FRealBufferSize := acmDoConvert(FConvert,FRealBufferSize);
if FRealBufferSize <= 0 then exit;
end;
{$IFDEF WIN32}
finally
LeaveCriticalSection(FDataSection);
end;
{$ENDIF}
if assigned(FLevel1) or assigned(FLevel2) then
begin
FRefreshLevel := True;
FIndexLevel := 0;
end;
{$IFNDEF LEVEL_ONLY}
if assigned(FMeter1) or assigned(FMeter2) then
begin
FRefreshMeter := True;
FIndexMeter := 0;
end;
if assigned(FOscope1) or assigned(FOscope2) then
begin
FRefreshScope := True;
FIndexScope := 0;
end;
if assigned(FLight1) or assigned(FLight2) then
begin
FRefreshLight := True;
FIndexLight := 0;
end;
if assigned(FSpectrum1) or assigned(FSpectrum2) or
assigned(FSpectrum3) or assigned(FSpectrum4) then
begin
FRefreshSpectrum := True;
FIndexSpectrum := 0;
end;
if assigned(FSpectrogram1) or assigned(FSpectrogram2) then
begin
FRefreshSpectrogram := True;
FIndexSpectrogram1 := 0;
FIndexSpectrogram2 := 0;
end;
{$ENDIF}
if not FRealTime and FAutoTrigger then ProcessData;
end;
end;
end;
{-- TMMConnector --------------------------------------------------------}
procedure TMMConnector.BufferReady(lpwh: PWaveHdr);
var
p: PWaveHdr;
begin
if FSynchronize and (PMMWaveHdr(lpwh)^.lpNext <> nil) and (PMMWaveHdr(lpwh)^.wh.dwBytesRecorded > 0) then
p := PMMWaveHdr(lpwh)^.lpNext
else
p := lpwh;
if (p <> nil) then
NewBuffer(p^.lpData,p^.dwBytesRecorded);
inherited BufferReady(lpwh);
end;
{-- TMMConnector --------------------------------------------------------}
procedure TMMConnector.BufferLoad(lpwh: PWaveHdr; var MoreBuffers: Boolean);
begin
inherited BufferLoad(lpwh, MoreBuffers);
NewBuffer(lpwh^.lpData,lpwh.dwBytesRecorded);
end;
{-- TMMConnector --------------------------------------------------------}
procedure TMMConnector.GetPeak(var PeakL, PeakR: Smallint);
begin
if (FIsPCMFormat or FCanConvert) and (FDstData <> nil) then
begin
pcmFindPeak(FDstWaveFormat,
FDstData, FRealBufferSize,
PeakL, PeakR);
end
else
begin
PeakL := FSilence;
PeakR := FSilence;
end;
end;
{-- TMMConnector --------------------------------------------------------}
procedure TMMConnector.SetAutoTrigger(aValue: Boolean);
begin
if (aValue <> FAutoTrigger) then
begin
FAutoTrigger := aValue;
if not (csDesigning in ComponentState) then
begin
if not FAutoTrigger then
begin
if FRunning then
begin
dec(LoopStarted);
FRunning := False;
end;
if (LoopStarted = 0) and RestoreIdle then
begin
Application.OnIdle := nil;
IdleHandler.Free;
IdleHandler := nil;
RestoreIdle := False;
end;
end
else if FStarted and FEnabled and FRealTime then
begin
if FAutoTrigger and ENTER_IDLE_MODE then
begin
{$IFDEF WIN32}
if not assigned(Application.OnIdle) and (IdleHandler = nil) then
begin
IdleHandler := TIdleHandler.Create;
Application.OnIdle := IdleHandler.Idle;
RestoreIdle := True;
end;
{$ENDIF}
end;
PostMessage(ConnectorWindow,CM_CON_START,0,Longint(Self));
end;
end;
end;
{$IFDEF WIN32}
{$IFDEF TRIAL}
{$DEFINE _HACK1}
{$I MMHACK.INC}
{$ENDIF}
{$ENDIF}
end;
{-- TMMConnector --------------------------------------------------------}
procedure TMMConnector.Trigger;
begin
if FEnabled and (FRunning or (not FRealtime and FStarted)) and not FAutoTrigger then
begin
{$IFDEF WIN32}
if (FInHandler = 0) then
begin
if (GetCurrentThreadID <> MainThreadID) then
begin
{$IFDEF WIN32}
InterlockedIncrement(FInHandler);
{$ENDIF}
PostMessage(ConnectorWindow,CM_CON_TRIGGER,0,Longint(Self));
end
else ProcessData;
end;
{$ELSE}
ProcessData;
{$ENDIF}
end;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -