1 /*
2 ********************************************************************************
3 File: wav2cdr.h
4 
5 Tab size:           4
6 Max line length:    80
7 Programmer:         Volker Kuhlmann
8 
9 
10 wav2cdr 2.3.4 Copyright (C) 1997, 1998, 1999, 2000, 2006 Volker Kuhlmann
11 This program is free software under the terms of the GNU General Public License
12 version 2 (or later, at your option).
13 See the file COPYING for details about license terms and warranty.
14 <VolkerKuhlmann@gmx.de>
15 
16 
17 DESCRIPTION:
18 
19 Header for the wav2cdr program. See wav2cdr.c for more.
20 
21 
22 CONDITIONALS:
23 	see wav2cdr.c
24 
25 
26 HISTORY:
27 	see wav2cdr.c
28 
29 ********************************************************************************
30 */
31 
32 
33 
34 #include <limits.h>
35 #include <stddef.h>
36 #include <stdio.h>
37 
38 #include "chelp.h"
39 
40 
41 
42 /*
43 	cdr file format
44 	Audio-CDs (CD-DA) and Data CDs
45 	size of a sector, and the whole CD, in bytes
46 */
47 #define CDSECTORSPERSEC 75
48 #define CDSIZEINSECTORS (74L * 60 * CDSECTORSPERSEC)
49 /* sizes in bytes: */
50 #define CDAUDIOSECTORSIZE 2352
51 #define CDDATASECTORSIZE 2048
52 #define CDAUDIOSIZE (CDSIZEINSECTORS * CDAUDIOSECTORSIZE)
53 #define CDDATASIZE (CDSIZEINSECTORS * CDDATASECTORSIZE)
54 #define CDAUDIOBYTESPERSEC (CDSECTORSPERSEC * CDAUDIOSECTORSIZE)
55 /* sampling rate in samples per second:
56       CDSECTORSPERSEC        75
57 	* CDAUDIOSECTORSIZE    * 2352
58 	/ channels             / 2
59 	/ bytes-per-channel    / 2     */
60 #define CDAUDIOSAMPLINGRATE 44100L
61 
62 
63 /*
64 	wav file format
65 */
66 typedef struct {
67 	char id[4];					/* watch char order! */
68 	UINT32 size;				/* size of the chunk of stuff following, excl
69 									the 8 bytes of this chunk header */
70 } wav_chunkheader_t;
71 
72 typedef struct {
73 	/* RIFF header: */
74 	wav_chunkheader_t RIFF;		/* "RIFF", size is that of fmt header + chunk,
75 									 + header of data chunk */
76 	char wavename[4];			/* "WAVE" */
77 	/* Format header: */
78 	wav_chunkheader_t Format;	/* "fmt ", size is that of fmt chunk only */
79 	UINT16 FormatTag;			/* 1 (PCM) */
80 	UINT16 channels;			/* 1, 2, 4 */
81 	UINT32 SamplingRate;
82 	UINT32 AvgBytesPerSec;
83 	UINT16 BlockAlignment;		/* 1, 2, 4 */
84 	UINT16 BitsPerSample;		/* 8, 16 */
85 	/* Sampla data header: */
86 	wav_chunkheader_t Data;		/* "data", size is that of the data */
87 	/*unsigned char bytes[44];*/
88 } wav_header_t;
89 
90 
91 /* debug output */
92 #ifdef DEBUG
93   extern FILE *dbgfile;
94   #define DBGPRINTF0(fmt) fprintf (dbgfile, fmt)
95   #define DBGPRINTF1(fmt,v1) fprintf (dbgfile, fmt, v1)
96   #define DBGPRINTF2(fmt,v1,v2) fprintf (dbgfile, fmt, v1, v2)
97   #define DBGPRINTF3(fmt,v1,v2,v3) fprintf (dbgfile, fmt, v1, v2, v3)
98   #define STRNULL(charptr) ((charptr) == NULL ? "(NULL)" : (charptr))
99 #else
100   #define DBGPRINTF0(fmt)
101   #define DBGPRINTF1(fmt,v1)
102   #define DBGPRINTF2(fmt,v1,v2)
103   #define DBGPRINTF3(fmt,v1,v2,v3)
104 #endif
105 
106 
107 /*
108 	Expressions and functions for byte-swapping, implemented as macros
109 */
110 #define BYTES2SWAPPED(val) (\
111 		  (((val) >> 8) BITAND 0x00ff) \
112 	BITOR ((val) << 8) \
113 	)
114 #define BYTES4SWAPPED(val) (\
115 	      (((val) >> 24) BITAND 0x000000ffUL) \
116 	BITOR (((val) >>  8) BITAND 0x0000ff00UL) \
117 	BITOR (((val) <<  8) BITAND 0x00ff0000UL) \
118 	BITOR ((val) << 24) \
119 	)
120 #define WORDS2SWAPPED(val) (\
121 		  (((val) >> 16) BITAND 0x0000ffffUL) \
122 	BITOR ((val) << 16)\
123 	)
124 #define SWAP2BYTES(arg) (arg) = BYTES2SWAPPED ((arg))
125 #define SWAP4BYTES(arg) (arg) = BYTES4SWAPPED ((arg))
126 #define SWAP2WORDS(arg) (arg) = WORDS2SWAPPED ((arg))
127 
128 
129 /* turn a pointer into a pointer to a certain sized signed(!) integer */
130 #define AS_S16(bufptr) ((SINT16 *) bufptr)
131 #define AS_S32(bufptr) ((SINT32 *) bufptr)
132 
133 
134 /* max num of characters in a path name, Unix systems have this in limits.h? */
135 #ifndef PATH_MAX
136 #define PATH_MAX 1024
137 #endif
138 
139 
140 /* strings for std io names */
141 #define STRSTDIN(ptr) ((ptr) == NULL ? "(stdin)" : (ptr))
142 #define STRSTDOUT(ptr) ((ptr) == NULL ? "(stdout)" : (ptr))
143 #define STRSTDERR(ptr) ((ptr) == NULL ? "(stderr)" : (ptr))
144 
145 
146 /* Borland C 3.1 under MSDOS does not allow to have large variables (2k or
147 	so) local to functions. Declare those static. */
148 #ifdef MSDOS_BC
149 #define BORCRAP_largevar static
150 #else
151 #define BORCRAP_largevar
152 #endif
153 
154 
155 /* I/O buffer */
156 /* functions in here assume:
157 	BUFSIZE is divisable by 4!
158 	BUFSIZE >= WAVHEADERSIZE!
159 	BUFSIZE >= CDAUDIOSECTORSIZE!
160 */
161 /*#define BUFSIZE (CDAUDIOSECTORSIZE)
162   #if BUFSIZE != (4*(BUFSIZE/4))
163   #error BUFSIZE must be divisable by 4!
164   #endif
165   #if BUFSIZE < WAVHEADERSIZE
166   #error BUFSIZE must be >= WAVHEADERSIZE!
167   #endif
168   #if BUFSIZE < CDAUDIOSECTORSIZE
169   #error BUFSIZE must be >= CDAUDIOSECTORSIZE!
170   #endif*/
171 typedef union {
172 	UINT8  i8 [CDAUDIOSECTORSIZE];
173 	SINT16 i16[CDAUDIOSECTORSIZE/2];
174 	UINT32 i32[CDAUDIOSECTORSIZE/4];
175 } audiosect_t;
176 
177 
178 /* program exit codes */
179 typedef enum {
180 	ERR_OK = 0,		/* successful completion */
181 	ERR_USAGE,		/* usage or help requested + displayed */
182 	ERR_CMDARG,		/* error with a cmd arg, syntax, or missing parameter */
183 	ERR_IO,			/* I/O error */
184 	ERR_NOMEM,		/* memory allocation failed */
185 	ERR_INTERNAL	/* internal error (shouldn't happen ;-) )*/
186 } exit_t;
187 
188 
189 /* max scale factor (more than 16 bit makes little sense; also limited by
190 	process_t->iscale) */
191 #define SCALE_MAX SHRT_MAX
192 #define SCALE_MIN SHRT_MIN
193 
194 
195 /* the result of command line parameter scanning */
196 
197 typedef enum {
198 	AF_default, AF_raw, AF_cdr, AF_wav, AF_err
199 } audioformat_t;
200 
201 #define AF_NAMEIDX {"dflt", "raw", "cdr", "wav", "???"}
202 
203 typedef struct {
204 	BOOL little_input;		/* input data is little endian */
205 	BOOL little_output;		/* output data as little endian */
206 	signed long iscale;		/* scale factor for signal level,
207 								integer arithmetic, 100 = no scaling
208 								(big size for range checking, allow negative) */
209 	float fscale;			/* scale factor for input data,
210 								floating point arithmetic, 1.0 = no scaling */
211 	BOOL swapwords;			/* swap halves of a 32-bit word, i.e. channels */
212 	BOOL monostereo;		/* convert to mono then to stereo */
213 	BOOL silencecuts;		/* find cut numbers for silent intervals */
214 	BOOL silenceinfo;		/* as silencecuts, but print more info */
215 	long silence_thresh; 	/* silence cuts: see process_t */
216 	long silence_delay; 	/* silence cuts: see process_t */
217 	unsigned long fadein;	/* fade in at the start, in bytes */
218 	unsigned long fadeout;	/* fade in out the end, in bytes */
219 	audioformat_t informat;	/* input file format */
220 	audioformat_t outformat;/* output file format */
221 	unsigned long startsilence;	/* silence to add at start, in bytes */
222 	unsigned long endsilence;	/* silence to add at end, in bytes */
223 	string *infilename;		/* input filename */
224 	string *outfilename;	/* output filename */
225 	int numcuts;			/* number of cut positions */
226 	string **cutstarts;		/* array of the cut positions */
227 	BOOL version;			/* version requested */
228 	BOOL usage;				/* usage requested */
229 	BOOL help;				/* help requested */
230 	BOOL quiet; 			/* no messages */
231 	BOOL verbose; 			/* more messages / more output */
232 } cmdarg_t;
233 
234 /* default values and initialisation: */
235 #define CMDARG_DEFAULT \
236 	{\
237 		TRUE, FALSE,\
238 		100, 1.0,\
239 		FALSE, FALSE, FALSE, FALSE, 10, 30, 0, 0,\
240 		AF_wav, AF_cdr, 0, 0,\
241 		NULL, NULL,\
242 		0, NULL,\
243 		FALSE, FALSE, FALSE, FALSE, FALSE\
244 	}
245 #define RAW_FORMAT_DEFAULT_IS_LITTLE FALSE
246 
247 
248 /*
249 	Operations which can be done on a sector/block of the data
250 
251 	Buffer sizes are declared with type size_t; on systems where that is only
252 	16 bit (32 k bytes - 1) will be the largets sector size which can be
253 	processed. System library functions (e.g. string.h) can not handle more
254 	than size_t.
255 
256 	This is kind of extendible, by adding more values at the end of the
257 	structure. Making it extendible without having to change the struct every
258 	time would require function pointers. In that case - how to pass args? (e.g.
259 	threshold to silencecuts?)
260 */
261 
262 #define PROCESS_MAX_MULTIPLY 2
263 
264 typedef enum {
265 	MS_NONE, MS_TOMONO, MS_TOSTEREO, MS_TOMONOSTEREO
266 } monostereo_t;
267 
268 /* type counting CD sectors; this must be >=32 bit, so we can't use size_t as
269 	that may only be int which may only be 16 bit (e.g. Borland C 5) */
270 typedef unsigned long cdseccount_t;
271 
272 /*
273 	Information for processing 1 block of data.
274 	Some of the variables will be modified during processing and returned!
275 */
276 typedef struct {
277 	size_t n_in;			/* number of bytes in buffer */
278 	size_t n_returned;		/* number of bytes returned by operation,
279 								this can be PROCESS_MAX_MULTIPLY times larger
280 								than n_in!! */
281 	/* Is it useful to have the buffer pointer in here too? Or 2 pointers, for
282 		source and destination buffer?
283 		Currently buffer ptr is passed as func arg, and data is written back
284 		to source buffer */
285 	BOOL first; 			/* this is the first block to process
286 								not yet used, but will be necessary for re-
287 								entrant code;
288 								or better use an initialisation function? */
289 	/*
290 	short id; or better: callerid_t caller_id; ?
291 	for shared libraries - to identify the caller? together with init function?
292 	*/
293 	BOOL last;				/* this will be the last block to process */
294 	BOOL little_host;		/* host is little endian */
295 	BOOL from_little;		/* input data is little endian */
296 	BOOL to_little;			/* generate little endian data */
297 	signed short iscale;	/* scale values to this many %; only 16 bit! */
298 	float fscale;			/* scale values by this factor */
299 	BOOL swap_channels;		/* swap first (left) and second (right) channel */
300 	monostereo_t monostereo;/* convert to mono/stereo */
301 	BOOL silencecuts;		/* find cut numbers, cutting at silent intervals */
302 	unsigned short silence_thresh; 	/* silence cuts: threshold */
303 	unsigned short silence_delay;	/* silence cuts: num of blocks required to
304 										be below the threshold */
305 	BOOL silence_val;		/* silence cuts: return silence value of sector */
306 	cdseccount_t fadein;	/* level of fade-in / fade-out for THIS sector */
307 	cdseccount_t fadeout;	/* 1..100, 0 = no fading; these variables are
308 							   modified during processing and must keep value
309 							   from one call to the next! */
310 } process_t;
311 
312 
313 
314 /*
315 	function prototypes
316 */
317 /* in wav2cdr.c */
318 void version (void);
319 void usage (void);
320 void help (void);
321 void exit_error (exit_t err, const char *errtext, const char *errtext2);
322 BOOL is_localhost_little (void);
323 int timeprintf (string *buf, unsigned long bytes);
324 #define TIMESTRSIZE (10 + 5/*safe*/)
325 int main (int argc, char *argv[]);
326 
327 /* in cmdarg.c */
328 void scan_cmd_args (int argc, char **argv);
329 void set_message_output (void);
330 void check_cmd_args (void);
331 void showcmdargs (void);
332 signed long get_input_size_in_cd_blocks (void);
333 unsigned long get_cut_value (int n);
334 unsigned long get_silence_value (const string *s);
335 void get_cmdarg_info (cmdarg_t *pcmdarg);
336 void init_process_info (process_t *pinfo);
337 
338 /* in data.c */
339 void open_out (int track);
340 void close_out (void);
341 int get_af_header_size (audioformat_t af);
342 void read_header (void);
343 void write_header (void);
344 void write_trailer (void);
345 void add_silence (unsigned long bytes);
346 BOOL copy_sector_check_file (void);
347 BOOL got_silence_number (char **pstr, UINT16 *ps);
348 BOOL got_cut_number (char **pstr, unsigned long *pi);
349 void sprint_cutinfo (void *buffer, unsigned long start, unsigned long end,
350 						BOOL is_audio_interval);
351 void silence_info (void *buffer, BOOL eof);
352 void handle_sectors (void);
353 void do_data_io (void);
354 
355 /* in fileio.c */
356 void open_input_file (const string *name);
357 void close_input_file (void);
358 signed long get_file_size (const string *name, FILE *stream);
359 void open_output_file (const string *name, int track);
360 void close_output_file (void);
361 FILE *open_message_file (void);
362 void close_message_file (void);
363 void emergency_close (void);
364 void read_wav_header (wav_header_t *header);
365 void make_wav_header (wav_header_t *header, unsigned long databytes);
366 void write_wav_header (const wav_header_t *header);
367 size_t read_block (void *buf, size_t bytes);
368 BOOL read_eof (void);
369 size_t write_block (const void *buf, size_t bytes);
370 
371 /* in process.c */
372 void process_swap_bytes (void * buf, process_t *pinfo);
373 void process_swap_words (void * buf, process_t *pinfo);
374 void process_swap_tolocal (void * buf, process_t *pinfo);
375 void process_swap_totarget (void * buf, process_t *pinfo);
376 void process_tomono (void * buf, process_t *pinfo);
377 void process_tostereo (void * buf, process_t *pinfo);
378 void process_tomonostereo (void * buf, process_t *pinfo);
379 void process_swap_iscale (void * buf, process_t *pinfo);
380 void process_swap_fscale (void * buf, process_t *pinfo);
381 void process_swap_noscale (void * buf, process_t *pinfo);
382 void process_fading (void * buf, process_t *pinfo);
383 void process_silencecuts (void * buf, process_t *pinfo);
384 void process_sector (void *buf, process_t *pinfo);
385 
386 
387 
388 /* EOF wav2cdr.h */
389 /******************************************************************************/
390