]> code.ossystems Code Review - openembedded-core.git/blob
89363d55d216bc56468578e7b542e7f2a83656ac
[openembedded-core.git] /
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