Add a basic message handler interface
[alure.git] / include / AL / alure2.h
blobf1af98cbebac12cbde36906521676da92c2faef2
1 #ifndef AL_ALURE2_H
2 #define AL_ALURE2_H
4 #include <vector>
5 #include <string>
6 #include <memory>
7 #include <cmath>
9 #include "alc.h"
10 #include "al.h"
12 #ifndef EFXEAXREVERBPROPERTIES_DEFINED
13 #define EFXEAXREVERBPROPERTIES_DEFINED
14 typedef struct {
15 float flDensity;
16 float flDiffusion;
17 float flGain;
18 float flGainHF;
19 float flGainLF;
20 float flDecayTime;
21 float flDecayHFRatio;
22 float flDecayLFRatio;
23 float flReflectionsGain;
24 float flReflectionsDelay;
25 float flReflectionsPan[3];
26 float flLateReverbGain;
27 float flLateReverbDelay;
28 float flLateReverbPan[3];
29 float flEchoTime;
30 float flEchoDepth;
31 float flModulationTime;
32 float flModulationDepth;
33 float flAirAbsorptionGainHF;
34 float flHFReference;
35 float flLFReference;
36 float flRoomRolloffFactor;
37 int iDecayHFLimit;
38 } EFXEAXREVERBPROPERTIES, *LPEFXEAXREVERBPROPERTIES;
39 #endif
41 namespace alure {
43 class DeviceManager;
44 class Device;
45 class Context;
46 class Listener;
47 class Buffer;
48 class Source;
49 class AuxiliaryEffectSlot;
50 class Effect;
51 class Decoder;
52 class DecoderFactory;
53 class MessageHandler;
56 // A SharedPtr implementation, defaults to C++11's std::shared_ptr. If this is
57 // changed, you must recompile the library.
58 template<typename T>
59 using SharedPtr = std::shared_ptr<T>;
62 struct FilterParams {
63 ALfloat mGain;
64 ALfloat mGainHF; // For low-pass and band-pass filters
65 ALfloat mGainLF; // For high-pass and band-pass filters
69 class Vector3 {
70 ALfloat mValue[3];
72 public:
73 Vector3() { }
74 Vector3(const Vector3 &rhs) : mValue{rhs.mValue[0], rhs.mValue[1], rhs.mValue[2]}
75 { }
76 Vector3(ALfloat val) : mValue{val, val, val}
77 { }
78 Vector3(ALfloat x, ALfloat y, ALfloat z) : mValue{x, y, z}
79 { }
80 Vector3(const ALfloat *vec) : mValue{vec[0], vec[1], vec[2]}
81 { }
83 const ALfloat *getPtr() const
84 { return mValue; }
86 ALfloat& operator[](size_t i)
87 { return mValue[i]; }
88 const ALfloat& operator[](size_t i) const
89 { return mValue[i]; }
91 #define ALURE_DECL_OP(op) \
92 Vector3 operator op(const Vector3 &rhs) const \
93 { \
94 return Vector3(mValue[0] op rhs.mValue[0], \
95 mValue[1] op rhs.mValue[1], \
96 mValue[2] op rhs.mValue[2]); \
98 ALURE_DECL_OP(+)
99 ALURE_DECL_OP(-)
100 ALURE_DECL_OP(*)
101 ALURE_DECL_OP(/)
102 #undef ALURE_DECL_OP
103 #define ALURE_DECL_OP(op) \
104 Vector3& operator op(const Vector3 &rhs) \
106 mValue[0] op rhs.mValue[0]; \
107 mValue[1] op rhs.mValue[1]; \
108 mValue[2] op rhs.mValue[2]; \
109 return *this; \
111 ALURE_DECL_OP(+=)
112 ALURE_DECL_OP(-=)
113 ALURE_DECL_OP(*=)
114 ALURE_DECL_OP(/=)
115 #undef ALURE_DECL_OP
116 #define ALURE_DECL_OP(op) \
117 Vector3 operator op(ALfloat scale) const \
119 return Vector3(mValue[0] op scale, \
120 mValue[1] op scale, \
121 mValue[2] op scale); \
123 ALURE_DECL_OP(*)
124 ALURE_DECL_OP(/)
125 #undef ALURE_DECL_OP
126 #define ALURE_DECL_OP(op) \
127 Vector3& operator op(ALfloat scale) \
129 mValue[0] op scale; \
130 mValue[1] op scale; \
131 mValue[2] op scale; \
132 return *this; \
134 ALURE_DECL_OP(*=)
135 ALURE_DECL_OP(/=)
136 #undef ALURE_DECL_OP
138 ALfloat getLengthSquared() const
139 { return mValue[0]*mValue[0] + mValue[1]*mValue[1] + mValue[2]*mValue[2]; }
140 ALfloat getLength() const
141 { return sqrtf(getLengthSquared()); }
143 ALfloat getDistanceSquared(const Vector3 &pos) const
144 { return (pos - *this).getLengthSquared(); }
145 ALfloat getDistance(const Vector3 &pos) const
146 { return (pos - *this).getLength(); }
148 static_assert(sizeof(Vector3) == sizeof(ALfloat[3]), "Bad Vector3 size");
152 * Creates a version number value using the specified \param major and
153 * \param minor values.
155 inline ALCuint MakeVersion(ALCushort major, ALCushort minor)
156 { return (major<<16) | minor; }
159 * Retrieves the major version of a version number value created by
160 * \ref MakeVersion.
162 inline ALCuint MajorVersion(ALCuint version)
163 { return version>>16; }
165 * Retrieves the minor version of a version number value created by
166 * \ref MakeVersion.
168 inline ALCuint MinorVersion(ALCuint version)
169 { return version&0xffff; }
172 enum DeviceEnumeration {
173 DevEnum_Basic = ALC_DEVICE_SPECIFIER,
174 DevEnum_Complete = ALC_ALL_DEVICES_SPECIFIER,
175 DevEnum_Capture = ALC_CAPTURE_DEVICE_SPECIFIER
178 enum DefaultDeviceType {
179 DefaultDevType_Basic = ALC_DEFAULT_DEVICE_SPECIFIER,
180 DefaultDevType_Complete = ALC_DEFAULT_ALL_DEVICES_SPECIFIER,
181 DefaultDevType_Capture = ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
185 * A class managing \ref Device objects and other related functionality. This
186 * class is a singleton, only one instance will exist in a process.
188 class DeviceManager {
189 public:
190 /** Retrieves the DeviceManager instance. */
191 static DeviceManager *get();
193 /** Queries the existence of a non-device-specific ALC extension. */
194 virtual bool queryExtension(const char *extname) = 0;
196 /** Enumerates available device names of the given \param type. */
197 virtual std::vector<std::string> enumerate(DeviceEnumeration type) = 0;
198 /** Retrieves the default device of the given \param type. */
199 virtual std::string defaultDeviceName(DefaultDeviceType type) = 0;
201 /** Opens the playback device given by \param name, or the default if empty. */
202 virtual Device *openPlayback(const std::string &name=std::string()) = 0;
206 enum PlaybackDeviceType {
207 PlaybackDevType_Basic = ALC_DEVICE_SPECIFIER,
208 PlaybackDevType_Complete = ALC_ALL_DEVICES_SPECIFIER
211 class Device {
212 public:
213 /** Retrieves the device name as given by \param type. */
214 virtual std::string getName(PlaybackDeviceType type) = 0;
215 /** Queries the existence of an ALC extension on this device. */
216 virtual bool queryExtension(const char *extname) = 0;
219 * Retrieves the ALC version supported by this device, as constructed by
220 * \ref MakeVersion.
222 virtual ALCuint getALCVersion() = 0;
225 * Retrieves the EFX version supported by this device, as constructed by
226 * \ref MakeVersion. If the ALC_EXT_EFX extension is unsupported, this
227 * will be 0.
229 virtual ALCuint getEFXVersion() = 0;
231 /** Retrieves the device's playback frequency, in hz. */
232 virtual ALCuint getFrequency() = 0;
235 * Retrieves the maximum number of auxiliary source sends. If ALC_EXT_EFX
236 * is unsupported, this will be 0.
238 virtual ALCuint getMaxAuxiliarySends() = 0;
241 * Creates a new \ref Context on this device, using the specified
242 * \param attributes.
244 virtual Context *createContext(ALCint *attributes=0) = 0;
247 * Closes and frees the device. All previously-created contexts must first
248 * be destroyed.
250 virtual void close() = 0;
254 enum DistanceModel {
255 DistanceModel_InverseClamped = AL_INVERSE_DISTANCE_CLAMPED,
256 DistanceModel_LinearClamped = AL_LINEAR_DISTANCE_CLAMPED,
257 DistanceModel_ExponentClamped = AL_EXPONENT_DISTANCE_CLAMPED,
258 DistanceModel_Inverse = AL_INVERSE_DISTANCE,
259 DistanceModel_Linear = AL_LINEAR_DISTANCE,
260 DistanceModel_Exponent = AL_EXPONENT_DISTANCE,
261 DistanceModel_None = AL_NONE,
264 class Context {
265 public:
266 /** Makes the specified \param context current for OpenAL operations. */
267 static void MakeCurrent(Context *context);
268 /** Retrieves the current context used for OpenAL operations. */
269 static Context *GetCurrent();
272 * Makes the specified \param context current for OpenAL operations on the
273 * calling thread only. Requires the ALC_EXT_thread_local_context extension.
275 static void MakeThreadCurrent(Context *context);
277 * Retrieves the thread-specific context used for OpenAL operations.
278 * Requires the ALC_EXT_thread_local_context extension.
280 static Context *GetThreadCurrent();
283 * Destroys the context. The context must not be current when this is
284 * called.
286 virtual void destroy() = 0;
288 /** Retrieves the \ref Device this context was created from. */
289 virtual Device *getDevice() = 0;
291 virtual void startBatch() = 0;
292 virtual void endBatch() = 0;
295 * Retrieves a \ref Listener instance for this context. Each context will
296 * only have one listener.
298 virtual Listener *getListener() = 0;
301 * Sets a MessageHandler instance which will be used to provide certain
302 * messages back to the application. Only one handler may be set for a
303 * context at a time. The previously set handler will be returned.
305 virtual SharedPtr<MessageHandler> setMessageHandler(SharedPtr<MessageHandler> handler) = 0;
307 /** Gets the currently-set message handler. */
308 virtual SharedPtr<MessageHandler> getMessageHandler() const = 0;
310 // Functions below require the context to be current
313 * Creates a \ref Decoder instance for the given audio file or resource
314 * \param name. The caller is responsible for deleting the returned object.
316 virtual SharedPtr<Decoder> createDecoder(const std::string &name) = 0;
319 * Creates and caches a \ref Buffer for the given audio file or resource
320 * \param name. Multiple calls with the same name will return the same
321 * \ref Buffer object.
323 virtual Buffer *getBuffer(const std::string &name) = 0;
326 * Deletes the cached \ref Buffer object for the given audio file or
327 * resource \param name. The buffer must not be in use by a \ref Source.
329 virtual void removeBuffer(const std::string &name) = 0;
331 * Deletes the given cached \param buffer instance. The buffer must not be
332 * in use by a \ref Source.
334 virtual void removeBuffer(Buffer *buffer) = 0;
337 * Gets a new \ref Source. There is no practical limit to the number of
338 * sources you may get.
340 virtual Source *getSource() = 0;
342 virtual AuxiliaryEffectSlot *createAuxiliaryEffectSlot() = 0;
344 virtual Effect *createEffect() = 0;
346 virtual void setDopplerFactor(ALfloat factor) = 0;
348 virtual void setSpeedOfSound(ALfloat speed) = 0;
350 virtual void setDistanceModel(DistanceModel model) = 0;
353 * Updates the context and all sources belonging to this context (you do
354 * not need to call the individual sources' update method if you call this
355 * function).
357 virtual void update() = 0;
361 enum SampleType {
362 SampleType_UInt8,
363 SampleType_Int16,
364 SampleType_Float32,
365 SampleType_Mulaw
367 const char *GetSampleTypeName(SampleType type);
369 enum SampleConfig {
370 SampleConfig_Mono,
371 SampleConfig_Stereo,
372 SampleConfig_Rear,
373 SampleConfig_Quad,
374 SampleConfig_X51,
375 SampleConfig_X61,
376 SampleConfig_X71,
377 SampleConfig_BFmt_WXY,
378 SampleConfig_BFmt_WXYZ
380 const char *GetSampleConfigName(SampleConfig cfg);
383 class Listener {
384 public:
385 virtual void setGain(ALfloat gain) = 0;
387 virtual void setPosition(ALfloat x, ALfloat y, ALfloat z) = 0;
388 virtual void setPosition(const ALfloat *pos) = 0;
390 virtual void setVelocity(ALfloat x, ALfloat y, ALfloat z) = 0;
391 virtual void setVelocity(const ALfloat *vel) = 0;
393 virtual void setOrientation(ALfloat x1, ALfloat y1, ALfloat z1, ALfloat x2, ALfloat y2, ALfloat z2) = 0;
394 virtual void setOrientation(const ALfloat *at, const ALfloat *up) = 0;
395 virtual void setOrientation(const ALfloat *ori) = 0;
399 class Buffer {
400 public:
401 /** Retrieves the length of the buffer in sample frames. */
402 virtual ALuint getLength() const = 0;
404 /** Retrieves the buffer's frequency in hz. */
405 virtual ALuint getFrequency() const = 0;
407 /** Retrieves the buffer's sample configuration. */
408 virtual SampleConfig getSampleConfig() const = 0;
410 /** Retrieves the buffer's sample type. */
411 virtual SampleType getSampleType() const = 0;
413 /** Retrieves the storage size used by the buffer, in bytes. */
414 virtual ALuint getSize() const = 0;
416 /** Queries if the buffer is not in use and can be removed. */
417 virtual bool isRemovable() const = 0;
421 class Source {
422 public:
424 * Plays the source using \param buffer. The same buffer may be played from
425 * multiple sources simultaneously.
427 virtual void play(Buffer *buffer) = 0;
429 * Plays the source by streaming audio from \param decoder. This will use
430 * \param queuelen buffers, each with \param updatelen sample frames. The
431 * given decoder must *NOT* have its read or seek methods called from
432 * elsewhere while in use.
434 virtual void play(SharedPtr<Decoder> decoder, ALuint updatelen, ALuint queuesize) = 0;
436 * Stops playback, releasing the buffer or decoder reference.
438 virtual void stop() = 0;
440 /** Pauses the source if it is playing. */
441 virtual void pause() = 0;
443 /** Resumes the source if it is paused. */
444 virtual void resume() = 0;
446 /** Specifies if the source is currently playing. */
447 virtual bool isPlaying() const = 0;
449 /** Specifies if the source is currently paused. */
450 virtual bool isPaused() const = 0;
453 * Specifies the source's playback priority. Lowest priority sources will
454 * be evicted first when higher priority sources are played.
456 virtual void setPriority(ALuint priority) = 0;
457 /** Retrieves the source's priority. */
458 virtual ALuint getPriority() const = 0;
461 * Sets the source's offset, in sample frames. If the source is playing or
462 * paused, it will go to that offset immediately, otherwise the source will
463 * start at the specified offset the next time it's played.
465 virtual void setOffset(uint64_t offset) = 0;
467 * Retrieves the source offset in sample frames. For streaming sources,
468 * this will be the offset from the beginning of the stream based on the
469 * decoder's reported position.
471 * \param latency If non-NULL and the device supports it, the source's
472 * latency, in nanoseconds, will be written to that location.
474 virtual uint64_t getOffset(uint64_t *latency=0) const = 0;
476 virtual void setLooping(bool looping) = 0;
477 virtual bool getLooping() const = 0;
479 virtual void setPitch(ALfloat pitch) = 0;
480 virtual ALfloat getPitch() const = 0;
482 virtual void setGain(ALfloat gain) = 0;
483 virtual ALfloat getGain() const = 0;
485 virtual void setGainRange(ALfloat mingain, ALfloat maxgain) = 0;
486 virtual ALfloat getMinGain() const = 0;
487 virtual ALfloat getMaxGain() const = 0;
489 virtual void setDistanceRange(ALfloat refdist, ALfloat maxdist) = 0;
490 virtual ALfloat getReferenceDistance() const = 0;
491 virtual ALfloat getMaxDistance() const = 0;
493 virtual void setPosition(ALfloat x, ALfloat y, ALfloat z) = 0;
494 virtual void setPosition(const ALfloat *pos) = 0;
495 virtual Vector3 getPosition() const = 0;
497 virtual void setVelocity(ALfloat x, ALfloat y, ALfloat z) = 0;
498 virtual void setVelocity(const ALfloat *vel) = 0;
499 virtual Vector3 getVelocity() const = 0;
501 virtual void setDirection(ALfloat x, ALfloat y, ALfloat z) = 0;
502 virtual void setDirection(const ALfloat *dir) = 0;
503 virtual Vector3 getDirection() const = 0;
505 virtual void setOrientation(ALfloat x1, ALfloat y1, ALfloat z1, ALfloat x2, ALfloat y2, ALfloat z2) = 0;
506 virtual void setOrientation(const ALfloat *at, const ALfloat *up) = 0;
507 virtual void setOrientation(const ALfloat *ori) = 0;
509 virtual void setConeAngles(ALfloat inner, ALfloat outer) = 0;
510 virtual ALfloat getInnerConeAngle() const = 0;
511 virtual ALfloat getOuterConeAngle() const = 0;
513 virtual void setOuterConeGain(ALfloat gain) = 0;
514 virtual ALfloat getOuterConeGain() const = 0;
516 virtual void setRolloffFactor(ALfloat factor) = 0;
517 virtual ALfloat getRolloffFactor() const = 0;
519 virtual void setDopplerFactor(ALfloat factor) = 0;
520 virtual ALfloat getDopplerFactor() const = 0;
522 virtual void setRelative(bool relative) = 0;
523 virtual bool getRelative() const = 0;
525 virtual void setDirectFilter(const FilterParams &filter) = 0;
526 virtual void setSendFilter(ALuint send, const FilterParams &filter) = 0;
527 virtual void setAuxiliarySend(AuxiliaryEffectSlot *slot, ALuint send) = 0;
528 virtual void setAuxiliarySendFilter(AuxiliaryEffectSlot *slot, ALuint send, const FilterParams &filter) = 0;
531 * Updates the source, ensuring that streaming buffers are kept full and
532 * resources are released when playback is finished.
534 virtual void update() = 0;
537 * Releases the source, stopping playback, releasing resources, and
538 * returning it to the system.
540 virtual void release() = 0;
544 class AuxiliaryEffectSlot {
545 public:
546 virtual void setGain(ALfloat gain) = 0;
547 virtual void setSendAuto(bool sendauto) = 0;
549 virtual void applyEffect(const Effect *effect) = 0;
551 virtual void release() = 0;
553 virtual bool isInUse() const = 0;
557 class Effect {
558 public:
559 virtual void setReverbProperties(const EFXEAXREVERBPROPERTIES &props) = 0;
561 virtual void destroy() = 0;
566 * Audio decoder interface. Applications may derive from this, implementing the
567 * necessary methods, and use it in places the API wants a Decoder object.
569 class Decoder {
570 public:
571 virtual ~Decoder() { }
573 /** Retrieves the sample frequency, in hz, of the audio being decoded. */
574 virtual ALuint getFrequency() = 0;
575 /** Retrieves the channel configuration of the audio being decoded. */
576 virtual SampleConfig getSampleConfig() = 0;
577 /** Retrieves the sample type of the audio being decoded. */
578 virtual SampleType getSampleType() = 0;
581 * Retrieves the total length of the audio, in sample frames. If unknown,
582 * returns 0. Note that if the returned length is 0, the decoder may not be
583 * used to load a \ref Buffer.
585 virtual uint64_t getLength() = 0;
587 * Retrieves the current sample frame position (i.e. the number of sample
588 * frames from the beginning).
590 virtual uint64_t getPosition() = 0;
592 * Seek as close as possible to \param pos, specified in sample frames.
593 * Returns true if the seek was successful.
595 virtual bool seek(uint64_t pos) = 0;
598 * Decodes \param count sample frames, writing them to \param ptr, and
599 * returns the number of sample frames written. Returning less than the
600 * requested count indicates the end of the audio.
602 virtual ALuint read(ALvoid *ptr, ALuint count) = 0;
606 * Audio decoder factory interface. Applications may derive from this,
607 * implementing the necessary methods, and use it in places the API wants a
608 * DecoderFactory object.
610 class DecoderFactory {
611 public:
612 virtual ~DecoderFactory() { }
615 * Creates and returns a \ref Decoder instance for the given resource
616 * \param file. Returns NULL if a decoder can't be created from the file.
618 virtual SharedPtr<Decoder> createDecoder(SharedPtr<std::istream> file) = 0;
622 * Registers a decoder factory for decoding audio. Registered factories are
623 * used on a last-registered basis, e.g. if Factory1 is registered, then
624 * Factory2 is registered, Factory2 will be used before Factory1. Alure retains
625 * a reference to the DecoderFactory instance and will release it (potentially
626 * destroying the object) when the library unloads.
628 * \param name A unique name identifying this decoder factory.
629 * \param factory A DecoderFactory instance used to create Decoder instances.
631 void RegisterDecoder(const std::string &name, SharedPtr<DecoderFactory> factory);
634 * Unregisters a decoder factory by name. Alure gives a reference to the
635 * instance back to the application and releases its own.
637 * \param name The unique name identifying a previously-registered decoder
638 * factory.
640 * \return The unregistered decoder factory instance, or 0 (nullptr) if a
641 * decoder factory with the given name doesn't exist.
643 SharedPtr<DecoderFactory> UnregisterDecoder(const std::string &name);
647 * A file I/O factory interface. Applications may derive from this and set an
648 * instance to be used by the audio decoders. By default, the library uses
649 * standard I/O.
651 class FileIOFactory {
652 public:
654 * Sets the \param factory instance to be used by the audio decoders. If a
655 * previous factory was set, it's returned to the application. Passing in a
656 * NULL factory reverts to the default.
658 static SharedPtr<FileIOFactory> set(SharedPtr<FileIOFactory> factory);
661 * Gets the current FileIOFactory instance being used by the audio
662 * decoders.
664 static FileIOFactory &get();
666 virtual ~FileIOFactory() { }
668 /** Opens a read-only binary file for the given \param name. */
669 virtual SharedPtr<std::istream> openFile(const std::string &name) = 0;
674 * A message handler interface. Applications may derive from this and set an
675 * instance on a context to receive messages.
677 class MessageHandler {
678 public:
679 virtual ~MessageHandler() { }
682 } // namespace alure
684 #endif /* AL_ALURE2_H */