• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  aplay.c - plays and records
3  *
4  *      CREATIVE LABS CHANNEL-files
5  *      Microsoft WAVE-files
6  *      SPARC AUDIO .AU-files
7  *      Raw Data
8  *
9  *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
10  *  Based on vplay program by Michael Beck
11  *
12  *
13  *   This program is free software; you can redistribute it and/or modify
14  *   it under the terms of the GNU General Public License as published by
15  *   the Free Software Foundation; either version 2 of the License, or
16  *   (at your option) any later version.
17  *
18  *   This program is distributed in the hope that it will be useful,
19  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
20  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  *   GNU General Public License for more details.
22  *
23  *   You should have received a copy of the GNU General Public License
24  *   along with this program; if not, write to the Free Software
25  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
26  *
27  */
28 
29 #define _GNU_SOURCE
30 #include "aconfig.h"
31 #include <stdio.h>
32 #include <stdint.h>
33 #if HAVE_MALLOC_H
34 #include <malloc.h>
35 #endif
36 #include <unistd.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <getopt.h>
40 #include <fcntl.h>
41 #include <ctype.h>
42 #include <errno.h>
43 #include <limits.h>
44 #include <time.h>
45 #include <locale.h>
46 #include <alsa/asoundlib.h>
47 #include <assert.h>
48 #include <termios.h>
49 #include <signal.h>
50 #include <poll.h>
51 #include <sys/uio.h>
52 #include <sys/time.h>
53 #include <sys/stat.h>
54 #include <endian.h>
55 #include "gettext.h"
56 #include "formats.h"
57 #include "version.h"
58 #include "os_compat.h"
59 
60 #define ABS(a)  (a) < 0 ? -(a) : (a)
61 
62 #ifdef SND_CHMAP_API_VERSION
63 #define CONFIG_SUPPORT_CHMAP	1
64 #endif
65 
66 #ifndef LLONG_MAX
67 #define LLONG_MAX    9223372036854775807LL
68 #endif
69 
70 #ifndef le16toh
71 #include <asm/byteorder.h>
72 #define le16toh(x) __le16_to_cpu(x)
73 #define be16toh(x) __be16_to_cpu(x)
74 #define le32toh(x) __le32_to_cpu(x)
75 #define be32toh(x) __be32_to_cpu(x)
76 #endif
77 
78 #define DEFAULT_FORMAT		SND_PCM_FORMAT_U8
79 #define DEFAULT_SPEED 		8000
80 
81 #define FORMAT_DEFAULT		-1
82 #define FORMAT_RAW		0
83 #define FORMAT_VOC		1
84 #define FORMAT_WAVE		2
85 #define FORMAT_AU		3
86 
87 /* global data */
88 
89 static snd_pcm_sframes_t (*readi_func)(snd_pcm_t *handle, void *buffer, snd_pcm_uframes_t size);
90 static snd_pcm_sframes_t (*writei_func)(snd_pcm_t *handle, const void *buffer, snd_pcm_uframes_t size);
91 static snd_pcm_sframes_t (*readn_func)(snd_pcm_t *handle, void **bufs, snd_pcm_uframes_t size);
92 static snd_pcm_sframes_t (*writen_func)(snd_pcm_t *handle, void **bufs, snd_pcm_uframes_t size);
93 
94 enum {
95 	VUMETER_NONE,
96 	VUMETER_MONO,
97 	VUMETER_STEREO
98 };
99 
100 static char *command;
101 static snd_pcm_t *handle;
102 static struct {
103 	snd_pcm_format_t format;
104 	snd_pcm_subformat_t subformat;
105 	unsigned int channels;
106 	unsigned int rate;
107 } hwparams, rhwparams;
108 static int timelimit = 0;
109 static int sampleslimit = 0;
110 static int quiet_mode = 0;
111 static int file_type = FORMAT_DEFAULT;
112 static int open_mode = 0;
113 static snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK;
114 static int mmap_flag = 0;
115 static int interleaved = 1;
116 static int nonblock = 0;
117 static volatile sig_atomic_t in_aborting = 0;
118 static uint8_t *audiobuf = NULL;
119 static snd_pcm_uframes_t chunk_size = 0;
120 static unsigned period_time = 0;
121 static unsigned buffer_time = 0;
122 static snd_pcm_uframes_t period_frames = 0;
123 static snd_pcm_uframes_t buffer_frames = 0;
124 static int avail_min = -1;
125 static int start_delay = 0;
126 static int stop_delay = 0;
127 static int monotonic = 0;
128 static int interactive = 0;
129 static int can_pause = 0;
130 static int fatal_errors = 0;
131 static int verbose = 0;
132 static int vumeter = VUMETER_NONE;
133 static int buffer_pos = 0;
134 static size_t significant_bits_per_sample, bits_per_sample, bits_per_frame;
135 static size_t chunk_bytes;
136 static int test_position = 0;
137 static int test_coef = 8;
138 static int test_nowait = 0;
139 static snd_output_t *log;
140 static long long max_file_size = 0;
141 static int max_file_time = 0;
142 static int use_strftime = 0;
143 static volatile int recycle_capture_file = 0;
144 static long term_c_lflag = -1;
145 static int dump_hw_params = 0;
146 
147 static int fd = -1;
148 static off_t pbrec_count = LLONG_MAX, fdcount;
149 static int vocmajor, vocminor;
150 
151 static char *pidfile_name = NULL;
152 FILE *pidf = NULL;
153 static int pidfile_written = 0;
154 
155 #ifdef CONFIG_SUPPORT_CHMAP
156 static snd_pcm_chmap_t *channel_map = NULL; /* chmap to override */
157 static unsigned int *hw_map = NULL; /* chmap to follow */
158 #endif
159 
160 /* needed prototypes */
161 
162 static void done_stdin(void);
163 
164 static void playback(char *filename);
165 static void capture(char *filename);
166 static void playbackv(char **filenames, unsigned int count);
167 static void capturev(char **filenames, unsigned int count);
168 
169 static void begin_voc(int fd, size_t count);
170 static void end_voc(int fd);
171 static void begin_wave(int fd, size_t count);
172 static void end_wave(int fd);
173 static void begin_au(int fd, size_t count);
174 static void end_au(int fd);
175 
176 static void suspend(void);
177 
178 static const struct fmt_capture {
179 	void (*start) (int fd, size_t count);
180 	void (*end) (int fd);
181 	char *what;
182 	long long max_filesize;
183 } fmt_rec_table[] = {
184 	{	NULL,		NULL,		N_("raw data"),		LLONG_MAX },
185 	{	begin_voc,	end_voc,	N_("VOC"),		16000000LL },
186 	/* FIXME: can WAV handle exactly 2GB or less than it? */
187 	{	begin_wave,	end_wave,	N_("WAVE"),		2147483648LL },
188 	{	begin_au,	end_au,		N_("Sparc Audio"),	LLONG_MAX }
189 };
190 
191 #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95)
192 #define error(...) do {\
193 	fprintf(stderr, "%s: %s:%d: ", command, __func__, __LINE__); \
194 	fprintf(stderr, __VA_ARGS__); \
195 	putc('\n', stderr); \
196 } while (0)
197 #else
198 #define error(args...) do {\
199 	fprintf(stderr, "%s: %s:%d: ", command, __func__, __LINE__); \
200 	fprintf(stderr, ##args); \
201 	putc('\n', stderr); \
202 } while (0)
203 #endif
204 
usage(char * command)205 static void usage(char *command)
206 {
207 	snd_pcm_format_t k;
208 	printf(
209 _("Usage: %s [OPTION]... [FILE]...\n"
210 "\n"
211 "-h, --help              help\n"
212 "    --version           print current version\n"
213 "-l, --list-devices      list all soundcards and digital audio devices\n"
214 "-L, --list-pcms         list device names\n"
215 "-D, --device=NAME       select PCM by name\n"
216 "-q, --quiet             quiet mode\n"
217 "-t, --file-type TYPE    file type (voc, wav, raw or au)\n"
218 "-c, --channels=#        channels\n"
219 "-f, --format=FORMAT     sample format (case insensitive)\n"
220 "    --subformat=SUBFORMAT  sample subformat (case insensitive)\n"
221 "-r, --rate=#            sample rate\n"
222 "-d, --duration=#        interrupt after # seconds\n"
223 "-s, --samples=#         interrupt after # samples per channel\n"
224 "-M, --mmap              mmap stream\n"
225 "-N, --nonblock          nonblocking mode\n"
226 "-F, --period-time=#     distance between interrupts is # microseconds\n"
227 "-B, --buffer-time=#     buffer duration is # microseconds\n"
228 "    --period-size=#     distance between interrupts is # frames\n"
229 "    --buffer-size=#     buffer duration is # frames\n"
230 "-A, --avail-min=#       min available space for wakeup is # microseconds\n"
231 "-R, --start-delay=#     delay for automatic PCM start is # microseconds \n"
232 "                        (relative to buffer size if <= 0)\n"
233 "-T, --stop-delay=#      delay for automatic PCM stop is # microseconds from xrun\n"
234 "-v, --verbose           show PCM structure and setup (accumulative)\n"
235 "-V, --vumeter=TYPE      enable VU meter (TYPE: mono or stereo)\n"
236 "-I, --separate-channels one file for each channel\n"
237 "-i, --interactive       allow interactive operation from stdin\n"
238 "-m, --chmap=ch1,ch2,..  Give the channel map to override or follow\n"
239 "    --disable-resample  disable automatic rate resample\n"
240 "    --disable-channels  disable automatic channel conversions\n"
241 "    --disable-format    disable automatic format conversions\n"
242 "    --disable-softvol   disable software volume control (softvol)\n"
243 "    --test-position     test ring buffer position\n"
244 "    --test-coef=#       test coefficient for ring buffer position (default 8)\n"
245 "                        expression for validation is: coef * (buffer_size / 2)\n"
246 "    --test-nowait       do not wait for ring buffer - eats whole CPU\n"
247 "    --max-file-time=#   start another output file when the old file has recorded\n"
248 "                        for this many seconds\n"
249 "    --process-id-file   write the process ID here\n"
250 "    --use-strftime      apply the strftime facility to the output file name\n"
251 "    --dump-hw-params    dump hw_params of the device\n"
252 "    --fatal-errors      treat all errors as fatal\n"
253   )
254 		, command);
255 	printf(_("Recognized sample formats are:"));
256 	for (k = 0; k <= SND_PCM_FORMAT_LAST; ++k) {
257 		const char *s = snd_pcm_format_name(k);
258 		if (s)
259 			printf(" %s", s);
260 	}
261 	printf(_("\nSome of these may not be available on selected hardware\n"));
262 	printf(_("The available format shortcuts are:\n"));
263 	printf(_("-f cd (16 bit little endian, 44100, stereo)\n"));
264 	printf(_("-f cdr (16 bit big endian, 44100, stereo)\n"));
265 	printf(_("-f dat (16 bit little endian, 48000, stereo)\n"));
266 }
267 
device_list(void)268 static void device_list(void)
269 {
270 	snd_ctl_t *handle;
271 	int card, err, dev, idx;
272 	snd_ctl_card_info_t *info;
273 	snd_pcm_info_t *pcminfo;
274 	snd_ctl_card_info_alloca(&info);
275 	snd_pcm_info_alloca(&pcminfo);
276 
277 	card = -1;
278 	if (snd_card_next(&card) < 0 || card < 0) {
279 		error(_("no soundcards found..."));
280 		return;
281 	}
282 	printf(_("**** List of %s Hardware Devices ****\n"),
283 	       snd_pcm_stream_name(stream));
284 	while (card >= 0) {
285 		char name[32];
286 		sprintf(name, "hw:%d", card);
287 		if ((err = snd_ctl_open(&handle, name, 0)) < 0) {
288 			error("control open (%i): %s", card, snd_strerror(err));
289 			goto next_card;
290 		}
291 		if ((err = snd_ctl_card_info(handle, info)) < 0) {
292 			error("control hardware info (%i): %s", card, snd_strerror(err));
293 			snd_ctl_close(handle);
294 			goto next_card;
295 		}
296 		dev = -1;
297 		while (1) {
298 			unsigned int count;
299 			if (snd_ctl_pcm_next_device(handle, &dev)<0)
300 				error("snd_ctl_pcm_next_device");
301 			if (dev < 0)
302 				break;
303 			snd_pcm_info_set_device(pcminfo, dev);
304 			snd_pcm_info_set_subdevice(pcminfo, 0);
305 			snd_pcm_info_set_stream(pcminfo, stream);
306 			if ((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) {
307 				if (err != -ENOENT)
308 					error("control digital audio info (%i): %s", card, snd_strerror(err));
309 				continue;
310 			}
311 			printf(_("card %i: %s [%s], device %i: %s [%s]\n"),
312 				card, snd_ctl_card_info_get_id(info), snd_ctl_card_info_get_name(info),
313 				dev,
314 				snd_pcm_info_get_id(pcminfo),
315 				snd_pcm_info_get_name(pcminfo));
316 			count = snd_pcm_info_get_subdevices_count(pcminfo);
317 			printf( _("  Subdevices: %i/%i\n"),
318 				snd_pcm_info_get_subdevices_avail(pcminfo), count);
319 			for (idx = 0; idx < (int)count; idx++) {
320 				snd_pcm_info_set_subdevice(pcminfo, idx);
321 				if ((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) {
322 					error("control digital audio playback info (%i): %s", card, snd_strerror(err));
323 				} else {
324 					printf(_("  Subdevice #%i: %s\n"),
325 						idx, snd_pcm_info_get_subdevice_name(pcminfo));
326 				}
327 			}
328 		}
329 		snd_ctl_close(handle);
330 	next_card:
331 		if (snd_card_next(&card) < 0) {
332 			error("snd_card_next");
333 			break;
334 		}
335 	}
336 }
337 
pcm_list(void)338 static void pcm_list(void)
339 {
340 	void **hints, **n;
341 	char *name, *descr, *descr1, *io;
342 	const char *filter;
343 
344 	if (snd_device_name_hint(-1, "pcm", &hints) < 0)
345 		return;
346 	n = hints;
347 	filter = stream == SND_PCM_STREAM_CAPTURE ? "Input" : "Output";
348 	while (*n != NULL) {
349 		name = snd_device_name_get_hint(*n, "NAME");
350 		descr = snd_device_name_get_hint(*n, "DESC");
351 		io = snd_device_name_get_hint(*n, "IOID");
352 		if (io != NULL && strcmp(io, filter) != 0)
353 			goto __end;
354 		printf("%s\n", name);
355 		if ((descr1 = descr) != NULL) {
356 			printf("    ");
357 			while (*descr1) {
358 				if (*descr1 == '\n')
359 					printf("\n    ");
360 				else
361 					putchar(*descr1);
362 				descr1++;
363 			}
364 			putchar('\n');
365 		}
366 	      __end:
367 	      	if (name != NULL)
368 	      		free(name);
369 		if (descr != NULL)
370 			free(descr);
371 		if (io != NULL)
372 			free(io);
373 		n++;
374 	}
375 	snd_device_name_free_hint(hints);
376 }
377 
version(void)378 static void version(void)
379 {
380 	printf("%s: version " SND_UTIL_VERSION_STR " by Jaroslav Kysela <perex@perex.cz>\n", command);
381 }
382 
383 /*
384  *	Subroutine to clean up before exit.
385  */
prg_exit(int code)386 static void prg_exit(int code)
387 {
388 	done_stdin();
389 	if (handle)
390 		snd_pcm_close(handle);
391 	if (pidfile_written)
392 		remove (pidfile_name);
393 	exit(code);
394 }
395 
signal_handler(int sig)396 static void signal_handler(int sig)
397 {
398 	if (in_aborting)
399 		return;
400 
401 	in_aborting = 1;
402 	if (verbose==2)
403 		putchar('\n');
404 	if (!quiet_mode)
405 		fprintf(stderr, _("Aborted by signal %s...\n"), strsignal(sig));
406 	if (handle)
407 		snd_pcm_abort(handle);
408 	if (sig == SIGABRT) {
409 		/* do not call snd_pcm_close() and abort immediately */
410 		handle = NULL;
411 		prg_exit(EXIT_FAILURE);
412 	}
413 	signal(sig, SIG_DFL);
414 }
415 
416 /* call on SIGUSR1 signal. */
signal_handler_recycle(int sig ATTRIBUTE_UNUSED)417 static void signal_handler_recycle(int sig ATTRIBUTE_UNUSED)
418 {
419 	/* flag the capture loop to start a new output file */
420 	recycle_capture_file = 1;
421 }
422 
423 enum {
424 	OPT_VERSION = 1,
425 	OPT_PERIOD_SIZE,
426 	OPT_BUFFER_SIZE,
427 	OPT_DISABLE_RESAMPLE,
428 	OPT_DISABLE_CHANNELS,
429 	OPT_DISABLE_FORMAT,
430 	OPT_DISABLE_SOFTVOL,
431 	OPT_TEST_POSITION,
432 	OPT_TEST_COEF,
433 	OPT_TEST_NOWAIT,
434 	OPT_MAX_FILE_TIME,
435 	OPT_PROCESS_ID_FILE,
436 	OPT_USE_STRFTIME,
437 	OPT_DUMP_HWPARAMS,
438 	OPT_FATAL_ERRORS,
439 	OPT_SUBFORMAT,
440 };
441 
442 /*
443  * make sure we write all bytes or return an error
444  */
xwrite(int fd,const void * buf,size_t count)445 static ssize_t xwrite(int fd, const void *buf, size_t count)
446 {
447 	ssize_t written;
448 	size_t offset = 0;
449 
450 	while (offset < count) {
451 		written = write(fd, (char *)buf + offset, count - offset);
452 		if (written <= 0)
453 			return written;
454 
455 		offset += written;
456 	};
457 
458 	return offset;
459 }
460 
parse_long(const char * str,int * err)461 static long parse_long(const char *str, int *err)
462 {
463 	long val;
464 	char *endptr;
465 
466 	errno = 0;
467 	val = strtol(str, &endptr, 0);
468 
469 	if (errno != 0 || *endptr != '\0')
470 		*err = -1;
471 	else
472 		*err = 0;
473 
474 	return val;
475 }
476 
main(int argc,char * argv[])477 int main(int argc, char *argv[])
478 {
479 	int duration_or_sample = 0;
480 	int option_index;
481 	static const char short_options[] = "hnlLD:qt:c:f:r:d:s:MNF:A:R:T:B:vV:IPCi"
482 #ifdef CONFIG_SUPPORT_CHMAP
483 		"m:"
484 #endif
485 		;
486 	static const struct option long_options[] = {
487 		{"help", 0, 0, 'h'},
488 		{"version", 0, 0, OPT_VERSION},
489 		{"list-devnames", 0, 0, 'n'},
490 		{"list-devices", 0, 0, 'l'},
491 		{"list-pcms", 0, 0, 'L'},
492 		{"device", 1, 0, 'D'},
493 		{"quiet", 0, 0, 'q'},
494 		{"file-type", 1, 0, 't'},
495 		{"channels", 1, 0, 'c'},
496 		{"format", 1, 0, 'f'},
497 		{"subformat", 1, 0, OPT_SUBFORMAT},
498 		{"rate", 1, 0, 'r'},
499 		{"duration", 1, 0 ,'d'},
500 		{"samples", 1, 0, 's'},
501 		{"mmap", 0, 0, 'M'},
502 		{"nonblock", 0, 0, 'N'},
503 		{"period-time", 1, 0, 'F'},
504 		{"period-size", 1, 0, OPT_PERIOD_SIZE},
505 		{"avail-min", 1, 0, 'A'},
506 		{"start-delay", 1, 0, 'R'},
507 		{"stop-delay", 1, 0, 'T'},
508 		{"buffer-time", 1, 0, 'B'},
509 		{"buffer-size", 1, 0, OPT_BUFFER_SIZE},
510 		{"verbose", 0, 0, 'v'},
511 		{"vumeter", 1, 0, 'V'},
512 		{"separate-channels", 0, 0, 'I'},
513 		{"playback", 0, 0, 'P'},
514 		{"capture", 0, 0, 'C'},
515 		{"disable-resample", 0, 0, OPT_DISABLE_RESAMPLE},
516 		{"disable-channels", 0, 0, OPT_DISABLE_CHANNELS},
517 		{"disable-format", 0, 0, OPT_DISABLE_FORMAT},
518 		{"disable-softvol", 0, 0, OPT_DISABLE_SOFTVOL},
519 		{"test-position", 0, 0, OPT_TEST_POSITION},
520 		{"test-coef", 1, 0, OPT_TEST_COEF},
521 		{"test-nowait", 0, 0, OPT_TEST_NOWAIT},
522 		{"max-file-time", 1, 0, OPT_MAX_FILE_TIME},
523 		{"process-id-file", 1, 0, OPT_PROCESS_ID_FILE},
524 		{"use-strftime", 0, 0, OPT_USE_STRFTIME},
525 		{"interactive", 0, 0, 'i'},
526 		{"dump-hw-params", 0, 0, OPT_DUMP_HWPARAMS},
527 		{"fatal-errors", 0, 0, OPT_FATAL_ERRORS},
528 #ifdef CONFIG_SUPPORT_CHMAP
529 		{"chmap", 1, 0, 'm'},
530 #endif
531 		{0, 0, 0, 0}
532 	};
533 	char *pcm_name = "default";
534 	int tmp, err, c;
535 	int do_device_list = 0, do_pcm_list = 0, force_sample_format = 0;
536 	snd_pcm_info_t *info;
537 	FILE *direction;
538 
539 #ifdef ENABLE_NLS
540 	setlocale(LC_ALL, "");
541 	textdomain(PACKAGE);
542 #endif
543 
544 	snd_pcm_info_alloca(&info);
545 
546 	err = snd_output_stdio_attach(&log, stderr, 0);
547 	assert(err >= 0);
548 
549 	command = argv[0];
550 	file_type = FORMAT_DEFAULT;
551 	if (strstr(argv[0], "arecord")) {
552 		stream = SND_PCM_STREAM_CAPTURE;
553 		file_type = FORMAT_WAVE;
554 		command = "arecord";
555 		start_delay = 1;
556 		direction = stdout;
557 	} else if (strstr(argv[0], "aplay")) {
558 		stream = SND_PCM_STREAM_PLAYBACK;
559 		command = "aplay";
560 		direction = stdin;
561 	} else {
562 		error(_("command should be named either arecord or aplay"));
563 		return 1;
564 	}
565 
566 	if (isatty(fileno(direction)) && (argc == 1)) {
567 		usage(command);
568 		return 1;
569 	}
570 
571 	chunk_size = -1;
572 	rhwparams.format = DEFAULT_FORMAT;
573 	rhwparams.subformat = SND_PCM_SUBFORMAT_STD;
574 	rhwparams.rate = DEFAULT_SPEED;
575 	rhwparams.channels = 1;
576 
577 	while ((c = getopt_long(argc, argv, short_options, long_options, &option_index)) != -1) {
578 		switch (c) {
579 		case 'h':
580 			usage(command);
581 			return 0;
582 		case OPT_VERSION:
583 			version();
584 			return 0;
585 		case 'l':
586 			do_device_list = 1;
587 			break;
588 		case 'L':
589 			do_pcm_list = 1;
590 			break;
591 		case 'D':
592 			pcm_name = optarg;
593 			break;
594 		case 'q':
595 			quiet_mode = 1;
596 			break;
597 		case 't':
598 			if (strcasecmp(optarg, "raw") == 0)
599 				file_type = FORMAT_RAW;
600 			else if (strcasecmp(optarg, "voc") == 0)
601 				file_type = FORMAT_VOC;
602 			else if (strcasecmp(optarg, "wav") == 0)
603 				file_type = FORMAT_WAVE;
604 			else if (strcasecmp(optarg, "au") == 0 || strcasecmp(optarg, "sparc") == 0)
605 				file_type = FORMAT_AU;
606 			else {
607 				error(_("unrecognized file format %s"), optarg);
608 				return 1;
609 			}
610 			break;
611 		case 'c':
612 			rhwparams.channels = parse_long(optarg, &err);
613 			if (err < 0) {
614 				error(_("invalid channels argument '%s'"), optarg);
615 				return 1;
616 			}
617 			if (rhwparams.channels < 1 || rhwparams.channels > 256) {
618 				error(_("value %i for channels is invalid"), rhwparams.channels);
619 				return 1;
620 			}
621 			break;
622 		case 'f':
623 			force_sample_format = 1;
624 			if (strcasecmp(optarg, "cd") == 0 || strcasecmp(optarg, "cdr") == 0) {
625 				if (strcasecmp(optarg, "cdr") == 0)
626 					rhwparams.format = SND_PCM_FORMAT_S16_BE;
627 				else
628 					rhwparams.format = file_type == FORMAT_AU ? SND_PCM_FORMAT_S16_BE : SND_PCM_FORMAT_S16_LE;
629 				rhwparams.rate = 44100;
630 				rhwparams.channels = 2;
631 			} else if (strcasecmp(optarg, "dat") == 0) {
632 				rhwparams.format = file_type == FORMAT_AU ? SND_PCM_FORMAT_S16_BE : SND_PCM_FORMAT_S16_LE;
633 				rhwparams.rate = 48000;
634 				rhwparams.channels = 2;
635 			} else {
636 				rhwparams.format = snd_pcm_format_value(optarg);
637 				if (rhwparams.format == SND_PCM_FORMAT_UNKNOWN) {
638 					error(_("wrong extended format '%s'"), optarg);
639 					prg_exit(EXIT_FAILURE);
640 				}
641 			}
642 			break;
643 		case OPT_SUBFORMAT:
644 #if SND_LIB_VER(1, 2, 10) < SND_LIB_VERSION
645 			rhwparams.subformat = snd_pcm_subformat_value(optarg);
646 			if (rhwparams.subformat == SND_PCM_SUBFORMAT_UNKNOWN) {
647 #else
648 			if (strcasecmp(optarg, "std") != 0 && strcasecmp(optarg, "standard") != 0) {
649 #endif
650 				error(_("wrong extended subformat '%s'"), optarg);
651 				prg_exit(EXIT_FAILURE);
652 			}
653 			break;
654 		case 'r':
655 			tmp = parse_long(optarg, &err);
656 			if (err < 0) {
657 				error(_("invalid rate argument '%s'"), optarg);
658 				return 1;
659 			}
660 			if (tmp < 1000)
661 				tmp *= 1000;
662 			rhwparams.rate = tmp;
663 			if (tmp < 2000 || tmp > 768000) {
664 				error(_("bad speed value %i"), tmp);
665 				return 1;
666 			}
667 			break;
668 		case 'd':
669 			if (duration_or_sample) {
670 				error(_("duration and samples arguments cannot be used together"));
671 				return 1;
672 			}
673 			timelimit = parse_long(optarg, &err);
674 			if (err < 0) {
675 				error(_("invalid duration argument '%s'"), optarg);
676 				return 1;
677 			}
678 			duration_or_sample = 1;
679 			break;
680 		case 's':
681 			if (duration_or_sample) {
682 				error(_("samples and duration arguments cannot be used together"));
683 				return 1;
684 			}
685 			sampleslimit = parse_long(optarg, &err);
686 			if (err < 0) {
687 				error(_("invalid samples argument '%s'"), optarg);
688 				return 1;
689 			}
690 			duration_or_sample = 1;
691 			break;
692 		case 'N':
693 			nonblock = 1;
694 			open_mode |= SND_PCM_NONBLOCK;
695 			break;
696 		case 'F':
697 			period_time = parse_long(optarg, &err);
698 			if (err < 0) {
699 				error(_("invalid period time argument '%s'"), optarg);
700 				return 1;
701 			}
702 			break;
703 		case 'B':
704 			buffer_time = parse_long(optarg, &err);
705 			if (err < 0) {
706 				error(_("invalid buffer time argument '%s'"), optarg);
707 				return 1;
708 			}
709 			break;
710 		case OPT_PERIOD_SIZE:
711 			period_frames = parse_long(optarg, &err);
712 			if (err < 0) {
713 				error(_("invalid period size argument '%s'"), optarg);
714 				return 1;
715 			}
716 			break;
717 		case OPT_BUFFER_SIZE:
718 			buffer_frames = parse_long(optarg, &err);
719 			if (err < 0) {
720 				error(_("invalid buffer size argument '%s'"), optarg);
721 				return 1;
722 			}
723 			break;
724 		case 'A':
725 			avail_min = parse_long(optarg, &err);
726 			if (err < 0) {
727 				error(_("invalid min available space argument '%s'"), optarg);
728 				return 1;
729 			}
730 			break;
731 		case 'R':
732 			start_delay = parse_long(optarg, &err);
733 			if (err < 0) {
734 				error(_("invalid start delay argument '%s'"), optarg);
735 				return 1;
736 			}
737 			break;
738 		case 'T':
739 			stop_delay = parse_long(optarg, &err);
740 			if (err < 0) {
741 				error(_("invalid stop delay argument '%s'"), optarg);
742 				return 1;
743 			}
744 			break;
745 		case 'v':
746 			verbose++;
747 			if (verbose > 1 && !vumeter)
748 				vumeter = VUMETER_MONO;
749 			break;
750 		case 'V':
751 			if (*optarg == 's')
752 				vumeter = VUMETER_STEREO;
753 			else if (*optarg == 'm')
754 				vumeter = VUMETER_MONO;
755 			else
756 				vumeter = VUMETER_NONE;
757 			break;
758 		case 'M':
759 			mmap_flag = 1;
760 			break;
761 		case 'I':
762 			interleaved = 0;
763 			break;
764 		case 'P':
765 			stream = SND_PCM_STREAM_PLAYBACK;
766 			command = "aplay";
767 			break;
768 		case 'C':
769 			stream = SND_PCM_STREAM_CAPTURE;
770 			command = "arecord";
771 			start_delay = 1;
772 			if (file_type == FORMAT_DEFAULT)
773 				file_type = FORMAT_WAVE;
774 			break;
775 		case 'i':
776 			interactive = 1;
777 			break;
778 		case OPT_DISABLE_RESAMPLE:
779 			open_mode |= SND_PCM_NO_AUTO_RESAMPLE;
780 			break;
781 		case OPT_DISABLE_CHANNELS:
782 			open_mode |= SND_PCM_NO_AUTO_CHANNELS;
783 			break;
784 		case OPT_DISABLE_FORMAT:
785 			open_mode |= SND_PCM_NO_AUTO_FORMAT;
786 			break;
787 		case OPT_DISABLE_SOFTVOL:
788 			open_mode |= SND_PCM_NO_SOFTVOL;
789 			break;
790 		case OPT_TEST_POSITION:
791 			test_position = 1;
792 			break;
793 		case OPT_TEST_COEF:
794 			test_coef = parse_long(optarg, &err);
795 			if (err < 0) {
796 				error(_("invalid test coef argument '%s'"), optarg);
797 				return 1;
798 			}
799 			if (test_coef < 1)
800 				test_coef = 1;
801 			break;
802 		case OPT_TEST_NOWAIT:
803 			test_nowait = 1;
804 			break;
805 		case OPT_MAX_FILE_TIME:
806 			max_file_time = parse_long(optarg, &err);
807 			if (err < 0) {
808 				error(_("invalid max file time argument '%s'"), optarg);
809 				return 1;
810 			}
811 			break;
812 		case OPT_PROCESS_ID_FILE:
813 			pidfile_name = optarg;
814 			break;
815 		case OPT_USE_STRFTIME:
816 			use_strftime = 1;
817 			break;
818 		case OPT_DUMP_HWPARAMS:
819 			dump_hw_params = 1;
820 			break;
821 		case OPT_FATAL_ERRORS:
822 			fatal_errors = 1;
823 			break;
824 #ifdef CONFIG_SUPPORT_CHMAP
825 		case 'm':
826 			channel_map = snd_pcm_chmap_parse_string(optarg);
827 			if (!channel_map) {
828 				fprintf(stderr, _("Unable to parse channel map string: %s\n"), optarg);
829 				return 1;
830 			}
831 			break;
832 #endif
833 		default:
834 			fprintf(stderr, _("Try `%s --help' for more information.\n"), command);
835 			return 1;
836 		}
837 	}
838 
839 	if (do_device_list) {
840 		if (do_pcm_list) pcm_list();
841 		device_list();
842 		goto __end;
843 	} else if (do_pcm_list) {
844 		pcm_list();
845 		goto __end;
846 	}
847 
848 	err = snd_pcm_open(&handle, pcm_name, stream, open_mode);
849 	if (err < 0) {
850 		error(_("audio open error: %s"), snd_strerror(err));
851 		return 1;
852 	}
853 
854 	if ((err = snd_pcm_info(handle, info)) < 0) {
855 		error(_("info error: %s"), snd_strerror(err));
856 		return 1;
857 	}
858 
859 	if (nonblock) {
860 		err = snd_pcm_nonblock(handle, 1);
861 		if (err < 0) {
862 			error(_("nonblock setting error: %s"), snd_strerror(err));
863 			return 1;
864 		}
865 	}
866 
867 	if (!force_sample_format &&
868 	    isatty(fileno(stdin)) &&
869 	    stream == SND_PCM_STREAM_CAPTURE &&
870 	    snd_pcm_format_width(rhwparams.format) <= 8)
871 		fprintf(stderr, "Warning: Some sources (like microphones) may produce inaudible results\n"
872 				"         with 8-bit sampling. Use '-f' argument to increase resolution\n"
873 				"         e.g. '-f S16_LE'.\n");
874 
875 	chunk_size = 1024;
876 	hwparams = rhwparams;
877 
878 	audiobuf = (uint8_t *)malloc(1024);
879 	if (audiobuf == NULL) {
880 		error(_("not enough memory"));
881 		return 1;
882 	}
883 
884 	if (mmap_flag) {
885 		writei_func = snd_pcm_mmap_writei;
886 		readi_func = snd_pcm_mmap_readi;
887 		writen_func = snd_pcm_mmap_writen;
888 		readn_func = snd_pcm_mmap_readn;
889 	} else {
890 		writei_func = snd_pcm_writei;
891 		readi_func = snd_pcm_readi;
892 		writen_func = snd_pcm_writen;
893 		readn_func = snd_pcm_readn;
894 	}
895 
896 	if (pidfile_name) {
897 		errno = 0;
898 		pidf = fopen (pidfile_name, "w");
899 		if (pidf) {
900 			(void)fprintf (pidf, "%d\n", getpid());
901 			fclose(pidf);
902 			pidfile_written = 1;
903 		} else {
904 			error(_("Cannot create process ID file %s: %s"),
905 				pidfile_name, strerror (errno));
906 			return 1;
907 		}
908 	}
909 
910 	signal(SIGINT, signal_handler);
911 	signal(SIGTERM, signal_handler);
912 	signal(SIGABRT, signal_handler);
913 	signal(SIGUSR1, signal_handler_recycle);
914 	if (interleaved) {
915 		if (optind > argc - 1) {
916 			if (stream == SND_PCM_STREAM_PLAYBACK)
917 				playback(NULL);
918 			else
919 				capture(NULL);
920 		} else {
921 			while (optind <= argc - 1) {
922 				if (stream == SND_PCM_STREAM_PLAYBACK)
923 					playback(argv[optind++]);
924 				else
925 					capture(argv[optind++]);
926 			}
927 		}
928 	} else {
929 		if (stream == SND_PCM_STREAM_PLAYBACK)
930 			playbackv(&argv[optind], argc - optind);
931 		else
932 			capturev(&argv[optind], argc - optind);
933 	}
934 	if (verbose==2)
935 		putchar('\n');
936 	snd_pcm_close(handle);
937 	handle = NULL;
938 	free(audiobuf);
939       __end:
940 	snd_output_close(log);
941 	snd_config_update_free_global();
942 	prg_exit(EXIT_SUCCESS);
943 	/* avoid warning */
944 	return EXIT_SUCCESS;
945 }
946 
947 /*
948  * Safe read (for pipes)
949  */
950 
951 static ssize_t safe_read(int fd, void *buf, size_t count)
952 {
953 	ssize_t result = 0, res;
954 
955 	while (count > 0 && !in_aborting) {
956 		if ((res = read(fd, buf, count)) == 0)
957 			break;
958 		if (res < 0)
959 			return result > 0 ? result : res;
960 		count -= res;
961 		result += res;
962 		buf = (char *)buf + res;
963 	}
964 	return result;
965 }
966 
967 /*
968  * Test, if it is a .VOC file and return >=0 if ok (this is the length of rest)
969  *                                       < 0 if not
970  */
971 static int test_vocfile(void *buffer)
972 {
973 	VocHeader *vp = buffer;
974 
975 	if (!memcmp(vp->magic, VOC_MAGIC_STRING, 20)) {
976 		vocminor = LE_SHORT(vp->version) & 0xFF;
977 		vocmajor = LE_SHORT(vp->version) / 256;
978 		if (LE_SHORT(vp->version) != (0x1233 - LE_SHORT(vp->coded_ver)))
979 			return -2;	/* coded version mismatch */
980 		return LE_SHORT(vp->headerlen) - sizeof(VocHeader);	/* 0 mostly */
981 	}
982 	return -1;		/* magic string fail */
983 }
984 
985 /*
986  * helper for test_wavefile
987  */
988 
989 static size_t test_wavefile_read(int fd, uint8_t *buffer, size_t *size, size_t reqsize, int line)
990 {
991 	if (*size >= reqsize)
992 		return *size;
993 	if ((size_t)safe_read(fd, buffer + *size, reqsize - *size) != reqsize - *size) {
994 		error(_("read error (called from line %i)"), line);
995 		prg_exit(EXIT_FAILURE);
996 	}
997 	return *size = reqsize;
998 }
999 
1000 #define check_wavefile_space(buffer, len, blimit) \
1001 	if (len > blimit) { \
1002 		blimit = len; \
1003 		if ((buffer = realloc(buffer, blimit)) == NULL) { \
1004 			error(_("not enough memory"));		  \
1005 			prg_exit(EXIT_FAILURE);  \
1006 		} \
1007 	}
1008 
1009 /*
1010  * test, if it's a .WAV file, > 0 if ok (and set the speed, stereo etc.)
1011  *                            == 0 if not
1012  * Value returned is bytes to be discarded.
1013  */
1014 static ssize_t test_wavefile(int fd, uint8_t *_buffer, size_t size)
1015 {
1016 	WaveHeader *h = (WaveHeader *)_buffer;
1017 	uint8_t *buffer = NULL;
1018 	size_t blimit = 0;
1019 	WaveFmtBody *f;
1020 	WaveChunkHeader *c;
1021 	uint32_t type, len;
1022 	unsigned short format, channels;
1023 	int big_endian, native_format;
1024 	uint8_t vbps = 0;
1025 
1026 	if (size < sizeof(WaveHeader))
1027 		return -1;
1028 	if (h->magic == WAV_RIFF)
1029 		big_endian = 0;
1030 	else if (h->magic == WAV_RIFX)
1031 		big_endian = 1;
1032 	else
1033 		return -1;
1034 	if (h->type != WAV_WAVE)
1035 		return -1;
1036 
1037 	if (size > sizeof(WaveHeader)) {
1038 		check_wavefile_space(buffer, size - sizeof(WaveHeader), blimit);
1039 		memcpy(buffer, _buffer + sizeof(WaveHeader), size - sizeof(WaveHeader));
1040 	}
1041 	size -= sizeof(WaveHeader);
1042 	while (1) {
1043 		check_wavefile_space(buffer, sizeof(WaveChunkHeader), blimit);
1044 		test_wavefile_read(fd, buffer, &size, sizeof(WaveChunkHeader), __LINE__);
1045 		c = (WaveChunkHeader*)buffer;
1046 		type = c->type;
1047 		len = TO_CPU_INT(c->length, big_endian);
1048 		len += len % 2;
1049 		if (size > sizeof(WaveChunkHeader))
1050 			memmove(buffer, buffer + sizeof(WaveChunkHeader), size - sizeof(WaveChunkHeader));
1051 		size -= sizeof(WaveChunkHeader);
1052 		if (type == WAV_FMT)
1053 			break;
1054 		check_wavefile_space(buffer, len, blimit);
1055 		test_wavefile_read(fd, buffer, &size, len, __LINE__);
1056 		if (size > len)
1057 			memmove(buffer, buffer + len, size - len);
1058 		size -= len;
1059 	}
1060 
1061 	if (len < sizeof(WaveFmtBody)) {
1062 		error(_("unknown length of 'fmt ' chunk (read %u, should be %u at least)"),
1063 		      len, (uint32_t)sizeof(WaveFmtBody));
1064 		prg_exit(EXIT_FAILURE);
1065 	}
1066 	check_wavefile_space(buffer, len, blimit);
1067 	test_wavefile_read(fd, buffer, &size, len, __LINE__);
1068 	f = (WaveFmtBody*) buffer;
1069 	format = TO_CPU_SHORT(f->format, big_endian);
1070 	if (format == WAV_FMT_EXTENSIBLE) {
1071 		WaveFmtExtensibleBody *fe = (WaveFmtExtensibleBody*)buffer;
1072 		if (len < sizeof(WaveFmtExtensibleBody)) {
1073 			error(_("unknown length of extensible 'fmt ' chunk (read %u, should be %u at least)"),
1074 					len, (unsigned int)sizeof(WaveFmtExtensibleBody));
1075 			prg_exit(EXIT_FAILURE);
1076 		}
1077 		if (memcmp(fe->guid_tag, WAV_GUID_TAG, 14) != 0) {
1078 			error(_("wrong format tag in extensible 'fmt ' chunk"));
1079 			prg_exit(EXIT_FAILURE);
1080 		}
1081 		vbps = TO_CPU_SHORT(fe->bit_p_spl, big_endian);
1082 		format = TO_CPU_SHORT(fe->guid_format, big_endian);
1083 	}
1084 	if (format != WAV_FMT_PCM &&
1085 	    format != WAV_FMT_IEEE_FLOAT) {
1086                 error(_("can't play WAVE-file format 0x%04x which is not PCM or FLOAT encoded"), format);
1087 		prg_exit(EXIT_FAILURE);
1088 	}
1089 	channels = TO_CPU_SHORT(f->channels, big_endian);
1090 	if (channels < 1) {
1091 		error(_("can't play WAVE-files with %d tracks"), channels);
1092 		prg_exit(EXIT_FAILURE);
1093 	}
1094 	hwparams.channels = channels;
1095 	if (vbps > TO_CPU_SHORT(f->bit_p_spl, big_endian)) {
1096 		error(_("valid bps greater than bps: %d > %d"), vbps, TO_CPU_SHORT(f->bit_p_spl, big_endian));
1097 		prg_exit(EXIT_FAILURE);
1098 	}
1099 	switch (TO_CPU_SHORT(f->bit_p_spl, big_endian)) {
1100 	case 8:
1101 		if (hwparams.format != DEFAULT_FORMAT &&
1102 		    hwparams.format != SND_PCM_FORMAT_U8)
1103 			fprintf(stderr, _("Warning: format is changed to U8\n"));
1104 		hwparams.format = SND_PCM_FORMAT_U8;
1105 		break;
1106 	case 16:
1107 		if (big_endian)
1108 			native_format = SND_PCM_FORMAT_S16_BE;
1109 		else
1110 			native_format = SND_PCM_FORMAT_S16_LE;
1111 		if (hwparams.format != DEFAULT_FORMAT &&
1112 		    hwparams.format != native_format)
1113 			fprintf(stderr, _("Warning: format is changed to %s\n"),
1114 				snd_pcm_format_name(native_format));
1115 		hwparams.format = native_format;
1116 		break;
1117 	case 24:
1118 		switch (TO_CPU_SHORT(f->byte_p_spl, big_endian) / hwparams.channels) {
1119 		case 3:
1120 			if (big_endian)
1121 				native_format = SND_PCM_FORMAT_S24_3BE;
1122 			else
1123 				native_format = SND_PCM_FORMAT_S24_3LE;
1124 			if (hwparams.format != DEFAULT_FORMAT &&
1125 			    hwparams.format != native_format)
1126 				fprintf(stderr, _("Warning: format is changed to %s\n"),
1127 					snd_pcm_format_name(native_format));
1128 			hwparams.format = native_format;
1129 			break;
1130 		case 4:
1131 			if (big_endian)
1132 				native_format = SND_PCM_FORMAT_S24_BE;
1133 			else
1134 				native_format = SND_PCM_FORMAT_S24_LE;
1135 			if (hwparams.format != DEFAULT_FORMAT &&
1136 			    hwparams.format != native_format)
1137 				fprintf(stderr, _("Warning: format is changed to %s\n"),
1138 					snd_pcm_format_name(native_format));
1139 			hwparams.format = native_format;
1140 			break;
1141 		default:
1142 			error(_(" can't play WAVE-files with sample %d bits in %d bytes wide (%d channels)"),
1143 			      TO_CPU_SHORT(f->bit_p_spl, big_endian),
1144 			      TO_CPU_SHORT(f->byte_p_spl, big_endian),
1145 			      hwparams.channels);
1146 			prg_exit(EXIT_FAILURE);
1147 		}
1148 		break;
1149 	case 32:
1150 		if (format == WAV_FMT_PCM) {
1151 			switch (vbps) {
1152 			case 24:
1153 				if (big_endian)
1154 					native_format = SND_PCM_FORMAT_S24_BE;
1155 				else
1156 					native_format = SND_PCM_FORMAT_S24_LE;
1157 				break;
1158 			default:
1159 				if (big_endian)
1160 					native_format = SND_PCM_FORMAT_S32_BE;
1161 				else
1162 					native_format = SND_PCM_FORMAT_S32_LE;
1163 				break;
1164 			}
1165                         hwparams.format = native_format;
1166 		} else if (format == WAV_FMT_IEEE_FLOAT) {
1167 			if (big_endian)
1168 				native_format = SND_PCM_FORMAT_FLOAT_BE;
1169 			else
1170 				native_format = SND_PCM_FORMAT_FLOAT_LE;
1171 			hwparams.format = native_format;
1172 		}
1173 		break;
1174 	default:
1175 		error(_(" can't play WAVE-files with sample %d bits wide"),
1176 		      TO_CPU_SHORT(f->bit_p_spl, big_endian));
1177 		prg_exit(EXIT_FAILURE);
1178 	}
1179 	hwparams.rate = TO_CPU_INT(f->sample_fq, big_endian);
1180 
1181 	if (size > len)
1182 		memmove(buffer, buffer + len, size - len);
1183 	size -= len;
1184 
1185 	while (1) {
1186 		uint32_t type, len;
1187 
1188 		check_wavefile_space(buffer, sizeof(WaveChunkHeader), blimit);
1189 		test_wavefile_read(fd, buffer, &size, sizeof(WaveChunkHeader), __LINE__);
1190 		c = (WaveChunkHeader*)buffer;
1191 		type = c->type;
1192 		len = TO_CPU_INT(c->length, big_endian);
1193 		if (size > sizeof(WaveChunkHeader))
1194 			memmove(buffer, buffer + sizeof(WaveChunkHeader), size - sizeof(WaveChunkHeader));
1195 		size -= sizeof(WaveChunkHeader);
1196 		if (type == WAV_DATA) {
1197 			if (len < pbrec_count && len < 0x7ffffffe)
1198 				pbrec_count = len;
1199 			if (size > 0)
1200 				memcpy(_buffer, buffer, size);
1201 			free(buffer);
1202 			return size;
1203 		}
1204 		len += len % 2;
1205 		check_wavefile_space(buffer, len, blimit);
1206 		test_wavefile_read(fd, buffer, &size, len, __LINE__);
1207 		if (size > len)
1208 			memmove(buffer, buffer + len, size - len);
1209 		size -= len;
1210 	}
1211 
1212 	/* shouldn't be reached */
1213 	return -1;
1214 }
1215 
1216 /*
1217 
1218  */
1219 
1220 static int test_au(int fd, void *buffer)
1221 {
1222 	AuHeader *ap = buffer;
1223 
1224 	if (ap->magic != AU_MAGIC)
1225 		return -1;
1226 	if (BE_INT(ap->hdr_size) > 128 || BE_INT(ap->hdr_size) < 24)
1227 		return -1;
1228 	pbrec_count = BE_INT(ap->data_size);
1229 	switch (BE_INT(ap->encoding)) {
1230 	case AU_FMT_ULAW:
1231 		if (hwparams.format != DEFAULT_FORMAT &&
1232 		    hwparams.format != SND_PCM_FORMAT_MU_LAW)
1233 			fprintf(stderr, _("Warning: format is changed to MU_LAW\n"));
1234 		hwparams.format = SND_PCM_FORMAT_MU_LAW;
1235 		break;
1236 	case AU_FMT_LIN8:
1237 		if (hwparams.format != DEFAULT_FORMAT &&
1238 		    hwparams.format != SND_PCM_FORMAT_U8)
1239 			fprintf(stderr, _("Warning: format is changed to U8\n"));
1240 		hwparams.format = SND_PCM_FORMAT_U8;
1241 		break;
1242 	case AU_FMT_LIN16:
1243 		if (hwparams.format != DEFAULT_FORMAT &&
1244 		    hwparams.format != SND_PCM_FORMAT_S16_BE)
1245 			fprintf(stderr, _("Warning: format is changed to S16_BE\n"));
1246 		hwparams.format = SND_PCM_FORMAT_S16_BE;
1247 		break;
1248 	default:
1249 		return -1;
1250 	}
1251 	hwparams.rate = BE_INT(ap->sample_rate);
1252 	if (hwparams.rate < 2000 || hwparams.rate > 256000)
1253 		return -1;
1254 	hwparams.channels = BE_INT(ap->channels);
1255 	if (hwparams.channels < 1 || hwparams.channels > 256)
1256 		return -1;
1257 	if ((size_t)safe_read(fd, (char *)buffer + sizeof(AuHeader), BE_INT(ap->hdr_size) - sizeof(AuHeader)) != BE_INT(ap->hdr_size) - sizeof(AuHeader)) {
1258 		error(_("read error"));
1259 		prg_exit(EXIT_FAILURE);
1260 	}
1261 	return 0;
1262 }
1263 
1264 static void show_available_sample_formats(snd_pcm_hw_params_t* params)
1265 {
1266 	snd_pcm_format_t format;
1267 
1268 	fprintf(stderr, "Available formats:\n");
1269 	for (format = 0; format <= SND_PCM_FORMAT_LAST; format++) {
1270 		if (snd_pcm_hw_params_test_format(handle, params, format) == 0)
1271 			fprintf(stderr, "- %s\n", snd_pcm_format_name(format));
1272 	}
1273 }
1274 
1275 #ifdef CONFIG_SUPPORT_CHMAP
1276 static int setup_chmap(void)
1277 {
1278 	snd_pcm_chmap_t *chmap = channel_map;
1279 	char mapped[hwparams.channels];
1280 	snd_pcm_chmap_t *hw_chmap;
1281 	unsigned int ch, i;
1282 	int err;
1283 
1284 	if (!chmap)
1285 		return 0;
1286 
1287 	if (chmap->channels != hwparams.channels) {
1288 		error(_("Channel numbers don't match between hw_params and channel map"));
1289 		return -1;
1290 	}
1291 	err = snd_pcm_set_chmap(handle, chmap);
1292 	if (!err)
1293 		return 0;
1294 
1295 	hw_chmap = snd_pcm_get_chmap(handle);
1296 	if (!hw_chmap) {
1297 		fprintf(stderr, _("Warning: unable to get channel map\n"));
1298 		return 0;
1299 	}
1300 
1301 	if (hw_chmap->channels == chmap->channels &&
1302 	    !memcmp(hw_chmap, chmap, 4 * (chmap->channels + 1))) {
1303 		/* maps are identical, so no need to convert */
1304 		free(hw_chmap);
1305 		return 0;
1306 	}
1307 
1308 	hw_map = calloc(hwparams.channels, sizeof(int));
1309 	if (!hw_map) {
1310 		error(_("not enough memory"));
1311 		free(hw_chmap);
1312 		return -1;
1313 	}
1314 
1315 	memset(mapped, 0, sizeof(mapped));
1316 	for (ch = 0; ch < hw_chmap->channels; ch++) {
1317 		if (chmap->pos[ch] == hw_chmap->pos[ch]) {
1318 			mapped[ch] = 1;
1319 			hw_map[ch] = ch;
1320 			continue;
1321 		}
1322 		for (i = 0; i < hw_chmap->channels; i++) {
1323 			if (!mapped[i] && chmap->pos[ch] == hw_chmap->pos[i]) {
1324 				mapped[i] = 1;
1325 				hw_map[ch] = i;
1326 				break;
1327 			}
1328 		}
1329 		if (i >= hw_chmap->channels) {
1330 			char buf[256];
1331 			error(_("Channel %d doesn't match with hw_params"), ch);
1332 			snd_pcm_chmap_print(hw_chmap, sizeof(buf), buf);
1333 			fprintf(stderr, "hardware chmap = %s\n", buf);
1334 			free(hw_chmap);
1335 			return -1;
1336 		}
1337 	}
1338 	free(hw_chmap);
1339 	return 0;
1340 }
1341 #else
1342 #define setup_chmap()	0
1343 #endif
1344 
1345 static void set_params(void)
1346 {
1347 	snd_pcm_hw_params_t *params;
1348 	snd_pcm_sw_params_t *swparams;
1349 	snd_pcm_uframes_t buffer_size;
1350 	int err;
1351 	size_t n;
1352 	unsigned int rate;
1353 	snd_pcm_uframes_t start_threshold, stop_threshold;
1354 	snd_pcm_hw_params_alloca(&params);
1355 	snd_pcm_sw_params_alloca(&swparams);
1356 	err = snd_pcm_hw_params_any(handle, params);
1357 	if (err < 0) {
1358 		error(_("Broken configuration for this PCM: no configurations available"));
1359 		prg_exit(EXIT_FAILURE);
1360 	}
1361 	if (dump_hw_params) {
1362 		fprintf(stderr, _("HW Params of device \"%s\":\n"),
1363 			snd_pcm_name(handle));
1364 		fprintf(stderr, "--------------------\n");
1365 		snd_pcm_hw_params_dump(params, log);
1366 		fprintf(stderr, "--------------------\n");
1367 	}
1368 	if (mmap_flag) {
1369 		snd_pcm_access_mask_t *mask = alloca(snd_pcm_access_mask_sizeof());
1370 		snd_pcm_access_mask_none(mask);
1371 		snd_pcm_access_mask_set(mask, SND_PCM_ACCESS_MMAP_INTERLEAVED);
1372 		snd_pcm_access_mask_set(mask, SND_PCM_ACCESS_MMAP_NONINTERLEAVED);
1373 		snd_pcm_access_mask_set(mask, SND_PCM_ACCESS_MMAP_COMPLEX);
1374 		err = snd_pcm_hw_params_set_access_mask(handle, params, mask);
1375 	} else if (interleaved)
1376 		err = snd_pcm_hw_params_set_access(handle, params,
1377 						   SND_PCM_ACCESS_RW_INTERLEAVED);
1378 	else
1379 		err = snd_pcm_hw_params_set_access(handle, params,
1380 						   SND_PCM_ACCESS_RW_NONINTERLEAVED);
1381 	if (err < 0) {
1382 		error(_("Access type not available"));
1383 		prg_exit(EXIT_FAILURE);
1384 	}
1385 	err = snd_pcm_hw_params_set_format(handle, params, hwparams.format);
1386 	if (err < 0) {
1387 		error(_("Sample format non available"));
1388 		show_available_sample_formats(params);
1389 		prg_exit(EXIT_FAILURE);
1390 	}
1391 	err = snd_pcm_hw_params_set_subformat(handle, params, hwparams.subformat);
1392 	if (err < 0) {
1393 		error(_("Sample subformat not available"));
1394 		prg_exit(EXIT_FAILURE);
1395 	}
1396 	err = snd_pcm_hw_params_set_channels(handle, params, hwparams.channels);
1397 	if (err < 0) {
1398 		error(_("Channels count non available"));
1399 		prg_exit(EXIT_FAILURE);
1400 	}
1401 
1402 #if 0
1403 	err = snd_pcm_hw_params_set_periods_min(handle, params, 2);
1404 	assert(err >= 0);
1405 #endif
1406 	rate = hwparams.rate;
1407 	err = snd_pcm_hw_params_set_rate_near(handle, params, &hwparams.rate, 0);
1408 	assert(err >= 0);
1409 	if ((float)rate * 1.05 < hwparams.rate || (float)rate * 0.95 > hwparams.rate) {
1410 		if (!quiet_mode) {
1411 			char plugex[64];
1412 			const char *pcmname = snd_pcm_name(handle);
1413 			fprintf(stderr, _("Warning: rate is not accurate (requested = %iHz, got = %iHz)\n"), rate, hwparams.rate);
1414 			if (! pcmname || strchr(snd_pcm_name(handle), ':'))
1415 				*plugex = 0;
1416 			else
1417 				snprintf(plugex, sizeof(plugex), "(-Dplug:%s)",
1418 					 snd_pcm_name(handle));
1419 			fprintf(stderr, _("         please, try the plug plugin %s\n"),
1420 				plugex);
1421 		}
1422 	}
1423 	rate = hwparams.rate;
1424 	if (buffer_time == 0 && buffer_frames == 0) {
1425 		err = snd_pcm_hw_params_get_buffer_time_max(params,
1426 							    &buffer_time, 0);
1427 		assert(err >= 0);
1428 		if (buffer_time > 500000)
1429 			buffer_time = 500000;
1430 	}
1431 	if (period_time == 0 && period_frames == 0) {
1432 		if (buffer_time > 0)
1433 			period_time = buffer_time / 4;
1434 		else
1435 			period_frames = buffer_frames / 4;
1436 	}
1437 	if (period_time > 0)
1438 		err = snd_pcm_hw_params_set_period_time_near(handle, params,
1439 							     &period_time, 0);
1440 	else
1441 		err = snd_pcm_hw_params_set_period_size_near(handle, params,
1442 							     &period_frames, 0);
1443 	assert(err >= 0);
1444 	if (buffer_time > 0) {
1445 		err = snd_pcm_hw_params_set_buffer_time_near(handle, params,
1446 							     &buffer_time, 0);
1447 	} else {
1448 		err = snd_pcm_hw_params_set_buffer_size_near(handle, params,
1449 							     &buffer_frames);
1450 	}
1451 	assert(err >= 0);
1452 	monotonic = snd_pcm_hw_params_is_monotonic(params);
1453 	can_pause = snd_pcm_hw_params_can_pause(params);
1454 	err = snd_pcm_hw_params(handle, params);
1455 	if (err < 0) {
1456 		error(_("Unable to install hw params:"));
1457 		snd_pcm_hw_params_dump(params, log);
1458 		prg_exit(EXIT_FAILURE);
1459 	}
1460 	snd_pcm_hw_params_get_period_size(params, &chunk_size, 0);
1461 	snd_pcm_hw_params_get_buffer_size(params, &buffer_size);
1462 	if (chunk_size == buffer_size) {
1463 		error(_("Can't use period equal to buffer size (%lu == %lu)"),
1464 		      chunk_size, buffer_size);
1465 		prg_exit(EXIT_FAILURE);
1466 	}
1467 	err = snd_pcm_sw_params_current(handle, swparams);
1468 	if (err < 0) {
1469 		error(_("Unable to get current sw params."));
1470 		prg_exit(EXIT_FAILURE);
1471 	}
1472 	if (avail_min < 0)
1473 		n = chunk_size;
1474 	else
1475 		n = (double) rate * avail_min / 1000000;
1476 	err = snd_pcm_sw_params_set_avail_min(handle, swparams, n);
1477 
1478 	/* round up to closest transfer boundary */
1479 	n = buffer_size;
1480 	if (start_delay <= 0) {
1481 		start_threshold = n + (double) rate * start_delay / 1000000;
1482 	} else
1483 		start_threshold = (double) rate * start_delay / 1000000;
1484 	if (start_threshold < 1)
1485 		start_threshold = 1;
1486 	if (start_threshold > n)
1487 		start_threshold = n;
1488 	err = snd_pcm_sw_params_set_start_threshold(handle, swparams, start_threshold);
1489 	assert(err >= 0);
1490 	if (stop_delay <= 0)
1491 		stop_threshold = buffer_size + (double) rate * stop_delay / 1000000;
1492 	else
1493 		stop_threshold = (double) rate * stop_delay / 1000000;
1494 	err = snd_pcm_sw_params_set_stop_threshold(handle, swparams, stop_threshold);
1495 	assert(err >= 0);
1496 
1497 	if (verbose) {
1498 		err = snd_pcm_sw_params_set_tstamp_mode(handle, swparams, SND_PCM_TSTAMP_ENABLE);
1499 		assert(err >= 0);
1500 
1501 		if (monotonic)
1502 			err = snd_pcm_sw_params_set_tstamp_type(handle, swparams, SND_PCM_TSTAMP_TYPE_MONOTONIC);
1503 		else
1504 			err = snd_pcm_sw_params_set_tstamp_type(handle, swparams, SND_PCM_TSTAMP_TYPE_GETTIMEOFDAY);
1505 		assert(err >= 0);
1506 	}
1507 
1508 	if (snd_pcm_sw_params(handle, swparams) < 0) {
1509 		error(_("unable to install sw params:"));
1510 		snd_pcm_sw_params_dump(swparams, log);
1511 		prg_exit(EXIT_FAILURE);
1512 	}
1513 
1514 	if (setup_chmap())
1515 		prg_exit(EXIT_FAILURE);
1516 
1517 	if (verbose)
1518 		snd_pcm_dump(handle, log);
1519 
1520 	bits_per_sample = snd_pcm_format_physical_width(hwparams.format);
1521 	significant_bits_per_sample = snd_pcm_format_width(hwparams.format);
1522 	bits_per_frame = bits_per_sample * hwparams.channels;
1523 	chunk_bytes = chunk_size * bits_per_frame / 8;
1524 	audiobuf = realloc(audiobuf, chunk_bytes);
1525 	if (audiobuf == NULL) {
1526 		error(_("not enough memory"));
1527 		prg_exit(EXIT_FAILURE);
1528 	}
1529 	// fprintf(stderr, "real chunk_size = %i, frags = %i, total = %i\n", chunk_size, setup.buf.block.frags, setup.buf.block.frags * chunk_size);
1530 
1531 	/* stereo VU-meter isn't always available... */
1532 	if (vumeter == VUMETER_STEREO) {
1533 		if (hwparams.channels != 2 || !interleaved || verbose > 2)
1534 			vumeter = VUMETER_MONO;
1535 	}
1536 
1537 	/* show mmap buffer arragment */
1538 	if (mmap_flag && verbose) {
1539 		const snd_pcm_channel_area_t *areas;
1540 		snd_pcm_uframes_t offset, size = chunk_size;
1541 		int i;
1542 		err = snd_pcm_mmap_begin(handle, &areas, &offset, &size);
1543 		if (err < 0) {
1544 			error(_("snd_pcm_mmap_begin problem: %s"), snd_strerror(err));
1545 			prg_exit(EXIT_FAILURE);
1546 		}
1547 		for (i = 0; i < (int)hwparams.channels; i++)
1548 			fprintf(stderr, "mmap_area[%i] = %p,%u,%u (%u)\n", i, areas[i].addr, areas[i].first, areas[i].step, snd_pcm_format_physical_width(hwparams.format));
1549 		/* not required, but for sure */
1550 		snd_pcm_mmap_commit(handle, offset, 0);
1551 	}
1552 
1553 	buffer_frames = buffer_size;	/* for position test */
1554 }
1555 
1556 static void init_stdin(void)
1557 {
1558 	struct termios term;
1559 	long flags;
1560 
1561 	if (!interactive)
1562 		return;
1563 	if (!isatty(fileno(stdin))) {
1564 		interactive = 0;
1565 		return;
1566 	}
1567 	tcgetattr(fileno(stdin), &term);
1568 	term_c_lflag = term.c_lflag;
1569 	if (fd == fileno(stdin))
1570 		return;
1571 	flags = fcntl(fileno(stdin), F_GETFL);
1572 	if (flags < 0 || fcntl(fileno(stdin), F_SETFL, flags|O_NONBLOCK) < 0)
1573 		fprintf(stderr, _("stdin O_NONBLOCK flag setup failed\n"));
1574 	term.c_lflag &= ~ICANON;
1575 	tcsetattr(fileno(stdin), TCSANOW, &term);
1576 }
1577 
1578 static void done_stdin(void)
1579 {
1580 	struct termios term;
1581 
1582 	if (!interactive)
1583 		return;
1584 	if (fd == fileno(stdin) || term_c_lflag == -1)
1585 		return;
1586 	tcgetattr(fileno(stdin), &term);
1587 	term.c_lflag = term_c_lflag;
1588 	tcsetattr(fileno(stdin), TCSANOW, &term);
1589 }
1590 
1591 static char wait_for_input(void)
1592 {
1593 	struct pollfd pfd;
1594 	unsigned char b;
1595 
1596 	do {
1597 		pfd.fd = fileno(stdin);
1598 		pfd.events = POLLIN;
1599 		poll(&pfd, 1, -1);
1600 	} while (read(fileno(stdin), &b, 1) != 1);
1601 	return b;
1602 }
1603 
1604 static void do_pause(void)
1605 {
1606 	int err;
1607 	unsigned char b;
1608 
1609 	if (!can_pause) {
1610 		fprintf(stderr, _("\rPAUSE command ignored (no hw support)\n"));
1611 		return;
1612 	}
1613 	if (snd_pcm_state(handle) == SND_PCM_STATE_SUSPENDED)
1614 		suspend();
1615 
1616 	err = snd_pcm_pause(handle, 1);
1617 	if (err < 0) {
1618 		error(_("pause push error: %s"), snd_strerror(err));
1619 		return;
1620 	}
1621 	while (1) {
1622 		b = wait_for_input();
1623 		if (b == ' ' || b == '\r') {
1624 			while (read(fileno(stdin), &b, 1) == 1);
1625 			if (snd_pcm_state(handle) == SND_PCM_STATE_SUSPENDED)
1626 				suspend();
1627 			err = snd_pcm_pause(handle, 0);
1628 			if (err < 0)
1629 				error(_("pause release error: %s"), snd_strerror(err));
1630 			return;
1631 		}
1632 	}
1633 }
1634 
1635 static void check_stdin(void)
1636 {
1637 	unsigned char b;
1638 
1639 	if (!interactive)
1640 		return;
1641 	if (fd != fileno(stdin)) {
1642 		while (read(fileno(stdin), &b, 1) == 1) {
1643 			if (b == ' ' || b == '\r') {
1644 				while (read(fileno(stdin), &b, 1) == 1);
1645 				fprintf(stderr, _("\r=== PAUSE ===                                                            "));
1646 				fflush(stderr);
1647 				do_pause();
1648 				fprintf(stderr, "                                                                          \r");
1649 				fflush(stderr);
1650 			}
1651 		}
1652 	}
1653 }
1654 
1655 #ifndef timersub
1656 #define	timersub(a, b, result) \
1657 do { \
1658 	(result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
1659 	(result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
1660 	if ((result)->tv_usec < 0) { \
1661 		--(result)->tv_sec; \
1662 		(result)->tv_usec += 1000000; \
1663 	} \
1664 } while (0)
1665 #endif
1666 
1667 #ifndef timermsub
1668 #define	timermsub(a, b, result) \
1669 do { \
1670 	(result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
1671 	(result)->tv_nsec = (a)->tv_nsec - (b)->tv_nsec; \
1672 	if ((result)->tv_nsec < 0) { \
1673 		--(result)->tv_sec; \
1674 		(result)->tv_nsec += 1000000000L; \
1675 	} \
1676 } while (0)
1677 #endif
1678 
1679 /* I/O error handler */
1680 static void xrun(void)
1681 {
1682 	snd_pcm_status_t *status;
1683 	int res;
1684 
1685 	snd_pcm_status_alloca(&status);
1686 	if ((res = snd_pcm_status(handle, status))<0) {
1687 		error(_("status error: %s"), snd_strerror(res));
1688 		prg_exit(EXIT_FAILURE);
1689 	}
1690 	if (snd_pcm_status_get_state(status) == SND_PCM_STATE_XRUN) {
1691 		if (monotonic) {
1692 #ifdef HAVE_CLOCK_GETTIME
1693 			struct timespec now, diff, tstamp;
1694 			clock_gettime(CLOCK_MONOTONIC, &now);
1695 			snd_pcm_status_get_trigger_htstamp(status, &tstamp);
1696 			timermsub(&now, &tstamp, &diff);
1697 			fprintf(stderr, _("%s!!! (at least %.3f ms long)\n"),
1698 				stream == SND_PCM_STREAM_PLAYBACK ? _("underrun") : _("overrun"),
1699 				diff.tv_sec * 1000 + diff.tv_nsec / 1000000.0);
1700 #else
1701 			fprintf(stderr, "%s !!!\n", _("underrun"));
1702 #endif
1703 		} else {
1704 			struct timeval now, diff, tstamp;
1705 			gettimeofday(&now, 0);
1706 			snd_pcm_status_get_trigger_tstamp(status, &tstamp);
1707 			timersub(&now, &tstamp, &diff);
1708 			fprintf(stderr, _("%s!!! (at least %.3f ms long)\n"),
1709 				stream == SND_PCM_STREAM_PLAYBACK ? _("underrun") : _("overrun"),
1710 				diff.tv_sec * 1000 + diff.tv_usec / 1000.0);
1711 		}
1712 		if (verbose) {
1713 			fprintf(stderr, _("Status:\n"));
1714 			snd_pcm_status_dump(status, log);
1715 		}
1716 		if (fatal_errors) {
1717 			error(_("fatal %s: %s"),
1718 					stream == SND_PCM_STREAM_PLAYBACK ? _("underrun") : _("overrun"),
1719 					snd_strerror(res));
1720 			prg_exit(EXIT_FAILURE);
1721 		}
1722 		if ((res = snd_pcm_prepare(handle))<0) {
1723 			error(_("xrun: prepare error: %s"), snd_strerror(res));
1724 			prg_exit(EXIT_FAILURE);
1725 		}
1726 		return;		/* ok, data should be accepted again */
1727 	}
1728 	if (snd_pcm_status_get_state(status) == SND_PCM_STATE_DRAINING) {
1729 		if (verbose) {
1730 			fprintf(stderr, _("Status(DRAINING):\n"));
1731 			snd_pcm_status_dump(status, log);
1732 		}
1733 		if (stream == SND_PCM_STREAM_CAPTURE) {
1734 			fprintf(stderr, _("capture stream format change? attempting recover...\n"));
1735 			if ((res = snd_pcm_prepare(handle))<0) {
1736 				error(_("xrun(DRAINING): prepare error: %s"), snd_strerror(res));
1737 				prg_exit(EXIT_FAILURE);
1738 			}
1739 			return;
1740 		}
1741 	}
1742 	if (verbose) {
1743 		fprintf(stderr, _("Status(R/W):\n"));
1744 		snd_pcm_status_dump(status, log);
1745 	}
1746 	error(_("read/write error, state = %s"), snd_pcm_state_name(snd_pcm_status_get_state(status)));
1747 	prg_exit(EXIT_FAILURE);
1748 }
1749 
1750 /* I/O suspend handler */
1751 static void suspend(void)
1752 {
1753 	int res;
1754 
1755 	if (!quiet_mode) {
1756 		fprintf(stderr, _("Suspended. Trying resume. ")); fflush(stderr);
1757 	}
1758 	while ((res = snd_pcm_resume(handle)) == -EAGAIN)
1759 		sleep(1);	/* wait until suspend flag is released */
1760 	if (res < 0) {
1761 		if (!quiet_mode) {
1762 			fprintf(stderr, _("Failed. Restarting stream. ")); fflush(stderr);
1763 		}
1764 		if ((res = snd_pcm_prepare(handle)) < 0) {
1765 			error(_("suspend: prepare error: %s"), snd_strerror(res));
1766 			prg_exit(EXIT_FAILURE);
1767 		}
1768 	}
1769 	if (!quiet_mode)
1770 		fprintf(stderr, _("Done.\n"));
1771 }
1772 
1773 static void print_vu_meter_mono(int perc, int maxperc)
1774 {
1775 	const int bar_length = 50;
1776 	char line[80];
1777 	int val;
1778 
1779 	for (val = 0; val <= perc * bar_length / 100 && val < bar_length; val++)
1780 		line[val] = '#';
1781 	for (; val <= maxperc * bar_length / 100 && val < bar_length; val++)
1782 		line[val] = ' ';
1783 	line[val] = '+';
1784 	for (++val; val <= bar_length; val++)
1785 		line[val] = ' ';
1786 	if (maxperc > 99)
1787 		sprintf(line + val, "| MAX");
1788 	else
1789 		sprintf(line + val, "| %02i%%", maxperc);
1790 	fputs(line, stderr);
1791 	if (perc > 100)
1792 		fprintf(stderr, _(" !clip  "));
1793 }
1794 
1795 static void print_vu_meter_stereo(int *perc, int *maxperc)
1796 {
1797 	const int bar_length = 35;
1798 	char line[80];
1799 	int c;
1800 
1801 	memset(line, ' ', sizeof(line) - 1);
1802 	line[bar_length + 3] = '|';
1803 
1804 	for (c = 0; c < 2; c++) {
1805 		int p = perc[c] * bar_length / 100;
1806 		char tmp[4];
1807 		if (p > bar_length)
1808 			p = bar_length;
1809 		if (c)
1810 			memset(line + bar_length + 6 + 1, '#', p);
1811 		else
1812 			memset(line + bar_length - p, '#', p);
1813 		p = maxperc[c] * bar_length / 100 - 1;
1814 		if (p < 0)
1815 			p = 0;
1816 		else if (p >= bar_length)
1817 			p = bar_length - 1;
1818 		if (c)
1819 			line[bar_length + 6 + 1 + p] = '+';
1820 		else
1821 			line[bar_length - p - 1] = '+';
1822 		if (ABS(maxperc[c]) > 99)
1823 			sprintf(tmp, "MAX");
1824 		else
1825 			sprintf(tmp, "%02d%%", maxperc[c]);
1826 		if (c)
1827 			memcpy(line + bar_length + 3 + 1, tmp, 3);
1828 		else
1829 			memcpy(line + bar_length, tmp, 3);
1830 	}
1831 	line[bar_length * 2 + 6 + 2] = 0;
1832 	fputs(line, stderr);
1833 }
1834 
1835 static void print_vu_meter(signed int *perc, signed int *maxperc)
1836 {
1837 	if (vumeter == VUMETER_STEREO)
1838 		print_vu_meter_stereo(perc, maxperc);
1839 	else
1840 		print_vu_meter_mono(*perc, *maxperc);
1841 }
1842 
1843 /* peak handler */
1844 static void compute_max_peak(uint8_t *data, size_t samples)
1845 {
1846 	signed int val, max, perc[2], max_peak[2];
1847 	static int run = 0;
1848 	size_t osamples = samples;
1849 	int format_little_endian = snd_pcm_format_little_endian(hwparams.format);
1850 	int ichans, c;
1851 
1852 	if (vumeter == VUMETER_STEREO)
1853 		ichans = 2;
1854 	else
1855 		ichans = 1;
1856 
1857 	memset(max_peak, 0, sizeof(max_peak));
1858 	switch (bits_per_sample) {
1859 	case 8: {
1860 		signed char *valp = (signed char *)data;
1861 		signed char mask = snd_pcm_format_silence(hwparams.format);
1862 		c = 0;
1863 		while (samples-- > 0) {
1864 			val = *valp++ ^ mask;
1865 			val = abs(val);
1866 			if (max_peak[c] < val)
1867 				max_peak[c] = val;
1868 			if (vumeter == VUMETER_STEREO)
1869 				c = !c;
1870 		}
1871 		break;
1872 	}
1873 	case 16: {
1874 		signed short *valp = (signed short *)data;
1875 		signed short mask = snd_pcm_format_silence_16(hwparams.format);
1876 		signed short sval;
1877 
1878 		c = 0;
1879 		while (samples-- > 0) {
1880 			if (format_little_endian)
1881 				sval = le16toh(*valp);
1882 			else
1883 				sval = be16toh(*valp);
1884 			sval ^= mask;
1885 			val = abs(sval);
1886 			if (max_peak[c] < val)
1887 				max_peak[c] = val;
1888 			valp++;
1889 			if (vumeter == VUMETER_STEREO)
1890 				c = !c;
1891 		}
1892 		break;
1893 	}
1894 	case 24: {
1895 		unsigned char *valp = data;
1896 		signed int mask = snd_pcm_format_silence_32(hwparams.format);
1897 
1898 		c = 0;
1899 		while (samples-- > 0) {
1900 			if (format_little_endian) {
1901 				val = valp[0] | (valp[1]<<8) | (valp[2]<<16);
1902 			} else {
1903 				val = (valp[0]<<16) | (valp[1]<<8) | valp[2];
1904 			}
1905 			val ^= mask;
1906 			/* Correct signed bit in 32-bit value */
1907 			if (val & (1<<(bits_per_sample-1))) {
1908 				val |= 0xff<<24;	/* Negate upper bits too */
1909 			}
1910 			val = abs(val);
1911 			if (max_peak[c] < val)
1912 				max_peak[c] = val;
1913 			valp += 3;
1914 			if (vumeter == VUMETER_STEREO)
1915 				c = !c;
1916 		}
1917 		break;
1918 	}
1919 	case 32: {
1920 		signed int *valp = (signed int *)data;
1921 		signed int mask = snd_pcm_format_silence_32(hwparams.format);
1922 
1923 		c = 0;
1924 		while (samples-- > 0) {
1925 			if (format_little_endian)
1926 				val = le32toh(*valp);
1927 			else
1928 				val = be32toh(*valp);
1929 			val ^= mask;
1930 			if ((unsigned int)val == 0x80000000U)
1931 				val = 0x7fffffff;
1932 			else
1933 				val = abs(val);
1934 			if (max_peak[c] < val)
1935 				max_peak[c] = val;
1936 			valp++;
1937 			if (vumeter == VUMETER_STEREO)
1938 				c = !c;
1939 		}
1940 		break;
1941 	}
1942 	default:
1943 		if (run == 0) {
1944 			fprintf(stderr, _("Unsupported bit size %d.\n"), (int)bits_per_sample);
1945 			run = 1;
1946 		}
1947 		return;
1948 	}
1949 	max = 1 << (significant_bits_per_sample-1);
1950 	if (max <= 0)
1951 		max = 0x7fffffff;
1952 
1953 	for (c = 0; c < ichans; c++) {
1954 		if (max_peak[c] > max)
1955 			max_peak[c] = max;
1956 		if (bits_per_sample > 16)
1957 			perc[c] = max_peak[c] / (max / 100);
1958 		else
1959 			perc[c] = max_peak[c] * 100 / max;
1960 	}
1961 
1962 	if (interleaved && verbose <= 2) {
1963 		static int maxperc[2];
1964 		static time_t t=0;
1965 		const time_t tt=time(NULL);
1966 		if(tt>t) {
1967 			t=tt;
1968 			maxperc[0] = 0;
1969 			maxperc[1] = 0;
1970 		}
1971 		for (c = 0; c < ichans; c++)
1972 			if (perc[c] > maxperc[c])
1973 				maxperc[c] = perc[c];
1974 
1975 		putc('\r', stderr);
1976 		print_vu_meter(perc, maxperc);
1977 		fflush(stderr);
1978 	}
1979 	else if (verbose==3) {
1980 		fprintf(stderr, _("Max peak (%li samples): 0x%08x "), (long)osamples, max_peak[0]);
1981 		for (val = 0; val < 20; val++)
1982 			if (val <= perc[0] / 5)
1983 				putc('#', stderr);
1984 			else
1985 				putc(' ', stderr);
1986 		fprintf(stderr, " %i%%\n", perc[0]);
1987 		fflush(stderr);
1988 	}
1989 }
1990 
1991 static void do_test_position(void)
1992 {
1993 	static long counter = 0;
1994 	static time_t tmr = -1;
1995 	time_t now;
1996 	static float availsum, delaysum, samples;
1997 	static snd_pcm_sframes_t maxavail, maxdelay;
1998 	static snd_pcm_sframes_t minavail, mindelay;
1999 	static snd_pcm_sframes_t badavail = 0, baddelay = 0;
2000 	snd_pcm_sframes_t outofrange;
2001 	snd_pcm_sframes_t avail, delay, savail, sdelay;
2002 	snd_pcm_status_t *status;
2003 	int err;
2004 
2005 	snd_pcm_status_alloca(&status);
2006 	err = snd_pcm_avail_delay(handle, &avail, &delay);
2007 	if (err < 0)
2008 		return;
2009 	err = snd_pcm_status(handle, status);
2010 	if (err < 0)
2011 		return;
2012 	savail = snd_pcm_status_get_avail(status);
2013 	sdelay = snd_pcm_status_get_delay(status);
2014 	outofrange = (test_coef * (snd_pcm_sframes_t)buffer_frames) / 2;
2015 	if (avail > outofrange || avail < -outofrange ||
2016 	    delay > outofrange || delay < -outofrange) {
2017 		badavail = avail; baddelay = delay;
2018 		availsum = delaysum = samples = 0;
2019 		maxavail = maxdelay = 0;
2020 		minavail = mindelay = buffer_frames * 16;
2021 		fprintf(stderr, _("Suspicious buffer position (%li total): "
2022 			"avail = %li, delay = %li, buffer = %li\n"),
2023 			++counter, (long)avail, (long)delay, (long)buffer_frames);
2024 	} else if (savail > outofrange || savail < -outofrange ||
2025 		   sdelay > outofrange || sdelay < -outofrange) {
2026 		badavail = savail; baddelay = sdelay;
2027 		availsum = delaysum = samples = 0;
2028 		maxavail = maxdelay = 0;
2029 		minavail = mindelay = buffer_frames * 16;
2030 		fprintf(stderr, _("Suspicious status buffer position (%li total): "
2031 			"avail = %li, delay = %li, buffer = %li\n"),
2032 			++counter, (long)savail, (long)sdelay, (long)buffer_frames);
2033 	} else if (stream == SND_PCM_STREAM_CAPTURE && avail > delay) {
2034 		fprintf(stderr, _("Suspicious buffer position avail > delay (%li total): "
2035 			"avail = %li, delay = %li\n"),
2036 			++counter, (long)avail, (long)delay);
2037 	} else if (stream == SND_PCM_STREAM_CAPTURE && savail > sdelay) {
2038 		fprintf(stderr, _("Suspicious status buffer position avail > delay (%li total): "
2039 			"avail = %li, delay = %li\n"),
2040 			++counter, (long)savail, (long)sdelay);
2041 	} else if (verbose) {
2042 		time(&now);
2043 		if (tmr == (time_t) -1) {
2044 			tmr = now;
2045 			availsum = delaysum = samples = 0;
2046 			maxavail = maxdelay = 0;
2047 			minavail = mindelay = buffer_frames * 16;
2048 		}
2049 		if (avail > maxavail)
2050 			maxavail = avail;
2051 		if (savail > maxavail)
2052 			maxavail = savail;
2053 		if (delay > maxdelay)
2054 			maxdelay = delay;
2055 		if (sdelay > maxdelay)
2056 			maxdelay = sdelay;
2057 		if (avail < minavail)
2058 			minavail = avail;
2059 		if (savail < minavail)
2060 			minavail = savail;
2061 		if (delay < mindelay)
2062 			mindelay = delay;
2063 		if (sdelay < mindelay)
2064 			mindelay = sdelay;
2065 		availsum += avail;
2066 		delaysum += delay;
2067 		samples++;
2068 		if ((maxavail != 0 || maxdelay != 0) && now != tmr) {
2069 			fprintf(stderr, "BUFPOS: avg%li/%li "
2070 				"min%li/%li max%li/%li (%li) (%li:%li/%li)\n",
2071                          (long)(availsum / samples),
2072 				(long)(delaysum / samples),
2073 				(long)minavail, (long)mindelay,
2074 				(long)maxavail, (long)maxdelay,
2075 				(long)buffer_frames,
2076 				counter, badavail, baddelay);
2077 			tmr = now;
2078 		}
2079 	}
2080 	if (verbose == 1) {
2081 		fprintf(stderr, _("Status(R/W) (standalone avail=%li delay=%li):\n"), (long)avail, (long)delay);
2082 		snd_pcm_status_dump(status, log);
2083 	}
2084 }
2085 
2086 /*
2087  */
2088 #ifdef CONFIG_SUPPORT_CHMAP
2089 static uint8_t *remap_data(uint8_t *data, size_t count)
2090 {
2091 	static uint8_t *tmp, *src, *dst;
2092 	static size_t tmp_size;
2093 	size_t sample_bytes = bits_per_sample / 8;
2094 	size_t step = bits_per_frame / 8;
2095 	size_t chunk_bytes;
2096 	unsigned int ch, i;
2097 
2098 	if (!hw_map)
2099 		return data;
2100 
2101 	chunk_bytes = count * bits_per_frame / 8;
2102 	if (tmp_size < chunk_bytes) {
2103 		free(tmp);
2104 		tmp = malloc(chunk_bytes);
2105 		if (!tmp) {
2106 			error(_("not enough memory"));
2107 			exit(1);
2108 		}
2109 		tmp_size = count;
2110 	}
2111 
2112 	src = data;
2113 	dst = tmp;
2114 	for (i = 0; i < count; i++) {
2115 		for (ch = 0; ch < hwparams.channels; ch++) {
2116 			memcpy(dst, src + sample_bytes * hw_map[ch],
2117 			       sample_bytes);
2118 			dst += sample_bytes;
2119 		}
2120 		src += step;
2121 	}
2122 	return tmp;
2123 }
2124 
2125 static uint8_t **remap_datav(uint8_t **data, size_t count ATTRIBUTE_UNUSED)
2126 {
2127 	static uint8_t **tmp;
2128 	unsigned int ch;
2129 
2130 	if (!hw_map)
2131 		return data;
2132 
2133 	if (!tmp) {
2134 		tmp = malloc(sizeof(*tmp) * hwparams.channels);
2135 		if (!tmp) {
2136 			error(_("not enough memory"));
2137 			exit(1);
2138 		}
2139 		for (ch = 0; ch < hwparams.channels; ch++)
2140 			tmp[ch] = data[hw_map[ch]];
2141 	}
2142 	return tmp;
2143 }
2144 #else
2145 #define remap_data(data, count)		(data)
2146 #define remap_datav(data, count)	(data)
2147 #endif
2148 
2149 /*
2150  *  write function
2151  */
2152 
2153 static ssize_t pcm_write(uint8_t *data, size_t count)
2154 {
2155 	ssize_t r;
2156 	ssize_t result = 0;
2157 
2158 	if (count < chunk_size) {
2159 		snd_pcm_format_set_silence(hwparams.format, data + count * bits_per_frame / 8, (chunk_size - count) * hwparams.channels);
2160 		count = chunk_size;
2161 	}
2162 	data = remap_data(data, count);
2163 	while (count > 0 && !in_aborting) {
2164 		if (test_position)
2165 			do_test_position();
2166 		check_stdin();
2167 		r = writei_func(handle, data, count);
2168 		if (test_position)
2169 			do_test_position();
2170 		if (r == -EAGAIN || (r >= 0 && (size_t)r < count)) {
2171 			if (!test_nowait)
2172 				snd_pcm_wait(handle, 100);
2173 		} else if (r == -EPIPE) {
2174 			xrun();
2175 		} else if (r == -ESTRPIPE) {
2176 			suspend();
2177 		} else if (r < 0) {
2178 			error(_("write error: %s"), snd_strerror(r));
2179 			prg_exit(EXIT_FAILURE);
2180 		}
2181 		if (r > 0) {
2182 			if (vumeter)
2183 				compute_max_peak(data, r * hwparams.channels);
2184 			result += r;
2185 			count -= r;
2186 			data += r * bits_per_frame / 8;
2187 		}
2188 	}
2189 	return result;
2190 }
2191 
2192 static ssize_t pcm_writev(uint8_t **data, unsigned int channels, size_t count)
2193 {
2194 	ssize_t r;
2195 	size_t result = 0;
2196 
2197 	if (count != chunk_size) {
2198 		unsigned int channel;
2199 		size_t offset = count;
2200 		size_t remaining = chunk_size - count;
2201 		for (channel = 0; channel < channels; channel++)
2202 			snd_pcm_format_set_silence(hwparams.format, data[channel] + offset * bits_per_sample / 8, remaining);
2203 		count = chunk_size;
2204 	}
2205 	data = remap_datav(data, count);
2206 	while (count > 0 && !in_aborting) {
2207 		unsigned int channel;
2208 		void *bufs[channels];
2209 		size_t offset = result;
2210 		for (channel = 0; channel < channels; channel++)
2211 			bufs[channel] = data[channel] + offset * bits_per_sample / 8;
2212 		if (test_position)
2213 			do_test_position();
2214 		check_stdin();
2215 		r = writen_func(handle, bufs, count);
2216 		if (test_position)
2217 			do_test_position();
2218 		if (r == -EAGAIN || (r >= 0 && (size_t)r < count)) {
2219 			if (!test_nowait)
2220 				snd_pcm_wait(handle, 100);
2221 		} else if (r == -EPIPE) {
2222 			xrun();
2223 		} else if (r == -ESTRPIPE) {
2224 			suspend();
2225 		} else if (r < 0) {
2226 			error(_("writev error: %s"), snd_strerror(r));
2227 			prg_exit(EXIT_FAILURE);
2228 		}
2229 		if (r > 0) {
2230 			if (vumeter) {
2231 				for (channel = 0; channel < channels; channel++)
2232 					compute_max_peak(data[channel], r);
2233 			}
2234 			result += r;
2235 			count -= r;
2236 		}
2237 	}
2238 	return result;
2239 }
2240 
2241 /*
2242  *  read function
2243  */
2244 
2245 static ssize_t pcm_read(uint8_t *data, size_t rcount)
2246 {
2247 	ssize_t r;
2248 	size_t result = 0;
2249 	size_t count = rcount;
2250 
2251 	if (count != chunk_size) {
2252 		count = chunk_size;
2253 	}
2254 
2255 	while (count > 0) {
2256 		if (in_aborting)
2257 			goto abort;
2258 		if (test_position)
2259 			do_test_position();
2260 		check_stdin();
2261 		r = readi_func(handle, data, count);
2262 		if (test_position)
2263 			do_test_position();
2264 		if (r == -EAGAIN || (r >= 0 && (size_t)r < count)) {
2265 			if (!test_nowait)
2266 				snd_pcm_wait(handle, 100);
2267 		} else if (r == -EPIPE) {
2268 			xrun();
2269 		} else if (r == -ESTRPIPE) {
2270 			suspend();
2271 		} else if (r < 0) {
2272 			error(_("read error: %s"), snd_strerror(r));
2273 			prg_exit(EXIT_FAILURE);
2274 		}
2275 		if (r > 0) {
2276 			if (vumeter)
2277 				compute_max_peak(data, r * hwparams.channels);
2278 			result += r;
2279 			count -= r;
2280 			data += r * bits_per_frame / 8;
2281 		}
2282 	}
2283 abort:
2284 	return result > rcount ? rcount : result;
2285 }
2286 
2287 static ssize_t pcm_readv(uint8_t **data, unsigned int channels, size_t rcount)
2288 {
2289 	ssize_t r;
2290 	size_t result = 0;
2291 	size_t count = rcount;
2292 
2293 	if (count != chunk_size) {
2294 		count = chunk_size;
2295 	}
2296 
2297 	while (count > 0) {
2298 		if (in_aborting)
2299 			goto abort;
2300 		unsigned int channel;
2301 		void *bufs[channels];
2302 		size_t offset = result;
2303 		for (channel = 0; channel < channels; channel++)
2304 			bufs[channel] = data[channel] + offset * bits_per_sample / 8;
2305 		if (test_position)
2306 			do_test_position();
2307 		check_stdin();
2308 		r = readn_func(handle, bufs, count);
2309 		if (test_position)
2310 			do_test_position();
2311 		if (r == -EAGAIN || (r >= 0 && (size_t)r < count)) {
2312 			if (!test_nowait)
2313 				snd_pcm_wait(handle, 100);
2314 		} else if (r == -EPIPE) {
2315 			xrun();
2316 		} else if (r == -ESTRPIPE) {
2317 			suspend();
2318 		} else if (r < 0) {
2319 			error(_("readv error: %s"), snd_strerror(r));
2320 			prg_exit(EXIT_FAILURE);
2321 		}
2322 		if (r > 0) {
2323 			if (vumeter) {
2324 				for (channel = 0; channel < channels; channel++)
2325 					compute_max_peak(data[channel], r);
2326 			}
2327 			result += r;
2328 			count -= r;
2329 		}
2330 	}
2331 abort:
2332 	return rcount;
2333 }
2334 
2335 /*
2336  *  ok, let's play a .voc file
2337  */
2338 
2339 static ssize_t voc_pcm_write(uint8_t *data, size_t count)
2340 {
2341 	ssize_t result = count, r;
2342 	size_t size;
2343 
2344 	while (count > 0 && !in_aborting) {
2345 		size = count;
2346 		if (size > chunk_bytes - buffer_pos)
2347 			size = chunk_bytes - buffer_pos;
2348 		memcpy(audiobuf + buffer_pos, data, size);
2349 		data += size;
2350 		count -= size;
2351 		buffer_pos += size;
2352 		if ((size_t)buffer_pos == chunk_bytes) {
2353 			if ((size_t)(r = pcm_write(audiobuf, chunk_size)) != chunk_size)
2354 				return r;
2355 			buffer_pos = 0;
2356 		}
2357 	}
2358 	return result;
2359 }
2360 
2361 static void voc_write_silence(unsigned x)
2362 {
2363 	unsigned l;
2364 	uint8_t *buf;
2365 
2366 	buf = (uint8_t *) malloc(chunk_bytes);
2367 	if (buf == NULL) {
2368 		error(_("can't allocate buffer for silence"));
2369 		return;		/* not fatal error */
2370 	}
2371 	snd_pcm_format_set_silence(hwparams.format, buf, chunk_size * hwparams.channels);
2372 	while (x > 0 && !in_aborting) {
2373 		l = x;
2374 		if (l > chunk_size)
2375 			l = chunk_size;
2376 		if (voc_pcm_write(buf, l) != (ssize_t)l) {
2377 			error(_("write error"));
2378 			prg_exit(EXIT_FAILURE);
2379 		}
2380 		x -= l;
2381 	}
2382 	free(buf);
2383 }
2384 
2385 static void voc_pcm_flush(void)
2386 {
2387 	if (buffer_pos > 0) {
2388 		size_t b;
2389 		if (snd_pcm_format_set_silence(hwparams.format, audiobuf + buffer_pos, chunk_bytes - buffer_pos * 8 / bits_per_sample) < 0)
2390 			fprintf(stderr, _("voc_pcm_flush - silence error"));
2391 		b = chunk_size;
2392 		if (pcm_write(audiobuf, b) != (ssize_t)b)
2393 			error(_("voc_pcm_flush error"));
2394 	}
2395 	snd_pcm_nonblock(handle, 0);
2396 	snd_pcm_drain(handle);
2397 	snd_pcm_nonblock(handle, nonblock);
2398 }
2399 
2400 static void voc_play(int fd, int ofs, char *name)
2401 {
2402 	int l;
2403 	VocBlockType *bp;
2404 	VocVoiceData *vd;
2405 	VocExtBlock *eb;
2406 	size_t nextblock, in_buffer;
2407 	uint8_t *data, *buf;
2408 	char was_extended = 0, output = 0;
2409 	uint16_t *sp, repeat = 0;
2410 	off_t filepos = 0;
2411 
2412 #define COUNT(x)	nextblock -= x; in_buffer -= x; data += x
2413 #define COUNT1(x)	in_buffer -= x; data += x
2414 
2415 	data = buf = (uint8_t *)malloc(64 * 1024);
2416 	buffer_pos = 0;
2417 	if (data == NULL) {
2418 		error(_("malloc error"));
2419 		prg_exit(EXIT_FAILURE);
2420 	}
2421 	if (!quiet_mode) {
2422 		fprintf(stderr, _("Playing Creative Labs Channel file '%s'...\n"), name);
2423 	}
2424 	/* first we waste the rest of header, ugly but we don't need seek */
2425 	while (ofs > (ssize_t)chunk_bytes) {
2426 		if ((size_t)safe_read(fd, buf, chunk_bytes) != chunk_bytes) {
2427 			error(_("read error"));
2428 			prg_exit(EXIT_FAILURE);
2429 		}
2430 		ofs -= chunk_bytes;
2431 	}
2432 	if (ofs) {
2433 		if (safe_read(fd, buf, ofs) != ofs) {
2434 			error(_("read error"));
2435 			prg_exit(EXIT_FAILURE);
2436 		}
2437 	}
2438 	hwparams.format = DEFAULT_FORMAT;
2439 	hwparams.subformat = SND_PCM_SUBFORMAT_STD;
2440 	hwparams.channels = 1;
2441 	hwparams.rate = DEFAULT_SPEED;
2442 	set_params();
2443 
2444 	in_buffer = nextblock = 0;
2445 	while (!in_aborting) {
2446 	      Fill_the_buffer:	/* need this for repeat */
2447 		if (in_buffer < 32) {
2448 			/* move the rest of buffer to pos 0 and fill the buf up */
2449 			if (in_buffer)
2450 				memcpy(buf, data, in_buffer);
2451 			data = buf;
2452 			if ((l = safe_read(fd, buf + in_buffer, chunk_bytes - in_buffer)) > 0)
2453 				in_buffer += l;
2454 			else if (!in_buffer) {
2455 				/* the file is truncated, so simulate 'Terminator'
2456 				   and reduce the datablock for safe landing */
2457 				nextblock = buf[0] = 0;
2458 				if (l == -1) {
2459 					perror(name);
2460 					prg_exit(EXIT_FAILURE);
2461 				}
2462 			}
2463 		}
2464 		while (!nextblock) {	/* this is a new block */
2465 			if (in_buffer < sizeof(VocBlockType))
2466 				goto __end;
2467 			bp = (VocBlockType *) data;
2468 			COUNT1(sizeof(VocBlockType));
2469 			nextblock = VOC_DATALEN(bp);
2470 			if (output && !quiet_mode)
2471 				fprintf(stderr, "\n");	/* write /n after ASCII-out */
2472 			output = 0;
2473 			switch (bp->type) {
2474 			case 0:
2475 #if 0
2476 				d_printf("Terminator\n");
2477 #endif
2478 				return;		/* VOC-file stop */
2479 			case 1:
2480 				vd = (VocVoiceData *) data;
2481 				COUNT1(sizeof(VocVoiceData));
2482 				/* we need a SYNC, before we can set new SPEED, STEREO ... */
2483 
2484 				if (!was_extended) {
2485 					hwparams.rate = (int) (vd->tc);
2486 					hwparams.rate = 1000000 / (256 - hwparams.rate);
2487 #if 0
2488 					d_printf("Channel data %d Hz\n", dsp_speed);
2489 #endif
2490 					if (vd->pack) {		/* /dev/dsp can't it */
2491 						error(_("can't play packed .voc files"));
2492 						return;
2493 					}
2494 					if (hwparams.channels == 2)		/* if we are in Stereo-Mode, switch back */
2495 						hwparams.channels = 1;
2496 				} else {	/* there was extended block */
2497 					hwparams.channels = 2;
2498 					was_extended = 0;
2499 				}
2500 				set_params();
2501 				break;
2502 			case 2:	/* nothing to do, pure data */
2503 #if 0
2504 				d_printf("Channel continuation\n");
2505 #endif
2506 				break;
2507 			case 3:	/* a silence block, no data, only a count */
2508 				sp = (uint16_t *) data;
2509 				COUNT1(sizeof(uint16_t));
2510 				hwparams.rate = (int) (*data);
2511 				COUNT1(1);
2512 				hwparams.rate = 1000000 / (256 - hwparams.rate);
2513 				set_params();
2514 #if 0
2515 				{
2516 					size_t silence;
2517 					silence = (((size_t) * sp) * 1000) / hwparams.rate;
2518 					d_printf("Silence for %d ms\n", (int) silence);
2519 				}
2520 #endif
2521 				voc_write_silence(*sp);
2522 				break;
2523 			case 4:	/* a marker for syncronisation, no effect */
2524 				sp = (uint16_t *) data;
2525 				COUNT1(sizeof(uint16_t));
2526 #if 0
2527 				d_printf("Marker %d\n", *sp);
2528 #endif
2529 				break;
2530 			case 5:	/* ASCII text, we copy to stderr */
2531 				output = 1;
2532 #if 0
2533 				d_printf("ASCII - text :\n");
2534 #endif
2535 				break;
2536 			case 6:	/* repeat marker, says repeatcount */
2537 				/* my specs don't say it: maybe this can be recursive, but
2538 				   I don't think somebody use it */
2539 				repeat = *(uint16_t *) data;
2540 				COUNT1(sizeof(uint16_t));
2541 #if 0
2542 				d_printf("Repeat loop %d times\n", repeat);
2543 #endif
2544 				if (filepos >= 0) {	/* if < 0, one seek fails, why test another */
2545 					if ((filepos = lseek(fd, 0, 1)) < 0) {
2546 						error(_("can't play loops; %s isn't seekable\n"), name);
2547 						repeat = 0;
2548 					} else {
2549 						filepos -= in_buffer;	/* set filepos after repeat */
2550 					}
2551 				} else {
2552 					repeat = 0;
2553 				}
2554 				break;
2555 			case 7:	/* ok, lets repeat that be rewinding tape */
2556 				if (repeat) {
2557 					if (repeat != 0xFFFF) {
2558 #if 0
2559 						d_printf("Repeat loop %d\n", repeat);
2560 #endif
2561 						--repeat;
2562 					}
2563 #if 0
2564 					else
2565 						d_printf("Neverending loop\n");
2566 #endif
2567 					lseek(fd, filepos, 0);
2568 					in_buffer = 0;	/* clear the buffer */
2569 					goto Fill_the_buffer;
2570 				}
2571 #if 0
2572 				else
2573 					d_printf("End repeat loop\n");
2574 #endif
2575 				break;
2576 			case 8:	/* the extension to play Stereo, I have SB 1.0 :-( */
2577 				was_extended = 1;
2578 				eb = (VocExtBlock *) data;
2579 				COUNT1(sizeof(VocExtBlock));
2580 				hwparams.rate = (int) (eb->tc);
2581 				hwparams.rate = 256000000L / (65536 - hwparams.rate);
2582 				hwparams.channels = eb->mode == VOC_MODE_STEREO ? 2 : 1;
2583 				if (hwparams.channels == 2)
2584 					hwparams.rate = hwparams.rate >> 1;
2585 				if (eb->pack) {		/* /dev/dsp can't it */
2586 					error(_("can't play packed .voc files"));
2587 					return;
2588 				}
2589 #if 0
2590 				d_printf("Extended block %s %d Hz\n",
2591 					 (eb->mode ? "Stereo" : "Mono"), dsp_speed);
2592 #endif
2593 				break;
2594 			default:
2595 				error(_("unknown blocktype %d. terminate."), bp->type);
2596 				return;
2597 			}	/* switch (bp->type) */
2598 		}		/* while (! nextblock)  */
2599 		/* put nextblock data bytes to dsp */
2600 		l = in_buffer;
2601 		if (nextblock < (size_t)l)
2602 			l = nextblock;
2603 		if (l) {
2604 			if (output && !quiet_mode) {
2605 				if (xwrite(2, data, l) != l) {	/* to stderr */
2606 					error(_("write error"));
2607 					prg_exit(EXIT_FAILURE);
2608 				}
2609 			} else {
2610 				if (voc_pcm_write(data, l) != l) {
2611 					error(_("write error"));
2612 					prg_exit(EXIT_FAILURE);
2613 				}
2614 			}
2615 			COUNT(l);
2616 		}
2617 	}			/* while(1) */
2618       __end:
2619 	if (!in_aborting) {
2620 		voc_pcm_flush();
2621 	}
2622         free(buf);
2623 }
2624 /* that was a big one, perhaps somebody split it :-) */
2625 
2626 /* setting the globals for playing raw data */
2627 static void init_raw_data(void)
2628 {
2629 	hwparams = rhwparams;
2630 }
2631 
2632 /* calculate the data count to read from/to dsp */
2633 static off_t calc_count(void)
2634 {
2635 	off_t count;
2636 
2637 	if (timelimit == 0)
2638 		if (sampleslimit == 0)
2639 			count = pbrec_count;
2640 		else
2641 			count = snd_pcm_format_size(hwparams.format, sampleslimit * hwparams.channels);
2642 	else {
2643 		count = snd_pcm_format_size(hwparams.format, hwparams.rate * hwparams.channels);
2644 		count *= (off_t)timelimit;
2645 	}
2646 	return count < pbrec_count ? count : pbrec_count;
2647 }
2648 
2649 /* write a .VOC-header */
2650 static void begin_voc(int fd, size_t cnt)
2651 {
2652 	VocHeader vh;
2653 	VocBlockType bt;
2654 	VocVoiceData vd;
2655 	VocExtBlock eb;
2656 
2657 	memcpy(vh.magic, VOC_MAGIC_STRING, 20);
2658 	vh.headerlen = LE_SHORT(sizeof(VocHeader));
2659 	vh.version = LE_SHORT(VOC_ACTUAL_VERSION);
2660 	vh.coded_ver = LE_SHORT(0x1233 - VOC_ACTUAL_VERSION);
2661 
2662 	if (xwrite(fd, &vh, sizeof(VocHeader)) != sizeof(VocHeader)) {
2663 		error(_("write error"));
2664 		prg_exit(EXIT_FAILURE);
2665 	}
2666 	if (hwparams.channels > 1) {
2667 		/* write an extended block */
2668 		bt.type = 8;
2669 		bt.datalen = 4;
2670 		bt.datalen_m = bt.datalen_h = 0;
2671 		if (xwrite(fd, &bt, sizeof(VocBlockType)) != sizeof(VocBlockType)) {
2672 			error(_("write error"));
2673 			prg_exit(EXIT_FAILURE);
2674 		}
2675 		eb.tc = LE_SHORT(65536 - 256000000L / (hwparams.rate << 1));
2676 		eb.pack = 0;
2677 		eb.mode = 1;
2678 		if (xwrite(fd, &eb, sizeof(VocExtBlock)) != sizeof(VocExtBlock)) {
2679 			error(_("write error"));
2680 			prg_exit(EXIT_FAILURE);
2681 		}
2682 	}
2683 	bt.type = 1;
2684 	cnt += sizeof(VocVoiceData);	/* Channel_data block follows */
2685 	bt.datalen = (uint8_t) (cnt & 0xFF);
2686 	bt.datalen_m = (uint8_t) ((cnt & 0xFF00) >> 8);
2687 	bt.datalen_h = (uint8_t) ((cnt & 0xFF0000) >> 16);
2688 	if (xwrite(fd, &bt, sizeof(VocBlockType)) != sizeof(VocBlockType)) {
2689 		error(_("write error"));
2690 		prg_exit(EXIT_FAILURE);
2691 	}
2692 	vd.tc = (uint8_t) (256 - (1000000 / hwparams.rate));
2693 	vd.pack = 0;
2694 	if (xwrite(fd, &vd, sizeof(VocVoiceData)) != sizeof(VocVoiceData)) {
2695 		error(_("write error"));
2696 		prg_exit(EXIT_FAILURE);
2697 	}
2698 }
2699 
2700 /* write a WAVE-header */
2701 static void begin_wave(int fd, size_t cnt)
2702 {
2703 	WaveHeader h;
2704 	WaveFmtBody f;
2705 	WaveChunkHeader cf, cd;
2706 	int bits;
2707 	uint32_t tmp;
2708 	uint16_t tmp2;
2709 
2710 	/* WAVE cannot handle greater than 32bit (signed?) int */
2711 	if (cnt == (size_t)-2)
2712 		cnt = 0x7fffff00;
2713 
2714 	bits = 8;
2715 	switch ((unsigned long) hwparams.format) {
2716 	case SND_PCM_FORMAT_U8:
2717 		bits = 8;
2718 		break;
2719 	case SND_PCM_FORMAT_S16_LE:
2720 		bits = 16;
2721 		break;
2722 	case SND_PCM_FORMAT_S32_LE:
2723         case SND_PCM_FORMAT_FLOAT_LE:
2724 		bits = 32;
2725 		break;
2726 	case SND_PCM_FORMAT_S24_LE:
2727 	case SND_PCM_FORMAT_S24_3LE:
2728 		bits = 24;
2729 		break;
2730 	default:
2731 		error(_("Wave doesn't support %s format..."), snd_pcm_format_name(hwparams.format));
2732 		prg_exit(EXIT_FAILURE);
2733 	}
2734 	h.magic = WAV_RIFF;
2735 	tmp = cnt + sizeof(WaveHeader) + sizeof(WaveChunkHeader) + sizeof(WaveFmtBody) + sizeof(WaveChunkHeader) - 8;
2736 	h.length = LE_INT(tmp);
2737 	h.type = WAV_WAVE;
2738 
2739 	cf.type = WAV_FMT;
2740 	cf.length = LE_INT(16);
2741 
2742         if (hwparams.format == SND_PCM_FORMAT_FLOAT_LE)
2743                 f.format = LE_SHORT(WAV_FMT_IEEE_FLOAT);
2744         else
2745                 f.format = LE_SHORT(WAV_FMT_PCM);
2746 	f.channels = LE_SHORT(hwparams.channels);
2747 	f.sample_fq = LE_INT(hwparams.rate);
2748 #if 0
2749 	tmp2 = (samplesize == 8) ? 1 : 2;
2750 	f.byte_p_spl = LE_SHORT(tmp2);
2751 	tmp = dsp_speed * hwparams.channels * (uint32_t) tmp2;
2752 #else
2753 	tmp2 = hwparams.channels * snd_pcm_format_physical_width(hwparams.format) / 8;
2754 	f.byte_p_spl = LE_SHORT(tmp2);
2755 	tmp = (uint32_t) tmp2 * hwparams.rate;
2756 #endif
2757 	f.byte_p_sec = LE_INT(tmp);
2758 	f.bit_p_spl = LE_SHORT(bits);
2759 
2760 	cd.type = WAV_DATA;
2761 	cd.length = LE_INT(cnt);
2762 
2763 	if (xwrite(fd, &h, sizeof(WaveHeader)) != sizeof(WaveHeader) ||
2764 	    xwrite(fd, &cf, sizeof(WaveChunkHeader)) != sizeof(WaveChunkHeader) ||
2765 	    xwrite(fd, &f, sizeof(WaveFmtBody)) != sizeof(WaveFmtBody) ||
2766 	    xwrite(fd, &cd, sizeof(WaveChunkHeader)) != sizeof(WaveChunkHeader)) {
2767 		error(_("write error"));
2768 		prg_exit(EXIT_FAILURE);
2769 	}
2770 }
2771 
2772 /* write a Au-header */
2773 static void begin_au(int fd, size_t cnt)
2774 {
2775 	AuHeader ah;
2776 
2777 	ah.magic = AU_MAGIC;
2778 	ah.hdr_size = BE_INT(24);
2779 	ah.data_size = BE_INT(cnt);
2780 	switch ((unsigned long) hwparams.format) {
2781 	case SND_PCM_FORMAT_MU_LAW:
2782 		ah.encoding = BE_INT(AU_FMT_ULAW);
2783 		break;
2784 	case SND_PCM_FORMAT_U8:
2785 		ah.encoding = BE_INT(AU_FMT_LIN8);
2786 		break;
2787 	case SND_PCM_FORMAT_S16_BE:
2788 		ah.encoding = BE_INT(AU_FMT_LIN16);
2789 		break;
2790 	default:
2791 		error(_("Sparc Audio doesn't support %s format..."), snd_pcm_format_name(hwparams.format));
2792 		prg_exit(EXIT_FAILURE);
2793 	}
2794 	ah.sample_rate = BE_INT(hwparams.rate);
2795 	ah.channels = BE_INT(hwparams.channels);
2796 	if (xwrite(fd, &ah, sizeof(AuHeader)) != sizeof(AuHeader)) {
2797 		error(_("write error"));
2798 		prg_exit(EXIT_FAILURE);
2799 	}
2800 }
2801 
2802 /* closing .VOC */
2803 static void end_voc(int fd)
2804 {
2805 	off_t length_seek;
2806 	VocBlockType bt;
2807 	size_t cnt;
2808 	char dummy = 0;		/* Write a Terminator */
2809 
2810 	if (xwrite(fd, &dummy, 1) != 1) {
2811 		error(_("write error"));
2812 		prg_exit(EXIT_FAILURE);
2813 	}
2814 	length_seek = sizeof(VocHeader);
2815 	if (hwparams.channels > 1)
2816 		length_seek += sizeof(VocBlockType) + sizeof(VocExtBlock);
2817 	bt.type = 1;
2818 	cnt = fdcount;
2819 	cnt += sizeof(VocVoiceData);	/* Channel_data block follows */
2820 	if (cnt > 0x00ffffff)
2821 		cnt = 0x00ffffff;
2822 	bt.datalen = (uint8_t) (cnt & 0xFF);
2823 	bt.datalen_m = (uint8_t) ((cnt & 0xFF00) >> 8);
2824 	bt.datalen_h = (uint8_t) ((cnt & 0xFF0000) >> 16);
2825 	if (lseek(fd, length_seek, SEEK_SET) == length_seek)
2826 		xwrite(fd, &bt, sizeof(VocBlockType));
2827 }
2828 
2829 static void end_wave(int fd)
2830 {				/* only close output */
2831 	WaveChunkHeader cd;
2832 	off_t length_seek;
2833 	off_t filelen;
2834 	uint32_t rifflen;
2835 
2836 	length_seek = sizeof(WaveHeader) +
2837 		      sizeof(WaveChunkHeader) +
2838 		      sizeof(WaveFmtBody);
2839 	cd.type = WAV_DATA;
2840 	cd.length = fdcount > 0x7fffffff ? LE_INT(0x7fffffff) : LE_INT(fdcount);
2841 	filelen = fdcount + 2*sizeof(WaveChunkHeader) + sizeof(WaveFmtBody) + 4;
2842 	rifflen = filelen > 0x7fffffff ? LE_INT(0x7fffffff) : LE_INT(filelen);
2843 	if (lseek(fd, 4, SEEK_SET) == 4)
2844 		xwrite(fd, &rifflen, 4);
2845 	if (lseek(fd, length_seek, SEEK_SET) == length_seek)
2846 		xwrite(fd, &cd, sizeof(WaveChunkHeader));
2847 }
2848 
2849 static void end_au(int fd)
2850 {				/* only close output */
2851 	AuHeader ah;
2852 	off_t length_seek;
2853 
2854 	length_seek = (char *)&ah.data_size - (char *)&ah;
2855 	ah.data_size = fdcount > 0xffffffff ? 0xffffffff : BE_INT(fdcount);
2856 	if (lseek(fd, length_seek, SEEK_SET) == length_seek)
2857 		xwrite(fd, &ah.data_size, sizeof(ah.data_size));
2858 }
2859 
2860 static void header(int rtype, char *name)
2861 {
2862 	if (!quiet_mode) {
2863 		if (! name)
2864 			name = (stream == SND_PCM_STREAM_PLAYBACK) ? "stdout" : "stdin";
2865 		fprintf(stderr, "%s %s '%s' : ",
2866 			(stream == SND_PCM_STREAM_PLAYBACK) ? _("Playing") : _("Recording"),
2867 			gettext(fmt_rec_table[rtype].what),
2868 			name);
2869 		fprintf(stderr, "%s, ", snd_pcm_format_description(hwparams.format));
2870 		fprintf(stderr, _("Rate %d Hz, "), hwparams.rate);
2871 		if (hwparams.channels == 1)
2872 			fprintf(stderr, _("Mono"));
2873 		else if (hwparams.channels == 2)
2874 			fprintf(stderr, _("Stereo"));
2875 		else
2876 			fprintf(stderr, _("Channels %i"), hwparams.channels);
2877 		fprintf(stderr, "\n");
2878 	}
2879 }
2880 
2881 /* playing raw data */
2882 
2883 static void playback_go(int fd, size_t loaded, off_t count, int rtype, char *name)
2884 {
2885 	int l, r;
2886 	off_t written = 0;
2887 	off_t c;
2888 
2889 	header(rtype, name);
2890 	set_params();
2891 
2892 	while (loaded > chunk_bytes && written < count && !in_aborting) {
2893 		if (pcm_write(audiobuf + written, chunk_size) <= 0)
2894 			return;
2895 		written += chunk_bytes;
2896 		loaded -= chunk_bytes;
2897 	}
2898 	if (written > 0 && loaded > 0)
2899 		memmove(audiobuf, audiobuf + written, loaded);
2900 
2901 	l = loaded;
2902 	while (written < count && !in_aborting) {
2903 		do {
2904 			c = count - written;
2905 			if (c > (off_t)chunk_bytes)
2906 				c = chunk_bytes;
2907 
2908 			/* c < l, there is more data loaded
2909 			 * then we actually need to write
2910 			 */
2911 			if (c < l)
2912 				l = c;
2913 
2914 			c -= l;
2915 
2916 			if (c == 0)
2917 				break;
2918 			r = safe_read(fd, audiobuf + l, c);
2919 			if (r < 0) {
2920 				perror(name);
2921 				prg_exit(EXIT_FAILURE);
2922 			}
2923 			fdcount += r;
2924 			if (r == 0)
2925 				break;
2926 			l += r;
2927 		} while ((size_t)l < chunk_bytes);
2928 		l = l * 8 / bits_per_frame;
2929 		r = pcm_write(audiobuf, l);
2930 		if (r != l)
2931 			break;
2932 		r = r * bits_per_frame / 8;
2933 		written += r;
2934 		l = 0;
2935 	}
2936 	if (!in_aborting) {
2937 		snd_pcm_nonblock(handle, 0);
2938 		snd_pcm_drain(handle);
2939 		snd_pcm_nonblock(handle, nonblock);
2940 	}
2941 }
2942 
2943 static int read_header(int *loaded, int header_size)
2944 {
2945 	int ret;
2946 	struct stat buf;
2947 
2948 	ret = fstat(fd, &buf);
2949 	if (ret < 0) {
2950 		perror("fstat");
2951 		prg_exit(EXIT_FAILURE);
2952 	}
2953 
2954 	/* don't be adventurous, get out if file size is smaller than
2955 	 * requested header size */
2956 	if ((buf.st_mode & S_IFMT) == S_IFREG &&
2957 	    buf.st_size < header_size)
2958 		return -1;
2959 
2960 	if (*loaded < header_size) {
2961 		header_size -= *loaded;
2962 		ret = safe_read(fd, audiobuf + *loaded, header_size);
2963 		if (ret != header_size) {
2964 			error(_("read error"));
2965 			prg_exit(EXIT_FAILURE);
2966 		}
2967 		*loaded += header_size;
2968 	}
2969 	return 0;
2970 }
2971 
2972 static int playback_au(char *name, int *loaded)
2973 {
2974 	if (read_header(loaded, sizeof(AuHeader)) < 0)
2975 		return -1;
2976 
2977 	if (test_au(fd, audiobuf) < 0)
2978 		return -1;
2979 
2980 	rhwparams.format = hwparams.format;
2981 	pbrec_count = calc_count();
2982 	playback_go(fd, *loaded - sizeof(AuHeader), pbrec_count, FORMAT_AU, name);
2983 
2984 	return 0;
2985 }
2986 
2987 static int playback_voc(char *name, int *loaded)
2988 {
2989 	int ofs;
2990 
2991 	if (read_header(loaded, sizeof(VocHeader)) < 0)
2992 		return -1;
2993 
2994 	if ((ofs = test_vocfile(audiobuf)) < 0)
2995 		return -1;
2996 
2997 	pbrec_count = calc_count();
2998 	voc_play(fd, ofs, name);
2999 
3000 	return 0;
3001 }
3002 
3003 static int playback_wave(char *name, int *loaded)
3004 {
3005 	ssize_t dtawave;
3006 
3007 	if (read_header(loaded, sizeof(WaveHeader)) < 0)
3008 		return -1;
3009 
3010 	if ((dtawave = test_wavefile(fd, audiobuf, *loaded)) < 0)
3011 		return -1;
3012 
3013 	pbrec_count = calc_count();
3014 	playback_go(fd, dtawave, pbrec_count, FORMAT_WAVE, name);
3015 
3016 	return 0;
3017 }
3018 
3019 static int playback_raw(char *name, int *loaded)
3020 {
3021 	init_raw_data();
3022 	pbrec_count = calc_count();
3023 	playback_go(fd, *loaded, pbrec_count, FORMAT_RAW, name);
3024 
3025 	return 0;
3026 }
3027 
3028 /*
3029  *  let's play or capture it (capture_type says VOC/WAVE/raw)
3030  */
3031 
3032 static void playback(char *name)
3033 {
3034 	int loaded = 0;
3035 
3036 	pbrec_count = LLONG_MAX;
3037 	fdcount = 0;
3038 	if (!name || !strcmp(name, "-")) {
3039 		fd = fileno(stdin);
3040 		name = "stdin";
3041 	} else {
3042 		init_stdin();
3043 		if ((fd = open(name, O_RDONLY, 0)) == -1) {
3044 			perror(name);
3045 			prg_exit(EXIT_FAILURE);
3046 		}
3047 	}
3048 
3049 	switch(file_type) {
3050 	case FORMAT_AU:
3051 		playback_au(name, &loaded);
3052 		break;
3053 	case FORMAT_VOC:
3054 		playback_voc(name, &loaded);
3055 		break;
3056 	case FORMAT_WAVE:
3057 		playback_wave(name, &loaded);
3058 		break;
3059 	case FORMAT_RAW:
3060 		playback_raw(name, &loaded);
3061 		break;
3062 	default:
3063 		/* parse the file header */
3064 		if (playback_au(name, &loaded) < 0 &&
3065 		    playback_voc(name, &loaded) < 0 &&
3066 		    playback_wave(name, &loaded) < 0)
3067 			playback_raw(name, &loaded); /* should be raw data */
3068 		break;
3069         }
3070 
3071 	if (fd != fileno(stdin))
3072 		close(fd);
3073 }
3074 
3075 /**
3076  * mystrftime
3077  *
3078  *   Variant of strftime(3) that supports additional format
3079  *   specifiers in the format string.
3080  *
3081  * Parameters:
3082  *
3083  *   s	  - destination string
3084  *   max	- max number of bytes to write
3085  *   userformat - format string
3086  *   tm	 - time information
3087  *   filenumber - the number of the file, starting at 1
3088  *
3089  * Returns: number of bytes written to the string s
3090  */
3091 size_t mystrftime(char *s, size_t max, const char *userformat,
3092 		  const struct tm *tm, const int filenumber)
3093 {
3094 	char formatstring[PATH_MAX] = "";
3095 	char tempstring[PATH_MAX] = "";
3096 	char *format, *tempstr;
3097 	const char *pos_userformat;
3098 
3099 	format = formatstring;
3100 
3101 	/* if mystrftime is called with userformat = NULL we return a zero length string */
3102 	if (userformat == NULL) {
3103 		*s = '\0';
3104 		return 0;
3105 	}
3106 
3107 	for (pos_userformat = userformat; *pos_userformat; ++pos_userformat) {
3108 		if (*pos_userformat == '%') {
3109 			tempstr = tempstring;
3110 			tempstr[0] = '\0';
3111 			switch (*++pos_userformat) {
3112 
3113 				case '\0': // end of string
3114 					--pos_userformat;
3115 					break;
3116 
3117 				case 'v': // file number
3118 					sprintf(tempstr, "%02d", filenumber);
3119 					break;
3120 
3121 				default: // All other codes will be handled by strftime
3122 					*format++ = '%';
3123 					*format++ = *pos_userformat;
3124 					continue;
3125 			}
3126 
3127 			/* If a format specifier was found and used, copy the result. */
3128 			if (tempstr[0]) {
3129 				while ((*format = *tempstr++) != '\0')
3130 					++format;
3131 				continue;
3132 			}
3133 		}
3134 
3135 		/* For any other character than % we simply copy the character */
3136 		*format++ = *pos_userformat;
3137 	}
3138 
3139 	*format = '\0';
3140 	format = formatstring;
3141 	return strftime(s, max, format, tm);
3142 }
3143 
3144 static int new_capture_file(char *name, char *namebuf, size_t namelen,
3145 			    int filecount)
3146 {
3147 	char *s;
3148 	char buf[PATH_MAX-10];
3149 	time_t t;
3150 	struct tm *tmp;
3151 
3152 	if (use_strftime) {
3153 		t = time(NULL);
3154 		tmp = localtime(&t);
3155 		if (tmp == NULL) {
3156 			perror("localtime");
3157 			prg_exit(EXIT_FAILURE);
3158 		}
3159 		if (mystrftime(namebuf, namelen, name, tmp, filecount+1) == 0) {
3160 			fprintf(stderr, "mystrftime returned 0");
3161 			prg_exit(EXIT_FAILURE);
3162 		}
3163 		return filecount;
3164 	}
3165 
3166 	/* get a copy of the original filename */
3167 	strncpy(buf, name, sizeof(buf));
3168 	buf[sizeof(buf)-1] = '\0';
3169 
3170 	/* separate extension from filename */
3171 	s = buf + strlen(buf);
3172 	while (s > buf && *s != '.' && *s != '/')
3173 		--s;
3174 	if (*s == '.')
3175 		*s++ = 0;
3176 	else if (*s == '/')
3177 		s = buf + strlen(buf);
3178 
3179 	/* upon first jump to this if block rename the first file */
3180 	if (filecount == 1) {
3181 		if (*s)
3182 			snprintf(namebuf, namelen, "%s-01.%s", buf, s);
3183 		else
3184 			snprintf(namebuf, namelen, "%s-01", buf);
3185 		remove(namebuf);
3186 		rename(name, namebuf);
3187 		filecount = 2;
3188 	}
3189 
3190 	/* name of the current file */
3191 	if (*s)
3192 		snprintf(namebuf, namelen, "%s-%02i.%s", buf, filecount, s);
3193 	else
3194 		snprintf(namebuf, namelen, "%s-%02i", buf, filecount);
3195 
3196 	return filecount;
3197 }
3198 
3199 /**
3200  * create_path
3201  *
3202  *   This function creates a file path, like mkdir -p.
3203  *
3204  * Parameters:
3205  *
3206  *   path - the path to create
3207  *
3208  * Returns: 0 on success, -1 on failure
3209  * On failure, a message has been printed to stderr.
3210  */
3211 int create_path(const char *path)
3212 {
3213 	char *start;
3214 	mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
3215 
3216 	if (path[0] == '/')
3217 		start = strchr(path + 1, '/');
3218 	else
3219 		start = strchr(path, '/');
3220 
3221 	while (start) {
3222 		char *buffer = strdup(path);
3223 		buffer[start-path] = 0x00;
3224 
3225 		if (mkdir(buffer, mode) == -1 && errno != EEXIST) {
3226 			fprintf(stderr, "Problem creating directory %s", buffer);
3227 			perror(" ");
3228 			free(buffer);
3229 			return -1;
3230 		}
3231 		free(buffer);
3232 		start = strchr(start + 1, '/');
3233 	}
3234 	return 0;
3235 }
3236 
3237 static int safe_open(const char *name)
3238 {
3239 	int fd;
3240 
3241 	fd = open(name, O_WRONLY | O_CREAT, 0644);
3242 	if (fd == -1) {
3243 		if (errno != ENOENT || !use_strftime)
3244 			return -1;
3245 		if (create_path(name) == 0)
3246 			fd = open(name, O_WRONLY | O_CREAT, 0644);
3247 	}
3248 	return fd;
3249 }
3250 
3251 static void capture(char *orig_name)
3252 {
3253 	int tostdout=0;		/* boolean which describes output stream */
3254 	int filecount=0;	/* number of files written */
3255 	char *name = orig_name;	/* current filename */
3256 	char namebuf[PATH_MAX+2];
3257 	off_t count, rest;		/* number of bytes to capture */
3258 	struct stat statbuf;
3259 
3260 	/* setup sound hardware */
3261 	set_params();
3262 
3263 	/* get number of bytes to capture */
3264 	count = calc_count();
3265 	if (count == 0)
3266 		count = LLONG_MAX;
3267 	/* compute the number of bytes per file */
3268 	max_file_size = (long long) max_file_time *
3269 		snd_pcm_format_size(hwparams.format,
3270 				    hwparams.rate * hwparams.channels);
3271 	/* WAVE-file should be even (I'm not sure), but wasting one byte
3272 	   isn't a problem (this can only be in 8 bit mono) */
3273 	if (count < LLONG_MAX)
3274 		count += count % 2;
3275 	else
3276 		count -= count % 2;
3277 
3278 	/* display verbose output to console */
3279 	header(file_type, name);
3280 
3281 	/* write to stdout? */
3282 	if (!name || !strcmp(name, "-")) {
3283 		fd = fileno(stdout);
3284 		name = "stdout";
3285 		tostdout = 1;
3286 		if (count > fmt_rec_table[file_type].max_filesize)
3287 			count = fmt_rec_table[file_type].max_filesize;
3288 	}
3289 	init_stdin();
3290 
3291 	do {
3292 		/* open a file to write */
3293 		if (!tostdout) {
3294 			/* upon the second file we start the numbering scheme */
3295 			if (filecount || use_strftime) {
3296 				filecount = new_capture_file(orig_name, namebuf,
3297 							     sizeof(namebuf),
3298 							     filecount);
3299 				name = namebuf;
3300 			}
3301 
3302 			/* open a new file */
3303 			if (!lstat(name, &statbuf)) {
3304 				if (S_ISREG(statbuf.st_mode))
3305 					remove(name);
3306 			}
3307 			fd = safe_open(name);
3308 			if (fd < 0) {
3309 				perror(name);
3310 				prg_exit(EXIT_FAILURE);
3311 			}
3312 			filecount++;
3313 		}
3314 
3315 		rest = count;
3316 		if (rest > fmt_rec_table[file_type].max_filesize)
3317 			rest = fmt_rec_table[file_type].max_filesize;
3318 		if (max_file_size && (rest > max_file_size))
3319 			rest = max_file_size;
3320 
3321 		/* setup sample header */
3322 		if (fmt_rec_table[file_type].start)
3323 			fmt_rec_table[file_type].start(fd, rest);
3324 
3325 		/* capture */
3326 		fdcount = 0;
3327 		while (rest > 0 && recycle_capture_file == 0 && !in_aborting) {
3328 			size_t c = (rest <= (off_t)chunk_bytes) ?
3329 				(size_t)rest : chunk_bytes;
3330 			size_t f = c * 8 / bits_per_frame;
3331 			size_t read = pcm_read(audiobuf, f);
3332 			size_t save;
3333 			if (read != f)
3334 				in_aborting = 1;
3335 			save = read * bits_per_frame / 8;
3336 			if (xwrite(fd, audiobuf, save) != (ssize_t)save) {
3337 				perror(name);
3338 				in_aborting = 1;
3339 				break;
3340 			}
3341 			count -= c;
3342 			rest -= c;
3343 			fdcount += save;
3344 		}
3345 
3346 		/* re-enable SIGUSR1 signal */
3347 		if (recycle_capture_file) {
3348 			recycle_capture_file = 0;
3349 			signal(SIGUSR1, signal_handler_recycle);
3350 		}
3351 
3352 		/* finish sample container */
3353 		if (!tostdout) {
3354 			if (fmt_rec_table[file_type].end)
3355 				fmt_rec_table[file_type].end(fd);
3356 			close(fd);
3357 			fd = -1;
3358 		}
3359 
3360 		if (in_aborting)
3361 			prg_exit(EXIT_FAILURE);
3362 
3363 		/* repeat the loop when format is raw without timelimit or
3364 		 * requested counts of data are recorded
3365 		 */
3366 	} while ((file_type == FORMAT_RAW && !timelimit && !sampleslimit) || count > 0);
3367 }
3368 
3369 static void playbackv_go(int* fds, unsigned int channels, size_t loaded, off_t count, int rtype, char **names)
3370 {
3371 	int r;
3372 	size_t vsize;
3373 
3374 	unsigned int channel;
3375 	uint8_t *bufs[channels];
3376 
3377 	header(rtype, names[0]);
3378 	set_params();
3379 
3380 	vsize = chunk_bytes / channels;
3381 
3382 	// Not yet implemented
3383 	assert(loaded == 0);
3384 
3385 	for (channel = 0; channel < channels; ++channel)
3386 		bufs[channel] = audiobuf + vsize * channel;
3387 
3388 	while (count > 0 && !in_aborting) {
3389 		size_t c = 0;
3390 		size_t expected = count / channels;
3391 		if (expected > vsize)
3392 			expected = vsize;
3393 		do {
3394 			r = safe_read(fds[0], bufs[0], expected);
3395 			if (r < 0) {
3396 				perror(names[0]);
3397 				prg_exit(EXIT_FAILURE);
3398 			}
3399 			for (channel = 1; channel < channels; ++channel) {
3400 				if (safe_read(fds[channel], bufs[channel], r) != r) {
3401 					perror(names[channel]);
3402 					prg_exit(EXIT_FAILURE);
3403 				}
3404 			}
3405 			if (r == 0)
3406 				break;
3407 			c += r;
3408 		} while (c < expected);
3409 		c = c * 8 / bits_per_sample;
3410 		r = pcm_writev(bufs, channels, c);
3411 		if ((size_t)r != c)
3412 			break;
3413 		r = r * bits_per_frame / 8;
3414 		count -= r;
3415 	}
3416 	if (!in_aborting) {
3417 		snd_pcm_nonblock(handle, 0);
3418 		snd_pcm_drain(handle);
3419 		snd_pcm_nonblock(handle, nonblock);
3420 	}
3421 }
3422 
3423 static void capturev_go(int* fds, unsigned int channels, off_t count, int rtype, char **names)
3424 {
3425 	size_t c;
3426 	ssize_t r;
3427 	unsigned int channel;
3428 	size_t vsize;
3429 	uint8_t *bufs[channels];
3430 
3431 	header(rtype, names[0]);
3432 	set_params();
3433 
3434 	vsize = chunk_bytes / channels;
3435 
3436 	for (channel = 0; channel < channels; ++channel)
3437 		bufs[channel] = audiobuf + vsize * channel;
3438 
3439 	while (count > 0 && !in_aborting) {
3440 		size_t rv;
3441 		c = count;
3442 		if (c > chunk_bytes)
3443 			c = chunk_bytes;
3444 		c = c * 8 / bits_per_frame;
3445 		if ((size_t)(r = pcm_readv(bufs, channels, c)) != c)
3446 			break;
3447 		rv = r * bits_per_sample / 8;
3448 		for (channel = 0; channel < channels; ++channel) {
3449 			if ((size_t)xwrite(fds[channel], bufs[channel], rv) != rv) {
3450 				perror(names[channel]);
3451 				prg_exit(EXIT_FAILURE);
3452 			}
3453 		}
3454 		r = r * bits_per_frame / 8;
3455 		count -= r;
3456 		fdcount += r;
3457 	}
3458 }
3459 
3460 static void playbackv(char **names, unsigned int count)
3461 {
3462 	int ret = 0;
3463 	unsigned int channel;
3464 	unsigned int channels = rhwparams.channels;
3465 	int alloced = 0;
3466 	int fds[channels];
3467 	for (channel = 0; channel < channels; ++channel)
3468 		fds[channel] = -1;
3469 
3470 	if (count == 1 && channels > 1) {
3471 		size_t len = strlen(names[0]);
3472 		char buf[len + 1];
3473 		strcpy(buf, names[0]);
3474 		/* 1 for "." + 3 for channel (<= 256) + 1 for null terminator */
3475 		len += 5;
3476 		names = malloc(sizeof(*names) * channels);
3477 		for (channel = 0; channel < channels; ++channel) {
3478 			names[channel] = malloc(len);
3479 			snprintf(names[channel], len, "%s.%d", buf, channel);
3480 		}
3481 		alloced = 1;
3482 	} else if (count != channels) {
3483 		error(_("You need to specify %u files"), channels);
3484 		prg_exit(EXIT_FAILURE);
3485 	}
3486 
3487 	for (channel = 0; channel < channels; ++channel) {
3488 		fds[channel] = open(names[channel], O_RDONLY, 0);
3489 		if (fds[channel] < 0) {
3490 			perror(names[channel]);
3491 			ret = EXIT_FAILURE;
3492 			goto __end;
3493 		}
3494 	}
3495 	/* should be raw data */
3496 	init_raw_data();
3497 	pbrec_count = calc_count();
3498 	playbackv_go(fds, channels, 0, pbrec_count, FORMAT_RAW, names);
3499 
3500       __end:
3501 	for (channel = 0; channel < channels; ++channel) {
3502 		if (fds[channel] >= 0)
3503 			close(fds[channel]);
3504 		if (alloced)
3505 			free(names[channel]);
3506 	}
3507 	if (alloced)
3508 		free(names);
3509 	if (ret)
3510 		prg_exit(ret);
3511 }
3512 
3513 static void capturev(char **names, unsigned int count)
3514 {
3515 	int ret = 0;
3516 	unsigned int channel;
3517 	unsigned int channels = rhwparams.channels;
3518 	int alloced = 0;
3519 	int fds[channels];
3520 	for (channel = 0; channel < channels; ++channel)
3521 		fds[channel] = -1;
3522 
3523 	if (count == 1) {
3524 		size_t len = strlen(names[0]);
3525 		char buf[len + 1];
3526 		strcpy(buf, names[0]);
3527 		/* 1 for "." + 3 for channel (<= 256) + 1 for null terminator */
3528 		len += 5;
3529 		names = malloc(sizeof(*names) * channels);
3530 		for (channel = 0; channel < channels; ++channel) {
3531 			names[channel] = malloc(len);
3532 			snprintf(names[channel], len, "%s.%d", buf, channel);
3533 		}
3534 		alloced = 1;
3535 	} else if (count != channels) {
3536 		error(_("You need to specify %d files"), channels);
3537 		prg_exit(EXIT_FAILURE);
3538 	}
3539 
3540 	for (channel = 0; channel < channels; ++channel) {
3541 		fds[channel] = open(names[channel], O_WRONLY + O_CREAT, 0644);
3542 		if (fds[channel] < 0) {
3543 			perror(names[channel]);
3544 			ret = EXIT_FAILURE;
3545 			goto __end;
3546 		}
3547 	}
3548 	/* should be raw data */
3549 	init_raw_data();
3550 	pbrec_count = calc_count();
3551 	capturev_go(fds, channels, pbrec_count, FORMAT_RAW, names);
3552 
3553       __end:
3554 	for (channel = 0; channel < channels; ++channel) {
3555 		if (fds[channel] >= 0)
3556 			close(fds[channel]);
3557 		if (alloced)
3558 			free(names[channel]);
3559 	}
3560 	if (alloced)
3561 		free(names);
3562 	if (ret)
3563 		prg_exit(ret);
3564 }
3565