MMDSPObj.pas
上传用户:hylc_2004
上传日期:2014-01-23
资源大小:46800k
文件大小:33k
- {========================================================================}
- {= (c) 1995-98 SwiftSoft Ronald Dittrich =}
- {========================================================================}
- {= All Rights Reserved =}
- {========================================================================}
- {= D 01099 Dresden = Fax.: +49 (0)351-8037944 =}
- {= 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: 15.09.98 - 16:09:44 $ =}
- {========================================================================}
- unit MMDSPObj;
- {$I COMPILER.INC}
- interface
- uses
- {$IFDEF WIN32}
- Windows,
- {$ELSE}
- WinTypes,
- WinProcs,
- {$ENDIF}
- SysUtils,
- Messages,
- Classes,
- Controls,
- Forms,
- MMSystem,
- MMObj,
- MMRegs,
- MMWaveIO,
- MMUtils,
- MMString;
- const
- QUEUE_READ_SIZE : Longint = 2*32768; { used for queue-auto-read operations }
- QUEUE_WRITE_SIZE: Longint = 2*32768; { used for queue-auto-write operations }
- type
- TMMBufferEvent = procedure(Sender: TObject; lpWaveHdr: PWaveHdr) of object;
- TMMBufferLoadEvent = procedure(Sender: TObject; lpWaveHdr: PWaveHdr; var MoreBuffers: Boolean) of object;
- TMMPort = (poInput,poOutput);
- TPropString = string[20];
- {$IFDEF WIN32}
- {-- TMMDSPThread -----------------------------------------------------------}
- TMMDSPThread = class(TMMThreadEx)
- public
- Owner: TComponent;
- constructor CreateSuspended(aOwner: TComponent); virtual;
- destructor Destroy; override;
- end;
- {$ENDIF}
- TMMCustomDSPComponent = class(TMMNonVisualComponent)
- end;
- {-- TMMDSPComponent --------------------------------------------------------}
- TMMDSPComponent = class(TMMCustomDSPComponent)
- private
- FInput : TMMDSPComponent;
- FOutput : TMMDSPComponent;
- FPWaveFormat : PWaveFormatEx;
- FOrigBufferSize: Longint;
- FBufferSize : Longint;
- FOpen : Boolean;
- FStarted : Boolean;
- FPaused : Boolean;
- FOnBufferReady : TMMBufferEvent;
- FOnBufferLoad : TMMBufferLoadEvent;
- FOnBufferFilled: TMMBufferEvent;
- protected
- FInputValid : Boolean;
- FOutputValid : Boolean;
- FInpPropName : TPropString;
- FOutPropName : TPropString;
- procedure UpdateParams; virtual;
- procedure Loaded; override;
- procedure DeconnectNotification(C: TComponent; Port: TMMPort; PortName: string); virtual;
- procedure Notification(AComponent: TComponent; Operation: TOperation); override;
- procedure SetInput(aValue: TMMDSPComponent); virtual;
- function GetInput: TMMDSPComponent; virtual;
- procedure SetOutput(aValue: TMMDSPComponent); virtual;
- function GetOutput: TMMDSPComponent; virtual;
- procedure SetPWaveFormat(aValue: PWaveFormatEx); virtual;
- function GetPWaveFormat: PWaveFormatEx; virtual;
- function GetBufferSize: Longint; virtual;
- procedure SetBufferSize(aValue: Longint); virtual;
- property OnBufferReady: TMMBufferEvent read FOnBufferReady write FOnBufferReady;
- property OnBufferLoad: TMMBufferLoadEvent read FOnBufferLoad write FOnBufferLoad;
- property OnBufferFilled: TMMBufferEvent read FOnBufferFilled write FOnBufferFilled;
- public
- FPreloaded: Boolean;
- constructor Create(aOwner: TComponent); override;
- destructor Destroy; override;
- procedure ChangePWaveFormat(aValue: PWaveFormatEx); virtual;
- procedure Opened; virtual;
- procedure Closed; virtual;
- procedure Started; virtual;
- procedure Paused; virtual;
- procedure Restarted; virtual;
- procedure Stopped; virtual;
- procedure Reseting; virtual;
- procedure Looped; virtual;
- procedure BufferReady(lpwh: PWaveHdr); virtual;
- procedure BufferLoad(lpwh: PWaveHdr; var MoreBuffers: Boolean); virtual;
- procedure SetInputPort(aValue: TMMDSPComponent; PropName: TPropString); virtual;
- procedure SetOutputPort(aValue: TMMDSPComponent; PropName: TPropString); virtual;
- function CanConnectInput(aComponent: TComponent): Boolean; virtual;
- function CanConnectOutput(aComponent: TComponent): Boolean; virtual;
- property IsOpen: Boolean read FOpen;
- property IsStarted: Boolean read FStarted;
- property IsPaused: Boolean read FPaused;
- property Input : TMMDSPComponent read GetInput write SetInput;
- property Output: TMMDSPComponent read GetOutput write SetOutput;
- property PWaveFormat: PWaveFormatEx read GetPWaveFormat write SetPWaveFormat;
- property BufferSize: Longint read GetBufferSize write SetBufferSize default 2048;
- end;
- {-- TMMDSPInterface --------------------------------------------------------}
- TMMDSPInterface = class(TMMDSPComponent)
- private
- FOnOpen : TNotifyEvent;
- FOnStart : TNotifyEvent;
- FOnPause : TNotifyEvent;
- FOnRestart : TNotifyEvent;
- FOnLooped : TNotifyEvent;
- FOnStop : TNotifyEvent;
- FOnClose : TNotifyEvent;
- published
- procedure Opened; override;
- procedure Closed; override;
- procedure Started; override;
- procedure Paused; override;
- procedure Restarted; override;
- procedure Stopped; override;
- property OnOpen: TNotifyEvent read FOnOpen write FOnOpen;
- property OnStart: TNotifyEvent read FOnStart write FOnStart;
- property OnPause: TNotifyEvent read FOnPause write FOnPause;
- property OnRestart: TNotifyEvent read FOnRestart write FOnRestart;
- property OnLooped: TNotifyEvent read FOnLooped write FOnLooped;
- property OnStop: TNotifyEvent read FOnStop write FOnStop;
- property OnClose: TNotifyEvent read FOnClose write FOnClose;
- property OnBufferReady;
- property OnBufferLoad;
- property OnBufferFilled;
- property Input;
- property Output;
- end;
- {-- internal for loop handling ---------------------------------------------}
- PMMLoopRec = ^TMMLoopRec;
- TMMLoopRec = packed record
- dwLoop : LongBool; { is Loop enabled ? }
- dwLoopCnt : Longint; { number of loops required }
- dwLoopTmpCnt: Longint; { temp loop counter }
- dwLooping : LongBool; { End is reached Loop it or not }
- end;
- {-- internal WaveHdr -------------------------------------------------------}
- PMMWaveHdr = ^TMMWaveHdr;
- TMMWaveHdr = packed record
- wh : TWaveHdr;
- dwUser1 : Longint; { private user data }
- dwUser2 : Longint; { private user data }
- lpNext : PWaveHdr; { internal for buffer handling }
- LoopRec : TMMLoopRec; { internal for loop handling }
- end;
- {-- TMMCustomSoundComponent ------------------------------------------------}
- TMMCustomSoundComponent = class(TMMDSPComponent)
- protected
- FFullDuplex : Boolean;
- procedure SetNumBuffers(aValue: integer); virtual; abstract;
- function GetNumBuffers: integer; virtual; abstract;
- procedure SetDeviceID(aValue: TMMDeviceID); virtual; abstract;
- function GetDeviceID: TMMDeviceID; virtual; abstract;
- procedure SetProductName(aValue: string); virtual; abstract;
- function GetProductName: string; virtual; abstract;
- procedure SetCallBackMode(aValue: TMMCBMode); virtual; abstract;
- function GetCallBackMode: TMMCBMode; virtual; abstract;
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- procedure Opened; override;
- procedure Closed; override;
- procedure Started; override;
- procedure Paused; override;
- procedure Restarted; override;
- procedure Stopped; override;
- procedure Reseting; override;
- procedure Looped; override;
- property NumBuffers: integer read GetNumBuffers write SetNumBuffers default 10;
- property DeviceID: TMMDeviceID read GetDeviceID write SetDeviceID default 0;
- property ProductName: String read GetProductName write SetProductName stored False;
- property CallBackMode: TMMCBMode read GetCallBackMode write SetCallBackMode default cmWindow;
- end;
- {-- TMMCustomWaveOutCommponent ---------------------------------------------}
- TMMCustomWaveOutComponent = class(TMMCustomSoundComponent)
- protected
- function GetPosition: MM_int64; virtual; abstract;
- public
- procedure Open; virtual; abstract;
- procedure Close; virtual; abstract;
- procedure Reset; virtual; abstract;
- procedure Start; virtual; abstract;
- procedure Pause; virtual; abstract;
- procedure Restart; virtual; abstract;
- procedure Stop; virtual; abstract;
- property Position: MM_int64 read GetPosition;
- end;
- function DSPOutConnectCheck(C1, C2: TComponent): Boolean; far;
- function DSPInpConnectCheck(C1, C2: TComponent): Boolean; far;
- procedure GlobalDeconnectNotification(C: TComponent; Port: TMMPort; PortName: string);
- procedure GlobalSynchronize(VCLProc: TThreadMethod);
- const
- DSPList : TList = nil;
- ThreadList: TList = nil;
- implementation
- uses TypInfo;
- {------------------------------------------------------------------------------}
- procedure GlobalSynchronize(VCLProc: TThreadMethod);
- var
- i: integer;
- CurID: THandle;
- begin
- {$IFDEF WIN32}
- if (ThreadList <> nil) then
- begin
- CurID := GetCurrentThreadID;
- if (CurID <> MainThreadID) then
- for i := 0 to ThreadList.Count-1 do
- with TMMDSPThread(ThreadList[i]) do
- begin
- if ThreadID = CurID then
- begin
- Synchronize(VCLProc);
- exit;
- end;
- end;
- end;
- {$ENDIF}
- VCLProc;
- end;
- {$IFDEF WIN32}
- {== TMMDSPThread ==============================================================}
- constructor TMMDSPThread.CreateSuspended(aOwner: TComponent);
- begin
- Owner := aOwner;
- Create(True);
- if ThreadList = nil then
- ThreadList := TList.Create;
- ThreadList.Add(Self);
- end;
- {-- TMMDSPThread --------------------------------------------------------------}
- destructor TMMDSPThread.Destroy;
- begin
- ThreadList.Remove(Self);
- if ThreadList.Count = 0 then
- begin
- ThreadList.Free;
- ThreadList := nil;
- end;
- inherited Destroy;
- end;
- {$ENDIF}
- {------------------------------------------------------------------------------}
- function DSPOutConnectCheck(C1, C2: TComponent): Boolean;
- begin
- Result := (C1 as TMMDSPComponent).CanConnectOutput(C2);
- end;
- {------------------------------------------------------------------------------}
- function DSPInpConnectCheck(C1, C2: TComponent): Boolean;
- begin
- Result := (C2 as TMMDSPComponent).CanConnectInput(C1);
- end;
- {------------------------------------------------------------------------------}
- procedure GlobalDeconnectNotification(C: TComponent; Port: TMMPort; PortName: string);
- var
- i: integer;
- begin
- for i := 0 to DSPList.Count-1 do
- begin
- TMMDSPComponent(DSPList[i]).DeconnectNotification(C,Port,PortName);
- end;
- end;
- {== TMMDSPComponent ===========================================================}
- constructor TMMDSPComponent.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- FInput := nil;
- FOutput := nil;
- FInputValid := False;
- FOutputValid := False;
- FInpPropName := '';
- FOutPropName := '';
- FOrigBufferSize := 2048;
- FBufferSize := FOrigBufferSize;
- FOpen := False;
- FStarted := False;
- FPaused := False;
-
- if DSPList = nil then
- DSPList := TList.Create;
- DSPList.Add(Self);
- ErrorCode := ComponentRegistered(InitCode, Self, ClassName);
- if (ErrorCode <> 0) then RegisterFailed(InitCode, Self , ClassName);
- end;
- {-- TMMDSPComponent -----------------------------------------------------------}
- destructor TMMDSPComponent.Destroy;
- begin
- Input := nil;
- Output := nil;
- PWaveFormat := nil;
- DSPList.Remove(Self);
- if DSPList.Count = 0 then
- begin
- DSPList.Free;
- DSPList := nil;
- end;
- inherited Destroy;
- end;
- {-- TMMDSPComponent -----------------------------------------------------------}
- procedure TMMDSPComponent.Notification(AComponent: TComponent; Operation: TOperation);
- begin
- inherited Notification(AComponent, Operation);
- if Operation = opRemove then
- begin
- if AComponent = FInput then
- Input := nil
- else if AComponent = FOutput then
- Output := nil;
- end;
- end;
- {-- TMMDSPComponent -----------------------------------------------------------}
- function TMMDSPComponent.CanConnectInput(aComponent: TComponent): Boolean;
- begin
- Result := False;
- if (aComponent <> Self) and (aComponent is TMMDSPComponent) and
- ((GetPropInfo(TMMDSPComponent(aComponent).ClassInfo, 'Output') <> nil) or
- TMMDSPComponent(aComponent).FOutputValid) then
- begin
- { don't allow ring connection }
- if (Output <> nil) then
- Result := Output.CanConnectInput(aComponent)
- else
- Result := True;
- end;
- end;
- {-- TMMDSPComponent -----------------------------------------------------------}
- function TMMDSPComponent.CanConnectOutput(aComponent: TComponent): Boolean;
- begin
- Result := False;
- if (aComponent <> Self) and (aComponent is TMMDSPComponent) and
- ((GetPropInfo(TMMDSPComponent(aComponent).ClassInfo, 'Input') <> nil) or
- TMMDSPComponent(aComponent).FInputValid) then
- begin
- { don't allow ring connection }
- if (Input <> nil) then
- Result := Input.CanConnectOutput(aComponent)
- else
- Result := True;
- end;
- end;
- {-- TMMDSPComponent -----------------------------------------------------------}
- procedure TMMDSPComponent.DeconnectNotification(C: TComponent; Port: TMMPort; PortName: string);
- var
- PropInfo: PPropInfo;
- begin
- if (Port = poInput) then
- begin
- if (Output = C) and (FOutPropName = PortName) then
- begin
- PropInfo := GetPropInfo(C.ClassInfo, FOutPropName);
- if (PropInfo <> nil) and (GetOrdProp(C,PropInfo) = Longint(Self)) then
- SetOutputPort(nil,'');
- end;
- end
- else
- begin
- if (Input = C) and (FInpPropName = PortName) then
- begin
- PropInfo := GetPropInfo(C.ClassInfo, FInpPropName);
- if (PropInfo <> nil) and (GetOrdProp(C,PropInfo) = Longint(Self)) then
- SetInputPort(nil,'');
- end;
- end;
- end;
- {-- TMMDSPComponent -----------------------------------------------------------}
- procedure TMMDSPComponent.SetInputPort(aValue: TMMDSPComponent; PropName: TPropString);
- begin
- FInput := aValue;
- FInpPropName := PropName;
- end;
- {-- TMMDSPComponent -----------------------------------------------------------}
- procedure TMMDSPComponent.SetOutputPort(aValue: TMMDSPComponent; PropName: TPropString);
- begin
- FOutput := aValue;
- FOutPropName := PropName;
- end;
- {-- TMMDSPComponent -----------------------------------------------------------}
- procedure TMMDSPComponent.SetInput(aValue: TMMDSPComponent);
- begin
- if (aValue <> FInput) and ((aValue = nil) or CanConnectInput(aValue)) then
- begin
- Stopped;
- if (FInput <> nil) then
- begin
- GlobalDeconnectNotification(Self,poInput,'Input');
- SetInputPort(nil,'');
- ChangePWaveFormat(nil);
- end;
- if (aValue <> nil) then
- begin
- GlobalDeconnectNotification(aValue,poOutput,'Output');
- SetInputPort(aValue,'Output');
- FInput.SetOutputPort(Self,'Input');
- UpdateParams;
- end;
- end;
- {$IFDEF WIN32}
- {$IFDEF TRIAL}
- {$DEFINE _HACK1}
- {$I MMHACK.INC}
- {$ENDIF}
- {$ENDIF}
- end;
- {-- TMMDSPComponent -----------------------------------------------------------}
- function TMMDSPComponent.GetInput: TMMDSPComponent;
- begin
- Result := FInput;
- end;
- {-- TMMDSPComponent -----------------------------------------------------------}
- procedure TMMDSPComponent.SetOutput(aValue: TMMDSPComponent);
- begin
- if (aValue <> FOutput) and ((aValue = nil) or CanConnectOutput(aValue)) then
- begin
- Stopped;
- if (FOutput <> nil) then
- begin
- GlobalDeconnectNotification(Self,poOutput,'Output');
- FOutput.ChangePWaveFormat(nil);
- SetOutputPort(nil,'');
- end;
- if (aValue <> nil) then
- begin
- GlobalDeconnectNotification(aValue,poInput,'Input');
- SetOutputPort(aValue,'Input');
- FOutput.SetInputPort(Self,'Output');
- UpdateParams;
- end;
- end;
- {$IFDEF WIN32}
- {$IFDEF TRIAL}
- {$DEFINE _HACK2}
- {$I MMHACK.INC}
- {$ENDIF}
- {$ENDIF}
- end;
- {-- TMMDSPComponent -----------------------------------------------------------}
- function TMMDSPComponent.GetOutput: TMMDSPComponent;
- begin
- Result := FOutput;
- end;
- {-- TMMDSPComponent -----------------------------------------------------------}
- procedure TMMDSPComponent.UpdateParams;
- begin
- if (csLoading in ComponentState) or
- (csReading in ComponentState) or
- (csDestroying in ComponentState) then exit;
- if (Input <> nil) then
- begin
- ChangePWaveFormat(Input.PWaveFormat);
- end
- else if (Output <> nil) then
- begin
- Output.ChangePWaveFormat(PWaveFormat);
- end;
- end;
- {-- TMMDSPComponent -----------------------------------------------------------}
- procedure TMMDSPComponent.Loaded;
- begin
- inherited Loaded;
- PWaveFormat := FPWaveFormat;
- end;
- {-- TMMDSPComponent -----------------------------------------------------------}
- procedure TMMDSPComponent.ChangePWaveFormat(aValue: PWaveFormatEx);
- begin
- PWaveFormat := aValue;
- end;
- {-- TMMDSPComponent -----------------------------------------------------------}
- procedure TMMDSPComponent.SetPWaveFormat(aValue: PWaveFormatEx);
- begin
- if (aValue <> FPWaveFormat) then
- begin
- if FStarted then Stopped;
- GlobalFreeMem(Pointer(FPWaveFormat));
- FPWaveFormat := wioCopyWaveFormat(aValue);
- end;
- if not (csLoading in ComponentState) and
- not (csReading in ComponentState) and
- not (csDestroying in ComponentState) then
- if (Output <> nil) then
- Output.ChangePWaveFormat(PWaveFormat);
- end;
- {-- TMMDSPComponent -----------------------------------------------------------}
- function TMMDSPComponent.GetPWaveFormat: PWaveFormatEx;
- begin
- Result := FPWaveFormat;
- end;
- {-- TMMDSPComponent -----------------------------------------------------------}
- Procedure TMMDSPComponent.SetBufferSize(aValue: Longint);
- begin
- if (aValue <> FOrigBufferSize) then
- begin
- if FStarted then Stopped;
- FOrigBufferSize := aValue;
- end;
- {$IFDEF WIN32}
- {$IFDEF TRIAL}
- {$DEFINE _HACK3}
- {$I MMHACK.INC}
- {$ENDIF}
- {$ENDIF}
- end;
- {-- TMMDSPComponent -----------------------------------------------------------}
- function TMMDSPComponent.GetBufferSize: Longint;
- begin
- if FOpen then
- Result := FBufferSize
- else
- Result := FOrigBufferSize;
- end;
- {-- TMMDSPComponent -----------------------------------------------------------}
- procedure TMMDSPComponent.Opened;
- begin
- if not FOpen then
- begin
- if (PWaveFormat <> nil) then
- { make the wave buffer size a multiple of the block align... }
- FBufferSize := Max(FOrigBufferSize-(FOrigBufferSize mod PWaveFormat^.nBlockAlign),PWaveFormat^.nBlockAlign)
- else
- FBufferSize := FOrigBufferSize;
- FOpen := True;
- FStarted := False;
- FPaused := False;
- end;
- end;
- {-- TMMDSPComponent -----------------------------------------------------------}
- procedure TMMDSPComponent.Closed;
- begin
- if FOpen then
- begin
- FOpen := False;
- end;
- end;
- {-- TMMDSPComponent -----------------------------------------------------------}
- procedure TMMDSPComponent.Started;
- begin
- if not FStarted and FOpen then
- begin
- FStarted := True;
- end;
- end;
- {-- TMMDSPComponent -----------------------------------------------------------}
- procedure TMMDSPComponent.Paused;
- begin
- if not FPaused then
- FPaused := True;
- end;
- {-- TMMDSPComponent -----------------------------------------------------------}
- procedure TMMDSPComponent.Restarted;
- begin
- if FPaused then
- FPaused := False;
- end;
- {-- TMMDSPComponent -----------------------------------------------------------}
- procedure TMMDSPComponent.Reseting;
- begin
- end;
- {-- TMMDSPComponent -----------------------------------------------------------}
- procedure TMMDSPComponent.Looped;
- begin
- end;
- {-- TMMDSPComponent -----------------------------------------------------------}
- procedure TMMDSPComponent.Stopped;
- begin
- if FStarted then
- begin
- FStarted := False;
- FPaused := False;
- end;
- end;
- {-- TMMDSPComponent -----------------------------------------------------------}
- procedure TMMDSPComponent.BufferReady(lpwh: PWaveHdr);
- begin
- if assigned(FOnBufferReady) then FOnBufferReady(Self, lpwh);
- if (Output <> nil) then Output.BufferReady(lpwh);
- end;
- {-- TMMDSPComponent -----------------------------------------------------------}
- procedure TMMDSPComponent.BufferLoad(lpwh: PWaveHdr; var MoreBuffers: Boolean);
- begin
- if assigned(FOnBufferLoad) then FOnBufferLoad(Self, lpwh, MoreBuffers);
- if (Input <> nil) then Input.BufferLoad(lpwh, MoreBuffers);
- if assigned(FOnBufferFilled) and (lpwh^.dwBytesRecorded > 0) then FOnBufferFilled(Self,lpwh);
- end;
- {== TMMDSPInterface ===========================================================}
- procedure TMMDSPInterface.Opened;
- begin
- if not FOpen then
- begin
- inherited Opened;
- if assigned(FOnOpen) then FOnOpen(Self);
- end;
- end;
- {-- TMMDSPInterface -----------------------------------------------------------}
- procedure TMMDSPInterface.Closed;
- begin
- if FOpen then
- begin
- inherited Closed;
- if assigned(FOnClose) then FOnClose(Self);
- end;
- end;
- {-- TMMDSPInterface -----------------------------------------------------------}
- procedure TMMDSPInterface.Started;
- begin
- if not FStarted and FOpen then
- begin
- inherited Started;
- if assigned(FOnStart) then FOnStart(Self);
- end;
- end;
- {-- TMMDSPInterface -----------------------------------------------------------}
- procedure TMMDSPInterface.Paused;
- begin
- inherited Paused;
- if assigned(FOnPause) then FOnPause(Self);
- end;
- {-- TMMDSPInterface -----------------------------------------------------------}
- procedure TMMDSPInterface.Restarted;
- begin
- inherited Restarted;
- if assigned(FOnRestart) then FOnRestart(Self);
- end;
- {-- TMMDSPInterface -----------------------------------------------------------}
- procedure TMMDSPInterface.Stopped;
- begin
- if FStarted then
- begin
- inherited Stopped;
- if assigned(FOnStop) then FOnStop(Self);
- end;
- end;
- {== TMMCustomSoundComponent ===================================================}
- constructor TMMCustomSoundComponent.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- FFullDuplex := False;
- end;
- {-- TMMCustomSoundComponent ---------------------------------------------------}
- destructor TMMCustomSoundComponent.Destroy;
- begin
- inherited Destroy;
- end;
- {-- TMMCustomSoundComponent ---------------------------------------------------}
- procedure TMMCustomSoundComponent.Opened;
- var
- Current: TMMDSPComponent;
- begin
- FFullDuplex := False;
- { search the first valid component }
- Current := Self;
- while (Current.Input <> nil) do
- begin
- Current := Current.Input;
- { if we have a preloader it is the first component for us }
- if Current.FPreloaded then break;
- if (Current is TMMCustomSoundComponent) and (Current <> Self) then
- begin
- { there is another sound component on the left side }
- FFullDuplex := True;
- Current := Self;
- break;
- end;
- end;
- { no go trough all components and notify }
- repeat
- if not (Current is TMMCustomSoundComponent) then
- begin
- Current.BufferSize := BufferSize;
- Current.Opened;
- end
- else if (Current <> Self) then
- begin { there is another sound component on the right side }
- Current.BufferSize := BufferSize;
- Current.Opened;
- break;
- end;
- Current := Current.Output;
- until (Current = nil);
- inherited Opened;
- end;
- {-- TMMCustomSoundComponent ---------------------------------------------------}
- procedure TMMCustomSoundComponent.Closed;
- var
- Current: TMMDSPComponent;
- begin
- { search the last component }
- Current := Self;
- while (Current.Output <> nil) do
- begin
- Current := Current.Output;
- if (Current is TMMCustomSoundComponent) and (Current <> Self) then
- begin
- { there is another sound component on the right side }
- Current.Closed;
- break;
- end;
- end;
- { search the first component }
- Current := Self;
- while (Current.Input <> nil) do
- begin
- Current := Current.Input;
- if (Current is TMMCustomSoundComponent) and (Current <> Self) then
- begin
- { there is another sound component on the left side }
- Current := Self;
- break;
- end;
- end;
- { no go trough all components and notify }
- repeat
- if not (Current is TMMCustomSoundComponent) then
- begin
- Current.Closed;
- end
- else if (Current <> Self) then
- begin
- { there is another sound component on the right side }
- break;
- end;
- Current := Current.Output;
- until (Current = nil);
- inherited Closed;
- end;
- {-- TMMCustomSoundComponent ---------------------------------------------------}
- procedure TMMCustomSoundComponent.Started;
- var
- Current: TMMDSPComponent;
- begin
- { search the first component }
- Current := Self;
- while (Current.Input <> nil) do
- begin
- Current := Current.Input;
- { if we have a preloader it is the first component for us }
- if Current.FPreloaded then break;
- if (Current is TMMCustomSoundComponent) and (Current <> Self) then
- begin
- { there is another sound component on the left side }
- Current := Self;
- break;
- end;
- end;
- { no go trough all components and notify }
- repeat
- if not (Current is TMMCustomSoundComponent) then
- begin
- Current.Started;
- end
- else if (Current <> Self) then
- begin
- Current.Started;
- break; { there is another sound component on the right side }
- end;
- Current := Current.Output;
- until (Current = nil);
- inherited Started;
- end;
- {-- TMMCustomSoundComponent ---------------------------------------------------}
- procedure TMMCustomSoundComponent.Paused;
- var
- Current: TMMDSPComponent;
- begin
- { search the first component }
- Current := Self;
- while (Current.Input <> nil) do
- begin
- Current := Current.Input;
- if (Current is TMMCustomSoundComponent) and (Current <> Self) then
- begin
- { there is another sound component on the left side }
- Current := Self;
- break;
- end;
- end;
- { no go trough all components and notify }
- repeat
- if not (Current is TMMCustomSoundComponent) then
- begin
- Current.Paused;
- end
- else if (Current <> Self) then
- begin
- Current.Paused;
- break; { there is another sound component on the right side }
- end;
- Current := Current.Output;
- until (Current = nil);
- inherited Paused;
- end;
- {-- TMMCustomSoundComponent ---------------------------------------------------}
- procedure TMMCustomSoundComponent.Restarted;
- var
- Current: TMMDSPComponent;
- begin
- { search the first component }
- Current := Self;
- while (Current.Input <> nil) do
- begin
- Current := Current.Input;
- if (Current is TMMCustomSoundComponent) and (Current <> Self) then
- begin
- { there is another sound component on the left side }
- Current := Self;
- break;
- end;
- end;
- { no go trough all components and notify }
- repeat
- if not (Current is TMMCustomSoundComponent) then
- begin
- Current.Restarted;
- end
- else if (Current <> Self) then
- begin
- Current.Restarted;
- break; { there is another sound component on the right side }
- end;
- Current := Current.Output;
- until (Current = nil);
- inherited Restarted;
- end;
- {-- TMMCustomSoundComponent ---------------------------------------------------}
- procedure TMMCustomSoundComponent.Stopped;
- var
- Current: TMMDSPComponent;
- begin
- { search the last component }
- Current := Self;
- while (Current.Output <> nil) do
- begin
- Current := Current.Output;
- if (Current is TMMCustomSoundComponent) and (Current <> Self) then
- begin
- { there is another sound component on the right side }
- Current.Stopped;
- break;
- end;
- end;
- { search the first component }
- Current := Self;
- while (Current.Input <> nil) do
- begin
- Current := Current.Input;
- if (Current is TMMCustomSoundComponent) and (Current <> Self) then
- begin
- { there is another sound component on the left side }
- Current := Self;
- break;
- end;
- end;
- { no go trough all components and notify }
- repeat
- if not (Current is TMMCustomSoundComponent) then
- begin
- Current.Stopped;
- end
- else if (Current <> Self) then
- begin
- { there is another sound component on the right side }
- break;
- end;
- Current := Current.Output;
- until (Current = nil);
- inherited Stopped;
- end;
- {-- TMMCustomSoundComponent ---------------------------------------------------}
- procedure TMMCustomSoundComponent.Reseting;
- var
- Current: TMMDSPComponent;
- begin
- { search the first component }
- Current := Self;
- while (Current.Input <> nil) do
- begin
- Current := Current.Input;
- if (Current is TMMCustomSoundComponent) and (Current <> Self) then
- begin
- { there is another sound component on the left side }
- Current := Self;
- break;
- end;
- end;
- { no go trough all components and notify }
- repeat
- if not (Current is TMMCustomSoundComponent) then
- begin
- Current.Reseting;
- end
- else if (Current <> Self) then
- begin
- Current.Reseting;
- break; { there is another sound component on the right side }
- end;
- Current := Current.Output;
- until (Current = nil);
- inherited Reseting;
- end;
- {-- TMMCustomSoundComponent ---------------------------------------------------}
- procedure TMMCustomSoundComponent.Looped;
- var
- Current: TMMDSPComponent;
- begin
- { search the first component }
- Current := Self;
- while (Current.Input <> nil) do
- begin
- Current := Current.Input;
- if (Current is TMMCustomSoundComponent) and (Current <> Self) then
- begin
- { there is another sound component on the left side }
- Current := Self;
- break;
- end;
- end;
- { no go trough all components and notify }
- repeat
- if not (Current is TMMCustomSoundComponent) then
- begin
- Current.Looped;
- end
- else if (Current <> Self) then
- begin
- Current.Looped;
- break; { there is another sound component on the right side }
- end;
- Current := Current.Output;
- until (Current = nil);
- inherited Looped;
- end;
- end.