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 */
10 #define ESD_UNIX_SOCKET_DIR	esd_get_socket_dirname()
11 #define ESD_UNIX_SOCKET_NAME	esd_get_socket_name()
12 
13 /* size of the audio buffer */
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 
327 /******************************************************************/
328 /* util.c utilities						  */
329 
330 const char *esd_get_socket_dirname( void );
331 const char *esd_get_socket_name( void );
332 
333 int have_ipv6( void );
334 
335 #ifdef __cplusplus
336 }
337 #endif
338 
339 
340 #endif /* #ifndef ESD_H */
341