nkeynes@66 | 1 | /**
|
nkeynes@561 | 2 | * $Id$
|
nkeynes@66 | 3 | *
|
nkeynes@66 | 4 | * Audio engine, ie the part that does the actual work.
|
nkeynes@66 | 5 | *
|
nkeynes@66 | 6 | * Copyright (c) 2005 Nathan Keynes.
|
nkeynes@66 | 7 | *
|
nkeynes@66 | 8 | * This program is free software; you can redistribute it and/or modify
|
nkeynes@66 | 9 | * it under the terms of the GNU General Public License as published by
|
nkeynes@66 | 10 | * the Free Software Foundation; either version 2 of the License, or
|
nkeynes@66 | 11 | * (at your option) any later version.
|
nkeynes@66 | 12 | *
|
nkeynes@66 | 13 | * This program is distributed in the hope that it will be useful,
|
nkeynes@66 | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
nkeynes@66 | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
nkeynes@66 | 16 | * GNU General Public License for more details.
|
nkeynes@66 | 17 | */
|
nkeynes@66 | 18 | #ifndef dream_audio_H
|
nkeynes@66 | 19 | #define dream_audio_H 1
|
nkeynes@66 | 20 |
|
nkeynes@66 | 21 | #include <stdint.h>
|
nkeynes@465 | 22 | #include <stdio.h>
|
nkeynes@66 | 23 | #include <glib/gtypes.h>
|
nkeynes@66 | 24 |
|
nkeynes@66 | 25 | #ifdef __cplusplus
|
nkeynes@66 | 26 | extern "C" {
|
nkeynes@66 | 27 | #endif
|
nkeynes@66 | 28 |
|
nkeynes@465 | 29 | #define AUDIO_CHANNEL_COUNT 64
|
nkeynes@465 | 30 |
|
nkeynes@66 | 31 | #define AUDIO_FMT_8BIT 0
|
nkeynes@66 | 32 | #define AUDIO_FMT_16BIT 1
|
nkeynes@66 | 33 | #define AUDIO_FMT_ADPCM 2
|
nkeynes@66 | 34 | #define AUDIO_FMT_MONO 0
|
nkeynes@66 | 35 | #define AUDIO_FMT_STEREO 4
|
nkeynes@66 | 36 | #define AUDIO_FMT_SIGNED 0
|
nkeynes@66 | 37 | #define AUDIO_FMT_UNSIGNED 8
|
nkeynes@66 | 38 |
|
nkeynes@106 | 39 | #define AUDIO_FMT_16ST (AUDIO_FMT_16BIT|AUDIO_FMT_STEREO)
|
nkeynes@66 | 40 |
|
nkeynes@463 | 41 | typedef enum { LOOP_OFF = 0, LOOP_ON = 1, LOOP_LOOPED = 2 } loop_t;
|
nkeynes@463 | 42 |
|
nkeynes@66 | 43 | typedef struct audio_channel {
|
nkeynes@66 | 44 | gboolean active;
|
nkeynes@434 | 45 | uint32_t posn; /* current sample #, 0 = first sample */
|
nkeynes@66 | 46 | uint32_t posn_left;
|
nkeynes@66 | 47 | uint32_t start;
|
nkeynes@66 | 48 | uint32_t end;
|
nkeynes@463 | 49 | loop_t loop;
|
nkeynes@66 | 50 | uint32_t loop_start;
|
nkeynes@82 | 51 | int vol; /* 0..255 */
|
nkeynes@82 | 52 | int pan; /* 0 (left) .. 31 (right) */
|
nkeynes@66 | 53 | uint32_t sample_rate;
|
nkeynes@66 | 54 | int sample_format;
|
nkeynes@66 | 55 | /* Envelope etc stuff */
|
nkeynes@66 | 56 | /* ADPCM */
|
nkeynes@66 | 57 | int adpcm_step;
|
nkeynes@66 | 58 | int adpcm_predict;
|
nkeynes@66 | 59 | } *audio_channel_t;
|
nkeynes@66 | 60 |
|
nkeynes@66 | 61 |
|
nkeynes@66 | 62 | typedef struct audio_buffer {
|
nkeynes@73 | 63 | uint32_t length; /* Bytes */
|
nkeynes@73 | 64 | uint32_t posn; /* Bytes */
|
nkeynes@66 | 65 | int status;
|
nkeynes@66 | 66 | char data[0];
|
nkeynes@66 | 67 | } *audio_buffer_t;
|
nkeynes@66 | 68 |
|
nkeynes@91 | 69 | typedef struct audio_driver {
|
nkeynes@74 | 70 | char *name;
|
bhaal22@643 | 71 | gboolean (*init)( );
|
nkeynes@66 | 72 | gboolean (*set_output_format)( uint32_t sample_rate, uint32_t format );
|
nkeynes@66 | 73 | gboolean (*process_buffer)( audio_buffer_t buffer );
|
bhaal22@643 | 74 | gboolean (*close)( );
|
nkeynes@91 | 75 | } *audio_driver_t;
|
nkeynes@66 | 76 |
|
nkeynes@106 | 77 | extern struct audio_driver audio_null_driver;
|
nkeynes@657 | 78 | extern struct audio_driver audio_pulse_driver;
|
nkeynes@106 | 79 | extern struct audio_driver audio_esd_driver;
|
bhaal22@643 | 80 | extern struct audio_driver audio_alsa_driver;
|
nkeynes@66 | 81 |
|
nkeynes@531 | 82 | audio_driver_t get_audio_driver_by_name( const char *name );
|
nkeynes@531 | 83 |
|
nkeynes@66 | 84 | /**
|
nkeynes@66 | 85 | * Set the output driver, sample rate and format. Also initializes the
|
nkeynes@66 | 86 | * output buffers, flushing any current data and reallocating as
|
nkeynes@66 | 87 | * necessary. Must be called before attempting to generate any audio.
|
nkeynes@66 | 88 | */
|
nkeynes@111 | 89 | gboolean audio_set_driver( audio_driver_t driver, uint32_t samplerate,
|
nkeynes@66 | 90 | int format );
|
nkeynes@66 | 91 |
|
nkeynes@66 | 92 | /**
|
nkeynes@66 | 93 | * Mark the current write buffer as full and prepare the next buffer for
|
nkeynes@66 | 94 | * writing. Returns the next buffer to write to.
|
nkeynes@66 | 95 | * If all buffers are full, returns NULL.
|
nkeynes@66 | 96 | */
|
nkeynes@66 | 97 | audio_buffer_t audio_next_write_buffer();
|
nkeynes@66 | 98 |
|
nkeynes@66 | 99 | /**
|
nkeynes@66 | 100 | * Mark the current read buffer as empty and return the next buffer for
|
nkeynes@66 | 101 | * reading. If there is no next buffer yet, returns NULL.
|
nkeynes@66 | 102 | */
|
nkeynes@66 | 103 | audio_buffer_t audio_next_read_buffer();
|
nkeynes@66 | 104 |
|
nkeynes@66 | 105 | /**
|
nkeynes@66 | 106 | * Mix a single output sample and append it to the output buffers
|
nkeynes@66 | 107 | */
|
nkeynes@73 | 108 | void audio_mix_samples( int num_samples );
|
nkeynes@66 | 109 |
|
nkeynes@66 | 110 | /**
|
nkeynes@66 | 111 | * Retrieve the channel information for the channel, numbered 0..63.
|
nkeynes@66 | 112 | */
|
nkeynes@66 | 113 | audio_channel_t audio_get_channel( int channel );
|
nkeynes@66 | 114 |
|
nkeynes@434 | 115 | void audio_start_stop_channel( int channel, gboolean start );
|
nkeynes@66 | 116 | void audio_start_channel( int channel );
|
nkeynes@66 | 117 | void audio_stop_channel( int channel );
|
nkeynes@66 | 118 |
|
nkeynes@465 | 119 | void audio_save_state( FILE *f );
|
nkeynes@465 | 120 | int audio_load_state( FILE *f );
|
nkeynes@66 | 121 |
|
nkeynes@66 | 122 | #ifdef __cplusplus
|
nkeynes@66 | 123 | }
|
nkeynes@66 | 124 | #endif
|
nkeynes@66 | 125 | #endif
|