Add comparison operators for pImpl objects
[alure.git] / include / AL / alure2.h
blobd489d151341cd82747e2d1d060b2f4eab3d8e15f
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;
107 * An attribute pair, for passing attributes to Device::createContext and
108 * Device::reset.
110 using AttributePair = std::pair<ALCint,ALCint>;
111 static_assert(sizeof(AttributePair) == sizeof(ALCint[2]), "Bad AttributePair size");
114 struct FilterParams {
115 ALfloat mGain;
116 ALfloat mGainHF; // For low-pass and band-pass filters
117 ALfloat mGainLF; // For high-pass and band-pass filters
121 class ALURE_API Vector3 {
122 std::array<ALfloat,3> mValue;
124 public:
125 constexpr Vector3() noexcept
126 : mValue{{0.0f, 0.0f, 0.0f}}
128 constexpr Vector3(const Vector3 &rhs) noexcept
129 : mValue{{rhs.mValue[0], rhs.mValue[1], rhs.mValue[2]}}
131 constexpr Vector3(ALfloat val) noexcept
132 : mValue{{val, val, val}}
134 constexpr Vector3(ALfloat x, ALfloat y, ALfloat z) noexcept
135 : mValue{{x, y, z}}
137 Vector3(const ALfloat *vec) noexcept
138 : mValue{{vec[0], vec[1], vec[2]}}
141 const ALfloat *getPtr() const noexcept
142 { return mValue.data(); }
144 ALfloat& operator[](size_t i) noexcept
145 { return mValue[i]; }
146 constexpr const ALfloat& operator[](size_t i) const noexcept
147 { return mValue[i]; }
149 #define ALURE_DECL_OP(op) \
150 constexpr Vector3 operator op(const Vector3 &rhs) const noexcept \
152 return Vector3(mValue[0] op rhs.mValue[0], \
153 mValue[1] op rhs.mValue[1], \
154 mValue[2] op rhs.mValue[2]); \
156 ALURE_DECL_OP(+)
157 ALURE_DECL_OP(-)
158 ALURE_DECL_OP(*)
159 ALURE_DECL_OP(/)
160 #undef ALURE_DECL_OP
161 #define ALURE_DECL_OP(op) \
162 Vector3& operator op(const Vector3 &rhs) noexcept \
164 mValue[0] op rhs.mValue[0]; \
165 mValue[1] op rhs.mValue[1]; \
166 mValue[2] op rhs.mValue[2]; \
167 return *this; \
169 ALURE_DECL_OP(+=)
170 ALURE_DECL_OP(-=)
171 ALURE_DECL_OP(*=)
172 ALURE_DECL_OP(/=)
174 #undef ALURE_DECL_OP
175 #define ALURE_DECL_OP(op) \
176 constexpr Vector3 operator op(ALfloat scale) const noexcept \
178 return Vector3(mValue[0] op scale, \
179 mValue[1] op scale, \
180 mValue[2] op scale); \
182 ALURE_DECL_OP(*)
183 ALURE_DECL_OP(/)
184 #undef ALURE_DECL_OP
185 #define ALURE_DECL_OP(op) \
186 Vector3& operator op(ALfloat scale) noexcept \
188 mValue[0] op scale; \
189 mValue[1] op scale; \
190 mValue[2] op scale; \
191 return *this; \
193 ALURE_DECL_OP(*=)
194 ALURE_DECL_OP(/=)
195 #undef ALURE_DECL_OP
197 constexpr ALfloat getLengthSquared() const noexcept
198 { return mValue[0]*mValue[0] + mValue[1]*mValue[1] + mValue[2]*mValue[2]; }
199 ALfloat getLength() const noexcept
200 { return std::sqrt(getLengthSquared()); }
202 constexpr ALfloat getDistanceSquared(const Vector3 &pos) const noexcept
203 { return (pos - *this).getLengthSquared(); }
204 ALfloat getDistance(const Vector3 &pos) const noexcept
205 { return (pos - *this).getLength(); }
207 static_assert(sizeof(Vector3) == sizeof(ALfloat[3]), "Bad Vector3 size");
210 enum class SampleType {
211 UInt8,
212 Int16,
213 Float32,
214 Mulaw
216 ALURE_API const char *GetSampleTypeName(SampleType type);
218 enum class ChannelConfig {
219 /** 1-channel mono sound. */
220 Mono,
221 /** 2-channel stereo sound. */
222 Stereo,
223 /** 2-channel rear sound (back-left and back-right). */
224 Rear,
225 /** 4-channel surround sound. */
226 Quad,
227 /** 5.1 surround sound. */
228 X51,
229 /** 6.1 surround sound. */
230 X61,
231 /** 7.1 surround sound. */
232 X71,
233 /** 3-channel B-Format, using FuMa channel ordering and scaling. */
234 BFormat2D,
235 /** 4-channel B-Format, using FuMa channel ordering and scaling. */
236 BFormat3D
238 ALURE_API const char *GetChannelConfigName(ChannelConfig cfg);
240 ALURE_API ALuint FramesToBytes(ALuint frames, ChannelConfig chans, SampleType type);
241 ALURE_API ALuint BytesToFrames(ALuint bytes, ChannelConfig chans, SampleType type);
245 * Creates a version number value using the specified major and minor values.
247 constexpr inline ALCuint MakeVersion(ALCushort major, ALCushort minor)
248 { return (major<<16) | minor; }
251 * Retrieves the major version of a version number value created by
252 * MakeVersion.
254 constexpr inline ALCuint MajorVersion(ALCuint version)
255 { return version>>16; }
257 * Retrieves the minor version of a version number value created by
258 * MakeVersion.
260 constexpr inline ALCuint MinorVersion(ALCuint version)
261 { return version&0xffff; }
264 enum class DeviceEnumeration {
265 Basic = ALC_DEVICE_SPECIFIER,
266 Complete = ALC_ALL_DEVICES_SPECIFIER,
267 Capture = ALC_CAPTURE_DEVICE_SPECIFIER
270 enum class DefaultDeviceType {
271 Basic = ALC_DEFAULT_DEVICE_SPECIFIER,
272 Complete = ALC_DEFAULT_ALL_DEVICES_SPECIFIER,
273 Capture = ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
277 * A class managing Device objects and other related functionality. This class
278 * is a singleton, only one instance will exist in a process.
280 class ALURE_API DeviceManager {
281 public:
282 /** Retrieves the DeviceManager instance. */
283 static DeviceManager &get();
285 /** Queries the existence of a non-device-specific ALC extension. */
286 virtual bool queryExtension(const String &name) const = 0;
288 /** Enumerates available device names of the given type. */
289 virtual Vector<String> enumerate(DeviceEnumeration type) const = 0;
290 /** Retrieves the default device of the given type. */
291 virtual String defaultDeviceName(DefaultDeviceType type) const = 0;
293 /** Opens the playback device given by name, or the default if empty. */
294 virtual Device openPlayback(const String &name=String()) = 0;
298 enum class PlaybackDeviceName {
299 Basic = ALC_DEVICE_SPECIFIER,
300 Complete = ALC_ALL_DEVICES_SPECIFIER
303 #define MAKE_PIMPL(BaseT, ImplT) \
304 private: \
305 ImplT *pImpl; \
307 BaseT(ImplT *impl) : pImpl(impl) { } \
309 public: \
310 BaseT() : pImpl(nullptr) { } \
311 BaseT(const BaseT&) = default; \
312 BaseT(BaseT&&) = default; \
314 BaseT& operator=(std::nullptr_t) { pImpl = nullptr; return *this; } \
315 BaseT& operator=(const BaseT&) = default; \
316 BaseT& operator=(BaseT&&) = default; \
318 bool operator==(const BaseT &rhs) const { return pImpl == rhs.pImpl; } \
319 bool operator==(BaseT&& rhs) const { return pImpl == rhs.pImpl; }
321 class ALDevice;
322 class ALURE_API Device {
323 friend class ALDeviceManager;
324 friend class ALContext;
326 MAKE_PIMPL(Device, ALDevice)
328 public:
329 /** Retrieves the device name as given by type. */
330 String getName(PlaybackDeviceName type=PlaybackDeviceName::Basic) const;
331 /** Queries the existence of an ALC extension on this device. */
332 bool queryExtension(const String &name) const;
335 * Retrieves the ALC version supported by this device, as constructed by
336 * MakeVersion.
338 ALCuint getALCVersion() const;
341 * Retrieves the EFX version supported by this device, as constructed by
342 * MakeVersion. If the ALC_EXT_EFX extension is unsupported, this will be
343 * 0.
345 ALCuint getEFXVersion() const;
347 /** Retrieves the device's playback frequency, in hz. */
348 ALCuint getFrequency() const;
351 * Retrieves the maximum number of auxiliary source sends. If ALC_EXT_EFX
352 * is unsupported, this will be 0.
354 ALCuint getMaxAuxiliarySends() const;
357 * Enumerates available HRTF names. The names are sorted as OpenAL gives
358 * them, such that the index of a given name is the ID to use with
359 * ALC_HRTF_ID_SOFT.
361 * Requires the ALC_SOFT_HRTF extension.
363 Vector<String> enumerateHRTFNames() const;
366 * Retrieves whether HRTF is enabled on the device or not.
368 * Requires the ALC_SOFT_HRTF extension.
370 bool isHRTFEnabled() const;
373 * Retrieves the name of the HRTF currently being used by this device.
375 * Requires the ALC_SOFT_HRTF extension.
377 String getCurrentHRTF() const;
380 * Resets the device, using the specified attributes.
382 * Requires the ALC_SOFT_HRTF extension.
384 void reset(const Vector<AttributePair> &attributes);
387 * Creates a new Context on this device, using the specified attributes.
389 Context createContext(const Vector<AttributePair> &attributes=Vector<AttributePair>{});
392 * Pauses device processing, stopping updates for its contexts. Multiple
393 * calls are allowed but it is not reference counted, so the device will
394 * resume after one resumeDSP call.
396 * Requires the ALC_SOFT_pause_device extension.
398 void pauseDSP();
401 * Resumes device processing, restarting updates for its contexts. Multiple
402 * calls are allowed and will no-op.
404 void resumeDSP();
407 * Closes and frees the device. All previously-created contexts must first
408 * be destroyed.
410 void close();
414 enum class DistanceModel {
415 InverseClamped = AL_INVERSE_DISTANCE_CLAMPED,
416 LinearClamped = AL_LINEAR_DISTANCE_CLAMPED,
417 ExponentClamped = AL_EXPONENT_DISTANCE_CLAMPED,
418 Inverse = AL_INVERSE_DISTANCE,
419 Linear = AL_LINEAR_DISTANCE,
420 Exponent = AL_EXPONENT_DISTANCE,
421 None = AL_NONE,
424 class ALContext;
425 class ALURE_API Context {
426 friend class ALDevice;
428 MAKE_PIMPL(Context, ALContext)
430 public:
431 /** Makes the specified context current for OpenAL operations. */
432 static void MakeCurrent(Context context);
433 /** Removes the current context for OpenAL operations. */
434 static void MakeCurrent(std::nullptr_t);
435 /** Retrieves the current context used for OpenAL operations. */
436 static Context GetCurrent();
439 * Makes the specified context current for OpenAL operations on the calling
440 * thread only. Requires the ALC_EXT_thread_local_context extension on both
441 * the context's device and the DeviceManager.
443 static void MakeThreadCurrent(Context context);
445 * Removes the current context for OpenAL operations on the calling thread
446 * only.
448 static void MakeThreadCurrent(std::nullptr_t);
449 /** Retrieves the thread-specific context used for OpenAL operations. */
450 static Context GetThreadCurrent();
453 * Destroys the context. The context must not be current when this is
454 * called.
456 void destroy();
458 /** Retrieves the Device this context was created from. */
459 Device getDevice();
461 void startBatch();
462 void endBatch();
465 * Retrieves a Listener instance for this context. Each context will only
466 * have one listener.
468 Listener *getListener();
471 * Sets a MessageHandler instance which will be used to provide certain
472 * messages back to the application. Only one handler may be set for a
473 * context at a time. The previously set handler will be returned.
475 SharedPtr<MessageHandler> setMessageHandler(SharedPtr<MessageHandler> handler);
477 /** Gets the currently-set message handler. */
478 SharedPtr<MessageHandler> getMessageHandler() const;
481 * Specifies the desired interval (in milliseconds) that the background
482 * thread will be woken up to process tasks, e.g. keeping streaming sources
483 * filled. An interval of 0 means the background thread will only be woken
484 * up manually with calls to update. The default is 0.
486 void setAsyncWakeInterval(ALuint msec);
489 * Retrieves the current interval used for waking up the background thread.
491 ALuint getAsyncWakeInterval() const;
494 * Creates a Decoder instance for the given audio file or resource name.
496 SharedPtr<Decoder> createDecoder(const String &name);
498 // Functions below require the context to be current
501 * Queries if the channel configuration and sample type are supported by
502 * the context.
504 bool isSupported(ChannelConfig channels, SampleType type) const;
507 * Creates and caches a Buffer for the given audio file or resource name.
508 * Multiple calls with the same name will return the same Buffer object.
510 Buffer getBuffer(const String &name);
513 * Creates and caches a Buffer for the given audio file or resource name.
514 * Multiple calls with the same name will return the same Buffer object.
516 * The returned Buffer object will be scheduled for loading asynchronously,
517 * and must be checked with a call to Buffer::getLoadStatus prior to being
518 * played.
520 Buffer getBufferAsync(const String &name);
523 * Deletes the cached Buffer object for the given audio file or
524 * resource name. The buffer must not be in use by a Source.
526 void removeBuffer(const String &name);
528 * Deletes the given cached buffer instance. The buffer must not be in use
529 * by a Source.
531 void removeBuffer(Buffer buffer);
534 * Creates a new Source. There is no practical limit to the number of
535 * sources you may create.
537 Source *createSource();
539 AuxiliaryEffectSlot createAuxiliaryEffectSlot();
541 Effect createEffect();
543 SourceGroup createSourceGroup(String name);
544 SourceGroup getSourceGroup(const String &name);
546 void setDopplerFactor(ALfloat factor);
548 void setSpeedOfSound(ALfloat speed);
550 void setDistanceModel(DistanceModel model);
553 * Updates the context and all sources belonging to this context (you do
554 * not need to call the individual sources' update method if you call this
555 * function).
557 void update();
560 class ALURE_API Listener {
561 public:
562 virtual void setGain(ALfloat gain) = 0;
564 virtual void setPosition(ALfloat x, ALfloat y, ALfloat z) = 0;
565 virtual void setPosition(const ALfloat *pos) = 0;
567 virtual void setVelocity(ALfloat x, ALfloat y, ALfloat z) = 0;
568 virtual void setVelocity(const ALfloat *vel) = 0;
570 virtual void setOrientation(ALfloat x1, ALfloat y1, ALfloat z1, ALfloat x2, ALfloat y2, ALfloat z2) = 0;
571 virtual void setOrientation(const ALfloat *at, const ALfloat *up) = 0;
572 virtual void setOrientation(const ALfloat *ori) = 0;
574 virtual void setMetersPerUnit(ALfloat m_u) = 0;
578 enum class BufferLoadStatus {
579 Pending,
580 Ready
583 class ALBuffer;
584 class ALURE_API Buffer {
585 friend class ALContext;
586 friend class ALSource;
588 MAKE_PIMPL(Buffer, ALBuffer)
590 public:
592 * Retrieves the length of the buffer in sample frames. The buffer must be
593 * fully loaded before this method is called.
595 ALuint getLength() const;
597 /** Retrieves the buffer's frequency in hz. */
598 ALuint getFrequency() const;
600 /** Retrieves the buffer's sample configuration. */
601 ChannelConfig getChannelConfig() const;
603 /** Retrieves the buffer's sample type. */
604 SampleType getSampleType() const;
607 * Retrieves the storage size used by the buffer, in bytes. The buffer must
608 * be fully loaded before this method is called.
610 ALuint getSize() const;
613 * Sets the buffer's loop points, used for looping sources. If the current
614 * context does not support the AL_SOFT_loop_points extension, start and
615 * end must be 0 and getLength() respectively. Otherwise, start must be
616 * less than end, and end must be less than or equal to getLength().
618 * The buffer must not be in use when this method is called, and the buffer
619 * must be fully loaded.
621 * \param start The starting point, in sample frames (inclusive).
622 * \param end The ending point, in sample frames (exclusive).
624 void setLoopPoints(ALuint start, ALuint end);
627 * Retrieves the current loop points as a [start,end) pair. The buffer must
628 * be fully loaded before this method is called.
630 std::pair<ALuint,ALuint> getLoopPoints() const;
633 * Retrieves the Source objects currently playing the buffer. Stopping the
634 * returned sources will allow the buffer to be removed from the context.
636 Vector<Source*> getSources() const;
639 * Queries the buffer's load status. A return of BufferLoadStatus::Pending
640 * indicates the buffer is not finished loading and can't be used with a
641 * call to Source::play. Buffers created with Context::getBuffer will
642 * always return BufferLoadStatus::Ready.
644 BufferLoadStatus getLoadStatus();
646 /** Retrieves the name the buffer was created with. */
647 const String &getName() const;
649 /** Queries if the buffer is in use and can't be removed. */
650 bool isInUse() const;
654 class ALURE_API Source {
655 public:
657 * Plays the source using buffer. The same buffer may be played from
658 * multiple sources simultaneously.
660 virtual void play(Buffer buffer) = 0;
662 * Plays the source by streaming audio from decoder. This will use
663 * queuesize buffers, each with updatelen sample frames. The given decoder
664 * must *NOT* have its read or seek methods called from elsewhere while in
665 * use.
667 virtual void play(SharedPtr<Decoder> decoder, ALuint updatelen, ALuint queuesize) = 0;
669 * Stops playback, releasing the buffer or decoder reference.
671 virtual void stop() = 0;
673 /** Pauses the source if it is playing. */
674 virtual void pause() = 0;
676 /** Resumes the source if it is paused. */
677 virtual void resume() = 0;
679 /** Specifies if the source is currently playing. */
680 virtual bool isPlaying() const = 0;
682 /** Specifies if the source is currently paused. */
683 virtual bool isPaused() const = 0;
686 * Specifies the source's playback priority. Lowest priority sources will
687 * be evicted first when higher priority sources are played.
689 virtual void setPriority(ALuint priority) = 0;
690 /** Retrieves the source's priority. */
691 virtual ALuint getPriority() const = 0;
694 * Sets the source's offset, in sample frames. If the source is playing or
695 * paused, it will go to that offset immediately, otherwise the source will
696 * start at the specified offset the next time it's played.
698 virtual void setOffset(uint64_t offset) = 0;
700 * Retrieves the source offset in sample frames. For streaming sources,
701 * this will be the offset from the beginning of the stream based on the
702 * decoder's reported position.
704 * \param latency If non-NULL and the device supports it, the source's
705 * latency, in nanoseconds, will be written to that location.
707 virtual uint64_t getOffset(uint64_t *latency=nullptr) const = 0;
710 * Specifies if the source should loop on the Buffer or Decoder object's
711 * loop points.
713 virtual void setLooping(bool looping) = 0;
714 virtual bool getLooping() const = 0;
717 * Specifies a linear pitch shift base. A value of 1.0 is the default
718 * normal speed.
720 virtual void setPitch(ALfloat pitch) = 0;
721 virtual ALfloat getPitch() const = 0;
724 * Specifies the base linear gain. A value of 1.0 is the default normal
725 * volume.
727 virtual void setGain(ALfloat gain) = 0;
728 virtual ALfloat getGain() const = 0;
731 * Specifies the minimum and maximum gain. The source's gain is clamped to
732 * this range after distance attenuation and cone attenuation are applied
733 * to the gain base, although before the filter gain adjustements.
735 virtual void setGainRange(ALfloat mingain, ALfloat maxgain) = 0;
736 virtual std::pair<ALfloat,ALfloat> getGainRange() const = 0;
737 ALfloat getMinGain() const { return std::get<0>(getGainRange()); }
738 ALfloat getMaxGain() const { return std::get<1>(getGainRange()); }
741 * Specifies the reference distance and maximum distance the source will
742 * use for the current distance model. For Clamped distance models, the
743 * source's calculated distance is clamped to the specified range before
744 * applying distance-related attenuation.
746 * For all distance models, the reference distance is the distance at which
747 * the source's volume will not have any extra attenuation (an effective
748 * gain multiplier of 1).
750 virtual void setDistanceRange(ALfloat refdist, ALfloat maxdist) = 0;
751 virtual std::pair<ALfloat,ALfloat> getDistanceRange() const = 0;
752 ALfloat getReferenceDistance() const { return std::get<0>(getDistanceRange()); }
753 ALfloat getMaxDistance() const { return std::get<1>(getDistanceRange()); }
755 /** Specifies the source's 3D position. */
756 virtual void setPosition(ALfloat x, ALfloat y, ALfloat z) = 0;
757 virtual void setPosition(const ALfloat *pos) = 0;
758 virtual Vector3 getPosition() const = 0;
761 * Specifies the source's 3D velocity, in units per second. As with OpenAL,
762 * this does not actually alter the source's position, and instead just
763 * alters the pitch as determined by the doppler effect.
765 virtual void setVelocity(ALfloat x, ALfloat y, ALfloat z) = 0;
766 virtual void setVelocity(const ALfloat *vel) = 0;
767 virtual Vector3 getVelocity() const = 0;
770 * Specifies the source's 3D facing direction. Deprecated in favor of
771 * setOrientation.
773 virtual void setDirection(ALfloat x, ALfloat y, ALfloat z) = 0;
774 virtual void setDirection(const ALfloat *dir) = 0;
775 virtual Vector3 getDirection() const = 0;
778 * Specifies the source's 3D orientation. Note: unlike the AL_EXT_BFORMAT
779 * extension this property comes from, this also affects the facing
780 * direction, superceding setDirection.
782 virtual void setOrientation(ALfloat x1, ALfloat y1, ALfloat z1, ALfloat x2, ALfloat y2, ALfloat z2) = 0;
783 virtual void setOrientation(const ALfloat *at, const ALfloat *up) = 0;
784 virtual void setOrientation(const ALfloat *ori) = 0;
785 virtual std::pair<Vector3,Vector3> getOrientation() const = 0;
788 * Specifies the source's cone angles, in degrees. The inner angle is the
789 * area within which the listener will hear the source with no extra
790 * attenuation, while the listener being outside of the outer angle will
791 * hear the source attenuated according to the outer cone gains.
793 virtual void setConeAngles(ALfloat inner, ALfloat outer) = 0;
794 virtual std::pair<ALfloat,ALfloat> getConeAngles() const = 0;
795 ALfloat getInnerConeAngle() const { return std::get<0>(getConeAngles()); }
796 ALfloat getOuterConeAngle() const { return std::get<1>(getConeAngles()); }
799 * Specifies the linear gain multiplier when the listener is outside of the
800 * source's outer cone area. The specified gain applies to all frequencies,
801 * while gainhf applies extra attenuation to high frequencies.
803 * \param gainhf has no effect without the ALC_EXT_EFX extension.
805 virtual void setOuterConeGains(ALfloat gain, ALfloat gainhf=1.0f) = 0;
806 virtual std::pair<ALfloat,ALfloat> getOuterConeGains() const = 0;
807 ALfloat getOuterConeGain() const { return std::get<0>(getOuterConeGains()); }
808 ALfloat getOuterConeGainHF() const { return std::get<1>(getOuterConeGains()); }
811 * Specifies the rolloff factors for the direct and send paths. This is
812 * effectively a distance scaling relative to the reference distance. Note:
813 * the room rolloff factor is 0 by default, disabling distance attenuation
814 * for send paths. This is because the reverb engine will, by default,
815 * apply a more realistic room attenuation based on the reverb decay time
816 * and direct path attenuation.
818 virtual void setRolloffFactors(ALfloat factor, ALfloat roomfactor=0.0f) = 0;
819 virtual std::pair<ALfloat,ALfloat> getRolloffFactors() const = 0;
820 ALfloat getRolloffFactor() const { return std::get<0>(getRolloffFactors()); }
821 ALfloat getRoomRolloffFactor() const { return std::get<1>(getRolloffFactors()); }
824 * Specifies the doppler factor for the doppler effect's pitch shift. This
825 * effectively scales the source and listener velocities for the doppler
826 * calculation.
828 virtual void setDopplerFactor(ALfloat factor) = 0;
829 virtual ALfloat getDopplerFactor() const = 0;
831 /** Specifies if the source properties are relative to the listener. */
832 virtual void setRelative(bool relative) = 0;
833 virtual bool getRelative() const = 0;
836 * Specifies the source's radius. This causes the source to behave as if
837 * every point within the spherical area emits sound.
839 * Has no effect without the AL_EXT_SOURCE_RADIUS extension.
841 virtual void setRadius(ALfloat radius) = 0;
842 virtual ALfloat getRadius() const = 0;
845 * Specifies the left and right channel angles, in radians, when playing a
846 * stereo buffer or stream. The angles go counter-clockwise, with 0 being
847 * in front and positive values going left.
849 * Has no effect without the AL_EXT_STEREO_ANGLES extension.
851 virtual void setStereoAngles(ALfloat leftAngle, ALfloat rightAngle) = 0;
852 virtual std::pair<ALfloat,ALfloat> getStereoAngles() const = 0;
854 virtual void setAirAbsorptionFactor(ALfloat factor) = 0;
855 virtual ALfloat getAirAbsorptionFactor() const = 0;
857 virtual void setGainAuto(bool directhf, bool send, bool sendhf) = 0;
858 virtual std::tuple<bool,bool,bool> getGainAuto() const = 0;
859 bool getDirectGainHFAuto() const { return std::get<0>(getGainAuto()); }
860 bool getSendGainAuto() const { return std::get<1>(getGainAuto()); }
861 bool getSendGainHFAuto() const { return std::get<2>(getGainAuto()); }
863 /** Sets the filter properties on the direct path signal. */
864 virtual void setDirectFilter(const FilterParams &filter) = 0;
866 * Sets the filter properties on the given send path signal. Any auxiliary
867 * effect slot on the send path remains in place.
869 virtual void setSendFilter(ALuint send, const FilterParams &filter) = 0;
871 * Connects the effect slot slot to the given send path. Any filter
872 * properties on the send path remain as they were.
874 virtual void setAuxiliarySend(AuxiliaryEffectSlot slot, ALuint send) = 0;
876 * Connects the effect slot slot to the given send path, using the filter
877 * properties.
879 virtual void setAuxiliarySendFilter(AuxiliaryEffectSlot slot, ALuint send, const FilterParams &filter) = 0;
882 * Updates the source, ensuring that resources are released when playback
883 * is finished.
885 virtual void update() = 0;
888 * Releases the source, stopping playback, releasing resources, and
889 * returning it to the system.
891 virtual void release() = 0;
895 class ALSourceGroup;
896 class ALURE_API SourceGroup {
897 friend class ALContext;
898 friend class ALSourceGroup;
900 MAKE_PIMPL(SourceGroup, ALSourceGroup)
902 public:
903 /** Retrieves the associated name of the source group. */
904 const String &getName() const;
907 * Adds source to the source group. A source may only be part of one group
908 * at a time, and will automatically be removed from its current group as
909 * needed.
911 void addSource(Source *source);
912 /** Removes source from the source group. */
913 void removeSource(Source *source);
915 /** Adds a list of sources to the group at once. */
916 void addSources(const Vector<Source*> &sources);
917 /** Removes a list of sources from the source group. */
918 void removeSources(const Vector<Source*> &sources);
921 * Adds group as a subgroup of the source group. This method will throw an
922 * exception if group is being added to a group it has as a sub-group (i.e.
923 * it would create a circular sub-group chain).
925 void addSubGroup(SourceGroup group);
926 /** Removes group from the source group. */
927 void removeSubGroup(SourceGroup group);
929 /** Returns the list of sources currently in the group. */
930 Vector<Source*> getSources() const;
932 /** Returns the list of subgroups currently in the group. */
933 Vector<SourceGroup> getSubGroups() const;
935 /** Sets the source group gain, which accumulates with its sources. */
936 void setGain(ALfloat gain);
937 /** Gets the source group gain. */
938 ALfloat getGain() const;
940 /** Sets the source group pitch, which accumulates with its sources. */
941 void setPitch(ALfloat pitch);
942 /** Gets the source group pitch. */
943 ALfloat getPitch() const;
946 * Pauses all currently-playing sources that are under this group,
947 * including sub-groups.
949 void pauseAll() const;
951 * Resumes all paused sources that are under this group, including
952 * sub-groups.
954 void resumeAll() const;
956 /** Stops all sources that are under this group, including sub-groups. */
957 void stopAll() const;
960 * Releases the source group, removing all sources from it before being
961 * freed.
963 void release();
967 struct SourceSend {
968 Source *mSource;
969 ALuint mSend;
972 class ALAuxiliaryEffectSlot;
973 class ALURE_API AuxiliaryEffectSlot {
974 friend class ALContext;
975 friend class ALSource;
977 MAKE_PIMPL(AuxiliaryEffectSlot, ALAuxiliaryEffectSlot)
979 public:
980 void setGain(ALfloat gain);
982 * If set to true, the reverb effect will automatically apply adjustments
983 * to the source's send slot based on the effect properties.
985 * Has no effect when using non-reverb effects. Default is true.
987 void setSendAuto(bool sendauto);
990 * Updates the effect slot with a new effect. The given effect object may
991 * be altered or destroyed without affecting the effect slot.
993 void applyEffect(Effect effect);
996 * Releases the effect slot, returning it to the system. It must not be in
997 * use by a source.
999 void release();
1002 * Retrieves each Source object and its pairing send this effect slot is
1003 * set on. Setting a different (or null) effect slot on each source's given
1004 * send will allow the effect slot to be released.
1006 Vector<SourceSend> getSourceSends() const;
1008 /** Determines if the effect slot is in use by a source. */
1009 bool isInUse() const;
1013 class ALEffect;
1014 class ALURE_API Effect {
1015 friend class ALContext;
1016 friend class ALAuxiliaryEffectSlot;
1018 MAKE_PIMPL(Effect, ALEffect)
1020 public:
1022 * Updates the effect with the specified reverb properties. If the
1023 * EAXReverb effect is not supported, it will automatically attempt to
1024 * downgrade to the Standard Reverb effect.
1026 void setReverbProperties(const EFXEAXREVERBPROPERTIES &props);
1028 void destroy();
1033 * Audio decoder interface. Applications may derive from this, implementing the
1034 * necessary methods, and use it in places the API wants a Decoder object.
1036 class ALURE_API Decoder {
1037 public:
1038 virtual ~Decoder() { }
1040 /** Retrieves the sample frequency, in hz, of the audio being decoded. */
1041 virtual ALuint getFrequency() const = 0;
1042 /** Retrieves the channel configuration of the audio being decoded. */
1043 virtual ChannelConfig getChannelConfig() const = 0;
1044 /** Retrieves the sample type of the audio being decoded. */
1045 virtual SampleType getSampleType() const = 0;
1048 * Retrieves the total length of the audio, in sample frames. If unknown,
1049 * returns 0. Note that if the returned length is 0, the decoder may not be
1050 * used to load a Buffer.
1052 virtual uint64_t getLength() const = 0;
1054 * Retrieves the current sample frame position (i.e. the number of sample
1055 * frames from the beginning).
1057 virtual uint64_t getPosition() const = 0;
1059 * Seek to pos, specified in sample frames. Returns true if the seek was
1060 * successful.
1062 virtual bool seek(uint64_t pos) = 0;
1065 * Retrieves the loop points, in sample frames, as a [start,end) pair. If
1066 * start >= end, use all available data.
1068 virtual std::pair<uint64_t,uint64_t> getLoopPoints() const = 0;
1071 * Decodes count sample frames, writing them to ptr, and returns the number
1072 * of sample frames written. Returning less than the requested count
1073 * indicates the end of the audio.
1075 virtual ALuint read(ALvoid *ptr, ALuint count) = 0;
1079 * Audio decoder factory interface. Applications may derive from this,
1080 * implementing the necessary methods, and use it in places the API wants a
1081 * DecoderFactory object.
1083 class ALURE_API DecoderFactory {
1084 public:
1085 virtual ~DecoderFactory() { }
1088 * Creates and returns a Decoder instance for the given resource file. If
1089 * the decoder needs to retain the file handle for reading as-needed, it
1090 * should move the UniquePtr to internal storage.
1092 * \return nullptr if a decoder can't be created from the file.
1094 virtual SharedPtr<Decoder> createDecoder(UniquePtr<std::istream> &file) = 0;
1098 * Registers a decoder factory for decoding audio. Registered factories are
1099 * used in lexicographical order, e.g. if Factory1 is registered with name1 and
1100 * Factory2 is registered with name2, Factory1 will be used before Factory2 if
1101 * name1 < name2. Internal decoder factories are always used after registered
1102 * ones.
1104 * Alure retains a reference to the DecoderFactory instance and will release it
1105 * (potentially destroying the object) when the library unloads.
1107 * \param name A unique name identifying this decoder factory.
1108 * \param factory A DecoderFactory instance used to create Decoder instances.
1110 ALURE_API void RegisterDecoder(const String &name, UniquePtr<DecoderFactory> factory);
1113 * Unregisters a decoder factory by name. Alure returns the instance back to
1114 * the application.
1116 * \param name The unique name identifying a previously-registered decoder
1117 * factory.
1119 * \return The unregistered decoder factory instance, or 0 (nullptr) if a
1120 * decoder factory with the given name doesn't exist.
1122 ALURE_API UniquePtr<DecoderFactory> UnregisterDecoder(const String &name);
1126 * A file I/O factory interface. Applications may derive from this and set an
1127 * instance to be used by the audio decoders. By default, the library uses
1128 * standard I/O.
1130 class ALURE_API FileIOFactory {
1131 public:
1133 * Sets the factory instance to be used by the audio decoders. If a
1134 * previous factory was set, it's returned to the application. Passing in a
1135 * NULL factory reverts to the default.
1137 static UniquePtr<FileIOFactory> set(UniquePtr<FileIOFactory> factory);
1140 * Gets the current FileIOFactory instance being used by the audio
1141 * decoders.
1143 static FileIOFactory &get();
1145 virtual ~FileIOFactory() { }
1147 /** Opens a read-only binary file for the given name. */
1148 virtual UniquePtr<std::istream> openFile(const String &name) = 0;
1153 * A message handler interface. Applications may derive from this and set an
1154 * instance on a context to receive messages. The base methods are no-ops, so
1155 * derived classes only need to implement methods for relevant messages.
1157 * It's recommended that applications mark their handler methods using the
1158 * override keyword, to ensure they're properly overriding the base methods in
1159 * case they change.
1161 class ALURE_API MessageHandler {
1162 public:
1163 virtual ~MessageHandler();
1166 * Called when the given device has been disconnected and is no longer
1167 * usable for output. As per the ALC_EXT_disconnect specification,
1168 * disconnected devices remain valid, however all playing sources are
1169 * automatically stopped, any sources that are attempted to play will
1170 * immediately stop, and new contexts may not be created on the device.
1172 * Note that connection status is checked during Context::update calls, so
1173 * that method must be called regularly to be notified when a device is
1174 * disconnected. This method may not be called if the device lacks support
1175 * for the ALC_EXT_disconnect extension.
1177 * WARNING: Do not attempt to clean up resources within this callback
1178 * method, as Alure is in the middle of doing updates. Instead, flag the
1179 * device as having been lost and do cleanup later.
1181 virtual void deviceDisconnected(Device device);
1184 * Called when the given source reaches the end of the buffer or stream.
1186 * Sources that stopped automatically will be detected upon a call to
1187 * Context::update or Source::update, and will have forced set to false.
1189 virtual void sourceStopped(Source *source);
1192 * Called when the given source was forced to stop. This can be because
1193 * either there were no more system sources and a higher-priority source
1194 * needs to play, or it's part of a SourceGroup (or sub-group thereof) that
1195 * had its SourceGroup::stopAll method called.
1197 virtual void sourceForceStopped(Source *source);
1200 * Called when a new buffer is about to be created and loaded. May be
1201 * called asynchronously for buffers being loaded asynchronously.
1203 * \param name The resource name, as passed to Context::getBuffer.
1204 * \param channels Channel configuration of the given audio data.
1205 * \param type Sample type of the given audio data.
1206 * \param samplerate Sample rate of the given audio data.
1207 * \param data The audio data that is about to be fed to the OpenAL buffer.
1209 virtual void bufferLoading(const String &name, ChannelConfig channels, SampleType type, ALuint samplerate, const Vector<ALbyte> &data);
1212 * Called when a resource isn't found, allowing the app to substitute in a
1213 * different resource. For buffers created with Context::getBuffer or
1214 * Context::getBufferAsync, the original name will still be used for the
1215 * cache map so the app doesn't have to keep track of substituted resource
1216 * names.
1218 * This will be called again if the new name isn't found.
1220 * \param name The resource name that was not found.
1221 * \return The replacement resource name to use instead. Returning an empty
1222 * string means to stop trying.
1224 virtual String resourceNotFound(const String &name);
1227 } // namespace alure
1229 #endif /* AL_ALURE2_H */