1 /* $Header: /home/cvs/wavplay/wavplay.h,v 1.3 1999/12/04 00:05:34 wwg Exp $
2  * Warren W. Gay VE3WWG		Sun Feb 16 18:17:17 1997
3  *
4  * WAVPLAY OPTION SETTINGS:
5  *
6  * 	X LessTif WAV Play :
7  *
8  * 	Copyright (C) 1997  Warren W. Gay VE3WWG
9  *
10  * This  program is free software; you can redistribute it and/or modify it
11  * under the  terms  of  the GNU General Public License as published by the
12  * Free Software Foundation version 2 of the License.
13  *
14  * This  program  is  distributed  in  the hope that it will be useful, but
15  * WITHOUT   ANY   WARRANTY;   without   even  the   implied   warranty  of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
17  * Public License for more details (see enclosed file COPYING).
18  *
19  * You  should have received a copy of the GNU General Public License along
20  * with this  program; if not, write to the Free Software Foundation, Inc.,
21  * 675 Mass Ave, Cambridge, MA 02139, USA.
22  *
23  * Send correspondance to:
24  *
25  * 	Warren W. Gay VE3WWG
26  *
27  * Email:
28  *	ve3wwg@yahoo.com
29  *	wgay@mackenziefinancial.com
30  *
31  * $Log: wavplay.h,v $
32  * Revision 1.3  1999/12/04 00:05:34  wwg
33  * Fixed release number
34  *
35  * Revision 1.2  1999/12/04 00:01:20  wwg
36  * Implement wavplay-1.4 release changes
37  *
38  * Revision 1.1.1.1  1999/11/21 19:50:56  wwg
39  * Import wavplay-1.3 into CVS
40  *
41  * Revision 1.4  1997/04/17 23:39:26  wwg
42  * Now at 1.0pl2 : attempting to fix Linux 2.0.29 compile problems
43  * with the way errno and sys_errlist[] are handled for thread
44  * safety.. here we removed our incompatible extern sys_errlist[]
45  *
46  * Revision 1.3  1997/04/17 01:59:37  wwg
47  * Added version change to reflect patch level "1.0pl1"
48  *
49  * Revision 1.2  1997/04/17 00:27:36  wwg
50  * Fixed references to the name errno. For thread safety
51  * this name has been macro-ized, which I should have
52  * anticipated, since I knew it was coming.
53  *
54  * Revision 1.1  1997/04/14 00:56:48  wwg
55  * Initial revision
56  *
57  */
58 #ifndef _wavplay_h_
59 #define _wavplay_h_ "$Id: wavplay.h,v 1.3 1999/12/04 00:05:34 wwg Exp $"
60 
61 #define WAVPLAY_VERSION		"1.4"
62 
63 #include <stdarg.h>
64 #include <sys/types.h>
65 #include <sys/ipc.h>
66 #include <sys/stat.h>
67 
68 /*
69  * From the man page semctl(2) :
70  */
71 #if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
72 	/* union semun is defined by including <sys/sem.h> */
73 #else
74 	/* according to X/OPEN we have to define it ourselves */
75 	union semun {
76 		int		val;		/* value for SETVAL */
77 		struct semid_ds	*buf;		/* buffer for IPC_STAT, IPC_SET */
78 		unsigned short	*array;		/* array for GETALL, SETALL */
79 		struct seminfo	*__buf;		/* buffer for IPC_INFO */
80 	};
81 #endif
82 
83 typedef void (*ErrFunc)(const char *format,va_list ap);
84 
85 #include "wavfile.h"
86 
87 /*
88  * Default location of the wavplay server program if not overrided by the Makefile
89  */
90 #ifndef WAVPLAYPATH
91 #define WAVPLAYPATH "/usr/local/bin/wavplay"	/* Default location of wavplay server */
92 #endif
93 
94 /*
95  * Default pathname for recordings if not overriden by the Makefile:
96  */
97 #ifndef RECORD_PATH
98 #define RECORD_PATH "recorded.wav"
99 #endif
100 
101 /*
102  * Default lowest sampling rate unless overriden by the Makefile:
103  */
104 #ifndef DSP_MIN
105 #define DSP_MIN		4000			/* Lowest acceptable sample rate */
106 #endif
107 
108 /*
109  * Default maximum sampling rate unless overrided by the Makefile:
110  */
111 #ifndef DSP_MAX
112 #define DSP_MAX		48000			/* Highest acceptable sample rate */
113 #endif
114 
115 /*
116  * Default pathname of the audio device, unless overrided by the Makefile:
117  */
118 #ifndef AUDIODEV
119 #define AUDIODEV	"/dev/dsp"		/* Default pathname for audio device */
120 #endif
121 
122 /*
123  * Default locking semaphore IPC Key, unless overrided by the Makefile:
124  */
125 #ifndef AUDIOLCK
126 #define AUDIOLCK	0x33333333		/* Default IPC Key for semaphores */
127 #endif
128 
129 /*
130  * Short option flag characters:
131  */
132 #define OPF_DEVICE      'd'                     /* -d device ; Override /dev/dsp default */
133 #define OPF_INFO	'i'			/* -i ; info mode option */
134 #define OPF_HELP	'h'			/* -h ; help optino */
135 #define OPF_QUIET	'q'			/* -q ; quiet mode */
136 #define OPF_SAMPRATE	's'			/* -s rate ; Sampling rate */
137 #define OPF_STEREO	'S'			/* -S ; Stereo */
138 #define OPF_MONO	'M'			/* -M ; Mono */
139 #define OPF_TIME	't'			/* -t seconds ; Time option */
140 #define OPF_DATABITS	'b'			/* -b data_bits; sample bits */
141 #define OPF_IPCKEY	'k'			/* -k key ; IPC Key */
142 #define OPF_RESET	'R'			/* -r ; reset semaphores option */
143 #define OPF_PLAY_LOCK	'l'			/* -l ; lock for play option */
144 #define OPF_PLAY_UNLOCK	'u'			/* -u ; unlock play option */
145 #define OPF_RECD_LOCK	'L'			/* -L ; lock for record option */
146 #define OPF_RECD_UNLOCK	'U'			/* -U ; unlock record option */
147 #define OPF_DEBUG	'x'			/* -x ; debug option */
148 #define OPF_VERSION	'V'			/* -V ; version and copyright */
149 
150 /*
151  * Types internal to wavplay, in an attempt to isolate ourselves from
152  * a dependance on a particular platform.
153  */
154 typedef unsigned char Byte;
155 typedef short Int16;
156 typedef long Int32;
157 typedef unsigned long UInt32;
158 typedef unsigned short UInt16;
159 
160 /*
161  * This value sets buffer sizes for temporary buffers that sprintf()
162  * uses, and for copying pathnames around in. You probably don't want
163  * to mess with this.
164  */
165 #define MAXTXTLEN	2048			/* Must allow for long pathnames */
166 
167 /*
168  * These are the wavplay command operation modes.
169  */
170 typedef enum {
171 	OprNoMode=0,				/* No mode given (not determined yet) */
172 	OprRecord=1,				/* wavplay command is in "Record Mode" */
173 	OprPlay=2,				/* wavplay command is in "Play Mode" */
174 	OprServer=3,				/* wavplay is accting in "Server Mode" */
175 } OprMode;
176 
177 /*
178  * This enumerated type, selects between monophonic sound and
179  * stereo sound (1 or 2 channels).
180  */
181 typedef enum {
182 	Mono,					/* Monophonic sound (1 channel) */
183 	Stereo					/* Stereo sound (2 channels) */
184 } Chan;
185 
186 /*
187  * This type is used for those options that can be one or another
188  * option flags (represented as the ASCII character), or no option
189  * flags at all (zero value, ie. 0x00).
190  */
191 typedef struct {
192 	char	optChar;			/* Option character */
193 } FlgOpt;
194 
195 /*
196  * This type represents any unsigned 32 bit option value, if the member
197  * optChar is non-zero (usually holds the ASCII flag option character).
198  * If optChar is zero, then no value is present (or specified).
199  */
200 typedef struct {
201 	char	optChar;			/* Zero if not valid, else non-zero if active */
202 	UInt32	optValue;			/* The unsigned 32 bit value if optChar is true */
203 } U32Opt;
204 
205 typedef struct {
206 	char	optChar;			/* Zero if not valid, else non-zero if active */
207 	UInt16	optValue;			/* The unsigned 16 bit value if optChar is true */
208 } U16Opt;
209 
210 typedef struct {
211 	char	optChar;			/* Zero if not valid, else non-zero if active */
212 	Chan	optValue;			/* The enumerated value for Stereo/Mono */
213 } ChnOpt;
214 
215 /*
216  * This structure holds the command line options for the wavplay command.
217  * It is also used to pass option values around (in server mode etc.)
218  */
219 typedef struct {
220 	key_t	IPCKey;				/* Default IPC Key for lock */
221 	OprMode	Mode;				/* Operation Mode: OprRecord or OprPlay */
222 	FlgOpt	PlayLock;			/* -l or -u option flag */
223 	FlgOpt	RecdLock;			/* -L or -U option flag */
224 	char	bResetLocks;			/* True if semaphores are to be reset */
225 	char	bQuietMode;			/* True if quiet mode is requested */
226 	char	bInfoMode;			/* True if only wav header info is to be printed */
227 	U32Opt	SamplingRate;			/* -s rate ; sampling rate in Hz */
228 	ChnOpt	Channels;			/* -S ; or no -S option (stereo/mono respectively) */
229 	U16Opt	DataBits;			/* -b bits ; number of bits per sample */
230 	UInt32	Seconds;			/* Time limited to this many seconds, else zero */
231         UInt32  StartSample;                    /* Sample to start playback with */
232 	int	ipc;				/* Semaphore IPC ID */
233 } WavPlayOpts;
234 
235 /*
236  * These values represent values found in/or destined for a
237  * WAV file.
238  */
239 typedef struct {
240 	UInt32	SamplingRate;			/* Sampling rate in Hz */
241 	Chan	Channels;			/* Mono or Stereo */
242 	UInt32	Samples;			/* Sample count */
243 	UInt16	DataBits;			/* Sample bit size (8/12/16) */
244 	UInt32	DataStart;			/* Offset to wav data */
245 	UInt32	DataBytes;			/* Data bytes in current chunk */
246 	char	bOvrSampling;			/* True if sampling_rate overrided */
247 	char	bOvrMode;			/* True if chan_mode overrided */
248 	char	bOvrBits;			/* True if data_bits is overrided */
249 } WAVINF;
250 
251 /*
252  * This structure manages an open WAV file.
253  */
254 typedef struct {
255 	char	rw;				/* 'R' for read, 'W' for write */
256 	char	*Pathname;			/* Pathname of wav file */
257 	int	fd;				/* Open file descriptor or -1 */
258 	WAVINF	wavinfo;			/* WAV file hdr info */
259         UInt32  num_samples;                    /* Total number of samples */
260         UInt32  StartSample;                    /* First sample to play */
261 } WAVFILE;
262 
263 /*
264  * This macro is used to return the system file descriptor
265  * associated with the open WAV file, given a (WAVFILE *).
266  */
267 #define WAV_FD(wfile) (wfile->fd)		/* Return file descriptor */
268 
269 /*
270  * This structure manages an opened DSP device.
271  */
272 typedef struct {
273 	int	fd;				/* Open fd of /dev/dsp */
274 	int	dspblksiz;			/* Size of the DSP buffer */
275 	char	*dspbuf;			/* The buffer */
276 } DSPFILE;
277 
278 /*
279  * This structure manages server information and state:
280  */
281 typedef struct {
282 	UInt32	SamplingRate;			/* Sampling rate in Hz */
283 	Chan	Channels;			/* Mono or Stereo */
284 	UInt32	Samples;			/* Sample count */
285 	UInt16	DataBits;			/* Sample bit size (8/12/16) */
286 	char	WavType[16];			/* "PCM" */
287 	char	bOvrSampling;			/* True if sampling is overrided */
288 	char	bOvrMode;			/* True if mode is overrided */
289 	char	bOvrBits;			/* True if bits is overrided */
290 } SVRINF;
291 
292 /*
293  * This is the function type that is called between blocks
294  * of I/O with the DSP.
295  */
296 typedef int (*DSPPROC)(DSPFILE *dfile);		/* DSP work procedure */
297 
298 /*
299  * Client/Server Message Types. These definitions must be coordinated with
300  * source module msg.c, function msg_name(), for their corresponding
301  * message texts.
302  */
303 typedef enum {
304 	ToClnt_Fatal=0,				/* Fatal server error */
305 	ToClnt_Ready=1,				/* Tell client that server is ready */
306 	ToSvr_Bye=2,				/* Client tells server to exit */
307 	ToSvr_Path=3,				/* Client tells server a pathname */
308 	ToClnt_Path=4,				/* Client tells server a pathname */
309 	ToClnt_Stat=5,				/* Response: Svr->Clnt to ToSvr_Path */
310 	ToClnt_WavInfo=6,			/* Server tells client wav info */
311 	ToSvr_Play=7,				/* Client tells server to play */
312 	ToSvr_Pause=8,				/* Tell server to pause */
313 	ToSvr_Stop=9,				/* Tell server to stop */
314 	ToSvr_Bits=10,				/* Tell server to use 8 bits */
315 	ToClnt_Bits=11,				/* Server tells what bit setting is in effect */
316 	ToClnt_Settings=12,			/* Current server settings */
317 	ToSvr_SamplingRate=13,			/* Tell server new sampling rate */
318 	ToSvr_Restore=14,			/* Clear overrides: restore original settings */
319 	ToSvr_Chan=15,				/* Change Stereo/Mono mode */
320 	ToSvr_Record=16,			/* Tell server to start recording */
321 	ToSvr_Debug=17,				/* Tell server debug mode setting */
322 	ToClnt_ErrMsg=18,			/* Pass back to client, an error message string */
323 	ToSvr_SemReset=19,			/* Reset locking semaphores */
324         ToSvr_StartSample=20,                   /* Start playback at requested sample */
325         ToClnt_PlayState=21,                    /* Playback status */
326         ToClnt_RecState=22,                     /* Record status */
327         MSGTYP_Last=23,                         /* This is not really a message type */
328 } MSGTYP;
329 
330 /*
331  * Client/Server Message Structure: This consists of a common header
332  * component, and then a union of specific format variations according
333  * to the message type.
334  */
335 typedef struct {
336 	long	type;				/* Message Type: 1=server, 0=client */
337 	MSGTYP	msg_type;			/* Client/Server message type */
338 	UInt16	bytes;				/* Byte length of the union */
339 	union	{
340 
341 		/*
342 		 * Message from server to client, to convey a fatal error that
343 		 * has occured in the server.
344 		 */
345 		struct	{
346 			int	Errno;		/* Error code */
347 			char	msg[128];	/* Error message text */
348 		} toclnt_fatal;
349 
350 		/*
351 		 * Message from the X client, to the server, to indicate that
352 		 * a new pathname is to be referenced.
353 		 */
354 		struct	{
355 			char	path[1024];	/* Pathname */
356 		} tosvr_path;			/* Tell server a pathname */
357 
358 		/*
359 		 * Message from the server to the X client, to indicate
360 		 * that the indicated pathname has been accepted and
361 		 * ready (the pathname may be canonicalized at some future
362 		 * revision of the server)
363 		 */
364 		struct	{
365 			char	path[1024];	/* Pathname */
366 		} toclnt_path;			/* ..from server as confirmation */
367 
368 		/*
369 		 * Message to X client, from the server, indicating a
370 		 * stat() error when Errno != 0, or stat() information
371 		 * when Errno == 0.
372 		 */
373 		struct	{
374 			int	Errno;		/* Zero if OK, else errno from stat() */
375 			struct stat sbuf;	/* Path's stat info */
376 		} toclnt_stat;
377 
378 		/*
379 		 * Message to X client, from server, indicating an
380 		 * error if errno != 0, or successfully obtained
381 		 * WAV file info if errno == 0.
382 		 */
383 		struct	{
384 			int	Errno;		/* Zero if OK, else errno value */
385 			WAVINF	wavinfo;	/* WAV file info */
386 			char	errmsg[256];	/* Error message */
387 		} toclnt_wavinfo;
388 
389 		/*
390 		 * Message from X client, to server, indicating how
391 		 * many bits per sample to use (request).
392 		 */
393 		struct	{
394 			int	DataBits;	/* 8/12/16 bit override requested */
395 		} tosvr_bits;
396 
397 		/*
398 		 * Message to X client, from server, indicating
399 		 * the accepted number of bits per sample (response
400 		 * to request).
401 		 */
402 		struct	{
403 			int	DataBits;	/* Server says this # of bits in effect */
404 		} toclnt_bits;
405 
406 		/*
407 		 * Message to X client, from server, indicating the
408 		 * current server settings.
409 		 */
410 		SVRINF	toclnt_settings;	/* Current server settings */
411 
412 		/*
413 		 * Message from X client, to server, indicating the
414 		 * requested sampling rate to use (request).
415 		 */
416 		struct S_SvrSampRate {
417 			UInt32	SamplingRate;	/* In Hz */
418 		} tosvr_sampling_rate;
419 
420 		/*
421 		 * Message from X client, to server, indicating the
422 		 * number of channels to use (request).
423 		 */
424 		struct	{
425 			Chan	Channels;	/* New channel mode: Stereo/Mono */
426 		} tosvr_chan;
427 
428                 /*
429                  * Message from X client, to server, indicating the sample to
430                  * start playback at (request).
431                  */
432                 struct  {
433                         UInt32  StartSample;    /* New origin */
434                 } tosvr_start_sample;
435 
436 		/*
437 		 * Message from X client, to server, indicating the
438 		 * channels to use, the sampling rate to use, and
439 		 * the data bits per channel to use (request).
440 		 */
441 		struct	{
442 			Chan	Channels;	/* Stereo or Mono */
443 			UInt32	SamplingRate;	/* Start recording at this rate */
444 			UInt16	DataBits;	/* 8/12/16 data bits */
445 		} tosvr_record;
446 
447 		/*
448 		 * Message from X client to server, to set the server's
449 		 * debug mode global (cmdopt_x).
450 		 */
451 		struct	{
452 			char	bDebugMode;	/* True if debug mode set, else not debug mode */
453 		} tosvr_debug;
454 
455 		/*
456 		 * Message from server to client, to convey a NON-fatal error that
457 		 * has occured in the server.
458 		 */
459 		struct	{
460 			int	Errno;		/* Error code */
461 			char	msg[512];	/* Error message text */
462 		} toclnt_errmsg;
463 
464                 /*
465                  * Message from server to client with playback status.
466                  */
467                 struct {
468                         int     CurrentSample;  /* Currently playing sample */
469                         int     SamplesLeft;    /* Samples left */
470                 } toclnt_playstate;
471 
472                 /*
473                  * Message from server to client with record status.
474                  */
475                 struct {
476                         int     bytes_written;  /* Number of bytes sampled */
477                         int     num_samples;    /* Samples taken */
478                 } toclnt_recstate;
479 	} u;					/* The message union of all message types */
480 } SVRMSG;
481 
482 extern char *ProcTerm(int procstat);
483 
484 extern int MsgCreate(void);
485 extern int MsgSend(int ipcid,SVRMSG *msg,int flags,long msgtype);
486 extern int MsgRecv(int ipcid,SVRMSG *msg,int flags,long msgtype);
487 extern int MsgClose(int ipcid);
488 extern char *msg_name(MSGTYP mtyp);
489 extern void msg_dump(const char *desc,MSGTYP mtyp);
490 
491 #define MSGNO_CLNT	3L
492 #define MSGNO_SRVR	2L
493 #define MsgToClient(ipcid,msg,flags) MsgSend(ipcid,msg,flags,MSGNO_CLNT)
494 #define MsgToServer(ipcid,msg,flags) MsgSend(ipcid,msg,flags,MSGNO_SRVR)
495 #define MsgFromClient(ipcid,msg,flags) MsgRecv(ipcid,msg,flags,MSGNO_SRVR)
496 #define MsgFromServer(ipcid,msg,flags) MsgRecv(ipcid,msg,flags,MSGNO_CLNT)
497 
498 extern int OpenDSPLocks(key_t LockIPCKey,int SemUndoFlag,ErrFunc erf);
499 extern int LockDSP(int ipc,int playrecx,ErrFunc erf,unsigned timeout_secs);
500 extern int UnlockDSP(int ipc,int playrecx,ErrFunc erf);
501 
502 extern WAVFILE *WavOpenForRead(const char *Pathname,ErrFunc erf);
503 extern WAVFILE *WavOpenForWrite(const char *Pathname,Chan chmode,UInt32 sample_rate,UInt16 bits,UInt32 samples,ErrFunc erf);
504 extern void WavReadOverrides(WAVFILE *wfile,WavPlayOpts *wavopts);
505 extern int WavClose(WAVFILE *wfile,ErrFunc erf);
506 
507 extern DSPFILE *OpenDSP(WAVFILE *wfile,int omode,ErrFunc erf);
508 extern int PlayDSP(DSPFILE *dfile,WAVFILE *wfile,DSPPROC work_proc,ErrFunc erf);
509 extern int RecordDSP(DSPFILE *dfile,WAVFILE *wfile,UInt32 samples,DSPPROC work_proc,ErrFunc erf);
510 extern int CloseDSP(DSPFILE *dfile,ErrFunc erf);
511 
512 extern int recplay(WavPlayOpts *wavopts,char **argv,ErrFunc erf);
513 extern int wavplay(WavPlayOpts *wavopts,char **argv,ErrFunc erf);
514 extern int wavrecd(WavPlayOpts *wavopts,char *Pathname,ErrFunc erf);
515 
516 extern void RegisterSigHandlers(void);
517 
518 extern char *env_WAVPLAYPATH;			/* Default pathname of executable /usr/local/bin/wavplay */
519 extern char *env_AUDIODEV;			/* Default compiled in audio device */
520 extern unsigned long env_AUDIOLCK;		/* Default compiled in locking semaphore */
521 
522 extern int cmdopt_x;				/* Debug option flag */
523 
524 #endif /* _wavplay_h_ */
525 
526 /* $Source: /home/cvs/wavplay/wavplay.h,v $ */
527