Sync usage with man page.
[netbsd-mini2440.git] / usr.bin / audio / record / record.c
bloba40462116d221c8b6cb6f5f360845828ff7451ca
1 /* $NetBSD: record.c,v 1.46 2008/05/29 14:51:27 mrg Exp $ */
3 /*
4 * Copyright (c) 1999, 2002 Matthew R. Green
5 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
30 * SunOS compatible audiorecord(1)
32 #include <sys/cdefs.h>
34 #ifndef lint
35 __RCSID("$NetBSD: record.c,v 1.46 2008/05/29 14:51:27 mrg Exp $");
36 #endif
39 #include <sys/types.h>
40 #include <sys/audioio.h>
41 #include <sys/ioctl.h>
42 #include <sys/time.h>
43 #include <sys/uio.h>
45 #include <err.h>
46 #include <fcntl.h>
47 #include <paths.h>
48 #include <signal.h>
49 #include <stdio.h>
50 #include <stdlib.h>
51 #include <string.h>
52 #include <unistd.h>
53 #include <util.h>
55 #include "libaudio.h"
56 #include "auconv.h"
58 audio_info_t info, oinfo;
59 ssize_t total_size = -1;
60 const char *device;
61 int format = AUDIO_FORMAT_DEFAULT;
62 char *header_info;
63 char default_info[8] = { '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0' };
64 int audiofd, outfd;
65 int qflag, aflag, fflag;
66 int verbose;
67 int monitor_gain, omonitor_gain;
68 int gain;
69 int balance;
70 int port;
71 int encoding;
72 char *encoding_str;
73 int precision;
74 int sample_rate;
75 int channels;
76 struct timeval record_time;
77 struct timeval start_time;
79 void (*conv_func) (u_char *, int);
81 void usage (void);
82 int main (int, char *[]);
83 int timeleft (struct timeval *, struct timeval *);
84 void cleanup (int) __dead;
85 int write_header_sun (void **, size_t *, int *);
86 int write_header_wav (void **, size_t *, int *);
87 void write_header (void);
88 void rewrite_header (void);
90 int
91 main(argc, argv)
92 int argc;
93 char *argv[];
95 u_char *buffer;
96 size_t len, bufsize;
97 int ch, no_time_limit = 1;
98 const char *defdevice = _PATH_SOUND;
100 while ((ch = getopt(argc, argv, "ab:C:F:c:d:e:fhi:m:P:p:qt:s:Vv:")) != -1) {
101 switch (ch) {
102 case 'a':
103 aflag++;
104 break;
105 case 'b':
106 decode_int(optarg, &balance);
107 if (balance < 0 || balance > 63)
108 errx(1, "balance must be between 0 and 63");
109 break;
110 case 'C':
111 /* Ignore, compatibility */
112 break;
113 case 'F':
114 format = audio_format_from_str(optarg);
115 if (format < 0)
116 errx(1, "Unknown audio format; supported "
117 "formats: \"sun\", \"wav\", and \"none\"");
118 break;
119 case 'c':
120 decode_int(optarg, &channels);
121 if (channels < 0 || channels > 16)
122 errx(1, "channels must be between 0 and 16");
123 break;
124 case 'd':
125 device = optarg;
126 break;
127 case 'e':
128 encoding_str = optarg;
129 break;
130 case 'f':
131 fflag++;
132 break;
133 case 'i':
134 header_info = optarg;
135 break;
136 case 'm':
137 decode_int(optarg, &monitor_gain);
138 if (monitor_gain < 0 || monitor_gain > 255)
139 errx(1, "monitor volume must be between 0 and 255");
140 break;
141 case 'P':
142 decode_int(optarg, &precision);
143 if (precision != 4 && precision != 8 &&
144 precision != 16 && precision != 24 &&
145 precision != 32)
146 errx(1, "precision must be between 4, 8, 16, 24 or 32");
147 break;
148 case 'p':
149 len = strlen(optarg);
151 if (strncmp(optarg, "mic", len) == 0)
152 port |= AUDIO_MICROPHONE;
153 else if (strncmp(optarg, "cd", len) == 0 ||
154 strncmp(optarg, "internal-cd", len) == 0)
155 port |= AUDIO_CD;
156 else if (strncmp(optarg, "line", len) == 0)
157 port |= AUDIO_LINE_IN;
158 else
159 errx(1,
160 "port must be `cd', `internal-cd', `mic', or `line'");
161 break;
162 case 'q':
163 qflag++;
164 break;
165 case 's':
166 decode_int(optarg, &sample_rate);
167 if (sample_rate < 0 || sample_rate > 48000 * 2) /* XXX */
168 errx(1, "sample rate must be between 0 and 96000");
169 break;
170 case 't':
171 no_time_limit = 0;
172 decode_time(optarg, &record_time);
173 break;
174 case 'V':
175 verbose++;
176 break;
177 case 'v':
178 decode_int(optarg, &gain);
179 if (gain < 0 || gain > 255)
180 errx(1, "volume must be between 0 and 255");
181 break;
182 /* case 'h': */
183 default:
184 usage();
185 /* NOTREACHED */
188 argc -= optind;
189 argv += optind;
191 if (argc != 1)
192 usage();
195 * convert the encoding string into a value.
197 if (encoding_str) {
198 encoding = audio_enc_to_val(encoding_str);
199 if (encoding == -1)
200 errx(1, "unknown encoding, bailing...");
202 #if 0
203 else
204 encoding = AUDIO_ENCODING_ULAW;
205 #endif
208 * open the output file
210 if (argv[0][0] != '-' || argv[0][1] != '\0') {
211 /* intuit the file type from the name */
212 if (format == AUDIO_FORMAT_DEFAULT)
214 size_t flen = strlen(*argv);
215 const char *arg = *argv;
217 if (strcasecmp(arg + flen - 3, ".au") == 0)
218 format = AUDIO_FORMAT_SUN;
219 else if (strcasecmp(arg + flen - 4, ".wav") == 0)
220 format = AUDIO_FORMAT_WAV;
222 outfd = open(*argv, O_CREAT|(aflag ? O_APPEND : O_TRUNC)|O_WRONLY, 0666);
223 if (outfd < 0)
224 err(1, "could not open %s", *argv);
225 } else
226 outfd = STDOUT_FILENO;
229 * open the audio device
231 if (device == NULL && (device = getenv("AUDIODEVICE")) == NULL &&
232 (device = getenv("AUDIODEV")) == NULL) /* Sun compatibility */
233 device = defdevice;
235 audiofd = open(device, O_RDONLY);
236 if (audiofd < 0 && device == defdevice) {
237 device = _PATH_SOUND0;
238 audiofd = open(device, O_RDONLY);
240 if (audiofd < 0)
241 err(1, "failed to open %s", device);
244 * work out the buffer size to use, and allocate it. also work out
245 * what the old monitor gain value is, so that we can reset it later.
247 if (ioctl(audiofd, AUDIO_GETINFO, &oinfo) < 0)
248 err(1, "failed to get audio info");
249 bufsize = oinfo.record.buffer_size;
250 if (bufsize < 32 * 1024)
251 bufsize = 32 * 1024;
252 omonitor_gain = oinfo.monitor_gain;
254 buffer = malloc(bufsize);
255 if (buffer == NULL)
256 err(1, "couldn't malloc buffer of %d size", (int)bufsize);
259 * set up audio device for recording with the speified parameters
261 AUDIO_INITINFO(&info);
264 * for these, get the current values for stuffing into the header
266 #define SETINFO(x) if (x) \
267 info.record.x = x; \
268 else \
269 info.record.x = x = oinfo.record.x;
270 SETINFO (sample_rate)
271 SETINFO (channels)
272 SETINFO (precision)
273 SETINFO (encoding)
274 SETINFO (gain)
275 SETINFO (port)
276 SETINFO (balance)
277 #undef SETINFO
279 if (monitor_gain)
280 info.monitor_gain = monitor_gain;
281 else
282 monitor_gain = oinfo.monitor_gain;
284 info.mode = AUMODE_RECORD;
285 if (ioctl(audiofd, AUDIO_SETINFO, &info) < 0)
286 err(1, "failed to set audio info");
288 signal(SIGINT, cleanup);
289 write_header();
290 total_size = 0;
292 if (verbose && conv_func) {
293 const char *s = NULL;
295 if (conv_func == swap_bytes)
296 s = "swap bytes (16 bit)";
297 else if (conv_func == swap_bytes32)
298 s = "swap bytes (32 bit)";
299 else if (conv_func == change_sign16_be)
300 s = "change sign (big-endian, 16 bit)";
301 else if (conv_func == change_sign16_le)
302 s = "change sign (little-endian, 16 bit)";
303 else if (conv_func == change_sign32_be)
304 s = "change sign (big-endian, 32 bit)";
305 else if (conv_func == change_sign32_le)
306 s = "change sign (little-endian, 32 bit)";
307 else if (conv_func == change_sign16_swap_bytes_be)
308 s = "change sign & swap bytes (big-endian, 16 bit)";
309 else if (conv_func == change_sign16_swap_bytes_le)
310 s = "change sign & swap bytes (little-endian, 16 bit)";
311 else if (conv_func == change_sign32_swap_bytes_be)
312 s = "change sign (big-endian, 32 bit)";
313 else if (conv_func == change_sign32_swap_bytes_le)
314 s = "change sign & swap bytes (little-endian, 32 bit)";
316 if (s)
317 fprintf(stderr, "%s: converting, using function: %s\n",
318 getprogname(), s);
319 else
320 fprintf(stderr, "%s: using unnamed conversion "
321 "function\n", getprogname());
324 if (verbose)
325 fprintf(stderr,
326 "sample_rate=%d channels=%d precision=%d encoding=%s\n",
327 info.record.sample_rate, info.record.channels,
328 info.record.precision,
329 audio_enc_from_val(info.record.encoding));
331 if (!no_time_limit && verbose)
332 fprintf(stderr, "recording for %lu seconds, %lu microseconds\n",
333 (u_long)record_time.tv_sec, (u_long)record_time.tv_usec);
335 (void)gettimeofday(&start_time, NULL);
336 while (no_time_limit || timeleft(&start_time, &record_time)) {
337 if ((size_t)read(audiofd, buffer, bufsize) != bufsize)
338 err(1, "read failed");
339 if (conv_func)
340 (*conv_func)(buffer, bufsize);
341 if ((size_t)write(outfd, buffer, bufsize) != bufsize)
342 err(1, "write failed");
343 total_size += bufsize;
345 cleanup(0);
349 timeleft(start_tvp, record_tvp)
350 struct timeval *start_tvp;
351 struct timeval *record_tvp;
353 struct timeval now, diff;
355 (void)gettimeofday(&now, NULL);
356 timersub(&now, start_tvp, &diff);
357 timersub(record_tvp, &diff, &now);
359 return (now.tv_sec > 0 || (now.tv_sec == 0 && now.tv_usec > 0));
362 void
363 cleanup(signo)
364 int signo;
367 rewrite_header();
368 close(outfd);
369 if (omonitor_gain) {
370 AUDIO_INITINFO(&info);
371 info.monitor_gain = omonitor_gain;
372 if (ioctl(audiofd, AUDIO_SETINFO, &info) < 0)
373 err(1, "failed to reset audio info");
375 close(audiofd);
376 if (signo != 0) {
377 (void)raise_default_signal(signo);
379 exit(0);
383 write_header_sun(hdrp, lenp, leftp)
384 void **hdrp;
385 size_t *lenp;
386 int *leftp;
388 static int warned = 0;
389 static sun_audioheader auh;
390 int sunenc, oencoding = encoding;
392 /* only perform conversions if we don't specify the encoding */
393 switch (encoding) {
394 case AUDIO_ENCODING_ULINEAR_LE:
395 #if BYTE_ORDER == LITTLE_ENDIAN
396 case AUDIO_ENCODING_ULINEAR:
397 #endif
398 if (precision == 16)
399 conv_func = change_sign16_swap_bytes_le;
400 else if (precision == 32)
401 conv_func = change_sign32_swap_bytes_le;
402 if (conv_func)
403 encoding = AUDIO_ENCODING_SLINEAR_BE;
404 break;
406 case AUDIO_ENCODING_ULINEAR_BE:
407 #if BYTE_ORDER == BIG_ENDIAN
408 case AUDIO_ENCODING_ULINEAR:
409 #endif
410 if (precision == 16)
411 conv_func = change_sign16_be;
412 else if (precision == 32)
413 conv_func = change_sign32_be;
414 if (conv_func)
415 encoding = AUDIO_ENCODING_SLINEAR_BE;
416 break;
418 case AUDIO_ENCODING_SLINEAR_LE:
419 #if BYTE_ORDER == LITTLE_ENDIAN
420 case AUDIO_ENCODING_SLINEAR:
421 #endif
422 if (precision == 16)
423 conv_func = swap_bytes;
424 else if (precision == 32)
425 conv_func = swap_bytes32;
426 if (conv_func)
427 encoding = AUDIO_ENCODING_SLINEAR_BE;
428 break;
430 #if BYTE_ORDER == BIG_ENDIAN
431 case AUDIO_ENCODING_SLINEAR:
432 encoding = AUDIO_ENCODING_SLINEAR_BE;
433 break;
434 #endif
437 /* if we can't express this as a Sun header, don't write any */
438 if (audio_encoding_to_sun(encoding, precision, &sunenc) != 0) {
439 if (!qflag && !warned) {
440 const char *s = audio_enc_from_val(oencoding);
442 if (s == NULL)
443 s = "(unknown)";
444 warnx("failed to convert to sun encoding from %s "
445 "(precision %d);\nSun audio header not written",
446 s, precision);
448 format = AUDIO_FORMAT_NONE;
449 conv_func = 0;
450 warned = 1;
451 return -1;
454 auh.magic = htonl(AUDIO_FILE_MAGIC);
455 if (outfd == STDOUT_FILENO)
456 auh.data_size = htonl(AUDIO_UNKNOWN_SIZE);
457 else if (total_size != -1)
458 auh.data_size = htonl(total_size);
459 else
460 auh.data_size = 0;
461 auh.encoding = htonl(sunenc);
462 auh.sample_rate = htonl(sample_rate);
463 auh.channels = htonl(channels);
464 if (header_info) {
465 int len, infolen;
467 infolen = ((len = strlen(header_info)) + 7) & 0xfffffff8;
468 *leftp = infolen - len;
469 auh.hdr_size = htonl(sizeof(auh) + infolen);
470 } else {
471 *leftp = sizeof(default_info);
472 auh.hdr_size = htonl(sizeof(auh) + *leftp);
474 *(sun_audioheader **)hdrp = &auh;
475 *lenp = sizeof auh;
476 return 0;
480 write_header_wav(hdrp, lenp, leftp)
481 void **hdrp;
482 size_t *lenp;
483 int *leftp;
486 * WAV header we write looks like this:
488 * bytes purpose
489 * 0-3 "RIFF"
490 * 4-7 file length (minus 8)
491 * 8-15 "WAVEfmt "
492 * 16-19 format size
493 * 20-21 format tag
494 * 22-23 number of channels
495 * 24-27 sample rate
496 * 28-31 average bytes per second
497 * 32-33 block alignment
498 * 34-35 bits per sample
500 * then for ULAW and ALAW outputs, we have an extended chunk size
501 * and a WAV "fact" to add:
503 * 36-37 length of extension (== 0)
504 * 38-41 "fact"
505 * 42-45 fact size
506 * 46-49 number of samples written
507 * 50-53 "data"
508 * 54-57 data length
509 * 58- raw audio data
511 * for PCM outputs we have just the data remaining:
513 * 36-39 "data"
514 * 40-43 data length
515 * 44- raw audio data
517 * RIFF\^@^C^@WAVEfmt ^P^@^@^@^A^@^B^@D<AC>^@^@^P<B1>^B^@^D^@^P^@data^@^@^C^@^@^@^@^@^@^@^@^@^@
519 char wavheaderbuf[64], *p = wavheaderbuf;
520 const char *riff = "RIFF",
521 *wavefmt = "WAVEfmt ",
522 *fact = "fact",
523 *data = "data";
524 u_int32_t filelen, fmtsz, sps, abps, factsz = 4, nsample, datalen;
525 u_int16_t fmttag, nchan, align, bps, extln = 0;
527 if (header_info)
528 warnx("header information not supported for WAV");
529 *leftp = 0;
531 switch (precision) {
532 case 8:
533 bps = 8;
534 break;
535 case 16:
536 bps = 16;
537 break;
538 case 32:
539 bps = 32;
540 break;
541 default:
543 static int warned = 0;
545 if (warned == 0) {
546 warnx("can not support precision of %d", precision);
547 warned = 1;
550 return (-1);
553 switch (encoding) {
554 case AUDIO_ENCODING_ULAW:
555 fmttag = WAVE_FORMAT_MULAW;
556 fmtsz = 18;
557 align = channels;
558 break;
560 case AUDIO_ENCODING_ALAW:
561 fmttag = WAVE_FORMAT_ALAW;
562 fmtsz = 18;
563 align = channels;
564 break;
567 * we could try to support RIFX but it seems to be more portable
568 * to output little-endian data for WAV files.
570 case AUDIO_ENCODING_ULINEAR_BE:
571 #if BYTE_ORDER == BIG_ENDIAN
572 case AUDIO_ENCODING_ULINEAR:
573 #endif
574 if (bps == 16)
575 conv_func = change_sign16_swap_bytes_be;
576 else if (bps == 32)
577 conv_func = change_sign32_swap_bytes_be;
578 goto fmt_pcm;
580 case AUDIO_ENCODING_SLINEAR_BE:
581 #if BYTE_ORDER == BIG_ENDIAN
582 case AUDIO_ENCODING_SLINEAR:
583 #endif
584 if (bps == 8)
585 conv_func = change_sign8;
586 else if (bps == 16)
587 conv_func = swap_bytes;
588 else if (bps == 32)
589 conv_func = swap_bytes32;
590 goto fmt_pcm;
592 case AUDIO_ENCODING_ULINEAR_LE:
593 #if BYTE_ORDER == LITTLE_ENDIAN
594 case AUDIO_ENCODING_ULINEAR:
595 #endif
596 if (bps == 16)
597 conv_func = change_sign16_le;
598 else if (bps == 32)
599 conv_func = change_sign32_le;
600 /* FALLTHROUGH */
602 case AUDIO_ENCODING_SLINEAR_LE:
603 case AUDIO_ENCODING_PCM16:
604 #if BYTE_ORDER == LITTLE_ENDIAN
605 case AUDIO_ENCODING_SLINEAR:
606 #endif
607 if (bps == 8)
608 conv_func = change_sign8;
609 fmt_pcm:
610 fmttag = WAVE_FORMAT_PCM;
611 fmtsz = 16;
612 align = channels * (bps / 8);
613 break;
615 default:
617 static int warned = 0;
619 if (warned == 0) {
620 const char *s = wav_enc_from_val(encoding);
622 if (s == NULL)
623 warnx("can not support encoding of %s", s);
624 else
625 warnx("can not support encoding of %d", encoding);
626 warned = 1;
629 format = AUDIO_FORMAT_NONE;
630 return (-1);
633 nchan = channels;
634 sps = sample_rate;
636 /* data length */
637 if (outfd == STDOUT_FILENO)
638 datalen = 0;
639 else if (total_size != -1)
640 datalen = total_size;
641 else
642 datalen = 0;
644 /* file length */
645 filelen = 4 + (8 + fmtsz) + (8 + datalen);
646 if (fmttag != WAVE_FORMAT_PCM)
647 filelen += 8 + factsz;
649 abps = (double)align*sample_rate / (double)1 + 0.5;
651 nsample = (datalen / bps) / sample_rate;
654 * now we've calculated the info, write it out!
656 #define put32(x) do { \
657 u_int32_t _f; \
658 putle32(_f, (x)); \
659 memcpy(p, &_f, 4); \
660 } while (0)
661 #define put16(x) do { \
662 u_int16_t _f; \
663 putle16(_f, (x)); \
664 memcpy(p, &_f, 2); \
665 } while (0)
666 memcpy(p, riff, 4);
667 p += 4; /* 4 */
668 put32(filelen);
669 p += 4; /* 8 */
670 memcpy(p, wavefmt, 8);
671 p += 8; /* 16 */
672 put32(fmtsz);
673 p += 4; /* 20 */
674 put16(fmttag);
675 p += 2; /* 22 */
676 put16(nchan);
677 p += 2; /* 24 */
678 put32(sps);
679 p += 4; /* 28 */
680 put32(abps);
681 p += 4; /* 32 */
682 put16(align);
683 p += 2; /* 34 */
684 put16(bps);
685 p += 2; /* 36 */
686 /* NON PCM formats have an extended chunk; write it */
687 if (fmttag != WAVE_FORMAT_PCM) {
688 put16(extln);
689 p += 2; /* 38 */
690 memcpy(p, fact, 4);
691 p += 4; /* 42 */
692 put32(factsz);
693 p += 4; /* 46 */
694 put32(nsample);
695 p += 4; /* 50 */
697 memcpy(p, data, 4);
698 p += 4; /* 40/54 */
699 put32(datalen);
700 p += 4; /* 44/58 */
701 #undef put32
702 #undef put16
704 *hdrp = wavheaderbuf;
705 *lenp = (p - wavheaderbuf);
707 return 0;
710 void
711 write_header()
713 struct iovec iv[3];
714 int veclen, left, tlen;
715 void *hdr;
716 size_t hdrlen;
718 switch (format) {
719 case AUDIO_FORMAT_DEFAULT:
720 case AUDIO_FORMAT_SUN:
721 if (write_header_sun(&hdr, &hdrlen, &left) != 0)
722 return;
723 break;
724 case AUDIO_FORMAT_WAV:
725 if (write_header_wav(&hdr, &hdrlen, &left) != 0)
726 return;
727 break;
728 case AUDIO_FORMAT_NONE:
729 return;
730 default:
731 errx(1, "unknown audio format");
734 veclen = 0;
735 tlen = 0;
737 if (hdrlen != 0) {
738 iv[veclen].iov_base = hdr;
739 iv[veclen].iov_len = hdrlen;
740 tlen += iv[veclen++].iov_len;
742 if (header_info) {
743 iv[veclen].iov_base = header_info;
744 iv[veclen].iov_len = (int)strlen(header_info) + 1;
745 tlen += iv[veclen++].iov_len;
747 if (left) {
748 iv[veclen].iov_base = default_info;
749 iv[veclen].iov_len = left;
750 tlen += iv[veclen++].iov_len;
753 if (tlen == 0)
754 return;
756 if (writev(outfd, iv, veclen) != tlen)
757 err(1, "could not write audio header");
760 void
761 rewrite_header()
764 /* can't do this here! */
765 if (outfd == STDOUT_FILENO)
766 return;
768 if (lseek(outfd, SEEK_SET, 0) < 0)
769 err(1, "could not seek to start of file for header rewrite");
770 write_header();
773 void
774 usage()
777 fprintf(stderr, "Usage: %s [-afhqV] [options] {files ...|-}\n",
778 getprogname());
779 fprintf(stderr, "Options:\n\t"
780 "-b balance (0-63)\n\t"
781 "-c channels\n\t"
782 "-d audio device\n\t"
783 "-e encoding\n\t"
784 "-F format\n\t"
785 "-i header information\n\t"
786 "-m monitor volume\n\t"
787 "-P precision (4, 8, 16, 24, or 32 bits)\n\t"
788 "-p input port\n\t"
789 "-s sample rate\n\t"
790 "-t recording time\n\t"
791 "-v volume\n");
792 exit(EXIT_FAILURE);