[15362] | 1 | #ifndef ESD_H |
---|
| 2 | #define ESD_H |
---|
| 3 | #include <audiofile.h> |
---|
| 4 | |
---|
| 5 | #ifdef __cplusplus |
---|
| 6 | extern "C" { |
---|
| 7 | #endif |
---|
| 8 | |
---|
| 9 | /* path and name of the default EsounD domain socket */ |
---|
[18232] | 10 | #define ESD_UNIX_SOCKET_DIR esd_get_socket_dirname() |
---|
| 11 | #define ESD_UNIX_SOCKET_NAME esd_get_socket_name() |
---|
[15362] | 12 | |
---|
[20225] | 13 | /* size of the audio buffer */ |
---|
[15362] | 14 | #define ESD_BUF_SIZE (4 * 1024) |
---|
| 15 | |
---|
| 16 | /* length of the authorization key, octets */ |
---|
| 17 | #define ESD_KEY_LEN (16) |
---|
| 18 | |
---|
| 19 | /* default port for the EsounD server */ |
---|
| 20 | #define ESD_DEFAULT_PORT (16001) |
---|
| 21 | |
---|
| 22 | /* default sample rate for the EsounD server */ |
---|
| 23 | #define ESD_DEFAULT_RATE (44100) |
---|
| 24 | |
---|
| 25 | /* maximum length of a stream/sample name */ |
---|
| 26 | #define ESD_NAME_MAX (128) |
---|
| 27 | |
---|
| 28 | /* a magic number to identify the relative endianness of a client */ |
---|
| 29 | #define ESD_ENDIAN_KEY \ |
---|
| 30 | ( (unsigned int) ( ('E' << 24) + ('N' << 16) + ('D' << 8) + ('N') ) ) |
---|
| 31 | |
---|
| 32 | #define ESD_VOLUME_BASE (256) |
---|
| 33 | |
---|
| 34 | /*************************************/ |
---|
| 35 | /* what can we do to/with the EsounD */ |
---|
| 36 | enum esd_proto { |
---|
| 37 | ESD_PROTO_CONNECT, /* implied on inital client connection */ |
---|
| 38 | |
---|
| 39 | /* pseudo "security" functionality */ |
---|
| 40 | ESD_PROTO_LOCK, /* disable "foreign" client connections */ |
---|
| 41 | ESD_PROTO_UNLOCK, /* enable "foreign" client connections */ |
---|
| 42 | |
---|
| 43 | /* stream functionality: play, record, monitor */ |
---|
| 44 | ESD_PROTO_STREAM_PLAY, /* play all following data as a stream */ |
---|
| 45 | ESD_PROTO_STREAM_REC, /* record data from card as a stream */ |
---|
| 46 | ESD_PROTO_STREAM_MON, /* send mixed buffer output as a stream */ |
---|
| 47 | |
---|
| 48 | /* sample functionality: cache, free, play, loop, EOL, kill */ |
---|
| 49 | ESD_PROTO_SAMPLE_CACHE, /* cache a sample in the server */ |
---|
| 50 | ESD_PROTO_SAMPLE_FREE, /* release a sample in the server */ |
---|
| 51 | ESD_PROTO_SAMPLE_PLAY, /* play a cached sample */ |
---|
| 52 | ESD_PROTO_SAMPLE_LOOP, /* loop a cached sample, til eoloop */ |
---|
| 53 | ESD_PROTO_SAMPLE_STOP, /* stop a looping sample when done */ |
---|
| 54 | ESD_PROTO_SAMPLE_KILL, /* stop the looping sample immed. */ |
---|
| 55 | |
---|
| 56 | /* free and reclaim /dev/dsp functionality */ |
---|
| 57 | ESD_PROTO_STANDBY, /* release /dev/dsp and ignore all data */ |
---|
| 58 | ESD_PROTO_RESUME, /* reclaim /dev/dsp and play sounds again */ |
---|
| 59 | |
---|
| 60 | /* TODO: move these to a more logical place. NOTE: will break the protocol */ |
---|
| 61 | ESD_PROTO_SAMPLE_GETID, /* get the ID for an already-cached sample */ |
---|
| 62 | ESD_PROTO_STREAM_FILT, /* filter mixed buffer output as a stream */ |
---|
| 63 | |
---|
| 64 | /* esd remote management */ |
---|
| 65 | ESD_PROTO_SERVER_INFO, /* get server info (ver, sample rate, format) */ |
---|
| 66 | ESD_PROTO_ALL_INFO, /* get all info (server info, players, samples) */ |
---|
| 67 | ESD_PROTO_SUBSCRIBE, /* track new and removed players and samples */ |
---|
| 68 | ESD_PROTO_UNSUBSCRIBE, /* stop tracking updates */ |
---|
| 69 | |
---|
| 70 | /* esd remote control */ |
---|
| 71 | ESD_PROTO_STREAM_PAN, /* set stream panning */ |
---|
| 72 | ESD_PROTO_SAMPLE_PAN, /* set default sample panning */ |
---|
| 73 | |
---|
| 74 | /* esd status */ |
---|
| 75 | ESD_PROTO_STANDBY_MODE, /* see if server is in standby, autostandby, etc */ |
---|
| 76 | |
---|
| 77 | /* esd latency */ |
---|
| 78 | ESD_PROTO_LATENCY, /* retrieve latency between write()'s and output */ |
---|
| 79 | |
---|
| 80 | ESD_PROTO_MAX /* for bounds checking */ |
---|
| 81 | }; |
---|
| 82 | |
---|
| 83 | |
---|
| 84 | /******************/ |
---|
| 85 | /* The EsounD api */ |
---|
| 86 | |
---|
| 87 | /* the properties of a sound buffer are logically or'd */ |
---|
| 88 | |
---|
| 89 | /* bits of stream/sample data */ |
---|
| 90 | #define ESD_MASK_BITS ( 0x000F ) |
---|
| 91 | #define ESD_BITS8 ( 0x0000 ) |
---|
| 92 | #define ESD_BITS16 ( 0x0001 ) |
---|
| 93 | |
---|
| 94 | /* how many interleaved channels of data */ |
---|
| 95 | #define ESD_MASK_CHAN ( 0x00F0 ) |
---|
| 96 | #define ESD_MONO ( 0x0010 ) |
---|
| 97 | #define ESD_STEREO ( 0x0020 ) |
---|
| 98 | |
---|
| 99 | /* whether it's a stream or a sample */ |
---|
| 100 | #define ESD_MASK_MODE ( 0x0F00 ) |
---|
| 101 | #define ESD_STREAM ( 0x0000 ) |
---|
| 102 | #define ESD_SAMPLE ( 0x0100 ) |
---|
| 103 | #define ESD_ADPCM ( 0x0200 ) /* TODO: anyone up for this? =P */ |
---|
| 104 | |
---|
| 105 | /* the function of the stream/sample, and common functions */ |
---|
| 106 | #define ESD_MASK_FUNC ( 0xF000 ) |
---|
| 107 | #define ESD_PLAY ( 0x1000 ) |
---|
| 108 | /* functions for streams only */ |
---|
| 109 | #define ESD_MONITOR ( 0x0000 ) |
---|
| 110 | #define ESD_RECORD ( 0x2000 ) |
---|
| 111 | /* functions for samples only */ |
---|
| 112 | #define ESD_STOP ( 0x0000 ) |
---|
| 113 | #define ESD_LOOP ( 0x2000 ) |
---|
| 114 | |
---|
| 115 | typedef int esd_format_t; |
---|
| 116 | typedef int esd_proto_t; |
---|
| 117 | |
---|
| 118 | /*******************************************************************/ |
---|
| 119 | /* client side API for playing sounds */ |
---|
| 120 | |
---|
| 121 | typedef unsigned char octet; |
---|
| 122 | |
---|
| 123 | /*******************************************************************/ |
---|
| 124 | /* esdlib.c - basic esd client interface functions */ |
---|
| 125 | |
---|
| 126 | /* opens channel, authenticates connection, and prefares for protos */ |
---|
| 127 | /* returns EsounD socket for communication, result < 0 = error */ |
---|
| 128 | /* server = listen socket (localhost:5001, 192.168.168.0:9999 */ |
---|
| 129 | /* rate, format = (bits | channels | stream | func) */ |
---|
| 130 | int esd_open_sound( const char *host ); |
---|
| 131 | |
---|
| 132 | /* send the authorization cookie, create one if needed */ |
---|
| 133 | int esd_send_auth( int sock ); |
---|
| 134 | |
---|
| 135 | /* lock/unlock will disable/enable foreign clients from connecting */ |
---|
| 136 | int esd_lock( int esd ); |
---|
| 137 | int esd_unlock( int esd ); |
---|
| 138 | |
---|
| 139 | /* standby/resume will free/reclaim audio device so others may use it */ |
---|
| 140 | int esd_standby( int esd ); |
---|
| 141 | int esd_resume( int esd ); |
---|
| 142 | |
---|
| 143 | /* open a socket for playing, monitoring, or recording as a stream */ |
---|
| 144 | /* the *_fallback functions try to open /dev/dsp if there's no EsounD */ |
---|
| 145 | int esd_play_stream( esd_format_t format, int rate, |
---|
| 146 | const char *host, const char *name ); |
---|
| 147 | int esd_play_stream_fallback( esd_format_t format, int rate, |
---|
| 148 | const char *host, const char *name ); |
---|
| 149 | int esd_monitor_stream( esd_format_t format, int rate, |
---|
| 150 | const char *host, const char *name ); |
---|
| 151 | /* int esd_monitor_stream_fallback( esd_format_t format, int rate ); */ |
---|
| 152 | int esd_record_stream( esd_format_t format, int rate, |
---|
| 153 | const char *host, const char *name ); |
---|
| 154 | int esd_record_stream_fallback( esd_format_t format, int rate, |
---|
| 155 | const char *host, const char *name ); |
---|
| 156 | int esd_filter_stream( esd_format_t format, int rate, |
---|
| 157 | const char *host, const char *name ); |
---|
| 158 | |
---|
| 159 | /* cache a sample in the server returns sample id, < 0 = error */ |
---|
| 160 | int esd_sample_cache( int esd, esd_format_t format, const int rate, |
---|
| 161 | const int length, const char *name ); |
---|
| 162 | int esd_confirm_sample_cache( int esd ); |
---|
| 163 | |
---|
| 164 | /* get the sample id for an already-cached sample */ |
---|
| 165 | int esd_sample_getid( int esd, const char *name); |
---|
| 166 | |
---|
| 167 | /* uncache a sample in the server */ |
---|
| 168 | int esd_sample_free( int esd, int sample ); |
---|
| 169 | |
---|
| 170 | /* play a cached sample once */ |
---|
| 171 | int esd_sample_play( int esd, int sample ); |
---|
| 172 | /* make a cached sample loop */ |
---|
| 173 | int esd_sample_loop( int esd, int sample ); |
---|
| 174 | |
---|
| 175 | /* stop the looping sample at end */ |
---|
| 176 | int esd_sample_stop( int esd, int sample ); |
---|
| 177 | /* stop a playing sample immed. */ |
---|
| 178 | int esd_sample_kill( int esd, int sample ); |
---|
| 179 | |
---|
| 180 | /* closes fd, previously obtained by esd_open */ |
---|
| 181 | int esd_close( int esd ); |
---|
| 182 | |
---|
| 183 | /* get the stream latency to esound (latency is number of samples */ |
---|
| 184 | /* at 44.1khz stereo 16 bit - you'll have to adjust if oyur input */ |
---|
| 185 | /* sampling rate is less (in bytes per second) */ |
---|
| 186 | /* so if you're at 44.1khz stereo 16bit in your stream - your lag */ |
---|
| 187 | /* in bytes woudl be lag * 2 * 2 bytes (2 for stereo, 2 for 16bit) */ |
---|
| 188 | /* if your stream is at 22.05 Khz it'll be double this - in mono */ |
---|
| 189 | /* double again ... etc. */ |
---|
| 190 | int esd_get_latency(int esd); |
---|
| 191 | |
---|
| 192 | |
---|
| 193 | /*******************************************************************/ |
---|
| 194 | /* esdmgr.c - functions to implement a "sound manager" for esd */ |
---|
| 195 | |
---|
| 196 | /* structures to retrieve information about streams/samples from the server */ |
---|
| 197 | typedef struct esd_server_info { |
---|
| 198 | |
---|
| 199 | int version; /* server version encoded as an int */ |
---|
| 200 | esd_format_t format; /* magic int with the format info */ |
---|
| 201 | int rate; /* sample rate */ |
---|
| 202 | |
---|
| 203 | } esd_server_info_t; |
---|
| 204 | |
---|
| 205 | typedef struct esd_player_info { |
---|
| 206 | |
---|
| 207 | struct esd_player_info *next; /* point to next entry in list */ |
---|
| 208 | esd_server_info_t *server; /* the server that contains this stream */ |
---|
| 209 | |
---|
| 210 | int source_id; /* either a stream fd or sample id */ |
---|
| 211 | char name[ ESD_NAME_MAX ]; /* name of stream for remote control */ |
---|
| 212 | int rate; /* sample rate */ |
---|
| 213 | int left_vol_scale; /* volume scaling */ |
---|
| 214 | int right_vol_scale; |
---|
| 215 | |
---|
| 216 | esd_format_t format; /* magic int with the format info */ |
---|
| 217 | |
---|
| 218 | } esd_player_info_t; |
---|
| 219 | |
---|
| 220 | typedef struct esd_sample_info { |
---|
| 221 | |
---|
| 222 | struct esd_sample_info *next; /* point to next entry in list */ |
---|
| 223 | esd_server_info_t *server; /* the server that contains this sample */ |
---|
| 224 | |
---|
| 225 | int sample_id; /* either a stream fd or sample id */ |
---|
| 226 | char name[ ESD_NAME_MAX ]; /* name of stream for remote control */ |
---|
| 227 | int rate; /* sample rate */ |
---|
| 228 | int left_vol_scale; /* volume scaling */ |
---|
| 229 | int right_vol_scale; |
---|
| 230 | |
---|
| 231 | esd_format_t format; /* magic int with the format info */ |
---|
| 232 | int length; /* total buffer length */ |
---|
| 233 | |
---|
| 234 | } esd_sample_info_t; |
---|
| 235 | |
---|
| 236 | typedef struct esd_info { |
---|
| 237 | |
---|
| 238 | esd_server_info_t *server; |
---|
| 239 | esd_player_info_t *player_list; |
---|
| 240 | esd_sample_info_t *sample_list; |
---|
| 241 | |
---|
| 242 | } esd_info_t; |
---|
| 243 | |
---|
| 244 | enum esd_standby_mode { |
---|
| 245 | ESM_ERROR, ESM_ON_STANDBY, ESM_ON_AUTOSTANDBY, ESM_RUNNING |
---|
| 246 | }; |
---|
| 247 | typedef int esd_standby_mode_t; |
---|
| 248 | |
---|
| 249 | /* define callbacks for esd_update_info() */ |
---|
| 250 | /* what to do when a stream connects, or sample is played */ |
---|
| 251 | typedef int esd_new_player_callback_t( esd_player_info_t * ); |
---|
| 252 | /* what to do when a stream disconnects, or sample stops playing */ |
---|
| 253 | typedef int esd_old_player_callback_t( esd_player_info_t * ); |
---|
| 254 | /* what to do when a sample is cached */ |
---|
| 255 | typedef int esd_new_sample_callback_t( esd_sample_info_t * ); |
---|
| 256 | /* what to do when a sample is uncached */ |
---|
| 257 | typedef int esd_old_sample_callback_t( esd_sample_info_t * ); |
---|
| 258 | |
---|
| 259 | typedef struct esd_update_info_callbacks { |
---|
| 260 | esd_new_player_callback_t *esd_new_player_callback; |
---|
| 261 | esd_old_player_callback_t *esd_old_player_callback; |
---|
| 262 | esd_new_sample_callback_t *esd_new_sample_callback; |
---|
| 263 | esd_old_sample_callback_t *esd_old_sample_callback; |
---|
| 264 | } esd_update_info_callbacks_t; |
---|
| 265 | |
---|
| 266 | /* print server into to stdout */ |
---|
| 267 | void esd_print_server_info( esd_server_info_t *server_info ); |
---|
| 268 | void esd_print_player_info( esd_player_info_t *player_info ); |
---|
| 269 | void esd_print_sample_info( esd_sample_info_t *sample_info ); |
---|
| 270 | /* print all info to stdout */ |
---|
| 271 | void esd_print_all_info( esd_info_t *all_info ); |
---|
| 272 | |
---|
| 273 | /* retrieve server properties (sample rate, format, version number) */ |
---|
| 274 | esd_server_info_t *esd_get_server_info( int esd ); |
---|
| 275 | /* release all memory allocated for the server properties structure */ |
---|
| 276 | void esd_free_server_info( esd_server_info_t *server_info ); |
---|
| 277 | |
---|
| 278 | /* retrieve all information from server */ |
---|
| 279 | esd_info_t *esd_get_all_info( int esd ); |
---|
| 280 | |
---|
| 281 | /* retrieve all information from server, and update until unsubsribed or closed */ |
---|
| 282 | esd_info_t *esd_subscribe_all_info( int esd ); |
---|
| 283 | |
---|
| 284 | /* call to update the info structure with new information, and call callbacks */ |
---|
| 285 | esd_info_t *esd_update_info( int esd, esd_info_t *info, |
---|
| 286 | esd_update_info_callbacks_t *callbacks ); |
---|
| 287 | esd_info_t *esd_unsubscribe_info( int esd ); |
---|
| 288 | |
---|
| 289 | /* release all memory allocated for the esd info structure */ |
---|
| 290 | void esd_free_all_info( esd_info_t *info ); |
---|
| 291 | |
---|
| 292 | |
---|
| 293 | /* reset the volume panning for a stream */ |
---|
| 294 | int esd_set_stream_pan( int esd, int stream_id, |
---|
| 295 | int left_scale, int right_scale ); |
---|
| 296 | |
---|
| 297 | /* reset the default volume panning for a sample */ |
---|
| 298 | int esd_set_default_sample_pan( int esd, int sample_id, |
---|
| 299 | int left_scale, int right_scale ); |
---|
| 300 | |
---|
| 301 | /* see if the server is in stnaby, autostandby, etc */ |
---|
| 302 | esd_standby_mode_t esd_get_standby_mode( int esd ); |
---|
| 303 | |
---|
| 304 | |
---|
| 305 | /*******************************************************************/ |
---|
| 306 | /* esdfile.c - audiofile wrappers for sane handling of files */ |
---|
| 307 | |
---|
| 308 | int esd_send_file( int esd, AFfilehandle au_file, int frame_length ); |
---|
| 309 | int esd_play_file( const char *name_prefix, const char *filename, int fallback ); |
---|
| 310 | int esd_file_cache( int esd, const char *name_prefix, const char *filename ); |
---|
| 311 | |
---|
| 312 | |
---|
| 313 | /*******************************************************************/ |
---|
| 314 | /* audio.c - abstract the sound hardware for cross platform usage */ |
---|
| 315 | extern esd_format_t esd_audio_format; |
---|
| 316 | extern int esd_audio_rate; |
---|
| 317 | extern char *esd_audio_device; |
---|
| 318 | |
---|
| 319 | const char *esd_audio_devices( void ); |
---|
| 320 | int esd_audio_open( void ); |
---|
| 321 | void esd_audio_close( void ); |
---|
| 322 | void esd_audio_pause( void ); |
---|
| 323 | int esd_audio_write( void *buffer, int buf_size ); |
---|
| 324 | int esd_audio_read( void *buffer, int buf_size ); |
---|
| 325 | void esd_audio_flush( void ); |
---|
| 326 | |
---|
[18232] | 327 | /******************************************************************/ |
---|
| 328 | /* util.c utilities */ |
---|
| 329 | |
---|
[21329] | 330 | const char *esd_get_socket_dirname( void ); |
---|
| 331 | const char *esd_get_socket_name( void ); |
---|
[18232] | 332 | |
---|
[21329] | 333 | int have_ipv6( void ); |
---|
[18232] | 334 | |
---|
[15362] | 335 | #ifdef __cplusplus |
---|
| 336 | } |
---|
| 337 | #endif |
---|
| 338 | |
---|
| 339 | |
---|
| 340 | #endif /* #ifndef ESD_H */ |
---|