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_POOL_H
22 #define LOVE_AUDIO_OPENAL_POOL_H
23 
24 // STD
25 #include <queue>
26 #include <map>
27 #include <vector>
28 #include <cmath>
29 
30 // LOVE
31 #include "common/config.h"
32 #include "common/Exception.h"
33 #include "thread/threads.h"
34 #include "audio/Source.h"
35 
36 // OpenAL
37 #ifdef LOVE_APPLE_USE_FRAMEWORKS
38 #ifdef LOVE_IOS
39 #include <OpenAL/alc.h>
40 #include <OpenAL/al.h>
41 #include <OpenAL/oalMacOSX_OALExtensions.h>
42 #include <OpenAL/oalStaticBufferExtension.h>
43 #else
44 #include <OpenAL-Soft/alc.h>
45 #include <OpenAL-Soft/al.h>
46 #include <OpenAL-Soft/alext.h>
47 #endif
48 #else
49 #include <AL/alc.h>
50 #include <AL/al.h>
51 #include <AL/alext.h>
52 #endif
53 
54 namespace love
55 {
56 namespace audio
57 {
58 namespace openal
59 {
60 
61 class Source;
62 
63 class Pool
64 {
65 public:
66 
67 	Pool();
68 	~Pool();
69 
70 	/**
71 	 * Checks whether an OpenAL source is available.
72 	 * @return True if at least one is available, false otherwise.
73 	 **/
74 	bool isAvailable() const;
75 
76 	/**
77 	 * Checks whether a Source is currently in the playing list.
78 	 **/
79 	bool isPlaying(Source *s);
80 
81 	void update();
82 
83 	int getActiveSourceCount() const;
84 	int getMaxSources() const;
85 
86 private:
87 
88 	friend class Source;
89 	LOVE_WARN_UNUSED thread::Lock lock();
90 	std::vector<love::audio::Source*> getPlayingSources();
91 
92 	/**
93 	 * Makes the specified OpenAL source available for use.
94 	 * @param source The OpenAL source.
95 	 **/
96 	bool releaseSource(Source *source, bool stop = true);
97 
98 	bool assignSource(Source *source, ALuint &out, char &wasPlaying);
99 	bool findSource(Source *source, ALuint &out);
100 
101 	// Maximum possible number of OpenAL sources the pool attempts to generate.
102 	static const int MAX_SOURCES = 64;
103 
104 	// OpenAL sources
105 	ALuint sources[MAX_SOURCES];
106 
107 	// Total number of created sources in the pool.
108 	int totalSources;
109 
110 	// A queue of available sources.
111 	std::queue<ALuint> available;
112 
113 	// A map of playing sources.
114 	std::map<Source *, ALuint> playing;
115 
116 	// Only one thread can access this object at the same time. This mutex will
117 	// make sure of that.
118 	love::thread::MutexRef mutex;
119 
120 }; // Pool
121 
122 } // openal
123 } // audio
124 } // love
125 
126 #endif // LOVE_AUDIO_OPENAL_POOL_H
127