Esempio n. 1
0
static int snd_func_iops(snd_config_t **dst,
			 snd_config_t *root,
			 snd_config_t *src,
			 snd_config_t *private_data,
			 int op)
{
	snd_config_t *n;
	snd_config_iterator_t i, next;
	const char *id;
	char *res = NULL;
	long result = 0, val;
	int idx = 0, err, hit;
	
	err = snd_config_search(src, "integers", &n);
	if (err < 0) {
		SNDERR("field integers not found");
		goto __error;
	}
	err = snd_config_evaluate(n, root, private_data, NULL);
	if (err < 0) {
		SNDERR("error evaluating integers");
		goto __error;
	}
	do {
		hit = 0;
		snd_config_for_each(i, next, n) {
			snd_config_t *n = snd_config_iterator_entry(i);
			const char *id;
			long i;
			if (snd_config_get_id(n, &id) < 0)
				continue;
			err = safe_strtol(id, &i);
			if (err < 0) {
				SNDERR("id of field %s is not an integer", id);
				err = -EINVAL;
				goto __error;
			}
			if (i == idx) {
				idx++;
				err = snd_config_get_integer(n, &val);
				if (err < 0) {
					SNDERR("invalid integer for id %s", id);
					err = -EINVAL;
					goto __error;
				}
				switch (op) {
				case 0: result += val; break;
				case 1: result *= val; break;
				}
				hit = 1;
			}
		}
	} while (hit);
	err = snd_config_get_id(src, &id);
	if (err >= 0)
		err = snd_config_imake_integer(dst, id, result);
	free(res);
      __error:
	return err;
}
Esempio n. 2
0
/**
 * \brief Returns an integer environment value.
 * \param dst The function puts the handle to the result configuration node
 *            (with type integer) at the address specified by \p dst.
 * \param root Handle to the root source node.
 * \param src Handle to the source node, with definitions for \c vars and
 *            \c default.
 * \param private_data Handle to the \c private_data node.
 * \return Zero if successful, otherwise a negative error code.
 *
 * Example:
\code
	{
		@func igetenv
		vars [ MY_DEVICE DEVICE D ]
		default 0
	}
\endcode
 */ 
int snd_func_igetenv(snd_config_t **dst, snd_config_t *root, snd_config_t *src,
		     snd_config_t *private_data)
{
	snd_config_t *d;
	const char *str, *id;
	int err;
	long v;

	err = snd_func_getenv(&d, root, src, private_data);
	if (err < 0)
		return err;
	err = snd_config_get_string(d, &str);
	if (err < 0) {
		snd_config_delete(d);
		return err;
	}
	err = safe_strtol(str, &v);
	if (err < 0) {
		snd_config_delete(d);
		return err;
	}
	snd_config_delete(d);
	err = snd_config_get_id(src, &id);
	if (err < 0)
		return err;
	err = snd_config_imake_integer(dst, id, v);
	if (err < 0)
		return err;
	return 0;
}
Esempio n. 3
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;
}
Esempio n. 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/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;
}