1 /** 2 * Copyright (c) 2006-2019 LOVE Development Team 3 * 4 * This software is provided 'as-is', without any express or implied 5 * warranty. In no event will the authors be held liable for any damages 6 * arising from the use of this software. 7 * 8 * Permission is granted to anyone to use this software for any purpose, 9 * including commercial applications, and to alter it and redistribute it 10 * freely, subject to the following restrictions: 11 * 12 * 1. The origin of this software must not be misrepresented; you must not 13 * claim that you wrote the original software. If you use this software 14 * in a product, an acknowledgment in the product documentation would be 15 * appreciated but is not required. 16 * 2. Altered source versions must be plainly marked as such, and must not be 17 * misrepresented as being the original software. 18 * 3. This notice may not be removed or altered from any source distribution. 19 **/ 20 21 #ifndef LOVE_AUDIO_OPENAL_SOURCE_H 22 #define LOVE_AUDIO_OPENAL_SOURCE_H 23 24 // LOVE 25 #include "common/config.h" 26 #include "common/Object.h" 27 #include "audio/Source.h" 28 #include "audio/Filter.h" 29 #include "sound/SoundData.h" 30 #include "sound/Decoder.h" 31 #include "Audio.h" 32 #include "Filter.h" 33 34 // STL 35 #include <vector> 36 #include <stack> 37 38 // C 39 #include <float.h> 40 41 // OpenAL 42 #ifdef LOVE_APPLE_USE_FRAMEWORKS 43 #ifdef LOVE_IOS 44 #include <OpenAL/alc.h> 45 #include <OpenAL/al.h> 46 #else 47 #include <OpenAL-Soft/alc.h> 48 #include <OpenAL-Soft/al.h> 49 #endif 50 #else 51 #include <AL/alc.h> 52 #include <AL/al.h> 53 #endif 54 55 namespace love 56 { 57 namespace audio 58 { 59 namespace openal 60 { 61 62 #ifdef LOVE_IOS 63 // OpenAL on iOS barfs if the max distance is +inf. 64 static const float MAX_ATTENUATION_DISTANCE = 1000000.0f; 65 #else 66 static const float MAX_ATTENUATION_DISTANCE = FLT_MAX; 67 #endif 68 69 class Audio; 70 class Pool; 71 72 // Basically just a reference-counted non-streaming OpenAL buffer object. 73 class StaticDataBuffer : public love::Object 74 { 75 public: 76 77 StaticDataBuffer(ALenum format, const ALvoid *data, ALsizei size, ALsizei freq); 78 virtual ~StaticDataBuffer(); 79 getBuffer()80 inline ALuint getBuffer() const 81 { 82 return buffer; 83 } 84 getSize()85 inline ALsizei getSize() const 86 { 87 return size; 88 } 89 90 private: 91 92 ALuint buffer; 93 ALsizei size; 94 95 }; // StaticDataBuffer 96 97 class Source : public love::audio::Source 98 { 99 public: 100 101 Source(Pool *pool, love::sound::SoundData *soundData); 102 Source(Pool *pool, love::sound::Decoder *decoder); 103 Source(Pool *pool, int sampleRate, int bitDepth, int channels, int buffers); 104 Source(const Source &s); 105 virtual ~Source(); 106 107 virtual love::audio::Source *clone(); 108 virtual bool play(); 109 virtual void stop(); 110 virtual void pause(); 111 virtual bool isPlaying() const; 112 virtual bool isFinished() const; 113 virtual bool update(); 114 virtual void setPitch(float pitch); 115 virtual float getPitch() const; 116 virtual void setVolume(float volume); 117 virtual float getVolume() const; 118 virtual void seek(double offset, Unit unit); 119 virtual double tell(Unit unit); 120 virtual double getDuration(Unit unit); 121 virtual void setPosition(float *v); 122 virtual void getPosition(float *v) const; 123 virtual void setVelocity(float *v); 124 virtual void getVelocity(float *v) const; 125 virtual void setDirection(float *v); 126 virtual void getDirection(float *v) const; 127 virtual void setCone(float innerAngle, float outerAngle, float outerVolume, float outerHighGain); 128 virtual void getCone(float &innerAngle, float &outerAngle, float &outerVolume, float &outerHighGain) const; 129 virtual void setRelative(bool enable); 130 virtual bool isRelative() const; 131 void setLooping(bool looping); 132 bool isLooping() const; 133 virtual void setMinVolume(float volume); 134 virtual float getMinVolume() const; 135 virtual void setMaxVolume(float volume); 136 virtual float getMaxVolume() const; 137 virtual void setReferenceDistance(float distance); 138 virtual float getReferenceDistance() const; 139 virtual void setRolloffFactor(float factor); 140 virtual float getRolloffFactor() const; 141 virtual void setMaxDistance(float distance); 142 virtual float getMaxDistance() const; 143 virtual void setAirAbsorptionFactor(float factor); 144 virtual float getAirAbsorptionFactor() const; 145 virtual int getChannelCount() const; 146 147 virtual bool setFilter(const std::map<Filter::Parameter, float> ¶ms); 148 virtual bool setFilter(); 149 virtual bool getFilter(std::map<Filter::Parameter, float> ¶ms); 150 151 virtual bool setEffect(const char *effect); 152 virtual bool setEffect(const char *effect, const std::map<Filter::Parameter, float> ¶ms); 153 virtual bool unsetEffect(const char *effect); 154 virtual bool getEffect(const char *effect, std::map<Filter::Parameter, float> ¶ms); 155 virtual bool getActiveEffects(std::vector<std::string> &list) const; 156 157 virtual int getFreeBufferCount() const; 158 virtual bool queue(void *data, size_t length, int dataSampleRate, int dataBitDepth, int dataChannels); 159 160 void prepareAtomic(); 161 void teardownAtomic(); 162 163 bool playAtomic(ALuint source); 164 void stopAtomic(); 165 void pauseAtomic(); 166 void resumeAtomic(); 167 168 static bool play(const std::vector<love::audio::Source*> &sources); 169 static void stop(const std::vector<love::audio::Source*> &sources); 170 static void pause(const std::vector<love::audio::Source*> &sources); 171 172 static std::vector<love::audio::Source*> pause(Pool *pool); 173 static void stop(Pool *pool); 174 175 private: 176 177 void reset(); 178 179 void setFloatv(float *dst, const float *src) const; 180 181 int streamAtomic(ALuint buffer, love::sound::Decoder *d); 182 183 Pool *pool = nullptr; 184 ALuint source = 0; 185 bool valid = false; 186 187 const static int DEFAULT_BUFFERS = 8; 188 const static int MAX_BUFFERS = 64; 189 std::queue<ALuint> streamBuffers; 190 std::stack<ALuint> unusedBuffers; 191 192 StrongRef<StaticDataBuffer> staticBuffer; 193 194 float pitch = 1.0f; 195 float volume = 1.0f; 196 float position[3]; 197 float velocity[3]; 198 float direction[3]; 199 bool relative = false; 200 bool looping = false; 201 float minVolume = 0.0f; 202 float maxVolume = 1.0f; 203 float referenceDistance = 1.0f; 204 float rolloffFactor = 1.0f; 205 float absorptionFactor = 0.0f; 206 float maxDistance = MAX_ATTENUATION_DISTANCE; 207 208 struct Cone 209 { 210 int innerAngle = 360; // degrees 211 int outerAngle = 360; // degrees 212 float outerVolume = 0.0f; 213 float outerHighGain = 1.0f; 214 } cone; 215 216 int offsetSamples = 0; 217 218 int sampleRate = 0; 219 int channels = 0; 220 int bitDepth = 0; 221 222 StrongRef<love::sound::Decoder> decoder; 223 224 unsigned int toLoop = 0; 225 ALsizei bufferedBytes = 0; 226 int buffers = 0; 227 228 Filter *directfilter = nullptr; 229 230 struct EffectMapStorage 231 { 232 Filter *filter; 233 ALuint slot, target; 234 }; 235 std::map<std::string, EffectMapStorage> effectmap; 236 std::stack<ALuint> slotlist; 237 }; // Source 238 239 } // openal 240 } // audio 241 } // love 242 243 #endif // LOVE_AUDIO_OPENAL_SOURCE_H 244