14 #if defined(ALURE_BUILD_STATIC) || defined(ALURE_STATIC_LIB)
16 #elif defined(ALURE_BUILD_DLL)
17 #define ALURE_API __declspec(dllexport)
19 #define ALURE_API __declspec(dllimport)
27 #ifndef EFXEAXREVERBPROPERTIES_DEFINED
28 #define EFXEAXREVERBPROPERTIES_DEFINED
38 float flReflectionsGain
;
39 float flReflectionsDelay
;
40 float flReflectionsPan
[3];
41 float flLateReverbGain
;
42 float flLateReverbDelay
;
43 float flLateReverbPan
[3];
46 float flModulationTime
;
47 float flModulationDepth
;
48 float flAirAbsorptionGainHF
;
51 float flRoomRolloffFactor
;
53 } EFXEAXREVERBPROPERTIES
, *LPEFXEAXREVERBPROPERTIES
;
65 class AuxiliaryEffectSlot
;
72 // A SharedPtr implementation, defaults to C++11's std::shared_ptr. If this is
73 // changed, you must recompile the library.
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
)...);
92 return std::unique_ptr
<T
>(new T(std::forward
<Args
>(args
)...));
96 // A Vector implementation, defaults to C++'s std::vector. If this is changed,
97 // you must recompile the library.
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
{
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
;
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
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]); \
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]; \
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); \
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; \
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
220 constexpr inline ALCuint
MajorVersion(ALCuint version
)
221 { return version
>>16; }
223 * Retrieves the minor version of a version number value created by
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
{
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
{
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
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
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
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
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
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
,
367 class ALURE_API Context
{
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
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
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
484 virtual void update() = 0;
487 class ALURE_API Listener
{
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
{
511 ALURE_API
const char *GetSampleTypeName(SampleType type
);
513 enum class ChannelConfig
{
514 /** 1-channel mono sound. */
516 /** 2-channel stereo sound. */
518 /** 2-channel rear sound (back-left and back-right). */
520 /** 4-channel surround sound. */
522 /** 5.1 surround sound. */
524 /** 6.1 surround sound. */
526 /** 7.1 surround sound. */
528 /** 3-channel B-Format, using FuMa channel ordering and scaling. */
530 /** 4-channel B-Format, using FuMa channel ordering and scaling. */
533 ALURE_API
const char *GetChannelConfigName(ChannelConfig cfg
);
535 enum class BufferLoadStatus
{
540 class ALURE_API Buffer
{
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
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
{
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
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
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
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
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
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
{
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
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
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
912 virtual void release() = 0;
921 class ALURE_API AuxiliaryEffectSlot
{
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
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
{
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
{
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
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
{
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
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
1052 * \param name The unique name identifying a previously-registered decoder
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
1066 class ALURE_API FileIOFactory
{
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
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
1097 class ALURE_API MessageHandler
{
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
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
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 */