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 in file is parameter for audio DSPs, and it's just passed by UCM/ALSA as raw data. The data type of parameter elements must be byte, and the count must matches driver definition.
src/ucm/main.c +62 -3
@@ -34,6 +34,7 @@#include <ctype.h> #include <stdarg.h> #include <pthread.h> +#include <sys/stat.h> /* * misc
@@ -160,11 +161,65 @@ static int open_ctl(snd_use_case_mgr_t *uc_mgr,return 0 ; } +static int binary_file_parse (snd_ctl_elem_value_t *dst, +snd_ctl_elem_info_t *info, +const char *filepath) +{ +int err =0 ; +int fd; +struct stat st; +size_t sz; +ssize_t sz_read; +char *res; +snd_ctl_elem_type_t type; +unsigned int idx, count; + + type =snd_ctl_elem_info_get_type (info); +if (type !=SND_CTL_ELEM_TYPE_BYTES ) { +uc_error ("only support byte type!" ); + err = -EINVAL ; +return err; + } + fd =open (filepath,O_RDONLY ); +if (fd <0 ) { + err = -errno; +return err; + } +if (stat (filepath, &st) ==-1 ) { + err = -errno; + goto __fail; + } + sz = st.st_size; + count =snd_ctl_elem_info_get_count (info); +if (sz != count || sz >sizeof (dst->value.bytes)) { +uc_error ("invalid parameter size %d!" , sz); + err = -EINVAL ; + goto __fail; + } + res =malloc (sz); +if (res ==NULL ) { + err = -ENOMEM ; + goto __fail; + } + sz_read =read (fd, res, sz); +if (sz_read <0 || (size_t )sz_read != sz) { + err = -errno; + goto __fail_read; + } +for (idx =0 ; idx < sz; idx++) +snd_ctl_elem_value_set_byte (dst, idx, *(res + idx)); + __fail_read: +free (res); + __fail: +close (fd); +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,unsigned int type) {const char *pos;int err;
@@ -194,7 +249,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 (type ==SEQUENCE_ELEMENT_TYPE_CSET_BIN_FILE ) + err =binary_file_parse (value, info, 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 +297,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 +333,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->type);if (err <0 ) {uc_error ("unable to execute cset '%s'\n" , s->data.cset); goto __fail;
src/ucm/parser.c +10 -0
@@ -306,6 +306,16 @@ 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 ; + 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 +1 -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;
Signature · 1 line
2.1.0
Takashi Iwai
AppliedAt Thu, 22 Jan 2015 09:32:47 +0800,
Quoted 8 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>"
Quoted 7 lines
where "cset-bin-file" is a newly added keyword alongside of "cset", to indicate cset with binary data in file.
The binary data in file is parameter for audio DSPs, and it's just passed by UCM/ALSA as raw data. The data type of parameter elements must be byte, and the count must matches driver definition.Signed-off-by Lu, Han <[email protected]>
Applied, thanks.
Takashi
Quoted 145 lines
src/ucm/main.c +62
-3@@ -34,6 +34,7 @@#include <ctype.h> #include <stdarg.h> #include <pthread.h> +#include <sys/stat.h> /* * misc @@ -160,11 +161,65 @@ static int open_ctl(snd_use_case_mgr_t *uc_mgr,return 0 ; } +static int binary_file_parse (snd_ctl_elem_value_t *dst, +snd_ctl_elem_info_t *info, +const char *filepath) +{ +int err =0 ; +int fd; +struct stat st; +size_t sz; +ssize_t sz_read; +char *res; +snd_ctl_elem_type_t type; +unsigned int idx, count; + + type =snd_ctl_elem_info_get_type (info); +if (type !=SND_CTL_ELEM_TYPE_BYTES ) { +uc_error ("only support byte type!" ); + err = -EINVAL ; +return err; + } + fd =open (filepath,O_RDONLY ); +if (fd <0 ) { + err = -errno; +return err; + } +if (stat (filepath, &st) ==-1 ) { + err = -errno; + goto __fail; + } + sz = st.st_size; + count =snd_ctl_elem_info_get_count (info); +if (sz != count || sz >sizeof (dst->value.bytes)) { +uc_error ("invalid parameter size %d!" , sz); + err = -EINVAL ; + goto __fail; + } + res =malloc (sz); +if (res ==NULL ) { + err = -ENOMEM ; + goto __fail; + } + sz_read =read (fd, res, sz); +if (sz_read <0 || (size_t )sz_read != sz) { + err = -errno; + goto __fail_read; + } +for (idx =0 ; idx < sz; idx++) +snd_ctl_elem_value_set_byte (dst, idx, *(res + idx)); + __fail_read: +free (res); + __fail: +close (fd); +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,unsigned int type) {const char *pos;int err;@@ -194,7 +249,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 (type ==SEQUENCE_ELEMENT_TYPE_CSET_BIN_FILE ) + err =binary_file_parse (value, info, 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 +297,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 +333,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->type);if (err <0 ) {uc_error ("unable to execute cset '%s'\n" , s->data.cset); goto __fail;src/ucm/parser.c +10
-0@@ -306,6 +306,16 @@ 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 ; + 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 +1
-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;Signature · 1 line
2.1.0