pwaudio.c (24a9095c13e34e95a89adbe7cb8e11179ff48f94) pwaudio.c (92fd78689d0b06a00637e4e821a502b194d09328)
1/*
2 * QEMU PipeWire audio driver
3 *
4 * Copyright (c) 2023 Red Hat Inc.
5 *
6 * Author: Dorinda Bassey <dbassey@redhat.com>
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later

--- 52 unchanged lines hidden (view full) ---

61 PWVoice v;
62} PWVoiceOut;
63
64typedef struct PWVoiceIn {
65 HWVoiceIn hw;
66 PWVoice v;
67} PWVoiceIn;
68
1/*
2 * QEMU PipeWire audio driver
3 *
4 * Copyright (c) 2023 Red Hat Inc.
5 *
6 * Author: Dorinda Bassey <dbassey@redhat.com>
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later

--- 52 unchanged lines hidden (view full) ---

61 PWVoice v;
62} PWVoiceOut;
63
64typedef struct PWVoiceIn {
65 HWVoiceIn hw;
66 PWVoice v;
67} PWVoiceIn;
68
69#define PW_VOICE_IN(v) ((PWVoiceIn *)v)
70#define PW_VOICE_OUT(v) ((PWVoiceOut *)v)
71
69static void
70stream_destroy(void *data)
71{
72 PWVoice *v = (PWVoice *) data;
73 spa_hook_remove(&v->stream_listener);
74 v->stream = NULL;
75}
76

--- 548 unchanged lines hidden (view full) ---

625 hw->samples = audio_buffer_frames(
626 qapi_AudiodevPipewirePerDirectionOptions_base(ppdo), &obt_as, 46440);
627
628 pw_thread_loop_unlock(c->thread_loop);
629 return 0;
630}
631
632static void
72static void
73stream_destroy(void *data)
74{
75 PWVoice *v = (PWVoice *) data;
76 spa_hook_remove(&v->stream_listener);
77 v->stream = NULL;
78}
79

--- 548 unchanged lines hidden (view full) ---

628 hw->samples = audio_buffer_frames(
629 qapi_AudiodevPipewirePerDirectionOptions_base(ppdo), &obt_as, 46440);
630
631 pw_thread_loop_unlock(c->thread_loop);
632 return 0;
633}
634
635static void
633qpw_fini_out(HWVoiceOut *hw)
636qpw_voice_fini(PWVoice *v)
634{
637{
635 PWVoiceOut *pw = (PWVoiceOut *) hw;
636 PWVoice *v = &pw->v;
638 pwaudio *c = v->g;
637
639
638 if (v->stream) {
639 pwaudio *c = v->g;
640 pw_thread_loop_lock(c->thread_loop);
641 pw_stream_destroy(v->stream);
642 v->stream = NULL;
643 pw_thread_loop_unlock(c->thread_loop);
640 if (!v->stream) {
641 return;
644 }
642 }
643 pw_thread_loop_lock(c->thread_loop);
644 pw_stream_destroy(v->stream);
645 v->stream = NULL;
646 pw_thread_loop_unlock(c->thread_loop);
645}
646
647static void
647}
648
649static void
648qpw_fini_in(HWVoiceIn *hw)
650qpw_fini_out(HWVoiceOut *hw)
649{
651{
650 PWVoiceIn *pw = (PWVoiceIn *) hw;
651 PWVoice *v = &pw->v;
652 qpw_voice_fini(&PW_VOICE_OUT(hw)->v);
653}
652
654
653 if (v->stream) {
654 pwaudio *c = v->g;
655 pw_thread_loop_lock(c->thread_loop);
656 pw_stream_destroy(v->stream);
657 v->stream = NULL;
658 pw_thread_loop_unlock(c->thread_loop);
659 }
655static void
656qpw_fini_in(HWVoiceIn *hw)
657{
658 qpw_voice_fini(&PW_VOICE_IN(hw)->v);
660}
661
662static void
659}
660
661static void
663qpw_enable_out(HWVoiceOut *hw, bool enable)
662qpw_voice_set_enabled(PWVoice *v, bool enable)
664{
663{
665 PWVoiceOut *po = (PWVoiceOut *) hw;
666 PWVoice *v = &po->v;
667 pwaudio *c = v->g;
668 pw_thread_loop_lock(c->thread_loop);
669 pw_stream_set_active(v->stream, enable);
670 pw_thread_loop_unlock(c->thread_loop);
671}
672
673static void
664 pwaudio *c = v->g;
665 pw_thread_loop_lock(c->thread_loop);
666 pw_stream_set_active(v->stream, enable);
667 pw_thread_loop_unlock(c->thread_loop);
668}
669
670static void
671qpw_enable_out(HWVoiceOut *hw, bool enable)
672{
673 qpw_voice_set_enabled(&PW_VOICE_OUT(hw)->v, enable);
674}
675
676static void
674qpw_enable_in(HWVoiceIn *hw, bool enable)
675{
677qpw_enable_in(HWVoiceIn *hw, bool enable)
678{
676 PWVoiceIn *pi = (PWVoiceIn *) hw;
677 PWVoice *v = &pi->v;
678 pwaudio *c = v->g;
679 pw_thread_loop_lock(c->thread_loop);
680 pw_stream_set_active(v->stream, enable);
681 pw_thread_loop_unlock(c->thread_loop);
679 qpw_voice_set_enabled(&PW_VOICE_IN(hw)->v, enable);
682}
683
684static void
680}
681
682static void
685qpw_volume_out(HWVoiceOut *hw, Volume *vol)
683qpw_voice_set_volume(PWVoice *v, Volume *vol)
686{
684{
687 PWVoiceOut *pw = (PWVoiceOut *) hw;
688 PWVoice *v = &pw->v;
689 pwaudio *c = v->g;
690 int i, ret;
691
692 pw_thread_loop_lock(c->thread_loop);
693 v->volume.channels = vol->channels;
694
695 for (i = 0; i < vol->channels; ++i) {
696 v->volume.values[i] = (float)vol->vol[i] / 255;

--- 5 unchanged lines hidden (view full) ---

702
703 v->muted = vol->mute;
704 float val = v->muted ? 1.f : 0.f;
705 ret = pw_stream_set_control(v->stream, SPA_PROP_mute, 1, &val, 0);
706 pw_thread_loop_unlock(c->thread_loop);
707}
708
709static void
685 pwaudio *c = v->g;
686 int i, ret;
687
688 pw_thread_loop_lock(c->thread_loop);
689 v->volume.channels = vol->channels;
690
691 for (i = 0; i < vol->channels; ++i) {
692 v->volume.values[i] = (float)vol->vol[i] / 255;

--- 5 unchanged lines hidden (view full) ---

698
699 v->muted = vol->mute;
700 float val = v->muted ? 1.f : 0.f;
701 ret = pw_stream_set_control(v->stream, SPA_PROP_mute, 1, &val, 0);
702 pw_thread_loop_unlock(c->thread_loop);
703}
704
705static void
710qpw_volume_in(HWVoiceIn *hw, Volume *vol)
706qpw_volume_out(HWVoiceOut *hw, Volume *vol)
711{
707{
712 PWVoiceIn *pw = (PWVoiceIn *) hw;
713 PWVoice *v = &pw->v;
714 pwaudio *c = v->g;
715 int i, ret;
708 qpw_voice_set_volume(&PW_VOICE_OUT(hw)->v, vol);
709}
716
710
717 pw_thread_loop_lock(c->thread_loop);
718 v->volume.channels = vol->channels;
719
720 for (i = 0; i < vol->channels; ++i) {
721 v->volume.values[i] = (float)vol->vol[i] / 255;
722 }
723
724 ret = pw_stream_set_control(v->stream,
725 SPA_PROP_channelVolumes, v->volume.channels, v->volume.values, 0);
726 trace_pw_vol(ret == 0 ? "success" : "failed");
727
728 v->muted = vol->mute;
729 float val = v->muted ? 1.f : 0.f;
730 ret = pw_stream_set_control(v->stream, SPA_PROP_mute, 1, &val, 0);
731 pw_thread_loop_unlock(c->thread_loop);
711static void
712qpw_volume_in(HWVoiceIn *hw, Volume *vol)
713{
714 qpw_voice_set_volume(&PW_VOICE_IN(hw)->v, vol);
732}
733
734static int wait_resync(pwaudio *pw)
735{
736 int res;
737 pw->pending_seq = pw_core_sync(pw->core, PW_ID_CORE, pw->pending_seq);
738
739 while (true) {

--- 164 unchanged lines hidden ---
715}
716
717static int wait_resync(pwaudio *pw)
718{
719 int res;
720 pw->pending_seq = pw_core_sync(pw->core, PW_ID_CORE, pw->pending_seq);
721
722 while (true) {

--- 164 unchanged lines hidden ---