Fix out-dated comment
[alure.git] / include / AL / alure2.h
blob825985410324a7fb5ba423c414b094b2f22605fc
1 #ifndef AL_ALURE2_H
2 #define AL_ALURE2_H
4 #include <vector>
5 #include <string>
6 #include <memory>
7 #include <utility>
8 #include <array>
9 #include <cmath>
11 #include "alc.h"
12 #include "al.h"
14 #ifdef _WIN32
15 #if defined(ALURE_BUILD_STATIC) || defined(ALURE_STATIC_LIB)
16 #define ALURE_API
17 #elif defined(ALURE_BUILD_DLL)
18 #define ALURE_API __declspec(dllexport)
19 #else
20 #define ALURE_API __declspec(dllimport)
21 #endif
23 #else
25 #define ALURE_API
26 #endif
28 #ifndef EFXEAXREVERBPROPERTIES_DEFINED
29 #define EFXEAXREVERBPROPERTIES_DEFINED
30 typedef struct {
31 float flDensity;
32 float flDiffusion;
33 float flGain;
34 float flGainHF;
35 float flGainLF;
36 float flDecayTime;
37 float flDecayHFRatio;
38 float flDecayLFRatio;
39 float flReflectionsGain;
40 float flReflectionsDelay;
41 float flReflectionsPan[3];
42 float flLateReverbGain;
43 float flLateReverbDelay;
44 float flLateReverbPan[3];
45 float flEchoTime;
46 float flEchoDepth;
47 float flModulationTime;
48 float flModulationDepth;
49 float flAirAbsorptionGainHF;
50 float flHFReference;
51 float flLFReference;
52 float flRoomRolloffFactor;
53 int iDecayHFLimit;
54 } EFXEAXREVERBPROPERTIES, *LPEFXEAXREVERBPROPERTIES;
55 #endif
57 namespace alure {
59 class DeviceManager;
60 class Device;
61 class Context;
62 class Listener;
63 class Buffer;
64 class Source;
65 class SourceGroup;
66 class AuxiliaryEffectSlot;
67 class Effect;
68 class Decoder;
69 class DecoderFactory;
70 class MessageHandler;
73 // A SharedPtr implementation, defaults to C++11's std::shared_ptr. If this is
74 // changed, you must recompile the library.
75 template<typename T>
76 using SharedPtr = std::shared_ptr<T>;
77 template<typename T, typename... Args>
78 constexpr inline SharedPtr<T> MakeShared(Args&&... args)
80 return std::make_shared<T>(std::forward<Args>(args)...);
83 // A UniquePtr implementation, defaults to C++11's std::unique_ptr. If this is
84 // changed, you must recompile the library.
85 template<typename T, typename D = std::default_delete<T>>
86 using UniquePtr = std::unique_ptr<T, D>;
87 template<typename T, typename... Args>
88 constexpr inline UniquePtr<T> MakeUnique(Args&&... args)
90 #if __cplusplus >= 201402L
91 return std::make_unique<T>(std::forward<Args>(args)...);
92 #else
93 return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
94 #endif
97 // A Vector implementation, defaults to C++'s std::vector. If this is changed,
98 // you must recompile the library.
99 template<typename T>
100 using Vector = std::vector<T>;
102 // A String implementation, default's to C++'s std::string. If this is changed,
103 // you must recompile the library.
104 using String = std::string;
106 // A rather simple ArrayView container. This allows accepting various array
107 // types (std::array, Vector, a static-sized array, a dynamic array + size)
108 // without copying its elements.
109 template<typename T>
110 class ArrayView {
111 T *mElems;
112 size_t mNumElems;
114 public:
115 typedef T *iterator;
116 typedef const T *const_iterator;
118 ArrayView() : mElems(nullptr), mNumElems(0) { }
119 ArrayView(const ArrayView &rhs) : mElems(rhs.data()), mNumElems(rhs.size()) { }
120 ArrayView(ArrayView&& rhs) : mElems(rhs.data()), mNumElems(rhs.size()) { }
121 ArrayView(T *elems, size_t num_elems) : mElems(elems), mNumElems(num_elems) { }
122 template<size_t N>
123 ArrayView(T (&elems)[N]) : mElems(elems), mNumElems(N) { }
124 template<typename OtherT>
125 ArrayView(OtherT &arr) : mElems(arr.data()), mNumElems(arr.size()) { }
127 ArrayView& operator=(const ArrayView &rhs)
129 mElems = rhs.data();
130 mNumElems = rhs.size();
132 ArrayView& operator=(ArrayView&& rhs)
134 mElems = rhs.data();
135 mNumElems = rhs.size();
137 template<size_t N>
138 ArrayView& operator=(T (&elems)[N])
140 mElems = elems;
141 mNumElems = N;
143 template<typename OtherT>
144 ArrayView& operator=(OtherT &arr)
146 mElems = arr.data();
147 mNumElems = arr.size();
151 const T *data() const { return mElems; }
152 T *data() { return mElems; }
154 size_t size() const { return mNumElems; }
155 bool empty() const { return mNumElems == 0; }
157 const T& operator[](size_t i) const { return mElems[i]; }
158 T& operator[](size_t i) { return mElems[i]; }
160 const T& front() const { return mElems[0]; }
161 T& front() { return mElems[0]; }
162 const T& back() const { return mElems[mNumElems-1]; }
163 T& back() { return mElems[mNumElems-1]; }
165 const T& at(size_t i) const
167 if(i >= mNumElems)
168 throw std::out_of_range("alure::ArrayView::at: element out of range");
169 return mElems[i];
171 T& at(size_t i)
173 if(i >= mNumElems)
174 throw std::out_of_range("alure::ArrayView::at: element out of range");
175 return mElems[i];
178 iterator begin() { return mElems; }
179 const_iterator begin() const { return mElems; }
180 const_iterator cbegin() const { return mElems; }
182 iterator end() { return mElems + mNumElems; }
183 const_iterator end() const { return mElems + mNumElems; }
184 const_iterator cend() const { return mElems + mNumElems; }
189 * An attribute pair, for passing attributes to Device::createContext and
190 * Device::reset.
192 using AttributePair = std::pair<ALCint,ALCint>;
193 static_assert(sizeof(AttributePair) == sizeof(ALCint[2]), "Bad AttributePair size");
196 struct FilterParams {
197 ALfloat mGain;
198 ALfloat mGainHF; // For low-pass and band-pass filters
199 ALfloat mGainLF; // For high-pass and band-pass filters
203 class ALURE_API Vector3 {
204 std::array<ALfloat,3> mValue;
206 public:
207 constexpr Vector3() noexcept
208 : mValue{{0.0f, 0.0f, 0.0f}}
210 constexpr Vector3(const Vector3 &rhs) noexcept
211 : mValue{{rhs.mValue[0], rhs.mValue[1], rhs.mValue[2]}}
213 constexpr Vector3(ALfloat val) noexcept
214 : mValue{{val, val, val}}
216 constexpr Vector3(ALfloat x, ALfloat y, ALfloat z) noexcept
217 : mValue{{x, y, z}}
219 Vector3(const ALfloat *vec) noexcept
220 : mValue{{vec[0], vec[1], vec[2]}}
223 const ALfloat *getPtr() const noexcept
224 { return mValue.data(); }
226 ALfloat& operator[](size_t i) noexcept
227 { return mValue[i]; }
228 constexpr const ALfloat& operator[](size_t i) const noexcept
229 { return mValue[i]; }
231 #define ALURE_DECL_OP(op) \
232 constexpr Vector3 operator op(const Vector3 &rhs) const noexcept \
234 return Vector3(mValue[0] op rhs.mValue[0], \
235 mValue[1] op rhs.mValue[1], \
236 mValue[2] op rhs.mValue[2]); \
238 ALURE_DECL_OP(+)
239 ALURE_DECL_OP(-)
240 ALURE_DECL_OP(*)
241 ALURE_DECL_OP(/)
242 #undef ALURE_DECL_OP
243 #define ALURE_DECL_OP(op) \
244 Vector3& operator op(const Vector3 &rhs) noexcept \
246 mValue[0] op rhs.mValue[0]; \
247 mValue[1] op rhs.mValue[1]; \
248 mValue[2] op rhs.mValue[2]; \
249 return *this; \
251 ALURE_DECL_OP(+=)
252 ALURE_DECL_OP(-=)
253 ALURE_DECL_OP(*=)
254 ALURE_DECL_OP(/=)
256 #undef ALURE_DECL_OP
257 #define ALURE_DECL_OP(op) \
258 constexpr Vector3 operator op(ALfloat scale) const noexcept \
260 return Vector3(mValue[0] op scale, \
261 mValue[1] op scale, \
262 mValue[2] op scale); \
264 ALURE_DECL_OP(*)
265 ALURE_DECL_OP(/)
266 #undef ALURE_DECL_OP
267 #define ALURE_DECL_OP(op) \
268 Vector3& operator op(ALfloat scale) noexcept \
270 mValue[0] op scale; \
271 mValue[1] op scale; \
272 mValue[2] op scale; \
273 return *this; \
275 ALURE_DECL_OP(*=)
276 ALURE_DECL_OP(/=)
277 #undef ALURE_DECL_OP
279 constexpr ALfloat getLengthSquared() const noexcept
280 { return mValue[0]*mValue[0] + mValue[1]*mValue[1] + mValue[2]*mValue[2]; }
281 ALfloat getLength() const noexcept
282 { return std::sqrt(getLengthSquared()); }
284 constexpr ALfloat getDistanceSquared(const Vector3 &pos) const noexcept
285 { return (pos - *this).getLengthSquared(); }
286 ALfloat getDistance(const Vector3 &pos) const noexcept
287 { return (pos - *this).getLength(); }
289 static_assert(sizeof(Vector3) == sizeof(ALfloat[3]), "Bad Vector3 size");
292 enum class SampleType {
293 UInt8,
294 Int16,
295 Float32,
296 Mulaw
298 ALURE_API const char *GetSampleTypeName(SampleType type);
300 enum class ChannelConfig {
301 /** 1-channel mono sound. */
302 Mono,
303 /** 2-channel stereo sound. */
304 Stereo,
305 /** 2-channel rear sound (back-left and back-right). */
306 Rear,
307 /** 4-channel surround sound. */
308 Quad,
309 /** 5.1 surround sound. */
310 X51,
311 /** 6.1 surround sound. */
312 X61,
313 /** 7.1 surround sound. */
314 X71,
315 /** 3-channel B-Format, using FuMa channel ordering and scaling. */
316 BFormat2D,
317 /** 4-channel B-Format, using FuMa channel ordering and scaling. */
318 BFormat3D
320 ALURE_API const char *GetChannelConfigName(ChannelConfig cfg);
322 ALURE_API ALuint FramesToBytes(ALuint frames, ChannelConfig chans, SampleType type);
323 ALURE_API ALuint BytesToFrames(ALuint bytes, ChannelConfig chans, SampleType type);
327 * Creates a version number value using the specified major and minor values.
329 constexpr inline ALCuint MakeVersion(ALCushort major, ALCushort minor)
330 { return (major<<16) | minor; }
333 * Retrieves the major version of a version number value created by
334 * MakeVersion.
336 constexpr inline ALCuint MajorVersion(ALCuint version)
337 { return version>>16; }
339 * Retrieves the minor version of a version number value created by
340 * MakeVersion.
342 constexpr inline ALCuint MinorVersion(ALCuint version)
343 { return version&0xffff; }
346 enum class DeviceEnumeration {
347 Basic = ALC_DEVICE_SPECIFIER,
348 Complete = ALC_ALL_DEVICES_SPECIFIER,
349 Capture = ALC_CAPTURE_DEVICE_SPECIFIER
352 enum class DefaultDeviceType {
353 Basic = ALC_DEFAULT_DEVICE_SPECIFIER,
354 Complete = ALC_DEFAULT_ALL_DEVICES_SPECIFIER,
355 Capture = ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
359 * A class managing Device objects and other related functionality. This class
360 * is a singleton, only one instance will exist in a process.
362 class ALURE_API DeviceManager {
363 public:
364 /** Retrieves the DeviceManager instance. */
365 static DeviceManager &get();
367 /** Queries the existence of a non-device-specific ALC extension. */
368 virtual bool queryExtension(const String &name) const = 0;
370 /** Enumerates available device names of the given type. */
371 virtual Vector<String> enumerate(DeviceEnumeration type) const = 0;
372 /** Retrieves the default device of the given type. */
373 virtual String defaultDeviceName(DefaultDeviceType type) const = 0;
375 /** Opens the playback device given by name, or the default if empty. */
376 virtual Device openPlayback(const String &name=String()) = 0;
380 enum class PlaybackDeviceName {
381 Basic = ALC_DEVICE_SPECIFIER,
382 Complete = ALC_ALL_DEVICES_SPECIFIER
385 #define MAKE_PIMPL(BaseT, ImplT) \
386 private: \
387 ImplT *pImpl; \
389 BaseT(ImplT *impl) : pImpl(impl) { } \
391 public: \
392 BaseT() : pImpl(nullptr) { } \
393 BaseT(const BaseT&) = default; \
394 BaseT(BaseT&&) = default; \
396 BaseT& operator=(std::nullptr_t) { pImpl = nullptr; return *this; } \
397 BaseT& operator=(const BaseT&) = default; \
398 BaseT& operator=(BaseT&&) = default; \
400 bool operator==(const BaseT &rhs) const { return pImpl == rhs.pImpl; } \
401 bool operator==(BaseT&& rhs) const { return pImpl == rhs.pImpl; }
403 class ALDevice;
404 class ALURE_API Device {
405 friend class ALDeviceManager;
406 friend class ALContext;
408 MAKE_PIMPL(Device, ALDevice)
410 public:
411 /** Retrieves the device name as given by type. */
412 String getName(PlaybackDeviceName type=PlaybackDeviceName::Basic) const;
413 /** Queries the existence of an ALC extension on this device. */
414 bool queryExtension(const String &name) const;
417 * Retrieves the ALC version supported by this device, as constructed by
418 * MakeVersion.
420 ALCuint getALCVersion() const;
423 * Retrieves the EFX version supported by this device, as constructed by
424 * MakeVersion. If the ALC_EXT_EFX extension is unsupported, this will be
425 * 0.
427 ALCuint getEFXVersion() const;
429 /** Retrieves the device's playback frequency, in hz. */
430 ALCuint getFrequency() const;
433 * Retrieves the maximum number of auxiliary source sends. If ALC_EXT_EFX
434 * is unsupported, this will be 0.
436 ALCuint getMaxAuxiliarySends() const;
439 * Enumerates available HRTF names. The names are sorted as OpenAL gives
440 * them, such that the index of a given name is the ID to use with
441 * ALC_HRTF_ID_SOFT.
443 * Requires the ALC_SOFT_HRTF extension.
445 Vector<String> enumerateHRTFNames() const;
448 * Retrieves whether HRTF is enabled on the device or not.
450 * Requires the ALC_SOFT_HRTF extension.
452 bool isHRTFEnabled() const;
455 * Retrieves the name of the HRTF currently being used by this device.
457 * Requires the ALC_SOFT_HRTF extension.
459 String getCurrentHRTF() const;
462 * Resets the device, using the specified attributes.
464 * Requires the ALC_SOFT_HRTF extension.
466 void reset(ArrayView<AttributePair> attributes);
469 * Creates a new Context on this device, using the specified attributes.
471 Context createContext(ArrayView<AttributePair> attributes=ArrayView<AttributePair>());
474 * Pauses device processing, stopping updates for its contexts. Multiple
475 * calls are allowed but it is not reference counted, so the device will
476 * resume after one resumeDSP call.
478 * Requires the ALC_SOFT_pause_device extension.
480 void pauseDSP();
483 * Resumes device processing, restarting updates for its contexts. Multiple
484 * calls are allowed and will no-op.
486 void resumeDSP();
489 * Closes and frees the device. All previously-created contexts must first
490 * be destroyed.
492 void close();
496 enum class DistanceModel {
497 InverseClamped = AL_INVERSE_DISTANCE_CLAMPED,
498 LinearClamped = AL_LINEAR_DISTANCE_CLAMPED,
499 ExponentClamped = AL_EXPONENT_DISTANCE_CLAMPED,
500 Inverse = AL_INVERSE_DISTANCE,
501 Linear = AL_LINEAR_DISTANCE,
502 Exponent = AL_EXPONENT_DISTANCE,
503 None = AL_NONE,
506 class ALContext;
507 class ALURE_API Context {
508 friend class ALDevice;
510 MAKE_PIMPL(Context, ALContext)
512 public:
513 /** Makes the specified context current for OpenAL operations. */
514 static void MakeCurrent(Context context);
515 /** Removes the current context for OpenAL operations. */
516 static void MakeCurrent(std::nullptr_t);
517 /** Retrieves the current context used for OpenAL operations. */
518 static Context GetCurrent();
521 * Makes the specified context current for OpenAL operations on the calling
522 * thread only. Requires the ALC_EXT_thread_local_context extension on both
523 * the context's device and the DeviceManager.
525 static void MakeThreadCurrent(Context context);
527 * Removes the current context for OpenAL operations on the calling thread
528 * only.
530 static void MakeThreadCurrent(std::nullptr_t);
531 /** Retrieves the thread-specific context used for OpenAL operations. */
532 static Context GetThreadCurrent();
535 * Destroys the context. The context must not be current when this is
536 * called.
538 void destroy();
540 /** Retrieves the Device this context was created from. */
541 Device getDevice();
543 void startBatch();
544 void endBatch();
547 * Retrieves a Listener instance for this context. Each context will only
548 * have one listener.
550 Listener getListener();
553 * Sets a MessageHandler instance which will be used to provide certain
554 * messages back to the application. Only one handler may be set for a
555 * context at a time. The previously set handler will be returned.
557 SharedPtr<MessageHandler> setMessageHandler(SharedPtr<MessageHandler> handler);
559 /** Gets the currently-set message handler. */
560 SharedPtr<MessageHandler> getMessageHandler() const;
563 * Specifies the desired interval (in milliseconds) that the background
564 * thread will be woken up to process tasks, e.g. keeping streaming sources
565 * filled. An interval of 0 means the background thread will only be woken
566 * up manually with calls to update. The default is 0.
568 void setAsyncWakeInterval(ALuint msec);
571 * Retrieves the current interval used for waking up the background thread.
573 ALuint getAsyncWakeInterval() const;
576 * Creates a Decoder instance for the given audio file or resource name.
578 SharedPtr<Decoder> createDecoder(const String &name);
580 // Functions below require the context to be current
583 * Queries if the channel configuration and sample type are supported by
584 * the context.
586 bool isSupported(ChannelConfig channels, SampleType type) const;
589 * Queries the list of resamplers supported by the context. If the
590 * AL_SOFT_source_resampler extension is unsupported this will be an empty
591 * vector, otherwise there will be at least one entry.
593 const Vector<String> &getAvailableResamplers();
595 * Queries the context's default resampler index. Be aware, if the
596 * AL_SOFT_source_resampler extension is unsupported the resampler list
597 * will be empty and this will resturn 0. If you try to access the
598 * resampler list with this index without the extension, undefined behavior
599 * (accessing an out of bounds array index) will occur.
601 ALsizei getDefaultResamplerIndex() const;
604 * Creates and caches a Buffer for the given audio file or resource name.
605 * Multiple calls with the same name will return the same Buffer object.
607 Buffer getBuffer(const String &name);
610 * Creates and caches a Buffer for the given audio file or resource name.
611 * Multiple calls with the same name will return the same Buffer object.
613 * The returned Buffer object will be scheduled for loading asynchronously,
614 * and must be checked with a call to Buffer::getLoadStatus prior to being
615 * played.
617 Buffer getBufferAsync(const String &name);
620 * Deletes the cached Buffer object for the given audio file or
621 * resource name. The buffer must not be in use by a Source.
623 void removeBuffer(const String &name);
625 * Deletes the given cached buffer instance. The buffer must not be in use
626 * by a Source.
628 void removeBuffer(Buffer buffer);
631 * Creates a new Source. There is no practical limit to the number of
632 * sources you may create.
634 Source createSource();
636 AuxiliaryEffectSlot createAuxiliaryEffectSlot();
638 Effect createEffect();
640 SourceGroup createSourceGroup(String name);
641 SourceGroup getSourceGroup(const String &name);
643 void setDopplerFactor(ALfloat factor);
645 void setSpeedOfSound(ALfloat speed);
647 void setDistanceModel(DistanceModel model);
650 * Updates the context and all sources belonging to this context (you do
651 * not need to call the individual sources' update method if you call this
652 * function).
654 void update();
657 class ALListener;
658 class ALURE_API Listener {
659 friend class ALContext;
661 MAKE_PIMPL(Listener, ALListener)
663 public:
664 void setGain(ALfloat gain);
666 void setPosition(ALfloat x, ALfloat y, ALfloat z);
667 void setPosition(const ALfloat *pos);
669 void setVelocity(ALfloat x, ALfloat y, ALfloat z);
670 void setVelocity(const ALfloat *vel);
672 void setOrientation(ALfloat x1, ALfloat y1, ALfloat z1, ALfloat x2, ALfloat y2, ALfloat z2);
673 void setOrientation(const ALfloat *at, const ALfloat *up);
674 void setOrientation(const ALfloat *ori);
676 void setMetersPerUnit(ALfloat m_u);
680 enum class BufferLoadStatus {
681 Pending,
682 Ready
685 class ALBuffer;
686 class ALURE_API Buffer {
687 friend class ALContext;
688 friend class ALSource;
690 MAKE_PIMPL(Buffer, ALBuffer)
692 public:
694 * Retrieves the length of the buffer in sample frames. The buffer must be
695 * fully loaded before this method is called.
697 ALuint getLength() const;
699 /** Retrieves the buffer's frequency in hz. */
700 ALuint getFrequency() const;
702 /** Retrieves the buffer's sample configuration. */
703 ChannelConfig getChannelConfig() const;
705 /** Retrieves the buffer's sample type. */
706 SampleType getSampleType() const;
709 * Retrieves the storage size used by the buffer, in bytes. The buffer must
710 * be fully loaded before this method is called.
712 ALuint getSize() const;
715 * Sets the buffer's loop points, used for looping sources. If the current
716 * context does not support the AL_SOFT_loop_points extension, start and
717 * end must be 0 and getLength() respectively. Otherwise, start must be
718 * less than end, and end must be less than or equal to getLength().
720 * The buffer must not be in use when this method is called, and the buffer
721 * must be fully loaded.
723 * \param start The starting point, in sample frames (inclusive).
724 * \param end The ending point, in sample frames (exclusive).
726 void setLoopPoints(ALuint start, ALuint end);
729 * Retrieves the current loop points as a [start,end) pair. The buffer must
730 * be fully loaded before this method is called.
732 std::pair<ALuint,ALuint> getLoopPoints() const;
735 * Retrieves the Source objects currently playing the buffer. Stopping the
736 * returned sources will allow the buffer to be removed from the context.
738 Vector<Source> getSources() const;
741 * Queries the buffer's load status. A return of BufferLoadStatus::Pending
742 * indicates the buffer is not finished loading and can't be used with a
743 * call to Source::play. Buffers created with Context::getBuffer will
744 * always return BufferLoadStatus::Ready.
746 BufferLoadStatus getLoadStatus();
748 /** Retrieves the name the buffer was created with. */
749 const String &getName() const;
751 /** Queries if the buffer is in use and can't be removed. */
752 bool isInUse() const;
756 enum class Spatialize {
757 Off = AL_FALSE,
758 On = AL_TRUE,
759 Auto = 0x0002 /* AL_AUTO_SOFT */
762 class ALSource;
763 class ALURE_API Source {
764 friend class ALContext;
765 friend class ALSource;
766 friend class ALSourceGroup;
768 MAKE_PIMPL(Source, ALSource)
770 public:
772 * Plays the source using buffer. The same buffer may be played from
773 * multiple sources simultaneously.
775 void play(Buffer buffer);
777 * Plays the source by streaming audio from decoder. This will use
778 * queuesize buffers, each with updatelen sample frames. The given decoder
779 * must *NOT* have its read or seek methods called from elsewhere while in
780 * use.
782 void play(SharedPtr<Decoder> decoder, ALuint updatelen, ALuint queuesize);
784 * Stops playback, releasing the buffer or decoder reference.
786 void stop();
788 /** Pauses the source if it is playing. */
789 void pause();
791 /** Resumes the source if it is paused. */
792 void resume();
794 /** Specifies if the source is currently playing. */
795 bool isPlaying() const;
797 /** Specifies if the source is currently paused. */
798 bool isPaused() const;
801 * Specifies the source's playback priority. Lowest priority sources will
802 * be evicted first when higher priority sources are played.
804 void setPriority(ALuint priority);
805 /** Retrieves the source's priority. */
806 ALuint getPriority() const;
809 * Sets the source's offset, in sample frames. If the source is playing or
810 * paused, it will go to that offset immediately, otherwise the source will
811 * start at the specified offset the next time it's played.
813 void setOffset(uint64_t offset);
815 * Retrieves the source offset in sample frames. For streaming sources,
816 * this will be the offset from the beginning of the stream based on the
817 * decoder's reported position.
819 * \param latency If non-NULL and the device supports it, the source's
820 * latency, in nanoseconds, will be written to that location.
822 uint64_t getOffset(uint64_t *latency=nullptr) const;
825 * Specifies if the source should loop on the Buffer or Decoder object's
826 * loop points.
828 void setLooping(bool looping);
829 bool getLooping() const;
832 * Specifies a linear pitch shift base. A value of 1.0 is the default
833 * normal speed.
835 void setPitch(ALfloat pitch);
836 ALfloat getPitch() const;
839 * Specifies the base linear gain. A value of 1.0 is the default normal
840 * volume.
842 void setGain(ALfloat gain);
843 ALfloat getGain() const;
846 * Specifies the minimum and maximum gain. The source's gain is clamped to
847 * this range after distance attenuation and cone attenuation are applied
848 * to the gain base, although before the filter gain adjustements.
850 void setGainRange(ALfloat mingain, ALfloat maxgain);
851 std::pair<ALfloat,ALfloat> getGainRange() const;
852 ALfloat getMinGain() const { return std::get<0>(getGainRange()); }
853 ALfloat getMaxGain() const { return std::get<1>(getGainRange()); }
856 * Specifies the reference distance and maximum distance the source will
857 * use for the current distance model. For Clamped distance models, the
858 * source's calculated distance is clamped to the specified range before
859 * applying distance-related attenuation.
861 * For all distance models, the reference distance is the distance at which
862 * the source's volume will not have any extra attenuation (an effective
863 * gain multiplier of 1).
865 void setDistanceRange(ALfloat refdist, ALfloat maxdist);
866 std::pair<ALfloat,ALfloat> getDistanceRange() const;
867 ALfloat getReferenceDistance() const { return std::get<0>(getDistanceRange()); }
868 ALfloat getMaxDistance() const { return std::get<1>(getDistanceRange()); }
870 /** Specifies the source's 3D position. */
871 void setPosition(ALfloat x, ALfloat y, ALfloat z);
872 void setPosition(const ALfloat *pos);
873 Vector3 getPosition() const;
876 * Specifies the source's 3D velocity, in units per second. As with OpenAL,
877 * this does not actually alter the source's position, and instead just
878 * alters the pitch as determined by the doppler effect.
880 void setVelocity(ALfloat x, ALfloat y, ALfloat z);
881 void setVelocity(const ALfloat *vel);
882 Vector3 getVelocity() const;
885 * Specifies the source's 3D facing direction. Deprecated in favor of
886 * setOrientation.
888 void setDirection(ALfloat x, ALfloat y, ALfloat z);
889 void setDirection(const ALfloat *dir);
890 Vector3 getDirection() const;
893 * Specifies the source's 3D orientation. Note: unlike the AL_EXT_BFORMAT
894 * extension this property comes from, this also affects the facing
895 * direction, superceding setDirection.
897 void setOrientation(ALfloat x1, ALfloat y1, ALfloat z1, ALfloat x2, ALfloat y2, ALfloat z2);
898 void setOrientation(const ALfloat *at, const ALfloat *up);
899 void setOrientation(const ALfloat *ori);
900 std::pair<Vector3,Vector3> getOrientation() const;
903 * Specifies the source's cone angles, in degrees. The inner angle is the
904 * area within which the listener will hear the source with no extra
905 * attenuation, while the listener being outside of the outer angle will
906 * hear the source attenuated according to the outer cone gains.
908 void setConeAngles(ALfloat inner, ALfloat outer);
909 std::pair<ALfloat,ALfloat> getConeAngles() const;
910 ALfloat getInnerConeAngle() const { return std::get<0>(getConeAngles()); }
911 ALfloat getOuterConeAngle() const { return std::get<1>(getConeAngles()); }
914 * Specifies the linear gain multiplier when the listener is outside of the
915 * source's outer cone area. The specified gain applies to all frequencies,
916 * while gainhf applies extra attenuation to high frequencies.
918 * \param gainhf has no effect without the ALC_EXT_EFX extension.
920 void setOuterConeGains(ALfloat gain, ALfloat gainhf=1.0f);
921 std::pair<ALfloat,ALfloat> getOuterConeGains() const;
922 ALfloat getOuterConeGain() const { return std::get<0>(getOuterConeGains()); }
923 ALfloat getOuterConeGainHF() const { return std::get<1>(getOuterConeGains()); }
926 * Specifies the rolloff factors for the direct and send paths. This is
927 * effectively a distance scaling relative to the reference distance. Note:
928 * the room rolloff factor is 0 by default, disabling distance attenuation
929 * for send paths. This is because the reverb engine will, by default,
930 * apply a more realistic room attenuation based on the reverb decay time
931 * and direct path attenuation.
933 void setRolloffFactors(ALfloat factor, ALfloat roomfactor=0.0f);
934 std::pair<ALfloat,ALfloat> getRolloffFactors() const;
935 ALfloat getRolloffFactor() const { return std::get<0>(getRolloffFactors()); }
936 ALfloat getRoomRolloffFactor() const { return std::get<1>(getRolloffFactors()); }
939 * Specifies the doppler factor for the doppler effect's pitch shift. This
940 * effectively scales the source and listener velocities for the doppler
941 * calculation.
943 void setDopplerFactor(ALfloat factor);
944 ALfloat getDopplerFactor() const;
946 /** Specifies if the source properties are relative to the listener. */
947 void setRelative(bool relative);
948 bool getRelative() const;
951 * Specifies the source's radius. This causes the source to behave as if
952 * every point within the spherical area emits sound.
954 * Has no effect without the AL_EXT_SOURCE_RADIUS extension.
956 void setRadius(ALfloat radius);
957 ALfloat getRadius() const;
960 * Specifies the left and right channel angles, in radians, when playing a
961 * stereo buffer or stream. The angles go counter-clockwise, with 0 being
962 * in front and positive values going left.
964 * Has no effect without the AL_EXT_STEREO_ANGLES extension.
966 void setStereoAngles(ALfloat leftAngle, ALfloat rightAngle);
967 std::pair<ALfloat,ALfloat> getStereoAngles() const;
969 void set3DSpatialize(Spatialize spatialize);
970 Spatialize get3DSpatialize() const;
972 void setResamplerIndex(ALsizei index);
973 ALsizei getResamplerIndex() const;
975 void setAirAbsorptionFactor(ALfloat factor);
976 ALfloat getAirAbsorptionFactor() const;
978 void setGainAuto(bool directhf, bool send, bool sendhf);
979 std::tuple<bool,bool,bool> getGainAuto() const;
980 bool getDirectGainHFAuto() const { return std::get<0>(getGainAuto()); }
981 bool getSendGainAuto() const { return std::get<1>(getGainAuto()); }
982 bool getSendGainHFAuto() const { return std::get<2>(getGainAuto()); }
984 /** Sets the filter properties on the direct path signal. */
985 void setDirectFilter(const FilterParams &filter);
987 * Sets the filter properties on the given send path signal. Any auxiliary
988 * effect slot on the send path remains in place.
990 void setSendFilter(ALuint send, const FilterParams &filter);
992 * Connects the effect slot slot to the given send path. Any filter
993 * properties on the send path remain as they were.
995 void setAuxiliarySend(AuxiliaryEffectSlot slot, ALuint send);
997 * Connects the effect slot slot to the given send path, using the filter
998 * properties.
1000 void setAuxiliarySendFilter(AuxiliaryEffectSlot slot, ALuint send, const FilterParams &filter);
1003 * Updates the source, ensuring that resources are released when playback
1004 * is finished.
1006 void update();
1009 * Releases the source, stopping playback, releasing resources, and
1010 * returning it to the system.
1012 void release();
1016 class ALSourceGroup;
1017 class ALURE_API SourceGroup {
1018 friend class ALContext;
1019 friend class ALSourceGroup;
1021 MAKE_PIMPL(SourceGroup, ALSourceGroup)
1023 public:
1024 /** Retrieves the associated name of the source group. */
1025 const String &getName() const;
1028 * Adds source to the source group. A source may only be part of one group
1029 * at a time, and will automatically be removed from its current group as
1030 * needed.
1032 void addSource(Source source);
1033 /** Removes source from the source group. */
1034 void removeSource(Source source);
1036 /** Adds a list of sources to the group at once. */
1037 void addSources(ArrayView<Source> sources);
1038 /** Removes a list of sources from the source group. */
1039 void removeSources(ArrayView<Source> sources);
1042 * Adds group as a subgroup of the source group. This method will throw an
1043 * exception if group is being added to a group it has as a sub-group (i.e.
1044 * it would create a circular sub-group chain).
1046 void addSubGroup(SourceGroup group);
1047 /** Removes group from the source group. */
1048 void removeSubGroup(SourceGroup group);
1050 /** Returns the list of sources currently in the group. */
1051 Vector<Source> getSources() const;
1053 /** Returns the list of subgroups currently in the group. */
1054 Vector<SourceGroup> getSubGroups() const;
1056 /** Sets the source group gain, which accumulates with its sources. */
1057 void setGain(ALfloat gain);
1058 /** Gets the source group gain. */
1059 ALfloat getGain() const;
1061 /** Sets the source group pitch, which accumulates with its sources. */
1062 void setPitch(ALfloat pitch);
1063 /** Gets the source group pitch. */
1064 ALfloat getPitch() const;
1067 * Pauses all currently-playing sources that are under this group,
1068 * including sub-groups.
1070 void pauseAll() const;
1072 * Resumes all paused sources that are under this group, including
1073 * sub-groups.
1075 void resumeAll() const;
1077 /** Stops all sources that are under this group, including sub-groups. */
1078 void stopAll() const;
1081 * Releases the source group, removing all sources from it before being
1082 * freed.
1084 void release();
1088 struct SourceSend {
1089 Source mSource;
1090 ALuint mSend;
1093 class ALAuxiliaryEffectSlot;
1094 class ALURE_API AuxiliaryEffectSlot {
1095 friend class ALContext;
1096 friend class ALSource;
1098 MAKE_PIMPL(AuxiliaryEffectSlot, ALAuxiliaryEffectSlot)
1100 public:
1101 void setGain(ALfloat gain);
1103 * If set to true, the reverb effect will automatically apply adjustments
1104 * to the source's send slot based on the effect properties.
1106 * Has no effect when using non-reverb effects. Default is true.
1108 void setSendAuto(bool sendauto);
1111 * Updates the effect slot with a new effect. The given effect object may
1112 * be altered or destroyed without affecting the effect slot.
1114 void applyEffect(Effect effect);
1117 * Releases the effect slot, returning it to the system. It must not be in
1118 * use by a source.
1120 void release();
1123 * Retrieves each Source object and its pairing send this effect slot is
1124 * set on. Setting a different (or null) effect slot on each source's given
1125 * send will allow the effect slot to be released.
1127 Vector<SourceSend> getSourceSends() const;
1129 /** Determines if the effect slot is in use by a source. */
1130 bool isInUse() const;
1134 class ALEffect;
1135 class ALURE_API Effect {
1136 friend class ALContext;
1137 friend class ALAuxiliaryEffectSlot;
1139 MAKE_PIMPL(Effect, ALEffect)
1141 public:
1143 * Updates the effect with the specified reverb properties. If the
1144 * EAXReverb effect is not supported, it will automatically attempt to
1145 * downgrade to the Standard Reverb effect.
1147 void setReverbProperties(const EFXEAXREVERBPROPERTIES &props);
1149 void destroy();
1154 * Audio decoder interface. Applications may derive from this, implementing the
1155 * necessary methods, and use it in places the API wants a Decoder object.
1157 class ALURE_API Decoder {
1158 public:
1159 virtual ~Decoder() { }
1161 /** Retrieves the sample frequency, in hz, of the audio being decoded. */
1162 virtual ALuint getFrequency() const = 0;
1163 /** Retrieves the channel configuration of the audio being decoded. */
1164 virtual ChannelConfig getChannelConfig() const = 0;
1165 /** Retrieves the sample type of the audio being decoded. */
1166 virtual SampleType getSampleType() const = 0;
1169 * Retrieves the total length of the audio, in sample frames. If unknown,
1170 * returns 0. Note that if the returned length is 0, the decoder may not be
1171 * used to load a Buffer.
1173 virtual uint64_t getLength() const = 0;
1175 * Retrieves the current sample frame position (i.e. the number of sample
1176 * frames from the beginning).
1178 virtual uint64_t getPosition() const = 0;
1180 * Seek to pos, specified in sample frames. Returns true if the seek was
1181 * successful.
1183 virtual bool seek(uint64_t pos) = 0;
1186 * Retrieves the loop points, in sample frames, as a [start,end) pair. If
1187 * start >= end, use all available data.
1189 virtual std::pair<uint64_t,uint64_t> getLoopPoints() const = 0;
1192 * Decodes count sample frames, writing them to ptr, and returns the number
1193 * of sample frames written. Returning less than the requested count
1194 * indicates the end of the audio.
1196 virtual ALuint read(ALvoid *ptr, ALuint count) = 0;
1200 * Audio decoder factory interface. Applications may derive from this,
1201 * implementing the necessary methods, and use it in places the API wants a
1202 * DecoderFactory object.
1204 class ALURE_API DecoderFactory {
1205 public:
1206 virtual ~DecoderFactory() { }
1209 * Creates and returns a Decoder instance for the given resource file. If
1210 * the decoder needs to retain the file handle for reading as-needed, it
1211 * should move the UniquePtr to internal storage.
1213 * \return nullptr if a decoder can't be created from the file.
1215 virtual SharedPtr<Decoder> createDecoder(UniquePtr<std::istream> &file) = 0;
1219 * Registers a decoder factory for decoding audio. Registered factories are
1220 * used in lexicographical order, e.g. if Factory1 is registered with name1 and
1221 * Factory2 is registered with name2, Factory1 will be used before Factory2 if
1222 * name1 < name2. Internal decoder factories are always used after registered
1223 * ones.
1225 * Alure retains a reference to the DecoderFactory instance and will release it
1226 * (potentially destroying the object) when the library unloads.
1228 * \param name A unique name identifying this decoder factory.
1229 * \param factory A DecoderFactory instance used to create Decoder instances.
1231 ALURE_API void RegisterDecoder(const String &name, UniquePtr<DecoderFactory> factory);
1234 * Unregisters a decoder factory by name. Alure returns the instance back to
1235 * the application.
1237 * \param name The unique name identifying a previously-registered decoder
1238 * factory.
1240 * \return The unregistered decoder factory instance, or 0 (nullptr) if a
1241 * decoder factory with the given name doesn't exist.
1243 ALURE_API UniquePtr<DecoderFactory> UnregisterDecoder(const String &name);
1247 * A file I/O factory interface. Applications may derive from this and set an
1248 * instance to be used by the audio decoders. By default, the library uses
1249 * standard I/O.
1251 class ALURE_API FileIOFactory {
1252 public:
1254 * Sets the factory instance to be used by the audio decoders. If a
1255 * previous factory was set, it's returned to the application. Passing in a
1256 * NULL factory reverts to the default.
1258 static UniquePtr<FileIOFactory> set(UniquePtr<FileIOFactory> factory);
1261 * Gets the current FileIOFactory instance being used by the audio
1262 * decoders.
1264 static FileIOFactory &get();
1266 virtual ~FileIOFactory() { }
1268 /** Opens a read-only binary file for the given name. */
1269 virtual UniquePtr<std::istream> openFile(const String &name) = 0;
1274 * A message handler interface. Applications may derive from this and set an
1275 * instance on a context to receive messages. The base methods are no-ops, so
1276 * derived classes only need to implement methods for relevant messages.
1278 * It's recommended that applications mark their handler methods using the
1279 * override keyword, to ensure they're properly overriding the base methods in
1280 * case they change.
1282 class ALURE_API MessageHandler {
1283 public:
1284 virtual ~MessageHandler();
1287 * Called when the given device has been disconnected and is no longer
1288 * usable for output. As per the ALC_EXT_disconnect specification,
1289 * disconnected devices remain valid, however all playing sources are
1290 * automatically stopped, any sources that are attempted to play will
1291 * immediately stop, and new contexts may not be created on the device.
1293 * Note that connection status is checked during Context::update calls, so
1294 * that method must be called regularly to be notified when a device is
1295 * disconnected. This method may not be called if the device lacks support
1296 * for the ALC_EXT_disconnect extension.
1298 * WARNING: Do not attempt to clean up resources within this callback
1299 * method, as Alure is in the middle of doing updates. Instead, flag the
1300 * device as having been lost and do cleanup later.
1302 virtual void deviceDisconnected(Device device);
1305 * Called when the given source reaches the end of the buffer or stream.
1307 * Sources that stopped automatically will be detected upon a call to
1308 * Context::update or Source::update.
1310 virtual void sourceStopped(Source source);
1313 * Called when the given source was forced to stop. This can be because
1314 * either there were no more system sources and a higher-priority source
1315 * needs to play, or it's part of a SourceGroup (or sub-group thereof) that
1316 * had its SourceGroup::stopAll method called.
1318 virtual void sourceForceStopped(Source source);
1321 * Called when a new buffer is about to be created and loaded. May be
1322 * called asynchronously for buffers being loaded asynchronously.
1324 * \param name The resource name, as passed to Context::getBuffer.
1325 * \param channels Channel configuration of the given audio data.
1326 * \param type Sample type of the given audio data.
1327 * \param samplerate Sample rate of the given audio data.
1328 * \param data The audio data that is about to be fed to the OpenAL buffer.
1330 virtual void bufferLoading(const String &name, ChannelConfig channels, SampleType type, ALuint samplerate, const Vector<ALbyte> &data);
1333 * Called when a resource isn't found, allowing the app to substitute in a
1334 * different resource. For buffers created with Context::getBuffer or
1335 * Context::getBufferAsync, the original name will still be used for the
1336 * cache map so the app doesn't have to keep track of substituted resource
1337 * names.
1339 * This will be called again if the new name isn't found.
1341 * \param name The resource name that was not found.
1342 * \return The replacement resource name to use instead. Returning an empty
1343 * string means to stop trying.
1345 virtual String resourceNotFound(const String &name);
1348 } // namespace alure
1350 #endif /* AL_ALURE2_H */