static int snd_config_compound_add(snd_config_t *father, const char *id, int join,
				   snd_config_t **node)
{
	int err;
	snd_config_t *leaf;
	err = snd_config_make_compound(&leaf, id, join);
	if (err < 0)
		return err;
	err = snd_config_add(father, leaf);
	if (err < 0) {
		snd_config_delete(leaf);
		return err;
	}
	*node = leaf;
	return 0;
}
static int snd_config_integer64_add(snd_config_t *father, char *id, long long integer)
{
	int err;
	snd_config_t *leaf;
	err = snd_config_make_integer64(&leaf, id);
	if (err < 0)
		return err;
	err = snd_config_add(father, leaf);
	if (err < 0) {
		snd_config_delete(leaf);
		return err;
	}
	err = snd_config_set_integer64(leaf, integer);
	if (err < 0) {
		snd_config_delete(leaf);
		return err;
	}
	return 0;
}
static int snd_config_string_add(snd_config_t *father, const char *id, const char *string)
{
	int err;
	snd_config_t *leaf;
	err = snd_config_make_string(&leaf, id);
	if (err < 0)
		return err;
	err = snd_config_add(father, leaf);
	if (err < 0) {
		snd_config_delete(leaf);
		return err;
	}
	err = snd_config_set_string(leaf, string);
	if (err < 0) {
		snd_config_delete(leaf);
		return err;
	}
	return 0;
}
示例#4
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;
}
示例#5
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/053391.html
   From Mozilla https://github.com/kinetiknz/cubeb/blob/1aa0058d0729eb85505df104cd1ac072432c6d24/src/cubeb_alsa.c
*/
static snd_config_t *init_local_config_with_workaround(ao_device *device, char const *name){
  char pcm_node_name[80];
  int r;
  snd_config_t * lconf;
  snd_config_t * device_node;
  snd_config_t * type_node;
  snd_config_t * node;
  char const * type_string;

  lconf = NULL;
  snprintf(pcm_node_name,80,"pcm.%s",name);

  if (snd_config == NULL) snd_config_update();

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

  r = snd_config_search(lconf, pcm_node_name, &device_node);
  if (r != 0) {
    snd_config_delete(lconf);
    return NULL;
  }

  /* Fetch the PCM node's type, and bail out if it's not the PulseAudio plugin. */
  r = snd_config_search(device_node, "type", &type_node);
  if (r != 0) {
    snd_config_delete(lconf);
    return NULL;
  }

  r = snd_config_get_string(type_node, &type_string);
  if (r != 0) {
    snd_config_delete(lconf);
    return NULL;
  }

  if (strcmp(type_string, "pulse") != 0) {
    snd_config_delete(lconf);
    return NULL;
  }

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

  r = snd_config_imake_integer(&node, "handle_underrun", 0);
  if (r != 0) {
    snd_config_delete(lconf);
    return NULL;
  }

  r = snd_config_add(device_node, node);
  if (r != 0) {
    snd_config_delete(lconf);
    return NULL;
  }

  adebug("PulseAudio ALSA-emulation detected: disabling underrun detection\n");
  return lconf;
}