1From 7472a43ccf2f5bae14cd736102daab8b4be0df31 Mon Sep 17 00:00:00 2001
2From: Michael Forney <mforney@mforney.org>
3Date: Mon, 31 Oct 2022 03:47:44 -0700
4Subject: [PATCH] alsa: Add support for s24le3/s24be3
5
6---
7 libsndio/sio_alsa.c | 41 +++++++++++++++++++++++++++++++++--------
8 1 file changed, 33 insertions(+), 8 deletions(-)
9
10diff --git a/libsndio/sio_alsa.c b/libsndio/sio_alsa.c
11index e460bf6..9a65288 100644
12--- a/libsndio/sio_alsa.c
13+++ b/libsndio/sio_alsa.c
14@@ -112,40 +112,60 @@ static enum pcm_format cap_fmts[] = {
15 */
16 static int
17 sio_alsa_fmttopar(struct sio_alsa_hdl *hdl, enum pcm_format fmt,
18- unsigned int *bits, unsigned int *sig, unsigned int *le)
19+ unsigned int *bits, unsigned int *bps, unsigned int *sig, unsigned int *le)
20 {
21 switch (fmt) {
22 case PCM_FORMAT_S8:
23 *bits = 8;
24+ *bps = 1;
25 *sig = 1;
26+ *le = 1;
27 break;
28 case PCM_FORMAT_S16_LE:
29 *bits = 16;
30+ *bps = 2;
31 *sig = 1;
32 *le = 1;
33 break;
34 case PCM_FORMAT_S16_BE:
35 *bits = 16;
36+ *bps = 2;
37+ *sig = 1;
38+ *le = 0;
39+ break;
40+ case PCM_FORMAT_S24_3LE:
41+ *bits = 24;
42+ *bps = 3;
43+ *sig = 1;
44+ *le = 1;
45+ break;
46+ case PCM_FORMAT_S24_3BE:
47+ *bits = 24;
48+ *bps = 3;
49 *sig = 1;
50 *le = 0;
51 break;
52 case PCM_FORMAT_S24_LE:
53 *bits = 24;
54+ *bps = 4;
55 *sig = 1;
56 *le = 1;
57 break;
58 case PCM_FORMAT_S24_BE:
59 *bits = 24;
60+ *bps = 4;
61 *sig = 1;
62 *le = 0;
63 break;
64 case PCM_FORMAT_S32_LE:
65 *bits = 32;
66+ *bps = 4;
67 *sig = 1;
68 *le = 1;
69 break;
70 case PCM_FORMAT_S32_BE:
71 *bits = 32;
72+ *bps = 4;
73 *sig = 1;
74 *le = 0;
75 break;
76@@ -163,13 +183,17 @@ sio_alsa_fmttopar(struct sio_alsa_hdl *hdl, enum pcm_format fmt,
77 */
78 static void
79 sio_alsa_enctofmt(struct sio_alsa_hdl *hdl, enum pcm_format *rfmt,
80- unsigned int bits, unsigned int sig, unsigned int le)
81+ unsigned int bits, unsigned int bps, unsigned int sig, unsigned int le)
82 {
83+ if (bps == ~0U)
84+ bps = SIO_BPS(bits);
85 if (le == ~0U)
86 le = SIO_LE_NATIVE;
87 if (bits == 8)
88 *rfmt = PCM_FORMAT_S8;
89- else if (bits == 24)
90+ else if (bits == 24 && bps == 3)
91+ *rfmt = le ? PCM_FORMAT_S24_3LE : PCM_FORMAT_S24_3BE;
92+ else if (bits == 24 && bps == 4)
93 *rfmt = le ? PCM_FORMAT_S24_LE : PCM_FORMAT_S24_BE;
94 else if (bits == 32)
95 *rfmt = le ? PCM_FORMAT_S32_LE : PCM_FORMAT_S32_BE;
96@@ -450,6 +474,7 @@ sio_alsa_setpar_hw(struct pcm *pcm, struct pcm_params *par,
97 static enum pcm_format fmts[] = {
98 PCM_FORMAT_S32_LE, PCM_FORMAT_S32_BE,
99 PCM_FORMAT_S24_LE, PCM_FORMAT_S24_BE,
100+ PCM_FORMAT_S24_3LE, PCM_FORMAT_S24_3BE,
101 PCM_FORMAT_S16_LE, PCM_FORMAT_S16_BE,
102 PCM_FORMAT_S8
103 };
104@@ -582,9 +607,9 @@ sio_alsa_getcap(struct sio_hdl *sh, struct sio_cap *cap)
105 for (i = 0; i < CAP_NFMTS; i++) {
106 sio_alsa_fmttopar(hdl, cap_fmts[i],
107 &cap->enc[i].bits,
108+ &cap->enc[i].bps,
109 &cap->enc[i].sig,
110 &cap->enc[i].le);
111- cap->enc[i].bps = SIO_BPS(cap->enc[0].bits);
112 cap->enc[i].msb = 0;
113 }
114 for (i = 0; i < CAP_NRATES; i++) {
115@@ -620,7 +645,8 @@ sio_alsa_setpar(struct sio_hdl *sh, struct sio_par *par)
116 struct sio_alsa_hdl *hdl = (struct sio_alsa_hdl *)sh;
117 struct pcm_config icfg, ocfg;
118
119- sio_alsa_enctofmt(hdl, &icfg.format, par->bits, par->sig, par->le);
120+ sio_alsa_enctofmt(hdl, &icfg.format, par->bits, par->bps, par->sig,
121+ par->le);
122 icfg.rate = (par->rate == ~0U) ? 48000 : par->rate;
123 if (par->appbufsz != ~0U) {
124 icfg.period_size = (par->round != ~0U) ?
125@@ -674,11 +700,10 @@ sio_alsa_setpar(struct sio_hdl *sh, struct sio_par *par)
126 hdl->sio.eof = 1;
127 return 0;
128 }
129- if (!sio_alsa_fmttopar(hdl, icfg.format,
130- &hdl->par.bits, &hdl->par.sig, &hdl->par.le))
131+ if (!sio_alsa_fmttopar(hdl, icfg.format, &hdl->par.bits, &hdl->par.bps,
132+ &hdl->par.sig, &hdl->par.le))
133 return 0;
134 hdl->par.msb = 0;
135- hdl->par.bps = SIO_BPS(hdl->par.bits);
136 hdl->par.rate = ocfg.rate;
137 hdl->par.round = ocfg.period_size;
138 hdl->par.bufsz = ocfg.period_size * ocfg.period_count;
139--
1402.37.3
141