ucm: add binary configure file parse
PATCH 1/1 ucm: add binary configure file parse
From: "Lu, Han" <[email protected]>
with cset command, UCM set kcontrol parameters directly:
cset "name='<KCONTROL_NAME>' 1<,2,3,...>"
This patch enables UCM to set kcontrol with parameters from
configure file:
cset-bin-file "name='<KCONTROL_NAME>' <path/to/file>"where "cset-bin-file" is a newly added keyword alongside of "cset", to indicate cset with binary data in file.
The binary data is parameter only for audio DSPs, and it's just passed by UCM/ALSA as raw data. The data type of the parameter element must be byte, and the maxim number of parameter elements is 512 (the maxim value that struct snd_ctl_elem_value can hold).
src/ucm/main.c +41 -3
@@ -160,11 +160,45 @@ static int open_ctl(snd_use_case_mgr_t *uc_mgr,return 0 ; } +static int binary_file_parse (snd_ctl_elem_value_t *dst, +const char *filepath) +{ +int err =0 ; +FILE *in; +long len; +char *res; +unsigned int idx; + + in =fopen (filepath,"r" ); +if (!in) { + err = -errno; + goto __fail; + } +fseek (in,0L ,SEEK_END ); + len =ftell (in); +rewind (in); +if (len >512 ) + len =512 ; + res =calloc (1 , (size_t )len); +if (res ==NULL ) { + err = -ENOMEM ; + goto __fail_nomem; + } +fread (res, (size_t )len,1 , in); +for (idx =0 ; idx < len; idx++) +snd_ctl_elem_value_set_byte (dst, idx, *(res + idx)); +free (res); + __fail_nomem: +fclose (in); + __fail: +return err; +} +extern int __snd_ctl_ascii_elem_id_parse (snd_ctl_elem_id_t *dst,const char *str,const char **ret_ptr); -static int execute_cset (snd_ctl_t *ctl,const char *cset) +static int execute_cset (snd_ctl_t *ctl,const char *cset,int isbin) {const char *pos;int err;
@@ -194,7 +228,10 @@ static int execute_cset(snd_ctl_t *ctl, const char *cset) err =snd_ctl_elem_info (ctl, info);if (err <0 ) goto __fail; - err =snd_ctl_ascii_value_parse (ctl, value, info, pos); +if (isbin) + err =binary_file_parse (value, pos); +else + err =snd_ctl_ascii_value_parse (ctl, value, info, pos);if (err <0 ) goto __fail; err =snd_ctl_elem_write (ctl, value);
@@ -239,6 +276,7 @@ static int execute_sequence(snd_use_case_mgr_t *uc_mgr, goto __fail_nomem;break ;case SEQUENCE_ELEMENT_TYPE_CSET : +case SEQUENCE_ELEMENT_TYPE_CSET_BIN_FILE :if (cdev ==NULL ) {const char *cdev1 =NULL , *cdev2 =NULL ; err = get_value3(&cdev1, "PlaybackCTL",
@@ -274,7 +312,7 @@ static int execute_sequence(snd_use_case_mgr_t *uc_mgr, goto __fail; } } - err =execute_cset (ctl, s->data.cset); + err =execute_cset (ctl, s->data.cset, s->isbin);if (err <0 ) {uc_error ("unable to execute cset '%s'\n" , s->data.cset); goto __fail;
src/ucm/parser.c +11 -0
@@ -306,6 +306,17 @@ static int parse_sequence(snd_use_case_mgr_t *uc_mgr ATTRIBUTE_UNUSED,continue ; } +if (strcmp (cmd,"cset-bin-file" ) ==0 ) { + curr->type =SEQUENCE_ELEMENT_TYPE_CSET_BIN_FILE ; + curr->isbin =1 ; + err =parse_string (n, &curr->data.cset); +if (err <0 ) { +uc_error ("error: cset-bin-file requires a string!" ); +return err; + } +continue ; + } +if (strcmp (cmd,"usleep" ) ==0 ) { curr->type =SEQUENCE_ELEMENT_TYPE_SLEEP ; err =snd_config_get_integer (n, &curr->data.sleep);
src/ucm/ucm_local.h +2 -0
@@ -47,6 +47,7 @@#define SEQUENCE_ELEMENT_TYPE_CSET 2#define SEQUENCE_ELEMENT_TYPE_SLEEP 3#define SEQUENCE_ELEMENT_TYPE_EXEC 4 +#define SEQUENCE_ELEMENT_TYPE_CSET_BIN_FILE 5struct ucm_value {struct list_head list;
@@ -63,6 +64,7 @@ struct sequence_element {char *cset;char *exec; } data; +int isbin;/* Indicate cset to handle binary or ascii array */ };/*
Signature · 1 line
1.9.1
At Thu, 15 Jan 2015 09:26:28 +0800,
Quoted 32 lines · [email protected] wrote:
From: "Lu, Han" <[email protected]>
with cset command, UCM set kcontrol parameters directly:
cset "name='<KCONTROL_NAME>' 1<,2,3,...>" This patch enables UCM to set kcontrol with parameters from configure file: cset-bin-file "name='<KCONTROL_NAME>' <path/to/file>"where "cset-bin-file" is a newly added keyword alongside of "cset", to indicate cset with binary data in file.
The binary data is parameter only for audio DSPs, and it's just passed by UCM/ALSA as raw data. The data type of the parameter element must be byte, and the maxim number of parameter elements is 512 (the maxim value that structsnd_ctl_elem_valuecan hold).Signed-off-by Lu, Han <[email protected]>src/ucm/main.c +7
-0@@ -160,11 +160,45 @@ static int open_ctl(snd_use_case_mgr_t *uc_mgr,return 0 ; } +static int binary_file_parse (snd_ctl_elem_value_t *dst, +const char *filepath) +{ +int err =0 ; +FILE *in; +long len; +char *res;
src/ucm/main.c static int open_ctl(snd_use_case_mgr_t *uc_mgr, · line 179
Quoted 10 lines
src/ucm/main.c +10
-0+unsigned int idx; + + in =fopen (filepath,"r" ); +if (!in) { + err = -errno; + goto __fail; + } +fseek (in,0L ,SEEK_END ); + len =ftell (in); +rewind (in);
There is a better way to identify the length of a file. Also, for reading a file as a chunk, no need to use the buffered access.
src/ucm/main.c static int open_ctl(snd_use_case_mgr_t *uc_mgr, · line 189
Quoted 10 lines
src/ucm/main.c +10
-0+if (len >512 ) + len =512 ; + res =calloc (1 , (size_t )len); +if (res ==NULL ) { + err = -ENOMEM ; + goto __fail_nomem; + } +fread (res, (size_t )len,1 , in); +for (idx =0 ; idx < len; idx++) +snd_ctl_elem_value_set_byte (dst, idx, *(res + idx));
What if the ctl element isn't a binary type?
Quoted 37 lines
src/ucm/main.c +13
-2+free (res); + __fail_nomem: +fclose (in); + __fail: +return err; +} +extern int __snd_ctl_ascii_elem_id_parse (snd_ctl_elem_id_t *dst,const char *str,const char **ret_ptr); -static int execute_cset (snd_ctl_t *ctl,const char *cset) +static int execute_cset (snd_ctl_t *ctl,const char *cset,int isbin) {const char *pos;int err;@@ -194,7 +228,10 @@ static int execute_cset(snd_ctl_t *ctl, const char *cset) err =snd_ctl_elem_info (ctl, info);if (err <0 ) goto __fail; - err =snd_ctl_ascii_value_parse (ctl, value, info, pos); +if (isbin) + err =binary_file_parse (value, pos); +else + err =snd_ctl_ascii_value_parse (ctl, value, info, pos);if (err <0 ) goto __fail; err =snd_ctl_elem_write (ctl, value);@@ -239,6 +276,7 @@ static int execute_sequence(snd_use_case_mgr_t *uc_mgr, goto __fail_nomem;break ;case SEQUENCE_ELEMENT_TYPE_CSET : +case SEQUENCE_ELEMENT_TYPE_CSET_BIN_FILE :if (cdev ==NULL ) {const char *cdev1 =NULL , *cdev2 =NULL ; err = get_value3(&cdev1, "PlaybackCTL",
src/ucm/main.c static int execute_sequence(snd_use_case_mgr_t *uc_mgr, · line 315
Quoted 5 lines
src/ucm/main.c +1
-1@@ -274,7 +312,7 @@ static int execute_sequence(snd_use_case_mgr_t *uc_mgr, goto __fail; } } - err =execute_cset (ctl, s->data.cset); + err =execute_cset (ctl, s->data.cset, s->isbin);
isbin doesn't have to be a struct member at all since it's referred only here can be identified via s->type.
Takashi
Quoted 48 lines
src/ucm/main.c +0
-0if (err <0 ) {uc_error ("unable to execute cset '%s'\n" , s->data.cset); goto __fail;src/ucm/parser.c +11
-0@@ -306,6 +306,17 @@ static int parse_sequence(snd_use_case_mgr_t *uc_mgr ATTRIBUTE_UNUSED,continue ; } +if (strcmp (cmd,"cset-bin-file" ) ==0 ) { + curr->type =SEQUENCE_ELEMENT_TYPE_CSET_BIN_FILE ; + curr->isbin =1 ; + err =parse_string (n, &curr->data.cset); +if (err <0 ) { +uc_error ("error: cset-bin-file requires a string!" ); +return err; + } +continue ; + } +if (strcmp (cmd,"usleep" ) ==0 ) { curr->type =SEQUENCE_ELEMENT_TYPE_SLEEP ; err =snd_config_get_integer (n, &curr->data.sleep);src/ucm/ucm_local.h +2
-0@@ -47,6 +47,7 @@#define SEQUENCE_ELEMENT_TYPE_CSET 2#define SEQUENCE_ELEMENT_TYPE_SLEEP 3#define SEQUENCE_ELEMENT_TYPE_EXEC 4 +#define SEQUENCE_ELEMENT_TYPE_CSET_BIN_FILE 5struct ucm_value {struct list_head list;@@ -63,6 +64,7 @@ struct sequence_element {char *cset;char *exec; } data; +int isbin;/* Indicate cset to handle binary or ascii array */ };/* Signature · 1 line
1.9.1