diff options
Diffstat (limited to 'meta/recipes-multimedia/alsa/alsa-lib')
-rwxr-xr-x | meta/recipes-multimedia/alsa/alsa-lib/0001-pcm-route-Use-get32-for-multi-source-route-calculati.patch | 345 |
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 @@ | |||
1 | From 3f179d6cc7c222dfa42fe094b7ef1e21685a05bc Mon Sep 17 00:00:00 2001 | ||
2 | From: Takashi Iwai <tiwai@suse.de> | ||
3 | Date: Tue, 22 Jul 2014 11:55:40 +0200 | ||
4 | Subject: [PATCH] pcm: route: Use get32 for multi-source route calculation | ||
5 | |||
6 | The PCM route plugin can assign the destination value from average of | ||
7 | multiple sources with attenuation. This requires the read of each | ||
8 | channel value, sums and writes the resultant value in the requested | ||
9 | format. | ||
10 | |||
11 | Currently, get_labels is used for reading source values while | ||
12 | put32_labels is used for writing the dest value. This is, however, | ||
13 | a buggy implementation; get_labels gives the value as is only with | ||
14 | endianness and signedness conversions, but put32_labels assumes that | ||
15 | the value is normalized to 32bit int and it shifts down to the dest | ||
16 | format. In addition, the current code lacks get_labels entries for | ||
17 | the 24bit formats, as Shengjiu Wang spotted out. | ||
18 | |||
19 | For fixing these bugs, this patch replaces the read with | ||
20 | get32_labels and use always 64bit int for sum. This simplifies the | ||
21 | code a lot and drops many lines. | ||
22 | |||
23 | Commit fd84adc63e307572d05274be44c782a787087cda in master branch | ||
24 | |||
25 | Upstream Status: Backported | ||
26 | |||
27 | Signed-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 | |||
33 | diff --git a/src/pcm/pcm_route.c b/src/pcm/pcm_route.c | ||
34 | index 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 | } | ||
251 | diff --git a/src/pcm/plugin_ops.h b/src/pcm/plugin_ops.h | ||
252 | index 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 | -- | ||
344 | 1.7.9.5 | ||
345 | |||