Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE
alsa.5967
0008-test-use-actual-information-for-TLV-operat...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0008-test-use-actual-information-for-TLV-operation.patch of Package alsa.5967
From ee1182d2cbb4930ca1166bc03f3b0fcfbb594145 Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto <o-takashi@sakamocchi.jp> Date: Thu, 29 Sep 2016 08:57:21 +0900 Subject: [PATCH] test: use actual information for TLV operation Currently, this test program uses undefined type of TLV data. This can bring confusions to userspace applications. This commit replaces the array with valid information, constructed by newly exported TLV macros from kernel land. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de> --- test/user-ctl-element-set.c | 214 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 178 insertions(+), 36 deletions(-) diff --git a/test/user-ctl-element-set.c b/test/user-ctl-element-set.c index 9b9dc598f0af..75083d219fe6 100644 --- a/test/user-ctl-element-set.c +++ b/test/user-ctl-element-set.c @@ -8,6 +8,7 @@ */ #include "../include/asoundlib.h" +#include <sound/tlv.h> struct elem_set_trial { snd_ctl_t *handle; @@ -25,8 +26,30 @@ struct elem_set_trial { snd_ctl_elem_info_t *info); void (*change_elem_members)(struct elem_set_trial *trial, snd_ctl_elem_value_t *elem_data); + int (*allocate_elem_set_tlv)(struct elem_set_trial *trial, + unsigned int **tlv); }; +struct chmap_entry { + unsigned int type; + unsigned int length; + unsigned int maps[0]; +}; + +/* + * History of TLV feature: + * + * 2016/09/15: 398fa4db6c69 ("ALSA: control: move layout of TLV payload to UAPI + * header") + * 2012/07/21: 2d3391ec0ecc ("ALSA: PCM: channel mapping API implementation") + * 2011/11/20: bf1d1c9b6179 ("ALSA: tlv: add DECLARE_TLV_DB_RANGE()") + * 2009/07/16: 085f30654175 ("ALSA: Add new TLV types for dBwith min/max") + * 2006/09/06: 55a29af5ed5d ("[ALSA] Add definition of TLV dB range compound") + * 2006/08/28: 063a40d9111c ("Add the definition of linear volume TLV") + * 2006/08/28: 42750b04c5ba ("[ALSA] Control API - TLV implementation for + * additional information like dB scale") + */ + /* Operations for elements in an element set with boolean type. */ static int add_bool_elem_set(struct elem_set_trial *trial, snd_ctl_elem_info_t *info) @@ -47,13 +70,30 @@ static void change_bool_elem_members(struct elem_set_trial *trial, } } +static int allocate_bool_elem_set_tlv(struct elem_set_trial *trial, + unsigned int **tlv) +{ + /* + * Performs like a toggle switch for attenuation, because they're bool + * elements. + */ + static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(range, -10000, 0); + + *tlv = malloc(sizeof(range)); + if (*tlv == NULL) + return -ENOMEM; + memcpy(*tlv, range, sizeof(range)); + + return 0; +} + /* Operations for elements in an element set with integer type. */ static int add_int_elem_set(struct elem_set_trial *trial, snd_ctl_elem_info_t *info) { return snd_ctl_add_integer_elem_set(trial->handle, info, trial->element_count, trial->member_count, - 0, 99, 1); + 0, 25, 1); } static int check_int_elem_props(struct elem_set_trial *trial, @@ -61,7 +101,7 @@ static int check_int_elem_props(struct elem_set_trial *trial, { if (snd_ctl_elem_info_get_min(info) != 0) return -EIO; - if (snd_ctl_elem_info_get_max(info) != 99) + if (snd_ctl_elem_info_get_max(info) != 25) return -EIO; if (snd_ctl_elem_info_get_step(info) != 1) return -EIO; @@ -81,6 +121,41 @@ static void change_int_elem_members(struct elem_set_trial *trial, } } +static int allocate_int_elem_set_tlv(struct elem_set_trial *trial, + unsigned int **tlv) +{ + unsigned int len, pos; + unsigned int i, j; + struct chmap_entry *entry; + + /* Calculate size of TLV packet for channel-mapping information. */ + len = 0; + for (i = 1; i <= 25; ++i) { + len += sizeof(struct chmap_entry); + len += i * sizeof(unsigned int); + } + + *tlv = malloc(len); + if (*tlv == NULL) + return -ENOMEM; + + /* + * Emulate channel-mapping information in in-kernel implementation. + * Here, 25 entries are for each different channel. + */ + pos = 0; + for (i = 1; i <= 25 && pos < len; ++i) { + entry = (struct chmap_entry *)&(*tlv)[pos]; + entry->type = SNDRV_CTL_TLVT_CHMAP_FIXED; + entry->length = i * sizeof(unsigned int); + for (j = 0; j < i; ++j) + entry->maps[j] = SND_CHMAP_MONO + j; + pos += sizeof(struct chmap_entry) + i * sizeof(unsigned int); + } + + return 0; +} + /* Operations for elements in an element set with enumerated type. */ static const char *const labels[] = { "trusty", @@ -158,6 +233,24 @@ static void change_bytes_elem_members(struct elem_set_trial *trial, } } +static int allocate_bytes_elem_set_tlv(struct elem_set_trial *trial, + unsigned int **tlv) +{ + /* + * Emulate AK4396. + * 20 * log10(x/255) (dB) + * Here, x is written value. + */ + static const SNDRV_CTL_TLVD_DECLARE_DB_LINEAR(range, -4813, 0); + + *tlv = malloc(sizeof(range)); + if (*tlv == NULL) + return -ENOMEM; + memcpy(*tlv, range, sizeof(range)); + + return 0; +} + /* Operations for elements in an element set with iec958 type. */ static int add_iec958_elem_set(struct elem_set_trial *trial, snd_ctl_elem_info_t *info) @@ -197,17 +290,17 @@ static int add_int64_elem_set(struct elem_set_trial *trial, { return snd_ctl_add_integer64_elem_set(trial->handle, info, trial->element_count, trial->member_count, - 100, 10000, 30); + 0, 10000, 1); } static int check_int64_elem_props(struct elem_set_trial *trial, snd_ctl_elem_info_t *info) { - if (snd_ctl_elem_info_get_min64(info) != 100) + if (snd_ctl_elem_info_get_min64(info) != 0) return -EIO; if (snd_ctl_elem_info_get_max64(info) != 10000) return -EIO; - if (snd_ctl_elem_info_get_step64(info) != 30) + if (snd_ctl_elem_info_get_step64(info) != 1) return -EIO; return 0; @@ -225,6 +318,45 @@ static void change_int64_elem_members(struct elem_set_trial *trial, } } +static int allocate_int64_elem_set_tlv(struct elem_set_trial *trial, + unsigned int **tlv) +{ + /* + * Use this fomula between linear/dB value: + * + * Linear: dB range (coeff) + * 0<-> 4: -59.40<->-56.36 (44) + * 4<->22: -56.36<->-45.56 (60) + * 22<->33: -45.56<->-40.72 (76) + * 33<->37: -40.72<->-38.32 (44) + * 37<->48: -38.32<->-29.96 (76) + * 48<->66: -29.96<->-22.04 (60) + * 66<->84: -22.04<-> -8.36 (44) + * 84<->95: -8.36<-> -1.76 (60) + * 95<->99: -1.76<-> 0.00 (76) + * 100<->..: 0.0 + */ + static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(range, + 0, 4, SNDRV_CTL_TLVD_DB_SCALE_ITEM(-5940, 44, 1), + 4, 22, SNDRV_CTL_TLVD_DB_SCALE_ITEM(-5636, 60, 0), + 22, 33, SNDRV_CTL_TLVD_DB_SCALE_ITEM(-4556, 76, 0), + 33, 37, SNDRV_CTL_TLVD_DB_SCALE_ITEM(-4072, 44, 0), + 37, 48, SNDRV_CTL_TLVD_DB_SCALE_ITEM(-3832, 76, 0), + 48, 66, SNDRV_CTL_TLVD_DB_SCALE_ITEM(-2996, 60, 0), + 66, 84, SNDRV_CTL_TLVD_DB_SCALE_ITEM(-2204, 44, 0), + 84, 95, SNDRV_CTL_TLVD_DB_SCALE_ITEM( -836, 60, 0), + 95, 99, SNDRV_CTL_TLVD_DB_SCALE_ITEM( -176, 76, 0), + 100, 10000, SNDRV_CTL_TLVD_DB_SCALE_ITEM(0, 0, 0), + ); + + *tlv = malloc(sizeof(range)); + if (*tlv == NULL) + return -ENOMEM; + memcpy(*tlv, range, sizeof(range)); + + return 0; +} + /* Common operations. */ static int add_elem_set(struct elem_set_trial *trial) { @@ -414,41 +546,41 @@ static int check_elems(struct elem_set_trial *trial) static int check_tlv(struct elem_set_trial *trial) { - unsigned int orig[8], curr[8]; + unsigned int *tlv; + unsigned int len; + unsigned int *curr; int err; - /* - * See a layout of 'struct snd_ctl_tlv'. I don't know the reason to - * construct this buffer with the same layout. It should be abstracted - * inner userspace library... - */ - orig[0] = snd_ctl_elem_id_get_numid(trial->id); - orig[1] = 6 * sizeof(orig[0]); - orig[2] = 'a'; - orig[3] = 'b'; - orig[4] = 'c'; - orig[5] = 'd'; - orig[6] = 'e'; - orig[7] = 'f'; + err = trial->allocate_elem_set_tlv(trial, &tlv); + if (err < 0) + return err; + + len = tlv[1] + sizeof(unsigned int) * 2; + curr = malloc(len); + if (curr == NULL) { + free(tlv); + return -ENOMEM; + } /* * In in-kernel implementation, write and command operations are the - * same for an element set added by userspace applications. Here, I + * same for an element set added by userspace applications. Here, I * use write. */ err = snd_ctl_elem_tlv_write(trial->handle, trial->id, - (const unsigned int *)orig); + (const unsigned int *)tlv); if (err < 0) - return err; + goto end; - err = snd_ctl_elem_tlv_read(trial->handle, trial->id, curr, - sizeof(curr)); + err = snd_ctl_elem_tlv_read(trial->handle, trial->id, curr, len); if (err < 0) - return err; - - if (memcmp(curr, orig, sizeof(orig)) != 0) - return -EIO; + goto end; + if (memcmp(curr, tlv, len) != 0) + err = -EIO; +end: + free(tlv); + free(curr); return 0; } @@ -484,6 +616,8 @@ int main(void) trial.add_elem_set = add_bool_elem_set; trial.check_elem_props = NULL; trial.change_elem_members = change_bool_elem_members; + trial.allocate_elem_set_tlv = + allocate_bool_elem_set_tlv; break; case SND_CTL_ELEM_TYPE_INTEGER: trial.element_count = 900; @@ -495,6 +629,8 @@ int main(void) trial.add_elem_set = add_int_elem_set; trial.check_elem_props = check_int_elem_props; trial.change_elem_members = change_int_elem_members; + trial.allocate_elem_set_tlv = + allocate_int_elem_set_tlv; break; case SND_CTL_ELEM_TYPE_ENUMERATED: trial.element_count = 900; @@ -506,6 +642,7 @@ int main(void) trial.add_elem_set = add_enum_elem_set; trial.check_elem_props = check_enum_elem_props; trial.change_elem_members = change_enum_elem_members; + trial.allocate_elem_set_tlv = NULL; break; case SND_CTL_ELEM_TYPE_BYTES: trial.element_count = 900; @@ -517,6 +654,8 @@ int main(void) trial.add_elem_set = add_bytes_elem_set; trial.check_elem_props = NULL; trial.change_elem_members = change_bytes_elem_members; + trial.allocate_elem_set_tlv = + allocate_bytes_elem_set_tlv; break; case SND_CTL_ELEM_TYPE_IEC958: trial.element_count = 1; @@ -528,6 +667,7 @@ int main(void) trial.add_elem_set = add_iec958_elem_set; trial.check_elem_props = NULL; trial.change_elem_members = change_iec958_elem_members; + trial.allocate_elem_set_tlv = NULL; break; case SND_CTL_ELEM_TYPE_INTEGER64: default: @@ -540,6 +680,8 @@ int main(void) trial.add_elem_set = add_int64_elem_set; trial.check_elem_props = check_int64_elem_props; trial.change_elem_members = change_int64_elem_members; + trial.allocate_elem_set_tlv = + allocate_int64_elem_set_tlv; break; } @@ -589,22 +731,22 @@ int main(void) } /* - * Test an operation to change threshold data of this element set, - * except for IEC958 type. + * Test an operation to change TLV data of this element set, + * except for enumerated and IEC958 type. */ - if (trial.type != SND_CTL_ELEM_TYPE_IEC958) { + if (trial.allocate_elem_set_tlv != NULL) { err = check_tlv(&trial); if (err < 0) { - printf("Fail to change threshold level of an " - "element set with %s type.\n", + printf("Fail to change TLV data of an element " + "set with %s type.\n", snd_ctl_elem_type_name(trial.type)); break; } err = check_event(&trial, SND_CTL_EVENT_MASK_TLV, 1); if (err < 0) { - printf("Fail to check an event to change " - "threshold level of an an element set " - "with %s type.\n", + printf("Fail to check an event to change TLV" + "data of an an element set with %s " + "type.\n", snd_ctl_elem_type_name(trial.type)); break; } -- 2.10.2
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor