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