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[] = {