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