1/**
2 * Copyright (c) 2006-2023 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_AUDIO_H
22#define LOVE_AUDIO_OPENAL_AUDIO_H
23
24// STD
25#include <queue>
26#include <map>
27#include <vector>
28#include <stack>
29#include <cmath>
30
31// LOVE
32#include "audio/Audio.h"
33#include "audio/RecordingDevice.h"
34#include "audio/Filter.h"
35#include "common/config.h"
36#include "sound/SoundData.h"
37
38#include "Source.h"
39#include "Effect.h"
40#include "Pool.h"
41#include "thread/threads.h"
42
43// OpenAL
44#ifdef LOVE_APPLE_USE_FRAMEWORKS // Frameworks have different include paths.
45#ifdef LOVE_IOS
46#include <OpenAL/alc.h>
47#include <OpenAL/al.h>
48#else
49#include <OpenAL-Soft/alc.h>
50#include <OpenAL-Soft/al.h>
51#endif
52#else
53#include <AL/alc.h>
54#include <AL/al.h>
55#include <AL/alext.h>
56#endif
57
58namespace love
59{
60namespace audio
61{
62namespace openal
63{
64
65class Audio : public love::audio::Audio
66{
67public:
68
69 Audio();
70 ~Audio();
71
72 /**
73 * Gets the OpenAL format identifier based on number of
74 * channels and bits.
75 * @param channels.
76 * @param bitDepth Either 8-bit samples, or 16-bit samples.
77 * @return One of AL_FORMAT_*, or AL_NONE if unsupported format.
78 **/
79 static ALenum getFormat(int bitDepth, int channels);
80
81 // Implements Module.
82 const char *getName() const;
83
84 // Implements Audio.
85 love::audio::Source *newSource(love::sound::Decoder *decoder);
86 love::audio::Source *newSource(love::sound::SoundData *soundData);
87 love::audio::Source *newSource(int sampleRate, int bitDepth, int channels, int buffers);
88 int getActiveSourceCount() const;
89 int getMaxSources() const;
90 bool play(love::audio::Source *source);
91 bool play(const std::vector<love::audio::Source*> &sources);
92 void stop(love::audio::Source *source);
93 void stop(const std::vector<love::audio::Source*> &sources);
94 void stop();
95 void pause(love::audio::Source *source);
96 void pause(const std::vector<love::audio::Source*> &sources);
97 std::vector<love::audio::Source*> pause();
98 void pauseContext();
99 void resumeContext();
100 void setVolume(float volume);
101 float getVolume() const;
102
103 void getPosition(float *v) const;
104 void setPosition(float *v);
105 void getOrientation(float *v) const;
106 void setOrientation(float *v);
107 void getVelocity(float *v) const;
108 void setVelocity(float *v);
109
110 void setDopplerScale(float scale);
111 float getDopplerScale() const;
112 //void setMeter(float scale);
113 //float getMeter() const;
114
115 const std::vector<love::audio::RecordingDevice*> &getRecordingDevices();
116
117 DistanceModel getDistanceModel() const;
118 void setDistanceModel(DistanceModel distanceModel);
119
120 bool setEffect(const char *name, std::map<Effect::Parameter, float> &params);
121 bool unsetEffect(const char *name);
122 bool getEffect(const char *name, std::map<Effect::Parameter, float> &params);
123 bool getActiveEffects(std::vector<std::string> &list) const;
124 int getMaxSceneEffects() const;
125 int getMaxSourceEffects() const;
126 bool isEFXsupported() const;
127
128 bool getEffectID(const char *name, ALuint &id);
129
130private:
131 void initializeEFX();
132 // The OpenAL device.
133 ALCdevice *device;
134
135 // The OpenAL capture devices.
136 std::vector<love::audio::RecordingDevice*> capture;
137
138 // The OpenAL context.
139 ALCcontext *context;
140
141 // The OpenAL effects
142 struct EffectMapStorage
143 {
144 Effect *effect;
145 ALuint slot;
146 };
147 std::map<std::string, struct EffectMapStorage> effectmap;
148 std::stack<ALuint> slotlist;
149 int MAX_SCENE_EFFECTS = 64;
150 int MAX_SOURCE_EFFECTS = 64;
151
152 // The Pool.
153 Pool *pool;
154
155 class PoolThread: public thread::Threadable
156 {
157 protected:
158 Pool *pool;
159
160 // Set this to true when the thread should finish.
161 // Main thread will write to this value, and PoolThread
162 // will read from it.
163 volatile bool finish;
164
165 // finish lock
166 love::thread::MutexRef mutex;
167
168 public:
169 PoolThread(Pool *pool);
170 virtual ~PoolThread();
171 void setFinish();
172 void threadFunction();
173 };
174
175 PoolThread *poolThread;
176
177 DistanceModel distanceModel;
178 //float metersPerUnit = 1.0;
179
180#ifdef LOVE_ANDROID
181# ifndef ALC_SOFT_pause_device
182 typedef void (ALC_APIENTRY*LPALCDEVICEPAUSESOFT)(ALCdevice *device);
183 typedef void (ALC_APIENTRY*LPALCDEVICERESUMESOFT)(ALCdevice *device);
184# endif
185 LPALCDEVICEPAUSESOFT alcDevicePauseSOFT;
186 LPALCDEVICERESUMESOFT alcDeviceResumeSOFT;
187 std::vector<love::audio::Source*> pausedSources;
188#endif
189}; // Audio
190
191#ifdef ALC_EXT_EFX
192 // Effect objects
193extern LPALGENEFFECTS alGenEffects;
194extern LPALDELETEEFFECTS alDeleteEffects;
195extern LPALISEFFECT alIsEffect;
196extern LPALEFFECTI alEffecti;
197extern LPALEFFECTIV alEffectiv;
198extern LPALEFFECTF alEffectf;
199extern LPALEFFECTFV alEffectfv;
200extern LPALGETEFFECTI alGetEffecti;
201extern LPALGETEFFECTIV alGetEffectiv;
202extern LPALGETEFFECTF alGetEffectf;
203extern LPALGETEFFECTFV alGetEffectfv;
204
205//Filter objects
206extern LPALGENFILTERS alGenFilters;
207extern LPALDELETEFILTERS alDeleteFilters;
208extern LPALISFILTER alIsFilter;
209extern LPALFILTERI alFilteri;
210extern LPALFILTERIV alFilteriv;
211extern LPALFILTERF alFilterf;
212extern LPALFILTERFV alFilterfv;
213extern LPALGETFILTERI alGetFilteri;
214extern LPALGETFILTERIV alGetFilteriv;
215extern LPALGETFILTERF alGetFilterf;
216extern LPALGETFILTERFV alGetFilterfv;
217
218// Auxiliary slot object
219extern LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots;
220extern LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots;
221extern LPALISAUXILIARYEFFECTSLOT alIsAuxiliaryEffectSlot;
222extern LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti;
223extern LPALAUXILIARYEFFECTSLOTIV alAuxiliaryEffectSlotiv;
224extern LPALAUXILIARYEFFECTSLOTF alAuxiliaryEffectSlotf;
225extern LPALAUXILIARYEFFECTSLOTFV alAuxiliaryEffectSlotfv;
226extern LPALGETAUXILIARYEFFECTSLOTI alGetAuxiliaryEffectSloti;
227extern LPALGETAUXILIARYEFFECTSLOTIV alGetAuxiliaryEffectSlotiv;
228extern LPALGETAUXILIARYEFFECTSLOTF alGetAuxiliaryEffectSlotf;
229extern LPALGETAUXILIARYEFFECTSLOTFV alGetAuxiliaryEffectSlotfv;
230#endif
231
232} // openal
233} // audio
234} // love
235
236#endif // LOVE_AUDIO_OPENAL_AUDIO_H
237