1 /* 2 * This program is free software; you can redistribute it and/or modify 3 * it under the terms of the GNU General Public License as published by 4 * the Free Software Foundation; either version 2 of the License, or 5 * (at your option) any later version. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU General Public License for more details. 11 * 12 * You should have received a copy of the GNU General Public License 13 * along with this program; if not, write to the Free Software 14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 15 */ 16 17 /* Mixer for low-level sound output drivers 18 */ 19 20 #ifndef LIBS_SOUND_MIXER_MIXER_H_ 21 #define LIBS_SOUND_MIXER_MIXER_H_ 22 23 #include "config.h" 24 #include "types.h" 25 #include "endian_uqm.h" 26 27 /** 28 * The interface heavily influenced by OpenAL 29 * to the point where you should use OpenAL's 30 * documentation when programming the mixer. 31 * (some source properties are not supported) 32 * 33 * EXCEPTION: You may not queue the same buffer 34 * on more than one source 35 */ 36 37 #ifdef WORDS_BIGENDIAN 38 # define MIX_IS_BIG_ENDIAN true 39 # define MIX_WANT_BIG_ENDIAN true 40 #else 41 # define MIX_IS_BIG_ENDIAN false 42 # define MIX_WANT_BIG_ENDIAN false 43 #endif 44 45 /** 46 * Mixer errors (see OpenAL errors) 47 */ 48 enum 49 { 50 MIX_NO_ERROR = 0, 51 MIX_INVALID_NAME = 0xA001U, 52 MIX_INVALID_ENUM = 0xA002U, 53 MIX_INVALID_VALUE = 0xA003U, 54 MIX_INVALID_OPERATION = 0xA004U, 55 MIX_OUT_OF_MEMORY = 0xA005U, 56 57 MIX_DRIVER_FAILURE = 0xA101U 58 }; 59 60 /** 61 * Source properties (see OpenAL) 62 */ 63 typedef enum 64 { 65 MIX_POSITION = 0x1004, 66 MIX_LOOPING = 0x1007, 67 MIX_BUFFER = 0x1009, 68 MIX_GAIN = 0x100A, 69 MIX_SOURCE_STATE = 0x1010, 70 71 MIX_BUFFERS_QUEUED = 0x1015, 72 MIX_BUFFERS_PROCESSED = 0x1016 73 74 } mixer_SourceProp; 75 76 /** 77 * Source state information 78 */ 79 typedef enum 80 { 81 MIX_INITIAL = 0, 82 MIX_STOPPED, 83 MIX_PLAYING, 84 MIX_PAUSED, 85 86 } mixer_SourceState; 87 88 /** 89 * Sound buffer properties 90 */ 91 typedef enum 92 { 93 MIX_FREQUENCY = 0x2001, 94 MIX_BITS = 0x2002, 95 MIX_CHANNELS = 0x2003, 96 MIX_SIZE = 0x2004, 97 MIX_DATA = 0x2005 98 99 } mixer_BufferProp; 100 101 /** 102 * Buffer states: semi-private 103 */ 104 typedef enum 105 { 106 MIX_BUF_INITIAL = 0, 107 MIX_BUF_FILLED, 108 MIX_BUF_QUEUED, 109 MIX_BUF_PLAYING, 110 MIX_BUF_PROCESSED 111 112 } mixer_BufferState; 113 114 /** Sound buffers: format specifier. 115 * bits 00..07: bytes per sample 116 * bits 08..15: channels 117 * bits 15..31: meaningless 118 */ 119 #define MIX_FORMAT_DUMMYID 0x00170000 120 #define MIX_FORMAT_BPC(f) ((f) & 0xff) 121 #define MIX_FORMAT_CHANS(f) (((f) >> 8) & 0xff) 122 #define MIX_FORMAT_BPC_MAX 2 123 #define MIX_FORMAT_CHANS_MAX 2 124 #define MIX_FORMAT_MAKE(b, c) \ 125 ( MIX_FORMAT_DUMMYID | ((b) & 0xff) | (((c) & 0xff) << 8) ) 126 127 #define MIX_FORMAT_SAMPSIZE(f) \ 128 ( MIX_FORMAT_BPC(f) * MIX_FORMAT_CHANS(f) ) 129 130 typedef enum 131 { 132 MIX_FORMAT_MONO8 = MIX_FORMAT_MAKE (1, 1), 133 MIX_FORMAT_STEREO8 = MIX_FORMAT_MAKE (1, 2), 134 MIX_FORMAT_MONO16 = MIX_FORMAT_MAKE (2, 1), 135 MIX_FORMAT_STEREO16 = MIX_FORMAT_MAKE (2, 2) 136 137 } mixer_Format; 138 139 typedef enum 140 { 141 MIX_QUALITY_LOW = 0, 142 MIX_QUALITY_MEDIUM, 143 MIX_QUALITY_HIGH, 144 MIX_QUALITY_DEFAULT = MIX_QUALITY_MEDIUM, 145 MIX_QUALITY_COUNT 146 147 } mixer_Quality; 148 149 typedef enum 150 { 151 MIX_NOFLAGS = 0, 152 MIX_FAKE_DATA = 1 153 } mixer_Flags; 154 155 /************************************************* 156 * Interface Types 157 */ 158 159 typedef intptr_t mixer_Object; 160 typedef intptr_t mixer_IntVal; 161 162 typedef struct _mixer_Source mixer_Source; 163 164 typedef struct _mixer_Buffer 165 { 166 uint32 magic; 167 bool locked; 168 mixer_BufferState state; 169 uint8 *data; 170 uint32 size; 171 uint32 sampsize; 172 uint32 high; 173 uint32 low; 174 float (* Resample) (mixer_Source *src, bool left); 175 /* original buffer values for OpenAL compat */ 176 void* orgdata; 177 uint32 orgfreq; 178 uint32 orgsize; 179 uint32 orgchannels; 180 uint32 orgchansize; 181 /* next buffer in chain */ 182 struct _mixer_Buffer *next; 183 184 } mixer_Buffer; 185 186 #define mixer_bufMagic 0x4258494DU /* MIXB in LSB */ 187 188 struct _mixer_Source 189 { 190 uint32 magic; 191 bool locked; 192 mixer_SourceState state; 193 bool looping; 194 float gain; 195 uint32 cqueued; 196 uint32 cprocessed; 197 mixer_Buffer *firstqueued; /* first buf in the queue */ 198 mixer_Buffer *nextqueued; /* next to play, or 0 */ 199 mixer_Buffer *prevqueued; /* previously played */ 200 mixer_Buffer *lastqueued; /* last in queue */ 201 uint32 pos; /* position in current buffer */ 202 uint32 count; /* fractional part of pos */ 203 204 float samplecache; 205 206 }; 207 208 #define mixer_srcMagic 0x5358494DU /* MIXS in LSB */ 209 210 /************************************************* 211 * General interface 212 */ 213 uint32 mixer_GetError (void); 214 215 bool mixer_Init (uint32 frequency, uint32 format, mixer_Quality quality, 216 mixer_Flags flags); 217 void mixer_Uninit (void); 218 void mixer_MixChannels (void *userdata, uint8 *stream, sint32 len); 219 void mixer_MixFake (void *userdata, uint8 *stream, sint32 len); 220 221 /************************************************* 222 * Sources 223 */ 224 void mixer_GenSources (uint32 n, mixer_Object *psrcobj); 225 void mixer_DeleteSources (uint32 n, mixer_Object *psrcobj); 226 bool mixer_IsSource (mixer_Object srcobj); 227 void mixer_Sourcei (mixer_Object srcobj, mixer_SourceProp pname, 228 mixer_IntVal value); 229 void mixer_Sourcef (mixer_Object srcobj, mixer_SourceProp pname, 230 float value); 231 void mixer_Sourcefv (mixer_Object srcobj, mixer_SourceProp pname, 232 float *value); 233 void mixer_GetSourcei (mixer_Object srcobj, mixer_SourceProp pname, 234 mixer_IntVal *value); 235 void mixer_GetSourcef (mixer_Object srcobj, mixer_SourceProp pname, 236 float *value); 237 void mixer_SourceRewind (mixer_Object srcobj); 238 void mixer_SourcePlay (mixer_Object srcobj); 239 void mixer_SourcePause (mixer_Object srcobj); 240 void mixer_SourceStop (mixer_Object srcobj); 241 void mixer_SourceQueueBuffers (mixer_Object srcobj, uint32 n, 242 mixer_Object* pbufobj); 243 void mixer_SourceUnqueueBuffers (mixer_Object srcobj, uint32 n, 244 mixer_Object* pbufobj); 245 246 /************************************************* 247 * Buffers 248 */ 249 void mixer_GenBuffers (uint32 n, mixer_Object *pbufobj); 250 void mixer_DeleteBuffers (uint32 n, mixer_Object *pbufobj); 251 bool mixer_IsBuffer (mixer_Object bufobj); 252 void mixer_GetBufferi (mixer_Object bufobj, mixer_BufferProp pname, 253 mixer_IntVal *value); 254 void mixer_BufferData (mixer_Object bufobj, uint32 format, void* data, 255 uint32 size, uint32 freq); 256 257 258 /* Make sure the prop-value type is of suitable size 259 * it must be able to store both int and void* 260 * Adapted from SDL 261 * This will generate "negative subscript or subscript is too large" 262 * error during compile, if the actual size of a type is wrong 263 */ 264 #define MIX_COMPILE_TIME_ASSERT(name, x) \ 265 typedef int mixer_dummy_##name [(x) * 2 - 1] 266 267 MIX_COMPILE_TIME_ASSERT (mixer_Object, 268 sizeof(mixer_Object) >= sizeof(void*)); 269 MIX_COMPILE_TIME_ASSERT (mixer_IntVal, 270 sizeof(mixer_IntVal) >= sizeof(mixer_Object)); 271 272 #undef MIX_COMPILE_TIME_ASSERT 273 274 #endif /* LIBS_SOUND_MIXER_MIXER_H_ */ 275