summaryrefslogtreecommitdiff
path: root/src/libs/sound/mixer/mixer.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/sound/mixer/mixer.h')
-rw-r--r--src/libs/sound/mixer/mixer.h274
1 files changed, 274 insertions, 0 deletions
diff --git a/src/libs/sound/mixer/mixer.h b/src/libs/sound/mixer/mixer.h
new file mode 100644
index 0000000..71e7878
--- /dev/null
+++ b/src/libs/sound/mixer/mixer.h
@@ -0,0 +1,274 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/* Mixer for low-level sound output drivers
+ */
+
+#ifndef LIBS_SOUND_MIXER_MIXER_H_
+#define LIBS_SOUND_MIXER_MIXER_H_
+
+#include "config.h"
+#include "types.h"
+#include "endian_uqm.h"
+
+/**
+ * The interface heavily influenced by OpenAL
+ * to the point where you should use OpenAL's
+ * documentation when programming the mixer.
+ * (some source properties are not supported)
+ *
+ * EXCEPTION: You may not queue the same buffer
+ * on more than one source
+ */
+
+#ifdef WORDS_BIGENDIAN
+# define MIX_IS_BIG_ENDIAN true
+# define MIX_WANT_BIG_ENDIAN true
+#else
+# define MIX_IS_BIG_ENDIAN false
+# define MIX_WANT_BIG_ENDIAN false
+#endif
+
+/**
+ * Mixer errors (see OpenAL errors)
+ */
+enum
+{
+ MIX_NO_ERROR = 0,
+ MIX_INVALID_NAME = 0xA001U,
+ MIX_INVALID_ENUM = 0xA002U,
+ MIX_INVALID_VALUE = 0xA003U,
+ MIX_INVALID_OPERATION = 0xA004U,
+ MIX_OUT_OF_MEMORY = 0xA005U,
+
+ MIX_DRIVER_FAILURE = 0xA101U
+};
+
+/**
+ * Source properties (see OpenAL)
+ */
+typedef enum
+{
+ MIX_POSITION = 0x1004,
+ MIX_LOOPING = 0x1007,
+ MIX_BUFFER = 0x1009,
+ MIX_GAIN = 0x100A,
+ MIX_SOURCE_STATE = 0x1010,
+
+ MIX_BUFFERS_QUEUED = 0x1015,
+ MIX_BUFFERS_PROCESSED = 0x1016
+
+} mixer_SourceProp;
+
+/**
+ * Source state information
+ */
+typedef enum
+{
+ MIX_INITIAL = 0,
+ MIX_STOPPED,
+ MIX_PLAYING,
+ MIX_PAUSED,
+
+} mixer_SourceState;
+
+/**
+ * Sound buffer properties
+ */
+typedef enum
+{
+ MIX_FREQUENCY = 0x2001,
+ MIX_BITS = 0x2002,
+ MIX_CHANNELS = 0x2003,
+ MIX_SIZE = 0x2004,
+ MIX_DATA = 0x2005
+
+} mixer_BufferProp;
+
+/**
+ * Buffer states: semi-private
+ */
+typedef enum
+{
+ MIX_BUF_INITIAL = 0,
+ MIX_BUF_FILLED,
+ MIX_BUF_QUEUED,
+ MIX_BUF_PLAYING,
+ MIX_BUF_PROCESSED
+
+} mixer_BufferState;
+
+/** Sound buffers: format specifier.
+ * bits 00..07: bytes per sample
+ * bits 08..15: channels
+ * bits 15..31: meaningless
+ */
+#define MIX_FORMAT_DUMMYID 0x00170000
+#define MIX_FORMAT_BPC(f) ((f) & 0xff)
+#define MIX_FORMAT_CHANS(f) (((f) >> 8) & 0xff)
+#define MIX_FORMAT_BPC_MAX 2
+#define MIX_FORMAT_CHANS_MAX 2
+#define MIX_FORMAT_MAKE(b, c) \
+ ( MIX_FORMAT_DUMMYID | ((b) & 0xff) | (((c) & 0xff) << 8) )
+
+#define MIX_FORMAT_SAMPSIZE(f) \
+ ( MIX_FORMAT_BPC(f) * MIX_FORMAT_CHANS(f) )
+
+typedef enum
+{
+ MIX_FORMAT_MONO8 = MIX_FORMAT_MAKE (1, 1),
+ MIX_FORMAT_STEREO8 = MIX_FORMAT_MAKE (1, 2),
+ MIX_FORMAT_MONO16 = MIX_FORMAT_MAKE (2, 1),
+ MIX_FORMAT_STEREO16 = MIX_FORMAT_MAKE (2, 2)
+
+} mixer_Format;
+
+typedef enum
+{
+ MIX_QUALITY_LOW = 0,
+ MIX_QUALITY_MEDIUM,
+ MIX_QUALITY_HIGH,
+ MIX_QUALITY_DEFAULT = MIX_QUALITY_MEDIUM,
+ MIX_QUALITY_COUNT
+
+} mixer_Quality;
+
+typedef enum
+{
+ MIX_NOFLAGS = 0,
+ MIX_FAKE_DATA = 1
+} mixer_Flags;
+
+/*************************************************
+ * Interface Types
+ */
+
+typedef intptr_t mixer_Object;
+typedef intptr_t mixer_IntVal;
+
+typedef struct _mixer_Source mixer_Source;
+
+typedef struct _mixer_Buffer
+{
+ uint32 magic;
+ bool locked;
+ mixer_BufferState state;
+ uint8 *data;
+ uint32 size;
+ uint32 sampsize;
+ uint32 high;
+ uint32 low;
+ float (* Resample) (mixer_Source *src, bool left);
+ /* original buffer values for OpenAL compat */
+ void* orgdata;
+ uint32 orgfreq;
+ uint32 orgsize;
+ uint32 orgchannels;
+ uint32 orgchansize;
+ /* next buffer in chain */
+ struct _mixer_Buffer *next;
+
+} mixer_Buffer;
+
+#define mixer_bufMagic 0x4258494DU /* MIXB in LSB */
+
+struct _mixer_Source
+{
+ uint32 magic;
+ bool locked;
+ mixer_SourceState state;
+ bool looping;
+ float gain;
+ uint32 cqueued;
+ uint32 cprocessed;
+ mixer_Buffer *firstqueued; /* first buf in the queue */
+ mixer_Buffer *nextqueued; /* next to play, or 0 */
+ mixer_Buffer *prevqueued; /* previously played */
+ mixer_Buffer *lastqueued; /* last in queue */
+ uint32 pos; /* position in current buffer */
+ uint32 count; /* fractional part of pos */
+
+ float samplecache;
+
+};
+
+#define mixer_srcMagic 0x5358494DU /* MIXS in LSB */
+
+/*************************************************
+ * General interface
+ */
+uint32 mixer_GetError (void);
+
+bool mixer_Init (uint32 frequency, uint32 format, mixer_Quality quality,
+ mixer_Flags flags);
+void mixer_Uninit (void);
+void mixer_MixChannels (void *userdata, uint8 *stream, sint32 len);
+void mixer_MixFake (void *userdata, uint8 *stream, sint32 len);
+
+/*************************************************
+ * Sources
+ */
+void mixer_GenSources (uint32 n, mixer_Object *psrcobj);
+void mixer_DeleteSources (uint32 n, mixer_Object *psrcobj);
+bool mixer_IsSource (mixer_Object srcobj);
+void mixer_Sourcei (mixer_Object srcobj, mixer_SourceProp pname,
+ mixer_IntVal value);
+void mixer_Sourcef (mixer_Object srcobj, mixer_SourceProp pname,
+ float value);
+void mixer_Sourcefv (mixer_Object srcobj, mixer_SourceProp pname,
+ float *value);
+void mixer_GetSourcei (mixer_Object srcobj, mixer_SourceProp pname,
+ mixer_IntVal *value);
+void mixer_GetSourcef (mixer_Object srcobj, mixer_SourceProp pname,
+ float *value);
+void mixer_SourceRewind (mixer_Object srcobj);
+void mixer_SourcePlay (mixer_Object srcobj);
+void mixer_SourcePause (mixer_Object srcobj);
+void mixer_SourceStop (mixer_Object srcobj);
+void mixer_SourceQueueBuffers (mixer_Object srcobj, uint32 n,
+ mixer_Object* pbufobj);
+void mixer_SourceUnqueueBuffers (mixer_Object srcobj, uint32 n,
+ mixer_Object* pbufobj);
+
+/*************************************************
+ * Buffers
+ */
+void mixer_GenBuffers (uint32 n, mixer_Object *pbufobj);
+void mixer_DeleteBuffers (uint32 n, mixer_Object *pbufobj);
+bool mixer_IsBuffer (mixer_Object bufobj);
+void mixer_GetBufferi (mixer_Object bufobj, mixer_BufferProp pname,
+ mixer_IntVal *value);
+void mixer_BufferData (mixer_Object bufobj, uint32 format, void* data,
+ uint32 size, uint32 freq);
+
+
+/* Make sure the prop-value type is of suitable size
+ * it must be able to store both int and void*
+ * Adapted from SDL
+ * This will generate "negative subscript or subscript is too large"
+ * error during compile, if the actual size of a type is wrong
+ */
+#define MIX_COMPILE_TIME_ASSERT(name, x) \
+ typedef int mixer_dummy_##name [(x) * 2 - 1]
+
+MIX_COMPILE_TIME_ASSERT (mixer_Object,
+ sizeof(mixer_Object) >= sizeof(void*));
+MIX_COMPILE_TIME_ASSERT (mixer_IntVal,
+ sizeof(mixer_IntVal) >= sizeof(mixer_Object));
+
+#undef MIX_COMPILE_TIME_ASSERT
+
+#endif /* LIBS_SOUND_MIXER_MIXER_H_ */