diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..7168275 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.0) + +project(CMAudio) + +include(path_config.cmake) +CMAudioSetup(${CMAKE_CURRENT_SOURCE_DIR}) + +add_subdirectory(${CMAUDIO_ROOT_SOURCE_PATH}) diff --git a/inc/hgl/al/al.h b/inc/hgl/al/al.h new file mode 100644 index 0000000..335e8eb --- /dev/null +++ b/inc/hgl/al/al.h @@ -0,0 +1,278 @@ +#ifndef HGL_AL_INCLUDE +#define HGL_AL_INCLUDE + +#if defined(_WIN32) + #define AL_APIENTRY __cdecl +#else + #define AL_APIENTRY +#endif + +#define OPENAL +#define ALAPI AL_API +#define ALAPIENTRY AL_APIENTRY +#define AL_VERSION_1_0 +#define AL_VERSION_1_1 +#define AL_INVALID -1 +#define AL_NONE 0 +#define AL_FALSE 0 +#define AL_TRUE 1 +#define AL_SOURCE_RELATIVE 0x202 +#define AL_CONE_INNER_ANGLE 0x1001 +#define AL_CONE_OUTER_ANGLE 0x1002 +#define AL_PITCH 0x1003 +#define AL_POSITION 0x1004 +#define AL_DIRECTION 0x1005 +#define AL_VELOCITY 0x1006 +#define AL_LOOPING 0x1007 +#define AL_BUFFER 0x1009 +#define AL_GAIN 0x100A +#define AL_MIN_GAIN 0x100D +#define AL_MAX_GAIN 0x100E +#define AL_ORIENTATION 0x100F +#define AL_CHANNEL_MASK 0x3000 +#define AL_SOURCE_STATE 0x1010 +#define AL_INITIAL 0x1011 +#define AL_PLAYING 0x1012 +#define AL_PAUSED 0x1013 +#define AL_STOPPED 0x1014 +#define AL_BUFFERS_QUEUED 0x1015 +#define AL_BUFFERS_PROCESSED 0x1016 +#define AL_SEC_OFFSET 0x1024 +#define AL_SAMPLE_OFFSET 0x1025 +#define AL_BYTE_OFFSET 0x1026 +#define AL_SOURCE_TYPE 0x1027 +#define AL_STATIC 0x1028 +#define AL_STREAMING 0x1029 +#define AL_UNDETERMINED 0x1030 +#define AL_FORMAT_MONO8 0x1100 +#define AL_FORMAT_MONO16 0x1101 +#define AL_FORMAT_STEREO8 0x1102 +#define AL_FORMAT_STEREO16 0x1103 +#define AL_REFERENCE_DISTANCE 0x1020 +#define AL_ROLLOFF_FACTOR 0x1021 +#define AL_CONE_OUTER_GAIN 0x1022 +#define AL_MAX_DISTANCE 0x1023 +#define AL_FREQUENCY 0x2001 +#define AL_BITS 0x2002 +#define AL_CHANNELS 0x2003 +#define AL_SIZE 0x2004 +#define AL_UNUSED 0x2010 +#define AL_PENDING 0x2011 +#define AL_PROCESSED 0x2012 +#define AL_NO_ERROR AL_FALSE +#define AL_INVALID_NAME 0xA001 +#define AL_ILLEGAL_ENUM 0xA002 +#define AL_INVALID_ENUM 0xA002 +#define AL_INVALID_VALUE 0xA003 +#define AL_ILLEGAL_COMMAND 0xA004 +#define AL_INVALID_OPERATION 0xA004 +#define AL_OUT_OF_MEMORY 0xA005 +#define AL_VENDOR 0xB001 +#define AL_VERSION 0xB002 +#define AL_RENDERER 0xB003 +#define AL_EXTENSIONS 0xB004 +#define AL_DOPPLER_FACTOR 0xC000 +#define AL_DOPPLER_VELOCITY 0xC001 +#define AL_SPEED_OF_SOUND 0xC003 +#define AL_DISTANCE_MODEL 0xD000 +#define AL_INVERSE_DISTANCE 0xD001 +#define AL_INVERSE_DISTANCE_CLAMPED 0xD002 +#define AL_LINEAR_DISTANCE 0xD003 +#define AL_LINEAR_DISTANCE_CLAMPED 0xD004 +#define AL_EXPONENT_DISTANCE 0xD005 +#define AL_EXPONENT_DISTANCE_CLAMPED 0xD006 + +#define AL_FORMAT_MONO_FLOAT32 0x10010 +#define AL_FORMAT_STEREO_FLOAT32 0x10011 +#define AL_FORMAT_MONO_DOUBLE_EXT 0x10012 +#define AL_FORMAT_STEREO_DOUBLE_EXT 0x10013 + +#define AL_FORMAT_QUAD8 0x1204 +#define AL_FORMAT_QUAD16 0x1205 +#define AL_FORMAT_QUAD32 0x1206 +#define AL_FORMAT_REAR8 0x1207 +#define AL_FORMAT_REAR16 0x1208 +#define AL_FORMAT_REAR32 0x1209 +#define AL_FORMAT_51CHN8 0x120A +#define AL_FORMAT_51CHN16 0x120B +#define AL_FORMAT_51CHN32 0x120C +#define AL_FORMAT_61CHN8 0x120D +#define AL_FORMAT_61CHN16 0x120E +#define AL_FORMAT_61CHN32 0x120F +#define AL_FORMAT_71CHN8 0x1210 +#define AL_FORMAT_71CHN16 0x1211 +#define AL_FORMAT_71CHN32 0x1212 + +#define AL_SOURCE_DISTANCE_MODEL 0x200 + +namespace openal +{ + typedef char ALboolean; + typedef char ALchar; + typedef char ALbyte; + typedef unsigned char ALubyte; + typedef short ALshort; + typedef unsigned short ALushort; + typedef int ALint; + typedef unsigned int ALuint; + typedef int ALsizei; + typedef int ALenum; + typedef float ALfloat; + typedef double ALdouble; + typedef void ALvoid; +} + +namespace openal +{ + typedef void (*alEnablePROC)( ALenum capability ); + typedef void (*alDisablePROC)( ALenum capability ); + typedef ALboolean (*alIsEnabledPROC)( ALenum capability ); + typedef const ALchar* (*alGetStringPROC)( ALenum param ); + typedef void (*alGetBooleanvPROC)( ALenum param, ALboolean* data ); + typedef void (*alGetIntegervPROC)( ALenum param, ALint* data ); + typedef void (*alGetFloatvPROC)( ALenum param, ALfloat* data ); + typedef void (*alGetDoublevPROC)( ALenum param, ALdouble* data ); + typedef ALboolean (*alGetBooleanPROC)( ALenum param ); + typedef ALint (*alGetIntegerPROC)( ALenum param ); + typedef ALfloat (*alGetFloatPROC)( ALenum param ); + typedef ALdouble (*alGetDoublePROC)( ALenum param ); + typedef ALenum (*alGetErrorPROC)( void ); + typedef ALboolean (*alIsExtensionPresentPROC)( const ALchar* extname ); + typedef void* (*alGetProcAddressPROC)( const ALchar* fname ); + typedef ALenum (*alGetEnumValuePROC)( const ALchar* ename ); + typedef void (*alListenerfPROC)( ALenum param, ALfloat value ); + typedef void (*alListener3fPROC)( ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ); + typedef void (*alListenerfvPROC)( ALenum param, const ALfloat* values ); + typedef void (*alListeneriPROC)( ALenum param, ALint value ); + typedef void (*alListener3iPROC)( ALenum param, ALint value1, ALint value2, ALint value3 ); + typedef void (*alListenerivPROC)( ALenum param, const ALint* values ); + typedef void (*alGetListenerfPROC)( ALenum param, ALfloat* value ); + typedef void (*alGetListener3fPROC)( ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3 ); + typedef void (*alGetListenerfvPROC)( ALenum param, ALfloat* values ); + typedef void (*alGetListeneriPROC)( ALenum param, ALint* value ); + typedef void (*alGetListener3iPROC)( ALenum param, ALint *value1, ALint *value2, ALint *value3 ); + typedef void (*alGetListenerivPROC)( ALenum param, ALint* values ); + typedef void (*alGenSourcesPROC)( ALsizei n, ALuint* sources ); + typedef void (*alDeleteSourcesPROC)( ALsizei n, const ALuint* sources ); + typedef ALboolean (*alIsSourcePROC)( ALuint sid ); + typedef void (*alSourcefPROC)( ALuint sid, ALenum param, ALfloat value ); + typedef void (*alSource3fPROC)( ALuint sid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ); + typedef void (*alSourcefvPROC)( ALuint sid, ALenum param, const ALfloat* values ); + typedef void (*alSourceiPROC)( ALuint sid, ALenum param, ALint value ); + typedef void (*alSource3iPROC)( ALuint sid, ALenum param, ALint value1, ALint value2, ALint value3 ); + typedef void (*alSourceivPROC)( ALuint sid, ALenum param, const ALint* values ); + typedef void (*alGetSourcefPROC)( ALuint sid, ALenum param, ALfloat* value ); + typedef void (*alGetSource3fPROC)( ALuint sid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3); + typedef void (*alGetSourcefvPROC)( ALuint sid, ALenum param, ALfloat* values ); + typedef void (*alGetSourceiPROC)( ALuint sid, ALenum param, ALint* value ); + typedef void (*alGetSource3iPROC)( ALuint sid, ALenum param, ALint* value1, ALint* value2, ALint* value3); + typedef void (*alGetSourceivPROC)( ALuint sid, ALenum param, ALint* values ); + typedef void (*alSourcePlayvPROC)( ALsizei ns, const ALuint *sids ); + typedef void (*alSourceStopvPROC)( ALsizei ns, const ALuint *sids ); + typedef void (*alSourceRewindvPROC)( ALsizei ns, const ALuint *sids ); + typedef void (*alSourcePausevPROC)( ALsizei ns, const ALuint *sids ); + typedef void (*alSourcePlayPROC)( ALuint sid ); + typedef void (*alSourceStopPROC)( ALuint sid ); + typedef void (*alSourceRewindPROC)( ALuint sid ); + typedef void (*alSourcePausePROC)( ALuint sid ); + typedef void (*alSourceQueueBuffersPROC)( ALuint sid, ALsizei numEntries, const ALuint *bids ); + typedef void (*alSourceUnqueueBuffersPROC)( ALuint sid, ALsizei numEntries, ALuint *bids ); + typedef void (*alGenBuffersPROC)( ALsizei n, ALuint* buffers ); + typedef void (*alDeleteBuffersPROC)( ALsizei n, const ALuint* buffers ); + typedef ALboolean (*alIsBufferPROC)( ALuint bid ); + typedef void (*alBufferDataPROC)( ALuint bid, ALenum format, const ALvoid* data, ALsizei size, ALsizei freq ); + typedef void (*alBufferfPROC)( ALuint bid, ALenum param, ALfloat value ); + typedef void (*alBuffer3fPROC)( ALuint bid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ); + typedef void (*alBufferfvPROC)( ALuint bid, ALenum param, const ALfloat* values ); + typedef void (*alBufferiPROC)( ALuint bid, ALenum param, ALint value ); + typedef void (*alBuffer3iPROC)( ALuint bid, ALenum param, ALint value1, ALint value2, ALint value3 ); + typedef void (*alBufferivPROC)( ALuint bid, ALenum param, const ALint* values ); + typedef void (*alGetBufferfPROC)( ALuint bid, ALenum param, ALfloat* value ); + typedef void (*alGetBuffer3fPROC)( ALuint bid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3); + typedef void (*alGetBufferfvPROC)( ALuint bid, ALenum param, ALfloat* values ); + typedef void (*alGetBufferiPROC)( ALuint bid, ALenum param, ALint* value ); + typedef void (*alGetBuffer3iPROC)( ALuint bid, ALenum param, ALint* value1, ALint* value2, ALint* value3); + typedef void (*alGetBufferivPROC)( ALuint bid, ALenum param, ALint* values ); + typedef void (*alDopplerFactorPROC)( ALfloat value ); + typedef void (*alDopplerVelocityPROC)( ALfloat value ); + typedef void (*alSpeedOfSoundPROC)( ALfloat value ); + typedef void (*alDistanceModelPROC)( ALenum distanceModel ); +} + +namespace openal +{ + extern alEnablePROC alEnable; + extern alDisablePROC alDisable; + extern alIsEnabledPROC alIsEnabled; + extern alGetStringPROC alGetString; + extern alGetBooleanvPROC alGetBooleanv; + extern alGetIntegervPROC alGetIntegerv; + extern alGetFloatvPROC alGetFloatv; + extern alGetDoublevPROC alGetDoublev; + extern alGetBooleanPROC alGetBoolean; + extern alGetIntegerPROC alGetInteger; + extern alGetFloatPROC alGetFloat; + extern alGetDoublePROC alGetDouble; + extern alGetErrorPROC alGetError; + extern alIsExtensionPresentPROC alIsExtensionPresent; + extern alGetProcAddressPROC alGetProcAddress; + extern alGetEnumValuePROC alGetEnumValue; + extern alListenerfPROC alListenerf; + extern alListener3fPROC alListener3f; + extern alListenerfvPROC alListenerfv; + extern alListeneriPROC alListeneri; + extern alListener3iPROC alListener3i; + extern alListenerivPROC alListeneriv; + extern alGetListenerfPROC alGetListenerf; + extern alGetListener3fPROC alGetListener3f; + extern alGetListenerfvPROC alGetListenerfv; + extern alGetListeneriPROC alGetListeneri; + extern alGetListener3iPROC alGetListener3i; + extern alGetListenerivPROC alGetListeneriv; + extern alGenSourcesPROC alGenSources; + extern alDeleteSourcesPROC alDeleteSources; + extern alIsSourcePROC alIsSource; + extern alSourcefPROC alSourcef; + extern alSource3fPROC alSource3f; + extern alSourcefvPROC alSourcefv; + extern alSourceiPROC alSourcei; + extern alSource3iPROC alSource3i; + extern alSourceivPROC alSourceiv; + extern alGetSourcefPROC alGetSourcef; + extern alGetSource3fPROC alGetSource3f; + extern alGetSourcefvPROC alGetSourcefv; + extern alGetSourceiPROC alGetSourcei; + extern alGetSource3iPROC alGetSource3i; + extern alGetSourceivPROC alGetSourceiv; + extern alSourcePlayvPROC alSourcePlayv; + extern alSourceStopvPROC alSourceStopv; + extern alSourceRewindvPROC alSourceRewindv; + extern alSourcePausevPROC alSourcePausev; + extern alSourcePlayPROC alSourcePlay; + extern alSourceStopPROC alSourceStop; + extern alSourceRewindPROC alSourceRewind; + extern alSourcePausePROC alSourcePause; + extern alSourceQueueBuffersPROC alSourceQueueBuffers; + extern alSourceUnqueueBuffersPROC alSourceUnqueueBuffers; + extern alGenBuffersPROC alGenBuffers; + extern alDeleteBuffersPROC alDeleteBuffers; + extern alIsBufferPROC alIsBuffer; + extern alBufferDataPROC alBufferData; + extern alBufferfPROC alBufferf; + extern alBuffer3fPROC alBuffer3f; + extern alBufferfvPROC alBufferfv; + extern alBufferiPROC alBufferi; + extern alBuffer3iPROC alBuffer3i; + extern alBufferivPROC alBufferiv; + extern alGetBufferfPROC alGetBufferf; + extern alGetBuffer3fPROC alGetBuffer3f; + extern alGetBufferfvPROC alGetBufferfv; + extern alGetBufferiPROC alGetBufferi; + extern alGetBuffer3iPROC alGetBuffer3i; + extern alGetBufferivPROC alGetBufferiv; + extern alDopplerFactorPROC alDopplerFactor; + extern alDopplerVelocityPROC alDopplerVelocity; + extern alSpeedOfSoundPROC alSpeedOfSound; + extern alDistanceModelPROC alDistanceModel; +} +#endif//HGL_AL_INCLUDE diff --git a/inc/hgl/al/alc.h b/inc/hgl/al/alc.h new file mode 100644 index 0000000..a2a5c97 --- /dev/null +++ b/inc/hgl/al/alc.h @@ -0,0 +1,100 @@ +#ifndef HGL_ALC_INCLUDE +#define HGL_ALC_INCLUDE + +#define ALCAPI ALC_API +#define ALCAPIENTRY ALC_APIENTRY +#define ALC_INVALID 0 +#define ALC_VERSION_0_1 1 +#define ALC_FALSE 0 +#define ALC_TRUE 1 +#define ALC_FREQUENCY 0x1007 +#define ALC_REFRESH 0x1008 +#define ALC_SYNC 0x1009 +#define ALC_MONO_SOURCES 0x1010 +#define ALC_STEREO_SOURCES 0x1011 +#define ALC_NO_ERROR ALC_FALSE +#define ALC_INVALID_DEVICE 0xA001 +#define ALC_INVALID_CONTEXT 0xA002 +#define ALC_INVALID_ENUM 0xA003 +#define ALC_INVALID_VALUE 0xA004 +#define ALC_OUT_OF_MEMORY 0xA005 +#define ALC_DEFAULT_DEVICE_SPECIFIER 0x1004 +#define ALC_DEVICE_SPECIFIER 0x1005 +#define ALC_EXTENSIONS 0x1006 +#define ALC_MAJOR_VERSION 0x1000 +#define ALC_MINOR_VERSION 0x1001 +#define ALC_ATTRIBUTES_SIZE 0x1002 +#define ALC_ALL_ATTRIBUTES 0x1003 +#define ALC_DEFAULT_ALL_DEVICES_SPECIFIER 0x1012 +#define ALC_ALL_DEVICES_SPECIFIER 0x1013 +#define ALC_CAPTURE_DEVICE_SPECIFIER 0x310 +#define ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER 0x311 +#define ALC_CAPTURE_SAMPLES 0x312 + +namespace openal +{ + typedef struct ALCdevice_struct ALCdevice; + typedef struct ALCcontext_struct ALCcontext; + typedef char ALCboolean; + typedef char ALCchar; + typedef char ALCbyte; + typedef unsigned char ALCubyte; + typedef short ALCshort; + typedef unsigned short ALCushort; + typedef int ALCint; + typedef unsigned int ALCuint; + typedef int ALCsizei; + typedef int ALCenum; + typedef float ALCfloat; + typedef double ALCdouble; + typedef void ALCvoid; +} + +namespace openal +{ + typedef ALCcontext * (*alcCreateContextPROC)( ALCdevice *device, const ALCint* attrlist ); + typedef ALCboolean (*alcMakeContextCurrentPROC)( ALCcontext *context ); + typedef void (*alcProcessContextPROC)( ALCcontext *context ); + typedef void (*alcSuspendContextPROC)( ALCcontext *context ); + typedef void (*alcDestroyContextPROC)( ALCcontext *context ); + typedef ALCcontext * (*alcGetCurrentContextPROC)( void ); + typedef ALCdevice* (*alcGetContextsDevicePROC)( ALCcontext *context ); + typedef ALCdevice * (*alcOpenDevicePROC)( const ALCchar *devicename ); + typedef ALCboolean (*alcCloseDevicePROC)( ALCdevice *device ); + typedef ALCenum (*alcGetErrorPROC)( ALCdevice *device ); + typedef ALCboolean (*alcIsExtensionPresentPROC)( ALCdevice *device, const ALCchar *extname ); + typedef void * (*alcGetProcAddressPROC)( ALCdevice *device, const ALCchar *funcname ); + typedef ALCenum (*alcGetEnumValuePROC)( ALCdevice *device, const ALCchar *enumname ); + typedef const ALCchar * (*alcGetStringPROC)( ALCdevice *device, ALCenum param ); + typedef void (*alcGetIntegervPROC)( ALCdevice *device, ALCenum param, ALCsizei size, ALCint *data ); + typedef ALCdevice* (*alcCaptureOpenDevicePROC)( const ALCchar *devicename, ALCuint frequency, ALCenum format, ALCsizei buffersize ); + typedef ALCboolean (*alcCaptureCloseDevicePROC)( ALCdevice *device ); + typedef void (*alcCaptureStartPROC)( ALCdevice *device ); + typedef void (*alcCaptureStopPROC)( ALCdevice *device ); + typedef void (*alcCaptureSamplesPROC)( ALCdevice *device, ALCvoid *buffer, ALCsizei samples ); +} + +namespace openal +{ + extern alcCreateContextPROC alcCreateContext; + extern alcMakeContextCurrentPROC alcMakeContextCurrent; + extern alcProcessContextPROC alcProcessContext; + extern alcSuspendContextPROC alcSuspendContext; + extern alcDestroyContextPROC alcDestroyContext; + extern alcGetCurrentContextPROC alcGetCurrentContext; + extern alcGetContextsDevicePROC alcGetContextsDevice; + extern alcOpenDevicePROC alcOpenDevice; + extern alcCloseDevicePROC alcCloseDevice; + extern alcGetErrorPROC alcGetError; + extern alcIsExtensionPresentPROC alcIsExtensionPresent; + extern alcGetProcAddressPROC alcGetProcAddress; + extern alcGetEnumValuePROC alcGetEnumValue; + extern alcGetStringPROC alcGetString; + extern alcGetIntegervPROC alcGetIntegerv; + extern alcCaptureOpenDevicePROC alcCaptureOpenDevice; + extern alcCaptureCloseDevicePROC alcCaptureCloseDevice; + extern alcCaptureStartPROC alcCaptureStart; + extern alcCaptureStopPROC alcCaptureStop; + extern alcCaptureSamplesPROC alcCaptureSamples; +} +#endif//HGL_ALC_INCLUDE diff --git a/inc/hgl/al/efx-creative.h b/inc/hgl/al/efx-creative.h new file mode 100644 index 0000000..91e0ff4 --- /dev/null +++ b/inc/hgl/al/efx-creative.h @@ -0,0 +1,151 @@ +#ifndef __efxcreative_h_ +#define __efxcreative_h_ + +/** + * efx-creative.h - Environmental Audio Extensions + * for OpenAL Effects Extension. + * + */ +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * Effect object definitions to be used with alEffect functions. + * + * Effect parameter value definitions, ranges, and defaults + * appear farther down in this file. + */ + +/* AL EAXReverb effect parameters. */ +#define AL_EAXREVERB_DENSITY 0x0001 +#define AL_EAXREVERB_DIFFUSION 0x0002 +#define AL_EAXREVERB_GAIN 0x0003 +#define AL_EAXREVERB_GAINHF 0x0004 +#define AL_EAXREVERB_GAINLF 0x0005 +#define AL_EAXREVERB_DECAY_TIME 0x0006 +#define AL_EAXREVERB_DECAY_HFRATIO 0x0007 +#define AL_EAXREVERB_DECAY_LFRATIO 0x0008 +#define AL_EAXREVERB_REFLECTIONS_GAIN 0x0009 +#define AL_EAXREVERB_REFLECTIONS_DELAY 0x000A +#define AL_EAXREVERB_REFLECTIONS_PAN 0x000B +#define AL_EAXREVERB_LATE_REVERB_GAIN 0x000C +#define AL_EAXREVERB_LATE_REVERB_DELAY 0x000D +#define AL_EAXREVERB_LATE_REVERB_PAN 0x000E +#define AL_EAXREVERB_ECHO_TIME 0x000F +#define AL_EAXREVERB_ECHO_DEPTH 0x0010 +#define AL_EAXREVERB_MODULATION_TIME 0x0011 +#define AL_EAXREVERB_MODULATION_DEPTH 0x0012 +#define AL_EAXREVERB_AIR_ABSORPTION_GAINHF 0x0013 +#define AL_EAXREVERB_HFREFERENCE 0x0014 +#define AL_EAXREVERB_LFREFERENCE 0x0015 +#define AL_EAXREVERB_ROOM_ROLLOFF_FACTOR 0x0016 +#define AL_EAXREVERB_DECAY_HFLIMIT 0x0017 + +/* Effect type definitions to be used with AL_EFFECT_TYPE. */ +#define AL_EFFECT_EAXREVERB 0x8000 + + + + /********************************************************** + * Effect parameter structures, value definitions, ranges and defaults. + */ + +/** + * AL reverb effect parameter ranges and defaults + */ +#define AL_EAXREVERB_MIN_DENSITY 0.0f +#define AL_EAXREVERB_MAX_DENSITY 1.0f +#define AL_EAXREVERB_DEFAULT_DENSITY 1.0f + +#define AL_EAXREVERB_MIN_DIFFUSION 0.0f +#define AL_EAXREVERB_MAX_DIFFUSION 1.0f +#define AL_EAXREVERB_DEFAULT_DIFFUSION 1.0f + +#define AL_EAXREVERB_MIN_GAIN 0.0f +#define AL_EAXREVERB_MAX_GAIN 1.0f +#define AL_EAXREVERB_DEFAULT_GAIN 0.32f + +#define AL_EAXREVERB_MIN_GAINHF 0.0f +#define AL_EAXREVERB_MAX_GAINHF 1.0f +#define AL_EAXREVERB_DEFAULT_GAINHF 0.89f + +#define AL_EAXREVERB_MIN_GAINLF 0.0f +#define AL_EAXREVERB_MAX_GAINLF 1.0f +#define AL_EAXREVERB_DEFAULT_GAINLF 1.0f + +#define AL_EAXREVERB_MIN_DECAY_TIME 0.1f +#define AL_EAXREVERB_MAX_DECAY_TIME 20.0f +#define AL_EAXREVERB_DEFAULT_DECAY_TIME 1.49f + +#define AL_EAXREVERB_MIN_DECAY_HFRATIO 0.1f +#define AL_EAXREVERB_MAX_DECAY_HFRATIO 2.0f +#define AL_EAXREVERB_DEFAULT_DECAY_HFRATIO 0.83f + +#define AL_EAXREVERB_MIN_DECAY_LFRATIO 0.1f +#define AL_EAXREVERB_MAX_DECAY_LFRATIO 2.0f +#define AL_EAXREVERB_DEFAULT_DECAY_LFRATIO 1.0f + +#define AL_EAXREVERB_MIN_REFLECTIONS_GAIN 0.0f +#define AL_EAXREVERB_MAX_REFLECTIONS_GAIN 3.16f +#define AL_EAXREVERB_DEFAULT_REFLECTIONS_GAIN 0.05f + +#define AL_EAXREVERB_MIN_REFLECTIONS_DELAY 0.0f +#define AL_EAXREVERB_MAX_REFLECTIONS_DELAY 0.3f +#define AL_EAXREVERB_DEFAULT_REFLECTIONS_DELAY 0.007f + +#define AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN {0.0f, 0.0f, 0.0f} + +#define AL_EAXREVERB_MIN_LATE_REVERB_GAIN 0.0f +#define AL_EAXREVERB_MAX_LATE_REVERB_GAIN 10.0f +#define AL_EAXREVERB_DEFAULT_LATE_REVERB_GAIN 1.26f + +#define AL_EAXREVERB_MIN_LATE_REVERB_DELAY 0.0f +#define AL_EAXREVERB_MAX_LATE_REVERB_DELAY 0.1f +#define AL_EAXREVERB_DEFAULT_LATE_REVERB_DELAY 0.011f + +#define AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN {0.0f, 0.0f, 0.0f} + +#define AL_EAXREVERB_MIN_ECHO_TIME 0.075f +#define AL_EAXREVERB_MAX_ECHO_TIME 0.25f +#define AL_EAXREVERB_DEFAULT_ECHO_TIME 0.25f + +#define AL_EAXREVERB_MIN_ECHO_DEPTH 0.0f +#define AL_EAXREVERB_MAX_ECHO_DEPTH 1.0f +#define AL_EAXREVERB_DEFAULT_ECHO_DEPTH 0.0f + +#define AL_EAXREVERB_MIN_MODULATION_TIME 0.04f +#define AL_EAXREVERB_MAX_MODULATION_TIME 4.0f +#define AL_EAXREVERB_DEFAULT_MODULATION_TIME 0.25f + +#define AL_EAXREVERB_MIN_MODULATION_DEPTH 0.0f +#define AL_EAXREVERB_MAX_MODULATION_DEPTH 1.0f +#define AL_EAXREVERB_DEFAULT_MODULATION_DEPTH 0.0f + +#define AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF 0.892f +#define AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF 1.0f +#define AL_EAXREVERB_DEFAULT_AIR_ABSORPTION_GAINHF 0.994f + +#define AL_EAXREVERB_MIN_HFREFERENCE 1000.0f +#define AL_EAXREVERB_MAX_HFREFERENCE 20000.0f +#define AL_EAXREVERB_DEFAULT_HFREFERENCE 5000.0f + +#define AL_EAXREVERB_MIN_LFREFERENCE 20.0f +#define AL_EAXREVERB_MAX_LFREFERENCE 1000.0f +#define AL_EAXREVERB_DEFAULT_LFREFERENCE 250.0f + +#define AL_EAXREVERB_MIN_ROOM_ROLLOFF_FACTOR 0.0f +#define AL_EAXREVERB_MAX_ROOM_ROLLOFF_FACTOR 10.0f +#define AL_EAXREVERB_DEFAULT_ROOM_ROLLOFF_FACTOR 0.0f + +#define AL_EAXREVERB_MIN_DECAY_HFLIMIT AL_FALSE +#define AL_EAXREVERB_MAX_DECAY_HFLIMIT AL_TRUE +#define AL_EAXREVERB_DEFAULT_DECAY_HFLIMIT AL_TRUE + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* __efxcreative_h_ */ diff --git a/inc/hgl/al/efx.h b/inc/hgl/al/efx.h new file mode 100644 index 0000000..8c4ec29 --- /dev/null +++ b/inc/hgl/al/efx.h @@ -0,0 +1,771 @@ +#ifndef HGL_EFX_INCLUDE +#define HGL_EFX_INCLUDE + +#include + +#define ALC_EXT_EFX_NAME "ALC_EXT_EFX" + +/** + * Context definitions to be used with alcCreateContext. + * These values must be unique and not conflict with other + * al context values. + */ +#define ALC_EFX_MAJOR_VERSION 0x20001 +#define ALC_EFX_MINOR_VERSION 0x20002 +#define ALC_MAX_AUXILIARY_SENDS 0x20003 + + + + +/** + * Listener definitions to be used with alListener functions. + * These values must be unique and not conflict with other + * al listener values. + */ +#define AL_METERS_PER_UNIT 0x20004 + + + + +/** + * Source definitions to be used with alSource functions. + * These values must be unique and not conflict with other + * al source values. + */ +#define AL_DIRECT_FILTER 0x20005 +#define AL_AUXILIARY_SEND_FILTER 0x20006 +#define AL_AIR_ABSORPTION_FACTOR 0x20007 +#define AL_ROOM_ROLLOFF_FACTOR 0x20008 +#define AL_CONE_OUTER_GAINHF 0x20009 +#define AL_DIRECT_FILTER_GAINHF_AUTO 0x2000A +#define AL_AUXILIARY_SEND_FILTER_GAIN_AUTO 0x2000B +#define AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO 0x2000C + + + + +/** + * Effect object definitions to be used with alEffect functions. + * + * Effect parameter value definitions, ranges, and defaults + * appear farther down in this file. + */ + +/* Reverb Parameters */ +#define AL_REVERB_DENSITY 0x0001 +#define AL_REVERB_DIFFUSION 0x0002 +#define AL_REVERB_GAIN 0x0003 +#define AL_REVERB_GAINHF 0x0004 +#define AL_REVERB_DECAY_TIME 0x0005 +#define AL_REVERB_DECAY_HFRATIO 0x0006 +#define AL_REVERB_REFLECTIONS_GAIN 0x0007 +#define AL_REVERB_REFLECTIONS_DELAY 0x0008 +#define AL_REVERB_LATE_REVERB_GAIN 0x0009 +#define AL_REVERB_LATE_REVERB_DELAY 0x000A +#define AL_REVERB_AIR_ABSORPTION_GAINHF 0x000B +#define AL_REVERB_ROOM_ROLLOFF_FACTOR 0x000C +#define AL_REVERB_DECAY_HFLIMIT 0x000D + +/* Chorus Parameters */ +#define AL_CHORUS_WAVEFORM 0x0001 +#define AL_CHORUS_PHASE 0x0002 +#define AL_CHORUS_RATE 0x0003 +#define AL_CHORUS_DEPTH 0x0004 +#define AL_CHORUS_FEEDBACK 0x0005 +#define AL_CHORUS_DELAY 0x0006 + +/* Distortion Parameters */ +#define AL_DISTORTION_EDGE 0x0001 +#define AL_DISTORTION_GAIN 0x0002 +#define AL_DISTORTION_LOWPASS_CUTOFF 0x0003 +#define AL_DISTORTION_EQCENTER 0x0004 +#define AL_DISTORTION_EQBANDWIDTH 0x0005 + +/* Echo Parameters */ +#define AL_ECHO_DELAY 0x0001 +#define AL_ECHO_LRDELAY 0x0002 +#define AL_ECHO_DAMPING 0x0003 +#define AL_ECHO_FEEDBACK 0x0004 +#define AL_ECHO_SPREAD 0x0005 + +/* Flanger Parameters */ +#define AL_FLANGER_WAVEFORM 0x0001 +#define AL_FLANGER_PHASE 0x0002 +#define AL_FLANGER_RATE 0x0003 +#define AL_FLANGER_DEPTH 0x0004 +#define AL_FLANGER_FEEDBACK 0x0005 +#define AL_FLANGER_DELAY 0x0006 + +/* Frequencyshifter Parameters */ +#define AL_FREQUENCY_SHIFTER_FREQUENCY 0x0001 +#define AL_FREQUENCY_SHIFTER_LEFT_DIRECTION 0x0002 +#define AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION 0x0003 + +/* Vocalmorpher Parameters */ +#define AL_VOCAL_MORPHER_PHONEMEA 0x0001 +#define AL_VOCAL_MORPHER_PHONEMEA_COARSE_TUNING 0x0002 +#define AL_VOCAL_MORPHER_PHONEMEB 0x0003 +#define AL_VOCAL_MORPHER_PHONEMEB_COARSE_TUNING 0x0004 +#define AL_VOCAL_MORPHER_WAVEFORM 0x0005 +#define AL_VOCAL_MORPHER_RATE 0x0006 + +/* Pitchshifter Parameters */ +#define AL_PITCH_SHIFTER_COARSE_TUNE 0x0001 +#define AL_PITCH_SHIFTER_FINE_TUNE 0x0002 + +/* Ringmodulator Parameters */ +#define AL_RING_MODULATOR_FREQUENCY 0x0001 +#define AL_RING_MODULATOR_HIGHPASS_CUTOFF 0x0002 +#define AL_RING_MODULATOR_WAVEFORM 0x0003 + +/* Autowah Parameters */ +#define AL_AUTOWAH_ATTACK_TIME 0x0001 +#define AL_AUTOWAH_RELEASE_TIME 0x0002 +#define AL_AUTOWAH_RESONANCE 0x0003 +#define AL_AUTOWAH_PEAK_GAIN 0x0004 + +/* Compressor Parameters */ +#define AL_COMPRESSOR_ONOFF 0x0001 + +/* Equalizer Parameters */ +#define AL_EQUALIZER_LOW_GAIN 0x0001 +#define AL_EQUALIZER_LOW_CUTOFF 0x0002 +#define AL_EQUALIZER_MID1_GAIN 0x0003 +#define AL_EQUALIZER_MID1_CENTER 0x0004 +#define AL_EQUALIZER_MID1_WIDTH 0x0005 +#define AL_EQUALIZER_MID2_GAIN 0x0006 +#define AL_EQUALIZER_MID2_CENTER 0x0007 +#define AL_EQUALIZER_MID2_WIDTH 0x0008 +#define AL_EQUALIZER_HIGH_GAIN 0x0009 +#define AL_EQUALIZER_HIGH_CUTOFF 0x000A + +/* Effect type */ +#define AL_EFFECT_FIRST_PARAMETER 0x0000 +#define AL_EFFECT_LAST_PARAMETER 0x8000 +#define AL_EFFECT_TYPE 0x8001 + +/* Effect type definitions to be used with AL_EFFECT_TYPE. */ +#define AL_EFFECT_NULL 0x0000 /* Can also be used as an Effect Object ID */ +#define AL_EFFECT_REVERB 0x0001 +#define AL_EFFECT_CHORUS 0x0002 +#define AL_EFFECT_DISTORTION 0x0003 +#define AL_EFFECT_ECHO 0x0004 +#define AL_EFFECT_FLANGER 0x0005 +#define AL_EFFECT_FREQUENCY_SHIFTER 0x0006 +#define AL_EFFECT_VOCAL_MORPHER 0x0007 +#define AL_EFFECT_PITCH_SHIFTER 0x0008 +#define AL_EFFECT_RING_MODULATOR 0x0009 +#define AL_EFFECT_AUTOWAH 0x000A +#define AL_EFFECT_COMPRESSOR 0x000B +#define AL_EFFECT_EQUALIZER 0x000C + +/** + * Auxiliary Slot object definitions to be used with alAuxiliaryEffectSlot functions. + */ +#define AL_EFFECTSLOT_EFFECT 0x0001 +#define AL_EFFECTSLOT_GAIN 0x0002 +#define AL_EFFECTSLOT_AUXILIARY_SEND_AUTO 0x0003 + +/** + * Value to be used as an Auxiliary Slot ID to disable a source send.. + */ +#define AL_EFFECTSLOT_NULL 0x0000 + + + +/** + * Filter object definitions to be used with alFilter functions. + */ + +/* Lowpass parameters. */ +#define AL_LOWPASS_GAIN 0x0001 +#define AL_LOWPASS_GAINHF 0x0002 + +/* Highpass Parameters */ +#define AL_HIGHPASS_GAIN 0x0001 +#define AL_HIGHPASS_GAINLF 0x0002 + +/* Bandpass Parameters */ +#define AL_BANDPASS_GAIN 0x0001 +#define AL_BANDPASS_GAINLF 0x0002 +#define AL_BANDPASS_GAINHF 0x0003 + +/* Filter type */ +#define AL_FILTER_FIRST_PARAMETER 0x0000 +#define AL_FILTER_LAST_PARAMETER 0x8000 +#define AL_FILTER_TYPE 0x8001 + +/* Filter type definitions to be used with AL_FILTER_TYPE. */ +#define AL_FILTER_NULL 0x0000 /* Can also be used as a Filter Object ID */ +#define AL_FILTER_LOWPASS 0x0001 +#define AL_FILTER_HIGHPASS 0x0002 +#define AL_FILTER_BANDPASS 0x0003 + +/********************************************************** + * Filter ranges and defaults. + */ + +/** + * Lowpass filter + */ + +#define LOWPASS_MIN_GAIN 0.0f +#define LOWPASS_MAX_GAIN 1.0f +#define LOWPASS_DEFAULT_GAIN 1.0f + +#define LOWPASS_MIN_GAINHF 0.0f +#define LOWPASS_MAX_GAINHF 1.0f +#define LOWPASS_DEFAULT_GAINHF 1.0f + +/** + * Highpass filter + */ + +#define HIGHPASS_MIN_GAIN 0.0f +#define HIGHPASS_MAX_GAIN 1.0f +#define HIGHPASS_DEFAULT_GAIN 1.0f + +#define HIGHPASS_MIN_GAINLF 0.0f +#define HIGHPASS_MAX_GAINLF 1.0f +#define HIGHPASS_DEFAULT_GAINLF 1.0f + +/** + * Bandpass filter + */ + +#define BANDPASS_MIN_GAIN 0.0f +#define BANDPASS_MAX_GAIN 1.0f +#define BANDPASS_DEFAULT_GAIN 1.0f + +#define BANDPASS_MIN_GAINHF 0.0f +#define BANDPASS_MAX_GAINHF 1.0f +#define BANDPASS_DEFAULT_GAINHF 1.0f + +#define BANDPASS_MIN_GAINLF 0.0f +#define BANDPASS_MAX_GAINLF 1.0f +#define BANDPASS_DEFAULT_GAINLF 1.0f + + + + + /********************************************************** + * Effect parameter structures, value definitions, ranges and defaults. + */ + +/** + * AL reverb effect parameter ranges and defaults + */ +#define AL_REVERB_MIN_DENSITY 0.0f +#define AL_REVERB_MAX_DENSITY 1.0f +#define AL_REVERB_DEFAULT_DENSITY 1.0f + +#define AL_REVERB_MIN_DIFFUSION 0.0f +#define AL_REVERB_MAX_DIFFUSION 1.0f +#define AL_REVERB_DEFAULT_DIFFUSION 1.0f + +#define AL_REVERB_MIN_GAIN 0.0f +#define AL_REVERB_MAX_GAIN 1.0f +#define AL_REVERB_DEFAULT_GAIN 0.32f + +#define AL_REVERB_MIN_GAINHF 0.0f +#define AL_REVERB_MAX_GAINHF 1.0f +#define AL_REVERB_DEFAULT_GAINHF 0.89f + +#define AL_REVERB_MIN_DECAY_TIME 0.1f +#define AL_REVERB_MAX_DECAY_TIME 20.0f +#define AL_REVERB_DEFAULT_DECAY_TIME 1.49f + +#define AL_REVERB_MIN_DECAY_HFRATIO 0.1f +#define AL_REVERB_MAX_DECAY_HFRATIO 2.0f +#define AL_REVERB_DEFAULT_DECAY_HFRATIO 0.83f + +#define AL_REVERB_MIN_REFLECTIONS_GAIN 0.0f +#define AL_REVERB_MAX_REFLECTIONS_GAIN 3.16f +#define AL_REVERB_DEFAULT_REFLECTIONS_GAIN 0.05f + +#define AL_REVERB_MIN_REFLECTIONS_DELAY 0.0f +#define AL_REVERB_MAX_REFLECTIONS_DELAY 0.3f +#define AL_REVERB_DEFAULT_REFLECTIONS_DELAY 0.007f + +#define AL_REVERB_MIN_LATE_REVERB_GAIN 0.0f +#define AL_REVERB_MAX_LATE_REVERB_GAIN 10.0f +#define AL_REVERB_DEFAULT_LATE_REVERB_GAIN 1.26f + +#define AL_REVERB_MIN_LATE_REVERB_DELAY 0.0f +#define AL_REVERB_MAX_LATE_REVERB_DELAY 0.1f +#define AL_REVERB_DEFAULT_LATE_REVERB_DELAY 0.011f + +#define AL_REVERB_MIN_AIR_ABSORPTION_GAINHF 0.892f +#define AL_REVERB_MAX_AIR_ABSORPTION_GAINHF 1.0f +#define AL_REVERB_DEFAULT_AIR_ABSORPTION_GAINHF 0.994f + +#define AL_REVERB_MIN_ROOM_ROLLOFF_FACTOR 0.0f +#define AL_REVERB_MAX_ROOM_ROLLOFF_FACTOR 10.0f +#define AL_REVERB_DEFAULT_ROOM_ROLLOFF_FACTOR 0.0f + +#define AL_REVERB_MIN_DECAY_HFLIMIT AL_FALSE +#define AL_REVERB_MAX_DECAY_HFLIMIT AL_TRUE +#define AL_REVERB_DEFAULT_DECAY_HFLIMIT AL_TRUE + +/** + * AL chorus effect parameter ranges and defaults + */ +#define AL_CHORUS_MIN_WAVEFORM 0 +#define AL_CHORUS_MAX_WAVEFORM 1 +#define AL_CHORUS_DEFAULT_WAVEFORM 1 + +#define AL_CHORUS_WAVEFORM_SINUSOID 0 +#define AL_CHORUS_WAVEFORM_TRIANGLE 1 + +#define AL_CHORUS_MIN_PHASE (-180) +#define AL_CHORUS_MAX_PHASE 180 +#define AL_CHORUS_DEFAULT_PHASE 90 + +#define AL_CHORUS_MIN_RATE 0.0f +#define AL_CHORUS_MAX_RATE 10.0f +#define AL_CHORUS_DEFAULT_RATE 1.1f + +#define AL_CHORUS_MIN_DEPTH 0.0f +#define AL_CHORUS_MAX_DEPTH 1.0f +#define AL_CHORUS_DEFAULT_DEPTH 0.1f + +#define AL_CHORUS_MIN_FEEDBACK (-1.0f) +#define AL_CHORUS_MAX_FEEDBACK 1.0f +#define AL_CHORUS_DEFAULT_FEEDBACK 0.25f + +#define AL_CHORUS_MIN_DELAY 0.0f +#define AL_CHORUS_MAX_DELAY 0.016f +#define AL_CHORUS_DEFAULT_DELAY 0.016f + +/** + * AL distortion effect parameter ranges and defaults + */ +#define AL_DISTORTION_MIN_EDGE 0.0f +#define AL_DISTORTION_MAX_EDGE 1.0f +#define AL_DISTORTION_DEFAULT_EDGE 0.2f + +#define AL_DISTORTION_MIN_GAIN 0.01f +#define AL_DISTORTION_MAX_GAIN 1.0f +#define AL_DISTORTION_DEFAULT_GAIN 0.05f + +#define AL_DISTORTION_MIN_LOWPASS_CUTOFF 80.0f +#define AL_DISTORTION_MAX_LOWPASS_CUTOFF 24000.0f +#define AL_DISTORTION_DEFAULT_LOWPASS_CUTOFF 8000.0f + +#define AL_DISTORTION_MIN_EQCENTER 80.0f +#define AL_DISTORTION_MAX_EQCENTER 24000.0f +#define AL_DISTORTION_DEFAULT_EQCENTER 3600.0f + +#define AL_DISTORTION_MIN_EQBANDWIDTH 80.0f +#define AL_DISTORTION_MAX_EQBANDWIDTH 24000.0f +#define AL_DISTORTION_DEFAULT_EQBANDWIDTH 3600.0f + +/** + * AL echo effect parameter ranges and defaults + */ +#define AL_ECHO_MIN_DELAY 0.0f +#define AL_ECHO_MAX_DELAY 0.207f +#define AL_ECHO_DEFAULT_DELAY 0.1f + +#define AL_ECHO_MIN_LRDELAY 0.0f +#define AL_ECHO_MAX_LRDELAY 0.404f +#define AL_ECHO_DEFAULT_LRDELAY 0.1f + +#define AL_ECHO_MIN_DAMPING 0.0f +#define AL_ECHO_MAX_DAMPING 0.99f +#define AL_ECHO_DEFAULT_DAMPING 0.5f + +#define AL_ECHO_MIN_FEEDBACK 0.0f +#define AL_ECHO_MAX_FEEDBACK 1.0f +#define AL_ECHO_DEFAULT_FEEDBACK 0.5f + +#define AL_ECHO_MIN_SPREAD (-1.0f) +#define AL_ECHO_MAX_SPREAD 1.0f +#define AL_ECHO_DEFAULT_SPREAD (-1.0f) + +/** + * AL flanger effect parameter ranges and defaults + */ +#define AL_FLANGER_MIN_WAVEFORM 0 +#define AL_FLANGER_MAX_WAVEFORM 1 +#define AL_FLANGER_DEFAULT_WAVEFORM 1 + +#define AL_FLANGER_WAVEFORM_SINUSOID 0 +#define AL_FLANGER_WAVEFORM_TRIANGLE 1 + +#define AL_FLANGER_MIN_PHASE (-180) +#define AL_FLANGER_MAX_PHASE 180 +#define AL_FLANGER_DEFAULT_PHASE 0 + +#define AL_FLANGER_MIN_RATE 0.0f +#define AL_FLANGER_MAX_RATE 10.0f +#define AL_FLANGER_DEFAULT_RATE 0.27f + +#define AL_FLANGER_MIN_DEPTH 0.0f +#define AL_FLANGER_MAX_DEPTH 1.0f +#define AL_FLANGER_DEFAULT_DEPTH 1.0f + +#define AL_FLANGER_MIN_FEEDBACK (-1.0f) +#define AL_FLANGER_MAX_FEEDBACK 1.0f +#define AL_FLANGER_DEFAULT_FEEDBACK (-0.5f) + +#define AL_FLANGER_MIN_DELAY 0.0f +#define AL_FLANGER_MAX_DELAY 0.004f +#define AL_FLANGER_DEFAULT_DELAY 0.002f + +/** + * AL frequency shifter effect parameter ranges and defaults + */ +#define AL_FREQUENCY_SHIFTER_MIN_FREQUENCY 0.0f +#define AL_FREQUENCY_SHIFTER_MAX_FREQUENCY 24000.0f +#define AL_FREQUENCY_SHIFTER_DEFAULT_FREQUENCY 0.0f + +#define AL_FREQUENCY_SHIFTER_MIN_LEFT_DIRECTION 0 +#define AL_FREQUENCY_SHIFTER_MAX_LEFT_DIRECTION 2 +#define AL_FREQUENCY_SHIFTER_DEFAULT_LEFT_DIRECTION 0 + +#define AL_FREQUENCY_SHIFTER_MIN_RIGHT_DIRECTION 0 +#define AL_FREQUENCY_SHIFTER_MAX_RIGHT_DIRECTION 2 +#define AL_FREQUENCY_SHIFTER_DEFAULT_RIGHT_DIRECTION 0 + +#define AL_FREQUENCY_SHIFTER_DIRECTION_DOWN 0 +#define AL_FREQUENCY_SHIFTER_DIRECTION_UP 1 +#define AL_FREQUENCY_SHIFTER_DIRECTION_OFF 2 + +/** + * AL vocal morpher effect parameter ranges and defaults + */ +#define AL_VOCAL_MORPHER_MIN_PHONEMEA 0 +#define AL_VOCAL_MORPHER_MAX_PHONEMEA 29 +#define AL_VOCAL_MORPHER_DEFAULT_PHONEMEA 0 + +#define AL_VOCAL_MORPHER_MIN_PHONEMEA_COARSE_TUNING (-24) +#define AL_VOCAL_MORPHER_MAX_PHONEMEA_COARSE_TUNING 24 +#define AL_VOCAL_MORPHER_DEFAULT_PHONEMEA_COARSE_TUNING 0 + +#define AL_VOCAL_MORPHER_MIN_PHONEMEB 0 +#define AL_VOCAL_MORPHER_MAX_PHONEMEB 29 +#define AL_VOCAL_MORPHER_DEFAULT_PHONEMEB 10 + +#define AL_VOCAL_MORPHER_PHONEME_A 0 +#define AL_VOCAL_MORPHER_PHONEME_E 1 +#define AL_VOCAL_MORPHER_PHONEME_I 2 +#define AL_VOCAL_MORPHER_PHONEME_O 3 +#define AL_VOCAL_MORPHER_PHONEME_U 4 +#define AL_VOCAL_MORPHER_PHONEME_AA 5 +#define AL_VOCAL_MORPHER_PHONEME_AE 6 +#define AL_VOCAL_MORPHER_PHONEME_AH 7 +#define AL_VOCAL_MORPHER_PHONEME_AO 8 +#define AL_VOCAL_MORPHER_PHONEME_EH 9 +#define AL_VOCAL_MORPHER_PHONEME_ER 10 +#define AL_VOCAL_MORPHER_PHONEME_IH 11 +#define AL_VOCAL_MORPHER_PHONEME_IY 12 +#define AL_VOCAL_MORPHER_PHONEME_UH 13 +#define AL_VOCAL_MORPHER_PHONEME_UW 14 +#define AL_VOCAL_MORPHER_PHONEME_B 15 +#define AL_VOCAL_MORPHER_PHONEME_D 16 +#define AL_VOCAL_MORPHER_PHONEME_F 17 +#define AL_VOCAL_MORPHER_PHONEME_G 18 +#define AL_VOCAL_MORPHER_PHONEME_J 19 +#define AL_VOCAL_MORPHER_PHONEME_K 20 +#define AL_VOCAL_MORPHER_PHONEME_L 21 +#define AL_VOCAL_MORPHER_PHONEME_M 22 +#define AL_VOCAL_MORPHER_PHONEME_N 23 +#define AL_VOCAL_MORPHER_PHONEME_P 24 +#define AL_VOCAL_MORPHER_PHONEME_R 25 +#define AL_VOCAL_MORPHER_PHONEME_S 26 +#define AL_VOCAL_MORPHER_PHONEME_T 27 +#define AL_VOCAL_MORPHER_PHONEME_V 28 +#define AL_VOCAL_MORPHER_PHONEME_Z 29 + +#define AL_VOCAL_MORPHER_MIN_PHONEMEB_COARSE_TUNING (-24) +#define AL_VOCAL_MORPHER_MAX_PHONEMEB_COARSE_TUNING 24 +#define AL_VOCAL_MORPHER_DEFAULT_PHONEMEB_COARSE_TUNING 0 + +#define AL_VOCAL_MORPHER_MIN_WAVEFORM 0 +#define AL_VOCAL_MORPHER_MAX_WAVEFORM 2 +#define AL_VOCAL_MORPHER_DEFAULT_WAVEFORM 0 + +#define AL_VOCAL_MORPHER_WAVEFORM_SINUSOID 0 +#define AL_VOCAL_MORPHER_WAVEFORM_TRIANGLE 1 +#define AL_VOCAL_MORPHER_WAVEFORM_SAWTOOTH 2 + +#define AL_VOCAL_MORPHER_MIN_RATE 0.0f +#define AL_VOCAL_MORPHER_MAX_RATE 10.0f +#define AL_VOCAL_MORPHER_DEFAULT_RATE 1.41f + +/** + * AL pitch shifter effect parameter ranges and defaults + */ +#define AL_PITCH_SHIFTER_MIN_COARSE_TUNE (-12) +#define AL_PITCH_SHIFTER_MAX_COARSE_TUNE 12 +#define AL_PITCH_SHIFTER_DEFAULT_COARSE_TUNE 12 + +#define AL_PITCH_SHIFTER_MIN_FINE_TUNE (-50) +#define AL_PITCH_SHIFTER_MAX_FINE_TUNE 50 +#define AL_PITCH_SHIFTER_DEFAULT_FINE_TUNE 0 + +/** + * AL ring modulator effect parameter ranges and defaults + */ +#define AL_RING_MODULATOR_MIN_FREQUENCY 0.0f +#define AL_RING_MODULATOR_MAX_FREQUENCY 8000.0f +#define AL_RING_MODULATOR_DEFAULT_FREQUENCY 440.0f + +#define AL_RING_MODULATOR_MIN_HIGHPASS_CUTOFF 0.0f +#define AL_RING_MODULATOR_MAX_HIGHPASS_CUTOFF 24000.0f +#define AL_RING_MODULATOR_DEFAULT_HIGHPASS_CUTOFF 800.0f + +#define AL_RING_MODULATOR_MIN_WAVEFORM 0 +#define AL_RING_MODULATOR_MAX_WAVEFORM 2 +#define AL_RING_MODULATOR_DEFAULT_WAVEFORM 0 + +#define AL_RING_MODULATOR_SINUSOID 0 +#define AL_RING_MODULATOR_SAWTOOTH 1 +#define AL_RING_MODULATOR_SQUARE 2 + +/** + * AL autowah effect parameter ranges and defaults + */ +#define AL_AUTOWAH_MIN_ATTACK_TIME 0.0001f +#define AL_AUTOWAH_MAX_ATTACK_TIME 1.0f +#define AL_AUTOWAH_DEFAULT_ATTACK_TIME 0.06f + +#define AL_AUTOWAH_MIN_RELEASE_TIME 0.0001f +#define AL_AUTOWAH_MAX_RELEASE_TIME 1.0f +#define AL_AUTOWAH_DEFAULT_RELEASE_TIME 0.06f + +#define AL_AUTOWAH_MIN_RESONANCE 2.0f +#define AL_AUTOWAH_MAX_RESONANCE 1000.0f +#define AL_AUTOWAH_DEFAULT_RESONANCE 1000.0f + +#define AL_AUTOWAH_MIN_PEAK_GAIN 0.00003f +#define AL_AUTOWAH_MAX_PEAK_GAIN 31621.0f +#define AL_AUTOWAH_DEFAULT_PEAK_GAIN 11.22f + +/** + * AL compressor effect parameter ranges and defaults + */ +#define AL_COMPRESSOR_MIN_ONOFF 0 +#define AL_COMPRESSOR_MAX_ONOFF 1 +#define AL_COMPRESSOR_DEFAULT_ONOFF 1 + +/** + * AL equalizer effect parameter ranges and defaults + */ +#define AL_EQUALIZER_MIN_LOW_GAIN 0.126f +#define AL_EQUALIZER_MAX_LOW_GAIN 7.943f +#define AL_EQUALIZER_DEFAULT_LOW_GAIN 1.0f + +#define AL_EQUALIZER_MIN_LOW_CUTOFF 50.0f +#define AL_EQUALIZER_MAX_LOW_CUTOFF 800.0f +#define AL_EQUALIZER_DEFAULT_LOW_CUTOFF 200.0f + +#define AL_EQUALIZER_MIN_MID1_GAIN 0.126f +#define AL_EQUALIZER_MAX_MID1_GAIN 7.943f +#define AL_EQUALIZER_DEFAULT_MID1_GAIN 1.0f + +#define AL_EQUALIZER_MIN_MID1_CENTER 200.0f +#define AL_EQUALIZER_MAX_MID1_CENTER 3000.0f +#define AL_EQUALIZER_DEFAULT_MID1_CENTER 500.0f + +#define AL_EQUALIZER_MIN_MID1_WIDTH 0.01f +#define AL_EQUALIZER_MAX_MID1_WIDTH 1.0f +#define AL_EQUALIZER_DEFAULT_MID1_WIDTH 1.0f + +#define AL_EQUALIZER_MIN_MID2_GAIN 0.126f +#define AL_EQUALIZER_MAX_MID2_GAIN 7.943f +#define AL_EQUALIZER_DEFAULT_MID2_GAIN 1.0f + +#define AL_EQUALIZER_MIN_MID2_CENTER 1000.0f +#define AL_EQUALIZER_MAX_MID2_CENTER 8000.0f +#define AL_EQUALIZER_DEFAULT_MID2_CENTER 3000.0f + +#define AL_EQUALIZER_MIN_MID2_WIDTH 0.01f +#define AL_EQUALIZER_MAX_MID2_WIDTH 1.0f +#define AL_EQUALIZER_DEFAULT_MID2_WIDTH 1.0f + +#define AL_EQUALIZER_MIN_HIGH_GAIN 0.126f +#define AL_EQUALIZER_MAX_HIGH_GAIN 7.943f +#define AL_EQUALIZER_DEFAULT_HIGH_GAIN 1.0f + +#define AL_EQUALIZER_MIN_HIGH_CUTOFF 4000.0f +#define AL_EQUALIZER_MAX_HIGH_CUTOFF 16000.0f +#define AL_EQUALIZER_DEFAULT_HIGH_CUTOFF 6000.0f + + + + +/********************************************************** + * Source parameter value definitions, ranges and defaults. + */ +#define AL_MIN_AIR_ABSORPTION_FACTOR 0.0f +#define AL_MAX_AIR_ABSORPTION_FACTOR 10.0f +#define AL_DEFAULT_AIR_ABSORPTION_FACTOR 0.0f + +#define AL_MIN_ROOM_ROLLOFF_FACTOR 0.0f +#define AL_MAX_ROOM_ROLLOFF_FACTOR 10.0f +#define AL_DEFAULT_ROOM_ROLLOFF_FACTOR 0.0f + +#define AL_MIN_CONE_OUTER_GAINHF 0.0f +#define AL_MAX_CONE_OUTER_GAINHF 1.0f +#define AL_DEFAULT_CONE_OUTER_GAINHF 1.0f + +#define AL_MIN_DIRECT_FILTER_GAINHF_AUTO AL_FALSE +#define AL_MAX_DIRECT_FILTER_GAINHF_AUTO AL_TRUE +#define AL_DEFAULT_DIRECT_FILTER_GAINHF_AUTO AL_TRUE + +#define AL_MIN_AUXILIARY_SEND_FILTER_GAIN_AUTO AL_FALSE +#define AL_MAX_AUXILIARY_SEND_FILTER_GAIN_AUTO AL_TRUE +#define AL_DEFAULT_AUXILIARY_SEND_FILTER_GAIN_AUTO AL_TRUE + +#define AL_MIN_AUXILIARY_SEND_FILTER_GAINHF_AUTO AL_FALSE +#define AL_MAX_AUXILIARY_SEND_FILTER_GAINHF_AUTO AL_TRUE +#define AL_DEFAULT_AUXILIARY_SEND_FILTER_GAINHF_AUTO AL_TRUE + + + + +/********************************************************** + * Listener parameter value definitions, ranges and defaults. + */ +#define AL_MIN_METERS_PER_UNIT FLT_MIN +#define AL_MAX_METERS_PER_UNIT FLT_MAX +#define AL_DEFAULT_METERS_PER_UNIT 1.0f + +namespace openal +{ + /** + * Effect object functions. + */ + + /* Create Effect objects. */ + typedef void (AL_APIENTRY *LPALGENEFFECTS)( ALsizei n, ALuint* effects ); + + /* Delete Effect objects. */ + typedef void (AL_APIENTRY *LPALDELETEEFFECTS)( ALsizei n, ALuint* effects ); + + /* Verify a handle is a valid Effect. */ + typedef ALboolean (AL_APIENTRY *LPALISEFFECT)( ALuint eid ); + + /* Set an integer parameter for an Effect object. */ + typedef void (AL_APIENTRY *LPALEFFECTI)( ALuint eid, ALenum param, ALint value); + typedef void (AL_APIENTRY *LPALEFFECTIV)( ALuint eid, ALenum param, ALint* values ); + + /* Set a floating point parameter for an Effect object. */ + typedef void (AL_APIENTRY *LPALEFFECTF)( ALuint eid, ALenum param, ALfloat value); + typedef void (AL_APIENTRY *LPALEFFECTFV)( ALuint eid, ALenum param, ALfloat* values ); + + /* Get an integer parameter for an Effect object. */ + typedef void (AL_APIENTRY *LPALGETEFFECTI)( ALuint eid, ALenum pname, ALint* value ); + typedef void (AL_APIENTRY *LPALGETEFFECTIV)( ALuint eid, ALenum pname, ALint* values ); + + /* Get a floating point parameter for an Effect object. */ + typedef void (AL_APIENTRY *LPALGETEFFECTF)( ALuint eid, ALenum pname, ALfloat* value ); + typedef void (AL_APIENTRY *LPALGETEFFECTFV)( ALuint eid, ALenum pname, ALfloat* values ); + + + /** + * Filter object functions + */ + + /* Create Filter objects. */ + typedef void (AL_APIENTRY *LPALGENFILTERS)( ALsizei n, ALuint* filters ); + + /* Delete Filter objects. */ + typedef void (AL_APIENTRY *LPALDELETEFILTERS)( ALsizei n, ALuint* filters ); + + /* Verify a handle is a valid Filter. */ + typedef ALboolean (AL_APIENTRY *LPALISFILTER)( ALuint fid ); + + /* Set an integer parameter for a Filter object. */ + typedef void (AL_APIENTRY *LPALFILTERI)( ALuint fid, ALenum param, ALint value ); + typedef void (AL_APIENTRY *LPALFILTERIV)( ALuint fid, ALenum param, ALint* values ); + + /* Set a floating point parameter for an Filter object. */ + typedef void (AL_APIENTRY *LPALFILTERF)( ALuint fid, ALenum param, ALfloat value); + typedef void (AL_APIENTRY *LPALFILTERFV)( ALuint fid, ALenum param, ALfloat* values ); + + /* Get an integer parameter for a Filter object. */ + typedef void (AL_APIENTRY *LPALGETFILTERI)( ALuint fid, ALenum pname, ALint* value ); + typedef void (AL_APIENTRY *LPALGETFILTERIV)( ALuint fid, ALenum pname, ALint* values ); + + /* Get a floating point parameter for a Filter object. */ + typedef void (AL_APIENTRY *LPALGETFILTERF)( ALuint fid, ALenum pname, ALfloat* value ); + typedef void (AL_APIENTRY *LPALGETFILTERFV)( ALuint fid, ALenum pname, ALfloat* values ); + + + /** + * Auxiliary Slot object functions + */ + + /* Create Auxiliary Slot objects. */ + typedef void (AL_APIENTRY *LPALGENAUXILIARYEFFECTSLOTS)( ALsizei n, ALuint* slots ); + + /* Delete Auxiliary Slot objects. */ + typedef void (AL_APIENTRY *LPALDELETEAUXILIARYEFFECTSLOTS)( ALsizei n, ALuint* slots ); + + /* Verify a handle is a valid Auxiliary Slot. */ + typedef ALboolean (AL_APIENTRY *LPALISAUXILIARYEFFECTSLOT)( ALuint slot ); + + /* Set an integer parameter for a Auxiliary Slot object. */ + typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTI)( ALuint asid, ALenum param, ALint value ); + typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTIV)( ALuint asid, ALenum param, ALint* values ); + + /* Set a floating point parameter for an Auxiliary Slot object. */ + typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTF)( ALuint asid, ALenum param, ALfloat value ); + typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTFV)( ALuint asid, ALenum param, ALfloat* values ); + + /* Get an integer parameter for a Auxiliary Slot object. */ + typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTI)( ALuint asid, ALenum pname, ALint* value ); + typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTIV)( ALuint asid, ALenum pname, ALint* values ); + + /* Get a floating point parameter for a Auxiliary Slot object. */ + typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTF)( ALuint asid, ALenum pname, ALfloat* value ); + typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTFV)( ALuint asid, ALenum pname, ALfloat* values ); +} + +namespace openal +{ + // EFX Extension function pointer variables + + // Effect objects + extern LPALGENEFFECTS alGenEffects; + extern LPALDELETEEFFECTS alDeleteEffects; + extern LPALISEFFECT alIsEffect; + extern LPALEFFECTI alEffecti; + extern LPALEFFECTIV alEffectiv; + extern LPALEFFECTF alEffectf; + extern LPALEFFECTFV alEffectfv; + extern LPALGETEFFECTI alGetEffecti; + extern LPALGETEFFECTIV alGetEffectiv; + extern LPALGETEFFECTF alGetEffectf; + extern LPALGETEFFECTFV alGetEffectfv; + + // Filter objects + extern LPALGENFILTERS alGenFilters; + extern LPALDELETEFILTERS alDeleteFilters; + extern LPALISFILTER alIsFilter; + extern LPALFILTERI alFilteri; + extern LPALFILTERIV alFilteriv; + extern LPALFILTERF alFilterf; + extern LPALFILTERFV alFilterfv; + extern LPALGETFILTERI alGetFilteri; + extern LPALGETFILTERIV alGetFilteriv; + extern LPALGETFILTERF alGetFilterf; + extern LPALGETFILTERFV alGetFilterfv; + + // Auxiliary slot object + extern LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots; + extern LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots; + extern LPALISAUXILIARYEFFECTSLOT alIsAuxiliaryEffectSlot; + extern LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti; + extern LPALAUXILIARYEFFECTSLOTIV alAuxiliaryEffectSlotiv; + extern LPALAUXILIARYEFFECTSLOTF alAuxiliaryEffectSlotf; + extern LPALAUXILIARYEFFECTSLOTFV alAuxiliaryEffectSlotfv; + extern LPALGETAUXILIARYEFFECTSLOTI alGetAuxiliaryEffectSloti; + extern LPALGETAUXILIARYEFFECTSLOTIV alGetAuxiliaryEffectSlotiv; + extern LPALGETAUXILIARYEFFECTSLOTF alGetAuxiliaryEffectSlotf; + extern LPALGETAUXILIARYEFFECTSLOTFV alGetAuxiliaryEffectSlotfv; +} +#endif//HGL_EFX_INCLUDE diff --git a/inc/hgl/al/xram.h b/inc/hgl/al/xram.h new file mode 100644 index 0000000..7431eed --- /dev/null +++ b/inc/hgl/al/xram.h @@ -0,0 +1,19 @@ +#ifndef HGL_XRAM_INCLUDE +#define HGL_XRAM_INCLUDE + +#include +namespace openal +{ + // XRAM Extension function pointer variables and enum values + + typedef ALboolean (AL_APIENTRY *LPEAXSETBUFFERMODE)(ALsizei n, ALuint *buffers, ALint value); + typedef ALenum (AL_APIENTRY *LPEAXGETBUFFERMODE)(ALuint buffer, ALint *value); + + extern LPEAXSETBUFFERMODE eaxSetBufferMode; + extern LPEAXGETBUFFERMODE eaxGetBufferMode; + + // X-RAM Enum values + extern ALenum eXRAMSize, eXRAMFree; + extern ALenum eXRAMAuto, eXRAMHardware, eXRAMAccessible; +}//namespace openal +#endif// diff --git a/inc/hgl/audio/AudioBuffer.h b/inc/hgl/audio/AudioBuffer.h new file mode 100644 index 0000000..7cc2f46 --- /dev/null +++ b/inc/hgl/audio/AudioBuffer.h @@ -0,0 +1,50 @@ +#ifndef HGL_AUDIO_BUFFER_INCLUDE +#define HGL_AUDIO_BUFFER_INCLUDE + +#include +// #include +#include +#include + +namespace hgl +{ + using namespace io; + + /** + * AudioBuffer是一个简单的音频数据管理类 + */ + class AudioBuffer ///音频数据缓冲区类 + { + bool ok; + + void InitPrivate(); + + public: + + uint Index; + double Time; ///<缓冲区中音频数据可以播放的时间(秒) + uint Size; ///<缓冲区中音频数据的总字节数 + uint Freq; ///<音频数量采样率 + + public: + + AudioBuffer(void *,int,AudioFileType); ///<本类构造函数 + AudioBuffer(InputStream *,int,AudioFileType); ///<本类构造函数 + AudioBuffer(const os_char *filename=0,AudioFileType=aftNone); ///<本类构造函数 +// AudioBuffer(HAC *,const os_char *,AudioFileType=aftNone); ///<本类构造函数 + virtual ~AudioBuffer(); ///<本类析构函数 + + bool SetData(uint format,const void *data,uint size,uint freq); + + bool Load(void *,int,AudioFileType); ///<从内存中加载音频数据 + bool Load(InputStream *,int,AudioFileType); ///<从流中加载音频数据 + bool Load(const os_char *,AudioFileType=aftNone); ///<从文件中加载音频数据 +// bool Load(HAC *,const os_char *,AudioFileType=aftNone); ///<从HAC包的文件中加载音频数据 + + void Clear(); ///<清除数据 + };//class AudioBuffer + +// typedef ObjectBuffer AudioBufferBuffer; /// AudioBufferHAC; /// +namespace hgl +{ + /** + * 音频文件格式 + */ + enum AudioFileType + { + aftNone=0, ///<起始定义,如使用表示自动根据扩展名识别 + + aftWAV, /// +namespace hgl +{ + class AudioSource; + class AudioBuffer; + + /** + * 简单的音频播放管理,为一般应用的简单操作工具 + */ + class AudioManage + { + struct AudioItem + { + AudioSource *source; + AudioBuffer *buffer; + + AudioItem(); + ~AudioItem(); + + bool Check(); + void Play(const os_char *,float); + };//struct AudioItem + + ObjectList Items; + + public: + + /** + * 本类构造函数 + * @param count 创建的音源数量,默认为8 + */ + AudioManage(int count=8); + ~AudioManage(); + + /** + * 播放一个音效 + * @param filename 文件名 + * @param gain 音量,默认为1 + */ + bool Play(const os_char *filename,float gain=1); + };//class AudioManage +}//namespace hgl +#endif//HGL_AUDIO_MANAGE_INCLUDEE diff --git a/inc/hgl/audio/AudioPlayer.Attrib.h b/inc/hgl/audio/AudioPlayer.Attrib.h new file mode 100644 index 0000000..c841f0f --- /dev/null +++ b/inc/hgl/audio/AudioPlayer.Attrib.h @@ -0,0 +1,82 @@ +protected: + + ALbyte *audio_data; + int audio_data_size; + + void *audio_ptr; ///<音频数据指针 + + char *audio_buffer; + int audio_buffer_size; + uint audio_buffer_count; ///<播放数据计数 + + AudioPlugInInterface *decode; + + ALenum format; ///<音频数据格式 + ALsizei rate; ///<音频数据采样率 + + struct + { + bool open; + uint64 time; + float gap; + + struct + { + float gain; + double time; + }start,end; + }auto_gain; ///<自动增益 + + bool ReadData(ALuint); + bool UpdateBuffer(); + void ClearBuffer(); + + bool Playback(); + + bool IsExitDelete()const override{return false;} + bool Execute() override; + + void InitPrivate(); + bool Load(AudioFileType); + +protected: + + volatile bool loop; + volatile PlayState ps; + + AudioSource audiosource; + ALuint source; + ALuint buffer[3]; + double time; + double wait_time; + + double gain; + + double start_time; + + double fade_in_time; + double fade_out_time; + + bool GetLoop(); + void SetLoop(bool); + +public: + + uint GetIndex(){return audiosource.index;} + double GetTime(){return time;} + PlayState GetPlayState(){return ps;} + int GetSourceState(){return audiosource.GetState();} + float GetMinGain(){return audiosource.GetMinGain();} + float GetMaxGain(){return audiosource.GetMaxGain();} + + float GetPitch(){return audiosource.pitch;} + void SetPitch(float val){audiosource.SetPitch(val);} + + float GetGain(){return audiosource.gain;} + void SetGain(float val){audiosource.SetGain(val);} + + float GetConeGain(){return audiosource.cone_gain;} + void SetConeGain(float val){audiosource.SetConeGain(val);} + + float GetRolloffFactor(){return audiosource.rolloff_factor;} + void SetRolloffFactor(float rf){audiosource.SetRolloffFactor(rf);} diff --git a/inc/hgl/audio/AudioPlayer.h b/inc/hgl/audio/AudioPlayer.h new file mode 100644 index 0000000..82d75ce --- /dev/null +++ b/inc/hgl/audio/AudioPlayer.h @@ -0,0 +1,99 @@ +#ifndef HGL_AUDIO_PLAYER_INCLUDE +#define HGL_AUDIO_PLAYER_INCLUDE + +// #include +#include +#include +#include +#include +#include +using namespace openal; +namespace hgl +{ + namespace io + { + class InputStream; + }//namespace io + + struct AudioPlugInInterface; + + /** + * 使用AudioPlayer创建的音频播放器类,一般用于背景音乐等独占的音频处理。 + * 这个音频播放器将使用一个单独的线程,在播放器被删除时线程也会被关闭。 + */ + class AudioPlayer:public Thread ///音频播放器基类 + { + ThreadMutex lock; + + public: + + enum PlayState //播放器状态 + { + psNone=0, + psPlay, + psPause, + psExit + }; + + #include + + public: //属性 + + Property Index; ///<音源索引 + Property Time; ///<音频总时间 + + Property State; ///<播放器状态 + Property SourceState; ///<音源状态 + Property MinGain; ///<最小增益 + Property MaxGain; ///<最大增益 + + Property Loop; ///<是否循环播放虚拟变量 + + Property Pitch; ///<播放频率 + Property Gain; ///<音量增益幅度 + Property ConeGain; ///< + + Property RolloffFactor; ///< + + public: //属性方法 + + const Vector3f & GetPosition(){return audiosource.position;} const + void SetPosition(const Vector3f &pos){audiosource.SetPosition(pos);} + + const Vector3f & GetVelocity(){return audiosource.velocity;} const + void SetVelocity(const Vector3f &vel){audiosource.SetVelocity(vel);} + + const Vector3f & GetDirection(){return audiosource.direction;} const + void SetDirection(const Vector3f &dir){audiosource.SetDirection(dir);} + + const void GetDistance(float &ref_distance, float &max_distance)const{audiosource.GetDistance(ref_distance,max_distance);} const + void SetDistance(const float &ref_distance,const float &max_distance){audiosource.SetDistance(ref_distance,max_distance);} + + const ConeAngle & GetConeAngle(){return audiosource.angle;} const + void SetConeAngle(const ConeAngle &ca){audiosource.SetConeAngle(ca);} + + public: //方法 + + AudioPlayer(); + AudioPlayer(io::InputStream *,int,AudioFileType); + AudioPlayer(const os_char *,AudioFileType=aftNone); +// AudioPlayer(HAC *,const os_char *,AudioFileType=aftNone); + virtual ~AudioPlayer(); + + virtual bool Load(io::InputStream *,int,AudioFileType); ///<从流中加载一个音频文件 + virtual bool Load(const os_char *,AudioFileType=aftNone); ///<加载一个音频文件 +// virtual bool Load(HAC *,const os_char *,AudioFileType=aftNone); ///<从HAC包中加载一个音频文件 + + virtual void Play(bool=true); ///<播放音频 + virtual void Stop(); ///<停止播放 + virtual void Pause(); ///<暂停播放 + virtual void Resume(); ///<继续播放 + virtual void Clear(); ///<清除音频数据 + + virtual double GetPlayTime(); ///<取得已播放时间(单位秒) + virtual void SetFadeTime(double,double); ///<设置淡入淡出时间 + + virtual void AutoGain(float,double); ///<自动音量 + };//class AudioPlayer +}//namespace hgl +#endif//HGL_AUDIO_PLAYER_INCLUDE diff --git a/inc/hgl/audio/AudioScene.h b/inc/hgl/audio/AudioScene.h new file mode 100644 index 0000000..da9e9f7 --- /dev/null +++ b/inc/hgl/audio/AudioScene.h @@ -0,0 +1,176 @@ +#ifndef HGL_AUDIO_SCENE_INCLUDE +#define HGL_AUDIO_SCENE_INCLUDE + +#include +#include +#include +#include +namespace hgl +{ + class AudioBuffer; + class AudioSource; + class AudioListener; + + /** + * 邏輯發聲源 + */ + struct AudioSourceItem + { + friend const double GetGain(AudioListener *,AudioSourceItem *); + friend class AudioScene; + + private: + + AudioBuffer *buffer; + + public: + + bool loop; ///<是否循环播放 +// float min_gain,max_gain; + float gain; ///<音量增益 + + uint distance_model; ///<音量衰减模型 + float rolloff_factor; ///<环境衰减比率,默认为1 + float doppler_factor; ///<多普勒效果强度,默认为0 + + float ref_distance; ///<衰减距离 + float max_distance; ///<最大距离 + ConeAngle cone_angle; + Vector3f velocity; + Vector3f direction; + + private: + + double start_play_time; ///<开播时间 + bool is_play; ///<是否需要播放 + + Vector3f last_pos; + double last_time; + + Vector3f cur_pos; + double cur_time; + + double move_speed; + + double last_gain; ///<最近一次的音量 + + AudioSource *source; + + public: + + /** + * 请求播放这个音源 + * @param play_time 开播时间(默认为0,表示自能听到后再响) + */ + void Play(const double play_time=0) + { + start_play_time=play_time; + is_play=true; + last_time=0; + } + + /** + * 请求立即停播这个音源 + */ + void Stop() + { + is_play=false; + } + + /** + * 移动音源到指定位置 + * @param pos 坐标 + * @param ct 当前时间 + */ + void MoveTo(const Vector3f &pos,const double &ct) + { + if(last_time==0) + { + last_pos=cur_pos=pos; + last_time=cur_time=ct; + + move_speed=0; + } + else + { + last_pos=cur_pos; + last_time=cur_time; + + cur_pos=pos; + cur_time=ct; + } + } + };//struct AudioSourceItem + + const double GetGain(AudioListener *,AudioSourceItem *); ///<取得相對音量 + + /** + * 音频场景管理 + */ + class AudioScene ///<音频场景管理 + { + protected: + + double cur_time; ///<当前时间 + + float ref_distance; ///<默认1000 + float max_distance; ///<默认100000 + + AudioListener *listener; ///<收聽者 + + ObjectPool source_pool; ///<音源数据池 + Set source_list; ///<音源列表 + + protected: + + bool ToMute(AudioSourceItem *); ///<转静默处理 + bool ToHear(AudioSourceItem *); ///<转发声处理 + + bool UpdateSource(AudioSourceItem *); ///<刷新音源处理 + + public: //事件 + + virtual float OnCheckGain(AudioSourceItem *asi) ///<檢測音量事件 + { + return asi?GetGain(listener,asi)*asi->gain:0; + } + + virtual void OnToMute(AudioSourceItem *){/*無任何處理,請自行重載處理*/} ///<从有声变成聽不到聲音 + virtual void OnToHear(AudioSourceItem *){/*無任何處理,請自行重載處理*/} ///<从听不到声变成能听到声音 + + virtual void OnContinuedMute(AudioSourceItem *){/*無任何處理,請自行重載處理*/} ///<持续聽不到聲音 + virtual void OnContinuedHear(AudioSourceItem *){/*無任何處理,請自行重載處理*/} ///<持续可以聽到聲音 + + virtual bool OnStopped(AudioSourceItem *){return true;} ///<单个音源播放结束事件,返回TRUE表示可以释放这个音源,返回FALSE依然占用这个音源 + + public: + + AudioScene(int max_source,AudioListener *al); ///<构造函数(指定最大音源数) + virtual ~AudioScene()=default; ///<析构函数 + + void SetListener(AudioListener *al){listener=al;} ///<設置收聽者 + + /** + * 设定距离场数据,无预设单位,按自行使用单位设定即可。但后期坐标等数据单位需与次相同 + * @param rd 衰减距离 + * @param md 最大距离 + */ + void SetDistance(const float &rd,const float &md) ///<设定参考距离 + { + ref_distance=rd; + max_distance=md; + } + + virtual AudioSourceItem * Create(AudioBuffer *,const Vector3f &pos,const float &gain=1); ///<创建一個音源 + virtual void Delete(AudioSourceItem *); ///<删除一个音源 + + virtual void Clear() ///<清除所有音源 + { + source_list.Clear(); + source_pool.ReleaseAll(); + } + + virtual int Update(const double &ct=0); ///<刷新,返回仍在發聲的音源數量 + };//class AudioScene +}//namespace hgl +#endif//HGL_AUDIO_SCENE_INCLUDE diff --git a/inc/hgl/audio/AudioSource.Attrib.h b/inc/hgl/audio/AudioSource.Attrib.h new file mode 100644 index 0000000..ca0cdad --- /dev/null +++ b/inc/hgl/audio/AudioSource.Attrib.h @@ -0,0 +1,67 @@ + friend class AudioPlayer; + +private: + + void InitPrivate(); + + AudioBuffer *Buffer; + +protected: + + uint index; + + bool pause; + + bool loop; + float pitch; + float gain; + float cone_gain; + Vector3f position; + Vector3f velocity; + Vector3f direction; + float ref_dist,max_dist; + uint distance_model; + float rolloff_factor; + ConeAngle angle; + + float doppler_factor; + float doppler_velocity; + +public: + + uint GetIndex()const{return index;} + + double GetCurTime(); + void SetCurTime(const double &); + + int GetState(); + float GetMinGain(); + float GetMaxGain(); + + const bool GetLoop()const{return loop;} + + const float GetPitch()const{return pitch;} + const float GetGain()const{return gain;} + const float GetConeGain()const{return cone_gain;} + + const uint GetDistanceModel()const{return distance_model;} + const float GetRolloffFactor()const{return rolloff_factor;} + + const void GetDistance(float &rd,float &md)const + { + rd=ref_dist; + md=max_dist; + } + + void GetDoppler(float &factor,float &velocity) + { + factor=doppler_factor; + velocity=doppler_velocity; + } + + virtual void SetLoop(bool); + void SetPitch(float); + void SetGain(float); + void SetConeGain(float); + void SetDistanceModel(uint); + void SetRolloffFactor(float); diff --git a/inc/hgl/audio/AudioSource.h b/inc/hgl/audio/AudioSource.h new file mode 100644 index 0000000..7c014c4 --- /dev/null +++ b/inc/hgl/audio/AudioSource.h @@ -0,0 +1,72 @@ +#ifndef HGL_AUDIO_SOURCE_INCLUDE +#define HGL_AUDIO_SOURCE_INCLUDE + +#include +#include + +namespace hgl +{ + class AudioListener; + + /** + * 音频源,指的是一个发声源,要发声必须创建至少一个发声源。而这个类就是管理发声源所用的。 + */ + class AudioSource ///音频源类 + { + #include + + public: //属性 + + Property Index; + + Property CurTime; ///<当前播放到的时间 + + Property State; ///<音源状态 + Property MinGain; ///<最小增益 + Property MaxGain; ///<最大增益 + + Property Loop; ///<是否循环播放虚拟变量 + + Property Pitch; ///<播放频率 + Property Gain; ///<音量增益幅度 + Property ConeGain; ///<音源锥增益 + + Property DistanceModel; ///<距离衰减模型(默认钳位倒数距离模型) + Property RolloffFactor; ///<音源衰减因(>=0,默认1.0) + + public: //属性方法 + + const Vector3f &GetPosition(){return position;} + const Vector3f &GetVelocity(){return velocity;} + const Vector3f &GetDirection(){return direction;} + const ConeAngle &GetAngle(){return angle;} + + void SetPosition(const Vector3f &); + void SetVelocity(const Vector3f &); + void SetDirection(const Vector3f &); + void SetDistance(const float &ref_distance,const float &max_distance); + void SetConeAngle(const ConeAngle &); + void SetDopplerFactor(const float &); ///<设置多普勒效果强度 + void SetDopplerVelocity(const float &); ///<设置多普勒速度 + + public: //方法 + + AudioSource(bool=false); ///<本类构造函数 + AudioSource(AudioBuffer *); ///<本类构造函数 + virtual ~AudioSource(); ///<本类析构函数 + + virtual bool Play(); ///<播放当前音源 + virtual bool Play(bool); ///<播放当前音源,并指定是否循环播放 + virtual void Pause(); ///<暂停播放 + virtual void Resume(); ///<继续播放 + virtual void Stop(); ///<停止播放 + virtual void Rewind(); ///<重绕播放 + + virtual bool Create(); ///<创建音源 + virtual void Close(); ///<关闭音源 + + bool Link(AudioBuffer *); ///<绑定一个音频缓冲区 + void Unlink(); ///<解除绑定 + };//class AudioSource +}//namespace hgl +#endif//HGL_AUDIO_SOURCE_INCLUDE diff --git a/inc/hgl/audio/ConeAngle.h b/inc/hgl/audio/ConeAngle.h new file mode 100644 index 0000000..437297d --- /dev/null +++ b/inc/hgl/audio/ConeAngle.h @@ -0,0 +1,22 @@ +#ifndef HGL_CONEANGLE_INCLUDE +#define HGL_CONEANGLE_INCLUDE + +namespace hgl +{ + class ConeAngle ///锥形角度数据类 + { + public: + + float inner; //内部 + float outer; //外部 + + public: + + ConeAngle() + { + inner=0; + outer=0; + } + }; +}//namespace hgl +#endif//HGL_CONEANGLE_INCLUDE diff --git a/inc/hgl/audio/Listener.h b/inc/hgl/audio/Listener.h new file mode 100644 index 0000000..09c8a51 --- /dev/null +++ b/inc/hgl/audio/Listener.h @@ -0,0 +1,47 @@ +#ifndef HGL_LISTENER_INCLUDE +#define HGL_LISTENER_INCLUDE + +#include +namespace hgl +{ + /** + * 收听者方向,用值请参考gluLookAt + */ + struct ListenerOrientation + { + Vector3f direction; + Vector3f rotation; + }; + + /** + * 这个类用于管理收听者的一些状态,可以通过它设定统一的音量,收听者的位置、方向等 + */ + class AudioListener ///收听者管理类 + { + protected: + + float gain; + + Vector3f position; + Vector3f velocity; + ListenerOrientation orientation; + + public: //属性方法 + + const float GetGain ()const{return gain;} ///<读取音量增益幅度 + const Vector3f & GetPosition ()const{return position;} ///<读取音源坐标位置 + const Vector3f & GetVelocity ()const{return velocity;} ///<读取速率 + const ListenerOrientation & GetOrientation ()const{return orientation;} ///<读取导向 + + void SetGain(float); ///<设置音量增益幅度 + void SetPosition(const Vector3f &); ///<设置音源坐标位置 + void SetVelocity(const Vector3f &); ///<设置速率 + void SetOrientation(const ListenerOrientation &); ///<设置导向 + + public: //方法 + + AudioListener(); + ~AudioListener(); + };//class AudioListener +}//namespace hgl +#endif//HGL_LISTENER_INCLUDE diff --git a/inc/hgl/audio/OpenAL.h b/inc/hgl/audio/OpenAL.h new file mode 100644 index 0000000..ed0468b --- /dev/null +++ b/inc/hgl/audio/OpenAL.h @@ -0,0 +1,108 @@ +//-------------------------------------------------------------------------------------------------- +// OpenAL ExtEdition SDK +// +// 这是一个根据标准OpenAL SDK所编写的特殊增强版本,它支持目前所有的OpenAL扩展。 +// +// 作者: 胡颖卓 +// 版本: 1.15 +// 对应OpenAL版本: 1.1 +// 对应语言: C/C++ +// 对应操作系统: Windows,MacOSX,iOS,Linux,BSD,Android +// +// 第一版编写时间: 2003年10月5日 +// 当前版完成时间: 2015年7月6日 +// +// 官方网站: http://www.hyzgame.com.cn +// OpenAL官方网站: http://www.openal.org +//-------------------------------------------------------------------------------------------------- +#ifndef OpenALH +#define OpenALH + +#ifdef __al_h_ + #error 请不要使用原始的OpenAL头文件 +#else + #define __al_h_ +#endif //__al_h_ + +#include +#include + +#include +#include +#include +#include + +namespace openal ///OpenAL EE所使用的名字空间 +{ + bool LoadOpenAL(const os_char *driver_name=nullptr); ///<加载OpenAL,参数为驱动名称 + + #define AL_DEVICE_NAME_MAX_LEN 256 ///<音频设备名称最大长度 + + struct OpenALDevice + { + char name[AL_DEVICE_NAME_MAX_LEN]; ///<设备名称 + char specifier[AL_DEVICE_NAME_MAX_LEN]; ///<设备技术名称 + int major,minor; ///<设备版本号 + }; + + bool alcGetDefaultDevice(OpenALDevice &); ///<取得缺省设备 + int alcGetDeviceList(hgl::List &); ///<取得设备列表 + + void alcSetDefaultContext(); ///<设置缺省上下文 + + const char *alGetErrorInfo(const char *,const int); ///<取得最近的错误 + + /** + * 初始化OpenAL驱动 + * @param driver_name 驱动名称 + * @return 是否成功 + */ + bool InitOpenALDriver(const os_char *driver_name=nullptr); ///<初始化OpenAL驱动 + + /** + * 初始化OpenAL设备 + * @param device 设备名称 + * @return 是否成功 + */ + bool InitOpenALDevice(const OpenALDevice *device=nullptr); + + /** + * 初始化OpenAL驱动与设备(使用本函数等同于依次调用InitOpenALDriver,InitOpenALDevice) + */ + bool InitOpenAL(const os_char *driver_name=nullptr, + const char *device_name=nullptr, + bool out_info=false, + bool enum_device=false); + + void CloseOpenAL(); ///<关闭OpenAL + + unsigned int AudioTime(ALenum,ALsizei); + double AudioDataTime(ALuint,ALenum,ALsizei); + + bool IsSupportFloatAudioData(); ///<是否支持浮点音频数据 + + // #define AL_INVERSE_DISTANCE 0xD001 //倒数距离 + // #define AL_INVERSE_DISTANCE_CLAMPED 0xD002 //钳位倒数距离 + // #define AL_LINEAR_DISTANCE 0xD003 //线性距离 + // #define AL_LINEAR_DISTANCE_CLAMPED 0xD004 //钳位线性距离 + // #define AL_EXPONENT_DISTANCE 0xD005 //指数距离 + // #define AL_EXPONENT_DISTANCE_CLAMPED 0xD006 //钳位指数距离 + bool SetDistanceModel(ALenum dm = AL_INVERSE_DISTANCE_CLAMPED); ///<设置距离模型 + + bool SetSpeedOfSound(const float ss = 1.0f); ///<设置声音速度比值 + + /** + * 根据海拔和温度设置音速 + * @param height 海拔高度 + * @param temperature 温度(摄氏度) + * @param humidity 相对湿度 + * @return 音速(米/秒) + */ + double SetSpeedOfSound(const double height=0,const double temperature=15,const double humidity=0.5); ///<根据海拔和温度设置音速 + + bool SetDopplerFactor(const float); ///<设置多普勒缩放倍数 + bool SetDopplerVelocity(const float); ///<设置多普勒速度 + //-------------------------------------------------------------------------------------------------- + #define alLastError() alGetErrorInfo(__FILE__,__LINE__) +}//namespace openal +#endif //OpenALH diff --git a/path_config.cmake b/path_config.cmake new file mode 100644 index 0000000..26ddefb --- /dev/null +++ b/path_config.cmake @@ -0,0 +1,9 @@ +macro(CMAudioSetup CMAUDIO_ROOT_PATH) + + message("CMAUDIO_ROOT_PATH: " ${CMAUDIO_ROOT_PATH}) + + set(CMAUIOD_ROOT_INCLUDE_PATH ${CMAUDIO_ROOT_PATH}/inc) + set(CMAUDIO_ROOT_SOURCE_PATH ${CMAUDIO_ROOT_PATH}/src) + + include_directories(${CMAUIOD_ROOT_INCLUDE_PATH}) +endmacro() diff --git a/src/AudioBuffer.cpp b/src/AudioBuffer.cpp new file mode 100644 index 0000000..4c6aa53 --- /dev/null +++ b/src/AudioBuffer.cpp @@ -0,0 +1,263 @@ +#include +#include +#include +#include +#include +#include +#include +#include"AudioDecode.h" + +using namespace openal; + +namespace hgl +{ + using namespace io; + + const os_char *GetAudioDecodeName(const AudioFileType aft); + + double LoadAudioData(int index,AudioFileType aft,void *memory,int memory_size,uint &Freq) + { + ALenum format; + ALvoid *data; + ALsizei size; + ALsizei freq; + ALboolean loop; + + const os_char *plugin_name=GetAudioDecodeName(aft); + + if(!plugin_name)RETURN_ERROR(0); + + AudioPlugInInterface *decode=AudioInterfaceCheck(plugin_name); + + if(!decode)RETURN_ERROR(0); + + AudioFloatPlugInInterface *decode_float=nullptr; + + if(IsSupportFloatAudioData()) + decode_float=AudioFloatInterfaceCheck(plugin_name); + + if(decode_float) + decode_float->Load((ALbyte *)memory, memory_size, &format,(float **)&data, &size, &freq, &loop); + else + decode->Load((ALbyte *)memory, memory_size, &format, &data, &size, &freq, &loop); + + alLastError(); + + alBufferData(index, format, data, size, freq); + + if(decode_float) + decode_float->Clear(format, data, size, freq); + else + decode->Clear(format, data, size, freq); + + if(alLastError())RETURN_ERROR(0); + + Freq=freq; + + return AudioDataTime(size,format,freq); + } + + void AudioBuffer::InitPrivate() + { + ok=false; + Time=0; + Size=0; + } + + AudioBuffer::AudioBuffer(void *data,int size,AudioFileType aft) + { + InitPrivate(); + Load(data,size,aft); + } + + AudioBuffer::AudioBuffer(InputStream *str,int size,AudioFileType aft) + { + InitPrivate(); + Load(str,size,aft); + } + + AudioBuffer::AudioBuffer(const os_char *filename,AudioFileType aft) + { + InitPrivate(); + if(filename)Load(filename,aft); + } + +// AudioBuffer::AudioBuffer(HAC *hac,const os_char *filename,AudioFileType aft) +// { +// InitPrivate(); +// Load(hac,filename,aft); +// } + + AudioBuffer::~AudioBuffer() + { + Clear(); + } + + /** + * 直接设置音频数据 + * @param format 音频数据格式,可以为“AL_FORMAT_MONO8、AL_FORMAT_MONO16、AL_FORMAT_STEREO16” + * @param data 数据指针 + * @param size 数据长度 + * @param freq 采样频率 + * @return 音频数据可播放时间 + */ + bool AudioBuffer::SetData(uint format, const void* data, uint size, uint freq ) + { + if(!alGenBuffers)RETURN_FALSE; + + Clear(); + alGenBuffers(1,&Index); + + if(alLastError())return(ok=false); + + alBufferData(Index, format, data, size, freq); + + if(alLastError())return(ok=false); + + Time=AudioDataTime(size,format,freq); + + Freq=freq; + + return(true); + } + + /** + * 从内存中加载一个音频文件到当前缓冲区,仅支持OGG和WAV。注:由于这个函数会一次性将音频数据载入内存,所以较长的音乐请使用CreateAudioPlayer,以免占用太多的内存。 + * @param memory 要加载数据的内存 + * @param aft 音频文件类型 + * @return 是否加载成功 + */ + bool AudioBuffer::Load(void *memory,int size,AudioFileType aft) + { + if(!alGenBuffers)RETURN_FALSE; + + Clear(); + alGenBuffers(1,&Index); + + if(alLastError())return(ok=false); + + if(aft<=aftNone||aft>=aftEnd) + { + LOG_ERROR(OS_TEXT("未知的音频文件类型!AudioFileType:")+OSString(aft)); + alDeleteBuffers(1,&Index); + RETURN_FALSE; + } + else + { + Time=LoadAudioData(Index,aft,memory,size,Freq); + Size=size; + } + + if(Time==0) + { + alDeleteBuffers(1,&Index); + RETURN_FALSE; + } + + return(ok=true); + } + + /** + * 从流中加载一个音频文件到当前缓冲区,仅支持OGG和WAV。注:由于这个函数会一次性将音频数据载入内存,所以较长的音乐请使用CreateAudioPlayer,以免占用太多的内存。 + * @param in 要加载数据的流 + * @param aft 音频文件类型 + * @return 是否加载成功 + */ + bool AudioBuffer::Load(InputStream *in,int size,AudioFileType aft) + { + if(!alGenBuffers)RETURN_FALSE; + if(!in)RETURN_FALSE; + if(size<=0)RETURN_FALSE; + + if(aft<=aftNone||aft>=aftEnd) + { + LOG_ERROR(OS_TEXT("未知的音频文件类型!AudioFileType:")+OSString(aft)); + ok=false; + } + else + { + char *memory=new char[size]; + + in->Read(memory,size); + ok=Load(memory,size,aft); + + delete[] memory; + } + + RETURN_BOOL(ok); + } + + /** + * 加载一个音频文件到当前缓冲区,仅支持OGG和WAV。注:由于这个函数会一次性将音频数据载入内存,所以较长的音乐请使用CreateAudioPlayer,以免占用太多的内存。 + * @param filename 音频文件名称 + * @param aft 音频文件类型 + * @return 加载是否成功 + */ + bool AudioBuffer::Load(const os_char *filename,AudioFileType aft) + { + if(!alGenBuffers)RETURN_FALSE; + + aft=CheckAudioFileType(filename); + + if(!aft) + { + LOG_ERROR(OS_TEXT("未知的音频文件类型!AudioFile: ")+OSString(filename)); + ok=false; + RETURN_FALSE; + } + + OpenFileInputStream fis(filename); + + RETURN_BOOL(Load(fis,fis->Available(),aft)); + } + +// /** +// * 加载一个音频文件到当前缓冲区,仅支持OGG和WAV。注:由于这个函数会一次性将音频数据载入内存,所以较长的音乐请使用CreateAudioPlayer,以免占用太多的内存。 +// * @param filename 音频文件名称 +// * @param aft 音频文件类型 +// * @return 加载是否成功 +// */ +// bool AudioBuffer::Load(HAC *hac,const os_char *filename,AudioFileType aft) +// { +// if(!alGenBuffers)RETURN_FALSE; +// +// os_char *ext; +// InputStream *stream; +// bool result; +// +// ext=strrchr(filename,u'.'); +// LowerString(ext); +// +// if(aft<=aftNone||aft>=aftEnd) +// { +// if(strcmp(ext,u".ogg")==0)aft=aftOGG;else +// if(strcmp(ext,u".wav")==0)aft=aftWAV;else +// { +// PutError(u"未知的音频文件类型!AudioFileType:%d",aft); +// RETURN_FALSE; +// } +// } +// +// stream=hac->LoadFile(filename); +// if(stream) +// { +// result=Load(stream,aft); +// delete stream; +// +// return(result); +// } +// +// RETURN_FALSE; +// } + + void AudioBuffer::Clear() + { + if(!alDeleteBuffers)return; + if(ok) + { + alDeleteBuffers(1,&Index); + ok=false; + Time=0; + } + } +}//namespace hgl diff --git a/src/AudioDecode.cpp b/src/AudioDecode.cpp new file mode 100644 index 0000000..7d505d9 --- /dev/null +++ b/src/AudioDecode.cpp @@ -0,0 +1,16 @@ +#include"AudioDecode.h" +#include + +using namespace openal; +namespace hgl +{ + /*PlugInManage( AudioInterface, //管理器名称,仅此一次,所以随便命名 + AudioPlugInInterface, //接口结构名称,来自外部 + AudioInterfaceCheck, //检查接口函数名称,要对外用 + u"Audio", //插件前缀 + 2); //当前所用版本 + */ + + PlugInManage(Audio,"Audio",2); + PlugInManage(AudioFloat,"Audio",3); +}//namespace hgl diff --git a/src/AudioDecode.h b/src/AudioDecode.h new file mode 100644 index 0000000..f060d14 --- /dev/null +++ b/src/AudioDecode.h @@ -0,0 +1,33 @@ +#ifndef HGL_AUDIO_DECODE_INCLUDE +#define HGL_AUDIO_DECODE_INCLUDE + +#include +#include + +using namespace openal; +namespace hgl +{ + struct AudioPlugInInterface + { + void (AL_APIENTRY *Load )(ALbyte *,ALsizei,ALenum *,ALvoid **,ALsizei *,ALsizei *,ALboolean *); + void (AL_APIENTRY *Clear )(ALenum,ALvoid *,ALsizei,ALsizei); + + void * (AL_APIENTRY *Open )(ALbyte *,ALsizei,ALenum *,ALsizei *,double *); + void (AL_APIENTRY *Close )(void *); + uint (AL_APIENTRY *Read )(void *,char *,uint); + void (AL_APIENTRY *Restart )(void *); + };//struct AudioPlugInInterface + + AudioPlugInInterface *AudioInterfaceCheck(const OSString &); + + struct AudioFloatPlugInInterface + { + void (AL_APIENTRY *Load )(ALbyte *,ALsizei,ALenum *,float **,ALsizei *,ALsizei *,ALboolean *); + void (AL_APIENTRY *Clear )(ALenum,ALvoid *,ALsizei,ALsizei); + + uint (AL_APIENTRY *Read )(void *,float *,uint); + };//struct AudioPlugInInterface + + AudioFloatPlugInInterface *AudioFloatInterfaceCheck(const OSString &); +}//namespace hgl +#endif//HGL_AUDIO_DECODE_INCLUDE diff --git a/src/AudioFileType.cpp b/src/AudioFileType.cpp new file mode 100644 index 0000000..645d7fd --- /dev/null +++ b/src/AudioFileType.cpp @@ -0,0 +1,67 @@ +#include +#include + +namespace hgl +{ + struct AudioFormatExt + { + os_char name[8]; + AudioFileType type; + };//struct AudioFormatExt + + const AudioFormatExt audio_format_ext_name[]= + { + {OS_TEXT("wav"), aftWAV }, + {OS_TEXT("ogg"), aftVorbis }, + {OS_TEXT("opus"), aftOpus }, + {OS_TEXT(""), aftNone } + }; + + AudioFileType CheckAudioExtName(const os_char *ext_name) + { + auto *afp=audio_format_ext_name; + + while(afp->type) + { + if(hgl::strcmp(ext_name,afp->name)==0) + return(afp->type); + + ++afp; + } + + return(aftNone); + } + + AudioFileType CheckAudioFileType(const os_char *filename) + { + const os_char *ext; + os_char extname[16]; + + ext=hgl::strrchr(filename,hgl::strlen(filename),'.'); + + if(!ext) + return(aftNone); + + ++ext; + + hgl::strcpy(extname,16,ext); + hgl::tolower(extname); + + return CheckAudioExtName(extname); + } + + const os_char audio_decode_name[aftEnd][32]= + { + OS_TEXT(""), + OS_TEXT("Wav"), + OS_TEXT("Vorbis"), + OS_TEXT("Opus") + }; + + const os_char *GetAudioDecodeName(const AudioFileType aft) + { + if(aft<=aftNone||aft>=aftEnd)return(nullptr); + + return audio_decode_name[aft]; + } +}//namespace hgl diff --git a/src/AudioManage.cpp b/src/AudioManage.cpp new file mode 100644 index 0000000..735c066 --- /dev/null +++ b/src/AudioManage.cpp @@ -0,0 +1,85 @@ +#include +#include +#include +#include + +namespace hgl +{ + AudioManage::AudioItem::AudioItem() + { + source=new AudioSource; + buffer=nullptr; + } + + AudioManage::AudioItem::~AudioItem() + { + source->Unlink(); + + delete source; + + if(buffer) + delete buffer; + } + + bool AudioManage::AudioItem::Check() + { + if(!buffer)return(true); + + if(source->State==AL_PLAYING)return(false); + + source->Unlink(); + + delete source; //这么做的原因是有些声卡上一个音源上播放的数据格式必须一致,否则新格式的数据会发不出来 + source=new AudioSource; + + delete buffer; + buffer=nullptr; + + return(true); + } + + void AudioManage::AudioItem::Play(const os_char *filename,float gain) + { + if(buffer) + { //实质上绝对不可能到这一段 + source->Unlink(); + delete buffer; + } + + buffer=new AudioBuffer(filename); + + source->Link(buffer); + source->Gain=gain; + source->Play(false); + } +}//namespace hgl + +namespace hgl +{ + AudioManage::AudioManage(int count) + { + Items.PreMalloc(count); + } + + AudioManage::~AudioManage() + { + } + + bool AudioManage::Play(const os_char *filename,float gain) + { + int n=Items.GetCount(); + + while(n--) + { + AudioItem *item=Items[n]; + + if(item->Check()) + { + item->Play(filename,gain); + return(true); + } + } + + return(false); + } +}//namespace hgl diff --git a/src/AudioPlayer.cpp b/src/AudioPlayer.cpp new file mode 100644 index 0000000..e7a6401 --- /dev/null +++ b/src/AudioPlayer.cpp @@ -0,0 +1,561 @@ +#include +#include +#include +#include +#include +#include"AudioDecode.h" + +namespace hgl +{ + const os_char *GetAudioDecodeName(const AudioFileType aft); + + void AudioPlayer::InitPrivate() + { + if(!alGenSources) + { + LOG_ERROR(OS_TEXT("OpenAL/EE 还未初始化!")); + return; + } + + auto_gain.open=false; + + audio_ptr=nullptr; + + audio_data=nullptr; + audio_data_size=0; + + audio_buffer=nullptr; + audio_buffer_size=0; + + decode=nullptr; + + ps=psNone; + + { + hglSetPropertyRead( Index, this,AudioPlayer::GetIndex ); + hglSetPropertyRead( Time, this,AudioPlayer::GetTime ); + + hglSetPropertyRead( State, this,AudioPlayer::GetPlayState ); + hglSetPropertyRead( SourceState, this,AudioPlayer::GetSourceState); + hglSetPropertyRead( MinGain, this,AudioPlayer::GetMinGain ); + hglSetPropertyRead( MaxGain, this,AudioPlayer::GetMaxGain ); + + hglSetProperty( Loop, this,AudioPlayer::GetLoop, AudioPlayer::SetLoop ); + + hglSetProperty( Pitch, this,AudioPlayer::GetPitch, AudioPlayer::SetPitch ); + hglSetProperty( Gain, this,AudioPlayer::GetGain, AudioPlayer::SetGain ); + hglSetProperty( ConeGain, this,AudioPlayer::GetConeGain, AudioPlayer::SetConeGain ); + + hglSetProperty( RolloffFactor, this,AudioPlayer::GetRolloffFactor, AudioPlayer::SetRolloffFactor ); + } + + if(!audiosource.Create())return; + + audiosource.Loop=false; + + source=audiosource.index; + + alGenBuffers(3,buffer); + } + + AudioPlayer::AudioPlayer() + { + InitPrivate(); + } + + AudioPlayer::AudioPlayer(const os_char *filename,AudioFileType aft) + { + InitPrivate(); + + if(filename) + Load(filename,aft); + } + + AudioPlayer::AudioPlayer(InputStream *stream,int size,AudioFileType aft) + { + InitPrivate(); + + Load(stream,size,aft); + } + +// AudioPlayer::AudioPlayer(HAC *hac,const os_char *filename,AudioFileType aft) +// { +// InitPrivate(); +// +// Load(hac,filename,aft); +// } + + AudioPlayer::~AudioPlayer() + { + if(!audio_data)return; + + Clear(); + + alDeleteBuffers(3,buffer); + + SAFE_CLEAR_ARRAY(audio_buffer); + } + + bool AudioPlayer::Load(AudioFileType aft) + { + const os_char *plugin_name=GetAudioDecodeName(aft); + + if(!plugin_name)return(false); + + decode=AudioInterfaceCheck(plugin_name); + + if(decode) + { + audio_ptr=decode->Open(audio_data,audio_data_size,&format,&rate,&time); + + audio_buffer_size=(AudioTime(format,rate)+9)/10; // 1/10 秒 + + if(audio_buffer) + delete[] audio_buffer; + + audio_buffer=new char[audio_buffer_size]; + + wait_time=0.1; + + if(wait_time>time/3.0f) + wait_time=time/10.0f; + + return(true); + } + else return(false); + } + + /** + * 从流中加载音频数据,仅支持OGG + * @param stream 要加载数据的流 + * @param size 音频数据长度 + * @param aft 音频文件类型 + * @return 是否加载成功 + */ + bool AudioPlayer::Load(InputStream *stream,int size,AudioFileType aft) + { + if(!alGenBuffers)return(false); + if(!stream)return(false); + if(size<=0)return(false); + + Clear(); + + if(aft<=aftNone||aft>=aftEnd) + { + LOG_ERROR(OS_TEXT("未支持的音频文件类型!AudioFileType: ")+OSString(aft)); + + return(false); + } + else + { + audio_data=new ALbyte[size]; + + stream->Read(audio_data,size); + + audio_data_size=size; + return Load(aft); + } + } + + /** + * 从文件中加载一段音频数据 + * @param filename 音频文件名称 + * @param aft 音频文件类型 + * @return 是否加载成功 + */ + bool AudioPlayer::Load(const os_char *filename,AudioFileType aft) + { + if(!alGenBuffers)return(false); + if(!filename||!(*filename))return(false); + + if(aft<=aftNone||aft>=aftEnd) + aft=CheckAudioFileType(filename); + + if(aft<=aftNone||aft>=aftEnd) + { + LOG_ERROR(OS_TEXT("未知的音频文件类型!AudioFile: ")+OSString(filename)); + return(false); + } + + OpenFileInputStream fis(filename); + + return(Load(fis,fis->Available(),aft)); + } + +// /** +// * 从文件中加载一段音频数据 +// * @param hac HAC包指针 +// * @param filename 音频文件名称 +// * @param aft 音频文件类型 +// * @return 是否加载成功 +// */ +// bool AudioPlayer::Load(HAC *hac,const os_char *filename,AudioFileType aft) +// { +// if(!alGenBuffers)return(false); +// +// os_char *ext; +// Stream *stream; +// bool result; +// +// ext=strrchr(filename,u'.'); +// +// LowerString(ext); +// +// if(aft<=aftNone||aft>=aftEnd) +// { +// if(strcmp(ext,u".ogg")==0)aft=aftOGG;else +// { +// PutError(u"未支持的音频文件类型!AudioFileType:%d",aft); +// return(false); +// } +// } +// +// stream=hac->LoadFile(filename); +// +// if(stream) +// { +// result=Load(stream,aft); +// +// delete stream; +// +// return(result); +// } +// +// return(false); +// } + + void AudioPlayer::Clear() + { + Stop(); + + if(decode&&audio_ptr) + decode->Close(audio_ptr); + + SAFE_CLEAR_ARRAY(audio_data); + SAFE_CLEAR_ARRAY(audio_buffer); + + audio_ptr=nullptr; + + time=0; + } + + bool AudioPlayer::GetLoop() + { + lock.Lock(); + bool rv=loop; + lock.Unlock(); + + return(rv); + } + + void AudioPlayer::SetLoop(bool val) + { + lock.Lock(); + loop=val; + lock.Unlock(); + } + + bool AudioPlayer::ReadData(ALuint n) + { + uint size; + + size=decode->Read(audio_ptr,audio_buffer,audio_buffer_size); + + if(size) + { + alBufferData(n,format,audio_buffer,size,rate); + + if(alLastError())return(false); + + return(true); + } + + return(false); + } + + bool AudioPlayer::Playback() + { + if(!audio_data)return(false); + + alSourceStop(source); + ClearBuffer(); + decode->Restart(audio_ptr); + + int count=0; + + audio_buffer_count=0; + + if(ReadData(buffer[0])) + { + count++; + + if(ReadData(buffer[1])) //以免有些音效太短,在这里直接失败 + count++; + + if(ReadData(buffer[2])) //以免有些音效太短,在这里直接失败 + count++; + + alSourceQueueBuffers(source,count,buffer); + alSourcePlay(source); + start_time=GetDoubleTime(); + + ps=psPlay; + return(true); + } + else + { + ps=psExit; + + return(false); + } + } + + /** + * 开始播放 + * @param _loop 是否循环播放 + */ + void AudioPlayer::Play(bool _loop) + { + if(!audio_data)return; + + lock.Lock(); + + loop=_loop; + + if(ps==psNone||ps==psPause) //未启动线程 + Start(); + + Playback(); //Execute执行有检测Lock,所以不必担心该操作会引起线程冲突 + + lock.Unlock(); + } + + /** + * 停止播放 + */ + void AudioPlayer::Stop() + { + if(!audio_data)return; + + bool thread_is_live=true; + + lock.Lock(); + + if(Thread::IsLive()) + ps=psExit; + else + thread_is_live=false; + + lock.Unlock(); + + if(thread_is_live) + Thread::WaitExit(); + + ps=psNone; + } + + /** + * 暂停播放 + */ + void AudioPlayer::Pause() + { + if(!audio_data)return; + + lock.Lock(); + + if(ps==psPlay) + ps=psPause; + + lock.Unlock(); + } + + /** + * 继续播放 + */ + void AudioPlayer::Resume() + { + if(!audio_data)return; + + lock.Lock(); + + if(ps==psPause) + { + ps=psPlay; + + Thread::Start(); + } + + lock.Unlock(); + } + + bool AudioPlayer::UpdateBuffer() + { + int processed=0; + bool active=true; + + alGetSourcei(source,AL_BUFFERS_PROCESSED,&processed); //取得处理结束的缓冲区数量 + + if(processed<=0)return(true); + + const double cur_time=GetDoubleTime(); + + if(cur_time-start_timetime-fade_out_time) //淡出时间 + { + audiosource.SetGain(((time-(cur_time-start_time))/fade_out_time)*gain); + } + + if(auto_gain.open) + { + if(cur_time>=auto_gain.end.time) + { + auto_gain.open=false; + + Gain=auto_gain.end.gain; + + if(auto_gain.end.gain<=0) + ps=psExit; + } + else + { + Gain=auto_gain.start.gain+auto_gain.gap*((cur_time-auto_gain.start.time)/auto_gain.time); + } + } + + while(processed--) + { + ALuint buffer; + + audio_buffer_count+=audio_buffer_size; + + alSourceUnqueueBuffers(source,1,&buffer); //解除一个已处理完成的缓冲区 + alLastError(); + + active=ReadData(buffer); //解码数据到这个缓冲区 + + if(active) + { + alSourceQueueBuffers(source,1,&buffer); //重新将这个缓冲区加入队列 + alLastError(); + } + else + return(false); + } + + return(true); + } + + void AudioPlayer::ClearBuffer() + { + int queued; + ALuint buffer; + + alGetSourcei(source, AL_BUFFERS_QUEUED, &queued); + + while(queued--) + alSourceUnqueueBuffers(source, 1, &buffer); + } + + bool AudioPlayer::Execute() + { + if(!audio_data)return(false); + + while(true) + { + lock.Lock(); + + if(ps==psPlay) //被要求播放 + { + if(!UpdateBuffer()) + { + if(loop) //被要求循环播放 + { + if(SourceState!=AL_STOPPED) //等它放完 + Playback(); + } + else + { + //退出 + lock.Unlock(); + + ps=psNone; + return(false); + } + } + else + { + if(SourceState!=AL_PLAYING) + alSourcePlay(source); + } + } + else + if(ps==psPause) //被要求暂停 + { + alSourcePause(source); + + lock.Unlock(); + return(false); + } + else + if(ps==psExit) //被要求暂停或退出 + { + alSourceStop(source); + alSourcei(source,AL_BUFFER,0); + ClearBuffer(); + + lock.Unlock(); + return(false); + } + + lock.Unlock(); + + WaitTime(wait_time); //以让线程空出CPU时间片 + } + } + + double AudioPlayer::GetPlayTime() + { + if(!audio_data)return(0); + + uint base=audio_buffer_count; + int off; + + lock.Lock(); + + alGetSourcei(source,AL_BYTE_OFFSET,&off); + + lock.Unlock(); + + return AudioDataTime(base+off,format,rate); + } + + /** + * 自动调整增益 + */ + void AudioPlayer::AutoGain(float target_gain,double adjust_time) + { + if(!audio_data)return; + + lock.Lock(); + auto_gain.start.gain=Gain; + auto_gain.start.time=GetDoubleTime(); + auto_gain.end.gain=target_gain; + auto_gain.end.time=auto_gain.start.time+adjust_time; + + auto_gain.time=adjust_time; + auto_gain.gap=target_gain-auto_gain.start.gain; + + auto_gain.open=true; + lock.Unlock(); + } + + void AudioPlayer::SetFadeTime(double in,double out) + { + fade_in_time=in; + fade_out_time=out; + } +}//namespace hgl diff --git a/src/AudioScene.cpp b/src/AudioScene.cpp new file mode 100644 index 0000000..b895f69 --- /dev/null +++ b/src/AudioScene.cpp @@ -0,0 +1,309 @@ +#include +#include +#include +#include +#include +namespace hgl +{ + /** + * 計算指定音源相對收聽者的音量 + */ + const double GetGain(AudioListener *l,AudioSourceItem *s) + { + if(!l||!s)return(0); + + if(s->gain<=0)return(0); //本身音量就是0 + + float distance; + + const Vector3f & lpos=l->GetPosition(); + + distance=length(lpos,s->cur_pos); + + if(s->distance_model==AL_INVERSE_DISTANCE_CLAMPED||s->distance_model==AL_INVERSE_DISTANCE) + { + if(s->distance_model==AL_INVERSE_DISTANCE_CLAMPED) + if(distance<=s->ref_distance) + return 1; + + distance = hgl_max(distance,s->ref_distance); + distance = hgl_min(distance,s->max_distance); + + return s->ref_distance/(s->ref_distance+s->rolloff_factor*(distance-s->ref_distance)); + } + else + if(s->distance_model==AL_LINEAR_DISTANCE_CLAMPED) + { + distance = hgl_max(distance,s->ref_distance); + distance = hgl_min(distance,s->max_distance); + + return (1-s->rolloff_factor*(distance-s->ref_distance)/(s->max_distance-s->ref_distance)); + } + else + if(s->distance_model==AL_LINEAR_DISTANCE) + { + distance = hgl_min(distance,s->max_distance); + return (1-s->rolloff_factor*(distance-s->ref_distance)/(s->max_distance-s->ref_distance)); + } + else + if(s->distance_model==AL_EXPONENT_DISTANCE) + { + return pow(distance/s->ref_distance,-s->rolloff_factor); + } + else + if(s->distance_model==AL_EXPONENT_DISTANCE_CLAMPED) + { + distance = hgl_max(distance,s->ref_distance); + distance = hgl_min(distance,s->max_distance); + + return pow(distance/s->ref_distance,-s->rolloff_factor); + } + else + return 1; + } + + /** + * 音频场景管理类构造函数 + * @param max_source 最大音源数量 + * @param al 收的者 + */ + AudioScene::AudioScene(int max_source,AudioListener *al) + { + source_pool.PreMalloc(max_source); + + listener=al; + + ref_distance=1; + max_distance=10000; + } + + AudioSourceItem *AudioScene::Create(AudioBuffer *buf,const Vector3f &pos,const float &gain) + { + if(!buf) + return(nullptr); + + AudioSourceItem *asi=new AudioSourceItem; + + asi->buffer=buf; + + asi->loop=false; + + asi->gain=gain; + + asi->distance_model=AL_INVERSE_DISTANCE_CLAMPED; + asi->rolloff_factor=1; + asi->ref_distance=ref_distance; + asi->max_distance=max_distance; + + asi->start_play_time=0; + asi->is_play=false; + + asi->last_pos=pos; + asi->cur_pos=pos; + + asi->last_time=asi->cur_time=0; + asi->move_speed=0; + + asi->last_gain=0; + + asi->source=nullptr; + + return asi; + } + + void AudioScene::Delete(AudioSourceItem *asi) + { + if(!asi)return; + + ToMute(asi); + + source_list.Delete(asi); + } + + bool AudioScene::ToMute(AudioSourceItem *asi) + { + if(!asi)return(false); + if(!asi->source)return(false); + + OnToMute(asi); + + asi->source->Stop(); + asi->source->Unlink(); + source_pool.Release(asi->source); + + asi->source=nullptr; + + return(true); + } + + bool AudioScene::ToHear(AudioSourceItem *asi) + { + if(!asi)return(false); + if(!asi->buffer)return(false); + + if(asi->start_play_time>cur_time) //还没到起播时间 + return(false); + + double time_off=0; + + if(asi->start_play_time>0 + &&asi->start_play_timestart_play_time; + + if(time_off>=asi->buffer->Time) //大于整个音频的时间 + { + if(!asi->loop) //无需循环 + { + asi->is_play=false; //不用放了 + return(false); + } + else //循环播放的 + { + const int count=int(time_off/asi->buffer->Time); //计算超了几次并取整 + + time_off-=asi->buffer->Time*count; //计算单次的偏移时间 + } + } + } + + if(!asi->source) + { + asi->source=source_pool.Acquire(); + + if(!asi->source)return(false); + } + + asi->source->Link(asi->buffer); + + asi->source->Gain=asi->gain; + asi->source->DistanceModel=asi->distance_model; + asi->source->RolloffFactor=asi->rolloff_factor; + asi->source->SetDistance(asi->ref_distance,asi->max_distance); + asi->source->SetPosition(asi->cur_pos); + asi->source->SetConeAngle(asi->cone_angle); + asi->source->SetVelocity(asi->velocity); + asi->source->SetDirection(asi->direction); + asi->source->SetDopplerFactor(asi->doppler_factor); + asi->source->SetDopplerVelocity(0); + + asi->source->CurTime=time_off; + asi->source->Play(asi->loop); + + OnToHear(asi); + + return(true); + } + + bool AudioScene::UpdateSource(AudioSourceItem *asi) + { + if(!asi)return(false); + if(!asi->source)return(false); + + if(asi->source->State==AL_STOPPED) //停播状态 + { + if(!asi->loop) //不是循环播放 + { + if(OnStopped(asi)) + ToMute(asi); + + return(true); + } + else + { + asi->source->Play(); //继续播放 + } + } + + if(asi->doppler_factor>0) //需要多普勒效果 + { +// double shift=0; + + if(asi->last_pos!=asi->cur_pos) //坐标不一样了 + { + asi->move_speed=length(asi->last_pos,asi->cur_pos)/(asi->cur_time-asi->last_time); + //根据离收听者的距离和速度进行多普勒调整 + +// shift = DOPPLER_FACTOR * freq * (DOPPLER_VELOCITY - l.velocity) / (DOPPLER_VELOCITY + s.velocity) + + asi->source->SetDopplerVelocity(asi->move_speed); //由于计算未理清,暂用move_speed代替 + } + + if(cur_time>asi->cur_time) //更新时间和坐标 + { + asi->last_pos=asi->cur_pos; + asi->last_time=asi->cur_time; + } + } + + return(true); + } + + /** + * 刷新處理 + * @param ct 当前时间 + * @return 收聽者仍可聽到的音源數量 + * @return -1 出錯 + */ + int AudioScene::Update(const double &ct) + { + if(!listener)return(-1); + + const int count=source_list.GetCount(); + + if(count<=0)return 0; + + if(ct!=0) + cur_time=ct; + else + cur_time=GetDoubleTime(); + + float new_gain; + int hear_count=0; + + AudioSourceItem **ptr=source_list.GetData(); + + for(int i=0;iis_play) + { + if((*ptr)->source) //还有音源 + ToMute(*ptr); + + continue; //不需要放的音源 + } + + new_gain=OnCheckGain(*ptr); + + if(new_gain<=0) //听不到声音了 + { + if((*ptr)->last_gain>0) //之前可以听到 + ToMute(*ptr); + else + OnContinuedMute(*ptr); //之前就听不到 + } + else + { + if((*ptr)->last_gain<=0) + { + if(!ToHear(*ptr)) //之前没声 + new_gain=0; //没有足够可用音源、或是已经放完了,所以还是听不到 + } + else + { + UpdateSource(*ptr); //刷新音源处理 + OnContinuedHear(*ptr); //之前就有声音 + } + } + + (*ptr)->last_gain=new_gain; + + if(new_gain>0) + ++hear_count; + + ++ptr; + } + + return hear_count; + } +}//namespace hgl diff --git a/src/AudioSource.cpp b/src/AudioSource.cpp new file mode 100644 index 0000000..568d7e7 --- /dev/null +++ b/src/AudioSource.cpp @@ -0,0 +1,439 @@ +#include +#include +#include + +using namespace openal; +namespace hgl +{ + inline void alSourcefv(openal::ALuint sid, openal::ALenum param, const Vector3f &v3f) + { + openal::alSourcefv(sid, param, (const openal::ALfloat *)&v3f); + } + + inline void alGetSourcefv(openal::ALuint sid, openal::ALenum param, Vector3f &v3f) + { + openal::alGetSourcefv(sid, param, (openal::ALfloat *)&v3f); + } + + const unsigned int InvalidIndex=0xFFFFFFFF; + + void AudioSource::InitPrivate() + { + index=InvalidIndex; + Buffer=nullptr; + + hglSetPropertyRead( Index, this,AudioSource::GetIndex); + + hglSetProperty( CurTime, this,AudioSource::GetCurTime, AudioSource::SetCurTime); + + hglSetPropertyRead( State, this,AudioSource::GetState); + hglSetPropertyRead( MinGain, this,AudioSource::GetMinGain); + hglSetPropertyRead( MaxGain, this,AudioSource::GetMaxGain); + + hglSetProperty( Loop, this,AudioSource::GetLoop, AudioSource::SetLoop); + + hglSetProperty( Pitch, this,AudioSource::GetPitch, AudioSource::SetPitch); + hglSetProperty( Gain, this,AudioSource::GetGain, AudioSource::SetGain); + hglSetProperty( ConeGain, this,AudioSource::GetConeGain, AudioSource::SetConeGain); + + hglSetProperty( DistanceModel, this,AudioSource::GetDistanceModel, AudioSource::SetDistanceModel); + hglSetProperty( RolloffFactor, this,AudioSource::GetRolloffFactor, AudioSource::SetRolloffFactor); + } + + /** + * 音频发声源基类 + * @param create 是否创建发声源 + */ + AudioSource::AudioSource(bool create) + { + InitPrivate(); + + if(create)Create(); + } + + /** + * 音频发声源基类 + * @param ab 音频缓冲区 + */ + AudioSource::AudioSource(AudioBuffer *ab) + { + InitPrivate(); + + Create(); + + Link(ab); + } + + AudioSource::~AudioSource() + { + Close(); + } + + double AudioSource::GetCurTime() + { + if(!alGetSourcei)return(0); + if(index==InvalidIndex)return(0); + + float offset; + + alGetSourcef(index,AL_SEC_OFFSET,&offset); + + return offset; + } + + void AudioSource::SetCurTime(const double &ct) + { + if(!alGetSourcef)return; + if(index==InvalidIndex)return; + + alSourcef(index,AL_SEC_OFFSET,ct); + } + + int AudioSource::GetState() + { + if(!alGetSourcei)return(0); + if(index==InvalidIndex)return(AL_NONE); + + int state; + + alGetSourcei(index,AL_SOURCE_STATE,&state); + + return(state); + } + + float AudioSource::GetMinGain() + { + if(!alGetSourcef)return(0); + if(index==InvalidIndex)return(0); + + float min; + + alGetSourcef(index,AL_MIN_GAIN,&min); + + return(min); + } + + float AudioSource::GetMaxGain() + { + if(!alGetSourcef)return(0); + if(index==InvalidIndex)return(0); + + float max; + + alGetSourcef(index,AL_MIN_GAIN,&max); + + return(max); + } + + void AudioSource::SetLoop(bool _loop) + { + if(!alSourcei)return; + if(index==InvalidIndex)return; + + loop=_loop; + alSourcei(index,AL_LOOPING,loop); + } + + void AudioSource::SetPitch(float _pitch) + { + if(!alSourcef)return; + if(index==InvalidIndex)return; + + pitch=_pitch; + alSourcef(index,AL_PITCH,pitch); + } + + void AudioSource::SetGain(float _gain) + { + if(!alSourcef)return; + if(index==InvalidIndex)return; + + gain=_gain; + alSourcef(index,AL_GAIN,gain); + } + + void AudioSource::SetConeGain(float _gain) + { + if(!alSourcef)return; + if(index==InvalidIndex)return; + + cone_gain=_gain; + alSourcef(index,AL_CONE_OUTER_GAIN,cone_gain); + } + + void AudioSource::SetPosition(const Vector3f &pos) + { + if(!openal::alSourcefv)return; + if(index==InvalidIndex)return; + + position=pos; + alSourcefv(index,AL_POSITION,position); + } + + void AudioSource::SetVelocity(const Vector3f &vel) + { + if(!openal::alSourcefv)return; + if(index==InvalidIndex)return; + + velocity=vel; + alSourcefv(index,AL_VELOCITY,velocity); + } + + void AudioSource::SetDirection(const Vector3f &dir) + { + if(!openal::alSourcefv)return; + if(index==InvalidIndex)return; + + direction=dir; + alSourcefv(index,AL_DIRECTION,direction); + } + + void AudioSource::SetDistance(const float &ref_distance,const float &max_distance) + { + if(!alSourcef)return; + if(index==InvalidIndex)return; + + ref_dist=ref_distance; + max_dist=max_distance; + alSourcef(index,AL_REFERENCE_DISTANCE,ref_dist); + alSourcef(index,AL_MAX_DISTANCE,max_dist); + } + + void AudioSource::SetDistanceModel(uint dm) + { + if(!alSourcef)return; + if(index==InvalidIndex)return; + if(!alDistanceModel)return; + +// #define AL_INVERSE_DISTANCE 0xD001 //倒数距离 +// #define AL_INVERSE_DISTANCE_CLAMPED 0xD002 //钳位倒数距离 +// #define AL_LINEAR_DISTANCE 0xD003 //线性距离 +// #define AL_LINEAR_DISTANCE_CLAMPED 0xD004 //钳位线性距离 +// #define AL_EXPONENT_DISTANCE 0xD005 //指数距离 +// #define AL_EXPONENT_DISTANCE_CLAMPED 0xD006 //钳位指数距离 + if(dmAL_EXPONENT_DISTANCE_CLAMPED)return; + + distance_model=dm; + alDistanceModel(distance_model); + } + + void AudioSource::SetRolloffFactor(float rf) + { + if(!alSourcef)return; + if(index==InvalidIndex)return; + + rolloff_factor=rf; + alSourcef(index,AL_ROLLOFF_FACTOR,rolloff_factor); + } + + void AudioSource::SetConeAngle(const ConeAngle &ca) + { + if(!alSourcef)return; + if(index==InvalidIndex)return; + + angle=ca; + alSourcef(index,AL_CONE_INNER_ANGLE,ca.inner); + alSourcef(index,AL_CONE_OUTER_ANGLE,ca.outer); + } + + void AudioSource::SetDopplerFactor(const float &factor) + { + if(!alSourcef)return; + if(index==InvalidIndex)return; + + doppler_factor=factor; + + alDopplerFactor(doppler_factor); + } + + void AudioSource::SetDopplerVelocity(const float &velocity) + { + if(!alSourcef)return; + if(index==InvalidIndex)return; + + doppler_velocity=velocity; + + alDopplerVelocity(doppler_velocity); + } + + /** + * 播放当前音源 + */ + bool AudioSource::Play() + { + if(!alSourcePlay)return(false); + if(index==InvalidIndex)return(false); + if(!Buffer + ||Buffer->Time<=0)return(false); + + if(State==AL_PLAYING) + alSourceStop(index); + + alSourcePlay(index); + + pause=false; + + return(!alLastError()); + } + + /** + * 播放当前音源,并指定是否循环播放 + * @param _loop 是否循环播放 + */ + bool AudioSource::Play(bool _loop) + { + if(!alSourcePlay)return(false); + if(index==InvalidIndex)return(false); + if(!Buffer + ||Buffer->Time<=0)return(false); + + if(State==AL_PLAYING) + alSourceStop(index); + + alSourcePlay(index); + alSourcei(index,AL_LOOPING,loop=_loop); + + pause=false; + + return(!alLastError()); + } + + void AudioSource::Pause() + { + if(!alSourcePlay)return; + if(!alSourcePause)return; + + if(index==InvalidIndex)return; + + if(!pause) + { + alSourcePause(index); + pause=true; + } + } + + void AudioSource::Resume() + { + if(!alSourcePlay)return; + if(!alSourcePause)return; + + if(index==InvalidIndex)return; + + if(pause) + { + alSourcePlay(index); + pause=false; + } + } + + void AudioSource::Stop() + { + if(!alSourceStop)return; + if(index==InvalidIndex)return; + + alSourceStop(index); + } + + void AudioSource::Rewind() + { + if(!alSourceRewind)return; + if(index==InvalidIndex)return; + + alSourceRewind(index); + } + + /** + * 创建一个发声源 + * @return 发声源是否创建成功 + */ + bool AudioSource::Create() + { + if(!alGenSources) + { + LOG_INFO(OS_TEXT("OpenAL/EE 还未初始化!")); + return(false); + } + + if(index!=InvalidIndex)Close(); + + alGetError(); //清空错误 + + alGenSources(1,&index); + + if(alLastError()) + { + index=InvalidIndex; + + LOG_INFO(OS_TEXT("无法再创建音频播放源了!")); + return(false); + } + + loop=false; + + alGetSourcef (index,AL_PITCH, &pitch); + alGetSourcef (index,AL_GAIN, &gain); + alGetSourcef (index,AL_CONE_OUTER_GAIN, &cone_gain); + alGetSourcefv (index,AL_POSITION, position); + alGetSourcefv (index,AL_VELOCITY, velocity); + alGetSourcefv (index,AL_DIRECTION, direction); + alGetSourcef (index,AL_MAX_DISTANCE, &max_dist); + alGetSourcef (index,AL_REFERENCE_DISTANCE, &ref_dist); + alGetSourcef (index,AL_ROLLOFF_FACTOR, &rolloff_factor); + alGetSourcef (index,AL_CONE_INNER_ANGLE, &angle.inner); + alGetSourcef (index,AL_CONE_OUTER_ANGLE, &angle.outer); + + return(true); + } + + /** + * 关闭发声源 + */ + void AudioSource::Close() + { + if(!alDeleteSources)return; + if(index==InvalidIndex)return; + + alSourceStop(index); + alSourcei(index,AL_BUFFER,0); + alDeleteSources(1,&index); + } + + /** + * 绑定一个音频数据缓冲区到当前发声源上 + * @param buf 要绑定的音频数据缓冲区 + * @return 是否绑定成功 + */ + bool AudioSource::Link(AudioBuffer *buf) + { + if(!buf)return(false); + if(!buf->Time)return(false); + if(!alSourcei)return(false); + if(index==InvalidIndex) + { + if(!Create())return(false); + } + else + Stop(); + + + alSourcei(index,AL_BUFFER,buf->Index); + + Buffer=buf; + + return(!alLastError()); + } + + /** + * 解决绑定在当前音频源上的数据缓冲区 + */ + void AudioSource::Unlink() + { + if(!alSourcei)return; + if(index==InvalidIndex)return; + + Buffer=nullptr; + + alSourcei(index,AL_BUFFER,0); + } +}//namespace hgl diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..3fd5419 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,36 @@ +file(GLOB CM_OPENAL_HEADER ${CMAUDIO_ROOT_INCLUDE_PATH}/hgl/al/*.*) +file(GLOB CM_AUDIO_HEADER ${CMAUDIO_ROOT_INCLUDE_PATH}/hgl/audio/*.*) + +set(CM_OPENAL_SOURCE al.cpp + alc.cpp + EFX.cpp + XRAM.cpp) + +set(CM_AUDIO_SOURCE + OpenAL.cpp + AudioFileType.cpp + AudioBuffer.cpp + AudioDecode.cpp + AudioManage.cpp + AudioScene.cpp + AudioPlayer.cpp + AudioSource.cpp + Listener.cpp) + +source_group("OpenAL" FILES ${CM_OPENAL_HEADER} + ${CM_OPENAL_SOURCE}) + +source_group("Audio" FILES ${CM_AUDIO_HEADER} + ${CM_AUDIO_SOURCE}) + +add_cm_library(CMAudio "CM" ${CM_OPENAL_HEADER} + ${CM_OPENAL_SOURCE} + ${CM_AUDIO_HEADER} + ${CM_AUDIO_SOURCE}) + +#ADD_LIBRARY(CM.OpenALEE.StandAlone SHARED ${OpenALEESource} OpenALEECPort.cpp OpenALEEStandAlone.cpp ${CM_BASE_ALL_SOURCE}) + +#IF(WIN32) +# target_compile_options(CM.OpenALEE.StandAlone PRIVATE "/MT") +# target_link_libraries(CM.OpenALEE.StandAlone CM.Base.Static CM.Platform.Static) +#ENDIF(WIN32) diff --git a/src/EFX.cpp b/src/EFX.cpp new file mode 100644 index 0000000..31f0bef --- /dev/null +++ b/src/EFX.cpp @@ -0,0 +1,117 @@ +#include +#include +#include + +using namespace hgl; + +namespace openal +{ + // Imported EFX functions + + // Effect objects + LPALGENEFFECTS alGenEffects = 0; + LPALDELETEEFFECTS alDeleteEffects = 0; + LPALISEFFECT alIsEffect = 0; + LPALEFFECTI alEffecti = 0; + LPALEFFECTIV alEffectiv = 0; + LPALEFFECTF alEffectf = 0; + LPALEFFECTFV alEffectfv = 0; + LPALGETEFFECTI alGetEffecti = 0; + LPALGETEFFECTIV alGetEffectiv = 0; + LPALGETEFFECTF alGetEffectf = 0; + LPALGETEFFECTFV alGetEffectfv = 0; + + //Filter objects + LPALGENFILTERS alGenFilters = 0; + LPALDELETEFILTERS alDeleteFilters = 0; + LPALISFILTER alIsFilter = 0; + LPALFILTERI alFilteri = 0; + LPALFILTERIV alFilteriv = 0; + LPALFILTERF alFilterf = 0; + LPALFILTERFV alFilterfv = 0; + LPALGETFILTERI alGetFilteri = 0; + LPALGETFILTERIV alGetFilteriv = 0; + LPALGETFILTERF alGetFilterf = 0; + LPALGETFILTERFV alGetFilterfv = 0; + + // Auxiliary slot object + LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots = 0; + LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots = 0; + LPALISAUXILIARYEFFECTSLOT alIsAuxiliaryEffectSlot = 0; + LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti = 0; + LPALAUXILIARYEFFECTSLOTIV alAuxiliaryEffectSlotiv = 0; + LPALAUXILIARYEFFECTSLOTF alAuxiliaryEffectSlotf = 0; + LPALAUXILIARYEFFECTSLOTFV alAuxiliaryEffectSlotfv = 0; + LPALGETAUXILIARYEFFECTSLOTI alGetAuxiliaryEffectSloti = 0; + LPALGETAUXILIARYEFFECTSLOTIV alGetAuxiliaryEffectSlotiv = 0; + LPALGETAUXILIARYEFFECTSLOTF alGetAuxiliaryEffectSlotf = 0; + LPALGETAUXILIARYEFFECTSLOTFV alGetAuxiliaryEffectSlotfv = 0; +} + +namespace openal +{ + bool CheckEFX(ALCdevice_struct *AudioDevice) + { + HGL_FUNC_LOAD_LIST_BEGIN(al_efx_func_load_list) + HGL_FUNC_LOAD(alGenEffects) + HGL_FUNC_LOAD(alDeleteEffects) + HGL_FUNC_LOAD(alIsEffect) + HGL_FUNC_LOAD(alEffecti) + HGL_FUNC_LOAD(alEffectiv) + HGL_FUNC_LOAD(alEffectf) + HGL_FUNC_LOAD(alEffectfv) + HGL_FUNC_LOAD(alGetEffecti) + HGL_FUNC_LOAD(alGetEffectiv) + HGL_FUNC_LOAD(alGetEffectf) + HGL_FUNC_LOAD(alGetEffectfv) + + HGL_FUNC_LOAD(alGenFilters) + HGL_FUNC_LOAD(alDeleteFilters) + HGL_FUNC_LOAD(alIsFilter) + HGL_FUNC_LOAD(alFilteri) + HGL_FUNC_LOAD(alFilteriv) + HGL_FUNC_LOAD(alFilterf) + HGL_FUNC_LOAD(alFilterfv) + HGL_FUNC_LOAD(alGetFilteri) + HGL_FUNC_LOAD(alGetFilteriv) + HGL_FUNC_LOAD(alGetFilterf) + HGL_FUNC_LOAD(alGetFilterfv) + + HGL_FUNC_LOAD(alGenAuxiliaryEffectSlots) + HGL_FUNC_LOAD(alDeleteAuxiliaryEffectSlots) + HGL_FUNC_LOAD(alIsAuxiliaryEffectSlot) + HGL_FUNC_LOAD(alAuxiliaryEffectSloti) + HGL_FUNC_LOAD(alAuxiliaryEffectSlotiv) + HGL_FUNC_LOAD(alAuxiliaryEffectSlotf) + HGL_FUNC_LOAD(alAuxiliaryEffectSlotfv) + HGL_FUNC_LOAD(alGetAuxiliaryEffectSloti) + HGL_FUNC_LOAD(alGetAuxiliaryEffectSlotiv) + HGL_FUNC_LOAD(alGetAuxiliaryEffectSlotf) + HGL_FUNC_LOAD(alGetAuxiliaryEffectSlotfv) + HGL_FUNC_LOAD_LIST_END + + if (alcIsExtensionPresent(AudioDevice, (ALCchar*)ALC_EXT_EFX_NAME)) + { + FuncLoad *flp=al_efx_func_load_list; + + while(flp->func_pointer) + { + (*(flp->func_pointer))=alGetProcAddress(flp->func_name); + + if(!(*(flp->func_pointer))) + return(false); + + ++flp; + } + + return(true); + } + + return(false); + } + + void ClearEFX() + { +// ClearFuncLoadPointer(al_efx_func_load_list); + } +}//namespace openal diff --git a/src/Listener.cpp b/src/Listener.cpp new file mode 100644 index 0000000..cfdef54 --- /dev/null +++ b/src/Listener.cpp @@ -0,0 +1,69 @@ +#include +#include +#include + +using namespace openal; +namespace hgl +{ + inline void alGetListenerfv(ALenum param, Vector3f &v3f) + { + openal::alGetListenerfv(param, (ALfloat *)&v3f); + } + + inline void alGetListenerfv(ALenum param, ListenerOrientation &v3f) + { + openal::alGetListenerfv(param, (ALfloat *)&v3f); + } + + inline void alListenerfv(ALenum param, const Vector3f &v3f) + { + openal::alListenerfv(param, (const ALfloat *)&v3f); + } + + inline void alListenerfv(ALenum param, const ListenerOrientation &v3f) + { + openal::alListenerfv(param, (const ALfloat *)&v3f); + } + + AudioListener::AudioListener() + { + if(!alGetListenerf) + { + LOG_ERROR(OS_TEXT("OpenAL/EE 还未初始化!")); + return; + } + + alGetListenerf(AL_GAIN,&gain); + alGetListenerfv(AL_POSITION,position); + alGetListenerfv(AL_VELOCITY,velocity); + alGetListenerfv(AL_ORIENTATION,orientation); + } + + AudioListener::~AudioListener() + { + } + + void AudioListener::SetGain(float _gain) + { + gain=_gain; + alListenerf(AL_GAIN,gain); + } + + void AudioListener::SetPosition(const Vector3f &pos) + { + position=pos; + alListenerfv(AL_POSITION,position); + } + + void AudioListener::SetVelocity(const Vector3f &vel) + { + velocity=vel; + alListenerfv(AL_VELOCITY,velocity); + } + + void AudioListener::SetOrientation(const ListenerOrientation &ori) + { + memcpy(&orientation,&ori,sizeof(ListenerOrientation)); + alListenerfv(AL_ORIENTATION,orientation); + } +}//namespace hgl diff --git a/src/OpenAL.cpp b/src/OpenAL.cpp new file mode 100644 index 0000000..38f2d1b --- /dev/null +++ b/src/OpenAL.cpp @@ -0,0 +1,747 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace hgl; + +namespace openal +{ + static ALCchar AudioDeviceName[AL_DEVICE_NAME_MAX_LEN]={0}; + + static ExternalModule *AudioEM =nullptr; //OpenAL动态链接库指针 + static ALCdevice *AudioDevice =nullptr; //OpenAL设备 + static ALCcontext *AudioContext =nullptr; //OpenAL上下文 + + static UTF8StringList OpenALExt_List; + static UTF8StringList OpenALContextExt_List; + + static bool AudioFloat32 =false; //是否支持float 32数据 + static bool AudioEFX =false; //EFX是否可用 + static bool AudioXRAM =false; //X-RAM是否可用 + + bool LoadALCFunc(ExternalModule *); + bool LoadALFunc(ExternalModule *); + + bool CheckXRAM(ALCdevice_struct *); + bool CheckEFX(ALCdevice_struct *); + + void ClearAL(); + void ClearALC(); + void ClearXRAM(); + void ClearEFX(); + + void PutOpenALInfo(); + //-------------------------------------------------------------------------------------------------- + /** + * 加载OpenAL + * @return 加载OpenAL是否成功 + */ + bool LoadOpenAL(const os_char *filename) + { + const os_char oalfn[][HGL_MAX_PATH]= + { +#if HGL_OS == HGL_OS_Windows + OS_TEXT("\\OpenAL32.dll"), + OS_TEXT("\\ct_oal.dll"), + OS_TEXT("\\nvOpenAL.dll"), + OS_TEXT("\\soft_oal.dll"), + OS_TEXT("\\wrap_oal.dll"), +#elif (HGL_OS == HGL_OS_Linux)||(HGL_OS == HGL_OS_FreeBSD)||(HGL_OS == HGL_OS_NetBSD)||(HGL_OS == HGL_OS_OpenBSD) + OS_TEXT("/libopenal.so"), + OS_TEXT("/libopenal.so.1"), +#elif HGL_OS == HGL_OS_MacOS + OS_TEXT("/libopenal.dylib"), +#endif//HGL_OS == HGL_OS_Windows + OS_TEXT("\x0") + }; + + int count=0; + const os_char *pi_path=GetString(hfsPlugInPath); + os_char pifn[HGL_MAX_PATH]; + os_char dllfn[HGL_MAX_PATH]; + os_char *final_filename=nullptr; + + CloseOpenAL(); + + if(filename) + { + hgl::strcpy(dllfn,HGL_MAX_PATH,hgl::info::GetString(hgl::info::hfsOSLibraryPath).c_str()); + hgl::strcat(dllfn,HGL_MAX_PATH,HGL_DIRECTORY_SEPARATOR); + hgl::strcat(dllfn,HGL_MAX_PATH,filename,HGL_MAX_PATH); + + hgl::strcpy(pifn,HGL_MAX_PATH,pi_path); + hgl::strcat(pifn,HGL_MAX_PATH,HGL_DIRECTORY_SEPARATOR); + hgl::strcat(pifn,HGL_MAX_PATH,filename,HGL_MAX_PATH); + + if(filesystem::FileExist(filename ))final_filename=(os_char *)filename;else + if(filesystem::FileExist(dllfn ))final_filename=dllfn;else + if(filesystem::FileExist(pifn ))final_filename=pifn; + + AudioEM=LoadExternalModule(final_filename); + } + else + { + do + { + hgl::strcpy(pifn,HGL_MAX_PATH,pi_path); + hgl::strcat(pifn,HGL_MAX_PATH,oalfn[count],HGL_MAX_PATH); + + hgl::strcpy(dllfn,HGL_MAX_PATH,hgl::info::GetString(hgl::info::hfsOSLibraryPath).c_str()); + hgl::strcat(dllfn,HGL_MAX_PATH,oalfn[count],HGL_MAX_PATH); + + if(filesystem::FileExist(dllfn))final_filename=dllfn;else + if(filesystem::FileExist(pifn ))final_filename=pifn;else + continue; + + AudioEM=LoadExternalModule(final_filename); + + if(AudioEM)break; //如果加载成功 + + }while(oalfn[++count][0]); + } + + if(AudioEM) + { + LOG_INFO(OS_TEXT("加载OpenAL成功!使用动态链接库: ")+OSString(final_filename)); + + return (AL_TRUE); + } + else + { + #if HGL_OS == HGL_OS_Windows + LOG_ERROR( OS_TEXT("加载OpenAL动态链接库失败!OpenAL动态链接库可能是: OpenAL32.dll、soft_oal.dll、wrap_oal.dll、ct_oal.dll、nvOpenAL.dll\n") + OS_TEXT("软件实现的OpenAL32.DLL、wrap_oal可在http://www.openal.org上下载、soft_oal.dll可在http://kcat.strangesoft.net/openal.html下载!\n") + OS_TEXT("硬件实现的OpenAL32.DLL请到对应您声卡的厂商网站下载对应的驱动程序! 下载完成后可其放入Windows\\System32目录下或应用程序Plug-Ins目录下即可!")); + #else + LOG_ERROR( OS_TEXT("加载OpenAL动态链接库失败!")); + #endif//#if HGL_OS == HGL_OS_Windows + return (AL_FALSE); + } + } + + const char *alcGetDeviceNameList() + { + if(!alcIsExtensionPresent)return(nullptr); + + if(alcIsExtensionPresent(nullptr,"ALC_ENUMERATE_ALL_EXT")) + return (char *)alcGetString(nullptr,ALC_ALL_DEVICES_SPECIFIER); + else + if(alcIsExtensionPresent(nullptr,"ALC_ENUMERATION_EXT")) + return (char *)alcGetString(nullptr,ALC_DEVICE_SPECIFIER); + else + return(nullptr); + } + + bool alcGetDefaultDeviceName(char *name) + { + if(alcIsExtensionPresent) + { + const char *result=nullptr; + + if(alcIsExtensionPresent(nullptr,"ALC_ENUMERATE_ALL_EXT")) + result=(char *)alcGetString(nullptr,ALC_DEFAULT_ALL_DEVICES_SPECIFIER); + else + if(alcIsExtensionPresent(nullptr,"ALC_ENUMERATION_EXT")) + result=(char *)alcGetString(nullptr,ALC_DEFAULT_DEVICE_SPECIFIER); + + if(result&&(*result)) + { + hgl::strcpy(name,AL_DEVICE_NAME_MAX_LEN,result); + return(true); + } + } + + *name=0; + return(false); + } + + bool alcGetDeviceInfo(OpenALDevice &dev,const char *device_name) + { + ALCdevice *device=alcOpenDevice(device_name); + + if(!device) + return(false); + + hgl::strcpy(dev.name, AL_DEVICE_NAME_MAX_LEN,device_name); + hgl::strcpy(dev.specifier, AL_DEVICE_NAME_MAX_LEN,alcGetString(device,ALC_DEVICE_SPECIFIER)); + + alcGetIntegerv(device,ALC_MAJOR_VERSION,sizeof(int),&dev.major); + + if(dev.major) + { + alcGetIntegerv(device,ALC_MINOR_VERSION,sizeof(int),&dev.minor); + } + else + { + dev.major=1; + dev.minor=0; + } + + alcCloseDevice(device); + return(true); + } + + bool alcGetDefaultDevice(OpenALDevice &dev) + { + if(!alcGetDefaultDeviceName(dev.name)) + return(false); + + return alcGetDeviceInfo(dev,dev.name); + } + + int alcGetDeviceList(List &device_list) + { + const char *devices=alcGetDeviceNameList(); + + if(!devices) + { + LOG_INFO(OS_TEXT("取得的OpenAL设备列表为空!")); + return(-1); + } + + while(*devices) + { + OpenALDevice dev; + + if(alcGetDeviceInfo(dev,devices)) + device_list.Add(dev); + + devices+=::strlen(devices)+1; + } + + return device_list.GetCount(); + } + + void EnumOpenALDevice() + { + const char *devices=alcGetDeviceNameList(); + const char *actual_devicename; + + if(!devices) + { + LOG_INFO(OS_TEXT("取得的OpenAL设备列表为空!")); + return; + } + + while(*devices) + { + ALCdevice *device=alcOpenDevice(devices); + + if(device) + { + actual_devicename=alcGetString(device,ALC_DEVICE_SPECIFIER); + + int major=0,minor=0; + + alcGetIntegerv(device,ALC_MAJOR_VERSION,sizeof(int),&major); + + if(major) + { + alcGetIntegerv(device,ALC_MINOR_VERSION,sizeof(int),&minor); + + LOG_INFO(u8"OpenAL设备: "+UTF8String(devices)+u8" Specifier:"+UTF8String(actual_devicename)+u8",支持OpenAL特性版本: "+UTF8String::valueOf(major)+"."+UTF8String::valueOf(minor)); + } + else + { + LOG_INFO(u8"OpenAL设备: "+UTF8String(devices)+u8" Specifier:"+UTF8String(actual_devicename)+u8",不支持版本获取,按OpenAL 1.0标准执行"); + } + + alcCloseDevice(device); + } + + devices+=::strlen(devices)+1; + } + } + + void alcSetDefaultContext() + { + alcMakeContextCurrent(AudioContext); + } + + void GetOpenALExt(UTF8StringList &ext_list,const char *ext_str) + { + int len=hgl::strlen(ext_str); + + SplitToStringListBySpace(ext_list,ext_str,len); //space指所有不可打印字符 + } + + void InitOpenALExt() + { + GetOpenALExt(OpenALExt_List,alGetString(AL_EXTENSIONS)); + GetOpenALExt(OpenALContextExt_List,alcGetString(AudioDevice,ALC_EXTENSIONS)); + + if(OpenALExt_List.Find("AL_EXT_FLOAT32")!=-1) + AudioFloat32=true; + } + + /** + * 初始化OpenAL驱动 + * @param driver_name 驱动名称,如果不写则自动查找 + * @return 是否初始化成功 + */ + bool InitOpenALDriver(const os_char *driver_name) + { + if (!AudioEM) + if (!LoadOpenAL(driver_name))RETURN_FALSE; + + RETURN_BOOL(LoadALCFunc(AudioEM)); + } + + bool InitOpenALDeviceByName(const char *device_name) + { + bool default_device=false; + + if(device_name) + hgl::strcpy(AudioDeviceName,AL_DEVICE_NAME_MAX_LEN,device_name); + else + { + alcGetDefaultDeviceName(AudioDeviceName); + + if(*AudioDeviceName) + { + LOG_INFO(u8"没有指定音频设备,按缺省设备初始化,可能不是最佳选择:"+UTF8String(AudioDeviceName)); + } + else + { + LOG_INFO(OS_TEXT("没有指定音频设备,按缺省设备初始化,可能不是最佳选择!也有可能初始化失败!")); + } + + default_device=true; + } + + AudioDevice=alcOpenDevice(AudioDeviceName); + + if(AudioDevice==nullptr) + { + LOG_ERROR(u8"打开音频设备失败: "+UTF8String(AudioDeviceName)); + + if(default_device) + { + CloseOpenAL(); + return(AL_FALSE); + } + + //使用缺省设备 + { + alcGetDefaultDeviceName(AudioDeviceName); + AudioDevice=alcOpenDevice(AudioDeviceName); + + if(!AudioDevice) + { + LOG_ERROR(OS_TEXT("使用指定设备和缺省设备均无法正常初始化音频设备!")); + CloseOpenAL(); + return(AL_FALSE); + } + + LOG_INFO(OS_TEXT("指定音频设备初始化失败,改用缺省设备!")); + } + } + + LOG_INFO(U8_TEXT("打开音频设备成功: ")+UTF8String(AudioDeviceName)); + + AudioContext=alcCreateContext(AudioDevice,0); + if(AudioContext==nullptr) + { + LOG_ERROR(OS_TEXT("关联音频设备上下文失败!")); + CloseOpenAL(); + return (AL_FALSE); + } + #ifdef _DEBUG + else + { + LOG_INFO(OS_TEXT("关联音频设备成功!")); + } + #endif//_DEBUG + + if(!alcMakeContextCurrent(AudioContext)) + { + LOG_ERROR(OS_TEXT("关联音频设备上下文与音频设备失败!")); + CloseOpenAL(); + RETURN_FALSE; + } + #ifdef _DEBUG + else + { + LOG_INFO(OS_TEXT("关联音频设备上下文与音频设备成功!")); + } + #endif//_DEBUG + + hgl::strcpy(AudioDeviceName,AL_DEVICE_NAME_MAX_LEN,alcGetString(AudioDevice,ALC_DEVICE_SPECIFIER)); + + LOG_INFO(u8"初始化音频设备完成: "+UTF8String(AudioDeviceName)); + + if (!LoadALFunc(AudioEM)) + { + LOG_INFO(OS_TEXT("加载OpenAL函数失败!")); + CloseOpenAL(); + RETURN_FALSE; + } + + LOG_INFO(OS_TEXT("加载OpenAL函数完成!")); + + if(alcIsExtensionPresent) + { + AudioXRAM=CheckXRAM(AudioDevice); + AudioEFX=CheckEFX(AudioDevice); + } + else + { + AudioXRAM=false; + AudioEFX=false; + } + + alGetError(); + + InitOpenALExt(); + + LOG_INFO(OS_TEXT("初始化OpenAL完成!")); + PutOpenALInfo(); + + return(AL_TRUE); + } + + bool InitOpenALDevice(const OpenALDevice *device) + { + if(device) + return InitOpenALDeviceByName(device->name); + else + return InitOpenALDeviceByName(nullptr); + } + + //-------------------------------------------------------------------------------------------------- + /** + * 关闭OpenAL + */ + void CloseOpenAL() + { + if(AudioEM) + { + alcMakeContextCurrent(0); + + if(AudioContext) alcDestroyContext(AudioContext); + if(AudioDevice) alcCloseDevice(AudioDevice); + SAFE_CLEAR(AudioEM); + + LOG_INFO(OS_TEXT("关闭OpenAL完成!")); + } + + ClearAL(); + ClearALC(); + ClearXRAM(); + ClearEFX(); + } + + /** + * 设置距离衰减模型(默认钳位倒数距离模型) + */ + bool SetDistanceModel(ALenum distance_model) + { + if (!AudioEM)return(false); + if (!alDistanceModel)return(false); + + if (distance_modelAL_EXPONENT_DISTANCE_CLAMPED) + return(false); + + alDistanceModel(distance_model); + return(true); + } + + bool SetSpeedOfSound(const float ss) + { + if (!AudioEM)return(false); + if (!alSpeedOfSound)return(false); + + alSpeedOfSound(ss); + return(true); + } + + double SetSpeedOfSound(const double height,const double temperature,const double humidity) + { + if (!AudioEM)return(0); + if (!alSpeedOfSound)return(0); + + double v=HGL_SPEED_OF_SOUND; //海拔0米,0摄氏度 + + v*=sqrt(1.0f+temperature/(-HGL_ABSOLUTE_ZERO)); //先计算温度 + + ////11000米高度,温度-56.5,音速295m/s。需根据大气密度来计算 + + //另需计算温度,影响在0.1-0.6之间。 + + alSpeedOfSound(v/HGL_SPEED_OF_SOUND); + return(v); + } + + bool SetDopplerFactor(const float df) + { + if (!AudioEM)return(false); + if (!alDopplerFactor)return(false); + + alDopplerFactor(df); + return(true); + } + + bool SetDopplerVelocity(const float dv) + { + if (!AudioEM)return(false); + if (!alDopplerVelocity)return(false); + + alDopplerVelocity(dv); + return(true); + } + //-------------------------------------------------------------------------------------------------- +// void *alcGetCurrentDevice() { return (AudioDevice); } +// char *alcGetCurrentDeviceName() { return(AudioDeviceName); } + + const struct ALFormatBytes + { + ALenum format; + uint bytes; + } + al_format_bytes[]= + { + {AL_FORMAT_MONO8, 1}, + {AL_FORMAT_MONO16, 2}, + {AL_FORMAT_STEREO8, 2}, + {AL_FORMAT_STEREO16, 4}, + +// {AL_FORMAT_QUAD16, 8}, +// {AL_FORMAT_51CHN16, 12}, +// {AL_FORMAT_61CHN16, 14}, +// {AL_FORMAT_71CHN16, 16}, +// + {AL_FORMAT_MONO_FLOAT32, 4}, + {AL_FORMAT_STEREO_FLOAT32, 8}, +// +// {AL_FORMAT_QUAD8, 4}, +// {AL_FORMAT_QUAD16, 8}, +// {AL_FORMAT_QUAD32, 16}, +// {AL_FORMAT_REAR8, 4}, +// {AL_FORMAT_REAR16, 8}, +// {AL_FORMAT_REAR32, 16}, +// {AL_FORMAT_51CHN8, 6}, +// {AL_FORMAT_51CHN16, 12}, +// {AL_FORMAT_51CHN32, 24}, +// {AL_FORMAT_61CHN8, 7}, +// {AL_FORMAT_61CHN16, 14}, +// {AL_FORMAT_61CHN32, 28}, +// {AL_FORMAT_71CHN8, 8}, +// {AL_FORMAT_71CHN16, 16}, +// {AL_FORMAT_71CHN32, 32}, + + {0,0} + }; + + const int al_get_format_byte(ALenum format) + { + const ALFormatBytes *p=al_format_bytes; + + while(p->format) + { + if(p->format==format) + return p->bytes; + + ++p; + } + + return(0); + } + + /** + * 计算音频数据可播放的时间 + * @param size 数据字节长度 + * @param format 数据格式 + * @param freq 数据采样率 + * @return 时间(秒) + */ + double AudioDataTime(ALuint size,ALenum format,ALsizei freq) + { + if(size==0||freq==0)return(0); + + const uint byte=al_get_format_byte(format); + + if(byte==0) + return(0); + + return (double(size)/double(freq)/double(byte)); + } + + /** + * 计算一秒钟音频数据所需要的字节数 + * @param format 数据格式 + * @param freq 数据采样率 + * @return 时间(秒) + */ + unsigned int AudioTime(ALenum format,ALsizei freq) + { + const uint byte=al_get_format_byte(format); + + if(byte==0) + return(0); + + return byte*freq; + } + + unsigned int GetMaxNumSources() + { + ALuint source; + Stack source_stack; + + // Clear AL Error Code + alGetError(); + + for(;;) + { + alGenSources(1, &source); + + if (alGetError() != AL_NO_ERROR) + break; + + source_stack.Push(source); + } + + const int count=source_stack.GetCount(); + const ALuint *p=source_stack.GetData(); + + alDeleteSources(count,p); + + if (alGetError() != AL_NO_ERROR) + { + for(int i=0;i +#include +#include +#include +#include + +using namespace hgl; +using namespace openal; + +namespace openal +{ + const char *alcGetDeviceNameList(); + bool alcGetDefaultDeviceName(char *name); +}//namespace openal + +HGL_PLUGIN_FUNC const char *GetAudioDeviceNameList() +{ + return openal::alcGetDeviceNameList(); +} + +HGL_PLUGIN_FUNC bool GetDefaultAudioDeviceName(char *name) +{ + return openal::alcGetDefaultDeviceName(name); +} + +HGL_PLUGIN_FUNC AudioListener *CreateListener() +{ + return(new AudioListener()); +} + +HGL_PLUGIN_FUNC void ClearListener(AudioListener *listener) +{ + if(listener) + delete listener; +} + +HGL_PLUGIN_FUNC const float ListenerGetGain (AudioListener *listener) +{ + if (!listener) + return(0); + + return listener->GetGain(); +} + +HGL_PLUGIN_FUNC const bool ListenerGetPosition (AudioListener *listener, Vector3f &pos) +{ + if (!listener) + return(false); + + pos = listener->GetPosition(); + return(true); +} + +HGL_PLUGIN_FUNC const bool ListenerGetVelocity (AudioListener *listener, Vector3f &vel) +{ + if (!listener) + return(false); + + vel = listener->GetVelocity(); + return(true); +} + +HGL_PLUGIN_FUNC const bool ListenerGetOrientation (AudioListener *listener, ListenerOrientation & ori) +{ + if (!listener)return(false); + memcpy(&ori, &(listener->GetOrientation()), sizeof(ListenerOrientation)); + return(true); +} + +HGL_PLUGIN_FUNC void ListenerSetGain (AudioListener *listener, float gain) {if (listener)listener->SetGain(gain); } +HGL_PLUGIN_FUNC void ListenerSetPosition (AudioListener *listener, const Vector3f & pos ) {if (listener)listener->SetPosition(pos);} +HGL_PLUGIN_FUNC void ListenerSetVelocity (AudioListener *listener, const Vector3f & vel ) {if (listener)listener->SetVelocity(vel);} +HGL_PLUGIN_FUNC void ListenerSetOrientation (AudioListener *listener, const ListenerOrientation & ori ) {if (listener)listener->SetOrientation(ori);} + +HGL_PLUGIN_FUNC AudioBuffer *CreateAudioBufferFromData(void *buf, int size, AudioFileType aft){return(new AudioBuffer(buf, size, aft));} +HGL_PLUGIN_FUNC AudioBuffer *CreateAudioBufferFromFile(const os_char *filename, AudioFileType aft){return(new AudioBuffer(filename, aft));} + +HGL_PLUGIN_FUNC void ClearAudioBuffer(AudioBuffer *buf){if(buf)delete buf;} + +HGL_PLUGIN_FUNC bool SetAudioBufferData(AudioBuffer *audio_buffer, uint format, const void *data, uint size, uint freq) +{ + if (!audio_buffer)return(false); + + return audio_buffer->SetData(format, data, size, freq); +} + +HGL_PLUGIN_FUNC bool LoadDataToAudioBuffer(AudioBuffer *audio_buffer, void *data, int size, AudioFileType aft) +{ + if (!audio_buffer)return(false); + + return audio_buffer->Load(data, size, aft); +} + +HGL_PLUGIN_FUNC bool LoadFileToAudioBuffer(AudioBuffer *audio_buffer, const os_char *filename, AudioFileType aft) +{ + if (!audio_buffer)return(false); + + return audio_buffer->Load(filename, aft); +} + +HGL_PLUGIN_FUNC void ClearAudioBufferData(AudioBuffer *audio_buffer) +{ + if (!audio_buffer)return; + + audio_buffer->Clear(); +} + +HGL_PLUGIN_FUNC double AudioBufferTime (AudioBuffer *buf){return buf?buf->Time:0;} +HGL_PLUGIN_FUNC uint AudioBufferBytes (AudioBuffer *buf){return buf?buf->Size:0;} +HGL_PLUGIN_FUNC uint AudioBufferFreq (AudioBuffer *buf){return buf?buf->Freq:0;} + +HGL_PLUGIN_FUNC uint SourceGetIndex (AudioSource *source){return source?source->GetIndex():0;} + +HGL_PLUGIN_FUNC double SourceGetCurTime (AudioSource *source){return source?source->GetCurTime():0;} +HGL_PLUGIN_FUNC void SourceSetCurTime (AudioSource *source,const double &t){if(source)source->SetCurTime(t);} + +HGL_PLUGIN_FUNC int SourceGetState (AudioSource *source){return source?source->GetState():-1;} +HGL_PLUGIN_FUNC float SourceGetMinGain (AudioSource *source){return source?source->GetMinGain():0;} +HGL_PLUGIN_FUNC float SourceGetMaxGain (AudioSource *source){return source?source->GetMaxGain():0;} + +HGL_PLUGIN_FUNC const bool SourceGetLoop (AudioSource *source){return source?source->GetLoop():false;} + +HGL_PLUGIN_FUNC const float SourceGetPitch (AudioSource *source){return source?source->GetPitch():0;} +HGL_PLUGIN_FUNC const float SourceGetGain (AudioSource *source){return source?source->GetGain():0;} +HGL_PLUGIN_FUNC const float SourceGetConeGain (AudioSource *source){return source?source->GetConeGain():0;} + +HGL_PLUGIN_FUNC const uint SourceGetDistanceModel (AudioSource *source){return source?source->GetDistanceModel():0;} +HGL_PLUGIN_FUNC const float SourceGetRolloffFactor (AudioSource *source){return source?source->GetRolloffFactor():0;} + +HGL_PLUGIN_FUNC bool SourceGetDistance (AudioSource *source,float &rd,float &md){if(!source)return(false);source->GetDistance(rd,md);return(true);} + +HGL_PLUGIN_FUNC bool SourceGetDoppler (AudioSource *source,float &factor,float &velocity){if(!source)return(false);source->GetDoppler(factor,velocity);return(true);} + +HGL_PLUGIN_FUNC void SourceSetLoop (AudioSource *source,bool l ){if(source)source->SetLoop(l);} +HGL_PLUGIN_FUNC void SourceSetPitch (AudioSource *source,float p ){if(source)source->SetPitch(p);} +HGL_PLUGIN_FUNC void SourceSetGain (AudioSource *source,float g ){if(source)source->SetGain(g);} +HGL_PLUGIN_FUNC void SourceSetConeGain (AudioSource *source,float cg ){if(source)source->SetConeGain(cg);} +HGL_PLUGIN_FUNC void SourceSetDistanceModel (AudioSource *source,uint dm ){if(source)source->SetDistanceModel(dm);} +HGL_PLUGIN_FUNC void SourceSetRolloffFactor (AudioSource *source,float rf ){if(source)source->SetRolloffFactor(rf);} + +HGL_PLUGIN_FUNC bool SourceGetPosition (AudioSource *source,Vector3f &pos){if(!source)return(false);pos=source->GetPosition();return(true);} +HGL_PLUGIN_FUNC bool SourceGetVelocity (AudioSource *source,Vector3f &vel){if(!source)return(false);vel=source->GetVelocity();return(true);} +HGL_PLUGIN_FUNC bool SourceGetDirection (AudioSource *source,Vector3f &dir){if(!source)return(false);dir=source->GetDirection();return(true);} +HGL_PLUGIN_FUNC bool SourceGetAngle (AudioSource *source,ConeAngle &ca){if(!source)return(false);ca =source->GetAngle();return(true);} + +HGL_PLUGIN_FUNC void SourceSetPosition (AudioSource *source,const Vector3f &pos ){if(source)source->SetPosition(pos);} +HGL_PLUGIN_FUNC void SourceSetVelocity (AudioSource *source,const Vector3f &vel ){if(source)source->SetVelocity(vel);} +HGL_PLUGIN_FUNC void SourceSetDirection (AudioSource *source,const Vector3f &dir ){if(source)source->SetDirection(dir);} +HGL_PLUGIN_FUNC void SourceSetDistance (AudioSource *source,const float &ref_distance, const float &max_distance){if(source)source->SetDistance(ref_distance,max_distance);} +HGL_PLUGIN_FUNC void SourceSetConeAngle (AudioSource *source,const ConeAngle &ca ){if(source)source->SetConeAngle(ca);} +HGL_PLUGIN_FUNC void SourceSetDopplerFactor (AudioSource *source,const float &df ){if(source)source->SetDopplerFactor(df);} +HGL_PLUGIN_FUNC void SourceSetDopplerVelocity(AudioSource *source,const float &dv ){if(source)source->SetDopplerVelocity(dv);} + +HGL_PLUGIN_FUNC AudioSource *CreateAudioSource(bool create){return(new AudioSource(create));} +HGL_PLUGIN_FUNC AudioSource *CreateAudioSourceFromBuffer(AudioBuffer *buf){return(new AudioSource(buf));} +HGL_PLUGIN_FUNC void ClearAudioSource(AudioSource *source){if(source)delete source;} + +HGL_PLUGIN_FUNC bool SourcePlay (AudioSource *source,bool loop){return source?source->Play(loop):false;} +HGL_PLUGIN_FUNC void SourcePause (AudioSource *source){if(source)source->Pause();} +HGL_PLUGIN_FUNC void SourceResume (AudioSource *source){if(source)source->Resume();} +HGL_PLUGIN_FUNC void SourceStop (AudioSource *source){if(source)source->Stop();} +HGL_PLUGIN_FUNC void SourceRewind (AudioSource *source){if(source)source->Rewind();} + +HGL_PLUGIN_FUNC bool SourceCreate (AudioSource *source){return source?source->Create():false;} +HGL_PLUGIN_FUNC void SourceClose (AudioSource *source){if(source)source->Close();} + +HGL_PLUGIN_FUNC bool SourceLink (AudioSource *source,AudioBuffer *buf){return source?source->Link(buf):false;} +HGL_PLUGIN_FUNC void SourceUnlink (AudioSource *source){if(source)source->Unlink();} + + +HGL_PLUGIN_FUNC uint PlayerGetSource (AudioPlayer *ap){return ap?ap->GetIndex():0;} +HGL_PLUGIN_FUNC double PlayerGetTime (AudioPlayer *ap){return ap?ap->GetTime():0;} +HGL_PLUGIN_FUNC AudioPlayer::PlayState PlayerGetPlayState (AudioPlayer *ap){return ap?ap->GetPlayState():(AudioPlayer::psNone);} +HGL_PLUGIN_FUNC int PlayerGetSourceState(AudioPlayer *ap){return ap?ap->GetSourceState():0;} +HGL_PLUGIN_FUNC float PlayerGetMinGain (AudioPlayer *ap){return ap?ap->GetMinGain():0;} +HGL_PLUGIN_FUNC float PlayerGetMaxGain (AudioPlayer *ap){return ap?ap->GetMaxGain():0;} + +HGL_PLUGIN_FUNC float PlayerGetPitch(AudioPlayer *ap){return ap?ap->GetPitch():0;} +HGL_PLUGIN_FUNC void PlayerSetPitch(AudioPlayer *ap,float val){if(ap)ap->SetPitch(val);} + +HGL_PLUGIN_FUNC float PlayerGetGain(AudioPlayer *ap){return ap?ap->GetGain():0;} +HGL_PLUGIN_FUNC void PlayerSetGain(AudioPlayer *ap,float val){if(ap)ap->SetGain(val);} + +HGL_PLUGIN_FUNC float PlayerGetConeGain(AudioPlayer *ap){return ap?ap->GetConeGain():0;} +HGL_PLUGIN_FUNC void PlayerSetConeGain(AudioPlayer *ap,float val){if(ap)ap->SetConeGain(val);} + +HGL_PLUGIN_FUNC float PlayerGetRolloffFactor(AudioPlayer *ap){return ap?ap->GetRolloffFactor():0;} +HGL_PLUGIN_FUNC void PlayerSetRolloffFactor(AudioPlayer *ap,float rf){if(ap)ap->SetRolloffFactor(rf);} + +HGL_PLUGIN_FUNC bool PlayerGetPosition(AudioPlayer *ap,Vector3f &pos){if(!ap)return(false);pos=ap->GetPosition();return(true);} +HGL_PLUGIN_FUNC void PlayerSetPosition(AudioPlayer *ap,const Vector3f &pos){if(!ap)return;ap->SetPosition(pos);} + +HGL_PLUGIN_FUNC bool PlayerGetVelocity(AudioPlayer *ap,Vector3f &vel){if(!ap)return(false);vel=ap->GetVelocity();return(true);} +HGL_PLUGIN_FUNC void PlayerSetVelocity(AudioPlayer *ap,const Vector3f &vel){if(!ap)return;ap->SetVelocity(vel);} + +HGL_PLUGIN_FUNC bool PlayerGetDirection(AudioPlayer *ap,Vector3f &dir){if(!ap)return(false);dir=ap->GetDirection();return(true);} +HGL_PLUGIN_FUNC void PlayerSetDirection(AudioPlayer *ap,const Vector3f &dir){if(!ap)return;ap->SetDirection(dir);} + +HGL_PLUGIN_FUNC void PlayerGetDistance(AudioPlayer *ap,float &ref_distance, float &max_distance){if(!ap)return;ap->GetDistance(ref_distance,max_distance);} +HGL_PLUGIN_FUNC void PlayerSetDistance(AudioPlayer *ap,const float &ref_distance,const float &max_distance){if(!ap)return;ap->SetDistance(ref_distance,max_distance);} + +HGL_PLUGIN_FUNC bool PlayerGetConeAngle(AudioPlayer *ap,ConeAngle &ca){if(!ap)return(false);ca=ap->GetConeAngle();return(true);} +HGL_PLUGIN_FUNC void PlayerSetConeAngle(AudioPlayer *ap,const ConeAngle &ca){if(!ap)return;ap->SetConeAngle(ca);} + +HGL_PLUGIN_FUNC AudioPlayer * CreateAudioPlayer(){return(new AudioPlayer());} +HGL_PLUGIN_FUNC AudioPlayer * CreateAudioPlayerFromFile(const os_char *filename,AudioFileType aft){return(new AudioPlayer(filename,aft));} +HGL_PLUGIN_FUNC void ClearAudioPlayer(AudioPlayer *ap){if(ap)delete ap;} + +HGL_PLUGIN_FUNC bool LoadFileToPlayer(AudioPlayer *ap,const os_char *filename,AudioFileType aft){return ap?ap->Load(filename,aft):false;} + +HGL_PLUGIN_FUNC void PlayerPlay (AudioPlayer *ap,bool loop){if(ap)ap->Play(loop);} +HGL_PLUGIN_FUNC void PlayerStop (AudioPlayer *ap){if(ap)ap->Stop();} +HGL_PLUGIN_FUNC void PlayerPause (AudioPlayer *ap){if(ap)ap->Pause();} +HGL_PLUGIN_FUNC void PlayerResume(AudioPlayer *ap){if(ap)ap->Resume();} +HGL_PLUGIN_FUNC void PlayerClear (AudioPlayer *ap){if(ap)ap->Clear();} + +HGL_PLUGIN_FUNC double PlayerGetPlayTime(AudioPlayer *ap){return ap?ap->GetPlayTime():0;} +HGL_PLUGIN_FUNC void PlayerSetFadeTime(AudioPlayer *ap,double in,double out){if(ap)ap->SetFadeTime(in,out);} + +HGL_PLUGIN_FUNC void PlayerSetAutoGain(AudioPlayer *ap,float target_gain,double adjust_time){if(ap)ap->AutoGain(target_gain,adjust_time);} diff --git a/src/OpenALEEStandAlone.cpp b/src/OpenALEEStandAlone.cpp new file mode 100644 index 0000000..3891ca5 --- /dev/null +++ b/src/OpenALEEStandAlone.cpp @@ -0,0 +1,33 @@ +#include +#include + +namespace hgl +{ +// void SystemCheck(SystemInfo *,bool); + + class ConsoleSystemInitInfo; + + bool InitCore(SystemInfo &si, ConsoleSystemInitInfo *sii); + void CloseCore(); +} + +using namespace hgl; + +HGL_PLUGIN_FUNC bool InitOpenALEE(const os_char *driver_name,const char *device_name) +{ + SystemInfo si; + + InitCore(si,nullptr); //初始化内核 + + if(!openal::InitOpenAL(driver_name,device_name)) + return(false); + + return(true); +} + +HGL_PLUGIN_FUNC void CloseOpenALEE() +{ + openal::CloseOpenAL(); + + CloseCore(); +} diff --git a/src/XRAM.cpp b/src/XRAM.cpp new file mode 100644 index 0000000..488ce1c --- /dev/null +++ b/src/XRAM.cpp @@ -0,0 +1,51 @@ +#include +#include + +namespace openal +{ + // XRAM functions and enum values + + LPEAXSETBUFFERMODE eaxSetBufferMode = 0; + LPEAXGETBUFFERMODE eaxGetBufferMode = 0; + + ALenum eXRAMSize = 0; + ALenum eXRAMFree = 0; + ALenum eXRAMAuto = 0; + ALenum eXRAMHardware = 0; + ALenum eXRAMAccessible = 0; +} + +namespace openal +{ + bool CheckXRAM(ALCdevice_struct *AudioDevice) + { + if(alcIsExtensionPresent(AudioDevice, "EAX-RAM")) + { + if (eaxSetBufferMode && eaxGetBufferMode) + { + eXRAMSize = alGetEnumValue("AL_EAX_RAM_SIZE"); + eXRAMFree = alGetEnumValue("AL_EAX_RAM_FREE"); + eXRAMAuto = alGetEnumValue("AL_STORAGE_AUTOMATIC"); + eXRAMHardware = alGetEnumValue("AL_STORAGE_HARDWARE"); + eXRAMAccessible = alGetEnumValue("AL_STORAGE_ACCESSIBLE"); + + if (eXRAMSize && eXRAMFree && eXRAMAuto && eXRAMHardware && eXRAMAccessible) + return(true); + } + } + + return(false); + } + + void ClearXRAM() + { + eaxSetBufferMode = 0; + eaxGetBufferMode = 0; + + eXRAMSize = 0; + eXRAMFree = 0; + eXRAMAuto = 0; + eXRAMHardware = 0; + eXRAMAccessible = 0; + } +}//namespace openal diff --git a/src/al.cpp b/src/al.cpp new file mode 100644 index 0000000..2dc9ba5 --- /dev/null +++ b/src/al.cpp @@ -0,0 +1,191 @@ +#include +#include +#include +#include + +using namespace hgl; + +namespace openal +{ + alEnablePROC alEnable=nullptr; + alDisablePROC alDisable=nullptr; + alIsEnabledPROC alIsEnabled=nullptr; + alGetStringPROC alGetString=nullptr; + alGetBooleanvPROC alGetBooleanv=nullptr; + alGetIntegervPROC alGetIntegerv=nullptr; + alGetFloatvPROC alGetFloatv=nullptr; + alGetDoublevPROC alGetDoublev=nullptr; + alGetBooleanPROC alGetBoolean=nullptr; + alGetIntegerPROC alGetInteger=nullptr; + alGetFloatPROC alGetFloat=nullptr; + alGetDoublePROC alGetDouble=nullptr; + alGetErrorPROC alGetError=nullptr; + alIsExtensionPresentPROC alIsExtensionPresent=nullptr; + alGetProcAddressPROC alGetProcAddress=nullptr; + alGetEnumValuePROC alGetEnumValue=nullptr; + alListenerfPROC alListenerf=nullptr; + alListener3fPROC alListener3f=nullptr; + alListenerfvPROC alListenerfv=nullptr; + alListeneriPROC alListeneri=nullptr; + alListener3iPROC alListener3i=nullptr; + alListenerivPROC alListeneriv=nullptr; + alGetListenerfPROC alGetListenerf=nullptr; + alGetListener3fPROC alGetListener3f=nullptr; + alGetListenerfvPROC alGetListenerfv=nullptr; + alGetListeneriPROC alGetListeneri=nullptr; + alGetListener3iPROC alGetListener3i=nullptr; + alGetListenerivPROC alGetListeneriv=nullptr; + alGenSourcesPROC alGenSources=nullptr; + alDeleteSourcesPROC alDeleteSources=nullptr; + alIsSourcePROC alIsSource=nullptr; + alSourcefPROC alSourcef=nullptr; + alSource3fPROC alSource3f=nullptr; + alSourcefvPROC alSourcefv=nullptr; + alSourceiPROC alSourcei=nullptr; + alSource3iPROC alSource3i=nullptr; + alSourceivPROC alSourceiv=nullptr; + alGetSourcefPROC alGetSourcef=nullptr; + alGetSource3fPROC alGetSource3f=nullptr; + alGetSourcefvPROC alGetSourcefv=nullptr; + alGetSourceiPROC alGetSourcei=nullptr; + alGetSource3iPROC alGetSource3i=nullptr; + alGetSourceivPROC alGetSourceiv=nullptr; + alSourcePlayvPROC alSourcePlayv=nullptr; + alSourceStopvPROC alSourceStopv=nullptr; + alSourceRewindvPROC alSourceRewindv=nullptr; + alSourcePausevPROC alSourcePausev=nullptr; + alSourcePlayPROC alSourcePlay=nullptr; + alSourceStopPROC alSourceStop=nullptr; + alSourceRewindPROC alSourceRewind=nullptr; + alSourcePausePROC alSourcePause=nullptr; + alSourceQueueBuffersPROC alSourceQueueBuffers=nullptr; + alSourceUnqueueBuffersPROC alSourceUnqueueBuffers=nullptr; + alGenBuffersPROC alGenBuffers=nullptr; + alDeleteBuffersPROC alDeleteBuffers=nullptr; + alIsBufferPROC alIsBuffer=nullptr; + alBufferDataPROC alBufferData=nullptr; + alBufferfPROC alBufferf=nullptr; + alBuffer3fPROC alBuffer3f=nullptr; + alBufferfvPROC alBufferfv=nullptr; + alBufferiPROC alBufferi=nullptr; + alBuffer3iPROC alBuffer3i=nullptr; + alBufferivPROC alBufferiv=nullptr; + alGetBufferfPROC alGetBufferf=nullptr; + alGetBuffer3fPROC alGetBuffer3f=nullptr; + alGetBufferfvPROC alGetBufferfv=nullptr; + alGetBufferiPROC alGetBufferi=nullptr; + alGetBuffer3iPROC alGetBuffer3i=nullptr; + alGetBufferivPROC alGetBufferiv=nullptr; + alDopplerFactorPROC alDopplerFactor=nullptr; + alDopplerVelocityPROC alDopplerVelocity=nullptr; + alSpeedOfSoundPROC alSpeedOfSound=nullptr; + alDistanceModelPROC alDistanceModel=nullptr; +} + +namespace openal +{ + bool LoadALFunc(hgl::ExternalModule *module) + { + if(!module)RETURN_FALSE; + + alGetProcAddress=(alGetProcAddressPROC)(module->GetFunc("alGetProcAddress")); + + if(!alGetProcAddress)RETURN_FALSE; + + HGL_FUNC_LOAD_LIST_BEGIN(al_func_load_list) + HGL_FUNC_LOAD(alGetProcAddress) + + HGL_FUNC_LOAD(alEnable) + HGL_FUNC_LOAD(alDisable) + HGL_FUNC_LOAD(alIsEnabled) + HGL_FUNC_LOAD(alGetString) + HGL_FUNC_LOAD(alGetBooleanv) + HGL_FUNC_LOAD(alGetIntegerv) + HGL_FUNC_LOAD(alGetFloatv) + HGL_FUNC_LOAD(alGetDoublev) + HGL_FUNC_LOAD(alGetBoolean) + HGL_FUNC_LOAD(alGetInteger) + HGL_FUNC_LOAD(alGetFloat) + HGL_FUNC_LOAD(alGetDouble) + HGL_FUNC_LOAD(alGetError) + HGL_FUNC_LOAD(alIsExtensionPresent) + HGL_FUNC_LOAD(alGetEnumValue) + HGL_FUNC_LOAD(alListenerf) + HGL_FUNC_LOAD(alListener3f) + HGL_FUNC_LOAD(alListenerfv) + HGL_FUNC_LOAD(alListeneri) + HGL_FUNC_LOAD(alListener3i) + HGL_FUNC_LOAD(alListeneriv) + HGL_FUNC_LOAD(alGetListenerf) + HGL_FUNC_LOAD(alGetListener3f) + HGL_FUNC_LOAD(alGetListenerfv) + HGL_FUNC_LOAD(alGetListeneri) + HGL_FUNC_LOAD(alGetListener3i) + HGL_FUNC_LOAD(alGetListeneriv) + HGL_FUNC_LOAD(alGenSources) + HGL_FUNC_LOAD(alDeleteSources) + HGL_FUNC_LOAD(alIsSource) + HGL_FUNC_LOAD(alSourcef) + HGL_FUNC_LOAD(alSource3f) + HGL_FUNC_LOAD(alSourcefv) + HGL_FUNC_LOAD(alSourcei) + HGL_FUNC_LOAD(alSource3i) + HGL_FUNC_LOAD(alSourceiv) + HGL_FUNC_LOAD(alGetSourcef) + HGL_FUNC_LOAD(alGetSource3f) + HGL_FUNC_LOAD(alGetSourcefv) + HGL_FUNC_LOAD(alGetSourcei) + HGL_FUNC_LOAD(alGetSource3i) + HGL_FUNC_LOAD(alGetSourceiv) + HGL_FUNC_LOAD(alSourcePlayv) + HGL_FUNC_LOAD(alSourceStopv) + HGL_FUNC_LOAD(alSourceRewindv) + HGL_FUNC_LOAD(alSourcePausev) + HGL_FUNC_LOAD(alSourcePlay) + HGL_FUNC_LOAD(alSourceStop) + HGL_FUNC_LOAD(alSourceRewind) + HGL_FUNC_LOAD(alSourcePause) + HGL_FUNC_LOAD(alSourceQueueBuffers) + HGL_FUNC_LOAD(alSourceUnqueueBuffers) + HGL_FUNC_LOAD(alGenBuffers) + HGL_FUNC_LOAD(alDeleteBuffers) + HGL_FUNC_LOAD(alIsBuffer) + HGL_FUNC_LOAD(alBufferData) + HGL_FUNC_LOAD(alBufferf) + HGL_FUNC_LOAD(alBuffer3f) + HGL_FUNC_LOAD(alBufferfv) + HGL_FUNC_LOAD(alBufferi) + HGL_FUNC_LOAD(alBuffer3i) + HGL_FUNC_LOAD(alBufferiv) + HGL_FUNC_LOAD(alGetBufferf) + HGL_FUNC_LOAD(alGetBuffer3f) + HGL_FUNC_LOAD(alGetBufferfv) + HGL_FUNC_LOAD(alGetBufferi) + HGL_FUNC_LOAD(alGetBuffer3i) + HGL_FUNC_LOAD(alGetBufferiv) + HGL_FUNC_LOAD(alDopplerFactor) + HGL_FUNC_LOAD(alDopplerVelocity) + HGL_FUNC_LOAD(alSpeedOfSound) + HGL_FUNC_LOAD(alDistanceModel) + HGL_FUNC_LOAD_LIST_END + + FuncLoad *flp=al_func_load_list; + + while(flp->func_pointer) + { + (*(flp->func_pointer))=alGetProcAddress(flp->func_name); + + if(!(*(flp->func_pointer))) + (*(flp->func_pointer))=module->GetFunc(flp->func_name); + + ++flp; + } + + return(true); + } + + void ClearAL() + { +// ClearFuncLoadPointer(al_func_load_list); + } +}//namespace openal diff --git a/src/alc.cpp b/src/alc.cpp new file mode 100644 index 0000000..a624b3d --- /dev/null +++ b/src/alc.cpp @@ -0,0 +1,68 @@ +#include +#include +#include + +using namespace hgl; + +namespace openal +{ + alcCreateContextPROC alcCreateContext=nullptr; + alcMakeContextCurrentPROC alcMakeContextCurrent=nullptr; + alcProcessContextPROC alcProcessContext=nullptr; + alcSuspendContextPROC alcSuspendContext=nullptr; + alcDestroyContextPROC alcDestroyContext=nullptr; + alcGetCurrentContextPROC alcGetCurrentContext=nullptr; + alcGetContextsDevicePROC alcGetContextsDevice=nullptr; + alcOpenDevicePROC alcOpenDevice=nullptr; + alcCloseDevicePROC alcCloseDevice=nullptr; + alcGetErrorPROC alcGetError=nullptr; + alcIsExtensionPresentPROC alcIsExtensionPresent=nullptr; + alcGetProcAddressPROC alcGetProcAddress=nullptr; + alcGetEnumValuePROC alcGetEnumValue=nullptr; + alcGetStringPROC alcGetString=nullptr; + alcGetIntegervPROC alcGetIntegerv=nullptr; + alcCaptureOpenDevicePROC alcCaptureOpenDevice=nullptr; + alcCaptureCloseDevicePROC alcCaptureCloseDevice=nullptr; + alcCaptureStartPROC alcCaptureStart=nullptr; + alcCaptureStopPROC alcCaptureStop=nullptr; + alcCaptureSamplesPROC alcCaptureSamples=nullptr; +} + +namespace openal +{ + bool LoadALCFunc(hgl::ExternalModule *module) + { + if(!module)RETURN_FALSE; + + HGL_FUNC_LOAD_LIST_BEGIN(alc_func_load_list) + HGL_FUNC_LOAD(alcGetProcAddress) + + HGL_FUNC_LOAD(alcCreateContext) + HGL_FUNC_LOAD(alcMakeContextCurrent) + HGL_FUNC_LOAD(alcProcessContext) + HGL_FUNC_LOAD(alcSuspendContext) + HGL_FUNC_LOAD(alcDestroyContext) + HGL_FUNC_LOAD(alcGetCurrentContext) + HGL_FUNC_LOAD(alcGetContextsDevice) + HGL_FUNC_LOAD(alcOpenDevice) + HGL_FUNC_LOAD(alcCloseDevice) + HGL_FUNC_LOAD(alcGetError) + HGL_FUNC_LOAD(alcIsExtensionPresent) + HGL_FUNC_LOAD(alcGetEnumValue) + HGL_FUNC_LOAD(alcGetString) + HGL_FUNC_LOAD(alcGetIntegerv) + HGL_FUNC_LOAD(alcCaptureOpenDevice) + HGL_FUNC_LOAD(alcCaptureCloseDevice) + HGL_FUNC_LOAD(alcCaptureStart) + HGL_FUNC_LOAD(alcCaptureStop) + HGL_FUNC_LOAD(alcCaptureSamples) + HGL_FUNC_LOAD_LIST_END + + return module->Get(alc_func_load_list); + } + + void ClearALC() + { +// ClearFuncLoadPointer(alc_func_load_list); + } +}//namespace openal