1 /* internal-only header 2 * Updated for 4.9 api inclusion by Ryan Dickie 3 * Originally done by KC/Milan 4 */ 5 #ifndef AINTERN_AUDIO_H 6 #define AINTERN_AUDIO_H 7 8 #include "allegro5/allegro.h" 9 #include "allegro5/internal/aintern_list.h" 10 #include "allegro5/internal/aintern_vector.h" 11 #include "../allegro_audio.h" 12 13 struct ALLEGRO_AUDIO_RECORDER { 14 ALLEGRO_EVENT_SOURCE source; 15 16 ALLEGRO_THREAD *thread; 17 ALLEGRO_MUTEX *mutex; 18 ALLEGRO_COND *cond; 19 /* recording is done in its own thread as 20 implemented by the driver */ 21 22 ALLEGRO_AUDIO_DEPTH depth; 23 ALLEGRO_CHANNEL_CONF chan_conf; 24 unsigned int frequency; 25 26 void **fragments; 27 /* the buffers to record into */ 28 29 unsigned int fragment_count; 30 /* the number of fragments */ 31 32 unsigned int samples; 33 /* the number of samples returned at every FRAGMENT event */ 34 35 size_t fragment_size; 36 /* size in bytes of each fragument */ 37 38 unsigned int sample_size; 39 /* the size in bytes of each sample */ 40 41 volatile bool is_recording; 42 /* true if the driver should actively be updating 43 the buffer */ 44 45 void *extra; 46 /* custom data for the driver to use as needed */ 47 }; 48 49 typedef enum ALLEGRO_AUDIO_DRIVER_ENUM 50 { 51 /* Various driver modes. */ 52 ALLEGRO_AUDIO_DRIVER_AUTODETECT = 0x20000, 53 ALLEGRO_AUDIO_DRIVER_OPENAL = 0x20001, 54 ALLEGRO_AUDIO_DRIVER_ALSA = 0x20002, 55 ALLEGRO_AUDIO_DRIVER_DSOUND = 0x20003, 56 ALLEGRO_AUDIO_DRIVER_OSS = 0x20004, 57 ALLEGRO_AUDIO_DRIVER_AQUEUE = 0x20005, 58 ALLEGRO_AUDIO_DRIVER_PULSEAUDIO = 0x20006, 59 ALLEGRO_AUDIO_DRIVER_OPENSL = 0x20007, 60 ALLEGRO_AUDIO_DRIVER_SDL = 0x20008 61 } ALLEGRO_AUDIO_DRIVER_ENUM; 62 63 typedef struct ALLEGRO_AUDIO_DRIVER ALLEGRO_AUDIO_DRIVER; 64 struct ALLEGRO_AUDIO_DRIVER { 65 const char *specifier; 66 67 int (*open)(void); 68 void (*close)(void); 69 70 int (*allocate_voice)(ALLEGRO_VOICE*); 71 void (*deallocate_voice)(ALLEGRO_VOICE*); 72 73 int (*load_voice)(ALLEGRO_VOICE*, const void*); 74 void (*unload_voice)(ALLEGRO_VOICE*); 75 76 int (*start_voice)(ALLEGRO_VOICE*); 77 int (*stop_voice)(ALLEGRO_VOICE*); 78 79 bool (*voice_is_playing)(const ALLEGRO_VOICE*); 80 81 unsigned int (*get_voice_position)(const ALLEGRO_VOICE*); 82 int (*set_voice_position)(ALLEGRO_VOICE*, unsigned int); 83 84 85 int (*allocate_recorder)(struct ALLEGRO_AUDIO_RECORDER *); 86 void (*deallocate_recorder)(struct ALLEGRO_AUDIO_RECORDER *); 87 }; 88 89 extern ALLEGRO_AUDIO_DRIVER *_al_kcm_driver; 90 91 const void *_al_voice_update(ALLEGRO_VOICE *voice, ALLEGRO_MUTEX *mutex, 92 unsigned int *samples); 93 bool _al_kcm_set_voice_playing(ALLEGRO_VOICE *voice, ALLEGRO_MUTEX *mutex, 94 bool val); 95 96 /* A voice structure that you'd attach a mixer or sample to. Ideally there 97 * would be one ALLEGRO_VOICE per system/hardware voice. 98 */ 99 struct ALLEGRO_VOICE { 100 ALLEGRO_AUDIO_DEPTH depth; 101 ALLEGRO_CHANNEL_CONF chan_conf; 102 103 unsigned int frequency; 104 105 size_t buffer_size; 106 size_t num_buffers; 107 /* If non-0, they must be honored by the driver. */ 108 109 ALLEGRO_SAMPLE_INSTANCE *attached_stream; 110 /* The stream that is attached to the voice, or NULL. 111 * May be an ALLEGRO_SAMPLE_INSTANCE or ALLEGRO_MIXER object. 112 */ 113 114 bool is_streaming; 115 /* True for voices with an attached mixer. */ 116 117 ALLEGRO_MUTEX *mutex; 118 ALLEGRO_COND *cond; 119 120 _AL_LIST_ITEM *dtor_item; 121 122 ALLEGRO_AUDIO_DRIVER *driver; 123 /* XXX shouldn't there only be one audio driver active 124 * at a time? 125 */ 126 127 void *extra; 128 /* Extra data for use by the driver. */ 129 }; 130 131 132 typedef union { 133 float *f32; 134 uint32_t *u24; 135 int32_t *s24; 136 uint16_t *u16; 137 int16_t *s16; 138 uint8_t *u8; 139 int8_t *s8; 140 void *ptr; 141 } any_buffer_t; 142 143 struct ALLEGRO_SAMPLE { 144 ALLEGRO_AUDIO_DEPTH depth; 145 ALLEGRO_CHANNEL_CONF chan_conf; 146 unsigned int frequency; 147 int len; 148 any_buffer_t buffer; 149 bool free_buf; 150 /* Whether `buffer' needs to be freed when the sample 151 * is destroyed, or when `buffer' changes. 152 */ 153 _AL_LIST_ITEM *dtor_item; 154 }; 155 156 /* Read some samples into a mixer buffer. 157 * 158 * source: 159 * The object to read samples from. This may be one of several types. 160 * 161 * *vbuf: (in-out parameter) 162 * Pointer to pointer to destination buffer. 163 * (should confirm what it means to change the pointer on return) 164 * 165 * *samples: (in-out parameter) 166 * On input indicates the maximum number of samples that can fit into *vbuf. 167 * On output indicates the actual number of samples that were read. 168 * 169 * buffer_depth: 170 * The audio depth of the destination buffer. 171 * 172 * dest_maxc: 173 * The number of channels in the destination. 174 */ 175 typedef void (*stream_reader_t)(void *source, void **vbuf, 176 unsigned int *samples, ALLEGRO_AUDIO_DEPTH buffer_depth, size_t dest_maxc); 177 178 typedef struct { 179 union { 180 ALLEGRO_MIXER *mixer; 181 ALLEGRO_VOICE *voice; 182 void *ptr; 183 } u; 184 bool is_voice; 185 } sample_parent_t; 186 187 /* The sample struct also serves the base of ALLEGRO_AUDIO_STREAM, ALLEGRO_MIXER. */ 188 struct ALLEGRO_SAMPLE_INSTANCE { 189 /* ALLEGRO_SAMPLE_INSTANCE does not generate any events yet but ALLEGRO_AUDIO_STREAM 190 * does, which can inherit only ALLEGRO_SAMPLE_INSTANCE. */ 191 ALLEGRO_EVENT_SOURCE es; 192 193 ALLEGRO_SAMPLE spl_data; 194 195 volatile bool is_playing; 196 /* Is this sample is playing? */ 197 198 ALLEGRO_PLAYMODE loop; 199 float speed; 200 float gain; 201 float pan; 202 203 /* When resampling an audio stream there will be fractional sample 204 * positions due to the difference in frequencies. 205 */ 206 int pos; 207 int pos_bresenham_error; 208 209 int loop_start; 210 int loop_end; 211 212 int step; 213 int step_denom; 214 /* The numerator and denominator of the step are 215 * stored separately. The actual step is obtained by 216 * dividing step by step_denom */ 217 218 float *matrix; 219 /* Used to convert from this format to the attached 220 * mixers, if any. Otherwise is NULL. 221 * The gain is premultiplied in. 222 */ 223 224 bool is_mixer; 225 stream_reader_t spl_read; 226 /* Reads sample data into the provided buffer, using 227 * the specified format, converting as necessary. 228 */ 229 230 ALLEGRO_MUTEX *mutex; 231 /* Points to the parent object's mutex. It is NULL if 232 * the sample is not directly or indirectly attached 233 * to a voice. 234 */ 235 236 sample_parent_t parent; 237 /* The object that this sample is attached to, if any. 238 */ 239 _AL_LIST_ITEM *dtor_item; 240 }; 241 242 void _al_kcm_destroy_sample(ALLEGRO_SAMPLE_INSTANCE *sample, bool unregister); 243 void _al_kcm_stream_set_mutex(ALLEGRO_SAMPLE_INSTANCE *stream, ALLEGRO_MUTEX *mutex); 244 void _al_kcm_detach_from_parent(ALLEGRO_SAMPLE_INSTANCE *spl); 245 246 247 typedef size_t (*stream_callback_t)(ALLEGRO_AUDIO_STREAM *, void *, size_t); 248 typedef void (*unload_feeder_t)(ALLEGRO_AUDIO_STREAM *); 249 typedef bool (*rewind_feeder_t)(ALLEGRO_AUDIO_STREAM *); 250 typedef bool (*seek_feeder_t)(ALLEGRO_AUDIO_STREAM *, double); 251 typedef double (*get_feeder_position_t)(ALLEGRO_AUDIO_STREAM *); 252 typedef double (*get_feeder_length_t)(ALLEGRO_AUDIO_STREAM *); 253 typedef bool (*set_feeder_loop_t)(ALLEGRO_AUDIO_STREAM *, double, double); 254 255 struct ALLEGRO_AUDIO_STREAM { 256 ALLEGRO_SAMPLE_INSTANCE spl; 257 /* ALLEGRO_AUDIO_STREAM is derived from 258 * ALLEGRO_SAMPLE_INSTANCE. 259 */ 260 261 unsigned int buf_count; 262 /* The stream buffer is divided into a number of 263 * fragments; this is the number of fragments. 264 */ 265 266 void *main_buffer; 267 /* Pointer to a single buffer big enough to hold all 268 * the fragments. Each fragment has additional samples 269 * at the start for linear/cubic interpolation. 270 */ 271 272 void **pending_bufs; 273 void **used_bufs; 274 /* Arrays of offsets into the main_buffer. 275 * The arrays are each 'buf_count' long. 276 * 277 * 'pending_bufs' holds pointers to fragments supplied 278 * by the user which are yet to be handed off to the 279 * audio driver. 280 * 281 * 'used_bufs' holds pointers to fragments which 282 * have been sent to the audio driver and so are 283 * ready to receive new data. 284 */ 285 286 volatile bool is_draining; 287 /* Set to true if sample data is not going to be passed 288 * to the stream any more. The stream must change its 289 * playing state to false after all buffers have been 290 * played. 291 */ 292 293 uint64_t consumed_fragments; 294 /* Number of complete fragment buffers consumed since 295 * the stream was started. 296 */ 297 298 ALLEGRO_THREAD *feed_thread; 299 ALLEGRO_MUTEX *feed_thread_started_mutex; 300 ALLEGRO_COND *feed_thread_started_cond; 301 bool feed_thread_started; 302 volatile bool quit_feed_thread; 303 unload_feeder_t unload_feeder; 304 rewind_feeder_t rewind_feeder; 305 seek_feeder_t seek_feeder; 306 get_feeder_position_t get_feeder_position; 307 get_feeder_length_t get_feeder_length; 308 set_feeder_loop_t set_feeder_loop; 309 stream_callback_t feeder; 310 /* If ALLEGRO_AUDIO_STREAM has been created by 311 * al_load_audio_stream(), the stream will be fed 312 * by a thread using the 'feeder' callback. Such 313 * streams don't need to be fed by the user. 314 */ 315 316 _AL_LIST_ITEM *dtor_item; 317 318 void *extra; 319 /* Extra data for use by the flac/vorbis addons. */ 320 }; 321 322 bool _al_kcm_refill_stream(ALLEGRO_AUDIO_STREAM *stream); 323 324 325 typedef void (*postprocess_callback_t)(void *buf, unsigned int samples, 326 void *userdata); 327 328 /* ALLEGRO_MIXER is derived from ALLEGRO_SAMPLE_INSTANCE. Certain internal functions and 329 * pointers may take either object type, and such things are explicitly noted. 330 * This is never exposed to the user, though. The sample object's read method 331 * will be set to a different function that will call the read method of all 332 * attached streams (which may be a sample, or another mixer). 333 */ 334 struct ALLEGRO_MIXER { 335 ALLEGRO_SAMPLE_INSTANCE ss; 336 /* ALLEGRO_MIXER is derived from ALLEGRO_SAMPLE_INSTANCE. */ 337 338 ALLEGRO_MIXER_QUALITY quality; 339 340 postprocess_callback_t postprocess_callback; 341 void *pp_callback_userdata; 342 343 _AL_VECTOR streams; 344 /* Vector of ALLEGRO_SAMPLE_INSTANCE*. Holds the list of 345 * streams being mixed together. 346 */ 347 _AL_LIST_ITEM *dtor_item; 348 }; 349 350 extern void _al_kcm_mixer_rejig_sample_matrix(ALLEGRO_MIXER *mixer, 351 ALLEGRO_SAMPLE_INSTANCE *spl); 352 extern void _al_kcm_mixer_read(void *source, void **buf, unsigned int *samples, 353 ALLEGRO_AUDIO_DEPTH buffer_depth, size_t dest_maxc); 354 355 356 typedef enum { 357 ALLEGRO_NO_ERROR = 0, 358 ALLEGRO_INVALID_PARAM = 1, 359 ALLEGRO_INVALID_OBJECT = 2, 360 ALLEGRO_GENERIC_ERROR = 255 361 } AL_ERROR_ENUM; 362 363 extern void _al_set_error(int error, char* string); 364 365 /* Supposedly internal */ 366 ALLEGRO_KCM_AUDIO_FUNC(void*, _al_kcm_feed_stream, (ALLEGRO_THREAD *self, void *vstream)); 367 368 /* Helper to emit an event that the stream has got a buffer ready to be refilled. */ 369 void _al_kcm_emit_stream_events(ALLEGRO_AUDIO_STREAM *stream); 370 371 void _al_kcm_init_destructors(void); 372 void _al_kcm_shutdown_destructors(void); 373 _AL_LIST_ITEM *_al_kcm_register_destructor(char const *name, void *object, 374 void (*func)(void*)); 375 void _al_kcm_unregister_destructor(_AL_LIST_ITEM *dtor_item); 376 void _al_kcm_foreach_destructor( 377 void (*callback)(void *object, void (*func)(void *), void *udata), 378 void *userdata); 379 380 ALLEGRO_KCM_AUDIO_FUNC(void, _al_kcm_shutdown_default_mixer, (void)); 381 382 ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_CHANNEL_CONF, _al_count_to_channel_conf, (int num_channels)); 383 ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_AUDIO_DEPTH, _al_word_size_to_depth_conf, (int word_size)); 384 385 ALLEGRO_KCM_AUDIO_FUNC(void, _al_emit_audio_event, (int event_type)); 386 387 #endif 388 389 /* vim: set sts=3 sw=3 et: */ 390