Ejemplo n.º 1
0
static snd_config_t *
get_slave_pcm_node(snd_config_t * lconf, snd_config_t * root_pcm)
{
  int r;
  snd_config_t * slave_pcm;
  snd_config_t * slave_def;
  snd_config_t * pcm;
  char const * string;
  char node_name[64];

  slave_def = NULL;

  r = snd_config_search(root_pcm, "slave", &slave_pcm);
  if (r < 0) {
    return NULL;
  }

  r = snd_config_get_string(slave_pcm, &string);
  if (r >= 0) {
    r = snd_config_search_definition(lconf, "pcm_slave", string, &slave_def);
    if (r < 0) {
      return NULL;
    }
  }

  do {
    r = snd_config_search(slave_def ? slave_def : slave_pcm, "pcm", &pcm);
    if (r < 0) {
      break;
    }

    r = snd_config_get_string(slave_def ? slave_def : slave_pcm, &string);
    if (r < 0) {
      break;
    }

    r = snprintf(node_name, sizeof(node_name), "pcm.%s", string);
    if (r < 0 || r > (int) sizeof(node_name)) {
      break;
    }
    r = snd_config_search(lconf, node_name, &pcm);
    if (r < 0) {
      break;
    }

    return pcm;
  } while (0);

  if (slave_def) {
    snd_config_delete(slave_def);
  }

  return NULL;
}
Ejemplo n.º 2
0
/* Work around PulseAudio ALSA plugin bug where the PA server forces a
   higher than requested latency, but the plugin does not update its (and
   ALSA's) internal state to reflect that, leading to an immediate underrun
   situation.  Inspired by WINE's make_handle_underrun_config.
   Reference: http://mailman.alsa-project.org/pipermail/alsa-devel/2012-July/05 */
static snd_config_t *
init_local_config_with_workaround(char const * pcm_name)
{
  int r;
  snd_config_t * lconf;
  snd_config_t * pcm_node;
  snd_config_t * node;
  char const * string;
  char node_name[64];

  lconf = NULL;

  if (snd_config == NULL) {
    return NULL;
  }

  r = snd_config_copy(&lconf, snd_config);
  if (r < 0) {
    return NULL;
  }

  do {
    r = snd_config_search_definition(lconf, "pcm", pcm_name, &pcm_node);
    if (r < 0) {
      break;
    }

    r = snd_config_get_id(pcm_node, &string);
    if (r < 0) {
      break;
    }

    r = snprintf(node_name, sizeof(node_name), "pcm.%s", string);
    if (r < 0 || r > (int) sizeof(node_name)) {
      break;
    }
    r = snd_config_search(lconf, node_name, &pcm_node);
    if (r < 0) {
      break;
    }

    /* If this PCM has a slave, walk the slave configurations until we reach the bottom. */
    while ((node = get_slave_pcm_node(lconf, pcm_node)) != NULL) {
      pcm_node = node;
    }

    /* Fetch the PCM node's type, and bail out if it's not the PulseAudio plugin. */
    r = snd_config_search(pcm_node, "type", &node);
    if (r < 0) {
      break;
    }

    r = snd_config_get_string(node, &string);
    if (r < 0) {
      break;
    }

    if (strcmp(string, "pulse") != 0) {
      break;
    }

    /* Don't clobber an explicit existing handle_underrun value, set it only
       if it doesn't already exist. */
    r = snd_config_search(pcm_node, "handle_underrun", &node);
    if (r != -ENOENT) {
      break;
    }

    /* Disable pcm_pulse's asynchronous underrun handling. */
    r = snd_config_imake_integer(&node, "handle_underrun", 0);
    if (r < 0) {
      break;
    }

    r = snd_config_add(pcm_node, node);
    if (r < 0) {
      break;
    }

    return lconf;
  } while (0);

  snd_config_delete(lconf);

  return NULL;
}
Ejemplo n.º 3
0
static int snd_rawmidi_open_conf(snd_rawmidi_t **inputp, snd_rawmidi_t **outputp,
				 const char *name, snd_config_t *rawmidi_root,
				 snd_config_t *rawmidi_conf, int mode)
{
	const char *str;
	char buf[256];
	int err;
	snd_config_t *conf, *type_conf = NULL;
	snd_config_iterator_t i, next;
	snd_rawmidi_params_t params;
	const char *id;
	const char *lib = NULL, *open_name = NULL;
	int (*open_func)(snd_rawmidi_t **, snd_rawmidi_t **,
			 const char *, snd_config_t *, snd_config_t *, int) = NULL;
#ifndef PIC
	extern void *snd_rawmidi_open_symbols(void);
#endif
	void *h = NULL;
	if (snd_config_get_type(rawmidi_conf) != SND_CONFIG_TYPE_COMPOUND) {
		if (name)
			SNDERR("Invalid type for RAWMIDI %s definition", name);
		else
			SNDERR("Invalid type for RAWMIDI definition");
		return -EINVAL;
	}
	err = snd_config_search(rawmidi_conf, "type", &conf);
	if (err < 0) {
		SNDERR("type is not defined");
		return err;
	}
	err = snd_config_get_id(conf, &id);
	if (err < 0) {
		SNDERR("unable to get id");
		return err;
	}
	err = snd_config_get_string(conf, &str);
	if (err < 0) {
		SNDERR("Invalid type for %s", id);
		return err;
	}
	err = snd_config_search_definition(rawmidi_root, "rawmidi_type", str, &type_conf);
	if (err >= 0) {
		if (snd_config_get_type(type_conf) != SND_CONFIG_TYPE_COMPOUND) {
			SNDERR("Invalid type for RAWMIDI type %s definition", str);
			goto _err;
		}
		snd_config_for_each(i, next, type_conf) {
			snd_config_t *n = snd_config_iterator_entry(i);
			const char *id;
			if (snd_config_get_id(n, &id) < 0)
				continue;
			if (strcmp(id, "comment") == 0)
				continue;
			if (strcmp(id, "lib") == 0) {
				err = snd_config_get_string(n, &lib);
				if (err < 0) {
					SNDERR("Invalid type for %s", id);
					goto _err;
				}
				continue;
			}
			if (strcmp(id, "open") == 0) {
				err = snd_config_get_string(n, &open_name);
				if (err < 0) {
					SNDERR("Invalid type for %s", id);
					goto _err;
				}
				continue;
			}
			SNDERR("Unknown field %s", id);
			err = -EINVAL;
			goto _err;
		}
	}