1d5ac70f0Sopenharmony_ci/** 2d5ac70f0Sopenharmony_ci * \file confmisc.c 3d5ac70f0Sopenharmony_ci * \ingroup Configuration 4d5ac70f0Sopenharmony_ci * \brief Configuration helper functions 5d5ac70f0Sopenharmony_ci * \author Abramo Bagnara <abramo@alsa-project.org> 6d5ac70f0Sopenharmony_ci * \author Jaroslav Kysela <perex@perex.cz> 7d5ac70f0Sopenharmony_ci * \date 2000-2001 8d5ac70f0Sopenharmony_ci * 9d5ac70f0Sopenharmony_ci * Configuration helper functions. 10d5ac70f0Sopenharmony_ci * 11d5ac70f0Sopenharmony_ci * See the \ref conffunc page for more details. 12d5ac70f0Sopenharmony_ci */ 13d5ac70f0Sopenharmony_ci/* 14d5ac70f0Sopenharmony_ci * Miscellaneous configuration helper functions 15d5ac70f0Sopenharmony_ci * Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>, 16d5ac70f0Sopenharmony_ci * Jaroslav Kysela <perex@perex.cz> 17d5ac70f0Sopenharmony_ci * 18d5ac70f0Sopenharmony_ci * 19d5ac70f0Sopenharmony_ci * This library is free software; you can redistribute it and/or modify 20d5ac70f0Sopenharmony_ci * it under the terms of the GNU Lesser General Public License as 21d5ac70f0Sopenharmony_ci * published by the Free Software Foundation; either version 2.1 of 22d5ac70f0Sopenharmony_ci * the License, or (at your option) any later version. 23d5ac70f0Sopenharmony_ci * 24d5ac70f0Sopenharmony_ci * This program is distributed in the hope that it will be useful, 25d5ac70f0Sopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 26d5ac70f0Sopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 27d5ac70f0Sopenharmony_ci * GNU Lesser General Public License for more details. 28d5ac70f0Sopenharmony_ci * 29d5ac70f0Sopenharmony_ci * You should have received a copy of the GNU Lesser General Public 30d5ac70f0Sopenharmony_ci * License along with this library; if not, write to the Free Software 31d5ac70f0Sopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 32d5ac70f0Sopenharmony_ci * 33d5ac70f0Sopenharmony_ci */ 34d5ac70f0Sopenharmony_ci 35d5ac70f0Sopenharmony_ci/*! \page conffunc 36d5ac70f0Sopenharmony_ci 37d5ac70f0Sopenharmony_ci\section conffunc_ref Function reference 38d5ac70f0Sopenharmony_ci 39d5ac70f0Sopenharmony_ci<UL> 40d5ac70f0Sopenharmony_ci <LI>The getenv function - snd_func_getenv() - obtains 41d5ac70f0Sopenharmony_ci an environment value. The result is a string. 42d5ac70f0Sopenharmony_ci <LI>The igetenv function - snd_func_igetenv() - obtains 43d5ac70f0Sopenharmony_ci an environment value. The result is an integer. 44d5ac70f0Sopenharmony_ci <LI>The concat function - snd_func_concat() - merges all specified 45d5ac70f0Sopenharmony_ci strings. The result is a string. 46d5ac70f0Sopenharmony_ci <LI>The iadd function - snd_func_iadd() - sum all specified integers. 47d5ac70f0Sopenharmony_ci The result is an integer. 48d5ac70f0Sopenharmony_ci <LI>The imul function - snd_func_imul() - multiply all specified integers. 49d5ac70f0Sopenharmony_ci The result is an integer. 50d5ac70f0Sopenharmony_ci <LI>The datadir function - snd_func_datadir() - returns the 51d5ac70f0Sopenharmony_ci ALSA data directory. The result is a string. 52d5ac70f0Sopenharmony_ci <LI>The refer function - snd_func_refer() - copies the referred 53d5ac70f0Sopenharmony_ci configuration. The result has the same type as the referred node. 54d5ac70f0Sopenharmony_ci <LI>The card_inum function - snd_func_card_inum() - returns 55d5ac70f0Sopenharmony_ci a card number (integers). 56d5ac70f0Sopenharmony_ci <LI>The card_driver function - snd_func_card_driver() - returns 57d5ac70f0Sopenharmony_ci a driver identification. The result is a string. 58d5ac70f0Sopenharmony_ci <LI>The card_id function - snd_func_card_id() - returns 59d5ac70f0Sopenharmony_ci a card identification. The result is a string. 60d5ac70f0Sopenharmony_ci <LI>The card_name function - snd_func_card_name() - returns 61d5ac70f0Sopenharmony_ci a card's name. The result is a string. 62d5ac70f0Sopenharmony_ci <LI>The pcm_id function - snd_func_pcm_id() - returns 63d5ac70f0Sopenharmony_ci a pcm identification. The result is a string. 64d5ac70f0Sopenharmony_ci <LI>The private_string function - snd_func_private_string() - returns the 65d5ac70f0Sopenharmony_ci string from the private_data node. 66d5ac70f0Sopenharmony_ci <LI>The private_card_driver function - snd_func_private_card_driver() - 67d5ac70f0Sopenharmony_ci returns the driver identification from the private_data node. 68d5ac70f0Sopenharmony_ci The result is a string. 69d5ac70f0Sopenharmony_ci <LI>The private_pcm_subdevice function - snd_func_private_pcm_subdevice() - 70d5ac70f0Sopenharmony_ci returns the PCM subdevice number from the private_data node. 71d5ac70f0Sopenharmony_ci The result is a string. 72d5ac70f0Sopenharmony_ci</UL> 73d5ac70f0Sopenharmony_ci 74d5ac70f0Sopenharmony_ci*/ 75d5ac70f0Sopenharmony_ci 76d5ac70f0Sopenharmony_ci 77d5ac70f0Sopenharmony_ci#include "local.h" 78d5ac70f0Sopenharmony_ci#include <stdlib.h> 79d5ac70f0Sopenharmony_ci#include <stdio.h> 80d5ac70f0Sopenharmony_ci#include <string.h> 81d5ac70f0Sopenharmony_ci#include <ctype.h> 82d5ac70f0Sopenharmony_ci#include <limits.h> 83d5ac70f0Sopenharmony_ci 84d5ac70f0Sopenharmony_ci/** 85d5ac70f0Sopenharmony_ci * \brief Gets the boolean value from the given ASCII string. 86d5ac70f0Sopenharmony_ci * \param ascii The string to be parsed. 87d5ac70f0Sopenharmony_ci * \return 0 or 1 if successful, otherwise a negative error code. 88d5ac70f0Sopenharmony_ci */ 89d5ac70f0Sopenharmony_ciint snd_config_get_bool_ascii(const char *ascii) 90d5ac70f0Sopenharmony_ci{ 91d5ac70f0Sopenharmony_ci unsigned int k; 92d5ac70f0Sopenharmony_ci static const struct { 93d5ac70f0Sopenharmony_ci const char str[8]; 94d5ac70f0Sopenharmony_ci int val; 95d5ac70f0Sopenharmony_ci } b[] = { 96d5ac70f0Sopenharmony_ci { "0", 0 }, 97d5ac70f0Sopenharmony_ci { "1", 1 }, 98d5ac70f0Sopenharmony_ci { "false", 0 }, 99d5ac70f0Sopenharmony_ci { "true", 1 }, 100d5ac70f0Sopenharmony_ci { "no", 0 }, 101d5ac70f0Sopenharmony_ci { "yes", 1 }, 102d5ac70f0Sopenharmony_ci { "off", 0 }, 103d5ac70f0Sopenharmony_ci { "on", 1 }, 104d5ac70f0Sopenharmony_ci }; 105d5ac70f0Sopenharmony_ci for (k = 0; k < sizeof(b) / sizeof(*b); k++) { 106d5ac70f0Sopenharmony_ci if (strcasecmp(b[k].str, ascii) == 0) 107d5ac70f0Sopenharmony_ci return b[k].val; 108d5ac70f0Sopenharmony_ci } 109d5ac70f0Sopenharmony_ci return -EINVAL; 110d5ac70f0Sopenharmony_ci} 111d5ac70f0Sopenharmony_ci 112d5ac70f0Sopenharmony_ci/** 113d5ac70f0Sopenharmony_ci * \brief Gets the boolean value from a configuration node. 114d5ac70f0Sopenharmony_ci * \param conf Handle to the configuration node to be parsed. 115d5ac70f0Sopenharmony_ci * \return 0 or 1 if successful, otherwise a negative error code. 116d5ac70f0Sopenharmony_ci */ 117d5ac70f0Sopenharmony_ciint snd_config_get_bool(const snd_config_t *conf) 118d5ac70f0Sopenharmony_ci{ 119d5ac70f0Sopenharmony_ci long v; 120d5ac70f0Sopenharmony_ci const char *str, *id; 121d5ac70f0Sopenharmony_ci int err; 122d5ac70f0Sopenharmony_ci 123d5ac70f0Sopenharmony_ci err = snd_config_get_id(conf, &id); 124d5ac70f0Sopenharmony_ci if (err < 0) 125d5ac70f0Sopenharmony_ci return err; 126d5ac70f0Sopenharmony_ci err = snd_config_get_integer(conf, &v); 127d5ac70f0Sopenharmony_ci if (err >= 0) { 128d5ac70f0Sopenharmony_ci if (v < 0 || v > 1) { 129d5ac70f0Sopenharmony_ci _invalid_value: 130d5ac70f0Sopenharmony_ci SNDERR("Invalid value for %s", id); 131d5ac70f0Sopenharmony_ci return -EINVAL; 132d5ac70f0Sopenharmony_ci } 133d5ac70f0Sopenharmony_ci return v; 134d5ac70f0Sopenharmony_ci } 135d5ac70f0Sopenharmony_ci err = snd_config_get_string(conf, &str); 136d5ac70f0Sopenharmony_ci if (err < 0) { 137d5ac70f0Sopenharmony_ci SNDERR("Invalid type for %s", id); 138d5ac70f0Sopenharmony_ci return -EINVAL; 139d5ac70f0Sopenharmony_ci } 140d5ac70f0Sopenharmony_ci err = snd_config_get_bool_ascii(str); 141d5ac70f0Sopenharmony_ci if (err < 0) 142d5ac70f0Sopenharmony_ci goto _invalid_value; 143d5ac70f0Sopenharmony_ci return err; 144d5ac70f0Sopenharmony_ci} 145d5ac70f0Sopenharmony_ci 146d5ac70f0Sopenharmony_ci/** 147d5ac70f0Sopenharmony_ci * \brief Gets the card number from a configuration node. 148d5ac70f0Sopenharmony_ci * \param conf Handle to the configuration node to be parsed. 149d5ac70f0Sopenharmony_ci * \return The card number if successful, otherwise a negative error code. 150d5ac70f0Sopenharmony_ci */ 151d5ac70f0Sopenharmony_ciint snd_config_get_card(const snd_config_t *conf) 152d5ac70f0Sopenharmony_ci{ 153d5ac70f0Sopenharmony_ci const char *str, *id; 154d5ac70f0Sopenharmony_ci long v; 155d5ac70f0Sopenharmony_ci int err; 156d5ac70f0Sopenharmony_ci 157d5ac70f0Sopenharmony_ci if (snd_config_get_integer(conf, &v) < 0) { 158d5ac70f0Sopenharmony_ci if (snd_config_get_string(conf, &str)) { 159d5ac70f0Sopenharmony_ci if (snd_config_get_id(conf, &id) >= 0) 160d5ac70f0Sopenharmony_ci SNDERR("Invalid field %s", id); 161d5ac70f0Sopenharmony_ci return -EINVAL; 162d5ac70f0Sopenharmony_ci } 163d5ac70f0Sopenharmony_ci err = snd_card_get_index(str); 164d5ac70f0Sopenharmony_ci if (err < 0) { 165d5ac70f0Sopenharmony_ci SNDERR("Cannot get card index for %s", str); 166d5ac70f0Sopenharmony_ci return err; 167d5ac70f0Sopenharmony_ci } 168d5ac70f0Sopenharmony_ci v = err; 169d5ac70f0Sopenharmony_ci } 170d5ac70f0Sopenharmony_ci if (v < 0 || v > INT_MAX) 171d5ac70f0Sopenharmony_ci return -EINVAL; 172d5ac70f0Sopenharmony_ci return v; 173d5ac70f0Sopenharmony_ci} 174d5ac70f0Sopenharmony_ci 175d5ac70f0Sopenharmony_ci/** 176d5ac70f0Sopenharmony_ci * \brief Gets the control interface index from the given ASCII string. 177d5ac70f0Sopenharmony_ci * \param ascii The string to be parsed. 178d5ac70f0Sopenharmony_ci * \return The control interface index if successful, otherwise a negative error code. 179d5ac70f0Sopenharmony_ci */ 180d5ac70f0Sopenharmony_ciint snd_config_get_ctl_iface_ascii(const char *ascii) 181d5ac70f0Sopenharmony_ci{ 182d5ac70f0Sopenharmony_ci long v; 183d5ac70f0Sopenharmony_ci snd_ctl_elem_iface_t idx; 184d5ac70f0Sopenharmony_ci if (isdigit(ascii[0])) { 185d5ac70f0Sopenharmony_ci if (safe_strtol(ascii, &v) >= 0) { 186d5ac70f0Sopenharmony_ci if (v < 0 || v > SND_CTL_ELEM_IFACE_LAST) 187d5ac70f0Sopenharmony_ci return -EINVAL; 188d5ac70f0Sopenharmony_ci return v; 189d5ac70f0Sopenharmony_ci } 190d5ac70f0Sopenharmony_ci } 191d5ac70f0Sopenharmony_ci for (idx = 0; idx <= SND_CTL_ELEM_IFACE_LAST; idx++) { 192d5ac70f0Sopenharmony_ci if (strcasecmp(snd_ctl_elem_iface_name(idx), ascii) == 0) 193d5ac70f0Sopenharmony_ci return idx; 194d5ac70f0Sopenharmony_ci } 195d5ac70f0Sopenharmony_ci return -EINVAL; 196d5ac70f0Sopenharmony_ci} 197d5ac70f0Sopenharmony_ci 198d5ac70f0Sopenharmony_ci/** 199d5ac70f0Sopenharmony_ci * \brief Gets the control interface index from a configuration node. 200d5ac70f0Sopenharmony_ci * \param conf Handle to the configuration node to be parsed. 201d5ac70f0Sopenharmony_ci * \return The control interface index if successful, otherwise a negative error code. 202d5ac70f0Sopenharmony_ci */ 203d5ac70f0Sopenharmony_ciint snd_config_get_ctl_iface(const snd_config_t *conf) 204d5ac70f0Sopenharmony_ci{ 205d5ac70f0Sopenharmony_ci long v; 206d5ac70f0Sopenharmony_ci const char *str, *id; 207d5ac70f0Sopenharmony_ci int err; 208d5ac70f0Sopenharmony_ci 209d5ac70f0Sopenharmony_ci err = snd_config_get_id(conf, &id); 210d5ac70f0Sopenharmony_ci if (err < 0) 211d5ac70f0Sopenharmony_ci return err; 212d5ac70f0Sopenharmony_ci err = snd_config_get_integer(conf, &v); 213d5ac70f0Sopenharmony_ci if (err >= 0) { 214d5ac70f0Sopenharmony_ci if (v < 0 || v > SND_CTL_ELEM_IFACE_LAST) { 215d5ac70f0Sopenharmony_ci _invalid_value: 216d5ac70f0Sopenharmony_ci SNDERR("Invalid value for %s", id); 217d5ac70f0Sopenharmony_ci return -EINVAL; 218d5ac70f0Sopenharmony_ci } 219d5ac70f0Sopenharmony_ci return v; 220d5ac70f0Sopenharmony_ci } 221d5ac70f0Sopenharmony_ci err = snd_config_get_string(conf, &str); 222d5ac70f0Sopenharmony_ci if (err < 0) { 223d5ac70f0Sopenharmony_ci SNDERR("Invalid type for %s", id); 224d5ac70f0Sopenharmony_ci return -EINVAL; 225d5ac70f0Sopenharmony_ci } 226d5ac70f0Sopenharmony_ci err = snd_config_get_ctl_iface_ascii(str); 227d5ac70f0Sopenharmony_ci if (err < 0) 228d5ac70f0Sopenharmony_ci goto _invalid_value; 229d5ac70f0Sopenharmony_ci return err; 230d5ac70f0Sopenharmony_ci} 231d5ac70f0Sopenharmony_ci 232d5ac70f0Sopenharmony_ci/* 233d5ac70f0Sopenharmony_ci * Helper functions for the configuration file 234d5ac70f0Sopenharmony_ci */ 235d5ac70f0Sopenharmony_ci 236d5ac70f0Sopenharmony_ci/** 237d5ac70f0Sopenharmony_ci * \brief Returns an environment value. 238d5ac70f0Sopenharmony_ci * \param dst The function puts the handle to the result configuration node 239d5ac70f0Sopenharmony_ci * (with type string) at the address specified by \p dst. 240d5ac70f0Sopenharmony_ci * \param root Handle to the root source node. 241d5ac70f0Sopenharmony_ci * \param src Handle to the source node, with definitions for \c vars and 242d5ac70f0Sopenharmony_ci * \c default. 243d5ac70f0Sopenharmony_ci * \param private_data Handle to the \c private_data node. 244d5ac70f0Sopenharmony_ci * \return Zero if successful, otherwise a negative error code. 245d5ac70f0Sopenharmony_ci * 246d5ac70f0Sopenharmony_ci * Example: 247d5ac70f0Sopenharmony_ci\code 248d5ac70f0Sopenharmony_ci { 249d5ac70f0Sopenharmony_ci @func getenv 250d5ac70f0Sopenharmony_ci vars [ MY_CARD CARD C ] 251d5ac70f0Sopenharmony_ci default 0 252d5ac70f0Sopenharmony_ci } 253d5ac70f0Sopenharmony_ci\endcode 254d5ac70f0Sopenharmony_ci */ 255d5ac70f0Sopenharmony_ciint snd_func_getenv(snd_config_t **dst, snd_config_t *root, snd_config_t *src, 256d5ac70f0Sopenharmony_ci snd_config_t *private_data) 257d5ac70f0Sopenharmony_ci{ 258d5ac70f0Sopenharmony_ci snd_config_t *n, *d; 259d5ac70f0Sopenharmony_ci snd_config_iterator_t i, next; 260d5ac70f0Sopenharmony_ci const char *res, *id; 261d5ac70f0Sopenharmony_ci char *def = NULL; 262d5ac70f0Sopenharmony_ci int idx = 0, err, hit; 263d5ac70f0Sopenharmony_ci 264d5ac70f0Sopenharmony_ci err = snd_config_search(src, "vars", &n); 265d5ac70f0Sopenharmony_ci if (err < 0) { 266d5ac70f0Sopenharmony_ci SNDERR("field vars not found"); 267d5ac70f0Sopenharmony_ci goto __error; 268d5ac70f0Sopenharmony_ci } 269d5ac70f0Sopenharmony_ci err = snd_config_evaluate(n, root, private_data, NULL); 270d5ac70f0Sopenharmony_ci if (err < 0) { 271d5ac70f0Sopenharmony_ci SNDERR("error evaluating vars"); 272d5ac70f0Sopenharmony_ci goto __error; 273d5ac70f0Sopenharmony_ci } 274d5ac70f0Sopenharmony_ci err = snd_config_search(src, "default", &d); 275d5ac70f0Sopenharmony_ci if (err < 0) { 276d5ac70f0Sopenharmony_ci SNDERR("field default not found"); 277d5ac70f0Sopenharmony_ci goto __error; 278d5ac70f0Sopenharmony_ci } 279d5ac70f0Sopenharmony_ci err = snd_config_evaluate(d, root, private_data, NULL); 280d5ac70f0Sopenharmony_ci if (err < 0) { 281d5ac70f0Sopenharmony_ci SNDERR("error evaluating default"); 282d5ac70f0Sopenharmony_ci goto __error; 283d5ac70f0Sopenharmony_ci } 284d5ac70f0Sopenharmony_ci err = snd_config_get_ascii(d, &def); 285d5ac70f0Sopenharmony_ci if (err < 0) { 286d5ac70f0Sopenharmony_ci SNDERR("error getting field default"); 287d5ac70f0Sopenharmony_ci goto __error; 288d5ac70f0Sopenharmony_ci } 289d5ac70f0Sopenharmony_ci do { 290d5ac70f0Sopenharmony_ci hit = 0; 291d5ac70f0Sopenharmony_ci snd_config_for_each(i, next, n) { 292d5ac70f0Sopenharmony_ci snd_config_t *n = snd_config_iterator_entry(i); 293d5ac70f0Sopenharmony_ci const char *ptr; 294d5ac70f0Sopenharmony_ci long i; 295d5ac70f0Sopenharmony_ci if (snd_config_get_id(n, &id) < 0) 296d5ac70f0Sopenharmony_ci continue; 297d5ac70f0Sopenharmony_ci if (snd_config_get_type(n) != SND_CONFIG_TYPE_STRING) { 298d5ac70f0Sopenharmony_ci SNDERR("field %s is not a string", id); 299d5ac70f0Sopenharmony_ci err = -EINVAL; 300d5ac70f0Sopenharmony_ci goto __error; 301d5ac70f0Sopenharmony_ci } 302d5ac70f0Sopenharmony_ci err = safe_strtol(id, &i); 303d5ac70f0Sopenharmony_ci if (err < 0) { 304d5ac70f0Sopenharmony_ci SNDERR("id of field %s is not an integer", id); 305d5ac70f0Sopenharmony_ci err = -EINVAL; 306d5ac70f0Sopenharmony_ci goto __error; 307d5ac70f0Sopenharmony_ci } 308d5ac70f0Sopenharmony_ci if (i == idx) { 309d5ac70f0Sopenharmony_ci idx++; 310d5ac70f0Sopenharmony_ci err = snd_config_get_string(n, &ptr); 311d5ac70f0Sopenharmony_ci if (err < 0) { 312d5ac70f0Sopenharmony_ci SNDERR("invalid string for id %s", id); 313d5ac70f0Sopenharmony_ci err = -EINVAL; 314d5ac70f0Sopenharmony_ci goto __error; 315d5ac70f0Sopenharmony_ci } 316d5ac70f0Sopenharmony_ci res = getenv(ptr); 317d5ac70f0Sopenharmony_ci if (res != NULL && *res != '\0') 318d5ac70f0Sopenharmony_ci goto __ok; 319d5ac70f0Sopenharmony_ci hit = 1; 320d5ac70f0Sopenharmony_ci } 321d5ac70f0Sopenharmony_ci } 322d5ac70f0Sopenharmony_ci } while (hit); 323d5ac70f0Sopenharmony_ci res = def; 324d5ac70f0Sopenharmony_ci __ok: 325d5ac70f0Sopenharmony_ci err = snd_config_get_id(src, &id); 326d5ac70f0Sopenharmony_ci if (err >= 0) 327d5ac70f0Sopenharmony_ci err = snd_config_imake_string(dst, id, res); 328d5ac70f0Sopenharmony_ci __error: 329d5ac70f0Sopenharmony_ci free(def); 330d5ac70f0Sopenharmony_ci return err; 331d5ac70f0Sopenharmony_ci} 332d5ac70f0Sopenharmony_ci#ifndef DOC_HIDDEN 333d5ac70f0Sopenharmony_ciSND_DLSYM_BUILD_VERSION(snd_func_getenv, SND_CONFIG_DLSYM_VERSION_EVALUATE); 334d5ac70f0Sopenharmony_ci#endif 335d5ac70f0Sopenharmony_ci 336d5ac70f0Sopenharmony_ci/** 337d5ac70f0Sopenharmony_ci * \brief Returns an integer environment value. 338d5ac70f0Sopenharmony_ci * \param dst The function puts the handle to the result configuration node 339d5ac70f0Sopenharmony_ci * (with type integer) at the address specified by \p dst. 340d5ac70f0Sopenharmony_ci * \param root Handle to the root source node. 341d5ac70f0Sopenharmony_ci * \param src Handle to the source node, with definitions for \c vars and 342d5ac70f0Sopenharmony_ci * \c default. 343d5ac70f0Sopenharmony_ci * \param private_data Handle to the \c private_data node. 344d5ac70f0Sopenharmony_ci * \return Zero if successful, otherwise a negative error code. 345d5ac70f0Sopenharmony_ci * 346d5ac70f0Sopenharmony_ci * Example: 347d5ac70f0Sopenharmony_ci\code 348d5ac70f0Sopenharmony_ci { 349d5ac70f0Sopenharmony_ci @func igetenv 350d5ac70f0Sopenharmony_ci vars [ MY_DEVICE DEVICE D ] 351d5ac70f0Sopenharmony_ci default 0 352d5ac70f0Sopenharmony_ci } 353d5ac70f0Sopenharmony_ci\endcode 354d5ac70f0Sopenharmony_ci */ 355d5ac70f0Sopenharmony_ciint snd_func_igetenv(snd_config_t **dst, snd_config_t *root, snd_config_t *src, 356d5ac70f0Sopenharmony_ci snd_config_t *private_data) 357d5ac70f0Sopenharmony_ci{ 358d5ac70f0Sopenharmony_ci snd_config_t *d; 359d5ac70f0Sopenharmony_ci const char *str, *id; 360d5ac70f0Sopenharmony_ci int err; 361d5ac70f0Sopenharmony_ci long v; 362d5ac70f0Sopenharmony_ci 363d5ac70f0Sopenharmony_ci err = snd_func_getenv(&d, root, src, private_data); 364d5ac70f0Sopenharmony_ci if (err < 0) 365d5ac70f0Sopenharmony_ci return err; 366d5ac70f0Sopenharmony_ci err = snd_config_get_string(d, &str); 367d5ac70f0Sopenharmony_ci if (err < 0) { 368d5ac70f0Sopenharmony_ci snd_config_delete(d); 369d5ac70f0Sopenharmony_ci return err; 370d5ac70f0Sopenharmony_ci } 371d5ac70f0Sopenharmony_ci err = safe_strtol(str, &v); 372d5ac70f0Sopenharmony_ci if (err < 0) { 373d5ac70f0Sopenharmony_ci snd_config_delete(d); 374d5ac70f0Sopenharmony_ci return err; 375d5ac70f0Sopenharmony_ci } 376d5ac70f0Sopenharmony_ci snd_config_delete(d); 377d5ac70f0Sopenharmony_ci err = snd_config_get_id(src, &id); 378d5ac70f0Sopenharmony_ci if (err < 0) 379d5ac70f0Sopenharmony_ci return err; 380d5ac70f0Sopenharmony_ci err = snd_config_imake_integer(dst, id, v); 381d5ac70f0Sopenharmony_ci if (err < 0) 382d5ac70f0Sopenharmony_ci return err; 383d5ac70f0Sopenharmony_ci return 0; 384d5ac70f0Sopenharmony_ci} 385d5ac70f0Sopenharmony_ci#ifndef DOC_HIDDEN 386d5ac70f0Sopenharmony_ciSND_DLSYM_BUILD_VERSION(snd_func_igetenv, SND_CONFIG_DLSYM_VERSION_EVALUATE); 387d5ac70f0Sopenharmony_ci#endif 388d5ac70f0Sopenharmony_ci 389d5ac70f0Sopenharmony_ci/** 390d5ac70f0Sopenharmony_ci * \brief Merges the given strings. 391d5ac70f0Sopenharmony_ci * \param dst The function puts the handle to the result configuration node 392d5ac70f0Sopenharmony_ci * (with type string) at the address specified by \p dst. 393d5ac70f0Sopenharmony_ci * \param root Handle to the root source node. 394d5ac70f0Sopenharmony_ci * \param src Handle to the source node, with a definition for \c strings. 395d5ac70f0Sopenharmony_ci * \param private_data Handle to the \c private_data node. 396d5ac70f0Sopenharmony_ci * \return A non-negative value if successful, otherwise a negative error code. 397d5ac70f0Sopenharmony_ci * 398d5ac70f0Sopenharmony_ci * Example (result is "a1b2c3"): 399d5ac70f0Sopenharmony_ci\code 400d5ac70f0Sopenharmony_ci { 401d5ac70f0Sopenharmony_ci @func concat 402d5ac70f0Sopenharmony_ci strings [ "a1" "b2" "c3" ] 403d5ac70f0Sopenharmony_ci } 404d5ac70f0Sopenharmony_ci\endcode 405d5ac70f0Sopenharmony_ci */ 406d5ac70f0Sopenharmony_ciint snd_func_concat(snd_config_t **dst, snd_config_t *root, snd_config_t *src, 407d5ac70f0Sopenharmony_ci snd_config_t *private_data) 408d5ac70f0Sopenharmony_ci{ 409d5ac70f0Sopenharmony_ci snd_config_t *n; 410d5ac70f0Sopenharmony_ci snd_config_iterator_t i, next; 411d5ac70f0Sopenharmony_ci const char *id; 412d5ac70f0Sopenharmony_ci char *res = NULL, *tmp; 413d5ac70f0Sopenharmony_ci int idx = 0, len = 0, len1, err, hit; 414d5ac70f0Sopenharmony_ci 415d5ac70f0Sopenharmony_ci err = snd_config_search(src, "strings", &n); 416d5ac70f0Sopenharmony_ci if (err < 0) { 417d5ac70f0Sopenharmony_ci SNDERR("field strings not found"); 418d5ac70f0Sopenharmony_ci goto __error; 419d5ac70f0Sopenharmony_ci } 420d5ac70f0Sopenharmony_ci err = snd_config_evaluate(n, root, private_data, NULL); 421d5ac70f0Sopenharmony_ci if (err < 0) { 422d5ac70f0Sopenharmony_ci SNDERR("error evaluating strings"); 423d5ac70f0Sopenharmony_ci goto __error; 424d5ac70f0Sopenharmony_ci } 425d5ac70f0Sopenharmony_ci do { 426d5ac70f0Sopenharmony_ci hit = 0; 427d5ac70f0Sopenharmony_ci snd_config_for_each(i, next, n) { 428d5ac70f0Sopenharmony_ci snd_config_t *n = snd_config_iterator_entry(i); 429d5ac70f0Sopenharmony_ci char *ptr; 430d5ac70f0Sopenharmony_ci const char *id; 431d5ac70f0Sopenharmony_ci long i; 432d5ac70f0Sopenharmony_ci if (snd_config_get_id(n, &id) < 0) 433d5ac70f0Sopenharmony_ci continue; 434d5ac70f0Sopenharmony_ci err = safe_strtol(id, &i); 435d5ac70f0Sopenharmony_ci if (err < 0) { 436d5ac70f0Sopenharmony_ci SNDERR("id of field %s is not an integer", id); 437d5ac70f0Sopenharmony_ci err = -EINVAL; 438d5ac70f0Sopenharmony_ci goto __error; 439d5ac70f0Sopenharmony_ci } 440d5ac70f0Sopenharmony_ci if (i == idx) { 441d5ac70f0Sopenharmony_ci idx++; 442d5ac70f0Sopenharmony_ci err = snd_config_get_ascii(n, &ptr); 443d5ac70f0Sopenharmony_ci if (err < 0) { 444d5ac70f0Sopenharmony_ci SNDERR("invalid ascii string for id %s", id); 445d5ac70f0Sopenharmony_ci err = -EINVAL; 446d5ac70f0Sopenharmony_ci goto __error; 447d5ac70f0Sopenharmony_ci } 448d5ac70f0Sopenharmony_ci len1 = strlen(ptr); 449d5ac70f0Sopenharmony_ci tmp = realloc(res, len + len1 + 1); 450d5ac70f0Sopenharmony_ci if (tmp == NULL) { 451d5ac70f0Sopenharmony_ci free(ptr); 452d5ac70f0Sopenharmony_ci err = -ENOMEM; 453d5ac70f0Sopenharmony_ci goto __error; 454d5ac70f0Sopenharmony_ci } 455d5ac70f0Sopenharmony_ci memcpy(tmp + len, ptr, len1); 456d5ac70f0Sopenharmony_ci free(ptr); 457d5ac70f0Sopenharmony_ci len += len1; 458d5ac70f0Sopenharmony_ci tmp[len] = '\0'; 459d5ac70f0Sopenharmony_ci res = tmp; 460d5ac70f0Sopenharmony_ci hit = 1; 461d5ac70f0Sopenharmony_ci } 462d5ac70f0Sopenharmony_ci } 463d5ac70f0Sopenharmony_ci } while (hit); 464d5ac70f0Sopenharmony_ci if (res == NULL) { 465d5ac70f0Sopenharmony_ci SNDERR("empty string is not accepted"); 466d5ac70f0Sopenharmony_ci err = -EINVAL; 467d5ac70f0Sopenharmony_ci goto __error; 468d5ac70f0Sopenharmony_ci } 469d5ac70f0Sopenharmony_ci err = snd_config_get_id(src, &id); 470d5ac70f0Sopenharmony_ci if (err >= 0) 471d5ac70f0Sopenharmony_ci err = snd_config_imake_string(dst, id, res); 472d5ac70f0Sopenharmony_ci __error: 473d5ac70f0Sopenharmony_ci free(res); 474d5ac70f0Sopenharmony_ci return err; 475d5ac70f0Sopenharmony_ci} 476d5ac70f0Sopenharmony_ci#ifndef DOC_HIDDEN 477d5ac70f0Sopenharmony_ciSND_DLSYM_BUILD_VERSION(snd_func_concat, SND_CONFIG_DLSYM_VERSION_EVALUATE); 478d5ac70f0Sopenharmony_ci#endif 479d5ac70f0Sopenharmony_ci 480d5ac70f0Sopenharmony_ci 481d5ac70f0Sopenharmony_cistatic int snd_func_iops(snd_config_t **dst, 482d5ac70f0Sopenharmony_ci snd_config_t *root, 483d5ac70f0Sopenharmony_ci snd_config_t *src, 484d5ac70f0Sopenharmony_ci snd_config_t *private_data, 485d5ac70f0Sopenharmony_ci int op) 486d5ac70f0Sopenharmony_ci{ 487d5ac70f0Sopenharmony_ci snd_config_t *n; 488d5ac70f0Sopenharmony_ci snd_config_iterator_t i, next; 489d5ac70f0Sopenharmony_ci const char *id; 490d5ac70f0Sopenharmony_ci char *res = NULL; 491d5ac70f0Sopenharmony_ci long result = 0, val; 492d5ac70f0Sopenharmony_ci int idx = 0, err, hit; 493d5ac70f0Sopenharmony_ci 494d5ac70f0Sopenharmony_ci err = snd_config_search(src, "integers", &n); 495d5ac70f0Sopenharmony_ci if (err < 0) { 496d5ac70f0Sopenharmony_ci SNDERR("field integers not found"); 497d5ac70f0Sopenharmony_ci goto __error; 498d5ac70f0Sopenharmony_ci } 499d5ac70f0Sopenharmony_ci err = snd_config_evaluate(n, root, private_data, NULL); 500d5ac70f0Sopenharmony_ci if (err < 0) { 501d5ac70f0Sopenharmony_ci SNDERR("error evaluating integers"); 502d5ac70f0Sopenharmony_ci goto __error; 503d5ac70f0Sopenharmony_ci } 504d5ac70f0Sopenharmony_ci do { 505d5ac70f0Sopenharmony_ci hit = 0; 506d5ac70f0Sopenharmony_ci snd_config_for_each(i, next, n) { 507d5ac70f0Sopenharmony_ci snd_config_t *n = snd_config_iterator_entry(i); 508d5ac70f0Sopenharmony_ci const char *id; 509d5ac70f0Sopenharmony_ci long i; 510d5ac70f0Sopenharmony_ci if (snd_config_get_id(n, &id) < 0) 511d5ac70f0Sopenharmony_ci continue; 512d5ac70f0Sopenharmony_ci err = safe_strtol(id, &i); 513d5ac70f0Sopenharmony_ci if (err < 0) { 514d5ac70f0Sopenharmony_ci SNDERR("id of field %s is not an integer", id); 515d5ac70f0Sopenharmony_ci err = -EINVAL; 516d5ac70f0Sopenharmony_ci goto __error; 517d5ac70f0Sopenharmony_ci } 518d5ac70f0Sopenharmony_ci if (i == idx) { 519d5ac70f0Sopenharmony_ci idx++; 520d5ac70f0Sopenharmony_ci err = snd_config_get_integer(n, &val); 521d5ac70f0Sopenharmony_ci if (err < 0) { 522d5ac70f0Sopenharmony_ci SNDERR("invalid integer for id %s", id); 523d5ac70f0Sopenharmony_ci err = -EINVAL; 524d5ac70f0Sopenharmony_ci goto __error; 525d5ac70f0Sopenharmony_ci } 526d5ac70f0Sopenharmony_ci switch (op) { 527d5ac70f0Sopenharmony_ci case 0: result += val; break; 528d5ac70f0Sopenharmony_ci case 1: result *= val; break; 529d5ac70f0Sopenharmony_ci } 530d5ac70f0Sopenharmony_ci hit = 1; 531d5ac70f0Sopenharmony_ci } 532d5ac70f0Sopenharmony_ci } 533d5ac70f0Sopenharmony_ci } while (hit); 534d5ac70f0Sopenharmony_ci err = snd_config_get_id(src, &id); 535d5ac70f0Sopenharmony_ci if (err >= 0) 536d5ac70f0Sopenharmony_ci err = snd_config_imake_integer(dst, id, result); 537d5ac70f0Sopenharmony_ci free(res); 538d5ac70f0Sopenharmony_ci __error: 539d5ac70f0Sopenharmony_ci return err; 540d5ac70f0Sopenharmony_ci} 541d5ac70f0Sopenharmony_ci 542d5ac70f0Sopenharmony_ci 543d5ac70f0Sopenharmony_ci/** 544d5ac70f0Sopenharmony_ci * \brief Sum the given integers. 545d5ac70f0Sopenharmony_ci * \param dst The function puts the handle to the result configuration node 546d5ac70f0Sopenharmony_ci * (with type integer) at the address specified by \p dst. 547d5ac70f0Sopenharmony_ci * \param root Handle to the root source node. 548d5ac70f0Sopenharmony_ci * \param src Handle to the source node, with a definition for \c integers. 549d5ac70f0Sopenharmony_ci * \param private_data Handle to the \c private_data node. 550d5ac70f0Sopenharmony_ci * \return A non-negative value if successful, otherwise a negative error code. 551d5ac70f0Sopenharmony_ci * 552d5ac70f0Sopenharmony_ci * Example (result is 10): 553d5ac70f0Sopenharmony_ci\code 554d5ac70f0Sopenharmony_ci { 555d5ac70f0Sopenharmony_ci @func iadd 556d5ac70f0Sopenharmony_ci integers [ 2 3 5 ] 557d5ac70f0Sopenharmony_ci } 558d5ac70f0Sopenharmony_ci\endcode 559d5ac70f0Sopenharmony_ci */ 560d5ac70f0Sopenharmony_ciint snd_func_iadd(snd_config_t **dst, snd_config_t *root, 561d5ac70f0Sopenharmony_ci snd_config_t *src, snd_config_t *private_data) 562d5ac70f0Sopenharmony_ci{ 563d5ac70f0Sopenharmony_ci return snd_func_iops(dst, root, src, private_data, 0); 564d5ac70f0Sopenharmony_ci} 565d5ac70f0Sopenharmony_ci#ifndef DOC_HIDDEN 566d5ac70f0Sopenharmony_ciSND_DLSYM_BUILD_VERSION(snd_func_iadd, SND_CONFIG_DLSYM_VERSION_EVALUATE); 567d5ac70f0Sopenharmony_ci#endif 568d5ac70f0Sopenharmony_ci 569d5ac70f0Sopenharmony_ci/** 570d5ac70f0Sopenharmony_ci * \brief Multiply the given integers. 571d5ac70f0Sopenharmony_ci * \param dst The function puts the handle to the result configuration node 572d5ac70f0Sopenharmony_ci * (with type integer) at the address specified by \p dst. 573d5ac70f0Sopenharmony_ci * \param root Handle to the root source node. 574d5ac70f0Sopenharmony_ci * \param src Handle to the source node, with a definition for \c integers. 575d5ac70f0Sopenharmony_ci * \param private_data Handle to the \c private_data node. 576d5ac70f0Sopenharmony_ci * \return A non-negative value if successful, otherwise a negative error code. 577d5ac70f0Sopenharmony_ci * 578d5ac70f0Sopenharmony_ci * Example (result is 12): 579d5ac70f0Sopenharmony_ci\code 580d5ac70f0Sopenharmony_ci { 581d5ac70f0Sopenharmony_ci @func imul 582d5ac70f0Sopenharmony_ci integers [ 2 3 2 ] 583d5ac70f0Sopenharmony_ci } 584d5ac70f0Sopenharmony_ci\endcode 585d5ac70f0Sopenharmony_ci */ 586d5ac70f0Sopenharmony_ciint snd_func_imul(snd_config_t **dst, snd_config_t *root, 587d5ac70f0Sopenharmony_ci snd_config_t *src, snd_config_t *private_data) 588d5ac70f0Sopenharmony_ci{ 589d5ac70f0Sopenharmony_ci return snd_func_iops(dst, root, src, private_data, 1); 590d5ac70f0Sopenharmony_ci} 591d5ac70f0Sopenharmony_ci#ifndef DOC_HIDDEN 592d5ac70f0Sopenharmony_ciSND_DLSYM_BUILD_VERSION(snd_func_imul, SND_CONFIG_DLSYM_VERSION_EVALUATE); 593d5ac70f0Sopenharmony_ci#endif 594d5ac70f0Sopenharmony_ci 595d5ac70f0Sopenharmony_ci/** 596d5ac70f0Sopenharmony_ci * \brief Returns the ALSA data directory. 597d5ac70f0Sopenharmony_ci * \param dst The function puts the handle to the result configuration node 598d5ac70f0Sopenharmony_ci * (with type string) at the address specified by \p dst. 599d5ac70f0Sopenharmony_ci * \param root Handle to the root source node. 600d5ac70f0Sopenharmony_ci * \param src Handle to the source node. 601d5ac70f0Sopenharmony_ci * \param private_data Handle to the \c private_data node. Not used. 602d5ac70f0Sopenharmony_ci * \return A non-negative value if successful, otherwise a negative error code. 603d5ac70f0Sopenharmony_ci * 604d5ac70f0Sopenharmony_ci * Example (result is "/usr/share/alsa" using the default paths): 605d5ac70f0Sopenharmony_ci\code 606d5ac70f0Sopenharmony_ci { 607d5ac70f0Sopenharmony_ci @func datadir 608d5ac70f0Sopenharmony_ci } 609d5ac70f0Sopenharmony_ci\endcode 610d5ac70f0Sopenharmony_ci */ 611d5ac70f0Sopenharmony_ciint snd_func_datadir(snd_config_t **dst, snd_config_t *root ATTRIBUTE_UNUSED, 612d5ac70f0Sopenharmony_ci snd_config_t *src, snd_config_t *private_data ATTRIBUTE_UNUSED) 613d5ac70f0Sopenharmony_ci{ 614d5ac70f0Sopenharmony_ci int err; 615d5ac70f0Sopenharmony_ci const char *id; 616d5ac70f0Sopenharmony_ci 617d5ac70f0Sopenharmony_ci err = snd_config_get_id(src, &id); 618d5ac70f0Sopenharmony_ci if (err < 0) 619d5ac70f0Sopenharmony_ci return err; 620d5ac70f0Sopenharmony_ci return snd_config_imake_string(dst, id, snd_config_topdir()); 621d5ac70f0Sopenharmony_ci} 622d5ac70f0Sopenharmony_ci#ifndef DOC_HIDDEN 623d5ac70f0Sopenharmony_ciSND_DLSYM_BUILD_VERSION(snd_func_datadir, SND_CONFIG_DLSYM_VERSION_EVALUATE); 624d5ac70f0Sopenharmony_ci#endif 625d5ac70f0Sopenharmony_ci 626d5ac70f0Sopenharmony_cistatic int open_ctl(long card, snd_ctl_t **ctl) 627d5ac70f0Sopenharmony_ci{ 628d5ac70f0Sopenharmony_ci char name[16]; 629d5ac70f0Sopenharmony_ci snprintf(name, sizeof(name), "hw:%li", card); 630d5ac70f0Sopenharmony_ci name[sizeof(name)-1] = '\0'; 631d5ac70f0Sopenharmony_ci return snd_ctl_open(ctl, name, 0); 632d5ac70f0Sopenharmony_ci} 633d5ac70f0Sopenharmony_ci 634d5ac70f0Sopenharmony_ci#if 0 635d5ac70f0Sopenharmony_cistatic int string_from_integer(char **dst, long v) 636d5ac70f0Sopenharmony_ci{ 637d5ac70f0Sopenharmony_ci char str[32]; 638d5ac70f0Sopenharmony_ci char *res; 639d5ac70f0Sopenharmony_ci sprintf(str, "%li", v); 640d5ac70f0Sopenharmony_ci res = strdup(str); 641d5ac70f0Sopenharmony_ci if (res == NULL) 642d5ac70f0Sopenharmony_ci return -ENOMEM; 643d5ac70f0Sopenharmony_ci *dst = res; 644d5ac70f0Sopenharmony_ci return 0; 645d5ac70f0Sopenharmony_ci} 646d5ac70f0Sopenharmony_ci#endif 647d5ac70f0Sopenharmony_ci 648d5ac70f0Sopenharmony_cistatic int _snd_func_private_data(snd_config_t **dst, snd_config_t *src, 649d5ac70f0Sopenharmony_ci snd_config_t **private_data, const char *id) 650d5ac70f0Sopenharmony_ci{ 651d5ac70f0Sopenharmony_ci int err; 652d5ac70f0Sopenharmony_ci 653d5ac70f0Sopenharmony_ci if (*private_data == NULL) 654d5ac70f0Sopenharmony_ci return snd_config_copy(dst, src); 655d5ac70f0Sopenharmony_ci if (snd_config_get_type(*private_data) == SND_CONFIG_TYPE_COMPOUND) { 656d5ac70f0Sopenharmony_ci err = snd_config_search(*private_data, id, private_data); 657d5ac70f0Sopenharmony_ci if (err) 658d5ac70f0Sopenharmony_ci goto notfound; 659d5ac70f0Sopenharmony_ci } 660d5ac70f0Sopenharmony_ci err = snd_config_test_id(*private_data, id); 661d5ac70f0Sopenharmony_ci if (err) { 662d5ac70f0Sopenharmony_cinotfound: 663d5ac70f0Sopenharmony_ci SNDERR("field %s not found", id); 664d5ac70f0Sopenharmony_ci return -EINVAL; 665d5ac70f0Sopenharmony_ci } 666d5ac70f0Sopenharmony_ci return 0; 667d5ac70f0Sopenharmony_ci} 668d5ac70f0Sopenharmony_ci 669d5ac70f0Sopenharmony_ci 670d5ac70f0Sopenharmony_ci/** 671d5ac70f0Sopenharmony_ci * \brief Returns the string from \c private_data. 672d5ac70f0Sopenharmony_ci * \param dst The function puts the handle to the result configuration node 673d5ac70f0Sopenharmony_ci * (with type string) at the address specified by \p dst. 674d5ac70f0Sopenharmony_ci * \param root Handle to the root source node. 675d5ac70f0Sopenharmony_ci * \param src Handle to the source node. 676d5ac70f0Sopenharmony_ci * \param private_data Handle to the \c private_data node (type string, 677d5ac70f0Sopenharmony_ci * id "string"). 678d5ac70f0Sopenharmony_ci * \return A non-negative value if successful, otherwise a negative error code. 679d5ac70f0Sopenharmony_ci * 680d5ac70f0Sopenharmony_ci * Example: 681d5ac70f0Sopenharmony_ci\code 682d5ac70f0Sopenharmony_ci { 683d5ac70f0Sopenharmony_ci @func private_string 684d5ac70f0Sopenharmony_ci } 685d5ac70f0Sopenharmony_ci\endcode 686d5ac70f0Sopenharmony_ci */ 687d5ac70f0Sopenharmony_ciint snd_func_private_string(snd_config_t **dst, snd_config_t *root ATTRIBUTE_UNUSED, 688d5ac70f0Sopenharmony_ci snd_config_t *src, snd_config_t *private_data) 689d5ac70f0Sopenharmony_ci{ 690d5ac70f0Sopenharmony_ci int err; 691d5ac70f0Sopenharmony_ci const char *str, *id; 692d5ac70f0Sopenharmony_ci 693d5ac70f0Sopenharmony_ci err = _snd_func_private_data(dst, src, &private_data, "string"); 694d5ac70f0Sopenharmony_ci if (err) 695d5ac70f0Sopenharmony_ci return err; 696d5ac70f0Sopenharmony_ci err = snd_config_get_string(private_data, &str); 697d5ac70f0Sopenharmony_ci if (err < 0) { 698d5ac70f0Sopenharmony_ci SNDERR("field string is not a string"); 699d5ac70f0Sopenharmony_ci return err; 700d5ac70f0Sopenharmony_ci } 701d5ac70f0Sopenharmony_ci err = snd_config_get_id(src, &id); 702d5ac70f0Sopenharmony_ci if (err >= 0) 703d5ac70f0Sopenharmony_ci err = snd_config_imake_string(dst, id, str); 704d5ac70f0Sopenharmony_ci return err; 705d5ac70f0Sopenharmony_ci} 706d5ac70f0Sopenharmony_ci#ifndef DOC_HIDDEN 707d5ac70f0Sopenharmony_ciSND_DLSYM_BUILD_VERSION(snd_func_private_string, SND_CONFIG_DLSYM_VERSION_EVALUATE); 708d5ac70f0Sopenharmony_ci#endif 709d5ac70f0Sopenharmony_ci 710d5ac70f0Sopenharmony_ci/** 711d5ac70f0Sopenharmony_ci * \brief Returns the integer from \c private_data. 712d5ac70f0Sopenharmony_ci * \param dst The function puts the handle to the result configuration node 713d5ac70f0Sopenharmony_ci * (with type integer) at the address specified by \p dst. 714d5ac70f0Sopenharmony_ci * \param root Handle to the root source node. 715d5ac70f0Sopenharmony_ci * \param src Handle to the source node. 716d5ac70f0Sopenharmony_ci * \param private_data Handle to the \c private_data node (type integer, 717d5ac70f0Sopenharmony_ci * id "integer"). 718d5ac70f0Sopenharmony_ci * \return A non-negative value if successful, otherwise a negative error code. 719d5ac70f0Sopenharmony_ci * 720d5ac70f0Sopenharmony_ci * Example: 721d5ac70f0Sopenharmony_ci\code 722d5ac70f0Sopenharmony_ci { 723d5ac70f0Sopenharmony_ci @func private_integer 724d5ac70f0Sopenharmony_ci } 725d5ac70f0Sopenharmony_ci\endcode 726d5ac70f0Sopenharmony_ci */ 727d5ac70f0Sopenharmony_ciint snd_func_private_integer(snd_config_t **dst, snd_config_t *root ATTRIBUTE_UNUSED, 728d5ac70f0Sopenharmony_ci snd_config_t *src, snd_config_t *private_data) 729d5ac70f0Sopenharmony_ci{ 730d5ac70f0Sopenharmony_ci int err; 731d5ac70f0Sopenharmony_ci const char *id; 732d5ac70f0Sopenharmony_ci long val; 733d5ac70f0Sopenharmony_ci 734d5ac70f0Sopenharmony_ci err = _snd_func_private_data(dst, src, &private_data, "integer"); 735d5ac70f0Sopenharmony_ci if (err) 736d5ac70f0Sopenharmony_ci return err; 737d5ac70f0Sopenharmony_ci err = snd_config_get_integer(private_data, &val); 738d5ac70f0Sopenharmony_ci if (err < 0) { 739d5ac70f0Sopenharmony_ci SNDERR("field integer is not a string"); 740d5ac70f0Sopenharmony_ci return err; 741d5ac70f0Sopenharmony_ci } 742d5ac70f0Sopenharmony_ci err = snd_config_get_id(src, &id); 743d5ac70f0Sopenharmony_ci if (err >= 0) 744d5ac70f0Sopenharmony_ci err = snd_config_imake_integer(dst, id, val); 745d5ac70f0Sopenharmony_ci return err; 746d5ac70f0Sopenharmony_ci} 747d5ac70f0Sopenharmony_ci#ifndef DOC_HIDDEN 748d5ac70f0Sopenharmony_ciSND_DLSYM_BUILD_VERSION(snd_func_private_integer, SND_CONFIG_DLSYM_VERSION_EVALUATE); 749d5ac70f0Sopenharmony_ci#endif 750d5ac70f0Sopenharmony_ci 751d5ac70f0Sopenharmony_ci#ifndef DOC_HIDDEN 752d5ac70f0Sopenharmony_ciint snd_determine_driver(int card, char **driver) 753d5ac70f0Sopenharmony_ci{ 754d5ac70f0Sopenharmony_ci snd_ctl_t *ctl = NULL; 755d5ac70f0Sopenharmony_ci snd_ctl_card_info_t info = {0}; 756d5ac70f0Sopenharmony_ci char *res = NULL; 757d5ac70f0Sopenharmony_ci int err; 758d5ac70f0Sopenharmony_ci 759d5ac70f0Sopenharmony_ci assert(card >= 0 && card <= SND_MAX_CARDS); 760d5ac70f0Sopenharmony_ci err = open_ctl(card, &ctl); 761d5ac70f0Sopenharmony_ci if (err < 0) { 762d5ac70f0Sopenharmony_ci SNDERR("could not open control for card %i", card); 763d5ac70f0Sopenharmony_ci goto __error; 764d5ac70f0Sopenharmony_ci } 765d5ac70f0Sopenharmony_ci err = snd_ctl_card_info(ctl, &info); 766d5ac70f0Sopenharmony_ci if (err < 0) { 767d5ac70f0Sopenharmony_ci SNDERR("snd_ctl_card_info error: %s", snd_strerror(err)); 768d5ac70f0Sopenharmony_ci goto __error; 769d5ac70f0Sopenharmony_ci } 770d5ac70f0Sopenharmony_ci res = strdup(snd_ctl_card_info_get_driver(&info)); 771d5ac70f0Sopenharmony_ci if (res == NULL) 772d5ac70f0Sopenharmony_ci err = -ENOMEM; 773d5ac70f0Sopenharmony_ci else { 774d5ac70f0Sopenharmony_ci *driver = res; 775d5ac70f0Sopenharmony_ci err = 0; 776d5ac70f0Sopenharmony_ci } 777d5ac70f0Sopenharmony_ci __error: 778d5ac70f0Sopenharmony_ci if (ctl) 779d5ac70f0Sopenharmony_ci snd_ctl_close(ctl); 780d5ac70f0Sopenharmony_ci return err; 781d5ac70f0Sopenharmony_ci} 782d5ac70f0Sopenharmony_ci#endif 783d5ac70f0Sopenharmony_ci 784d5ac70f0Sopenharmony_ci/** 785d5ac70f0Sopenharmony_ci * \brief Returns the driver identification from \c private_data. 786d5ac70f0Sopenharmony_ci * \param dst The function puts the handle to the result configuration node 787d5ac70f0Sopenharmony_ci * (with type string) at the address specified by \p dst. 788d5ac70f0Sopenharmony_ci * \param root Handle to the root source node. 789d5ac70f0Sopenharmony_ci * \param src Handle to the source node. 790d5ac70f0Sopenharmony_ci * \param private_data Handle to the \c private_data node (type integer, 791d5ac70f0Sopenharmony_ci * id "card"). 792d5ac70f0Sopenharmony_ci * \return A non-negative value if successful, otherwise a negative error code. 793d5ac70f0Sopenharmony_ci * 794d5ac70f0Sopenharmony_ci * Example: 795d5ac70f0Sopenharmony_ci\code 796d5ac70f0Sopenharmony_ci { 797d5ac70f0Sopenharmony_ci @func private_card_driver 798d5ac70f0Sopenharmony_ci } 799d5ac70f0Sopenharmony_ci\endcode 800d5ac70f0Sopenharmony_ci */ 801d5ac70f0Sopenharmony_ciint snd_func_private_card_driver(snd_config_t **dst, snd_config_t *root ATTRIBUTE_UNUSED, snd_config_t *src, 802d5ac70f0Sopenharmony_ci snd_config_t *private_data) 803d5ac70f0Sopenharmony_ci{ 804d5ac70f0Sopenharmony_ci char *driver; 805d5ac70f0Sopenharmony_ci const char *id; 806d5ac70f0Sopenharmony_ci int err; 807d5ac70f0Sopenharmony_ci long card; 808d5ac70f0Sopenharmony_ci 809d5ac70f0Sopenharmony_ci err = snd_config_test_id(private_data, "card"); 810d5ac70f0Sopenharmony_ci if (err) { 811d5ac70f0Sopenharmony_ci SNDERR("field card not found"); 812d5ac70f0Sopenharmony_ci return -EINVAL; 813d5ac70f0Sopenharmony_ci } 814d5ac70f0Sopenharmony_ci err = snd_config_get_integer(private_data, &card); 815d5ac70f0Sopenharmony_ci if (err < 0) { 816d5ac70f0Sopenharmony_ci SNDERR("field card is not an integer"); 817d5ac70f0Sopenharmony_ci return err; 818d5ac70f0Sopenharmony_ci } 819d5ac70f0Sopenharmony_ci if ((err = snd_determine_driver(card, &driver)) < 0) 820d5ac70f0Sopenharmony_ci return err; 821d5ac70f0Sopenharmony_ci err = snd_config_get_id(src, &id); 822d5ac70f0Sopenharmony_ci if (err >= 0) 823d5ac70f0Sopenharmony_ci err = snd_config_imake_string(dst, id, driver); 824d5ac70f0Sopenharmony_ci free(driver); 825d5ac70f0Sopenharmony_ci return err; 826d5ac70f0Sopenharmony_ci} 827d5ac70f0Sopenharmony_ci#ifndef DOC_HIDDEN 828d5ac70f0Sopenharmony_ciSND_DLSYM_BUILD_VERSION(snd_func_private_card_driver, SND_CONFIG_DLSYM_VERSION_EVALUATE); 829d5ac70f0Sopenharmony_ci#endif 830d5ac70f0Sopenharmony_ci 831d5ac70f0Sopenharmony_cistatic int parse_card(snd_config_t *root, snd_config_t *src, 832d5ac70f0Sopenharmony_ci snd_config_t *private_data) 833d5ac70f0Sopenharmony_ci{ 834d5ac70f0Sopenharmony_ci snd_config_t *n; 835d5ac70f0Sopenharmony_ci char *str; 836d5ac70f0Sopenharmony_ci int card, err; 837d5ac70f0Sopenharmony_ci 838d5ac70f0Sopenharmony_ci err = snd_config_search(src, "card", &n); 839d5ac70f0Sopenharmony_ci if (err < 0) { 840d5ac70f0Sopenharmony_ci SNDERR("field card not found"); 841d5ac70f0Sopenharmony_ci return err; 842d5ac70f0Sopenharmony_ci } 843d5ac70f0Sopenharmony_ci err = snd_config_evaluate(n, root, private_data, NULL); 844d5ac70f0Sopenharmony_ci if (err < 0) { 845d5ac70f0Sopenharmony_ci SNDERR("error evaluating card"); 846d5ac70f0Sopenharmony_ci return err; 847d5ac70f0Sopenharmony_ci } 848d5ac70f0Sopenharmony_ci err = snd_config_get_ascii(n, &str); 849d5ac70f0Sopenharmony_ci if (err < 0) { 850d5ac70f0Sopenharmony_ci SNDERR("field card is not an integer or a string"); 851d5ac70f0Sopenharmony_ci return err; 852d5ac70f0Sopenharmony_ci } 853d5ac70f0Sopenharmony_ci card = snd_card_get_index(str); 854d5ac70f0Sopenharmony_ci if (card < 0) 855d5ac70f0Sopenharmony_ci SNDERR("cannot find card '%s'", str); 856d5ac70f0Sopenharmony_ci free(str); 857d5ac70f0Sopenharmony_ci return card; 858d5ac70f0Sopenharmony_ci} 859d5ac70f0Sopenharmony_ci 860d5ac70f0Sopenharmony_ci/** 861d5ac70f0Sopenharmony_ci * \brief Returns the card number as integer. 862d5ac70f0Sopenharmony_ci * \param dst The function puts the handle to the result configuration node 863d5ac70f0Sopenharmony_ci * (with type string) at the address specified by \p dst. 864d5ac70f0Sopenharmony_ci * \param root Handle to the root source node. 865d5ac70f0Sopenharmony_ci * \param src Handle to the source node, with a \c card definition. 866d5ac70f0Sopenharmony_ci * \param private_data Handle to the \c private_data node. 867d5ac70f0Sopenharmony_ci * \return A non-negative value if successful, otherwise a negative error code. 868d5ac70f0Sopenharmony_ci * 869d5ac70f0Sopenharmony_ci * Example: 870d5ac70f0Sopenharmony_ci\code 871d5ac70f0Sopenharmony_ci { 872d5ac70f0Sopenharmony_ci @func card_inum 873d5ac70f0Sopenharmony_ci card '0' 874d5ac70f0Sopenharmony_ci } 875d5ac70f0Sopenharmony_ci\endcode 876d5ac70f0Sopenharmony_ci */ 877d5ac70f0Sopenharmony_ciint snd_func_card_inum(snd_config_t **dst, snd_config_t *root, snd_config_t *src, 878d5ac70f0Sopenharmony_ci snd_config_t *private_data) 879d5ac70f0Sopenharmony_ci{ 880d5ac70f0Sopenharmony_ci const char *id; 881d5ac70f0Sopenharmony_ci int card, err; 882d5ac70f0Sopenharmony_ci 883d5ac70f0Sopenharmony_ci card = parse_card(root, src, private_data); 884d5ac70f0Sopenharmony_ci if (card < 0) 885d5ac70f0Sopenharmony_ci return card; 886d5ac70f0Sopenharmony_ci err = snd_config_get_id(src, &id); 887d5ac70f0Sopenharmony_ci if (err >= 0) 888d5ac70f0Sopenharmony_ci err = snd_config_imake_integer(dst, id, card); 889d5ac70f0Sopenharmony_ci return err; 890d5ac70f0Sopenharmony_ci} 891d5ac70f0Sopenharmony_ci#ifndef DOC_HIDDEN 892d5ac70f0Sopenharmony_ciSND_DLSYM_BUILD_VERSION(snd_func_card_inum, SND_CONFIG_DLSYM_VERSION_EVALUATE); 893d5ac70f0Sopenharmony_ci#endif 894d5ac70f0Sopenharmony_ci 895d5ac70f0Sopenharmony_ci/** 896d5ac70f0Sopenharmony_ci * \brief Returns the driver identification for a card. 897d5ac70f0Sopenharmony_ci * \param dst The function puts the handle to the result configuration node 898d5ac70f0Sopenharmony_ci * (with type string) at the address specified by \p dst. 899d5ac70f0Sopenharmony_ci * \param root Handle to the root source node. 900d5ac70f0Sopenharmony_ci * \param src Handle to the source node, with a \c card definition. 901d5ac70f0Sopenharmony_ci * \param private_data Handle to the \c private_data node. 902d5ac70f0Sopenharmony_ci * \return A non-negative value if successful, otherwise a negative error code. 903d5ac70f0Sopenharmony_ci * 904d5ac70f0Sopenharmony_ci * Example: 905d5ac70f0Sopenharmony_ci\code 906d5ac70f0Sopenharmony_ci { 907d5ac70f0Sopenharmony_ci @func card_driver 908d5ac70f0Sopenharmony_ci card 0 909d5ac70f0Sopenharmony_ci } 910d5ac70f0Sopenharmony_ci\endcode 911d5ac70f0Sopenharmony_ci */ 912d5ac70f0Sopenharmony_ciint snd_func_card_driver(snd_config_t **dst, snd_config_t *root, snd_config_t *src, 913d5ac70f0Sopenharmony_ci snd_config_t *private_data) 914d5ac70f0Sopenharmony_ci{ 915d5ac70f0Sopenharmony_ci snd_config_t *val; 916d5ac70f0Sopenharmony_ci int card, err; 917d5ac70f0Sopenharmony_ci 918d5ac70f0Sopenharmony_ci card = parse_card(root, src, private_data); 919d5ac70f0Sopenharmony_ci if (card < 0) 920d5ac70f0Sopenharmony_ci return card; 921d5ac70f0Sopenharmony_ci err = snd_config_imake_integer(&val, "card", card); 922d5ac70f0Sopenharmony_ci if (err < 0) 923d5ac70f0Sopenharmony_ci return err; 924d5ac70f0Sopenharmony_ci err = snd_func_private_card_driver(dst, root, src, val); 925d5ac70f0Sopenharmony_ci snd_config_delete(val); 926d5ac70f0Sopenharmony_ci return err; 927d5ac70f0Sopenharmony_ci} 928d5ac70f0Sopenharmony_ci#ifndef DOC_HIDDEN 929d5ac70f0Sopenharmony_ciSND_DLSYM_BUILD_VERSION(snd_func_card_driver, SND_CONFIG_DLSYM_VERSION_EVALUATE); 930d5ac70f0Sopenharmony_ci#endif 931d5ac70f0Sopenharmony_ci 932d5ac70f0Sopenharmony_ci/** 933d5ac70f0Sopenharmony_ci * \brief Returns the identification of a card. 934d5ac70f0Sopenharmony_ci * \param dst The function puts the handle to the result configuration node 935d5ac70f0Sopenharmony_ci * (with type string) at the address specified by \p dst. 936d5ac70f0Sopenharmony_ci * \param root Handle to the root source node. 937d5ac70f0Sopenharmony_ci * \param src Handle to the source node, with a \c card definition. 938d5ac70f0Sopenharmony_ci * \param private_data Handle to the \c private_data node. 939d5ac70f0Sopenharmony_ci * \return A non-negative value if successful, otherwise a negative error code. 940d5ac70f0Sopenharmony_ci * 941d5ac70f0Sopenharmony_ci * Example: 942d5ac70f0Sopenharmony_ci\code 943d5ac70f0Sopenharmony_ci { 944d5ac70f0Sopenharmony_ci @func card_id 945d5ac70f0Sopenharmony_ci card 0 946d5ac70f0Sopenharmony_ci } 947d5ac70f0Sopenharmony_ci\endcode 948d5ac70f0Sopenharmony_ci */ 949d5ac70f0Sopenharmony_ciint snd_func_card_id(snd_config_t **dst, snd_config_t *root, snd_config_t *src, 950d5ac70f0Sopenharmony_ci snd_config_t *private_data) 951d5ac70f0Sopenharmony_ci{ 952d5ac70f0Sopenharmony_ci snd_ctl_t *ctl = NULL; 953d5ac70f0Sopenharmony_ci snd_ctl_card_info_t info = {0}; 954d5ac70f0Sopenharmony_ci const char *id; 955d5ac70f0Sopenharmony_ci int card, err; 956d5ac70f0Sopenharmony_ci 957d5ac70f0Sopenharmony_ci card = parse_card(root, src, private_data); 958d5ac70f0Sopenharmony_ci if (card < 0) 959d5ac70f0Sopenharmony_ci return card; 960d5ac70f0Sopenharmony_ci err = open_ctl(card, &ctl); 961d5ac70f0Sopenharmony_ci if (err < 0) { 962d5ac70f0Sopenharmony_ci SNDERR("could not open control for card %i", card); 963d5ac70f0Sopenharmony_ci goto __error; 964d5ac70f0Sopenharmony_ci } 965d5ac70f0Sopenharmony_ci err = snd_ctl_card_info(ctl, &info); 966d5ac70f0Sopenharmony_ci if (err < 0) { 967d5ac70f0Sopenharmony_ci SNDERR("snd_ctl_card_info error: %s", snd_strerror(err)); 968d5ac70f0Sopenharmony_ci goto __error; 969d5ac70f0Sopenharmony_ci } 970d5ac70f0Sopenharmony_ci err = snd_config_get_id(src, &id); 971d5ac70f0Sopenharmony_ci if (err >= 0) 972d5ac70f0Sopenharmony_ci err = snd_config_imake_string(dst, id, 973d5ac70f0Sopenharmony_ci snd_ctl_card_info_get_id(&info)); 974d5ac70f0Sopenharmony_ci __error: 975d5ac70f0Sopenharmony_ci if (ctl) 976d5ac70f0Sopenharmony_ci snd_ctl_close(ctl); 977d5ac70f0Sopenharmony_ci return err; 978d5ac70f0Sopenharmony_ci} 979d5ac70f0Sopenharmony_ci#ifndef DOC_HIDDEN 980d5ac70f0Sopenharmony_ciSND_DLSYM_BUILD_VERSION(snd_func_card_id, SND_CONFIG_DLSYM_VERSION_EVALUATE); 981d5ac70f0Sopenharmony_ci#endif 982d5ac70f0Sopenharmony_ci 983d5ac70f0Sopenharmony_ci/** 984d5ac70f0Sopenharmony_ci * \brief Returns the name of a card. 985d5ac70f0Sopenharmony_ci * \param dst The function puts the handle to the result configuration node 986d5ac70f0Sopenharmony_ci * (with type string) at the address specified by \p dst. 987d5ac70f0Sopenharmony_ci * \param root Handle to the root source node. 988d5ac70f0Sopenharmony_ci * \param src Handle to the source node, with a \c card definition. 989d5ac70f0Sopenharmony_ci * \param private_data Handle to the \c private_data node. 990d5ac70f0Sopenharmony_ci * \return A non-negative value if successful, otherwise a negative error code. 991d5ac70f0Sopenharmony_ci * 992d5ac70f0Sopenharmony_ci * Example: 993d5ac70f0Sopenharmony_ci\code 994d5ac70f0Sopenharmony_ci { 995d5ac70f0Sopenharmony_ci @func card_name 996d5ac70f0Sopenharmony_ci card 0 997d5ac70f0Sopenharmony_ci } 998d5ac70f0Sopenharmony_ci\endcode 999d5ac70f0Sopenharmony_ci */ 1000d5ac70f0Sopenharmony_ciint snd_func_card_name(snd_config_t **dst, snd_config_t *root, 1001d5ac70f0Sopenharmony_ci snd_config_t *src, snd_config_t *private_data) 1002d5ac70f0Sopenharmony_ci{ 1003d5ac70f0Sopenharmony_ci snd_ctl_t *ctl = NULL; 1004d5ac70f0Sopenharmony_ci snd_ctl_card_info_t info = {0}; 1005d5ac70f0Sopenharmony_ci const char *id; 1006d5ac70f0Sopenharmony_ci int card, err; 1007d5ac70f0Sopenharmony_ci 1008d5ac70f0Sopenharmony_ci card = parse_card(root, src, private_data); 1009d5ac70f0Sopenharmony_ci if (card < 0) 1010d5ac70f0Sopenharmony_ci return card; 1011d5ac70f0Sopenharmony_ci err = open_ctl(card, &ctl); 1012d5ac70f0Sopenharmony_ci if (err < 0) { 1013d5ac70f0Sopenharmony_ci SNDERR("could not open control for card %i", card); 1014d5ac70f0Sopenharmony_ci goto __error; 1015d5ac70f0Sopenharmony_ci } 1016d5ac70f0Sopenharmony_ci err = snd_ctl_card_info(ctl, &info); 1017d5ac70f0Sopenharmony_ci if (err < 0) { 1018d5ac70f0Sopenharmony_ci SNDERR("snd_ctl_card_info error: %s", snd_strerror(err)); 1019d5ac70f0Sopenharmony_ci goto __error; 1020d5ac70f0Sopenharmony_ci } 1021d5ac70f0Sopenharmony_ci err = snd_config_get_id(src, &id); 1022d5ac70f0Sopenharmony_ci if (err >= 0) 1023d5ac70f0Sopenharmony_ci err = snd_config_imake_safe_string(dst, id, 1024d5ac70f0Sopenharmony_ci snd_ctl_card_info_get_name(&info)); 1025d5ac70f0Sopenharmony_ci __error: 1026d5ac70f0Sopenharmony_ci if (ctl) 1027d5ac70f0Sopenharmony_ci snd_ctl_close(ctl); 1028d5ac70f0Sopenharmony_ci return err; 1029d5ac70f0Sopenharmony_ci} 1030d5ac70f0Sopenharmony_ci#ifndef DOC_HIDDEN 1031d5ac70f0Sopenharmony_ciSND_DLSYM_BUILD_VERSION(snd_func_card_name, SND_CONFIG_DLSYM_VERSION_EVALUATE); 1032d5ac70f0Sopenharmony_ci#endif 1033d5ac70f0Sopenharmony_ci 1034d5ac70f0Sopenharmony_ci#ifdef DOXYGEN 1035d5ac70f0Sopenharmony_ci/* For consistency with the PCM Interface module, include documentation even 1036d5ac70f0Sopenharmony_ci * when PCM module is not included in the build. */ 1037d5ac70f0Sopenharmony_ci#ifndef BUILD_PCM 1038d5ac70f0Sopenharmony_ci#define BUILD_PCM 1039d5ac70f0Sopenharmony_ci#endif 1040d5ac70f0Sopenharmony_ci#endif /* DOXYGEN */ 1041d5ac70f0Sopenharmony_ci 1042d5ac70f0Sopenharmony_ci#ifdef BUILD_PCM 1043d5ac70f0Sopenharmony_ci 1044d5ac70f0Sopenharmony_ci/** 1045d5ac70f0Sopenharmony_ci * \brief Returns the pcm identification of a device. 1046d5ac70f0Sopenharmony_ci * \param dst The function puts the handle to the result configuration node 1047d5ac70f0Sopenharmony_ci * (with type string) at the address specified by \p dst. 1048d5ac70f0Sopenharmony_ci * \param root Handle to the root source node. 1049d5ac70f0Sopenharmony_ci * \param src Handle to the source node, with definitions for \c card, 1050d5ac70f0Sopenharmony_ci * \c device and (optionally) \c subdevice. 1051d5ac70f0Sopenharmony_ci * \param private_data Handle to the \c private_data node. 1052d5ac70f0Sopenharmony_ci * \return A non-negative value if successful, otherwise a negative error code. 1053d5ac70f0Sopenharmony_ci * 1054d5ac70f0Sopenharmony_ci * Example: 1055d5ac70f0Sopenharmony_ci\code 1056d5ac70f0Sopenharmony_ci { 1057d5ac70f0Sopenharmony_ci @func pcm_id 1058d5ac70f0Sopenharmony_ci card 0 1059d5ac70f0Sopenharmony_ci device 0 1060d5ac70f0Sopenharmony_ci subdevice 0 # optional 1061d5ac70f0Sopenharmony_ci } 1062d5ac70f0Sopenharmony_ci\endcode 1063d5ac70f0Sopenharmony_ci */ 1064d5ac70f0Sopenharmony_ciint snd_func_pcm_id(snd_config_t **dst, snd_config_t *root, snd_config_t *src, void *private_data) 1065d5ac70f0Sopenharmony_ci{ 1066d5ac70f0Sopenharmony_ci snd_config_t *n; 1067d5ac70f0Sopenharmony_ci snd_ctl_t *ctl = NULL; 1068d5ac70f0Sopenharmony_ci snd_pcm_info_t info = {0}; 1069d5ac70f0Sopenharmony_ci const char *id; 1070d5ac70f0Sopenharmony_ci long card, device, subdevice = 0; 1071d5ac70f0Sopenharmony_ci int err; 1072d5ac70f0Sopenharmony_ci 1073d5ac70f0Sopenharmony_ci card = parse_card(root, src, private_data); 1074d5ac70f0Sopenharmony_ci if (card < 0) 1075d5ac70f0Sopenharmony_ci return card; 1076d5ac70f0Sopenharmony_ci err = snd_config_search(src, "device", &n); 1077d5ac70f0Sopenharmony_ci if (err < 0) { 1078d5ac70f0Sopenharmony_ci SNDERR("field device not found"); 1079d5ac70f0Sopenharmony_ci goto __error; 1080d5ac70f0Sopenharmony_ci } 1081d5ac70f0Sopenharmony_ci err = snd_config_evaluate(n, root, private_data, NULL); 1082d5ac70f0Sopenharmony_ci if (err < 0) { 1083d5ac70f0Sopenharmony_ci SNDERR("error evaluating device"); 1084d5ac70f0Sopenharmony_ci goto __error; 1085d5ac70f0Sopenharmony_ci } 1086d5ac70f0Sopenharmony_ci err = snd_config_get_integer(n, &device); 1087d5ac70f0Sopenharmony_ci if (err < 0) { 1088d5ac70f0Sopenharmony_ci SNDERR("field device is not an integer"); 1089d5ac70f0Sopenharmony_ci goto __error; 1090d5ac70f0Sopenharmony_ci } 1091d5ac70f0Sopenharmony_ci if (snd_config_search(src, "subdevice", &n) >= 0) { 1092d5ac70f0Sopenharmony_ci err = snd_config_evaluate(n, root, private_data, NULL); 1093d5ac70f0Sopenharmony_ci if (err < 0) { 1094d5ac70f0Sopenharmony_ci SNDERR("error evaluating subdevice"); 1095d5ac70f0Sopenharmony_ci goto __error; 1096d5ac70f0Sopenharmony_ci } 1097d5ac70f0Sopenharmony_ci err = snd_config_get_integer(n, &subdevice); 1098d5ac70f0Sopenharmony_ci if (err < 0) { 1099d5ac70f0Sopenharmony_ci SNDERR("field subdevice is not an integer"); 1100d5ac70f0Sopenharmony_ci goto __error; 1101d5ac70f0Sopenharmony_ci } 1102d5ac70f0Sopenharmony_ci } 1103d5ac70f0Sopenharmony_ci err = open_ctl(card, &ctl); 1104d5ac70f0Sopenharmony_ci if (err < 0) { 1105d5ac70f0Sopenharmony_ci SNDERR("could not open control for card %li", card); 1106d5ac70f0Sopenharmony_ci goto __error; 1107d5ac70f0Sopenharmony_ci } 1108d5ac70f0Sopenharmony_ci snd_pcm_info_set_device(&info, device); 1109d5ac70f0Sopenharmony_ci snd_pcm_info_set_subdevice(&info, subdevice); 1110d5ac70f0Sopenharmony_ci err = snd_ctl_pcm_info(ctl, &info); 1111d5ac70f0Sopenharmony_ci if (err < 0) { 1112d5ac70f0Sopenharmony_ci SNDERR("snd_ctl_pcm_info error: %s", snd_strerror(err)); 1113d5ac70f0Sopenharmony_ci goto __error; 1114d5ac70f0Sopenharmony_ci } 1115d5ac70f0Sopenharmony_ci err = snd_config_get_id(src, &id); 1116d5ac70f0Sopenharmony_ci if (err >= 0) 1117d5ac70f0Sopenharmony_ci err = snd_config_imake_string(dst, id, 1118d5ac70f0Sopenharmony_ci snd_pcm_info_get_id(&info)); 1119d5ac70f0Sopenharmony_ci __error: 1120d5ac70f0Sopenharmony_ci if (ctl) 1121d5ac70f0Sopenharmony_ci snd_ctl_close(ctl); 1122d5ac70f0Sopenharmony_ci return err; 1123d5ac70f0Sopenharmony_ci} 1124d5ac70f0Sopenharmony_ci#ifndef DOC_HIDDEN 1125d5ac70f0Sopenharmony_ciSND_DLSYM_BUILD_VERSION(snd_func_pcm_id, SND_CONFIG_DLSYM_VERSION_EVALUATE); 1126d5ac70f0Sopenharmony_ci#endif 1127d5ac70f0Sopenharmony_ci 1128d5ac70f0Sopenharmony_ci/** 1129d5ac70f0Sopenharmony_ci * \brief Returns the pcm card and device arguments (in form CARD=N,DEV=M) 1130d5ac70f0Sopenharmony_ci * for pcm specified by class and index. 1131d5ac70f0Sopenharmony_ci * \param dst The function puts the handle to the result configuration node 1132d5ac70f0Sopenharmony_ci * (with type string) at the address specified by \p dst. 1133d5ac70f0Sopenharmony_ci * \param root Handle to the root source node. 1134d5ac70f0Sopenharmony_ci * \param src Handle to the source node, with definitions for \c class 1135d5ac70f0Sopenharmony_ci * and \c index. 1136d5ac70f0Sopenharmony_ci * \param private_data Handle to the \c private_data node. 1137d5ac70f0Sopenharmony_ci * \return A non-negative value if successful, otherwise a negative error code. 1138d5ac70f0Sopenharmony_ci * 1139d5ac70f0Sopenharmony_ci * Example: 1140d5ac70f0Sopenharmony_ci\code 1141d5ac70f0Sopenharmony_ci { 1142d5ac70f0Sopenharmony_ci @func pcm_args_by_class 1143d5ac70f0Sopenharmony_ci class 0 1144d5ac70f0Sopenharmony_ci index 0 1145d5ac70f0Sopenharmony_ci } 1146d5ac70f0Sopenharmony_ci\endcode 1147d5ac70f0Sopenharmony_ci */ 1148d5ac70f0Sopenharmony_ciint snd_func_pcm_args_by_class(snd_config_t **dst, snd_config_t *root, snd_config_t *src, void *private_data) 1149d5ac70f0Sopenharmony_ci{ 1150d5ac70f0Sopenharmony_ci snd_config_t *n; 1151d5ac70f0Sopenharmony_ci snd_ctl_t *ctl = NULL; 1152d5ac70f0Sopenharmony_ci snd_pcm_info_t info = {0}; 1153d5ac70f0Sopenharmony_ci const char *id; 1154d5ac70f0Sopenharmony_ci int card = -1, dev; 1155d5ac70f0Sopenharmony_ci long class, index; 1156d5ac70f0Sopenharmony_ci int idx = 0; 1157d5ac70f0Sopenharmony_ci int err; 1158d5ac70f0Sopenharmony_ci 1159d5ac70f0Sopenharmony_ci err = snd_config_search(src, "class", &n); 1160d5ac70f0Sopenharmony_ci if (err < 0) { 1161d5ac70f0Sopenharmony_ci SNDERR("field class not found"); 1162d5ac70f0Sopenharmony_ci goto __out; 1163d5ac70f0Sopenharmony_ci } 1164d5ac70f0Sopenharmony_ci err = snd_config_evaluate(n, root, private_data, NULL); 1165d5ac70f0Sopenharmony_ci if (err < 0) { 1166d5ac70f0Sopenharmony_ci SNDERR("error evaluating class"); 1167d5ac70f0Sopenharmony_ci goto __out; 1168d5ac70f0Sopenharmony_ci } 1169d5ac70f0Sopenharmony_ci err = snd_config_get_integer(n, &class); 1170d5ac70f0Sopenharmony_ci if (err < 0) { 1171d5ac70f0Sopenharmony_ci SNDERR("field class is not an integer"); 1172d5ac70f0Sopenharmony_ci goto __out; 1173d5ac70f0Sopenharmony_ci } 1174d5ac70f0Sopenharmony_ci err = snd_config_search(src, "index", &n); 1175d5ac70f0Sopenharmony_ci if (err < 0) { 1176d5ac70f0Sopenharmony_ci SNDERR("field index not found"); 1177d5ac70f0Sopenharmony_ci goto __out; 1178d5ac70f0Sopenharmony_ci } 1179d5ac70f0Sopenharmony_ci err = snd_config_evaluate(n, root, private_data, NULL); 1180d5ac70f0Sopenharmony_ci if (err < 0) { 1181d5ac70f0Sopenharmony_ci SNDERR("error evaluating index"); 1182d5ac70f0Sopenharmony_ci goto __out; 1183d5ac70f0Sopenharmony_ci } 1184d5ac70f0Sopenharmony_ci err = snd_config_get_integer(n, &index); 1185d5ac70f0Sopenharmony_ci if (err < 0) { 1186d5ac70f0Sopenharmony_ci SNDERR("field index is not an integer"); 1187d5ac70f0Sopenharmony_ci goto __out; 1188d5ac70f0Sopenharmony_ci } 1189d5ac70f0Sopenharmony_ci 1190d5ac70f0Sopenharmony_ci while(1) { 1191d5ac70f0Sopenharmony_ci err = snd_card_next(&card); 1192d5ac70f0Sopenharmony_ci if (err < 0) { 1193d5ac70f0Sopenharmony_ci SNDERR("could not get next card"); 1194d5ac70f0Sopenharmony_ci goto __out; 1195d5ac70f0Sopenharmony_ci } 1196d5ac70f0Sopenharmony_ci if (card < 0) 1197d5ac70f0Sopenharmony_ci break; 1198d5ac70f0Sopenharmony_ci err = open_ctl(card, &ctl); 1199d5ac70f0Sopenharmony_ci if (err < 0) { 1200d5ac70f0Sopenharmony_ci SNDERR("could not open control for card %i", card); 1201d5ac70f0Sopenharmony_ci goto __out; 1202d5ac70f0Sopenharmony_ci } 1203d5ac70f0Sopenharmony_ci dev = -1; 1204d5ac70f0Sopenharmony_ci while(1) { 1205d5ac70f0Sopenharmony_ci err = snd_ctl_pcm_next_device(ctl, &dev); 1206d5ac70f0Sopenharmony_ci if (err < 0) { 1207d5ac70f0Sopenharmony_ci SNDERR("could not get next pcm for card %i", card); 1208d5ac70f0Sopenharmony_ci goto __out; 1209d5ac70f0Sopenharmony_ci } 1210d5ac70f0Sopenharmony_ci if (dev < 0) 1211d5ac70f0Sopenharmony_ci break; 1212d5ac70f0Sopenharmony_ci snd_pcm_info_set_device(&info, dev); 1213d5ac70f0Sopenharmony_ci err = snd_ctl_pcm_info(ctl, &info); 1214d5ac70f0Sopenharmony_ci if (err < 0) 1215d5ac70f0Sopenharmony_ci continue; 1216d5ac70f0Sopenharmony_ci if (snd_pcm_info_get_class(&info) == (snd_pcm_class_t)class && 1217d5ac70f0Sopenharmony_ci index == idx++) 1218d5ac70f0Sopenharmony_ci goto __out; 1219d5ac70f0Sopenharmony_ci } 1220d5ac70f0Sopenharmony_ci snd_ctl_close(ctl); 1221d5ac70f0Sopenharmony_ci ctl = NULL; 1222d5ac70f0Sopenharmony_ci } 1223d5ac70f0Sopenharmony_ci err = -ENODEV; 1224d5ac70f0Sopenharmony_ci 1225d5ac70f0Sopenharmony_ci __out: 1226d5ac70f0Sopenharmony_ci if (ctl) 1227d5ac70f0Sopenharmony_ci snd_ctl_close(ctl); 1228d5ac70f0Sopenharmony_ci if (err < 0) 1229d5ac70f0Sopenharmony_ci return err; 1230d5ac70f0Sopenharmony_ci if((err = snd_config_get_id(src, &id)) >= 0) { 1231d5ac70f0Sopenharmony_ci char name[32]; 1232d5ac70f0Sopenharmony_ci snprintf(name, sizeof(name), "CARD=%i,DEV=%i", card, dev); 1233d5ac70f0Sopenharmony_ci err = snd_config_imake_string(dst, id, name); 1234d5ac70f0Sopenharmony_ci } 1235d5ac70f0Sopenharmony_ci return err; 1236d5ac70f0Sopenharmony_ci} 1237d5ac70f0Sopenharmony_ci#ifndef DOC_HIDDEN 1238d5ac70f0Sopenharmony_ciSND_DLSYM_BUILD_VERSION(snd_func_pcm_args_by_class, SND_CONFIG_DLSYM_VERSION_EVALUATE); 1239d5ac70f0Sopenharmony_ci#endif 1240d5ac70f0Sopenharmony_ci 1241d5ac70f0Sopenharmony_ci/** 1242d5ac70f0Sopenharmony_ci * \brief Returns the PCM subdevice from \c private_data. 1243d5ac70f0Sopenharmony_ci * \param dst The function puts the handle to the result configuration node 1244d5ac70f0Sopenharmony_ci * (with type integer) at the address specified by \p dst. 1245d5ac70f0Sopenharmony_ci * \param root Handle to the root source node. 1246d5ac70f0Sopenharmony_ci * \param src Handle to the source node. 1247d5ac70f0Sopenharmony_ci * \param private_data Handle to the \c private_data node (type pointer, 1248d5ac70f0Sopenharmony_ci * id "pcm_handle"). 1249d5ac70f0Sopenharmony_ci * \return A non-negative value if successful, otherwise a negative error code. 1250d5ac70f0Sopenharmony_ci * 1251d5ac70f0Sopenharmony_ci * Example: 1252d5ac70f0Sopenharmony_ci\code 1253d5ac70f0Sopenharmony_ci { 1254d5ac70f0Sopenharmony_ci @func private_pcm_subdevice 1255d5ac70f0Sopenharmony_ci } 1256d5ac70f0Sopenharmony_ci\endcode 1257d5ac70f0Sopenharmony_ci */ 1258d5ac70f0Sopenharmony_ciint snd_func_private_pcm_subdevice(snd_config_t **dst, snd_config_t *root ATTRIBUTE_UNUSED, 1259d5ac70f0Sopenharmony_ci snd_config_t *src, snd_config_t *private_data) 1260d5ac70f0Sopenharmony_ci{ 1261d5ac70f0Sopenharmony_ci snd_pcm_info_t info = {0}; 1262d5ac70f0Sopenharmony_ci const char *id; 1263d5ac70f0Sopenharmony_ci const void *data; 1264d5ac70f0Sopenharmony_ci snd_pcm_t *pcm; 1265d5ac70f0Sopenharmony_ci int err; 1266d5ac70f0Sopenharmony_ci 1267d5ac70f0Sopenharmony_ci if (private_data == NULL) 1268d5ac70f0Sopenharmony_ci return snd_config_copy(dst, src); 1269d5ac70f0Sopenharmony_ci err = snd_config_test_id(private_data, "pcm_handle"); 1270d5ac70f0Sopenharmony_ci if (err) { 1271d5ac70f0Sopenharmony_ci SNDERR("field pcm_handle not found"); 1272d5ac70f0Sopenharmony_ci return -EINVAL; 1273d5ac70f0Sopenharmony_ci } 1274d5ac70f0Sopenharmony_ci err = snd_config_get_pointer(private_data, &data); 1275d5ac70f0Sopenharmony_ci pcm = (snd_pcm_t *)data; 1276d5ac70f0Sopenharmony_ci if (err < 0) { 1277d5ac70f0Sopenharmony_ci SNDERR("field pcm_handle is not a pointer"); 1278d5ac70f0Sopenharmony_ci return err; 1279d5ac70f0Sopenharmony_ci } 1280d5ac70f0Sopenharmony_ci err = snd_pcm_info(pcm, &info); 1281d5ac70f0Sopenharmony_ci if (err < 0) { 1282d5ac70f0Sopenharmony_ci SNDERR("snd_ctl_pcm_info error: %s", snd_strerror(err)); 1283d5ac70f0Sopenharmony_ci return err; 1284d5ac70f0Sopenharmony_ci } 1285d5ac70f0Sopenharmony_ci err = snd_config_get_id(src, &id); 1286d5ac70f0Sopenharmony_ci if (err >= 0) 1287d5ac70f0Sopenharmony_ci err = snd_config_imake_integer(dst, id, 1288d5ac70f0Sopenharmony_ci snd_pcm_info_get_subdevice(&info)); 1289d5ac70f0Sopenharmony_ci return err; 1290d5ac70f0Sopenharmony_ci} 1291d5ac70f0Sopenharmony_ci#ifndef DOC_HIDDEN 1292d5ac70f0Sopenharmony_ciSND_DLSYM_BUILD_VERSION(snd_func_private_pcm_subdevice, SND_CONFIG_DLSYM_VERSION_EVALUATE); 1293d5ac70f0Sopenharmony_ci#endif 1294d5ac70f0Sopenharmony_ci 1295d5ac70f0Sopenharmony_ci#endif /* BUILD_PCM */ 1296d5ac70f0Sopenharmony_ci 1297d5ac70f0Sopenharmony_ci/** 1298d5ac70f0Sopenharmony_ci * \brief Copies the specified configuration node. 1299d5ac70f0Sopenharmony_ci * \param dst The function puts the handle to the result configuration node 1300d5ac70f0Sopenharmony_ci * (with the same type as the specified node) at the address 1301d5ac70f0Sopenharmony_ci * specified by \p dst. 1302d5ac70f0Sopenharmony_ci * \param root Handle to the root source node. 1303d5ac70f0Sopenharmony_ci * \param src Handle to the source node, with definitions for \c name and 1304d5ac70f0Sopenharmony_ci * (optionally) \c file. 1305d5ac70f0Sopenharmony_ci * \param private_data Handle to the \c private_data node. 1306d5ac70f0Sopenharmony_ci * \return A non-negative value if successful, otherwise a negative error code. 1307d5ac70f0Sopenharmony_ci * \note The root source node can be modified! 1308d5ac70f0Sopenharmony_ci * 1309d5ac70f0Sopenharmony_ci * Example: 1310d5ac70f0Sopenharmony_ci\code 1311d5ac70f0Sopenharmony_ci { 1312d5ac70f0Sopenharmony_ci @func refer 1313d5ac70f0Sopenharmony_ci file "/etc/myconf.conf" # optional 1314d5ac70f0Sopenharmony_ci name "id1.id2.id3" 1315d5ac70f0Sopenharmony_ci } 1316d5ac70f0Sopenharmony_ci\endcode 1317d5ac70f0Sopenharmony_ci */ 1318d5ac70f0Sopenharmony_ciint snd_func_refer(snd_config_t **dst, snd_config_t *root, snd_config_t *src, 1319d5ac70f0Sopenharmony_ci snd_config_t *private_data) 1320d5ac70f0Sopenharmony_ci{ 1321d5ac70f0Sopenharmony_ci snd_config_t *n; 1322d5ac70f0Sopenharmony_ci const char *file = NULL, *name = NULL; 1323d5ac70f0Sopenharmony_ci int err; 1324d5ac70f0Sopenharmony_ci 1325d5ac70f0Sopenharmony_ci err = snd_config_search(src, "file", &n); 1326d5ac70f0Sopenharmony_ci if (err >= 0) { 1327d5ac70f0Sopenharmony_ci err = snd_config_evaluate(n, root, private_data, NULL); 1328d5ac70f0Sopenharmony_ci if (err < 0) { 1329d5ac70f0Sopenharmony_ci SNDERR("error evaluating file"); 1330d5ac70f0Sopenharmony_ci goto _end; 1331d5ac70f0Sopenharmony_ci } 1332d5ac70f0Sopenharmony_ci err = snd_config_get_string(n, &file); 1333d5ac70f0Sopenharmony_ci if (err < 0) { 1334d5ac70f0Sopenharmony_ci SNDERR("file is not a string"); 1335d5ac70f0Sopenharmony_ci goto _end; 1336d5ac70f0Sopenharmony_ci } 1337d5ac70f0Sopenharmony_ci } 1338d5ac70f0Sopenharmony_ci err = snd_config_search(src, "name", &n); 1339d5ac70f0Sopenharmony_ci if (err >= 0) { 1340d5ac70f0Sopenharmony_ci err = snd_config_evaluate(n, root, private_data, NULL); 1341d5ac70f0Sopenharmony_ci if (err < 0) { 1342d5ac70f0Sopenharmony_ci SNDERR("error evaluating name"); 1343d5ac70f0Sopenharmony_ci goto _end; 1344d5ac70f0Sopenharmony_ci } 1345d5ac70f0Sopenharmony_ci err = snd_config_get_string(n, &name); 1346d5ac70f0Sopenharmony_ci if (err < 0) { 1347d5ac70f0Sopenharmony_ci SNDERR("name is not a string"); 1348d5ac70f0Sopenharmony_ci goto _end; 1349d5ac70f0Sopenharmony_ci } 1350d5ac70f0Sopenharmony_ci } 1351d5ac70f0Sopenharmony_ci if (!name) { 1352d5ac70f0Sopenharmony_ci err = -EINVAL; 1353d5ac70f0Sopenharmony_ci SNDERR("name is not specified"); 1354d5ac70f0Sopenharmony_ci goto _end; 1355d5ac70f0Sopenharmony_ci } 1356d5ac70f0Sopenharmony_ci if (file) { 1357d5ac70f0Sopenharmony_ci snd_input_t *input; 1358d5ac70f0Sopenharmony_ci err = snd_input_stdio_open(&input, file, "r"); 1359d5ac70f0Sopenharmony_ci if (err < 0) { 1360d5ac70f0Sopenharmony_ci SNDERR("Unable to open file %s: %s", file, snd_strerror(err)); 1361d5ac70f0Sopenharmony_ci goto _end; 1362d5ac70f0Sopenharmony_ci } 1363d5ac70f0Sopenharmony_ci err = snd_config_load(root, input); 1364d5ac70f0Sopenharmony_ci snd_input_close(input); 1365d5ac70f0Sopenharmony_ci if (err < 0) 1366d5ac70f0Sopenharmony_ci goto _end; 1367d5ac70f0Sopenharmony_ci } 1368d5ac70f0Sopenharmony_ci err = snd_config_search_definition(root, NULL, name, dst); 1369d5ac70f0Sopenharmony_ci if (err >= 0) { 1370d5ac70f0Sopenharmony_ci const char *id; 1371d5ac70f0Sopenharmony_ci err = snd_config_get_id(src, &id); 1372d5ac70f0Sopenharmony_ci if (err >= 0) 1373d5ac70f0Sopenharmony_ci err = snd_config_set_id(*dst, id); 1374d5ac70f0Sopenharmony_ci } else { 1375d5ac70f0Sopenharmony_ci err = snd_config_search(src, "default", &n); 1376d5ac70f0Sopenharmony_ci if (err < 0) 1377d5ac70f0Sopenharmony_ci SNDERR("Unable to find definition '%s'", name); 1378d5ac70f0Sopenharmony_ci else { 1379d5ac70f0Sopenharmony_ci const char *id; 1380d5ac70f0Sopenharmony_ci err = snd_config_evaluate(n, root, private_data, NULL); 1381d5ac70f0Sopenharmony_ci if (err < 0) 1382d5ac70f0Sopenharmony_ci return err; 1383d5ac70f0Sopenharmony_ci if ((err = snd_config_copy(dst, n)) >= 0) { 1384d5ac70f0Sopenharmony_ci if ((err = snd_config_get_id(src, &id)) < 0 || 1385d5ac70f0Sopenharmony_ci (err = snd_config_set_id(*dst, id)) < 0) 1386d5ac70f0Sopenharmony_ci snd_config_delete(*dst); 1387d5ac70f0Sopenharmony_ci } 1388d5ac70f0Sopenharmony_ci } 1389d5ac70f0Sopenharmony_ci } 1390d5ac70f0Sopenharmony_ci _end: 1391d5ac70f0Sopenharmony_ci return err; 1392d5ac70f0Sopenharmony_ci} 1393d5ac70f0Sopenharmony_ci#ifndef DOC_HIDDEN 1394d5ac70f0Sopenharmony_ciSND_DLSYM_BUILD_VERSION(snd_func_refer, SND_CONFIG_DLSYM_VERSION_EVALUATE); 1395d5ac70f0Sopenharmony_ci#endif 1396d5ac70f0Sopenharmony_ci 1397d5ac70f0Sopenharmony_ci#ifndef DOC_HIDDEN 1398d5ac70f0Sopenharmony_ciint _snd_conf_generic_id(const char *id) 1399d5ac70f0Sopenharmony_ci{ 1400d5ac70f0Sopenharmony_ci static const char ids[3][8] = { "comment", "type", "hint" }; 1401d5ac70f0Sopenharmony_ci unsigned int k; 1402d5ac70f0Sopenharmony_ci for (k = 0; k < sizeof(ids) / sizeof(ids[0]); ++k) { 1403d5ac70f0Sopenharmony_ci if (strcmp(id, ids[k]) == 0) 1404d5ac70f0Sopenharmony_ci return 1; 1405d5ac70f0Sopenharmony_ci } 1406d5ac70f0Sopenharmony_ci return 0; 1407d5ac70f0Sopenharmony_ci} 1408d5ac70f0Sopenharmony_ci#endif 1409