From b53bcac5289d7d76d1a970b864a45505d5408b9d Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 30 May 2016 11:04:09 +0200 Subject: [PATCH 1/8] OpenAL Test --- CrystalJohan.vcxproj | 6 +- CrystalJohan.vcxproj.filters | 6 + OpenAL.cpp | 161 ++++ OpenAL.h | 10 + WAVE/Sound.wav | Bin 0 -> 24685 bytes openAL/include/EFX-Util.h | 446 +++++++++++ openAL/include/al.h | 732 +++++++++++++++++ openAL/include/alc.h | 281 +++++++ openAL/include/efx-creative.h | 151 ++++ openAL/include/efx.h | 737 ++++++++++++++++++ openAL/include/xram.h | 94 +++ openAL/libs/Win32/EFX-Util_MT/EFX-Util.lib | Bin 0 -> 9072 bytes openAL/libs/Win32/EFX-Util_MTDLL/EFX-Util.lib | Bin 0 -> 9220 bytes openAL/libs/Win32/OpenAL32.lib | Bin 0 -> 20552 bytes openAL/libs/Win64/EFX-Util_MT/EFX-Util.lib | Bin 0 -> 15158 bytes openAL/libs/Win64/EFX-Util_MTDLL/EFX-Util.lib | Bin 0 -> 15308 bytes openAL/libs/Win64/OpenAL32.lib | Bin 0 -> 19858 bytes 17 files changed, 2622 insertions(+), 2 deletions(-) create mode 100644 OpenAL.cpp create mode 100644 OpenAL.h create mode 100644 WAVE/Sound.wav create mode 100644 openAL/include/EFX-Util.h create mode 100644 openAL/include/al.h create mode 100644 openAL/include/alc.h create mode 100644 openAL/include/efx-creative.h create mode 100644 openAL/include/efx.h create mode 100644 openAL/include/xram.h create mode 100644 openAL/libs/Win32/EFX-Util_MT/EFX-Util.lib create mode 100644 openAL/libs/Win32/EFX-Util_MTDLL/EFX-Util.lib create mode 100644 openAL/libs/Win32/OpenAL32.lib create mode 100644 openAL/libs/Win64/EFX-Util_MT/EFX-Util.lib create mode 100644 openAL/libs/Win64/EFX-Util_MTDLL/EFX-Util.lib create mode 100644 openAL/libs/Win64/OpenAL32.lib diff --git a/CrystalJohan.vcxproj b/CrystalJohan.vcxproj index eb8f65c..1b7f959 100644 --- a/CrystalJohan.vcxproj +++ b/CrystalJohan.vcxproj @@ -120,14 +120,14 @@ true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - freeglut/include + freeglut/include; openAL/include Console true true true - freeglut/lib + freeglut/lib; openAL/libs @@ -161,6 +161,7 @@ + @@ -175,6 +176,7 @@ + diff --git a/CrystalJohan.vcxproj.filters b/CrystalJohan.vcxproj.filters index 4b5393a..1a2e551 100644 --- a/CrystalJohan.vcxproj.filters +++ b/CrystalJohan.vcxproj.filters @@ -54,6 +54,9 @@ Source Files + + Source Files + @@ -98,6 +101,9 @@ Header Files + + Header Files + diff --git a/OpenAL.cpp b/OpenAL.cpp new file mode 100644 index 0000000..36073c9 --- /dev/null +++ b/OpenAL.cpp @@ -0,0 +1,161 @@ +#include "OpenAL.h" +#include +#include +#include +#include +#include + +int OpenAL::endWithError(char* msg, int error = 0) +{ + //Display error message in console + std::cout << msg << "\n"; + system("PAUSE"); + return error; +} + +OpenAL::OpenAL() +{ + Test(); + +} + +OpenAL::~OpenAL() +{ +} + +boolean OpenAL::Test() +{ + //Loading of the WAVE file + FILE *fp = NULL; //Create FILE pointer for the WAVE file + fp = fopen("WAVE/Sound.wav", "rb"); //Open the WAVE file + if (!fp) return endWithError("Failed to open file"); //Could not open file + + //Variables to store info about the WAVE file (all of them is not needed for OpenAL) + char type[4]; + DWORD size, chunkSize; + short formatType, channels; + DWORD sampleRate, avgBytesPerSec; + short bytesPerSample, bitsPerSample; + DWORD dataSize; + + //Check that the WAVE file is OK + fread(type, sizeof(char), 4, fp); //Reads the first bytes in the file + if (type[0] != 'R' || type[1] != 'I' || type[2] != 'F' || type[3] != 'F') //Should be "RIFF" + return endWithError("No RIFF"); //Not RIFF + + fread(&size, sizeof(DWORD), 1, fp); //Continue to read the file + fread(type, sizeof(char), 4, fp); //Continue to read the file + if (type[0] != 'W' || type[1] != 'A' || type[2] != 'V' || type[3] != 'E') //This part should be "WAVE" + return endWithError("not WAVE"); //Not WAVE + + fread(type, sizeof(char), 4, fp); //Continue to read the file + if (type[0] != 'f' || type[1] != 'm' || type[2] != 't' || type[3] != ' ') //This part should be "fmt " + return endWithError("not fmt "); //Not fmt + + //Now we know that the file is a acceptable WAVE file + //Info about the WAVE data is now read and stored + fread(&chunkSize, sizeof(DWORD), 1, fp); + fread(&formatType, sizeof(short), 1, fp); + fread(&channels, sizeof(short), 1, fp); + fread(&sampleRate, sizeof(DWORD), 1, fp); + fread(&avgBytesPerSec, sizeof(DWORD), 1, fp); + fread(&bytesPerSample, sizeof(short), 1, fp); + fread(&bitsPerSample, sizeof(short), 1, fp); + + fread(type, sizeof(char), 4, fp); + if (type[0] != 'd' || type[1] != 'a' || type[2] != 't' || type[3] != 'a') //This part should be "data" + return endWithError("Missing DATA"); //not data + + fread(&dataSize, sizeof(DWORD), 1, fp); //The size of the sound data is read + + //Display the info about the WAVE file + std::cout << "Chunk Size: " << chunkSize << "\n"; + std::cout << "Format Type: " << formatType << "\n"; + std::cout << "Channels: " << channels << "\n"; + std::cout << "Sample Rate: " << sampleRate << "\n"; + std::cout << "Average Bytes Per Second: " << avgBytesPerSec << "\n"; + std::cout << "Bytes Per Sample: " << bytesPerSample << "\n"; + std::cout << "Bits Per Sample: " << bitsPerSample << "\n"; + std::cout << "Data Size: " << dataSize << "\n"; + + unsigned char* buf = new unsigned char[dataSize]; //Allocate memory for the sound data + std::cout << fread(buf, sizeof(BYTE), dataSize, fp) << " bytes loaded\n"; //Read the sound data and display the + //number of bytes loaded. + //Should be the same as the Data Size if OK + + + //Now OpenAL needs to be initialized + ALCdevice *device; //Create an OpenAL Device + ALCcontext *context; //And an OpenAL Context + device = alcOpenDevice(NULL); //Open the device + if (!device) return endWithError("no sound device"); //Error during device oening + context = alcCreateContext(device, NULL); //Give the device a context + alcMakeContextCurrent(context); //Make the context the current + if (!context) return endWithError("no sound context"); //Error during context handeling + + ALuint source; //Is the name of source (where the sound come from) + ALuint buffer; //Stores the sound data + ALuint frequency = sampleRate;; //The Sample Rate of the WAVE file + ALenum format = 0; //The audio format (bits per sample, number of channels) + + alGenBuffers(1, &buffer); //Generate one OpenAL Buffer and link to "buffer" + alGenSources(1, &source); //Generate one OpenAL Source and link to "source" + if (alGetError() != AL_NO_ERROR) return endWithError("Error GenSource"); //Error during buffer/source generation + + //Figure out the format of the WAVE file + if (bitsPerSample == 8) + { + if (channels == 1) + format = AL_FORMAT_MONO8; + else if (channels == 2) + format = AL_FORMAT_STEREO8; + } + else if (bitsPerSample == 16) + { + if (channels == 1) + format = AL_FORMAT_MONO16; + else if (channels == 2) + format = AL_FORMAT_STEREO16; + } + if (!format) return endWithError("Wrong BitPerSample"); //Not valid format + + alBufferData(buffer, format, buf, dataSize, frequency); //Store the sound data in the OpenAL Buffer + if (alGetError() != AL_NO_ERROR) + return endWithError("Error loading ALBuffer"); //Error during buffer loading + + //Sound setting variables + ALfloat SourcePos[] = { 0.0, 0.0, 0.0 }; //Position of the source sound + ALfloat SourceVel[] = { 0.0, 0.0, 0.0 }; //Velocity of the source sound + ALfloat ListenerPos[] = { 0.0, 0.0, 0.0 }; //Position of the listener + ALfloat ListenerVel[] = { 0.0, 0.0, 0.0 }; //Velocity of the listener + ALfloat ListenerOri[] = { 0.0, 0.0, -1.0, 0.0, 1.0, 0.0 }; //Orientation of the listener + //First direction vector, then vector pointing up) + //Listener + alListenerfv(AL_POSITION, ListenerPos); //Set position of the listener + alListenerfv(AL_VELOCITY, ListenerVel); //Set velocity of the listener + alListenerfv(AL_ORIENTATION, ListenerOri); //Set orientation of the listener + + //Source + alSourcei(source, AL_BUFFER, buffer); //Link the buffer to the source + alSourcef(source, AL_PITCH, 1.0f); //Set the pitch of the source + alSourcef(source, AL_GAIN, 1.0f); //Set the gain of the source + alSourcefv(source, AL_POSITION, SourcePos); //Set the position of the source + alSourcefv(source, AL_VELOCITY, SourceVel); //Set the velocity of the source + alSourcei(source, AL_LOOPING, AL_FALSE); //Set if source is looping sound + + //PLAY + alSourcePlay(source); //Play the sound buffer linked to the source + if (alGetError() != AL_NO_ERROR) return endWithError("Error playing sound"); //Error when playing sound + system("PAUSE"); //Pause to let the sound play + + //Clean-up + fclose(fp); //Close the WAVE file + delete[] buf; //Delete the sound data buffer + alDeleteSources(1, &source); //Delete the OpenAL Source + alDeleteBuffers(1, &buffer); //Delete the OpenAL Buffer + alcMakeContextCurrent(NULL); //Make no context current + alcDestroyContext(context); //Destroy the OpenAL Context + alcCloseDevice(device); //Close the OpenAL Device + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/OpenAL.h b/OpenAL.h new file mode 100644 index 0000000..fdf32ae --- /dev/null +++ b/OpenAL.h @@ -0,0 +1,10 @@ +#pragma once +class OpenAL +{ +public: + int endWithError(char* msg, int error = 0); + OpenAL(); + ~OpenAL(); + boolean Test(); + +}; diff --git a/WAVE/Sound.wav b/WAVE/Sound.wav new file mode 100644 index 0000000000000000000000000000000000000000..74ccfd2bec31c8f33aa6ceac01b964ac3ba46b9d GIT binary patch literal 24685 zcmW)|X_GD2btT6B<}VK0;V+JGI6^H&TT-_MYiiAu0C64wJiK|RSM#kq=RD^*Cr{3E z=ACcN^=1H%06`E0MM^DEq{XI0N>oeHY7K2iI2>Vz{i(yh!0X}yFJ8T>doxe&v-jF- zuf0#b`T5U$=5Xf|pSbQDT)pZLTl{ssQ~$y=ZJ_|L!i#DDdPgI#s^6}%_t z{ntPD<&Tbj`X3j+`r?QGC6)7=cYpBXKY!)Zx1IO?zgK?Y?$7*;-MR5|zw`P3?&o(G z&%S=|_g}eX{&WB5{_#(y_0j*d6@FiM^}nItb&2!ax613Ed;Kdv`1U{j!>@(^`A7M$ zf9L9dzPWer8~^#QgrB)5#y|QGKYX|P)F1uFgXz0x)94lb`y_hbIe2ZzpXt{Iul+Qg ztZ%%b#{R2nbJ*$q{LlXC|L{{^K7J{D>SuoCmw)4}AN?0~d+<}Q{6GKvy}iNsXMf@+ zzWGu5*MGkEwI6<%^S^2C{Tcn~O8S@82Y>vTpW6P+Z;d+jxsK>qLl_iy;D_?<6oU3~EE-+e9ky)Sy#e)pH(`wu%t^P%|P|DyDddHKVaXP2M< zA3w*xQGVqgnxkJ3ed%j|{r#8oI*q?|dcClJ)+o1s<6r*DYe#mxe169FcWrU+R}Y&% zUhMae|LKG2{a^c)(X~(ATK`Dfx#dOv-+uR#zy7(?7mvR*|GV+l&0o6nqZe=e$bI-9 zXRj^1JO9g1{lp*r`O)1k{$%ju@A1z(vVZbtUQvGYvws@i`{HLm*Kz7MzjWi`+ka_) z@t3bZ{8u+q=*>bJf@N%2QN{`(if=U%<`-S2$!AOGQR{?m7+ zZMb)1_dD6)vGd?BKk5$j`s)23|MTCU|H_U_rF`p_VOD)_~E~Q`-8tZ_m3pg>%8`h_q<~OECYb8 z{{8pE-}%)~-ucRR-Z#XzXXO#Z6*wa@oXzxC+mJAZZRb$=Qsc0OV<{Ed~>fJ zNX^S<)GMDH-TdZX{rIEh=npy{e*OJ--+KAY&KLfqxp7UHjvwB>`{t*mEH(Pw`uunM zA3U!|;)7rM@U%K`BXNOE&Z7)-zQ1gf2y`kttJDsnz{x{y5zxVE1x7IJ;nH_c(qpfN-JwHDFFn#rR z??;N7yUDk{(Z2cF-bdeiK6ve#mPHTl1xA1LrO_&ays{QPhJ#+P*Skf+ww`o^1g zzjP4In(AqEpYwZnj?~VzFZx&d>gDcEmNmtLhtofNHZZ5t!>y}kVDA3zza71$-#DCp z>-*n)`<*KJ=(|tH=8EoIyS*o0yuT`AUY(x2{nh2OZ_T$q-%&?Z*_*%gjr`GEy8Gtc zUH`3bKc!x1-g&+A=Jiy|5>+0pn!rs1r=bqr0>C<=5*Dw6rhx3m?SRHRH+G&ZeG!er|7l`VBL)yt2MHOPZN&IK5%Kc=^>+PdnO?R%hnzez}~SR-+wx za`oQ3XY1MM=D`8G$fe|J4F~bPt=F~u9{Q$0FhS z7J2lf2{ZZD-NWwD_MIC>?gURixSDwJ;&N5VH@>vpf9TAu*B%C^(`C&pargBDQ-1T7 z^W<%RuQOj*^86{?-;SpfkJvo2-PF2$yE7K{u7BaKK=P&uC?h1#ysDcF5AlZ@qIK zZFT9g@(FP%_vOx=TQ}bL!WXXXj-xE({TTi}ycx@5S2}{=we%&bWO1?1DKj+~?W1ay?%#a# z=G}v!nXitQQPDPa;aggK{POE>oj$#2$QhN zy1sZ)hW2cIVs!7BUL*=Z9NU!nbsN}PmX}o#cW;00Q1*G4U!Je1!^$$XEdTWB)3+X< z6~Urz3*V1IG1uGIHT(i;qSdxx4AJ%0D2t2xt-?h6BVY)>xVx@6j2LsC?2eKv)^ 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 Hz + */ +#define ALC_FREQUENCY 0x1007 + +/** + * followed by Hz + */ +#define ALC_REFRESH 0x1008 + +/** + * followed by AL_TRUE, AL_FALSE + */ +#define ALC_SYNC 0x1009 + +/** + * followed by Num of requested Mono (3D) Sources + */ +#define ALC_MONO_SOURCES 0x1010 + +/** + * followed by Num of requested Stereo Sources + */ +#define ALC_STEREO_SOURCES 0x1011 + +/** + * errors + */ + +/** + * No error + */ +#define ALC_NO_ERROR ALC_FALSE + +/** + * No device + */ +#define ALC_INVALID_DEVICE 0xA001 + +/** + * invalid context ID + */ +#define ALC_INVALID_CONTEXT 0xA002 + +/** + * bad enum + */ +#define ALC_INVALID_ENUM 0xA003 + +/** + * bad value + */ +#define ALC_INVALID_VALUE 0xA004 + +/** + * Out of memory. + */ +#define ALC_OUT_OF_MEMORY 0xA005 + + +/** + * The Specifier string for default device + */ +#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 + +/** + * ALC_ENUMERATE_ALL_EXT enums + */ +#define ALC_DEFAULT_ALL_DEVICES_SPECIFIER 0x1012 +#define ALC_ALL_DEVICES_SPECIFIER 0x1013 + +/** + * Capture extension + */ +#define ALC_CAPTURE_DEVICE_SPECIFIER 0x310 +#define ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER 0x311 +#define ALC_CAPTURE_SAMPLES 0x312 + + +/* + * Context Management + */ +ALC_API ALCcontext * ALC_APIENTRY alcCreateContext( ALCdevice *device, const ALCint* attrlist ); + +ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent( ALCcontext *context ); + +ALC_API void ALC_APIENTRY alcProcessContext( ALCcontext *context ); + +ALC_API void ALC_APIENTRY alcSuspendContext( ALCcontext *context ); + +ALC_API void ALC_APIENTRY alcDestroyContext( ALCcontext *context ); + +ALC_API ALCcontext * ALC_APIENTRY alcGetCurrentContext( void ); + +ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice( ALCcontext *context ); + + +/* + * Device Management + */ +ALC_API ALCdevice * ALC_APIENTRY alcOpenDevice( const ALCchar *devicename ); + +ALC_API ALCboolean ALC_APIENTRY alcCloseDevice( ALCdevice *device ); + + +/* + * Error support. + * Obtain the most recent Context error + */ +ALC_API ALCenum ALC_APIENTRY alcGetError( ALCdevice *device ); + + +/* + * Extension support. + * Query for the presence of an extension, and obtain any appropriate + * function pointers and enum values. + */ +ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent( ALCdevice *device, const ALCchar *extname ); + +ALC_API void * ALC_APIENTRY alcGetProcAddress( ALCdevice *device, const ALCchar *funcname ); + +ALC_API ALCenum ALC_APIENTRY alcGetEnumValue( ALCdevice *device, const ALCchar *enumname ); + + +/* + * Query functions + */ +ALC_API const ALCchar * ALC_APIENTRY alcGetString( ALCdevice *device, ALCenum param ); + +ALC_API void ALC_APIENTRY alcGetIntegerv( ALCdevice *device, ALCenum param, ALCsizei size, ALCint *data ); + + +/* + * Capture functions + */ +ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice( const ALCchar *devicename, ALCuint frequency, ALCenum format, ALCsizei buffersize ); + +ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice( ALCdevice *device ); + +ALC_API void ALC_APIENTRY alcCaptureStart( ALCdevice *device ); + +ALC_API void ALC_APIENTRY alcCaptureStop( ALCdevice *device ); + +ALC_API void ALC_APIENTRY alcCaptureSamples( ALCdevice *device, ALCvoid *buffer, ALCsizei samples ); + +/* + * Pointer-to-function types, useful for dynamically getting ALC entry points. + */ +typedef ALCcontext * (ALC_APIENTRY *LPALCCREATECONTEXT) (ALCdevice *device, const ALCint *attrlist); +typedef ALCboolean (ALC_APIENTRY *LPALCMAKECONTEXTCURRENT)( ALCcontext *context ); +typedef void (ALC_APIENTRY *LPALCPROCESSCONTEXT)( ALCcontext *context ); +typedef void (ALC_APIENTRY *LPALCSUSPENDCONTEXT)( ALCcontext *context ); +typedef void (ALC_APIENTRY *LPALCDESTROYCONTEXT)( ALCcontext *context ); +typedef ALCcontext * (ALC_APIENTRY *LPALCGETCURRENTCONTEXT)( void ); +typedef ALCdevice * (ALC_APIENTRY *LPALCGETCONTEXTSDEVICE)( ALCcontext *context ); +typedef ALCdevice * (ALC_APIENTRY *LPALCOPENDEVICE)( const ALCchar *devicename ); +typedef ALCboolean (ALC_APIENTRY *LPALCCLOSEDEVICE)( ALCdevice *device ); +typedef ALCenum (ALC_APIENTRY *LPALCGETERROR)( ALCdevice *device ); +typedef ALCboolean (ALC_APIENTRY *LPALCISEXTENSIONPRESENT)( ALCdevice *device, const ALCchar *extname ); +typedef void * (ALC_APIENTRY *LPALCGETPROCADDRESS)(ALCdevice *device, const ALCchar *funcname ); +typedef ALCenum (ALC_APIENTRY *LPALCGETENUMVALUE)(ALCdevice *device, const ALCchar *enumname ); +typedef const ALCchar* (ALC_APIENTRY *LPALCGETSTRING)( ALCdevice *device, ALCenum param ); +typedef void (ALC_APIENTRY *LPALCGETINTEGERV)( ALCdevice *device, ALCenum param, ALCsizei size, ALCint *dest ); +typedef ALCdevice * (ALC_APIENTRY *LPALCCAPTUREOPENDEVICE)( const ALCchar *devicename, ALCuint frequency, ALCenum format, ALCsizei buffersize ); +typedef ALCboolean (ALC_APIENTRY *LPALCCAPTURECLOSEDEVICE)( ALCdevice *device ); +typedef void (ALC_APIENTRY *LPALCCAPTURESTART)( ALCdevice *device ); +typedef void (ALC_APIENTRY *LPALCCAPTURESTOP)( ALCdevice *device ); +typedef void (ALC_APIENTRY *LPALCCAPTURESAMPLES)( ALCdevice *device, ALCvoid *buffer, ALCsizei samples ); + +#if defined(TARGET_OS_MAC) && TARGET_OS_MAC + #pragma export off +#endif + +#if defined(__cplusplus) +} +#endif + +#endif /* AL_ALC_H */ diff --git a/openAL/include/efx-creative.h b/openAL/include/efx-creative.h new file mode 100644 index 0000000..4ea9da6 --- /dev/null +++ b/openAL/include/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/openAL/include/efx.h b/openAL/include/efx.h new file mode 100644 index 0000000..fece160 --- /dev/null +++ b/openAL/include/efx.h @@ -0,0 +1,737 @@ +#ifndef __efx_h_ +#define __efx_h_ + + +#ifdef __cplusplus +extern "C" { +#endif + +#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 + + +/** + * Effect object functions. + */ + +/* Create Effect objects. */ +typedef void (__cdecl *LPALGENEFFECTS)( ALsizei n, ALuint* effects ); + +/* Delete Effect objects. */ +typedef void (__cdecl *LPALDELETEEFFECTS)( ALsizei n, ALuint* effects ); + +/* Verify a handle is a valid Effect. */ +typedef ALboolean (__cdecl *LPALISEFFECT)( ALuint eid ); + +/* Set an integer parameter for an Effect object. */ +typedef void (__cdecl *LPALEFFECTI)( ALuint eid, ALenum param, ALint value); +typedef void (__cdecl *LPALEFFECTIV)( ALuint eid, ALenum param, ALint* values ); + +/* Set a floating point parameter for an Effect object. */ +typedef void (__cdecl *LPALEFFECTF)( ALuint eid, ALenum param, ALfloat value); +typedef void (__cdecl *LPALEFFECTFV)( ALuint eid, ALenum param, ALfloat* values ); + +/* Get an integer parameter for an Effect object. */ +typedef void (__cdecl *LPALGETEFFECTI)( ALuint eid, ALenum pname, ALint* value ); +typedef void (__cdecl *LPALGETEFFECTIV)( ALuint eid, ALenum pname, ALint* values ); + +/* Get a floating point parameter for an Effect object. */ +typedef void (__cdecl *LPALGETEFFECTF)( ALuint eid, ALenum pname, ALfloat* value ); +typedef void (__cdecl *LPALGETEFFECTFV)( ALuint eid, ALenum pname, ALfloat* values ); + + +/** + * Filter object functions + */ + +/* Create Filter objects. */ +typedef void (__cdecl *LPALGENFILTERS)( ALsizei n, ALuint* filters ); + +/* Delete Filter objects. */ +typedef void (__cdecl *LPALDELETEFILTERS)( ALsizei n, ALuint* filters ); + +/* Verify a handle is a valid Filter. */ +typedef ALboolean (__cdecl *LPALISFILTER)( ALuint fid ); + +/* Set an integer parameter for a Filter object. */ +typedef void (__cdecl *LPALFILTERI)( ALuint fid, ALenum param, ALint value ); +typedef void (__cdecl *LPALFILTERIV)( ALuint fid, ALenum param, ALint* values ); + +/* Set a floating point parameter for an Filter object. */ +typedef void (__cdecl *LPALFILTERF)( ALuint fid, ALenum param, ALfloat value); +typedef void (__cdecl *LPALFILTERFV)( ALuint fid, ALenum param, ALfloat* values ); + +/* Get an integer parameter for a Filter object. */ +typedef void (__cdecl *LPALGETFILTERI)( ALuint fid, ALenum pname, ALint* value ); +typedef void (__cdecl *LPALGETFILTERIV)( ALuint fid, ALenum pname, ALint* values ); + +/* Get a floating point parameter for a Filter object. */ +typedef void (__cdecl *LPALGETFILTERF)( ALuint fid, ALenum pname, ALfloat* value ); +typedef void (__cdecl *LPALGETFILTERFV)( ALuint fid, ALenum pname, ALfloat* values ); + + +/** + * Auxiliary Slot object functions + */ + +/* Create Auxiliary Slot objects. */ +typedef void (__cdecl *LPALGENAUXILIARYEFFECTSLOTS)( ALsizei n, ALuint* slots ); + +/* Delete Auxiliary Slot objects. */ +typedef void (__cdecl *LPALDELETEAUXILIARYEFFECTSLOTS)( ALsizei n, ALuint* slots ); + +/* Verify a handle is a valid Auxiliary Slot. */ +typedef ALboolean (__cdecl *LPALISAUXILIARYEFFECTSLOT)( ALuint slot ); + +/* Set an integer parameter for a Auxiliary Slot object. */ +typedef void (__cdecl *LPALAUXILIARYEFFECTSLOTI)( ALuint asid, ALenum param, ALint value ); +typedef void (__cdecl *LPALAUXILIARYEFFECTSLOTIV)( ALuint asid, ALenum param, ALint* values ); + +/* Set a floating point parameter for an Auxiliary Slot object. */ +typedef void (__cdecl *LPALAUXILIARYEFFECTSLOTF)( ALuint asid, ALenum param, ALfloat value ); +typedef void (__cdecl *LPALAUXILIARYEFFECTSLOTFV)( ALuint asid, ALenum param, ALfloat* values ); + +/* Get an integer parameter for a Auxiliary Slot object. */ +typedef void (__cdecl *LPALGETAUXILIARYEFFECTSLOTI)( ALuint asid, ALenum pname, ALint* value ); +typedef void (__cdecl *LPALGETAUXILIARYEFFECTSLOTIV)( ALuint asid, ALenum pname, ALint* values ); + +/* Get a floating point parameter for a Auxiliary Slot object. */ +typedef void (__cdecl *LPALGETAUXILIARYEFFECTSLOTF)( ALuint asid, ALenum pname, ALfloat* value ); +typedef void (__cdecl *LPALGETAUXILIARYEFFECTSLOTFV)( ALuint asid, ALenum pname, ALfloat* values ); + + + + +/********************************************************** + * 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 + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* __efx_h_ */ diff --git a/openAL/include/xram.h b/openAL/include/xram.h new file mode 100644 index 0000000..5d83662 --- /dev/null +++ b/openAL/include/xram.h @@ -0,0 +1,94 @@ +#include + +// X-RAM Function pointer definitions +typedef ALboolean (__cdecl *EAXSetBufferMode)(ALsizei n, ALuint *buffers, ALint value); +typedef ALenum (__cdecl *EAXGetBufferMode)(ALuint buffer, ALint *value); + +////////////////////////////////////////////////////////////////////////////// +// Query for X-RAM extension +// +// if (alIsExtensionPresent("EAX-RAM") == AL_TRUE) +// X-RAM Extension found +// +////////////////////////////////////////////////////////////////////////////// + + +////////////////////////////////////////////////////////////////////////////// +// X-RAM enum names +// +// "AL_EAX_RAM_SIZE" +// "AL_EAX_RAM_FREE" +// "AL_STORAGE_AUTOMATIC" +// "AL_STORAGE_HARDWARE" +// "AL_STORAGE_ACCESSIBLE" +// +// Query enum values using alGetEnumValue, for example +// +// long lRamSizeEnum = alGetEnumValue("AL_EAX_RAM_SIZE") +// +////////////////////////////////////////////////////////////////////////////// + + +////////////////////////////////////////////////////////////////////////////// +// Query total amount of X-RAM +// +// long lTotalSize = alGetInteger(alGetEnumValue("AL_EAX_RAM_SIZE") +// +////////////////////////////////////////////////////////////////////////////// + + +////////////////////////////////////////////////////////////////////////////// +// Query free X-RAM available +// +// long lFreeSize = alGetInteger(alGetEnumValue("AL_EAX_RAM_FREE") +// +////////////////////////////////////////////////////////////////////////////// + + +////////////////////////////////////////////////////////////////////////////// +// Query X-RAM Function pointers +// +// Use typedefs defined above to get the X-RAM function pointers using +// alGetProcAddress +// +// EAXSetBufferMode eaxSetBufferMode; +// EAXGetBufferMode eaxGetBufferMode; +// +// eaxSetBufferMode = (EAXSetBufferMode)alGetProcAddress("EAXSetBufferMode"); +// eaxGetBufferMode = (EAXGetBufferMode)alGetProcAddress("EAXGetBufferMode"); +// +////////////////////////////////////////////////////////////////////////////// + + +////////////////////////////////////////////////////////////////////////////// +// Force an Open AL Buffer into X-RAM (good for non-streaming buffers) +// +// ALuint uiBuffer; +// alGenBuffers(1, &uiBuffer); +// eaxSetBufferMode(1, &uiBuffer, alGetEnumValue("AL_STORAGE_HARDWARE")); +// alBufferData(...); +// +////////////////////////////////////////////////////////////////////////////// + + +////////////////////////////////////////////////////////////////////////////// +// Force an Open AL Buffer into 'accessible' (currently host) RAM (good for streaming buffers) +// +// ALuint uiBuffer; +// alGenBuffers(1, &uiBuffer); +// eaxSetBufferMode(1, &uiBuffer, alGetEnumValue("AL_STORAGE_ACCESSIBLE")); +// alBufferData(...); +// +////////////////////////////////////////////////////////////////////////////// + + +////////////////////////////////////////////////////////////////////////////// +// Put an Open AL Buffer into X-RAM if memory is available, otherwise use +// host RAM. This is the default mode. +// +// ALuint uiBuffer; +// alGenBuffers(1, &uiBuffer); +// eaxSetBufferMode(1, &uiBuffer, alGetEnumValue("AL_STORAGE_AUTOMATIC")); +// alBufferData(...); +// +////////////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/openAL/libs/Win32/EFX-Util_MT/EFX-Util.lib b/openAL/libs/Win32/EFX-Util_MT/EFX-Util.lib new file mode 100644 index 0000000000000000000000000000000000000000..f984bc78127a5a932de4d368d4714f27db178e6a GIT binary patch literal 9072 zcmeHNdu&tJ89z>(#0@ENAziaJEpFnCltD1D38CfTK;lc769S|GN_ri~4=^(^b8aXE zrlKa%R8sz0r4^=)mbI&^`@ZkI&-Fd`t_Y_iJ6Dx1b{WHxdhfFO#)d{;gE8O3lgpMa6 zA;d*U@$moie|1|TnM|ySB|B5WL|-hN7Q%@>zkgd(TbutOvN{&uC#8~@UeD6W)Q%+{ zt$0uB5jlZ{p{D4rfqto_Z*L-<>f0UblQt&?VLF-skbiigWNjPdyZALGjDyS-M=y^?0;=qklfn z^0;1sidzz9bTwTcVMI0U^;-Mmi!-8%Tk7pappuR>EQz2!5@JIpPC_tN;^Yg@mxkrb z)%jwB2{T;GCJnLuhksv=du3jHIqq@2@cp;Pea=R4vwfo8tLz^=rFGq#V#!#zKi1t6 z*t+OJDUqy8_3nbXq--i2nos8vkEfvl_M>H9pHGJNlm=~!$jL{4)7p9)A&7AM?SmTImTeu!oSE2aA@aSCY;A#m!l7HDJz^jP7UL#A8VA+B?VxUDn9bah~+1_ARp$H8>TyN>@5Fh8Gx zzLx>>_ZjGOz~)ei8w7-W{#}8xYQU7h-iAS4uPo}j7%;0jPSFQ@P>Z+tyia%-j%cZf|O9*<9_y>Mtkqno=LRzq=!y+6DV)KknAJS$A)i!crmuG&raxi;*P61x+FiM}1KwW-~E63JMa5Zdgv zPhbUUx7&`1u_8#|Yh?xIvi%mHST77XUP>4Xzz!o5-N$B?nYeRdz^Y-uj**#0*7Wvn zS6N@w-kpp&^oawAWf#y2$yT{X?e3v7jxlr<+Ka%O01J(4@qwEox@#kam?ZPyA6#Z! zY@6&yA70AR$urG^w`Mc+y4qwHmLeLHSru!jq>4oCUidF2Zip8#sSe@=Oj-u9)_{b# z{g6S3|2ThEoy8<>r5KbhnGbRa8TzEGYgBSqj7*jfPk{>Y5z0OPxx~v62gH zJyi7YZtQkDN1NTw`vUIKfP3Wxbk@P5SMag&MrLa2@qqi$qE}EtPay?b>2)bc1GSmA z6iu|N_9hjpVjTygC-sE48ik_Fk!ijGOPfnKsWpslLm;lG3hagyO?wWVtmmk zCclEXgGp~gEU$7DBzYoU1*w{q`e1IgG3fwE>zOnJlE9=VK$5vX0ZC^34J6q{L4jgp zBS_7R@okWrnDiV-tC;i#NDnZn^n)7M4iEW{9X*QARpihEE$~*-4Cz(xoI8hG<TSCjSCf8%1MPvDppVd7K=(MxTsh) zF1WRF7Zqx$=%&I#D%MiLL&b$u@KMn-E;MQ=9~D+mv5^XXDz2bHGZp<*SVzTXDg>#x zjtU)A3{s(!iXBwgO2tkpbZhLbLuc$%=%Hda6{1w^p~6loMn{F@>4~DDOSZ=YJH^l# zF7LbHUtWymg|{BkyI9^9h;dw1keDjJh!E^5OR($!k_V{3awekHW4qGG0FX8YF0-EYohs7`C8^3m?d}u zDuqRW6<%}5#TP$1KYOFPrYPeP8YRb!2qYA7EfWe@$azb|-`#I3ahItXcO`hrc%z+R$?h@4m49Q;pRk zXA;B|5Pg5)Da+{3ER#R@Qc-Bb(Z~!==cqdg-b66#28ul4pwMG@3bI~R6>5nvk+rs;i%A9l`sG4kD9I5 zISVny7Msgh`Vl_c)MEG|RA|HP8PRtKI^dlI`w{~lKrmF8S`5$Vnm^Bc`WjG_T3luv zLJ(uD1jRz=bM&{Yb<3`M2wLIO{TMT@`=mGHC8>hg%~62E(1$=G25iE)^HYLjI1gH>xCmP z)o83uoP`)8>u$zUX56g9=T2*^Ud}>{k#)}PqKhRi* zISVmHmW#0z505a8BS&M;_*y7n(Ff#d2C>A=A7c z7@<%+DGl_;@LT!XR`z+9te);-K<+I9{z=}K`)PUlZ?Xz2?}u>f58TSfar1}iJl7SJ z@1n;00zUp(UQy$X=G+I!xi8?$`5x}e`Cjgg z+y3E1KKDE4{C?l}o%gx9=jsiibmWeW71!F0p|Q!`(&TM!ZFC#+U2?Kz{d!p%svv~e z2`L-@fBrUg#}kS8W+Bm^3dEB_D9wf9NuTfL_U>-qEo74r+bgCLnBL0LiPY_lF0FVt zb*GfT!eD!J*GNX}O74lLQ_0;zQtXS53MAN(O70QTV%OeCVk8q!C3{2Z&~8B#(iyev z#&AYVk3_@*rIEtS?E>fy>s1ERLMY*L$$Ua!HDF@E%ta6lp>6%i~(#s^z*|TE5XgkE=DNSD@k= zLyWGbn<9*;rrqxR{&-@HsN&YU!w6K;k>3bhApXhM;^r3%W z0%pZUAV65GzN-MUPKV2%ubqbgH>}f_ z&u##ei~{DEj4Oe3A-m^gjKOXm|K^u~Lp%R6;aomvjy}W{;b}@2d^W&I=ir=@%v(jMF^*TfAIpVd+_@oy(ViL%YjNxcqikm~i>W)k?tC%h*EWstyVo0n=9{ z)d7cgzHx>AJtJczB#tYye~3G@MBIz{aCzp(D}ej6j4f1;Hn4jNFtxZ)LxAa0a2seU;*swP`}$Mg6M)(n zi+IECaBHYhX!Hv1aDAQq+RiS2`%QuVz?RL|)php`fUTU&8v~s^?cH5{b$0BLRw6B( zO_A#cd()|1U@wCQ2s}Rw_K6`e9tp(5d5;!evchJmBcz<*h^{{-#aFA9wKr_P#(v|l z7~dTqjVEunccgX?#}h&tw$4sR$sD#h9dwjnVyYApxZYM{E;|C?6Pp?X4&idf0aEwY!BWrPcm#M6;YVVtjIrgCyh?O&Fh0NAECQBS+N3B!nDzq1Y zmlGDe9r(cg8r`*!VoZ{&;0G=3OxuX4WGbld~$;P)QYu z+THLgBMykyG06$>8YZYp$VcU(ONAAW!hi$UcVY|lfnDjf^=Ag6gE`1IkZ69YB z7Vh&q?kRl^CG-?hpp~8%1JvJ;eO=K+2O2Kmaf4EqGUS{q1E2fl+VTzaQ&urPu`rtz zt&*B^WolzqDiyGSeOopFBybpIo%;cBzsEc2_qP2J4&vZGK4ka32KT-6{QQ(n+(8d# zdp3ZkTC5cv*q}9N>0SB;Rmv6jt5`Qkx%`H6mq0xfC6Fwd&CXBxpgaA6>>t#Efk2_g zk+mDjrQs!Yw`?a69G|{*Untwt4?3&C<7zt4Ur1-Z^3u^unWIt}-_MU7t(;;tG3I1h z0ZxHI_?3}nh;L@n4!OnLw$iTg8>ST=XgVfHXCqdfCq*p+?o=Fw&tcD$Wzwe=g z2l2U)?7zN?kk30Iz46WC$8q<5^x(ngH^BpxytWzA5N`GX7V_Yg1vKG;Rm3(goJXbn)+H#-&4n8=A%lmHlNsFsssXrk6G^!@+FC|Gat~`Pf}@{K~IDC?+B!TkOiTXX$}TEwm_zoWwM25IHRpnldW=w zG1nAT)?fso+@#qGxkk<9Ce3(~%vTH4h@%3-MJCO-eHb-gWYWBhVOBzHf#2J+kKM1d zJ0a}A3AxK8&ARvRO2$IZF}(Hk*3UFnmy}5mQ$+Org{Lf|Kg&%1;7diZ1y7&YyZ`+0 zv;WX~_cqAEu-xPi9{Y+WR{Rm%fYB78fDz@PEjObPV zUU(70_Ty&nx;WGzbGu|C>9W7WZ~%2 zSYIx@oz+-Hva5(OvT(*|tkV1MBGnhgNH>?J^57M%F6EQbzc)`;Q;iSYerk z7$fUSgRPI=ocX238kJdyF|w{Qus;96-yhak_scBA7+H44Qan8H)RW+jGBzHPS%@*R zu4XJ{Htjid=77ffjm$y}uyp^Ysbehtyr?$K3usp8Q|xnGJy*Ya7L3RW$q`vtP3$@T zI2cQ*#s1?b9@qStmRX1~*5X?R*2LHo+cg#*+A$!;$oe+qXzR~|ZG7HTJ;)}<_44IHH&C&mo=|3Y5tB$^BR-p zwG49xVjK-W={*4F1i9(RZL;RICe2W>oYq*&H17jOFc?dSBN+id-*;?bU!2LN#qKKP zUTlzW33zh9b}#;!SYZ|XHlP2SyYju>{H?se4GQH`t?>$jN4_bbsBuSgt|;VOVesU9 zqW9!{!gmWf{AdJ&b|s>~RR+(6t`HQsqTp7qP{=n#3f<*!7q~0oE^z0;L0BoJc30x5Iq`)<{HU3B|7BTY-!@7-Is z>eRh;>-)-^59iBs7mqgWYj%I_?H!$MZSCD{`(1gPW^tKbFw zqNwdUnJ}9?d(czy^4^YpiiaOsX5_I%KMMu6Q5_Amul3vFXbo8L2 zW8Z@Z?Qc}ny`4zV{zXmS;0fx6{epT%743tI1nq&Z1P!z(Ix-JD(BNf7y{N08L6jkA zXjoD24ah-5*A*QEzMuoU6df#r7xcBF184(5hlUg#2ezaFo}fO|S<>5hf(B4mLH($& zB>1Nvbo?ttgUBzab&sMwS6~O|@SBSEp-e#?Unt7G27iOP#ue>DIf6R773ID|I;aa6 zf)0JGXfO07!PdQ?6B`xn`4)JfVfb0l2=oLE3mNDHVnNbxc!EY}6-@wB(nUN$V;?CR zMT`kL^@gJH4Mc**dK8`d8FJ7`_*c@qc!EwfDH;c!Bw&q$Ms5h2nHd?IoR~U2GcY*a zKQ%IWdSYs3VlgWAjdpg>%*^Vpp40KX|8X69{M^OT?x}1EG}ONHq)R5+%q+F&bW+8L^2p#+!2BJtMWz#sw*QHsXw)5Txjt zs55HJK91_E@t(x=RCn?OF=}zTv|OHx%xGjeqoD>LE6x`@fzeYM)0NVqh!D;hjgciK zRdH$FO{(Ih!|kh^rrfL&dDLii*`D#cn^*cuB{Fa7vRESbp;l+*dQqambdRu{L59mU zfC;0RP3YLz(8aisp@gQvEte?8jz$`Z*=lQJ<3Sh0kd$PykbgC9L&X`SScADms3c3t zFE7c#LT6E|SB?87M4tseKlzq&1F7mC}T`I+W2^>REY9L9g~)08Uv+e z4Gnd}u=JrqDKF;^BAxh}#@z*L!KB<*2%O;N1 zq`=qfFO-&|f#~wWoD5Z??TGz6Vg;Pc!lgC`0>Lh5=3>UCPcJW_u=)NHV(yBnuP?H? zVkLuB4A=EVRu@olXb51#ag8{l@&%z2^IWTcxm?Cli^D?Km)aa@%P|z6CboG{p0`XB z)p0~z*IB4ZuO?S&bN%HgUx|3FJ&7%GAX=)FORsWOUu1QK<*KcgSOla_w_LIJeBkLYdCHIy^jkNSYVf?OOJ?18OUfbk~k zSpeP_sQ+uI_jng{z;~nG-+})W{KqJBd@pc88&42@i+qd2kd5FS&#RFA2AUm3-U*_M zppVAjGw^SmBHDoSfFAHa<9*jjqIW?}c)tqyZ=f3}2gg*jfgYj;YLw5rXdSJkJE@88 zrhDji+CjZEPN!&;j?rzj9VQOZee?j`OY7-=dXW0*1U*I%(*O;_yb;<=TdA40(9^Vy z9;J55Q5$toCw0+Dx`X=Y5!y+Q)04E3HqjIG6z!%~>Y)SFP5bEx9iqe3LI>$6?V>%j z7Y#B-Q#4Hz^bAeXd3u@7(F{FLFVSgwj$Wi^=>?jlJe{R8^#5D)HStc??p;@MZlZTV zW*@Bju`N-boT$w|U-@eZTjd7NIn3~&PZ8LHLrD_l@b!L`LzpVNp~TXy${b(oqQg|( zUoG;}B%=eFTCift5X<6~VN%9Cfzeuf6`K~WDbK9<_Q-0cDSA8Ggnw;j?qUd2)}v{w zLpI5=I_kv)lO)%#)t8cvxyjicl{5Qs9)euV;)jV{_n0y~2N`jC5uTG$=YAlnR`+VB zg>J!0=+;cj+*nY;w9HrDmWXwD(V%8a1N=|N@ z_8%)uOISW7nG9`ljS*T^Zn2XxRz0N{+H?NS9@i~h9n2(U3B+nUR#l&b8+aTmm4sg$ zZ>H{u>fTrwJ4{BqMM@-8Qa3iPH=O069rXM~vMsuv^{>r@?pbwLfV7kWO|IS5c`q*| zIWh&e1Ae~@?=@;(c-tCP-DLSYHS-NZ^j`apSTXPJmkOq&PR8sEV)R8+nZrnxD0j%- zd@MKD>^#NWcvm?Chm zS5+C0L^EGXOgmGm?*s9^Px0*Afu0wo+{}oQ(a|Mbi_+s*ldKsrRTCoJ3QX;cz?for z*;p)xpTQdB%xw}?dD&uW))b&vgQq!zrdU_iBAK4SKc2}CCe9IC>Ngctu5gkuP*u-z z64G$8a+Z;GGn}KRYNpCo<>_~+rQY=%V-DCQD@)YLiKAPV=*}gk2s4YgJj^aCEouT24%hkVFi=xEW z?$-H2L7bWV-Yt^-9i93<$!ybT!x~!q!H>s(Y#{8&vF9ghxVzyFyaj&ik=97qt5^T6 zkx5V#y5f&~+DG+_|AUm)`RM%eD_f@x6pl`)0Q>o`m)0L|U6{v5`K>rTQ9oQ&pua-z zA6i$~*h_7nX+50qsNcPK{D=mHA`KKsYm6i(bRZzB(-ljEe6#qYf1-38kZDdl8gaxz*v+lvAfkGA zXyPW<(jPjy^s!;H=nsvuKm1KrPgIf`(&A-aCdGePyx??A{Y1R{#W4CQ;^h{_K`m|j z1gcT>PE6f?>uFDnBmV|~YUp&oy_N8X?PoZRR6h}p|1^w#vVMk>OZ5|a|1ykzuCjk? z@#&L*Ud3q48K)u|F$|!Sjy8x9`XOoIo%S4$w-(hM^C6T5%mm`zi@4L05v5B9h-b@V zu%%I;m^}hkQMV3hjf1q170KSsblc}~*mN65lKZ5LR^`(D_b9M#=UATmIBG2;U@p*3 zcQ`ngvwAOJk@zNHBf@K@)wJkN2PdmVUFLGG7vo}BxJx0qC(_&$$D6gZR0yq!qp4;5 zk^|r{wV>q!t#!9X)3+dQnN{m74m%RKWoY+kH0Qh_8=6^Mc=6GU__)_Wvxga(@N#Bx z@8LZHy!#ZMJ}Gfv>YqUZOmjN z8>l#PO?^3lwIRkb$6vho`p1m`)Q0aOjfnY;7E2$OW{bjr2Osy4JfrIO;DL0j#D;5=#fp!c9K-5I3#`|k zh|%OZ@~uO9(juu->WoN%xOmD%@*0cd)-)0Z;-c9inFDrS`U>`0fe~Y~kCoA`(Asc| z#WE+_{+5f|S&J7#Xiq26ydkPyv|ONnZB3wM9p^)~ZA+qMY`2hY+Y@M>BkLYJLbmNl zqGhzLtIBD{Qy3RpEE@lo#3N&M``b>7r&fwtdq6JGw|DtiUbAs4Yw2ydz?ik$!^#@{ zA-neYSQ+CZWY=B~%X4Afksq?F)yK+eS70{V7h|cb?mQUkUuy@}0&NP(Uh#2&>i1v3 zrgnp5{_nwo;!G{k-c`k>r!i`DSS0_8FGpFy$WaAToKhiEM_pd;Fbh}vI5XD=rmiP#b8v8vYuOrv*!GKjgE|%xO)wJq>hm_f>K(rrJ zSm~2w{r(Fe9deL7_tlRSn2!&0By~4~H;>b!Yl^_Ydh|#FD|2fFdht;QO~dO z9r~U);^1VqDA1cvY9xMhjayRx*wIyGEwB}FcuJv}3vm2ioCC_4T6`HABS&3KQMCSl zK8~^iI|JXW##~HurOyH6OieZhzM+nLc=Em=2XN-QTF^r0EfYQ(E+aZ%_4m0zgiabX z_V2sd&_d@e&loi4B4tLrK%`7*Jnx#O1IU?L+Ah=^rZryj4k$-iL2sxsK8xMxX@=?E zFwKY==n-dP%qkxgICd>w%~cuK#5b9<3@!OVp>Cu=Z+JFFvNvye`73C-Ky*GAqg6eA zuEBxClAfWi{@$KV@t(wrt}SsE?(G?h_a~MNcXkgBboKVM zcJy~_iYMaz17^{(wF8O%!OnzpVP{6(@;HRors=I&(;x5X4pzsis$+G54rX1~2PmoQ zd6d%1J1NDi^0*Bjx8c|6#9ypF#Xq5R|^4-QuVH>S;vVM zZf^Bj0-D#IwUwPz6ZR+1yJ~X=w&%Mr@n+@n$;VuO^1uI|O_+WE+h&t(I$bP^Rn?i% ztv$cIZMe3ktv}u!?-+=;Em^wi`dboR-Q~S&?_&8C=A@JGOuChUKy7WU&sSMpS1%~- z`LTPO*siUwHvRXNj2*{}rBoj4k9Q`9;^K<23K(}!Hm~Gwz8ARo+QIey6=umc7~i$w zg3P~ROQLu_BjMdC=nV$#erKa_2)L&t)`M$aKbs!qzj1+HAXx5zJ2+0VhH_L9_56n-diZd?bwsNb-T^CI7a(=;-WES!U06)-p0aW=ha&}aju&yI7@`#LaB z+Hp3$BIvyg%sY0RgWhj|IcLY&^nB1ODrBr42c>N7y%m_XcAQP`I%sSKX15*ZP`@{U z`8PYxrbqMiw-Q73qr}I}VP1VUP8_>b=$PkBdY*CO^2UjqGESU#oVaP@#1)MbH)EVQ zpA*iuF3%y5`GLEN768&EI5Mrv9l-3CIBWjd<^fIPH-R~7$2rWaPl54VMqbnAvrUiI zQ3){f?KlU$RlvmTIGf%K=zSHKr|mcgy*Uva#DM9u<81Aq`S*2Tp0VQ`^!5VtwjF2Fqkj3d#85jZIrYo85I4>O_sHi3CR@M! z5}1!AE?d7$#^U@uEl?y2=g^LMz$~%jZ0(@o>ICL5?KlU$CxCg*j>Ry*MymwBu}gG!GsEW~UwJpf>`{Av?~dN9*^5#K7c< z<^gWkD;k$94c*ebvbkyT{1TkPEh|g(%w^4uH-}o5tSIr(?dB&qhH)%pF23=1&Tnh& z@4XAR>jU&qK+gniD-s=vuFmGJwfvD`xzi&<9lN~HwH9|&tN>!O_lt8&S7(3kK<~PQ zuXK5tZ&_cWYg5;juAcS2aPOwRuI_k0V;=#|=ze_?4v)H|tT&r>;o3UJ>QHp=N4fNhyD=rL~F`}!H!fOcIMk5Q(*dN_~(Ac&fcgQQE_nd4u<)W#d7!@N!x$tnpYi1f1 zqeE`tGvqPKN488bwv~bzO?LZ-qsbTjTj3#^+~dC=zeZWY-)fZI?GH8@WsUy8nMPUD zGe%*PC-tT7)bEYbPf*tE_uccM3r#wesDvlp8Aj>;Gsfyr5j+AOD%uRUBO#+=uekDr zj8b6+&mPDjWzPDSQ%BC9PlS=@Ni2lK7^=a3IEG$16EaqhT+rKn={FBmbJ zM^kSsIAkmvNrwF-Vcd2;QK45TTq-IQF69+6Dh{AN;zC&9&+9?8_$axt9%|l3qZAz!P07wpp{EmNqI<#(jiN`w4V!t7$oe!;<#>G>pn&c# zMfV$}7>Puktv$`MJj2JT68{vISV5;@ ziM3IJWwnaq+F;$ntr#qU+X74APQzNxOAXA`W!zc-tC?G^u$s8F5f(iunkf#$jXE+W zELxSNJg*pMN@4M1!w59(WlM3mSrs%%+e}WnD+K?|ZIr#~q5Pm`hEcDGBb`5;Zgs&^mrpwT#OJZJ@yHY&3n{D%fA(Z@hoh;Z(bOM|ZEvAKtu!wpsV!29m^emtQn=N*bdBX|u2gtKxfN8+ z7--yf7OT&lisU83o-@X^%cdCR|GH)3AR_tx69tHaca9=>j!5;wa2{d2*)dZHGc7yD zn~D@A!_!ic8Od-_D&k9qXAsMuo#jhKN)c{Tk?WG-(o`gn3}2Uu)Fi_J;?`&9)}$g0 z$#8ut5=@30Qjx}FIGBn=li|ixq&XRmrXsD$aC0iMG8t}7MOG!l6tb4JL6e8VEjfuo zy*CiQM6eYBlVaGaRHQu_Zc9aCJbop^?WxFyWH^?JbdQYX-gC^A3~z|0+WdVK+19*< z_tzMc2XJ`!921-E&A5*7yjyWja%&yVVx#VbC1M=irihLDSy+NQYFQ^Oi{hRrz0o1@5wnVj^uaAa}e1Xc+B$*ZH(NO~9f=HC z2ff__S)7~0a%Cho`-gf?DC#W{{X=>tl5D5?3#4l*ZqI58*whz{KGY2BI2hy+<7=Q< z5hGwljKoGPhDj78e0*`QZo<9SCFH|g)|cVtiD#JmuerM2U>YVkCsE{xMU$)YqRBol?durm!%eAAqp8#Mz_g8SL|eA+HMXsQ zfyMX*?7-g86r-$f%qSZ^VwAp#y*)_JY-0B|R=tCp=}}}xU&g8R`7=h_`$ol^Llf!g z$8%!R8Dmul8g00nzm`8z@Vfx(*@DO+qkNPy_&Y!Z2s0?~z5XEf`q#{8FaaWyLAhxP zaWdnUQmt3eDV&EYqYk{5>2(W>y3rj5uiIqWQ(MjIWR^y|L>2O=3Vfptnme(otJsNG z`h5U2d-H?XYnxJcc$-oKMNO%HryxbQ_AwkDM)6aGp}&SD!qBs@rt{KQ za28?cL(2+bm_*)PmUSO2dckC-U&0WRT39rx;g*7lgy8;Sy;4z9>w8i0cevCGl_Ct|Hm9z%qB1<_1XO% z&4;cmG>X6yKBy+-$4pK>-a{e!W>y}X1s}y|!xZ@N4CiWosNPClSTth7PkO7#my;iX zEcWCu&jz#y$s7k7A;Hjl>=^RhI24j>C+%a%cQe=Y32b_-kWH`gvgwB}>kD?`wN80g zZ1(;hcK$pe(*N-5B91Hl762JY>3{Uam;$qn=ck|2|DZ}Wbh~Jslj8TD+jkA4$3mWH zG%2~64|!|WbteV~;xUm&DE@zB)|uCYNmnLzCS`h5rsUzu_|G+#3f>jjbf|7_7ro=A z8h-Z4?p@?tq+2jI{oVYxURUkIEIy{`6@uJ^7Ztd_8%$M$DG6X%TTO> zwAZ)P8n=s9H~BhP()6BUO_2k~F`6%4H>+JUZ~TjZV$G2(QU7#b^diIUqUc1vjx^;D zD%OpX#W9+%OF7Hz!#!WQ>0ZU^k}QtV+C}Tb?eftX$L#MP`+{QKFIgO;`QrUxwd%R{D^!tjnRk8@9v*`Xt)o}NNFI}xz4@(wdbe2zJo%`}9-%_j{l0_Ju zRjjdwUi#I8iuD7@B1{hRH{U$B78WInY!kG7rvy1}7rm6AD09;L5&|49c-kvTp;&*AERNB9VT(=k)$qIj98;_- zXu%_KjOJ?=a#j2pdum=lu@*=c$7sH2FH`N>H@4+xiq$4r9HaRvJEz z7msp$ltE`lXYX9ASmz~6M8fo)`g-om+~041??k7XnKNZJVf6W2uCX2~cv_rI7|mBTXPM)^b@=j+6zj*5#W9+% z8qL?7_=0?ikVg<_3K7RPA58Y~tJJ{F3VPq*Yq9HWf|^}Ie7^iIR=qGxAX7d?+neN?TB z>!r@Z3&w(;+SFL=IoIr3XpKcwvN%So^CHeN$71Jqy=98kEm<6+^-oaq_1wEHClu>p z$>JEzSBSIdeue_l!l9Xa6zfIF;uy`>V$L$x`!@I8)rxgQvN%Tb73M56&M&@i{!NPY znPhQ{=BrWj^_?#sKd)H6i6}(k7|qubzZ|%!p^X+(C zu{KB+$7sGHoMq1E+SmNgDAog##W9+%sOD=~DDtpk{XnufM)TFgSu{5&z1lK*jba^^ zERLc1Tul*;63yNT>~|<%l(2-f zb0rHvbXv{D6tVz>LiNQIvH*la;9?3{074;SFUY~qRBjEw?K>;;J1og_{;teiu4e5s zpyZ;x2+GzIS+%V0$bi!NBm+k87-x`dz0(JG_O?4>Y%O=h*xK!g5js|@9Wh#)9T9qq zogn6DJA5c8+goRiq7z2cGdo7qvvwRh*)c-LTHebt*C#th=va$9i%xco(6PoSi%xco N(8)Fu`Zzi{`X8r19rXYJ literal 0 HcmV?d00001 diff --git a/openAL/libs/Win64/EFX-Util_MTDLL/EFX-Util.lib b/openAL/libs/Win64/EFX-Util_MTDLL/EFX-Util.lib new file mode 100644 index 0000000000000000000000000000000000000000..8a926e5c1949624d5c37d672f0b065040b30f996 GIT binary patch literal 15308 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 literal 0 HcmV?d00001 diff --git a/openAL/libs/Win64/OpenAL32.lib b/openAL/libs/Win64/OpenAL32.lib new file mode 100644 index 0000000000000000000000000000000000000000..17663e0a388887093e8cff00a892b0c8c4851360 GIT binary patch literal 19858 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 literal 0 HcmV?d00001 From 0c73b5a5869626a46ddbef8524d54cd879201532 Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 30 May 2016 11:58:34 +0200 Subject: [PATCH 2/8] Settings aangepast, als het goed is zit het er nu volledig in --- CrystalJohan.vcxproj | 8 ++++--- OpenAL.cpp | 57 ++++++++++++++++++++++---------------------- OpenAL.h | 5 ++-- 3 files changed, 36 insertions(+), 34 deletions(-) diff --git a/CrystalJohan.vcxproj b/CrystalJohan.vcxproj index 1b7f959..2372055 100644 --- a/CrystalJohan.vcxproj +++ b/CrystalJohan.vcxproj @@ -103,12 +103,13 @@ Disabled _DEBUG;_CONSOLE;%(PreprocessorDefinitions) - freeglut/include + freeglut/include;C:\Program Files (x86)\OpenAL 1.1 SDK\include Console true - freeglut/lib + freeglut/lib;C:\Program Files (x86)\OpenAL 1.1 SDK\libs\Win32 + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;OpenAL32.lib;%(AdditionalDependencies) @@ -127,7 +128,8 @@ true true true - freeglut/lib; openAL/libs + freeglut/lib; openAL/libs/Win32 + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;OpenAL32.lib;%(AdditionalDependencies) diff --git a/OpenAL.cpp b/OpenAL.cpp index 36073c9..fd95666 100644 --- a/OpenAL.cpp +++ b/OpenAL.cpp @@ -2,33 +2,29 @@ #include #include #include -#include -#include +#include "al.h" +#include "alc.h" -int OpenAL::endWithError(char* msg, int error = 0) +OpenAL::OpenAL() +{ + Test(); +} + +bool OpenAL::EndWithError(char* msg) { //Display error message in console + bool error = false; std::cout << msg << "\n"; system("PAUSE"); return error; } -OpenAL::OpenAL() -{ - Test(); - -} - -OpenAL::~OpenAL() -{ -} - -boolean OpenAL::Test() +bool OpenAL::Test() { //Loading of the WAVE file FILE *fp = NULL; //Create FILE pointer for the WAVE file fp = fopen("WAVE/Sound.wav", "rb"); //Open the WAVE file - if (!fp) return endWithError("Failed to open file"); //Could not open file + if (!fp) return EndWithError("Failed to open file"); //Could not open file //Variables to store info about the WAVE file (all of them is not needed for OpenAL) char type[4]; @@ -41,16 +37,16 @@ boolean OpenAL::Test() //Check that the WAVE file is OK fread(type, sizeof(char), 4, fp); //Reads the first bytes in the file if (type[0] != 'R' || type[1] != 'I' || type[2] != 'F' || type[3] != 'F') //Should be "RIFF" - return endWithError("No RIFF"); //Not RIFF + return EndWithError("No RIFF"); //Not RIFF fread(&size, sizeof(DWORD), 1, fp); //Continue to read the file fread(type, sizeof(char), 4, fp); //Continue to read the file if (type[0] != 'W' || type[1] != 'A' || type[2] != 'V' || type[3] != 'E') //This part should be "WAVE" - return endWithError("not WAVE"); //Not WAVE + return EndWithError("not WAVE"); //Not WAVE fread(type, sizeof(char), 4, fp); //Continue to read the file if (type[0] != 'f' || type[1] != 'm' || type[2] != 't' || type[3] != ' ') //This part should be "fmt " - return endWithError("not fmt "); //Not fmt + return EndWithError("not fmt "); //Not fmt //Now we know that the file is a acceptable WAVE file //Info about the WAVE data is now read and stored @@ -64,7 +60,7 @@ boolean OpenAL::Test() fread(type, sizeof(char), 4, fp); if (type[0] != 'd' || type[1] != 'a' || type[2] != 't' || type[3] != 'a') //This part should be "data" - return endWithError("Missing DATA"); //not data + return EndWithError("Missing DATA"); //not data fread(&dataSize, sizeof(DWORD), 1, fp); //The size of the sound data is read @@ -80,18 +76,18 @@ boolean OpenAL::Test() unsigned char* buf = new unsigned char[dataSize]; //Allocate memory for the sound data std::cout << fread(buf, sizeof(BYTE), dataSize, fp) << " bytes loaded\n"; //Read the sound data and display the - //number of bytes loaded. - //Should be the same as the Data Size if OK + //number of bytes loaded. + //Should be the same as the Data Size if OK - //Now OpenAL needs to be initialized + //Now OpenAL needs to be initialized ALCdevice *device; //Create an OpenAL Device ALCcontext *context; //And an OpenAL Context device = alcOpenDevice(NULL); //Open the device - if (!device) return endWithError("no sound device"); //Error during device oening + if (!device) return EndWithError("no sound device"); //Error during device oening context = alcCreateContext(device, NULL); //Give the device a context alcMakeContextCurrent(context); //Make the context the current - if (!context) return endWithError("no sound context"); //Error during context handeling + if (!context) return EndWithError("no sound context"); //Error during context handeling ALuint source; //Is the name of source (where the sound come from) ALuint buffer; //Stores the sound data @@ -100,7 +96,7 @@ boolean OpenAL::Test() alGenBuffers(1, &buffer); //Generate one OpenAL Buffer and link to "buffer" alGenSources(1, &source); //Generate one OpenAL Source and link to "source" - if (alGetError() != AL_NO_ERROR) return endWithError("Error GenSource"); //Error during buffer/source generation + if (alGetError() != AL_NO_ERROR) return EndWithError("Error GenSource"); //Error during buffer/source generation //Figure out the format of the WAVE file if (bitsPerSample == 8) @@ -117,11 +113,11 @@ boolean OpenAL::Test() else if (channels == 2) format = AL_FORMAT_STEREO16; } - if (!format) return endWithError("Wrong BitPerSample"); //Not valid format + if (!format) return EndWithError("Wrong BitPerSample"); //Not valid format alBufferData(buffer, format, buf, dataSize, frequency); //Store the sound data in the OpenAL Buffer if (alGetError() != AL_NO_ERROR) - return endWithError("Error loading ALBuffer"); //Error during buffer loading + return EndWithError("Error loading ALBuffer"); //Error during buffer loading //Sound setting variables ALfloat SourcePos[] = { 0.0, 0.0, 0.0 }; //Position of the source sound @@ -145,7 +141,7 @@ boolean OpenAL::Test() //PLAY alSourcePlay(source); //Play the sound buffer linked to the source - if (alGetError() != AL_NO_ERROR) return endWithError("Error playing sound"); //Error when playing sound + if (alGetError() != AL_NO_ERROR) return EndWithError("Error playing sound"); //Error when playing sound system("PAUSE"); //Pause to let the sound play //Clean-up @@ -158,4 +154,9 @@ boolean OpenAL::Test() alcCloseDevice(device); //Close the OpenAL Device return EXIT_SUCCESS; +} + + +OpenAL::~OpenAL() +{ } \ No newline at end of file diff --git a/OpenAL.h b/OpenAL.h index fdf32ae..39b7e30 100644 --- a/OpenAL.h +++ b/OpenAL.h @@ -2,9 +2,8 @@ class OpenAL { public: - int endWithError(char* msg, int error = 0); OpenAL(); + bool EndWithError(char* msg); + bool Test(); ~OpenAL(); - boolean Test(); - }; From a80fc690437387d0061455232f8a2949f040ed37 Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 30 May 2016 11:59:36 +0200 Subject: [PATCH 3/8] .wav file toegevoegt --- CrystalJohan.vcxproj | 3 +++ CrystalJohan.vcxproj.filters | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/CrystalJohan.vcxproj b/CrystalJohan.vcxproj index 2372055..b2e698d 100644 --- a/CrystalJohan.vcxproj +++ b/CrystalJohan.vcxproj @@ -189,6 +189,9 @@ + + + diff --git a/CrystalJohan.vcxproj.filters b/CrystalJohan.vcxproj.filters index 1a2e551..e5e14d2 100644 --- a/CrystalJohan.vcxproj.filters +++ b/CrystalJohan.vcxproj.filters @@ -108,4 +108,9 @@ + + + Resource Files + + \ No newline at end of file From f0a833081997d4e87cd71efe3b98290d7b2cb484 Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 30 May 2016 12:46:49 +0200 Subject: [PATCH 4/8] Werkt, maar loopt vast --- Enemy.cpp | 3 ++- OpenAL.cpp | 21 +++++++++++---------- OpenAL.h | 4 ++-- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/Enemy.cpp b/Enemy.cpp index c62fb46..3ee1faf 100644 --- a/Enemy.cpp +++ b/Enemy.cpp @@ -1,6 +1,6 @@ #define _USE_MATH_DEFINES #include - +#include "OpenAL.h" #include "Enemy.h" #include "Model.h" #include @@ -53,6 +53,7 @@ void Enemy::update(float delta) { if (hasTarget) { + OpenAL(); //just 2d walking float dx, dz, length; diff --git a/OpenAL.cpp b/OpenAL.cpp index fd95666..092411f 100644 --- a/OpenAL.cpp +++ b/OpenAL.cpp @@ -2,24 +2,25 @@ #include #include #include -#include "al.h" -#include "alc.h" +#include +#include OpenAL::OpenAL() { - Test(); + Init(); + } -bool OpenAL::EndWithError(char* msg) +int OpenAL::EndWithError(char* msg) { //Display error message in console - bool error = false; + int error = 0; std::cout << msg << "\n"; system("PAUSE"); return error; } -bool OpenAL::Test() +int OpenAL::Init() { //Loading of the WAVE file FILE *fp = NULL; //Create FILE pointer for the WAVE file @@ -76,11 +77,11 @@ bool OpenAL::Test() unsigned char* buf = new unsigned char[dataSize]; //Allocate memory for the sound data std::cout << fread(buf, sizeof(BYTE), dataSize, fp) << " bytes loaded\n"; //Read the sound data and display the - //number of bytes loaded. - //Should be the same as the Data Size if OK + //number of bytes loaded. + //Should be the same as the Data Size if OK - //Now OpenAL needs to be initialized + //Now OpenAL needs to be initialized ALCdevice *device; //Create an OpenAL Device ALCcontext *context; //And an OpenAL Context device = alcOpenDevice(NULL); //Open the device @@ -142,7 +143,7 @@ bool OpenAL::Test() //PLAY alSourcePlay(source); //Play the sound buffer linked to the source if (alGetError() != AL_NO_ERROR) return EndWithError("Error playing sound"); //Error when playing sound - system("PAUSE"); //Pause to let the sound play + //system("PAUSE"); //Pause to let the sound play //Clean-up fclose(fp); //Close the WAVE file diff --git a/OpenAL.h b/OpenAL.h index 39b7e30..6b16ffa 100644 --- a/OpenAL.h +++ b/OpenAL.h @@ -3,7 +3,7 @@ class OpenAL { public: OpenAL(); - bool EndWithError(char* msg); - bool Test(); + int EndWithError(char* msg); + int Init(); ~OpenAL(); }; From 0afbca8ffc55bb2e6d29632698b00f81f02b4370 Mon Sep 17 00:00:00 2001 From: Aaldert Date: Sun, 5 Jun 2016 15:26:14 +0200 Subject: [PATCH 5/8] More Generalized --- Enemy.cpp | 7 +++++-- Enemy.h | 3 +++ OpenAL.cpp | 20 +++++++++++++------- OpenAL.h | 5 ++++- 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/Enemy.cpp b/Enemy.cpp index 3ee1faf..730835a 100644 --- a/Enemy.cpp +++ b/Enemy.cpp @@ -5,7 +5,6 @@ #include "Model.h" #include - Enemy::Enemy(const std::string &fileName, const Vec3f &position, Vec3f &rotation, @@ -21,6 +20,7 @@ Enemy::Enemy(const std::string &fileName, speed = 1; radius = 10; hasTarget = false; + openal = new OpenAL(); } @@ -51,9 +51,12 @@ void Enemy::draw() void Enemy::update(float delta) { + if (!openal->isMusicPlaying()) { + openal->playMusic(); + } if (hasTarget) { - OpenAL(); + //just 2d walking float dx, dz, length; diff --git a/Enemy.h b/Enemy.h index 9c14fb9..9d60def 100644 --- a/Enemy.h +++ b/Enemy.h @@ -3,6 +3,7 @@ #include "Entity.h" #include #include "Vector.h" +#include "OpenAL.h" class Enemy : public Entity { @@ -16,5 +17,7 @@ public: void update(float); void draw(); +private: + OpenAL *openal; }; diff --git a/OpenAL.cpp b/OpenAL.cpp index 092411f..138fe80 100644 --- a/OpenAL.cpp +++ b/OpenAL.cpp @@ -7,7 +7,6 @@ OpenAL::OpenAL() { - Init(); } @@ -20,8 +19,10 @@ int OpenAL::EndWithError(char* msg) return error; } -int OpenAL::Init() -{ +int OpenAL::playMusic(void) { + //start nieuwe thread + //speel sound; + isPlaying = true; //Loading of the WAVE file FILE *fp = NULL; //Create FILE pointer for the WAVE file fp = fopen("WAVE/Sound.wav", "rb"); //Open the WAVE file @@ -77,11 +78,11 @@ int OpenAL::Init() unsigned char* buf = new unsigned char[dataSize]; //Allocate memory for the sound data std::cout << fread(buf, sizeof(BYTE), dataSize, fp) << " bytes loaded\n"; //Read the sound data and display the - //number of bytes loaded. - //Should be the same as the Data Size if OK + //number of bytes loaded. + //Should be the same as the Data Size if OK - //Now OpenAL needs to be initialized + //Now OpenAL needs to be initialized ALCdevice *device; //Create an OpenAL Device ALCcontext *context; //And an OpenAL Context device = alcOpenDevice(NULL); //Open the device @@ -143,7 +144,7 @@ int OpenAL::Init() //PLAY alSourcePlay(source); //Play the sound buffer linked to the source if (alGetError() != AL_NO_ERROR) return EndWithError("Error playing sound"); //Error when playing sound - //system("PAUSE"); //Pause to let the sound play + system("PAUSE"); //Pause to let the sound play //Clean-up fclose(fp); //Close the WAVE file @@ -154,9 +155,14 @@ int OpenAL::Init() alcDestroyContext(context); //Destroy the OpenAL Context alcCloseDevice(device); //Close the OpenAL Device + isPlaying = false; return EXIT_SUCCESS; } +bool OpenAL::isMusicPlaying() +{ + return isPlaying; +} OpenAL::~OpenAL() { diff --git a/OpenAL.h b/OpenAL.h index 6b16ffa..1b04099 100644 --- a/OpenAL.h +++ b/OpenAL.h @@ -4,6 +4,9 @@ class OpenAL public: OpenAL(); int EndWithError(char* msg); - int Init(); + int playMusic(void); + bool isMusicPlaying(); ~OpenAL(); +private: + bool isPlaying; }; From 47b4d9570d3042d69ffae16b2b3c4255e3c6278f Mon Sep 17 00:00:00 2001 From: Aaldert Date: Sun, 5 Jun 2016 17:25:04 +0200 Subject: [PATCH 6/8] Music Handler --- Enemy.cpp | 8 +-- OpenAL.cpp | 195 ++++++++++++++++++++++++++++------------------------- OpenAL.h | 31 +++++++-- 3 files changed, 131 insertions(+), 103 deletions(-) diff --git a/Enemy.cpp b/Enemy.cpp index a2274d0..ad5243a 100644 --- a/Enemy.cpp +++ b/Enemy.cpp @@ -19,7 +19,7 @@ Enemy::Enemy(const std::string &fileName, speed = 1; radius = 10; hasTarget = false; - openal = new OpenAL(); +// openal = new OpenAL(); } @@ -66,9 +66,9 @@ bool Enemy::hasCollison(Vec3f &) void Enemy::update(float delta) { - if (!openal->isMusicPlaying()) { - openal->playMusic(); - } +// if (!openal->isMusicPlaying()) { +// openal->playMusic(); +// } if (hasTarget) { diff --git a/OpenAL.cpp b/OpenAL.cpp index 138fe80..613fb7c 100644 --- a/OpenAL.cpp +++ b/OpenAL.cpp @@ -5,102 +5,40 @@ #include #include -OpenAL::OpenAL() +SoundSystem::SoundSystem(): + device(nullptr), + context(nullptr) { - + device = alcOpenDevice(nullptr); + if (!device) + return; + context = alcCreateContext(device, nullptr); + if (!context) + return; + alcMakeContextCurrent(context); } -int OpenAL::EndWithError(char* msg) +SoundSystem::~SoundSystem() { - //Display error message in console - int error = 0; - std::cout << msg << "\n"; - system("PAUSE"); - return error; + alcMakeContextCurrent(nullptr); //Make no context current + alcDestroyContext(context); //Destroy the OpenAL Context + alcCloseDevice(device); //Close the OpenAL Device } -int OpenAL::playMusic(void) { - //start nieuwe thread - //speel sound; - isPlaying = true; - //Loading of the WAVE file - FILE *fp = NULL; //Create FILE pointer for the WAVE file - fp = fopen("WAVE/Sound.wav", "rb"); //Open the WAVE file - if (!fp) return EndWithError("Failed to open file"); //Could not open file - - //Variables to store info about the WAVE file (all of them is not needed for OpenAL) - char type[4]; - DWORD size, chunkSize; - short formatType, channels; - DWORD sampleRate, avgBytesPerSec; - short bytesPerSample, bitsPerSample; - DWORD dataSize; - - //Check that the WAVE file is OK - fread(type, sizeof(char), 4, fp); //Reads the first bytes in the file - if (type[0] != 'R' || type[1] != 'I' || type[2] != 'F' || type[3] != 'F') //Should be "RIFF" - return EndWithError("No RIFF"); //Not RIFF - - fread(&size, sizeof(DWORD), 1, fp); //Continue to read the file - fread(type, sizeof(char), 4, fp); //Continue to read the file - if (type[0] != 'W' || type[1] != 'A' || type[2] != 'V' || type[3] != 'E') //This part should be "WAVE" - return EndWithError("not WAVE"); //Not WAVE - - fread(type, sizeof(char), 4, fp); //Continue to read the file - if (type[0] != 'f' || type[1] != 'm' || type[2] != 't' || type[3] != ' ') //This part should be "fmt " - return EndWithError("not fmt "); //Not fmt - - //Now we know that the file is a acceptable WAVE file - //Info about the WAVE data is now read and stored - fread(&chunkSize, sizeof(DWORD), 1, fp); - fread(&formatType, sizeof(short), 1, fp); - fread(&channels, sizeof(short), 1, fp); - fread(&sampleRate, sizeof(DWORD), 1, fp); - fread(&avgBytesPerSec, sizeof(DWORD), 1, fp); - fread(&bytesPerSample, sizeof(short), 1, fp); - fread(&bitsPerSample, sizeof(short), 1, fp); - - fread(type, sizeof(char), 4, fp); - if (type[0] != 'd' || type[1] != 'a' || type[2] != 't' || type[3] != 'a') //This part should be "data" - return EndWithError("Missing DATA"); //not data - - fread(&dataSize, sizeof(DWORD), 1, fp); //The size of the sound data is read - - //Display the info about the WAVE file - std::cout << "Chunk Size: " << chunkSize << "\n"; - std::cout << "Format Type: " << formatType << "\n"; - std::cout << "Channels: " << channels << "\n"; - std::cout << "Sample Rate: " << sampleRate << "\n"; - std::cout << "Average Bytes Per Second: " << avgBytesPerSec << "\n"; - std::cout << "Bytes Per Sample: " << bytesPerSample << "\n"; - std::cout << "Bits Per Sample: " << bitsPerSample << "\n"; - std::cout << "Data Size: " << dataSize << "\n"; - - unsigned char* buf = new unsigned char[dataSize]; //Allocate memory for the sound data - std::cout << fread(buf, sizeof(BYTE), dataSize, fp) << " bytes loaded\n"; //Read the sound data and display the - //number of bytes loaded. - //Should be the same as the Data Size if OK - //Now OpenAL needs to be initialized - ALCdevice *device; //Create an OpenAL Device - ALCcontext *context; //And an OpenAL Context - device = alcOpenDevice(NULL); //Open the device - if (!device) return EndWithError("no sound device"); //Error during device oening - context = alcCreateContext(device, NULL); //Give the device a context - alcMakeContextCurrent(context); //Make the context the current - if (!context) return EndWithError("no sound context"); //Error during context handeling - ALuint source; //Is the name of source (where the sound come from) - ALuint buffer; //Stores the sound data - ALuint frequency = sampleRate;; //The Sample Rate of the WAVE file - ALenum format = 0; //The audio format (bits per sample, number of channels) +void SoundSystem::Play(ESoundID inID) +{ + ALuint buffer; alGenBuffers(1, &buffer); //Generate one OpenAL Buffer and link to "buffer" + ALuint source; alGenSources(1, &source); //Generate one OpenAL Source and link to "source" - if (alGetError() != AL_NO_ERROR) return EndWithError("Error GenSource"); //Error during buffer/source generation + if (alGetError() != AL_NO_ERROR) return ; //Error during buffer/source generation //Figure out the format of the WAVE file + ALenum format = 0; //The audio format (bits per sample, number of channels) if (bitsPerSample == 8) { if (channels == 1) @@ -115,8 +53,9 @@ int OpenAL::playMusic(void) { else if (channels == 2) format = AL_FORMAT_STEREO16; } - if (!format) return EndWithError("Wrong BitPerSample"); //Not valid format + if (!format) return; //Not valid format + ALuint frequency = sampleRate; //The Sample Rate of the WAVE file alBufferData(buffer, format, buf, dataSize, frequency); //Store the sound data in the OpenAL Buffer if (alGetError() != AL_NO_ERROR) return EndWithError("Error loading ALBuffer"); //Error during buffer loading @@ -151,19 +90,91 @@ int OpenAL::playMusic(void) { delete[] buf; //Delete the sound data buffer alDeleteSources(1, &source); //Delete the OpenAL Source alDeleteBuffers(1, &buffer); //Delete the OpenAL Buffer - alcMakeContextCurrent(NULL); //Make no context current - alcDestroyContext(context); //Destroy the OpenAL Context - alcCloseDevice(device); //Close the OpenAL Device - isPlaying = false; - return EXIT_SUCCESS; + return ; } -bool OpenAL::isMusicPlaying() + +void SoundSystem::Pause(ESoundID inID) { - return isPlaying; + } -OpenAL::~OpenAL() + +void SoundSystem::Stop(ESoundID inID) { -} \ No newline at end of file + +} + + + + +const char* SoundSystem::GetWaveFile(ESoundID inID) +{ + +} + +bool SoundSystem::LoadWave(ESoundID inID) +{ + const char* path = GetWaveFile(inID); + + FILE *fp = fopen(path, "rb"); //Open the WAVE file + if (!fp) + return false; // Could not open file + + //Check that the WAVE file is OK + char type[4]; + fread(type, sizeof(char), 4, fp); // Reads the first bytes in the file + if (type[0] != 'R' || type[1] != 'I' || type[2] != 'F' || type[3] != 'F') // Should be "RIFF" + return false; // Not RIFF + + DWORD size; + fread(&size, sizeof(DWORD), 1, fp); // Continue to read the file + fread(type, sizeof(char), 4, fp); // Continue to read the file + if (type[0] != 'W' || type[1] != 'A' || type[2] != 'V' || type[3] != 'E') //This part should be "WAVE" + return false; //Not WAVE + + fread(type, sizeof(char), 4, fp); //Continue to read the file + if (type[0] != 'f' || type[1] != 'm' || type[2] != 't' || type[3] != ' ') //This part should be "fmt " + return false; //Not fmt + + //Now we know that the file is a acceptable WAVE file + //Info about the WAVE data is now read and stored + DWORD chunkSize; + fread(&chunkSize, sizeof(DWORD), 1, fp); + short formatType; + fread(&formatType, sizeof(short), 1, fp); + short channels; + fread(&channels, sizeof(short), 1, fp); + DWORD sampleRate; + fread(&sampleRate, sizeof(DWORD), 1, fp); + DWORD avgBytesPerSec; + fread(&avgBytesPerSec, sizeof(DWORD), 1, fp); + short bytesPerSample; + fread(&bytesPerSample, sizeof(short), 1, fp); + short bitsPerSample; + fread(&bitsPerSample, sizeof(short), 1, fp); + + fread(type, sizeof(char), 4, fp); + if (type[0] != 'd' || type[1] != 'a' || type[2] != 't' || type[3] != 'a') //This part should be "data" + return false; //not data + + DWORD dataSize; + fread(&dataSize, sizeof(DWORD), 1, fp); //The size of the sound data is read + + //Display the info about the WAVE file + std::cout << "Chunk Size: " << chunkSize << "\n"; + std::cout << "Format Type: " << formatType << "\n"; + std::cout << "Channels: " << channels << "\n"; + std::cout << "Sample Rate: " << sampleRate << "\n"; + std::cout << "Average Bytes Per Second: " << avgBytesPerSec << "\n"; + std::cout << "Bytes Per Sample: " << bytesPerSample << "\n"; + std::cout << "Bits Per Sample: " << bitsPerSample << "\n"; + std::cout << "Data Size: " << dataSize << "\n"; + + unsigned char* buf = new unsigned char[dataSize]; //Allocate memory for the sound data + std::cout << fread(buf, sizeof(BYTE), dataSize, fp) << " bytes loaded\n"; //Read the sound data and display the + + return true; +} + diff --git a/OpenAL.h b/OpenAL.h index 1b04099..35b8953 100644 --- a/OpenAL.h +++ b/OpenAL.h @@ -1,12 +1,29 @@ #pragma once -class OpenAL + +struct ALCdevice; +struct ALCcontext; + +class SoundSystem { public: - OpenAL(); - int EndWithError(char* msg); - int playMusic(void); - bool isMusicPlaying(); - ~OpenAL(); + enum ESoundID + { + ES_Music1, + ES_Music2 + }; + + SoundSystem(); + ~SoundSystem(); + + void Play(ESoundID inID); + void Pause(ESoundID inID); + void Stop(ESoundID inID); + + private: - bool isPlaying; + const char* GetWaveFile(ESoundID inID); + bool LoadWave(ESoundID inID); + + ALCdevice* device; + ALCcontext* context; }; From 117010b9fe46256d3093bc7d503fc7d6aaf81128 Mon Sep 17 00:00:00 2001 From: Aaldert Date: Sun, 5 Jun 2016 23:49:06 +0200 Subject: [PATCH 7/8] OpenAl Werkt! en Setup enzo --- CrystalPoint.cpp | 4 + CrystalPoint.h | 6 ++ CrystalPoint.vcxproj | 12 ++- CrystalPoint.vcxproj.filters | 15 +++ Enemy.cpp | 18 ++-- Enemy.h | 4 +- Main.cpp | 2 + OpenAL.cpp | 180 ----------------------------------- OpenAL.h | 29 ------ Sound.cpp | 139 +++++++++++++++++++++++++++ Sound.h | 22 +++++ SoundSystem.cpp | 56 +++++++++++ SoundSystem.h | 25 +++++ WAVE/bond.wav | Bin 0 -> 73772 bytes World.cpp | 12 ++- World.h | 1 + WorldHandler.cpp | 1 + worlds/small.json | 31 +++--- 18 files changed, 320 insertions(+), 237 deletions(-) delete mode 100644 OpenAL.cpp delete mode 100644 OpenAL.h create mode 100644 Sound.cpp create mode 100644 Sound.h create mode 100644 SoundSystem.cpp create mode 100644 SoundSystem.h create mode 100644 WAVE/bond.wav diff --git a/CrystalPoint.cpp b/CrystalPoint.cpp index cf24833..867a0b6 100644 --- a/CrystalPoint.cpp +++ b/CrystalPoint.cpp @@ -9,6 +9,8 @@ int CrystalPoint::width = 0; int CrystalPoint::height = 0; +SoundSystem CrystalPoint::sound_system; + void CrystalPoint::init() { player = Player::getInstance(); @@ -90,6 +92,8 @@ void CrystalPoint::update() mouseOffset = Vec2f(0, 0); prevKeyboardState = keyboardState; glutPostRedisplay(); + + sound_system.SetListener(player->position, Vec3f(), Vec3f()); } diff --git a/CrystalPoint.h b/CrystalPoint.h index da4a3b8..5437d5c 100644 --- a/CrystalPoint.h +++ b/CrystalPoint.h @@ -1,8 +1,10 @@ #pragma once class WorldHandler; +class SoundSystem; class Player; #include "Vector.h" +#include "SoundSystem.h" class KeyboardState { @@ -33,4 +35,8 @@ public: float lastFrameTime; + static SoundSystem& GetSoundSystem() { return sound_system; } + +private: + static SoundSystem sound_system; }; \ No newline at end of file diff --git a/CrystalPoint.vcxproj b/CrystalPoint.vcxproj index 7784d07..87f744b 100644 --- a/CrystalPoint.vcxproj +++ b/CrystalPoint.vcxproj @@ -89,12 +89,13 @@ Disabled WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - freeglut/include + freeglut/include; openAL/include Console true - freeglut/lib + freeglut/lib; openAL/libs/Win32 + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;OpenAL32.lib;%(AdditionalDependencies) @@ -163,7 +164,8 @@ - + + @@ -181,7 +183,8 @@ - + + @@ -196,6 +199,7 @@ + diff --git a/CrystalPoint.vcxproj.filters b/CrystalPoint.vcxproj.filters index 57a4a5b..698daee 100644 --- a/CrystalPoint.vcxproj.filters +++ b/CrystalPoint.vcxproj.filters @@ -69,6 +69,12 @@ Source Files\World + + Source Files + + + Source Files + @@ -119,6 +125,12 @@ Header Files + + Header Files + + + Header Files + @@ -138,5 +150,8 @@ Resource Files + + Resource Files + \ No newline at end of file diff --git a/Enemy.cpp b/Enemy.cpp index ad5243a..61376ea 100644 --- a/Enemy.cpp +++ b/Enemy.cpp @@ -1,8 +1,8 @@ #define _USE_MATH_DEFINES #include -#include "OpenAL.h" #include "Enemy.h" #include "Model.h" +#include "CrystalPoint.h" #include Enemy::Enemy(const std::string &fileName, @@ -19,7 +19,7 @@ Enemy::Enemy(const std::string &fileName, speed = 1; radius = 10; hasTarget = false; -// openal = new OpenAL(); + hit_sound_id = CrystalPoint::GetSoundSystem().LoadSound("WAVE/Sound.wav", false); } @@ -61,14 +61,11 @@ void Enemy::inEyeSight(Vec3f & TargetPosition) bool Enemy::hasCollison(Vec3f &) { - + return false; } void Enemy::update(float delta) { -// if (!openal->isMusicPlaying()) { -// openal->playMusic(); -// } if (hasTarget) { @@ -91,5 +88,12 @@ void Enemy::update(float delta) position.z += dz; } rotation.y = atan2f(dx, dz) * 180 / M_PI; - } + } + + if (false) + { + Sound* sound = CrystalPoint::GetSoundSystem().GetSound(hit_sound_id); + sound->SetPos(position, Vec3f()); + sound->Play(); + } } diff --git a/Enemy.h b/Enemy.h index a92bb13..d7886da 100644 --- a/Enemy.h +++ b/Enemy.h @@ -3,7 +3,6 @@ #include "Entity.h" #include #include "Vector.h" -#include "OpenAL.h" class Enemy : public Entity { @@ -20,5 +19,8 @@ public: void inEyeSight(Vec3f &); bool hasCollison(Vec3f &); + +private: + int hit_sound_id; }; diff --git a/Main.cpp b/Main.cpp index d89aa26..f911678 100644 --- a/Main.cpp +++ b/Main.cpp @@ -54,6 +54,8 @@ int main(int argc, char* argv[]) CrystalPoint::width = GLUT_WINDOW_WIDTH; glutMainLoop(); + + delete app; return 0; } diff --git a/OpenAL.cpp b/OpenAL.cpp deleted file mode 100644 index 613fb7c..0000000 --- a/OpenAL.cpp +++ /dev/null @@ -1,180 +0,0 @@ -#include "OpenAL.h" -#include -#include -#include -#include -#include - -SoundSystem::SoundSystem(): - device(nullptr), - context(nullptr) -{ - device = alcOpenDevice(nullptr); - if (!device) - return; - context = alcCreateContext(device, nullptr); - if (!context) - return; - alcMakeContextCurrent(context); -} - -SoundSystem::~SoundSystem() -{ - alcMakeContextCurrent(nullptr); //Make no context current - alcDestroyContext(context); //Destroy the OpenAL Context - alcCloseDevice(device); //Close the OpenAL Device -} - - - - - -void SoundSystem::Play(ESoundID inID) -{ - ALuint buffer; - alGenBuffers(1, &buffer); //Generate one OpenAL Buffer and link to "buffer" - ALuint source; - alGenSources(1, &source); //Generate one OpenAL Source and link to "source" - if (alGetError() != AL_NO_ERROR) return ; //Error during buffer/source generation - - //Figure out the format of the WAVE file - ALenum format = 0; //The audio format (bits per sample, number of channels) - if (bitsPerSample == 8) - { - if (channels == 1) - format = AL_FORMAT_MONO8; - else if (channels == 2) - format = AL_FORMAT_STEREO8; - } - else if (bitsPerSample == 16) - { - if (channels == 1) - format = AL_FORMAT_MONO16; - else if (channels == 2) - format = AL_FORMAT_STEREO16; - } - if (!format) return; //Not valid format - - ALuint frequency = sampleRate; //The Sample Rate of the WAVE file - alBufferData(buffer, format, buf, dataSize, frequency); //Store the sound data in the OpenAL Buffer - if (alGetError() != AL_NO_ERROR) - return EndWithError("Error loading ALBuffer"); //Error during buffer loading - - //Sound setting variables - ALfloat SourcePos[] = { 0.0, 0.0, 0.0 }; //Position of the source sound - ALfloat SourceVel[] = { 0.0, 0.0, 0.0 }; //Velocity of the source sound - ALfloat ListenerPos[] = { 0.0, 0.0, 0.0 }; //Position of the listener - ALfloat ListenerVel[] = { 0.0, 0.0, 0.0 }; //Velocity of the listener - ALfloat ListenerOri[] = { 0.0, 0.0, -1.0, 0.0, 1.0, 0.0 }; //Orientation of the listener - //First direction vector, then vector pointing up) - //Listener - alListenerfv(AL_POSITION, ListenerPos); //Set position of the listener - alListenerfv(AL_VELOCITY, ListenerVel); //Set velocity of the listener - alListenerfv(AL_ORIENTATION, ListenerOri); //Set orientation of the listener - - //Source - alSourcei(source, AL_BUFFER, buffer); //Link the buffer to the source - alSourcef(source, AL_PITCH, 1.0f); //Set the pitch of the source - alSourcef(source, AL_GAIN, 1.0f); //Set the gain of the source - alSourcefv(source, AL_POSITION, SourcePos); //Set the position of the source - alSourcefv(source, AL_VELOCITY, SourceVel); //Set the velocity of the source - alSourcei(source, AL_LOOPING, AL_FALSE); //Set if source is looping sound - - //PLAY - alSourcePlay(source); //Play the sound buffer linked to the source - if (alGetError() != AL_NO_ERROR) return EndWithError("Error playing sound"); //Error when playing sound - system("PAUSE"); //Pause to let the sound play - - //Clean-up - fclose(fp); //Close the WAVE file - delete[] buf; //Delete the sound data buffer - alDeleteSources(1, &source); //Delete the OpenAL Source - alDeleteBuffers(1, &buffer); //Delete the OpenAL Buffer - - return ; -} - - -void SoundSystem::Pause(ESoundID inID) -{ - -} - - -void SoundSystem::Stop(ESoundID inID) -{ - -} - - - - -const char* SoundSystem::GetWaveFile(ESoundID inID) -{ - -} - -bool SoundSystem::LoadWave(ESoundID inID) -{ - const char* path = GetWaveFile(inID); - - FILE *fp = fopen(path, "rb"); //Open the WAVE file - if (!fp) - return false; // Could not open file - - //Check that the WAVE file is OK - char type[4]; - fread(type, sizeof(char), 4, fp); // Reads the first bytes in the file - if (type[0] != 'R' || type[1] != 'I' || type[2] != 'F' || type[3] != 'F') // Should be "RIFF" - return false; // Not RIFF - - DWORD size; - fread(&size, sizeof(DWORD), 1, fp); // Continue to read the file - fread(type, sizeof(char), 4, fp); // Continue to read the file - if (type[0] != 'W' || type[1] != 'A' || type[2] != 'V' || type[3] != 'E') //This part should be "WAVE" - return false; //Not WAVE - - fread(type, sizeof(char), 4, fp); //Continue to read the file - if (type[0] != 'f' || type[1] != 'm' || type[2] != 't' || type[3] != ' ') //This part should be "fmt " - return false; //Not fmt - - //Now we know that the file is a acceptable WAVE file - //Info about the WAVE data is now read and stored - DWORD chunkSize; - fread(&chunkSize, sizeof(DWORD), 1, fp); - short formatType; - fread(&formatType, sizeof(short), 1, fp); - short channels; - fread(&channels, sizeof(short), 1, fp); - DWORD sampleRate; - fread(&sampleRate, sizeof(DWORD), 1, fp); - DWORD avgBytesPerSec; - fread(&avgBytesPerSec, sizeof(DWORD), 1, fp); - short bytesPerSample; - fread(&bytesPerSample, sizeof(short), 1, fp); - short bitsPerSample; - fread(&bitsPerSample, sizeof(short), 1, fp); - - fread(type, sizeof(char), 4, fp); - if (type[0] != 'd' || type[1] != 'a' || type[2] != 't' || type[3] != 'a') //This part should be "data" - return false; //not data - - DWORD dataSize; - fread(&dataSize, sizeof(DWORD), 1, fp); //The size of the sound data is read - - //Display the info about the WAVE file - std::cout << "Chunk Size: " << chunkSize << "\n"; - std::cout << "Format Type: " << formatType << "\n"; - std::cout << "Channels: " << channels << "\n"; - std::cout << "Sample Rate: " << sampleRate << "\n"; - std::cout << "Average Bytes Per Second: " << avgBytesPerSec << "\n"; - std::cout << "Bytes Per Sample: " << bytesPerSample << "\n"; - std::cout << "Bits Per Sample: " << bitsPerSample << "\n"; - std::cout << "Data Size: " << dataSize << "\n"; - - unsigned char* buf = new unsigned char[dataSize]; //Allocate memory for the sound data - std::cout << fread(buf, sizeof(BYTE), dataSize, fp) << " bytes loaded\n"; //Read the sound data and display the - - return true; -} - diff --git a/OpenAL.h b/OpenAL.h deleted file mode 100644 index 35b8953..0000000 --- a/OpenAL.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -struct ALCdevice; -struct ALCcontext; - -class SoundSystem -{ -public: - enum ESoundID - { - ES_Music1, - ES_Music2 - }; - - SoundSystem(); - ~SoundSystem(); - - void Play(ESoundID inID); - void Pause(ESoundID inID); - void Stop(ESoundID inID); - - -private: - const char* GetWaveFile(ESoundID inID); - bool LoadWave(ESoundID inID); - - ALCdevice* device; - ALCcontext* context; -}; diff --git a/Sound.cpp b/Sound.cpp new file mode 100644 index 0000000..cc990da --- /dev/null +++ b/Sound.cpp @@ -0,0 +1,139 @@ +#include "Sound.h" + +#include +#include +#include + +Sound::Sound(const char* inWavPath, bool inLooping): + buffer_id(0), + source_id(0), + is_looping(inLooping) + +{ + const char* path = inWavPath; + + FILE *fp = fopen(path, "rb"); // Open the WAVE file + if (!fp) + return; // Could not open file + + // Check that the WAVE file is OK + char type[4]; + fread(type, sizeof(char), 4, fp); // Reads the first bytes in the file + if (type[0] != 'R' || type[1] != 'I' || type[2] != 'F' || type[3] != 'F') // Should be "RIFF" + return; // Not RIFF + + DWORD size; + fread(&size, sizeof(DWORD), 1, fp); // Continue to read the file + fread(type, sizeof(char), 4, fp); // Continue to read the file + if (type[0] != 'W' || type[1] != 'A' || type[2] != 'V' || type[3] != 'E') // This part should be "WAVE" + return; // Not WAVE + + fread(type, sizeof(char), 4, fp); // Continue to read the file + if (type[0] != 'f' || type[1] != 'm' || type[2] != 't' || type[3] != ' ') // This part should be "fmt " + return; // Not fmt + + // Now we know that the file is a acceptable WAVE file + // Info about the WAVE data is now read and stored + DWORD chunkSize; + fread(&chunkSize, sizeof(DWORD), 1, fp); + short formatType; + fread(&formatType, sizeof(short), 1, fp); + short channels; + fread(&channels, sizeof(short), 1, fp); + DWORD sampleRate; + fread(&sampleRate, sizeof(DWORD), 1, fp); + DWORD avgBytesPerSec; + fread(&avgBytesPerSec, sizeof(DWORD), 1, fp); + short bytesPerSample; + fread(&bytesPerSample, sizeof(short), 1, fp); + short bitsPerSample; + fread(&bitsPerSample, sizeof(short), 1, fp); + ALenum format = 0; // The audio format (bits per sample, number of channels) + if (bitsPerSample == 8) + { + if (channels == 1) + format = AL_FORMAT_MONO8; + else if (channels == 2) + format = AL_FORMAT_STEREO8; + } + else if (bitsPerSample == 16) + { + if (channels == 1) + format = AL_FORMAT_MONO16; + else if (channels == 2) + format = AL_FORMAT_STEREO16; + } + if (!format) + return; // Not valid format + + fread(type, sizeof(char), 4, fp); + if (type[0] != 'd' || type[1] != 'a' || type[2] != 't' || type[3] != 'a') // This part should be "data" + return; // not data + + DWORD dataSize; + fread(&dataSize, sizeof(DWORD), 1, fp); // The size of the sound data is read + + // Display the info about the WAVE file + std::cout << "Chunk Size: " << chunkSize << "\n"; + std::cout << "Format Type: " << formatType << "\n"; + std::cout << "Channels: " << channels << "\n"; + std::cout << "Sample Rate: " << sampleRate << "\n"; + std::cout << "Average Bytes Per Second: " << avgBytesPerSec << "\n"; + std::cout << "Bytes Per Sample: " << bytesPerSample << "\n"; + std::cout << "Bits Per Sample: " << bitsPerSample << "\n"; + std::cout << "Data Size: " << dataSize << "\n"; + + unsigned char* buf = new unsigned char[dataSize]; // Allocate memory for the sound data + std::cout << fread(buf, sizeof(BYTE), dataSize, fp) << " bytes loaded\n"; // Read the sound data and display the + fclose(fp); + + alGenBuffers(1, &buffer_id); // Generate one OpenAL Buffer and link to "buffer" + alGenSources(1, &source_id); // Generate one OpenAL Source and link to "source" + if (alGetError() != AL_NO_ERROR) + return; // Error during buffer/source generation + + alBufferData(buffer_id, format, buf, dataSize, sampleRate); // Store the sound data in the OpenAL Buffer + if (alGetError() != AL_NO_ERROR) + return; // Error during buffer loading + + delete[] buf; // Delete the sound data buffer +} + + +Sound::~Sound() +{ + alSourceStop(source_id); + alDeleteSources(1, &source_id); // Delete the OpenAL Source + alDeleteBuffers(1, &buffer_id); // Delete the OpenAL Buffer +} + + +void Sound::SetPos(const Vec3f& inPos, const Vec3f& inVel) +{ + alSourcei(source_id, AL_BUFFER, buffer_id); // Link the buffer to the source + alSourcef(source_id, AL_PITCH, 1.0f); // Set the pitch of the source + alSourcef(source_id, AL_GAIN, 1.0f); // Set the gain of the source + alSourcefv(source_id, AL_POSITION, inPos.v); // Set the position of the source + alSourcefv(source_id, AL_VELOCITY, inVel.v); // Set the velocity of the source + alSourcei(source_id, AL_LOOPING, is_looping ? AL_TRUE : AL_FALSE); // Set if source is looping sound +} + + +void Sound::Play() +{ + alSourcePlay(source_id); + int e = alGetError(); // != AL_NO_ERROR) return; +} + + +void Sound::Pause() +{ + alSourcePause(source_id); +} + + +void Sound::Stop() +{ + alSourceStop(source_id); +} + diff --git a/Sound.h b/Sound.h new file mode 100644 index 0000000..74e2f9f --- /dev/null +++ b/Sound.h @@ -0,0 +1,22 @@ +#pragma once + +#include "vector.h" + +class Sound +{ +public: + Sound(const char* inWavPath, bool inLooping); + ~Sound(); + + void SetPos(const Vec3f& inPos, const Vec3f& inVel); + + void Play(); + void Pause(); + void Stop(); + +private: + unsigned int buffer_id; + unsigned int source_id; + + bool is_looping; +}; \ No newline at end of file diff --git a/SoundSystem.cpp b/SoundSystem.cpp new file mode 100644 index 0000000..bd207be --- /dev/null +++ b/SoundSystem.cpp @@ -0,0 +1,56 @@ +#include "SoundSystem.h" + +#include +#include +#include + + + +SoundSystem::SoundSystem(): + device(nullptr), + context(nullptr) +{ + device = alcOpenDevice(nullptr); + if (!device) + return; + context = alcCreateContext(device, nullptr); + if (!context) + return; + alcMakeContextCurrent(context); +} + + +SoundSystem::~SoundSystem() +{ + for (auto sound : sounds) + delete sound; + alcMakeContextCurrent(nullptr); + alcDestroyContext(context); + alcCloseDevice(device); +} + + +void SoundSystem::SetListener(const Vec3f& inPos, const Vec3f& inVel, const Vec3f& inOri) +{ + ALfloat orientation[] = { 0.0, 0.0, -1.0, 0.0, 1.0, 0.0 }; + + alListenerfv(AL_POSITION, inPos.v); + alListenerfv(AL_VELOCITY, inVel.v); + alListenerfv(AL_ORIENTATION, orientation); +} + + +unsigned int SoundSystem::LoadSound(const char* inWavPath, bool inLooping) +{ + Sound* sound = new Sound(inWavPath, inLooping); + sounds.push_back(sound); + return sounds.size() - 1; +} + + +Sound* SoundSystem::GetSound(unsigned int inID) +{ + if (inID > sounds.size()) + return nullptr; + return sounds[inID]; +} diff --git a/SoundSystem.h b/SoundSystem.h new file mode 100644 index 0000000..d6908ce --- /dev/null +++ b/SoundSystem.h @@ -0,0 +1,25 @@ +#pragma once + +#include +#include +#include +#include "vector.h" +#include "Sound.h" + + +class SoundSystem +{ +public: + SoundSystem(); + ~SoundSystem(); + + void SetListener(const Vec3f& inPos, const Vec3f& inVel, const Vec3f& inOri); + + unsigned int LoadSound(const char* inWavPath, bool inLooping); + Sound* GetSound(unsigned int inID); + +private: + ALCdevice* device; + ALCcontext* context; + std::vector sounds; +}; diff --git a/WAVE/bond.wav b/WAVE/bond.wav new file mode 100644 index 0000000000000000000000000000000000000000..c478afed7f43a2667eed4396c96892c3bbea2883 GIT binary patch literal 73772 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 P #include -World::World(const std::string &fileName) +World::World(const std::string &fileName): + music_id(-1) { //Store player instance player = Player::getInstance(); @@ -113,6 +114,15 @@ World::World(const std::string &fileName) enemies.push_back(new Enemy(e["file"].asString(), position, rotation, scale)); } + + if (!v["world"]["music"].isNull()) + { + music_id = CrystalPoint::GetSoundSystem().LoadSound(v["world"]["music"].asString().c_str(), true); + Sound* music = CrystalPoint::GetSoundSystem().GetSound(music_id); + music->SetPos(Vec3f(), Vec3f()); + music->Play(); + } + } diff --git a/World.h b/World.h index 649e2d4..48f9506 100644 --- a/World.h +++ b/World.h @@ -17,6 +17,7 @@ private: Player* player; HeightMap* heightmap; Interface* interface; + int music_id; std::vector entities; std::vector enemies; diff --git a/WorldHandler.cpp b/WorldHandler.cpp index 97fa7a2..4b41fae 100644 --- a/WorldHandler.cpp +++ b/WorldHandler.cpp @@ -97,6 +97,7 @@ bool WorldHandler::isPlayerPositionValid(void) { if(!loadingWorld) return world->isPlayerPositionValid(); + return false; } float WorldHandler::getHeight(float x, float y) diff --git a/worlds/small.json b/worlds/small.json index 466db7c..274e4b6 100644 --- a/worlds/small.json +++ b/worlds/small.json @@ -1,17 +1,18 @@ { - "world": { - "heightmap": "worlds/small.png", - "object-templates": [ - { - "color":100, - "file": "models/boom/Boom.obj", - "collision": false - } - ] - }, - "player": { - "startposition": [ 20, 5, 20 ] - }, - "objects": [], - "enemies": [] + "world": { + "heightmap": "worlds/small.png", + "object-templates": [ + { + "color": 100, + "file": "models/boom/Boom.obj", + "collision": false + } + ], + "music": "WAVE/bond.wav" + }, + "player": { + "startposition": [ 20, 5, 20 ] + }, + "objects": [], + "enemies": [] } \ No newline at end of file From 9659caa1d8a66ff8289eab4ac5e75701a4052a3a Mon Sep 17 00:00:00 2001 From: Kenneth van Ewijk Date: Thu, 9 Jun 2016 12:32:13 +0200 Subject: [PATCH 8/8] Fix filters --- CrystalPoint.vcxproj.filters | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CrystalPoint.vcxproj.filters b/CrystalPoint.vcxproj.filters index 946125f..faa1d7c 100644 --- a/CrystalPoint.vcxproj.filters +++ b/CrystalPoint.vcxproj.filters @@ -73,8 +73,10 @@ Source Files + Source Files + - Source Files + Source Files @@ -130,6 +132,8 @@ Header Files + Header Files + Header Files