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 31 HWVoiceOut hw;
32 32 void *pcm_buf;
33 33 snd_pcm_t *handle;
34   - int can_pause;
35   - int was_enabled;
36 34 } ALSAVoiceOut;
37 35  
38 36 typedef struct ALSAVoiceIn {
39 37 HWVoiceIn hw;
40 38 snd_pcm_t *handle;
41 39 void *pcm_buf;
42   - int can_pause;
43 40 } ALSAVoiceIn;
44 41  
45 42 static struct {
... ... @@ -58,6 +55,7 @@ static struct {
58 55  
59 56 int buffer_size_out_overriden;
60 57 int period_size_out_overriden;
  58 + int verbose;
61 59 } conf = {
62 60 #ifdef HIGH_LATENCY
63 61 .size_in_usec_in = 1,
... ... @@ -73,8 +71,8 @@ static struct {
73 71 #else
74 72 #define DEFAULT_BUFFER_SIZE 1024
75 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 76 .buffer_size_out = DEFAULT_BUFFER_SIZE,
79 77 .period_size_out = DEFAULT_PERIOD_SIZE,
80 78 .buffer_size_in_overriden = 0,
... ... @@ -82,7 +80,8 @@ static struct {
82 80 .period_size_in_overriden = 0,
83 81 .period_size_out_overriden = 0,
84 82 #endif
85   - .threshold = 0
  83 + .threshold = 0,
  84 + .verbose = 0
86 85 };
87 86  
88 87 struct alsa_params_req {
... ... @@ -97,7 +96,6 @@ struct alsa_params_obt {
97 96 int freq;
98 97 audfmt_e fmt;
99 98 int nchannels;
100   - int can_pause;
101 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 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 475 if (!in && conf.threshold) {
484 476 snd_pcm_uframes_t threshold;
485 477 int bytes_per_sec;
... ... @@ -527,6 +519,28 @@ static int alsa_recover (snd_pcm_t *handle)
527 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 544 static int alsa_run_out (HWVoiceOut *hw)
531 545 {
532 546 ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
... ... @@ -541,57 +555,53 @@ static int alsa_run_out (HWVoiceOut *hw)
541 555 return 0;
542 556 }
543 557  
544   - avail = snd_pcm_avail_update (alsa->handle);
  558 + avail = alsa_get_avail (alsa->handle);
545 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 561 return 0;
557 562 }
558 563  
559   - ok:
560 564 decr = audio_MIN (live, avail);
561 565 samples = decr;
562 566 rpos = hw->rpos;
563 567 while (samples) {
564 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 570 snd_pcm_sframes_t written;
567 571  
568 572 src = hw->mix_buf + rpos;
569 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 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 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 597 continue;
591 598  
  599 + case -EAGAIN:
  600 + goto exit;
  601 +
592 602 default:
593 603 alsa_logerr (written, "Failed to write %d frames to %p\n",
594   - convert_samples, dst);
  604 + len, dst);
595 605 goto exit;
596 606 }
597 607 }
... ... @@ -599,7 +609,7 @@ static int alsa_run_out (HWVoiceOut *hw)
599 609 mixeng_clear (src, written);
600 610 rpos = (rpos + written) % hw->samples;
601 611 samples -= written;
602   - convert_samples -= written;
  612 + len -= written;
603 613 dst = advance (dst, written << hw->info.shift);
604 614 src += written;
605 615 }
... ... @@ -659,7 +669,6 @@ static int alsa_init_out (HWVoiceOut *hw, audsettings_t *as)
659 669 &obt_as,
660 670 audio_need_to_swap_endian (endianness)
661 671 );
662   - alsa->can_pause = obt.can_pause;
663 672 hw->samples = obt.samples;
664 673  
665 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 680 }
672 681  
673 682 alsa->handle = handle;
674   - alsa->was_enabled = 0;
675 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 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 710 ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
682 711  
683 712 switch (cmd) {
684 713 case VOICE_ENABLE:
685 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 717 case VOICE_DISABLE:
703 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 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 758 &obt_as,
750 759 audio_need_to_swap_endian (endianness)
751 760 );
752   - alsa->can_pause = obt.can_pause;
753 761 hw->samples = obt.samples;
754 762  
755 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 791 int i;
784 792 int live = audio_pcm_hw_get_live_in (hw);
785 793 int dead = hw->samples - live;
  794 + int decr;
786 795 struct {
787 796 int add;
788 797 int len;
... ... @@ -790,22 +799,36 @@ static int alsa_run_in (HWVoiceIn *hw)
790 799 { hw->wpos, 0 },
791 800 { 0, 0 }
792 801 };
793   -
  802 + snd_pcm_sframes_t avail;
794 803 snd_pcm_uframes_t read_samples = 0;
795 804  
796 805 if (!dead) {
797 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 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 828 else {
805   - bufs[0].len = dead;
  829 + bufs[0].len = decr;
806 830 }
807 831  
808   -
809 832 for (i = 0; i < 2; ++i) {
810 833 void *src;
811 834 st_sample_t *dst;
... ... @@ -820,24 +843,27 @@ static int alsa_run_in (HWVoiceIn *hw)
820 843 while (len) {
821 844 nread = snd_pcm_readi (alsa->handle, src, len);
822 845  
823   - if (nread < 0) {
  846 + if (nread <= 0) {
824 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 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 862 continue;
840 863  
  864 + case -EAGAIN:
  865 + goto exit;
  866 +
841 867 default:
842 868 alsa_logerr (
843 869 nread,
... ... @@ -871,9 +897,19 @@ static int alsa_read (SWVoiceIn *sw, void *buf, int size)
871 897  
872 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 915 static void *alsa_audio_init (void)
... ... @@ -909,6 +945,10 @@ static struct audio_option alsa_options[] = {
909 945  
910 946 {"ADC_DEV", AUD_OPT_STR, &conf.pcm_name_in,
911 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 952 {NULL, 0, NULL, NULL, NULL, 0}
913 953 };
914 954  
... ...
audio/audio.c
... ... @@ -96,7 +96,7 @@ static struct {
96 96  
97 97 { 0 }, /* period */
98 98 0, /* plive */
99   - 0
  99 + 0 /* log_to_monitor */
100 100 };
101 101  
102 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 623 /*
624 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 626 static int audio_pcm_hw_find_min_in (HWVoiceIn *hw)
646 627 {
647 628 SWVoiceIn *sw;
... ... @@ -668,64 +649,6 @@ int audio_pcm_hw_get_live_in (HWVoiceIn *hw)
668 649 /*
669 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 652 static int audio_pcm_sw_get_rpos_in (SWVoiceIn *sw)
730 653 {
731 654 HWVoiceIn *hw = sw->hw;
... ... @@ -750,7 +673,7 @@ int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int size)
750 673 {
751 674 HWVoiceIn *hw = sw->hw;
752 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 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 717 total += isamp;
795 718 }
796 719  
797   - sw->clip (buf, sw->conv_buf, ret);
  720 + sw->clip (buf, sw->buf, ret);
798 721 sw->total_hw_samples_acquired += total;
799 722 return ret << sw->info.shift;
800 723 }
... ... @@ -802,27 +725,6 @@ int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int size)
802 725 /*
803 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 728 static int audio_pcm_hw_find_min_out (HWVoiceOut *hw, int *nb_livep)
827 729 {
828 730 SWVoiceOut *sw;
... ... @@ -876,66 +778,6 @@ int audio_pcm_hw_get_live_out (HWVoiceOut *hw)
876 778 /*
877 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 781 int audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int size)
940 782 {
941 783 int hwsamples, samples, isamp, osamp, wpos, live, dead, left, swlim, blck;
... ... @@ -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 1171 static struct audio_option audio_options[] = {
1320 1172 /* DAC */
1321 1173 {"DAC_FIXED_SETTINGS", AUD_OPT_BOOL, &conf.fixed_out.enabled,
... ... @@ -1356,13 +1208,31 @@ static struct audio_option audio_options[] = {
1356 1208 {"PLIVE", AUD_OPT_BOOL, &conf.plive,
1357 1209 "(undocumented)", NULL, 0},
1358 1210  
1359   -
1360 1211 {"LOG_TO_MONITOR", AUD_OPT_BOOL, &conf.log_to_monitor,
1361 1212 "print logging messages to montior instead of stderr", NULL, 0},
1362 1213  
1363 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 1236 void AUD_help (void)
1367 1237 {
1368 1238 size_t i;
... ... @@ -1387,37 +1257,8 @@ void AUD_help (void)
1387 1257 printf ("Name: %s\n", d->name);
1388 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 1263 if (d->options) {
1423 1264 printf ("Options:\n");
... ... @@ -1434,7 +1275,7 @@ void AUD_help (void)
1434 1275 "Example:\n"
1435 1276 #ifdef _WIN32
1436 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 1279 #else
1439 1280 " export QEMU_AUDIO_DRV=wav\n"
1440 1281 " export QEMU_WAV_PATH=$HOME/tune.wav\n"
... ... @@ -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 1288 static int audio_driver_init (AudioState *s, struct audio_driver *drv)
1458 1289 {
1459 1290 if (drv->options) {
... ... @@ -1462,62 +1293,8 @@ static int audio_driver_init (AudioState *s, struct audio_driver *drv)
1462 1293 s->drv_opaque = drv->init ();
1463 1294  
1464 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 1298 s->drv = drv;
1522 1299 return 0;
1523 1300 }
... ... @@ -1549,25 +1326,13 @@ static void audio_atexit (void)
1549 1326 HWVoiceOut *hwo = NULL;
1550 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 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 1336 hwi->pcm_ops->fini_in (hwi);
1572 1337 }
1573 1338  
... ... @@ -1616,21 +1381,31 @@ AudioState *AUD_init (void)
1616 1381 const char *drvname;
1617 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 1394 audio_process_options ("AUDIO", audio_options);
1620 1395  
1621 1396 s->nb_hw_voices_out = conf.fixed_out.nb_voices;
1622 1397 s->nb_hw_voices_in = conf.fixed_in.nb_voices;
1623 1398  
1624 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 1401 s->nb_hw_voices_out);
1627 1402 s->nb_hw_voices_out = 1;
1628 1403 }
1629 1404  
1630 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 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 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 1416 if (drvname) {
1648 1417 int found = 0;
1649 1418  
... ... @@ -1680,6 +1449,8 @@ AudioState *AUD_init (void)
1680 1449 }
1681 1450  
1682 1451 if (done) {
  1452 + VMChangeStateEntry *e;
  1453 +
1683 1454 if (conf.period.hz <= 0) {
1684 1455 if (conf.period.hz < 0) {
1685 1456 dolog ("warning: Timer period is negative - %d "
... ... @@ -1692,7 +1463,11 @@ AudioState *AUD_init (void)
1692 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 1472 else {
1698 1473 qemu_del_timer (s->ts);
... ... @@ -1701,7 +1476,6 @@ AudioState *AUD_init (void)
1701 1476  
1702 1477 LIST_INIT (&s->card_head);
1703 1478 register_savevm ("audio", 0, 1, audio_save, audio_load, s);
1704   - atexit (audio_atexit);
1705 1479 qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + conf.period.ticks);
1706 1480 return s;
1707 1481 }
... ...
audio/audio.h
... ... @@ -73,7 +73,8 @@ SWVoiceOut *AUD_open_out (
73 73 const char *name,
74 74 void *callback_opaque,
75 75 audio_callback_fn_t callback_fn,
76   - audsettings_t *settings
  76 + audsettings_t *settings,
  77 + int sw_endian
77 78 );
78 79  
79 80 void AUD_close_out (QEMUSoundCard *card, SWVoiceOut *sw);
... ... @@ -91,7 +92,8 @@ SWVoiceIn *AUD_open_in (
91 92 const char *name,
92 93 void *callback_opaque,
93 94 audio_callback_fn_t callback_fn,
94   - audsettings_t *settings
  95 + audsettings_t *settings,
  96 + int sw_endian
95 97 );
96 98  
97 99 void AUD_close_in (QEMUSoundCard *card, SWVoiceIn *sw);
... ...
audio/audio_int.h
... ... @@ -123,7 +123,7 @@ struct SWVoiceIn {
123 123 int64_t ratio;
124 124 void *rate;
125 125 int total_hw_samples_acquired;
126   - st_sample_t *conv_buf;
  126 + st_sample_t *buf;
127 127 f_sample *clip;
128 128 HWVoiceIn *hw;
129 129 char *name;
... ...
audio/audio_template.h
... ... @@ -23,52 +23,159 @@
23 23 */
24 24  
25 25 #ifdef DAC
  26 +#define NAME "playback"
  27 +#define HWBUF hw->mix_buf
26 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 31 #else
  32 +#define NAME "capture"
30 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 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 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 113 #ifdef DAC
53   - hw->clip =
54   - mixeng_clip
  114 + samples = sw->hw->samples;
55 115 #else
56   - hw->conv =
57   - mixeng_conv
  116 + samples = ((int64_t) sw->hw->samples << 32) / sw->ratio;
58 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 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 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 179 static void glue (audio_pcm_sw_fini_, TYPE) (SW *sw)
73 180 {
74 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 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 227 static HW *glue (audio_pcm_hw_find_specific_, TYPE) (
146 228 AudioState *s,
147 229 HW *hw,
... ... @@ -159,23 +241,63 @@ static HW *glue (audio_pcm_hw_find_specific_, TYPE) (
159 241 static HW *glue (audio_pcm_hw_add_new_, TYPE) (AudioState *s, audsettings_t *as)
160 242 {
161 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 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 328 static SW *glue (audio_pcm_create_voice_pair_, TYPE) (
207 329 AudioState *s,
208 330 const char *sw_name,
209   - audsettings_t *as
  331 + audsettings_t *as,
  332 + int sw_endian
210 333 )
211 334 {
212 335 SW *sw;
... ... @@ -234,7 +357,7 @@ static SW *glue (audio_pcm_create_voice_pair_, TYPE) (
234 357  
235 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 361 goto err3;
239 362 }
240 363  
... ... @@ -256,6 +379,7 @@ static void glue (audio_close_, TYPE) (AudioState *s, SW *sw)
256 379 glue (audio_pcm_hw_gc_, TYPE) (s, &sw->hw);
257 380 qemu_free (sw);
258 381 }
  382 +
259 383 void glue (AUD_close_, TYPE) (QEMUSoundCard *card, SW *sw)
260 384 {
261 385 if (sw) {
... ... @@ -275,7 +399,8 @@ SW *glue (AUD_open_, TYPE) (
275 399 const char *name,
276 400 void *callback_opaque ,
277 401 audio_callback_fn_t callback_fn,
278   - audsettings_t *as
  402 + audsettings_t *as,
  403 + int sw_endian
279 404 )
280 405 {
281 406 AudioState *s;
... ... @@ -347,15 +472,16 @@ SW *glue (AUD_open_, TYPE) (
347 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 477 goto fail;
352 478 }
353 479 }
354 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 482 if (!sw) {
357 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 561 #undef TYPE
436 562 #undef HW
437 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 75 {
76 76 va_list ap;
77 77  
  78 + va_start (ap, fmt);
78 79 AUD_vlog (AUDIO_CAP, fmt, ap);
  80 + va_end (ap);
79 81  
80   - va_start (ap, fmt);
81 82 AUD_log (AUDIO_CAP, "Reason: %s\n", strerror (err));
82   - va_end (ap);
83 83 }
84 84  
85 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 422 audfmt_e effective_fmt;
423 423 audsettings_t obt_as;
424 424  
  425 + oss->fd = -1;
  426 +
425 427 req.fmt = aud_to_ossfmt (as->fmt);
426 428 req.freq = as->freq;
427 429 req.nchannels = as->nchannels;
... ... @@ -565,6 +567,8 @@ static int oss_init_in (HWVoiceIn *hw, audsettings_t *as)
565 567 audfmt_e effective_fmt;
566 568 audsettings_t obt_as;
567 569  
  570 + oss->fd = -1;
  571 +
568 572 req.fmt = aud_to_ossfmt (as->fmt);
569 573 req.freq = as->freq;
570 574 req.nchannels = as->nchannels;
... ...