alsa/0013-pcm-route-Use-get32-for-multi-source-route-calculati.patch
Ismail Dönmez 5da7a20162 Accepting request 241986 from home:tiwai:branches:multimedia:libs
- Remove superfluous Loopback.conf from the source, as it was
  already included in 1.0.28 tarball
- Backport upstream fixes: UCM dummy PCM definition, ICE1712 surround
  definitions, USB-audio secondary PCM definition, PCM rate plugin
  boundary overwrap fix, MONOTONIC_RAW timestamp support, PCM route
  plugin 3-byte format fixes, etc:
  0001-ucm-Document-PlaybackPCMIsDummy-and-CapturePCMIsDumm.patch
  0002-ICE1712-add-surround71-pcm-definition.patch
  0003-USB-Audio-Add-second-S-PDIF-device-on-Phiree-U2.patch
  0004-pcm-rate-fix-hw_ptr-exceed-the-boundary.patch
  0005-pcm-Provide-a-CLOCK_MONOTONIC_RAW-timestamp-type.patch
  0006-Add-timestamp-type-to-sw_params-internal-only.patch
  0007-pcm-Add-sw_params-API-functions-to-get-set-timestamp.patch
  0008-pcm-Implement-timestamp-type-setup-in-hw-plugin.patch
  0009-pcm-Implement-timestamp-type-handling-in-all-plugins.patch
  0010-test-audio_time-Set-timestamp-type-explicitly.patch
  0011-pcm-route-Use-get-put-labels-for-all-3-byte-formats.patch
  0012-pcm-Fill-sw_params-proto-field.patch
  0013-pcm-route-Use-get32-for-multi-source-route-calculati.patch
  0014-pcm-Drop-snd_pcm_linear_-get-put-32_index.patch

OBS-URL: https://build.opensuse.org/request/show/241986
OBS-URL: https://build.opensuse.org/package/show/multimedia:libs/alsa?expand=0&rev=162
2014-07-24 11:12:46 +00:00

343 lines
11 KiB
Diff

From fd84adc63e307572d05274be44c782a787087cda Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai@suse.de>
Date: Tue, 22 Jul 2014 11:55:40 +0200
Subject: [PATCH 13/14] pcm: route: Use get32 for multi-source route
calculation
The PCM route plugin can assign the destination value from average of
multiple sources with attenuation. This requires the read of each
channel value, sums and writes the resultant value in the requested
format.
Currently, get_labels is used for reading source values while
put32_labels is used for writing the dest value. This is, however,
a buggy implementation; get_labels gives the value as is only with
endianness and signedness conversions, but put32_labels assumes that
the value is normalized to 32bit int and it shifts down to the dest
format. In addition, the current code lacks get_labels entries for
the 24bit formats, as Shengjiu Wang spotted out.
For fixing these bugs, this patch replaces the read with
get32_labels and use always 64bit int for sum. This simplifies the
code a lot and drops many lines.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
src/pcm/pcm_route.c | 128 +++++++++------------------------------------------
src/pcm/plugin_ops.h | 81 --------------------------------
2 files changed, 23 insertions(+), 186 deletions(-)
diff --git a/src/pcm/pcm_route.c b/src/pcm/pcm_route.c
index 72c198cb25d2..5dac7ebcb7df 100644
--- a/src/pcm/pcm_route.c
+++ b/src/pcm/pcm_route.c
@@ -60,7 +60,7 @@ typedef struct {
typedef struct snd_pcm_route_ttable_dst snd_pcm_route_ttable_dst_t;
typedef struct {
- enum {UINT32=0, UINT64=1, FLOAT=2} sum_idx;
+ enum {UINT64, FLOAT} sum_idx;
unsigned int get_idx;
unsigned int put_idx;
unsigned int conv_idx;
@@ -233,55 +233,34 @@ static void snd_pcm_route_convert1_many(const snd_pcm_channel_area_t *dst_area,
const snd_pcm_route_ttable_dst_t* ttable,
const snd_pcm_route_params_t *params)
{
-#define GETS_LABELS
+#define GET32_LABELS
#define PUT32_LABELS
#include "plugin_ops.h"
-#undef GETS_LABELS
+#undef GET32_LABELS
#undef PUT32_LABELS
- static void *const zero_labels[3] = {
- &&zero_int32, &&zero_int64,
+ static void *const zero_labels[2] = {
+ &&zero_int64,
#if SND_PCM_PLUGIN_ROUTE_FLOAT
&&zero_float
#endif
};
/* sum_type att */
- static void *const add_labels[3 * 2] = {
- &&add_int32_noatt, &&add_int32_att,
+ static void *const add_labels[2 * 2] = {
&&add_int64_noatt, &&add_int64_att,
#if SND_PCM_PLUGIN_ROUTE_FLOAT
&&add_float_noatt, &&add_float_att
#endif
};
- /* sum_type att shift */
- static void *const norm_labels[3 * 2 * 4] = {
- 0,
- &&norm_int32_8_noatt,
- &&norm_int32_16_noatt,
- &&norm_int32_24_noatt,
- 0,
- &&norm_int32_8_att,
- &&norm_int32_16_att,
- &&norm_int32_24_att,
- &&norm_int64_0_noatt,
- &&norm_int64_8_noatt,
- &&norm_int64_16_noatt,
- &&norm_int64_24_noatt,
- &&norm_int64_0_att,
- &&norm_int64_8_att,
- &&norm_int64_16_att,
- &&norm_int64_24_att,
+ /* sum_type att */
+ static void *const norm_labels[2 * 2] = {
+ &&norm_int64_noatt,
+ &&norm_int64_att,
#if SND_PCM_PLUGIN_ROUTE_FLOAT
- &&norm_float_0,
- &&norm_float_8,
- &&norm_float_16,
- &&norm_float_24,
- &&norm_float_0,
- &&norm_float_8,
- &&norm_float_16,
- &&norm_float_24,
+ &&norm_float,
+ &&norm_float,
#endif
};
- void *zero, *get, *add, *norm, *put32;
+ void *zero, *get32, *add, *norm, *put32;
int nsrcs = ttable->nsrcs;
char *dst;
int dst_step;
@@ -323,9 +302,9 @@ static void snd_pcm_route_convert1_many(const snd_pcm_channel_area_t *dst_area,
}
zero = zero_labels[params->sum_idx];
- get = gets_labels[params->get_idx];
+ get32 = get32_labels[params->get_idx];
add = add_labels[params->sum_idx * 2 + ttable->att];
- norm = norm_labels[params->sum_idx * 8 + ttable->att * 4 + 4 - params->src_size];
+ norm = norm_labels[params->sum_idx * 2 + ttable->att];
put32 = put32_labels[params->put_idx];
dst = snd_pcm_channel_area_addr(dst_area, dst_offset);
dst_step = snd_pcm_channel_area_step(dst_area);
@@ -336,9 +315,6 @@ static void snd_pcm_route_convert1_many(const snd_pcm_channel_area_t *dst_area,
/* Zero sum */
goto *zero;
- zero_int32:
- sum.as_sint32 = 0;
- goto zero_end;
zero_int64:
sum.as_sint64 = 0;
goto zero_end;
@@ -352,21 +328,14 @@ static void snd_pcm_route_convert1_many(const snd_pcm_channel_area_t *dst_area,
const char *src = srcs[srcidx];
/* Get sample */
- goto *get;
-#define GETS_END after_get
+ goto *get32;
+#define GET32_END after_get
#include "plugin_ops.h"
-#undef GETS_END
+#undef GET32_END
after_get:
/* Sum */
goto *add;
- add_int32_att:
- sum.as_sint32 += sample * ttp->as_int;
- goto after_sum;
- add_int32_noatt:
- if (ttp->as_int)
- sum.as_sint32 += sample;
- goto after_sum;
add_int64_att:
sum.as_sint64 += (int64_t) sample * ttp->as_int;
goto after_sum;
@@ -390,48 +359,10 @@ static void snd_pcm_route_convert1_many(const snd_pcm_channel_area_t *dst_area,
/* Normalization */
goto *norm;
- norm_int32_8_att:
- sum.as_sint64 = sum.as_sint32;
- norm_int64_8_att:
- sum.as_sint64 <<= 8;
- norm_int64_0_att:
+ norm_int64_att:
div(sum.as_sint64);
- goto norm_int;
-
- norm_int32_16_att:
- sum.as_sint64 = sum.as_sint32;
- norm_int64_16_att:
- sum.as_sint64 <<= 16;
- div(sum.as_sint64);
- goto norm_int;
-
- norm_int32_24_att:
- sum.as_sint64 = sum.as_sint32;
- norm_int64_24_att:
- sum.as_sint64 <<= 24;
- div(sum.as_sint64);
- goto norm_int;
-
- norm_int32_8_noatt:
- sum.as_sint64 = sum.as_sint32;
- norm_int64_8_noatt:
- sum.as_sint64 <<= 8;
- goto norm_int;
-
- norm_int32_16_noatt:
- sum.as_sint64 = sum.as_sint32;
- norm_int64_16_noatt:
- sum.as_sint64 <<= 16;
- goto norm_int;
-
- norm_int32_24_noatt:
- sum.as_sint64 = sum.as_sint32;
- norm_int64_24_noatt:
- sum.as_sint64 <<= 24;
- goto norm_int;
-
- norm_int64_0_noatt:
- norm_int:
+ /* fallthru */
+ norm_int64_noatt:
if (sum.as_sint64 > (int64_t)0x7fffffff)
sample = 0x7fffffff; /* maximum positive value */
else if (sum.as_sint64 < -(int64_t)0x80000000)
@@ -441,16 +372,6 @@ static void snd_pcm_route_convert1_many(const snd_pcm_channel_area_t *dst_area,
goto after_norm;
#if SND_PCM_PLUGIN_ROUTE_FLOAT
- norm_float_8:
- sum.as_float *= 1 << 8;
- goto norm_float;
- norm_float_16:
- sum.as_float *= 1 << 16;
- goto norm_float;
- norm_float_24:
- sum.as_float *= 1 << 24;
- goto norm_float;
- norm_float_0:
norm_float:
sum.as_float = rint(sum.as_float);
if (sum.as_float > (int64_t)0x7fffffff)
@@ -648,7 +569,7 @@ static int snd_pcm_route_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
route->params.use_getput =
(snd_pcm_format_physical_width(src_format) + 7) / 3 == 3 ||
(snd_pcm_format_physical_width(dst_format) + 7) / 3 == 3;
- route->params.get_idx = snd_pcm_linear_get_index(src_format, SND_PCM_FORMAT_S16);
+ route->params.get_idx = snd_pcm_linear_get32_index(src_format, SND_PCM_FORMAT_S32);
route->params.put_idx = snd_pcm_linear_put32_index(SND_PCM_FORMAT_S32, dst_format);
route->params.conv_idx = snd_pcm_linear_convert_index(src_format, dst_format);
route->params.src_size = snd_pcm_format_width(src_format) / 8;
@@ -656,10 +577,7 @@ static int snd_pcm_route_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
#if SND_PCM_PLUGIN_ROUTE_FLOAT
route->params.sum_idx = FLOAT;
#else
- if (snd_pcm_format_width(src_format) == 32)
- route->params.sum_idx = UINT64;
- else
- route->params.sum_idx = UINT32;
+ route->params.sum_idx = UINT64;
#endif
return 0;
}
diff --git a/src/pcm/plugin_ops.h b/src/pcm/plugin_ops.h
index 21535c9ca8d6..eb8c2c4f4dac 100644
--- a/src/pcm/plugin_ops.h
+++ b/src/pcm/plugin_ops.h
@@ -668,87 +668,6 @@ getu_1234_C321: sample = bswap_32(as_u32c(src) ^ 0x80); goto GETU_END;
}
#endif
-#ifdef GETS_LABELS
-/* width endswap sign_toggle */
-static void *const gets_labels[4 * 2 * 2] = {
- &&gets_1_1, /* 8h -> 8h */
- &&gets_1_9, /* 8h ^> 8h */
- &&gets_1_1, /* 8s -> 8h */
- &&gets_1_9, /* 8s ^> 8h */
- &&gets_12_12, /* 16h -> 16h */
- &&gets_12_92, /* 16h ^> 16h */
- &&gets_12_21, /* 16s -> 16h */
- &&gets_12_A1, /* 16s ^> 16h */
- &&gets_0123_0123, /* 24h -> 24h */
- &&gets_0123_0923, /* 24h ^> 24h */
- &&gets_1230_0321, /* 24s -> 24h */
- &&gets_1230_0B21, /* 24s ^> 24h */
- &&gets_1234_1234, /* 32h -> 32h */
- &&gets_1234_9234, /* 32h ^> 32h */
- &&gets_1234_4321, /* 32s -> 32h */
- &&gets_1234_C321, /* 32s ^> 32h */
-};
-#endif
-
-#ifdef GETS_END
-while (0) {
-gets_1_1: sample = as_s8c(src); goto GETS_END;
-gets_1_9: sample = (int8_t)(as_s8c(src) ^ 0x80); goto GETS_END;
-gets_12_12: sample = as_s16c(src); goto GETS_END;
-gets_12_92: sample = (int16_t)(as_s16c(src) ^ 0x8000); goto GETS_END;
-gets_12_21: sample = (int16_t)bswap_16(as_s16c(src)); goto GETS_END;
-gets_12_A1: sample = (int16_t)bswap_16(as_s16c(src) ^ 0x80); goto GETS_END;
-gets_0123_0123: sample = sx24((int32_t)(as_s32c(src) << 8) >> 8); goto GETS_END;
-gets_0123_0923: sample = sx24((int32_t)((as_s32c(src) ^ 0x800000) << 8) >> 8); goto GETS_END;
-gets_1230_0321: sample = sx24((int32_t)(bswap_32(as_s32c(src)) << 8) >> 8); goto GETS_END;
-gets_1230_0B21: sample = sx24((int32_t)(bswap_32(as_s32c(src) ^ 0x8000) << 8) >> 8); goto GETS_END;
-gets_1234_1234: sample = as_s32c(src); goto GETS_END;
-gets_1234_9234: sample = (int32_t)(as_s32c(src) ^ 0x80000000); goto GETS_END;
-gets_1234_4321: sample = (int32_t)bswap_32(as_s32c(src)); goto GETS_END;
-gets_1234_C321: sample = (int32_t)bswap_32(as_s32c(src) ^ 0x80); goto GETS_END;
-}
-#endif
-
-#ifdef PUT_LABELS
-/* width endswap sign_toggle */
-static void *const put_labels[4 * 2 * 2] = {
- &&put_1_1, /* 8h -> 8h */
- &&put_1_9, /* 8h ^> 8h */
- &&put_1_1, /* 8h -> 8s */
- &&put_1_9, /* 8h ^> 8s */
- &&put_12_12, /* 16h -> 16h */
- &&put_12_92, /* 16h ^> 16h */
- &&put_12_21, /* 16h -> 16s */
- &&put_12_29, /* 16h ^> 16s */
- &&put_0123_0123, /* 24h -> 24h */
- &&put_0123_0923, /* 24h ^> 24h */
- &&put_0123_3210, /* 24h -> 24s */
- &&put_0123_3290, /* 24h ^> 24s */
- &&put_1234_1234, /* 32h -> 32h */
- &&put_1234_9234, /* 32h ^> 32h */
- &&put_1234_4321, /* 32h -> 32s */
- &&put_1234_4329, /* 32h ^> 32s */
-};
-#endif
-
-#ifdef PUT_END
-put_1_1: as_s8(dst) = sample; goto PUT_END;
-put_1_9: as_u8(dst) = sample ^ 0x80; goto PUT_END;
-put_12_12: as_s16(dst) = sample; goto PUT_END;
-put_12_92: as_u16(dst) = sample ^ 0x8000; goto PUT_END;
-put_12_21: as_s16(dst) = bswap_16(sample); goto PUT_END;
-put_12_29: as_u16(dst) = bswap_16(sample) ^ 0x80; goto PUT_END;
-/* this always writes the unused byte in 24-bit formats as 0x00 */
-put_0123_0123: as_s32(dst) = sx24(sample & 0x00ffffff); goto PUT_END;
-put_0123_0923: as_u32(dst) = sx24((sample & 0x00ffffff) ^ 0x800000); goto PUT_END;
-put_0123_3210: as_s32(dst) = sx24s(bswap_32(sample) & 0xffffff00); goto PUT_END;
-put_0123_3290: as_u32(dst) = sx24s((bswap_32(sample) & 0xffffff00) ^ 0x8000); goto PUT_END;
-put_1234_1234: as_s32(dst) = sample; goto PUT_END;
-put_1234_9234: as_u32(dst) = sample ^ 0x80000000; goto PUT_END;
-put_1234_4321: as_s32(dst) = bswap_32(sample); goto PUT_END;
-put_1234_4329: as_u32(dst) = bswap_32(sample) ^ 0x80; goto PUT_END;
-#endif
-
#ifdef PUT32F_LABELS
/* type (0 = float, 1 = float64), endswap */
static void *const put32float_labels[2 * 2] = {
--
2.0.1