home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2001 September
/
Chip_2001-09_cd1.bin
/
zkuste
/
delphi
/
nastroje
/
d5
/
DDX_SDK.ZIP
/
DDXBase.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
2001-06-02
|
24KB
|
711 lines
unit DDXBase;
interface
uses
windows, classes, SysUtils, ComObj, MMSystem, forms, dialogs;
const
WAVE_FORMAT_IEEE_FLOAT = 3; {missing from the Delphi MMSystem header...}
MaxParams = 16; {your effect can have up to 16 parameters}
DDX_SDK_Version = 1; {try to keep versions Delphi and C++ libraries together}
type
{the storage array for effect parameters}
TParamArray = array [0..MaxParams-1] of single;
{lets you easily specify the number of input and output channels you want}
tChannelMode = (
cmUnknown,
cmMonoToMono,
cmMonoToStereo,
cmStereoToMono,
cmStereoToStereo);
tChannelModes = set of tChannelMode;
{lets you easily specify the type of data you are prepared to process}
tSampleType = (stUnknown, stFloat32, stInteger16);
{Delphi equivalents: Single, SmallInt}
tSampleTypes = set of tSampleType;
{ Your plugins should inherit from this base class }
TDelphiDirectXPluginBase = class
private
{storage of our effect parameters}
fParamArray : TParamArray;
{what sample types are we PREPARED to handle}
fSampleTypes : tSampleTypes;
{what channel modes are we PREPARED to handle}
fChannelModes: tChannelModes;
{what sample type are we ACTUALLY dealing with}
fSampleType : tSampleType;
fInputChannels : integer;
fOutputChannels: integer;
fSampleRate : integer;
procedure SetChannelModes (val: tChannelModes);
function GetChannelModes : tChannelModes;
procedure SetSampleTypes (val: tSampleTypes);
function GetSampleTypes : tSampleTypes;
protected
{will need to be typecase to your actual form type}
fEditorForm : TForm;
{ these get/set methods are for our OWN "properties",
and not part of the dll inter-communication system. }
function GetParam (ndx: integer) : single;
procedure SetParam (ndx: integer; val: single);
public
{*** YOU PROBABALY DON'T need to override these calls}
function BaseConnectEditor (aEditorForm : tForm) : integer; virtual;
{ Called by the C++ plugin to connect the plugin to the editor form }
function FocusEditor : integer; virtual;
{ Called by the C++ plugin when focus is sent to the (MS) MFC property page,
which sadly does not refresh all the controls on a (Borland) VCL form,
so we have to do it ourself!}
function GetParameter (aParamNum : integer) : single; virtual;
{ Called by the C++ plugin to get a parameter }
{*** YOU MAY override these calls, but probably won't need to}
function CheckInputFormat (aFormat : PWAVEFORMATEX) : bool; virtual;
function CheckOutputFormat (aFormat : PWAVEFORMATEX) : bool; virtual;
function CheckTransform (aInputFormat, aOutputFormat : PWAVEFORMATEX) : bool; virtual;
function SetInputFormat (aFormat : PWAVEFORMATEX) : integer; virtual;
function SetOutputFormat (aFormat : PWAVEFORMATEX) : integer; virtual;
{ These Set...Format calls are the first time you will know about the
number of input and output channels, the sample format and the sample
rate. If you need to do some precomputation based on these items,
you might override these calls. Of course, if you just need to use
these values as they are, they will be in place by the time
Transform is called. }
function GetMaxBufferSize (
aSrcBufferSize : integer;
aDstBufferSize : pInteger) : integer; virtual;
function SetParameter (
aParamNum : integer;
aValue : single)
: integer; virtual;
{ Called by the C++ plugin to set a parameter.
If you need to do some pre-computation based on parameters,
you might override this. }
{*** YOU WILL PROBABLY NEED to override these calls}
constructor create; virtual; {virtual to "force" you to have no parameters}
{ Virtual constructors are one of the "tricky" features of delphi,
but we definitely need it here because we "register" our descended
class type (which gets stored in a class reference variable declared as
the ancestor's class reference), and then hope that the right class will
be created! }
destructor destroy; override;
{ You might want to dispose some buffers...}
procedure CompleteConnectEditor; virtual;
{ called after the effect has been connected to an editor form,
you'll need to override this so that your editor form can be
connected to the effect object. }
procedure DisplaySetParameter (
aParamNum : integer;
aValue : single); virtual;
{ you'll need to override this so that your editor form
(if connected) can update its visual controls with the
new values. }
{*** YOU MUST override these calls}
function Transform (
aInBuffer : pointer;
aInSamples : integer;
aOutBuffer : pointer;
aOutSamples: integer;
aProcessed : pInteger)
: integer; virtual; abstract;
{ If you don't know why you have to override this, you should be
doing something else! ;) }
//function TransformInPlace (
// aBuffer : pointer;
// aNumSamps : integer)
// : integer; virtual; abstract;
{ Not enabled }
property ParamArray [ndx: integer] : single read GetParam write SetParam;
{what sample types / channel modes are we PREPARED to handle}
property ChannelModes : tChannelModes read GetChannelModes write SetChannelModes;
property SampleTypes : tSampleTypes read GetSampleTypes write SetSampleTypes;
{what sample type / channel mode are we ACTUALLY dealing with}
property SampleType : tSampleType read fSampleType write fSampleType;
property InputChannels : integer read fInputChannels write fInputChannels;
property OutputChannels: integer read fOutputChannels write fOutputChannels;
property SampleRate : integer read fSampleRate write fSampleRate;
end;
TDelphiPluginClassRef = class of TDelphiDirectXPluginBase;
TDelphiEditorFormClassRef = class of TForm;
{You MUST call this procedure in the INITIALIZATION section of YOUR effect unit}
procedure RegisterEffect (
aEffectName : string;
aEffectDesc : string;
aEffectHelpFile : string;
aPropertiesName : string;
aEffectGUID : string;
aPropertiesGUID : string;
aPluginClassRef : TDelphiPluginClassRef;
aEditorFormClassRef: TDelphiEditorFormClassRef);
{Here are the declaration of the procedural interface to the DLL}
{You'll never call these, they are exported}
function DelphiDDXSDKVersion : integer; stdcall; export;
function DelphiEffectCLSID (aGuid : pGuid) : integer; stdcall; export;
function DelphiPropertiesCLSID (aGuid : pGuid) : integer; stdcall; export;
function DelphiEffectName (aName : pchar; aMaxLen : integer) : integer; stdcall; export;
function DelphiEffectDesc (aName : pchar; aMaxLen : integer) : integer; stdcall; export;
function DelphiEffectHelpFile (aName : pchar; aMaxLen : integer) : integer; stdcall; export;
function DelphiPropertiesName (aName : pchar; aMaxLen : integer) : integer; stdcall; export;
function DelphiCreateEffect : pointer; stdcall; export;
function DelphiFreeEffect (aEffect : pointer) : integer; stdcall; export;
function DelphiCheckInputFormat (aEffect : pointer; aFormat : PWAVEFORMATEX) : bool; stdcall; export;
function DelphiCheckOutputFormat (aEffect : pointer; aFormat : PWAVEFORMATEX) : bool; stdcall; export;
function DelphiCheckTransform (aEffect : pointer; aInputFormat, aOutputFormat : PWAVEFORMATEX) : bool; stdcall; export;
function DelphiSetInputFormat (aEffect : pointer; aFormat : PWAVEFORMATEX) : integer; stdcall; export;
function DelphiSetOutputFormat (aEffect : pointer; aFormat : PWAVEFORMATEX) : integer; stdcall; export;
function DelphiGetMaxBufferSize (
aEffect : pointer;
aSrcBufferSize : integer;
aDstBufferSize : pInteger) : integer; stdcall; export;
function DelphiSetParameter (
aEffect : pointer;
aParamNum : integer;
aValue : single)
: integer; stdcall; export;
function DelphiGetParameter (
aEffect : pointer;
aParamNum : integer)
: single; stdcall; export;
function DelphiTransform (
aEffect : pointer;
aInBuffer : pointer;
aInSamples : integer;
aOutBuffer : pointer;
aOutSamples: integer;
aProcessed : pInteger)
: integer; stdcall; export;
//function DelphiTransformInPlace (
// aEffect : pointer;
// aBuffer : pointer;
// aNumSamps : integer)
// : integer; stdcall; export;
function DelphiGetEditorSize (
aEditorWidth : PInteger;
aEditorHeight : PInteger)
: integer; stdcall; export;
function DelphiCreateEditor (
aParentHandle : HWND;
aEditorHandle : Pointer; {will be loaded with the handle of the created window}
aEditorPointer: Pointer) {will be loaded with the pointer of our created window}
: integer; stdcall; export;
function DelphiConnectEditor (
aEffect : pointer;
aEditor : Pointer)
: integer; stdcall; export;
function DelphiFocusEditor (aEffect : pointer) : integer; stdcall; export;
implementation
{********* TDelphiDirectXPluginBase implementation ************}
constructor TDelphiDirectXPluginBase.create;
begin
inherited create;
ChannelModes := [cmMonoToMono, cmMonoToStereo];
SampleTypes := [stFloat32, stInteger16];
end;
destructor TDelphiDirectXPluginBase.destroy;
begin
inherited destroy;
end;
function TDelphiDirectXPluginBase.GetParam (ndx: integer) : single;
begin
result := fParamArray [ndx];
end;
procedure TDelphiDirectXPluginBase.SetParam (ndx: integer; val: single);
begin
fParamArray [ndx] := val;
end;
procedure TDelphiDirectXPluginBase.SetChannelModes (val: tChannelModes);
begin
fChannelModes := val;
end;
function TDelphiDirectXPluginBase.GetChannelModes : tChannelModes;
begin
result := fChannelModes;
end;
procedure TDelphiDirectXPluginBase.SetSampleTypes (val: tSampleTypes);
begin
fSampleTypes := val;
end;
function TDelphiDirectXPluginBase.GetSampleTypes : tSampleTypes;
begin
result := fSampleTypes;
end;
procedure DecodeWaveFormat (
aFormat : PWAVEFORMATEX;
var aSampleType : tSampleType;
var aNumChannels: integer;
var aSampleRate : integer);
begin
aSampleType := stUnknown;
aNumChannels := 0;
with aFormat^ do begin
if (wFormatTag = WAVE_FORMAT_IEEE_FLOAT) and (wBitsPerSample = 32)
then aSampleType := stFloat32
else
if (wFormatTag = WAVE_FORMAT_PCM) and (wBitsPerSample = 16)
then aSampleType := stInteger16;
aNumChannels := nChannels;
aSampleRate := nSamplesPerSec;
end;
end;
function TDelphiDirectXPluginBase.CheckInputFormat (aFormat : PWAVEFORMATEX) : bool;
var
SampType : tSampleType;
Channels : integer;
SampRate : integer;
begin
{here is where we define what type of input we are prepared to accept}
{our approach here is to let the settings in out SampleTypes and ChannelModes
members do the work.}
DecodeWaveFormat (aFormat, SampType, Channels, SampRate);
{check the sample type first}
result := (SampType in SampleTypes);
{then go on and check the channels}
if result then begin
case Channels of
1 : result := (ChannelModes * [cmMonoToMono, cmMonoToStereo] <> []);
2 : result := (ChannelModes * [cmStereoToMono, cmStereoToStereo] <> []);
else result := false;
end;
end;
end;
function TDelphiDirectXPluginBase.CheckOutputFormat (aFormat : PWAVEFORMATEX) : bool;
var
SampType : tSampleType;
Channels : integer;
SampRate : integer;
begin
{here is where we define what type of input we are prepared to write}
{to force stereo output from mono input, don't allow nChannels = 1}
DecodeWaveFormat (aFormat, SampType, Channels, SampRate);
{check the sample type first}
result := (SampType in SampleTypes);
{then go on and check the channels}
if result then begin
case Channels of
1 : result := (ChannelModes * [cmMonoToMono, cmStereoToMono] <> []);
2 : result := (ChannelModes * [cmMonoToStereo, cmStereoToStereo] <> []);
else result := false;
end;
end;
end;
function TDelphiDirectXPluginBase.CheckTransform (aInputFormat, aOutputFormat : PWAVEFORMATEX) : bool;
var
InSampType : tSampleType;
InChannels : integer;
OutSampType : tSampleType;
OutChannels : integer;
InSampRate : integer;
OutSampRate : integer;
begin
{here is where we define what type of conversions we are prepareted to make}
{generally, we will only tolerate differences of number of channels,
ie for mono->stereo and stereo->mono}
DecodeWaveFormat (aInputFormat, InSampType, InChannels, InSampRate);
DecodeWaveFormat (aOutputFormat, OutSampType, OutChannels, OutSampRate);
{we won't handle conversion of sample types or rates}
result := (InSampType = OutSampType) and (InSampRate = OutSampRate);
{we have already checked that we handle both the input and output formats,
we only have to check that we can handle the relationship between them}
if result then begin
if (InChannels = 1) and (OutChannels = 1)
then result := cmMonoToMono in ChannelModes
else if (InChannels = 1) and (OutChannels = 2)
then result := cmMonoToStereo in ChannelModes
else if (InChannels = 2) and (OutChannels = 1)
then result := cmStereoToMono in ChannelModes
else if (InChannels = 2) and (OutChannels = 2)
then result := cmStereoToStereo in ChannelModes
else result := false;
end;
end;
function TDelphiDirectXPluginBase.SetInputFormat (aFormat : PWAVEFORMATEX) : integer;
begin
{keep track of what input format we will actually be using}
DecodeWaveFormat (aFormat, fSampleType, fInputChannels, fSampleRate);
result := 0;
end;
function TDelphiDirectXPluginBase.SetOutputFormat (aFormat : PWAVEFORMATEX) : integer;
begin
{keep track of what output format we will actually be using}
DecodeWaveFormat (aFormat, fSampleType, fOutputChannels, fSampleRate);
result := 0;
end;
function TDelphiDirectXPluginBase.GetMaxBufferSize (
aSrcBufferSize : integer;
aDstBufferSize : pInteger) : integer;
begin
aDstBufferSize^ := aSrcBufferSize;
result := 0;
end;
function TDelphiDirectXPluginBase.SetParameter (
aParamNum : integer;
aValue : single)
: integer;
begin
ParamArray [aParamNum] := avalue;
if fEditorForm <> nil then DisplaySetParameter (aParamNum, aValue);
result := 0;
end;
function TDelphiDirectXPluginBase.GetParameter (aParamNum : integer) : single;
begin
result := ParamArray [aParamNum];
end;
function TDelphiDirectXPluginBase.BaseConnectEditor (aEditorForm : tForm) : integer;
begin
fEditorForm := aEditorForm;
if fEditorForm <> nil then CompleteConnectEditor;
result := 0;
end;
procedure TDelphiDirectXPluginBase.CompleteConnectEditor;
begin
{nothing in base class}
end;
function TDelphiDirectXPluginBase.FocusEditor : integer;
var ctr : integer;
begin
if fEditorForm <> nil then begin
for ctr := 0 to fEditorForm.controlcount-1 do
fEditorForm.controls [ctr].invalidate;
end;
result := 0;
end;
procedure TDelphiDirectXPluginBase.DisplaySetParameter (
aParamNum : integer;
aValue : single);
begin
{nothing in base class}
end;
{********* end of TDelphiDirectXPluginBase implementation ************}
{********* our internal (within-Delphi) registration of user user details ************ }
type
TEffectRegistration = record
EffectName : string;
EffectDesc : string;
EffectHelpFile : string;
PropertiesName : string;
EffectGUID : string;
PropertiesGUID : string;
PluginClassRef : TDelphiPluginClassRef;
EditorFormClassRef: TDelphiEditorFormClassRef;
end;
var
GlobalEffectRegistration : TEffectRegistration;
const
GlobalEffectRegistered : boolean = false;
procedure RegisterEffect (
aEffectName : string;
aEffectDesc : string;
aEffectHelpFile : string;
aPropertiesName : string;
aEffectGUID : string;
aPropertiesGUID : string;
aPluginClassRef : TDelphiPluginClassRef;
aEditorFormClassRef: TDelphiEditorFormClassRef);
begin
with GlobalEffectRegistration do begin
EffectName := aEffectName;
EffectDesc := aEffectDesc;
EffectHelpFile := aEffectHelpFile;
PropertiesName := aPropertiesName;
EffectGUID := aEffectGUID;
PropertiesGUID := aPropertiesGUID;
PluginClassRef := aPluginClassRef;
EditorFormClassRef:= aEditorFormClassRef;
end;
GlobalEffectRegistered := true;
end;
procedure AssertRegistered;
begin
if not GlobalEffectRegistered then begin
ShowMessage ('YOu have not called RegisterEffect');
halt (1);
end;
end;
{********* procedural interface to the dll ************ }
function DelphiDDXSDKVersion : integer; stdcall; export;
begin
result := DDX_SDK_Version;
end;
function DelphiEffectCLSID (aGuid : pGuid) : integer; stdcall; export;
begin
AssertRegistered;
aGUID^ := StringToGUID (GlobalEffectRegistration.EffectGUID);
result := 0;
end;
function DelphiPropertiesCLSID (aGuid : pGuid) : integer; stdcall; export;
begin
AssertRegistered;
aGUID^ := StringToGUID (GlobalEffectRegistration.PropertiesGUID);
result := 0;
end;
function DelphiEffectName (aName : pchar; aMaxLen : integer) : integer; stdcall; export;
begin
AssertRegistered;
StrPCopy (aName, copy (GlobalEffectRegistration.EffectName, 1, aMaxLen));
result := 0;
end;
function DelphiEffectDesc (aName : pchar; aMaxLen : integer) : integer; stdcall; export;
begin
AssertRegistered;
StrPCopy (aName, copy (GlobalEffectRegistration.EffectDesc, 1, aMaxLen));
result := 0;
end;
function DelphiEffectHelpFile (aName : pchar; aMaxLen : integer) : integer; stdcall; export;
begin
AssertRegistered;
StrPCopy (aName, copy (GlobalEffectRegistration.EffectHelpFile, 1, aMaxLen));
result := 0;
end;
function DelphiPropertiesName (aName : pchar; aMaxLen : integer) : integer; stdcall; export;
begin
AssertRegistered;
StrPCopy (aName, copy (GlobalEffectRegistration.PropertiesName, 1, aMaxLen));
result := 0;
end;
function DelphiCreateEffect : pointer; stdcall; export;
begin
AssertRegistered;
result := GlobalEffectRegistration.PluginClassRef.create;
end;
function DelphiFreeEffect (aEffect : pointer) : integer; stdcall; export;
begin
TDelphiDirectXPluginBase (aEffect).free;
result := 0;
end;
function DelphiCheckInputFormat (aEffect : pointer; aFormat : PWAVEFORMATEX) : bool; stdcall; export;
begin
result := TDelphiDirectXPluginBase (aEffect).CheckInputFormat (aFormat);
end;
function DelphiCheckOutputFormat (aEffect : pointer; aFormat : PWAVEFORMATEX) : bool; stdcall; export;
begin
result := TDelphiDirectXPluginBase (aEffect).CheckOutputFormat (aFormat);
end;
function DelphiCheckTransform (aEffect : pointer; aInputFormat, aOutputFormat : PWAVEFORMATEX) : bool; stdcall; export;
begin
result := TDelphiDirectXPluginBase (aEffect).CheckTransform (aInputFormat, aOutputFormat);
end;
function DelphiSetInputFormat (aEffect : pointer; aFormat : PWAVEFORMATEX) : integer; stdcall; export;
begin
result := TDelphiDirectXPluginBase (aEffect).SetInputFormat (aFormat);
end;
function DelphiSetOutputFormat (aEffect : pointer; aFormat : PWAVEFORMATEX) : integer; stdcall; export;
begin
result := TDelphiDirectXPluginBase (aEffect).SetOutputFormat (aFormat);
end;
function DelphiGetMaxBufferSize (
aEffect : pointer;
aSrcBufferSize : integer;
aDstBufferSize : pInteger) : integer; stdcall; export;
begin
result := TDelphiDirectXPluginBase (aEffect).GetMaxBufferSize (aSrcBufferSize, aDstBufferSize);
end;
function DelphiSetParameter (
aEffect : pointer;
aParamNum : integer;
aValue : single)
: integer; stdcall; export;
begin
//showmessage (
// 'DelphiSetParameter ' + inttostr (aParamNum) +
// ' to ' + floattostr (aValue));
result := TDelphiDirectXPluginBase (aEffect).SetParameter (aParamNum, aValue);
end;
function DelphiGetParameter (
aEffect : pointer;
aParamNum : integer)
: single; stdcall; export;
begin
result := TDelphiDirectXPluginBase (aEffect).GetParameter (aParamNum);
//showmessage (
// 'DelphiGetParameter ' + inttostr (aParamNum) +
// ' returning ' + floattostr (result));
end;
function DelphiTransform (
aEffect : pointer;
aInBuffer : pointer;
aInSamples : integer;
aOutBuffer : pointer;
aOutSamples: integer;
aProcessed : pInteger)
: integer; stdcall; export;
begin
result := TDelphiDirectXPluginBase (aEffect).Transform (
aInBuffer, aInSamples, aOutBuffer, aOutSamples, aProcessed);
end;
//function DelphiTransformInPlace (
// aEffect : pointer;
// aBuffer : pointer;
// aNumSamps : integer)
// : integer; stdcall; export;
//begin
// result := TDelphiDirectXPluginBase (aEffect).TransformInPlace (aBuffer, aNumSamps);
//end;
const
GlobEditorWidth : integer = -1;
GlobEditorHeight: integer = -1;
function DelphiGetEditorSize (
aEditorWidth : PInteger;
aEditorHeight : PInteger)
: integer; stdcall; export;
var
vEditorForm : TForm;
begin
if GlobEditorWidth = -1 then begin
vEditorForm := GlobalEffectRegistration.EditorFormClassRef.Create (nil);
try
vEditorForm.visible := false;
GlobEditorWidth := vEditorForm.clientwidth;
GlobEditorHeight := vEditorForm.clientheight;
finally
vEditorForm.free;
end;
end;
aEditorWidth^ := GlobEditorWidth;
aEditorHeight^ := GlobEditorHeight;
result := 0;
end;
function DelphiCreateEditor (
aParentHandle : HWND;
aEditorHandle : Pointer; {will be loaded with the handle of the created window}
aEditorPointer: Pointer) {will be loaded with the pointer of our created window}
: integer; stdcall; export;
type
PHWND = ^HWND;
PFORM = ^TFORM;
var
vEditorForm : TForm;
vHandle : HWND;
begin
AssertRegistered;
vEditorForm := GlobalEffectRegistration.EditorFormClassRef.CreateParented (aParentHandle);
vEditorForm.visible := false;
vEditorForm.top := 0;
vEditorForm.left:= 0;
vEditorForm.visible := true;
vHandle := (vEditorForm as GlobalEffectRegistration.EditorFormClassRef).Handle;
PHWND (aEditorHandle)^ := vHandle;
PFORM (aEditorPointer)^ := vEditorForm;
result := 0;
end;
function DelphiConnectEditor (
aEffect : pointer;
aEditor : Pointer)
: integer; stdcall; export;
begin
result := TDelphiDirectXPluginBase (aEffect).BaseConnectEditor (aEditor);
end;
function DelphiFocusEditor (aEffect : pointer) : integer; stdcall; export;
begin
result := TDelphiDirectXPluginBase (aEffect).FocusEditor;
end;
end.