Blame src/alisp/alisp_snd.c

Packit Service db8eaa
/*
Packit Service db8eaa
 *  ALSA lisp implementation - sound related commands
Packit Service db8eaa
 *  Copyright (c) 2003 by Jaroslav Kysela <perex@perex.cz>
Packit Service db8eaa
 *
Packit Service db8eaa
 *
Packit Service db8eaa
 *   This library is free software; you can redistribute it and/or modify
Packit Service db8eaa
 *   it under the terms of the GNU Lesser General Public License as
Packit Service db8eaa
 *   published by the Free Software Foundation; either version 2.1 of
Packit Service db8eaa
 *   the License, or (at your option) any later version.
Packit Service db8eaa
 *
Packit Service db8eaa
 *   This program is distributed in the hope that it will be useful,
Packit Service db8eaa
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service db8eaa
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service db8eaa
 *   GNU Lesser General Public License for more details.
Packit Service db8eaa
 *
Packit Service db8eaa
 *   You should have received a copy of the GNU Lesser General Public
Packit Service db8eaa
 *   License along with this library; if not, write to the Free Software
Packit Service db8eaa
 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
Packit Service db8eaa
 *
Packit Service db8eaa
 */
Packit Service db8eaa
Packit Service db8eaa
#include "../control/control_local.h"
Packit Service db8eaa
Packit Service db8eaa
struct acall_table {
Packit Service db8eaa
	const char *name;
Packit Service db8eaa
	struct alisp_object * (*func) (struct alisp_instance *instance, struct acall_table * item, struct alisp_object * args);
Packit Service db8eaa
	void * xfunc;
Packit Service db8eaa
	const char *prefix;
Packit Service db8eaa
};
Packit Service db8eaa
Packit Service db8eaa
/*
Packit Service db8eaa
 *  helper functions
Packit Service db8eaa
 */
Packit Service db8eaa
Packit Service db8eaa
static inline int get_integer(struct alisp_object * obj)
Packit Service db8eaa
{
Packit Service db8eaa
	if (alisp_compare_type(obj, ALISP_OBJ_INTEGER))
Packit Service db8eaa
		return obj->value.i;
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static inline const void *get_pointer(struct alisp_object * obj)
Packit Service db8eaa
{
Packit Service db8eaa
	if (alisp_compare_type(obj, ALISP_OBJ_POINTER))
Packit Service db8eaa
		return obj->value.ptr;
Packit Service db8eaa
	return NULL;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static const char *get_string(struct alisp_object * obj, const char * deflt)
Packit Service db8eaa
{
Packit Service db8eaa
	if (obj == &alsa_lisp_t)
Packit Service db8eaa
		return "true";
Packit Service db8eaa
	if (alisp_compare_type(obj, ALISP_OBJ_STRING) ||
Packit Service db8eaa
	    alisp_compare_type(obj, ALISP_OBJ_IDENTIFIER))
Packit Service db8eaa
		return obj->value.s;
Packit Service db8eaa
	return deflt;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
struct flags {
Packit Service db8eaa
	const char *key;
Packit Service db8eaa
	unsigned int mask;
Packit Service db8eaa
}; 
Packit Service db8eaa
Packit Service db8eaa
static unsigned int get_flags(struct alisp_instance * instance,
Packit Service db8eaa
			      struct alisp_object * obj,
Packit Service db8eaa
			      const struct flags * flags,
Packit Service db8eaa
			      unsigned int deflt)
Packit Service db8eaa
{
Packit Service db8eaa
	const char *key;
Packit Service db8eaa
	int invert;
Packit Service db8eaa
	unsigned int result;
Packit Service db8eaa
	const struct flags *ptr;
Packit Service db8eaa
	struct alisp_object *n;
Packit Service db8eaa
Packit Service db8eaa
	if (obj == &alsa_lisp_nil)
Packit Service db8eaa
		return deflt;
Packit Service db8eaa
	result = deflt;
Packit Service db8eaa
	do {
Packit Service db8eaa
		key = get_string(obj, NULL);
Packit Service db8eaa
		if (key) {
Packit Service db8eaa
			invert = key[0] == '!';
Packit Service db8eaa
			key += invert;
Packit Service db8eaa
			ptr = flags;
Packit Service db8eaa
			while (ptr->key) {
Packit Service db8eaa
				if (!strcmp(ptr->key, key)) {
Packit Service db8eaa
					if (invert)
Packit Service db8eaa
						result &= ~ptr->mask;
Packit Service db8eaa
					else
Packit Service db8eaa
						result |= ptr->mask;
Packit Service db8eaa
					break;
Packit Service db8eaa
				}
Packit Service db8eaa
				ptr++;
Packit Service db8eaa
			}
Packit Service db8eaa
		}
Packit Service db8eaa
		delete_tree(instance, car(obj));
Packit Service db8eaa
		obj = cdr(n = obj);
Packit Service db8eaa
		delete_object(instance, n);
Packit Service db8eaa
	} while (obj != &alsa_lisp_nil);
Packit Service db8eaa
	return result;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static const void *get_ptr(struct alisp_instance * instance,
Packit Service db8eaa
			   struct alisp_object * obj,
Packit Service db8eaa
			   const char *_ptr_id)
Packit Service db8eaa
{
Packit Service db8eaa
	const char *ptr_id;
Packit Service db8eaa
	const void *ptr;
Packit Service db8eaa
	
Packit Service db8eaa
	ptr_id = get_string(car(obj), NULL);
Packit Service db8eaa
	if (ptr_id == NULL) {
Packit Service db8eaa
		delete_tree(instance, obj);
Packit Service db8eaa
		return NULL;
Packit Service db8eaa
	}
Packit Service db8eaa
	if (strcmp(ptr_id, _ptr_id)) {
Packit Service db8eaa
		delete_tree(instance, obj);
Packit Service db8eaa
		return NULL;
Packit Service db8eaa
	}
Packit Service db8eaa
	ptr = get_pointer(cdr(obj));
Packit Service db8eaa
	delete_tree(instance, obj);
Packit Service db8eaa
	return ptr;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static struct alisp_object * new_lexpr(struct alisp_instance * instance, int err)
Packit Service db8eaa
{
Packit Service db8eaa
	struct alisp_object * lexpr;
Packit Service db8eaa
Packit Service db8eaa
	lexpr = new_object(instance, ALISP_OBJ_CONS);
Packit Service db8eaa
	if (lexpr == NULL)
Packit Service db8eaa
		return NULL;
Packit Service db8eaa
	lexpr->value.c.car = new_integer(instance, err);
Packit Service db8eaa
	if (lexpr->value.c.car == NULL) {
Packit Service db8eaa
		delete_object(instance, lexpr);
Packit Service db8eaa
		return NULL;
Packit Service db8eaa
	}
Packit Service db8eaa
	lexpr->value.c.cdr = new_object(instance, ALISP_OBJ_CONS);
Packit Service db8eaa
	if (lexpr->value.c.cdr == NULL) {
Packit Service db8eaa
		delete_object(instance, lexpr->value.c.car);
Packit Service db8eaa
		delete_object(instance, lexpr);
Packit Service db8eaa
		return NULL;
Packit Service db8eaa
	}
Packit Service db8eaa
	return lexpr;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static struct alisp_object * add_cons(struct alisp_instance * instance,
Packit Service db8eaa
				      struct alisp_object *lexpr,
Packit Service db8eaa
				      int cdr, const char *id,
Packit Service db8eaa
				      struct alisp_object *obj)
Packit Service db8eaa
{
Packit Service db8eaa
	struct alisp_object * p1, * p2;
Packit Service db8eaa
Packit Service db8eaa
	if (lexpr == NULL || obj == NULL) {
Packit Service db8eaa
		delete_tree(instance, obj);
Packit Service db8eaa
		return NULL;
Packit Service db8eaa
	}
Packit Service db8eaa
	if (cdr) {
Packit Service db8eaa
		p1 = lexpr->value.c.cdr = new_object(instance, ALISP_OBJ_CONS);
Packit Service db8eaa
	} else {
Packit Service db8eaa
		p1 = lexpr->value.c.car = new_object(instance, ALISP_OBJ_CONS);
Packit Service db8eaa
	}
Packit Service db8eaa
	lexpr = p1;
Packit Service db8eaa
	if (p1 == NULL) {
Packit Service db8eaa
		delete_tree(instance, obj);
Packit Service db8eaa
		return NULL;
Packit Service db8eaa
	}
Packit Service db8eaa
	p1->value.c.car = new_object(instance, ALISP_OBJ_CONS);
Packit Service db8eaa
	if ((p2 = p1->value.c.car) == NULL)
Packit Service db8eaa
		goto __err;
Packit Service db8eaa
	p2->value.c.car = new_string(instance, id);
Packit Service db8eaa
	if (p2->value.c.car == NULL) {
Packit Service db8eaa
	      __err:
Packit Service db8eaa
		if (cdr)
Packit Service db8eaa
			lexpr->value.c.cdr = NULL;
Packit Service db8eaa
		else
Packit Service db8eaa
			lexpr->value.c.car = NULL;
Packit Service db8eaa
		delete_tree(instance, p1);
Packit Service db8eaa
		delete_tree(instance, obj);
Packit Service db8eaa
		return NULL;
Packit Service db8eaa
	}
Packit Service db8eaa
	p2->value.c.cdr = obj;
Packit Service db8eaa
	return lexpr;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static struct alisp_object * add_cons2(struct alisp_instance * instance,
Packit Service db8eaa
				       struct alisp_object *lexpr,
Packit Service db8eaa
				       int cdr, struct alisp_object *obj)
Packit Service db8eaa
{
Packit Service db8eaa
	struct alisp_object * p1;
Packit Service db8eaa
Packit Service db8eaa
	if (lexpr == NULL || obj == NULL) {
Packit Service db8eaa
		delete_tree(instance, obj);
Packit Service db8eaa
		return NULL;
Packit Service db8eaa
	}
Packit Service db8eaa
	if (cdr) {
Packit Service db8eaa
		p1 = lexpr->value.c.cdr = new_object(instance, ALISP_OBJ_CONS);
Packit Service db8eaa
	} else {
Packit Service db8eaa
		p1 = lexpr->value.c.car = new_object(instance, ALISP_OBJ_CONS);
Packit Service db8eaa
	}
Packit Service db8eaa
	lexpr = p1;
Packit Service db8eaa
	if (p1 == NULL) {
Packit Service db8eaa
		delete_tree(instance, obj);
Packit Service db8eaa
		return NULL;
Packit Service db8eaa
	}
Packit Service db8eaa
	p1->value.c.car = obj;
Packit Service db8eaa
	return lexpr;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static struct alisp_object * new_result1(struct alisp_instance * instance,
Packit Service db8eaa
					 int err, const char *ptr_id, void *ptr)
Packit Service db8eaa
{
Packit Service db8eaa
	struct alisp_object * lexpr, * p1;
Packit Service db8eaa
Packit Service db8eaa
	if (err < 0)
Packit Service db8eaa
		ptr = NULL;
Packit Service db8eaa
	lexpr = new_object(instance, ALISP_OBJ_CONS);
Packit Service db8eaa
	if (lexpr == NULL)
Packit Service db8eaa
		return NULL;
Packit Service db8eaa
	lexpr->value.c.car = new_integer(instance, err);
Packit Service db8eaa
	if (lexpr->value.c.car == NULL) {
Packit Service db8eaa
		delete_object(instance, lexpr);
Packit Service db8eaa
		return NULL;
Packit Service db8eaa
	}
Packit Service db8eaa
	p1 = add_cons(instance, lexpr, 1, ptr_id, new_pointer(instance, ptr));
Packit Service db8eaa
	if (p1 == NULL) {
Packit Service db8eaa
		delete_object(instance, lexpr);
Packit Service db8eaa
		return NULL;
Packit Service db8eaa
	}
Packit Service db8eaa
	return lexpr;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static struct alisp_object * new_result2(struct alisp_instance * instance,
Packit Service db8eaa
					 int err, int val)
Packit Service db8eaa
{
Packit Service db8eaa
	struct alisp_object * lexpr, * p1;
Packit Service db8eaa
Packit Service db8eaa
	if (err < 0)
Packit Service db8eaa
		val = 0;
Packit Service db8eaa
	lexpr = new_lexpr(instance, err);
Packit Service db8eaa
	if (lexpr == NULL)
Packit Service db8eaa
		return NULL;
Packit Service db8eaa
	p1 = lexpr->value.c.cdr;
Packit Service db8eaa
	p1->value.c.car = new_integer(instance, val);
Packit Service db8eaa
	if (p1->value.c.car == NULL) {
Packit Service db8eaa
		delete_object(instance, lexpr);
Packit Service db8eaa
		return NULL;
Packit Service db8eaa
	}
Packit Service db8eaa
	return lexpr;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static struct alisp_object * new_result3(struct alisp_instance * instance,
Packit Service db8eaa
					 int err, const char *str)
Packit Service db8eaa
{
Packit Service db8eaa
	struct alisp_object * lexpr, * p1;
Packit Service db8eaa
Packit Service db8eaa
	if (err < 0)
Packit Service db8eaa
		str = "";
Packit Service db8eaa
	lexpr = new_lexpr(instance, err);
Packit Service db8eaa
	if (lexpr == NULL)
Packit Service db8eaa
		return NULL;
Packit Service db8eaa
	p1 = lexpr->value.c.cdr;
Packit Service db8eaa
	p1->value.c.car = new_string(instance, str);
Packit Service db8eaa
	if (p1->value.c.car == NULL) {
Packit Service db8eaa
		delete_object(instance, lexpr);
Packit Service db8eaa
		return NULL;
Packit Service db8eaa
	}
Packit Service db8eaa
	return lexpr;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
/*
Packit Service db8eaa
 *  macros
Packit Service db8eaa
 */
Packit Service db8eaa
Packit Service db8eaa
/*
Packit Service db8eaa
 *  HCTL functions
Packit Service db8eaa
 */
Packit Service db8eaa
Packit Service db8eaa
typedef int (*snd_int_pp_strp_int_t)(void **rctl, const char *name, int mode);
Packit Service db8eaa
typedef int (*snd_int_pp_p_t)(void **rctl, void *handle);
Packit Service db8eaa
typedef int (*snd_int_p_t)(void *rctl);
Packit Service db8eaa
typedef char * (*snd_str_p_t)(void *rctl);
Packit Service db8eaa
typedef int (*snd_int_intp_t)(int *val);
Packit Service db8eaa
typedef int (*snd_int_str_t)(const char *str);
Packit Service db8eaa
typedef int (*snd_int_int_strp_t)(int val, char **str);
Packit Service db8eaa
typedef void *(*snd_p_p_t)(void *handle);
Packit Service db8eaa
Packit Service db8eaa
static struct alisp_object * FA_int_pp_strp_int(struct alisp_instance * instance, struct acall_table * item, struct alisp_object * args)
Packit Service db8eaa
{
Packit Service db8eaa
	const char *name;
Packit Service db8eaa
	int err, mode;
Packit Service db8eaa
	void *handle;
Packit Service db8eaa
	struct alisp_object *p1, *p2;
Packit Service db8eaa
	static const struct flags flags[] = {
Packit Service db8eaa
		{ "nonblock", SND_CTL_NONBLOCK },
Packit Service db8eaa
		{ "async", SND_CTL_ASYNC },
Packit Service db8eaa
		{ "readonly", SND_CTL_READONLY },
Packit Service db8eaa
		{ NULL, 0 }
Packit Service db8eaa
	};
Packit Service db8eaa
Packit Service db8eaa
	name = get_string(p1 = eval(instance, car(args)), NULL);
Packit Service db8eaa
	if (name == NULL)
Packit Service db8eaa
		return &alsa_lisp_nil;
Packit Service db8eaa
	mode = get_flags(instance, p2 = eval(instance, car(cdr(args))), flags, 0);
Packit Service db8eaa
	delete_tree(instance, cdr(cdr(args)));
Packit Service db8eaa
	delete_object(instance, cdr(args));
Packit Service db8eaa
	delete_object(instance, args);
Packit Service db8eaa
	delete_tree(instance, p2);
Packit Service db8eaa
	err = ((snd_int_pp_strp_int_t)item->xfunc)(&handle, name, mode);
Packit Service db8eaa
	delete_tree(instance, p1);
Packit Service db8eaa
	return new_result1(instance, err, item->prefix, handle);
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static struct alisp_object * FA_int_pp_p(struct alisp_instance * instance, struct acall_table * item, struct alisp_object * args)
Packit Service db8eaa
{
Packit Service db8eaa
	int err;
Packit Service db8eaa
	void *handle;
Packit Service db8eaa
	const char *prefix1;
Packit Service db8eaa
	struct alisp_object *p1;
Packit Service db8eaa
Packit Service db8eaa
	if (item->xfunc == &snd_hctl_open_ctl)
Packit Service db8eaa
		prefix1 = "ctl";
Packit Service db8eaa
	else {
Packit Service db8eaa
		delete_tree(instance, args);
Packit Service db8eaa
		return &alsa_lisp_nil;
Packit Service db8eaa
	}
Packit Service db8eaa
	p1 = eval(instance, car(args));
Packit Service db8eaa
	delete_tree(instance, cdr(args));
Packit Service db8eaa
	delete_object(instance, args);
Packit Service db8eaa
	handle = (void *)get_ptr(instance, p1, prefix1);
Packit Service db8eaa
	if (handle == NULL)
Packit Service db8eaa
		return &alsa_lisp_nil;
Packit Service db8eaa
	err = ((snd_int_pp_p_t)item->xfunc)(&handle, handle);
Packit Service db8eaa
	return new_result1(instance, err, item->prefix, handle);
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static struct alisp_object * FA_p_p(struct alisp_instance * instance, struct acall_table * item, struct alisp_object * args)
Packit Service db8eaa
{
Packit Service db8eaa
	void *handle;
Packit Service db8eaa
	const char *prefix1;
Packit Service db8eaa
	struct alisp_object * p1;
Packit Service db8eaa
Packit Service db8eaa
	if (item->xfunc == &snd_hctl_first_elem ||
Packit Service db8eaa
	    item->xfunc == &snd_hctl_last_elem ||
Packit Service db8eaa
	    item->xfunc == &snd_hctl_elem_next ||
Packit Service db8eaa
	    item->xfunc == &snd_hctl_elem_prev)
Packit Service db8eaa
		prefix1 = "hctl_elem";
Packit Service db8eaa
	else if (item->xfunc == &snd_hctl_ctl)
Packit Service db8eaa
		prefix1 = "ctl";
Packit Service db8eaa
	else {
Packit Service db8eaa
		delete_tree(instance, args);
Packit Service db8eaa
		return &alsa_lisp_nil;
Packit Service db8eaa
	}
Packit Service db8eaa
	p1 = eval(instance, car(args));
Packit Service db8eaa
	delete_tree(instance, cdr(args));
Packit Service db8eaa
	delete_object(instance, args);
Packit Service db8eaa
	handle = (void *)get_ptr(instance, p1, item->prefix);
Packit Service db8eaa
	if (handle == NULL)
Packit Service db8eaa
		return &alsa_lisp_nil;
Packit Service db8eaa
	handle = ((snd_p_p_t)item->xfunc)(handle);
Packit Service db8eaa
	return new_cons_pointer(instance, prefix1, handle);
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static struct alisp_object * FA_int_p(struct alisp_instance * instance, struct acall_table * item, struct alisp_object * args)
Packit Service db8eaa
{
Packit Service db8eaa
	void *handle;
Packit Service db8eaa
	struct alisp_object * p1;
Packit Service db8eaa
Packit Service db8eaa
	p1 = eval(instance, car(args));
Packit Service db8eaa
	delete_tree(instance, cdr(args));
Packit Service db8eaa
	delete_object(instance, args);
Packit Service db8eaa
	handle = (void *)get_ptr(instance, p1, item->prefix);
Packit Service db8eaa
	if (handle == NULL)
Packit Service db8eaa
		return &alsa_lisp_nil;
Packit Service db8eaa
	return new_integer(instance, ((snd_int_p_t)item->xfunc)(handle));
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static struct alisp_object * FA_str_p(struct alisp_instance * instance, struct acall_table * item, struct alisp_object * args)
Packit Service db8eaa
{
Packit Service db8eaa
	void *handle;
Packit Service db8eaa
	struct alisp_object * p1;
Packit Service db8eaa
Packit Service db8eaa
	p1 = eval(instance, car(args));
Packit Service db8eaa
	delete_tree(instance, cdr(args));
Packit Service db8eaa
	delete_object(instance, args);
Packit Service db8eaa
	handle = (void *)get_ptr(instance, p1, item->prefix);
Packit Service db8eaa
	if (handle == NULL)
Packit Service db8eaa
		return &alsa_lisp_nil;
Packit Service db8eaa
	return new_string(instance, ((snd_str_p_t)item->xfunc)(handle));
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static struct alisp_object * FA_int_intp(struct alisp_instance * instance, struct acall_table * item, struct alisp_object * args)
Packit Service db8eaa
{
Packit Service db8eaa
	int val, err;
Packit Service db8eaa
	struct alisp_object * p1;
Packit Service db8eaa
Packit Service db8eaa
	p1 = eval(instance, car(args));
Packit Service db8eaa
	delete_tree(instance, cdr(args));
Packit Service db8eaa
	delete_object(instance, args);
Packit Service db8eaa
	if (!alisp_compare_type(p1, ALISP_OBJ_INTEGER)) {
Packit Service db8eaa
		delete_tree(instance, p1);
Packit Service db8eaa
		return &alsa_lisp_nil;
Packit Service db8eaa
	}
Packit Service db8eaa
	val = p1->value.i;
Packit Service db8eaa
	delete_tree(instance, p1);
Packit Service db8eaa
	err = ((snd_int_intp_t)item->xfunc)(&val;;
Packit Service db8eaa
	return new_result2(instance, err, val);
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static struct alisp_object * FA_int_str(struct alisp_instance * instance, struct acall_table * item, struct alisp_object * args)
Packit Service db8eaa
{
Packit Service db8eaa
	int err;
Packit Service db8eaa
	struct alisp_object * p1;
Packit Service db8eaa
Packit Service db8eaa
	p1 = eval(instance, car(args));
Packit Service db8eaa
	delete_tree(instance, cdr(args));
Packit Service db8eaa
	delete_object(instance, args);
Packit Service db8eaa
	if (!alisp_compare_type(p1, ALISP_OBJ_STRING) &&
Packit Service db8eaa
	    !alisp_compare_type(p1, ALISP_OBJ_IDENTIFIER)) {
Packit Service db8eaa
		delete_tree(instance, p1);
Packit Service db8eaa
		return &alsa_lisp_nil;
Packit Service db8eaa
	}
Packit Service db8eaa
	err = ((snd_int_str_t)item->xfunc)(p1->value.s);
Packit Service db8eaa
	delete_tree(instance, p1);
Packit Service db8eaa
	return new_integer(instance, err);
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static struct alisp_object * FA_int_int_strp(struct alisp_instance * instance, struct acall_table * item, struct alisp_object * args)
Packit Service db8eaa
{
Packit Service db8eaa
	int err;
Packit Service db8eaa
	char *str;
Packit Service db8eaa
	long val;
Packit Service db8eaa
	struct alisp_object * p1;
Packit Service db8eaa
Packit Service db8eaa
	p1 = eval(instance, car(args));
Packit Service db8eaa
	delete_tree(instance, cdr(args));
Packit Service db8eaa
	delete_object(instance, args);
Packit Service db8eaa
	if (!alisp_compare_type(p1, ALISP_OBJ_INTEGER)) {
Packit Service db8eaa
		delete_tree(instance, p1);
Packit Service db8eaa
		return &alsa_lisp_nil;
Packit Service db8eaa
	}
Packit Service db8eaa
	val = p1->value.i;
Packit Service db8eaa
	delete_tree(instance, p1);
Packit Service db8eaa
	err = ((snd_int_int_strp_t)item->xfunc)(val, &str);
Packit Service db8eaa
	return new_result3(instance, err, str);
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static struct alisp_object * FA_card_info(struct alisp_instance * instance, struct acall_table * item, struct alisp_object * args)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_ctl_t *handle;
Packit Service db8eaa
	struct alisp_object * lexpr, * p1;
Packit Service db8eaa
	snd_ctl_card_info_t info = {0};
Packit Service db8eaa
	int err;
Packit Service db8eaa
Packit Service db8eaa
	p1 = eval(instance, car(args));
Packit Service db8eaa
	delete_tree(instance, cdr(args));
Packit Service db8eaa
	delete_object(instance, args);
Packit Service db8eaa
	handle = (snd_ctl_t *)get_ptr(instance, p1, item->prefix);
Packit Service db8eaa
	if (handle == NULL)
Packit Service db8eaa
		return &alsa_lisp_nil;
Packit Service db8eaa
	err = snd_ctl_card_info(handle, &info;;
Packit Service db8eaa
	lexpr = new_lexpr(instance, err);
Packit Service db8eaa
	if (err < 0)
Packit Service db8eaa
		return lexpr;
Packit Service db8eaa
	p1 = add_cons(instance, lexpr->value.c.cdr, 0, "id", new_string(instance, snd_ctl_card_info_get_id(&info)));
Packit Service db8eaa
	p1 = add_cons(instance, p1, 1, "driver", new_string(instance, snd_ctl_card_info_get_driver(&info)));
Packit Service db8eaa
	p1 = add_cons(instance, p1, 1, "name", new_string(instance, snd_ctl_card_info_get_name(&info)));
Packit Service db8eaa
	p1 = add_cons(instance, p1, 1, "longname", new_string(instance, snd_ctl_card_info_get_longname(&info)));
Packit Service db8eaa
	p1 = add_cons(instance, p1, 1, "mixername", new_string(instance, snd_ctl_card_info_get_mixername(&info)));
Packit Service db8eaa
	p1 = add_cons(instance, p1, 1, "components", new_string(instance, snd_ctl_card_info_get_components(&info)));
Packit Service db8eaa
	if (p1 == NULL) {
Packit Service db8eaa
		delete_tree(instance, lexpr);
Packit Service db8eaa
		return NULL;
Packit Service db8eaa
	}
Packit Service db8eaa
	return lexpr;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static struct alisp_object * create_ctl_elem_id(struct alisp_instance * instance, snd_ctl_elem_id_t * id, struct alisp_object * cons)
Packit Service db8eaa
{
Packit Service db8eaa
	cons = add_cons(instance, cons, 0, "numid", new_integer(instance, snd_ctl_elem_id_get_numid(id)));
Packit Service db8eaa
	cons = add_cons(instance, cons, 1, "iface", new_string(instance, snd_ctl_elem_iface_name(snd_ctl_elem_id_get_interface(id))));
Packit Service db8eaa
	cons = add_cons(instance, cons, 1, "dev", new_integer(instance, snd_ctl_elem_id_get_device(id)));
Packit Service db8eaa
	cons = add_cons(instance, cons, 1, "subdev", new_integer(instance, snd_ctl_elem_id_get_subdevice(id)));
Packit Service db8eaa
	cons = add_cons(instance, cons, 1, "name", new_string(instance, snd_ctl_elem_id_get_name(id)));
Packit Service db8eaa
	cons = add_cons(instance, cons, 1, "index", new_integer(instance, snd_ctl_elem_id_get_index(id)));
Packit Service db8eaa
	return cons;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int parse_ctl_elem_id(struct alisp_instance * instance,
Packit Service db8eaa
			     struct alisp_object * cons,
Packit Service db8eaa
			     snd_ctl_elem_id_t * id)
Packit Service db8eaa
{
Packit Service db8eaa
	struct alisp_object *p1;
Packit Service db8eaa
	const char *xid;
Packit Service db8eaa
Packit Service db8eaa
	if (cons == NULL)
Packit Service db8eaa
		return -ENOMEM;
Packit Service db8eaa
	snd_ctl_elem_id_clear(id);
Packit Service db8eaa
	id->numid = 0;
Packit Service db8eaa
	do {
Packit Service db8eaa
		p1 = car(cons);
Packit Service db8eaa
		if (alisp_compare_type(p1, ALISP_OBJ_CONS)) {
Packit Service db8eaa
			xid = get_string(p1->value.c.car, NULL);
Packit Service db8eaa
			if (xid == NULL) {
Packit Service db8eaa
				/* noop */
Packit Service db8eaa
			} else if (!strcmp(xid, "numid")) {
Packit Service db8eaa
				snd_ctl_elem_id_set_numid(id, get_integer(p1->value.c.cdr));
Packit Service db8eaa
			} else if (!strcmp(xid, "iface")) {
Packit Service db8eaa
				snd_ctl_elem_id_set_interface(id, snd_config_get_ctl_iface_ascii(get_string(p1->value.c.cdr, "0")));
Packit Service db8eaa
			} else if (!strcmp(xid, "dev")) {
Packit Service db8eaa
				snd_ctl_elem_id_set_device(id, get_integer(p1->value.c.cdr));
Packit Service db8eaa
			} else if (!strcmp(xid, "subdev")) {
Packit Service db8eaa
				snd_ctl_elem_id_set_subdevice(id, get_integer(p1->value.c.cdr));
Packit Service db8eaa
			} else if (!strcmp(xid, "name")) {
Packit Service db8eaa
				snd_ctl_elem_id_set_name(id, get_string(p1->value.c.cdr, "?"));
Packit Service db8eaa
			} else if (!strcmp(xid, "index")) {
Packit Service db8eaa
				snd_ctl_elem_id_set_index(id, get_integer(p1->value.c.cdr));
Packit Service db8eaa
			}
Packit Service db8eaa
		}
Packit Service db8eaa
		delete_tree(instance, p1);
Packit Service db8eaa
	        cons = cdr(p1 = cons);
Packit Service db8eaa
	        delete_object(instance, p1);
Packit Service db8eaa
	} while (cons != &alsa_lisp_nil);
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static struct alisp_object * FA_hctl_find_elem(struct alisp_instance * instance, struct acall_table * item, struct alisp_object * args)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_hctl_t *handle;
Packit Service db8eaa
	snd_ctl_elem_id_t id = {0};
Packit Service db8eaa
	struct alisp_object *p1;
Packit Service db8eaa
Packit Service db8eaa
	handle = (snd_hctl_t *)get_ptr(instance, car(args), item->prefix);
Packit Service db8eaa
	if (handle == NULL) {
Packit Service db8eaa
		delete_tree(instance, cdr(args));
Packit Service db8eaa
		delete_object(instance, args);
Packit Service db8eaa
		return &alsa_lisp_nil;
Packit Service db8eaa
	}
Packit Service db8eaa
	p1 = car(cdr(args));
Packit Service db8eaa
	delete_tree(instance, cdr(cdr(args)));
Packit Service db8eaa
	delete_object(instance, cdr(args));
Packit Service db8eaa
	delete_object(instance, args);
Packit Service db8eaa
	if (parse_ctl_elem_id(instance, eval(instance, p1), &id) < 0)
Packit Service db8eaa
		return &alsa_lisp_nil;
Packit Service db8eaa
	return new_cons_pointer(instance, "hctl_elem", snd_hctl_find_elem(handle, &id));
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static struct alisp_object * FA_hctl_elem_info(struct alisp_instance * instance, struct acall_table * item, struct alisp_object * args)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_hctl_elem_t *handle;
Packit Service db8eaa
	struct alisp_object * lexpr, * p1, * p2;
Packit Service db8eaa
	snd_ctl_elem_info_t info = {0};
Packit Service db8eaa
	snd_ctl_elem_id_t id = {0};
Packit Service db8eaa
	snd_ctl_elem_type_t type;
Packit Service db8eaa
	int err;
Packit Service db8eaa
Packit Service db8eaa
	p1 = eval(instance, car(args));
Packit Service db8eaa
	delete_tree(instance, cdr(args));
Packit Service db8eaa
	delete_object(instance, args);
Packit Service db8eaa
	handle = (snd_hctl_elem_t *)get_ptr(instance, p1, item->prefix);
Packit Service db8eaa
	if (handle == NULL)
Packit Service db8eaa
		return &alsa_lisp_nil;
Packit Service db8eaa
	err = snd_hctl_elem_info(handle, &info;;
Packit Service db8eaa
	lexpr = new_lexpr(instance, err);
Packit Service db8eaa
	if (err < 0)
Packit Service db8eaa
		return lexpr;
Packit Service db8eaa
	type = snd_ctl_elem_info_get_type(&info;;
Packit Service db8eaa
	p1 = add_cons(instance, lexpr->value.c.cdr, 0, "id", p2 = new_object(instance, ALISP_OBJ_CONS));
Packit Service db8eaa
	snd_ctl_elem_info_get_id(&info, &id;;
Packit Service db8eaa
	if (create_ctl_elem_id(instance, &id, p2) == NULL) {
Packit Service db8eaa
		delete_tree(instance, lexpr);
Packit Service db8eaa
		return NULL;
Packit Service db8eaa
	}
Packit Service db8eaa
	p1 = add_cons(instance, p1, 1, "type", new_string(instance, snd_ctl_elem_type_name(type)));
Packit Service db8eaa
	p1 = add_cons(instance, p1, 1, "readable", new_integer(instance, snd_ctl_elem_info_is_readable(&info)));
Packit Service db8eaa
	p1 = add_cons(instance, p1, 1, "writable", new_integer(instance, snd_ctl_elem_info_is_writable(&info)));
Packit Service db8eaa
	p1 = add_cons(instance, p1, 1, "volatile", new_integer(instance, snd_ctl_elem_info_is_volatile(&info)));
Packit Service db8eaa
	p1 = add_cons(instance, p1, 1, "inactive", new_integer(instance, snd_ctl_elem_info_is_inactive(&info)));
Packit Service db8eaa
	p1 = add_cons(instance, p1, 1, "locked", new_integer(instance, snd_ctl_elem_info_is_locked(&info)));
Packit Service db8eaa
	p1 = add_cons(instance, p1, 1, "isowner", new_integer(instance, snd_ctl_elem_info_is_owner(&info)));
Packit Service db8eaa
	p1 = add_cons(instance, p1, 1, "owner", new_integer(instance, snd_ctl_elem_info_get_owner(&info)));
Packit Service db8eaa
	p1 = add_cons(instance, p1, 1, "count", new_integer(instance, snd_ctl_elem_info_get_count(&info)));
Packit Service db8eaa
	err = INTERNAL(snd_ctl_elem_info_get_dimensions)(&info;;
Packit Service db8eaa
	if (err > 0) {
Packit Service db8eaa
		int idx;
Packit Service db8eaa
		p1 = add_cons(instance, p1, 1, "dimensions", p2 = new_object(instance, ALISP_OBJ_CONS));
Packit Service db8eaa
		for (idx = 0; idx < err; idx++)
Packit Service db8eaa
			p2 = add_cons2(instance, p2, idx > 0, new_integer(instance, INTERNAL(snd_ctl_elem_info_get_dimension)(&info, idx)));
Packit Service db8eaa
	}
Packit Service db8eaa
	switch (type) {
Packit Service db8eaa
	case SND_CTL_ELEM_TYPE_ENUMERATED: {
Packit Service db8eaa
		unsigned int items, item;
Packit Service db8eaa
		items = snd_ctl_elem_info_get_items(&info;;
Packit Service db8eaa
		p1 = add_cons(instance, p1, 1, "items", p2 = new_object(instance, ALISP_OBJ_CONS));
Packit Service db8eaa
		for (item = 0; item < items; item++) {
Packit Service db8eaa
			snd_ctl_elem_info_set_item(&info, item);
Packit Service db8eaa
			err = snd_hctl_elem_info(handle, &info;;
Packit Service db8eaa
			if (err < 0) {
Packit Service db8eaa
				p2 = add_cons2(instance, p2, item, &alsa_lisp_nil);
Packit Service db8eaa
			} else {
Packit Service db8eaa
				p2 = add_cons2(instance, p2, item, new_string(instance, snd_ctl_elem_info_get_item_name(&info)));
Packit Service db8eaa
			}
Packit Service db8eaa
		}
Packit Service db8eaa
		break;
Packit Service db8eaa
	}
Packit Service db8eaa
	case SND_CTL_ELEM_TYPE_INTEGER:
Packit Service db8eaa
		p1 = add_cons(instance, p1, 1, "min", new_integer(instance, snd_ctl_elem_info_get_min(&info)));
Packit Service db8eaa
		p1 = add_cons(instance, p1, 1, "max", new_integer(instance, snd_ctl_elem_info_get_max(&info)));
Packit Service db8eaa
		p1 = add_cons(instance, p1, 1, "step", new_integer(instance, snd_ctl_elem_info_get_step(&info)));
Packit Service db8eaa
		break;
Packit Service db8eaa
	case SND_CTL_ELEM_TYPE_INTEGER64:
Packit Service db8eaa
		p1 = add_cons(instance, p1, 1, "min64", new_float(instance, snd_ctl_elem_info_get_min64(&info)));
Packit Service db8eaa
		p1 = add_cons(instance, p1, 1, "max64", new_float(instance, snd_ctl_elem_info_get_max64(&info)));
Packit Service db8eaa
		p1 = add_cons(instance, p1, 1, "step64", new_float(instance, snd_ctl_elem_info_get_step64(&info)));
Packit Service db8eaa
		break;
Packit Service db8eaa
	default:
Packit Service db8eaa
		break;
Packit Service db8eaa
	}
Packit Service db8eaa
	if (p1 == NULL) {
Packit Service db8eaa
		delete_tree(instance, lexpr);
Packit Service db8eaa
		return NULL;
Packit Service db8eaa
	}
Packit Service db8eaa
	return lexpr;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static struct alisp_object * FA_hctl_elem_read(struct alisp_instance * instance, struct acall_table * item, struct alisp_object * args)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_hctl_elem_t *handle;
Packit Service db8eaa
	struct alisp_object * lexpr, * p1 = NULL, * obj;
Packit Service db8eaa
	snd_ctl_elem_info_t info = {0};
Packit Service db8eaa
	snd_ctl_elem_value_t value = {0};
Packit Service db8eaa
	snd_ctl_elem_type_t type;
Packit Service db8eaa
	unsigned int idx, count;
Packit Service db8eaa
	int err;
Packit Service db8eaa
Packit Service db8eaa
	p1 = eval(instance, car(args));
Packit Service db8eaa
	delete_tree(instance, cdr(args));
Packit Service db8eaa
	delete_object(instance, args);
Packit Service db8eaa
	handle = (snd_hctl_elem_t *)get_ptr(instance, p1, item->prefix);
Packit Service db8eaa
	if (handle == NULL)
Packit Service db8eaa
		return &alsa_lisp_nil;
Packit Service db8eaa
	err = snd_hctl_elem_info(handle, &info;;
Packit Service db8eaa
	if (err >= 0)
Packit Service db8eaa
		err = snd_hctl_elem_read(handle, &value);
Packit Service db8eaa
	lexpr = new_lexpr(instance, err);
Packit Service db8eaa
	if (err < 0)
Packit Service db8eaa
		return lexpr;
Packit Service db8eaa
	type = snd_ctl_elem_info_get_type(&info;;
Packit Service db8eaa
	count = snd_ctl_elem_info_get_count(&info;;
Packit Service db8eaa
	if (type == SND_CTL_ELEM_TYPE_IEC958) {
Packit Service db8eaa
		count = sizeof(snd_aes_iec958_t);
Packit Service db8eaa
		type = SND_CTL_ELEM_TYPE_BYTES;
Packit Service db8eaa
	}
Packit Service db8eaa
	for (idx = 0; idx < count; idx++) {
Packit Service db8eaa
		switch (type) {
Packit Service db8eaa
		case SND_CTL_ELEM_TYPE_BOOLEAN:
Packit Service db8eaa
			obj = new_integer(instance, snd_ctl_elem_value_get_boolean(&value, idx));
Packit Service db8eaa
			break;
Packit Service db8eaa
		case SND_CTL_ELEM_TYPE_INTEGER:
Packit Service db8eaa
			obj = new_integer(instance, snd_ctl_elem_value_get_integer(&value, idx));
Packit Service db8eaa
			break;
Packit Service db8eaa
		case SND_CTL_ELEM_TYPE_INTEGER64:
Packit Service db8eaa
			obj = new_integer(instance, snd_ctl_elem_value_get_integer64(&value, idx));
Packit Service db8eaa
			break;
Packit Service db8eaa
		case SND_CTL_ELEM_TYPE_ENUMERATED:
Packit Service db8eaa
			obj = new_integer(instance, snd_ctl_elem_value_get_enumerated(&value, idx));
Packit Service db8eaa
			break;
Packit Service db8eaa
		case SND_CTL_ELEM_TYPE_BYTES:
Packit Service db8eaa
			obj = new_integer(instance, snd_ctl_elem_value_get_byte(&value, idx));
Packit Service db8eaa
			break;
Packit Service db8eaa
		default:
Packit Service db8eaa
			obj = NULL;
Packit Service db8eaa
			break;
Packit Service db8eaa
		}
Packit Service db8eaa
		if (idx == 0) {
Packit Service db8eaa
			p1 = add_cons2(instance, lexpr->value.c.cdr, 0, obj);
Packit Service db8eaa
		} else {
Packit Service db8eaa
			p1 = add_cons2(instance, p1, 1, obj);
Packit Service db8eaa
		}
Packit Service db8eaa
	}
Packit Service db8eaa
	if (p1 == NULL) {
Packit Service db8eaa
		delete_tree(instance, lexpr);
Packit Service db8eaa
		return &alsa_lisp_nil;
Packit Service db8eaa
	}
Packit Service db8eaa
	return lexpr;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static struct alisp_object * FA_hctl_elem_write(struct alisp_instance * instance, struct acall_table * item, struct alisp_object * args)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_hctl_elem_t *handle;
Packit Service db8eaa
	struct alisp_object * p1 = NULL, * obj;
Packit Service db8eaa
	snd_ctl_elem_info_t info = {0};
Packit Service db8eaa
	snd_ctl_elem_value_t value = {0};
Packit Service db8eaa
	snd_ctl_elem_type_t type;
Packit Service db8eaa
	unsigned int idx, count;
Packit Service db8eaa
	int err;
Packit Service db8eaa
Packit Service db8eaa
	p1 = car(cdr(args));
Packit Service db8eaa
	obj = eval(instance, car(args));
Packit Service db8eaa
	delete_tree(instance, cdr(cdr(args)));
Packit Service db8eaa
	delete_object(instance, cdr(args));
Packit Service db8eaa
	delete_object(instance, args);
Packit Service db8eaa
	handle = (snd_hctl_elem_t *)get_ptr(instance, obj, item->prefix);
Packit Service db8eaa
	if (handle == NULL) {
Packit Service db8eaa
		delete_tree(instance, p1);
Packit Service db8eaa
		return &alsa_lisp_nil;
Packit Service db8eaa
	}
Packit Service db8eaa
	err = snd_hctl_elem_info(handle, &info;;
Packit Service db8eaa
	if (err < 0) {
Packit Service db8eaa
		delete_tree(instance, p1);
Packit Service db8eaa
		return new_integer(instance, err);
Packit Service db8eaa
	}
Packit Service db8eaa
	type = snd_ctl_elem_info_get_type(&info;;
Packit Service db8eaa
	count = snd_ctl_elem_info_get_count(&info;;
Packit Service db8eaa
	if (type == SND_CTL_ELEM_TYPE_IEC958) {
Packit Service db8eaa
		count = sizeof(snd_aes_iec958_t);
Packit Service db8eaa
		type = SND_CTL_ELEM_TYPE_BYTES;
Packit Service db8eaa
	}
Packit Service db8eaa
	idx = -1;
Packit Service db8eaa
	do {
Packit Service db8eaa
		if (++idx >= count) {
Packit Service db8eaa
			delete_tree(instance, p1);
Packit Service db8eaa
			break;
Packit Service db8eaa
		}
Packit Service db8eaa
		obj = car(p1);
Packit Service db8eaa
		switch (type) {
Packit Service db8eaa
		case SND_CTL_ELEM_TYPE_BOOLEAN:
Packit Service db8eaa
			snd_ctl_elem_value_set_boolean(&value, idx, get_integer(obj));
Packit Service db8eaa
			break;
Packit Service db8eaa
		case SND_CTL_ELEM_TYPE_INTEGER:
Packit Service db8eaa
			snd_ctl_elem_value_set_integer(&value, idx, get_integer(obj));
Packit Service db8eaa
			break;
Packit Service db8eaa
		case SND_CTL_ELEM_TYPE_INTEGER64:
Packit Service db8eaa
			snd_ctl_elem_value_set_integer64(&value, idx, get_integer(obj));
Packit Service db8eaa
			break;
Packit Service db8eaa
		case SND_CTL_ELEM_TYPE_ENUMERATED:
Packit Service db8eaa
			snd_ctl_elem_value_set_enumerated(&value, idx, get_integer(obj));
Packit Service db8eaa
			break;
Packit Service db8eaa
		case SND_CTL_ELEM_TYPE_BYTES:
Packit Service db8eaa
			snd_ctl_elem_value_set_byte(&value, idx, get_integer(obj));
Packit Service db8eaa
			break;
Packit Service db8eaa
		default:
Packit Service db8eaa
			break;
Packit Service db8eaa
		}
Packit Service db8eaa
		delete_tree(instance, obj);
Packit Service db8eaa
		p1 = cdr(obj = p1);
Packit Service db8eaa
		delete_object(instance, obj);
Packit Service db8eaa
	} while (p1 != &alsa_lisp_nil);
Packit Service db8eaa
	err = snd_hctl_elem_write(handle, &value);
Packit Service db8eaa
	return new_integer(instance, err);
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static struct alisp_object * FA_pcm_info(struct alisp_instance * instance, struct acall_table * item, struct alisp_object * args)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_pcm_t *handle;
Packit Service db8eaa
	struct alisp_object * lexpr, * p1;
Packit Service db8eaa
	snd_pcm_info_t info = {0};
Packit Service db8eaa
	int err;
Packit Service db8eaa
Packit Service db8eaa
	p1 = eval(instance, car(args));
Packit Service db8eaa
	delete_tree(instance, cdr(args));
Packit Service db8eaa
	delete_object(instance, args);
Packit Service db8eaa
	handle = (snd_pcm_t *)get_ptr(instance, p1, item->prefix);
Packit Service db8eaa
	if (handle == NULL)
Packit Service db8eaa
		return &alsa_lisp_nil;
Packit Service db8eaa
	err = snd_pcm_info(handle, &info;;
Packit Service db8eaa
	lexpr = new_lexpr(instance, err);
Packit Service db8eaa
	if (err < 0)
Packit Service db8eaa
		return lexpr;
Packit Service db8eaa
	p1 = add_cons(instance, lexpr->value.c.cdr, 0, "card", new_integer(instance, snd_pcm_info_get_card(&info)));
Packit Service db8eaa
	p1 = add_cons(instance, p1, 1, "device", new_integer(instance, snd_pcm_info_get_device(&info)));
Packit Service db8eaa
	p1 = add_cons(instance, p1, 1, "subdevice", new_integer(instance, snd_pcm_info_get_subdevice(&info)));
Packit Service db8eaa
	p1 = add_cons(instance, p1, 1, "id", new_string(instance, snd_pcm_info_get_id(&info)));
Packit Service db8eaa
	p1 = add_cons(instance, p1, 1, "name", new_string(instance, snd_pcm_info_get_name(&info)));
Packit Service db8eaa
	p1 = add_cons(instance, p1, 1, "subdevice_name", new_string(instance, snd_pcm_info_get_subdevice_name(&info)));
Packit Service db8eaa
	p1 = add_cons(instance, p1, 1, "class", new_integer(instance, snd_pcm_info_get_class(&info)));
Packit Service db8eaa
	p1 = add_cons(instance, p1, 1, "subclass", new_integer(instance, snd_pcm_info_get_subclass(&info)));
Packit Service db8eaa
	p1 = add_cons(instance, p1, 1, "subdevices_count", new_integer(instance, snd_pcm_info_get_subdevices_count(&info)));
Packit Service db8eaa
	p1 = add_cons(instance, p1, 1, "subdevices_avail", new_integer(instance, snd_pcm_info_get_subdevices_avail(&info)));
Packit Service db8eaa
	//p1 = add_cons(instance, p1, 1, "sync", new_string(instance, snd_pcm_info_get_sync(&info)));
Packit Service db8eaa
	return lexpr;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
/*
Packit Service db8eaa
 *  main code
Packit Service db8eaa
 */
Packit Service db8eaa
Packit Service db8eaa
static const struct acall_table acall_table[] = {
Packit Service db8eaa
	{ "card_get_index", &FA_int_str, (void *)snd_card_get_index, NULL },
Packit Service db8eaa
	{ "card_get_longname", &FA_int_int_strp, (void *)snd_card_get_longname, NULL },
Packit Service db8eaa
	{ "card_get_name", &FA_int_int_strp, (void *)snd_card_get_name, NULL },
Packit Service db8eaa
	{ "card_next", &FA_int_intp, (void *)&snd_card_next, NULL },
Packit Service db8eaa
	{ "ctl_card_info", &FA_card_info, NULL, "ctl" },
Packit Service db8eaa
	{ "ctl_close", &FA_int_p, (void *)&snd_ctl_close, "ctl" },
Packit Service db8eaa
	{ "ctl_open", &FA_int_pp_strp_int, (void *)&snd_ctl_open, "ctl" },
Packit Service db8eaa
	{ "hctl_close", &FA_int_p, (void *)&snd_hctl_close, "hctl" },
Packit Service db8eaa
	{ "hctl_ctl", &FA_p_p, (void *)&snd_hctl_ctl, "hctl" },
Packit Service db8eaa
	{ "hctl_elem_info", &FA_hctl_elem_info, (void *)&snd_hctl_elem_info, "hctl_elem" },
Packit Service db8eaa
	{ "hctl_elem_next", &FA_p_p, (void *)&snd_hctl_elem_next, "hctl_elem" },
Packit Service db8eaa
	{ "hctl_elem_prev", &FA_p_p, (void *)&snd_hctl_elem_prev, "hctl_elem" },
Packit Service db8eaa
	{ "hctl_elem_read", &FA_hctl_elem_read, (void *)&snd_hctl_elem_read, "hctl_elem" },
Packit Service db8eaa
	{ "hctl_elem_write", &FA_hctl_elem_write, (void *)&snd_hctl_elem_write, "hctl_elem" },
Packit Service db8eaa
	{ "hctl_find_elem", &FA_hctl_find_elem, (void *)&snd_hctl_find_elem, "hctl" },
Packit Service db8eaa
	{ "hctl_first_elem", &FA_p_p, (void *)&snd_hctl_first_elem, "hctl" },
Packit Service db8eaa
	{ "hctl_free", &FA_int_p, (void *)&snd_hctl_free, "hctl" },
Packit Service db8eaa
	{ "hctl_last_elem", &FA_p_p, (void *)&snd_hctl_last_elem, "hctl" },
Packit Service db8eaa
	{ "hctl_load", &FA_int_p, (void *)&snd_hctl_load, "hctl" },
Packit Service db8eaa
	{ "hctl_open", &FA_int_pp_strp_int, (void *)&snd_hctl_open, "hctl" },
Packit Service db8eaa
	{ "hctl_open_ctl", &FA_int_pp_p, (void *)&snd_hctl_open_ctl, "hctl" },
Packit Service db8eaa
	{ "pcm_info", &FA_pcm_info, NULL, "pcm" },
Packit Service db8eaa
	{ "pcm_name", &FA_str_p, (void *)&snd_pcm_name, "pcm" },
Packit Service db8eaa
};
Packit Service db8eaa
Packit Service db8eaa
static int acall_compar(const void *p1, const void *p2)
Packit Service db8eaa
{
Packit Service db8eaa
	return strcmp(((struct acall_table *)p1)->name,
Packit Service db8eaa
        	      ((struct acall_table *)p2)->name);
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static struct alisp_object * F_acall(struct alisp_instance *instance, struct alisp_object * args)
Packit Service db8eaa
{
Packit Service db8eaa
	struct alisp_object * p1, *p2;
Packit Service db8eaa
	struct acall_table key, *item;
Packit Service db8eaa
Packit Service db8eaa
	p1 = eval(instance, car(args));
Packit Service db8eaa
	p2 = cdr(args);
Packit Service db8eaa
	delete_object(instance, args);
Packit Service db8eaa
	if (!alisp_compare_type(p1, ALISP_OBJ_IDENTIFIER) &&
Packit Service db8eaa
	    !alisp_compare_type(p1, ALISP_OBJ_STRING)) {
Packit Service db8eaa
	    	delete_tree(instance, p2);
Packit Service db8eaa
		return &alsa_lisp_nil;
Packit Service db8eaa
	}
Packit Service db8eaa
	key.name = p1->value.s;
Packit Service db8eaa
	if ((item = bsearch(&key, acall_table,
Packit Service db8eaa
			    sizeof acall_table / sizeof acall_table[0],
Packit Service db8eaa
			    sizeof acall_table[0], acall_compar)) != NULL) {
Packit Service db8eaa
		delete_tree(instance, p1);
Packit Service db8eaa
		return item->func(instance, item, p2);
Packit Service db8eaa
	}
Packit Service db8eaa
	delete_tree(instance, p1);
Packit Service db8eaa
	delete_tree(instance, p2);
Packit Service db8eaa
	lisp_warn(instance, "acall function %s' is undefined", p1->value.s);
Packit Service db8eaa
	return &alsa_lisp_nil;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static struct alisp_object * F_ahandle(struct alisp_instance *instance, struct alisp_object * args)
Packit Service db8eaa
{
Packit Service db8eaa
	struct alisp_object *p1;
Packit Service db8eaa
Packit Service db8eaa
	p1 = eval(instance, car(args));
Packit Service db8eaa
	delete_tree(instance, cdr(args));
Packit Service db8eaa
	delete_object(instance, args);
Packit Service db8eaa
	args = car(cdr(p1));
Packit Service db8eaa
	delete_tree(instance, cdr(cdr(p1)));
Packit Service db8eaa
	delete_object(instance, cdr(p1));
Packit Service db8eaa
	delete_tree(instance, car(p1));
Packit Service db8eaa
	delete_object(instance, p1);
Packit Service db8eaa
	return args;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static struct alisp_object * F_aerror(struct alisp_instance *instance, struct alisp_object * args)
Packit Service db8eaa
{
Packit Service db8eaa
	struct alisp_object *p1;
Packit Service db8eaa
Packit Service db8eaa
	p1 = eval(instance, car(args));
Packit Service db8eaa
	delete_tree(instance, cdr(args));
Packit Service db8eaa
	delete_object(instance, args);
Packit Service db8eaa
	args = car(p1);
Packit Service db8eaa
	if (args == &alsa_lisp_nil) {
Packit Service db8eaa
		delete_tree(instance, p1);
Packit Service db8eaa
		return new_integer(instance, SND_ERROR_ALISP_NIL);
Packit Service db8eaa
	} else {
Packit Service db8eaa
		delete_tree(instance, cdr(p1));
Packit Service db8eaa
		delete_object(instance, p1);
Packit Service db8eaa
	}
Packit Service db8eaa
	return args;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int common_error(snd_output_t **rout, struct alisp_instance *instance, struct alisp_object * args)
Packit Service db8eaa
{
Packit Service db8eaa
	struct alisp_object * p = args, * p1;
Packit Service db8eaa
	snd_output_t *out;
Packit Service db8eaa
	int err;
Packit Service db8eaa
	
Packit Service db8eaa
	err = snd_output_buffer_open(&out;;
Packit Service db8eaa
	if (err < 0) {
Packit Service db8eaa
		delete_tree(instance, args);
Packit Service db8eaa
		return err;
Packit Service db8eaa
	}
Packit Service db8eaa
Packit Service db8eaa
	do {
Packit Service db8eaa
		p1 = eval(instance, car(p));
Packit Service db8eaa
		if (alisp_compare_type(p1, ALISP_OBJ_STRING))
Packit Service db8eaa
			snd_output_printf(out, "%s", p1->value.s);
Packit Service db8eaa
		else
Packit Service db8eaa
			princ_object(out, p1);
Packit Service db8eaa
		delete_tree(instance, p1);
Packit Service db8eaa
		p = cdr(p1 = p);
Packit Service db8eaa
		delete_object(instance, p1);
Packit Service db8eaa
	} while (p != &alsa_lisp_nil);
Packit Service db8eaa
Packit Service db8eaa
	*rout = out;
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static struct alisp_object * F_snderr(struct alisp_instance *instance, struct alisp_object * args)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_output_t *out;
Packit Service db8eaa
	char *str;
Packit Service db8eaa
Packit Service db8eaa
	if (common_error(&out, instance, args) < 0)
Packit Service db8eaa
		return &alsa_lisp_nil;
Packit Service db8eaa
	snd_output_buffer_string(out, &str);
Packit Service db8eaa
	SNDERR(str);
Packit Service db8eaa
	snd_output_close(out);
Packit Service db8eaa
	return &alsa_lisp_t;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static struct alisp_object * F_syserr(struct alisp_instance *instance, struct alisp_object * args)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_output_t *out;
Packit Service db8eaa
	char *str;
Packit Service db8eaa
Packit Service db8eaa
	if (common_error(&out, instance, args) < 0)
Packit Service db8eaa
		return &alsa_lisp_nil;
Packit Service db8eaa
	snd_output_buffer_string(out, &str);
Packit Service db8eaa
	SYSERR(str);
Packit Service db8eaa
	snd_output_close(out);
Packit Service db8eaa
	return &alsa_lisp_t;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static const struct intrinsic snd_intrinsics[] = {
Packit Service db8eaa
	{ "Acall", F_acall },
Packit Service db8eaa
	{ "Aerror", F_aerror },
Packit Service db8eaa
	{ "Ahandle", F_ahandle },
Packit Service db8eaa
	{ "Aresult", F_ahandle },
Packit Service db8eaa
	{ "Asnderr", F_snderr },
Packit Service db8eaa
	{ "Asyserr", F_syserr }
Packit Service db8eaa
};