qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

Merge remote-tracking branch 'remotes/kraxel/tags/audio-20190821-pull-request' into staging

audio: second batch of -audiodev support, adding support for multiple backends.

# gpg: Signature made Wed 21 Aug 2019 09:40:37 BST
# gpg: using RSA key 4CB6D8EED3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" [full]
# gpg: aka "Gerd Hoffmann <gerd@kraxel.org>" [full]
# gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>" [full]
# Primary key fingerprint: A032 8CFF B93A 17A7 9901 FE7D 4CB6 D8EE D3E8 7138

* remotes/kraxel/tags/audio-20190821-pull-request:
audio: fix memory leak reported by ASAN
audio: use size_t where makes sense
audio: remove read and write pcm_ops
paaudio: fix playback glitches
audio: do not run each backend in audio_run
audio: remove audio_MIN, audio_MAX
paaudio: properly disconnect streams in fini_*
paaudio: do not move stream when sink/source name is specified
audio: audiodev= parameters no longer optional when -audiodev present
paaudio: prepare for multiple audiodev
audio: add audiodev properties to frontends
audio: add audiodev property to vnc and wav_capture
audio: basic support for multi backend audio
audio: reduce glob_audio_state usage
audio: Add missing fall through comments

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

+790 -651
+20 -29
audio/alsaaudio.c
··· 39 39 struct pollfd *pfds; 40 40 int count; 41 41 int mask; 42 + AudioState *s; 42 43 }; 43 44 44 45 typedef struct ALSAVoiceOut { ··· 199 200 break; 200 201 201 202 case SND_PCM_STATE_PREPARED: 202 - audio_run ("alsa run (prepared)"); 203 + audio_run(hlp->s, "alsa run (prepared)"); 203 204 break; 204 205 205 206 case SND_PCM_STATE_RUNNING: 206 - audio_run ("alsa run (running)"); 207 + audio_run(hlp->s, "alsa run (running)"); 207 208 break; 208 209 209 210 default: ··· 267 268 ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw; 268 269 269 270 return alsa_poll_helper (alsa->handle, &alsa->pollhlp, POLLIN); 270 - } 271 - 272 - static int alsa_write (SWVoiceOut *sw, void *buf, int len) 273 - { 274 - return audio_pcm_sw_write (sw, buf, len); 275 271 } 276 272 277 273 static snd_pcm_format_t aud_to_alsafmt (AudioFormat fmt, int endianness) ··· 634 630 635 631 while (alsa->pending) { 636 632 int left_till_end_samples = hw->samples - alsa->wpos; 637 - int len = audio_MIN (alsa->pending, left_till_end_samples); 633 + int len = MIN (alsa->pending, left_till_end_samples); 638 634 char *src = advance (alsa->pcm_buf, alsa->wpos << hw->info.shift); 639 635 640 636 while (len) { ··· 685 681 } 686 682 } 687 683 688 - static int alsa_run_out (HWVoiceOut *hw, int live) 684 + static size_t alsa_run_out(HWVoiceOut *hw, size_t live) 689 685 { 690 686 ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw; 691 - int decr; 687 + size_t decr; 692 688 snd_pcm_sframes_t avail; 693 689 694 690 avail = alsa_get_avail (alsa->handle); ··· 697 693 return 0; 698 694 } 699 695 700 - decr = audio_MIN (live, avail); 696 + decr = MIN (live, avail); 701 697 decr = audio_pcm_hw_clip_out (hw, alsa->pcm_buf, decr, alsa->pending); 702 698 alsa->pending += decr; 703 699 alsa_write_pending (alsa); ··· 743 739 744 740 alsa->pcm_buf = audio_calloc(__func__, obt.samples, 1 << hw->info.shift); 745 741 if (!alsa->pcm_buf) { 746 - dolog ("Could not allocate DAC buffer (%d samples, each %d bytes)\n", 747 - hw->samples, 1 << hw->info.shift); 742 + dolog("Could not allocate DAC buffer (%zu samples, each %d bytes)\n", 743 + hw->samples, 1 << hw->info.shift); 748 744 alsa_anal_close1 (&handle); 749 745 return -1; 750 746 } 751 747 748 + alsa->pollhlp.s = hw->s; 752 749 alsa->handle = handle; 753 750 alsa->dev = dev; 754 751 return 0; ··· 844 841 845 842 alsa->pcm_buf = audio_calloc(__func__, hw->samples, 1 << hw->info.shift); 846 843 if (!alsa->pcm_buf) { 847 - dolog ("Could not allocate ADC buffer (%d samples, each %d bytes)\n", 848 - hw->samples, 1 << hw->info.shift); 844 + dolog("Could not allocate ADC buffer (%zu samples, each %d bytes)\n", 845 + hw->samples, 1 << hw->info.shift); 849 846 alsa_anal_close1 (&handle); 850 847 return -1; 851 848 } 852 849 850 + alsa->pollhlp.s = hw->s; 853 851 alsa->handle = handle; 854 852 alsa->dev = dev; 855 853 return 0; ··· 865 863 alsa->pcm_buf = NULL; 866 864 } 867 865 868 - static int alsa_run_in (HWVoiceIn *hw) 866 + static size_t alsa_run_in(HWVoiceIn *hw) 869 867 { 870 868 ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw; 871 869 int hwshift = hw->info.shift; 872 870 int i; 873 - int live = audio_pcm_hw_get_live_in (hw); 874 - int dead = hw->samples - live; 875 - int decr; 871 + size_t live = audio_pcm_hw_get_live_in (hw); 872 + size_t dead = hw->samples - live; 873 + size_t decr; 876 874 struct { 877 - int add; 878 - int len; 875 + size_t add; 876 + size_t len; 879 877 } bufs[2] = { 880 878 { .add = hw->wpos, .len = 0 }, 881 879 { .add = 0, .len = 0 } ··· 915 913 } 916 914 } 917 915 918 - decr = audio_MIN (dead, avail); 916 + decr = MIN(dead, avail); 919 917 if (!decr) { 920 918 return 0; 921 919 } ··· 985 983 return read_samples; 986 984 } 987 985 988 - static int alsa_read (SWVoiceIn *sw, void *buf, int size) 989 - { 990 - return audio_pcm_sw_read (sw, buf, size); 991 - } 992 - 993 986 static int alsa_ctl_in (HWVoiceIn *hw, int cmd, ...) 994 987 { 995 988 ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw; ··· 1073 1066 .init_out = alsa_init_out, 1074 1067 .fini_out = alsa_fini_out, 1075 1068 .run_out = alsa_run_out, 1076 - .write = alsa_write, 1077 1069 .ctl_out = alsa_ctl_out, 1078 1070 1079 1071 .init_in = alsa_init_in, 1080 1072 .fini_in = alsa_fini_in, 1081 1073 .run_in = alsa_run_in, 1082 - .read = alsa_read, 1083 1074 .ctl_in = alsa_ctl_in, 1084 1075 }; 1085 1076
+201 -146
audio/audio.c
··· 87 87 return NULL; 88 88 } 89 89 90 - static AudioState glob_audio_state; 90 + static QTAILQ_HEAD(AudioStateHead, AudioState) audio_states = 91 + QTAILQ_HEAD_INITIALIZER(audio_states); 91 92 92 93 const struct mixeng_volume nominal_volume = { 93 94 .mute = 0, ··· 99 100 .l = 1ULL << 32, 100 101 #endif 101 102 }; 103 + 104 + static bool legacy_config = true; 102 105 103 106 #ifdef AUDIO_IS_FLAWLESS_AND_NO_CHECKS_ARE_REQURIED 104 107 #error No its not ··· 306 309 307 310 case AUDIO_FORMAT_S16: 308 311 sign = 1; 312 + /* fall through */ 309 313 case AUDIO_FORMAT_U16: 310 314 bits = 16; 311 315 shift = 1; ··· 313 317 314 318 case AUDIO_FORMAT_S32: 315 319 sign = 1; 320 + /* fall through */ 316 321 case AUDIO_FORMAT_U32: 317 322 bits = 32; 318 323 shift = 2; ··· 399 404 (void) samples; 400 405 } 401 406 402 - static CaptureVoiceOut *audio_pcm_capture_find_specific ( 403 - struct audsettings *as 404 - ) 407 + static CaptureVoiceOut *audio_pcm_capture_find_specific(AudioState *s, 408 + struct audsettings *as) 405 409 { 406 410 CaptureVoiceOut *cap; 407 - AudioState *s = &glob_audio_state; 408 411 409 412 for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) { 410 413 if (audio_pcm_info_eq (&cap->hw.info, as)) { ··· 481 484 482 485 static int audio_attach_capture (HWVoiceOut *hw) 483 486 { 484 - AudioState *s = &glob_audio_state; 487 + AudioState *s = hw->s; 485 488 CaptureVoiceOut *cap; 486 489 487 490 audio_detach_capture (hw); ··· 525 528 /* 526 529 * Hard voice (capture) 527 530 */ 528 - static int audio_pcm_hw_find_min_in (HWVoiceIn *hw) 531 + static size_t audio_pcm_hw_find_min_in (HWVoiceIn *hw) 529 532 { 530 533 SWVoiceIn *sw; 531 - int m = hw->total_samples_captured; 534 + size_t m = hw->total_samples_captured; 532 535 533 536 for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) { 534 537 if (sw->active) { 535 - m = audio_MIN (m, sw->total_hw_samples_acquired); 538 + m = MIN (m, sw->total_hw_samples_acquired); 536 539 } 537 540 } 538 541 return m; 539 542 } 540 543 541 - int audio_pcm_hw_get_live_in (HWVoiceIn *hw) 544 + size_t audio_pcm_hw_get_live_in(HWVoiceIn *hw) 542 545 { 543 - int live = hw->total_samples_captured - audio_pcm_hw_find_min_in (hw); 544 - if (audio_bug(__func__, live < 0 || live > hw->samples)) { 545 - dolog ("live=%d hw->samples=%d\n", live, hw->samples); 546 + size_t live = hw->total_samples_captured - audio_pcm_hw_find_min_in (hw); 547 + if (audio_bug(__func__, live > hw->samples)) { 548 + dolog("live=%zu hw->samples=%zu\n", live, hw->samples); 546 549 return 0; 547 550 } 548 551 return live; 549 552 } 550 553 551 - int audio_pcm_hw_clip_out (HWVoiceOut *hw, void *pcm_buf, 552 - int live, int pending) 554 + size_t audio_pcm_hw_clip_out(HWVoiceOut *hw, void *pcm_buf, 555 + size_t live, size_t pending) 553 556 { 554 - int left = hw->samples - pending; 555 - int len = audio_MIN (left, live); 556 - int clipped = 0; 557 + size_t left = hw->samples - pending; 558 + size_t len = MIN (left, live); 559 + size_t clipped = 0; 557 560 558 561 while (len) { 559 562 struct st_sample *src = hw->mix_buf + hw->rpos; 560 563 uint8_t *dst = advance (pcm_buf, hw->rpos << hw->info.shift); 561 - int samples_till_end_of_buf = hw->samples - hw->rpos; 562 - int samples_to_clip = audio_MIN (len, samples_till_end_of_buf); 564 + size_t samples_till_end_of_buf = hw->samples - hw->rpos; 565 + size_t samples_to_clip = MIN (len, samples_till_end_of_buf); 563 566 564 567 hw->clip (dst, src, samples_to_clip); 565 568 ··· 573 576 /* 574 577 * Soft voice (capture) 575 578 */ 576 - static int audio_pcm_sw_get_rpos_in (SWVoiceIn *sw) 579 + static size_t audio_pcm_sw_get_rpos_in(SWVoiceIn *sw) 577 580 { 578 581 HWVoiceIn *hw = sw->hw; 579 - int live = hw->total_samples_captured - sw->total_hw_samples_acquired; 580 - int rpos; 582 + ssize_t live = hw->total_samples_captured - sw->total_hw_samples_acquired; 583 + ssize_t rpos; 581 584 582 585 if (audio_bug(__func__, live < 0 || live > hw->samples)) { 583 - dolog ("live=%d hw->samples=%d\n", live, hw->samples); 586 + dolog("live=%zu hw->samples=%zu\n", live, hw->samples); 584 587 return 0; 585 588 } 586 589 ··· 593 596 } 594 597 } 595 598 596 - int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int size) 599 + static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t size) 597 600 { 598 601 HWVoiceIn *hw = sw->hw; 599 - int samples, live, ret = 0, swlim, isamp, osamp, rpos, total = 0; 602 + size_t samples, live, ret = 0, swlim, isamp, osamp, rpos, total = 0; 600 603 struct st_sample *src, *dst = sw->buf; 601 604 602 605 rpos = audio_pcm_sw_get_rpos_in (sw) % hw->samples; 603 606 604 607 live = hw->total_samples_captured - sw->total_hw_samples_acquired; 605 - if (audio_bug(__func__, live < 0 || live > hw->samples)) { 606 - dolog ("live_in=%d hw->samples=%d\n", live, hw->samples); 608 + if (audio_bug(__func__, live > hw->samples)) { 609 + dolog("live_in=%zu hw->samples=%zu\n", live, hw->samples); 607 610 return 0; 608 611 } 609 612 ··· 613 616 } 614 617 615 618 swlim = (live * sw->ratio) >> 32; 616 - swlim = audio_MIN (swlim, samples); 619 + swlim = MIN (swlim, samples); 617 620 618 621 while (swlim) { 619 622 src = hw->conv_buf + rpos; 620 - isamp = hw->wpos - rpos; 621 - /* XXX: <= ? */ 622 - if (isamp <= 0) { 623 + if (hw->wpos > rpos) { 624 + isamp = hw->wpos - rpos; 625 + } else { 623 626 isamp = hw->samples - rpos; 624 627 } 625 628 ··· 627 630 break; 628 631 } 629 632 osamp = swlim; 630 - 631 - if (audio_bug(__func__, osamp < 0)) { 632 - dolog ("osamp=%d\n", osamp); 633 - return 0; 634 - } 635 633 636 634 st_rate_flow (sw->rate, src, dst, &isamp, &osamp); 637 635 swlim -= osamp; ··· 653 651 /* 654 652 * Hard voice (playback) 655 653 */ 656 - static int audio_pcm_hw_find_min_out (HWVoiceOut *hw, int *nb_livep) 654 + static size_t audio_pcm_hw_find_min_out (HWVoiceOut *hw, int *nb_livep) 657 655 { 658 656 SWVoiceOut *sw; 659 - int m = INT_MAX; 657 + size_t m = SIZE_MAX; 660 658 int nb_live = 0; 661 659 662 660 for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) { 663 661 if (sw->active || !sw->empty) { 664 - m = audio_MIN (m, sw->total_hw_samples_mixed); 662 + m = MIN (m, sw->total_hw_samples_mixed); 665 663 nb_live += 1; 666 664 } 667 665 } ··· 670 668 return m; 671 669 } 672 670 673 - static int audio_pcm_hw_get_live_out (HWVoiceOut *hw, int *nb_live) 671 + static size_t audio_pcm_hw_get_live_out (HWVoiceOut *hw, int *nb_live) 674 672 { 675 - int smin; 673 + size_t smin; 676 674 int nb_live1; 677 675 678 676 smin = audio_pcm_hw_find_min_out (hw, &nb_live1); ··· 681 679 } 682 680 683 681 if (nb_live1) { 684 - int live = smin; 682 + size_t live = smin; 685 683 686 - if (audio_bug(__func__, live < 0 || live > hw->samples)) { 687 - dolog ("live=%d hw->samples=%d\n", live, hw->samples); 684 + if (audio_bug(__func__, live > hw->samples)) { 685 + dolog("live=%zu hw->samples=%zu\n", live, hw->samples); 688 686 return 0; 689 687 } 690 688 return live; ··· 695 693 /* 696 694 * Soft voice (playback) 697 695 */ 698 - int audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int size) 696 + static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t size) 699 697 { 700 - int hwsamples, samples, isamp, osamp, wpos, live, dead, left, swlim, blck; 701 - int ret = 0, pos = 0, total = 0; 698 + size_t hwsamples, samples, isamp, osamp, wpos, live, dead, left, swlim, blck; 699 + size_t ret = 0, pos = 0, total = 0; 702 700 703 701 if (!sw) { 704 702 return size; ··· 707 705 hwsamples = sw->hw->samples; 708 706 709 707 live = sw->total_hw_samples_mixed; 710 - if (audio_bug(__func__, live < 0 || live > hwsamples)) { 711 - dolog ("live=%d hw->samples=%d\n", live, hwsamples); 708 + if (audio_bug(__func__, live > hwsamples)) { 709 + dolog("live=%zu hw->samples=%zu\n", live, hwsamples); 712 710 return 0; 713 711 } 714 712 ··· 724 722 725 723 dead = hwsamples - live; 726 724 swlim = ((int64_t) dead << 32) / sw->ratio; 727 - swlim = audio_MIN (swlim, samples); 725 + swlim = MIN (swlim, samples); 728 726 if (swlim) { 729 727 sw->conv (sw->buf, buf, swlim); 730 728 ··· 736 734 while (swlim) { 737 735 dead = hwsamples - live; 738 736 left = hwsamples - wpos; 739 - blck = audio_MIN (dead, left); 737 + blck = MIN (dead, left); 740 738 if (!blck) { 741 739 break; 742 740 } ··· 762 760 763 761 #ifdef DEBUG_OUT 764 762 dolog ( 765 - "%s: write size %d ret %d total sw %d\n", 763 + "%s: write size %zu ret %zu total sw %zu\n", 766 764 SW_NAME (sw), 767 765 size >> sw->info.shift, 768 766 ret, ··· 789 787 /* 790 788 * Timer 791 789 */ 792 - 793 - static bool audio_timer_running; 794 - static uint64_t audio_timer_last; 795 - 796 - static int audio_is_timer_needed (void) 790 + static int audio_is_timer_needed(AudioState *s) 797 791 { 798 792 HWVoiceIn *hwi = NULL; 799 793 HWVoiceOut *hwo = NULL; 800 794 801 - while ((hwo = audio_pcm_hw_find_any_enabled_out (hwo))) { 795 + while ((hwo = audio_pcm_hw_find_any_enabled_out(s, hwo))) { 802 796 if (!hwo->poll_mode) return 1; 803 797 } 804 - while ((hwi = audio_pcm_hw_find_any_enabled_in (hwi))) { 798 + while ((hwi = audio_pcm_hw_find_any_enabled_in(s, hwi))) { 805 799 if (!hwi->poll_mode) return 1; 806 800 } 807 801 return 0; ··· 809 803 810 804 static void audio_reset_timer (AudioState *s) 811 805 { 812 - if (audio_is_timer_needed ()) { 806 + if (audio_is_timer_needed(s)) { 813 807 timer_mod_anticipate_ns(s->ts, 814 808 qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->period_ticks); 815 - if (!audio_timer_running) { 816 - audio_timer_running = true; 817 - audio_timer_last = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 809 + if (!s->timer_running) { 810 + s->timer_running = true; 811 + s->timer_last = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 818 812 trace_audio_timer_start(s->period_ticks / SCALE_MS); 819 813 } 820 814 } else { 821 815 timer_del(s->ts); 822 - if (audio_timer_running) { 823 - audio_timer_running = false; 816 + if (s->timer_running) { 817 + s->timer_running = false; 824 818 trace_audio_timer_stop(); 825 819 } 826 820 } ··· 832 826 AudioState *s = opaque; 833 827 834 828 now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 835 - diff = now - audio_timer_last; 829 + diff = now - s->timer_last; 836 830 if (diff > s->period_ticks * 3 / 2) { 837 831 trace_audio_timer_delayed(diff / SCALE_MS); 838 832 } 839 - audio_timer_last = now; 833 + s->timer_last = now; 840 834 841 - audio_run("timer"); 835 + audio_run(s, "timer"); 842 836 audio_reset_timer(s); 843 837 } 844 838 845 839 /* 846 840 * Public API 847 841 */ 848 - int AUD_write (SWVoiceOut *sw, void *buf, int size) 842 + size_t AUD_write(SWVoiceOut *sw, void *buf, size_t size) 849 843 { 850 844 if (!sw) { 851 845 /* XXX: Consider options */ ··· 857 851 return 0; 858 852 } 859 853 860 - return sw->hw->pcm_ops->write(sw, buf, size); 854 + return audio_pcm_sw_write(sw, buf, size); 861 855 } 862 856 863 - int AUD_read (SWVoiceIn *sw, void *buf, int size) 857 + size_t AUD_read(SWVoiceIn *sw, void *buf, size_t size) 864 858 { 865 859 if (!sw) { 866 860 /* XXX: Consider options */ ··· 872 866 return 0; 873 867 } 874 868 875 - return sw->hw->pcm_ops->read(sw, buf, size); 869 + return audio_pcm_sw_read(sw, buf, size); 876 870 } 877 871 878 872 int AUD_get_buffer_size_out (SWVoiceOut *sw) ··· 890 884 891 885 hw = sw->hw; 892 886 if (sw->active != on) { 893 - AudioState *s = &glob_audio_state; 887 + AudioState *s = sw->s; 894 888 SWVoiceOut *temp_sw; 895 889 SWVoiceCap *sc; 896 890 ··· 937 931 938 932 hw = sw->hw; 939 933 if (sw->active != on) { 940 - AudioState *s = &glob_audio_state; 934 + AudioState *s = sw->s; 941 935 SWVoiceIn *temp_sw; 942 936 943 937 if (on) { ··· 969 963 } 970 964 } 971 965 972 - static int audio_get_avail (SWVoiceIn *sw) 966 + static size_t audio_get_avail (SWVoiceIn *sw) 973 967 { 974 - int live; 968 + size_t live; 975 969 976 970 if (!sw) { 977 971 return 0; 978 972 } 979 973 980 974 live = sw->hw->total_samples_captured - sw->total_hw_samples_acquired; 981 - if (audio_bug(__func__, live < 0 || live > sw->hw->samples)) { 982 - dolog ("live=%d sw->hw->samples=%d\n", live, sw->hw->samples); 975 + if (audio_bug(__func__, live > sw->hw->samples)) { 976 + dolog("live=%zu sw->hw->samples=%zu\n", live, sw->hw->samples); 983 977 return 0; 984 978 } 985 979 ··· 992 986 return (((int64_t) live << 32) / sw->ratio) << sw->info.shift; 993 987 } 994 988 995 - static int audio_get_free (SWVoiceOut *sw) 989 + static size_t audio_get_free(SWVoiceOut *sw) 996 990 { 997 - int live, dead; 991 + size_t live, dead; 998 992 999 993 if (!sw) { 1000 994 return 0; ··· 1002 996 1003 997 live = sw->total_hw_samples_mixed; 1004 998 1005 - if (audio_bug(__func__, live < 0 || live > sw->hw->samples)) { 1006 - dolog ("live=%d sw->hw->samples=%d\n", live, sw->hw->samples); 999 + if (audio_bug(__func__, live > sw->hw->samples)) { 1000 + dolog("live=%zu sw->hw->samples=%zu\n", live, sw->hw->samples); 1007 1001 return 0; 1008 1002 } 1009 1003 ··· 1018 1012 return (((int64_t) dead << 32) / sw->ratio) << sw->info.shift; 1019 1013 } 1020 1014 1021 - static void audio_capture_mix_and_clear (HWVoiceOut *hw, int rpos, int samples) 1015 + static void audio_capture_mix_and_clear(HWVoiceOut *hw, size_t rpos, 1016 + size_t samples) 1022 1017 { 1023 - int n; 1018 + size_t n; 1024 1019 1025 1020 if (hw->enabled) { 1026 1021 SWVoiceCap *sc; ··· 1031 1026 1032 1027 n = samples; 1033 1028 while (n) { 1034 - int till_end_of_hw = hw->samples - rpos2; 1035 - int to_write = audio_MIN (till_end_of_hw, n); 1036 - int bytes = to_write << hw->info.shift; 1037 - int written; 1029 + size_t till_end_of_hw = hw->samples - rpos2; 1030 + size_t to_write = MIN(till_end_of_hw, n); 1031 + size_t bytes = to_write << hw->info.shift; 1032 + size_t written; 1038 1033 1039 1034 sw->buf = hw->mix_buf + rpos2; 1040 1035 written = audio_pcm_sw_write (sw, NULL, bytes); 1041 1036 if (written - bytes) { 1042 - dolog ("Could not mix %d bytes into a capture " 1043 - "buffer, mixed %d\n", 1044 - bytes, written); 1037 + dolog("Could not mix %zu bytes into a capture " 1038 + "buffer, mixed %zu\n", 1039 + bytes, written); 1045 1040 break; 1046 1041 } 1047 1042 n -= to_write; ··· 1050 1045 } 1051 1046 } 1052 1047 1053 - n = audio_MIN (samples, hw->samples - rpos); 1054 - mixeng_clear (hw->mix_buf + rpos, n); 1055 - mixeng_clear (hw->mix_buf, samples - n); 1048 + n = MIN(samples, hw->samples - rpos); 1049 + mixeng_clear(hw->mix_buf + rpos, n); 1050 + mixeng_clear(hw->mix_buf, samples - n); 1056 1051 } 1057 1052 1058 1053 static void audio_run_out (AudioState *s) ··· 1060 1055 HWVoiceOut *hw = NULL; 1061 1056 SWVoiceOut *sw; 1062 1057 1063 - while ((hw = audio_pcm_hw_find_any_enabled_out (hw))) { 1064 - int played; 1065 - int live, free, nb_live, cleanup_required, prev_rpos; 1058 + while ((hw = audio_pcm_hw_find_any_enabled_out(s, hw))) { 1059 + size_t played, live, prev_rpos, free; 1060 + int nb_live, cleanup_required; 1066 1061 1067 1062 live = audio_pcm_hw_get_live_out (hw, &nb_live); 1068 1063 if (!nb_live) { 1069 1064 live = 0; 1070 1065 } 1071 1066 1072 - if (audio_bug(__func__, live < 0 || live > hw->samples)) { 1073 - dolog ("live=%d hw->samples=%d\n", live, hw->samples); 1067 + if (audio_bug(__func__, live > hw->samples)) { 1068 + dolog ("live=%zu hw->samples=%zu\n", live, hw->samples); 1074 1069 continue; 1075 1070 } 1076 1071 ··· 1105 1100 played = hw->pcm_ops->run_out (hw, live); 1106 1101 replay_audio_out(&played); 1107 1102 if (audio_bug(__func__, hw->rpos >= hw->samples)) { 1108 - dolog ("hw->rpos=%d hw->samples=%d played=%d\n", 1109 - hw->rpos, hw->samples, played); 1103 + dolog("hw->rpos=%zu hw->samples=%zu played=%zu\n", 1104 + hw->rpos, hw->samples, played); 1110 1105 hw->rpos = 0; 1111 1106 } 1112 1107 1113 1108 #ifdef DEBUG_OUT 1114 - dolog ("played=%d\n", played); 1109 + dolog("played=%zu\n", played); 1115 1110 #endif 1116 1111 1117 1112 if (played) { ··· 1126 1121 } 1127 1122 1128 1123 if (audio_bug(__func__, played > sw->total_hw_samples_mixed)) { 1129 - dolog ("played=%d sw->total_hw_samples_mixed=%d\n", 1130 - played, sw->total_hw_samples_mixed); 1124 + dolog("played=%zu sw->total_hw_samples_mixed=%zu\n", 1125 + played, sw->total_hw_samples_mixed); 1131 1126 played = sw->total_hw_samples_mixed; 1132 1127 } 1133 1128 ··· 1165 1160 { 1166 1161 HWVoiceIn *hw = NULL; 1167 1162 1168 - while ((hw = audio_pcm_hw_find_any_enabled_in (hw))) { 1163 + while ((hw = audio_pcm_hw_find_any_enabled_in(s, hw))) { 1169 1164 SWVoiceIn *sw; 1170 - int captured = 0, min; 1165 + size_t captured = 0, min; 1171 1166 1172 1167 if (replay_mode != REPLAY_MODE_PLAY) { 1173 1168 captured = hw->pcm_ops->run_in(hw); ··· 1182 1177 sw->total_hw_samples_acquired -= min; 1183 1178 1184 1179 if (sw->active) { 1185 - int avail; 1180 + size_t avail; 1186 1181 1187 1182 avail = audio_get_avail (sw); 1188 1183 if (avail > 0) { ··· 1198 1193 CaptureVoiceOut *cap; 1199 1194 1200 1195 for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) { 1201 - int live, rpos, captured; 1196 + size_t live, rpos, captured; 1202 1197 HWVoiceOut *hw = &cap->hw; 1203 1198 SWVoiceOut *sw; 1204 1199 1205 1200 captured = live = audio_pcm_hw_get_live_out (hw, NULL); 1206 1201 rpos = hw->rpos; 1207 1202 while (live) { 1208 - int left = hw->samples - rpos; 1209 - int to_capture = audio_MIN (live, left); 1203 + size_t left = hw->samples - rpos; 1204 + size_t to_capture = MIN(live, left); 1210 1205 struct st_sample *src; 1211 1206 struct capture_callback *cb; 1212 1207 ··· 1229 1224 } 1230 1225 1231 1226 if (audio_bug(__func__, captured > sw->total_hw_samples_mixed)) { 1232 - dolog ("captured=%d sw->total_hw_samples_mixed=%d\n", 1233 - captured, sw->total_hw_samples_mixed); 1227 + dolog("captured=%zu sw->total_hw_samples_mixed=%zu\n", 1228 + captured, sw->total_hw_samples_mixed); 1234 1229 captured = sw->total_hw_samples_mixed; 1235 1230 } 1236 1231 ··· 1240 1235 } 1241 1236 } 1242 1237 1243 - void audio_run (const char *msg) 1238 + void audio_run(AudioState *s, const char *msg) 1244 1239 { 1245 - AudioState *s = &glob_audio_state; 1240 + audio_run_out(s); 1241 + audio_run_in(s); 1242 + audio_run_capture(s); 1246 1243 1247 - audio_run_out (s); 1248 - audio_run_in (s); 1249 - audio_run_capture (s); 1250 1244 #ifdef DEBUG_POLL 1251 1245 { 1252 1246 static double prevtime; ··· 1271 1265 s->drv_opaque = drv->init(dev); 1272 1266 1273 1267 if (s->drv_opaque) { 1274 - audio_init_nb_voices_out (drv); 1275 - audio_init_nb_voices_in (drv); 1268 + audio_init_nb_voices_out(s, drv); 1269 + audio_init_nb_voices_in(s, drv); 1276 1270 s->drv = drv; 1277 1271 return 0; 1278 1272 } ··· 1293 1287 int op = running ? VOICE_ENABLE : VOICE_DISABLE; 1294 1288 1295 1289 s->vm_running = running; 1296 - while ((hwo = audio_pcm_hw_find_any_enabled_out (hwo))) { 1290 + while ((hwo = audio_pcm_hw_find_any_enabled_out(s, hwo))) { 1297 1291 hwo->pcm_ops->ctl_out(hwo, op); 1298 1292 } 1299 1293 1300 - while ((hwi = audio_pcm_hw_find_any_enabled_in (hwi))) { 1294 + while ((hwi = audio_pcm_hw_find_any_enabled_in(s, hwi))) { 1301 1295 hwi->pcm_ops->ctl_in(hwi, op); 1302 1296 } 1303 1297 audio_reset_timer (s); ··· 1310 1304 return is_cleaning_up; 1311 1305 } 1312 1306 1313 - void audio_cleanup(void) 1307 + static void free_audio_state(AudioState *s) 1314 1308 { 1315 - AudioState *s = &glob_audio_state; 1316 1309 HWVoiceOut *hwo, *hwon; 1317 1310 HWVoiceIn *hwi, *hwin; 1318 1311 1319 - is_cleaning_up = true; 1320 - QLIST_FOREACH_SAFE(hwo, &glob_audio_state.hw_head_out, entries, hwon) { 1312 + QLIST_FOREACH_SAFE(hwo, &s->hw_head_out, entries, hwon) { 1321 1313 SWVoiceCap *sc; 1322 1314 1323 1315 if (hwo->enabled) { ··· 1336 1328 QLIST_REMOVE(hwo, entries); 1337 1329 } 1338 1330 1339 - QLIST_FOREACH_SAFE(hwi, &glob_audio_state.hw_head_in, entries, hwin) { 1331 + QLIST_FOREACH_SAFE(hwi, &s->hw_head_in, entries, hwin) { 1340 1332 if (hwi->enabled) { 1341 1333 hwi->pcm_ops->ctl_in (hwi, VOICE_DISABLE); 1342 1334 } ··· 1353 1345 qapi_free_Audiodev(s->dev); 1354 1346 s->dev = NULL; 1355 1347 } 1348 + 1349 + if (s->ts) { 1350 + timer_free(s->ts); 1351 + s->ts = NULL; 1352 + } 1353 + 1354 + g_free(s); 1355 + } 1356 + 1357 + void audio_cleanup(void) 1358 + { 1359 + is_cleaning_up = true; 1360 + while (!QTAILQ_EMPTY(&audio_states)) { 1361 + AudioState *s = QTAILQ_FIRST(&audio_states); 1362 + QTAILQ_REMOVE(&audio_states, s, list); 1363 + free_audio_state(s); 1364 + } 1356 1365 } 1357 1366 1358 1367 static const VMStateDescription vmstate_audio = { ··· 1379 1388 return NULL; 1380 1389 } 1381 1390 1382 - static int audio_init(Audiodev *dev) 1391 + /* 1392 + * if we have dev, this function was called because of an -audiodev argument => 1393 + * initialize a new state with it 1394 + * if dev == NULL => legacy implicit initialization, return the already created 1395 + * state or create a new one 1396 + */ 1397 + static AudioState *audio_init(Audiodev *dev, const char *name) 1383 1398 { 1399 + static bool atexit_registered; 1384 1400 size_t i; 1385 1401 int done = 0; 1386 1402 const char *drvname = NULL; 1387 1403 VMChangeStateEntry *e; 1388 - AudioState *s = &glob_audio_state; 1404 + AudioState *s; 1389 1405 struct audio_driver *driver; 1390 1406 /* silence gcc warning about uninitialized variable */ 1391 1407 AudiodevListHead head = QSIMPLEQ_HEAD_INITIALIZER(head); 1392 1408 1393 - if (s->drv) { 1394 - if (dev) { 1395 - dolog("Cannot create more than one audio backend, sorry\n"); 1396 - qapi_free_Audiodev(dev); 1397 - } 1398 - return -1; 1399 - } 1400 - 1401 1409 if (dev) { 1402 1410 /* -audiodev option */ 1411 + legacy_config = false; 1403 1412 drvname = AudiodevDriver_str(dev->driver); 1413 + } else if (!QTAILQ_EMPTY(&audio_states)) { 1414 + if (!legacy_config) { 1415 + dolog("You must specify an audiodev= for the device %s\n", name); 1416 + exit(1); 1417 + } 1418 + return QTAILQ_FIRST(&audio_states); 1404 1419 } else { 1405 1420 /* legacy implicit initialization */ 1406 1421 head = audio_handle_legacy_opts(); ··· 1414 1429 dev = QSIMPLEQ_FIRST(&head)->dev; 1415 1430 audio_validate_opts(dev, &error_abort); 1416 1431 } 1432 + 1433 + s = g_malloc0(sizeof(AudioState)); 1417 1434 s->dev = dev; 1418 1435 1419 1436 QLIST_INIT (&s->hw_head_out); 1420 1437 QLIST_INIT (&s->hw_head_in); 1421 1438 QLIST_INIT (&s->cap_head); 1422 - atexit(audio_cleanup); 1439 + if (!atexit_registered) { 1440 + atexit(audio_cleanup); 1441 + atexit_registered = true; 1442 + } 1443 + QTAILQ_INSERT_TAIL(&audio_states, s, list); 1423 1444 1424 1445 s->ts = timer_new_ns(QEMU_CLOCK_VIRTUAL, audio_timer, s); 1425 1446 ··· 1484 1505 1485 1506 QLIST_INIT (&s->card_head); 1486 1507 vmstate_register (NULL, 0, &vmstate_audio, s); 1487 - return 0; 1508 + return s; 1488 1509 } 1489 1510 1490 1511 void audio_free_audiodev_list(AudiodevListHead *head) ··· 1499 1520 1500 1521 void AUD_register_card (const char *name, QEMUSoundCard *card) 1501 1522 { 1502 - audio_init(NULL); 1523 + if (!card->state) { 1524 + card->state = audio_init(NULL, name); 1525 + } 1526 + 1503 1527 card->name = g_strdup (name); 1504 1528 memset (&card->entries, 0, sizeof (card->entries)); 1505 - QLIST_INSERT_HEAD (&glob_audio_state.card_head, card, entries); 1529 + QLIST_INSERT_HEAD(&card->state->card_head, card, entries); 1506 1530 } 1507 1531 1508 1532 void AUD_remove_card (QEMUSoundCard *card) ··· 1512 1536 } 1513 1537 1514 1538 1515 - CaptureVoiceOut *AUD_add_capture ( 1539 + CaptureVoiceOut *AUD_add_capture( 1540 + AudioState *s, 1516 1541 struct audsettings *as, 1517 1542 struct audio_capture_ops *ops, 1518 1543 void *cb_opaque 1519 1544 ) 1520 1545 { 1521 - AudioState *s = &glob_audio_state; 1522 1546 CaptureVoiceOut *cap; 1523 1547 struct capture_callback *cb; 1524 1548 1549 + if (!s) { 1550 + if (!legacy_config) { 1551 + dolog("You must specify audiodev when trying to capture\n"); 1552 + return NULL; 1553 + } 1554 + s = audio_init(NULL, NULL); 1555 + } 1556 + 1525 1557 if (audio_validate_settings (as)) { 1526 1558 dolog ("Invalid settings were passed when trying to add capture\n"); 1527 1559 audio_print_settings (as); ··· 1532 1564 cb->ops = *ops; 1533 1565 cb->opaque = cb_opaque; 1534 1566 1535 - cap = audio_pcm_capture_find_specific (as); 1567 + cap = audio_pcm_capture_find_specific(s, as); 1536 1568 if (cap) { 1537 1569 QLIST_INSERT_HEAD (&cap->cb_head, cb, entries); 1538 1570 return cap; ··· 1544 1576 cap = g_malloc0(sizeof(*cap)); 1545 1577 1546 1578 hw = &cap->hw; 1579 + hw->s = s; 1547 1580 QLIST_INIT (&hw->sw_head); 1548 1581 QLIST_INIT (&cap->cb_head); 1549 1582 ··· 1564 1597 QLIST_INSERT_HEAD (&s->cap_head, cap, entries); 1565 1598 QLIST_INSERT_HEAD (&cap->cb_head, cb, entries); 1566 1599 1567 - QLIST_FOREACH(hw, &glob_audio_state.hw_head_out, entries) { 1600 + QLIST_FOREACH(hw, &s->hw_head_out, entries) { 1568 1601 audio_attach_capture (hw); 1569 1602 } 1570 1603 return cap; ··· 1749 1782 AudiodevListEntry *e; 1750 1783 1751 1784 QSIMPLEQ_FOREACH(e, &audiodevs, next) { 1752 - audio_init(e->dev); 1785 + audio_init(e->dev, NULL); 1753 1786 } 1754 1787 } 1755 1788 ··· 1810 1843 return audio_buffer_samples(pdo, as, def_usecs) * 1811 1844 audioformat_bytes_per_sample(as->fmt); 1812 1845 } 1846 + 1847 + AudioState *audio_state_by_name(const char *name) 1848 + { 1849 + AudioState *s; 1850 + QTAILQ_FOREACH(s, &audio_states, list) { 1851 + assert(s->dev); 1852 + if (strcmp(name, s->dev->id) == 0) { 1853 + return s; 1854 + } 1855 + } 1856 + return NULL; 1857 + } 1858 + 1859 + const char *audio_get_id(QEMUSoundCard *card) 1860 + { 1861 + if (card->state) { 1862 + assert(card->state->dev); 1863 + return card->state->dev->id; 1864 + } else { 1865 + return ""; 1866 + } 1867 + }
+15 -22
audio/audio.h
··· 27 27 28 28 #include "qemu/queue.h" 29 29 #include "qapi/qapi-types-audio.h" 30 + #include "hw/qdev-properties.h" 30 31 31 32 typedef void (*audio_callback_fn) (void *opaque, int avail); 32 33 ··· 78 79 typedef struct CaptureVoiceOut CaptureVoiceOut; 79 80 typedef struct SWVoiceIn SWVoiceIn; 80 81 82 + typedef struct AudioState AudioState; 81 83 typedef struct QEMUSoundCard { 82 84 char *name; 85 + AudioState *state; 83 86 QLIST_ENTRY (QEMUSoundCard) entries; 84 87 } QEMUSoundCard; 85 88 ··· 92 95 93 96 void AUD_register_card (const char *name, QEMUSoundCard *card); 94 97 void AUD_remove_card (QEMUSoundCard *card); 95 - CaptureVoiceOut *AUD_add_capture ( 98 + CaptureVoiceOut *AUD_add_capture( 99 + AudioState *s, 96 100 struct audsettings *as, 97 101 struct audio_capture_ops *ops, 98 102 void *opaque ··· 109 113 ); 110 114 111 115 void AUD_close_out (QEMUSoundCard *card, SWVoiceOut *sw); 112 - int AUD_write (SWVoiceOut *sw, void *pcm_buf, int size); 116 + size_t AUD_write (SWVoiceOut *sw, void *pcm_buf, size_t size); 113 117 int AUD_get_buffer_size_out (SWVoiceOut *sw); 114 118 void AUD_set_active_out (SWVoiceOut *sw, int on); 115 119 int AUD_is_active_out (SWVoiceOut *sw); ··· 130 134 ); 131 135 132 136 void AUD_close_in (QEMUSoundCard *card, SWVoiceIn *sw); 133 - int AUD_read (SWVoiceIn *sw, void *pcm_buf, int size); 137 + size_t AUD_read (SWVoiceIn *sw, void *pcm_buf, size_t size); 134 138 void AUD_set_active_in (SWVoiceIn *sw, int on); 135 139 int AUD_is_active_in (SWVoiceIn *sw); 136 140 ··· 143 147 return (d + incr); 144 148 } 145 149 146 - #ifdef __GNUC__ 147 - #define audio_MIN(a, b) ( __extension__ ({ \ 148 - __typeof (a) ta = a; \ 149 - __typeof (b) tb = b; \ 150 - ((ta)>(tb)?(tb):(ta)); \ 151 - })) 152 - 153 - #define audio_MAX(a, b) ( __extension__ ({ \ 154 - __typeof (a) ta = a; \ 155 - __typeof (b) tb = b; \ 156 - ((ta)<(tb)?(tb):(ta)); \ 157 - })) 158 - #else 159 - #define audio_MIN(a, b) ((a)>(b)?(b):(a)) 160 - #define audio_MAX(a, b) ((a)<(b)?(b):(a)) 161 - #endif 162 - 163 - int wav_start_capture (CaptureState *s, const char *path, int freq, 164 - int bits, int nchannels); 150 + int wav_start_capture(AudioState *state, CaptureState *s, const char *path, 151 + int freq, int bits, int nchannels); 165 152 166 153 bool audio_is_cleaning_up(void); 167 154 void audio_cleanup(void); ··· 174 161 void audio_parse_option(const char *opt); 175 162 void audio_init_audiodevs(void); 176 163 void audio_legacy_help(void); 164 + 165 + AudioState *audio_state_by_name(const char *name); 166 + const char *audio_get_id(QEMUSoundCard *card); 167 + 168 + #define DEFINE_AUDIO_PROPERTIES(_s, _f) \ 169 + DEFINE_PROP_AUDIODEV("audiodev", _s, _f) 177 170 178 171 #endif /* QEMU_AUDIO_H */
+24 -19
audio/audio_int.h
··· 49 49 int swap_endianness; 50 50 }; 51 51 52 + typedef struct AudioState AudioState; 52 53 typedef struct SWVoiceCap SWVoiceCap; 53 54 54 55 typedef struct HWVoiceOut { 56 + AudioState *s; 55 57 int enabled; 56 58 int poll_mode; 57 59 int pending_disable; ··· 59 61 60 62 f_sample *clip; 61 63 62 - int rpos; 64 + size_t rpos; 63 65 uint64_t ts_helper; 64 66 65 67 struct st_sample *mix_buf; 66 68 67 - int samples; 69 + size_t samples; 68 70 QLIST_HEAD (sw_out_listhead, SWVoiceOut) sw_head; 69 71 QLIST_HEAD (sw_cap_listhead, SWVoiceCap) cap_head; 70 72 int ctl_caps; ··· 73 75 } HWVoiceOut; 74 76 75 77 typedef struct HWVoiceIn { 78 + AudioState *s; 76 79 int enabled; 77 80 int poll_mode; 78 81 struct audio_pcm_info info; 79 82 80 83 t_sample *conv; 81 84 82 - int wpos; 83 - int total_samples_captured; 85 + size_t wpos; 86 + size_t total_samples_captured; 84 87 uint64_t ts_helper; 85 88 86 89 struct st_sample *conv_buf; 87 90 88 - int samples; 91 + size_t samples; 89 92 QLIST_HEAD (sw_in_listhead, SWVoiceIn) sw_head; 90 93 int ctl_caps; 91 94 struct audio_pcm_ops *pcm_ops; ··· 94 97 95 98 struct SWVoiceOut { 96 99 QEMUSoundCard *card; 100 + AudioState *s; 97 101 struct audio_pcm_info info; 98 102 t_sample *conv; 99 103 int64_t ratio; 100 104 struct st_sample *buf; 101 105 void *rate; 102 - int total_hw_samples_mixed; 106 + size_t total_hw_samples_mixed; 103 107 int active; 104 108 int empty; 105 109 HWVoiceOut *hw; ··· 111 115 112 116 struct SWVoiceIn { 113 117 QEMUSoundCard *card; 118 + AudioState *s; 114 119 int active; 115 120 struct audio_pcm_info info; 116 121 int64_t ratio; 117 122 void *rate; 118 - int total_hw_samples_acquired; 123 + size_t total_hw_samples_acquired; 119 124 struct st_sample *buf; 120 125 f_sample *clip; 121 126 HWVoiceIn *hw; ··· 144 149 struct audio_pcm_ops { 145 150 int (*init_out)(HWVoiceOut *hw, struct audsettings *as, void *drv_opaque); 146 151 void (*fini_out)(HWVoiceOut *hw); 147 - int (*run_out) (HWVoiceOut *hw, int live); 148 - int (*write) (SWVoiceOut *sw, void *buf, int size); 152 + size_t (*run_out)(HWVoiceOut *hw, size_t live); 149 153 int (*ctl_out) (HWVoiceOut *hw, int cmd, ...); 150 154 151 155 int (*init_in) (HWVoiceIn *hw, struct audsettings *as, void *drv_opaque); 152 156 void (*fini_in) (HWVoiceIn *hw); 153 - int (*run_in) (HWVoiceIn *hw); 154 - int (*read) (SWVoiceIn *sw, void *buf, int size); 157 + size_t (*run_in)(HWVoiceIn *hw); 155 158 int (*ctl_in) (HWVoiceIn *hw, int cmd, ...); 156 159 }; 157 160 ··· 188 191 int nb_hw_voices_in; 189 192 int vm_running; 190 193 int64_t period_ticks; 194 + 195 + bool timer_running; 196 + uint64_t timer_last; 197 + 198 + QTAILQ_ENTRY(AudioState) list; 191 199 } AudioState; 192 200 193 201 extern const struct mixeng_volume nominal_volume; ··· 200 208 void audio_pcm_init_info (struct audio_pcm_info *info, struct audsettings *as); 201 209 void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len); 202 210 203 - int audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int len); 204 - int audio_pcm_hw_get_live_in (HWVoiceIn *hw); 205 - 206 - int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int len); 211 + size_t audio_pcm_hw_get_live_in(HWVoiceIn *hw); 207 212 208 - int audio_pcm_hw_clip_out (HWVoiceOut *hw, void *pcm_buf, 209 - int live, int pending); 213 + size_t audio_pcm_hw_clip_out(HWVoiceOut *hw, void *pcm_buf, 214 + size_t live, size_t pending); 210 215 211 216 int audio_bug (const char *funcname, int cond); 212 217 void *audio_calloc (const char *funcname, int nmemb, size_t size); 213 218 214 - void audio_run (const char *msg); 219 + void audio_run(AudioState *s, const char *msg); 215 220 216 221 #define VOICE_ENABLE 1 217 222 #define VOICE_DISABLE 2 ··· 219 224 220 225 #define VOICE_VOLUME_CAP (1 << VOICE_VOLUME) 221 226 222 - static inline int audio_ring_dist (int dst, int src, int len) 227 + static inline size_t audio_ring_dist(size_t dst, size_t src, size_t len) 223 228 { 224 229 return (dst >= src) ? (dst - src) : (len - src + dst); 225 230 }
+30 -32
audio/audio_template.h
··· 36 36 #define HWBUF hw->conv_buf 37 37 #endif 38 38 39 - static void glue (audio_init_nb_voices_, TYPE) (struct audio_driver *drv) 39 + static void glue(audio_init_nb_voices_, TYPE)(AudioState *s, 40 + struct audio_driver *drv) 40 41 { 41 - AudioState *s = &glob_audio_state; 42 42 int max_voices = glue (drv->max_voices_, TYPE); 43 43 int voice_size = glue (drv->voice_size_, TYPE); 44 44 ··· 75 75 HWBUF = NULL; 76 76 } 77 77 78 - static int glue (audio_pcm_hw_alloc_resources_, TYPE) (HW *hw) 78 + static bool glue(audio_pcm_hw_alloc_resources_, TYPE)(HW *hw) 79 79 { 80 80 HWBUF = audio_calloc(__func__, hw->samples, sizeof(struct st_sample)); 81 81 if (!HWBUF) { 82 - dolog ("Could not allocate " NAME " buffer (%d samples)\n", 83 - hw->samples); 84 - return -1; 82 + dolog("Could not allocate " NAME " buffer (%zu samples)\n", 83 + hw->samples); 84 + return false; 85 85 } 86 86 87 - return 0; 87 + return true; 88 88 } 89 89 90 90 static void glue (audio_pcm_sw_free_resources_, TYPE) (SW *sw) ··· 183 183 184 184 static void glue (audio_pcm_hw_gc_, TYPE) (HW **hwp) 185 185 { 186 - AudioState *s = &glob_audio_state; 187 186 HW *hw = *hwp; 187 + AudioState *s = hw->s; 188 188 189 189 if (!hw->sw_head.lh_first) { 190 190 #ifdef DAC ··· 199 199 } 200 200 } 201 201 202 - static HW *glue (audio_pcm_hw_find_any_, TYPE) (HW *hw) 202 + static HW *glue(audio_pcm_hw_find_any_, TYPE)(AudioState *s, HW *hw) 203 203 { 204 - AudioState *s = &glob_audio_state; 205 204 return hw ? hw->entries.le_next : glue (s->hw_head_, TYPE).lh_first; 206 205 } 207 206 208 - static HW *glue (audio_pcm_hw_find_any_enabled_, TYPE) (HW *hw) 207 + static HW *glue(audio_pcm_hw_find_any_enabled_, TYPE)(AudioState *s, HW *hw) 209 208 { 210 - while ((hw = glue (audio_pcm_hw_find_any_, TYPE) (hw))) { 209 + while ((hw = glue(audio_pcm_hw_find_any_, TYPE)(s, hw))) { 211 210 if (hw->enabled) { 212 211 return hw; 213 212 } ··· 215 214 return NULL; 216 215 } 217 216 218 - static HW *glue (audio_pcm_hw_find_specific_, TYPE) ( 219 - HW *hw, 220 - struct audsettings *as 221 - ) 217 + static HW *glue(audio_pcm_hw_find_specific_, TYPE)(AudioState *s, HW *hw, 218 + struct audsettings *as) 222 219 { 223 - while ((hw = glue (audio_pcm_hw_find_any_, TYPE) (hw))) { 220 + while ((hw = glue(audio_pcm_hw_find_any_, TYPE)(s, hw))) { 224 221 if (audio_pcm_info_eq (&hw->info, as)) { 225 222 return hw; 226 223 } ··· 228 225 return NULL; 229 226 } 230 227 231 - static HW *glue (audio_pcm_hw_add_new_, TYPE) (struct audsettings *as) 228 + static HW *glue(audio_pcm_hw_add_new_, TYPE)(AudioState *s, 229 + struct audsettings *as) 232 230 { 233 231 HW *hw; 234 - AudioState *s = &glob_audio_state; 235 232 struct audio_driver *drv = s->drv; 236 233 237 234 if (!glue (s->nb_hw_voices_, TYPE)) { ··· 255 252 return NULL; 256 253 } 257 254 255 + hw->s = s; 258 256 hw->pcm_ops = drv->pcm_ops; 259 257 hw->ctl_caps = drv->ctl_caps; 260 258 ··· 267 265 } 268 266 269 267 if (audio_bug(__func__, hw->samples <= 0)) { 270 - dolog ("hw->samples=%d\n", hw->samples); 268 + dolog("hw->samples=%zd\n", hw->samples); 271 269 goto err1; 272 270 } 273 271 ··· 281 279 [hw->info.swap_endianness] 282 280 [audio_bits_to_index (hw->info.bits)]; 283 281 284 - if (glue (audio_pcm_hw_alloc_resources_, TYPE) (hw)) { 282 + if (!glue(audio_pcm_hw_alloc_resources_, TYPE)(hw)) { 285 283 goto err1; 286 284 } 287 285 ··· 328 326 abort(); 329 327 } 330 328 331 - static HW *glue (audio_pcm_hw_add_, TYPE) (struct audsettings *as) 329 + static HW *glue(audio_pcm_hw_add_, TYPE)(AudioState *s, struct audsettings *as) 332 330 { 333 331 HW *hw; 334 - AudioState *s = &glob_audio_state; 335 332 AudiodevPerDirectionOptions *pdo = glue(audio_get_pdo_, TYPE)(s->dev); 336 333 337 334 if (pdo->fixed_settings) { 338 - hw = glue (audio_pcm_hw_add_new_, TYPE) (as); 335 + hw = glue(audio_pcm_hw_add_new_, TYPE)(s, as); 339 336 if (hw) { 340 337 return hw; 341 338 } 342 339 } 343 340 344 - hw = glue (audio_pcm_hw_find_specific_, TYPE) (NULL, as); 341 + hw = glue(audio_pcm_hw_find_specific_, TYPE)(s, NULL, as); 345 342 if (hw) { 346 343 return hw; 347 344 } 348 345 349 - hw = glue (audio_pcm_hw_add_new_, TYPE) (as); 346 + hw = glue(audio_pcm_hw_add_new_, TYPE)(s, as); 350 347 if (hw) { 351 348 return hw; 352 349 } 353 350 354 - return glue (audio_pcm_hw_find_any_, TYPE) (NULL); 351 + return glue(audio_pcm_hw_find_any_, TYPE)(s, NULL); 355 352 } 356 353 357 - static SW *glue (audio_pcm_create_voice_pair_, TYPE) ( 354 + static SW *glue(audio_pcm_create_voice_pair_, TYPE)( 355 + AudioState *s, 358 356 const char *sw_name, 359 357 struct audsettings *as 360 358 ) ··· 362 360 SW *sw; 363 361 HW *hw; 364 362 struct audsettings hw_as; 365 - AudioState *s = &glob_audio_state; 366 363 AudiodevPerDirectionOptions *pdo = glue(audio_get_pdo_, TYPE)(s->dev); 367 364 368 365 if (pdo->fixed_settings) { ··· 378 375 sw_name ? sw_name : "unknown", sizeof (*sw)); 379 376 goto err1; 380 377 } 378 + sw->s = s; 381 379 382 - hw = glue (audio_pcm_hw_add_, TYPE) (&hw_as); 380 + hw = glue(audio_pcm_hw_add_, TYPE)(s, &hw_as); 383 381 if (!hw) { 384 382 goto err2; 385 383 } ··· 430 428 struct audsettings *as 431 429 ) 432 430 { 433 - AudioState *s = &glob_audio_state; 431 + AudioState *s = card->state; 434 432 AudiodevPerDirectionOptions *pdo = glue(audio_get_pdo_, TYPE)(s->dev); 435 433 436 434 if (audio_bug(__func__, !card || !name || !callback_fn || !as)) { ··· 476 474 } 477 475 } 478 476 else { 479 - sw = glue (audio_pcm_create_voice_pair_, TYPE) (name, as); 477 + sw = glue(audio_pcm_create_voice_pair_, TYPE)(s, name, as); 480 478 if (!sw) { 481 479 dolog ("Failed to create voice `%s'\n", name); 482 480 return NULL;
+6 -12
audio/coreaudio.c
··· 43 43 UInt32 audioDevicePropertyBufferFrameSize; 44 44 AudioStreamBasicDescription outputStreamBasicDescription; 45 45 AudioDeviceIOProcID ioprocid; 46 - int live; 47 - int decr; 48 - int rpos; 46 + size_t live; 47 + size_t decr; 48 + size_t rpos; 49 49 } coreaudioVoiceOut; 50 50 51 51 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 ··· 397 397 return 0; 398 398 } 399 399 400 - static int coreaudio_run_out (HWVoiceOut *hw, int live) 400 + static size_t coreaudio_run_out(HWVoiceOut *hw, size_t live) 401 401 { 402 - int decr; 402 + size_t decr; 403 403 coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw; 404 404 405 405 if (coreaudio_lock (core, "coreaudio_run_out")) { ··· 413 413 core->live); 414 414 } 415 415 416 - decr = audio_MIN (core->decr, live); 416 + decr = MIN (core->decr, live); 417 417 core->decr -= decr; 418 418 419 419 core->live = live - decr; ··· 487 487 488 488 coreaudio_unlock (core, "audioDeviceIOProc"); 489 489 return 0; 490 - } 491 - 492 - static int coreaudio_write (SWVoiceOut *sw, void *buf, int len) 493 - { 494 - return audio_pcm_sw_write (sw, buf, len); 495 490 } 496 491 497 492 static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as, ··· 692 687 .init_out = coreaudio_init_out, 693 688 .fini_out = coreaudio_fini_out, 694 689 .run_out = coreaudio_run_out, 695 - .write = coreaudio_write, 696 690 .ctl_out = coreaudio_ctl_out 697 691 }; 698 692
+10 -21
audio/dsoundaudio.c
··· 454 454 return 0; 455 455 } 456 456 457 - static int dsound_write (SWVoiceOut *sw, void *buf, int len) 458 - { 459 - return audio_pcm_sw_write (sw, buf, len); 460 - } 461 - 462 - static int dsound_run_out (HWVoiceOut *hw, int live) 457 + static size_t dsound_run_out(HWVoiceOut *hw, size_t live) 463 458 { 464 459 int err; 465 460 HRESULT hr; 466 461 DSoundVoiceOut *ds = (DSoundVoiceOut *) hw; 467 462 LPDIRECTSOUNDBUFFER dsb = ds->dsound_buffer; 468 - int len, hwshift; 463 + size_t len; 464 + int hwshift; 469 465 DWORD blen1, blen2; 470 466 DWORD len1, len2; 471 467 DWORD decr; 472 468 DWORD wpos, ppos, old_pos; 473 469 LPVOID p1, p2; 474 - int bufsize; 470 + size_t bufsize; 475 471 dsound *s = ds->s; 476 472 AudiodevDsoundOptions *dso = &s->dev->u.dsound; 477 473 ··· 538 534 } 539 535 } 540 536 541 - if (audio_bug(__func__, len < 0 || len > bufsize)) { 542 - dolog ("len=%d bufsize=%d old_pos=%ld ppos=%ld\n", 543 - len, bufsize, old_pos, ppos); 537 + if (audio_bug(__func__, len > bufsize)) { 538 + dolog("len=%zu bufsize=%zu old_pos=%ld ppos=%ld\n", 539 + len, bufsize, old_pos, ppos); 544 540 return 0; 545 541 } 546 542 ··· 645 641 return 0; 646 642 } 647 643 648 - static int dsound_read (SWVoiceIn *sw, void *buf, int len) 649 - { 650 - return audio_pcm_sw_read (sw, buf, len); 651 - } 652 - 653 - static int dsound_run_in (HWVoiceIn *hw) 644 + static size_t dsound_run_in(HWVoiceIn *hw) 654 645 { 655 646 int err; 656 647 HRESULT hr; 657 648 DSoundVoiceIn *ds = (DSoundVoiceIn *) hw; 658 649 LPDIRECTSOUNDCAPTUREBUFFER dscb = ds->dsound_capture_buffer; 659 - int live, len, dead; 650 + size_t live, len, dead; 660 651 DWORD blen1, blen2; 661 652 DWORD len1, len2; 662 653 DWORD decr; ··· 707 698 if (!len) { 708 699 return 0; 709 700 } 710 - len = audio_MIN (len, dead); 701 + len = MIN (len, dead); 711 702 712 703 err = dsound_lock_in ( 713 704 dscb, ··· 856 847 .init_out = dsound_init_out, 857 848 .fini_out = dsound_fini_out, 858 849 .run_out = dsound_run_out, 859 - .write = dsound_write, 860 850 .ctl_out = dsound_ctl_out, 861 851 862 852 .init_in = dsound_init_in, 863 853 .fini_in = dsound_fini_in, 864 854 .run_in = dsound_run_in, 865 - .read = dsound_read, 866 855 .ctl_in = dsound_ctl_in 867 856 }; 868 857
+5 -4
audio/mixeng.h
··· 33 33 struct mixeng_volume { int mute; int64_t r; int64_t l; }; 34 34 struct st_sample { int64_t l; int64_t r; }; 35 35 #endif 36 + typedef struct st_sample st_sample; 36 37 37 38 typedef void (t_sample) (struct st_sample *dst, const void *src, int samples); 38 39 typedef void (f_sample) (void *dst, const struct st_sample *src, int samples); ··· 41 42 extern f_sample *mixeng_clip[2][2][2][3]; 42 43 43 44 void *st_rate_start (int inrate, int outrate); 44 - void st_rate_flow (void *opaque, struct st_sample *ibuf, struct st_sample *obuf, 45 - int *isamp, int *osamp); 46 - void st_rate_flow_mix (void *opaque, struct st_sample *ibuf, struct st_sample *obuf, 47 - int *isamp, int *osamp); 45 + void st_rate_flow(void *opaque, st_sample *ibuf, st_sample *obuf, 46 + size_t *isamp, size_t *osamp); 47 + void st_rate_flow_mix(void *opaque, st_sample *ibuf, st_sample *obuf, 48 + size_t *isamp, size_t *osamp); 48 49 void st_rate_stop (void *opaque); 49 50 void mixeng_clear (struct st_sample *buf, int len); 50 51 void mixeng_volume (struct st_sample *buf, int len, struct mixeng_volume *vol);
+10 -29
audio/noaudio.c
··· 41 41 int64_t old_ticks; 42 42 } NoVoiceIn; 43 43 44 - static int no_run_out (HWVoiceOut *hw, int live) 44 + static size_t no_run_out(HWVoiceOut *hw, size_t live) 45 45 { 46 46 NoVoiceOut *no = (NoVoiceOut *) hw; 47 - int decr, samples; 47 + size_t decr, samples; 48 48 int64_t now; 49 49 int64_t ticks; 50 50 int64_t bytes; ··· 52 52 now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 53 53 ticks = now - no->old_ticks; 54 54 bytes = muldiv64(ticks, hw->info.bytes_per_second, NANOSECONDS_PER_SECOND); 55 - bytes = audio_MIN(bytes, INT_MAX); 55 + bytes = MIN(bytes, SIZE_MAX); 56 56 samples = bytes >> hw->info.shift; 57 57 58 58 no->old_ticks = now; 59 - decr = audio_MIN (live, samples); 59 + decr = MIN (live, samples); 60 60 hw->rpos = (hw->rpos + decr) % hw->samples; 61 61 return decr; 62 - } 63 - 64 - static int no_write (SWVoiceOut *sw, void *buf, int len) 65 - { 66 - return audio_pcm_sw_write(sw, buf, len); 67 62 } 68 63 69 64 static int no_init_out(HWVoiceOut *hw, struct audsettings *as, void *drv_opaque) ··· 97 92 (void) hw; 98 93 } 99 94 100 - static int no_run_in (HWVoiceIn *hw) 95 + static size_t no_run_in(HWVoiceIn *hw) 101 96 { 102 97 NoVoiceIn *no = (NoVoiceIn *) hw; 103 - int live = audio_pcm_hw_get_live_in (hw); 104 - int dead = hw->samples - live; 105 - int samples = 0; 98 + size_t live = audio_pcm_hw_get_live_in(hw); 99 + size_t dead = hw->samples - live; 100 + size_t samples = 0; 106 101 107 102 if (dead) { 108 103 int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); ··· 111 106 muldiv64(ticks, hw->info.bytes_per_second, NANOSECONDS_PER_SECOND); 112 107 113 108 no->old_ticks = now; 114 - bytes = audio_MIN (bytes, INT_MAX); 109 + bytes = MIN (bytes, SIZE_MAX); 115 110 samples = bytes >> hw->info.shift; 116 - samples = audio_MIN (samples, dead); 111 + samples = MIN (samples, dead); 117 112 } 118 113 return samples; 119 114 } 120 115 121 - static int no_read (SWVoiceIn *sw, void *buf, int size) 122 - { 123 - /* use custom code here instead of audio_pcm_sw_read() to avoid 124 - * useless resampling/mixing */ 125 - int samples = size >> sw->info.shift; 126 - int total = sw->hw->total_samples_captured - sw->total_hw_samples_acquired; 127 - int to_clear = audio_MIN (samples, total); 128 - sw->total_hw_samples_acquired += total; 129 - audio_pcm_info_clear_buf (&sw->info, buf, to_clear); 130 - return to_clear << sw->info.shift; 131 - } 132 - 133 116 static int no_ctl_in (HWVoiceIn *hw, int cmd, ...) 134 117 { 135 118 (void) hw; ··· 151 134 .init_out = no_init_out, 152 135 .fini_out = no_fini_out, 153 136 .run_out = no_run_out, 154 - .write = no_write, 155 137 .ctl_out = no_ctl_out, 156 138 157 139 .init_in = no_init_in, 158 140 .fini_in = no_fini_in, 159 141 .run_in = no_run_in, 160 - .read = no_read, 161 142 .ctl_in = no_ctl_in 162 143 }; 163 144
+32 -43
audio/ossaudio.c
··· 110 110 111 111 static void oss_helper_poll_out (void *opaque) 112 112 { 113 - (void) opaque; 114 - audio_run ("oss_poll_out"); 113 + AudioState *s = opaque; 114 + audio_run(s, "oss_poll_out"); 115 115 } 116 116 117 117 static void oss_helper_poll_in (void *opaque) 118 118 { 119 - (void) opaque; 120 - audio_run ("oss_poll_in"); 119 + AudioState *s = opaque; 120 + audio_run(s, "oss_poll_in"); 121 121 } 122 122 123 123 static void oss_poll_out (HWVoiceOut *hw) 124 124 { 125 125 OSSVoiceOut *oss = (OSSVoiceOut *) hw; 126 126 127 - qemu_set_fd_handler (oss->fd, NULL, oss_helper_poll_out, NULL); 127 + qemu_set_fd_handler(oss->fd, NULL, oss_helper_poll_out, hw->s); 128 128 } 129 129 130 130 static void oss_poll_in (HWVoiceIn *hw) 131 131 { 132 132 OSSVoiceIn *oss = (OSSVoiceIn *) hw; 133 133 134 - qemu_set_fd_handler (oss->fd, oss_helper_poll_in, NULL, NULL); 135 - } 136 - 137 - static int oss_write (SWVoiceOut *sw, void *buf, int len) 138 - { 139 - return audio_pcm_sw_write (sw, buf, len); 134 + qemu_set_fd_handler(oss->fd, oss_helper_poll_in, NULL, hw->s); 140 135 } 141 136 142 137 static int aud_to_ossfmt (AudioFormat fmt, int endianness) ··· 388 383 int samples_written; 389 384 ssize_t bytes_written; 390 385 int samples_till_end = hw->samples - oss->wpos; 391 - int samples_to_write = audio_MIN (oss->pending, samples_till_end); 386 + int samples_to_write = MIN (oss->pending, samples_till_end); 392 387 int bytes_to_write = samples_to_write << hw->info.shift; 393 388 void *pcm = advance (oss->pcm_buf, oss->wpos << hw->info.shift); 394 389 ··· 416 411 } 417 412 } 418 413 419 - static int oss_run_out (HWVoiceOut *hw, int live) 414 + static size_t oss_run_out(HWVoiceOut *hw, size_t live) 420 415 { 421 416 OSSVoiceOut *oss = (OSSVoiceOut *) hw; 422 - int err, decr; 417 + int err; 418 + size_t decr; 423 419 struct audio_buf_info abinfo; 424 420 struct count_info cntinfo; 425 - int bufsize; 421 + size_t bufsize; 426 422 427 423 bufsize = hw->samples << hw->info.shift; 428 424 ··· 437 433 438 434 pos = hw->rpos << hw->info.shift; 439 435 bytes = audio_ring_dist (cntinfo.ptr, pos, bufsize); 440 - decr = audio_MIN (bytes >> hw->info.shift, live); 436 + decr = MIN (bytes >> hw->info.shift, live); 441 437 } 442 438 else { 443 439 err = ioctl (oss->fd, SNDCTL_DSP_GETOSPACE, &abinfo); ··· 456 452 return 0; 457 453 } 458 454 459 - decr = audio_MIN (abinfo.bytes >> hw->info.shift, live); 455 + decr = MIN (abinfo.bytes >> hw->info.shift, live); 460 456 if (!decr) { 461 457 return 0; 462 458 } ··· 481 477 if (oss->mmapped) { 482 478 err = munmap (oss->pcm_buf, hw->samples << hw->info.shift); 483 479 if (err) { 484 - oss_logerr (errno, "Failed to unmap buffer %p, size %d\n", 485 - oss->pcm_buf, hw->samples << hw->info.shift); 480 + oss_logerr(errno, "Failed to unmap buffer %p, size %zu\n", 481 + oss->pcm_buf, hw->samples << hw->info.shift); 486 482 } 487 483 } 488 484 else { ··· 548 544 0 549 545 ); 550 546 if (oss->pcm_buf == MAP_FAILED) { 551 - oss_logerr (errno, "Failed to map %d bytes of DAC\n", 552 - hw->samples << hw->info.shift); 547 + oss_logerr(errno, "Failed to map %zu bytes of DAC\n", 548 + hw->samples << hw->info.shift); 553 549 } 554 550 else { 555 551 int err; ··· 573 569 if (!oss->mmapped) { 574 570 err = munmap (oss->pcm_buf, hw->samples << hw->info.shift); 575 571 if (err) { 576 - oss_logerr (errno, "Failed to unmap buffer %p size %d\n", 577 - oss->pcm_buf, hw->samples << hw->info.shift); 572 + oss_logerr(errno, "Failed to unmap buffer %p size %zu\n", 573 + oss->pcm_buf, hw->samples << hw->info.shift); 578 574 } 579 575 } 580 576 } ··· 586 582 1 << hw->info.shift); 587 583 if (!oss->pcm_buf) { 588 584 dolog ( 589 - "Could not allocate DAC buffer (%d samples, each %d bytes)\n", 585 + "Could not allocate DAC buffer (%zu samples, each %d bytes)\n", 590 586 hw->samples, 591 587 1 << hw->info.shift 592 588 ); ··· 698 694 hw->samples = (obt.nfrags * obt.fragsize) >> hw->info.shift; 699 695 oss->pcm_buf = audio_calloc(__func__, hw->samples, 1 << hw->info.shift); 700 696 if (!oss->pcm_buf) { 701 - dolog ("Could not allocate ADC buffer (%d samples, each %d bytes)\n", 702 - hw->samples, 1 << hw->info.shift); 697 + dolog("Could not allocate ADC buffer (%zu samples, each %d bytes)\n", 698 + hw->samples, 1 << hw->info.shift); 703 699 oss_anal_close (&fd); 704 700 return -1; 705 701 } ··· 719 715 oss->pcm_buf = NULL; 720 716 } 721 717 722 - static int oss_run_in (HWVoiceIn *hw) 718 + static size_t oss_run_in(HWVoiceIn *hw) 723 719 { 724 720 OSSVoiceIn *oss = (OSSVoiceIn *) hw; 725 721 int hwshift = hw->info.shift; 726 722 int i; 727 - int live = audio_pcm_hw_get_live_in (hw); 728 - int dead = hw->samples - live; 723 + size_t live = audio_pcm_hw_get_live_in (hw); 724 + size_t dead = hw->samples - live; 729 725 size_t read_samples = 0; 730 726 struct { 731 - int add; 732 - int len; 727 + size_t add; 728 + size_t len; 733 729 } bufs[2] = { 734 730 { .add = hw->wpos, .len = 0 }, 735 731 { .add = 0, .len = 0 } ··· 756 752 757 753 if (nread > 0) { 758 754 if (nread & hw->info.align) { 759 - dolog ("warning: Misaligned read %zd (requested %d), " 760 - "alignment %d\n", nread, bufs[i].add << hwshift, 761 - hw->info.align + 1); 755 + dolog("warning: Misaligned read %zd (requested %zu), " 756 + "alignment %d\n", nread, bufs[i].add << hwshift, 757 + hw->info.align + 1); 762 758 } 763 759 read_samples += nread >> hwshift; 764 760 hw->conv (hw->conv_buf + bufs[i].add, p, nread >> hwshift); ··· 771 767 case EAGAIN: 772 768 break; 773 769 default: 774 - oss_logerr ( 770 + oss_logerr( 775 771 errno, 776 - "Failed to read %d bytes of audio (to %p)\n", 772 + "Failed to read %zu bytes of audio (to %p)\n", 777 773 bufs[i].len, p 778 774 ); 779 775 break; ··· 786 782 787 783 hw->wpos = (hw->wpos + read_samples) % hw->samples; 788 784 return read_samples; 789 - } 790 - 791 - static int oss_read (SWVoiceIn *sw, void *buf, int size) 792 - { 793 - return audio_pcm_sw_read (sw, buf, size); 794 785 } 795 786 796 787 static int oss_ctl_in (HWVoiceIn *hw, int cmd, ...) ··· 855 846 .init_out = oss_init_out, 856 847 .fini_out = oss_fini_out, 857 848 .run_out = oss_run_out, 858 - .write = oss_write, 859 849 .ctl_out = oss_ctl_out, 860 850 861 851 .init_in = oss_init_in, 862 852 .fini_in = oss_fini_in, 863 853 .run_in = oss_run_in, 864 - .read = oss_read, 865 854 .ctl_in = oss_ctl_in 866 855 }; 867 856
+236 -177
audio/paaudio.c
··· 11 11 #include "audio_int.h" 12 12 #include "audio_pt_int.h" 13 13 14 - typedef struct { 15 - Audiodev *dev; 14 + typedef struct PAConnection { 15 + char *server; 16 + int refcount; 17 + QTAILQ_ENTRY(PAConnection) list; 18 + 16 19 pa_threaded_mainloop *mainloop; 17 20 pa_context *context; 21 + } PAConnection; 22 + 23 + static QTAILQ_HEAD(PAConnectionHead, PAConnection) pa_conns = 24 + QTAILQ_HEAD_INITIALIZER(pa_conns); 25 + 26 + typedef struct { 27 + Audiodev *dev; 28 + PAConnection *conn; 18 29 } paaudio; 19 30 20 31 typedef struct { 21 32 HWVoiceOut hw; 22 - int done; 23 - int live; 24 - int decr; 25 - int rpos; 33 + size_t done; 34 + size_t live; 35 + size_t decr; 36 + size_t rpos; 26 37 pa_stream *stream; 27 38 void *pcm_buf; 28 39 struct audio_pt pt; 29 40 paaudio *g; 30 - int samples; 41 + size_t samples; 31 42 } PAVoiceOut; 32 43 33 44 typedef struct { 34 45 HWVoiceIn hw; 35 - int done; 36 - int dead; 37 - int incr; 38 - int wpos; 46 + size_t done; 47 + size_t dead; 48 + size_t incr; 49 + size_t wpos; 39 50 pa_stream *stream; 40 51 void *pcm_buf; 41 52 struct audio_pt pt; 42 53 const void *read_data; 43 54 size_t read_index, read_length; 44 55 paaudio *g; 45 - int samples; 56 + size_t samples; 46 57 } PAVoiceIn; 47 58 48 - static void qpa_audio_fini(void *opaque); 59 + static void qpa_conn_fini(PAConnection *c); 49 60 50 61 static void GCC_FMT_ATTR (2, 3) qpa_logerr (int err, const char *fmt, ...) 51 62 { ··· 108 119 109 120 static int qpa_simple_read (PAVoiceIn *p, void *data, size_t length, int *rerror) 110 121 { 111 - paaudio *g = p->g; 122 + PAConnection *c = p->g->conn; 112 123 113 - pa_threaded_mainloop_lock (g->mainloop); 124 + pa_threaded_mainloop_lock(c->mainloop); 114 125 115 - CHECK_DEAD_GOTO (g, p->stream, rerror, unlock_and_fail); 126 + CHECK_DEAD_GOTO(c, p->stream, rerror, unlock_and_fail); 116 127 117 128 while (length > 0) { 118 129 size_t l; ··· 121 132 int r; 122 133 123 134 r = pa_stream_peek (p->stream, &p->read_data, &p->read_length); 124 - CHECK_SUCCESS_GOTO (g, rerror, r == 0, unlock_and_fail); 135 + CHECK_SUCCESS_GOTO(c, rerror, r == 0, unlock_and_fail); 125 136 126 137 if (!p->read_data) { 127 - pa_threaded_mainloop_wait (g->mainloop); 128 - CHECK_DEAD_GOTO (g, p->stream, rerror, unlock_and_fail); 138 + pa_threaded_mainloop_wait(c->mainloop); 139 + CHECK_DEAD_GOTO(c, p->stream, rerror, unlock_and_fail); 129 140 } else { 130 141 p->read_index = 0; 131 142 } ··· 148 159 p->read_length = 0; 149 160 p->read_index = 0; 150 161 151 - CHECK_SUCCESS_GOTO (g, rerror, r == 0, unlock_and_fail); 162 + CHECK_SUCCESS_GOTO(c, rerror, r == 0, unlock_and_fail); 152 163 } 153 164 } 154 165 155 - pa_threaded_mainloop_unlock (g->mainloop); 166 + pa_threaded_mainloop_unlock(c->mainloop); 156 167 return 0; 157 168 158 169 unlock_and_fail: 159 - pa_threaded_mainloop_unlock (g->mainloop); 170 + pa_threaded_mainloop_unlock(c->mainloop); 160 171 return -1; 161 172 } 162 173 163 174 static int qpa_simple_write (PAVoiceOut *p, const void *data, size_t length, int *rerror) 164 175 { 165 - paaudio *g = p->g; 176 + PAConnection *c = p->g->conn; 166 177 167 - pa_threaded_mainloop_lock (g->mainloop); 178 + pa_threaded_mainloop_lock(c->mainloop); 168 179 169 - CHECK_DEAD_GOTO (g, p->stream, rerror, unlock_and_fail); 180 + CHECK_DEAD_GOTO(c, p->stream, rerror, unlock_and_fail); 170 181 171 182 while (length > 0) { 172 183 size_t l; 173 184 int r; 174 185 175 186 while (!(l = pa_stream_writable_size (p->stream))) { 176 - pa_threaded_mainloop_wait (g->mainloop); 177 - CHECK_DEAD_GOTO (g, p->stream, rerror, unlock_and_fail); 187 + pa_threaded_mainloop_wait(c->mainloop); 188 + CHECK_DEAD_GOTO(c, p->stream, rerror, unlock_and_fail); 178 189 } 179 190 180 - CHECK_SUCCESS_GOTO (g, rerror, l != (size_t) -1, unlock_and_fail); 191 + CHECK_SUCCESS_GOTO(c, rerror, l != (size_t) -1, unlock_and_fail); 181 192 182 193 if (l > length) { 183 194 l = length; 184 195 } 185 196 186 197 r = pa_stream_write (p->stream, data, l, NULL, 0LL, PA_SEEK_RELATIVE); 187 - CHECK_SUCCESS_GOTO (g, rerror, r >= 0, unlock_and_fail); 198 + CHECK_SUCCESS_GOTO(c, rerror, r >= 0, unlock_and_fail); 188 199 189 200 data = (const uint8_t *) data + l; 190 201 length -= l; 191 202 } 192 203 193 - pa_threaded_mainloop_unlock (g->mainloop); 204 + pa_threaded_mainloop_unlock(c->mainloop); 194 205 return 0; 195 206 196 207 unlock_and_fail: 197 - pa_threaded_mainloop_unlock (g->mainloop); 208 + pa_threaded_mainloop_unlock(c->mainloop); 198 209 return -1; 199 210 } 200 211 ··· 208 219 } 209 220 210 221 for (;;) { 211 - int decr, to_mix, rpos; 222 + size_t decr, to_mix, rpos; 212 223 213 224 for (;;) { 214 225 if (pa->done) { ··· 224 235 } 225 236 } 226 237 227 - decr = to_mix = audio_MIN(pa->live, pa->samples >> 5); 238 + decr = to_mix = MIN(pa->live, pa->samples >> 5); 228 239 rpos = pa->rpos; 229 240 230 241 if (audio_pt_unlock(&pa->pt, __func__)) { ··· 233 244 234 245 while (to_mix) { 235 246 int error; 236 - int chunk = audio_MIN (to_mix, hw->samples - rpos); 247 + size_t chunk = MIN (to_mix, hw->samples - rpos); 237 248 struct st_sample *src = hw->mix_buf + rpos; 238 249 239 250 hw->clip (pa->pcm_buf, src, chunk); ··· 262 273 return NULL; 263 274 } 264 275 265 - static int qpa_run_out (HWVoiceOut *hw, int live) 276 + static size_t qpa_run_out(HWVoiceOut *hw, size_t live) 266 277 { 267 - int decr; 278 + size_t decr; 268 279 PAVoiceOut *pa = (PAVoiceOut *) hw; 269 280 270 281 if (audio_pt_lock(&pa->pt, __func__)) { 271 282 return 0; 272 283 } 273 284 274 - decr = audio_MIN (live, pa->decr); 285 + decr = MIN (live, pa->decr); 275 286 pa->decr -= decr; 276 287 pa->live = live - decr; 277 288 hw->rpos = pa->rpos; ··· 284 295 return decr; 285 296 } 286 297 287 - static int qpa_write (SWVoiceOut *sw, void *buf, int len) 288 - { 289 - return audio_pcm_sw_write (sw, buf, len); 290 - } 291 - 292 298 /* capture */ 293 299 static void *qpa_thread_in (void *arg) 294 300 { ··· 300 306 } 301 307 302 308 for (;;) { 303 - int incr, to_grab, wpos; 309 + size_t incr, to_grab, wpos; 304 310 305 311 for (;;) { 306 312 if (pa->done) { ··· 316 322 } 317 323 } 318 324 319 - incr = to_grab = audio_MIN(pa->dead, pa->samples >> 5); 325 + incr = to_grab = MIN(pa->dead, pa->samples >> 5); 320 326 wpos = pa->wpos; 321 327 322 328 if (audio_pt_unlock(&pa->pt, __func__)) { ··· 325 331 326 332 while (to_grab) { 327 333 int error; 328 - int chunk = audio_MIN (to_grab, hw->samples - wpos); 334 + size_t chunk = MIN (to_grab, hw->samples - wpos); 329 335 void *buf = advance (pa->pcm_buf, wpos); 330 336 331 337 if (qpa_simple_read (pa, buf, ··· 353 359 return NULL; 354 360 } 355 361 356 - static int qpa_run_in (HWVoiceIn *hw) 362 + static size_t qpa_run_in(HWVoiceIn *hw) 357 363 { 358 - int live, incr, dead; 364 + size_t live, incr, dead; 359 365 PAVoiceIn *pa = (PAVoiceIn *) hw; 360 366 361 367 if (audio_pt_lock(&pa->pt, __func__)) { ··· 364 370 365 371 live = audio_pcm_hw_get_live_in (hw); 366 372 dead = hw->samples - live; 367 - incr = audio_MIN (dead, pa->incr); 373 + incr = MIN (dead, pa->incr); 368 374 pa->incr -= incr; 369 375 pa->dead = dead - incr; 370 376 hw->wpos = pa->wpos; ··· 377 383 return incr; 378 384 } 379 385 380 - static int qpa_read (SWVoiceIn *sw, void *buf, int len) 381 - { 382 - return audio_pcm_sw_read (sw, buf, len); 383 - } 384 - 385 386 static pa_sample_format_t audfmt_to_pa (AudioFormat afmt, int endianness) 386 387 { 387 388 int format; ··· 432 433 433 434 static void context_state_cb (pa_context *c, void *userdata) 434 435 { 435 - paaudio *g = userdata; 436 + PAConnection *conn = userdata; 436 437 437 438 switch (pa_context_get_state(c)) { 438 439 case PA_CONTEXT_READY: 439 440 case PA_CONTEXT_TERMINATED: 440 441 case PA_CONTEXT_FAILED: 441 - pa_threaded_mainloop_signal (g->mainloop, 0); 442 + pa_threaded_mainloop_signal(conn->mainloop, 0); 442 443 break; 443 444 444 445 case PA_CONTEXT_UNCONNECTED: ··· 451 452 452 453 static void stream_state_cb (pa_stream *s, void * userdata) 453 454 { 454 - paaudio *g = userdata; 455 + PAConnection *c = userdata; 455 456 456 457 switch (pa_stream_get_state (s)) { 457 458 458 459 case PA_STREAM_READY: 459 460 case PA_STREAM_FAILED: 460 461 case PA_STREAM_TERMINATED: 461 - pa_threaded_mainloop_signal (g->mainloop, 0); 462 + pa_threaded_mainloop_signal(c->mainloop, 0); 462 463 break; 463 464 464 465 case PA_STREAM_UNCONNECTED: ··· 469 470 470 471 static void stream_request_cb (pa_stream *s, size_t length, void *userdata) 471 472 { 472 - paaudio *g = userdata; 473 + PAConnection *c = userdata; 473 474 474 - pa_threaded_mainloop_signal (g->mainloop, 0); 475 + pa_threaded_mainloop_signal(c->mainloop, 0); 475 476 } 476 477 477 478 static pa_stream *qpa_simple_new ( 478 - paaudio *g, 479 + PAConnection *c, 479 480 const char *name, 480 481 pa_stream_direction_t dir, 481 482 const char *dev, ··· 486 487 { 487 488 int r; 488 489 pa_stream *stream; 490 + pa_stream_flags_t flags; 489 491 490 - pa_threaded_mainloop_lock (g->mainloop); 492 + pa_threaded_mainloop_lock(c->mainloop); 491 493 492 - stream = pa_stream_new (g->context, name, ss, map); 494 + stream = pa_stream_new(c->context, name, ss, map); 493 495 if (!stream) { 494 496 goto fail; 495 497 } 496 498 497 - pa_stream_set_state_callback (stream, stream_state_cb, g); 498 - pa_stream_set_read_callback (stream, stream_request_cb, g); 499 - pa_stream_set_write_callback (stream, stream_request_cb, g); 499 + pa_stream_set_state_callback(stream, stream_state_cb, c); 500 + pa_stream_set_read_callback(stream, stream_request_cb, c); 501 + pa_stream_set_write_callback(stream, stream_request_cb, c); 502 + 503 + flags = 504 + PA_STREAM_INTERPOLATE_TIMING 505 + | PA_STREAM_AUTO_TIMING_UPDATE 506 + | PA_STREAM_EARLY_REQUESTS; 507 + 508 + if (dev) { 509 + /* don't move the stream if the user specified a sink/source */ 510 + flags |= PA_STREAM_DONT_MOVE; 511 + } 500 512 501 513 if (dir == PA_STREAM_PLAYBACK) { 502 - r = pa_stream_connect_playback (stream, dev, attr, 503 - PA_STREAM_INTERPOLATE_TIMING 504 - #ifdef PA_STREAM_ADJUST_LATENCY 505 - |PA_STREAM_ADJUST_LATENCY 506 - #endif 507 - |PA_STREAM_AUTO_TIMING_UPDATE, NULL, NULL); 514 + r = pa_stream_connect_playback(stream, dev, attr, flags, NULL, NULL); 508 515 } else { 509 - r = pa_stream_connect_record (stream, dev, attr, 510 - PA_STREAM_INTERPOLATE_TIMING 511 - #ifdef PA_STREAM_ADJUST_LATENCY 512 - |PA_STREAM_ADJUST_LATENCY 513 - #endif 514 - |PA_STREAM_AUTO_TIMING_UPDATE); 516 + r = pa_stream_connect_record(stream, dev, attr, flags); 515 517 } 516 518 517 519 if (r < 0) { 518 520 goto fail; 519 521 } 520 522 521 - pa_threaded_mainloop_unlock (g->mainloop); 523 + pa_threaded_mainloop_unlock(c->mainloop); 522 524 523 525 return stream; 524 526 525 527 fail: 526 - pa_threaded_mainloop_unlock (g->mainloop); 528 + pa_threaded_mainloop_unlock(c->mainloop); 527 529 528 530 if (stream) { 529 531 pa_stream_unref (stream); 530 532 } 531 533 532 - *rerror = pa_context_errno (g->context); 534 + *rerror = pa_context_errno(c->context); 533 535 534 536 return NULL; 535 537 } ··· 545 547 paaudio *g = pa->g = drv_opaque; 546 548 AudiodevPaOptions *popts = &g->dev->u.pa; 547 549 AudiodevPaPerDirectionOptions *ppdo = popts->out; 550 + PAConnection *c = g->conn; 548 551 549 552 ss.format = audfmt_to_pa (as->fmt, as->endianness); 550 553 ss.channels = as->nchannels; ··· 558 561 obt_as.fmt = pa_to_audfmt (ss.format, &obt_as.endianness); 559 562 560 563 pa->stream = qpa_simple_new ( 561 - g, 564 + c, 562 565 "qemu", 563 566 PA_STREAM_PLAYBACK, 564 567 ppdo->has_name ? ppdo->name : NULL, ··· 579 582 pa->pcm_buf = audio_calloc(__func__, hw->samples, 1 << hw->info.shift); 580 583 pa->rpos = hw->rpos; 581 584 if (!pa->pcm_buf) { 582 - dolog ("Could not allocate buffer (%d bytes)\n", 583 - hw->samples << hw->info.shift); 585 + dolog("Could not allocate buffer (%zu bytes)\n", 586 + hw->samples << hw->info.shift); 584 587 goto fail2; 585 588 } 586 589 ··· 612 615 paaudio *g = pa->g = drv_opaque; 613 616 AudiodevPaOptions *popts = &g->dev->u.pa; 614 617 AudiodevPaPerDirectionOptions *ppdo = popts->in; 618 + PAConnection *c = g->conn; 615 619 616 620 ss.format = audfmt_to_pa (as->fmt, as->endianness); 617 621 ss.channels = as->nchannels; ··· 625 629 obt_as.fmt = pa_to_audfmt (ss.format, &obt_as.endianness); 626 630 627 631 pa->stream = qpa_simple_new ( 628 - g, 632 + c, 629 633 "qemu", 630 634 PA_STREAM_RECORD, 631 635 ppdo->has_name ? ppdo->name : NULL, ··· 646 650 pa->pcm_buf = audio_calloc(__func__, hw->samples, 1 << hw->info.shift); 647 651 pa->wpos = hw->wpos; 648 652 if (!pa->pcm_buf) { 649 - dolog ("Could not allocate buffer (%d bytes)\n", 650 - hw->samples << hw->info.shift); 653 + dolog("Could not allocate buffer (%zu bytes)\n", 654 + hw->samples << hw->info.shift); 651 655 goto fail2; 652 656 } 653 657 ··· 669 673 return -1; 670 674 } 671 675 676 + static void qpa_simple_disconnect(PAConnection *c, pa_stream *stream) 677 + { 678 + int err; 679 + 680 + pa_threaded_mainloop_lock(c->mainloop); 681 + /* 682 + * wait until actually connects. workaround pa bug #247 683 + * https://gitlab.freedesktop.org/pulseaudio/pulseaudio/issues/247 684 + */ 685 + while (pa_stream_get_state(stream) == PA_STREAM_CREATING) { 686 + pa_threaded_mainloop_wait(c->mainloop); 687 + } 688 + 689 + err = pa_stream_disconnect(stream); 690 + if (err != 0) { 691 + dolog("Failed to disconnect! err=%d\n", err); 692 + } 693 + pa_stream_unref(stream); 694 + pa_threaded_mainloop_unlock(c->mainloop); 695 + } 696 + 672 697 static void qpa_fini_out (HWVoiceOut *hw) 673 698 { 674 699 void *ret; ··· 680 705 audio_pt_join(&pa->pt, &ret, __func__); 681 706 682 707 if (pa->stream) { 683 - pa_stream_unref (pa->stream); 708 + qpa_simple_disconnect(pa->g->conn, pa->stream); 684 709 pa->stream = NULL; 685 710 } 686 711 ··· 700 725 audio_pt_join(&pa->pt, &ret, __func__); 701 726 702 727 if (pa->stream) { 703 - pa_stream_unref (pa->stream); 728 + qpa_simple_disconnect(pa->g->conn, pa->stream); 704 729 pa->stream = NULL; 705 730 } 706 731 ··· 714 739 PAVoiceOut *pa = (PAVoiceOut *) hw; 715 740 pa_operation *op; 716 741 pa_cvolume v; 717 - paaudio *g = pa->g; 742 + PAConnection *c = pa->g->conn; 718 743 719 744 #ifdef PA_CHECK_VERSION /* macro is present in 0.9.16+ */ 720 745 pa_cvolume_init (&v); /* function is present in 0.9.13+ */ ··· 734 759 v.values[0] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * sw->vol.l) / UINT32_MAX; 735 760 v.values[1] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * sw->vol.r) / UINT32_MAX; 736 761 737 - pa_threaded_mainloop_lock (g->mainloop); 762 + pa_threaded_mainloop_lock(c->mainloop); 738 763 739 - op = pa_context_set_sink_input_volume (g->context, 764 + op = pa_context_set_sink_input_volume(c->context, 740 765 pa_stream_get_index (pa->stream), 741 766 &v, NULL, NULL); 742 - if (!op) 743 - qpa_logerr (pa_context_errno (g->context), 744 - "set_sink_input_volume() failed\n"); 745 - else 746 - pa_operation_unref (op); 767 + if (!op) { 768 + qpa_logerr(pa_context_errno(c->context), 769 + "set_sink_input_volume() failed\n"); 770 + } else { 771 + pa_operation_unref(op); 772 + } 747 773 748 - op = pa_context_set_sink_input_mute (g->context, 774 + op = pa_context_set_sink_input_mute(c->context, 749 775 pa_stream_get_index (pa->stream), 750 776 sw->vol.mute, NULL, NULL); 751 777 if (!op) { 752 - qpa_logerr (pa_context_errno (g->context), 753 - "set_sink_input_mute() failed\n"); 778 + qpa_logerr(pa_context_errno(c->context), 779 + "set_sink_input_mute() failed\n"); 754 780 } else { 755 - pa_operation_unref (op); 781 + pa_operation_unref(op); 756 782 } 757 783 758 - pa_threaded_mainloop_unlock (g->mainloop); 784 + pa_threaded_mainloop_unlock(c->mainloop); 759 785 } 760 786 } 761 787 return 0; ··· 766 792 PAVoiceIn *pa = (PAVoiceIn *) hw; 767 793 pa_operation *op; 768 794 pa_cvolume v; 769 - paaudio *g = pa->g; 795 + PAConnection *c = pa->g->conn; 770 796 771 797 #ifdef PA_CHECK_VERSION 772 798 pa_cvolume_init (&v); ··· 786 812 v.values[0] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * sw->vol.l) / UINT32_MAX; 787 813 v.values[1] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * sw->vol.r) / UINT32_MAX; 788 814 789 - pa_threaded_mainloop_lock (g->mainloop); 815 + pa_threaded_mainloop_lock(c->mainloop); 790 816 791 - op = pa_context_set_source_output_volume (g->context, 792 - pa_stream_get_index (pa->stream), 817 + op = pa_context_set_source_output_volume(c->context, 818 + pa_stream_get_index(pa->stream), 793 819 &v, NULL, NULL); 794 820 if (!op) { 795 - qpa_logerr (pa_context_errno (g->context), 796 - "set_source_output_volume() failed\n"); 821 + qpa_logerr(pa_context_errno(c->context), 822 + "set_source_output_volume() failed\n"); 797 823 } else { 798 824 pa_operation_unref(op); 799 825 } 800 826 801 - op = pa_context_set_source_output_mute (g->context, 827 + op = pa_context_set_source_output_mute(c->context, 802 828 pa_stream_get_index (pa->stream), 803 829 sw->vol.mute, NULL, NULL); 804 830 if (!op) { 805 - qpa_logerr (pa_context_errno (g->context), 806 - "set_source_output_mute() failed\n"); 831 + qpa_logerr(pa_context_errno(c->context), 832 + "set_source_output_mute() failed\n"); 807 833 } else { 808 834 pa_operation_unref (op); 809 835 } 810 836 811 - pa_threaded_mainloop_unlock (g->mainloop); 837 + pa_threaded_mainloop_unlock(c->mainloop); 812 838 } 813 839 } 814 840 return 0; ··· 828 854 return 1; 829 855 } 830 856 857 + /* common */ 858 + static void *qpa_conn_init(const char *server) 859 + { 860 + PAConnection *c = g_malloc0(sizeof(PAConnection)); 861 + QTAILQ_INSERT_TAIL(&pa_conns, c, list); 862 + 863 + c->mainloop = pa_threaded_mainloop_new(); 864 + if (!c->mainloop) { 865 + goto fail; 866 + } 867 + 868 + c->context = pa_context_new(pa_threaded_mainloop_get_api(c->mainloop), 869 + server); 870 + if (!c->context) { 871 + goto fail; 872 + } 873 + 874 + pa_context_set_state_callback(c->context, context_state_cb, c); 875 + 876 + if (pa_context_connect(c->context, server, 0, NULL) < 0) { 877 + qpa_logerr(pa_context_errno(c->context), 878 + "pa_context_connect() failed\n"); 879 + goto fail; 880 + } 881 + 882 + pa_threaded_mainloop_lock(c->mainloop); 883 + 884 + if (pa_threaded_mainloop_start(c->mainloop) < 0) { 885 + goto unlock_and_fail; 886 + } 887 + 888 + for (;;) { 889 + pa_context_state_t state; 890 + 891 + state = pa_context_get_state(c->context); 892 + 893 + if (state == PA_CONTEXT_READY) { 894 + break; 895 + } 896 + 897 + if (!PA_CONTEXT_IS_GOOD(state)) { 898 + qpa_logerr(pa_context_errno(c->context), 899 + "Wrong context state\n"); 900 + goto unlock_and_fail; 901 + } 902 + 903 + /* Wait until the context is ready */ 904 + pa_threaded_mainloop_wait(c->mainloop); 905 + } 906 + 907 + pa_threaded_mainloop_unlock(c->mainloop); 908 + return c; 909 + 910 + unlock_and_fail: 911 + pa_threaded_mainloop_unlock(c->mainloop); 912 + fail: 913 + AUD_log (AUDIO_CAP, "Failed to initialize PA context"); 914 + qpa_conn_fini(c); 915 + return NULL; 916 + } 917 + 831 918 static void *qpa_audio_init(Audiodev *dev) 832 919 { 833 920 paaudio *g; 834 921 AudiodevPaOptions *popts = &dev->u.pa; 835 922 const char *server; 923 + PAConnection *c; 924 + 925 + assert(dev->driver == AUDIODEV_DRIVER_PA); 836 926 837 927 if (!popts->has_server) { 838 928 char pidfile[64]; ··· 849 939 } 850 940 } 851 941 852 - assert(dev->driver == AUDIODEV_DRIVER_PA); 853 - 854 - g = g_malloc(sizeof(paaudio)); 855 - server = popts->has_server ? popts->server : NULL; 856 - 857 942 if (!qpa_validate_per_direction_opts(dev, popts->in)) { 858 - goto fail; 943 + return NULL; 859 944 } 860 945 if (!qpa_validate_per_direction_opts(dev, popts->out)) { 861 - goto fail; 946 + return NULL; 862 947 } 863 948 949 + g = g_malloc0(sizeof(paaudio)); 950 + server = popts->has_server ? popts->server : NULL; 951 + 864 952 g->dev = dev; 865 - g->mainloop = NULL; 866 - g->context = NULL; 867 953 868 - g->mainloop = pa_threaded_mainloop_new (); 869 - if (!g->mainloop) { 870 - goto fail; 954 + QTAILQ_FOREACH(c, &pa_conns, list) { 955 + if (server == NULL || c->server == NULL ? 956 + server == c->server : 957 + strcmp(server, c->server) == 0) { 958 + g->conn = c; 959 + break; 960 + } 871 961 } 872 - 873 - g->context = pa_context_new (pa_threaded_mainloop_get_api (g->mainloop), 874 - server); 875 - if (!g->context) { 876 - goto fail; 962 + if (!g->conn) { 963 + g->conn = qpa_conn_init(server); 964 + } 965 + if (!g->conn) { 966 + g_free(g); 967 + return NULL; 877 968 } 878 969 879 - pa_context_set_state_callback (g->context, context_state_cb, g); 970 + ++g->conn->refcount; 971 + return g; 972 + } 880 973 881 - if (pa_context_connect(g->context, server, 0, NULL) < 0) { 882 - qpa_logerr (pa_context_errno (g->context), 883 - "pa_context_connect() failed\n"); 884 - goto fail; 974 + static void qpa_conn_fini(PAConnection *c) 975 + { 976 + if (c->mainloop) { 977 + pa_threaded_mainloop_stop(c->mainloop); 885 978 } 886 979 887 - pa_threaded_mainloop_lock (g->mainloop); 888 - 889 - if (pa_threaded_mainloop_start (g->mainloop) < 0) { 890 - goto unlock_and_fail; 980 + if (c->context) { 981 + pa_context_disconnect(c->context); 982 + pa_context_unref(c->context); 891 983 } 892 984 893 - for (;;) { 894 - pa_context_state_t state; 895 - 896 - state = pa_context_get_state (g->context); 897 - 898 - if (state == PA_CONTEXT_READY) { 899 - break; 900 - } 901 - 902 - if (!PA_CONTEXT_IS_GOOD (state)) { 903 - qpa_logerr (pa_context_errno (g->context), 904 - "Wrong context state\n"); 905 - goto unlock_and_fail; 906 - } 907 - 908 - /* Wait until the context is ready */ 909 - pa_threaded_mainloop_wait (g->mainloop); 985 + if (c->mainloop) { 986 + pa_threaded_mainloop_free(c->mainloop); 910 987 } 911 988 912 - pa_threaded_mainloop_unlock (g->mainloop); 913 - 914 - return g; 915 - 916 - unlock_and_fail: 917 - pa_threaded_mainloop_unlock (g->mainloop); 918 - fail: 919 - AUD_log (AUDIO_CAP, "Failed to initialize PA context"); 920 - qpa_audio_fini(g); 921 - return NULL; 989 + QTAILQ_REMOVE(&pa_conns, c, list); 990 + g_free(c); 922 991 } 923 992 924 993 static void qpa_audio_fini (void *opaque) 925 994 { 926 995 paaudio *g = opaque; 996 + PAConnection *c = g->conn; 927 997 928 - if (g->mainloop) { 929 - pa_threaded_mainloop_stop (g->mainloop); 930 - } 931 - 932 - if (g->context) { 933 - pa_context_disconnect (g->context); 934 - pa_context_unref (g->context); 935 - } 936 - 937 - if (g->mainloop) { 938 - pa_threaded_mainloop_free (g->mainloop); 998 + if (--c->refcount == 0) { 999 + qpa_conn_fini(c); 939 1000 } 940 1001 941 1002 g_free(g); ··· 945 1006 .init_out = qpa_init_out, 946 1007 .fini_out = qpa_fini_out, 947 1008 .run_out = qpa_run_out, 948 - .write = qpa_write, 949 1009 .ctl_out = qpa_ctl_out, 950 1010 951 1011 .init_in = qpa_init_in, 952 1012 .fini_in = qpa_fini_in, 953 1013 .run_in = qpa_run_in, 954 - .read = qpa_read, 955 1014 .ctl_in = qpa_ctl_in 956 1015 }; 957 1016
+1 -1
audio/rate_template.h
··· 28 28 * Return number of samples processed. 29 29 */ 30 30 void NAME (void *opaque, struct st_sample *ibuf, struct st_sample *obuf, 31 - int *isamp, int *osamp) 31 + size_t *isamp, size_t *osamp) 32 32 { 33 33 struct rate *rate = opaque; 34 34 struct st_sample *istart, *iend;
+12 -18
audio/sdlaudio.c
··· 41 41 42 42 typedef struct SDLVoiceOut { 43 43 HWVoiceOut hw; 44 - int live; 45 - int decr; 44 + size_t live; 45 + size_t decr; 46 46 } SDLVoiceOut; 47 47 48 48 static struct SDLAudioState { ··· 184 184 SDLVoiceOut *sdl = opaque; 185 185 SDLAudioState *s = &glob_sdl; 186 186 HWVoiceOut *hw = &sdl->hw; 187 - int samples = len >> hw->info.shift; 188 - int to_mix, decr; 187 + size_t samples = len >> hw->info.shift; 188 + size_t to_mix, decr; 189 189 190 190 if (s->exit || !sdl->live) { 191 191 return; 192 192 } 193 193 194 - /* dolog ("in callback samples=%d live=%d\n", samples, sdl->live); */ 194 + /* dolog ("in callback samples=%zu live=%zu\n", samples, sdl->live); */ 195 195 196 - to_mix = audio_MIN(samples, sdl->live); 196 + to_mix = MIN(samples, sdl->live); 197 197 decr = to_mix; 198 198 while (to_mix) { 199 - int chunk = audio_MIN(to_mix, hw->samples - hw->rpos); 199 + size_t chunk = MIN(to_mix, hw->samples - hw->rpos); 200 200 struct st_sample *src = hw->mix_buf + hw->rpos; 201 201 202 - /* dolog ("in callback to_mix %d, chunk %d\n", to_mix, chunk); */ 202 + /* dolog ("in callback to_mix %zu, chunk %zu\n", to_mix, chunk); */ 203 203 hw->clip(buf, src, chunk); 204 204 hw->rpos = (hw->rpos + chunk) % hw->samples; 205 205 to_mix -= chunk; ··· 209 209 sdl->live -= decr; 210 210 sdl->decr += decr; 211 211 212 - /* dolog ("done len=%d\n", len); */ 212 + /* dolog ("done len=%zu\n", len); */ 213 213 214 214 /* SDL2 does not clear the remaining buffer for us, so do it on our own */ 215 215 if (samples) { ··· 217 217 } 218 218 } 219 219 220 - static int sdl_write_out (SWVoiceOut *sw, void *buf, int len) 221 - { 222 - return audio_pcm_sw_write (sw, buf, len); 223 - } 224 - 225 - static int sdl_run_out (HWVoiceOut *hw, int live) 220 + static size_t sdl_run_out(HWVoiceOut *hw, size_t live) 226 221 { 227 - int decr; 222 + size_t decr; 228 223 SDLVoiceOut *sdl = (SDLVoiceOut *) hw; 229 224 230 225 SDL_LockAudio(); ··· 236 231 sdl->live); 237 232 } 238 233 239 - decr = audio_MIN (sdl->decr, live); 234 + decr = MIN (sdl->decr, live); 240 235 sdl->decr -= decr; 241 236 242 237 sdl->live = live; ··· 342 337 .init_out = sdl_init_out, 343 338 .fini_out = sdl_fini_out, 344 339 .run_out = sdl_run_out, 345 - .write = sdl_write_out, 346 340 .ctl_out = sdl_ctl_out, 347 341 }; 348 342
+11 -23
audio/spiceaudio.c
··· 152 152 spice_server_remove_interface (&out->sin.base); 153 153 } 154 154 155 - static int line_out_run (HWVoiceOut *hw, int live) 155 + static size_t line_out_run (HWVoiceOut *hw, size_t live) 156 156 { 157 157 SpiceVoiceOut *out = container_of (hw, SpiceVoiceOut, hw); 158 - int rpos, decr; 159 - int samples; 158 + size_t rpos, decr; 159 + size_t samples; 160 160 161 161 if (!live) { 162 162 return 0; 163 163 } 164 164 165 165 decr = rate_get_samples (&hw->info, &out->rate); 166 - decr = audio_MIN (live, decr); 166 + decr = MIN (live, decr); 167 167 168 168 samples = decr; 169 169 rpos = hw->rpos; 170 170 while (samples) { 171 171 int left_till_end_samples = hw->samples - rpos; 172 - int len = audio_MIN (samples, left_till_end_samples); 172 + int len = MIN (samples, left_till_end_samples); 173 173 174 174 if (!out->frame) { 175 175 spice_server_playback_get_buffer (&out->sin, &out->frame, &out->fsize); 176 176 out->fpos = out->frame; 177 177 } 178 178 if (out->frame) { 179 - len = audio_MIN (len, out->fsize); 179 + len = MIN (len, out->fsize); 180 180 hw->clip (out->fpos, hw->mix_buf + rpos, len); 181 181 out->fsize -= len; 182 182 out->fpos += len; ··· 190 190 } 191 191 hw->rpos = rpos; 192 192 return decr; 193 - } 194 - 195 - static int line_out_write (SWVoiceOut *sw, void *buf, int len) 196 - { 197 - return audio_pcm_sw_write (sw, buf, len); 198 193 } 199 194 200 195 static int line_out_ctl (HWVoiceOut *hw, int cmd, ...) ··· 280 275 spice_server_remove_interface (&in->sin.base); 281 276 } 282 277 283 - static int line_in_run (HWVoiceIn *hw) 278 + static size_t line_in_run(HWVoiceIn *hw) 284 279 { 285 280 SpiceVoiceIn *in = container_of (hw, SpiceVoiceIn, hw); 286 - int num_samples; 281 + size_t num_samples; 287 282 int ready; 288 - int len[2]; 283 + size_t len[2]; 289 284 uint64_t delta_samp; 290 285 const uint32_t *samples; 291 286 ··· 294 289 } 295 290 296 291 delta_samp = rate_get_samples (&hw->info, &in->rate); 297 - num_samples = audio_MIN (num_samples, delta_samp); 292 + num_samples = MIN (num_samples, delta_samp); 298 293 299 294 ready = spice_server_record_get_samples (&in->sin, in->samples, num_samples); 300 295 samples = in->samples; ··· 304 299 ready = LINE_IN_SAMPLES; 305 300 } 306 301 307 - num_samples = audio_MIN (ready, num_samples); 302 + num_samples = MIN (ready, num_samples); 308 303 309 304 if (hw->wpos + num_samples > hw->samples) { 310 305 len[0] = hw->samples - hw->wpos; ··· 323 318 hw->wpos = (hw->wpos + num_samples) % hw->samples; 324 319 325 320 return num_samples; 326 - } 327 - 328 - static int line_in_read (SWVoiceIn *sw, void *buf, int size) 329 - { 330 - return audio_pcm_sw_read (sw, buf, size); 331 321 } 332 322 333 323 static int line_in_ctl (HWVoiceIn *hw, int cmd, ...) ··· 377 367 .init_out = line_out_init, 378 368 .fini_out = line_out_fini, 379 369 .run_out = line_out_run, 380 - .write = line_out_write, 381 370 .ctl_out = line_out_ctl, 382 371 383 372 .init_in = line_in_init, 384 373 .fini_in = line_in_fini, 385 374 .run_in = line_in_run, 386 - .read = line_in_read, 387 375 .ctl_in = line_in_ctl, 388 376 }; 389 377
+6 -12
audio/wavaudio.c
··· 40 40 int total_samples; 41 41 } WAVVoiceOut; 42 42 43 - static int wav_run_out (HWVoiceOut *hw, int live) 43 + static size_t wav_run_out(HWVoiceOut *hw, size_t live) 44 44 { 45 45 WAVVoiceOut *wav = (WAVVoiceOut *) hw; 46 - int rpos, decr, samples; 46 + size_t rpos, decr, samples; 47 47 uint8_t *dst; 48 48 struct st_sample *src; 49 49 int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); ··· 59 59 } 60 60 61 61 wav->old_ticks = now; 62 - decr = audio_MIN (live, samples); 62 + decr = MIN (live, samples); 63 63 samples = decr; 64 64 rpos = hw->rpos; 65 65 while (samples) { 66 66 int left_till_end_samples = hw->samples - rpos; 67 - int convert_samples = audio_MIN (samples, left_till_end_samples); 67 + int convert_samples = MIN (samples, left_till_end_samples); 68 68 69 69 src = hw->mix_buf + rpos; 70 70 dst = advance (wav->pcm_buf, rpos << hw->info.shift); ··· 84 84 return decr; 85 85 } 86 86 87 - static int wav_write_out (SWVoiceOut *sw, void *buf, int len) 88 - { 89 - return audio_pcm_sw_write (sw, buf, len); 90 - } 91 - 92 87 /* VICE code: Store number as little endian. */ 93 88 static void le_store (uint8_t *buf, uint32_t val, int len) 94 89 { ··· 144 139 hw->samples = 1024; 145 140 wav->pcm_buf = audio_calloc(__func__, hw->samples, 1 << hw->info.shift); 146 141 if (!wav->pcm_buf) { 147 - dolog ("Could not allocate buffer (%d bytes)\n", 148 - hw->samples << hw->info.shift); 142 + dolog("Could not allocate buffer (%zu bytes)\n", 143 + hw->samples << hw->info.shift); 149 144 return -1; 150 145 } 151 146 ··· 240 235 .init_out = wav_init_out, 241 236 .fini_out = wav_fini_out, 242 237 .run_out = wav_run_out, 243 - .write = wav_write_out, 244 238 .ctl_out = wav_ctl_out, 245 239 }; 246 240
+3 -3
audio/wavcapture.c
··· 104 104 .info = wav_capture_info 105 105 }; 106 106 107 - int wav_start_capture (CaptureState *s, const char *path, int freq, 108 - int bits, int nchannels) 107 + int wav_start_capture(AudioState *state, CaptureState *s, const char *path, 108 + int freq, int bits, int nchannels) 109 109 { 110 110 WAVState *wav; 111 111 uint8_t hdr[] = { ··· 170 170 goto error_free; 171 171 } 172 172 173 - cap = AUD_add_capture (&as, &ops, wav); 173 + cap = AUD_add_capture(state, &as, &ops, wav); 174 174 if (!cap) { 175 175 error_report("Failed to add audio capture"); 176 176 goto error_free;
+6 -5
hmp-commands.hx
··· 819 819 820 820 { 821 821 .name = "wavcapture", 822 - .args_type = "path:F,freq:i?,bits:i?,nchannels:i?", 823 - .params = "path [frequency [bits [channels]]]", 822 + .args_type = "path:F,audiodev:s,freq:i?,bits:i?,nchannels:i?", 823 + .params = "path audiodev [frequency [bits [channels]]]", 824 824 .help = "capture audio to a wave file (default frequency=44100 bits=16 channels=2)", 825 825 .cmd = hmp_wavcapture, 826 826 }, 827 827 STEXI 828 - @item wavcapture @var{filename} [@var{frequency} [@var{bits} [@var{channels}]]] 828 + @item wavcapture @var{filename} @var{audiodev} [@var{frequency} [@var{bits} [@var{channels}]]] 829 829 @findex wavcapture 830 - Capture audio into @var{filename}. Using sample rate @var{frequency} 831 - bits per sample @var{bits} and number of channels @var{channels}. 830 + Capture audio into @var{filename} from @var{audiodev}, using sample rate 831 + @var{frequency} bits per sample @var{bits} and number of channels 832 + @var{channels}. 832 833 833 834 Defaults: 834 835 @itemize @minus
+6 -5
hw/audio/ac97.c
··· 965 965 uint32_t temp = r->picb << 1; 966 966 uint32_t written = 0; 967 967 int to_copy = 0; 968 - temp = audio_MIN (temp, max); 968 + temp = MIN (temp, max); 969 969 970 970 if (!temp) { 971 971 *stop = 1; ··· 974 974 975 975 while (temp) { 976 976 int copied; 977 - to_copy = audio_MIN (temp, sizeof (tmpbuf)); 977 + to_copy = MIN (temp, sizeof (tmpbuf)); 978 978 pci_dma_read (&s->dev, addr, tmpbuf, to_copy); 979 979 copied = AUD_write (s->voice_po, tmpbuf, to_copy); 980 980 dolog ("write_audio max=%x to_copy=%x copied=%x\n", ··· 1020 1020 } 1021 1021 1022 1022 while (elapsed) { 1023 - int temp = audio_MIN (elapsed, sizeof (s->silence)); 1023 + int temp = MIN (elapsed, sizeof (s->silence)); 1024 1024 while (temp) { 1025 1025 int copied = AUD_write (s->voice_po, s->silence, temp); 1026 1026 if (!copied) ··· 1041 1041 int to_copy = 0; 1042 1042 SWVoiceIn *voice = (r - s->bm_regs) == MC_INDEX ? s->voice_mc : s->voice_pi; 1043 1043 1044 - temp = audio_MIN (temp, max); 1044 + temp = MIN (temp, max); 1045 1045 1046 1046 if (!temp) { 1047 1047 *stop = 1; ··· 1050 1050 1051 1051 while (temp) { 1052 1052 int acquired; 1053 - to_copy = audio_MIN (temp, sizeof (tmpbuf)); 1053 + to_copy = MIN (temp, sizeof (tmpbuf)); 1054 1054 acquired = AUD_read (voice, tmpbuf, to_copy); 1055 1055 if (!acquired) { 1056 1056 *stop = 1; ··· 1410 1410 } 1411 1411 1412 1412 static Property ac97_properties[] = { 1413 + DEFINE_AUDIO_PROPERTIES(AC97LinkState, card), 1413 1414 DEFINE_PROP_UINT32 ("use_broken_id", AC97LinkState, use_broken_id, 0), 1414 1415 DEFINE_PROP_END_OF_LIST (), 1415 1416 };
+3 -2
hw/audio/adlib.c
··· 195 195 return; 196 196 } 197 197 198 - to_play = audio_MIN (s->left, samples); 198 + to_play = MIN (s->left, samples); 199 199 while (to_play) { 200 200 written = write_audio (s, to_play); 201 201 ··· 210 210 } 211 211 } 212 212 213 - samples = audio_MIN (samples, s->samples - s->pos); 213 + samples = MIN (samples, s->samples - s->pos); 214 214 if (!samples) { 215 215 return; 216 216 } ··· 299 299 } 300 300 301 301 static Property adlib_properties[] = { 302 + DEFINE_AUDIO_PROPERTIES(AdlibState, card), 302 303 DEFINE_PROP_UINT32 ("iobase", AdlibState, port, 0x220), 303 304 DEFINE_PROP_UINT32 ("freq", AdlibState, freq, 44100), 304 305 DEFINE_PROP_END_OF_LIST (),
+3 -2
hw/audio/cs4231a.c
··· 536 536 int copied; 537 537 size_t to_copy; 538 538 539 - to_copy = audio_MIN (temp, left); 539 + to_copy = MIN (temp, left); 540 540 if (to_copy > sizeof (tmpbuf)) { 541 541 to_copy = sizeof (tmpbuf); 542 542 } ··· 579 579 till = (s->dregs[Playback_Lower_Base_Count] 580 580 | (s->dregs[Playback_Upper_Base_Count] << 8)) << s->shift; 581 581 till -= s->transferred; 582 - copy = audio_MIN (till, copy); 582 + copy = MIN (till, copy); 583 583 } 584 584 585 585 if ((copy <= 0) || (dma_len <= 0)) { ··· 690 690 } 691 691 692 692 static Property cs4231a_properties[] = { 693 + DEFINE_AUDIO_PROPERTIES(CSState, card), 693 694 DEFINE_PROP_UINT32 ("iobase", CSState, port, 0x534), 694 695 DEFINE_PROP_UINT32 ("irq", CSState, irq, 9), 695 696 DEFINE_PROP_UINT32 ("dma", CSState, dma, 3),
+9 -4
hw/audio/es1370.c
··· 645 645 int size = d->frame_cnt & 0xffff; 646 646 int left = ((size - cnt + 1) << 2) + d->leftover; 647 647 int transferred = 0; 648 - int temp = audio_MIN (max, audio_MIN (left, csc_bytes)); 648 + int temp = MIN (max, MIN (left, csc_bytes)); 649 649 int index = d - &s->chan[0]; 650 650 651 651 addr += (cnt << 2) + d->leftover; ··· 654 654 while (temp) { 655 655 int acquired, to_copy; 656 656 657 - to_copy = audio_MIN ((size_t) temp, sizeof (tmpbuf)); 657 + to_copy = MIN ((size_t) temp, sizeof (tmpbuf)); 658 658 acquired = AUD_read (s->adc_voice, tmpbuf, to_copy); 659 659 if (!acquired) 660 660 break; ··· 672 672 while (temp) { 673 673 int copied, to_copy; 674 674 675 - to_copy = audio_MIN ((size_t) temp, sizeof (tmpbuf)); 675 + to_copy = MIN ((size_t) temp, sizeof (tmpbuf)); 676 676 pci_dma_read (&s->dev, addr, tmpbuf, to_copy); 677 677 copied = AUD_write (voice, tmpbuf, to_copy); 678 678 if (!copied) ··· 887 887 return 0; 888 888 } 889 889 890 + static Property es1370_properties[] = { 891 + DEFINE_AUDIO_PROPERTIES(ES1370State, card), 892 + DEFINE_PROP_END_OF_LIST(), 893 + }; 894 + 890 895 static void es1370_class_init (ObjectClass *klass, void *data) 891 896 { 892 897 DeviceClass *dc = DEVICE_CLASS (klass); ··· 903 908 dc->desc = "ENSONIQ AudioPCI ES1370"; 904 909 dc->vmsd = &vmstate_es1370; 905 910 dc->reset = es1370_on_reset; 911 + dc->props = es1370_properties; 906 912 } 907 913 908 914 static const TypeInfo es1370_info = { ··· 923 929 } 924 930 925 931 type_init (es1370_register_types) 926 -
+4 -3
hw/audio/gus.c
··· 119 119 GUSState *s = opaque; 120 120 121 121 samples = free >> s->shift; 122 - to_play = audio_MIN (samples, s->left); 122 + to_play = MIN (samples, s->left); 123 123 124 124 while (to_play) { 125 125 int written = write_audio (s, to_play); ··· 134 134 net += written; 135 135 } 136 136 137 - samples = audio_MIN (samples, s->samples); 137 + samples = MIN (samples, s->samples); 138 138 if (samples) { 139 139 gus_mixvoices (&s->emu, s->freq, samples, s->mixbuf); 140 140 ··· 194 194 ldebug ("read DMA %#x %d\n", dma_pos, dma_len); 195 195 mode = k->has_autoinitialization(s->isa_dma, s->emu.gusdma); 196 196 while (left) { 197 - int to_copy = audio_MIN ((size_t) left, sizeof (tmpbuf)); 197 + int to_copy = MIN ((size_t) left, sizeof (tmpbuf)); 198 198 int copied; 199 199 200 200 ldebug ("left=%d to_copy=%d pos=%d\n", left, to_copy, pos); ··· 299 299 } 300 300 301 301 static Property gus_properties[] = { 302 + DEFINE_AUDIO_PROPERTIES(GUSState, card), 302 303 DEFINE_PROP_UINT32 ("freq", GUSState, freq, 44100), 303 304 DEFINE_PROP_UINT32 ("iobase", GUSState, port, 0x240), 304 305 DEFINE_PROP_UINT32 ("irq", GUSState, emu.gusirq, 7),
+9 -8
hw/audio/hda-codec.c
··· 235 235 goto out_timer; 236 236 } 237 237 238 - int64_t to_transfer = audio_MIN(wpos - rpos, wanted_rpos - rpos); 238 + int64_t to_transfer = MIN(wpos - rpos, wanted_rpos - rpos); 239 239 while (to_transfer) { 240 240 uint32_t start = (rpos & B_MASK); 241 - uint32_t chunk = audio_MIN(B_SIZE - start, to_transfer); 241 + uint32_t chunk = MIN(B_SIZE - start, to_transfer); 242 242 int rc = hda_codec_xfer( 243 243 &st->state->hda, st->stream, false, st->buf + start, chunk); 244 244 if (!rc) { ··· 263 263 int64_t wpos = st->wpos; 264 264 int64_t rpos = st->rpos; 265 265 266 - int64_t to_transfer = audio_MIN(B_SIZE - (wpos - rpos), avail); 266 + int64_t to_transfer = MIN(B_SIZE - (wpos - rpos), avail); 267 267 268 268 hda_timer_sync_adjust(st, -((wpos - rpos) + to_transfer - (B_SIZE >> 1))); 269 269 270 270 while (to_transfer) { 271 271 uint32_t start = (uint32_t) (wpos & B_MASK); 272 - uint32_t chunk = (uint32_t) audio_MIN(B_SIZE - start, to_transfer); 272 + uint32_t chunk = (uint32_t) MIN(B_SIZE - start, to_transfer); 273 273 uint32_t read = AUD_read(st->voice.in, st->buf + start, chunk); 274 274 wpos += read; 275 275 to_transfer -= read; ··· 299 299 goto out_timer; 300 300 } 301 301 302 - int64_t to_transfer = audio_MIN(B_SIZE - (wpos - rpos), wanted_wpos - wpos); 302 + int64_t to_transfer = MIN(B_SIZE - (wpos - rpos), wanted_wpos - wpos); 303 303 while (to_transfer) { 304 304 uint32_t start = (wpos & B_MASK); 305 - uint32_t chunk = audio_MIN(B_SIZE - start, to_transfer); 305 + uint32_t chunk = MIN(B_SIZE - start, to_transfer); 306 306 int rc = hda_codec_xfer( 307 307 &st->state->hda, st->stream, true, st->buf + start, chunk); 308 308 if (!rc) { ··· 327 327 int64_t wpos = st->wpos; 328 328 int64_t rpos = st->rpos; 329 329 330 - int64_t to_transfer = audio_MIN(wpos - rpos, avail); 330 + int64_t to_transfer = MIN(wpos - rpos, avail); 331 331 332 332 if (wpos - rpos == B_SIZE) { 333 333 /* drop buffer, reset timer adjust */ ··· 342 342 343 343 while (to_transfer) { 344 344 uint32_t start = (uint32_t) (rpos & B_MASK); 345 - uint32_t chunk = (uint32_t) audio_MIN(B_SIZE - start, to_transfer); 345 + uint32_t chunk = (uint32_t) MIN(B_SIZE - start, to_transfer); 346 346 uint32_t written = AUD_write(st->voice.out, st->buf + start, chunk); 347 347 rpos += written; 348 348 to_transfer -= written; ··· 841 841 }; 842 842 843 843 static Property hda_audio_properties[] = { 844 + DEFINE_AUDIO_PROPERTIES(HDAAudioState, card), 844 845 DEFINE_PROP_UINT32("debug", HDAAudioState, debug, 0), 845 846 DEFINE_PROP_BOOL("mixer", HDAAudioState, mixer, true), 846 847 DEFINE_PROP_BOOL("use-timer", HDAAudioState, use_timer, true),
+10 -4
hw/audio/milkymist-ac97.c
··· 185 185 MilkymistAC97State *s = opaque; 186 186 uint8_t buf[4096]; 187 187 uint32_t remaining = s->regs[R_U_REMAINING]; 188 - int temp = audio_MIN(remaining, avail_b); 188 + int temp = MIN(remaining, avail_b); 189 189 uint32_t addr = s->regs[R_U_ADDR]; 190 190 int transferred = 0; 191 191 ··· 199 199 while (temp) { 200 200 int acquired, to_copy; 201 201 202 - to_copy = audio_MIN(temp, sizeof(buf)); 202 + to_copy = MIN(temp, sizeof(buf)); 203 203 acquired = AUD_read(s->voice_in, buf, to_copy); 204 204 if (!acquired) { 205 205 break; ··· 228 228 MilkymistAC97State *s = opaque; 229 229 uint8_t buf[4096]; 230 230 uint32_t remaining = s->regs[R_D_REMAINING]; 231 - int temp = audio_MIN(remaining, free_b); 231 + int temp = MIN(remaining, free_b); 232 232 uint32_t addr = s->regs[R_D_ADDR]; 233 233 int transferred = 0; 234 234 ··· 242 242 while (temp) { 243 243 int copied, to_copy; 244 244 245 - to_copy = audio_MIN(temp, sizeof(buf)); 245 + to_copy = MIN(temp, sizeof(buf)); 246 246 cpu_physical_memory_read(addr, buf, to_copy); 247 247 copied = AUD_write(s->voice_out, buf, to_copy); 248 248 if (!copied) { ··· 330 330 } 331 331 }; 332 332 333 + static Property milkymist_ac97_properties[] = { 334 + DEFINE_AUDIO_PROPERTIES(MilkymistAC97State, card), 335 + DEFINE_PROP_END_OF_LIST(), 336 + }; 337 + 333 338 static void milkymist_ac97_class_init(ObjectClass *klass, void *data) 334 339 { 335 340 DeviceClass *dc = DEVICE_CLASS(klass); ··· 337 342 dc->realize = milkymist_ac97_realize; 338 343 dc->reset = milkymist_ac97_reset; 339 344 dc->vmsd = &vmstate_milkymist_ac97; 345 + dc->props = milkymist_ac97_properties; 340 346 } 341 347 342 348 static const TypeInfo milkymist_ac97_info = {
+2 -1
hw/audio/pcspk.c
··· 103 103 } 104 104 105 105 while (free > 0) { 106 - n = audio_MIN(s->samples - s->play_pos, (unsigned int)free); 106 + n = MIN(s->samples - s->play_pos, (unsigned int)free); 107 107 n = AUD_write(s->voice, &s->sample_buf[s->play_pos], n); 108 108 if (!n) 109 109 break; ··· 209 209 }; 210 210 211 211 static Property pcspk_properties[] = { 212 + DEFINE_AUDIO_PROPERTIES(PCSpkState, card), 212 213 DEFINE_PROP_UINT32("iobase", PCSpkState, iobase, -1), 213 214 DEFINE_PROP_BOOL("migrate", PCSpkState, migrate, true), 214 215 DEFINE_PROP_END_OF_LIST(),
+1
hw/audio/pl041.c
··· 625 625 }; 626 626 627 627 static Property pl041_device_properties[] = { 628 + DEFINE_AUDIO_PROPERTIES(PL041State, codec.card), 628 629 /* Non-compact FIFO depth property */ 629 630 DEFINE_PROP_UINT32("nc_fifo_depth", PL041State, fifo_depth, 630 631 DEFAULT_FIFO_DEPTH),
+2 -1
hw/audio/sb16.c
··· 1169 1169 int copied; 1170 1170 size_t to_copy; 1171 1171 1172 - to_copy = audio_MIN (temp, left); 1172 + to_copy = MIN (temp, left); 1173 1173 if (to_copy > sizeof (tmpbuf)) { 1174 1174 to_copy = sizeof (tmpbuf); 1175 1175 } ··· 1422 1422 } 1423 1423 1424 1424 static Property sb16_properties[] = { 1425 + DEFINE_AUDIO_PROPERTIES(SB16State, card), 1425 1426 DEFINE_PROP_UINT32 ("version", SB16State, ver, 0x0405), /* 4.5 */ 1426 1427 DEFINE_PROP_UINT32 ("iobase", SB16State, port, 0x220), 1427 1428 DEFINE_PROP_UINT32 ("irq", SB16State, irq, 5),
+8 -2
hw/audio/wm8750.c
··· 70 70 { 71 71 if (s->idx_in + s->req_in <= sizeof(s->data_in)) 72 72 return; 73 - s->idx_in = audio_MAX(0, (int) sizeof(s->data_in) - s->req_in); 73 + s->idx_in = MAX(0, (int) sizeof(s->data_in) - s->req_in); 74 74 AUD_read(*s->in[0], s->data_in + s->idx_in, 75 75 sizeof(s->data_in) - s->idx_in); 76 76 } ··· 101 101 wm8750_out_flush(s); 102 102 } else 103 103 s->req_out = free_b - s->idx_out; 104 - 104 + 105 105 s->data_req(s->opaque, s->req_out >> 2, s->req_in >> 2); 106 106 } 107 107 ··· 702 702 wm8750_clk_update(s, 1); 703 703 } 704 704 705 + static Property wm8750_properties[] = { 706 + DEFINE_AUDIO_PROPERTIES(WM8750State, card), 707 + DEFINE_PROP_END_OF_LIST(), 708 + }; 709 + 705 710 static void wm8750_class_init(ObjectClass *klass, void *data) 706 711 { 707 712 DeviceClass *dc = DEVICE_CLASS(klass); ··· 712 717 sc->recv = wm8750_rx; 713 718 sc->send = wm8750_tx; 714 719 dc->vmsd = &vmstate_wm8750; 720 + dc->props = wm8750_properties; 715 721 } 716 722 717 723 static const TypeInfo wm8750_info = {
+57
hw/core/qdev-properties-system.c
··· 11 11 */ 12 12 13 13 #include "qemu/osdep.h" 14 + #include "audio/audio.h" 14 15 #include "net/net.h" 15 16 #include "hw/qdev-properties.h" 16 17 #include "qapi/error.h" ··· 352 353 .set = set_netdev, 353 354 }; 354 355 356 + 357 + /* --- audiodev --- */ 358 + static void get_audiodev(Object *obj, Visitor *v, const char* name, 359 + void *opaque, Error **errp) 360 + { 361 + DeviceState *dev = DEVICE(obj); 362 + Property *prop = opaque; 363 + QEMUSoundCard *card = qdev_get_prop_ptr(dev, prop); 364 + char *p = g_strdup(audio_get_id(card)); 365 + 366 + visit_type_str(v, name, &p, errp); 367 + g_free(p); 368 + } 369 + 370 + static void set_audiodev(Object *obj, Visitor *v, const char* name, 371 + void *opaque, Error **errp) 372 + { 373 + DeviceState *dev = DEVICE(obj); 374 + Property *prop = opaque; 375 + QEMUSoundCard *card = qdev_get_prop_ptr(dev, prop); 376 + AudioState *state; 377 + Error *local_err = NULL; 378 + int err = 0; 379 + char *str; 380 + 381 + if (dev->realized) { 382 + qdev_prop_set_after_realize(dev, name, errp); 383 + return; 384 + } 385 + 386 + visit_type_str(v, name, &str, &local_err); 387 + if (local_err) { 388 + error_propagate(errp, local_err); 389 + return; 390 + } 391 + 392 + state = audio_state_by_name(str); 393 + 394 + if (!state) { 395 + err = -ENOENT; 396 + goto out; 397 + } 398 + card->state = state; 399 + 400 + out: 401 + error_set_from_qdev_prop_error(errp, err, dev, prop, str); 402 + g_free(str); 403 + } 404 + 405 + const PropertyInfo qdev_prop_audiodev = { 406 + .name = "str", 407 + .description = "ID of an audiodev to use as a backend", 408 + /* release done on shutdown */ 409 + .get = get_audiodev, 410 + .set = set_audiodev, 411 + }; 355 412 356 413 void qdev_prop_set_drive(DeviceState *dev, const char *name, 357 414 BlockBackend *value, Error **errp)
+1
hw/usb/dev-audio.c
··· 667 667 }; 668 668 669 669 static Property usb_audio_properties[] = { 670 + DEFINE_AUDIO_PROPERTIES(USBAudioState, card), 670 671 DEFINE_PROP_UINT32("debug", USBAudioState, debug, 0), 671 672 DEFINE_PROP_UINT32("buffer", USBAudioState, buffer, 672 673 32 * USBAUDIO_PACKET_SIZE),
+3
include/hw/qdev-properties.h
··· 33 33 extern const PropertyInfo qdev_prop_pci_host_devaddr; 34 34 extern const PropertyInfo qdev_prop_uuid; 35 35 extern const PropertyInfo qdev_prop_arraylen; 36 + extern const PropertyInfo qdev_prop_audiodev; 36 37 extern const PropertyInfo qdev_prop_link; 37 38 extern const PropertyInfo qdev_prop_off_auto_pcibar; 38 39 extern const PropertyInfo qdev_prop_pcie_link_speed; ··· 234 235 + type_check(QemuUUID, typeof_field(_state, _field)), \ 235 236 .set_default = true, \ 236 237 } 238 + #define DEFINE_PROP_AUDIODEV(_n, _s, _f) \ 239 + DEFINE_PROP(_n, _s, _f, qdev_prop_audiodev, QEMUSoundCard) 237 240 238 241 #define DEFINE_PROP_END_OF_LIST() \ 239 242 {}
+2 -2
include/sysemu/replay.h
··· 179 179 /* Audio */ 180 180 181 181 /*! Saves/restores number of played samples of audio out operation. */ 182 - void replay_audio_out(int *played); 182 + void replay_audio_out(size_t *played); 183 183 /*! Saves/restores recorded samples of audio in operation. */ 184 - void replay_audio_in(int *recorded, void *samples, int *wpos, int size); 184 + void replay_audio_in(size_t *recorded, void *samples, size_t *wpos, size_t size); 185 185 186 186 /* VM state operations */ 187 187
+11 -11
monitor/misc.c
··· 1142 1142 static void hmp_wavcapture(Monitor *mon, const QDict *qdict) 1143 1143 { 1144 1144 const char *path = qdict_get_str(qdict, "path"); 1145 - int has_freq = qdict_haskey(qdict, "freq"); 1146 - int freq = qdict_get_try_int(qdict, "freq", -1); 1147 - int has_bits = qdict_haskey(qdict, "bits"); 1148 - int bits = qdict_get_try_int(qdict, "bits", -1); 1149 - int has_channels = qdict_haskey(qdict, "nchannels"); 1150 - int nchannels = qdict_get_try_int(qdict, "nchannels", -1); 1145 + int freq = qdict_get_try_int(qdict, "freq", 44100); 1146 + int bits = qdict_get_try_int(qdict, "bits", 16); 1147 + int nchannels = qdict_get_try_int(qdict, "nchannels", 2); 1148 + const char *audiodev = qdict_get_str(qdict, "audiodev"); 1151 1149 CaptureState *s; 1150 + AudioState *as = audio_state_by_name(audiodev); 1151 + 1152 + if (!as) { 1153 + monitor_printf(mon, "Audiodev '%s' not found\n", audiodev); 1154 + return; 1155 + } 1152 1156 1153 1157 s = g_malloc0 (sizeof (*s)); 1154 1158 1155 - freq = has_freq ? freq : 44100; 1156 - bits = has_bits ? bits : 16; 1157 - nchannels = has_channels ? nchannels : 2; 1158 - 1159 - if (wav_start_capture (s, path, freq, bits, nchannels)) { 1159 + if (wav_start_capture(as, s, path, freq, bits, nchannels)) { 1160 1160 monitor_printf(mon, "Failed to add wave capture\n"); 1161 1161 g_free (s); 1162 1162 return;
+6
qemu-options.hx
··· 1978 1978 events are arriving in bulk. Possible causes for the latter are flaky 1979 1979 network connections, or scripts for automated testing. 1980 1980 1981 + @item audiodev=@var{audiodev} 1982 + 1983 + Use the specified @var{audiodev} when the VNC client requests audio 1984 + transmission. When not using an -audiodev argument, this option must 1985 + be omitted, otherwise is must be present and specify a valid audiodev. 1986 + 1981 1987 @end table 1982 1988 ETEXI 1983 1989
+8 -8
replay/replay-audio.c
··· 15 15 #include "replay-internal.h" 16 16 #include "audio/audio.h" 17 17 18 - void replay_audio_out(int *played) 18 + void replay_audio_out(size_t *played) 19 19 { 20 20 if (replay_mode == REPLAY_MODE_RECORD) { 21 21 g_assert(replay_mutex_locked()); 22 22 replay_save_instructions(); 23 23 replay_put_event(EVENT_AUDIO_OUT); 24 - replay_put_dword(*played); 24 + replay_put_qword(*played); 25 25 } else if (replay_mode == REPLAY_MODE_PLAY) { 26 26 g_assert(replay_mutex_locked()); 27 27 replay_account_executed_instructions(); 28 28 if (replay_next_event_is(EVENT_AUDIO_OUT)) { 29 - *played = replay_get_dword(); 29 + *played = replay_get_qword(); 30 30 replay_finish_event(); 31 31 } else { 32 32 error_report("Missing audio out event in the replay log"); ··· 35 35 } 36 36 } 37 37 38 - void replay_audio_in(int *recorded, void *samples, int *wpos, int size) 38 + void replay_audio_in(size_t *recorded, void *samples, size_t *wpos, size_t size) 39 39 { 40 40 int pos; 41 41 uint64_t left, right; ··· 43 43 g_assert(replay_mutex_locked()); 44 44 replay_save_instructions(); 45 45 replay_put_event(EVENT_AUDIO_IN); 46 - replay_put_dword(*recorded); 47 - replay_put_dword(*wpos); 46 + replay_put_qword(*recorded); 47 + replay_put_qword(*wpos); 48 48 for (pos = (*wpos - *recorded + size) % size ; pos != *wpos 49 49 ; pos = (pos + 1) % size) { 50 50 audio_sample_to_uint64(samples, pos, &left, &right); ··· 55 55 g_assert(replay_mutex_locked()); 56 56 replay_account_executed_instructions(); 57 57 if (replay_next_event_is(EVENT_AUDIO_IN)) { 58 - *recorded = replay_get_dword(); 59 - *wpos = replay_get_dword(); 58 + *recorded = replay_get_qword(); 59 + *wpos = replay_get_qword(); 60 60 for (pos = (*wpos - *recorded + size) % size ; pos != *wpos 61 61 ; pos = (pos + 1) % size) { 62 62 left = replay_get_qword();
+1 -1
replay/replay.c
··· 22 22 23 23 /* Current version of the replay mechanism. 24 24 Increase it when file format changes. */ 25 - #define REPLAY_VERSION 0xe02007 25 + #define REPLAY_VERSION 0xe02008 26 26 /* Size of replay log header */ 27 27 #define HEADER_SIZE (sizeof(uint32_t) + sizeof(uint64_t)) 28 28
+14 -1
ui/vnc.c
··· 1224 1224 ops.destroy = audio_capture_destroy; 1225 1225 ops.capture = audio_capture; 1226 1226 1227 - vs->audio_cap = AUD_add_capture(&vs->as, &ops, vs); 1227 + vs->audio_cap = AUD_add_capture(vs->vd->audio_state, &vs->as, &ops, vs); 1228 1228 if (!vs->audio_cap) { 1229 1229 error_report("Failed to add audio capture"); 1230 1230 } ··· 3371 3371 },{ 3372 3372 .name = "non-adaptive", 3373 3373 .type = QEMU_OPT_BOOL, 3374 + },{ 3375 + .name = "audiodev", 3376 + .type = QEMU_OPT_STRING, 3374 3377 }, 3375 3378 { /* end of list */ } 3376 3379 }, ··· 3808 3811 const char *saslauthz; 3809 3812 int lock_key_sync = 1; 3810 3813 int key_delay_ms; 3814 + const char *audiodev; 3811 3815 3812 3816 if (!vd) { 3813 3817 error_setg(errp, "VNC display not active"); ··· 3992 3996 vd->led = qemu_add_led_event_handler(kbd_leds, vd); 3993 3997 } 3994 3998 vd->ledstate = 0; 3999 + 4000 + audiodev = qemu_opt_get(opts, "audiodev"); 4001 + if (audiodev) { 4002 + vd->audio_state = audio_state_by_name(audiodev); 4003 + if (!vd->audio_state) { 4004 + error_setg(errp, "Audiodev '%s' not found", audiodev); 4005 + goto fail; 4006 + } 4007 + } 3995 4008 3996 4009 device_id = qemu_opt_get(opts, "display"); 3997 4010 if (device_id) {
+2
ui/vnc.h
··· 182 182 #ifdef CONFIG_VNC_SASL 183 183 VncDisplaySASL sasl; 184 184 #endif 185 + 186 + AudioState *audio_state; 185 187 }; 186 188 187 189 typedef struct VncTight {