16 #if defined(ALURE_BUILD_STATIC) || defined(ALURE_STATIC_LIB)
18 #elif defined(ALURE_BUILD_DLL)
19 #define ALURE_API __declspec(dllexport)
21 #define ALURE_API __declspec(dllimport)
29 #ifndef EFXEAXREVERBPROPERTIES_DEFINED
30 #define EFXEAXREVERBPROPERTIES_DEFINED
40 float flReflectionsGain
;
41 float flReflectionsDelay
;
42 float flReflectionsPan
[3];
43 float flLateReverbGain
;
44 float flLateReverbDelay
;
45 float flLateReverbPan
[3];
48 float flModulationTime
;
49 float flModulationDepth
;
50 float flAirAbsorptionGainHF
;
53 float flRoomRolloffFactor
;
55 } EFXEAXREVERBPROPERTIES
, *LPEFXEAXREVERBPROPERTIES
;
73 class AuxiliaryEffectSlot
;
74 class ALAuxiliaryEffectSlot
;
82 // Duration in seconds, using double precision
83 using Seconds
= std::chrono::duration
<double>;
85 // A SharedPtr implementation, defaults to C++11's std::shared_ptr. If this is
86 // changed, you must recompile the library.
88 using SharedPtr
= std::shared_ptr
<T
>;
89 template<typename T
, typename
... Args
>
90 constexpr inline SharedPtr
<T
> MakeShared(Args
&&... args
)
92 return std::make_shared
<T
>(std::forward
<Args
>(args
)...);
95 // A UniquePtr implementation, defaults to C++11's std::unique_ptr. If this is
96 // changed, you must recompile the library.
97 template<typename T
, typename D
= std::default_delete
<T
>>
98 using UniquePtr
= std::unique_ptr
<T
, D
>;
99 template<typename T
, typename
... Args
>
100 constexpr inline UniquePtr
<T
> MakeUnique(Args
&&... args
)
102 #if __cplusplus >= 201402L
103 return std::make_unique
<T
>(std::forward
<Args
>(args
)...);
105 return std::unique_ptr
<T
>(new T(std::forward
<Args
>(args
)...));
109 // A Vector implementation, defaults to C++'s std::vector. If this is changed,
110 // you must recompile the library.
112 using Vector
= std::vector
<T
>;
114 // A String implementation, default's to C++'s std::string. If this is changed,
115 // you must recompile the library.
116 using String
= std::string
;
118 // A rather simple ArrayView container. This allows accepting various array
119 // types (std::array, Vector, a static-sized array, a dynamic array + size)
120 // without copying its elements.
128 typedef const T
*const_iterator
;
130 ArrayView() : mElems(nullptr), mNumElems(0) { }
131 ArrayView(const ArrayView
&rhs
) : mElems(rhs
.data()), mNumElems(rhs
.size()) { }
132 ArrayView(ArrayView
&& rhs
) : mElems(rhs
.data()), mNumElems(rhs
.size()) { }
133 ArrayView(T
*elems
, size_t num_elems
) : mElems(elems
), mNumElems(num_elems
) { }
135 ArrayView(T (&elems
)[N
]) : mElems(elems
), mNumElems(N
) { }
136 template<typename OtherT
>
137 ArrayView(OtherT
&arr
) : mElems(arr
.data()), mNumElems(arr
.size()) { }
139 ArrayView
& operator=(const ArrayView
&rhs
)
142 mNumElems
= rhs
.size();
144 ArrayView
& operator=(ArrayView
&& rhs
)
147 mNumElems
= rhs
.size();
150 ArrayView
& operator=(T (&elems
)[N
])
155 template<typename OtherT
>
156 ArrayView
& operator=(OtherT
&arr
)
159 mNumElems
= arr
.size();
163 const T
*data() const { return mElems
; }
164 T
*data() { return mElems
; }
166 size_t size() const { return mNumElems
; }
167 bool empty() const { return mNumElems
== 0; }
169 const T
& operator[](size_t i
) const { return mElems
[i
]; }
170 T
& operator[](size_t i
) { return mElems
[i
]; }
172 const T
& front() const { return mElems
[0]; }
173 T
& front() { return mElems
[0]; }
174 const T
& back() const { return mElems
[mNumElems
-1]; }
175 T
& back() { return mElems
[mNumElems
-1]; }
177 const T
& at(size_t i
) const
180 throw std::out_of_range("alure::ArrayView::at: element out of range");
186 throw std::out_of_range("alure::ArrayView::at: element out of range");
190 iterator
begin() { return mElems
; }
191 const_iterator
begin() const { return mElems
; }
192 const_iterator
cbegin() const { return mElems
; }
194 iterator
end() { return mElems
+ mNumElems
; }
195 const_iterator
end() const { return mElems
+ mNumElems
; }
196 const_iterator
cend() const { return mElems
+ mNumElems
; }
201 * An attribute pair, for passing attributes to Device::createContext and
204 using AttributePair
= std::pair
<ALCint
,ALCint
>;
205 static_assert(sizeof(AttributePair
) == sizeof(ALCint
[2]), "Bad AttributePair size");
208 struct FilterParams
{
210 ALfloat mGainHF
; // For low-pass and band-pass filters
211 ALfloat mGainLF
; // For high-pass and band-pass filters
215 class ALURE_API Vector3
{
216 std::array
<ALfloat
,3> mValue
;
219 constexpr Vector3() noexcept
220 : mValue
{{0.0f
, 0.0f
, 0.0f
}}
222 constexpr Vector3(const Vector3
&rhs
) noexcept
223 : mValue
{{rhs
.mValue
[0], rhs
.mValue
[1], rhs
.mValue
[2]}}
225 constexpr Vector3(ALfloat val
) noexcept
226 : mValue
{{val
, val
, val
}}
228 constexpr Vector3(ALfloat x
, ALfloat y
, ALfloat z
) noexcept
231 Vector3(const ALfloat
*vec
) noexcept
232 : mValue
{{vec
[0], vec
[1], vec
[2]}}
235 const ALfloat
*getPtr() const noexcept
236 { return mValue
.data(); }
238 ALfloat
& operator[](size_t i
) noexcept
239 { return mValue
[i
]; }
240 constexpr const ALfloat
& operator[](size_t i
) const noexcept
241 { return mValue
[i
]; }
243 #define ALURE_DECL_OP(op) \
244 constexpr Vector3 operator op(const Vector3 &rhs) const noexcept \
246 return Vector3(mValue[0] op rhs.mValue[0], \
247 mValue[1] op rhs.mValue[1], \
248 mValue[2] op rhs.mValue[2]); \
255 #define ALURE_DECL_OP(op) \
256 Vector3& operator op(const Vector3 &rhs) noexcept \
258 mValue[0] op rhs.mValue[0]; \
259 mValue[1] op rhs.mValue[1]; \
260 mValue[2] op rhs.mValue[2]; \
269 #define ALURE_DECL_OP(op) \
270 constexpr Vector3 operator op(ALfloat scale) const noexcept \
272 return Vector3(mValue[0] op scale, \
273 mValue[1] op scale, \
274 mValue[2] op scale); \
279 #define ALURE_DECL_OP(op) \
280 Vector3& operator op(ALfloat scale) noexcept \
282 mValue[0] op scale; \
283 mValue[1] op scale; \
284 mValue[2] op scale; \
291 constexpr ALfloat
getLengthSquared() const noexcept
292 { return mValue
[0]*mValue
[0] + mValue
[1]*mValue
[1] + mValue
[2]*mValue
[2]; }
293 ALfloat
getLength() const noexcept
294 { return std::sqrt(getLengthSquared()); }
296 constexpr ALfloat
getDistanceSquared(const Vector3
&pos
) const noexcept
297 { return (pos
- *this).getLengthSquared(); }
298 ALfloat
getDistance(const Vector3
&pos
) const noexcept
299 { return (pos
- *this).getLength(); }
301 static_assert(sizeof(Vector3
) == sizeof(ALfloat
[3]), "Bad Vector3 size");
304 enum class SampleType
{
310 ALURE_API
const char *GetSampleTypeName(SampleType type
);
312 enum class ChannelConfig
{
313 /** 1-channel mono sound. */
315 /** 2-channel stereo sound. */
317 /** 2-channel rear sound (back-left and back-right). */
319 /** 4-channel surround sound. */
321 /** 5.1 surround sound. */
323 /** 6.1 surround sound. */
325 /** 7.1 surround sound. */
327 /** 3-channel B-Format, using FuMa channel ordering and scaling. */
329 /** 4-channel B-Format, using FuMa channel ordering and scaling. */
332 ALURE_API
const char *GetChannelConfigName(ChannelConfig cfg
);
334 ALURE_API ALuint
FramesToBytes(ALuint frames
, ChannelConfig chans
, SampleType type
);
335 ALURE_API ALuint
BytesToFrames(ALuint bytes
, ChannelConfig chans
, SampleType type
);
339 * Creates a version number value using the specified major and minor values.
341 constexpr inline ALCuint
MakeVersion(ALCushort major
, ALCushort minor
)
342 { return (major
<<16) | minor
; }
345 * Retrieves the major version of a version number value created by
348 constexpr inline ALCuint
MajorVersion(ALCuint version
)
349 { return version
>>16; }
351 * Retrieves the minor version of a version number value created by
354 constexpr inline ALCuint
MinorVersion(ALCuint version
)
355 { return version
&0xffff; }
358 enum class DeviceEnumeration
{
359 Basic
= ALC_DEVICE_SPECIFIER
,
360 Complete
= ALC_ALL_DEVICES_SPECIFIER
,
361 Capture
= ALC_CAPTURE_DEVICE_SPECIFIER
364 enum class DefaultDeviceType
{
365 Basic
= ALC_DEFAULT_DEVICE_SPECIFIER
,
366 Complete
= ALC_DEFAULT_ALL_DEVICES_SPECIFIER
,
367 Capture
= ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
371 * A class managing Device objects and other related functionality. This class
372 * is a singleton, only one instance will exist in a process.
374 class ALURE_API DeviceManager
{
376 /** Retrieves the DeviceManager instance. */
377 static DeviceManager
&get();
379 /** Queries the existence of a non-device-specific ALC extension. */
380 virtual bool queryExtension(const String
&name
) const = 0;
382 /** Enumerates available device names of the given type. */
383 virtual Vector
<String
> enumerate(DeviceEnumeration type
) const = 0;
384 /** Retrieves the default device of the given type. */
385 virtual String
defaultDeviceName(DefaultDeviceType type
) const = 0;
388 * Opens the playback device given by name, or the default if blank. Throws
389 * an exception on error.
391 virtual Device
openPlayback(const String
&name
=String()) = 0;
394 * Opens the playback device given by name, or the default if blank.
395 * Returns an empty Device on error.
397 virtual Device
openPlayback(const String
&name
, const std::nothrow_t
&) = 0;
399 /** Opens the default playback device. Returns an empty Device on error. */
400 Device
openPlayback(const std::nothrow_t
&);
404 enum class PlaybackName
{
405 Basic
= ALC_DEVICE_SPECIFIER
,
406 Full
= ALC_ALL_DEVICES_SPECIFIER
409 #define MAKE_PIMPL(BaseT, ImplT) \
414 using handle_type = ImplT*; \
416 BaseT() : pImpl(nullptr) { } \
417 BaseT(ImplT *impl) : pImpl(impl) { } \
418 BaseT(const BaseT&) = default; \
419 BaseT(BaseT&& rhs) : pImpl(rhs.pImpl) { rhs.pImpl = nullptr; } \
421 BaseT& operator=(const BaseT&) = default; \
422 BaseT& operator=(BaseT&& rhs) \
424 pImpl = rhs.pImpl; rhs.pImpl = nullptr; \
428 bool operator==(const BaseT &rhs) const { return pImpl == rhs.pImpl; } \
429 bool operator==(BaseT&& rhs) const { return pImpl == rhs.pImpl; } \
431 operator bool() const { return !!pImpl; } \
433 handle_type getHandle() const { return pImpl; }
435 class ALURE_API Device
{
436 MAKE_PIMPL(Device
, ALDevice
)
439 /** Retrieves the device name as given by type. */
440 String
getName(PlaybackName type
=PlaybackName::Full
) const;
441 /** Queries the existence of an ALC extension on this device. */
442 bool queryExtension(const String
&name
) const;
445 * Retrieves the ALC version supported by this device, as constructed by
448 ALCuint
getALCVersion() const;
451 * Retrieves the EFX version supported by this device, as constructed by
452 * MakeVersion. If the ALC_EXT_EFX extension is unsupported, this will be
455 ALCuint
getEFXVersion() const;
457 /** Retrieves the device's playback frequency, in hz. */
458 ALCuint
getFrequency() const;
461 * Retrieves the maximum number of auxiliary source sends. If ALC_EXT_EFX
462 * is unsupported, this will be 0.
464 ALCuint
getMaxAuxiliarySends() const;
467 * Enumerates available HRTF names. The names are sorted as OpenAL gives
468 * them, such that the index of a given name is the ID to use with
471 * Requires the ALC_SOFT_HRTF extension.
473 Vector
<String
> enumerateHRTFNames() const;
476 * Retrieves whether HRTF is enabled on the device or not.
478 * Requires the ALC_SOFT_HRTF extension.
480 bool isHRTFEnabled() const;
483 * Retrieves the name of the HRTF currently being used by this device.
485 * Requires the ALC_SOFT_HRTF extension.
487 String
getCurrentHRTF() const;
490 * Resets the device, using the specified attributes.
492 * Requires the ALC_SOFT_HRTF extension.
494 void reset(ArrayView
<AttributePair
> attributes
);
497 * Creates a new Context on this device, using the specified attributes.
499 Context
createContext(ArrayView
<AttributePair
> attributes
=ArrayView
<AttributePair
>());
502 * Pauses device processing, stopping updates for its contexts. Multiple
503 * calls are allowed but it is not reference counted, so the device will
504 * resume after one resumeDSP call.
506 * Requires the ALC_SOFT_pause_device extension.
511 * Resumes device processing, restarting updates for its contexts. Multiple
512 * calls are allowed and will no-op.
517 * Closes and frees the device. All previously-created contexts must first
524 enum class DistanceModel
{
525 InverseClamped
= AL_INVERSE_DISTANCE_CLAMPED
,
526 LinearClamped
= AL_LINEAR_DISTANCE_CLAMPED
,
527 ExponentClamped
= AL_EXPONENT_DISTANCE_CLAMPED
,
528 Inverse
= AL_INVERSE_DISTANCE
,
529 Linear
= AL_LINEAR_DISTANCE
,
530 Exponent
= AL_EXPONENT_DISTANCE
,
534 class ALURE_API Context
{
535 MAKE_PIMPL(Context
, ALContext
)
538 /** Makes the specified context current for OpenAL operations. */
539 static void MakeCurrent(Context context
);
540 /** Retrieves the current context used for OpenAL operations. */
541 static Context
GetCurrent();
544 * Makes the specified context current for OpenAL operations on the calling
545 * thread only. Requires the ALC_EXT_thread_local_context extension on both
546 * the context's device and the DeviceManager.
548 static void MakeThreadCurrent(Context context
);
549 /** Retrieves the thread-specific context used for OpenAL operations. */
550 static Context
GetThreadCurrent();
553 * Destroys the context. The context must not be current when this is
558 /** Retrieves the Device this context was created from. */
565 * Retrieves a Listener instance for this context. Each context will only
568 Listener
getListener();
571 * Sets a MessageHandler instance which will be used to provide certain
572 * messages back to the application. Only one handler may be set for a
573 * context at a time. The previously set handler will be returned.
575 SharedPtr
<MessageHandler
> setMessageHandler(SharedPtr
<MessageHandler
> handler
);
577 /** Gets the currently-set message handler. */
578 SharedPtr
<MessageHandler
> getMessageHandler() const;
581 * Specifies the desired interval that the background thread will be woken
582 * up to process tasks, e.g. keeping streaming sources filled. An interval
583 * of 0 means the background thread will only be woken up manually with
584 * calls to update. The default is 0.
586 void setAsyncWakeInterval(std::chrono::milliseconds msec
);
589 * Retrieves the current interval used for waking up the background thread.
591 std::chrono::milliseconds
getAsyncWakeInterval() const;
593 // Functions below require the context to be current
596 * Creates a Decoder instance for the given audio file or resource name.
598 SharedPtr
<Decoder
> createDecoder(const String
&name
);
601 * Queries if the channel configuration and sample type are supported by
604 bool isSupported(ChannelConfig channels
, SampleType type
) const;
607 * Queries the list of resamplers supported by the context. If the
608 * AL_SOFT_source_resampler extension is unsupported this will be an empty
609 * vector, otherwise there will be at least one entry.
611 const Vector
<String
> &getAvailableResamplers();
613 * Queries the context's default resampler index. Be aware, if the
614 * AL_SOFT_source_resampler extension is unsupported the resampler list
615 * will be empty and this will resturn 0. If you try to access the
616 * resampler list with this index without the extension, undefined behavior
617 * (accessing an out of bounds array index) will occur.
619 ALsizei
getDefaultResamplerIndex() const;
622 * Creates and caches a Buffer for the given audio file or resource name.
623 * Multiple calls with the same name will return the same Buffer object.
625 Buffer
getBuffer(const String
&name
);
628 * Creates and caches a Buffer for the given audio file or resource name.
629 * Multiple calls with the same name will return the same Buffer object.
631 * The returned Buffer object will be scheduled for loading asynchronously,
632 * and must be checked with a call to Buffer::getLoadStatus prior to being
635 Buffer
getBufferAsync(const String
&name
);
638 * Creates and caches a Buffer using the given name. The name may alias an
639 * audio file, but it must not currently exist in the buffer cache. As with
640 * other cached buffers, removeBuffer must be used to remove it from the
643 Buffer
createBufferFrom(const String
&name
, SharedPtr
<Decoder
> decoder
);
646 * Creates and caches a Buffer using the given name. The name may alias an
647 * audio file, but it must not currently exist in the buffer cache.
649 * The returned Buffer object will be scheduled for loading asynchronously,
650 * and must be checked with a call to Buffer::getLoadStatus prior to being
651 * played. The given decoder will be held on to and used asynchronously to
652 * load the buffer. The decoder must not have its read or seek methods
653 * called while the buffer load status is pending.
655 Buffer
createBufferAsyncFrom(const String
&name
, SharedPtr
<Decoder
> decoder
);
658 * Deletes the cached Buffer object for the given audio file or
659 * resource name. The buffer must not be in use by a Source.
661 void removeBuffer(const String
&name
);
663 * Deletes the given cached buffer. The buffer must not be in use by a
666 void removeBuffer(Buffer buffer
);
669 * Creates a new Source. There is no practical limit to the number of
670 * sources you may create.
672 Source
createSource();
674 AuxiliaryEffectSlot
createAuxiliaryEffectSlot();
676 Effect
createEffect();
678 SourceGroup
createSourceGroup(String name
);
679 SourceGroup
getSourceGroup(const String
&name
);
681 void setDopplerFactor(ALfloat factor
);
683 void setSpeedOfSound(ALfloat speed
);
685 void setDistanceModel(DistanceModel model
);
688 * Updates the context and all sources belonging to this context (you do
689 * not need to call the individual sources' update method if you call this
695 class ALURE_API Listener
{
696 MAKE_PIMPL(Listener
, ALListener
)
699 void setGain(ALfloat gain
);
701 void set3DParameters(const Vector3
&position
, const Vector3
&velocity
, std::pair
<Vector3
,Vector3
> orientation
);
703 void setPosition(ALfloat x
, ALfloat y
, ALfloat z
);
704 void setPosition(const ALfloat
*pos
);
706 void setVelocity(ALfloat x
, ALfloat y
, ALfloat z
);
707 void setVelocity(const ALfloat
*vel
);
709 void setOrientation(ALfloat x1
, ALfloat y1
, ALfloat z1
, ALfloat x2
, ALfloat y2
, ALfloat z2
);
710 void setOrientation(const ALfloat
*at
, const ALfloat
*up
);
711 void setOrientation(const ALfloat
*ori
);
713 void setMetersPerUnit(ALfloat m_u
);
717 enum class BufferLoadStatus
{
722 class ALURE_API Buffer
{
723 MAKE_PIMPL(Buffer
, ALBuffer
)
727 * Retrieves the length of the buffer in sample frames. The buffer must be
728 * fully loaded before this method is called.
730 ALuint
getLength() const;
732 /** Retrieves the buffer's frequency in hz. */
733 ALuint
getFrequency() const;
735 /** Retrieves the buffer's sample configuration. */
736 ChannelConfig
getChannelConfig() const;
738 /** Retrieves the buffer's sample type. */
739 SampleType
getSampleType() const;
742 * Retrieves the storage size used by the buffer, in bytes. The buffer must
743 * be fully loaded before this method is called.
745 ALuint
getSize() const;
748 * Sets the buffer's loop points, used for looping sources. If the current
749 * context does not support the AL_SOFT_loop_points extension, start and
750 * end must be 0 and getLength() respectively. Otherwise, start must be
751 * less than end, and end must be less than or equal to getLength().
753 * The buffer must not be in use when this method is called, and the buffer
754 * must be fully loaded.
756 * \param start The starting point, in sample frames (inclusive).
757 * \param end The ending point, in sample frames (exclusive).
759 void setLoopPoints(ALuint start
, ALuint end
);
762 * Retrieves the current loop points as a [start,end) pair. The buffer must
763 * be fully loaded before this method is called.
765 std::pair
<ALuint
,ALuint
> getLoopPoints() const;
768 * Retrieves the Source objects currently playing the buffer. Stopping the
769 * returned sources will allow the buffer to be removed from the context.
771 Vector
<Source
> getSources() const;
774 * Queries the buffer's load status. A return of BufferLoadStatus::Pending
775 * indicates the buffer is not finished loading and can't be used with a
776 * call to Source::play. Buffers created with Context::getBuffer will
777 * always return BufferLoadStatus::Ready.
779 BufferLoadStatus
getLoadStatus();
781 /** Retrieves the name the buffer was created with. */
782 const String
&getName() const;
784 /** Queries if the buffer is in use and can't be removed. */
785 bool isInUse() const;
789 enum class Spatialize
{
792 Auto
= 0x0002 /* AL_AUTO_SOFT */
795 class ALURE_API Source
{
796 MAKE_PIMPL(Source
, ALSource
)
800 * Plays the source using buffer. The same buffer may be played from
801 * multiple sources simultaneously.
803 void play(Buffer buffer
);
805 * Plays the source by streaming audio from decoder. This will use
806 * queuesize buffers, each with updatelen sample frames. The given decoder
807 * must *NOT* have its read or seek methods called from elsewhere while in
810 void play(SharedPtr
<Decoder
> decoder
, ALuint updatelen
, ALuint queuesize
);
812 * Stops playback, releasing the buffer or decoder reference.
816 /** Pauses the source if it is playing. */
819 /** Resumes the source if it is paused. */
822 /** Specifies if the source is currently playing. */
823 bool isPlaying() const;
825 /** Specifies if the source is currently paused. */
826 bool isPaused() const;
829 * Specifies the source's playback priority. Lowest priority sources will
830 * be evicted first when higher priority sources are played.
832 void setPriority(ALuint priority
);
833 /** Retrieves the source's priority. */
834 ALuint
getPriority() const;
837 * Sets the source's offset, in sample frames. If the source is playing or
838 * paused, it will go to that offset immediately, otherwise the source will
839 * start at the specified offset the next time it's played.
841 void setOffset(uint64_t offset
);
843 * Retrieves the source offset in sample frames and its latency in nano-
844 * seconds. For streaming sources, this will be the offset from the
845 * beginning of the stream based on the decoder's reported position.
847 * If the AL_SOFT_source_latency extension is unsupported, the latency will
850 std::pair
<uint64_t,std::chrono::nanoseconds
> getSampleOffsetLatency() const;
851 uint64_t getSampleOffset() const { return std::get
<0>(getSampleOffsetLatency()); }
853 * Retrieves the source offset and latency in seconds. For streaming
854 * sources, this will be the offset from the beginning of the stream based
855 * on the decoder's reported position.
857 * If the AL_SOFT_source_latency extension is unsupported, the latency will
860 std::pair
<Seconds
,Seconds
> getSecOffsetLatency() const;
861 Seconds
getSecOffset() const { return std::get
<0>(getSecOffsetLatency()); }
864 * Specifies if the source should loop on the Buffer or Decoder object's
867 void setLooping(bool looping
);
868 bool getLooping() const;
871 * Specifies a linear pitch shift base. A value of 1.0 is the default
874 void setPitch(ALfloat pitch
);
875 ALfloat
getPitch() const;
878 * Specifies the base linear gain. A value of 1.0 is the default normal
881 void setGain(ALfloat gain
);
882 ALfloat
getGain() const;
885 * Specifies the minimum and maximum gain. The source's gain is clamped to
886 * this range after distance attenuation and cone attenuation are applied
887 * to the gain base, although before the filter gain adjustements.
889 void setGainRange(ALfloat mingain
, ALfloat maxgain
);
890 std::pair
<ALfloat
,ALfloat
> getGainRange() const;
891 ALfloat
getMinGain() const { return std::get
<0>(getGainRange()); }
892 ALfloat
getMaxGain() const { return std::get
<1>(getGainRange()); }
895 * Specifies the reference distance and maximum distance the source will
896 * use for the current distance model. For Clamped distance models, the
897 * source's calculated distance is clamped to the specified range before
898 * applying distance-related attenuation.
900 * For all distance models, the reference distance is the distance at which
901 * the source's volume will not have any extra attenuation (an effective
902 * gain multiplier of 1).
904 void setDistanceRange(ALfloat refdist
, ALfloat maxdist
);
905 std::pair
<ALfloat
,ALfloat
> getDistanceRange() const;
906 ALfloat
getReferenceDistance() const { return std::get
<0>(getDistanceRange()); }
907 ALfloat
getMaxDistance() const { return std::get
<1>(getDistanceRange()); }
909 /** Specifies the source's 3D position, velocity, and direction together. */
910 void set3DParameters(const Vector3
&position
, const Vector3
&velocity
, const Vector3
&direction
);
912 /** Specifies the source's 3D position, velocity, and orientation together. */
913 void set3DParameters(const Vector3
&position
, const Vector3
&velocity
, std::pair
<Vector3
,Vector3
> orientation
);
915 /** Specifies the source's 3D position. */
916 void setPosition(ALfloat x
, ALfloat y
, ALfloat z
);
917 void setPosition(const ALfloat
*pos
);
918 Vector3
getPosition() const;
921 * Specifies the source's 3D velocity, in units per second. As with OpenAL,
922 * this does not actually alter the source's position, and instead just
923 * alters the pitch as determined by the doppler effect.
925 void setVelocity(ALfloat x
, ALfloat y
, ALfloat z
);
926 void setVelocity(const ALfloat
*vel
);
927 Vector3
getVelocity() const;
930 * Specifies the source's 3D facing direction. Deprecated in favor of
933 void setDirection(ALfloat x
, ALfloat y
, ALfloat z
);
934 void setDirection(const ALfloat
*dir
);
935 Vector3
getDirection() const;
938 * Specifies the source's 3D orientation. Note: unlike the AL_EXT_BFORMAT
939 * extension this property comes from, this also affects the facing
940 * direction, superceding setDirection.
942 void setOrientation(ALfloat x1
, ALfloat y1
, ALfloat z1
, ALfloat x2
, ALfloat y2
, ALfloat z2
);
943 void setOrientation(const ALfloat
*at
, const ALfloat
*up
);
944 void setOrientation(const ALfloat
*ori
);
945 std::pair
<Vector3
,Vector3
> getOrientation() const;
948 * Specifies the source's cone angles, in degrees. The inner angle is the
949 * area within which the listener will hear the source with no extra
950 * attenuation, while the listener being outside of the outer angle will
951 * hear the source attenuated according to the outer cone gains.
953 void setConeAngles(ALfloat inner
, ALfloat outer
);
954 std::pair
<ALfloat
,ALfloat
> getConeAngles() const;
955 ALfloat
getInnerConeAngle() const { return std::get
<0>(getConeAngles()); }
956 ALfloat
getOuterConeAngle() const { return std::get
<1>(getConeAngles()); }
959 * Specifies the linear gain multiplier when the listener is outside of the
960 * source's outer cone area. The specified gain applies to all frequencies,
961 * while gainhf applies extra attenuation to high frequencies.
963 * \param gainhf has no effect without the ALC_EXT_EFX extension.
965 void setOuterConeGains(ALfloat gain
, ALfloat gainhf
=1.0f
);
966 std::pair
<ALfloat
,ALfloat
> getOuterConeGains() const;
967 ALfloat
getOuterConeGain() const { return std::get
<0>(getOuterConeGains()); }
968 ALfloat
getOuterConeGainHF() const { return std::get
<1>(getOuterConeGains()); }
971 * Specifies the rolloff factors for the direct and send paths. This is
972 * effectively a distance scaling relative to the reference distance. Note:
973 * the room rolloff factor is 0 by default, disabling distance attenuation
974 * for send paths. This is because the reverb engine will, by default,
975 * apply a more realistic room attenuation based on the reverb decay time
976 * and direct path attenuation.
978 void setRolloffFactors(ALfloat factor
, ALfloat roomfactor
=0.0f
);
979 std::pair
<ALfloat
,ALfloat
> getRolloffFactors() const;
980 ALfloat
getRolloffFactor() const { return std::get
<0>(getRolloffFactors()); }
981 ALfloat
getRoomRolloffFactor() const { return std::get
<1>(getRolloffFactors()); }
984 * Specifies the doppler factor for the doppler effect's pitch shift. This
985 * effectively scales the source and listener velocities for the doppler
988 void setDopplerFactor(ALfloat factor
);
989 ALfloat
getDopplerFactor() const;
991 /** Specifies if the source properties are relative to the listener. */
992 void setRelative(bool relative
);
993 bool getRelative() const;
996 * Specifies the source's radius. This causes the source to behave as if
997 * every point within the spherical area emits sound.
999 * Has no effect without the AL_EXT_SOURCE_RADIUS extension.
1001 void setRadius(ALfloat radius
);
1002 ALfloat
getRadius() const;
1005 * Specifies the left and right channel angles, in radians, when playing a
1006 * stereo buffer or stream. The angles go counter-clockwise, with 0 being
1007 * in front and positive values going left.
1009 * Has no effect without the AL_EXT_STEREO_ANGLES extension.
1011 void setStereoAngles(ALfloat leftAngle
, ALfloat rightAngle
);
1012 std::pair
<ALfloat
,ALfloat
> getStereoAngles() const;
1014 void set3DSpatialize(Spatialize spatialize
);
1015 Spatialize
get3DSpatialize() const;
1017 void setResamplerIndex(ALsizei index
);
1018 ALsizei
getResamplerIndex() const;
1020 void setAirAbsorptionFactor(ALfloat factor
);
1021 ALfloat
getAirAbsorptionFactor() const;
1023 void setGainAuto(bool directhf
, bool send
, bool sendhf
);
1024 std::tuple
<bool,bool,bool> getGainAuto() const;
1025 bool getDirectGainHFAuto() const { return std::get
<0>(getGainAuto()); }
1026 bool getSendGainAuto() const { return std::get
<1>(getGainAuto()); }
1027 bool getSendGainHFAuto() const { return std::get
<2>(getGainAuto()); }
1029 /** Sets the filter properties on the direct path signal. */
1030 void setDirectFilter(const FilterParams
&filter
);
1032 * Sets the filter properties on the given send path signal. Any auxiliary
1033 * effect slot on the send path remains in place.
1035 void setSendFilter(ALuint send
, const FilterParams
&filter
);
1037 * Connects the effect slot slot to the given send path. Any filter
1038 * properties on the send path remain as they were.
1040 void setAuxiliarySend(AuxiliaryEffectSlot slot
, ALuint send
);
1042 * Connects the effect slot slot to the given send path, using the filter
1045 void setAuxiliarySendFilter(AuxiliaryEffectSlot slot
, ALuint send
, const FilterParams
&filter
);
1048 * Releases the source, stopping playback, releasing resources, and
1049 * returning it to the system.
1055 class ALURE_API SourceGroup
{
1056 MAKE_PIMPL(SourceGroup
, ALSourceGroup
)
1059 /** Retrieves the associated name of the source group. */
1060 const String
&getName() const;
1063 * Adds source to the source group. A source may only be part of one group
1064 * at a time, and will automatically be removed from its current group as
1067 void addSource(Source source
);
1068 /** Removes source from the source group. */
1069 void removeSource(Source source
);
1071 /** Adds a list of sources to the group at once. */
1072 void addSources(ArrayView
<Source
> sources
);
1073 /** Removes a list of sources from the source group. */
1074 void removeSources(ArrayView
<Source
> sources
);
1077 * Adds group as a subgroup of the source group. This method will throw an
1078 * exception if group is being added to a group it has as a sub-group (i.e.
1079 * it would create a circular sub-group chain).
1081 void addSubGroup(SourceGroup group
);
1082 /** Removes group from the source group. */
1083 void removeSubGroup(SourceGroup group
);
1085 /** Returns the list of sources currently in the group. */
1086 Vector
<Source
> getSources() const;
1088 /** Returns the list of subgroups currently in the group. */
1089 Vector
<SourceGroup
> getSubGroups() const;
1091 /** Sets the source group gain, which accumulates with its sources. */
1092 void setGain(ALfloat gain
);
1093 /** Gets the source group gain. */
1094 ALfloat
getGain() const;
1096 /** Sets the source group pitch, which accumulates with its sources. */
1097 void setPitch(ALfloat pitch
);
1098 /** Gets the source group pitch. */
1099 ALfloat
getPitch() const;
1102 * Pauses all currently-playing sources that are under this group,
1103 * including sub-groups.
1105 void pauseAll() const;
1107 * Resumes all paused sources that are under this group, including
1110 void resumeAll() const;
1112 /** Stops all sources that are under this group, including sub-groups. */
1113 void stopAll() const;
1116 * Releases the source group, removing all sources from it before being
1128 class ALURE_API AuxiliaryEffectSlot
{
1129 MAKE_PIMPL(AuxiliaryEffectSlot
, ALAuxiliaryEffectSlot
)
1132 void setGain(ALfloat gain
);
1134 * If set to true, the reverb effect will automatically apply adjustments
1135 * to the source's send slot based on the effect properties.
1137 * Has no effect when using non-reverb effects. Default is true.
1139 void setSendAuto(bool sendauto
);
1142 * Updates the effect slot with a new effect. The given effect object may
1143 * be altered or destroyed without affecting the effect slot.
1145 void applyEffect(Effect effect
);
1148 * Releases the effect slot, returning it to the system. It must not be in
1154 * Retrieves each Source object and its pairing send this effect slot is
1155 * set on. Setting a different (or null) effect slot on each source's given
1156 * send will allow the effect slot to be released.
1158 Vector
<SourceSend
> getSourceSends() const;
1160 /** Determines if the effect slot is in use by a source. */
1161 bool isInUse() const;
1165 class ALURE_API Effect
{
1166 MAKE_PIMPL(Effect
, ALEffect
)
1170 * Updates the effect with the specified reverb properties. If the
1171 * EAXReverb effect is not supported, it will automatically attempt to
1172 * downgrade to the Standard Reverb effect.
1174 void setReverbProperties(const EFXEAXREVERBPROPERTIES
&props
);
1181 * Audio decoder interface. Applications may derive from this, implementing the
1182 * necessary methods, and use it in places the API wants a Decoder object.
1184 class ALURE_API Decoder
{
1186 virtual ~Decoder() { }
1188 /** Retrieves the sample frequency, in hz, of the audio being decoded. */
1189 virtual ALuint
getFrequency() const = 0;
1190 /** Retrieves the channel configuration of the audio being decoded. */
1191 virtual ChannelConfig
getChannelConfig() const = 0;
1192 /** Retrieves the sample type of the audio being decoded. */
1193 virtual SampleType
getSampleType() const = 0;
1196 * Retrieves the total length of the audio, in sample frames. If unknown,
1197 * returns 0. Note that if the returned length is 0, the decoder may not be
1198 * used to load a Buffer.
1200 virtual uint64_t getLength() const = 0;
1202 * Retrieves the current sample frame position (i.e. the number of sample
1203 * frames from the beginning).
1205 virtual uint64_t getPosition() const = 0;
1207 * Seek to pos, specified in sample frames. Returns true if the seek was
1210 virtual bool seek(uint64_t pos
) = 0;
1213 * Retrieves the loop points, in sample frames, as a [start,end) pair. If
1214 * start >= end, use all available data.
1216 virtual std::pair
<uint64_t,uint64_t> getLoopPoints() const = 0;
1219 * Decodes count sample frames, writing them to ptr, and returns the number
1220 * of sample frames written. Returning less than the requested count
1221 * indicates the end of the audio.
1223 virtual ALuint
read(ALvoid
*ptr
, ALuint count
) = 0;
1227 * Audio decoder factory interface. Applications may derive from this,
1228 * implementing the necessary methods, and use it in places the API wants a
1229 * DecoderFactory object.
1231 class ALURE_API DecoderFactory
{
1233 virtual ~DecoderFactory() { }
1236 * Creates and returns a Decoder instance for the given resource file. If
1237 * the decoder needs to retain the file handle for reading as-needed, it
1238 * should move the UniquePtr to internal storage.
1240 * \return nullptr if a decoder can't be created from the file.
1242 virtual SharedPtr
<Decoder
> createDecoder(UniquePtr
<std::istream
> &file
) = 0;
1246 * Registers a decoder factory for decoding audio. Registered factories are
1247 * used in lexicographical order, e.g. if Factory1 is registered with name1 and
1248 * Factory2 is registered with name2, Factory1 will be used before Factory2 if
1249 * name1 < name2. Internal decoder factories are always used after registered
1252 * Alure retains a reference to the DecoderFactory instance and will release it
1253 * (potentially destroying the object) when the library unloads.
1255 * \param name A unique name identifying this decoder factory.
1256 * \param factory A DecoderFactory instance used to create Decoder instances.
1258 ALURE_API
void RegisterDecoder(const String
&name
, UniquePtr
<DecoderFactory
> factory
);
1261 * Unregisters a decoder factory by name. Alure returns the instance back to
1264 * \param name The unique name identifying a previously-registered decoder
1267 * \return The unregistered decoder factory instance, or 0 (nullptr) if a
1268 * decoder factory with the given name doesn't exist.
1270 ALURE_API UniquePtr
<DecoderFactory
> UnregisterDecoder(const String
&name
);
1274 * A file I/O factory interface. Applications may derive from this and set an
1275 * instance to be used by the audio decoders. By default, the library uses
1278 class ALURE_API FileIOFactory
{
1281 * Sets the factory instance to be used by the audio decoders. If a
1282 * previous factory was set, it's returned to the application. Passing in a
1283 * NULL factory reverts to the default.
1285 static UniquePtr
<FileIOFactory
> set(UniquePtr
<FileIOFactory
> factory
);
1288 * Gets the current FileIOFactory instance being used by the audio
1291 static FileIOFactory
&get();
1293 virtual ~FileIOFactory() { }
1295 /** Opens a read-only binary file for the given name. */
1296 virtual UniquePtr
<std::istream
> openFile(const String
&name
) = 0;
1301 * A message handler interface. Applications may derive from this and set an
1302 * instance on a context to receive messages. The base methods are no-ops, so
1303 * derived classes only need to implement methods for relevant messages.
1305 * It's recommended that applications mark their handler methods using the
1306 * override keyword, to ensure they're properly overriding the base methods in
1309 class ALURE_API MessageHandler
{
1311 virtual ~MessageHandler();
1314 * Called when the given device has been disconnected and is no longer
1315 * usable for output. As per the ALC_EXT_disconnect specification,
1316 * disconnected devices remain valid, however all playing sources are
1317 * automatically stopped, any sources that are attempted to play will
1318 * immediately stop, and new contexts may not be created on the device.
1320 * Note that connection status is checked during Context::update calls, so
1321 * that method must be called regularly to be notified when a device is
1322 * disconnected. This method may not be called if the device lacks support
1323 * for the ALC_EXT_disconnect extension.
1325 * WARNING: Do not attempt to clean up resources within this callback
1326 * method, as Alure is in the middle of doing updates. Instead, flag the
1327 * device as having been lost and do cleanup later.
1329 virtual void deviceDisconnected(Device device
);
1332 * Called when the given source reaches the end of the buffer or stream.
1334 * Sources that stopped automatically will be detected upon a call to
1335 * Context::update or Source::update.
1337 virtual void sourceStopped(Source source
);
1340 * Called when the given source was forced to stop. This can be because
1341 * either there were no more system sources and a higher-priority source
1342 * needs to play, or it's part of a SourceGroup (or sub-group thereof) that
1343 * had its SourceGroup::stopAll method called.
1345 virtual void sourceForceStopped(Source source
);
1348 * Called when a new buffer is about to be created and loaded. May be
1349 * called asynchronously for buffers being loaded asynchronously.
1351 * \param name The resource name, as passed to Context::getBuffer.
1352 * \param channels Channel configuration of the given audio data.
1353 * \param type Sample type of the given audio data.
1354 * \param samplerate Sample rate of the given audio data.
1355 * \param data The audio data that is about to be fed to the OpenAL buffer.
1357 virtual void bufferLoading(const String
&name
, ChannelConfig channels
, SampleType type
, ALuint samplerate
, const Vector
<ALbyte
> &data
);
1360 * Called when a resource isn't found, allowing the app to substitute in a
1361 * different resource. For buffers created with Context::getBuffer or
1362 * Context::getBufferAsync, the original name will still be used for the
1363 * cache map so the app doesn't have to keep track of substituted resource
1366 * This will be called again if the new name isn't found.
1368 * \param name The resource name that was not found.
1369 * \return The replacement resource name to use instead. Returning an empty
1370 * string means to stop trying.
1372 virtual String
resourceNotFound(const String
&name
);
1375 } // namespace alure
1377 #endif /* AL_ALURE2_H */