📄 mmdspobj.pas
字号:
{========================================================================}
{= (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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -