1 /*
2 ********************************************************************************
3 File: wav2cdr.c
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 Conversion utility for wav-files to files which can be written on a CD.
20 Reads from stdin, writes to stdout or file(s).
21 Can also read and write some raw formats.
22 Can perform various byte swapping operations as well as scaling of data,
23 and cutting the input into tracks.
24 Reading from file is not yet supported.
25 Call with -help for more info.
26 
27 Written with strict ANSI conformance.
28 Compiles without any problems with gcc under Solaris and Linux.
29 If you create Makefiles for other systems please send me a copy.
30 
31 
32 CONDITIONALS:
33 	NO_ASSERTMANY	Don't use so many asserts
34 	DEBUG			Writes some debugging output to msgfile.
35 	HAS_GNUGETOPT	The program will be linked with GNU getopt(). The GNU
36 					getopt.h must be available to the compiler. See the file
37 					README for details.
38 	MSDOS_BC		When compiling with Borland C under MSDOS.
39 
40 
41 HISTORY:
42 
43 2.1   03May98	See ChangeLog
44 2.0   25Mar98	Added silence detection and a few minor things.
45 1.9   20Jan98	Fixed bug in write_wav_header().
46 1.8   11Dec97	Put under GPL.
47 1.7   08Dec97	Cut number units, negative cut numbers, adding silence.
48 1.6   06Dec97	My own getopt.
49 1.5   05Dec97	Converting to mono/stereo. Minor changes.
50 1.4   02Dec97	Restructured, split into modules. It is now more flexible and
51 				extendible. wav headers are written correctly. Handling of
52 				system error strings fixed.
53 				Fixed a few bugs, probably introduced some.
54 1.3				You don't wanna know.
55 1.2   30Nov97	Writing wav files (preliminary).
56 1.1   29Nov97	Added execution time display. Fixed stdout bug. Simplified some
57 				lines.
58 1.0   28Nov97	First complete release.
59 0.3   26Nov97	Improved.
60 0.2   25Nov97	Commented, improved.
61 0.1   25Nov97	Created.
62 
63 ********************************************************************************
64 */
65 
66 
67 
68 #define PROGVERSION "Version 2.3.4  Copyright (C) 18 Jan 2006 by Volker Kuhlmann"
69 /*
70 #define PROGVERSION "Version 2.3.4  Copyright (C) 18 Jan 2006 by Volker Kuhlmann"
71 #define PROGVERSION "Version 2.3.3  Copyright (C) 27 Oct 2000 by Volker Kuhlmann"
72 #define PROGVERSION "Version 2.3.2  Copyright (C) 22 Aug 1999 by Volker Kuhlmann"
73 #define PROGVERSION "Version 2.3.1  Copyright (C) 18 Aug 1999 by Volker Kuhlmann"
74 #define PROGVERSION "Version 2.3  Copyright (C) 19 Jul 1999 by Volker Kuhlmann"
75 #define PROGVERSION "Version 2.2.2  Copyright (C) 07 Jun 1999 by Volker Kuhlmann"
76 #define PROGVERSION "Version 2.2.1  Copyright (C) 03 May 1999 by Volker Kuhlmann"
77 #define PROGVERSION "Version 2.2  Copyright (C) 21 Feb 1999 by Volker Kuhlmann"
78 #define PROGVERSION "Version 2.2  Copyright (C) 04 Feb 1999 by Volker Kuhlmann"
79 #define PROGVERSION "Version 2.1.2  Copyright (C) 03 Feb 1999 by Volker Kuhlmann"
80 #define PROGVERSION "Version 2.1  Copyright (C) 03 May 1998 by Volker Kuhlmann"
81 #define PROGVERSION "Version 2.0  Copyright (C) 27 Mar 1998 Volker Kuhlmann"
82 #define PROGVERSION "Version 2.0�3  Copyright (C) 18 Mar 1998 Volker Kuhlmann"
83 #define PROGVERSION "Version 2.0�2  Copyright (C) 13 Mar 1998 Volker Kuhlmann"
84 #define PROGVERSION "Version 2.0�  Copyright (C) 10 Mar 1998 Volker Kuhlmann"
85 #define PROGVERSION "Version 1.9  Copyright (C) 20 Jan 1998 Volker Kuhlmann"
86 #define PROGVERSION "Version 1.8  Copyright (C) 11 Dec 1997 Volker Kuhlmann"
87 #define PROGVERSION "Version 1.7  (C) VK 8 Dec 1997"
88 #define PROGVERSION "Version 1.6  (C) VK 6 Dec 1997"
89 #define PROGVERSION "Version 1.5  (C) VK 5 Dec 1997"
90 #define PROGVERSION "Version 1.5  (C) VK 4 Dec 1997"
91 */
92 
93 
94 
95 #include <stddef.h>
96 #include <stdlib.h>
97 #include <stdio.h>
98 #include <string.h>
99 #include <errno.h>
100 #include <limits.h>
101 #include <assert.h>
102 #include <time.h>
103 
104 #include "chelp.h"
105 
106 #include "wav2cdr.h"
107 
108 
109 /*
110 	Global + local variables
111 */
112 FILE
113 	*msgfile = NULL;	/* where to display cmd args and progress */
114 
115 #ifdef DEBUG
116 FILE
117 	*dbgfile = NULL;	/* where to display debug output */
118 #endif
119 						/* init these 2 to NULL just in case */
120 
121 
122 /*
123 	Local function prototypes
124 */
125 static void version_text (void);
126 
127 
128 
129 /*
130 	Display usage and exit.
131 	In: ---
132 */
version_text(void)133 static void version_text (void)
134 {
135 	fprintf (msgfile,
136 #include "version.-c"
137 	, PROGVERSION
138 #ifdef HAS_GNUGETOPT
139 	, "GNU getopt()"
140 #else
141 	, "mygetopt()"
142 #endif
143 	);
144 } /* version_text() */
145 
version(void)146 void version (void)
147 {
148 	version_text ();
149 	exit_error (ERR_USAGE, NULL, NULL);
150 } /* version() */
151 
152 
153 
154 /*
155 	Display usage and exit.
156 	In: ---
157 */
usage(void)158 void usage (void)
159 {
160 	version_text ();
161 	fprintf (msgfile,
162 #include "usage.-c"
163 	);
164 
165 	showcmdargs ();
166 	exit_error (ERR_USAGE, NULL, NULL);
167 
168 } /* usage() */
169 
170 
171 
172 /*
173 	Display help and exit.
174 	In: ---
175 */
help(void)176 void help (void)
177 {
178 	fprintf (msgfile,
179 #include "help.-c"
180 	, CDAUDIOSAMPLINGRATE
181 	, CDAUDIOSECTORSIZE
182 	, CDSECTORSPERSEC
183 	);
184 
185 	exit_error (ERR_USAGE, NULL, NULL);
186 
187 } /* help() */
188 
189 
190 
191 /*
192 	Display error msg and exit with error code.
193 	Also displays the system error text if error flag set.
194 	Close files still open (no error checking with that one).
195 	In: exit code, up to 2 error strings or NULL
196 	Out: ---
197 	Return: ---
198 */
exit_error(exit_t err,const char * errtext,const char * errtext2)199 void exit_error (exit_t err, const char *errtext, const char *errtext2)
200 {
201 	if (errtext != NULL) {
202 		fprintf (stderr, "wav2cdr: error: %s%s",
203 						errtext, errtext2 == NULL ? "" : errtext2);
204 	}
205 	if (err == ERR_IO) {
206 		if (errno != 0)
207 			fprintf (stderr, " (%s)", strerror (errno));
208 	}
209 	if (errtext != NULL  OR  err == ERR_IO)
210 		putc ('\n', stderr);
211 	if (err == ERR_CMDARG)
212 		fprintf (stderr,
213 			"Use -h or -u or --usage for usage, or --help for more help\n");
214 
215 	emergency_close (); /* emergency close files */
216 
217 	exit ((int) err);
218 
219 } /* exit_error() */
220 
221 
222 
223 /*
224 	In: ---
225 	Out: ---
226 	Return: endianness of local host (TRUE if little)
227 */
is_localhost_little(void)228 BOOL is_localhost_little (void)
229 {
230 UINT16 lclfmt = 1;
231 UINT8 *is_little = (UINT8 *) &lclfmt;
232 
233 	/* make sure this works */
234 	assert (sizeof(UINT16) == 2 * sizeof(UINT8));
235 
236 	#ifdef DEBUG
237 	#ifdef LITTLE_ENDIAN
238 	  return TRUE;
239 	#endif
240 	#ifdef BIG_ENDIAN
241 	  return FALSE;
242 	#endif
243 	#endif
244 
245 	/* test endianness of local machine */
246 	return (*is_little != 0);
247 
248 } /* is_localhost_little() */
249 
250 
251 
252 /*
253 	Format a time as "MM:SS.ss".
254 	In: buffer, time in (seconds * CDSECTORSPERSEC * CDAUDIOSECTORSIZE)
255 	Out: formatted time; at most 10 bytes (TIMESTRSIZE) incl '\0'
256 	Return: return value of sprintf
257 */
timeprintf(string * buf,unsigned long bytes)258 int timeprintf (string *buf, unsigned long bytes)
259 {
260 unsigned short
261 	m,			/* minutes */
262 	s,			/* seconds */
263 	fs; 		/* fractional second */
264 
265 	s = (bytes / CDAUDIOSECTORSIZE) / CDSECTORSPERSEC;
266 	fs = (bytes - (unsigned long) s * CDAUDIOBYTESPERSEC)
267 	     * 100 / ((unsigned long) CDAUDIOBYTESPERSEC);
268 	m = s / 60;
269 	s = s % 60;
270 
271 	return sprintf (buf, "%02d:%02d.%02d", m, s, fs);
272 
273 } /* timeprintf */
274 
275 
276 
main(int argc,char * argv[])277 int main (int argc, char *argv[])
278 {
279 	assert (sizeof(UINT8)  == 1);
280 	assert (sizeof(UINT16) == 2);
281 	assert (sizeof(UINT32) == 4);
282 	assert (sizeof(SINT16) == 2);
283 	assert (sizeof(SINT32) == 4);
284 
285 	assert (sizeof(audiosect_t) >= sizeof(wav_header_t));
286 	assert (sizeof(audiosect_t) % 4 == 0);
287 	/* assert (sizeof(buffer_t) >= CDAUDIOSECTORSIZE); */
288 
289 	/* This program assumes that a short is 2 bytes, and that SHRT_MAX is
290 		the max value of a signed short. (Why doesn't limit.h bloody have
291 		a SSHRT_MAX?) */
292 	assert (SHRT_MAX == USHRT_MAX/2);
293 	/* actually, better might be: */
294 	assert ((long)SHRT_MAX == 32767L);
295 
296 	scan_cmd_args (argc, argv);
297 	set_message_output ();
298 	check_cmd_args ();
299 	showcmdargs ();
300 
301 	do_data_io ();
302 
303 	return ERR_OK;
304 
305 } /* main() */
306 
307 
308 
309 /* EOF wav2cdr.c */
310 /******************************************************************************/
311