Make alure-local aliases for promise/future stuff
[alure.git] / include / AL / alure2.h
blobb63b1dff7472948e0b7873aa19707081303641e8
1 #ifndef AL_ALURE2_H
2 #define AL_ALURE2_H
4 #include <vector>
5 #include <string>
6 #include <memory>
7 #include <cstring>
8 #include <utility>
9 #include <future>
10 #include <chrono>
11 #include <array>
12 #include <cmath>
14 #include "alc.h"
15 #include "al.h"
17 #ifdef _WIN32
18 #if defined(ALURE_BUILD_STATIC) || defined(ALURE_STATIC_LIB)
19 #define ALURE_API
20 #elif defined(ALURE_BUILD_DLL)
21 #define ALURE_API __declspec(dllexport)
22 #else
23 #define ALURE_API __declspec(dllimport)
24 #endif
26 #else
28 #define ALURE_API
29 #endif
31 #ifndef EFXEAXREVERBPROPERTIES_DEFINED
32 #define EFXEAXREVERBPROPERTIES_DEFINED
33 typedef struct {
34 float flDensity;
35 float flDiffusion;
36 float flGain;
37 float flGainHF;
38 float flGainLF;
39 float flDecayTime;
40 float flDecayHFRatio;
41 float flDecayLFRatio;
42 float flReflectionsGain;
43 float flReflectionsDelay;
44 float flReflectionsPan[3];
45 float flLateReverbGain;
46 float flLateReverbDelay;
47 float flLateReverbPan[3];
48 float flEchoTime;
49 float flEchoDepth;
50 float flModulationTime;
51 float flModulationDepth;
52 float flAirAbsorptionGainHF;
53 float flHFReference;
54 float flLFReference;
55 float flRoomRolloffFactor;
56 int iDecayHFLimit;
57 } EFXEAXREVERBPROPERTIES, *LPEFXEAXREVERBPROPERTIES;
58 #endif
60 namespace alure {
62 class DeviceManager;
63 class DeviceManagerImpl;
64 class Device;
65 class DeviceImpl;
66 class Context;
67 class ContextImpl;
68 class Listener;
69 class ListenerImpl;
70 class Buffer;
71 class BufferImpl;
72 class Source;
73 class SourceImpl;
74 class SourceGroup;
75 class SourceGroupImpl;
76 class AuxiliaryEffectSlot;
77 class AuxiliaryEffectSlotImpl;
78 class Effect;
79 class EffectImpl;
80 class Decoder;
81 class DecoderFactory;
82 class MessageHandler;
85 template<typename T>
86 using RemoveRefT = typename std::remove_reference<T>::type;
87 template<bool B>
88 using EnableIfT = typename std::enable_if<B>::type;
91 // Duration in seconds, using double precision
92 using Seconds = std::chrono::duration<double>;
94 // A SharedPtr implementation, defaults to C++11's std::shared_ptr. If this is
95 // changed, you must recompile the library.
96 template<typename T>
97 using SharedPtr = std::shared_ptr<T>;
98 template<typename T, typename... Args>
99 constexpr inline SharedPtr<T> MakeShared(Args&&... args)
101 return std::make_shared<T>(std::forward<Args>(args)...);
104 // A UniquePtr implementation, defaults to C++11's std::unique_ptr. If this is
105 // changed, you must recompile the library.
106 template<typename T, typename D = std::default_delete<T>>
107 using UniquePtr = std::unique_ptr<T, D>;
108 template<typename T, typename... Args>
109 constexpr inline UniquePtr<T> MakeUnique(Args&&... args)
111 #if __cplusplus >= 201402L
112 return std::make_unique<T>(std::forward<Args>(args)...);
113 #else
114 return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
115 #endif
118 // A Promise/Future (+SharedFuture) implementation, defaults to C++11's
119 // std::promise, std::future, and std::shared_future. If this is changed, you
120 // must recompile the library.
121 template<typename T>
122 using Promise = std::promise<T>;
123 template<typename T>
124 using Future = std::future<T>;
125 template<typename T>
126 using SharedFuture = std::shared_future<T>;
128 // A Vector implementation, defaults to C++'s std::vector. If this is changed,
129 // you must recompile the library.
130 template<typename T>
131 using Vector = std::vector<T>;
133 // A static-sized Array implementation, defaults to C++11's std::array. If this
134 // is changed, you must recompile the library.
135 template<typename T, std::size_t N>
136 using Array = std::array<T, N>;
138 // A String implementation, default's to C++'s std::string. If this is changed,
139 // you must recompile the library.
140 template<typename T>
141 using BasicString = std::basic_string<T>;
142 using String = BasicString<std::string::value_type>;
144 // Tag specific containers that guarantee contiguous storage. The standard
145 // provides no such mechanism, so we have to manually specify which are
146 // acceptable.
147 template<typename T>
148 struct IsContiguousTag : std::false_type {};
149 template<typename T, size_t N>
150 struct IsContiguousTag<Array<T,N>> : std::true_type {};
151 template<typename T>
152 struct IsContiguousTag<Vector<T>> : std::true_type {};
153 template<typename T>
154 struct IsContiguousTag<BasicString<T>> : std::true_type {};
156 // A rather simple ArrayView container. This allows accepting various array
157 // types (Array, Vector, a static-sized array, a dynamic array + size) without
158 // copying its elements.
159 template<typename T>
160 class ArrayView {
161 public:
162 using value_type = T;
163 using iterator = const value_type*;
164 using const_iterator = const value_type*;
166 private:
167 const value_type *mElems;
168 size_t mNumElems;
170 public:
171 ArrayView() noexcept : mElems(nullptr), mNumElems(0) { }
172 ArrayView(const ArrayView&) noexcept = default;
173 ArrayView(ArrayView&&) noexcept = default;
174 ArrayView(const value_type *elems, size_t num_elems) noexcept
175 : mElems(elems), mNumElems(num_elems) { }
176 template<typename OtherT> ArrayView(RemoveRefT<OtherT>&&) = delete;
177 template<typename OtherT,
178 typename = EnableIfT<IsContiguousTag<RemoveRefT<OtherT>>::value>>
179 ArrayView(const OtherT &rhs) noexcept : mElems(rhs.data()), mNumElems(rhs.size()) { }
180 template<size_t N>
181 ArrayView(const value_type (&elems)[N]) noexcept : mElems(elems), mNumElems(N) { }
183 ArrayView& operator=(const ArrayView&) noexcept = default;
185 const value_type *data() const noexcept { return mElems; }
187 size_t size() const noexcept { return mNumElems; }
188 bool empty() const noexcept { return mNumElems == 0; }
190 const value_type& operator[](size_t i) const { return mElems[i]; }
192 const value_type& front() const { return mElems[0]; }
193 const value_type& back() const { return mElems[mNumElems-1]; }
195 const value_type& at(size_t i) const
197 if(i >= mNumElems)
198 throw std::out_of_range("alure::ArrayView::at: element out of range");
199 return mElems[i];
202 const_iterator begin() const noexcept { return mElems; }
203 const_iterator cbegin() const noexcept { return mElems; }
205 const_iterator end() const noexcept { return mElems + mNumElems; }
206 const_iterator cend() const noexcept { return mElems + mNumElems; }
209 template<typename T>
210 class BasicStringView : public ArrayView<T> {
211 using BaseT = ArrayView<T>;
212 using StringT = BasicString<T>;
214 public:
215 using typename BaseT::value_type;
217 BasicStringView() noexcept = default;
218 BasicStringView(const BasicStringView&) noexcept = default;
219 BasicStringView(const value_type *elems, size_t num_elems) noexcept
220 : ArrayView<T>(elems, num_elems) { }
221 BasicStringView(const value_type *elems) : ArrayView<T>(elems, std::strlen(elems)) { }
222 BasicStringView(StringT&&) = delete;
223 BasicStringView(const StringT &rhs) noexcept : ArrayView<T>(rhs) { }
224 #if __cplusplus >= 201703L
225 BasicStringView(const std::basic_string_view<T> &rhs) noexcept
226 : ArrayView<T>(rhs.data(), rhs.length()) { }
227 #endif
229 BasicStringView& operator=(const BasicStringView&) noexcept = default;
231 size_t length() const { return BaseT::size(); }
233 explicit operator StringT() const { return StringT(BaseT::data(), length()); }
234 #if __cplusplus >= 201703L
235 operator std::basic_string_view<T>() const
236 { return std::basic_string_view<T>(BaseT::data(), length()); }
237 #endif
239 StringT operator+(const StringT &rhs) const
241 StringT ret = StringT(*this);
242 ret += rhs;
243 return ret;
245 StringT operator+(const typename StringT::value_type *rhs) const
247 StringT ret = StringT(*this);
248 ret += rhs;
249 return ret;
252 using StringView = BasicStringView<String::value_type>;
254 // Inline operators to concat String and C-style strings with StringViews.
255 template<typename T>
256 inline BasicString<T> operator+(const BasicString<T> &lhs, const BasicStringView<T> &rhs)
257 { return BasicString<T>(lhs).append(rhs.data(), rhs.size()); }
258 template<typename T>
259 inline BasicString<T> operator+(BasicString<T>&& lhs, const BasicStringView<T> &rhs)
260 { return std::move(lhs.append(rhs.data(), rhs.size())); }
261 template<typename T>
262 inline BasicString<T> operator+(const typename BasicString<T>::value_type *lhs, const BasicStringView<T> &rhs)
263 { return lhs + BasicString<T>(rhs); }
264 template<typename T>
265 inline BasicString<T>& operator+=(BasicString<T> &lhs, const BasicStringView<T> &rhs)
266 { return lhs.append(rhs.data(), rhs.size()); }
267 // Inline operator to write out a StringView to an ostream
268 template<typename T>
269 inline std::basic_ostream<T>& operator<<(std::basic_ostream<T> &lhs, const BasicStringView<T> &rhs)
271 for(auto ch : rhs)
272 lhs << ch;
273 return lhs;
278 * An attribute pair, for passing attributes to Device::createContext and
279 * Device::reset.
281 using AttributePair = std::pair<ALCint,ALCint>;
282 static_assert(sizeof(AttributePair) == sizeof(ALCint[2]), "Bad AttributePair size");
285 struct FilterParams {
286 ALfloat mGain;
287 ALfloat mGainHF; // For low-pass and band-pass filters
288 ALfloat mGainLF; // For high-pass and band-pass filters
292 class ALURE_API Vector3 {
293 Array<ALfloat,3> mValue;
295 public:
296 constexpr Vector3() noexcept
297 : mValue{{0.0f, 0.0f, 0.0f}}
299 constexpr Vector3(const Vector3 &rhs) noexcept
300 : mValue{{rhs.mValue[0], rhs.mValue[1], rhs.mValue[2]}}
302 constexpr Vector3(ALfloat val) noexcept
303 : mValue{{val, val, val}}
305 constexpr Vector3(ALfloat x, ALfloat y, ALfloat z) noexcept
306 : mValue{{x, y, z}}
308 Vector3(const ALfloat *vec) noexcept
309 : mValue{{vec[0], vec[1], vec[2]}}
312 const ALfloat *getPtr() const noexcept
313 { return mValue.data(); }
315 ALfloat& operator[](size_t i) noexcept
316 { return mValue[i]; }
317 constexpr const ALfloat& operator[](size_t i) const noexcept
318 { return mValue[i]; }
320 #define ALURE_DECL_OP(op) \
321 constexpr Vector3 operator op(const Vector3 &rhs) const noexcept \
323 return Vector3(mValue[0] op rhs.mValue[0], \
324 mValue[1] op rhs.mValue[1], \
325 mValue[2] op rhs.mValue[2]); \
327 ALURE_DECL_OP(+)
328 ALURE_DECL_OP(-)
329 ALURE_DECL_OP(*)
330 ALURE_DECL_OP(/)
331 #undef ALURE_DECL_OP
332 #define ALURE_DECL_OP(op) \
333 Vector3& operator op(const Vector3 &rhs) noexcept \
335 mValue[0] op rhs.mValue[0]; \
336 mValue[1] op rhs.mValue[1]; \
337 mValue[2] op rhs.mValue[2]; \
338 return *this; \
340 ALURE_DECL_OP(+=)
341 ALURE_DECL_OP(-=)
342 ALURE_DECL_OP(*=)
343 ALURE_DECL_OP(/=)
345 #undef ALURE_DECL_OP
346 #define ALURE_DECL_OP(op) \
347 constexpr Vector3 operator op(ALfloat scale) const noexcept \
349 return Vector3(mValue[0] op scale, \
350 mValue[1] op scale, \
351 mValue[2] op scale); \
353 ALURE_DECL_OP(*)
354 ALURE_DECL_OP(/)
355 #undef ALURE_DECL_OP
356 #define ALURE_DECL_OP(op) \
357 Vector3& operator op(ALfloat scale) noexcept \
359 mValue[0] op scale; \
360 mValue[1] op scale; \
361 mValue[2] op scale; \
362 return *this; \
364 ALURE_DECL_OP(*=)
365 ALURE_DECL_OP(/=)
366 #undef ALURE_DECL_OP
368 constexpr ALfloat getLengthSquared() const noexcept
369 { return mValue[0]*mValue[0] + mValue[1]*mValue[1] + mValue[2]*mValue[2]; }
370 ALfloat getLength() const noexcept
371 { return std::sqrt(getLengthSquared()); }
373 constexpr ALfloat getDistanceSquared(const Vector3 &pos) const noexcept
374 { return (pos - *this).getLengthSquared(); }
375 ALfloat getDistance(const Vector3 &pos) const noexcept
376 { return (pos - *this).getLength(); }
378 static_assert(sizeof(Vector3) == sizeof(ALfloat[3]), "Bad Vector3 size");
381 enum class SampleType {
382 UInt8,
383 Int16,
384 Float32,
385 Mulaw
387 ALURE_API const char *GetSampleTypeName(SampleType type);
389 enum class ChannelConfig {
390 /** 1-channel mono sound. */
391 Mono,
392 /** 2-channel stereo sound. */
393 Stereo,
394 /** 2-channel rear sound (back-left and back-right). */
395 Rear,
396 /** 4-channel surround sound. */
397 Quad,
398 /** 5.1 surround sound. */
399 X51,
400 /** 6.1 surround sound. */
401 X61,
402 /** 7.1 surround sound. */
403 X71,
404 /** 3-channel B-Format, using FuMa channel ordering and scaling. */
405 BFormat2D,
406 /** 4-channel B-Format, using FuMa channel ordering and scaling. */
407 BFormat3D
409 ALURE_API const char *GetChannelConfigName(ChannelConfig cfg);
411 ALURE_API ALuint FramesToBytes(ALuint frames, ChannelConfig chans, SampleType type);
412 ALURE_API ALuint BytesToFrames(ALuint bytes, ChannelConfig chans, SampleType type);
415 /** Class for storing a major.minor version number. */
416 class Version {
417 ALuint mMajor : 16;
418 ALuint mMinor : 16;
420 public:
421 constexpr Version(ALuint _maj, ALuint _min) : mMajor(_maj), mMinor(_min) { }
423 constexpr ALuint getMajor() const noexcept { return mMajor; }
424 constexpr ALuint getMinor() const noexcept { return mMinor; }
425 constexpr bool isZero() const noexcept { return mMajor == 0 && mMinor == 0; }
428 #define MAKE_PIMPL(BaseT, ImplT) \
429 private: \
430 ImplT *pImpl; \
432 public: \
433 using handle_type = ImplT*; \
435 BaseT() : pImpl(nullptr) { } \
436 BaseT(ImplT *impl) : pImpl(impl) { } \
437 BaseT(const BaseT&) = default; \
438 BaseT(BaseT&& rhs) : pImpl(rhs.pImpl) { rhs.pImpl = nullptr; } \
440 BaseT& operator=(const BaseT&) = default; \
441 BaseT& operator=(BaseT&& rhs) \
443 pImpl = rhs.pImpl; rhs.pImpl = nullptr; \
444 return *this; \
447 bool operator==(const BaseT &rhs) const { return pImpl == rhs.pImpl; } \
448 bool operator==(BaseT&& rhs) const { return pImpl == rhs.pImpl; } \
450 operator bool() const { return !!pImpl; } \
452 handle_type getHandle() const { return pImpl; }
454 enum class DeviceEnumeration {
455 Basic = ALC_DEVICE_SPECIFIER,
456 Full = ALC_ALL_DEVICES_SPECIFIER,
457 Capture = ALC_CAPTURE_DEVICE_SPECIFIER
460 enum class DefaultDeviceType {
461 Basic = ALC_DEFAULT_DEVICE_SPECIFIER,
462 Full = ALC_DEFAULT_ALL_DEVICES_SPECIFIER,
463 Capture = ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
467 * A class managing Device objects and other related functionality. This class
468 * is a singleton, only one instance will exist in a process.
470 class ALURE_API DeviceManager {
471 DeviceManagerImpl *pImpl;
473 DeviceManager(DeviceManagerImpl *impl) : pImpl(impl) { }
474 friend class ALDeviceManager;
476 public:
477 DeviceManager(const DeviceManager&) = default;
478 DeviceManager(DeviceManager&& rhs) : pImpl(rhs.pImpl) { }
480 /** Retrieves the DeviceManager instance. */
481 static DeviceManager get();
483 /** Queries the existence of a non-device-specific ALC extension. */
484 bool queryExtension(StringView name) const;
485 bool queryExtension(const char *name) const;
487 /** Enumerates available device names of the given type. */
488 Vector<String> enumerate(DeviceEnumeration type) const;
489 /** Retrieves the default device of the given type. */
490 String defaultDeviceName(DefaultDeviceType type) const;
493 * Opens the playback device given by name, or the default if blank. Throws
494 * an exception on error.
496 Device openPlayback(StringView name=StringView());
497 Device openPlayback(const char *name);
500 * Opens the playback device given by name, or the default if blank.
501 * Returns an empty Device on error.
503 Device openPlayback(StringView name, const std::nothrow_t&);
504 Device openPlayback(const char *name, const std::nothrow_t&);
506 /** Opens the default playback device. Returns an empty Device on error. */
507 Device openPlayback(const std::nothrow_t&);
511 enum class PlaybackName {
512 Basic = ALC_DEVICE_SPECIFIER,
513 Full = ALC_ALL_DEVICES_SPECIFIER
516 class ALURE_API Device {
517 MAKE_PIMPL(Device, DeviceImpl)
519 public:
520 /** Retrieves the device name as given by type. */
521 String getName(PlaybackName type=PlaybackName::Full) const;
522 /** Queries the existence of an ALC extension on this device. */
523 bool queryExtension(StringView name) const;
524 bool queryExtension(const char *name) const;
526 /** Retrieves the ALC version supported by this device. */
527 Version getALCVersion() const;
530 * Retrieves the EFX version supported by this device. If the ALC_EXT_EFX
531 * extension is unsupported, this will be 0.0.
533 Version getEFXVersion() const;
535 /** Retrieves the device's playback frequency, in hz. */
536 ALCuint getFrequency() const;
539 * Retrieves the maximum number of auxiliary source sends. If ALC_EXT_EFX
540 * is unsupported, this will be 0.
542 ALCuint getMaxAuxiliarySends() const;
545 * Enumerates available HRTF names. The names are sorted as OpenAL gives
546 * them, such that the index of a given name is the ID to use with
547 * ALC_HRTF_ID_SOFT.
549 * Requires the ALC_SOFT_HRTF extension.
551 Vector<String> enumerateHRTFNames() const;
554 * Retrieves whether HRTF is enabled on the device or not.
556 * Requires the ALC_SOFT_HRTF extension.
558 bool isHRTFEnabled() const;
561 * Retrieves the name of the HRTF currently being used by this device.
563 * Requires the ALC_SOFT_HRTF extension.
565 String getCurrentHRTF() const;
568 * Resets the device, using the specified attributes.
570 * Requires the ALC_SOFT_HRTF extension.
572 void reset(ArrayView<AttributePair> attributes);
575 * Creates a new Context on this device, using the specified attributes.
577 Context createContext(ArrayView<AttributePair> attributes=ArrayView<AttributePair>());
580 * Pauses device processing, stopping updates for its contexts. Multiple
581 * calls are allowed but it is not reference counted, so the device will
582 * resume after one resumeDSP call.
584 * Requires the ALC_SOFT_pause_device extension.
586 void pauseDSP();
589 * Resumes device processing, restarting updates for its contexts. Multiple
590 * calls are allowed and will no-op.
592 void resumeDSP();
595 * Closes and frees the device. All previously-created contexts must first
596 * be destroyed.
598 void close();
602 enum class DistanceModel {
603 InverseClamped = AL_INVERSE_DISTANCE_CLAMPED,
604 LinearClamped = AL_LINEAR_DISTANCE_CLAMPED,
605 ExponentClamped = AL_EXPONENT_DISTANCE_CLAMPED,
606 Inverse = AL_INVERSE_DISTANCE,
607 Linear = AL_LINEAR_DISTANCE,
608 Exponent = AL_EXPONENT_DISTANCE,
609 None = AL_NONE,
612 class ALURE_API Context {
613 MAKE_PIMPL(Context, ContextImpl)
615 public:
616 /** Makes the specified context current for OpenAL operations. */
617 static void MakeCurrent(Context context);
618 /** Retrieves the current context used for OpenAL operations. */
619 static Context GetCurrent();
622 * Makes the specified context current for OpenAL operations on the calling
623 * thread only. Requires the ALC_EXT_thread_local_context extension on both
624 * the context's device and the DeviceManager.
626 static void MakeThreadCurrent(Context context);
627 /** Retrieves the thread-specific context used for OpenAL operations. */
628 static Context GetThreadCurrent();
631 * Destroys the context. The context must not be current when this is
632 * called.
634 void destroy();
636 /** Retrieves the Device this context was created from. */
637 Device getDevice();
639 void startBatch();
640 void endBatch();
643 * Retrieves a Listener instance for this context. Each context will only
644 * have one listener, which is automatically destroyed with the context.
646 Listener getListener();
649 * Sets a MessageHandler instance which will be used to provide certain
650 * messages back to the application. Only one handler may be set for a
651 * context at a time. The previously set handler will be returned.
653 SharedPtr<MessageHandler> setMessageHandler(SharedPtr<MessageHandler> handler);
655 /** Gets the currently-set message handler. */
656 SharedPtr<MessageHandler> getMessageHandler() const;
659 * Specifies the desired interval that the background thread will be woken
660 * up to process tasks, e.g. keeping streaming sources filled. An interval
661 * of 0 means the background thread will only be woken up manually with
662 * calls to update. The default is 0.
664 void setAsyncWakeInterval(std::chrono::milliseconds interval);
667 * Retrieves the current interval used for waking up the background thread.
669 std::chrono::milliseconds getAsyncWakeInterval() const;
671 // Functions below require the context to be current
674 * Creates a Decoder instance for the given audio file or resource name.
676 SharedPtr<Decoder> createDecoder(const String &name);
679 * Queries if the channel configuration and sample type are supported by
680 * the context.
682 bool isSupported(ChannelConfig channels, SampleType type) const;
685 * Queries the list of resamplers supported by the context. If the
686 * AL_SOFT_source_resampler extension is unsupported this will be an empty
687 * array, otherwise there will be at least one entry.
689 ArrayView<String> getAvailableResamplers();
691 * Queries the context's default resampler index. Be aware, if the
692 * AL_SOFT_source_resampler extension is unsupported the resampler list
693 * will be empty and this will resturn 0. If you try to access the
694 * resampler list with this index without the extension, undefined behavior
695 * will occur (accessing an out of bounds array index).
697 ALsizei getDefaultResamplerIndex() const;
700 * Creates and caches a Buffer for the given audio file or resource name.
701 * Multiple calls with the same name will return the same Buffer object.
702 * Cached buffers must be freed using removeBuffer before destroying the
703 * context. If the buffer can't be loaded it will throw an exception.
705 Buffer getBuffer(const String &name);
708 * Asynchronously prepares a cached Buffer for the given audio file or
709 * resource name. Multiple calls with the same name will return multiple
710 * SharedFutures for the same Buffer object. Once called, the buffer must
711 * be freed using removeBuffer before destroying the context, even if you
712 * never get the Buffer from the SharedFuture.
714 * The Buffer will be scheduled to load asynchronously, and the caller gets
715 * back a SharedFuture that can be checked later (or waited on) to get the
716 * actual Buffer when it's ready. The application must take care to handle
717 * exceptions from the SharedFuture in case an unrecoverable error ocurred
718 * during the load.
720 SharedFuture<Buffer> getBufferAsync(const String &name);
723 * Asynchronously prepares cached Buffers for the given audio file or
724 * resource names. Duplicate names and buffers already cached are ignored.
725 * Cached buffers must be freed using removeBuffer before destroying the
726 * context.
728 * The Buffer objects will be scheduled for loading asynchronously, and
729 * should be retrieved later when needed using getBufferAsync or getBuffer.
730 * Buffers that cannot be loaded, for example due to an unsupported format,
731 * will be ignored and a later call to getBuffer or getBufferAsync will
732 * throw an exception.
734 * Note that you should avoid trying to asynchronously cache more than 16
735 * buffers at a time. The internal ringbuffer used to communicate with the
736 * background thread can only hold 16 async load requests, and trying to
737 * add more will cause the call to stall until the background thread
738 * completes some loads for more to be filled in.
740 void precacheBuffersAsync(ArrayView<String> names);
743 * Creates and caches a Buffer using the given name. The name may alias an
744 * audio file, but it must not currently exist in the buffer cache.
746 Buffer createBufferFrom(const String &name, SharedPtr<Decoder> decoder);
749 * Asynchronously prepares a cached Buffer using the given name. The name
750 * may alias an audio file, but it must not currently exist in the buffer
751 * cache. Once called, the buffer must be freed using removeBuffer before
752 * destroying the context, even if you never get the Buffer from the
753 * SharedFuture.
755 * The Buffer will be scheduled to load asynchronously, and the caller gets
756 * back a SharedFuture that can be checked later (or waited on) to get the
757 * actual Buffer when it's ready. The application must take care to handle
758 * exceptions from the SharedFuture in case an unrecoverable error ocurred
759 * during the load. The decoder must not have its read or seek methods
760 * called while the buffer is not ready.
762 SharedFuture<Buffer> createBufferAsyncFrom(const String &name, SharedPtr<Decoder> decoder);
765 * Deletes the cached Buffer object for the given audio file or resource
766 * name. The buffer must not be in use by a Source.
768 void removeBuffer(const String &name);
770 * Deletes the given cached buffer. The buffer must not be in use by a
771 * Source.
773 void removeBuffer(Buffer buffer);
776 * Creates a new Source. There is no practical limit to the number of
777 * sources you may create. You must call Source::release when the source is
778 * no longer needed.
780 Source createSource();
782 AuxiliaryEffectSlot createAuxiliaryEffectSlot();
784 Effect createEffect();
786 SourceGroup createSourceGroup(String name);
787 SourceGroup getSourceGroup(const String &name);
789 /** Sets the doppler factor to apply to all source calculations. */
790 void setDopplerFactor(ALfloat factor);
793 * Sets the speed of sound propagation, in units per second, to calculate
794 * the doppler effect along with other distance-related time effects. The
795 * default is 343.3 units per second (a realistic speed assuming 1 meter
796 * per unit). If this is adjusted for a different unit scale,
797 * Listener::setMetersPerUnit should also be adjusted.
799 void setSpeedOfSound(ALfloat speed);
801 void setDistanceModel(DistanceModel model);
803 /** Updates the context and all sources belonging to this context. */
804 void update();
807 class ALURE_API Listener {
808 MAKE_PIMPL(Listener, ListenerImpl)
810 public:
811 /** Sets the "master" gain for all context output. */
812 void setGain(ALfloat gain);
815 * Specifies the listener's 3D position, velocity, and orientation
816 * together.
818 void set3DParameters(const Vector3 &position, const Vector3 &velocity, std::pair<Vector3,Vector3> orientation);
820 /** Specifies the listener's 3D position. */
821 void setPosition(ALfloat x, ALfloat y, ALfloat z);
822 void setPosition(const ALfloat *pos);
825 * Specifies the listener's 3D velocity, in units per second. As with
826 * OpenAL, this does not actually alter the listener's position, and
827 * instead just alters the pitch as determined by the doppler effect.
829 void setVelocity(ALfloat x, ALfloat y, ALfloat z);
830 void setVelocity(const ALfloat *vel);
833 * Specifies the listener's 3D orientation, using position-relative 'at'
834 * and 'up' direction vectors.
836 void setOrientation(ALfloat x1, ALfloat y1, ALfloat z1, ALfloat x2, ALfloat y2, ALfloat z2);
837 void setOrientation(const ALfloat *at, const ALfloat *up);
838 void setOrientation(const ALfloat *ori);
841 * Sets the number of meters per unit, used for various effects that rely
842 * on the distance in meters (including air absorption and initial reverb
843 * decay). If this is changed, it's strongly recommended to also set the
844 * speed of sound (e.g. context.setSpeedOfSound(343.3 / m_u) to maintain a
845 * realistic 343.3m/s for sound propagation).
847 void setMetersPerUnit(ALfloat m_u);
851 class ALURE_API Buffer {
852 MAKE_PIMPL(Buffer, BufferImpl)
854 public:
855 /** Retrieves the length of the buffer in sample frames. */
856 ALuint getLength() const;
858 /** Retrieves the buffer's frequency in hz. */
859 ALuint getFrequency() const;
861 /** Retrieves the buffer's sample configuration. */
862 ChannelConfig getChannelConfig() const;
864 /** Retrieves the buffer's sample type. */
865 SampleType getSampleType() const;
867 /** Retrieves the storage size used by the buffer, in bytes. */
868 ALuint getSize() const;
871 * Sets the buffer's loop points, used for looping sources. If the current
872 * context does not support the AL_SOFT_loop_points extension, start and
873 * end must be 0 and getLength() respectively. Otherwise, start must be
874 * less than end, and end must be less than or equal to getLength().
876 * The buffer must not be in use when this method is called.
878 * \param start The starting point, in sample frames (inclusive).
879 * \param end The ending point, in sample frames (exclusive).
881 void setLoopPoints(ALuint start, ALuint end);
883 /** Retrieves the current loop points as a [start,end) pair. */
884 std::pair<ALuint,ALuint> getLoopPoints() const;
887 * Retrieves the Source objects currently playing the buffer. Stopping the
888 * returned sources will allow the buffer to be removed from the context.
890 Vector<Source> getSources() const;
892 /** Retrieves the name the buffer was created with. */
893 const String &getName() const;
895 /** Queries if the buffer is in use and can't be removed. */
896 bool isInUse() const;
900 enum class Spatialize {
901 Off = AL_FALSE,
902 On = AL_TRUE,
903 Auto = 0x0002 /* AL_AUTO_SOFT */
906 class ALURE_API Source {
907 MAKE_PIMPL(Source, SourceImpl)
909 public:
911 * Plays the source using buffer. The same buffer may be played from
912 * multiple sources simultaneously.
914 void play(Buffer buffer);
916 * Plays the source by streaming audio from decoder. This will use
917 * queuesize buffers, each with updatelen sample frames. The given decoder
918 * must *NOT* have its read or seek methods called from elsewhere while in
919 * use.
921 void play(SharedPtr<Decoder> decoder, ALuint updatelen, ALuint queuesize);
923 * Stops playback, releasing the buffer or decoder reference.
925 void stop();
927 /** Pauses the source if it is playing. */
928 void pause();
930 /** Resumes the source if it is paused. */
931 void resume();
933 /** Specifies if the source is currently playing. */
934 bool isPlaying() const;
936 /** Specifies if the source is currently paused. */
937 bool isPaused() const;
940 * Specifies the source's playback priority. Lowest priority sources will
941 * be evicted first when higher priority sources are played.
943 void setPriority(ALuint priority);
944 /** Retrieves the source's priority. */
945 ALuint getPriority() const;
948 * Sets the source's offset, in sample frames. If the source is playing or
949 * paused, it will go to that offset immediately, otherwise the source will
950 * start at the specified offset the next time it's played.
952 void setOffset(uint64_t offset);
954 * Retrieves the source offset in sample frames and its latency in nano-
955 * seconds. For streaming sources this will be the offset based on the
956 * decoder's read position.
958 * If the AL_SOFT_source_latency extension is unsupported, the latency will
959 * be 0.
961 std::pair<uint64_t,std::chrono::nanoseconds> getSampleOffsetLatency() const;
962 uint64_t getSampleOffset() const { return std::get<0>(getSampleOffsetLatency()); }
964 * Retrieves the source offset and latency in seconds. For streaming
965 * sources this will be the offset based on the decoder's read position.
967 * If the AL_SOFT_source_latency extension is unsupported, the latency will
968 * be 0.
970 std::pair<Seconds,Seconds> getSecOffsetLatency() const;
971 Seconds getSecOffset() const { return std::get<0>(getSecOffsetLatency()); }
974 * Specifies if the source should loop on the Buffer or Decoder object's
975 * loop points.
977 void setLooping(bool looping);
978 bool getLooping() const;
981 * Specifies a linear pitch shift base. A value of 1.0 is the default
982 * normal speed.
984 void setPitch(ALfloat pitch);
985 ALfloat getPitch() const;
988 * Specifies the base linear gain. A value of 1.0 is the default normal
989 * volume.
991 void setGain(ALfloat gain);
992 ALfloat getGain() const;
995 * Specifies the minimum and maximum gain. The source's gain is clamped to
996 * this range after distance attenuation and cone attenuation are applied
997 * to the gain base, although before the filter gain adjustements.
999 void setGainRange(ALfloat mingain, ALfloat maxgain);
1000 std::pair<ALfloat,ALfloat> getGainRange() const;
1001 ALfloat getMinGain() const { return std::get<0>(getGainRange()); }
1002 ALfloat getMaxGain() const { return std::get<1>(getGainRange()); }
1005 * Specifies the reference distance and maximum distance the source will
1006 * use for the current distance model. For Clamped distance models, the
1007 * source's calculated distance is clamped to the specified range before
1008 * applying distance-related attenuation.
1010 * For all distance models, the reference distance is the distance at which
1011 * the source's volume will not have any extra attenuation (an effective
1012 * gain multiplier of 1).
1014 void setDistanceRange(ALfloat refdist, ALfloat maxdist);
1015 std::pair<ALfloat,ALfloat> getDistanceRange() const;
1016 ALfloat getReferenceDistance() const { return std::get<0>(getDistanceRange()); }
1017 ALfloat getMaxDistance() const { return std::get<1>(getDistanceRange()); }
1019 /** Specifies the source's 3D position, velocity, and direction together. */
1020 void set3DParameters(const Vector3 &position, const Vector3 &velocity, const Vector3 &direction);
1022 /** Specifies the source's 3D position, velocity, and orientation together. */
1023 void set3DParameters(const Vector3 &position, const Vector3 &velocity, std::pair<Vector3,Vector3> orientation);
1025 /** Specifies the source's 3D position. */
1026 void setPosition(ALfloat x, ALfloat y, ALfloat z);
1027 void setPosition(const ALfloat *pos);
1028 Vector3 getPosition() const;
1031 * Specifies the source's 3D velocity, in units per second. As with OpenAL,
1032 * this does not actually alter the source's position, and instead just
1033 * alters the pitch as determined by the doppler effect.
1035 void setVelocity(ALfloat x, ALfloat y, ALfloat z);
1036 void setVelocity(const ALfloat *vel);
1037 Vector3 getVelocity() const;
1040 * Specifies the source's 3D facing direction. Deprecated in favor of
1041 * setOrientation.
1043 void setDirection(ALfloat x, ALfloat y, ALfloat z);
1044 void setDirection(const ALfloat *dir);
1045 Vector3 getDirection() const;
1048 * Specifies the source's 3D orientation. Note: unlike the AL_EXT_BFORMAT
1049 * extension this property comes from, this also affects the facing
1050 * direction, superceding setDirection.
1052 void setOrientation(ALfloat x1, ALfloat y1, ALfloat z1, ALfloat x2, ALfloat y2, ALfloat z2);
1053 void setOrientation(const ALfloat *at, const ALfloat *up);
1054 void setOrientation(const ALfloat *ori);
1055 std::pair<Vector3,Vector3> getOrientation() const;
1058 * Specifies the source's cone angles, in degrees. The inner angle is the
1059 * area within which the listener will hear the source with no extra
1060 * attenuation, while the listener being outside of the outer angle will
1061 * hear the source attenuated according to the outer cone gains.
1063 void setConeAngles(ALfloat inner, ALfloat outer);
1064 std::pair<ALfloat,ALfloat> getConeAngles() const;
1065 ALfloat getInnerConeAngle() const { return std::get<0>(getConeAngles()); }
1066 ALfloat getOuterConeAngle() const { return std::get<1>(getConeAngles()); }
1069 * Specifies the linear gain multiplier when the listener is outside of the
1070 * source's outer cone area. The specified gain applies to all frequencies,
1071 * while gainhf applies extra attenuation to high frequencies.
1073 * \param gainhf has no effect without the ALC_EXT_EFX extension.
1075 void setOuterConeGains(ALfloat gain, ALfloat gainhf=1.0f);
1076 std::pair<ALfloat,ALfloat> getOuterConeGains() const;
1077 ALfloat getOuterConeGain() const { return std::get<0>(getOuterConeGains()); }
1078 ALfloat getOuterConeGainHF() const { return std::get<1>(getOuterConeGains()); }
1081 * Specifies the rolloff factors for the direct and send paths. This is
1082 * effectively a distance scaling relative to the reference distance. Note:
1083 * the room rolloff factor is 0 by default, disabling distance attenuation
1084 * for send paths. This is because the reverb engine will, by default,
1085 * apply a more realistic room decay based on the reverb decay time and
1086 * distance.
1088 void setRolloffFactors(ALfloat factor, ALfloat roomfactor=0.0f);
1089 std::pair<ALfloat,ALfloat> getRolloffFactors() const;
1090 ALfloat getRolloffFactor() const { return std::get<0>(getRolloffFactors()); }
1091 ALfloat getRoomRolloffFactor() const { return std::get<1>(getRolloffFactors()); }
1094 * Specifies the doppler factor for the doppler effect's pitch shift. This
1095 * effectively scales the source and listener velocities for the doppler
1096 * calculation.
1098 void setDopplerFactor(ALfloat factor);
1099 ALfloat getDopplerFactor() const;
1102 * Specifies if the source's position, velocity, and direction/orientation
1103 * are relative to the listener.
1105 void setRelative(bool relative);
1106 bool getRelative() const;
1109 * Specifies the source's radius. This causes the source to behave as if
1110 * every point within the spherical area emits sound.
1112 * Has no effect without the AL_EXT_SOURCE_RADIUS extension.
1114 void setRadius(ALfloat radius);
1115 ALfloat getRadius() const;
1118 * Specifies the left and right channel angles, in radians, when playing a
1119 * stereo buffer or stream. The angles go counter-clockwise, with 0 being
1120 * in front and positive values going left.
1122 * Has no effect without the AL_EXT_STEREO_ANGLES extension.
1124 void setStereoAngles(ALfloat leftAngle, ALfloat rightAngle);
1125 std::pair<ALfloat,ALfloat> getStereoAngles() const;
1128 * Specifies if the source always has 3D spatialization features (On),
1129 * never has 3D spatialization features (Off), or if spatialization is
1130 * enabled based on playing a mono sound or not (Auto, default). Has no
1131 * effect without the AL_SOFT_source_spatialize extension.
1133 void set3DSpatialize(Spatialize spatialize);
1134 Spatialize get3DSpatialize() const;
1136 void setResamplerIndex(ALsizei index);
1137 ALsizei getResamplerIndex() const;
1140 * Specifies a multiplier for the amount of atmospheric high-frequency
1141 * absorption, ranging from 0 to 10. A factor of 1 results in a nominal
1142 * -0.05dB per meter, with higher values simulating foggy air and lower
1143 * values simulating dryer air. The default is 0.
1145 void setAirAbsorptionFactor(ALfloat factor);
1146 ALfloat getAirAbsorptionFactor() const;
1148 void setGainAuto(bool directhf, bool send, bool sendhf);
1149 std::tuple<bool,bool,bool> getGainAuto() const;
1150 bool getDirectGainHFAuto() const { return std::get<0>(getGainAuto()); }
1151 bool getSendGainAuto() const { return std::get<1>(getGainAuto()); }
1152 bool getSendGainHFAuto() const { return std::get<2>(getGainAuto()); }
1154 /** Sets the filter properties on the direct path signal. */
1155 void setDirectFilter(const FilterParams &filter);
1157 * Sets the filter properties on the given send path signal. Any auxiliary
1158 * effect slot on the send path remains in place.
1160 void setSendFilter(ALuint send, const FilterParams &filter);
1162 * Connects the effect slot to the given send path. Any filter properties
1163 * on the send path remain as they were.
1165 void setAuxiliarySend(AuxiliaryEffectSlot slot, ALuint send);
1167 * Connects the effect slot to the given send path, using the filter
1168 * properties.
1170 void setAuxiliarySendFilter(AuxiliaryEffectSlot slot, ALuint send, const FilterParams &filter);
1173 * Releases the source, stopping playback, releasing resources, and
1174 * returning it to the system.
1176 void release();
1180 class ALURE_API SourceGroup {
1181 MAKE_PIMPL(SourceGroup, SourceGroupImpl)
1183 public:
1184 /** Retrieves the associated name of the source group. */
1185 const String &getName() const;
1188 * Adds source to the source group. A source may only be part of one group
1189 * at a time, and will automatically be removed from its current group as
1190 * needed.
1192 void addSource(Source source);
1193 /** Removes source from the source group. */
1194 void removeSource(Source source);
1196 /** Adds a list of sources to the group at once. */
1197 void addSources(ArrayView<Source> sources);
1198 /** Removes a list of sources from the source group. */
1199 void removeSources(ArrayView<Source> sources);
1202 * Adds group as a subgroup of the source group. This method will throw an
1203 * exception if group is being added to a group it has as a sub-group (i.e.
1204 * it would create a circular sub-group chain).
1206 void addSubGroup(SourceGroup group);
1207 /** Removes group from the source group. */
1208 void removeSubGroup(SourceGroup group);
1210 /** Returns the list of sources currently in the group. */
1211 Vector<Source> getSources() const;
1213 /** Returns the list of subgroups currently in the group. */
1214 Vector<SourceGroup> getSubGroups() const;
1216 /** Sets the source group gain, which accumulates with its sources. */
1217 void setGain(ALfloat gain);
1218 /** Gets the source group gain. */
1219 ALfloat getGain() const;
1221 /** Sets the source group pitch, which accumulates with its sources. */
1222 void setPitch(ALfloat pitch);
1223 /** Gets the source group pitch. */
1224 ALfloat getPitch() const;
1227 * Pauses all currently-playing sources that are under this group,
1228 * including sub-groups.
1230 void pauseAll() const;
1232 * Resumes all paused sources that are under this group, including
1233 * sub-groups.
1235 void resumeAll() const;
1237 /** Stops all sources that are under this group, including sub-groups. */
1238 void stopAll() const;
1241 * Releases the source group, removing all sources from it before being
1242 * freed.
1244 void release();
1248 struct SourceSend {
1249 Source mSource;
1250 ALuint mSend;
1253 class ALURE_API AuxiliaryEffectSlot {
1254 MAKE_PIMPL(AuxiliaryEffectSlot, AuxiliaryEffectSlotImpl)
1256 public:
1257 void setGain(ALfloat gain);
1259 * If set to true, the reverb effect will automatically apply adjustments
1260 * to the source's send slot gains based on the effect properties.
1262 * Has no effect when using non-reverb effects. Default is true.
1264 void setSendAuto(bool sendauto);
1267 * Updates the effect slot with a new effect. The given effect object may
1268 * be altered or destroyed without affecting the effect slot.
1270 void applyEffect(Effect effect);
1273 * Releases the effect slot, returning it to the system. It must not be in
1274 * use by a source.
1276 void release();
1279 * Retrieves each Source object and its pairing send this effect slot is
1280 * set on. Setting a different (or null) effect slot on each source's given
1281 * send will allow the effect slot to be released.
1283 Vector<SourceSend> getSourceSends() const;
1285 /** Determines if the effect slot is in use by a source. */
1286 bool isInUse() const;
1290 class ALURE_API Effect {
1291 MAKE_PIMPL(Effect, EffectImpl)
1293 public:
1295 * Updates the effect with the specified reverb properties. If the
1296 * EAXReverb effect is not supported, it will automatically attempt to
1297 * downgrade to the Standard Reverb effect.
1299 void setReverbProperties(const EFXEAXREVERBPROPERTIES &props);
1301 void destroy();
1306 * Audio decoder interface. Applications may derive from this, implementing the
1307 * necessary methods, and use it in places the API wants a Decoder object.
1309 class ALURE_API Decoder {
1310 public:
1311 virtual ~Decoder();
1313 /** Retrieves the sample frequency, in hz, of the audio being decoded. */
1314 virtual ALuint getFrequency() const = 0;
1315 /** Retrieves the channel configuration of the audio being decoded. */
1316 virtual ChannelConfig getChannelConfig() const = 0;
1317 /** Retrieves the sample type of the audio being decoded. */
1318 virtual SampleType getSampleType() const = 0;
1321 * Retrieves the total length of the audio, in sample frames. If unknown,
1322 * returns 0. Note that if the returned length is 0, the decoder may not be
1323 * used to load a Buffer.
1325 virtual uint64_t getLength() const = 0;
1327 * Seek to pos, specified in sample frames. Returns true if the seek was
1328 * successful.
1330 virtual bool seek(uint64_t pos) = 0;
1333 * Retrieves the loop points, in sample frames, as a [start,end) pair. If
1334 * start >= end, use all available data.
1336 virtual std::pair<uint64_t,uint64_t> getLoopPoints() const = 0;
1339 * Decodes count sample frames, writing them to ptr, and returns the number
1340 * of sample frames written. Returning less than the requested count
1341 * indicates the end of the audio.
1343 virtual ALuint read(ALvoid *ptr, ALuint count) = 0;
1347 * Audio decoder factory interface. Applications may derive from this,
1348 * implementing the necessary methods, and use it in places the API wants a
1349 * DecoderFactory object.
1351 class ALURE_API DecoderFactory {
1352 public:
1353 virtual ~DecoderFactory();
1356 * Creates and returns a Decoder instance for the given resource file. If
1357 * the decoder needs to retain the file handle for reading as-needed, it
1358 * should move the UniquePtr to internal storage.
1360 * \return nullptr if a decoder can't be created from the file.
1362 virtual SharedPtr<Decoder> createDecoder(UniquePtr<std::istream> &file) = 0;
1366 * Registers a decoder factory for decoding audio. Registered factories are
1367 * used in lexicographical order, e.g. if Factory1 is registered with name1 and
1368 * Factory2 is registered with name2, Factory1 will be used before Factory2 if
1369 * name1 < name2. Internal decoder factories are always used after registered
1370 * ones.
1372 * Alure retains a reference to the DecoderFactory instance and will release it
1373 * (destructing the object) when the library unloads.
1375 * \param name A unique name identifying this decoder factory.
1376 * \param factory A DecoderFactory instance used to create Decoder instances.
1378 ALURE_API void RegisterDecoder(const String &name, UniquePtr<DecoderFactory> factory);
1381 * Unregisters a decoder factory by name. Alure returns the instance back to
1382 * the application.
1384 * \param name The unique name identifying a previously-registered decoder
1385 * factory.
1387 * \return The unregistered decoder factory instance, or 0 (nullptr) if a
1388 * decoder factory with the given name doesn't exist.
1390 ALURE_API UniquePtr<DecoderFactory> UnregisterDecoder(const String &name);
1394 * A file I/O factory interface. Applications may derive from this and set an
1395 * instance to be used by the audio decoders. By default, the library uses
1396 * standard I/O.
1398 class ALURE_API FileIOFactory {
1399 public:
1401 * Sets the factory instance to be used by the audio decoders. If a
1402 * previous factory was set, it's returned to the application. Passing in a
1403 * nullptr reverts to the default.
1405 static UniquePtr<FileIOFactory> set(UniquePtr<FileIOFactory> factory);
1408 * Gets the current FileIOFactory instance being used by the audio
1409 * decoders.
1411 static FileIOFactory &get();
1413 virtual ~FileIOFactory();
1415 /** Opens a read-only binary file for the given name. */
1416 virtual UniquePtr<std::istream> openFile(const String &name) = 0;
1421 * A message handler interface. Applications may derive from this and set an
1422 * instance on a context to receive messages. The base methods are no-ops, so
1423 * derived classes only need to implement methods for relevant messages.
1425 * It's recommended that applications mark their handler methods using the
1426 * override keyword, to ensure they're properly overriding the base methods in
1427 * case they change.
1429 class ALURE_API MessageHandler {
1430 public:
1431 virtual ~MessageHandler();
1434 * Called when the given device has been disconnected and is no longer
1435 * usable for output. As per the ALC_EXT_disconnect specification,
1436 * disconnected devices remain valid, however all playing sources are
1437 * automatically stopped, any sources that are attempted to play will
1438 * immediately stop, and new contexts may not be created on the device.
1440 * Note that connection status is checked during Context::update calls, so
1441 * that method must be called regularly to be notified when a device is
1442 * disconnected. This method may not be called if the device lacks support
1443 * for the ALC_EXT_disconnect extension.
1445 virtual void deviceDisconnected(Device device);
1448 * Called when the given source reaches the end of the buffer or stream.
1450 * Sources that stopped automatically will be detected upon a call to
1451 * Context::update.
1453 virtual void sourceStopped(Source source);
1456 * Called when the given source was forced to stop. This can be because
1457 * either there were no more system sources and a higher-priority source
1458 * preempted it, or it's part of a SourceGroup (or sub-group thereof) that
1459 * had its SourceGroup::stopAll method called.
1461 virtual void sourceForceStopped(Source source);
1464 * Called when a new buffer is about to be created and loaded. May be
1465 * called asynchronously for buffers being loaded asynchronously.
1467 * \param name The resource name, as passed to Context::getBuffer.
1468 * \param channels Channel configuration of the given audio data.
1469 * \param type Sample type of the given audio data.
1470 * \param samplerate Sample rate of the given audio data.
1471 * \param data The audio data that is about to be fed to the OpenAL buffer.
1473 virtual void bufferLoading(StringView name, ChannelConfig channels, SampleType type, ALuint samplerate, ArrayView<ALbyte> data);
1476 * Called when a resource isn't found, allowing the app to substitute in a
1477 * different resource. For buffers created with Context::getBuffer or
1478 * Context::getBufferAsync, the original name will still be used for the
1479 * cache map so the app doesn't have to keep track of substituted resource
1480 * names.
1482 * This will be called again if the new name isn't found.
1484 * \param name The resource name that was not found.
1485 * \return The replacement resource name to use instead. Returning an empty
1486 * string means to stop trying.
1488 virtual String resourceNotFound(StringView name);
1491 #undef MAKE_PIMPL
1493 } // namespace alure
1495 #endif /* AL_ALURE2_H */