📄 xact.pas
字号:
{$EXTERNALSYM a2Point1Layout}
aQuadLayout: array[0..3] of Single =
(
FRONT_LEFT_AZIMUTH,
FRONT_RIGHT_AZIMUTH,
BACK_LEFT_AZIMUTH,
BACK_RIGHT_AZIMUTH
);
{$EXTERNALSYM aQuadLayout}
a4Point1Layout: array[0..4] of Single =
(
FRONT_LEFT_AZIMUTH,
FRONT_RIGHT_AZIMUTH,
LOW_FREQUENCY_AZIMUTH,
BACK_LEFT_AZIMUTH,
BACK_RIGHT_AZIMUTH
);
{$EXTERNALSYM a4Point1Layout}
a5Point1Layout: array[0..5] of Single =
(
FRONT_LEFT_AZIMUTH,
FRONT_RIGHT_AZIMUTH,
FRONT_CENTER_AZIMUTH,
LOW_FREQUENCY_AZIMUTH,
BACK_LEFT_AZIMUTH,
BACK_RIGHT_AZIMUTH
);
{$EXTERNALSYM a5Point1Layout}
a7Point1Layout: array[0..7] of Single =
(
FRONT_LEFT_AZIMUTH,
FRONT_RIGHT_AZIMUTH,
FRONT_CENTER_AZIMUTH,
LOW_FREQUENCY_AZIMUTH,
BACK_LEFT_AZIMUTH,
BACK_RIGHT_AZIMUTH,
LEFT_AZIMUTH,
RIGHT_AZIMUTH
);
{$EXTERNALSYM a7Point1Layout}
const
DefaultCurvePoints: array[0..1] of TX3DAudioDistanceCurvePoint =
((Distance: 0.0; DSPSetting: 1.0), (Distance: 1.0; DSPSetting: 1.0));
DefaultCurve: TX3DAudioDistanceCurve = (pPoints: @DefaultCurvePoints; PointCount: 2);
//--------------<F-U-N-C-T-I-O-N-S>-----------------------------------------//
////
// DESCRIPTION:
// Initializes the 3D API's:
//
// REMARKS:
// This method only needs to be called once
// The number of bits set in SpeakerChannelMask should equal the number of
// channels expected on the final mix.
//
// PARAMETERS:
// SpeakerChannelMask - [in] speaker geometry configuration on the final mix, specifies assignment of channels to speaker positions, defined as per WAVEFORMATEXTENSIBLE.dwChannelMask, must be != 0
// Currently only SPEAKER_STEREO and SPEAKER_5POINT1 is supported by X3DAudio.
// pEngine - [in] pointer to the XACT engine
// X3DInstance - [out] Handle to the X3DAudio instance
//
// RETURN VALUE:
// HResult error code
////
function XACT3DInitialize(SpeakerChannelMask: LongWord; const pEngine: IXACTEngine; out X3DInstance: TX3DAudioHandle): HRESULT; cdecl;{$IFDEF SUPPORTS_INLINE} inline;{$ENDIF}
{$EXTERNALSYM XACT3DInitialize}
////
// DESCRIPTION:
// Calculates DSP settings with respect to 3D parameters:
//
// PARAMETERS:
// X3DInstance - [in] X3DAudio instance (returned from XACT3DInitialize)
// pListener - [in] point of 3D audio reception
// pEmitter - [in] 3D audio source
// pDSPSettings - [out] receives calculation results, applied to an XACT cue via XACT3DApply
//
// RETURN VALUE:
// HResult error code
////
function XACT3DCalculate (const X3DInstance: TX3DAudioHandle; const pListener: TX3DAudioListener;
var pEmitter: TX3DAudioEmitter; var pDSPSettings: TX3DAudioDspSettings): HRESULT; cdecl;{$IFDEF SUPPORTS_INLINE} inline;{$ENDIF}
{$EXTERNALSYM XACT3DCalculate}
////
// DESCRIPTION:
// Applies a 3D calculation returned by XACT3DCalculate to a cue:
//
// PARAMETERS:
// pDSPSettings - [in] calculation results generated by XACT3DCalculate
// pCue - [in] cue to which to apply pDSPSettings
//
// RETURN VALUE:
// HResult error code
////
function XACT3DApply(const pDSPSettings: TX3DAudioDspSettings; const pCue: IXACTCue;
ChannelCount: LongWord): HRESULT; cdecl;{$IFDEF SUPPORTS_INLINE} inline;{$ENDIF}
{$EXTERNALSYM XACT3DApply}
implementation
{.$IFDEF XBOX}
function XACTCreateEngine(dwCreationFlags: DWORD; out ppEngine: IXACTEngine): HRESULT; stdcall; // inline
var
key: HKEY;
data: DWORD;
type_: DWORD;
dataSize: DWORD;
debug: Boolean;
audition: Boolean;
guid: TGUID;
begin
type_ := REG_DWORD;
dataSize := SizeOf(DWORD);
debug := (dwCreationFlags and XACT_FLAG_API_DEBUG_MODE) <> 0;
audition := (dwCreationFlags and XACT_FLAG_API_AUDITION_MODE) <> 0;
// If neither the debug nor audition flags are set, see if the debug registry key is set
if (not debug and not audition and
(RegOpenKeyEx(HKEY_LOCAL_MACHINE, XACT_DEBUGENGINE_REGISTRY_KEY, 0, KEY_READ, key) = ERROR_SUCCESS)) then
begin
if RegQueryValueEx(key, XACT_DEBUGENGINE_REGISTRY_VALUE, nil, @type_, @data, @dataSize) = ERROR_SUCCESS
then debug := (data <> 0);
RegCloseKey(key);
end;
if audition then guid := CLSID_XACTAuditionEngine
else if debug then guid := CLSID_XACTDebugEngine
else guid := CLSID_XACTEngine;
// Priority order: Audition, Debug, Retail
Result:= CoCreateInstance(guid, nil, CLSCTX_INPROC_SERVER, IID_IXACTEngine, ppEngine);
// If debug engine does not exist fallback to retail version
if FAILED(Result) and debug and not audition then
begin
Result := CoCreateInstance(CLSID_XACTEngine, nil, CLSCTX_INPROC_SERVER, IID_IXACTEngine, ppEngine);
end;
end;
{.$ENDIF XBOX}
(***************************************************************************
* File: xact2wb.h
* Content: XACT 2 wave bank definitions.
****************************************************************************)
procedure SwapBytes(_dw_: PDWORD); overload;
asm
mov edi, _dw_
// mov edi, dw
mov eax, [edi]
bswap eax
mov [edi], eax
end;
// dw = _byteswap_ulong(dw); //todo: add inline in pure pascal case
procedure SwapBytes(w: PWORD); overload;
asm
mov edi, w
mov ax, [edi]
xchg ah, al
mov [edi], ax
end;
// w = _byteswap_ushort(w); //todo: add inline in pure pascal case
(***************************************************************************
* File: xact3d.h
* Content: XACT 3D support.
****************************************************************************)
////
// DESCRIPTION:
// Initializes the 3D API's:
//
// REMARKS:
// This method only needs to be called once
// The number of bits set in SpeakerChannelMask should equal the number of
// channels expected on the final mix.
//
// PARAMETERS:
// SpeakerChannelMask - [in] speaker geometry configuration on the final mix, specifies assignment of channels to speaker positions, defined as per WAVEFORMATEXTENSIBLE.dwChannelMask, must be != 0
// Currently only SPEAKER_STEREO and SPEAKER_5POINT1 is supported by X3DAudio.
// pEngine - [in] pointer to the XACT engine
// X3DInstance - [out] Handle to the X3DAudio instance
//
// RETURN VALUE:
// HResult error code
////
function XACT3DInitialize(SpeakerChannelMask: LongWord; const pEngine: IXACTEngine;
out X3DInstance: TX3DAudioHandle): HRESULT; cdecl;{$IFDEF SUPPORTS_INLINE} inline;{$ENDIF}
var
xactSpeedOfSoundID: TXACTVariableIndex;
nSpeedOfSound: TXACTVariableValue;
begin
Result := S_OK;
if (pEngine = nil) then Result := E_POINTER;
nSpeedOfSound := 0.0;
if SUCCEEDED(Result) then
begin
xactSpeedOfSoundID := pEngine.GetGlobalVariableIndex('SpeedOfSound');
Result := pEngine.GetGlobalVariable(xactSpeedOfSoundID, nSpeedOfSound);
end;
if SUCCEEDED(Result)
then X3DAudioInitialize(SpeakerChannelMask, nSpeedOfSound, X3DInstance);
end;
////
// DESCRIPTION:
// Calculates DSP settings with respect to 3D parameters:
//
// PARAMETERS:
// X3DInstance - [in] X3DAudio instance (returned from XACT3DInitialize)
// pListener - [in] point of 3D audio reception
// pEmitter - [in] 3D audio source
// pDSPSettings - [out] receives calculation results, applied to an XACT cue via XACT3DApply
//
// RETURN VALUE:
// HResult error code
////
function XACT3DCalculate(const X3DInstance: TX3DAudioHandle; const pListener: TX3DAudioListener;
var pEmitter: TX3DAudioEmitter; var pDSPSettings: TX3DAudioDspSettings): HRESULT; cdecl;{$IFDEF SUPPORTS_INLINE} inline;{$ENDIF}
begin
Result := S_OK;
{ if (pListener = nil) or (pEmitter = nil) or (pDSPSettings = nil)
then Result := E_POINTER; }
// if(SUCCEEDED(Result) then
if (pEmitter.ChannelCount > 1) and (pEmitter.pChannelAzimuths = nil) then
begin
pEmitter.ChannelRadius := 1.0;
case pEmitter.ChannelCount of
2: pEmitter.pChannelAzimuths := @aStereoLayout[0];
3: pEmitter.pChannelAzimuths := @a2Point1Layout[0];
4: pEmitter.pChannelAzimuths := @aQuadLayout[0];
5: pEmitter.pChannelAzimuths := @a4Point1Layout[0];
6: pEmitter.pChannelAzimuths := @a5Point1Layout[0];
8: pEmitter.pChannelAzimuths := @a7Point1Layout[0];
else
Result := E_FAIL;
end;
end;
if SUCCEEDED(Result) then
begin
if (pEmitter.pVolumeCurve = nil) then pEmitter.pVolumeCurve := @DefaultCurve;
if (pEmitter.pLFECurve = nil) then pEmitter.pLFECurve := @DefaultCurve;
X3DAudioCalculate(X3DInstance, pListener, pEmitter,
X3DAUDIO_CALCULATE_MATRIX or X3DAUDIO_CALCULATE_DOPPLER or X3DAUDIO_CALCULATE_EMITTER_ANGLE,
pDSPSettings);
end;
end;
////
// DESCRIPTION:
// Applies a 3D calculation returned by XACT3DCalculate to a cue:
//
// PARAMETERS:
// pDSPSettings - [in] calculation results generated by XACT3DCalculate
// pCue - [in] cue to which to apply pDSPSettings
// ChannelCount - [in] should be set equal to pDSPSettings->SrcChannelCount.
//
// RETURN VALUE:
// HResult error code
////
function XACT3DApply(const pDSPSettings: TX3DAudioDspSettings; const pCue: IXACTCue;
ChannelCount: LongWord): HRESULT; cdecl;{$IFDEF SUPPORTS_INLINE} inline;{$ENDIF}
var
xactDistanceID: TXACTVariableIndex;
xactDopplerID: TXACTVariableIndex;
xactOrientationID: TXACTVariableIndex;
begin
{ Result := S_OK;
if (pDSPSettings = nil) or )pCue = nil) then Result := E_POINTER;
if SUCCEEDED(Result) then }
Result := pCue.SetMatrixCoefficients(pDSPSettings.SrcChannelCount, pDSPSettings.DstChannelCount, pDSPSettings.pMatrixCoefficients);
if SUCCEEDED(Result) then
begin
xactDistanceID := pCue.GetVariableIndex('Distance'
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -