From 5efcf32772def5591c79def5c656d2a006afec5b Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Sun, 3 Aug 2003 20:36:53 +0000 Subject: [PATCH] alisp - implemented hctl_elem_read/write and find --- alsalisp/hctl.lisp | 9 +- src/alisp/alisp.c | 16 ++- src/alisp/alisp_local.h | 14 +-- src/alisp/alisp_snd.c | 245 +++++++++++++++++++++++++++++++++++++--- 4 files changed, 256 insertions(+), 28 deletions(-) diff --git a/alsalisp/hctl.lisp b/alsalisp/hctl.lisp index bcf4ec0b..521334b1 100644 --- a/alsalisp/hctl.lisp +++ b/alsalisp/hctl.lisp @@ -13,7 +13,7 @@ (princ "card_get_index test (SI7018): " (acall 'card_get_index "SI7018") "\n") (princ "card_get_index test (ABCD): " (acall 'card_get_index "ABCD") "\n") -(setq hctl (acall 'hctl_open ('default nil))) +(setq hctl (acall 'hctl_open 'default nil)) (if (= (aerror hctl) 0) (progn (princ "open success: " hctl "\n") @@ -30,7 +30,7 @@ ) ) -(setq ctl (acall 'ctl_open ('default nil))) +(setq ctl (acall 'ctl_open 'default nil)) (if (= (aerror ctl) 0) (progn (princ "ctl open success: " ctl "\n") @@ -54,6 +54,11 @@ (progn (setq info (acall 'hctl_elem_info elem)) (princ info "\n") + (setq value (acall 'hctl_elem_read elem)) + (princ value "\n") + (when (equal (cdr (assq "name" (car (cdr (assq "id" (aresult info)))))) "Master Playback Volume") + (princ "write Master: " (acall 'hctl_elem_write elem (20 20)) "\n") + ) (setq elem (acall 'hctl_elem_next elem)) ) ) diff --git a/src/alisp/alisp.c b/src/alisp/alisp.c index 3c41f728..c60265bd 100644 --- a/src/alisp/alisp.c +++ b/src/alisp/alisp.c @@ -35,6 +35,8 @@ #include "alisp.h" #include "alisp_local.h" +#define ALISP_FREE_OBJ_POOL 1000 /* free objects above this pool */ + struct alisp_object alsa_lisp_nil; struct alisp_object alsa_lisp_t; @@ -138,6 +140,8 @@ static struct alisp_object * new_object(struct alisp_instance *instance, int typ p->gc = 1; ++instance->used_objs; + if (instance->used_objs + instance->free_objs > instance->max_objs) + instance->max_objs = instance->used_objs + instance->free_objs; return p; } @@ -778,7 +782,7 @@ static void do_garbage_collect(struct alisp_instance *instance) lisp_debug(instance, "** collecting cons %p", p); free_object(p); - if (instance->free_objs < 1000) { + if (instance->free_objs < ALISP_FREE_OBJ_POOL) { p->next = instance->free_objs_list; instance->free_objs_list = p; ++instance->free_objs; @@ -799,7 +803,7 @@ static void do_garbage_collect(struct alisp_instance *instance) static void garbage_collect(struct alisp_instance *instance) { - if (++instance->gc_id == INT_MAX) + if (++instance->gc_id == 255) instance->gc_id = 1; do_garbage_collect(instance); } @@ -1892,11 +1896,13 @@ static struct alisp_object * F_dump_memory(struct alisp_instance *instance, stru static struct alisp_object * F_stat_memory(struct alisp_instance *instance, struct alisp_object * args ATTRIBUTE_UNUSED) { snd_output_printf(instance->out, "*** Memory stats\n"); - snd_output_printf(instance->out, " used_objs = %i, free_objs = %i, obj_size = %i (total = %i)\n", + snd_output_printf(instance->out, " used_objs = %li, free_objs = %li, max_objs = %li, obj_size = %i (total bytes = %li, max bytes = %li)\n", instance->used_objs, instance->free_objs, + instance->max_objs, sizeof(struct alisp_object), - (instance->used_objs + instance->free_objs) * sizeof(struct alisp_object)); + (instance->used_objs + instance->free_objs) * sizeof(struct alisp_object), + instance->max_objs * sizeof(struct alisp_object)); return &alsa_lisp_nil; } @@ -1967,6 +1973,8 @@ static struct intrinsic intrinsics[] = { { "setf", F_setq }, { "setq", F_setq }, { "str", F_str }, + { "string=", F_equal }, + { "string-equal", F_equal }, { "unless", F_unless }, { "when", F_when }, { "while", F_while }, diff --git a/src/alisp/alisp_local.h b/src/alisp/alisp_local.h index 38fab288..88f49180 100644 --- a/src/alisp/alisp_local.h +++ b/src/alisp/alisp_local.h @@ -41,8 +41,8 @@ enum alisp_objects { }; struct alisp_object { - int type; - int gc; + unsigned char type; + unsigned char gc; union { char *id; char *s; @@ -85,15 +85,13 @@ struct alisp_instance { int token_buffer_max; int thistoken; /* object allocator */ - int free_objs; - int used_objs; + long free_objs; + long used_objs; + long max_objs; struct alisp_object *free_objs_list; struct alisp_object *used_objs_list; /* set object */ struct alisp_object_pair *setobjs_list; /* garbage collect */ - int gc_id; - /* alsa configuration */ - snd_config_t *root; /* configuration root */ - snd_config_t *node; /* result */ + unsigned char gc_id; }; diff --git a/src/alisp/alisp_snd.c b/src/alisp/alisp_snd.c index 4383c0d5..c26c4a32 100644 --- a/src/alisp/alisp_snd.c +++ b/src/alisp/alisp_snd.c @@ -30,6 +30,13 @@ struct acall_table { * helper functions */ +static inline int get_integer(struct alisp_object * obj) +{ + if (obj->type == ALISP_OBJ_INTEGER) + return obj->value.i; + return 0; +} + static inline const void *get_pointer(struct alisp_object * obj) { if (obj->type == ALISP_OBJ_POINTER) @@ -137,6 +144,7 @@ static struct alisp_object * add_cons(struct alisp_instance * instance, struct a return lexpr; } +#if 0 static struct alisp_object * add_cons1(struct alisp_instance * instance, struct alisp_object *lexpr, int cdr, int id, struct alisp_object *obj) { struct alisp_object * p1; @@ -160,6 +168,25 @@ static struct alisp_object * add_cons1(struct alisp_instance * instance, struct p1->value.c.cdr = obj; return lexpr; } +#endif + +static struct alisp_object * add_cons2(struct alisp_instance * instance, struct alisp_object *lexpr, int cdr, struct alisp_object *obj) +{ + struct alisp_object * p1; + + if (lexpr == NULL || obj == NULL) + return NULL; + if (cdr) { + p1 = lexpr->value.c.cdr = new_object(instance, ALISP_OBJ_CONS); + } else { + p1 = lexpr->value.c.car = new_object(instance, ALISP_OBJ_CONS); + } + lexpr = p1; + if (p1 == NULL) + return NULL; + p1->value.c.car = obj; + return lexpr; +} static inline struct alisp_object * new_result(struct alisp_instance * instance, int err) { @@ -281,7 +308,7 @@ static struct alisp_object * FA_int_pp_p(struct alisp_instance * instance, struc prefix1 = "ctl"; else return &alsa_lisp_nil; - args = eval(instance, args); + args = eval(instance, car(args)); handle = (void *)get_ptr(args, prefix1); if (handle == NULL) return &alsa_lisp_nil; @@ -301,7 +328,7 @@ static struct alisp_object * FA_p_p(struct alisp_instance * instance, struct aca prefix1 = "hctl_elem"; else return &alsa_lisp_nil; - args = eval(instance, args); + args = eval(instance, car(args)); handle = (void *)get_ptr(args, item->prefix); if (handle == NULL) return &alsa_lisp_nil; @@ -313,7 +340,7 @@ static struct alisp_object * FA_int_p(struct alisp_instance * instance, struct a { void *handle; - args = eval(instance, args); + args = eval(instance, car(args)); handle = (void *)get_ptr(args, item->prefix); if (handle == NULL) return &alsa_lisp_nil; @@ -324,7 +351,7 @@ static struct alisp_object * FA_int_intp(struct alisp_instance * instance, struc { int val, err; - args = eval(instance, args); + args = eval(instance, car(args)); if (args->type != ALISP_OBJ_INTEGER) return &alsa_lisp_nil; val = args->value.i; @@ -336,7 +363,7 @@ static struct alisp_object * FA_int_str(struct alisp_instance * instance, struct { int err; - args = eval(instance, args); + args = eval(instance, car(args)); if (args->type != ALISP_OBJ_STRING && args->type != ALISP_OBJ_IDENTIFIER) return &alsa_lisp_nil; err = ((snd_int_str_t)item->xfunc)(args->value.s); @@ -348,7 +375,7 @@ static struct alisp_object * FA_int_int_strp(struct alisp_instance * instance, s int err; char *str; - args = eval(instance, args); + args = eval(instance, car(args)); if (args->type != ALISP_OBJ_INTEGER) return &alsa_lisp_nil; err = ((snd_int_int_strp_t)item->xfunc)(args->value.i, &str); @@ -362,7 +389,7 @@ static struct alisp_object * FA_card_info(struct alisp_instance * instance, stru snd_ctl_card_info_t *info; int err; - args = eval(instance, args); + args = eval(instance, car(args)); handle = (snd_ctl_t *)get_ptr(args, item->prefix); if (handle == NULL) return &alsa_lisp_nil; @@ -393,6 +420,55 @@ static struct alisp_object * create_ctl_elem_id(struct alisp_instance * instance return cons; } +static int parse_ctl_elem_id(struct alisp_object * cons, snd_ctl_elem_id_t * id) +{ + struct alisp_object *p1; + const char *xid; + + if (cons == NULL) + return -ENOMEM; + snd_ctl_elem_id_clear(id); + id->numid = 0; + do { + p1 = car(cons); + if (p1->type == ALISP_OBJ_CONS) { + xid = get_string(p1->value.c.car, NULL); + printf("id = '%s'\n", xid); + if (xid == NULL) { + /* noop */ + } else if (!strcmp(xid, "numid")) { + snd_ctl_elem_id_set_numid(id, get_integer(p1->value.c.cdr)); + } else if (!strcmp(xid, "iface")) { + snd_ctl_elem_id_set_interface(id, snd_config_get_ctl_iface_ascii(get_string(p1->value.c.cdr, "0"))); + } else if (!strcmp(xid, "dev")) { + snd_ctl_elem_id_set_device(id, get_integer(p1->value.c.cdr)); + } else if (!strcmp(xid, "subdev")) { + snd_ctl_elem_id_set_subdevice(id, get_integer(p1->value.c.cdr)); + } else if (!strcmp(xid, "name")) { + snd_ctl_elem_id_set_name(id, get_string(p1->value.c.cdr, "?")); + } else if (!strcmp(xid, "index")) { + snd_ctl_elem_id_set_index(id, get_integer(p1->value.c.cdr)); + } + } + cons = cdr(cons); + } while (cons != &alsa_lisp_nil); + return 0; +} + +static struct alisp_object * FA_hctl_find_elem(struct alisp_instance * instance, struct acall_table * item, struct alisp_object * args) +{ + snd_hctl_t *handle; + snd_ctl_elem_id_t *id; + + handle = (snd_hctl_t *)get_ptr(car(args), item->prefix); + if (handle == NULL) + return &alsa_lisp_nil; + snd_ctl_elem_id_alloca(&id); + if (parse_ctl_elem_id(eval(instance, car(cdr(args))), id) < 0) + return &alsa_lisp_nil; + return new_result4(instance, "hctl_elem", snd_hctl_find_elem(handle, id)); +} + static struct alisp_object * FA_hctl_elem_info(struct alisp_instance * instance, struct acall_table * item, struct alisp_object * args) { snd_hctl_elem_t *handle; @@ -402,7 +478,7 @@ static struct alisp_object * FA_hctl_elem_info(struct alisp_instance * instance, snd_ctl_elem_type_t type; int err; - args = eval(instance, args); + args = eval(instance, car(args)); handle = (snd_hctl_elem_t *)get_ptr(args, item->prefix); if (handle == NULL) return &alsa_lisp_nil; @@ -426,26 +502,164 @@ static struct alisp_object * FA_hctl_elem_info(struct alisp_instance * instance, p1 = add_cons(instance, p1, 1, "isowner", new_integer(instance, snd_ctl_elem_info_is_owner(info))); p1 = add_cons(instance, p1, 1, "owner", new_integer(instance, snd_ctl_elem_info_get_owner(info))); p1 = add_cons(instance, p1, 1, "count", new_integer(instance, snd_ctl_elem_info_get_count(info))); - if (type == SND_CTL_ELEM_TYPE_ENUMERATED) { + err = snd_ctl_elem_info_get_dimensions(info); + if (err > 0) { + int idx; + p1 = add_cons(instance, p1, 1, "dimensions", p2 = new_object(instance, ALISP_OBJ_CONS)); + for (idx = 0; idx < err; idx++) + p2 = add_cons2(instance, p2, idx > 0, new_integer(instance, snd_ctl_elem_info_get_dimension(info, idx))); + } + switch (type) { + case SND_CTL_ELEM_TYPE_ENUMERATED: { unsigned int items, item; items = snd_ctl_elem_info_get_items(info); - p1 = add_cons(instance, p1, 1, "items", new_integer(instance, items)); - p1 = add_cons(instance, p1, 1, "inames", p2 = new_object(instance, ALISP_OBJ_CONS)); + p1 = add_cons(instance, p1, 1, "items", p2 = new_object(instance, ALISP_OBJ_CONS)); for (item = 0; item < items; item++) { snd_ctl_elem_info_set_item(info, item); err = snd_hctl_elem_info(handle, info); if (err < 0) { - p2 = add_cons1(instance, p2, item > 0, item, &alsa_lisp_nil); + p2 = add_cons2(instance, p2, item, &alsa_lisp_nil); } else { - p2 = add_cons1(instance, p2, item > 0, item, new_string(instance, snd_ctl_elem_info_get_item_name(info))); + p2 = add_cons2(instance, p2, item, new_string(instance, snd_ctl_elem_info_get_item_name(info))); } } + break; + } + case SND_CTL_ELEM_TYPE_INTEGER: + p1 = add_cons(instance, p1, 1, "min", new_integer(instance, snd_ctl_elem_info_get_min(info))); + p1 = add_cons(instance, p1, 1, "max", new_integer(instance, snd_ctl_elem_info_get_max(info))); + p1 = add_cons(instance, p1, 1, "step", new_integer(instance, snd_ctl_elem_info_get_step(info))); + break; + case SND_CTL_ELEM_TYPE_INTEGER64: + p1 = add_cons(instance, p1, 1, "min64", new_float(instance, snd_ctl_elem_info_get_min64(info))); + p1 = add_cons(instance, p1, 1, "max64", new_float(instance, snd_ctl_elem_info_get_max64(info))); + p1 = add_cons(instance, p1, 1, "step64", new_float(instance, snd_ctl_elem_info_get_step64(info))); + break; + default: + break; } if (p1 == NULL) return NULL; return lexpr; } +static struct alisp_object * FA_hctl_elem_read(struct alisp_instance * instance, struct acall_table * item, struct alisp_object * args) +{ + snd_hctl_elem_t *handle; + struct alisp_object * lexpr, * p1 = NULL, * obj; + snd_ctl_elem_info_t *info; + snd_ctl_elem_value_t *value; + snd_ctl_elem_type_t type; + unsigned int idx, count; + int err; + + args = eval(instance, car(args)); + handle = (snd_hctl_elem_t *)get_ptr(args, item->prefix); + if (handle == NULL) + return &alsa_lisp_nil; + snd_ctl_elem_info_alloca(&info); + snd_ctl_elem_value_alloca(&value); + err = snd_hctl_elem_info(handle, info); + if (err >= 0) + err = snd_hctl_elem_read(handle, value); + lexpr = new_lexpr(instance, err); + if (err < 0) + return lexpr; + type = snd_ctl_elem_info_get_type(info); + count = snd_ctl_elem_info_get_count(info); + if (type == SND_CTL_ELEM_TYPE_IEC958) { + count = sizeof(snd_aes_iec958_t); + type = SND_CTL_ELEM_TYPE_BYTES; + } + for (idx = 0; idx < count; idx++) { + switch (type) { + case SND_CTL_ELEM_TYPE_BOOLEAN: + obj = new_integer(instance, snd_ctl_elem_value_get_boolean(value, idx)); + break; + case SND_CTL_ELEM_TYPE_INTEGER: + obj = new_integer(instance, snd_ctl_elem_value_get_integer(value, idx)); + break; + case SND_CTL_ELEM_TYPE_INTEGER64: + obj = new_integer(instance, snd_ctl_elem_value_get_integer64(value, idx)); + break; + case SND_CTL_ELEM_TYPE_ENUMERATED: + obj = new_integer(instance, snd_ctl_elem_value_get_enumerated(value, idx)); + break; + case SND_CTL_ELEM_TYPE_BYTES: + obj = new_integer(instance, snd_ctl_elem_value_get_byte(value, idx)); + break; + default: + obj = NULL; + break; + } + if (idx == 0) { + p1 = add_cons2(instance, lexpr->value.c.cdr, 0, obj); + } else { + p1 = add_cons2(instance, p1, 1, obj); + } + } + if (p1 == NULL) + return &alsa_lisp_nil; + return lexpr; +} + +static struct alisp_object * FA_hctl_elem_write(struct alisp_instance * instance, struct acall_table * item, struct alisp_object * args) +{ + snd_hctl_elem_t *handle; + struct alisp_object * p1 = NULL, * obj; + snd_ctl_elem_info_t *info; + snd_ctl_elem_value_t *value; + snd_ctl_elem_type_t type; + unsigned int idx, count; + int err; + + p1 = car(cdr(args)); + args = eval(instance, car(args)); + handle = (snd_hctl_elem_t *)get_ptr(args, item->prefix); + if (handle == NULL) + return &alsa_lisp_nil; + snd_ctl_elem_info_alloca(&info); + snd_ctl_elem_value_alloca(&value); + err = snd_hctl_elem_info(handle, info); + if (err < 0) + return new_result(instance, err); + type = snd_ctl_elem_info_get_type(info); + count = snd_ctl_elem_info_get_count(info); + if (type == SND_CTL_ELEM_TYPE_IEC958) { + count = sizeof(snd_aes_iec958_t); + type = SND_CTL_ELEM_TYPE_BYTES; + } + idx = -1; + do { + if (++idx >= count) + break; + obj = car(p1); + switch (type) { + case SND_CTL_ELEM_TYPE_BOOLEAN: + snd_ctl_elem_value_set_boolean(value, idx, get_integer(obj)); + break; + case SND_CTL_ELEM_TYPE_INTEGER: + snd_ctl_elem_value_set_integer(value, idx, get_integer(obj)); + break; + case SND_CTL_ELEM_TYPE_INTEGER64: + snd_ctl_elem_value_set_integer64(value, idx, get_integer(obj)); + break; + case SND_CTL_ELEM_TYPE_ENUMERATED: + snd_ctl_elem_value_set_enumerated(value, idx, get_integer(obj)); + break; + case SND_CTL_ELEM_TYPE_BYTES: + snd_ctl_elem_value_set_byte(value, idx, get_integer(obj)); + break; + default: + obj = NULL; + break; + } + p1 = cdr(p1); + } while (p1 != &alsa_lisp_nil); + err = snd_hctl_elem_write(handle, value); + return new_result(instance, err); +} + /* * main code */ @@ -462,6 +676,9 @@ static struct acall_table acall_table[] = { { "hctl_elem_info", &FA_hctl_elem_info, (void *)&snd_hctl_elem_info, "hctl_elem" }, { "hctl_elem_next", &FA_p_p, (void *)&snd_hctl_elem_next, "hctl_elem" }, { "hctl_elem_prev", &FA_p_p, (void *)&snd_hctl_elem_prev, "hctl_elem" }, + { "hctl_elem_read", &FA_hctl_elem_read, (void *)&snd_hctl_elem_read, "hctl_elem" }, + { "hctl_elem_write", &FA_hctl_elem_write, (void *)&snd_hctl_elem_write, "hctl_elem" }, + { "hctl_find_elem", &FA_hctl_find_elem, (void *)&snd_hctl_find_elem, "hctl" }, { "hctl_first_elem", &FA_p_p, (void *)&snd_hctl_first_elem, "hctl" }, { "hctl_free", &FA_int_p, (void *)&snd_hctl_free, "hctl" }, { "hctl_last_elem", &FA_p_p, (void *)&snd_hctl_last_elem, "hctl" }, @@ -484,7 +701,7 @@ static struct alisp_object * F_acall(struct alisp_instance *instance, struct ali p1 = eval(instance, car(args)); if (p1->type != ALISP_OBJ_IDENTIFIER && p1->type != ALISP_OBJ_STRING) return &alsa_lisp_nil; - p2 = car(cdr(args)); + p2 = cdr(args); key.name = p1->value.s; if ((item = bsearch(&key, acall_table, sizeof acall_table / sizeof acall_table[0], -- 2.47.1