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