mirror of
https://github.com/jmarshall23/DoomRTX.git
synced 2026-08-17 11:00:38 +02:00
OpenAL is enabled, EAX fixes and removed DirectSound completely.
This commit is contained in:
@@ -1,533 +0,0 @@
|
||||
/******************************************************************
|
||||
*
|
||||
* EAX.H - Environmental Audio Extensions version 3.0
|
||||
* for OpenAL and DirectSound3D
|
||||
* Updated May 22, 2001 by Jean-Marc Jot, Sam Dicker (version 1.0).
|
||||
*
|
||||
*******************************************************************
|
||||
*/
|
||||
|
||||
#ifndef EAX_H_INCLUDED
|
||||
#define EAX_H_INCLUDED
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
#ifndef OPENAL
|
||||
#include <dsound.h>
|
||||
|
||||
/*
|
||||
* EAX Wrapper Interface (using Direct X 7) {4FF53B81-1CE0-11d3-AAB8-00A0C95949D5}
|
||||
*/
|
||||
DEFINE_GUID(CLSID_EAXDirectSound,
|
||||
0x4ff53b81,
|
||||
0x1ce0,
|
||||
0x11d3,
|
||||
0xaa, 0xb8, 0x0, 0xa0, 0xc9, 0x59, 0x49, 0xd5);
|
||||
|
||||
/*
|
||||
* EAX Wrapper Interface (using Direct X 8) {CA503B60-B176-11d4-A094-D0C0BF3A560C}
|
||||
*/
|
||||
DEFINE_GUID(CLSID_EAXDirectSound8,
|
||||
0xca503b60,
|
||||
0xb176,
|
||||
0x11d4,
|
||||
0xa0, 0x94, 0xd0, 0xc0, 0xbf, 0x3a, 0x56, 0xc);
|
||||
|
||||
|
||||
|
||||
#ifdef DIRECTSOUND_VERSION
|
||||
#if DIRECTSOUND_VERSION == 0x0800
|
||||
__declspec(dllimport) HRESULT WINAPI EAXDirectSoundCreate8(GUID*, LPDIRECTSOUND8*, IUnknown FAR *);
|
||||
typedef HRESULT (FAR PASCAL *LPEAXDIRECTSOUNDCREATE8)(GUID*, LPDIRECTSOUND*, IUnknown FAR*);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
__declspec(dllimport) HRESULT WINAPI EAXDirectSoundCreate(GUID*, LPDIRECTSOUND*, IUnknown FAR *);
|
||||
typedef HRESULT (FAR PASCAL *LPEAXDIRECTSOUNDCREATE)(GUID*, LPDIRECTSOUND*, IUnknown FAR*);
|
||||
|
||||
#else // OPENAL
|
||||
#include "..\Sdk\OpenAL\Include\al.h"
|
||||
|
||||
#ifndef GUID_DEFINED
|
||||
#define GUID_DEFINED
|
||||
typedef struct _GUID
|
||||
{
|
||||
unsigned long Data1;
|
||||
unsigned short Data2;
|
||||
unsigned short Data3;
|
||||
unsigned char Data4[8];
|
||||
} GUID;
|
||||
#endif // !GUID_DEFINED
|
||||
|
||||
#ifndef DEFINE_GUID
|
||||
#ifndef INITGUID
|
||||
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
|
||||
extern const GUID FAR name
|
||||
#else
|
||||
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
|
||||
extern const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
|
||||
#endif // INITGUID
|
||||
#endif // DEFINE_GUID
|
||||
|
||||
|
||||
/*
|
||||
* EAX OpenAL Extension
|
||||
*/
|
||||
typedef ALenum (*EAXSet)(const GUID*, ALuint, ALuint, ALvoid*, ALuint);
|
||||
typedef ALenum (*EAXGet)(const GUID*, ALuint, ALuint, ALvoid*, ALuint);
|
||||
#endif
|
||||
|
||||
#pragma pack(push, 4)
|
||||
|
||||
/*
|
||||
* EAX 3.0 listener property set {A8FA6880-B476-11d3-BDB9-00C0F02DDF87}
|
||||
*/
|
||||
DEFINE_GUID(DSPROPSETID_EAX30_ListenerProperties,
|
||||
0xa8fa6882,
|
||||
0xb476,
|
||||
0x11d3,
|
||||
0xbd, 0xb9, 0x00, 0xc0, 0xf0, 0x2d, 0xdf, 0x87);
|
||||
|
||||
// For compatibility with future EAX versions:
|
||||
#define DSPROPSETID_EAX_ListenerProperties DSPROPSETID_EAX30_ListenerProperties
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DSPROPERTY_EAXLISTENER_NONE,
|
||||
DSPROPERTY_EAXLISTENER_ALLPARAMETERS,
|
||||
DSPROPERTY_EAXLISTENER_ENVIRONMENT,
|
||||
DSPROPERTY_EAXLISTENER_ENVIRONMENTSIZE,
|
||||
DSPROPERTY_EAXLISTENER_ENVIRONMENTDIFFUSION,
|
||||
DSPROPERTY_EAXLISTENER_ROOM,
|
||||
DSPROPERTY_EAXLISTENER_ROOMHF,
|
||||
DSPROPERTY_EAXLISTENER_ROOMLF,
|
||||
DSPROPERTY_EAXLISTENER_DECAYTIME,
|
||||
DSPROPERTY_EAXLISTENER_DECAYHFRATIO,
|
||||
DSPROPERTY_EAXLISTENER_DECAYLFRATIO,
|
||||
DSPROPERTY_EAXLISTENER_REFLECTIONS,
|
||||
DSPROPERTY_EAXLISTENER_REFLECTIONSDELAY,
|
||||
DSPROPERTY_EAXLISTENER_REFLECTIONSPAN,
|
||||
DSPROPERTY_EAXLISTENER_REVERB,
|
||||
DSPROPERTY_EAXLISTENER_REVERBDELAY,
|
||||
DSPROPERTY_EAXLISTENER_REVERBPAN,
|
||||
DSPROPERTY_EAXLISTENER_ECHOTIME,
|
||||
DSPROPERTY_EAXLISTENER_ECHODEPTH,
|
||||
DSPROPERTY_EAXLISTENER_MODULATIONTIME,
|
||||
DSPROPERTY_EAXLISTENER_MODULATIONDEPTH,
|
||||
DSPROPERTY_EAXLISTENER_AIRABSORPTIONHF,
|
||||
DSPROPERTY_EAXLISTENER_HFREFERENCE,
|
||||
DSPROPERTY_EAXLISTENER_LFREFERENCE,
|
||||
DSPROPERTY_EAXLISTENER_ROOMROLLOFFFACTOR,
|
||||
DSPROPERTY_EAXLISTENER_FLAGS
|
||||
} DSPROPERTY_EAX_LISTENERPROPERTY;
|
||||
|
||||
// OR these flags with property id
|
||||
#define DSPROPERTY_EAXLISTENER_IMMEDIATE 0x00000000 // changes take effect immediately
|
||||
#define DSPROPERTY_EAXLISTENER_DEFERRED 0x80000000 // changes take effect later
|
||||
#define DSPROPERTY_EAXLISTENER_COMMITDEFERREDSETTINGS (DSPROPERTY_EAXLISTENER_NONE | \
|
||||
DSPROPERTY_EAXLISTENER_IMMEDIATE)
|
||||
|
||||
typedef struct _EAXVECTOR {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
} EAXVECTOR;
|
||||
|
||||
// Use this structure for DSPROPERTY_EAXLISTENER_ALLPARAMETERS
|
||||
// - all levels are hundredths of decibels
|
||||
// - all times and delays are in seconds
|
||||
//
|
||||
// NOTE: This structure may change in future EAX versions.
|
||||
// It is recommended to initialize fields by name:
|
||||
// myListener.lRoom = -1000;
|
||||
// myListener.lRoomHF = -100;
|
||||
// ...
|
||||
// myListener.dwFlags = myFlags /* see EAXLISTENERFLAGS below */ ;
|
||||
// instead of:
|
||||
// myListener = { -1000, -100, ... , 0x00000009 };
|
||||
// If you want to save and load presets in binary form, you
|
||||
// should define your own structure to insure future compatibility.
|
||||
//
|
||||
typedef struct _EAXLISTENERPROPERTIES
|
||||
{
|
||||
unsigned long ulEnvironment; // sets all listener properties
|
||||
float flEnvironmentSize; // environment size in meters
|
||||
float flEnvironmentDiffusion; // environment diffusion
|
||||
long lRoom; // room effect level (at mid frequencies)
|
||||
long lRoomHF; // relative room effect level at high frequencies
|
||||
long lRoomLF; // relative room effect level at low frequencies
|
||||
float flDecayTime; // reverberation decay time at mid frequencies
|
||||
float flDecayHFRatio; // high-frequency to mid-frequency decay time ratio
|
||||
float flDecayLFRatio; // low-frequency to mid-frequency decay time ratio
|
||||
long lReflections; // early reflections level relative to room effect
|
||||
float flReflectionsDelay; // initial reflection delay time
|
||||
EAXVECTOR vReflectionsPan; // early reflections panning vector
|
||||
long lReverb; // late reverberation level relative to room effect
|
||||
float flReverbDelay; // late reverberation delay time relative to initial reflection
|
||||
EAXVECTOR vReverbPan; // late reverberation panning vector
|
||||
float flEchoTime; // echo time
|
||||
float flEchoDepth; // echo depth
|
||||
float flModulationTime; // modulation time
|
||||
float flModulationDepth; // modulation depth
|
||||
float flAirAbsorptionHF; // change in level per meter at high frequencies
|
||||
float flHFReference; // reference high frequency
|
||||
float flLFReference; // reference low frequency
|
||||
float flRoomRolloffFactor; // like DS3D flRolloffFactor but for room effect
|
||||
unsigned long ulFlags; // modifies the behavior of properties
|
||||
} EAXLISTENERPROPERTIES, *LPEAXLISTENERPROPERTIES;
|
||||
|
||||
// used by DSPROPERTY_EAXLISTENER_ENVIRONMENT
|
||||
enum
|
||||
{
|
||||
EAX_ENVIRONMENT_GENERIC,
|
||||
EAX_ENVIRONMENT_PADDEDCELL,
|
||||
EAX_ENVIRONMENT_ROOM,
|
||||
EAX_ENVIRONMENT_BATHROOM,
|
||||
EAX_ENVIRONMENT_LIVINGROOM,
|
||||
EAX_ENVIRONMENT_STONEROOM,
|
||||
EAX_ENVIRONMENT_AUDITORIUM,
|
||||
EAX_ENVIRONMENT_CONCERTHALL,
|
||||
EAX_ENVIRONMENT_CAVE,
|
||||
EAX_ENVIRONMENT_ARENA,
|
||||
EAX_ENVIRONMENT_HANGAR,
|
||||
EAX_ENVIRONMENT_CARPETEDHALLWAY,
|
||||
EAX_ENVIRONMENT_HALLWAY,
|
||||
EAX_ENVIRONMENT_STONECORRIDOR,
|
||||
EAX_ENVIRONMENT_ALLEY,
|
||||
EAX_ENVIRONMENT_FOREST,
|
||||
EAX_ENVIRONMENT_CITY,
|
||||
EAX_ENVIRONMENT_MOUNTAINS,
|
||||
EAX_ENVIRONMENT_QUARRY,
|
||||
EAX_ENVIRONMENT_PLAIN,
|
||||
EAX_ENVIRONMENT_PARKINGLOT,
|
||||
EAX_ENVIRONMENT_SEWERPIPE,
|
||||
EAX_ENVIRONMENT_UNDERWATER,
|
||||
EAX_ENVIRONMENT_DRUGGED,
|
||||
EAX_ENVIRONMENT_DIZZY,
|
||||
EAX_ENVIRONMENT_PSYCHOTIC,
|
||||
|
||||
EAX_ENVIRONMENT_UNDEFINED,
|
||||
|
||||
EAX_ENVIRONMENT_COUNT
|
||||
};
|
||||
|
||||
// Used by DSPROPERTY_EAXLISTENER_FLAGS
|
||||
//
|
||||
// Note: The number and order of flags may change in future EAX versions.
|
||||
// It is recommended to use the flag defines as follows:
|
||||
// myFlags = EAXLISTENERFLAGS_DECAYTIMESCALE | EAXLISTENERFLAGS_REVERBSCALE;
|
||||
// instead of:
|
||||
// myFlags = 0x00000009;
|
||||
//
|
||||
// These flags determine what properties are affected by environment size.
|
||||
#define EAXLISTENERFLAGS_DECAYTIMESCALE 0x00000001 // reverberation decay time
|
||||
#define EAXLISTENERFLAGS_REFLECTIONSSCALE 0x00000002 // reflection level
|
||||
#define EAXLISTENERFLAGS_REFLECTIONSDELAYSCALE 0x00000004 // initial reflection delay time
|
||||
#define EAXLISTENERFLAGS_REVERBSCALE 0x00000008 // reflections level
|
||||
#define EAXLISTENERFLAGS_REVERBDELAYSCALE 0x00000010 // late reverberation delay time
|
||||
#define EAXLISTENERFLAGS_ECHOTIMESCALE 0x00000040 // echo time
|
||||
#define EAXLISTENERFLAGS_MODULATIONTIMESCALE 0x00000080 // modulation time
|
||||
|
||||
// This flag limits high-frequency decay time according to air absorption.
|
||||
#define EAXLISTENERFLAGS_DECAYHFLIMIT 0x00000020
|
||||
|
||||
#define EAXLISTENERFLAGS_RESERVED 0xFFFFFF00 // reserved future use
|
||||
|
||||
// Property ranges and defaults:
|
||||
|
||||
#define EAXLISTENER_MINENVIRONMENT 0
|
||||
#define EAXLISTENER_MAXENVIRONMENT (EAX_ENVIRONMENT_COUNT-1)
|
||||
#define EAXLISTENER_DEFAULTENVIRONMENT EAX_ENVIRONMENT_GENERIC
|
||||
|
||||
#define EAXLISTENER_MINENVIRONMENTSIZE 1.0f
|
||||
#define EAXLISTENER_MAXENVIRONMENTSIZE 100.0f
|
||||
#define EAXLISTENER_DEFAULTENVIRONMENTSIZE 7.5f
|
||||
|
||||
#define EAXLISTENER_MINENVIRONMENTDIFFUSION 0.0f
|
||||
#define EAXLISTENER_MAXENVIRONMENTDIFFUSION 1.0f
|
||||
#define EAXLISTENER_DEFAULTENVIRONMENTDIFFUSION 1.0f
|
||||
|
||||
#define EAXLISTENER_MINROOM (-10000)
|
||||
#define EAXLISTENER_MAXROOM 0
|
||||
#define EAXLISTENER_DEFAULTROOM (-1000)
|
||||
|
||||
#define EAXLISTENER_MINROOMHF (-10000)
|
||||
#define EAXLISTENER_MAXROOMHF 0
|
||||
#define EAXLISTENER_DEFAULTROOMHF (-100)
|
||||
|
||||
#define EAXLISTENER_MINROOMLF (-10000)
|
||||
#define EAXLISTENER_MAXROOMLF 0
|
||||
#define EAXLISTENER_DEFAULTROOMLF 0
|
||||
|
||||
#define EAXLISTENER_MINDECAYTIME 0.1f
|
||||
#define EAXLISTENER_MAXDECAYTIME 20.0f
|
||||
#define EAXLISTENER_DEFAULTDECAYTIME 1.49f
|
||||
|
||||
#define EAXLISTENER_MINDECAYHFRATIO 0.1f
|
||||
#define EAXLISTENER_MAXDECAYHFRATIO 2.0f
|
||||
#define EAXLISTENER_DEFAULTDECAYHFRATIO 0.83f
|
||||
|
||||
#define EAXLISTENER_MINDECAYLFRATIO 0.1f
|
||||
#define EAXLISTENER_MAXDECAYLFRATIO 2.0f
|
||||
#define EAXLISTENER_DEFAULTDECAYLFRATIO 1.00f
|
||||
|
||||
#define EAXLISTENER_MINREFLECTIONS (-10000)
|
||||
#define EAXLISTENER_MAXREFLECTIONS 1000
|
||||
#define EAXLISTENER_DEFAULTREFLECTIONS (-2602)
|
||||
|
||||
#define EAXLISTENER_MINREFLECTIONSDELAY 0.0f
|
||||
#define EAXLISTENER_MAXREFLECTIONSDELAY 0.3f
|
||||
#define EAXLISTENER_DEFAULTREFLECTIONSDELAY 0.007f
|
||||
|
||||
#define EAXLISTENER_MINREVERB (-10000)
|
||||
#define EAXLISTENER_MAXREVERB 2000
|
||||
#define EAXLISTENER_DEFAULTREVERB 200
|
||||
|
||||
#define EAXLISTENER_MINREVERBDELAY 0.0f
|
||||
#define EAXLISTENER_MAXREVERBDELAY 0.1f
|
||||
#define EAXLISTENER_DEFAULTREVERBDELAY 0.011f
|
||||
|
||||
#define EAXLISTENER_MINECHOTIME 0.075f
|
||||
#define EAXLISTENER_MAXECHOTIME 0.25f
|
||||
#define EAXLISTENER_DEFAULTECHOTIME 0.25f
|
||||
|
||||
#define EAXLISTENER_MINECHODEPTH 0.0f
|
||||
#define EAXLISTENER_MAXECHODEPTH 1.0f
|
||||
#define EAXLISTENER_DEFAULTECHODEPTH 0.0f
|
||||
|
||||
#define EAXLISTENER_MINMODULATIONTIME 0.04f
|
||||
#define EAXLISTENER_MAXMODULATIONTIME 4.0f
|
||||
#define EAXLISTENER_DEFAULTMODULATIONTIME 0.25f
|
||||
|
||||
#define EAXLISTENER_MINMODULATIONDEPTH 0.0f
|
||||
#define EAXLISTENER_MAXMODULATIONDEPTH 1.0f
|
||||
#define EAXLISTENER_DEFAULTMODULATIONDEPTH 0.0f
|
||||
|
||||
#define EAXLISTENER_MINAIRABSORPTIONHF (-100.0f)
|
||||
#define EAXLISTENER_MAXAIRABSORPTIONHF 0.0f
|
||||
#define EAXLISTENER_DEFAULTAIRABSORPTIONHF (-5.0f)
|
||||
|
||||
#define EAXLISTENER_MINHFREFERENCE 1000.0f
|
||||
#define EAXLISTENER_MAXHFREFERENCE 20000.0f
|
||||
#define EAXLISTENER_DEFAULTHFREFERENCE 5000.0f
|
||||
|
||||
#define EAXLISTENER_MINLFREFERENCE 20.0f
|
||||
#define EAXLISTENER_MAXLFREFERENCE 1000.0f
|
||||
#define EAXLISTENER_DEFAULTLFREFERENCE 250.0f
|
||||
|
||||
#define EAXLISTENER_MINROOMROLLOFFFACTOR 0.0f
|
||||
#define EAXLISTENER_MAXROOMROLLOFFFACTOR 10.0f
|
||||
#define EAXLISTENER_DEFAULTROOMROLLOFFFACTOR 0.0f
|
||||
|
||||
#define EAXLISTENER_DEFAULTFLAGS (EAXLISTENERFLAGS_DECAYTIMESCALE | \
|
||||
EAXLISTENERFLAGS_REFLECTIONSSCALE | \
|
||||
EAXLISTENERFLAGS_REFLECTIONSDELAYSCALE | \
|
||||
EAXLISTENERFLAGS_REVERBSCALE | \
|
||||
EAXLISTENERFLAGS_REVERBDELAYSCALE | \
|
||||
EAXLISTENERFLAGS_DECAYHFLIMIT)
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* EAX 3.0 buffer property set {A8FA6881-B476-11d3-BDB9-00C0F02DDF87}
|
||||
*/
|
||||
DEFINE_GUID(DSPROPSETID_EAX30_BufferProperties,
|
||||
0xa8fa6881,
|
||||
0xb476,
|
||||
0x11d3,
|
||||
0xbd, 0xb9, 0x0, 0xc0, 0xf0, 0x2d, 0xdf, 0x87);
|
||||
|
||||
// For compatibility with future EAX versions:
|
||||
#define DSPROPSETID_EAX_BufferProperties DSPROPSETID_EAX30_BufferProperties
|
||||
#define DSPROPSETID_EAX_SourceProperties DSPROPSETID_EAX30_BufferProperties
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DSPROPERTY_EAXBUFFER_NONE,
|
||||
DSPROPERTY_EAXBUFFER_ALLPARAMETERS,
|
||||
DSPROPERTY_EAXBUFFER_OBSTRUCTIONPARAMETERS,
|
||||
DSPROPERTY_EAXBUFFER_OCCLUSIONPARAMETERS,
|
||||
DSPROPERTY_EAXBUFFER_EXCLUSIONPARAMETERS,
|
||||
DSPROPERTY_EAXBUFFER_DIRECT,
|
||||
DSPROPERTY_EAXBUFFER_DIRECTHF,
|
||||
DSPROPERTY_EAXBUFFER_ROOM,
|
||||
DSPROPERTY_EAXBUFFER_ROOMHF,
|
||||
DSPROPERTY_EAXBUFFER_OBSTRUCTION,
|
||||
DSPROPERTY_EAXBUFFER_OBSTRUCTIONLFRATIO,
|
||||
DSPROPERTY_EAXBUFFER_OCCLUSION,
|
||||
DSPROPERTY_EAXBUFFER_OCCLUSIONLFRATIO,
|
||||
DSPROPERTY_EAXBUFFER_OCCLUSIONROOMRATIO,
|
||||
DSPROPERTY_EAXBUFFER_OCCLUSIONDIRECTRATIO,
|
||||
DSPROPERTY_EAXBUFFER_EXCLUSION,
|
||||
DSPROPERTY_EAXBUFFER_EXCLUSIONLFRATIO,
|
||||
DSPROPERTY_EAXBUFFER_OUTSIDEVOLUMEHF,
|
||||
DSPROPERTY_EAXBUFFER_DOPPLERFACTOR,
|
||||
DSPROPERTY_EAXBUFFER_ROLLOFFFACTOR,
|
||||
DSPROPERTY_EAXBUFFER_ROOMROLLOFFFACTOR,
|
||||
DSPROPERTY_EAXBUFFER_AIRABSORPTIONFACTOR,
|
||||
DSPROPERTY_EAXBUFFER_FLAGS
|
||||
} DSPROPERTY_EAX_BUFFERPROPERTY;
|
||||
|
||||
// OR these flags with property id
|
||||
#define DSPROPERTY_EAXBUFFER_IMMEDIATE 0x00000000 // changes take effect immediately
|
||||
#define DSPROPERTY_EAXBUFFER_DEFERRED 0x80000000 // changes take effect later
|
||||
#define DSPROPERTY_EAXBUFFER_COMMITDEFERREDSETTINGS (DSPROPERTY_EAXBUFFER_NONE | \
|
||||
DSPROPERTY_EAXBUFFER_IMMEDIATE)
|
||||
|
||||
// Use this structure for DSPROPERTY_EAXBUFFER_ALLPARAMETERS
|
||||
// - all levels are hundredths of decibels
|
||||
// - all delays are in seconds
|
||||
//
|
||||
// NOTE: This structure may change in future EAX versions.
|
||||
// It is recommended to initialize fields by name:
|
||||
// myBuffer.lDirect = 0;
|
||||
// myBuffer.lDirectHF = -200;
|
||||
// ...
|
||||
// myBuffer.dwFlags = myFlags /* see EAXBUFFERFLAGS below */ ;
|
||||
// instead of:
|
||||
// myBuffer = { 0, -200, ... , 0x00000003 };
|
||||
//
|
||||
typedef struct _EAXBUFFERPROPERTIES
|
||||
{
|
||||
long lDirect; // direct path level (at low and mid frequencies)
|
||||
long lDirectHF; // relative direct path level at high frequencies
|
||||
long lRoom; // room effect level (at low and mid frequencies)
|
||||
long lRoomHF; // relative room effect level at high frequencies
|
||||
long lObstruction; // main obstruction control (attenuation at high frequencies)
|
||||
float flObstructionLFRatio; // obstruction low-frequency level re. main control
|
||||
long lOcclusion; // main occlusion control (attenuation at high frequencies)
|
||||
float flOcclusionLFRatio; // occlusion low-frequency level re. main control
|
||||
float flOcclusionRoomRatio; // relative occlusion control for room effect
|
||||
float flOcclusionDirectRatio; // relative occlusion control for direct path
|
||||
long lExclusion; // main exlusion control (attenuation at high frequencies)
|
||||
float flExclusionLFRatio; // exclusion low-frequency level re. main control
|
||||
long lOutsideVolumeHF; // outside sound cone level at high frequencies
|
||||
float flDopplerFactor; // like DS3D flDopplerFactor but per source
|
||||
float flRolloffFactor; // like DS3D flRolloffFactor but per source
|
||||
float flRoomRolloffFactor; // like DS3D flRolloffFactor but for room effect
|
||||
float flAirAbsorptionFactor; // multiplies DSPROPERTY_EAXLISTENER_AIRABSORPTIONHF
|
||||
unsigned long ulFlags; // modifies the behavior of properties
|
||||
} EAXBUFFERPROPERTIES, *LPEAXBUFFERPROPERTIES;
|
||||
|
||||
// Use this structure for DSPROPERTY_EAXBUFFER_OBSTRUCTION,
|
||||
typedef struct _EAXOBSTRUCTIONPROPERTIES
|
||||
{
|
||||
long lObstruction;
|
||||
float flObstructionLFRatio;
|
||||
} EAXOBSTRUCTIONPROPERTIES, *LPEAXOBSTRUCTIONPROPERTIES;
|
||||
|
||||
// Use this structure for DSPROPERTY_EAXBUFFER_OCCLUSION
|
||||
typedef struct _EAXOCCLUSIONPROPERTIES
|
||||
{
|
||||
long lOcclusion;
|
||||
float flOcclusionLFRatio;
|
||||
float flOcclusionRoomRatio;
|
||||
float flOcclusionDirectRatio;
|
||||
} EAXOCCLUSIONPROPERTIES, *LPEAXOCCLUSIONPROPERTIES;
|
||||
|
||||
// Use this structure for DSPROPERTY_EAXBUFFER_EXCLUSION
|
||||
typedef struct _EAXEXCLUSIONPROPERTIES
|
||||
{
|
||||
long lExclusion;
|
||||
float flExclusionLFRatio;
|
||||
} EAXEXCLUSIONPROPERTIES, *LPEAXEXCLUSIONPROPERTIES;
|
||||
|
||||
// Used by DSPROPERTY_EAXBUFFER_FLAGS
|
||||
// TRUE: value is computed automatically - property is an offset
|
||||
// FALSE: value is used directly
|
||||
//
|
||||
// Note: The number and order of flags may change in future EAX versions.
|
||||
// To insure future compatibility, use flag defines as follows:
|
||||
// myFlags = EAXBUFFERFLAGS_DIRECTHFAUTO | EAXBUFFERFLAGS_ROOMAUTO;
|
||||
// instead of:
|
||||
// myFlags = 0x00000003;
|
||||
//
|
||||
#define EAXBUFFERFLAGS_DIRECTHFAUTO 0x00000001 // affects DSPROPERTY_EAXBUFFER_DIRECTHF
|
||||
#define EAXBUFFERFLAGS_ROOMAUTO 0x00000002 // affects DSPROPERTY_EAXBUFFER_ROOM
|
||||
#define EAXBUFFERFLAGS_ROOMHFAUTO 0x00000004 // affects DSPROPERTY_EAXBUFFER_ROOMHF
|
||||
|
||||
#define EAXBUFFERFLAGS_RESERVED 0xFFFFFFF8 // reserved future use
|
||||
|
||||
// Property ranges and defaults:
|
||||
|
||||
#define EAXBUFFER_MINDIRECT (-10000)
|
||||
#define EAXBUFFER_MAXDIRECT 1000
|
||||
#define EAXBUFFER_DEFAULTDIRECT 0
|
||||
|
||||
#define EAXBUFFER_MINDIRECTHF (-10000)
|
||||
#define EAXBUFFER_MAXDIRECTHF 0
|
||||
#define EAXBUFFER_DEFAULTDIRECTHF 0
|
||||
|
||||
#define EAXBUFFER_MINROOM (-10000)
|
||||
#define EAXBUFFER_MAXROOM 1000
|
||||
#define EAXBUFFER_DEFAULTROOM 0
|
||||
|
||||
#define EAXBUFFER_MINROOMHF (-10000)
|
||||
#define EAXBUFFER_MAXROOMHF 0
|
||||
#define EAXBUFFER_DEFAULTROOMHF 0
|
||||
|
||||
#define EAXBUFFER_MINOBSTRUCTION (-10000)
|
||||
#define EAXBUFFER_MAXOBSTRUCTION 0
|
||||
#define EAXBUFFER_DEFAULTOBSTRUCTION 0
|
||||
|
||||
#define EAXBUFFER_MINOBSTRUCTIONLFRATIO 0.0f
|
||||
#define EAXBUFFER_MAXOBSTRUCTIONLFRATIO 1.0f
|
||||
#define EAXBUFFER_DEFAULTOBSTRUCTIONLFRATIO 0.0f
|
||||
|
||||
#define EAXBUFFER_MINOCCLUSION (-10000)
|
||||
#define EAXBUFFER_MAXOCCLUSION 0
|
||||
#define EAXBUFFER_DEFAULTOCCLUSION 0
|
||||
|
||||
#define EAXBUFFER_MINOCCLUSIONLFRATIO 0.0f
|
||||
#define EAXBUFFER_MAXOCCLUSIONLFRATIO 1.0f
|
||||
#define EAXBUFFER_DEFAULTOCCLUSIONLFRATIO 0.25f
|
||||
|
||||
#define EAXBUFFER_MINOCCLUSIONROOMRATIO 0.0f
|
||||
#define EAXBUFFER_MAXOCCLUSIONROOMRATIO 10.0f
|
||||
#define EAXBUFFER_DEFAULTOCCLUSIONROOMRATIO 1.5f
|
||||
|
||||
#define EAXBUFFER_MINOCCLUSIONDIRECTRATIO 0.0f
|
||||
#define EAXBUFFER_MAXOCCLUSIONDIRECTRATIO 10.0f
|
||||
#define EAXBUFFER_DEFAULTOCCLUSIONDIRECTRATIO 1.0f
|
||||
|
||||
#define EAXBUFFER_MINEXCLUSION (-10000)
|
||||
#define EAXBUFFER_MAXEXCLUSION 0
|
||||
#define EAXBUFFER_DEFAULTEXCLUSION 0
|
||||
|
||||
#define EAXBUFFER_MINEXCLUSIONLFRATIO 0.0f
|
||||
#define EAXBUFFER_MAXEXCLUSIONLFRATIO 1.0f
|
||||
#define EAXBUFFER_DEFAULTEXCLUSIONLFRATIO 1.0f
|
||||
|
||||
#define EAXBUFFER_MINOUTSIDEVOLUMEHF (-10000)
|
||||
#define EAXBUFFER_MAXOUTSIDEVOLUMEHF 0
|
||||
#define EAXBUFFER_DEFAULTOUTSIDEVOLUMEHF 0
|
||||
|
||||
#define EAXBUFFER_MINDOPPLERFACTOR 0.0f
|
||||
#define EAXBUFFER_MAXDOPPLERFACTOR 10.f
|
||||
#define EAXBUFFER_DEFAULTDOPPLERFACTOR 0.0f
|
||||
|
||||
#define EAXBUFFER_MINROLLOFFFACTOR 0.0f
|
||||
#define EAXBUFFER_MAXROLLOFFFACTOR 10.f
|
||||
#define EAXBUFFER_DEFAULTROLLOFFFACTOR 0.0f
|
||||
|
||||
#define EAXBUFFER_MINROOMROLLOFFFACTOR 0.0f
|
||||
#define EAXBUFFER_MAXROOMROLLOFFFACTOR 10.f
|
||||
#define EAXBUFFER_DEFAULTROOMROLLOFFFACTOR 0.0f
|
||||
|
||||
#define EAXBUFFER_MINAIRABSORPTIONFACTOR 0.0f
|
||||
#define EAXBUFFER_MAXAIRABSORPTIONFACTOR 10.0f
|
||||
#define EAXBUFFER_DEFAULTAIRABSORPTIONFACTOR 1.0f
|
||||
|
||||
#define EAXBUFFER_DEFAULTFLAGS (EAXBUFFERFLAGS_DIRECTHFAUTO | \
|
||||
EAXBUFFERFLAGS_ROOMAUTO | \
|
||||
EAXBUFFERFLAGS_ROOMHFAUTO )
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
@@ -2,507 +2,59 @@
|
||||
===========================================================================
|
||||
|
||||
IceTech GPL Source Code
|
||||
Copyright (C) 2026 Justin Marshall
|
||||
|
||||
This file is part of the IceTech GPL Source Code (?IceTech Source Code?).
|
||||
|
||||
IceTech Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
IceTech Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with IceTech Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the IceTech Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the IceTech Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing Justin Marshall, justinmarshall20@gmail.com
|
||||
Copyright (C) 2026 Justin Marshall
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
#include "precompiled.h"
|
||||
#pragma hdrstop
|
||||
|
||||
// DirectX SDK
|
||||
//#include <DxErr.h>
|
||||
#define DXTRACE_ERR(str,hr) (hr)
|
||||
|
||||
#include <ks.h>
|
||||
#include <ksmedia.h>
|
||||
#include "../../sound/snd_local.h"
|
||||
#include "win_local.h"
|
||||
|
||||
#include "../../openal/idal.cpp"
|
||||
|
||||
#define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } }
|
||||
#define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p); (p)=NULL; } }
|
||||
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
|
||||
|
||||
class idAudioBufferWIN32 : public idAudioBuffer {
|
||||
public:
|
||||
idAudioBufferWIN32( LPDIRECTSOUNDBUFFER apDSBuffer, dword dwDSBufferSize, idWaveFile* pWaveFile=NULL );
|
||||
~idAudioBufferWIN32();
|
||||
|
||||
int FillBufferWithSound( LPDIRECTSOUNDBUFFER pDSB, bool bRepeatWavIfBufferLarger );
|
||||
|
||||
bool Lock( void **pDSLockedBuffer, ulong *dwDSLockedBufferSize );
|
||||
bool Unlock(void *pDSLockedBuffer, dword dwDSLockedBufferSize );
|
||||
bool GetCurrentPosition( ulong *pdwCurrentWriteCursor );
|
||||
|
||||
int Play( dword dwPriority=0, dword dwFlags=0 );
|
||||
int Stop( void );
|
||||
int Reset( void );
|
||||
bool IsSoundPlaying( void );
|
||||
void SetVolume( float x);
|
||||
|
||||
idWaveFile* m_pWaveFile;
|
||||
private:
|
||||
LPDIRECTSOUNDBUFFER m_apDSBuffer;
|
||||
dword m_dwDSBufferSize;
|
||||
|
||||
int RestoreBuffer( LPDIRECTSOUNDBUFFER pDSB, bool* pbWasRestored );
|
||||
};
|
||||
/*
|
||||
===============
|
||||
idAudioHardwareWIN32
|
||||
|
||||
OpenAL owns the Windows playback device. The sound system still asks for an
|
||||
idAudioHardware object so shared mixer timing and speaker-count code can run.
|
||||
===============
|
||||
*/
|
||||
class idAudioHardwareWIN32 : public idAudioHardware {
|
||||
|
||||
public:
|
||||
idAudioHardwareWIN32();
|
||||
~idAudioHardwareWIN32();
|
||||
idAudioHardwareWIN32() {
|
||||
numSpeakers = idSoundSystemLocal::s_numberOfSpeakers.GetInteger();
|
||||
if ( numSpeakers != 6 ) {
|
||||
numSpeakers = 2;
|
||||
}
|
||||
}
|
||||
|
||||
bool Initialize( );
|
||||
bool InitializeSpeakers( byte *buffer, int bufferSize, dword dwPrimaryFreq, dword dwPrimaryBitRate, dword dwSpeakers );
|
||||
|
||||
void SetPrimaryBufferFormat( dword dwPrimaryFreq, dword dwPrimaryBitRate, dword dwSpeakers );
|
||||
|
||||
int Create( idWaveFile* pWaveFile, idAudioBuffer** ppiab );
|
||||
int Create( idAudioBuffer** ppSound, const char* strWaveFileName, dword dwCreationFlags = 0 );
|
||||
int CreateFromMemory( idAudioBufferWIN32** ppSound, byte* pbData, ulong ulDataSize, waveformatextensible_t *pwfx, dword dwCreationFlags = 0 );
|
||||
|
||||
bool Lock( void **pDSLockedBuffer, ulong *dwDSLockedBufferSize );
|
||||
bool Unlock( void *pDSLockedBuffer, dword dwDSLockedBufferSize );
|
||||
bool GetCurrentPosition( ulong *pdwCurrentWriteCursor );
|
||||
|
||||
int GetNumberOfSpeakers() { return numSpeakers; }
|
||||
int GetMixBufferSize() { return MIXBUFFER_SAMPLES * blockAlign; }
|
||||
|
||||
// WIN32 driver doesn't support write API
|
||||
bool Flush( void ) { return true; }
|
||||
void Write( bool ) { }
|
||||
short* GetMixBuffer( void ) { return NULL; }
|
||||
virtual bool Initialize() { return true; }
|
||||
virtual bool Lock( void **pDSLockedBuffer, ulong *dwDSLockedBufferSize ) {
|
||||
*pDSLockedBuffer = NULL;
|
||||
*dwDSLockedBufferSize = 0;
|
||||
return false;
|
||||
}
|
||||
virtual bool Unlock( void *pDSLockedBuffer, dword dwDSLockedBufferSize ) { return false; }
|
||||
virtual bool GetCurrentPosition( ulong *pdwCurrentWriteCursor ) {
|
||||
*pdwCurrentWriteCursor = 0;
|
||||
return false;
|
||||
}
|
||||
virtual bool Flush( void ) { return true; }
|
||||
virtual void Write( bool flushing ) {}
|
||||
virtual int GetNumberOfSpeakers( void ) { return numSpeakers; }
|
||||
virtual int GetMixBufferSize( void ) { return MIXBUFFER_SAMPLES * numSpeakers * sizeof( short ); }
|
||||
virtual short *GetMixBuffer( void ) { return NULL; }
|
||||
|
||||
private:
|
||||
LPDIRECTSOUND m_pDS;
|
||||
LPDIRECTSOUNDBUFFER pDSBPrimary;
|
||||
idAudioBufferWIN32 *speakers;
|
||||
|
||||
int numSpeakers;
|
||||
int bitsPerSample;
|
||||
int bufferSize; // allocate buffer handed over to DirectSound
|
||||
int blockAlign; // channels * bits per sample / 8: sound frame size
|
||||
int numSpeakers;
|
||||
};
|
||||
|
||||
idAudioHardware *idAudioHardware::Alloc() { return new idAudioHardwareWIN32; }
|
||||
idAudioHardware::~idAudioHardware() {}
|
||||
|
||||
/*
|
||||
================
|
||||
idAudioHardwareWIN32::idAudioHardware
|
||||
================
|
||||
*/
|
||||
idAudioHardwareWIN32::idAudioHardwareWIN32() {
|
||||
m_pDS = NULL;
|
||||
pDSBPrimary = NULL;
|
||||
speakers = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idAudioHardwareWIN32::~idAudioHardware
|
||||
================
|
||||
*/
|
||||
idAudioHardwareWIN32::~idAudioHardwareWIN32() {
|
||||
SAFE_DELETE( speakers );
|
||||
SAFE_RELEASE( pDSBPrimary );
|
||||
SAFE_RELEASE( m_pDS );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idAudioHardwareWIN32::Initialize
|
||||
===============
|
||||
*/
|
||||
bool idAudioHardwareWIN32::Initialize( void ) {
|
||||
int hr;
|
||||
|
||||
bufferSize = 0;
|
||||
numSpeakers = 0;
|
||||
blockAlign = 0;
|
||||
|
||||
SAFE_RELEASE( m_pDS );
|
||||
|
||||
// Create IDirectSound using the primary sound device
|
||||
if( FAILED( hr = DirectSoundCreate( NULL, &m_pDS, NULL ) )) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set primary buffer format
|
||||
SetPrimaryBufferFormat( PRIMARYFREQ, 16, idSoundSystemLocal::s_numberOfSpeakers.GetInteger() );
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idAudioHardwareWIN32::InitializeSpeakers
|
||||
===============
|
||||
*/
|
||||
bool idAudioHardwareWIN32::InitializeSpeakers( byte *speakerData, int bufferSize, dword dwPrimaryFreq, dword dwPrimaryBitRate, dword dwSpeakers ) {
|
||||
if ( dwSpeakers == 2 ) {
|
||||
WAVEFORMATEXTENSIBLE wfx;
|
||||
ZeroMemory( &wfx, sizeof(WAVEFORMATEXTENSIBLE) );
|
||||
wfx.Format.wFormatTag = WAVE_FORMAT_PCM;
|
||||
wfx.Format.nChannels = 2;
|
||||
wfx.Format.nSamplesPerSec = dwPrimaryFreq;
|
||||
wfx.Format.wBitsPerSample = dwPrimaryBitRate;
|
||||
wfx.Format.nBlockAlign = wfx.Format.wBitsPerSample / 8 * wfx.Format.nChannels;
|
||||
wfx.Format.nAvgBytesPerSec = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign;
|
||||
wfx.Format.cbSize = sizeof(WAVEFORMATEX);
|
||||
|
||||
CreateFromMemory( &speakers, speakerData, bufferSize, (waveformatextensible_t *)&wfx );
|
||||
|
||||
common->Printf("sound: STEREO\n");
|
||||
} else {
|
||||
WAVEFORMATEXTENSIBLE waveFormatPCMEx;
|
||||
ZeroMemory( &waveFormatPCMEx, sizeof(WAVEFORMATEXTENSIBLE) );
|
||||
|
||||
waveFormatPCMEx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
|
||||
waveFormatPCMEx.Format.nChannels = 6;
|
||||
waveFormatPCMEx.Format.nSamplesPerSec = dwPrimaryFreq;
|
||||
waveFormatPCMEx.Format.wBitsPerSample = dwPrimaryBitRate;
|
||||
waveFormatPCMEx.Format.nBlockAlign = waveFormatPCMEx.Format.wBitsPerSample / 8 * waveFormatPCMEx.Format.nChannels;
|
||||
waveFormatPCMEx.Format.nAvgBytesPerSec = waveFormatPCMEx.Format.nSamplesPerSec * waveFormatPCMEx.Format.nBlockAlign;
|
||||
waveFormatPCMEx.dwChannelMask = KSAUDIO_SPEAKER_5POINT1;
|
||||
// SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT |
|
||||
// SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY |
|
||||
// SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT
|
||||
waveFormatPCMEx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; // Specify PCM
|
||||
waveFormatPCMEx.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE);
|
||||
waveFormatPCMEx.Samples.wValidBitsPerSample = 16;
|
||||
|
||||
CreateFromMemory( &speakers, speakerData, bufferSize, (waveformatextensible_t *)&waveFormatPCMEx );
|
||||
|
||||
common->Printf("sound: MULTICHANNEL\n");
|
||||
}
|
||||
|
||||
if (!speakers) {
|
||||
return false;
|
||||
}
|
||||
|
||||
speakers->Play(0,DSBPLAY_LOOPING);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idAudioHardwareWIN32::SetPrimaryBufferFormat
|
||||
Set primary buffer to a specified format
|
||||
For example, to set the primary buffer format to 22kHz stereo, 16-bit
|
||||
then: dwPrimaryChannels = 2
|
||||
dwPrimaryFreq = 22050,
|
||||
dwPrimaryBitRate = 16
|
||||
===============
|
||||
*/
|
||||
void idAudioHardwareWIN32::SetPrimaryBufferFormat( dword dwPrimaryFreq, dword dwPrimaryBitRate, dword dwSpeakers ) {
|
||||
HRESULT hr;
|
||||
|
||||
if( m_pDS == NULL ) {
|
||||
return;
|
||||
}
|
||||
|
||||
ulong cfgSpeakers;
|
||||
m_pDS->GetSpeakerConfig( &cfgSpeakers );
|
||||
|
||||
DSCAPS dscaps;
|
||||
dscaps.dwSize = sizeof(DSCAPS);
|
||||
m_pDS->GetCaps(&dscaps);
|
||||
|
||||
if (dscaps.dwFlags & DSCAPS_EMULDRIVER) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the primary buffer
|
||||
DSBUFFERDESC dsbd;
|
||||
ZeroMemory( &dsbd, sizeof(DSBUFFERDESC) );
|
||||
dsbd.dwSize = sizeof(DSBUFFERDESC);
|
||||
dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER;
|
||||
dsbd.dwBufferBytes = 0;
|
||||
dsbd.lpwfxFormat = NULL;
|
||||
|
||||
// Obtain write-primary cooperative level.
|
||||
if( FAILED( hr = m_pDS->SetCooperativeLevel(win32.hWnd, DSSCL_PRIORITY ) ) ) {
|
||||
DXTRACE_ERR( TEXT("SetPrimaryBufferFormat"), hr );
|
||||
return;
|
||||
}
|
||||
|
||||
if( FAILED( hr = m_pDS->CreateSoundBuffer( &dsbd, &pDSBPrimary, NULL ) ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( dwSpeakers == 6 && (cfgSpeakers == DSSPEAKER_5POINT1 || cfgSpeakers == DSSPEAKER_SURROUND) ) {
|
||||
WAVEFORMATEXTENSIBLE waveFormatPCMEx;
|
||||
ZeroMemory( &waveFormatPCMEx, sizeof(WAVEFORMATEXTENSIBLE) );
|
||||
|
||||
waveFormatPCMEx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
|
||||
waveFormatPCMEx.Format.nChannels = 6;
|
||||
waveFormatPCMEx.Format.nSamplesPerSec = dwPrimaryFreq;
|
||||
waveFormatPCMEx.Format.wBitsPerSample = (WORD) dwPrimaryBitRate;
|
||||
waveFormatPCMEx.Format.nBlockAlign = waveFormatPCMEx.Format.wBitsPerSample / 8 * waveFormatPCMEx.Format.nChannels;
|
||||
waveFormatPCMEx.Format.nAvgBytesPerSec = waveFormatPCMEx.Format.nSamplesPerSec * waveFormatPCMEx.Format.nBlockAlign;
|
||||
waveFormatPCMEx.dwChannelMask = KSAUDIO_SPEAKER_5POINT1;
|
||||
// SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT |
|
||||
// SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY |
|
||||
// SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT
|
||||
waveFormatPCMEx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; // Specify PCM
|
||||
waveFormatPCMEx.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE);
|
||||
waveFormatPCMEx.Samples.wValidBitsPerSample = 16;
|
||||
|
||||
if( FAILED( hr = pDSBPrimary->SetFormat((WAVEFORMATEX*)&waveFormatPCMEx) ) ) {
|
||||
DXTRACE_ERR( TEXT("SetPrimaryBufferFormat"), hr );
|
||||
return;
|
||||
}
|
||||
numSpeakers = 6; // force it to think 5.1
|
||||
blockAlign = waveFormatPCMEx.Format.nBlockAlign;
|
||||
} else {
|
||||
if (dwSpeakers == 6) {
|
||||
common->Printf("sound: hardware reported unable to use multisound, defaulted to stereo\n");
|
||||
}
|
||||
WAVEFORMATEX wfx;
|
||||
ZeroMemory( &wfx, sizeof(WAVEFORMATEX) );
|
||||
wfx.wFormatTag = WAVE_FORMAT_PCM;
|
||||
wfx.nChannels = 2;
|
||||
wfx.nSamplesPerSec = dwPrimaryFreq;
|
||||
wfx.wBitsPerSample = (WORD) dwPrimaryBitRate;
|
||||
wfx.nBlockAlign = wfx.wBitsPerSample / 8 * wfx.nChannels;
|
||||
wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
|
||||
wfx.cbSize = sizeof(WAVEFORMATEX);
|
||||
|
||||
if( FAILED( hr = pDSBPrimary->SetFormat(&wfx) ) ) {
|
||||
return;
|
||||
}
|
||||
numSpeakers = 2; // force it to think stereo
|
||||
blockAlign = wfx.nBlockAlign;
|
||||
}
|
||||
|
||||
byte *speakerData;
|
||||
bufferSize = MIXBUFFER_SAMPLES * sizeof(word) * numSpeakers * ROOM_SLICES_IN_BUFFER;
|
||||
speakerData = (byte *)Mem_Alloc( bufferSize );
|
||||
memset( speakerData, 0, bufferSize );
|
||||
|
||||
InitializeSpeakers( speakerData, bufferSize, dwPrimaryFreq, dwPrimaryBitRate, numSpeakers );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idAudioHardwareWIN32::Create
|
||||
===============
|
||||
*/
|
||||
int idAudioHardwareWIN32::Create( idAudioBuffer** ppSound,
|
||||
const char* strWaveFileName,
|
||||
dword dwCreationFlags ) {
|
||||
int hr;
|
||||
LPDIRECTSOUNDBUFFER apDSBuffer = NULL;
|
||||
dword dwDSBufferSize = NULL;
|
||||
idWaveFile* pWaveFile = NULL;
|
||||
|
||||
if( m_pDS == NULL )
|
||||
return -1;
|
||||
if( strWaveFileName == NULL || ppSound == NULL )
|
||||
return -1;
|
||||
|
||||
pWaveFile = new idWaveFile();
|
||||
|
||||
pWaveFile->Open( strWaveFileName, NULL );
|
||||
|
||||
if( pWaveFile->GetOutputSize() == 0 ) {
|
||||
// Wave is blank, so don't create it.
|
||||
hr = E_FAIL;
|
||||
goto LFail;
|
||||
}
|
||||
|
||||
// Make the DirectSound buffer the same size as the wav file
|
||||
dwDSBufferSize = pWaveFile->GetOutputSize();
|
||||
|
||||
// Create the direct sound buffer, and only request the flags needed
|
||||
// since each requires some overhead and limits if the buffer can
|
||||
// be hardware accelerated
|
||||
DSBUFFERDESC dsbd;
|
||||
memset( &dsbd, 0, sizeof(DSBUFFERDESC) );
|
||||
dsbd.dwSize = sizeof(DSBUFFERDESC);
|
||||
dsbd.dwFlags = dwCreationFlags;
|
||||
dsbd.dwBufferBytes = dwDSBufferSize;
|
||||
dsbd.guid3DAlgorithm = GUID_NULL;
|
||||
dsbd.lpwfxFormat = (WAVEFORMATEX*)&pWaveFile->mpwfx;
|
||||
|
||||
// DirectSound is only guarenteed to play PCM data. Other
|
||||
// formats may or may not work depending the sound card driver.
|
||||
if( FAILED( hr = m_pDS->CreateSoundBuffer( &dsbd, &apDSBuffer, NULL ) ) )
|
||||
return -1;
|
||||
|
||||
// Create the sound
|
||||
*ppSound = new idAudioBufferWIN32( apDSBuffer, dwDSBufferSize, pWaveFile );
|
||||
|
||||
pWaveFile->Close();
|
||||
|
||||
return 0;
|
||||
|
||||
LFail:
|
||||
// Cleanup
|
||||
SAFE_DELETE( pWaveFile );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idAudioHardwareWIN32::Create
|
||||
===============
|
||||
*/
|
||||
int idAudioHardwareWIN32::Create( idWaveFile* pWaveFile, idAudioBuffer** ppiab ) {
|
||||
int hr;
|
||||
LPDIRECTSOUNDBUFFER apDSBuffer = NULL;
|
||||
dword dwDSBufferSize = NULL;
|
||||
|
||||
if( m_pDS == NULL )
|
||||
return -1;
|
||||
|
||||
if( pWaveFile == NULL )
|
||||
return -1;
|
||||
|
||||
*ppiab = NULL;
|
||||
|
||||
if( pWaveFile->GetOutputSize() == 0 ) {
|
||||
// Wave is blank, so don't create it.
|
||||
hr = E_FAIL;
|
||||
goto LFail;
|
||||
}
|
||||
|
||||
// Make the DirectSound buffer the same size as the wav file
|
||||
dwDSBufferSize = pWaveFile->GetOutputSize();
|
||||
|
||||
// Create the direct sound buffer, and only request the flags needed
|
||||
// since each requires some overhead and limits if the buffer can
|
||||
// be hardware accelerated
|
||||
DSBUFFERDESC dsbd;
|
||||
memset( &dsbd, 0, sizeof(DSBUFFERDESC) );
|
||||
dsbd.dwSize = sizeof(DSBUFFERDESC);
|
||||
dsbd.dwFlags = 0;
|
||||
dsbd.dwBufferBytes = dwDSBufferSize;
|
||||
dsbd.guid3DAlgorithm = GUID_NULL;
|
||||
dsbd.lpwfxFormat = (WAVEFORMATEX*)&pWaveFile->mpwfx;
|
||||
|
||||
// DirectSound is only guarenteed to play PCM data. Other
|
||||
// formats may or may not work depending the sound card driver.
|
||||
if( FAILED( hr = m_pDS->CreateSoundBuffer( &dsbd, &apDSBuffer, NULL ) ) )
|
||||
return -1;
|
||||
|
||||
// Create the sound
|
||||
*ppiab = new idAudioBufferWIN32( apDSBuffer, dwDSBufferSize, pWaveFile );
|
||||
|
||||
return 0;
|
||||
|
||||
LFail:
|
||||
// Cleanup
|
||||
SAFE_DELETE( pWaveFile );
|
||||
return -1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: idAudioHardwareWIN32::CreateFromMemory()
|
||||
// Desc:
|
||||
//-----------------------------------------------------------------------------
|
||||
int idAudioHardwareWIN32::CreateFromMemory( idAudioBufferWIN32** ppSound,
|
||||
byte* pbData,
|
||||
ulong ulDataSize,
|
||||
waveformatextensible_t* pwfx,
|
||||
dword dwCreationFlags ) {
|
||||
int hr;
|
||||
LPDIRECTSOUNDBUFFER apDSBuffer = NULL;
|
||||
dword dwDSBufferSize = NULL;
|
||||
idWaveFile* pWaveFile = NULL;
|
||||
|
||||
if( m_pDS == NULL )
|
||||
return -1;
|
||||
if( pbData == NULL || ppSound == NULL )
|
||||
return -1;
|
||||
|
||||
pWaveFile = new idWaveFile();
|
||||
|
||||
pWaveFile->OpenFromMemory( (short *)pbData, ulDataSize, (waveformatextensible_t *)pwfx);
|
||||
|
||||
|
||||
// Make the DirectSound buffer the same size as the wav file
|
||||
dwDSBufferSize = ulDataSize;
|
||||
|
||||
// Create the direct sound buffer, and only request the flags needed
|
||||
// since each requires some overhead and limits if the buffer can
|
||||
// be hardware accelerated
|
||||
DSBUFFERDESC dsbd;
|
||||
memset( &dsbd, 0, sizeof(DSBUFFERDESC) );
|
||||
dsbd.dwSize = sizeof(DSBUFFERDESC);
|
||||
dsbd.dwFlags = dwCreationFlags | DSBCAPS_GETCURRENTPOSITION2;
|
||||
dsbd.dwBufferBytes = dwDSBufferSize;
|
||||
dsbd.guid3DAlgorithm = GUID_NULL;
|
||||
dsbd.lpwfxFormat = (WAVEFORMATEX *)pwfx;
|
||||
|
||||
if( FAILED( hr = m_pDS->CreateSoundBuffer( &dsbd, &apDSBuffer, NULL ) ) )
|
||||
return -1;
|
||||
|
||||
// Create the sound
|
||||
*ppSound = new idAudioBufferWIN32( apDSBuffer, dwDSBufferSize, pWaveFile );
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idAudioHardwareWIN32::Lock
|
||||
===============
|
||||
*/
|
||||
bool idAudioHardwareWIN32::Lock( void **pDSLockedBuffer, ulong *dwDSLockedBufferSize ) {
|
||||
if (speakers) {
|
||||
return speakers->Lock( pDSLockedBuffer, dwDSLockedBufferSize );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idAudioHardwareWIN32::Unlock
|
||||
===============
|
||||
*/
|
||||
bool idAudioHardwareWIN32::Unlock(void *pDSLockedBuffer, dword dwDSLockedBufferSize ) {
|
||||
if (speakers) {
|
||||
return speakers->Unlock( pDSLockedBuffer, dwDSLockedBufferSize );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idAudioHardwareWIN32::GetCurrentPosition
|
||||
===============
|
||||
*/
|
||||
bool idAudioHardwareWIN32::GetCurrentPosition( ulong *pdwCurrentWriteCursor ) {
|
||||
if (speakers) {
|
||||
return speakers->GetCurrentPosition( pdwCurrentWriteCursor );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static HMODULE hOpenAL = NULL;
|
||||
|
||||
/*
|
||||
@@ -511,14 +63,13 @@ Sys_LoadOpenAL
|
||||
===============
|
||||
*/
|
||||
bool Sys_LoadOpenAL( void ) {
|
||||
#if ID_OPENAL
|
||||
const char *sym;
|
||||
|
||||
if ( hOpenAL ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
hOpenAL = LoadLibrary( idSoundSystemLocal::s_libOpenAL.GetString() );
|
||||
hOpenAL = LoadLibraryA( idSoundSystemLocal::s_libOpenAL.GetString() );
|
||||
if ( !hOpenAL ) {
|
||||
common->Warning( "LoadLibrary %s failed.", idSoundSystemLocal::s_libOpenAL.GetString() );
|
||||
return false;
|
||||
@@ -530,9 +81,6 @@ bool Sys_LoadOpenAL( void ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -546,303 +94,3 @@ void Sys_FreeOpenAL( void ) {
|
||||
hOpenAL = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idAudioBufferWIN32::idAudioBuffer
|
||||
===============
|
||||
*/
|
||||
idAudioBufferWIN32::idAudioBufferWIN32( LPDIRECTSOUNDBUFFER apDSBuffer, dword dwDSBufferSize, idWaveFile* pWaveFile ) {
|
||||
|
||||
m_apDSBuffer = apDSBuffer;
|
||||
|
||||
m_dwDSBufferSize = dwDSBufferSize;
|
||||
m_pWaveFile = pWaveFile;
|
||||
|
||||
if (pWaveFile) {
|
||||
FillBufferWithSound( m_apDSBuffer, false );
|
||||
|
||||
m_apDSBuffer->SetCurrentPosition(0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idAudioBufferWIN32::~idAudioBuffer
|
||||
===============
|
||||
*/
|
||||
idAudioBufferWIN32::~idAudioBufferWIN32() {
|
||||
SAFE_DELETE(m_pWaveFile);
|
||||
SAFE_RELEASE( m_apDSBuffer );
|
||||
m_pWaveFile = NULL;
|
||||
m_apDSBuffer = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idAudioBufferWIN32::FillBufferWithSound
|
||||
===============
|
||||
*/
|
||||
int idAudioBufferWIN32::FillBufferWithSound( LPDIRECTSOUNDBUFFER pDSB, bool bRepeatWavIfBufferLarger ) {
|
||||
int hr;
|
||||
void* pDSLockedBuffer = NULL; // Pointer to locked buffer memory
|
||||
ulong dwDSLockedBufferSize = 0; // Size of the locked DirectSound buffer
|
||||
int dwWavDataRead = 0; // Amount of data read from the wav file
|
||||
|
||||
if( pDSB == NULL )
|
||||
return -1;
|
||||
|
||||
// we may not even have a wavefile
|
||||
if (m_pWaveFile==NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Make sure we have focus, and we didn't just switch in from
|
||||
// an app which had a DirectSound device
|
||||
if( FAILED( hr = RestoreBuffer( pDSB, NULL ) ) ) {
|
||||
DXTRACE_ERR( TEXT("RestoreBuffer"), hr );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Lock the buffer down
|
||||
if( FAILED( hr = pDSB->Lock( 0, m_dwDSBufferSize, &pDSLockedBuffer, &dwDSLockedBufferSize, NULL, NULL, 0L ) ) ) {
|
||||
DXTRACE_ERR( TEXT("Lock"), hr );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Reset the wave file to the beginning
|
||||
m_pWaveFile->ResetFile();
|
||||
|
||||
if( FAILED( hr = m_pWaveFile->Read( (byte*) pDSLockedBuffer, dwDSLockedBufferSize, &dwWavDataRead ) ) ) {
|
||||
return DXTRACE_ERR( TEXT("Read"), hr );
|
||||
}
|
||||
|
||||
if( dwWavDataRead == 0 ) {
|
||||
// Wav is blank, so just fill with silence
|
||||
memset( pDSLockedBuffer, (byte)(m_pWaveFile->mpwfx.Format.wBitsPerSample == 8 ? 128 : 0 ), dwDSLockedBufferSize );
|
||||
} else if( dwWavDataRead < (int)dwDSLockedBufferSize ) {
|
||||
// If the wav file was smaller than the DirectSound buffer,
|
||||
// we need to fill the remainder of the buffer with data
|
||||
if( bRepeatWavIfBufferLarger ) {
|
||||
// Reset the file and fill the buffer with wav data
|
||||
int dwReadSoFar = dwWavDataRead; // From previous call above.
|
||||
while( dwReadSoFar < (int)dwDSLockedBufferSize ) {
|
||||
// This will keep reading in until the buffer is full
|
||||
// for very short files
|
||||
if( FAILED( hr = m_pWaveFile->ResetFile() ) ) {
|
||||
return DXTRACE_ERR( TEXT("ResetFile"), hr );
|
||||
}
|
||||
|
||||
hr = m_pWaveFile->Read( (byte*)pDSLockedBuffer + dwReadSoFar, dwDSLockedBufferSize - dwReadSoFar, &dwWavDataRead );
|
||||
if( FAILED(hr) ) {
|
||||
return DXTRACE_ERR( TEXT("Read"), hr );
|
||||
}
|
||||
|
||||
dwReadSoFar += dwWavDataRead;
|
||||
}
|
||||
} else {
|
||||
// Don't repeat the wav file, just fill in silence
|
||||
memset( (byte*) pDSLockedBuffer + dwWavDataRead, (byte)(m_pWaveFile->mpwfx.Format.wBitsPerSample == 8 ? 128 : 0 ), dwDSLockedBufferSize - dwWavDataRead);
|
||||
}
|
||||
}
|
||||
|
||||
// Unlock the buffer, we don't need it anymore.
|
||||
pDSB->Unlock( pDSLockedBuffer, dwDSLockedBufferSize, NULL, 0 );
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idAudioBufferWIN32::RestoreBuffer
|
||||
Desc: Restores the lost buffer. *pbWasRestored returns true if the buffer was
|
||||
restored. It can also NULL if the information is not needed.
|
||||
===============
|
||||
*/
|
||||
int idAudioBufferWIN32::RestoreBuffer( LPDIRECTSOUNDBUFFER pDSB, bool* pbWasRestored ) {
|
||||
int hr;
|
||||
|
||||
if( pDSB == NULL ) {
|
||||
return -1;
|
||||
}
|
||||
if( pbWasRestored ) {
|
||||
*pbWasRestored = false;
|
||||
}
|
||||
|
||||
ulong dwStatus;
|
||||
if( FAILED( hr = pDSB->GetStatus( &dwStatus ) ) ) {
|
||||
return DXTRACE_ERR( TEXT("GetStatus"), hr );
|
||||
}
|
||||
|
||||
if( dwStatus & DSBSTATUS_BUFFERLOST ) {
|
||||
// Since the app could have just been activated, then
|
||||
// DirectSound may not be giving us control yet, so
|
||||
// the restoring the buffer may fail.
|
||||
// If it does, sleep until DirectSound gives us control.
|
||||
do {
|
||||
hr = pDSB->Restore();
|
||||
if( hr == DSERR_BUFFERLOST ) {
|
||||
Sleep( 10 );
|
||||
}
|
||||
hr = pDSB->Restore();
|
||||
} while( hr );
|
||||
|
||||
if( pbWasRestored != NULL ) {
|
||||
*pbWasRestored = true;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
} else {
|
||||
return S_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idAudioBufferWIN32::Play
|
||||
Desc: Plays the sound using voice management flags. Pass in DSBPLAY_LOOPING
|
||||
in the dwFlags to loop the sound
|
||||
===============
|
||||
*/
|
||||
int idAudioBufferWIN32::Play( dword dwPriority, dword dwFlags ) {
|
||||
int hr;
|
||||
bool bRestored;
|
||||
|
||||
if( m_apDSBuffer == NULL ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Restore the buffer if it was lost
|
||||
if( FAILED( hr = RestoreBuffer( m_apDSBuffer, &bRestored ) ) ) {
|
||||
common->Error( TEXT("RestoreBuffer"), hr );
|
||||
}
|
||||
|
||||
if( bRestored ) {
|
||||
// The buffer was restored, so we need to fill it with new data
|
||||
if( FAILED( hr = FillBufferWithSound( m_apDSBuffer, false ) ) ) {
|
||||
common->Error( TEXT("FillBufferWithSound"), hr );
|
||||
}
|
||||
|
||||
// Make DirectSound do pre-processing on sound effects
|
||||
Reset();
|
||||
}
|
||||
|
||||
m_apDSBuffer->Play( 0, dwPriority, dwFlags );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idAudioBufferWIN32::Stop
|
||||
Desc: Stops the sound from playing
|
||||
===============
|
||||
*/
|
||||
int idAudioBufferWIN32::Stop() {
|
||||
if( this == NULL || m_apDSBuffer == NULL ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
m_apDSBuffer->Stop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idAudioBufferWIN32::Reset
|
||||
Desc: Reset all of the sound buffers
|
||||
===============
|
||||
*/
|
||||
int idAudioBufferWIN32::Reset() {
|
||||
if( m_apDSBuffer == NULL ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
m_apDSBuffer->SetCurrentPosition( 0 );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idAudioBufferWIN32::IsSoundPlaying
|
||||
Desc: Checks to see if a buffer is playing and returns true if it
|
||||
===============
|
||||
*/
|
||||
bool idAudioBufferWIN32::IsSoundPlaying( ) {
|
||||
if( m_apDSBuffer == NULL ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if( m_apDSBuffer ) {
|
||||
ulong dwStatus = 0;
|
||||
m_apDSBuffer->GetStatus( &dwStatus );
|
||||
if ( dwStatus & DSBSTATUS_PLAYING ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idAudioBufferWIN32::Lock
|
||||
===============
|
||||
*/
|
||||
bool idAudioBufferWIN32::Lock( void **pDSLockedBuffer, ulong *dwDSLockedBufferSize ) {
|
||||
int hr;
|
||||
// Restore the buffer if it was lost
|
||||
bool bRestored;
|
||||
if( FAILED( hr = RestoreBuffer( m_apDSBuffer, &bRestored ) ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Lock the DirectSound buffer
|
||||
if( FAILED( hr = m_apDSBuffer->Lock( 0, m_dwDSBufferSize, pDSLockedBuffer, dwDSLockedBufferSize, NULL, NULL, 0 ) ) ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idAudioBufferWIN32::Unlock
|
||||
===============
|
||||
*/
|
||||
bool idAudioBufferWIN32::Unlock(void *pDSLockedBuffer, dword dwDSLockedBufferSize ) {
|
||||
// Unlock the DirectSound buffer
|
||||
m_apDSBuffer->Unlock( pDSLockedBuffer, dwDSLockedBufferSize, NULL, 0 );
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idAudioBufferWIN32::GetCurrentPosition
|
||||
===============
|
||||
*/
|
||||
bool idAudioBufferWIN32::GetCurrentPosition( ulong *pdwCurrentWriteCursor ) {
|
||||
int hr;
|
||||
|
||||
// Make sure we have focus, and we didn't just switch in from
|
||||
// an app which had a DirectSound device
|
||||
if( FAILED( hr = RestoreBuffer( m_apDSBuffer, NULL ) ) ) {
|
||||
DXTRACE_ERR( TEXT("RestoreBuffer"), hr );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( FAILED( hr = m_apDSBuffer->GetCurrentPosition( NULL, pdwCurrentWriteCursor ) ) ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idAudioBufferWIN32::SetVolume
|
||||
===============
|
||||
*/
|
||||
void idAudioBufferWIN32::SetVolume( float x) {
|
||||
if (m_apDSBuffer) {
|
||||
m_apDSBuffer->SetVolume(x);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user