comparison libao2/ao_alsa1x.c @ 6702:df3bf0f971d1

fixed spdif spdif device depends now on the given subdevice was hardcoded to hw:0,2 before fixed opt-parsing for hw:x,y like opts seperated initialization of spdif from common init as it was probably intended before
author joyping
date Thu, 11 Jul 2002 10:20:54 +0000
parents 769246a4eb41
children 7f619a5d6eb8
comparison
equal deleted inserted replaced
6701:522713337297 6702:df3bf0f971d1
67 #undef BUFFERTIME 67 #undef BUFFERTIME
68 #define SET_CHUNKSIZE 68 #define SET_CHUNKSIZE
69 69
70 snd_pcm_t * 70 snd_pcm_t *
71 71
72 spdif_init(int acard, int adevice) 72 spdif_init(char *pcm_name)
73 { 73 {
74 //char *pcm_name = "hw:0,2"; /* first card second device */ 74 //char *pcm_name = "hw:0,2"; /* first card second device */
75 char pcm_name[255];
76 static snd_aes_iec958_t spdif; 75 static snd_aes_iec958_t spdif;
77 snd_pcm_info_t *info; 76 snd_pcm_info_t *info;
78 snd_pcm_t *handler; 77 snd_pcm_t *handler;
79 snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE; 78 snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE;
80 unsigned int channels = 2; 79 unsigned int channels = 2;
81 unsigned int rate = 48000; 80 unsigned int rate = 48000;
82 int err, c; 81 int err, c;
83
84 if (err = snprintf(&pcm_name[0], 11, "hw:%1d,%1d", acard, adevice) <= 0)
85 {
86 return NULL;
87 }
88 82
89 if ((err = snd_pcm_open(&handler, pcm_name, SND_PCM_STREAM_PLAYBACK, 0)) < 0) 83 if ((err = snd_pcm_open(&handler, pcm_name, SND_PCM_STREAM_PLAYBACK, 0)) < 0)
90 { 84 {
91 fprintf(stderr, "open: %s\n", snd_strerror(err)); 85 fprintf(stderr, "open: %s\n", snd_strerror(err));
92 return NULL; 86 return NULL;
126 goto __diga_end; 120 goto __diga_end;
127 } 121 }
128 sprintf(ctl_name, "hw:%d", ctl_card); 122 sprintf(ctl_name, "hw:%d", ctl_card);
129 printf("hw:%d\n", ctl_card); 123 printf("hw:%d\n", ctl_card);
130 if ((err = snd_ctl_open(&ctl_handler, ctl_name, 0)) < 0) { 124 if ((err = snd_ctl_open(&ctl_handler, ctl_name, 0)) < 0) {
131 fprintf(stderr, "Unable to open the control interface '%s': %s", ctl_name, snd_strerror(err)); 125 fprintf(stderr, "Unable to open the control interface '%s': %s\n", ctl_name, snd_strerror(err));
132 goto __diga_end; 126 goto __diga_end;
133 } 127 }
134 if ((err = snd_ctl_elem_write(ctl_handler, ctl)) < 0) { 128 if ((err = snd_ctl_elem_write(ctl_handler, ctl)) < 0) {
135 fprintf(stderr, "Unable to update the IEC958 control: %s", snd_strerror(err)); 129 fprintf(stderr, "Unable to update the IEC958 control: %s\n", snd_strerror(err));
136 goto __diga_end; 130 goto __diga_end;
137 } 131 }
138 snd_ctl_close(ctl_handler); 132 snd_ctl_close(ctl_handler);
139 __diga_end: 133 __diga_end:
140 134
141 } 135 }
142 136
143 { 137 {
144 snd_pcm_hw_params_t *params; 138 snd_pcm_hw_params_t *params;
145 snd_pcm_sw_params_t *swparams; 139 snd_pcm_sw_params_t *swparams;
146 140
300 int err; 294 int err;
301 int cards = -1; 295 int cards = -1;
302 int period_val; 296 int period_val;
303 snd_pcm_info_t *alsa_info; 297 snd_pcm_info_t *alsa_info;
304 char *str_block_mode; 298 char *str_block_mode;
299 int device_set = 0;
305 300
306 printf("alsa-init: testing and bugreports are welcome.\n"); 301 printf("alsa-init: testing and bugreports are welcome.\n");
307 printf("alsa-init: requested format: %d Hz, %d channels, %s\n", rate_hz, 302 printf("alsa-init: requested format: %d Hz, %d channels, %s\n", rate_hz,
308 channels, audio_out_format_name(format)); 303 channels, audio_out_format_name(format));
309 304
400 } 395 }
401 else if (strcmp(*(token_str+i3), "noblock") == 0) { 396 else if (strcmp(*(token_str+i3), "noblock") == 0) {
402 ao_noblock = 1; 397 ao_noblock = 1;
403 } 398 }
404 else if (strcmp(*(token_str+i3), "hw") == 0) { 399 else if (strcmp(*(token_str+i3), "hw") == 0) {
400 if ((i3 < i2-1) && (strcmp(*(token_str+i3+1), "noblock") != 0) && (strcmp(*(token_str+i3+1), "mmap") != 0)) {
401 //printf("next tok = %s\n", *(token_str+(i3+1)));
402 alsa_device = alloca(ALSA_DEVICE_SIZE);
403 snprintf(alsa_device, ALSA_DEVICE_SIZE, "hw:%s", *(token_str+(i3+1)));
404 device_set = 1;
405 }
406 else {
407 //printf("setting hw\n");
408 alsa_device = *(token_str+i3);
409 device_set = 1;
410 }
411 }
412 else if (device_set == 0 && (!ao_mmap || !ao_noblock)) {
413 //printf("setting common, %s\n", *(token_str+i3));
405 alsa_device = *(token_str+i3); 414 alsa_device = *(token_str+i3);
406 } 415 device_set = 1;
407 else if (!alsa_device || !ao_mmap || !ao_noblock) {
408 alsa_device = *(token_str+i3);
409 } 416 }
410 } 417 }
411 } 418 }
412 } //end parsing ao_subdevice 419 } //end parsing ao_subdevice
413 420
446 { 453 {
447 printf("alsa-init: cant wrote device-id\n"); 454 printf("alsa-init: cant wrote device-id\n");
448 } 455 }
449 456
450 snd_pcm_info_free(alsa_info); 457 snd_pcm_info_free(alsa_info);
451 } 458 printf("alsa-init: %d soundcard%s found, using: %s\n", cards+1,
452 459 (cards >= 0) ? "" : "s", alsa_device);
453 printf("alsa-init: %d soundcard%s found, using: %s\n", cards+1, 460 } else if (strcmp(alsa_device, "help") == 0) {
454 (cards >= 0) ? "" : "s", alsa_device); 461 printf("alsa-help: available options are:\n");
455 462 printf(" mmap: sets mmap-mode\n");
463 printf(" noblock: sets noblock-mode\n");
464 printf(" device-name: sets device name\n");
465 printf(" example -ao alsa9:mmap:noblock:hw:0,3 sets noblock-mode,\n");
466 printf(" mmap-mode and the device-name as first card third device\n");
467 return(0);
468 } else {
469 printf("alsa-init: soundcard set to %s\n", alsa_device);
470 }
471
472 // switch for spdif
473 // Try to initialize the SPDIF interface
456 if (format == AFMT_AC3) { 474 if (format == AFMT_AC3) {
457 // Try to initialize the SPDIF interface 475 if (device_set)
458 alsa_handler = spdif_init(0, 2); 476 alsa_handler = spdif_init(alsa_device);
459 } 477 else
478 alsa_handler = spdif_init("hw:0,2");
479 }
460 480
461 //setting modes for block or nonblock-mode 481 //setting modes for block or nonblock-mode
462 if (ao_noblock) { 482 if (ao_noblock) {
463 open_mode = SND_PCM_NONBLOCK; 483 open_mode = SND_PCM_NONBLOCK;
464 set_block_mode = 1; 484 set_block_mode = 1;
468 open_mode = 0; 488 open_mode = 0;
469 set_block_mode = 0; 489 set_block_mode = 0;
470 str_block_mode = "block-mode"; 490 str_block_mode = "block-mode";
471 } 491 }
472 492
473
474 //modes = 0, SND_PCM_NONBLOCK, SND_PCM_ASYNC
475 if (!alsa_handler) { 493 if (!alsa_handler) {
494 //modes = 0, SND_PCM_NONBLOCK, SND_PCM_ASYNC
476 if ((err = snd_pcm_open(&alsa_handler, alsa_device, SND_PCM_STREAM_PLAYBACK, open_mode)) < 0) 495 if ((err = snd_pcm_open(&alsa_handler, alsa_device, SND_PCM_STREAM_PLAYBACK, open_mode)) < 0)
477 { 496 {
478 if (ao_noblock) { 497 if (ao_noblock) {
479 printf("alsa-init: open in nonblock-mode failed, trying to open in block-mode\n"); 498 printf("alsa-init: open in nonblock-mode failed, trying to open in block-mode\n");
480 if ((err = snd_pcm_open(&alsa_handler, alsa_device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) { 499 if ((err = snd_pcm_open(&alsa_handler, alsa_device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
487 } else { 506 } else {
488 printf("alsa-init: playback open error: %s\n", snd_strerror(err)); 507 printf("alsa-init: playback open error: %s\n", snd_strerror(err));
489 return(0); 508 return(0);
490 } 509 }
491 } 510 }
492 } 511
493 512 if ((err = snd_pcm_nonblock(alsa_handler, set_block_mode)) < 0) {
494 if ((err = snd_pcm_nonblock(alsa_handler, set_block_mode)) < 0) { 513 printf("alsa-init: error set block-mode %s\n", snd_strerror(err));
495 printf("alsa-init: error set block-mode %s\n", snd_strerror(err)); 514 }
496 } 515 else if (verbose) {
497 else if (verbose) { 516 printf("alsa-init: pcm opend in %s\n", str_block_mode);
498 printf("alsa-init: pcm opend in %s\n", str_block_mode); 517 }
499 } 518
500 519 snd_pcm_hw_params_alloca(&alsa_hwparams);
501 snd_pcm_hw_params_alloca(&alsa_hwparams); 520 snd_pcm_sw_params_alloca(&alsa_swparams);
502 snd_pcm_sw_params_alloca(&alsa_swparams); 521
503 522 // setting hw-parameters
504 // setting hw-parameters 523 if ((err = snd_pcm_hw_params_any(alsa_handler, alsa_hwparams)) < 0)
505 if ((err = snd_pcm_hw_params_any(alsa_handler, alsa_hwparams)) < 0) 524 {
506 { 525 printf("alsa-init: unable to get initial parameters: %s\n",
507 printf("alsa-init: unable to get initial parameters: %s\n", 526 snd_strerror(err));
508 snd_strerror(err)); 527 return(0);
509 return(0); 528 }
510 } 529
511 530 if (ao_mmap) {
512 if (ao_mmap) { 531 snd_pcm_access_mask_t *mask = alloca(snd_pcm_access_mask_sizeof());
513 snd_pcm_access_mask_t *mask = alloca(snd_pcm_access_mask_sizeof()); 532 snd_pcm_access_mask_none(mask);
514 snd_pcm_access_mask_none(mask); 533 snd_pcm_access_mask_set(mask, SND_PCM_ACCESS_MMAP_INTERLEAVED);
515 snd_pcm_access_mask_set(mask, SND_PCM_ACCESS_MMAP_INTERLEAVED); 534 snd_pcm_access_mask_set(mask, SND_PCM_ACCESS_MMAP_NONINTERLEAVED);
516 snd_pcm_access_mask_set(mask, SND_PCM_ACCESS_MMAP_NONINTERLEAVED); 535 snd_pcm_access_mask_set(mask, SND_PCM_ACCESS_MMAP_COMPLEX);
517 snd_pcm_access_mask_set(mask, SND_PCM_ACCESS_MMAP_COMPLEX); 536 err = snd_pcm_hw_params_set_access_mask(alsa_handler, alsa_hwparams, mask);
518 err = snd_pcm_hw_params_set_access_mask(alsa_handler, alsa_hwparams, mask); 537 printf("alsa-init: mmap set\n");
519 printf("alsa-init: mmap set\n"); 538 } else {
520 } else { 539 err = snd_pcm_hw_params_set_access(alsa_handler, alsa_hwparams,SND_PCM_ACCESS_RW_INTERLEAVED);
521 err = snd_pcm_hw_params_set_access(alsa_handler, alsa_hwparams,SND_PCM_ACCESS_RW_INTERLEAVED); 540 printf("alsa-init: interleave set\n");
522 printf("alsa-init: interleave set\n"); 541 }
523 } 542 if (err < 0) {
524 if (err < 0) { 543 printf("alsa-init: unable to set access type: %s\n", snd_strerror(err));
525 printf("alsa-init: unable to set access type: %s\n", snd_strerror(err)); 544 return (0);
526 return (0); 545 }
527 } 546
528 547 if ((err = snd_pcm_hw_params_set_format(alsa_handler, alsa_hwparams,
529 if ((err = snd_pcm_hw_params_set_format(alsa_handler, alsa_hwparams, 548 alsa_format)) < 0)
530 alsa_format)) < 0) 549 {
531 { 550 printf("alsa-init: unable to set format: %s\n",
532 printf("alsa-init: unable to set format: %s\n", 551 snd_strerror(err));
533 snd_strerror(err)); 552 return(0);
534 return(0); 553 }
535 } 554
536 555 if ((err = snd_pcm_hw_params_set_channels(alsa_handler, alsa_hwparams,
537 if ((err = snd_pcm_hw_params_set_channels(alsa_handler, alsa_hwparams, 556 ao_data.channels)) < 0)
538 ao_data.channels)) < 0) 557 {
539 { 558 printf("alsa-init: unable to set channels: %s\n",
540 printf("alsa-init: unable to set channels: %s\n", 559 snd_strerror(err));
541 snd_strerror(err)); 560 return(0);
542 return(0); 561 }
543 } 562
544 563 if ((err = snd_pcm_hw_params_set_rate_near(alsa_handler, alsa_hwparams, ao_data.samplerate, 0)) < 0)
545 if ((err = snd_pcm_hw_params_set_rate_near(alsa_handler, alsa_hwparams, ao_data.samplerate, 0)) < 0)
546 { 564 {
547 printf("alsa-init: unable to set samplerate-2: %s\n", 565 printf("alsa-init: unable to set samplerate-2: %s\n",
548 snd_strerror(err)); 566 snd_strerror(err));
549 return(0); 567 return(0);
550 } 568 }
551 569
552 #ifdef BUFFERTIME 570 #ifdef BUFFERTIME
553 { 571 {
554 int alsa_buffer_time = 500000; /* original 60 */ 572 int alsa_buffer_time = 500000; /* original 60 */
555 573
556 if ((err = snd_pcm_hw_params_set_buffer_time_near(alsa_handler, alsa_hwparams, alsa_buffer_time, 0)) < 0) 574 if ((err = snd_pcm_hw_params_set_buffer_time_near(alsa_handler, alsa_hwparams, alsa_buffer_time, 0)) < 0)
557 { 575 {
558 printf("alsa-init: unable to set buffer time near: %s\n", 576 printf("alsa-init: unable to set buffer time near: %s\n",
559 snd_strerror(err)); 577 snd_strerror(err));
560 return(0); 578 return(0);
561 } else 579 } else
562 alsa_buffer_time = err; 580 alsa_buffer_time = err;
563 581
564 if ((err = snd_pcm_hw_params_set_period_time_near(alsa_handler, alsa_hwparams, alsa_buffer_time/4, 0)) < 0) 582 if ((err = snd_pcm_hw_params_set_period_time_near(alsa_handler, alsa_hwparams, alsa_buffer_time/4, 0)) < 0)
565 /* original: alsa_buffer_time/ao_data.bps */ 583 /* original: alsa_buffer_time/ao_data.bps */
566 { 584 {
567 printf("alsa-init: unable to set period time: %s\n", 585 printf("alsa-init: unable to set period time: %s\n",
568 snd_strerror(err)); 586 snd_strerror(err));
569 return(0); 587 return(0);
570 } 588 }
571 if (verbose) 589 if (verbose)
572 printf("alsa-init: buffer_time: %d, period_time :%d\n",alsa_buffer_time, err); 590 printf("alsa-init: buffer_time: %d, period_time :%d\n",alsa_buffer_time, err);
573 } 591 }
574 #endif 592 #endif
575 593
576 #ifdef SET_CHUNKSIZE 594 #ifdef SET_CHUNKSIZE
577 {
578 //set chunksize
579 chunk_size = alsa_fragsize / 4;
580
581 if ((err = snd_pcm_hw_params_set_period_size(alsa_handler, alsa_hwparams, chunk_size, 0)) < 0)
582 { 595 {
583 printf("alsa-init: unable to set periodsize: %s\n", snd_strerror(err)); 596 //set chunksize
584 return(0); 597 chunk_size = alsa_fragsize / 4;
585 } 598
586 else if (verbose) { 599 if ((err = snd_pcm_hw_params_set_period_size(alsa_handler, alsa_hwparams, chunk_size, 0)) < 0)
587 printf("alsa-init: chunksize set to %i\n", chunk_size); 600 {
588 } 601 printf("alsa-init: unable to set periodsize: %s\n", snd_strerror(err));
589 602 return(0);
590 //set period_count 603 }
591 if ((period_val = snd_pcm_hw_params_get_periods_max(alsa_hwparams, 0)) < alsa_fragcount) { 604 else if (verbose) {
592 alsa_fragcount = period_val; 605 printf("alsa-init: chunksize set to %i\n", chunk_size);
593 } 606 }
594 607
595 if (verbose) 608 //set period_count
596 printf("alsa-init: current val=%i, fragcount=%i\n", period_val, alsa_fragcount); 609 if ((period_val = snd_pcm_hw_params_get_periods_max(alsa_hwparams, 0)) < alsa_fragcount) {
597 610 alsa_fragcount = period_val;
598 if ((err = snd_pcm_hw_params_set_periods(alsa_handler, alsa_hwparams, alsa_fragcount, 0)) < 0) { 611 }
599 printf("alsa-init: unable to set periods: %s\n", snd_strerror(err)); 612
600 } 613 if (verbose)
601 } 614 printf("alsa-init: current val=%i, fragcount=%i\n", period_val, alsa_fragcount);
615
616 if ((err = snd_pcm_hw_params_set_periods(alsa_handler, alsa_hwparams, alsa_fragcount, 0)) < 0) {
617 printf("alsa-init: unable to set periods: %s\n", snd_strerror(err));
618 }
619 }
602 #endif 620 #endif
603 621
604 /* finally install hardware parameters */ 622 /* finally install hardware parameters */
605 if ((err = snd_pcm_hw_params(alsa_handler, alsa_hwparams)) < 0) 623 if ((err = snd_pcm_hw_params(alsa_handler, alsa_hwparams)) < 0)
606 { 624 {
607 printf("alsa-init: unable to set hw-parameters: %s\n", 625 printf("alsa-init: unable to set hw-parameters: %s\n",
608 snd_strerror(err)); 626 snd_strerror(err));
609 return(0); 627 return(0);
610 } 628 }
611 // end setting hw-params 629 // end setting hw-params
612 630
613 631
614 // gets buffersize for control 632 // gets buffersize for control
615 if ((err = snd_pcm_hw_params_get_buffer_size(alsa_hwparams)) < 0) 633 if ((err = snd_pcm_hw_params_get_buffer_size(alsa_hwparams)) < 0)
616 { 634 {
617 printf("alsa-init: unable to get buffersize: %s\n", snd_strerror(err)); 635 printf("alsa-init: unable to get buffersize: %s\n", snd_strerror(err));
618 return(0); 636 return(0);
619 } 637 }
620 else { 638 else {
621 ao_data.buffersize = err; 639 ao_data.buffersize = err;
622 if (verbose) 640 if (verbose)
623 printf("alsa-init: got buffersize=%i\n", ao_data.buffersize); 641 printf("alsa-init: got buffersize=%i\n", ao_data.buffersize);
624 } 642 }
625 643
626 // setting sw-params (only avail-min) if noblocking mode was choosed 644 // setting sw-params (only avail-min) if noblocking mode was choosed
627 if (ao_noblock) 645 if (ao_noblock)
628 { 646 {
629 647
630 if ((err = snd_pcm_sw_params_current(alsa_handler, alsa_swparams)) < 0) 648 if ((err = snd_pcm_sw_params_current(alsa_handler, alsa_swparams)) < 0)
631 { 649 {
632 printf("alsa-init: unable to get parameters: %s\n",snd_strerror(err)); 650 printf("alsa-init: unable to get parameters: %s\n",snd_strerror(err));
633 return(0); 651 return(0);
634 } 652 }
635 653
636 //set min available frames to consider pcm ready (4) 654 //set min available frames to consider pcm ready (4)
637 //increased for nonblock-mode should be set dynamically later 655 //increased for nonblock-mode should be set dynamically later
638 if ((err = snd_pcm_sw_params_set_avail_min(alsa_handler, alsa_swparams, chunk_size)) < 0) 656 if ((err = snd_pcm_sw_params_set_avail_min(alsa_handler, alsa_swparams, chunk_size)) < 0)
639 { 657 {
640 printf("alsa-init: unable to set avail_min %s\n",snd_strerror(err)); 658 printf("alsa-init: unable to set avail_min %s\n",snd_strerror(err));
641 return(0); 659 return(0);
642 } 660 }
643 661
644 if ((err = snd_pcm_sw_params(alsa_handler, alsa_swparams)) < 0) 662 if ((err = snd_pcm_sw_params(alsa_handler, alsa_swparams)) < 0)
645 { 663 {
646 printf("alsa-init: unable to install sw-params\n"); 664 printf("alsa-init: unable to install sw-params\n");
647 return(0); 665 return(0);
648 } 666 }
649 667
650 bits_per_sample = snd_pcm_format_physical_width(alsa_format); 668 bits_per_sample = snd_pcm_format_physical_width(alsa_format);
651 bits_per_frame = bits_per_sample * channels; 669 bits_per_frame = bits_per_sample * channels;
652 chunk_bytes = chunk_size * bits_per_frame / 8; 670 chunk_bytes = chunk_size * bits_per_frame / 8;
653 671
654 if (verbose) { 672 if (verbose) {
655 printf("alsa-init: bits per sample (bps)=%i, bits per frame (bpf)=%i, chunk_bytes=%i\n",bits_per_sample,bits_per_frame,chunk_bytes);} 673 printf("alsa-init: bits per sample (bps)=%i, bits per frame (bpf)=%i, chunk_bytes=%i\n",bits_per_sample,bits_per_frame,chunk_bytes);}
656 674
657 }//end swparams 675 }//end swparams
658 676
659 if ((err = snd_pcm_prepare(alsa_handler)) < 0) 677 if ((err = snd_pcm_prepare(alsa_handler)) < 0)
660 { 678 {
661 printf("alsa-init: pcm prepare error: %s\n", snd_strerror(err)); 679 printf("alsa-init: pcm prepare error: %s\n", snd_strerror(err));
662 return(0); 680 return(0);
663 } 681 }
664 682
665 printf("alsa9: %d Hz/%d channels/%d bpf/%d bytes buffer/%s\n", 683 printf("alsa9: %d Hz/%d channels/%d bpf/%d bytes buffer/%s\n",
666 ao_data.samplerate, ao_data.channels, ao_data.bps, ao_data.buffersize, 684 ao_data.samplerate, ao_data.channels, ao_data.bps, ao_data.buffersize,
667 snd_pcm_format_description(alsa_format)); 685 snd_pcm_format_description(alsa_format));
686
687 } // end switch alsa_handler (spdif)
668 return(1); 688 return(1);
669 } // end init 689 } // end init
670 690
671 691
672 /* close audio device */ 692 /* close audio device */