📄 mmeq.pas
字号:
begin
if FOpen then
with (Sender as TMMEQFilter) do
begin
{ now update the filter channels }
if Enabled then
SetFFTFilterBand(FPFilter,f1,f2,gain)
else
SetFFTFilterBand(FPFilter,f1,f2,0);
end;
Change;
end;
end;
{-- TMMEqualizer --------------------------------------------------------------}
procedure TMMEqualizer.FiltersChanged(Sender: TObject);
begin
if not FUpdating and (Filters.UpdateCount = 0) then
begin
Update;
Change;
end;
end;
{-- TMMEqualizer --------------------------------------------------------------}
procedure TMMEqualizer.Loaded;
begin
inherited Loaded;
NotifySpectrum;
end;
{-- TMMEqualizer --------------------------------------------------------------}
procedure TMMEqualizer.Change;
begin
NotifySpectrum;
if assigned(FOnChange) then FOnChange(Self);
end;
{-- TMMEqualizer --------------------------------------------------------------}
procedure TMMEqualizer.Update;
var
i: integer;
begin
{ setup the equalizer with the params }
if FOpen then
begin
ResetEQ;
for i := 0 to Filters.Count-1 do
with Filters[i] do
begin
{ now update the filter channels }
if Enabled then SetFFTFilterBand(FPFilter,f1,f2,Gain);
end;
end;
end;
{-- TMMEqualizer --------------------------------------------------------------}
procedure TMMEqualizer.ResetEQ;
begin
if FOpen and (FPFilter <> nil) then
begin
{ reset the equalizer }
SetFFTFilterBand(FPFilter,0,Ffs/2,0);
end;
end;
{-- TMMEqualizer --------------------------------------------------------------}
procedure TMMEqualizer.UpdateTempFilter(Init: Boolean);
var
wfx: TWaveFormatEx;
begin
DoneFFTFilter(FPTempFilter);
if Init and (FSpectrum <> nil) then
begin
pcmBuildWaveHeader(@wfx, 16, 1, Ffs);
FPTempFilter := InitFFTFilter(@wfx,FFTLen,8192);
FSpectrum.PCMWaveFormat := PPCMWaveFormat(@wfx)^;
SetFFTFilterWindow(FPTempFilter,Ord(FWindow));
NotifySpectrum;
end;
end;
{-- TMMEqualizer --------------------------------------------------------------}
procedure TMMEqualizer.SetSpectrum(aValue: TMMSpectrum);
begin
if Longint(Self) = Longint(aValue) then exit;
if (aValue <> FSpectrum) then
begin
if (aValue = nil) then
begin
FSpectrum.OnNeedData := nil;
NotifySpectrum;
UpdateTempFilter(False);
end;
FSpectrum := aValue;
if (FSpectrum <> nil) then
begin
UpdateTempFilter(True);
FSpectrum.Window := fwRectangular;
FSpectrum.OnNeedData := SpectrumNeedData;
NotifySpectrum;
end;
end;
end;
{-- TMMEqualizer --------------------------------------------------------------}
procedure TMMEqualizer.NotifySpectrum;
begin
if (FSpectrum = nil) or
(csLoading in ComponentState) or
(csReading in ComponentState) then exit;
FSpectrum.ResetData;
end;
{-- TMMEqualizer --------------------------------------------------------------}
procedure TMMEqualizer.SpectrumNeedData(Sender: TObject);
var
i: integer;
Buf: array[0..8192] of Smallint;
begin
if (Sender <> nil) and (FPTempFilter <> nil) then
with TMMSpectrum(Sender) do
begin
{ reset the filter }
SetFFTFilterBand(FPTempFilter,0,Ffs/2, 0);
for i := 0 to Filters.Count-1 do
with Filters[i] do
begin
{ now update the filter bands }
if Enabled then SetFFTFilterBand(FPTempFilter,f1,f2,Gain);
end;
GlobalFillMem(Buf,sizeOf(Buf),0);
Buf[0] := 21500;
DoFFTFilter(FPTempFilter, chLeft, @Buf, Max(BytesPerSpectrum,2*FFTLen));
RefreshPCMData(@Buf);
end;
end;
{-- TMMEqualizer --------------------------------------------------------------}
procedure TMMEqualizer.Assign(Source: TPersistent);
begin
if (Source is TMMEqualizer) then
begin
if (Source <> nil) then
begin
Channel := TMMEqualizer(Source).Channel;
Enabled := TMMEqualizer(Source).Enabled;
Description:= TMMEqualizer(Source).Description;
FFTLength := TMMEqualizer(Source).FFTLength;
Window := TMMEqualizer(Source).Window;
Filters := TMMEqualizer(Source).Filters;
SampleRate := TMMEqualizer(Source).SampleRate;
end;
end;
end;
{-- TMMEqualizer --------------------------------------------------------------}
procedure TMMEqualizer.SetChannel(aValue: TMMChannel);
begin
if (aValue <> FChannel) then
begin
FChannel := aValue;
end;
end;
{-- TMMEqualizer --------------------------------------------------------------}
procedure TMMEqualizer.SetSampleRate(aValue: Longint);
begin
if (aValue <> Ffs) then
begin
Ffs := MinMax(aValue,4000,100000);
UpdateTempFilter(True);
end;
end;
{-- TMMEqualizer --------------------------------------------------------------}
procedure TMMEqualizer.SetWindow(aValue: TMMFFTWindow);
begin
if (aValue <> FWindow) then
begin
FWindow := aValue;
if FOpen then SetFFTFilterWindow(FPFilter,Ord(FWindow));
UpdateTempFilter(True);
end;
end;
{-- TMMEqualizer --------------------------------------------------------------}
procedure TMMEqualizer.SetFFTLen(aValue: integer);
var
Order: integer;
begin
{ band wide = (44100/2)/(FFTLen/2) = 172 Hz. for fft(256) }
{ (44100/2)/(FFTLen/2) = 86 Hz wide of band. fft(512) }
aValue := MinMax(aValue,8,MAX_FFTLEN);
{ Convert FFTLen to a power of 2 }
Order := 0;
while aValue > 1 do
begin
aValue := aValue shr 1;
inc(Order);
end;
if (Order > 0) then aValue := aValue shl Order;
if (aValue <> FFTLen) then
begin
{ re-init the FFTObject with the new FFT-length }
FFTLen := aValue;
UpdateTempFilter(True);
if FOpen then
begin
DoneFFTFilter(FPFilter);
FPFilter := InitFFTFilter(PWaveFormat, FFTLength, FRealBufSize);
if (FPFilter = nil) then OutOfMemoryError;
SetFFTFilterWindow(FPFilter,Ord(FWindow));
Update;
end;
end;
end;
{-- TMMEqualizer --------------------------------------------------------------}
procedure TMMEqualizer.SetDescription(aValue: String);
begin
if (aValue <> FDescription) then
begin
FDescription := aValue;
end;
end;
{-- TMMEqualizer --------------------------------------------------------------}
procedure TMMEqualizer.SetEnabled(aValue: Boolean);
begin
if (aValue <> FEnabled) then
begin
FEnabled := aValue;
Reset;
end;
end;
{-- TMMEqualizer --------------------------------------------------------------}
procedure TMMEqualizer.Open;
begin
if not FOpen then
begin
if pcmIsValidFormat(PWaveFormat) then
begin
FRealBufSize := Max(Max(QUEUE_READ_SIZE,QUEUE_WRITE_SIZE),BufferSize);
FPFilter := InitFFTFilter(PWaveFormat, FFTLength, FRealBufSize);
if (FPFilter = nil) then OutOfMemoryError;
SetFFTFilterWindow(FPFilter,Ord(FWindow));
FOpen := True;
Update;
end;
end;
end;
{-- TMMEqualizer --------------------------------------------------------------}
procedure TMMEqualizer.Reset;
begin
if FOpen and (FPFilter <> nil) then
begin
ResetFFTFilter(FPFilter);
end;
end;
{-- TMMEqualizer --------------------------------------------------------------}
procedure TMMEqualizer.Close;
begin
if FOpen then
begin
FOpen := False;
DoneFFTFilter(FPFilter);
end;
end;
{-- TMMEqualizer --------------------------------------------------------------}
procedure TMMEqualizer.Process(Buffer: PChar; Length: integer);
begin
{ process the buffer trough the filter engine }
if FOpen and (FPFilter <> nil) and FEnabled then
begin
if DoFFTFilter(FPFilter, FChannel, Buffer, Length) then
begin
if assigned(FOnPcmOverflow) then
GlobalSynchronize(PcmOverflow);
end;
end;
end;
{-- TMMEqualizer --------------------------------------------------------------}
procedure TMMEqualizer.Opened;
begin
Open;
inherited Opened;
end;
{-- TMMEqualizer --------------------------------------------------------------}
procedure TMMEqualizer.Closed;
begin
Close;
inherited Closed;
end;
{-- TMMEqualizer --------------------------------------------------------------}
procedure TMMEqualizer.Started;
begin
Update;
Reset;
inherited Started;
end;
{-- TMMEqualizer --------------------------------------------------------------}
procedure TMMEqualizer.Reseting;
begin
Reset;
inherited Reseting;
end;
{-- TMMEqualizer --------------------------------------------------------------}
procedure TMMEqualizer.BufferReady(lpwh: PWaveHdr);
begin
if FOpen then
begin
Process(lpwh^.lpData, lpwh^.dwBytesRecorded);
end;
inherited BufferReady(lpwh);
end;
{-- TMMEqualizer --------------------------------------------------------------}
procedure TMMEqualizer.BufferLoad(lpwh: PWaveHdr; var MoreBuffers: Boolean);
begin
inherited BufferLoad(lpwh, MoreBuffers);
if FOpen then
begin
Process(lpwh^.lpData, lpwh^.dwBytesRecorded);
end;
end;
initialization
{ register filter class for streaming ! }
DoRegisterClass(@TMMEQFilter.Load,
@TMMEQFilter.Store,
TMMEQFilter);
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -