Constify some methods
[alure.git] / include / AL / alure2.h
blobdb8fc39770c245d1f5c653589abe9a428212e350
1 #ifndef AL_ALURE2_H
2 #define AL_ALURE2_H
4 #include <vector>
5 #include <string>
6 #include <memory>
7 #include <utility>
8 #include <cmath>
10 #include "alc.h"
11 #include "al.h"
13 #ifdef _WIN32
14 #if defined(ALURE_BUILD_STATIC) || defined(ALURE_STATIC_LIB)
15 #define ALURE_API
16 #elif defined(ALURE_BUILD_DLL)
17 #define ALURE_API __declspec(dllexport)
18 #else
19 #define ALURE_API __declspec(dllimport)
20 #endif
22 #else
24 #define ALURE_API
25 #endif
27 #ifndef EFXEAXREVERBPROPERTIES_DEFINED
28 #define EFXEAXREVERBPROPERTIES_DEFINED
29 typedef struct {
30 float flDensity;
31 float flDiffusion;
32 float flGain;
33 float flGainHF;
34 float flGainLF;
35 float flDecayTime;
36 float flDecayHFRatio;
37 float flDecayLFRatio;
38 float flReflectionsGain;
39 float flReflectionsDelay;
40 float flReflectionsPan[3];
41 float flLateReverbGain;
42 float flLateReverbDelay;
43 float flLateReverbPan[3];
44 float flEchoTime;
45 float flEchoDepth;
46 float flModulationTime;
47 float flModulationDepth;
48 float flAirAbsorptionGainHF;
49 float flHFReference;
50 float flLFReference;
51 float flRoomRolloffFactor;
52 int iDecayHFLimit;
53 } EFXEAXREVERBPROPERTIES, *LPEFXEAXREVERBPROPERTIES;
54 #endif
56 namespace alure {
58 class DeviceManager;
59 class Device;
60 class Context;
61 class Listener;
62 class Buffer;
63 class Source;
64 class SourceGroup;
65 class AuxiliaryEffectSlot;
66 class Effect;
67 class Decoder;
68 class DecoderFactory;
69 class MessageHandler;
72 // A SharedPtr implementation, defaults to C++11's std::shared_ptr. If this is
73 // changed, you must recompile the library.
74 template<typename T>
75 using SharedPtr = std::shared_ptr<T>;
76 template<typename T, typename... Args>
77 constexpr inline SharedPtr<T> MakeShared(Args&&... args)
79 return std::make_shared<T>(std::forward<Args>(args)...);
82 // A UniquePtr implementation, defaults to C++11's std::unique_ptr. If this is
83 // changed, you must recompile the library.
84 template<typename T, typename D = std::default_delete<T>>
85 using UniquePtr = std::unique_ptr<T, D>;
86 template<typename T, typename... Args>
87 constexpr inline UniquePtr<T> MakeUnique(Args&&... args)
89 #if __cplusplus >= 201402L
90 return std::make_unique<T>(std::forward<Args>(args)...);
91 #else
92 return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
93 #endif
96 // A Vector implementation, defaults to C++'s std::vector. If this is changed,
97 // you must recompile the library.
98 template<typename T>
99 using Vector = std::vector<T>;
101 // A String implementation, default's to C++'s std::string. If this is changed,
102 // you must recompile the library.
103 using String = std::string;
106 * An attribute pair, for passing attributes to \ref Device::createContext and
107 * \ref Device::reset.
109 using AttributePair = std::pair<ALCint,ALCint>;
110 static_assert(sizeof(AttributePair) == sizeof(ALCint[2]), "Bad AttributePair size");
113 struct FilterParams {
114 ALfloat mGain;
115 ALfloat mGainHF; // For low-pass and band-pass filters
116 ALfloat mGainLF; // For high-pass and band-pass filters
120 class ALURE_API Vector3 {
121 std::array<ALfloat,3> mValue;
123 public:
124 constexpr Vector3() noexcept
125 : mValue{{0.0f, 0.0f, 0.0f}}
127 constexpr Vector3(const Vector3 &rhs) noexcept
128 : mValue{{rhs.mValue[0], rhs.mValue[1], rhs.mValue[2]}}
130 constexpr Vector3(ALfloat val) noexcept
131 : mValue{{val, val, val}}
133 constexpr Vector3(ALfloat x, ALfloat y, ALfloat z) noexcept
134 : mValue{{x, y, z}}
136 Vector3(const ALfloat *vec) noexcept
137 : mValue{{vec[0], vec[1], vec[2]}}
140 const ALfloat *getPtr() const noexcept
141 { return mValue.data(); }
143 ALfloat& operator[](size_t i) noexcept
144 { return mValue[i]; }
145 constexpr const ALfloat& operator[](size_t i) const noexcept
146 { return mValue[i]; }
148 #define ALURE_DECL_OP(op) \
149 constexpr Vector3 operator op(const Vector3 &rhs) const noexcept \
151 return Vector3(mValue[0] op rhs.mValue[0], \
152 mValue[1] op rhs.mValue[1], \
153 mValue[2] op rhs.mValue[2]); \
155 ALURE_DECL_OP(+)
156 ALURE_DECL_OP(-)
157 ALURE_DECL_OP(*)
158 ALURE_DECL_OP(/)
159 #undef ALURE_DECL_OP
160 #define ALURE_DECL_OP(op) \
161 Vector3& operator op(const Vector3 &rhs) noexcept \
163 mValue[0] op rhs.mValue[0]; \
164 mValue[1] op rhs.mValue[1]; \
165 mValue[2] op rhs.mValue[2]; \
166 return *this; \
168 ALURE_DECL_OP(+=)
169 ALURE_DECL_OP(-=)
170 ALURE_DECL_OP(*=)
171 ALURE_DECL_OP(/=)
173 #undef ALURE_DECL_OP
174 #define ALURE_DECL_OP(op) \
175 constexpr Vector3 operator op(ALfloat scale) const noexcept \
177 return Vector3(mValue[0] op scale, \
178 mValue[1] op scale, \
179 mValue[2] op scale); \
181 ALURE_DECL_OP(*)
182 ALURE_DECL_OP(/)
183 #undef ALURE_DECL_OP
184 #define ALURE_DECL_OP(op) \
185 Vector3& operator op(ALfloat scale) noexcept \
187 mValue[0] op scale; \
188 mValue[1] op scale; \
189 mValue[2] op scale; \
190 return *this; \
192 ALURE_DECL_OP(*=)
193 ALURE_DECL_OP(/=)
194 #undef ALURE_DECL_OP
196 constexpr ALfloat getLengthSquared() const noexcept
197 { return mValue[0]*mValue[0] + mValue[1]*mValue[1] + mValue[2]*mValue[2]; }
198 constexpr ALfloat getLength() const noexcept
199 { return std::sqrt(getLengthSquared()); }
201 constexpr ALfloat getDistanceSquared(const Vector3 &pos) const noexcept
202 { return (pos - *this).getLengthSquared(); }
203 constexpr ALfloat getDistance(const Vector3 &pos) const noexcept
204 { return (pos - *this).getLength(); }
206 static_assert(sizeof(Vector3) == sizeof(ALfloat[3]), "Bad Vector3 size");
210 * Creates a version number value using the specified \param major and
211 * \param minor values.
213 constexpr inline ALCuint MakeVersion(ALCushort major, ALCushort minor)
214 { return (major<<16) | minor; }
217 * Retrieves the major version of a version number value created by
218 * \ref MakeVersion.
220 constexpr inline ALCuint MajorVersion(ALCuint version)
221 { return version>>16; }
223 * Retrieves the minor version of a version number value created by
224 * \ref MakeVersion.
226 constexpr inline ALCuint MinorVersion(ALCuint version)
227 { return version&0xffff; }
230 enum class DeviceEnumeration {
231 Basic = ALC_DEVICE_SPECIFIER,
232 Complete = ALC_ALL_DEVICES_SPECIFIER,
233 Capture = ALC_CAPTURE_DEVICE_SPECIFIER
236 enum class DefaultDeviceType {
237 Basic = ALC_DEFAULT_DEVICE_SPECIFIER,
238 Complete = ALC_DEFAULT_ALL_DEVICES_SPECIFIER,
239 Capture = ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
243 * A class managing \ref Device objects and other related functionality. This
244 * class is a singleton, only one instance will exist in a process.
246 class ALURE_API DeviceManager {
247 public:
248 /** Retrieves the DeviceManager instance. */
249 static DeviceManager &get();
251 /** Queries the existence of a non-device-specific ALC extension. */
252 virtual bool queryExtension(const String &name) const = 0;
254 /** Enumerates available device names of the given \param type. */
255 virtual Vector<String> enumerate(DeviceEnumeration type) const = 0;
256 /** Retrieves the default device of the given \param type. */
257 virtual String defaultDeviceName(DefaultDeviceType type) const = 0;
259 /** Opens the playback device given by \param name, or the default if empty. */
260 virtual Device *openPlayback(const String &name=String()) = 0;
264 enum class PlaybackDeviceName {
265 Basic = ALC_DEVICE_SPECIFIER,
266 Complete = ALC_ALL_DEVICES_SPECIFIER
269 class ALURE_API Device {
270 public:
271 /** Retrieves the device name as given by \param type. */
272 virtual String getName(PlaybackDeviceName type=PlaybackDeviceName::Basic) const = 0;
273 /** Queries the existence of an ALC extension on this device. */
274 virtual bool queryExtension(const String &name) const = 0;
277 * Retrieves the ALC version supported by this device, as constructed by
278 * \ref MakeVersion.
280 virtual ALCuint getALCVersion() const = 0;
283 * Retrieves the EFX version supported by this device, as constructed by
284 * \ref MakeVersion. If the ALC_EXT_EFX extension is unsupported, this
285 * will be 0.
287 virtual ALCuint getEFXVersion() const = 0;
289 /** Retrieves the device's playback frequency, in hz. */
290 virtual ALCuint getFrequency() const = 0;
293 * Retrieves the maximum number of auxiliary source sends. If ALC_EXT_EFX
294 * is unsupported, this will be 0.
296 virtual ALCuint getMaxAuxiliarySends() const = 0;
299 * Enumerates available HRTF names. The names are sorted as OpenAL gives
300 * them, such that the index of a given name is the ID to use with
301 * ALC_HRTF_ID_SOFT.
303 * Requires the ALC_SOFT_HRTF extension.
305 virtual Vector<String> enumerateHRTFNames() const = 0;
308 * Retrieves whether HRTF is enabled on the device or not.
310 * Requires the ALC_SOFT_HRTF extension.
312 virtual bool isHRTFEnabled() const = 0;
315 * Retrieves the name of the HRTF currently being used by this device.
317 * Requires the ALC_SOFT_HRTF extension.
319 virtual String getCurrentHRTF() const = 0;
322 * Resets the device, using the specified \param attributes.
324 * Requires the ALC_SOFT_HRTF extension.
326 virtual void reset(const Vector<AttributePair> &attributes) = 0;
329 * Creates a new \ref Context on this device, using the specified
330 * \param attributes.
332 virtual Context *createContext(const Vector<AttributePair> &attributes=Vector<AttributePair>{}) = 0;
335 * Pauses device processing, stopping updates for its contexts. Multiple
336 * calls are allowed but it is not reference counted, so the device will
337 * resume after one \ref resumeDSP call.
339 * Requires the ALC_SOFT_pause_device extension.
341 virtual void pauseDSP() = 0;
344 * Resumes device processing, restarting updates for its contexts. Multiple
345 * calls are allowed and will no-op.
347 virtual void resumeDSP() = 0;
350 * Closes and frees the device. All previously-created contexts must first
351 * be destroyed.
353 virtual void close() = 0;
357 enum class DistanceModel {
358 InverseClamped = AL_INVERSE_DISTANCE_CLAMPED,
359 LinearClamped = AL_LINEAR_DISTANCE_CLAMPED,
360 ExponentClamped = AL_EXPONENT_DISTANCE_CLAMPED,
361 Inverse = AL_INVERSE_DISTANCE,
362 Linear = AL_LINEAR_DISTANCE,
363 Exponent = AL_EXPONENT_DISTANCE,
364 None = AL_NONE,
367 class ALURE_API Context {
368 public:
369 /** Makes the specified \param context current for OpenAL operations. */
370 static void MakeCurrent(Context *context);
371 /** Retrieves the current context used for OpenAL operations. */
372 static Context *GetCurrent();
375 * Makes the specified \param context current for OpenAL operations on the
376 * calling thread only. Requires the ALC_EXT_thread_local_context extension
377 * on both the context's device and the \ref DeviceManager.
379 static void MakeThreadCurrent(Context *context);
380 /** Retrieves the thread-specific context used for OpenAL operations. */
381 static Context *GetThreadCurrent();
384 * Destroys the context. The context must not be current when this is
385 * called.
387 virtual void destroy() = 0;
389 /** Retrieves the \ref Device this context was created from. */
390 virtual Device *getDevice() = 0;
392 virtual void startBatch() = 0;
393 virtual void endBatch() = 0;
396 * Retrieves a \ref Listener instance for this context. Each context will
397 * only have one listener.
399 virtual Listener *getListener() = 0;
402 * Sets a MessageHandler instance which will be used to provide certain
403 * messages back to the application. Only one handler may be set for a
404 * context at a time. The previously set handler will be returned.
406 virtual SharedPtr<MessageHandler> setMessageHandler(SharedPtr<MessageHandler> handler) = 0;
408 /** Gets the currently-set message handler. */
409 virtual SharedPtr<MessageHandler> getMessageHandler() const = 0;
412 * Specifies the desired interval (in milliseconds) that the background
413 * thread will be woken up to process tasks, e.g. keeping streaming sources
414 * filled. An interval of 0 means the background thread will only be woken
415 * up manually, for instance with calls to \ref update. The default is 0.
417 virtual void setAsyncWakeInterval(ALuint msec) = 0;
420 * Retrieves the current interval used for waking up the background thread.
422 virtual ALuint getAsyncWakeInterval() const = 0;
425 * Creates a \ref Decoder instance for the given audio file or resource
426 * \param name.
428 virtual SharedPtr<Decoder> createDecoder(const String &name) = 0;
430 // Functions below require the context to be current
433 * Creates and caches a \ref Buffer for the given audio file or resource
434 * \param name. Multiple calls with the same name will return the same
435 * \ref Buffer object.
437 virtual Buffer *getBuffer(const String &name) = 0;
440 * Creates and caches a \ref Buffer for the given audio file or resource
441 * \param name. Multiple calls with the same name will return the same
442 * \ref Buffer object.
444 * The returned \ref Buffer object will be scheduled for loading
445 * asynchronously, and must be checked with a call to
446 * \ref Buffer::getLoadStatus prior to being played.
448 virtual Buffer *getBufferAsync(const String &name) = 0;
451 * Deletes the cached \ref Buffer object for the given audio file or
452 * resource \param name. The buffer must not be in use by a \ref Source.
454 virtual void removeBuffer(const String &name) = 0;
456 * Deletes the given cached \param buffer instance. The buffer must not be
457 * in use by a \ref Source.
459 virtual void removeBuffer(Buffer *buffer) = 0;
462 * Creates a new \ref Source. There is no practical limit to the number of
463 * sources you may get.
465 virtual Source *createSource() = 0;
467 virtual AuxiliaryEffectSlot *createAuxiliaryEffectSlot() = 0;
469 virtual Effect *createEffect() = 0;
471 virtual SourceGroup *createSourceGroup(String name) = 0;
473 virtual void setDopplerFactor(ALfloat factor) = 0;
475 virtual void setSpeedOfSound(ALfloat speed) = 0;
477 virtual void setDistanceModel(DistanceModel model) = 0;
480 * Updates the context and all sources belonging to this context (you do
481 * not need to call the individual sources' update method if you call this
482 * function).
484 virtual void update() = 0;
487 class ALURE_API Listener {
488 public:
489 virtual void setGain(ALfloat gain) = 0;
491 virtual void setPosition(ALfloat x, ALfloat y, ALfloat z) = 0;
492 virtual void setPosition(const ALfloat *pos) = 0;
494 virtual void setVelocity(ALfloat x, ALfloat y, ALfloat z) = 0;
495 virtual void setVelocity(const ALfloat *vel) = 0;
497 virtual void setOrientation(ALfloat x1, ALfloat y1, ALfloat z1, ALfloat x2, ALfloat y2, ALfloat z2) = 0;
498 virtual void setOrientation(const ALfloat *at, const ALfloat *up) = 0;
499 virtual void setOrientation(const ALfloat *ori) = 0;
501 virtual void setMetersPerUnit(ALfloat m_u) = 0;
505 enum class SampleType {
506 UInt8,
507 Int16,
508 Float32,
509 Mulaw
511 ALURE_API const char *GetSampleTypeName(SampleType type);
513 enum class ChannelConfig {
514 /** 1-channel mono sound. */
515 Mono,
516 /** 2-channel stereo sound. */
517 Stereo,
518 /** 2-channel rear sound (back-left and back-right). */
519 Rear,
520 /** 4-channel surround sound. */
521 Quad,
522 /** 5.1 surround sound. */
523 X51,
524 /** 6.1 surround sound. */
525 X61,
526 /** 7.1 surround sound. */
527 X71,
528 /** 3-channel B-Format, using FuMa channel ordering and scaling. */
529 BFormat2D,
530 /** 4-channel B-Format, using FuMa channel ordering and scaling. */
531 BFormat3D
533 ALURE_API const char *GetChannelConfigName(ChannelConfig cfg);
535 enum class BufferLoadStatus {
536 Pending,
537 Ready
540 class ALURE_API Buffer {
541 public:
543 * Retrieves the length of the buffer in sample frames. The buffer must be
544 * fully loaded before this method is called.
546 virtual ALuint getLength() const = 0;
548 /** Retrieves the buffer's frequency in hz. */
549 virtual ALuint getFrequency() const = 0;
551 /** Retrieves the buffer's sample configuration. */
552 virtual ChannelConfig getChannelConfig() const = 0;
554 /** Retrieves the buffer's sample type. */
555 virtual SampleType getSampleType() const = 0;
558 * Retrieves the storage size used by the buffer, in bytes. The buffer must
559 * be fully loaded before this method is called.
561 virtual ALuint getSize() const = 0;
564 * Sets the buffer's loop points, used for looping sources. If the current
565 * context does not support the AL_SOFT_loop_points extension, \param start
566 * and \param end must be 0 and \ref getLength() respectively. Otherwise,
567 * \param start must be less than \param end, and \param end must be less
568 * than or equal to \ref getLength().
570 * The buffer must not be in use when this method is called, and the buffer
571 * must be fully loaded.
573 * \param start The starting point, in sample frames (inclusive).
574 * \param end The ending point, in sample frames (exclusive).
576 virtual void setLoopPoints(ALuint start, ALuint end) = 0;
579 * Retrieves the current loop points as a [start,end) pair. The buffer must
580 * be fully loaded before this method is called.
582 virtual std::pair<ALuint,ALuint> getLoopPoints() const = 0;
585 * Retrieves the \ref Source objects currently playing the buffer. Stopping
586 * the returned sources will allow the buffer to be removed from the
587 * context.
589 virtual Vector<Source*> getSources() const = 0;
592 * Queries the buffer's load status. A return of
593 * \ref BufferLoadStatus::Pending indicates the buffer is not finished
594 * loading and can't be used with a call to \ref Source::play. Buffers
595 * created with \ref Context::getBuffer will always return
596 * \ref BufferLoadStatus::Ready.
598 virtual BufferLoadStatus getLoadStatus() = 0;
600 /** Retrieves the name the buffer was created with. */
601 virtual const String &getName() const = 0;
603 /** Queries if the buffer is in use and can't be removed. */
604 virtual bool isInUse() const = 0;
608 class ALURE_API Source {
609 public:
611 * Plays the source using \param buffer. The same buffer may be played from
612 * multiple sources simultaneously.
614 virtual void play(Buffer *buffer) = 0;
616 * Plays the source by streaming audio from \param decoder. This will use
617 * \param queuelen buffers, each with \param updatelen sample frames. The
618 * given decoder must *NOT* have its read or seek methods called from
619 * elsewhere while in use.
621 virtual void play(SharedPtr<Decoder> decoder, ALuint updatelen, ALuint queuesize) = 0;
623 * Stops playback, releasing the buffer or decoder reference.
625 virtual void stop() = 0;
627 /** Pauses the source if it is playing. */
628 virtual void pause() = 0;
630 /** Resumes the source if it is paused. */
631 virtual void resume() = 0;
633 /** Specifies if the source is currently playing. */
634 virtual bool isPlaying() const = 0;
636 /** Specifies if the source is currently paused. */
637 virtual bool isPaused() const = 0;
640 * Specifies the source's playback priority. Lowest priority sources will
641 * be evicted first when higher priority sources are played.
643 virtual void setPriority(ALuint priority) = 0;
644 /** Retrieves the source's priority. */
645 virtual ALuint getPriority() const = 0;
648 * Sets the source's offset, in sample frames. If the source is playing or
649 * paused, it will go to that offset immediately, otherwise the source will
650 * start at the specified offset the next time it's played.
652 virtual void setOffset(uint64_t offset) = 0;
654 * Retrieves the source offset in sample frames. For streaming sources,
655 * this will be the offset from the beginning of the stream based on the
656 * decoder's reported position.
658 * \param latency If non-NULL and the device supports it, the source's
659 * latency, in nanoseconds, will be written to that location.
661 virtual uint64_t getOffset(uint64_t *latency=0) const = 0;
664 * Specifies if the source should loop on the \ref Buffer or \ref Decoder
665 * object's loop points.
667 virtual void setLooping(bool looping) = 0;
668 virtual bool getLooping() const = 0;
671 * Specifies a linear pitch shift base. A value of 1.0 is the default
672 * normal speed.
674 virtual void setPitch(ALfloat pitch) = 0;
675 virtual ALfloat getPitch() const = 0;
678 * Specifies the base linear gain. A value of 1.0 is the default normal
679 * volume.
681 virtual void setGain(ALfloat gain) = 0;
682 virtual ALfloat getGain() const = 0;
685 * Specifies the minimum and maximum gain. The source's gain is clamped to
686 * this range after distance attenuation and cone attenuation are applied
687 * to the gain base, although before the filter gain adjustements.
689 virtual void setGainRange(ALfloat mingain, ALfloat maxgain) = 0;
690 virtual std::pair<ALfloat,ALfloat> getGainRange() const = 0;
691 ALfloat getMinGain() const { return std::get<0>(getGainRange()); }
692 ALfloat getMaxGain() const { return std::get<1>(getGainRange()); }
695 * Specifies the reference distance and maximum distance the source will
696 * use for the current distance model. For Clamped distance models, the
697 * source's calculated distance is clamped to the specified range before
698 * applying distance-related attenuation.
700 * For all distance models, the reference distance is the distance at which
701 * the source's volume will not have any extra attenuation (an effective
702 * gain multiplier of 1).
704 virtual void setDistanceRange(ALfloat refdist, ALfloat maxdist) = 0;
705 virtual std::pair<ALfloat,ALfloat> getDistanceRange() const = 0;
706 ALfloat getReferenceDistance() const { return std::get<0>(getDistanceRange()); }
707 ALfloat getMaxDistance() const { return std::get<1>(getDistanceRange()); }
709 /** Specifies the source's 3D position. */
710 virtual void setPosition(ALfloat x, ALfloat y, ALfloat z) = 0;
711 virtual void setPosition(const ALfloat *pos) = 0;
712 virtual Vector3 getPosition() const = 0;
715 * Specifies the source's 3D velocity, in units per second. As with OpenAL,
716 * this does not actually alter the source's position, and instead just
717 * alters the pitch as determined by the doppler effect.
719 virtual void setVelocity(ALfloat x, ALfloat y, ALfloat z) = 0;
720 virtual void setVelocity(const ALfloat *vel) = 0;
721 virtual Vector3 getVelocity() const = 0;
724 * Specifies the source's 3D facing direction. Deprecated in favor of
725 * \ref setOrientation.
727 virtual void setDirection(ALfloat x, ALfloat y, ALfloat z) = 0;
728 virtual void setDirection(const ALfloat *dir) = 0;
729 virtual Vector3 getDirection() const = 0;
732 * Specifies the source's 3D orientation. Note: unlike the AL_EXT_BFORMAT
733 * extension this property comes from, this also affects the facing
734 * direction, superceding \ref setDirection.
736 virtual void setOrientation(ALfloat x1, ALfloat y1, ALfloat z1, ALfloat x2, ALfloat y2, ALfloat z2) = 0;
737 virtual void setOrientation(const ALfloat *at, const ALfloat *up) = 0;
738 virtual void setOrientation(const ALfloat *ori) = 0;
739 virtual std::pair<Vector3,Vector3> getOrientation() const = 0;
742 * Specifies the source's cone angles, in degrees. The inner angle is the
743 * area within which the listener will hear the source with no extra
744 * attenuation, while the listener being outside of the outer angle will
745 * hear the source attenuated according to the outer cone gains.
747 virtual void setConeAngles(ALfloat inner, ALfloat outer) = 0;
748 virtual std::pair<ALfloat,ALfloat> getConeAngles() const = 0;
749 ALfloat getInnerConeAngle() const { return std::get<0>(getConeAngles()); }
750 ALfloat getOuterConeAngle() const { return std::get<1>(getConeAngles()); }
753 * Specifies the linear gain multiplier when the listener is outside of the
754 * source's outer cone area. The specified \param gain applies to all
755 * frequencies, while \param gainhf applies extra attenuation to high
756 * frequencies.
758 * \param gainhf has no effect without the ALC_EXT_EFX extension.
760 virtual void setOuterConeGains(ALfloat gain, ALfloat gainhf=1.0f) = 0;
761 virtual std::pair<ALfloat,ALfloat> getOuterConeGains() const = 0;
762 ALfloat getOuterConeGain() const { return std::get<0>(getOuterConeGains()); }
763 ALfloat getOuterConeGainHF() const { return std::get<1>(getOuterConeGains()); }
766 * Specifies the rolloff factors for the direct and send paths. This is
767 * effectively a distance scaling relative to the reference distance. Note:
768 * the room rolloff factor is 0 by default, disabling distance attenuation
769 * for send paths. This is because the reverb engine will, by default,
770 * apply a more realistic room attenuation based on the reverb decay time
771 * and direct path attenuation.
773 virtual void setRolloffFactors(ALfloat factor, ALfloat roomfactor=0.0f) = 0;
774 virtual std::pair<ALfloat,ALfloat> getRolloffFactors() const = 0;
775 ALfloat getRolloffFactor() const { return std::get<0>(getRolloffFactors()); }
776 ALfloat getRoomRolloffFactor() const { return std::get<1>(getRolloffFactors()); }
779 * Specifies the doppler factor for the doppler effect's pitch shift. This
780 * effectively scales the source and listener velocities for the doppler
781 * calculation.
783 virtual void setDopplerFactor(ALfloat factor) = 0;
784 virtual ALfloat getDopplerFactor() const = 0;
786 /** Specifies if the source properties are relative to the listener. */
787 virtual void setRelative(bool relative) = 0;
788 virtual bool getRelative() const = 0;
791 * Specifies the source's radius. This causes the source to behave as if
792 * every point within the spherical area emits sound.
794 * Has no effect without the AL_EXT_SOURCE_RADIUS extension.
796 virtual void setRadius(ALfloat radius) = 0;
797 virtual ALfloat getRadius() const = 0;
800 * Specifies the left and right channel angles, in radians, when playing a
801 * stereo buffer or stream. The angles go counter-clockwise, with 0 being
802 * in front and positive values going left.
804 * Has no effect without the AL_EXT_STEREO_ANGLES extension.
806 virtual void setStereoAngles(ALfloat leftAngle, ALfloat rightAngle) = 0;
807 virtual std::pair<ALfloat,ALfloat> getStereoAngles() const = 0;
809 virtual void setAirAbsorptionFactor(ALfloat factor) = 0;
810 virtual ALfloat getAirAbsorptionFactor() const = 0;
812 virtual void setGainAuto(bool directhf, bool send, bool sendhf) = 0;
813 virtual std::tuple<bool,bool,bool> getGainAuto() const = 0;
814 bool getDirectGainHFAuto() const { return std::get<0>(getGainAuto()); }
815 bool getSendGainAuto() const { return std::get<1>(getGainAuto()); }
816 bool getSendGainHFAuto() const { return std::get<2>(getGainAuto()); }
818 /** Sets the \param filter properties on the direct path signal. */
819 virtual void setDirectFilter(const FilterParams &filter) = 0;
821 * Sets the \param filter properties on the given \param send path signal.
822 * Any auxiliary effect slot on the send path remains in place.
824 virtual void setSendFilter(ALuint send, const FilterParams &filter) = 0;
826 * Connects the effect slot \param slot to the given \param send path. Any
827 * filter properties on the send path remain as they were.
829 virtual void setAuxiliarySend(AuxiliaryEffectSlot *slot, ALuint send) = 0;
831 * Connects the effect slot \param slot to the given \param send path,
832 * using the \param filter properties.
834 virtual void setAuxiliarySendFilter(AuxiliaryEffectSlot *slot, ALuint send, const FilterParams &filter) = 0;
837 * Updates the source, ensuring that resources are released when playback
838 * is finished.
840 virtual void update() = 0;
843 * Releases the source, stopping playback, releasing resources, and
844 * returning it to the system.
846 virtual void release() = 0;
850 class ALURE_API SourceGroup {
851 public:
852 /** Retrieves the associated name of the source group. */
853 virtual const String &getName() const = 0;
856 * Adds \param source to the source group. A source may only be part of one
857 * group at a time, and will automatically be removed from its current
858 * group as needed.
860 virtual void addSource(Source *source) = 0;
861 /** Removes \param source from the source group. */
862 virtual void removeSource(Source *source) = 0;
864 /** Adds a list of sources to the group at once. */
865 virtual void addSources(const Vector<Source*> &sources) = 0;
866 /** Removes a list of sources from the source group. */
867 virtual void removeSources(const Vector<Source*> &sources) = 0;
870 * Adds \param group as a subgroup of the source group. This method will
871 * throw an exception if \param group is being added to a group it has as a
872 * sub-group (i.e. it would create a circular sub-group chain).
874 virtual void addSubGroup(SourceGroup *group) = 0;
875 /** Removes \param group from the source group. */
876 virtual void removeSubGroup(SourceGroup *group) = 0;
878 /** Returns the list of sources currently in the group. */
879 virtual Vector<Source*> getSources() const = 0;
881 /** Returns the list of subgroups currently in the group. */
882 virtual Vector<SourceGroup*> getSubGroups() const = 0;
884 /** Sets the source group gain, which accumulates with its sources. */
885 virtual void setGain(ALfloat gain) = 0;
886 /** Gets the source group gain. */
887 virtual ALfloat getGain() const = 0;
889 /** Sets the source group pitch, which accumulates with its sources. */
890 virtual void setPitch(ALfloat pitch) = 0;
891 /** Gets the source group pitch. */
892 virtual ALfloat getPitch() const = 0;
895 * Pauses all currently-playing sources that are under this group,
896 * including sub-groups.
898 virtual void pauseAll() const = 0;
900 * Resumes all paused sources that are under this group, including
901 * sub-groups.
903 virtual void resumeAll() const = 0;
905 /** Stops all sources that are under this group, including sub-groups. */
906 virtual void stopAll() const = 0;
909 * Releases the source group, removing all sources from it before being
910 * freed.
912 virtual void release() = 0;
916 struct SourceSend {
917 Source *mSource;
918 ALuint mSend;
921 class ALURE_API AuxiliaryEffectSlot {
922 public:
923 virtual void setGain(ALfloat gain) = 0;
925 * If set to true, the reverb effect will automatically apply adjustments
926 * to the source's send slot based on the effect properties.
928 * Has no effect when using non-reverb effects. Default is true.
930 virtual void setSendAuto(bool sendauto) = 0;
933 * Updates the effect slot with a new \param effect. The given effect
934 * object may be altered or destroyed without affecting the effect slot.
936 virtual void applyEffect(const Effect *effect) = 0;
939 * Releases the effect slot, returning it to the system. It must not be in
940 * use by a source.
942 virtual void release() = 0;
945 * Retrieves each \ref Source object and its pairing send this effect slot
946 * is set on. Setting a different (or null) effect slot on each source's
947 * given send will allow the effect slot to be released.
949 virtual Vector<SourceSend> getSourceSends() const = 0;
951 /** Determines if the effect slot is in use by a source. */
952 virtual bool isInUse() const = 0;
956 class ALURE_API Effect {
957 public:
959 * Updates the effect with the specified reverb properties \param props. If
960 * the EAXReverb effect is not supported, it will automatically attempt to
961 * downgrade to the Standard Reverb effect.
963 virtual void setReverbProperties(const EFXEAXREVERBPROPERTIES &props) = 0;
965 virtual void destroy() = 0;
970 * Audio decoder interface. Applications may derive from this, implementing the
971 * necessary methods, and use it in places the API wants a Decoder object.
973 class ALURE_API Decoder {
974 public:
975 virtual ~Decoder() { }
977 /** Retrieves the sample frequency, in hz, of the audio being decoded. */
978 virtual ALuint getFrequency() const = 0;
979 /** Retrieves the channel configuration of the audio being decoded. */
980 virtual ChannelConfig getChannelConfig() const = 0;
981 /** Retrieves the sample type of the audio being decoded. */
982 virtual SampleType getSampleType() const = 0;
985 * Retrieves the total length of the audio, in sample frames. If unknown,
986 * returns 0. Note that if the returned length is 0, the decoder may not be
987 * used to load a \ref Buffer.
989 virtual uint64_t getLength() const = 0;
991 * Retrieves the current sample frame position (i.e. the number of sample
992 * frames from the beginning).
994 virtual uint64_t getPosition() const = 0;
996 * Seek to \param pos, specified in sample frames. Returns true if the seek
997 * was successful.
999 virtual bool seek(uint64_t pos) = 0;
1002 * Retrieves the loop points, in sample frames, as a [start,end) pair. If
1003 * start >= end, use all available data.
1005 virtual std::pair<uint64_t,uint64_t> getLoopPoints() const = 0;
1008 * Decodes \param count sample frames, writing them to \param ptr, and
1009 * returns the number of sample frames written. Returning less than the
1010 * requested count indicates the end of the audio.
1012 virtual ALuint read(ALvoid *ptr, ALuint count) = 0;
1016 * Audio decoder factory interface. Applications may derive from this,
1017 * implementing the necessary methods, and use it in places the API wants a
1018 * DecoderFactory object.
1020 class ALURE_API DecoderFactory {
1021 public:
1022 virtual ~DecoderFactory() { }
1025 * Creates and returns a \ref Decoder instance for the given resource
1026 * \param file. If the decoder needs to retain the file handle for reading
1027 * as-needed, it should move the UniquePtr to internal storage. Returns
1028 * nullptr if a decoder can't be created from the file.
1030 virtual SharedPtr<Decoder> createDecoder(UniquePtr<std::istream> &file) = 0;
1034 * Registers a decoder factory for decoding audio. Registered factories are
1035 * used in lexicographical order, e.g. if Factory1 is registered with name1 and
1036 * Factory2 is registered with name2, Factory1 will be used before Factory2 if
1037 * name1 < name2. Internal decoder factories are always used after registered
1038 * ones.
1040 * Alure retains a reference to the DecoderFactory instance and will release it
1041 * (potentially destroying the object) when the library unloads.
1043 * \param name A unique name identifying this decoder factory.
1044 * \param factory A DecoderFactory instance used to create Decoder instances.
1046 ALURE_API void RegisterDecoder(const String &name, UniquePtr<DecoderFactory> factory);
1049 * Unregisters a decoder factory by name. Alure returns the instance back to
1050 * the application.
1052 * \param name The unique name identifying a previously-registered decoder
1053 * factory.
1055 * \return The unregistered decoder factory instance, or 0 (nullptr) if a
1056 * decoder factory with the given name doesn't exist.
1058 ALURE_API UniquePtr<DecoderFactory> UnregisterDecoder(const String &name);
1062 * A file I/O factory interface. Applications may derive from this and set an
1063 * instance to be used by the audio decoders. By default, the library uses
1064 * standard I/O.
1066 class ALURE_API FileIOFactory {
1067 public:
1069 * Sets the \param factory instance to be used by the audio decoders. If a
1070 * previous factory was set, it's returned to the application. Passing in a
1071 * NULL factory reverts to the default.
1073 static UniquePtr<FileIOFactory> set(UniquePtr<FileIOFactory> factory);
1076 * Gets the current FileIOFactory instance being used by the audio
1077 * decoders.
1079 static FileIOFactory &get();
1081 virtual ~FileIOFactory() { }
1083 /** Opens a read-only binary file for the given \param name. */
1084 virtual UniquePtr<std::istream> openFile(const String &name) = 0;
1089 * A message handler interface. Applications may derive from this and set an
1090 * instance on a context to receive messages. The base methods are no-ops, so
1091 * derived classes only need to implement methods for relevant messages.
1093 * It's recommended that applications mark their handler methods using the
1094 * override keyword, to ensure they're properly overriding the base methods in
1095 * case they change.
1097 class ALURE_API MessageHandler {
1098 public:
1099 virtual ~MessageHandler();
1102 * Called when the given \param device has been disconnected and is no
1103 * longer usable for output. As per the ALC_EXT_disconnect specification,
1104 * disconnected devices remain valid, however all playing sources are
1105 * automatically stopped, any sources that are attempted to play will
1106 * immediately stop, and new contexts may not be created on the device.
1108 * Note that connection status is checked during \ref Context::update
1109 * calls, so that method must be called regularly to be notified when a
1110 * device is disconnected. This method may not be called if the device
1111 * lacks support for the ALC_EXT_disconnect extension.
1113 * WARNING: Do not attempt to clean up resources within this callback
1114 * method, as Alure is in the middle of doing updates. Instead, flag the
1115 * device as having been lost and do cleanup later.
1117 virtual void deviceDisconnected(Device *device);
1120 * Called when the given \param source stops playback. If \param forced is
1121 * true, the source was stopped because either there were no more system
1122 * sources and a higher-priority source needs to play, or it's part of a
1123 * \ref SourceGroup (or sub-group thereof) that had its
1124 * \ref SourceGroup::stopAll method called.
1126 * Sources that stopped automatically will be detected upon a call to
1127 * \ref Context::update or \ref Source::update, and will have \param forced
1128 * set to false.
1130 virtual void sourceStopped(Source *source, bool forced);
1133 * Called when a new buffer is about to be created and loaded. May be
1134 * called asynchronously for buffers being loaded asynchronously.
1136 * \param name The resource name, as passed to \ref Context::getBuffer.
1137 * \param channels Channel configuration of the given audio data.
1138 * \param type Sample type of the given audio data.
1139 * \param samplerate Sample rate of the given audio data.
1140 * \param data The audio data that is about to be fed to the OpenAL buffer.
1142 virtual void bufferLoading(const String &name, ChannelConfig channels, SampleType type, ALuint samplerate, const Vector<ALbyte> &data);
1145 * Called when a resource isn't found, allowing the app to substitute in a
1146 * different resource. For buffers created with \ref Context::getBuffer or
1147 * \ref Context::getBufferAsync, the original name will still be used for
1148 * the cache map so the app doesn't have to keep track of substituted
1149 * resource names.
1151 * This will be called again if the new name isn't found.
1153 * \param name The resource name that was not found.
1154 * \return The replacement resource name to use instead. Returning an empty
1155 * string means to stop trying.
1157 virtual String resourceNotFound(const String &name);
1160 } // namespace alure
1162 #endif /* AL_ALURE2_H */