summaryrefslogtreecommitdiffstats
path: root/meta/recipes-multimedia/alsa/alsa-lib/0001-pcm-route-Use-get32-for-multi-source-route-calculati.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-multimedia/alsa/alsa-lib/0001-pcm-route-Use-get32-for-multi-source-route-calculati.patch')
-rwxr-xr-xmeta/recipes-multimedia/alsa/alsa-lib/0001-pcm-route-Use-get32-for-multi-source-route-calculati.patch345
1 files changed, 345 insertions, 0 deletions
diff --git a/meta/recipes-multimedia/alsa/alsa-lib/0001-pcm-route-Use-get32-for-multi-source-route-calculati.patch b/meta/recipes-multimedia/alsa/alsa-lib/0001-pcm-route-Use-get32-for-multi-source-route-calculati.patch
new file mode 100755
index 0000000000..89363d55d2
--- /dev/null
+++ b/meta/recipes-multimedia/alsa/alsa-lib/0001-pcm-route-Use-get32-for-multi-source-route-calculati.patch
@@ -0,0 +1,345 @@
1From 3f179d6cc7c222dfa42fe094b7ef1e21685a05bc Mon Sep 17 00:00:00 2001
2From: Takashi Iwai <tiwai@suse.de>
3Date: Tue, 22 Jul 2014 11:55:40 +0200
4Subject: [PATCH] pcm: route: Use get32 for multi-source route calculation
5
6The PCM route plugin can assign the destination value from average of
7multiple sources with attenuation. This requires the read of each
8channel value, sums and writes the resultant value in the requested
9format.
10
11Currently, get_labels is used for reading source values while
12put32_labels is used for writing the dest value. This is, however,
13a buggy implementation; get_labels gives the value as is only with
14endianness and signedness conversions, but put32_labels assumes that
15the value is normalized to 32bit int and it shifts down to the dest
16format. In addition, the current code lacks get_labels entries for
17the 24bit formats, as Shengjiu Wang spotted out.
18
19For fixing these bugs, this patch replaces the read with
20get32_labels and use always 64bit int for sum. This simplifies the
21code a lot and drops many lines.
22
23Commit fd84adc63e307572d05274be44c782a787087cda in master branch
24
25Upstream Status: Backported
26
27Signed-off-by: Takashi Iwai <tiwai@suse.de>
28---
29 src/pcm/pcm_route.c | 128 +++++++++-----------------------------------------
30 src/pcm/plugin_ops.h | 81 --------------------------------
31 2 files changed, 23 insertions(+), 186 deletions(-)
32
33diff --git a/src/pcm/pcm_route.c b/src/pcm/pcm_route.c
34index 2beedf6..1ed9c5f 100644
35--- a/src/pcm/pcm_route.c
36+++ b/src/pcm/pcm_route.c
37@@ -60,7 +60,7 @@ typedef struct {
38 typedef struct snd_pcm_route_ttable_dst snd_pcm_route_ttable_dst_t;
39
40 typedef struct {
41- enum {UINT32=0, UINT64=1, FLOAT=2} sum_idx;
42+ enum {UINT64, FLOAT} sum_idx;
43 unsigned int get_idx;
44 unsigned int put_idx;
45 unsigned int conv_idx;
46@@ -232,55 +232,34 @@ static void snd_pcm_route_convert1_many(const snd_pcm_channel_area_t *dst_area,
47 const snd_pcm_route_ttable_dst_t* ttable,
48 const snd_pcm_route_params_t *params)
49 {
50-#define GETS_LABELS
51+#define GET32_LABELS
52 #define PUT32_LABELS
53 #include "plugin_ops.h"
54-#undef GETS_LABELS
55+#undef GET32_LABELS
56 #undef PUT32_LABELS
57- static void *const zero_labels[3] = {
58- &&zero_int32, &&zero_int64,
59+ static void *const zero_labels[2] = {
60+ &&zero_int64,
61 #if SND_PCM_PLUGIN_ROUTE_FLOAT
62 &&zero_float
63 #endif
64 };
65 /* sum_type att */
66- static void *const add_labels[3 * 2] = {
67- &&add_int32_noatt, &&add_int32_att,
68+ static void *const add_labels[2 * 2] = {
69 &&add_int64_noatt, &&add_int64_att,
70 #if SND_PCM_PLUGIN_ROUTE_FLOAT
71 &&add_float_noatt, &&add_float_att
72 #endif
73 };
74- /* sum_type att shift */
75- static void *const norm_labels[3 * 2 * 4] = {
76- 0,
77- &&norm_int32_8_noatt,
78- &&norm_int32_16_noatt,
79- &&norm_int32_24_noatt,
80- 0,
81- &&norm_int32_8_att,
82- &&norm_int32_16_att,
83- &&norm_int32_24_att,
84- &&norm_int64_0_noatt,
85- &&norm_int64_8_noatt,
86- &&norm_int64_16_noatt,
87- &&norm_int64_24_noatt,
88- &&norm_int64_0_att,
89- &&norm_int64_8_att,
90- &&norm_int64_16_att,
91- &&norm_int64_24_att,
92+ /* sum_type att */
93+ static void *const norm_labels[2 * 2] = {
94+ &&norm_int64_noatt,
95+ &&norm_int64_att,
96 #if SND_PCM_PLUGIN_ROUTE_FLOAT
97- &&norm_float_0,
98- &&norm_float_8,
99- &&norm_float_16,
100- &&norm_float_24,
101- &&norm_float_0,
102- &&norm_float_8,
103- &&norm_float_16,
104- &&norm_float_24,
105+ &&norm_float,
106+ &&norm_float,
107 #endif
108 };
109- void *zero, *get, *add, *norm, *put32;
110+ void *zero, *get32, *add, *norm, *put32;
111 int nsrcs = ttable->nsrcs;
112 char *dst;
113 int dst_step;
114@@ -322,9 +301,9 @@ static void snd_pcm_route_convert1_many(const snd_pcm_channel_area_t *dst_area,
115 }
116
117 zero = zero_labels[params->sum_idx];
118- get = gets_labels[params->get_idx];
119+ get32 = get32_labels[params->get_idx];
120 add = add_labels[params->sum_idx * 2 + ttable->att];
121- norm = norm_labels[params->sum_idx * 8 + ttable->att * 4 + 4 - params->src_size];
122+ norm = norm_labels[params->sum_idx * 2 + ttable->att];
123 put32 = put32_labels[params->put_idx];
124 dst = snd_pcm_channel_area_addr(dst_area, dst_offset);
125 dst_step = snd_pcm_channel_area_step(dst_area);
126@@ -335,9 +314,6 @@ static void snd_pcm_route_convert1_many(const snd_pcm_channel_area_t *dst_area,
127
128 /* Zero sum */
129 goto *zero;
130- zero_int32:
131- sum.as_sint32 = 0;
132- goto zero_end;
133 zero_int64:
134 sum.as_sint64 = 0;
135 goto zero_end;
136@@ -351,21 +327,14 @@ static void snd_pcm_route_convert1_many(const snd_pcm_channel_area_t *dst_area,
137 const char *src = srcs[srcidx];
138
139 /* Get sample */
140- goto *get;
141-#define GETS_END after_get
142+ goto *get32;
143+#define GET32_END after_get
144 #include "plugin_ops.h"
145-#undef GETS_END
146+#undef GET32_END
147 after_get:
148
149 /* Sum */
150 goto *add;
151- add_int32_att:
152- sum.as_sint32 += sample * ttp->as_int;
153- goto after_sum;
154- add_int32_noatt:
155- if (ttp->as_int)
156- sum.as_sint32 += sample;
157- goto after_sum;
158 add_int64_att:
159 sum.as_sint64 += (int64_t) sample * ttp->as_int;
160 goto after_sum;
161@@ -389,48 +358,10 @@ static void snd_pcm_route_convert1_many(const snd_pcm_channel_area_t *dst_area,
162
163 /* Normalization */
164 goto *norm;
165- norm_int32_8_att:
166- sum.as_sint64 = sum.as_sint32;
167- norm_int64_8_att:
168- sum.as_sint64 <<= 8;
169- norm_int64_0_att:
170- div(sum.as_sint64);
171- goto norm_int;
172-
173- norm_int32_16_att:
174- sum.as_sint64 = sum.as_sint32;
175- norm_int64_16_att:
176- sum.as_sint64 <<= 16;
177+ norm_int64_att:
178 div(sum.as_sint64);
179- goto norm_int;
180-
181- norm_int32_24_att:
182- sum.as_sint64 = sum.as_sint32;
183- norm_int64_24_att:
184- sum.as_sint64 <<= 24;
185- div(sum.as_sint64);
186- goto norm_int;
187-
188- norm_int32_8_noatt:
189- sum.as_sint64 = sum.as_sint32;
190- norm_int64_8_noatt:
191- sum.as_sint64 <<= 8;
192- goto norm_int;
193-
194- norm_int32_16_noatt:
195- sum.as_sint64 = sum.as_sint32;
196- norm_int64_16_noatt:
197- sum.as_sint64 <<= 16;
198- goto norm_int;
199-
200- norm_int32_24_noatt:
201- sum.as_sint64 = sum.as_sint32;
202- norm_int64_24_noatt:
203- sum.as_sint64 <<= 24;
204- goto norm_int;
205-
206- norm_int64_0_noatt:
207- norm_int:
208+ /* fallthru */
209+ norm_int64_noatt:
210 if (sum.as_sint64 > (int64_t)0x7fffffff)
211 sample = 0x7fffffff; /* maximum positive value */
212 else if (sum.as_sint64 < -(int64_t)0x80000000)
213@@ -440,16 +371,6 @@ static void snd_pcm_route_convert1_many(const snd_pcm_channel_area_t *dst_area,
214 goto after_norm;
215
216 #if SND_PCM_PLUGIN_ROUTE_FLOAT
217- norm_float_8:
218- sum.as_float *= 1 << 8;
219- goto norm_float;
220- norm_float_16:
221- sum.as_float *= 1 << 16;
222- goto norm_float;
223- norm_float_24:
224- sum.as_float *= 1 << 24;
225- goto norm_float;
226- norm_float_0:
227 norm_float:
228 sum.as_float = rint(sum.as_float);
229 if (sum.as_float > (int64_t)0x7fffffff)
230@@ -644,7 +565,7 @@ static int snd_pcm_route_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
231 return err;
232 route->params.use_getput = snd_pcm_format_physical_width(src_format) == 24 ||
233 snd_pcm_format_physical_width(dst_format) == 24;
234- route->params.get_idx = snd_pcm_linear_get_index(src_format, SND_PCM_FORMAT_S16);
235+ route->params.get_idx = snd_pcm_linear_get32_index(src_format, SND_PCM_FORMAT_S32);
236 route->params.put_idx = snd_pcm_linear_put32_index(SND_PCM_FORMAT_S32, dst_format);
237 route->params.conv_idx = snd_pcm_linear_convert_index(src_format, dst_format);
238 route->params.src_size = snd_pcm_format_width(src_format) / 8;
239@@ -652,10 +573,7 @@ static int snd_pcm_route_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
240 #if SND_PCM_PLUGIN_ROUTE_FLOAT
241 route->params.sum_idx = FLOAT;
242 #else
243- if (snd_pcm_format_width(src_format) == 32)
244- route->params.sum_idx = UINT64;
245- else
246- route->params.sum_idx = UINT32;
247+ route->params.sum_idx = UINT64;
248 #endif
249 return 0;
250 }
251diff --git a/src/pcm/plugin_ops.h b/src/pcm/plugin_ops.h
252index 21535c9..eb8c2c4 100644
253--- a/src/pcm/plugin_ops.h
254+++ b/src/pcm/plugin_ops.h
255@@ -668,87 +668,6 @@ getu_1234_C321: sample = bswap_32(as_u32c(src) ^ 0x80); goto GETU_END;
256 }
257 #endif
258
259-#ifdef GETS_LABELS
260-/* width endswap sign_toggle */
261-static void *const gets_labels[4 * 2 * 2] = {
262- &&gets_1_1, /* 8h -> 8h */
263- &&gets_1_9, /* 8h ^> 8h */
264- &&gets_1_1, /* 8s -> 8h */
265- &&gets_1_9, /* 8s ^> 8h */
266- &&gets_12_12, /* 16h -> 16h */
267- &&gets_12_92, /* 16h ^> 16h */
268- &&gets_12_21, /* 16s -> 16h */
269- &&gets_12_A1, /* 16s ^> 16h */
270- &&gets_0123_0123, /* 24h -> 24h */
271- &&gets_0123_0923, /* 24h ^> 24h */
272- &&gets_1230_0321, /* 24s -> 24h */
273- &&gets_1230_0B21, /* 24s ^> 24h */
274- &&gets_1234_1234, /* 32h -> 32h */
275- &&gets_1234_9234, /* 32h ^> 32h */
276- &&gets_1234_4321, /* 32s -> 32h */
277- &&gets_1234_C321, /* 32s ^> 32h */
278-};
279-#endif
280-
281-#ifdef GETS_END
282-while (0) {
283-gets_1_1: sample = as_s8c(src); goto GETS_END;
284-gets_1_9: sample = (int8_t)(as_s8c(src) ^ 0x80); goto GETS_END;
285-gets_12_12: sample = as_s16c(src); goto GETS_END;
286-gets_12_92: sample = (int16_t)(as_s16c(src) ^ 0x8000); goto GETS_END;
287-gets_12_21: sample = (int16_t)bswap_16(as_s16c(src)); goto GETS_END;
288-gets_12_A1: sample = (int16_t)bswap_16(as_s16c(src) ^ 0x80); goto GETS_END;
289-gets_0123_0123: sample = sx24((int32_t)(as_s32c(src) << 8) >> 8); goto GETS_END;
290-gets_0123_0923: sample = sx24((int32_t)((as_s32c(src) ^ 0x800000) << 8) >> 8); goto GETS_END;
291-gets_1230_0321: sample = sx24((int32_t)(bswap_32(as_s32c(src)) << 8) >> 8); goto GETS_END;
292-gets_1230_0B21: sample = sx24((int32_t)(bswap_32(as_s32c(src) ^ 0x8000) << 8) >> 8); goto GETS_END;
293-gets_1234_1234: sample = as_s32c(src); goto GETS_END;
294-gets_1234_9234: sample = (int32_t)(as_s32c(src) ^ 0x80000000); goto GETS_END;
295-gets_1234_4321: sample = (int32_t)bswap_32(as_s32c(src)); goto GETS_END;
296-gets_1234_C321: sample = (int32_t)bswap_32(as_s32c(src) ^ 0x80); goto GETS_END;
297-}
298-#endif
299-
300-#ifdef PUT_LABELS
301-/* width endswap sign_toggle */
302-static void *const put_labels[4 * 2 * 2] = {
303- &&put_1_1, /* 8h -> 8h */
304- &&put_1_9, /* 8h ^> 8h */
305- &&put_1_1, /* 8h -> 8s */
306- &&put_1_9, /* 8h ^> 8s */
307- &&put_12_12, /* 16h -> 16h */
308- &&put_12_92, /* 16h ^> 16h */
309- &&put_12_21, /* 16h -> 16s */
310- &&put_12_29, /* 16h ^> 16s */
311- &&put_0123_0123, /* 24h -> 24h */
312- &&put_0123_0923, /* 24h ^> 24h */
313- &&put_0123_3210, /* 24h -> 24s */
314- &&put_0123_3290, /* 24h ^> 24s */
315- &&put_1234_1234, /* 32h -> 32h */
316- &&put_1234_9234, /* 32h ^> 32h */
317- &&put_1234_4321, /* 32h -> 32s */
318- &&put_1234_4329, /* 32h ^> 32s */
319-};
320-#endif
321-
322-#ifdef PUT_END
323-put_1_1: as_s8(dst) = sample; goto PUT_END;
324-put_1_9: as_u8(dst) = sample ^ 0x80; goto PUT_END;
325-put_12_12: as_s16(dst) = sample; goto PUT_END;
326-put_12_92: as_u16(dst) = sample ^ 0x8000; goto PUT_END;
327-put_12_21: as_s16(dst) = bswap_16(sample); goto PUT_END;
328-put_12_29: as_u16(dst) = bswap_16(sample) ^ 0x80; goto PUT_END;
329-/* this always writes the unused byte in 24-bit formats as 0x00 */
330-put_0123_0123: as_s32(dst) = sx24(sample & 0x00ffffff); goto PUT_END;
331-put_0123_0923: as_u32(dst) = sx24((sample & 0x00ffffff) ^ 0x800000); goto PUT_END;
332-put_0123_3210: as_s32(dst) = sx24s(bswap_32(sample) & 0xffffff00); goto PUT_END;
333-put_0123_3290: as_u32(dst) = sx24s((bswap_32(sample) & 0xffffff00) ^ 0x8000); goto PUT_END;
334-put_1234_1234: as_s32(dst) = sample; goto PUT_END;
335-put_1234_9234: as_u32(dst) = sample ^ 0x80000000; goto PUT_END;
336-put_1234_4321: as_s32(dst) = bswap_32(sample); goto PUT_END;
337-put_1234_4329: as_u32(dst) = bswap_32(sample) ^ 0x80; goto PUT_END;
338-#endif
339-
340 #ifdef PUT32F_LABELS
341 /* type (0 = float, 1 = float64), endswap */
342 static void *const put32float_labels[2 * 2] = {
343--
3441.7.9.5
345