📄 mmphases.pas
字号:
{========================================================================}
{= (c) 1995-98 SwiftSoft Ronald Dittrich =}
{========================================================================}
{= All Rights Reserved =}
{========================================================================}
{= D 01099 Dresden = Tel.: +0351-8012255 =}
{= Loewenstr.7a = info@swiftsoft.de =}
{========================================================================}
{= Actual versions on http://www.swiftsoft.de/mmtools.html =}
{========================================================================}
{= This code is for reference purposes only and may not be copied or =}
{= distributed in any format electronic or otherwise except one copy =}
{= for backup purposes. =}
{= =}
{= No Delphi Component Kit or Component individually or in a collection=}
{= subclassed or otherwise from the code in this unit, or associated =}
{= .pas, .dfm, .dcu, .asm or .obj files may be sold or distributed =}
{= without express permission from SwiftSoft. =}
{= =}
{= For more licence informations please refer to the associated =}
{= HelpFile. =}
{========================================================================}
{= $Date: 20.01.1998 - 18:00:00 $ =}
{========================================================================}
unit MMPhaseS;
{$I COMPILER.INC}
interface
uses
{$IFDEF WIN32}
Windows,
{$ELSE}
WinTypes,
WinProcs,
{$ENDIF}
SysUtils,
Classes,
Controls,
IniFiles,
MMSystem,
MMRegs,
MMObj,
MMDSPObj,
MMUtils,
MMMath,
MMWaveIO,
MMPCMSup,
MMFX;
type
EMMPhaseShiftError = class(Exception);
{-- TMMPhaseShift ---------------------------------------------------------}
TMMPhaseShift = class(TMMDSPComponent)
private
FEnabled : Boolean;
FOpen : Boolean;
FPPhase : PPhaseShift;
FDescription : String;
FDryMix : TMMEffectVolume;
FWetMix : TMMEffectVolume;
FFeedBack : TMMFeedBack;
FSweep : Float;
FDepth : Float;
FRate : Float;
FOnChange : TNotifyEvent;
FOnPcmOverflow : TNotifyEvent;
procedure SetDescription(aValue: String);
procedure SetEnabled(aValue: Boolean);
procedure SetGains(index: integer; aValue: TMMEffectVolume);
procedure SetFeedBack(aValue: TMMFeedBack);
procedure SetSweep(aValue: Float);
procedure SetDepth(aValue: Float);
procedure SetRate(aValue: Float);
protected
procedure Assign(Source: TPersistent); override;
procedure SetPWaveFormat(aValue: PWaveFormatEx); override;
procedure Change; dynamic;
procedure Update; virtual;
procedure Opened; override;
procedure Closed; override;
procedure Started; override;
procedure PcmOverflow; dynamic;
procedure BufferReady(lpwh: PWaveHdr); override;
procedure BufferLoad(lpwh: PWaveHdr; var MoreBuffers: Boolean); override;
public
constructor Create(aOwner: TComponent); override;
destructor Destroy; override;
procedure SaveToIniFile(IniFile: TFileName; Section: string);
procedure ReadFromIniFile(IniFile: TFileName; Section: string);
procedure ReadIniSections(IniFile: TFileName; Strings: TStrings);
procedure DeleteSection(IniFile: TFileName; Section: string);
procedure Open;
procedure Close;
procedure Process(Buffer: PChar; Length: integer);
published
property OnChange: TNotifyEvent read FOnChange write FOnChange;
property OnPcmOverflow: TNotifyEvent read FOnPcmOverflow write FOnPcmOverflow;
property Input;
property Output;
property Enabled: Boolean read FEnabled write SetEnabled default True;
property Description: String read FDescription write SetDescription;
property DryMix: TMMEffectVolume index 0 read FDryMix write SetGains;
property WetMix: TMMEffectVolume index 1 read FWetMix write SetGains;
property FeedBack: TMMFeedBack read FFeedback write SetFeedBack;
property Sweep: Float read FSweep write SetSweep;
property Depth: Float read FDepth write SetDepth;
property Rate: Float read FRate write SetRate;
end;
implementation
{== TMMPhaseShift ============================================================}
constructor TMMPhaseShift.Create(aOwner: TComponent);
begin
inherited Create(aOwner);
FEnabled := True;
FOpen := False;
FPPhase := nil;
FDescription := 'Untitled';
FDryMix := 50;
FWetMix := 50;
FFeedBack := 0;
FSweep := 0;
FDepth := 0;
FRate := 0;
end;
{-- TMMPhaseShift ------------------------------------------------------------}
destructor TMMPhaseShift.Destroy;
begin
Close;
inherited Destroy;
end;
{-- TMMPhaseShift ------------------------------------------------------------}
procedure TMMPhaseShift.PcmOverflow;
begin
if assigned(FOnPcmOverflow) then FOnPcmOverflow(Self);
end;
{-- TMMPhaseShift ------------------------------------------------------------}
procedure TMMPhaseShift.Change;
begin
if assigned(FOnChange) then FOnChange(Self);
end;
{-- TMMPhaseShift ------------------------------------------------------------}
procedure TMMPhaseShift.Assign(Source: TPersistent);
begin
if (Source is TMMPhaseShift) then
begin
if (Source <> nil) then
begin
Enabled := TMMPhaseShift(Source).Enabled;
Description:= TMMPhaseShift(Source).Description;
DryMix := TMMPhaseShift(Source).DryMix;
WetMix := TMMPhaseShift(Source).WetMix;
FeedBack := TMMPhaseShift(Source).FeedBack;
Sweep := TMMPhaseShift(Source).Sweep;
Depth := TMMPhaseShift(Source).Depth;
Rate := TMMPhaseShift(Source).Rate;
end;
end;
end;
{-- TMMPhaseShift ------------------------------------------------------------}
procedure TMMPhaseShift.SaveToIniFile(IniFile: TFileName; Section: string);
begin
if (IniFile <> '') then
begin
with TIniFile.Create(IniFile) do
try
if Pos('PhaseShift.',Section) = 0 then Section := 'PhaseShift.'+Section;
WriteInteger(Section, 'DryMix', DryMix);
WriteInteger(Section, 'WetMix', WetMix);
WriteInteger(Section, 'FeedBack', FeedBack);
WriteString(Section, 'Sweep', FloatToStr(Sweep));
WriteString(Section, 'Depth', FloatToStr(Depth));
WriteString(Section, 'Rate', FloatToStr(Rate));
finally
Free;
end;
end;
end;
{-- TMMPhaseShift ------------------------------------------------------------}
procedure TMMPhaseShift.ReadFromIniFile(IniFile: TFileName; Section: string);
var
i,P: integer;
begin
if (IniFile <> '') then
begin
with TIniFile.Create(IniFile) do
try
if Pos('PhaseShift.',Section) = 0 then Section := 'PhaseShift.'+Section;
i := ReadInteger(Section, 'DryMix', -1);
if (i > 0) then
begin
DryMix := ReadInteger(Section, 'DryMix', 50);
WetMix := ReadInteger(Section, 'WetMix', 50);
FeedBack := ReadInteger(Section, 'FeedBack', 0);
Sweep := StrToFloat(ReadString(Section, 'Sweep', '100.0'));
Depth := StrToFloat(ReadString(Section, 'Depth', '4.0'));
Rate := StrToFloat(ReadString(Section, 'Rate', '1.0'));
P := Pos('.',Section);
if (P <> 0) then Section := Copy(Section,P+1,MaxInt);
Description := Section;
end;
finally
Free;
end;
end;
end;
{-- TMMPhaseShift ------------------------------------------------------------}
procedure TMMPhaseShift.ReadIniSections(IniFile: TFileName; Strings: TStrings);
var
i, P: integer;
Sections: TStringList;
begin
if (IniFile <> '') and (Strings <> nil) then
begin
with TIniFile.Create(IniFile) do
try
Sections := TStringList.Create;
try
ReadSections(Sections);
Strings.BeginUpdate;
try
Strings.Clear;
for i := 0 to Sections.Count-1 do
begin
P := Pos('.',Sections[i]);
if (P <> 0) then Strings.Add(Copy(Sections[i],P+1,MaxInt));
end;
finally
Strings.EndUpdate;
end;
finally
Sections.Free;
end;
finally
Free;
end;
end;
end;
{-- TMMPhaseShift ------------------------------------------------------------}
procedure TMMPhaseShift.DeleteSection(IniFile: TFileName; Section: string);
begin
if (IniFile <> '') then
begin
with TIniFile.Create(IniFile) do
try
if Pos('PhaseShift.',Section) = 0 then Section := 'PhaseShift.'+Section;
EraseSection(Section);
finally
Free;
end;
end;
end;
{-- TMMPhaseShift ------------------------------------------------------------}
procedure TMMPhaseShift.SetEnabled(aValue: Boolean);
begin
if (aValue <> FEnabled) then
begin
FEnabled := aValue;
if FEnabled then Update;
end;
end;
{-- TMMPhaseShift ------------------------------------------------------------}
procedure TMMPhaseShift.SetDescription(aValue: String);
begin
if (aValue <> FDescription) then
begin
FDescription := aValue;
Change;
end;
end;
{-- TMMPhaseShift ------------------------------------------------------------}
procedure TMMPhaseShift.SetGains(index: integer; aValue: TMMEffectVolume);
begin
case index of
0: if (aValue = FDryMix) then exit
else
begin
FDryMix := aValue;
if FOpen then FPPhase^.DryMix := MulDiv(aValue,256,100);
end;
1: if (aValue = FWetMix) then exit
else
begin
FWetMix := aValue;
if FOpen then FPPhase^.Wetmix := MulDiv(aValue,256,100);
end;
end;
Change;
end;
{-- TMMPhaseShift ------------------------------------------------------------}
procedure TMMPhaseShift.SetFeedBack(aValue: TMMFeedBack);
begin
if (aValue <> FFeedBack) then
begin
FFeedBack := aValue;
if FOpen then FPPhase^.FeedBack := MulDiv(aValue,256,100);
Change;
end;
end;
{-- TMMPhaseShift ------------------------------------------------------------}
procedure TMMPhaseShift.SetSweep(aValue: Float);
begin
if (aValue <> FSweep) then
begin
FSweep := MaxR(aValue,0);
Update;
Change;
end;
end;
{-- TMMPhaseShift ------------------------------------------------------------}
procedure TMMPhaseShift.SetDepth(aValue: Float);
begin
if (aValue <> FDepth) then
begin
FDepth := MaxR(aValue,0);
Update;
Change;
end;
end;
{-- TMMPhaseShift ------------------------------------------------------------}
procedure TMMPhaseShift.SetRate(aValue: Float);
begin
if (aValue <> FRate) then
begin
FRate := MaxR(aValue,0.0);
Update;
Change;
end;
end;
{-- TMMPhaseShift ------------------------------------------------------------}
procedure TMMPhaseShift.Update;
begin
{ setup the phaser with the params }
if FOpen then
SetPhaseShift(FPPhase, FDryMix, FWetMix, FFeedBack, FSweep, FDepth, FRate);
end;
{-- TMMPhaseShift ------------------------------------------------------------}
procedure TMMPhaseShift.SetPWaveFormat(aValue: PWaveFormatEx);
begin
if (aValue <> nil) then
begin
if not (csDesigning in ComponentState) then
if not pcmIsValidFormat(aValue) then
raise EMMPhaseShiftError.Create(LoadResStr(IDS_INVALIDFORMAT));
end;
inherited SetPWaveFormat(aValue);
end;
{-- TMMPhaseShift ------------------------------------------------------------}
procedure TMMPhaseShift.Open;
begin
if not FOpen then
begin
if pcmIsValidFormat(PWaveFormat) then
begin
FPPhase := InitPhaseShift(PWaveFormat);
if (FPPhase = nil) then OutOfMemoryError
else
begin
FOpen := True;
Update;
end;
end;
end;
end;
{-- TMMPhaseShift ------------------------------------------------------------}
procedure TMMPhaseShift.Close;
begin
if FOpen then
begin
FOpen := False;
DonePhaseShift(FPPhase);
end;
end;
{-- TMMPhaseShift ------------------------------------------------------------}
procedure TMMPhaseShift.Process(Buffer: PChar; Length: integer);
begin
{ process the buffer }
if (FPPhase <> nil) then
if DoPhaseShift(FPPhase, Buffer, Length) then
GlobalSynchronize(PcmOverflow);
end;
{-- TMMPhaseShift ------------------------------------------------------------}
procedure TMMPhaseShift.Opened;
begin
Open;
inherited Opened;
end;
{-- TMMPhaseShift ------------------------------------------------------------}
procedure TMMPhaseShift.Closed;
begin
Close;
inherited Closed;
end;
{-- TMMPhaseShift ------------------------------------------------------------}
procedure TMMPhaseShift.Started;
begin
Update;
inherited Started;
end;
{-- TMMPhaseShift ------------------------------------------------------------}
procedure TMMPhaseShift.BufferReady(lpwh: PWaveHdr);
begin
if Enabled and FOpen then
begin
Process(lpwh^.lpData, lpwh^.dwBytesRecorded);
end;
inherited BufferReady(lpwh);
end;
{-- TMMPhaseShift ------------------------------------------------------------}
procedure TMMPhaseShift.BufferLoad(lpwh: PWaveHdr; var MoreBuffers: Boolean);
begin
inherited BufferLoad(lpwh, MoreBuffers);
if Enabled and FOpen then
begin
Process(lpwh^.lpData, lpwh^.dwBytesRecorded);
end;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -