Commit 571ec3d68ddfa230f1c60eba1f7e24f5a3ffb03b

Authored by bellard
1 parent 5e941d4b

audio merge (malc)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1636 c046a42c-6fe2-441c-8c8c-71466251a162
audio/alsaaudio.c
@@ -31,15 +31,12 @@ typedef struct ALSAVoiceOut { @@ -31,15 +31,12 @@ typedef struct ALSAVoiceOut {
31 HWVoiceOut hw; 31 HWVoiceOut hw;
32 void *pcm_buf; 32 void *pcm_buf;
33 snd_pcm_t *handle; 33 snd_pcm_t *handle;
34 - int can_pause;  
35 - int was_enabled;  
36 } ALSAVoiceOut; 34 } ALSAVoiceOut;
37 35
38 typedef struct ALSAVoiceIn { 36 typedef struct ALSAVoiceIn {
39 HWVoiceIn hw; 37 HWVoiceIn hw;
40 snd_pcm_t *handle; 38 snd_pcm_t *handle;
41 void *pcm_buf; 39 void *pcm_buf;
42 - int can_pause;  
43 } ALSAVoiceIn; 40 } ALSAVoiceIn;
44 41
45 static struct { 42 static struct {
@@ -58,6 +55,7 @@ static struct { @@ -58,6 +55,7 @@ static struct {
58 55
59 int buffer_size_out_overriden; 56 int buffer_size_out_overriden;
60 int period_size_out_overriden; 57 int period_size_out_overriden;
  58 + int verbose;
61 } conf = { 59 } conf = {
62 #ifdef HIGH_LATENCY 60 #ifdef HIGH_LATENCY
63 .size_in_usec_in = 1, 61 .size_in_usec_in = 1,
@@ -73,8 +71,8 @@ static struct { @@ -73,8 +71,8 @@ static struct {
73 #else 71 #else
74 #define DEFAULT_BUFFER_SIZE 1024 72 #define DEFAULT_BUFFER_SIZE 1024
75 #define DEFAULT_PERIOD_SIZE 256 73 #define DEFAULT_PERIOD_SIZE 256
76 - .buffer_size_in = DEFAULT_BUFFER_SIZE,  
77 - .period_size_in = DEFAULT_PERIOD_SIZE, 74 + .buffer_size_in = DEFAULT_BUFFER_SIZE * 4,
  75 + .period_size_in = DEFAULT_PERIOD_SIZE * 4,
78 .buffer_size_out = DEFAULT_BUFFER_SIZE, 76 .buffer_size_out = DEFAULT_BUFFER_SIZE,
79 .period_size_out = DEFAULT_PERIOD_SIZE, 77 .period_size_out = DEFAULT_PERIOD_SIZE,
80 .buffer_size_in_overriden = 0, 78 .buffer_size_in_overriden = 0,
@@ -82,7 +80,8 @@ static struct { @@ -82,7 +80,8 @@ static struct {
82 .period_size_in_overriden = 0, 80 .period_size_in_overriden = 0,
83 .period_size_out_overriden = 0, 81 .period_size_out_overriden = 0,
84 #endif 82 #endif
85 - .threshold = 0 83 + .threshold = 0,
  84 + .verbose = 0
86 }; 85 };
87 86
88 struct alsa_params_req { 87 struct alsa_params_req {
@@ -97,7 +96,6 @@ struct alsa_params_obt { @@ -97,7 +96,6 @@ struct alsa_params_obt {
97 int freq; 96 int freq;
98 audfmt_e fmt; 97 audfmt_e fmt;
99 int nchannels; 98 int nchannels;
100 - int can_pause;  
101 snd_pcm_uframes_t samples; 99 snd_pcm_uframes_t samples;
102 }; 100 };
103 101
@@ -474,12 +472,6 @@ static int alsa_open (int in, struct alsa_params_req *req, @@ -474,12 +472,6 @@ static int alsa_open (int in, struct alsa_params_req *req,
474 goto err; 472 goto err;
475 } 473 }
476 474
477 - obt->can_pause = snd_pcm_hw_params_can_pause (hw_params);  
478 - if (obt->can_pause < 0) {  
479 - alsa_logerr (err, "Could not get pause capability for %s\n", typ);  
480 - obt->can_pause = 0;  
481 - }  
482 -  
483 if (!in && conf.threshold) { 475 if (!in && conf.threshold) {
484 snd_pcm_uframes_t threshold; 476 snd_pcm_uframes_t threshold;
485 int bytes_per_sec; 477 int bytes_per_sec;
@@ -527,6 +519,28 @@ static int alsa_recover (snd_pcm_t *handle) @@ -527,6 +519,28 @@ static int alsa_recover (snd_pcm_t *handle)
527 return 0; 519 return 0;
528 } 520 }
529 521
  522 +static snd_pcm_sframes_t alsa_get_avail (snd_pcm_t *handle)
  523 +{
  524 + snd_pcm_sframes_t avail;
  525 +
  526 + avail = snd_pcm_avail_update (handle);
  527 + if (avail < 0) {
  528 + if (avail == -EPIPE) {
  529 + if (!alsa_recover (handle)) {
  530 + avail = snd_pcm_avail_update (handle);
  531 + }
  532 + }
  533 +
  534 + if (avail < 0) {
  535 + alsa_logerr (avail,
  536 + "Could not obtain number of available frames\n");
  537 + return -1;
  538 + }
  539 + }
  540 +
  541 + return avail;
  542 +}
  543 +
530 static int alsa_run_out (HWVoiceOut *hw) 544 static int alsa_run_out (HWVoiceOut *hw)
531 { 545 {
532 ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw; 546 ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
@@ -541,57 +555,53 @@ static int alsa_run_out (HWVoiceOut *hw) @@ -541,57 +555,53 @@ static int alsa_run_out (HWVoiceOut *hw)
541 return 0; 555 return 0;
542 } 556 }
543 557
544 - avail = snd_pcm_avail_update (alsa->handle); 558 + avail = alsa_get_avail (alsa->handle);
545 if (avail < 0) { 559 if (avail < 0) {
546 - if (avail == -EPIPE) {  
547 - if (!alsa_recover (alsa->handle)) {  
548 - avail = snd_pcm_avail_update (alsa->handle);  
549 - if (avail >= 0) {  
550 - goto ok;  
551 - }  
552 - }  
553 - }  
554 -  
555 - alsa_logerr (avail, "Could not get amount free space\n"); 560 + dolog ("Could not get number of available playback frames\n");
556 return 0; 561 return 0;
557 } 562 }
558 563
559 - ok:  
560 decr = audio_MIN (live, avail); 564 decr = audio_MIN (live, avail);
561 samples = decr; 565 samples = decr;
562 rpos = hw->rpos; 566 rpos = hw->rpos;
563 while (samples) { 567 while (samples) {
564 int left_till_end_samples = hw->samples - rpos; 568 int left_till_end_samples = hw->samples - rpos;
565 - int convert_samples = audio_MIN (samples, left_till_end_samples); 569 + int len = audio_MIN (samples, left_till_end_samples);
566 snd_pcm_sframes_t written; 570 snd_pcm_sframes_t written;
567 571
568 src = hw->mix_buf + rpos; 572 src = hw->mix_buf + rpos;
569 dst = advance (alsa->pcm_buf, rpos << hw->info.shift); 573 dst = advance (alsa->pcm_buf, rpos << hw->info.shift);
570 574
571 - hw->clip (dst, src, convert_samples); 575 + hw->clip (dst, src, len);
572 576
573 - while (convert_samples) {  
574 - written = snd_pcm_writei (alsa->handle, dst, convert_samples); 577 + while (len) {
  578 + written = snd_pcm_writei (alsa->handle, dst, len);
575 579
576 - if (written < 0) { 580 + if (written <= 0) {
577 switch (written) { 581 switch (written) {
578 - case -EPIPE:  
579 - if (!alsa_recover (alsa->handle)) {  
580 - continue; 582 + case 0:
  583 + if (conf.verbose) {
  584 + dolog ("Failed to write %d frames (wrote zero)\n", len);
581 } 585 }
582 - dolog ("Failed to write %d frames to %p, "  
583 - "handle %p not prepared\n",  
584 - convert_samples,  
585 - dst,  
586 - alsa->handle);  
587 goto exit; 586 goto exit;
588 587
589 - case -EAGAIN: 588 + case -EPIPE:
  589 + if (alsa_recover (alsa->handle)) {
  590 + alsa_logerr (written, "Failed to write %d frames\n",
  591 + len);
  592 + goto exit;
  593 + }
  594 + if (conf.verbose) {
  595 + dolog ("Recovering from playback xrun\n");
  596 + }
590 continue; 597 continue;
591 598
  599 + case -EAGAIN:
  600 + goto exit;
  601 +
592 default: 602 default:
593 alsa_logerr (written, "Failed to write %d frames to %p\n", 603 alsa_logerr (written, "Failed to write %d frames to %p\n",
594 - convert_samples, dst); 604 + len, dst);
595 goto exit; 605 goto exit;
596 } 606 }
597 } 607 }
@@ -599,7 +609,7 @@ static int alsa_run_out (HWVoiceOut *hw) @@ -599,7 +609,7 @@ static int alsa_run_out (HWVoiceOut *hw)
599 mixeng_clear (src, written); 609 mixeng_clear (src, written);
600 rpos = (rpos + written) % hw->samples; 610 rpos = (rpos + written) % hw->samples;
601 samples -= written; 611 samples -= written;
602 - convert_samples -= written; 612 + len -= written;
603 dst = advance (dst, written << hw->info.shift); 613 dst = advance (dst, written << hw->info.shift);
604 src += written; 614 src += written;
605 } 615 }
@@ -659,7 +669,6 @@ static int alsa_init_out (HWVoiceOut *hw, audsettings_t *as) @@ -659,7 +669,6 @@ static int alsa_init_out (HWVoiceOut *hw, audsettings_t *as)
659 &obt_as, 669 &obt_as,
660 audio_need_to_swap_endian (endianness) 670 audio_need_to_swap_endian (endianness)
661 ); 671 );
662 - alsa->can_pause = obt.can_pause;  
663 hw->samples = obt.samples; 672 hw->samples = obt.samples;
664 673
665 alsa->pcm_buf = audio_calloc (AUDIO_FUNC, obt.samples, 1 << hw->info.shift); 674 alsa->pcm_buf = audio_calloc (AUDIO_FUNC, obt.samples, 1 << hw->info.shift);
@@ -671,46 +680,46 @@ static int alsa_init_out (HWVoiceOut *hw, audsettings_t *as) @@ -671,46 +680,46 @@ static int alsa_init_out (HWVoiceOut *hw, audsettings_t *as)
671 } 680 }
672 681
673 alsa->handle = handle; 682 alsa->handle = handle;
674 - alsa->was_enabled = 0;  
675 return 0; 683 return 0;
676 } 684 }
677 685
678 -static int alsa_ctl_out (HWVoiceOut *hw, int cmd, ...) 686 +static int alsa_voice_ctl (snd_pcm_t *handle, const char *typ, int pause)
679 { 687 {
680 int err; 688 int err;
  689 +
  690 + if (pause) {
  691 + err = snd_pcm_drop (handle);
  692 + if (err < 0) {
  693 + alsa_logerr (err, "Could not stop %s", typ);
  694 + return -1;
  695 + }
  696 + }
  697 + else {
  698 + err = snd_pcm_prepare (handle);
  699 + if (err < 0) {
  700 + alsa_logerr (err, "Could not prepare handle for %s", typ);
  701 + return -1;
  702 + }
  703 + }
  704 +
  705 + return 0;
  706 +}
  707 +
  708 +static int alsa_ctl_out (HWVoiceOut *hw, int cmd, ...)
  709 +{
681 ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw; 710 ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
682 711
683 switch (cmd) { 712 switch (cmd) {
684 case VOICE_ENABLE: 713 case VOICE_ENABLE:
685 ldebug ("enabling voice\n"); 714 ldebug ("enabling voice\n");
686 - audio_pcm_info_clear_buf (&hw->info, alsa->pcm_buf, hw->samples);  
687 - if (alsa->can_pause) {  
688 - /* Why this was_enabled madness is needed at all?? */  
689 - if (alsa->was_enabled) {  
690 - err = snd_pcm_pause (alsa->handle, 0);  
691 - if (err < 0) {  
692 - alsa_logerr (err, "Failed to resume playing\n");  
693 - /* not fatal really */  
694 - }  
695 - }  
696 - else {  
697 - alsa->was_enabled = 1;  
698 - }  
699 - }  
700 - break; 715 + return alsa_voice_ctl (alsa->handle, "playback", 0);
701 716
702 case VOICE_DISABLE: 717 case VOICE_DISABLE:
703 ldebug ("disabling voice\n"); 718 ldebug ("disabling voice\n");
704 - if (alsa->can_pause) {  
705 - err = snd_pcm_pause (alsa->handle, 1);  
706 - if (err < 0) {  
707 - alsa_logerr (err, "Failed to stop playing\n");  
708 - /* not fatal really */  
709 - }  
710 - }  
711 - break; 719 + return alsa_voice_ctl (alsa->handle, "playback", 1);
712 } 720 }
713 - return 0; 721 +
  722 + return -1;
714 } 723 }
715 724
716 static int alsa_init_in (HWVoiceIn *hw, audsettings_t *as) 725 static int alsa_init_in (HWVoiceIn *hw, audsettings_t *as)
@@ -749,7 +758,6 @@ static int alsa_init_in (HWVoiceIn *hw, audsettings_t *as) @@ -749,7 +758,6 @@ static int alsa_init_in (HWVoiceIn *hw, audsettings_t *as)
749 &obt_as, 758 &obt_as,
750 audio_need_to_swap_endian (endianness) 759 audio_need_to_swap_endian (endianness)
751 ); 760 );
752 - alsa->can_pause = obt.can_pause;  
753 hw->samples = obt.samples; 761 hw->samples = obt.samples;
754 762
755 alsa->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift); 763 alsa->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
@@ -783,6 +791,7 @@ static int alsa_run_in (HWVoiceIn *hw) @@ -783,6 +791,7 @@ static int alsa_run_in (HWVoiceIn *hw)
783 int i; 791 int i;
784 int live = audio_pcm_hw_get_live_in (hw); 792 int live = audio_pcm_hw_get_live_in (hw);
785 int dead = hw->samples - live; 793 int dead = hw->samples - live;
  794 + int decr;
786 struct { 795 struct {
787 int add; 796 int add;
788 int len; 797 int len;
@@ -790,22 +799,36 @@ static int alsa_run_in (HWVoiceIn *hw) @@ -790,22 +799,36 @@ static int alsa_run_in (HWVoiceIn *hw)
790 { hw->wpos, 0 }, 799 { hw->wpos, 0 },
791 { 0, 0 } 800 { 0, 0 }
792 }; 801 };
793 - 802 + snd_pcm_sframes_t avail;
794 snd_pcm_uframes_t read_samples = 0; 803 snd_pcm_uframes_t read_samples = 0;
795 804
796 if (!dead) { 805 if (!dead) {
797 return 0; 806 return 0;
798 } 807 }
799 808
800 - if (hw->wpos + dead > hw->samples) { 809 + avail = alsa_get_avail (alsa->handle);
  810 + if (avail < 0) {
  811 + dolog ("Could not get number of captured frames\n");
  812 + return 0;
  813 + }
  814 +
  815 + if (!avail && (snd_pcm_state (alsa->handle) == SND_PCM_STATE_PREPARED)) {
  816 + avail = hw->samples;
  817 + }
  818 +
  819 + decr = audio_MIN (dead, avail);
  820 + if (!decr) {
  821 + return 0;
  822 + }
  823 +
  824 + if (hw->wpos + decr > hw->samples) {
801 bufs[0].len = (hw->samples - hw->wpos); 825 bufs[0].len = (hw->samples - hw->wpos);
802 - bufs[1].len = (dead - (hw->samples - hw->wpos)); 826 + bufs[1].len = (decr - (hw->samples - hw->wpos));
803 } 827 }
804 else { 828 else {
805 - bufs[0].len = dead; 829 + bufs[0].len = decr;
806 } 830 }
807 831
808 -  
809 for (i = 0; i < 2; ++i) { 832 for (i = 0; i < 2; ++i) {
810 void *src; 833 void *src;
811 st_sample_t *dst; 834 st_sample_t *dst;
@@ -820,24 +843,27 @@ static int alsa_run_in (HWVoiceIn *hw) @@ -820,24 +843,27 @@ static int alsa_run_in (HWVoiceIn *hw)
820 while (len) { 843 while (len) {
821 nread = snd_pcm_readi (alsa->handle, src, len); 844 nread = snd_pcm_readi (alsa->handle, src, len);
822 845
823 - if (nread < 0) { 846 + if (nread <= 0) {
824 switch (nread) { 847 switch (nread) {
825 - case -EPIPE:  
826 - if (!alsa_recover (alsa->handle)) {  
827 - continue; 848 + case 0:
  849 + if (conf.verbose) {
  850 + dolog ("Failed to read %ld frames (read zero)\n", len);
828 } 851 }
829 - dolog (  
830 - "Failed to read %ld frames from %p, "  
831 - "handle %p not prepared\n",  
832 - len,  
833 - src,  
834 - alsa->handle  
835 - );  
836 goto exit; 852 goto exit;
837 853
838 - case -EAGAIN: 854 + case -EPIPE:
  855 + if (alsa_recover (alsa->handle)) {
  856 + alsa_logerr (nread, "Failed to read %ld frames\n", len);
  857 + goto exit;
  858 + }
  859 + if (conf.verbose) {
  860 + dolog ("Recovering from capture xrun\n");
  861 + }
839 continue; 862 continue;
840 863
  864 + case -EAGAIN:
  865 + goto exit;
  866 +
841 default: 867 default:
842 alsa_logerr ( 868 alsa_logerr (
843 nread, 869 nread,
@@ -871,9 +897,19 @@ static int alsa_read (SWVoiceIn *sw, void *buf, int size) @@ -871,9 +897,19 @@ static int alsa_read (SWVoiceIn *sw, void *buf, int size)
871 897
872 static int alsa_ctl_in (HWVoiceIn *hw, int cmd, ...) 898 static int alsa_ctl_in (HWVoiceIn *hw, int cmd, ...)
873 { 899 {
874 - (void) hw;  
875 - (void) cmd;  
876 - return 0; 900 + ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
  901 +
  902 + switch (cmd) {
  903 + case VOICE_ENABLE:
  904 + ldebug ("enabling voice\n");
  905 + return alsa_voice_ctl (alsa->handle, "capture", 0);
  906 +
  907 + case VOICE_DISABLE:
  908 + ldebug ("disabling voice\n");
  909 + return alsa_voice_ctl (alsa->handle, "capture", 1);
  910 + }
  911 +
  912 + return -1;
877 } 913 }
878 914
879 static void *alsa_audio_init (void) 915 static void *alsa_audio_init (void)
@@ -909,6 +945,10 @@ static struct audio_option alsa_options[] = { @@ -909,6 +945,10 @@ static struct audio_option alsa_options[] = {
909 945
910 {"ADC_DEV", AUD_OPT_STR, &conf.pcm_name_in, 946 {"ADC_DEV", AUD_OPT_STR, &conf.pcm_name_in,
911 "ADC device name", NULL, 0}, 947 "ADC device name", NULL, 0},
  948 +
  949 + {"VERBOSE", AUD_OPT_BOOL, &conf.verbose,
  950 + "Behave in a more verbose way", NULL, 0},
  951 +
912 {NULL, 0, NULL, NULL, NULL, 0} 952 {NULL, 0, NULL, NULL, NULL, 0}
913 }; 953 };
914 954
audio/audio.c
@@ -96,7 +96,7 @@ static struct { @@ -96,7 +96,7 @@ static struct {
96 96
97 { 0 }, /* period */ 97 { 0 }, /* period */
98 0, /* plive */ 98 0, /* plive */
99 - 0 99 + 0 /* log_to_monitor */
100 }; 100 };
101 101
102 static AudioState glob_audio_state; 102 static AudioState glob_audio_state;
@@ -623,25 +623,6 @@ void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len) @@ -623,25 +623,6 @@ void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len)
623 /* 623 /*
624 * Hard voice (capture) 624 * Hard voice (capture)
625 */ 625 */
626 -static void audio_pcm_hw_free_resources_in (HWVoiceIn *hw)  
627 -{  
628 - if (hw->conv_buf) {  
629 - qemu_free (hw->conv_buf);  
630 - }  
631 - hw->conv_buf = NULL;  
632 -}  
633 -  
634 -static int audio_pcm_hw_alloc_resources_in (HWVoiceIn *hw)  
635 -{  
636 - hw->conv_buf = audio_calloc (AUDIO_FUNC, hw->samples, sizeof (st_sample_t));  
637 - if (!hw->conv_buf) {  
638 - dolog ("Could not allocate ADC conversion buffer (%d samples)\n",  
639 - hw->samples);  
640 - return -1;  
641 - }  
642 - return 0;  
643 -}  
644 -  
645 static int audio_pcm_hw_find_min_in (HWVoiceIn *hw) 626 static int audio_pcm_hw_find_min_in (HWVoiceIn *hw)
646 { 627 {
647 SWVoiceIn *sw; 628 SWVoiceIn *sw;
@@ -668,64 +649,6 @@ int audio_pcm_hw_get_live_in (HWVoiceIn *hw) @@ -668,64 +649,6 @@ int audio_pcm_hw_get_live_in (HWVoiceIn *hw)
668 /* 649 /*
669 * Soft voice (capture) 650 * Soft voice (capture)
670 */ 651 */
671 -static void audio_pcm_sw_free_resources_in (SWVoiceIn *sw)  
672 -{  
673 - if (sw->conv_buf) {  
674 - qemu_free (sw->conv_buf);  
675 - }  
676 -  
677 - if (sw->rate) {  
678 - st_rate_stop (sw->rate);  
679 - }  
680 -  
681 - sw->conv_buf = NULL;  
682 - sw->rate = NULL;  
683 -}  
684 -  
685 -static int audio_pcm_sw_alloc_resources_in (SWVoiceIn *sw)  
686 -{  
687 - int samples = ((int64_t) sw->hw->samples << 32) / sw->ratio;  
688 - sw->conv_buf = audio_calloc (AUDIO_FUNC, samples, sizeof (st_sample_t));  
689 - if (!sw->conv_buf) {  
690 - dolog ("Could not allocate buffer for `%s' (%d samples)\n",  
691 - SW_NAME (sw), samples);  
692 - return -1;  
693 - }  
694 -  
695 - sw->rate = st_rate_start (sw->hw->info.freq, sw->info.freq);  
696 - if (!sw->rate) {  
697 - qemu_free (sw->conv_buf);  
698 - sw->conv_buf = NULL;  
699 - return -1;  
700 - }  
701 - return 0;  
702 -}  
703 -  
704 -static int audio_pcm_sw_init_in (  
705 - SWVoiceIn *sw,  
706 - HWVoiceIn *hw,  
707 - const char *name,  
708 - audsettings_t *as  
709 - )  
710 -{  
711 - /* None of the cards emulated by QEMU are big-endian  
712 - hence following shortcut */  
713 - audio_pcm_init_info (&sw->info, as, audio_need_to_swap_endian (0));  
714 - sw->hw = hw;  
715 - sw->ratio = ((int64_t) sw->info.freq << 32) / sw->hw->info.freq;  
716 -  
717 - sw->clip =  
718 - mixeng_clip  
719 - [sw->info.nchannels == 2]  
720 - [sw->info.sign]  
721 - [sw->info.swap_endian]  
722 - [sw->info.bits == 16];  
723 -  
724 - sw->name = qemu_strdup (name);  
725 - audio_pcm_sw_free_resources_in (sw);  
726 - return audio_pcm_sw_alloc_resources_in (sw);  
727 -}  
728 -  
729 static int audio_pcm_sw_get_rpos_in (SWVoiceIn *sw) 652 static int audio_pcm_sw_get_rpos_in (SWVoiceIn *sw)
730 { 653 {
731 HWVoiceIn *hw = sw->hw; 654 HWVoiceIn *hw = sw->hw;
@@ -750,7 +673,7 @@ int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int size) @@ -750,7 +673,7 @@ int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int size)
750 { 673 {
751 HWVoiceIn *hw = sw->hw; 674 HWVoiceIn *hw = sw->hw;
752 int samples, live, ret = 0, swlim, isamp, osamp, rpos, total = 0; 675 int samples, live, ret = 0, swlim, isamp, osamp, rpos, total = 0;
753 - st_sample_t *src, *dst = sw->conv_buf; 676 + st_sample_t *src, *dst = sw->buf;
754 677
755 rpos = audio_pcm_sw_get_rpos_in (sw) % hw->samples; 678 rpos = audio_pcm_sw_get_rpos_in (sw) % hw->samples;
756 679
@@ -794,7 +717,7 @@ int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int size) @@ -794,7 +717,7 @@ int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int size)
794 total += isamp; 717 total += isamp;
795 } 718 }
796 719
797 - sw->clip (buf, sw->conv_buf, ret); 720 + sw->clip (buf, sw->buf, ret);
798 sw->total_hw_samples_acquired += total; 721 sw->total_hw_samples_acquired += total;
799 return ret << sw->info.shift; 722 return ret << sw->info.shift;
800 } 723 }
@@ -802,27 +725,6 @@ int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int size) @@ -802,27 +725,6 @@ int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int size)
802 /* 725 /*
803 * Hard voice (playback) 726 * Hard voice (playback)
804 */ 727 */
805 -static void audio_pcm_hw_free_resources_out (HWVoiceOut *hw)  
806 -{  
807 - if (hw->mix_buf) {  
808 - qemu_free (hw->mix_buf);  
809 - }  
810 -  
811 - hw->mix_buf = NULL;  
812 -}  
813 -  
814 -static int audio_pcm_hw_alloc_resources_out (HWVoiceOut *hw)  
815 -{  
816 - hw->mix_buf = audio_calloc (AUDIO_FUNC, hw->samples, sizeof (st_sample_t));  
817 - if (!hw->mix_buf) {  
818 - dolog ("Could not allocate DAC mixing buffer (%d samples)\n",  
819 - hw->samples);  
820 - return -1;  
821 - }  
822 -  
823 - return 0;  
824 -}  
825 -  
826 static int audio_pcm_hw_find_min_out (HWVoiceOut *hw, int *nb_livep) 728 static int audio_pcm_hw_find_min_out (HWVoiceOut *hw, int *nb_livep)
827 { 729 {
828 SWVoiceOut *sw; 730 SWVoiceOut *sw;
@@ -876,66 +778,6 @@ int audio_pcm_hw_get_live_out (HWVoiceOut *hw) @@ -876,66 +778,6 @@ int audio_pcm_hw_get_live_out (HWVoiceOut *hw)
876 /* 778 /*
877 * Soft voice (playback) 779 * Soft voice (playback)
878 */ 780 */
879 -static void audio_pcm_sw_free_resources_out (SWVoiceOut *sw)  
880 -{  
881 - if (sw->buf) {  
882 - qemu_free (sw->buf);  
883 - }  
884 -  
885 - if (sw->rate) {  
886 - st_rate_stop (sw->rate);  
887 - }  
888 -  
889 - sw->buf = NULL;  
890 - sw->rate = NULL;  
891 -}  
892 -  
893 -static int audio_pcm_sw_alloc_resources_out (SWVoiceOut *sw)  
894 -{  
895 - sw->buf = audio_calloc (AUDIO_FUNC, sw->hw->samples, sizeof (st_sample_t));  
896 - if (!sw->buf) {  
897 - dolog ("Could not allocate buffer for `%s' (%d samples)\n",  
898 - SW_NAME (sw), sw->hw->samples);  
899 - return -1;  
900 - }  
901 -  
902 - sw->rate = st_rate_start (sw->info.freq, sw->hw->info.freq);  
903 - if (!sw->rate) {  
904 - qemu_free (sw->buf);  
905 - sw->buf = NULL;  
906 - return -1;  
907 - }  
908 - return 0;  
909 -}  
910 -  
911 -static int audio_pcm_sw_init_out (  
912 - SWVoiceOut *sw,  
913 - HWVoiceOut *hw,  
914 - const char *name,  
915 - audsettings_t *as  
916 - )  
917 -{  
918 - /* None of the cards emulated by QEMU are big-endian  
919 - hence following shortcut */  
920 - audio_pcm_init_info (&sw->info, as, audio_need_to_swap_endian (0));  
921 - sw->hw = hw;  
922 - sw->empty = 1;  
923 - sw->active = 0;  
924 - sw->ratio = ((int64_t) sw->hw->info.freq << 32) / sw->info.freq;  
925 - sw->total_hw_samples_mixed = 0;  
926 -  
927 - sw->conv =  
928 - mixeng_conv  
929 - [sw->info.nchannels == 2]  
930 - [sw->info.sign]  
931 - [sw->info.swap_endian]  
932 - [sw->info.bits == 16];  
933 - sw->name = qemu_strdup (name);  
934 -  
935 - audio_pcm_sw_free_resources_out (sw);  
936 - return audio_pcm_sw_alloc_resources_out (sw);  
937 -}  
938 -  
939 int audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int size) 781 int audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int size)
940 { 782 {
941 int hwsamples, samples, isamp, osamp, wpos, live, dead, left, swlim, blck; 783 int hwsamples, samples, isamp, osamp, wpos, live, dead, left, swlim, blck;
@@ -1316,6 +1158,16 @@ static void audio_run_in (AudioState *s) @@ -1316,6 +1158,16 @@ static void audio_run_in (AudioState *s)
1316 } 1158 }
1317 } 1159 }
1318 1160
  1161 +static void audio_timer (void *opaque)
  1162 +{
  1163 + AudioState *s = opaque;
  1164 +
  1165 + audio_run_out (s);
  1166 + audio_run_in (s);
  1167 +
  1168 + qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + conf.period.ticks);
  1169 +}
  1170 +
1319 static struct audio_option audio_options[] = { 1171 static struct audio_option audio_options[] = {
1320 /* DAC */ 1172 /* DAC */
1321 {"DAC_FIXED_SETTINGS", AUD_OPT_BOOL, &conf.fixed_out.enabled, 1173 {"DAC_FIXED_SETTINGS", AUD_OPT_BOOL, &conf.fixed_out.enabled,
@@ -1356,13 +1208,31 @@ static struct audio_option audio_options[] = { @@ -1356,13 +1208,31 @@ static struct audio_option audio_options[] = {
1356 {"PLIVE", AUD_OPT_BOOL, &conf.plive, 1208 {"PLIVE", AUD_OPT_BOOL, &conf.plive,
1357 "(undocumented)", NULL, 0}, 1209 "(undocumented)", NULL, 0},
1358 1210
1359 -  
1360 {"LOG_TO_MONITOR", AUD_OPT_BOOL, &conf.log_to_monitor, 1211 {"LOG_TO_MONITOR", AUD_OPT_BOOL, &conf.log_to_monitor,
1361 "print logging messages to montior instead of stderr", NULL, 0}, 1212 "print logging messages to montior instead of stderr", NULL, 0},
1362 1213
1363 {NULL, 0, NULL, NULL, NULL, 0} 1214 {NULL, 0, NULL, NULL, NULL, 0}
1364 }; 1215 };
1365 1216
  1217 +static void audio_pp_nb_voices (const char *typ, int nb)
  1218 +{
  1219 + switch (nb) {
  1220 + case 0:
  1221 + printf ("Does not support %s\n", typ);
  1222 + break;
  1223 + case 1:
  1224 + printf ("One %s voice\n", typ);
  1225 + break;
  1226 + case INT_MAX:
  1227 + printf ("Theoretically supports many %s voices\n", typ);
  1228 + break;
  1229 + default:
  1230 + printf ("Theoretically supports upto %d %s voices\n", nb, typ);
  1231 + break;
  1232 + }
  1233 +
  1234 +}
  1235 +
1366 void AUD_help (void) 1236 void AUD_help (void)
1367 { 1237 {
1368 size_t i; 1238 size_t i;
@@ -1387,37 +1257,8 @@ void AUD_help (void) @@ -1387,37 +1257,8 @@ void AUD_help (void)
1387 printf ("Name: %s\n", d->name); 1257 printf ("Name: %s\n", d->name);
1388 printf ("Description: %s\n", d->descr); 1258 printf ("Description: %s\n", d->descr);
1389 1259
1390 - switch (d->max_voices_out) {  
1391 - case 0:  
1392 - printf ("Does not support DAC\n");  
1393 - break;  
1394 - case 1:  
1395 - printf ("One DAC voice\n");  
1396 - break;  
1397 - case INT_MAX:  
1398 - printf ("Theoretically supports many DAC voices\n");  
1399 - break;  
1400 - default:  
1401 - printf ("Theoretically supports upto %d DAC voices\n",  
1402 - d->max_voices_out);  
1403 - break;  
1404 - }  
1405 -  
1406 - switch (d->max_voices_in) {  
1407 - case 0:  
1408 - printf ("Does not support ADC\n");  
1409 - break;  
1410 - case 1:  
1411 - printf ("One ADC voice\n");  
1412 - break;  
1413 - case INT_MAX:  
1414 - printf ("Theoretically supports many ADC voices\n");  
1415 - break;  
1416 - default:  
1417 - printf ("Theoretically supports upto %d ADC voices\n",  
1418 - d->max_voices_in);  
1419 - break;  
1420 - } 1260 + audio_pp_nb_voices ("playback", d->max_voices_out);
  1261 + audio_pp_nb_voices ("capture", d->max_voices_in);
1421 1262
1422 if (d->options) { 1263 if (d->options) {
1423 printf ("Options:\n"); 1264 printf ("Options:\n");
@@ -1434,7 +1275,7 @@ void AUD_help (void) @@ -1434,7 +1275,7 @@ void AUD_help (void)
1434 "Example:\n" 1275 "Example:\n"
1435 #ifdef _WIN32 1276 #ifdef _WIN32
1436 " set QEMU_AUDIO_DRV=wav\n" 1277 " set QEMU_AUDIO_DRV=wav\n"
1437 - " set QEMU_WAV_PATH=c:/tune.wav\n" 1278 + " set QEMU_WAV_PATH=c:\\tune.wav\n"
1438 #else 1279 #else
1439 " export QEMU_AUDIO_DRV=wav\n" 1280 " export QEMU_AUDIO_DRV=wav\n"
1440 " export QEMU_WAV_PATH=$HOME/tune.wav\n" 1281 " export QEMU_WAV_PATH=$HOME/tune.wav\n"
@@ -1444,16 +1285,6 @@ void AUD_help (void) @@ -1444,16 +1285,6 @@ void AUD_help (void)
1444 ); 1285 );
1445 } 1286 }
1446 1287
1447 -void audio_timer (void *opaque)  
1448 -{  
1449 - AudioState *s = opaque;  
1450 -  
1451 - audio_run_out (s);  
1452 - audio_run_in (s);  
1453 -  
1454 - qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + conf.period.ticks);  
1455 -}  
1456 -  
1457 static int audio_driver_init (AudioState *s, struct audio_driver *drv) 1288 static int audio_driver_init (AudioState *s, struct audio_driver *drv)
1458 { 1289 {
1459 if (drv->options) { 1290 if (drv->options) {
@@ -1462,62 +1293,8 @@ static int audio_driver_init (AudioState *s, struct audio_driver *drv) @@ -1462,62 +1293,8 @@ static int audio_driver_init (AudioState *s, struct audio_driver *drv)
1462 s->drv_opaque = drv->init (); 1293 s->drv_opaque = drv->init ();
1463 1294
1464 if (s->drv_opaque) { 1295 if (s->drv_opaque) {
1465 - if (s->nb_hw_voices_out > drv->max_voices_out) {  
1466 - if (!drv->max_voices_out) {  
1467 - dolog ("`%s' does not support DAC\n", drv->name);  
1468 - }  
1469 - else {  
1470 - dolog (  
1471 - "`%s' does not support %d multiple DAC voicess\n"  
1472 - "Resetting to %d\n",  
1473 - drv->name,  
1474 - s->nb_hw_voices_out,  
1475 - drv->max_voices_out  
1476 - );  
1477 - }  
1478 - s->nb_hw_voices_out = drv->max_voices_out;  
1479 - }  
1480 -  
1481 -  
1482 - if (!drv->voice_size_in && drv->max_voices_in) {  
1483 - ldebug ("warning: No ADC voice size defined for `%s'\n",  
1484 - drv->name);  
1485 - drv->max_voices_in = 0;  
1486 - }  
1487 -  
1488 - if (!drv->voice_size_out && drv->max_voices_out) {  
1489 - ldebug ("warning: No DAC voice size defined for `%s'\n",  
1490 - drv->name);  
1491 - }  
1492 -  
1493 - if (drv->voice_size_in && !drv->max_voices_in) {  
1494 - ldebug ("warning: `%s' ADC voice size %d, zero voices \n",  
1495 - drv->name, drv->voice_size_out);  
1496 - }  
1497 -  
1498 - if (drv->voice_size_out && !drv->max_voices_out) {  
1499 - ldebug ("warning: `%s' DAC voice size %d, zero voices \n",  
1500 - drv->name, drv->voice_size_in);  
1501 - }  
1502 -  
1503 - if (s->nb_hw_voices_in > drv->max_voices_in) {  
1504 - if (!drv->max_voices_in) {  
1505 - ldebug ("`%s' does not support ADC\n", drv->name);  
1506 - }  
1507 - else {  
1508 - dolog (  
1509 - "`%s' does not support %d multiple ADC voices\n"  
1510 - "Resetting to %d\n",  
1511 - drv->name,  
1512 - s->nb_hw_voices_in,  
1513 - drv->max_voices_in  
1514 - );  
1515 - }  
1516 - s->nb_hw_voices_in = drv->max_voices_in;  
1517 - }  
1518 -  
1519 - LIST_INIT (&s->hw_head_out);  
1520 - LIST_INIT (&s->hw_head_in); 1296 + audio_init_nb_voices_out (s, drv);
  1297 + audio_init_nb_voices_in (s, drv);
1521 s->drv = drv; 1298 s->drv = drv;
1522 return 0; 1299 return 0;
1523 } 1300 }
@@ -1549,25 +1326,13 @@ static void audio_atexit (void) @@ -1549,25 +1326,13 @@ static void audio_atexit (void)
1549 HWVoiceOut *hwo = NULL; 1326 HWVoiceOut *hwo = NULL;
1550 HWVoiceIn *hwi = NULL; 1327 HWVoiceIn *hwi = NULL;
1551 1328
1552 - while ((hwo = audio_pcm_hw_find_any_out (s, hwo))) {  
1553 - if (!hwo->pcm_ops) {  
1554 - continue;  
1555 - }  
1556 -  
1557 - if (hwo->enabled) {  
1558 - hwo->pcm_ops->ctl_out (hwo, VOICE_DISABLE);  
1559 - } 1329 + while ((hwo = audio_pcm_hw_find_any_enabled_out (s, hwo))) {
  1330 + hwo->pcm_ops->ctl_out (hwo, VOICE_DISABLE);
1560 hwo->pcm_ops->fini_out (hwo); 1331 hwo->pcm_ops->fini_out (hwo);
1561 } 1332 }
1562 1333
1563 - while ((hwi = audio_pcm_hw_find_any_in (s, hwi))) {  
1564 - if (!hwi->pcm_ops) {  
1565 - continue;  
1566 - }  
1567 -  
1568 - if (hwi->enabled) {  
1569 - hwi->pcm_ops->ctl_in (hwi, VOICE_DISABLE);  
1570 - } 1334 + while ((hwi = audio_pcm_hw_find_any_enabled_in (s, hwi))) {
  1335 + hwi->pcm_ops->ctl_in (hwi, VOICE_DISABLE);
1571 hwi->pcm_ops->fini_in (hwi); 1336 hwi->pcm_ops->fini_in (hwi);
1572 } 1337 }
1573 1338
@@ -1616,21 +1381,31 @@ AudioState *AUD_init (void) @@ -1616,21 +1381,31 @@ AudioState *AUD_init (void)
1616 const char *drvname; 1381 const char *drvname;
1617 AudioState *s = &glob_audio_state; 1382 AudioState *s = &glob_audio_state;
1618 1383
  1384 + LIST_INIT (&s->hw_head_out);
  1385 + LIST_INIT (&s->hw_head_in);
  1386 + atexit (audio_atexit);
  1387 +
  1388 + s->ts = qemu_new_timer (vm_clock, audio_timer, s);
  1389 + if (!s->ts) {
  1390 + dolog ("Could not create audio timer\n");
  1391 + return NULL;
  1392 + }
  1393 +
1619 audio_process_options ("AUDIO", audio_options); 1394 audio_process_options ("AUDIO", audio_options);
1620 1395
1621 s->nb_hw_voices_out = conf.fixed_out.nb_voices; 1396 s->nb_hw_voices_out = conf.fixed_out.nb_voices;
1622 s->nb_hw_voices_in = conf.fixed_in.nb_voices; 1397 s->nb_hw_voices_in = conf.fixed_in.nb_voices;
1623 1398
1624 if (s->nb_hw_voices_out <= 0) { 1399 if (s->nb_hw_voices_out <= 0) {
1625 - dolog ("Bogus number of DAC voices %d\n", 1400 + dolog ("Bogus number of playback voices %d, setting to 1\n",
1626 s->nb_hw_voices_out); 1401 s->nb_hw_voices_out);
1627 s->nb_hw_voices_out = 1; 1402 s->nb_hw_voices_out = 1;
1628 } 1403 }
1629 1404
1630 if (s->nb_hw_voices_in <= 0) { 1405 if (s->nb_hw_voices_in <= 0) {
1631 - dolog ("Bogus number of ADC voices %d\n", 1406 + dolog ("Bogus number of capture voices %d, setting to 0\n",
1632 s->nb_hw_voices_in); 1407 s->nb_hw_voices_in);
1633 - s->nb_hw_voices_in = 1; 1408 + s->nb_hw_voices_in = 0;
1634 } 1409 }
1635 1410
1636 { 1411 {
@@ -1638,12 +1413,6 @@ AudioState *AUD_init (void) @@ -1638,12 +1413,6 @@ AudioState *AUD_init (void)
1638 drvname = audio_get_conf_str ("QEMU_AUDIO_DRV", NULL, &def); 1413 drvname = audio_get_conf_str ("QEMU_AUDIO_DRV", NULL, &def);
1639 } 1414 }
1640 1415
1641 - s->ts = qemu_new_timer (vm_clock, audio_timer, s);  
1642 - if (!s->ts) {  
1643 - dolog ("Could not create audio timer\n");  
1644 - return NULL;  
1645 - }  
1646 -  
1647 if (drvname) { 1416 if (drvname) {
1648 int found = 0; 1417 int found = 0;
1649 1418
@@ -1680,6 +1449,8 @@ AudioState *AUD_init (void) @@ -1680,6 +1449,8 @@ AudioState *AUD_init (void)
1680 } 1449 }
1681 1450
1682 if (done) { 1451 if (done) {
  1452 + VMChangeStateEntry *e;
  1453 +
1683 if (conf.period.hz <= 0) { 1454 if (conf.period.hz <= 0) {
1684 if (conf.period.hz < 0) { 1455 if (conf.period.hz < 0) {
1685 dolog ("warning: Timer period is negative - %d " 1456 dolog ("warning: Timer period is negative - %d "
@@ -1692,7 +1463,11 @@ AudioState *AUD_init (void) @@ -1692,7 +1463,11 @@ AudioState *AUD_init (void)
1692 conf.period.ticks = ticks_per_sec / conf.period.hz; 1463 conf.period.ticks = ticks_per_sec / conf.period.hz;
1693 } 1464 }
1694 1465
1695 - qemu_add_vm_change_state_handler (audio_vm_change_state_handler, s); 1466 + e = qemu_add_vm_change_state_handler (audio_vm_change_state_handler, s);
  1467 + if (!e) {
  1468 + dolog ("warning: Could not register change state handler\n"
  1469 + "(Audio can continue looping even after stopping the VM)\n");
  1470 + }
1696 } 1471 }
1697 else { 1472 else {
1698 qemu_del_timer (s->ts); 1473 qemu_del_timer (s->ts);
@@ -1701,7 +1476,6 @@ AudioState *AUD_init (void) @@ -1701,7 +1476,6 @@ AudioState *AUD_init (void)
1701 1476
1702 LIST_INIT (&s->card_head); 1477 LIST_INIT (&s->card_head);
1703 register_savevm ("audio", 0, 1, audio_save, audio_load, s); 1478 register_savevm ("audio", 0, 1, audio_save, audio_load, s);
1704 - atexit (audio_atexit);  
1705 qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + conf.period.ticks); 1479 qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + conf.period.ticks);
1706 return s; 1480 return s;
1707 } 1481 }
audio/audio.h
@@ -73,7 +73,8 @@ SWVoiceOut *AUD_open_out ( @@ -73,7 +73,8 @@ SWVoiceOut *AUD_open_out (
73 const char *name, 73 const char *name,
74 void *callback_opaque, 74 void *callback_opaque,
75 audio_callback_fn_t callback_fn, 75 audio_callback_fn_t callback_fn,
76 - audsettings_t *settings 76 + audsettings_t *settings,
  77 + int sw_endian
77 ); 78 );
78 79
79 void AUD_close_out (QEMUSoundCard *card, SWVoiceOut *sw); 80 void AUD_close_out (QEMUSoundCard *card, SWVoiceOut *sw);
@@ -91,7 +92,8 @@ SWVoiceIn *AUD_open_in ( @@ -91,7 +92,8 @@ SWVoiceIn *AUD_open_in (
91 const char *name, 92 const char *name,
92 void *callback_opaque, 93 void *callback_opaque,
93 audio_callback_fn_t callback_fn, 94 audio_callback_fn_t callback_fn,
94 - audsettings_t *settings 95 + audsettings_t *settings,
  96 + int sw_endian
95 ); 97 );
96 98
97 void AUD_close_in (QEMUSoundCard *card, SWVoiceIn *sw); 99 void AUD_close_in (QEMUSoundCard *card, SWVoiceIn *sw);
audio/audio_int.h
@@ -123,7 +123,7 @@ struct SWVoiceIn { @@ -123,7 +123,7 @@ struct SWVoiceIn {
123 int64_t ratio; 123 int64_t ratio;
124 void *rate; 124 void *rate;
125 int total_hw_samples_acquired; 125 int total_hw_samples_acquired;
126 - st_sample_t *conv_buf; 126 + st_sample_t *buf;
127 f_sample *clip; 127 f_sample *clip;
128 HWVoiceIn *hw; 128 HWVoiceIn *hw;
129 char *name; 129 char *name;
audio/audio_template.h
@@ -23,52 +23,159 @@ @@ -23,52 +23,159 @@
23 */ 23 */
24 24
25 #ifdef DAC 25 #ifdef DAC
  26 +#define NAME "playback"
  27 +#define HWBUF hw->mix_buf
26 #define TYPE out 28 #define TYPE out
27 -#define HW glue (HWVoice, Out)  
28 -#define SW glue (SWVoice, Out) 29 +#define HW HWVoiceOut
  30 +#define SW SWVoiceOut
29 #else 31 #else
  32 +#define NAME "capture"
30 #define TYPE in 33 #define TYPE in
31 -#define HW glue (HWVoice, In)  
32 -#define SW glue (SWVoice, In) 34 +#define HW HWVoiceIn
  35 +#define SW SWVoiceIn
  36 +#define HWBUF hw->conv_buf
33 #endif 37 #endif
34 38
35 -static int glue (audio_pcm_hw_init_, TYPE) (  
36 - HW *hw,  
37 - audsettings_t *as 39 +static void glue (audio_init_nb_voices_, TYPE) (
  40 + AudioState *s,
  41 + struct audio_driver *drv
38 ) 42 )
39 { 43 {
40 - glue (audio_pcm_hw_free_resources_, TYPE) (hw); 44 + int max_voices = glue (drv->max_voices_, TYPE);
  45 + int voice_size = glue (drv->voice_size_, TYPE);
41 46
42 - if (glue (hw->pcm_ops->init_, TYPE) (hw, as)) {  
43 - return -1; 47 + if (glue (s->nb_hw_voices_, TYPE) > max_voices) {
  48 + if (!max_voices) {
  49 +#ifdef DAC
  50 + dolog ("Driver `%s' does not support " NAME "\n", drv->name);
  51 +#endif
  52 + }
  53 + else {
  54 + dolog ("Driver `%s' does not support %d " NAME " voices, max %d\n",
  55 + drv->name,
  56 + glue (s->nb_hw_voices_, TYPE),
  57 + max_voices);
  58 + }
  59 + glue (s->nb_hw_voices_, TYPE) = max_voices;
44 } 60 }
45 61
46 - if (audio_bug (AUDIO_FUNC, hw->samples <= 0)) {  
47 - dolog ("hw->samples=%d\n", hw->samples); 62 + if (audio_bug (AUDIO_FUNC, !voice_size && max_voices)) {
  63 + dolog ("drv=`%s' voice_size=0 max_voices=%d\n",
  64 + drv->name, max_voices);
  65 + glue (s->nb_hw_voices_, TYPE) = 0;
  66 + }
  67 +
  68 + if (audio_bug (AUDIO_FUNC, voice_size && !max_voices)) {
  69 + dolog ("drv=`%s' voice_size=%d max_voices=0\n",
  70 + drv->name, voice_size);
  71 + }
  72 +}
  73 +
  74 +static void glue (audio_pcm_hw_free_resources_, TYPE) (HW *hw)
  75 +{
  76 + if (HWBUF) {
  77 + qemu_free (HWBUF);
  78 + }
  79 +
  80 + HWBUF = NULL;
  81 +}
  82 +
  83 +static int glue (audio_pcm_hw_alloc_resources_, TYPE) (HW *hw)
  84 +{
  85 + HWBUF = audio_calloc (AUDIO_FUNC, hw->samples, sizeof (st_sample_t));
  86 + if (!HWBUF) {
  87 + dolog ("Could not allocate " NAME " buffer (%d samples)\n",
  88 + hw->samples);
48 return -1; 89 return -1;
49 } 90 }
50 91
51 - LIST_INIT (&hw->sw_head); 92 + return 0;
  93 +}
  94 +
  95 +static void glue (audio_pcm_sw_free_resources_, TYPE) (SW *sw)
  96 +{
  97 + if (sw->buf) {
  98 + qemu_free (sw->buf);
  99 + }
  100 +
  101 + if (sw->rate) {
  102 + st_rate_stop (sw->rate);
  103 + }
  104 +
  105 + sw->buf = NULL;
  106 + sw->rate = NULL;
  107 +}
  108 +
  109 +static int glue (audio_pcm_sw_alloc_resources_, TYPE) (SW *sw)
  110 +{
  111 + int samples;
  112 +
52 #ifdef DAC 113 #ifdef DAC
53 - hw->clip =  
54 - mixeng_clip 114 + samples = sw->hw->samples;
55 #else 115 #else
56 - hw->conv =  
57 - mixeng_conv 116 + samples = ((int64_t) sw->hw->samples << 32) / sw->ratio;
58 #endif 117 #endif
59 - [hw->info.nchannels == 2]  
60 - [hw->info.sign]  
61 - [hw->info.swap_endian]  
62 - [hw->info.bits == 16];  
63 118
64 - if (glue (audio_pcm_hw_alloc_resources_, TYPE) (hw)) {  
65 - glue (hw->pcm_ops->fini_, TYPE) (hw); 119 + sw->buf = audio_calloc (AUDIO_FUNC, samples, sizeof (st_sample_t));
  120 + if (!sw->buf) {
  121 + dolog ("Could not allocate buffer for `%s' (%d samples)\n",
  122 + SW_NAME (sw), samples);
66 return -1; 123 return -1;
67 } 124 }
68 125
  126 +#ifdef DAC
  127 + sw->rate = st_rate_start (sw->info.freq, sw->hw->info.freq);
  128 +#else
  129 + sw->rate = st_rate_start (sw->hw->info.freq, sw->info.freq);
  130 +#endif
  131 + if (!sw->rate) {
  132 + qemu_free (sw->buf);
  133 + sw->buf = NULL;
  134 + return -1;
  135 + }
69 return 0; 136 return 0;
70 } 137 }
71 138
  139 +static int glue (audio_pcm_sw_init_, TYPE) (
  140 + SW *sw,
  141 + HW *hw,
  142 + const char *name,
  143 + audsettings_t *as,
  144 + int endian
  145 + )
  146 +{
  147 + int err;
  148 +
  149 + audio_pcm_init_info (&sw->info, as, audio_need_to_swap_endian (endian));
  150 + sw->hw = hw;
  151 + sw->active = 0;
  152 +#ifdef DAC
  153 + sw->ratio = ((int64_t) sw->hw->info.freq << 32) / sw->info.freq;
  154 + sw->total_hw_samples_mixed = 0;
  155 + sw->empty = 1;
  156 +#else
  157 + sw->ratio = ((int64_t) sw->info.freq << 32) / sw->hw->info.freq;
  158 +#endif
  159 +
  160 +#ifdef DAC
  161 + sw->conv = mixeng_conv
  162 +#else
  163 + sw->clip = mixeng_clip
  164 +#endif
  165 + [sw->info.nchannels == 2]
  166 + [sw->info.sign]
  167 + [sw->info.swap_endian]
  168 + [sw->info.bits == 16];
  169 +
  170 + sw->name = qemu_strdup (name);
  171 + err = glue (audio_pcm_sw_alloc_resources_, TYPE) (sw);
  172 + if (err) {
  173 + qemu_free (sw->name);
  174 + sw->name = NULL;
  175 + }
  176 + return err;
  177 +}
  178 +
72 static void glue (audio_pcm_sw_fini_, TYPE) (SW *sw) 179 static void glue (audio_pcm_sw_fini_, TYPE) (SW *sw)
73 { 180 {
74 glue (audio_pcm_sw_free_resources_, TYPE) (sw); 181 glue (audio_pcm_sw_free_resources_, TYPE) (sw);
@@ -117,31 +224,6 @@ static HW *glue (audio_pcm_hw_find_any_enabled_, TYPE) (AudioState *s, HW *hw) @@ -117,31 +224,6 @@ static HW *glue (audio_pcm_hw_find_any_enabled_, TYPE) (AudioState *s, HW *hw)
117 return NULL; 224 return NULL;
118 } 225 }
119 226
120 -static HW *glue (audio_pcm_hw_find_any_passive_, TYPE) (AudioState *s)  
121 -{  
122 - if (glue (s->nb_hw_voices_, TYPE)) {  
123 - struct audio_driver *drv = s->drv;  
124 -  
125 - if (audio_bug (AUDIO_FUNC, !drv)) {  
126 - dolog ("No host audio driver\n");  
127 - return NULL;  
128 - }  
129 -  
130 - HW *hw = audio_calloc (AUDIO_FUNC, 1, glue (drv->voice_size_, TYPE));  
131 - if (!hw) {  
132 - dolog ("Can not allocate voice `%s' size %d\n",  
133 - drv->name, glue (drv->voice_size_, TYPE));  
134 - return NULL;  
135 - }  
136 -  
137 - LIST_INSERT_HEAD (&s->glue (hw_head_, TYPE), hw, entries);  
138 - glue (s->nb_hw_voices_, TYPE) -= 1;  
139 - return hw;  
140 - }  
141 -  
142 - return NULL;  
143 -}  
144 -  
145 static HW *glue (audio_pcm_hw_find_specific_, TYPE) ( 227 static HW *glue (audio_pcm_hw_find_specific_, TYPE) (
146 AudioState *s, 228 AudioState *s,
147 HW *hw, 229 HW *hw,
@@ -159,23 +241,63 @@ static HW *glue (audio_pcm_hw_find_specific_, TYPE) ( @@ -159,23 +241,63 @@ static HW *glue (audio_pcm_hw_find_specific_, TYPE) (
159 static HW *glue (audio_pcm_hw_add_new_, TYPE) (AudioState *s, audsettings_t *as) 241 static HW *glue (audio_pcm_hw_add_new_, TYPE) (AudioState *s, audsettings_t *as)
160 { 242 {
161 HW *hw; 243 HW *hw;
  244 + struct audio_driver *drv = s->drv;
162 245
163 - hw = glue (audio_pcm_hw_find_any_passive_, TYPE) (s);  
164 - if (hw) {  
165 - hw->pcm_ops = s->drv->pcm_ops;  
166 - if (!hw->pcm_ops) {  
167 - return NULL;  
168 - } 246 + if (!glue (s->nb_hw_voices_, TYPE)) {
  247 + return NULL;
  248 + }
169 249
170 - if (glue (audio_pcm_hw_init_, TYPE) (hw, as)) {  
171 - glue (audio_pcm_hw_gc_, TYPE) (s, &hw);  
172 - return NULL;  
173 - }  
174 - else {  
175 - return hw;  
176 - } 250 + if (audio_bug (AUDIO_FUNC, !drv)) {
  251 + dolog ("No host audio driver\n");
  252 + return NULL;
177 } 253 }
178 254
  255 + if (audio_bug (AUDIO_FUNC, !drv->pcm_ops)) {
  256 + dolog ("Host audio driver without pcm_ops\n");
  257 + return NULL;
  258 + }
  259 +
  260 + hw = audio_calloc (AUDIO_FUNC, 1, glue (drv->voice_size_, TYPE));
  261 + if (!hw) {
  262 + dolog ("Can not allocate voice `%s' size %d\n",
  263 + drv->name, glue (drv->voice_size_, TYPE));
  264 + return NULL;
  265 + }
  266 +
  267 + hw->pcm_ops = drv->pcm_ops;
  268 + LIST_INIT (&hw->sw_head);
  269 +
  270 + if (glue (hw->pcm_ops->init_, TYPE) (hw, as)) {
  271 + goto err0;
  272 + }
  273 +
  274 + if (audio_bug (AUDIO_FUNC, hw->samples <= 0)) {
  275 + dolog ("hw->samples=%d\n", hw->samples);
  276 + goto err1;
  277 + }
  278 +
  279 +#ifdef DAC
  280 + hw->clip = mixeng_clip
  281 +#else
  282 + hw->conv = mixeng_conv
  283 +#endif
  284 + [hw->info.nchannels == 2]
  285 + [hw->info.sign]
  286 + [hw->info.swap_endian]
  287 + [hw->info.bits == 16];
  288 +
  289 + if (glue (audio_pcm_hw_alloc_resources_, TYPE) (hw)) {
  290 + goto err1;
  291 + }
  292 +
  293 + LIST_INSERT_HEAD (&s->glue (hw_head_, TYPE), hw, entries);
  294 + glue (s->nb_hw_voices_, TYPE) -= 1;
  295 + return hw;
  296 +
  297 + err1:
  298 + glue (hw->pcm_ops->fini_, TYPE) (hw);
  299 + err0:
  300 + qemu_free (hw);
179 return NULL; 301 return NULL;
180 } 302 }
181 303
@@ -206,7 +328,8 @@ static HW *glue (audio_pcm_hw_add_, TYPE) (AudioState *s, audsettings_t *as) @@ -206,7 +328,8 @@ static HW *glue (audio_pcm_hw_add_, TYPE) (AudioState *s, audsettings_t *as)
206 static SW *glue (audio_pcm_create_voice_pair_, TYPE) ( 328 static SW *glue (audio_pcm_create_voice_pair_, TYPE) (
207 AudioState *s, 329 AudioState *s,
208 const char *sw_name, 330 const char *sw_name,
209 - audsettings_t *as 331 + audsettings_t *as,
  332 + int sw_endian
210 ) 333 )
211 { 334 {
212 SW *sw; 335 SW *sw;
@@ -234,7 +357,7 @@ static SW *glue (audio_pcm_create_voice_pair_, TYPE) ( @@ -234,7 +357,7 @@ static SW *glue (audio_pcm_create_voice_pair_, TYPE) (
234 357
235 glue (audio_pcm_hw_add_sw_, TYPE) (hw, sw); 358 glue (audio_pcm_hw_add_sw_, TYPE) (hw, sw);
236 359
237 - if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, sw_name, as)) { 360 + if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, sw_name, as, sw_endian)) {
238 goto err3; 361 goto err3;
239 } 362 }
240 363
@@ -256,6 +379,7 @@ static void glue (audio_close_, TYPE) (AudioState *s, SW *sw) @@ -256,6 +379,7 @@ static void glue (audio_close_, TYPE) (AudioState *s, SW *sw)
256 glue (audio_pcm_hw_gc_, TYPE) (s, &sw->hw); 379 glue (audio_pcm_hw_gc_, TYPE) (s, &sw->hw);
257 qemu_free (sw); 380 qemu_free (sw);
258 } 381 }
  382 +
259 void glue (AUD_close_, TYPE) (QEMUSoundCard *card, SW *sw) 383 void glue (AUD_close_, TYPE) (QEMUSoundCard *card, SW *sw)
260 { 384 {
261 if (sw) { 385 if (sw) {
@@ -275,7 +399,8 @@ SW *glue (AUD_open_, TYPE) ( @@ -275,7 +399,8 @@ SW *glue (AUD_open_, TYPE) (
275 const char *name, 399 const char *name,
276 void *callback_opaque , 400 void *callback_opaque ,
277 audio_callback_fn_t callback_fn, 401 audio_callback_fn_t callback_fn,
278 - audsettings_t *as 402 + audsettings_t *as,
  403 + int sw_endian
279 ) 404 )
280 { 405 {
281 AudioState *s; 406 AudioState *s;
@@ -347,15 +472,16 @@ SW *glue (AUD_open_, TYPE) ( @@ -347,15 +472,16 @@ SW *glue (AUD_open_, TYPE) (
347 goto fail; 472 goto fail;
348 } 473 }
349 474
350 - if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, name, as)) { 475 + glue (audio_pcm_sw_fini_, TYPE) (sw);
  476 + if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, name, as, sw_endian)) {
351 goto fail; 477 goto fail;
352 } 478 }
353 } 479 }
354 else { 480 else {
355 - sw = glue (audio_pcm_create_voice_pair_, TYPE) (s, name, as); 481 + sw = glue (audio_pcm_create_voice_pair_, TYPE) (s, name, as, sw_endian);
356 if (!sw) { 482 if (!sw) {
357 dolog ("Failed to create voice `%s'\n", name); 483 dolog ("Failed to create voice `%s'\n", name);
358 - goto fail; 484 + return NULL;
359 } 485 }
360 } 486 }
361 487
@@ -435,3 +561,5 @@ uint64_t glue (AUD_get_elapsed_usec_, TYPE) (SW *sw, QEMUAudioTimeStamp *ts) @@ -435,3 +561,5 @@ uint64_t glue (AUD_get_elapsed_usec_, TYPE) (SW *sw, QEMUAudioTimeStamp *ts)
435 #undef TYPE 561 #undef TYPE
436 #undef HW 562 #undef HW
437 #undef SW 563 #undef SW
  564 +#undef HWBUF
  565 +#undef NAME
audio/ossaudio.c
@@ -75,11 +75,11 @@ static void GCC_FMT_ATTR (2, 3) oss_logerr (int err, const char *fmt, ...) @@ -75,11 +75,11 @@ static void GCC_FMT_ATTR (2, 3) oss_logerr (int err, const char *fmt, ...)
75 { 75 {
76 va_list ap; 76 va_list ap;
77 77
  78 + va_start (ap, fmt);
78 AUD_vlog (AUDIO_CAP, fmt, ap); 79 AUD_vlog (AUDIO_CAP, fmt, ap);
  80 + va_end (ap);
79 81
80 - va_start (ap, fmt);  
81 AUD_log (AUDIO_CAP, "Reason: %s\n", strerror (err)); 82 AUD_log (AUDIO_CAP, "Reason: %s\n", strerror (err));
82 - va_end (ap);  
83 } 83 }
84 84
85 static void GCC_FMT_ATTR (3, 4) oss_logerr2 ( 85 static void GCC_FMT_ATTR (3, 4) oss_logerr2 (
@@ -422,6 +422,8 @@ static int oss_init_out (HWVoiceOut *hw, audsettings_t *as) @@ -422,6 +422,8 @@ static int oss_init_out (HWVoiceOut *hw, audsettings_t *as)
422 audfmt_e effective_fmt; 422 audfmt_e effective_fmt;
423 audsettings_t obt_as; 423 audsettings_t obt_as;
424 424
  425 + oss->fd = -1;
  426 +
425 req.fmt = aud_to_ossfmt (as->fmt); 427 req.fmt = aud_to_ossfmt (as->fmt);
426 req.freq = as->freq; 428 req.freq = as->freq;
427 req.nchannels = as->nchannels; 429 req.nchannels = as->nchannels;
@@ -565,6 +567,8 @@ static int oss_init_in (HWVoiceIn *hw, audsettings_t *as) @@ -565,6 +567,8 @@ static int oss_init_in (HWVoiceIn *hw, audsettings_t *as)
565 audfmt_e effective_fmt; 567 audfmt_e effective_fmt;
566 audsettings_t obt_as; 568 audsettings_t obt_as;
567 569
  570 + oss->fd = -1;
  571 +
568 req.fmt = aud_to_ossfmt (as->fmt); 572 req.fmt = aud_to_ossfmt (as->fmt);
569 req.freq = as->freq; 573 req.freq = as->freq;
570 req.nchannels = as->nchannels; 574 req.nchannels = as->nchannels;