@samitouri / QOSamiQemu / commits / 29a7f5da98

audio: move pcm_ops into AudioMixengBackendClass

Remove the separate audio_pcm_ops structure and move its function pointers directly into AudioMixengBackendClass. This is a cleaner QOM-style design where the PCM operations are part of the class vtable rather than a separate indirection through hw->pcm_ops. The HWVoiceOut and HWVoiceIn structures no longer need to store a pcm_ops pointer, as the operations are now accessed through the class with AUDIO_MIXENG_BACKEND_GET_CLASS(). Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp> Reviewed-by: Mark Cave-Ayland <mark.caveayland@nutanix.com>

Marc-André Lureau committed Jan 17, 2026 at 01:05 UTC 29a7f5da989328335815f53c8b291e052f183b13
16 files changed +308 -337
audio/alsaaudio.c
+13 -16
@@ -922,21 +922,6 @@ audio_alsa_realize(AudioBackend *abe, Audiodev *dev, Error **errp)
922 return audio_alsa_parent_class->realize(abe, dev, errp);
923 }
924
925 -static struct audio_pcm_ops alsa_pcm_ops = {
926 - .init_out = alsa_init_out,
927 - .fini_out = alsa_fini_out,
928 - .write = alsa_write,
929 - .buffer_get_free = alsa_buffer_get_free,
930 - .run_buffer_out = audio_generic_run_buffer_out,
931 - .enable_out = alsa_enable_out,
932 -
933 - .init_in = alsa_init_in,
934 - .fini_in = alsa_fini_in,
935 - .read = alsa_read,
936 - .run_buffer_in = audio_generic_run_buffer_in,
937 - .enable_in = alsa_enable_in,
938 -};
939 -
925 static void audio_alsa_class_init(ObjectClass *klass, const void *data)
926 {
927 AudioBackendClass *b = AUDIO_BACKEND_CLASS(klass);
@@ -946,11 +931,23 @@ static void audio_alsa_class_init(ObjectClass *klass, const void *data)
931
932 b->realize = audio_alsa_realize;
933 k->name = "alsa";
949 - k->pcm_ops = &alsa_pcm_ops;
934 k->max_voices_out = INT_MAX;
935 k->max_voices_in = INT_MAX;
936 k->voice_size_out = sizeof(ALSAVoiceOut);
937 k->voice_size_in = sizeof(ALSAVoiceIn);
938 +
939 + k->init_out = alsa_init_out;
940 + k->fini_out = alsa_fini_out;
941 + k->write = alsa_write;
942 + k->buffer_get_free = alsa_buffer_get_free;
943 + k->run_buffer_out = audio_generic_run_buffer_out;
944 + k->enable_out = alsa_enable_out;
945 +
946 + k->init_in = alsa_init_in;
947 + k->fini_in = alsa_fini_in;
948 + k->read = alsa_read;
949 + k->run_buffer_in = audio_generic_run_buffer_in;
950 + k->enable_in = alsa_enable_in;
951 }
952
953 static const TypeInfo audio_types[] = {
audio/audio-mixeng-be.c
+76 -63
@@ -526,7 +526,7 @@ static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t buf_len)
526
527 audio_pcm_sw_resample_in(sw, live, frames_out_max, &total_in, &total_out);
528
529 - if (!hw->pcm_ops->volume_in) {
529 + if (!AUDIO_MIXENG_BACKEND_GET_CLASS(hw->s)->volume_in) {
530 mixeng_volume(sw->resample_buf.buffer, total_out, &sw->vol);
531 }
532 sw->clip(buf, sw->resample_buf.buffer, total_out);
@@ -579,8 +579,10 @@ static size_t audio_pcm_hw_get_live_out (HWVoiceOut *hw, int *nb_live)
579
580 static size_t audio_pcm_hw_get_free(HWVoiceOut *hw)
581 {
582 - return (hw->pcm_ops->buffer_get_free ? hw->pcm_ops->buffer_get_free(hw) :
583 - INT_MAX) / hw->info.bytes_per_frame;
582 + AudioMixengBackendClass *k = AUDIO_MIXENG_BACKEND_GET_CLASS(hw->s);
583 +
584 + return (k->buffer_get_free ? k->buffer_get_free(hw) : INT_MAX) /
585 + hw->info.bytes_per_frame;
586 }
587
588 static void audio_pcm_hw_clip_out(HWVoiceOut *hw, void *pcm_buf, size_t len)
@@ -673,7 +675,7 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t buf_len)
675 if (frames_in_max > sw->resample_buf.pos) {
676 sw->conv(sw->resample_buf.buffer + sw->resample_buf.pos,
677 buf, frames_in_max - sw->resample_buf.pos);
676 - if (!sw->hw->pcm_ops->volume_out) {
678 + if (!AUDIO_MIXENG_BACKEND_GET_CLASS(sw->hw->s)->volume_out) {
679 mixeng_volume(sw->resample_buf.buffer + sw->resample_buf.pos,
680 frames_in_max - sw->resample_buf.pos, &sw->vol);
681 }
@@ -806,7 +808,7 @@ static size_t audio_mixeng_backend_write(AudioBackend *be, SWVoiceOut *sw,
808 if (audio_get_pdo_out(hw->s->dev)->mixing_engine) {
809 return audio_pcm_sw_write(sw, buf, size);
810 } else {
809 - return hw->pcm_ops->write(hw, buf, size);
811 + return AUDIO_MIXENG_BACKEND_GET_CLASS(hw->s)->write(hw, buf, size);
812 }
813 }
814
@@ -829,7 +831,7 @@ static size_t audio_mixeng_backend_read(AudioBackend *be,
831 if (audio_get_pdo_in(hw->s->dev)->mixing_engine) {
832 return audio_pcm_sw_read(sw, buf, size);
833 } else {
832 - return hw->pcm_ops->read(hw, buf, size);
834 + return AUDIO_MIXENG_BACKEND_GET_CLASS(hw->s)->read(hw, buf, size);
835 }
836
837 }
@@ -863,12 +865,14 @@ static void audio_mixeng_backend_set_active_out(AudioBackend *be, SWVoiceOut *sw
865 SWVoiceCap *sc;
866
867 if (on) {
868 + AudioMixengBackendClass *k = AUDIO_MIXENG_BACKEND_GET_CLASS(s);
869 +
870 hw->pending_disable = 0;
871 if (!hw->enabled) {
872 hw->enabled = true;
873 if (runstate_is_running()) {
870 - if (hw->pcm_ops->enable_out) {
871 - hw->pcm_ops->enable_out(hw, true);
874 + if (k->enable_out) {
875 + k->enable_out(hw, true);
876 }
877 audio_reset_timer (s);
878 }
@@ -908,14 +912,15 @@ static void audio_mixeng_backend_set_active_in(AudioBackend *be, SWVoiceIn *sw,
912 hw = sw->hw;
913 if (sw->active != on) {
914 AudioMixengBackend *s = sw->s;
915 + AudioMixengBackendClass *k = AUDIO_MIXENG_BACKEND_GET_CLASS(s);
916 SWVoiceIn *temp_sw;
917
918 if (on) {
919 if (!hw->enabled) {
920 hw->enabled = true;
921 if (runstate_is_running()) {
917 - if (hw->pcm_ops->enable_in) {
918 - hw->pcm_ops->enable_in(hw, true);
922 + if (k->enable_in) {
923 + k->enable_in(hw, true);
924 }
925 audio_reset_timer (s);
926 }
@@ -932,8 +937,8 @@ static void audio_mixeng_backend_set_active_in(AudioBackend *be, SWVoiceIn *sw,
937
938 if (nb_active == 1) {
939 hw->enabled = false;
935 - if (hw->pcm_ops->enable_in) {
936 - hw->pcm_ops->enable_in(hw, false);
940 + if (k->enable_in) {
941 + k->enable_in(hw, false);
942 }
943 }
944 }
@@ -1040,12 +1045,13 @@ static void audio_capture_mix_and_clear(HWVoiceOut *hw, size_t rpos,
1045
1046 static size_t audio_pcm_hw_run_out(HWVoiceOut *hw, size_t live)
1047 {
1048 + AudioMixengBackendClass *k = AUDIO_MIXENG_BACKEND_GET_CLASS(hw->s);
1049 size_t clipped = 0;
1050
1051 while (live) {
1052 size_t size = live * hw->info.bytes_per_frame;
1053 size_t decr, proc;
1048 - void *buf = hw->pcm_ops->get_buffer_out(hw, &size);
1054 + void *buf = k->get_buffer_out(hw, &size);
1055
1056 if (size == 0) {
1057 break;
@@ -1055,8 +1061,7 @@ static size_t audio_pcm_hw_run_out(HWVoiceOut *hw, size_t live)
1061 if (buf) {
1062 audio_pcm_hw_clip_out(hw, buf, decr);
1063 }
1058 - proc = hw->pcm_ops->put_buffer_out(hw, buf,
1059 - decr * hw->info.bytes_per_frame) /
1064 + proc = k->put_buffer_out(hw, buf, decr * hw->info.bytes_per_frame) /
1065 hw->info.bytes_per_frame;
1066
1067 live -= proc;
@@ -1068,8 +1073,8 @@ static size_t audio_pcm_hw_run_out(HWVoiceOut *hw, size_t live)
1073 }
1074 }
1075
1071 - if (hw->pcm_ops->run_buffer_out) {
1072 - hw->pcm_ops->run_buffer_out(hw);
1076 + if (k->run_buffer_out) {
1077 + k->run_buffer_out(hw);
1078 }
1079
1080 return clipped;
@@ -1077,6 +1082,7 @@ static size_t audio_pcm_hw_run_out(HWVoiceOut *hw, size_t live)
1082
1083 static void audio_run_out(AudioMixengBackend *s)
1084 {
1085 + AudioMixengBackendClass *k = AUDIO_MIXENG_BACKEND_GET_CLASS(s);
1086 HWVoiceOut *hw = NULL;
1087 SWVoiceOut *sw;
1088
@@ -1092,8 +1098,8 @@ static void audio_run_out(AudioMixengBackend *s)
1098 if (hw->pending_disable) {
1099 hw->enabled = false;
1100 hw->pending_disable = false;
1095 - if (hw->pcm_ops->enable_out) {
1096 - hw->pcm_ops->enable_out(hw, false);
1101 + if (k->enable_out) {
1102 + k->enable_out(hw, false);
1103 }
1104 }
1105
@@ -1102,8 +1108,8 @@ static void audio_run_out(AudioMixengBackend *s)
1108 hw_free * sw->info.bytes_per_frame);
1109 }
1110
1105 - if (hw->pcm_ops->run_buffer_out) {
1106 - hw->pcm_ops->run_buffer_out(hw);
1111 + if (k->run_buffer_out) {
1112 + k->run_buffer_out(hw);
1113 }
1114
1115 continue;
@@ -1146,8 +1152,8 @@ static void audio_run_out(AudioMixengBackend *s)
1152 #endif
1153 hw->enabled = false;
1154 hw->pending_disable = false;
1149 - if (hw->pcm_ops->enable_out) {
1150 - hw->pcm_ops->enable_out(hw, false);
1155 + if (k->enable_out) {
1156 + k->enable_out(hw, false);
1157 }
1158 for (sc = hw->cap_head.lh_first; sc; sc = sc->entries.le_next) {
1159 sc->sw.active = false;
@@ -1157,8 +1163,8 @@ static void audio_run_out(AudioMixengBackend *s)
1163 }
1164
1165 if (!live) {
1160 - if (hw->pcm_ops->run_buffer_out) {
1161 - hw->pcm_ops->run_buffer_out(hw);
1166 + if (k->run_buffer_out) {
1167 + k->run_buffer_out(hw);
1168 }
1169 continue;
1170 }
@@ -1202,16 +1208,17 @@ static void audio_run_out(AudioMixengBackend *s)
1208
1209 static size_t audio_pcm_hw_run_in(HWVoiceIn *hw, size_t samples)
1210 {
1211 + AudioMixengBackendClass *k = AUDIO_MIXENG_BACKEND_GET_CLASS(hw->s);
1212 size_t conv = 0;
1213
1207 - if (hw->pcm_ops->run_buffer_in) {
1208 - hw->pcm_ops->run_buffer_in(hw);
1214 + if (k->run_buffer_in) {
1215 + k->run_buffer_in(hw);
1216 }
1217
1218 while (samples) {
1219 size_t proc;
1220 size_t size = samples * hw->info.bytes_per_frame;
1214 - void *buf = hw->pcm_ops->get_buffer_in(hw, &size);
1221 + void *buf = k->get_buffer_in(hw, &size);
1222
1223 assert(size % hw->info.bytes_per_frame == 0);
1224 if (size == 0) {
@@ -1222,7 +1229,7 @@ static size_t audio_pcm_hw_run_in(HWVoiceIn *hw, size_t samples)
1229
1230 samples -= proc;
1231 conv += proc;
1225 - hw->pcm_ops->put_buffer_in(hw, buf, proc * hw->info.bytes_per_frame);
1232 + k->put_buffer_in(hw, buf, proc * hw->info.bytes_per_frame);
1233 }
1234
1235 return conv;
@@ -1367,6 +1374,8 @@ void audio_run(AudioMixengBackend *s, const char *msg)
1374
1375 void audio_generic_run_buffer_in(HWVoiceIn *hw)
1376 {
1377 + AudioMixengBackendClass *k = AUDIO_MIXENG_BACKEND_GET_CLASS(hw->s);
1378 +
1379 if (unlikely(!hw->buf_emul)) {
1380 hw->size_emul = hw->samples * hw->info.bytes_per_frame;
1381 hw->buf_emul = g_malloc(hw->size_emul);
@@ -1376,8 +1385,7 @@ void audio_generic_run_buffer_in(HWVoiceIn *hw)
1385 while (hw->pending_emul < hw->size_emul) {
1386 size_t read_len = MIN(hw->size_emul - hw->pos_emul,
1387 hw->size_emul - hw->pending_emul);
1379 - size_t read = hw->pcm_ops->read(hw, hw->buf_emul + hw->pos_emul,
1380 - read_len);
1388 + size_t read = k->read(hw, hw->buf_emul + hw->pos_emul, read_len);
1389 hw->pending_emul += read;
1390 hw->pos_emul = (hw->pos_emul + read) % hw->size_emul;
1391 if (read < read_len) {
@@ -1415,6 +1423,8 @@ size_t audio_generic_buffer_get_free(HWVoiceOut *hw)
1423
1424 void audio_generic_run_buffer_out(HWVoiceOut *hw)
1425 {
1426 + AudioMixengBackendClass *k = AUDIO_MIXENG_BACKEND_GET_CLASS(hw->s);
1427 +
1428 while (hw->pending_emul) {
1429 size_t write_len, written, start;
1430
@@ -1423,7 +1433,7 @@ void audio_generic_run_buffer_out(HWVoiceOut *hw)
1433
1434 write_len = MIN(hw->pending_emul, hw->size_emul - start);
1435
1426 - written = hw->pcm_ops->write(hw, hw->buf_emul + start, write_len);
1436 + written = k->write(hw, hw->buf_emul + start, write_len);
1437 hw->pending_emul -= written;
1438
1439 if (written < write_len) {
@@ -1458,10 +1468,11 @@ size_t audio_generic_put_buffer_out(HWVoiceOut *hw, void *buf, size_t size)
1468
1469 size_t audio_generic_write(HWVoiceOut *hw, void *buf, size_t size)
1470 {
1471 + AudioMixengBackendClass *k = AUDIO_MIXENG_BACKEND_GET_CLASS(hw->s);
1472 size_t total = 0;
1473
1463 - if (hw->pcm_ops->buffer_get_free) {
1464 - size_t free = hw->pcm_ops->buffer_get_free(hw);
1474 + if (k->buffer_get_free) {
1475 + size_t free = k->buffer_get_free(hw);
1476
1477 size = MIN(size, free);
1478 }
@@ -1469,7 +1480,7 @@ size_t audio_generic_write(HWVoiceOut *hw, void *buf, size_t size)
1480 while (total < size) {
1481 size_t dst_size = size - total;
1482 size_t copy_size, proc;
1472 - void *dst = hw->pcm_ops->get_buffer_out(hw, &dst_size);
1483 + void *dst = k->get_buffer_out(hw, &dst_size);
1484
1485 if (dst_size == 0) {
1486 break;
@@ -1479,7 +1490,7 @@ size_t audio_generic_write(HWVoiceOut *hw, void *buf, size_t size)
1490 if (dst) {
1491 memcpy(dst, (char *)buf + total, copy_size);
1492 }
1482 - proc = hw->pcm_ops->put_buffer_out(hw, dst, copy_size);
1493 + proc = k->put_buffer_out(hw, dst, copy_size);
1494 total += proc;
1495
1496 if (proc == 0 || proc < copy_size) {
@@ -1492,22 +1503,23 @@ size_t audio_generic_write(HWVoiceOut *hw, void *buf, size_t size)
1503
1504 size_t audio_generic_read(HWVoiceIn *hw, void *buf, size_t size)
1505 {
1506 + AudioMixengBackendClass *k = AUDIO_MIXENG_BACKEND_GET_CLASS(hw->s);
1507 size_t total = 0;
1508
1497 - if (hw->pcm_ops->run_buffer_in) {
1498 - hw->pcm_ops->run_buffer_in(hw);
1509 + if (k->run_buffer_in) {
1510 + k->run_buffer_in(hw);
1511 }
1512
1513 while (total < size) {
1514 size_t src_size = size - total;
1503 - void *src = hw->pcm_ops->get_buffer_in(hw, &src_size);
1515 + void *src = k->get_buffer_in(hw, &src_size);
1516
1517 if (src_size == 0) {
1518 break;
1519 }
1520
1521 memcpy((char *)buf + total, src, src_size);
1510 - hw->pcm_ops->put_buffer_in(hw, src, src_size);
1522 + k->put_buffer_in(hw, src, src_size);
1523 total += src_size;
1524 }
1525
@@ -1521,13 +1533,13 @@ static bool audio_mixeng_backend_realize(AudioBackend *abe,
1533 AudioMixengBackendClass *k = AUDIO_MIXENG_BACKEND_GET_CLASS(be);
1534
1535 be->dev = dev;
1524 - if (!k->pcm_ops->get_buffer_in) {
1525 - k->pcm_ops->get_buffer_in = audio_generic_get_buffer_in;
1526 - k->pcm_ops->put_buffer_in = audio_generic_put_buffer_in;
1536 + if (!k->get_buffer_in) {
1537 + k->get_buffer_in = audio_generic_get_buffer_in;
1538 + k->put_buffer_in = audio_generic_put_buffer_in;
1539 }
1528 - if (!k->pcm_ops->get_buffer_out) {
1529 - k->pcm_ops->get_buffer_out = audio_generic_get_buffer_out;
1530 - k->pcm_ops->put_buffer_out = audio_generic_put_buffer_out;
1540 + if (!k->get_buffer_out) {
1541 + k->get_buffer_out = audio_generic_get_buffer_out;
1542 + k->put_buffer_out = audio_generic_put_buffer_out;
1543 }
1544
1545 audio_init_nb_voices_out(be, k, 1);
@@ -1546,18 +1558,19 @@ static void audio_vm_change_state_handler (void *opaque, bool running,
1558 RunState state)
1559 {
1560 AudioMixengBackend *s = opaque;
1561 + AudioMixengBackendClass *k = AUDIO_MIXENG_BACKEND_GET_CLASS(s);
1562 HWVoiceOut *hwo = NULL;
1563 HWVoiceIn *hwi = NULL;
1564
1565 while ((hwo = audio_pcm_hw_find_any_enabled_out(s, hwo))) {
1553 - if (hwo->pcm_ops->enable_out) {
1554 - hwo->pcm_ops->enable_out(hwo, running);
1566 + if (k->enable_out) {
1567 + k->enable_out(hwo, running);
1568 }
1569 }
1570
1571 while ((hwi = audio_pcm_hw_find_any_enabled_in(s, hwi))) {
1559 - if (hwi->pcm_ops->enable_in) {
1560 - hwi->pcm_ops->enable_in(hwi, running);
1572 + if (k->enable_in) {
1573 + k->enable_in(hwi, running);
1574 }
1575 }
1576 audio_reset_timer (s);
@@ -1627,16 +1640,17 @@ static void audio_mixeng_backend_init(Object *obj)
1640 static void audio_mixeng_backend_finalize(Object *obj)
1641 {
1642 AudioMixengBackend *s = AUDIO_MIXENG_BACKEND(obj);
1643 + AudioMixengBackendClass *k = AUDIO_MIXENG_BACKEND_GET_CLASS(s);
1644 HWVoiceOut *hwo, *hwon;
1645 HWVoiceIn *hwi, *hwin;
1646
1647 QLIST_FOREACH_SAFE(hwo, &s->hw_head_out, entries, hwon) {
1648 SWVoiceCap *sc;
1649
1636 - if (hwo->enabled && hwo->pcm_ops->enable_out) {
1637 - hwo->pcm_ops->enable_out(hwo, false);
1650 + if (hwo->enabled && k->enable_out) {
1651 + k->enable_out(hwo, false);
1652 }
1639 - hwo->pcm_ops->fini_out (hwo);
1653 + k->fini_out(hwo);
1654
1655 for (sc = hwo->cap_head.lh_first; sc; sc = sc->entries.le_next) {
1656 CaptureVoiceOut *cap = sc->cap;
@@ -1650,10 +1664,10 @@ static void audio_mixeng_backend_finalize(Object *obj)
1664 }
1665
1666 QLIST_FOREACH_SAFE(hwi, &s->hw_head_in, entries, hwin) {
1653 - if (hwi->enabled && hwi->pcm_ops->enable_in) {
1654 - hwi->pcm_ops->enable_in(hwi, false);
1667 + if (hwi->enabled && k->enable_in) {
1668 + k->enable_in(hwi, false);
1669 }
1656 - hwi->pcm_ops->fini_in (hwi);
1670 + k->fini_in(hwi);
1671 QLIST_REMOVE(hwi, entries);
1672 }
1673
@@ -1694,8 +1708,6 @@ static const VMStateDescription vmstate_audio = {
1708 }
1709 };
1710
1697 -static struct audio_pcm_ops capture_pcm_ops;
1698 -
1711 static CaptureVoiceOut *audio_mixeng_backend_add_capture(
1712 AudioBackend *be,
1713 struct audsettings *as,
@@ -1736,7 +1748,6 @@ static CaptureVoiceOut *audio_mixeng_backend_add_capture(
1748
1749 hw = &cap->hw;
1750 hw->s = s;
1739 - hw->pcm_ops = &capture_pcm_ops;
1751 QLIST_INIT (&hw->sw_head);
1752 QLIST_INIT (&cap->cb_head);
1753
@@ -1817,14 +1828,15 @@ static void audio_mixeng_backend_set_volume_out(AudioBackend *be, SWVoiceOut *sw
1828 {
1829 if (sw) {
1830 HWVoiceOut *hw = sw->hw;
1831 + AudioMixengBackendClass *k = AUDIO_MIXENG_BACKEND_GET_CLASS(hw->s);
1832
1833 sw->vol.mute = vol->mute;
1834 sw->vol.l = nominal_volume.l * vol->vol[0] / 255;
1835 sw->vol.r = nominal_volume.l * vol->vol[vol->channels > 1 ? 1 : 0] /
1836 255;
1837
1826 - if (hw->pcm_ops->volume_out) {
1827 - hw->pcm_ops->volume_out(hw, vol);
1838 + if (k->volume_out) {
1839 + k->volume_out(hw, vol);
1840 }
1841 }
1842 }
@@ -1834,14 +1846,15 @@ static void audio_mixeng_backend_set_volume_in(AudioBackend *be, SWVoiceIn *sw,
1846 {
1847 if (sw) {
1848 HWVoiceIn *hw = sw->hw;
1849 + AudioMixengBackendClass *k = AUDIO_MIXENG_BACKEND_GET_CLASS(hw->s);
1850
1851 sw->vol.mute = vol->mute;
1852 sw->vol.l = nominal_volume.l * vol->vol[0] / 255;
1853 sw->vol.r = nominal_volume.r * vol->vol[vol->channels > 1 ? 1 : 0] /
1854 255;
1855
1843 - if (hw->pcm_ops->volume_in) {
1844 - hw->pcm_ops->volume_in(hw, vol);
1856 + if (k->volume_in) {
1857 + k->volume_in(hw, vol);
1858 }
1859 }
1860 }
audio/audio_int.h
+32 -39
@@ -39,8 +39,6 @@ AUD_vlog(const char *cap, const char *fmt, va_list ap);
39 void G_GNUC_PRINTF(2, 3)
40 AUD_log(const char *cap, const char *fmt, ...);
41
42 -struct audio_pcm_ops;
43 -
42 struct audio_callback {
43 void *opaque;
44 audio_callback_fn fn;
@@ -81,7 +79,6 @@ typedef struct HWVoiceOut {
79 size_t samples;
80 QLIST_HEAD (sw_out_listhead, SWVoiceOut) sw_head;
81 QLIST_HEAD (sw_cap_listhead, SWVoiceCap) cap_head;
84 - struct audio_pcm_ops *pcm_ops;
82 QLIST_ENTRY (HWVoiceOut) entries;
83 } HWVoiceOut;
84
@@ -101,7 +98,6 @@ typedef struct HWVoiceIn {
98
99 size_t samples;
100 QLIST_HEAD (sw_in_listhead, SWVoiceIn) sw_head;
104 - struct audio_pcm_ops *pcm_ops;
101 QLIST_ENTRY (HWVoiceIn) entries;
102 } HWVoiceIn;
103
@@ -136,40 +132,6 @@ struct SWVoiceIn {
132 QLIST_ENTRY (SWVoiceIn) entries;
133 };
134
139 -struct audio_pcm_ops {
140 - int (*init_out)(HWVoiceOut *hw, audsettings *as);
141 - void (*fini_out)(HWVoiceOut *hw);
142 - size_t (*write) (HWVoiceOut *hw, void *buf, size_t size);
143 - void (*run_buffer_out)(HWVoiceOut *hw);
144 - /*
145 - * Get the free output buffer size. This is an upper limit. The size
146 - * returned by function get_buffer_out may be smaller.
147 - */
148 - size_t (*buffer_get_free)(HWVoiceOut *hw);
149 - /*
150 - * get a buffer that after later can be passed to put_buffer_out; optional
151 - * returns the buffer, and writes it's size to size (in bytes)
152 - */
153 - void *(*get_buffer_out)(HWVoiceOut *hw, size_t *size);
154 - /*
155 - * put back the buffer returned by get_buffer_out; optional
156 - * buf must be equal the pointer returned by get_buffer_out,
157 - * size may be smaller
158 - */
159 - size_t (*put_buffer_out)(HWVoiceOut *hw, void *buf, size_t size);
160 - void (*enable_out)(HWVoiceOut *hw, bool enable);
161 - void (*volume_out)(HWVoiceOut *hw, Volume *vol);
162 -
163 - int (*init_in) (HWVoiceIn *hw, audsettings *as);
164 - void (*fini_in) (HWVoiceIn *hw);
165 - size_t (*read) (HWVoiceIn *hw, void *buf, size_t size);
166 - void (*run_buffer_in)(HWVoiceIn *hw);
167 - void *(*get_buffer_in)(HWVoiceIn *hw, size_t *size);
168 - void (*put_buffer_in)(HWVoiceIn *hw, void *buf, size_t size);
169 - void (*enable_in)(HWVoiceIn *hw, bool enable);
170 - void (*volume_in)(HWVoiceIn *hw, Volume *vol);
171 -};
172 -
135 audsettings audiodev_to_audsettings(AudiodevPerDirectionOptions *pdo);
136 int audioformat_bytes_per_sample(AudioFormat fmt);
137 int audio_buffer_frames(AudiodevPerDirectionOptions *pdo,
@@ -220,11 +182,42 @@ struct AudioMixengBackendClass {
182 AudioBackendClass parent_class;
183
184 const char *name;
223 - struct audio_pcm_ops *pcm_ops;
185 int max_voices_out;
186 int max_voices_in;
187 size_t voice_size_out;
188 size_t voice_size_in;
189 +
190 + int (*init_out)(HWVoiceOut *hw, audsettings *as);
191 + void (*fini_out)(HWVoiceOut *hw);
192 + size_t (*write) (HWVoiceOut *hw, void *buf, size_t size);
193 + void (*run_buffer_out)(HWVoiceOut *hw);
194 + /*
195 + * Get the free output buffer size. This is an upper limit. The size
196 + * returned by function get_buffer_out may be smaller.
197 + */
198 + size_t (*buffer_get_free)(HWVoiceOut *hw);
199 + /*
200 + * get a buffer that after later can be passed to put_buffer_out; optional
201 + * returns the buffer, and writes it's size to size (in bytes)
202 + */
203 + void *(*get_buffer_out)(HWVoiceOut *hw, size_t *size);
204 + /*
205 + * put back the buffer returned by get_buffer_out; optional
206 + * buf must be equal the pointer returned by get_buffer_out,
207 + * size may be smaller
208 + */
209 + size_t (*put_buffer_out)(HWVoiceOut *hw, void *buf, size_t size);
210 + void (*enable_out)(HWVoiceOut *hw, bool enable);
211 + void (*volume_out)(HWVoiceOut *hw, Volume *vol);
212 +
213 + int (*init_in) (HWVoiceIn *hw, audsettings *as);
214 + void (*fini_in) (HWVoiceIn *hw);
215 + size_t (*read) (HWVoiceIn *hw, void *buf, size_t size);
216 + void (*run_buffer_in)(HWVoiceIn *hw);
217 + void *(*get_buffer_in)(HWVoiceIn *hw, size_t *size);
218 + void (*put_buffer_in)(HWVoiceIn *hw, void *buf, size_t size);
219 + void (*enable_in)(HWVoiceIn *hw, bool enable);
220 + void (*volume_in)(HWVoiceIn *hw, Volume *vol);
221 };
222
223 struct AudioMixengBackend {
audio/audio_template.h
+9 -7
@@ -223,13 +223,14 @@ static void glue (audio_pcm_hw_gc_, TYPE) (HW **hwp)
223 {
224 HW *hw = *hwp;
225 AudioMixengBackend *s = hw->s;
226 + AudioMixengBackendClass *k = AUDIO_MIXENG_BACKEND_GET_CLASS(s);
227
228 if (!hw->sw_head.lh_first) {
229 #ifdef DAC
230 audio_detach_capture(hw);
231 #endif
232 QLIST_REMOVE(hw, entries);
232 - glue(hw->pcm_ops->fini_, TYPE) (hw);
233 + glue(k->fini_, TYPE)(hw);
234 glue(s->nb_hw_voices_, TYPE) += 1;
235 glue(audio_pcm_hw_free_resources_ , TYPE) (hw);
236 object_unref(hw->s);
@@ -274,8 +275,8 @@ static HW *glue(audio_pcm_hw_add_new_, TYPE)(AudioMixengBackend *s,
275 return NULL;
276 }
277
277 - if (audio_bug(__func__, !k->pcm_ops)) {
278 - dolog("No host audio driver or missing pcm_ops\n");
278 + if (audio_bug(__func__, !glue(k->init_, TYPE))) {
279 + dolog("No host audio driver or missing init_%s\n", NAME);
280 return NULL;
281 }
282
@@ -285,13 +286,12 @@ static HW *glue(audio_pcm_hw_add_new_, TYPE)(AudioMixengBackend *s,
286 */
287 hw = g_malloc0(glue(k->voice_size_, TYPE));
288 hw->s = AUDIO_MIXENG_BACKEND(object_ref(s));
288 - hw->pcm_ops = k->pcm_ops;
289
290 QLIST_INIT (&hw->sw_head);
291 #ifdef DAC
292 QLIST_INIT (&hw->cap_head);
293 #endif
294 - if (glue (hw->pcm_ops->init_, TYPE) (hw, as)) {
294 + if (glue(k->init_, TYPE)(hw, as)) {
295 goto err0;
296 }
297
@@ -330,7 +330,7 @@ static HW *glue(audio_pcm_hw_add_new_, TYPE)(AudioMixengBackend *s,
330 return hw;
331
332 err1:
333 - glue (hw->pcm_ops->fini_, TYPE) (hw);
333 + glue(k->fini_, TYPE)(hw);
334 err0:
335 object_unref(hw->s);
336 g_free (hw);
@@ -495,6 +495,7 @@ static SW *glue(audio_mixeng_backend_open_, TYPE) (
495 const struct audsettings *as)
496 {
497 AudioMixengBackend *s = AUDIO_MIXENG_BACKEND(be);
498 + AudioMixengBackendClass *k;
499 AudiodevPerDirectionOptions *pdo;
500
501 if (audio_bug(__func__, !be || !name || !callback_fn || !as)) {
@@ -503,6 +504,7 @@ static SW *glue(audio_mixeng_backend_open_, TYPE) (
504 goto fail;
505 }
506
507 + k = AUDIO_MIXENG_BACKEND_GET_CLASS(s);
508 pdo = glue(audio_get_pdo_, TYPE)(s->dev);
509
510 ldebug ("open %s, freq %d, nchannels %d, fmt %d\n",
@@ -513,7 +515,7 @@ static SW *glue(audio_mixeng_backend_open_, TYPE) (
515 goto fail;
516 }
517
516 - if (audio_bug(__func__, !AUDIO_MIXENG_BACKEND_GET_CLASS(s)->pcm_ops)) {
518 + if (audio_bug(__func__, !glue(k->init_, TYPE))) {
519 dolog("Can not open `%s' (no host audio driver)\n", name);
520 goto fail;
521 }
audio/coreaudio.m
+12 -15
@@ -646,30 +646,27 @@ static void coreaudio_enable_out(HWVoiceOut *hw, bool enable)
646 update_device_playback_state(core);
647 }
648
649 -static struct audio_pcm_ops coreaudio_pcm_ops = {
650 - .init_out = coreaudio_init_out,
651 - .fini_out = coreaudio_fini_out,
652 - /* wrapper for audio_generic_write */
653 - .write = coreaudio_write,
654 - /* wrapper for audio_generic_buffer_get_free */
655 - .buffer_get_free = coreaudio_buffer_get_free,
656 - /* wrapper for audio_generic_get_buffer_out */
657 - .get_buffer_out = coreaudio_get_buffer_out,
658 - /* wrapper for audio_generic_put_buffer_out */
659 - .put_buffer_out = coreaudio_put_buffer_out,
660 - .enable_out = coreaudio_enable_out
661 -};
662 -
649 static void audio_coreaudio_class_init(ObjectClass *klass, const void *data)
650 {
651 AudioMixengBackendClass *k = AUDIO_MIXENG_BACKEND_CLASS(klass);
652
653 k->name = "coreaudio";
668 - k->pcm_ops = &coreaudio_pcm_ops;
654 k->max_voices_out = 1;
655 k->max_voices_in = 0;
656 k->voice_size_out = sizeof(coreaudioVoiceOut);
657 k->voice_size_in = 0;
658 +
659 + k->init_out = coreaudio_init_out;
660 + k->fini_out = coreaudio_fini_out;
661 + /* wrapper for audio_generic_write */
662 + k->write = coreaudio_write;
663 + /* wrapper for audio_generic_buffer_get_free */
664 + k->buffer_get_free = coreaudio_buffer_get_free;
665 + /* wrapper for audio_generic_get_buffer_out */
666 + k->get_buffer_out = coreaudio_get_buffer_out;
667 + /* wrapper for audio_generic_put_buffer_out */
668 + k->put_buffer_out = coreaudio_put_buffer_out;
669 + k->enable_out = coreaudio_enable_out;
670 }
671
672 static const TypeInfo audio_types[] = {
audio/dbusaudio.c
+15 -18
@@ -691,23 +691,6 @@ dbus_audio_set_server(AudioBackend *s,
691 return true;
692 }
693
694 -static struct audio_pcm_ops dbus_pcm_ops = {
695 - .init_out = dbus_init_out,
696 - .fini_out = dbus_fini_out,
697 - .write = audio_generic_write,
698 - .get_buffer_out = dbus_get_buffer_out,
699 - .put_buffer_out = dbus_put_buffer_out,
700 - .enable_out = dbus_enable_out,
701 - .volume_out = dbus_volume_out,
702 -
703 - .init_in = dbus_init_in,
704 - .fini_in = dbus_fini_in,
705 - .read = dbus_read,
706 - .run_buffer_in = audio_generic_run_buffer_in,
707 - .enable_in = dbus_enable_in,
708 - .volume_in = dbus_volume_in,
709 -};
710 -
694 static void audio_dbus_class_init(ObjectClass *klass, const void *data)
695 {
696 AudioBackendClass *b = AUDIO_BACKEND_CLASS(klass);
@@ -718,11 +701,25 @@ static void audio_dbus_class_init(ObjectClass *klass, const void *data)
701 b->realize = audio_dbus_realize;
702 b->set_dbus_server = dbus_audio_set_server;
703 k->name = "dbus";
721 - k->pcm_ops = &dbus_pcm_ops;
704 k->max_voices_out = INT_MAX;
705 k->max_voices_in = INT_MAX;
706 k->voice_size_out = sizeof(DBusVoiceOut);
707 k->voice_size_in = sizeof(DBusVoiceIn);
708 +
709 + k->init_out = dbus_init_out;
710 + k->fini_out = dbus_fini_out;
711 + k->write = audio_generic_write;
712 + k->get_buffer_out = dbus_get_buffer_out;
713 + k->put_buffer_out = dbus_put_buffer_out;
714 + k->enable_out = dbus_enable_out;
715 + k->volume_out = dbus_volume_out;
716 +
717 + k->init_in = dbus_init_in;
718 + k->fini_in = dbus_fini_in;
719 + k->read = dbus_read;
720 + k->run_buffer_in = audio_generic_run_buffer_in;
721 + k->enable_in = dbus_enable_in;
722 + k->volume_in = dbus_volume_in;
723 }
724
725 static const TypeInfo audio_types[] = {
audio/dsoundaudio.c
+15 -18
@@ -667,23 +667,6 @@ audio_dsound_realize(AudioBackend *abe, Audiodev *dev, Error **errp)
667 return true;
668 }
669
670 -static struct audio_pcm_ops dsound_pcm_ops = {
671 - .init_out = dsound_init_out,
672 - .fini_out = dsound_fini_out,
673 - .write = audio_generic_write,
674 - .buffer_get_free = dsound_buffer_get_free,
675 - .get_buffer_out = dsound_get_buffer_out,
676 - .put_buffer_out = dsound_put_buffer_out,
677 - .enable_out = dsound_enable_out,
678 -
679 - .init_in = dsound_init_in,
680 - .fini_in = dsound_fini_in,
681 - .read = audio_generic_read,
682 - .get_buffer_in = dsound_get_buffer_in,
683 - .put_buffer_in = dsound_put_buffer_in,
684 - .enable_in = dsound_enable_in,
685 -};
686 -
670 static void audio_dsound_class_init(ObjectClass *klass, const void *data)
671 {
672 AudioBackendClass *b = AUDIO_BACKEND_CLASS(klass);
@@ -693,11 +676,25 @@ static void audio_dsound_class_init(ObjectClass *klass, const void *data)
676
677 b->realize = audio_dsound_realize;
678 k->name = "dsound";
696 - k->pcm_ops = &dsound_pcm_ops;
679 k->max_voices_out = INT_MAX;
680 k->max_voices_in = 1;
681 k->voice_size_out = sizeof(DSoundVoiceOut);
682 k->voice_size_in = sizeof(DSoundVoiceIn);
683 +
684 + k->init_out = dsound_init_out;
685 + k->fini_out = dsound_fini_out;
686 + k->write = audio_generic_write;
687 + k->buffer_get_free = dsound_buffer_get_free;
688 + k->get_buffer_out = dsound_get_buffer_out;
689 + k->put_buffer_out = dsound_put_buffer_out;
690 + k->enable_out = dsound_enable_out;
691 +
692 + k->init_in = dsound_init_in;
693 + k->fini_in = dsound_fini_in;
694 + k->read = audio_generic_read;
695 + k->get_buffer_in = dsound_get_buffer_in;
696 + k->put_buffer_in = dsound_put_buffer_in;
697 + k->enable_in = dsound_enable_in;
698 }
699
700 static const TypeInfo audio_types[] = {
audio/jackaudio.c
+13 -16
@@ -652,21 +652,6 @@ static int qjack_thread_creator(jack_native_thread_t *thread,
652 }
653 #endif
654
655 -static struct audio_pcm_ops jack_pcm_ops = {
656 - .init_out = qjack_init_out,
657 - .fini_out = qjack_fini_out,
658 - .write = qjack_write,
659 - .buffer_get_free = audio_generic_buffer_get_free,
660 - .run_buffer_out = audio_generic_run_buffer_out,
661 - .enable_out = qjack_enable_out,
662 -
663 - .init_in = qjack_init_in,
664 - .fini_in = qjack_fini_in,
665 - .read = qjack_read,
666 - .run_buffer_in = audio_generic_run_buffer_in,
667 - .enable_in = qjack_enable_in
668 -};
669 -
655 static void qjack_error(const char *msg)
656 {
657 dolog("E: %s\n", msg);
@@ -682,11 +667,23 @@ static void audio_jack_class_init(ObjectClass *klass, const void *data)
667 AudioMixengBackendClass *k = AUDIO_MIXENG_BACKEND_CLASS(klass);
668
669 k->name = "jack";
685 - k->pcm_ops = &jack_pcm_ops;
670 k->max_voices_out = INT_MAX;
671 k->max_voices_in = INT_MAX;
672 k->voice_size_out = sizeof(QJackOut);
673 k->voice_size_in = sizeof(QJackIn);
674 +
675 + k->init_out = qjack_init_out;
676 + k->fini_out = qjack_fini_out;
677 + k->write = qjack_write;
678 + k->buffer_get_free = audio_generic_buffer_get_free;
679 + k->run_buffer_out = audio_generic_run_buffer_out;
680 + k->enable_out = qjack_enable_out;
681 +
682 + k->init_in = qjack_init_in;
683 + k->fini_in = qjack_fini_in;
684 + k->read = qjack_read;
685 + k->run_buffer_in = audio_generic_run_buffer_in;
686 + k->enable_in = qjack_enable_in;
687 }
688
689 static const TypeInfo audio_types[] = {
audio/noaudio.c
+13 -16
@@ -110,31 +110,28 @@ static void no_enable_in(HWVoiceIn *hw, bool enable)
110 }
111 }
112
113 -static struct audio_pcm_ops no_pcm_ops = {
114 - .init_out = no_init_out,
115 - .fini_out = no_fini_out,
116 - .write = no_write,
117 - .buffer_get_free = audio_generic_buffer_get_free,
118 - .run_buffer_out = audio_generic_run_buffer_out,
119 - .enable_out = no_enable_out,
120 -
121 - .init_in = no_init_in,
122 - .fini_in = no_fini_in,
123 - .read = no_read,
124 - .run_buffer_in = audio_generic_run_buffer_in,
125 - .enable_in = no_enable_in
126 -};
127 -
113 static void audio_none_class_init(ObjectClass *klass, const void *data)
114 {
115 AudioMixengBackendClass *k = AUDIO_MIXENG_BACKEND_CLASS(klass);
116
117 k->name = "none";
133 - k->pcm_ops = &no_pcm_ops;
118 k->max_voices_out = INT_MAX;
119 k->max_voices_in = INT_MAX;
120 k->voice_size_out = sizeof(NoVoiceOut);
121 k->voice_size_in = sizeof(NoVoiceIn);
122 +
123 + k->init_out = no_init_out;
124 + k->fini_out = no_fini_out;
125 + k->write = no_write;
126 + k->buffer_get_free = audio_generic_buffer_get_free;
127 + k->run_buffer_out = audio_generic_run_buffer_out;
128 + k->enable_out = no_enable_out;
129 +
130 + k->init_in = no_init_in;
131 + k->fini_in = no_fini_in;
132 + k->read = no_read;
133 + k->run_buffer_in = audio_generic_run_buffer_in;
134 + k->enable_in = no_enable_in;
135 }
136
137 static const TypeInfo audio_types[] = {
audio/ossaudio.c
+15 -18
@@ -755,23 +755,6 @@ audio_oss_realize(AudioBackend *abe, Audiodev *dev, Error **errp)
755 return audio_oss_parent_class->realize(abe, dev, errp);
756 }
757
758 -static struct audio_pcm_ops oss_pcm_ops = {
759 - .init_out = oss_init_out,
760 - .fini_out = oss_fini_out,
761 - .write = oss_write,
762 - .buffer_get_free = oss_buffer_get_free,
763 - .run_buffer_out = oss_run_buffer_out,
764 - .get_buffer_out = oss_get_buffer_out,
765 - .put_buffer_out = oss_put_buffer_out,
766 - .enable_out = oss_enable_out,
767 -
768 - .init_in = oss_init_in,
769 - .fini_in = oss_fini_in,
770 - .read = oss_read,
771 - .run_buffer_in = audio_generic_run_buffer_in,
772 - .enable_in = oss_enable_in
773 -};
774 -
758 static void audio_oss_class_init(ObjectClass *klass, const void *data)
759 {
760 AudioBackendClass *b = AUDIO_BACKEND_CLASS(klass);
@@ -781,11 +764,25 @@ static void audio_oss_class_init(ObjectClass *klass, const void *data)
764
765 b->realize = audio_oss_realize;
766 k->name = "oss";
784 - k->pcm_ops = &oss_pcm_ops;
767 k->max_voices_out = INT_MAX;
768 k->max_voices_in = INT_MAX;
769 k->voice_size_out = sizeof(OSSVoiceOut);
770 k->voice_size_in = sizeof(OSSVoiceIn);
771 +
772 + k->init_out = oss_init_out;
773 + k->fini_out = oss_fini_out;
774 + k->write = oss_write;
775 + k->buffer_get_free = oss_buffer_get_free;
776 + k->run_buffer_out = oss_run_buffer_out;
777 + k->get_buffer_out = oss_get_buffer_out;
778 + k->put_buffer_out = oss_put_buffer_out;
779 + k->enable_out = oss_enable_out;
780 +
781 + k->init_in = oss_init_in;
782 + k->fini_in = oss_fini_in;
783 + k->read = oss_read;
784 + k->run_buffer_in = audio_generic_run_buffer_in;
785 + k->enable_in = oss_enable_in;
786 }
787
788 static const TypeInfo audio_types[] = {
audio/paaudio.c
+15 -18
@@ -913,23 +913,6 @@ static void audio_pa_finalize(Object *obj)
913 }
914 }
915
916 -static struct audio_pcm_ops qpa_pcm_ops = {
917 - .init_out = qpa_init_out,
918 - .fini_out = qpa_fini_out,
919 - .write = qpa_write,
920 - .buffer_get_free = qpa_buffer_get_free,
921 - .get_buffer_out = qpa_get_buffer_out,
922 - .put_buffer_out = qpa_put_buffer_out,
923 - .volume_out = qpa_volume_out,
924 -
925 - .init_in = qpa_init_in,
926 - .fini_in = qpa_fini_in,
927 - .read = qpa_read,
928 - .get_buffer_in = qpa_get_buffer_in,
929 - .put_buffer_in = qpa_put_buffer_in,
930 - .volume_in = qpa_volume_in
931 -};
932 -
916 static void audio_pa_class_init(ObjectClass *klass, const void *data)
917 {
918 AudioBackendClass *b = AUDIO_BACKEND_CLASS(klass);
@@ -939,11 +922,25 @@ static void audio_pa_class_init(ObjectClass *klass, const void *data)
922
923 b->realize = audio_pa_realize;
924 k->name = "pa";
942 - k->pcm_ops = &qpa_pcm_ops;
925 k->max_voices_out = INT_MAX;
926 k->max_voices_in = INT_MAX;
927 k->voice_size_out = sizeof(PAVoiceOut);
928 k->voice_size_in = sizeof(PAVoiceIn);
929 +
930 + k->init_out = qpa_init_out;
931 + k->fini_out = qpa_fini_out;
932 + k->write = qpa_write;
933 + k->buffer_get_free = qpa_buffer_get_free;
934 + k->get_buffer_out = qpa_get_buffer_out;
935 + k->put_buffer_out = qpa_put_buffer_out;
936 + k->volume_out = qpa_volume_out;
937 +
938 + k->init_in = qpa_init_in;
939 + k->fini_in = qpa_fini_in;
940 + k->read = qpa_read;
941 + k->get_buffer_in = qpa_get_buffer_in;
942 + k->put_buffer_in = qpa_put_buffer_in;
943 + k->volume_in = qpa_volume_in;
944 }
945
946 static const TypeInfo audio_types[] = {
audio/pwaudio.c
+15 -18
@@ -822,23 +822,6 @@ audio_pw_finalize(Object *obj)
822 g_clear_pointer(&pw->thread_loop, pw_thread_loop_destroy);
823 }
824
825 -static struct audio_pcm_ops qpw_pcm_ops = {
826 - .init_out = qpw_init_out,
827 - .fini_out = qpw_fini_out,
828 - .write = qpw_write,
829 - .buffer_get_free = qpw_buffer_get_free,
830 - .run_buffer_out = audio_generic_run_buffer_out,
831 - .enable_out = qpw_enable_out,
832 - .volume_out = qpw_volume_out,
833 - .volume_in = qpw_volume_in,
834 -
835 - .init_in = qpw_init_in,
836 - .fini_in = qpw_fini_in,
837 - .read = qpw_read,
838 - .run_buffer_in = audio_generic_run_buffer_in,
839 - .enable_in = qpw_enable_in
840 -};
841 -
825 static void audio_pw_class_init(ObjectClass *klass, const void *data)
826 {
827 AudioBackendClass *b = AUDIO_BACKEND_CLASS(klass);
@@ -848,11 +831,25 @@ static void audio_pw_class_init(ObjectClass *klass, const void *data)
831
832 b->realize = audio_pw_realize;
833 k->name = "pipewire";
851 - k->pcm_ops = &qpw_pcm_ops;
834 k->max_voices_out = INT_MAX;
835 k->max_voices_in = INT_MAX;
836 k->voice_size_out = sizeof(PWVoiceOut);
837 k->voice_size_in = sizeof(PWVoiceIn);
838 +
839 + k->init_out = qpw_init_out;
840 + k->fini_out = qpw_fini_out;
841 + k->write = qpw_write;
842 + k->buffer_get_free = qpw_buffer_get_free;
843 + k->run_buffer_out = audio_generic_run_buffer_out;
844 + k->enable_out = qpw_enable_out;
845 + k->volume_out = qpw_volume_out;
846 +
847 + k->init_in = qpw_init_in;
848 + k->fini_in = qpw_fini_in;
849 + k->read = qpw_read;
850 + k->run_buffer_in = audio_generic_run_buffer_in;
851 + k->enable_in = qpw_enable_in;
852 + k->volume_in = qpw_volume_in;
853 }
854
855 static const TypeInfo audio_types[] = {
audio/sdlaudio.c
+22 -24
@@ -468,29 +468,6 @@ static void audio_sdl_finalize(Object *obj)
468 SDL_QuitSubSystem(SDL_INIT_AUDIO);
469 }
470
471 -static struct audio_pcm_ops sdl_pcm_ops = {
472 - .init_out = sdl_init_out,
473 - .fini_out = sdl_fini_out,
474 - /* wrapper for audio_generic_write */
475 - .write = sdl_write,
476 - /* wrapper for audio_generic_buffer_get_free */
477 - .buffer_get_free = sdl_buffer_get_free,
478 - /* wrapper for audio_generic_get_buffer_out */
479 - .get_buffer_out = sdl_get_buffer_out,
480 - /* wrapper for audio_generic_put_buffer_out */
481 - .put_buffer_out = sdl_put_buffer_out,
482 - .enable_out = sdl_enable_out,
483 - .init_in = sdl_init_in,
484 - .fini_in = sdl_fini_in,
485 - /* wrapper for audio_generic_read */
486 - .read = sdl_read,
487 - /* wrapper for audio_generic_get_buffer_in */
488 - .get_buffer_in = sdl_get_buffer_in,
489 - /* wrapper for audio_generic_put_buffer_in */
490 - .put_buffer_in = sdl_put_buffer_in,
491 - .enable_in = sdl_enable_in,
492 -};
493 -
471 static void audio_sdl_class_init(ObjectClass *klass, const void *data)
472 {
473 AudioBackendClass *b = AUDIO_BACKEND_CLASS(klass);
@@ -500,11 +477,32 @@ static void audio_sdl_class_init(ObjectClass *klass, const void *data)
477
478 b->realize = audio_sdl_realize;
479 k->name = "sdl";
503 - k->pcm_ops = &sdl_pcm_ops;
480 k->max_voices_out = INT_MAX;
481 k->max_voices_in = INT_MAX;
482 k->voice_size_out = sizeof(SDLVoiceOut);
483 k->voice_size_in = sizeof(SDLVoiceIn);
484 +
485 + k->init_out = sdl_init_out;
486 + k->fini_out = sdl_fini_out;
487 + /* wrapper for audio_generic_write */
488 + k->write = sdl_write;
489 + /* wrapper for audio_generic_buffer_get_free */
490 + k->buffer_get_free = sdl_buffer_get_free;
491 + /* wrapper for audio_generic_get_buffer_out */
492 + k->get_buffer_out = sdl_get_buffer_out;
493 + /* wrapper for audio_generic_put_buffer_out */
494 + k->put_buffer_out = sdl_put_buffer_out;
495 + k->enable_out = sdl_enable_out;
496 +
497 + k->init_in = sdl_init_in;
498 + k->fini_in = sdl_fini_in;
499 + /* wrapper for audio_generic_read */
500 + k->read = sdl_read;
501 + /* wrapper for audio_generic_get_buffer_in */
502 + k->get_buffer_in = sdl_get_buffer_in;
503 + /* wrapper for audio_generic_put_buffer_in */
504 + k->put_buffer_in = sdl_put_buffer_in;
505 + k->enable_in = sdl_enable_in;
506 }
507
508 static const TypeInfo audio_types[] = {
audio/sndioaudio.c
+15 -17
@@ -527,32 +527,30 @@ static void sndio_fini_in(HWVoiceIn *hw)
527 sndio_fini(self);
528 }
529
530 -static struct audio_pcm_ops sndio_pcm_ops = {
531 - .init_out = sndio_init_out,
532 - .fini_out = sndio_fini_out,
533 - .enable_out = sndio_enable_out,
534 - .write = audio_generic_write,
535 - .buffer_get_free = sndio_buffer_get_free,
536 - .get_buffer_out = sndio_get_buffer_out,
537 - .put_buffer_out = sndio_put_buffer_out,
538 - .init_in = sndio_init_in,
539 - .fini_in = sndio_fini_in,
540 - .read = audio_generic_read,
541 - .enable_in = sndio_enable_in,
542 - .get_buffer_in = sndio_get_buffer_in,
543 - .put_buffer_in = sndio_put_buffer_in,
544 -};
545 -
530 static void audio_sndio_class_init(ObjectClass *klass, const void *data)
531 {
532 AudioMixengBackendClass *k = AUDIO_MIXENG_BACKEND_CLASS(klass);
533
534 k->name = "sndio";
551 - k->pcm_ops = &sndio_pcm_ops;
535 k->max_voices_out = INT_MAX;
536 k->max_voices_in = INT_MAX;
537 k->voice_size_out = sizeof(SndioVoice);
538 k->voice_size_in = sizeof(SndioVoice);
539 +
540 + k->init_out = sndio_init_out;
541 + k->fini_out = sndio_fini_out;
542 + k->write = audio_generic_write;
543 + k->buffer_get_free = sndio_buffer_get_free;
544 + k->get_buffer_out = sndio_get_buffer_out;
545 + k->put_buffer_out = sndio_put_buffer_out;
546 + k->enable_out = sndio_enable_out;
547 +
548 + k->init_in = sndio_init_in;
549 + k->fini_in = sndio_fini_in;
550 + k->read = audio_generic_read;
551 + k->get_buffer_in = sndio_get_buffer_in;
552 + k->put_buffer_in = sndio_put_buffer_in;
553 + k->enable_in = sndio_enable_in;
554 }
555
556 static const TypeInfo audio_types[] = {
audio/spiceaudio.c
+21 -24
@@ -296,29 +296,6 @@ static void line_in_volume(HWVoiceIn *hw, Volume *vol)
296 }
297 #endif
298
299 -static struct audio_pcm_ops audio_callbacks = {
300 - .init_out = line_out_init,
301 - .fini_out = line_out_fini,
302 - .write = audio_generic_write,
303 - .buffer_get_free = line_out_get_free,
304 - .get_buffer_out = line_out_get_buffer,
305 - .put_buffer_out = line_out_put_buffer,
306 - .enable_out = line_out_enable,
307 -#if (SPICE_INTERFACE_PLAYBACK_MAJOR >= 1) && \
308 - (SPICE_INTERFACE_PLAYBACK_MINOR >= 2)
309 - .volume_out = line_out_volume,
310 -#endif
311 -
312 - .init_in = line_in_init,
313 - .fini_in = line_in_fini,
314 - .read = line_in_read,
315 - .run_buffer_in = audio_generic_run_buffer_in,
316 - .enable_in = line_in_enable,
317 -#if ((SPICE_INTERFACE_RECORD_MAJOR >= 2) && (SPICE_INTERFACE_RECORD_MINOR >= 2))
318 - .volume_in = line_in_volume,
319 -#endif
320 -};
321 -
299 static void audio_spice_class_init(ObjectClass *klass, const void *data)
300 {
301 AudioBackendClass *b = AUDIO_BACKEND_CLASS(klass);
@@ -328,11 +305,31 @@ static void audio_spice_class_init(ObjectClass *klass, const void *data)
305
306 b->realize = spice_audio_realize;
307 k->name = "spice";
331 - k->pcm_ops = &audio_callbacks;
308 k->max_voices_out = 1;
309 k->max_voices_in = 1;
310 k->voice_size_out = sizeof(SpiceVoiceOut);
311 k->voice_size_in = sizeof(SpiceVoiceIn);
312 +
313 + k->init_out = line_out_init;
314 + k->fini_out = line_out_fini;
315 + k->write = audio_generic_write;
316 + k->buffer_get_free = line_out_get_free;
317 + k->get_buffer_out = line_out_get_buffer;
318 + k->put_buffer_out = line_out_put_buffer;
319 + k->enable_out = line_out_enable;
320 +#if (SPICE_INTERFACE_PLAYBACK_MAJOR >= 1) && \
321 + (SPICE_INTERFACE_PLAYBACK_MINOR >= 2)
322 + k->volume_out = line_out_volume;
323 +#endif
324 +
325 + k->init_in = line_in_init;
326 + k->fini_in = line_in_fini;
327 + k->read = line_in_read;
328 + k->run_buffer_in = audio_generic_run_buffer_in;
329 + k->enable_in = line_in_enable;
330 +#if ((SPICE_INTERFACE_RECORD_MAJOR >= 2) && (SPICE_INTERFACE_RECORD_MINOR >= 2))
331 + k->volume_in = line_in_volume;
332 +#endif
333 }
334
335 static const TypeInfo audio_types[] = {
audio/wavaudio.c
+7 -10
@@ -190,25 +190,22 @@ static void wav_enable_out(HWVoiceOut *hw, bool enable)
190 }
191 }
192
193 -static struct audio_pcm_ops wav_pcm_ops = {
194 - .init_out = wav_init_out,
195 - .fini_out = wav_fini_out,
196 - .write = wav_write_out,
197 - .buffer_get_free = audio_generic_buffer_get_free,
198 - .run_buffer_out = audio_generic_run_buffer_out,
199 - .enable_out = wav_enable_out,
200 -};
201 -
193 static void audio_wav_class_init(ObjectClass *klass, const void *data)
194 {
195 AudioMixengBackendClass *k = AUDIO_MIXENG_BACKEND_CLASS(klass);
196
197 k->name = "wav";
207 - k->pcm_ops = &wav_pcm_ops;
198 k->max_voices_out = 1;
199 k->max_voices_in = 0;
200 k->voice_size_out = sizeof(WAVVoiceOut);
201 k->voice_size_in = 0;
202 +
203 + k->init_out = wav_init_out;
204 + k->fini_out = wav_fini_out;
205 + k->write = wav_write_out;
206 + k->buffer_get_free = audio_generic_buffer_get_free;
207 + k->run_buffer_out = audio_generic_run_buffer_out;
208 + k->enable_out = wav_enable_out;
209 }
210
211 static const TypeInfo audio_types[] = {