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@736 | 18 | #ifndef lxdream_audio_H
|
nkeynes@736 | 19 | #define lxdream_audio_H 1
|
nkeynes@66 | 20 |
|
nkeynes@66 | 21 | #include <stdint.h>
|
nkeynes@465 | 22 | #include <stdio.h>
|
nkeynes@1296 | 23 | #include <glib.h>
|
nkeynes@755 | 24 | #include "gettext.h"
|
nkeynes@1024 | 25 | #include "plugin.h"
|
nkeynes@700 | 26 |
|
nkeynes@66 | 27 | #ifdef __cplusplus
|
nkeynes@66 | 28 | extern "C" {
|
nkeynes@66 | 29 | #endif
|
nkeynes@66 | 30 |
|
nkeynes@465 | 31 | #define AUDIO_CHANNEL_COUNT 64
|
nkeynes@465 | 32 |
|
nkeynes@66 | 33 | #define AUDIO_FMT_8BIT 0
|
nkeynes@66 | 34 | #define AUDIO_FMT_16BIT 1
|
nkeynes@66 | 35 | #define AUDIO_FMT_ADPCM 2
|
nkeynes@697 | 36 | #define AUDIO_FMT_FLOAT 3 // 32-bit -1.0 to 1.0
|
nkeynes@66 | 37 | #define AUDIO_FMT_MONO 0
|
nkeynes@66 | 38 | #define AUDIO_FMT_STEREO 4
|
nkeynes@66 | 39 | #define AUDIO_FMT_SIGNED 0
|
nkeynes@66 | 40 | #define AUDIO_FMT_UNSIGNED 8
|
nkeynes@697 | 41 |
|
nkeynes@697 | 42 | #define AUDIO_FMT_SAMPLE_MASK 3
|
nkeynes@66 | 43 |
|
nkeynes@106 | 44 | #define AUDIO_FMT_16ST (AUDIO_FMT_16BIT|AUDIO_FMT_STEREO)
|
nkeynes@697 | 45 | #define AUDIO_FMT_FLOATST (AUDIO_FMT_FLOAT|AUDIO_FMT_STEREO)
|
nkeynes@1089 | 46 | #define AUDIO_MEM_MASK 0x1FFFFF
|
nkeynes@66 | 47 |
|
nkeynes@697 | 48 | #define DEFAULT_SAMPLE_RATE 44100
|
nkeynes@697 | 49 | #define DEFAULT_SAMPLE_FORMAT AUDIO_FMT_16ST
|
nkeynes@697 | 50 |
|
nkeynes@463 | 51 | typedef enum { LOOP_OFF = 0, LOOP_ON = 1, LOOP_LOOPED = 2 } loop_t;
|
nkeynes@463 | 52 |
|
nkeynes@66 | 53 | typedef struct audio_channel {
|
nkeynes@66 | 54 | gboolean active;
|
nkeynes@434 | 55 | uint32_t posn; /* current sample #, 0 = first sample */
|
nkeynes@66 | 56 | uint32_t posn_left;
|
nkeynes@66 | 57 | uint32_t start;
|
nkeynes@66 | 58 | uint32_t end;
|
nkeynes@463 | 59 | loop_t loop;
|
nkeynes@66 | 60 | uint32_t loop_start;
|
nkeynes@82 | 61 | int vol; /* 0..255 */
|
nkeynes@82 | 62 | int pan; /* 0 (left) .. 31 (right) */
|
nkeynes@66 | 63 | uint32_t sample_rate;
|
nkeynes@66 | 64 | int sample_format;
|
nkeynes@66 | 65 | /* Envelope etc stuff */
|
nkeynes@66 | 66 | /* ADPCM */
|
nkeynes@66 | 67 | int adpcm_step;
|
nkeynes@66 | 68 | int adpcm_predict;
|
nkeynes@66 | 69 | } *audio_channel_t;
|
nkeynes@66 | 70 |
|
nkeynes@66 | 71 |
|
nkeynes@66 | 72 | typedef struct audio_buffer {
|
nkeynes@73 | 73 | uint32_t length; /* Bytes */
|
nkeynes@73 | 74 | uint32_t posn; /* Bytes */
|
nkeynes@66 | 75 | int status;
|
nkeynes@66 | 76 | char data[0];
|
nkeynes@66 | 77 | } *audio_buffer_t;
|
nkeynes@66 | 78 |
|
nkeynes@91 | 79 | typedef struct audio_driver {
|
nkeynes@1024 | 80 | const char *name;
|
nkeynes@1024 | 81 | const char *description;
|
nkeynes@1024 | 82 | int priority; /* Lower == higher priority */
|
nkeynes@697 | 83 | uint32_t sample_rate;
|
nkeynes@697 | 84 | uint32_t sample_format;
|
nkeynes@697 | 85 | gboolean (*init)( );
|
nkeynes@697 | 86 | void (*start)( );
|
nkeynes@66 | 87 | gboolean (*process_buffer)( audio_buffer_t buffer );
|
nkeynes@697 | 88 | void (*stop)( );
|
nkeynes@697 | 89 | gboolean (*shutdown)( );
|
nkeynes@91 | 90 | } *audio_driver_t;
|
nkeynes@66 | 91 |
|
nkeynes@700 | 92 |
|
nkeynes@700 | 93 | /**
|
nkeynes@700 | 94 | * Print the configured audio drivers to the output stream, one to a line.
|
nkeynes@700 | 95 | */
|
nkeynes@700 | 96 | void print_audio_drivers( FILE *out );
|
nkeynes@700 | 97 |
|
nkeynes@531 | 98 | audio_driver_t get_audio_driver_by_name( const char *name );
|
nkeynes@531 | 99 |
|
nkeynes@66 | 100 | /**
|
nkeynes@66 | 101 | * Set the output driver, sample rate and format. Also initializes the
|
nkeynes@66 | 102 | * output buffers, flushing any current data and reallocating as
|
nkeynes@66 | 103 | * necessary. Must be called before attempting to generate any audio.
|
nkeynes@66 | 104 | */
|
nkeynes@697 | 105 | gboolean audio_set_driver( audio_driver_t driver );
|
nkeynes@66 | 106 |
|
nkeynes@66 | 107 | /**
|
nkeynes@759 | 108 | * Initialize the audio driver, using the specified driver if available.
|
nkeynes@759 | 109 | */
|
nkeynes@759 | 110 | audio_driver_t audio_init_driver( const char *preferred_driver );
|
nkeynes@759 | 111 |
|
nkeynes@759 | 112 | /**
|
nkeynes@1024 | 113 | * Add a new audio driver to the available drivers list
|
nkeynes@1024 | 114 | */
|
nkeynes@1024 | 115 | gboolean audio_register_driver( audio_driver_t driver );
|
nkeynes@1024 | 116 |
|
nkeynes@1024 | 117 | /**
|
nkeynes@1024 | 118 | * Signal the audio driver that playback is beginning
|
nkeynes@1024 | 119 | */
|
nkeynes@1024 | 120 | void audio_start_driver();
|
nkeynes@1024 | 121 |
|
nkeynes@1024 | 122 | /**
|
nkeynes@1024 | 123 | * Signal the audio driver that playback is stopping
|
nkeynes@1024 | 124 | */
|
nkeynes@1024 | 125 | void audio_stop_driver();
|
nkeynes@1024 | 126 |
|
nkeynes@1024 | 127 | /**
|
nkeynes@66 | 128 | * Mark the current write buffer as full and prepare the next buffer for
|
nkeynes@66 | 129 | * writing. Returns the next buffer to write to.
|
nkeynes@66 | 130 | * If all buffers are full, returns NULL.
|
nkeynes@66 | 131 | */
|
nkeynes@66 | 132 | audio_buffer_t audio_next_write_buffer();
|
nkeynes@66 | 133 |
|
nkeynes@66 | 134 | /**
|
nkeynes@66 | 135 | * Mark the current read buffer as empty and return the next buffer for
|
nkeynes@66 | 136 | * reading. If there is no next buffer yet, returns NULL.
|
nkeynes@66 | 137 | */
|
nkeynes@66 | 138 | audio_buffer_t audio_next_read_buffer();
|
nkeynes@66 | 139 |
|
nkeynes@66 | 140 | /**
|
nkeynes@66 | 141 | * Mix a single output sample and append it to the output buffers
|
nkeynes@66 | 142 | */
|
nkeynes@73 | 143 | void audio_mix_samples( int num_samples );
|
nkeynes@66 | 144 |
|
nkeynes@66 | 145 | /**
|
nkeynes@66 | 146 | * Retrieve the channel information for the channel, numbered 0..63.
|
nkeynes@66 | 147 | */
|
nkeynes@66 | 148 | audio_channel_t audio_get_channel( int channel );
|
nkeynes@66 | 149 |
|
nkeynes@434 | 150 | void audio_start_stop_channel( int channel, gboolean start );
|
nkeynes@66 | 151 | void audio_start_channel( int channel );
|
nkeynes@66 | 152 | void audio_stop_channel( int channel );
|
nkeynes@66 | 153 |
|
nkeynes@465 | 154 | void audio_save_state( FILE *f );
|
nkeynes@465 | 155 | int audio_load_state( FILE *f );
|
nkeynes@66 | 156 |
|
nkeynes@66 | 157 | #ifdef __cplusplus
|
nkeynes@66 | 158 | }
|
nkeynes@66 | 159 | #endif
|
nkeynes@736 | 160 |
|
nkeynes@736 | 161 | #endif /* !lxdream_audio_H */
|