1 /* -*- c-file-style: "gnu" -*- 2 TiMidity++ -- MIDI to WAVE converter and player 3 Copyright (C) 1999-2002 Masanao Izumo <mo@goice.co.jp> 4 Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi> 5 ALSA 0.[56] support by Katsuhiro Ueno <katsu@blue.sky.or.jp> 6 rewritten by Takashi Iwai <tiwai@suse.de> 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 2 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; if not, write to the Free Software 20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 test_constexpr()22 alsa_a.c 23 24 Functions to play sound on the ALSA audio driver 25 26 */ 27 28 #ifdef HAVE_CONFIG_H 29 #include "config.h" 30 #endif /* HAVE_CONFIG_H */ 31 #define _GNU_SOURCE 32 #include <stdio.h> 33 #include <stdlib.h> 34 #include <unistd.h> 35 #include <fcntl.h> 36 37 #ifndef NO_STRING_H 38 #include <string.h> 39 #else 40 #include <strings.h> 41 #endif 42 43 /*ALSA header file*/ 44 #if HAVE_ALSA_ASOUNDLIB_H 45 #define ALSA_PCM_OLD_HW_PARAMS_API 46 #define ALSA_PCM_OLD_SW_PARAMS_API 47 #include <alsa/asoundlib.h> 48 #else 49 #include <sys/asoundlib.h> 50 #endif 51 52 #if SND_LIB_MAJOR > 0 53 #define ALSA_LIB 9 54 #elif defined(SND_LIB_MINOR) 55 #define ALSA_LIB SND_LIB_MINOR 56 #else 57 #define ALSA_LIB 3 58 #endif 59 60 #if ALSA_LIB < 4 61 typedef void snd_pcm_t; 62 #endif 63 64 #include "timidity.h" 65 #include "common.h" 66 #include "output.h" 67 #include "controls.h" 68 #include "timer.h" 69 #include "instrum.h" 70 #include "playmidi.h" 71 #include "miditrace.h" 72 73 static int open_output(void); /* 0=success, 1=warning, -1=fatal error */ 74 static void close_output(void); 75 static int output_data(char *buf, int32 nbytes); 76 static int acntl(int request, void *arg); 77 #if ALSA_LIB >= 5 78 static int detect(void); 79 #endif 80 81 /* export the playback mode */ 82 83 #define dpm alsa_play_mode 84 85 PlayMode dpm = { 86 DEFAULT_RATE, PE_16BIT|PE_SIGNED, PF_PCM_STREAM|PF_CAN_TRACE|PF_BUFF_FRAGM_OPT, 87 -1, 88 {0}, /* default: get all the buffer fragments you can */ 89 "ALSA pcm device", 's', 90 "", /* here leave it empty so that the pcm device name can be given 91 * via command line option. 92 */ 93 open_output, 94 close_output, 95 output_data, 96 acntl, 97 #if ALSA_LIB >= 5 98 detect 99 #endif 100 }; 101 102 /*************************************************************************/ 103 /* We currently only honor the PE_MONO bit, the sample rate, and the 104 number of buffer fragments. We try 16-bit signed data first, and 105 then 8-bit unsigned if it fails. If you have a sound device that 106 can't handle either, let me know. */ 107 108 109 /*ALSA PCM handler*/ 110 static snd_pcm_t* handle = NULL; 111 #if ALSA_LIB <= 5 112 static int card = 0; 113 static int device = 0; 114 #endif 115 static int total_bytes = -1; 116 static int frag_size = 0; 117 static int sample_shift = 0; 118 static int output_counter; 119 120 #if ALSA_LIB > 5 121 static char *alsa_device_name(void) 122 { 123 if (dpm.name && *dpm.name) 124 return dpm.name; 125 else 126 return "alsa pcm"; 127 } 128 #else 129 static char *alsa_device_name(void) 130 { 131 static char name[32]; 132 sprintf(name, "card%d/device%d", card, device); 133 return name; 134 } 135 #endif 136 137 static void error_report (int snd_error) 138 { 139 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s", 140 alsa_device_name(), snd_strerror (snd_error)); 141 } 142 143 144 #if ALSA_LIB < 6 145 /*return value == 0 sucess 146 == -1 fails 147 */ 148 static int check_sound_cards (int* card__, int* device__, 149 const int32 extra_param[5]) 150 { 151 /*Search sound cards*/ 152 struct snd_ctl_hw_info ctl_hw_info; 153 snd_pcm_info_t pcm_info; 154 snd_ctl_t* ctl_handle; 155 const char* env_sound_card = getenv ("TIMIDITY_SOUND_CARD"); 156 const char* env_pcm_device = getenv ("TIMIDITY_PCM_DEVICE"); 157 int tmp; 158 159 /*specify card*/ 160 *card__ = 0; 161 if (env_sound_card != NULL) 162 *card__ = atoi (env_sound_card); 163 /*specify device*/ 164 *device__ = 0; 165 if (env_pcm_device != NULL) 166 *device__ = atoi (env_pcm_device); 167 168 tmp = snd_cards (); 169 if (tmp == 0) 170 { 171 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "No sound card found."); 172 return -1; 173 } 174 if (tmp < 0) 175 { 176 error_report (tmp); 177 return -1; 178 } 179 180 if (*card__ < 0 || *card__ >= tmp) 181 { 182 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "There is %d sound cards." 183 " %d is invalid sound card. assuming 0.", 184 tmp, *card__); 185 *card__ = 0; 186 } 187 188 tmp = snd_ctl_open (&ctl_handle, *card__); 189 if (tmp < 0) 190 { 191 error_report (tmp); 192 return -1; 193 } 194 195 /*check whether sound card has pcm device(s)*/ 196 tmp = snd_ctl_hw_info (ctl_handle, & ctl_hw_info); 197 if (ctl_hw_info.pcmdevs == 0) 198 { 199 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, 200 "%d-th sound card(%s) has no pcm device", 201 ctl_hw_info.longname, *card__); 202 snd_ctl_close (ctl_handle); 203 return -1; 204 } 205 206 if (*device__ < 0 || *device__ >= ctl_hw_info.pcmdevs) 207 { 208 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, 209 "%d-th sound cards(%s) has %d pcm device(s)." 210 " %d is invalid pcm device. assuming 0.", 211 *card__, ctl_hw_info.longname, ctl_hw_info.pcmdevs, *device__); 212 *device__ = 0; 213 214 if (ctl_hw_info.pcmdevs == 0) 215 {/*sound card has no pcm devices*/ 216 snd_ctl_close (ctl_handle); 217 return -1; 218 } 219 } 220 221 /*check whether pcm device is able to playback*/ 222 tmp = snd_ctl_pcm_info(ctl_handle, *device__, &pcm_info); 223 if (tmp < 0) 224 { 225 error_report (tmp); 226 snd_ctl_close (ctl_handle); 227 return -1; 228 } 229 230 if ((pcm_info.flags & SND_PCM_INFO_PLAYBACK) == 0) 231 { 232 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, 233 "%d-th sound cards(%s), device=%d, " 234 "type=%d, flags=%d, id=%s, name=%s," 235 " does not support playback", 236 *card__, ctl_hw_info.longname, ctl_hw_info.pcmdevs, 237 pcm_info.type, pcm_info.flags, pcm_info.id, pcm_info.name); 238 snd_ctl_close (ctl_handle); 239 return -1; 240 } 241 242 tmp = snd_ctl_close (ctl_handle); 243 if (tmp < 0) 244 { 245 error_report (tmp); 246 return -1; 247 } 248 249 return 0; 250 } 251 #endif 252 253 254 #if ALSA_LIB > 5 255 /*================================================================ 256 * ALSA API version 0.9.x 257 *================================================================*/ 258 259 static char *get_pcm_name(void) 260 { 261 char *name; 262 if (dpm.name && *dpm.name) 263 return dpm.name; 264 name = getenv("TIMIDITY_PCM_NAME"); 265 if (! name || ! *name) 266 name = "default"; 267 return name; 268 } 269 270 static void error_handle(const char *file, int line, const char *func, int err, const char *fmt, ...) 271 { 272 } 273 274 static int detect(void) 275 { 276 snd_pcm_t *pcm; 277 snd_lib_error_set_handler(error_handle); 278 if (snd_pcm_open(&pcm, get_pcm_name(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK) < 0) 279 return 0; 280 snd_pcm_close(pcm); 281 return 1; /* found */ 282 } 283 284 /*return value == 0 sucess 285 == 1 warning 286 == -1 fails 287 */ 288 static int open_output(void) 289 { 290 int orig_rate = dpm.rate; 291 int ret_val = 0; 292 int tmp, frags, r, pfds; 293 int rate; 294 snd_pcm_hw_params_t *pinfo; 295 snd_pcm_sw_params_t *swpinfo; 296 297 dpm.name = get_pcm_name(); 298 snd_lib_error_set_handler(NULL); 299 tmp = snd_pcm_open(&handle, dpm.name, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); /* avoid blocking by open */ 300 if (tmp < 0) { 301 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Can't open pcm device '%s'.", dpm.name); 302 return -1; 303 } 304 snd_pcm_nonblock(handle, 0); /* set back to blocking mode */ 305 306 snd_pcm_hw_params_alloca(&pinfo); 307 snd_pcm_sw_params_alloca(&swpinfo); 308 309 if (snd_pcm_hw_params_any(handle, pinfo) < 0) { 310 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, 311 "ALSA pcm '%s' can't initialize hw_params", 312 alsa_device_name()); 313 snd_pcm_close(handle); 314 return -1; 315 } 316 317 #ifdef LITTLE_ENDIAN 318 #define S16_FORMAT SND_PCM_FORMAT_S16_LE 319 #define U16_FORMAT SND_PCM_FORMAT_U16_LE 320 #else 321 #define S16_FORMAT SND_PCM_FORMAT_S16_BE 322 #define U16_FORMAT SND_PCM_FORMAT_U16_LE 323 #endif 324 325 dpm.encoding &= ~(PE_ULAW|PE_ALAW|PE_BYTESWAP); 326 /*check sample bit*/ 327 if (snd_pcm_hw_params_test_format(handle, pinfo, S16_FORMAT) < 0 && 328 snd_pcm_hw_params_test_format(handle, pinfo, U16_FORMAT) < 0) 329 dpm.encoding &= ~PE_16BIT; /*force 8bit samples*/ 330 if (snd_pcm_hw_params_test_format(handle, pinfo, SND_PCM_FORMAT_U8) < 0 && 331 snd_pcm_hw_params_test_format(handle, pinfo, SND_PCM_FORMAT_S8) < 0) 332 dpm.encoding |= PE_16BIT; /*force 16bit samples*/ 333 334 /*check format*/ 335 if (dpm.encoding & PE_16BIT) { 336 /*16bit*/ 337 if (snd_pcm_hw_params_set_format(handle, pinfo, S16_FORMAT) == 0) 338 dpm.encoding |= PE_SIGNED; 339 else if (snd_pcm_hw_params_set_format(handle, pinfo, U16_FORMAT) == 0) 340 dpm.encoding &= ~PE_SIGNED; 341 else { 342 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, 343 "ALSA pcm '%s' doesn't support 16 bit sample width", 344 alsa_device_name()); 345 snd_pcm_close(handle); 346 return -1; 347 } 348 } else { 349 /*8bit*/ 350 if (snd_pcm_hw_params_set_format(handle, pinfo, SND_PCM_FORMAT_U8) == 0) 351 dpm.encoding &= ~PE_SIGNED; 352 else if (snd_pcm_hw_params_set_format(handle, pinfo, SND_PCM_FORMAT_S8) == 0) 353 dpm.encoding |= PE_SIGNED; 354 else { 355 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, 356 "ALSA pcm '%s' doesn't support 8 bit sample width", 357 alsa_device_name()); 358 snd_pcm_close(handle); 359 return -1; 360 } 361 } 362 363 if (snd_pcm_hw_params_set_access(handle, pinfo, 364 SND_PCM_ACCESS_RW_INTERLEAVED) < 0) { 365 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, 366 "ALSA pcm '%s' doesn't support interleaved data", 367 alsa_device_name()); 368 snd_pcm_close(handle); 369 return -1; 370 } 371 372 /*check rate*/ 373 r = snd_pcm_hw_params_get_rate_min(pinfo, NULL); 374 if (r >= 0 && r > dpm.rate) { 375 dpm.rate = r; 376 ret_val = 1; 377 } 378 r = snd_pcm_hw_params_get_rate_max(pinfo, NULL); 379 if (r >= 0 && r < dpm.rate) { 380 dpm.rate = r; 381 ret_val = 1; 382 } 383 if ((rate = snd_pcm_hw_params_set_rate_near(handle, pinfo, dpm.rate, 0)) < 0) { 384 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, 385 "ALSA pcm '%s' can't set rate %d", 386 alsa_device_name(), dpm.rate); 387 snd_pcm_close(handle); 388 return -1; 389 } 390 391 /*check channels*/ 392 if (dpm.encoding & PE_MONO) { 393 if (snd_pcm_hw_params_test_channels(handle, pinfo, 1) < 0) 394 dpm.encoding &= ~PE_MONO; 395 } else { 396 if (snd_pcm_hw_params_test_channels(handle, pinfo, 2) < 0) 397 dpm.encoding |= PE_MONO; 398 } 399 400 if (dpm.encoding & PE_MONO) { 401 if (snd_pcm_hw_params_set_channels(handle, pinfo, 1) < 0) { 402 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, 403 "ALSA pcm '%s' can't set mono channel", 404 alsa_device_name()); 405 snd_pcm_close(handle); 406 return -1; 407 } 408 } else { 409 if (snd_pcm_hw_params_set_channels(handle, pinfo, 2) < 0) { 410 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, 411 "ALSA pcm '%s' can't set stereo channels", 412 alsa_device_name()); 413 snd_pcm_close(handle); 414 return -1; 415 } 416 } 417 418 sample_shift = 0; 419 if (!(dpm.encoding & PE_MONO)) 420 sample_shift++; 421 if (dpm.encoding & PE_16BIT) 422 sample_shift++; 423 424 /* Set buffer fragment size (in extra_param[1]) */ 425 if (dpm.extra_param[1] != 0) 426 frag_size = dpm.extra_param[1]; 427 else 428 frag_size = audio_buffer_size << sample_shift; 429 430 /* Set buffer fragments (in extra_param[0]) */ 431 if (dpm.extra_param[0] == 0) 432 frags = 4; 433 else 434 frags = dpm.extra_param[0]; 435 436 total_bytes = frag_size * frags; 437 ctl->cmsg(CMSG_INFO, VERB_VERBOSE, 438 "Requested buffer size %d, fragment size %d", 439 total_bytes, frag_size); 440 if ((tmp = snd_pcm_hw_params_set_buffer_size_near(handle, pinfo, total_bytes >> sample_shift)) < 0) { 441 ctl->cmsg(CMSG_WARNING, VERB_NORMAL, 442 "ALSA pcm '%s' can't set buffer size %d", 443 alsa_device_name(), total_bytes); 444 snd_pcm_close(handle); 445 return -1; 446 } 447 448 if ((tmp = snd_pcm_hw_params_set_period_size_near(handle, pinfo, frag_size >> sample_shift, 0)) < 0) { 449 ctl->cmsg(CMSG_WARNING, VERB_NORMAL, 450 "ALSA pcm '%s' can't set period size %d", 451 alsa_device_name(), frag_size); 452 snd_pcm_close(handle); 453 return -1; 454 } 455 456 if (snd_pcm_hw_params(handle, pinfo) < 0) { 457 snd_output_t *log; 458 ctl->cmsg(CMSG_WARNING, VERB_NORMAL, 459 "ALSA pcm '%s' can't set hw_params", alsa_device_name()); 460 snd_output_stdio_attach(&log, stderr, 0); 461 snd_pcm_hw_params_dump(pinfo, log); 462 snd_pcm_close(handle); 463 return -1; 464 } 465 466 total_bytes = snd_pcm_hw_params_get_buffer_size(pinfo) << sample_shift; 467 frag_size = snd_pcm_hw_params_get_period_size(pinfo, NULL) << sample_shift; 468 ctl->cmsg(CMSG_INFO, VERB_VERBOSE, 469 "ALSA pcm '%s' set buffer size %d, period size %d bytes", 470 alsa_device_name(), total_bytes, frag_size); 471 tmp = snd_pcm_hw_params_get_rate(pinfo, NULL); 472 if (tmp > 0 && tmp != dpm.rate) { 473 dpm.rate = tmp; 474 ret_val = 1; 475 } 476 if (orig_rate != dpm.rate) { 477 ctl->cmsg(CMSG_WARNING, VERB_VERBOSE, 478 "Output rate adjusted to %d Hz (requested %d Hz)", 479 dpm.rate, orig_rate); 480 } 481 snd_pcm_sw_params_current(handle, swpinfo); 482 snd_pcm_sw_params_set_start_threshold(handle, swpinfo, total_bytes >> sample_shift); 483 snd_pcm_sw_params_set_stop_threshold(handle, swpinfo, total_bytes >> sample_shift); 484 485 tmp = snd_pcm_prepare(handle); 486 if (tmp < 0) { 487 ctl->cmsg(CMSG_WARNING, VERB_NORMAL, 488 "unable to prepare channel\n"); 489 snd_pcm_close(handle); 490 return -1; 491 } 492 493 pfds = snd_pcm_poll_descriptors_count(handle); 494 if (pfds > 1) { 495 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "too many poll descriptors: %s", 496 alsa_device_name()); 497 close_output (); 498 return -1; 499 } else if (pfds == 1) { 500 struct pollfd pfd; 501 if (snd_pcm_poll_descriptors(handle, &pfd, 1) >= 0) 502 dpm.fd = pfd.fd; 503 else 504 dpm.fd = -1; 505 } else 506 dpm.fd = -1; 507 508 output_counter = 0; 509 510 return ret_val; 511 } 512 513 static void close_output(void) 514 { 515 if (handle) { 516 int ret = snd_pcm_close (handle); 517 if (ret < 0) 518 error_report (ret); 519 handle = NULL; 520 } 521 522 dpm.fd = -1; 523 } 524 525 static int output_data(char *buf, int32 nbytes) 526 { 527 int n; 528 int nframes, shift; 529 530 if (! handle) 531 return -1; 532 533 nframes = nbytes; 534 shift = 0; 535 if (!(dpm.encoding & PE_MONO)) 536 shift++; 537 if (dpm.encoding & PE_16BIT) 538 shift++; 539 nframes >>= shift; 540 541 while (nframes > 0) { 542 n = snd_pcm_writei(handle, buf, nframes); 543 if (n == -EAGAIN || (n >= 0 && n < nframes)) { 544 snd_pcm_wait(handle, 1000); 545 } else if (n == -EPIPE) { 546 snd_pcm_status_t *status; 547 snd_pcm_status_alloca(&status); 548 if (snd_pcm_status(handle, status) < 0) { 549 ctl->cmsg(CMSG_WARNING, VERB_DEBUG, "%s: cannot get status", alsa_device_name()); 550 return -1; 551 } 552 ctl->cmsg(CMSG_INFO, VERB_DEBUG, 553 "%s: underrun at %ld", alsa_device_name(), output_counter << sample_shift); 554 snd_pcm_prepare(handle); 555 } else if (n < 0) { 556 ctl->cmsg(CMSG_WARNING, VERB_DEBUG, 557 "%s: %s", alsa_device_name(), 558 (n < 0) ? snd_strerror(n) : "write error"); 559 return -1; 560 } 561 if (n > 0) { 562 nframes -= n; 563 buf += n << shift; 564 output_counter += n; 565 } 566 } 567 568 return 0; 569 } 570 571 static int acntl(int request, void *arg) 572 { 573 snd_pcm_status_t *status; 574 snd_pcm_sframes_t delay; 575 576 if (handle == NULL) 577 return -1; 578 579 switch (request) { 580 case PM_REQ_GETFRAGSIZ: 581 if (frag_size == 0) 582 return -1; 583 *((int *)arg) = frag_size; 584 return 0; 585 586 case PM_REQ_GETQSIZ: 587 if (total_bytes == -1) 588 return -1; 589 *((int *)arg) = total_bytes; 590 return 0; 591 592 case PM_REQ_GETFILLABLE: 593 if (total_bytes == -1) 594 return -1; 595 snd_pcm_status_alloca(&status); 596 if (snd_pcm_status(handle, status) < 0) 597 return -1; 598 *((int *)arg) = snd_pcm_status_get_avail(status); 599 return 0; 600 601 case PM_REQ_GETFILLED: 602 if (total_bytes == -1) 603 return -1; 604 if (snd_pcm_delay(handle, &delay) < 0) 605 return -1; 606 *((int *)arg) = delay; 607 return 0; 608 609 case PM_REQ_GETSAMPLES: 610 if (total_bytes == -1) 611 return -1; 612 if (snd_pcm_delay(handle, &delay) < 0) 613 return -1; 614 *((int *)arg) = output_counter - delay; 615 return 0; 616 617 case PM_REQ_DISCARD: 618 if (snd_pcm_drop(handle) < 0) 619 return -1; 620 if (snd_pcm_prepare(handle) < 0) 621 return -1; 622 output_counter = 0; 623 return 0; 624 625 case PM_REQ_FLUSH: 626 if (snd_pcm_drain(handle) < 0) 627 return -1; 628 if (snd_pcm_prepare(handle) < 0) 629 return -1; 630 output_counter = 0; 631 return 0; 632 633 case PM_REQ_PLAY_START: /* Called just before playing */ 634 case PM_REQ_PLAY_END: /* Called just after playing */ 635 return 0; 636 } 637 return -1; 638 } 639 640 641 /* end ALSA API 0.9.x */ 642 643 644 #elif ALSA_LIB == 5 645 646 /*================================================================ 647 * ALSA API version 0.5.x 648 *================================================================*/ 649 650 /*return value == 0 sucess 651 == 1 warning 652 == -1 fails 653 */ 654 static int set_playback_info (snd_pcm_t* handle__, 655 int32* encoding__, int32* rate__, 656 const int32 extra_param[5]) 657 { 658 int ret_val = 0; 659 const int32 orig_rate = *rate__; 660 int tmp; 661 snd_pcm_channel_info_t pinfo; 662 snd_pcm_channel_params_t pparams; 663 snd_pcm_channel_setup_t psetup; 664 665 memset (&pinfo, 0, sizeof (pinfo)); 666 memset (&pparams, 0, sizeof (pparams)); 667 pinfo.channel = SND_PCM_CHANNEL_PLAYBACK; 668 tmp = snd_pcm_channel_info (handle__, &pinfo); 669 if (tmp < 0) 670 { 671 error_report (tmp); 672 return -1; 673 } 674 675 /*check sample bit*/ 676 if (!(pinfo.formats & ~(SND_PCM_FMT_S8 | SND_PCM_FMT_U8))) 677 *encoding__ &= ~PE_16BIT; /*force 8bit samples*/ 678 if (!(pinfo.formats & ~(SND_PCM_FMT_S16 | SND_PCM_FMT_U16))) 679 *encoding__ |= PE_16BIT; /*force 16bit samples*/ 680 681 /*check rate*/ 682 if (pinfo.min_rate > *rate__) 683 *rate__ = pinfo.min_rate; 684 if (pinfo.max_rate < *rate__) 685 *rate__ = pinfo.max_rate; 686 pparams.format.rate = *rate__; 687 688 /*check channels*/ 689 if ((*encoding__ & PE_MONO) != 0 && pinfo.min_voices > 1) 690 *encoding__ &= ~PE_MONO; 691 if ((*encoding__ & PE_MONO) == 0 && pinfo.max_voices < 2) 692 *encoding__ |= PE_MONO; 693 694 if ((*encoding__ & PE_MONO) != 0) 695 pparams.format.voices = 1; /*mono*/ 696 else 697 pparams.format.voices = 2; /*stereo*/ 698 699 /*check format*/ 700 if ((*encoding__ & PE_16BIT) != 0) 701 { /*16bit*/ 702 if ((pinfo.formats & SND_PCM_FMT_S16_LE) != 0) 703 { 704 pparams.format.format = SND_PCM_SFMT_S16_LE; 705 *encoding__ |= PE_SIGNED; 706 } 707 else if ((pinfo.formats & SND_PCM_FMT_U16_LE) != 0) 708 { 709 pparams.format.format = SND_PCM_SFMT_U16_LE; 710 *encoding__ &= ~PE_SIGNED; 711 } 712 else if ((pinfo.formats & SND_PCM_FMT_S16_BE) != 0) 713 { 714 pparams.format.format = SND_PCM_SFMT_S16_BE; 715 *encoding__ |= PE_SIGNED; 716 } 717 else if ((pinfo.formats & SND_PCM_FMT_U16_BE) != 0) 718 { 719 pparams.format.format = SND_PCM_SFMT_U16_BE; 720 *encoding__ &= ~PE_SIGNED; 721 } 722 else 723 { 724 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, 725 "%s doesn't support 16 bit sample width", 726 alsa_device_name()); 727 return -1; 728 } 729 } 730 else 731 { /*8bit*/ 732 if ((pinfo.formats & SND_PCM_FMT_U8) != 0) 733 { 734 pparams.format.format = SND_PCM_SFMT_U8; 735 *encoding__ &= ~PE_SIGNED; 736 } 737 #if 0 738 else if ((pinfo.formats & SND_PCM_FMT_S8) != 0) 739 { 740 pcm_format.format = SND_PCM_SFMT_U16_LE; 741 *encoding__ |= PE_SIGNED; 742 } 743 #endif 744 else 745 { 746 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, 747 "%s doesn't support 8 bit sample width", 748 alsa_device_name()); 749 return -1; 750 } 751 } 752 753 754 sample_shift = 0; 755 if (!(dpm.encoding & PE_MONO)) 756 sample_shift++; 757 if (dpm.encoding & PE_16BIT) 758 sample_shift++; 759 760 /* Set buffer fragment size (in extra_param[1]) */ 761 if (extra_param[1] != 0) 762 tmp = extra_param[1]; 763 else 764 tmp = audio_buffer_size << sample_shift; 765 766 /* Set buffer fragments (in extra_param[0]) */ 767 pparams.buf.block.frag_size = tmp; 768 pparams.buf.block.frags_max = (extra_param[0] == 0) ? -1 : extra_param[0]; 769 pparams.buf.block.frags_min = 1; 770 pparams.mode = SND_PCM_MODE_BLOCK; 771 pparams.channel = SND_PCM_CHANNEL_PLAYBACK; 772 pparams.start_mode = SND_PCM_START_DATA; /* .. should be START_FULL */ 773 pparams.stop_mode = SND_PCM_STOP_STOP; 774 pparams.format.interleave = 1; 775 snd_pcm_channel_flush (handle__, SND_PCM_CHANNEL_PLAYBACK); 776 tmp = snd_pcm_channel_params (handle__, &pparams); 777 if (tmp < 0) 778 { 779 ctl->cmsg(CMSG_WARNING, VERB_NORMAL, 780 "%s doesn't support buffer fragments" 781 ":request size=%d, max=%d, min=%d\n", 782 alsa_device_name(), 783 pparams.buf.block.frag_size, 784 pparams.buf.block.frags_max, 785 pparams.buf.block.frags_min); 786 return -1; 787 } 788 789 tmp = snd_pcm_channel_prepare (handle__, SND_PCM_CHANNEL_PLAYBACK); 790 if (tmp < 0) 791 { 792 ctl->cmsg(CMSG_WARNING, VERB_NORMAL, 793 "unable to prepare channel\n"); 794 return -1; 795 } 796 797 memset (&psetup, 0, sizeof(psetup)); 798 psetup.channel = SND_PCM_CHANNEL_PLAYBACK; 799 tmp = snd_pcm_channel_setup (handle__, &psetup); 800 if (tmp == 0) 801 { 802 if(psetup.format.rate != orig_rate) 803 { 804 ctl->cmsg(CMSG_WARNING, VERB_VERBOSE, 805 "Output rate adjusted to %d Hz (requested %d Hz)", 806 psetup.format.rate, orig_rate); 807 dpm.rate = psetup.format.rate; 808 ret_val = 1; 809 } 810 frag_size = psetup.buf.block.frag_size; 811 total_bytes = frag_size * psetup.buf.block.frags; 812 } 813 else 814 { 815 frag_size = 0; 816 total_bytes = -1; /* snd_pcm_playback_status fails */ 817 } 818 819 return ret_val; 820 } 821 822 823 static int detect(void) 824 { 825 snd_pcm_t *pcm; 826 if (snd_pcm_open(&pcm, card, device, SND_PCM_OPEN_PLAYBACK | SND_PCM_OPEN_NONBLOCK) < 0) 827 return 0; 828 snd_pcm_close(pcm); 829 return 1; /* found */ 830 } 831 832 static int open_output(void) 833 { 834 int tmp, warnings=0; 835 int ret; 836 837 tmp = check_sound_cards (&card, &device, dpm.extra_param); 838 if (tmp < 0) 839 return -1; 840 841 /* Open the audio device */ 842 ret = snd_pcm_open (&handle, card, device, SND_PCM_OPEN_PLAYBACK | SND_PCM_OPEN_NONBLOCK); 843 if (ret < 0) 844 { 845 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s", 846 alsa_device_name(), snd_strerror (ret)); 847 return -1; 848 } 849 850 snd_pcm_nonblock_mode(handle, 0); /* set back to blocking mode */ 851 /* They can't mean these */ 852 dpm.encoding &= ~(PE_ULAW|PE_ALAW|PE_BYTESWAP); 853 warnings = set_playback_info (handle, &dpm.encoding, &dpm.rate, 854 dpm.extra_param); 855 if (warnings < 0) 856 { 857 close_output (); 858 return -1; 859 } 860 861 dpm.fd = snd_pcm_file_descriptor (handle, SND_PCM_CHANNEL_PLAYBACK); 862 output_counter = 0; 863 return warnings; 864 } 865 866 static void close_output(void) 867 { 868 int ret; 869 870 if (handle == NULL) 871 return; 872 873 ret = snd_pcm_close (handle); 874 if (ret < 0 && ret != -EINVAL) /* Maybe alsa-driver 0.5 has a bug */ 875 error_report (ret); 876 handle = NULL; 877 878 dpm.fd = -1; 879 } 880 881 static int output_data(char *buf, int32 nbytes) 882 { 883 int n; 884 snd_pcm_channel_status_t status; 885 886 if (! handle) 887 return -1; 888 n = snd_pcm_write (handle, buf, nbytes); 889 if (n <= 0) 890 { 891 memset (&status, 0, sizeof(status)); 892 status.channel = SND_PCM_CHANNEL_PLAYBACK; 893 if (snd_pcm_channel_status(handle, &status) < 0) 894 { 895 ctl->cmsg(CMSG_WARNING, VERB_DEBUG, 896 "%s: could not get channel status", alsa_device_name()); 897 return -1; 898 } 899 if (status.status == SND_PCM_STATUS_UNDERRUN || n == -EPIPE) 900 { 901 ctl->cmsg(CMSG_INFO, VERB_DEBUG, 902 "%s: underrun at %d", alsa_device_name(), status.scount); 903 output_counter += status.scount; 904 snd_pcm_channel_flush (handle, SND_PCM_CHANNEL_PLAYBACK); 905 snd_pcm_channel_prepare (handle, SND_PCM_CHANNEL_PLAYBACK); 906 n = snd_pcm_write (handle, buf, nbytes); 907 } 908 if (n <= 0) 909 { 910 ctl->cmsg(CMSG_WARNING, VERB_DEBUG, 911 "%s: %s", alsa_device_name(), 912 (n < 0) ? snd_strerror(n) : "write error"); 913 if (n != -EPIPE) /* buffer underrun is ignored */ 914 return -1; 915 } 916 } 917 return 0; 918 } 919 920 921 static int acntl(int request, void *arg) 922 { 923 int i; 924 snd_pcm_channel_status_t pstatus; 925 memset (&pstatus, 0, sizeof (pstatus)); 926 pstatus.channel = SND_PCM_CHANNEL_PLAYBACK; 927 928 if (handle == NULL) 929 return -1; 930 931 switch (request) 932 { 933 case PM_REQ_GETFRAGSIZ: 934 if (frag_size == 0) 935 return -1; 936 *((int *)arg) = frag_size; 937 return 0; 938 939 case PM_REQ_GETQSIZ: 940 if (total_bytes == -1) 941 return -1; 942 *((int *)arg) = total_bytes; 943 return 0; 944 945 case PM_REQ_GETFILLABLE: 946 if (total_bytes == -1) 947 return -1; 948 if (snd_pcm_channel_status(handle, &pstatus) < 0) 949 return -1; 950 i = pstatus.free >> sample_shift; 951 *((int *)arg) = i; 952 return 0; 953 954 case PM_REQ_GETFILLED: 955 if (total_bytes == -1) 956 return -1; 957 if (snd_pcm_channel_status(handle, &pstatus) < 0) 958 return -1; 959 i = pstatus.count >> sample_shift; 960 *((int *)arg) = i; 961 return 0; 962 963 case PM_REQ_GETSAMPLES: 964 if (total_bytes == -1) 965 return -1; 966 if (snd_pcm_channel_status(handle, &pstatus) < 0) 967 return -1; 968 i = (output_counter + pstatus.scount) >> sample_shift; 969 *((int *)arg) = i; 970 return 0; 971 972 case PM_REQ_DISCARD: 973 if (snd_pcm_playback_drain(handle) < 0) 974 return -1; 975 if (snd_pcm_channel_prepare(handle, SND_PCM_CHANNEL_PLAYBACK) < 0) 976 return -1; 977 output_counter = 0; 978 return 0; 979 980 case PM_REQ_FLUSH: 981 if (snd_pcm_channel_flush(handle, SND_PCM_CHANNEL_PLAYBACK) < 0) 982 return -1; 983 if (snd_pcm_channel_prepare(handle, SND_PCM_CHANNEL_PLAYBACK) < 0) 984 return -1; 985 output_counter = 0; 986 return 0; 987 } 988 return -1; 989 } 990 991 /* end ALSA API 0.5.x */ 992 993 #elif ALSA_LIB < 5 994 995 /*================================================================ 996 * ALSA API version 0.4.x 997 *================================================================*/ 998 999 /*return value == 0 sucess 1000 == 1 warning 1001 == -1 fails 1002 */ 1003 static int set_playback_info (snd_pcm_t* handle__, 1004 int32* encoding__, int32* rate__, 1005 const int32 extra_param[5]) 1006 { 1007 int ret_val = 0; 1008 const int32 orig_encoding = *encoding__; 1009 const int32 orig_rate = *rate__; 1010 int tmp; 1011 snd_pcm_playback_info_t pinfo; 1012 snd_pcm_format_t pcm_format; 1013 struct snd_pcm_playback_params pparams; 1014 struct snd_pcm_playback_status pstatus; 1015 memset (&pcm_format, 0, sizeof (pcm_format)); 1016 1017 memset (&pinfo, 0, sizeof (pinfo)); 1018 memset (&pparams, 0, sizeof (pparams)); 1019 tmp = snd_pcm_playback_info (handle__, &pinfo); 1020 if (tmp < 0) 1021 { 1022 error_report (tmp); 1023 return -1; 1024 } 1025 1026 /*check sample bit*/ 1027 if ((pinfo.flags & SND_PCM_PINFO_8BITONLY) != 0) 1028 *encoding__ &= ~PE_16BIT; /*force 8bit samples*/ 1029 if ((pinfo.flags & SND_PCM_PINFO_16BITONLY) != 0) 1030 *encoding__ |= PE_16BIT; /*force 16bit samples*/ 1031 1032 /*check rate*/ 1033 if (pinfo.min_rate > *rate__) 1034 *rate__ = pinfo.min_rate; 1035 if (pinfo.max_rate < *rate__) 1036 *rate__ = pinfo.max_rate; 1037 pcm_format.rate = *rate__; 1038 1039 /*check channels*/ 1040 if ((*encoding__ & PE_MONO) != 0 && pinfo.min_channels > 1) 1041 *encoding__ &= ~PE_MONO; 1042 if ((*encoding__ & PE_MONO) == 0 && pinfo.max_channels < 2) 1043 *encoding__ |= PE_MONO; 1044 1045 if ((*encoding__ & PE_MONO) != 0) 1046 pcm_format.channels = 1; /*mono*/ 1047 else 1048 pcm_format.channels = 2; /*stereo*/ 1049 1050 /*check format*/ 1051 if ((*encoding__ & PE_16BIT) != 0) 1052 { /*16bit*/ 1053 if ((pinfo.formats & SND_PCM_FMT_S16_LE) != 0) 1054 { 1055 pcm_format.format = SND_PCM_SFMT_S16_LE; 1056 *encoding__ |= PE_SIGNED; 1057 } 1058 else 1059 { 1060 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, 1061 "%s doesn't support 16 bit sample width", 1062 alsa_device_name()); 1063 return -1; 1064 } 1065 } 1066 else 1067 { /*8bit*/ 1068 if ((pinfo.formats & SND_PCM_FMT_U8) != 0) 1069 { 1070 pcm_format.format = SND_PCM_SFMT_U8; 1071 *encoding__ &= ~PE_SIGNED; 1072 } 1073 #if 0 1074 else if ((pinfo.formats & SND_PCM_FMT_S8) != 0) 1075 { 1076 pcm_format.format = SND_PCM_SFMT_U16_LE; 1077 *encoding__ |= PE_SIGNED; 1078 } 1079 #endif 1080 else 1081 { 1082 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, 1083 "%s doesn't support 8 bit sample width", 1084 alsa_device_name()); 1085 return -1; 1086 } 1087 } 1088 1089 1090 tmp = snd_pcm_playback_format (handle__, &pcm_format); 1091 if (tmp < 0) 1092 { 1093 error_report (tmp); 1094 return -1; 1095 } 1096 /*check result of snd_pcm_playback_format*/ 1097 if ((*encoding__ & PE_16BIT) != (orig_encoding & PE_16BIT )) 1098 { 1099 ctl->cmsg (CMSG_WARNING, VERB_VERBOSE, 1100 "Sample width adjusted to %d bits", 1101 ((*encoding__ & PE_16BIT) != 0)? 16:8); 1102 ret_val = 1; 1103 } 1104 if (((pcm_format.channels == 1)? PE_MONO:0) != (orig_encoding & PE_MONO)) 1105 { 1106 ctl->cmsg(CMSG_WARNING, VERB_VERBOSE, "Sound adjusted to %sphonic", 1107 ((*encoding__ & PE_MONO) != 0)? "mono" : "stereo"); 1108 ret_val = 1; 1109 } 1110 1111 sample_shift = 0; 1112 if (!(dpm.encoding & PE_MONO)) 1113 sample_shift++; 1114 if (dpm.encoding & PE_16BIT) 1115 sample_shift++; 1116 1117 /* Set buffer fragment size (in extra_param[1]) */ 1118 if (extra_param[1] != 0) 1119 tmp = extra_param[1]; 1120 else 1121 tmp = audio_buffer_size << sample_shift; 1122 1123 /* Set buffer fragments (in extra_param[0]) */ 1124 pparams.fragment_size = tmp; 1125 pparams.fragments_max = (extra_param[0] == 0) ? -1 : extra_param[0]; 1126 pparams.fragments_room = 1; 1127 tmp = snd_pcm_playback_params (handle__, &pparams); 1128 if (tmp < 0) 1129 { 1130 ctl->cmsg(CMSG_WARNING, VERB_NORMAL, 1131 "%s doesn't support buffer fragments" 1132 ":request size=%d, max=%d, room=%d\n", 1133 alsa_device_name(), 1134 pparams.fragment_size, 1135 pparams.fragments_max, 1136 pparams.fragments_room); 1137 ret_val = 1; 1138 } 1139 1140 if (snd_pcm_playback_status(handle__, &pstatus) == 0) 1141 { 1142 if (pstatus.rate != orig_rate) 1143 { 1144 ctl->cmsg(CMSG_WARNING, VERB_VERBOSE, 1145 "Output rate adjusted to %d Hz (requested %d Hz)", 1146 pstatus.rate, orig_rate); 1147 dpm.rate = pstatus.rate; 1148 ret_val = 1; 1149 } 1150 frag_size = pstatus.fragment_size; 1151 total_bytes = pstatus.count; 1152 } 1153 else 1154 { 1155 frag_size = 0; 1156 total_bytes = -1; /* snd_pcm_playback_status fails */ 1157 } 1158 1159 return ret_val; 1160 } 1161 1162 static int open_output(void) 1163 { 1164 int tmp, warnings=0; 1165 int ret; 1166 1167 tmp = check_sound_cards (&card, &device, dpm.extra_param); 1168 if (tmp < 0) 1169 return -1; 1170 1171 /* Open the audio device */ 1172 ret = snd_pcm_open (&handle, card, device, SND_PCM_OPEN_PLAYBACK); 1173 if (ret < 0) 1174 { 1175 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s", 1176 alsa_device_name(), snd_strerror (ret)); 1177 return -1; 1178 } 1179 1180 /* They can't mean these */ 1181 dpm.encoding &= ~(PE_ULAW|PE_ALAW|PE_BYTESWAP); 1182 warnings = set_playback_info (handle, &dpm.encoding, &dpm.rate, 1183 dpm.extra_param); 1184 if (warnings < 0) 1185 { 1186 close_output (); 1187 return -1; 1188 } 1189 1190 dpm.fd = snd_pcm_file_descriptor (handle); 1191 output_counter = 0; 1192 return warnings; 1193 } 1194 1195 static void close_output(void) 1196 { 1197 int ret; 1198 1199 if (handle == NULL) 1200 return; 1201 1202 ret = snd_pcm_close (handle); 1203 if (ret < 0) 1204 error_report (ret); 1205 handle = NULL; 1206 1207 dpm.fd = -1; 1208 } 1209 1210 static int output_data(char *buf, int32 nbytes) 1211 { 1212 int n; 1213 1214 if (! handle) 1215 return -1; 1216 while (nbytes > 0) 1217 { 1218 n = snd_pcm_write (handle, buf, nbytes); 1219 1220 if (n < 0) 1221 { 1222 ctl->cmsg(CMSG_WARNING, VERB_DEBUG, 1223 "%s: %s", alsa_device_name(), snd_strerror(n)); 1224 if (n == -EWOULDBLOCK) 1225 continue; 1226 return -1; 1227 } 1228 buf += n; 1229 nbytes -= n; 1230 output_counter += n; 1231 } 1232 1233 return 0; 1234 } 1235 1236 static int acntl(int request, void *arg) 1237 { 1238 int i; 1239 struct snd_pcm_playback_status pstatus; 1240 1241 if (handle == NULL) 1242 return -1; 1243 1244 switch (request) 1245 { 1246 case PM_REQ_GETFRAGSIZ: 1247 if (frag_size == 0) 1248 return -1; 1249 *((int *)arg) = frag_size; 1250 return 0; 1251 1252 case PM_REQ_GETQSIZ: 1253 if (total_bytes == -1) 1254 return -1; 1255 *((int *)arg) = total_bytes; 1256 return 0; 1257 1258 case PM_REQ_GETFILLABLE: 1259 if (total_bytes == -1) 1260 return -1; 1261 if (snd_pcm_playback_status(handle, &pstatus) < 0) 1262 return -1; 1263 i = pstatus.count >> sample_shift; 1264 *((int *)arg) = i; 1265 return 0; 1266 1267 case PM_REQ_GETFILLED: 1268 if (total_bytes == -1) 1269 return -1; 1270 if (snd_pcm_playback_status(handle, &pstatus) < 0) 1271 return -1; 1272 i = pstatus.queue >> sample_shift; 1273 *((int *)arg) = i; 1274 return 0; 1275 1276 case PM_REQ_GETSAMPLES: 1277 if (total_bytes == -1) 1278 return -1; 1279 if (snd_pcm_playback_status(handle, &pstatus) < 0) 1280 return -1; 1281 i = output_counter - pstatus.queue; 1282 i >>= sample_shift; 1283 *((int *)arg) = i; 1284 return 0; 1285 1286 case PM_REQ_DISCARD: 1287 if (snd_pcm_drain_playback (handle) < 0) 1288 return -1; /* error */ 1289 output_counter = 0; 1290 return 0; 1291 1292 case PM_REQ_FLUSH: 1293 if (snd_pcm_flush_playback(handle) < 0) 1294 return -1; /* error */ 1295 output_counter = 0; 1296 return 0; 1297 } 1298 return -1; 1299 } 1300 1301 /* end ALSA API 0.4.x */ 1302 1303 #endif 1304 1305