pcm: fix ipc offset calculation for direct plugins

Also add more accurate description to x24 formats.
This commit is contained in:
Jaroslav Kysela 2006-10-23 11:34:00 +02:00
parent 21207351a8
commit ddf9599542
2 changed files with 22 additions and 7 deletions

View file

@ -120,13 +120,13 @@ typedef enum _snd_pcm_format {
SND_PCM_FORMAT_U16_LE, SND_PCM_FORMAT_U16_LE,
/** Unsigned 16 bit Big Endian */ /** Unsigned 16 bit Big Endian */
SND_PCM_FORMAT_U16_BE, SND_PCM_FORMAT_U16_BE,
/** Signed 24 bit Little Endian */ /** Signed 24 bit Little Endian using low three bytes in 32-bit word */
SND_PCM_FORMAT_S24_LE, SND_PCM_FORMAT_S24_LE,
/** Signed 24 bit Big Endian */ /** Signed 24 bit Big Endian using low three bytes in 32-bit word */
SND_PCM_FORMAT_S24_BE, SND_PCM_FORMAT_S24_BE,
/** Unsigned 24 bit Little Endian */ /** Unsigned 24 bit Little Endian using low three bytes in 32-bit word */
SND_PCM_FORMAT_U24_LE, SND_PCM_FORMAT_U24_LE,
/** Unsigned 24 bit Big Endian */ /** Unsigned 24 bit Big Endian using low three bytes in 32-bit word */
SND_PCM_FORMAT_U24_BE, SND_PCM_FORMAT_U24_BE,
/** Signed 32 bit Little Endian */ /** Signed 32 bit Little Endian */
SND_PCM_FORMAT_S32_LE, SND_PCM_FORMAT_S32_LE,

View file

@ -1426,12 +1426,12 @@ static int _snd_pcm_direct_get_slave_ipc_offset(snd_config_t *root,
int hop) int hop)
{ {
snd_config_iterator_t i, next; snd_config_iterator_t i, next;
snd_config_t *pcm_conf;
int err; int err;
long card = 0, device = 0, subdevice = 0; long card = 0, device = 0, subdevice = 0;
const char *str; const char *str;
if (snd_config_get_string(sconf, &str) >= 0) { if (snd_config_get_string(sconf, &str) >= 0) {
snd_config_t *pcm_conf;
if (hop > SND_CONF_MAX_HOPS) { if (hop > SND_CONF_MAX_HOPS) {
SNDERR("Too many definition levels (looped?)"); SNDERR("Too many definition levels (looped?)");
return -EINVAL; return -EINVAL;
@ -1448,6 +1448,21 @@ static int _snd_pcm_direct_get_slave_ipc_offset(snd_config_t *root,
return err; return err;
} }
#if 0 /* for debug purposes */
{
snd_output_t *out;
snd_output_stdio_attach(&out, stderr, 0);
snd_config_save(sconf, out);
snd_output_close(out);
}
#endif
if (snd_config_search(sconf, "slave", &pcm_conf) >= 0 &&
snd_config_search(pcm_conf, "pcm", &pcm_conf) >= 0)
return _snd_pcm_direct_get_slave_ipc_offset(root, pcm_conf,
direction,
hop + 1);
snd_config_for_each(i, next, sconf) { snd_config_for_each(i, next, sconf) {
snd_config_t *n = snd_config_iterator_entry(i); snd_config_t *n = snd_config_iterator_entry(i);
const char *id, *str; const char *id, *str;
@ -1631,7 +1646,7 @@ int snd_pcm_direct_parse_open_conf(snd_config_t *root, snd_config_t *conf,
SNDERR("Unknown field %s", id); SNDERR("Unknown field %s", id);
return -EINVAL; return -EINVAL;
} }
if (! rec->slave) { if (!rec->slave) {
SNDERR("slave is not defined"); SNDERR("slave is not defined");
return -EINVAL; return -EINVAL;
} }
@ -1641,7 +1656,7 @@ int snd_pcm_direct_parse_open_conf(snd_config_t *root, snd_config_t *conf,
} }
if (ipc_key_add_uid) if (ipc_key_add_uid)
rec->ipc_key += getuid(); rec->ipc_key += getuid();
err = snd_pcm_direct_get_slave_ipc_offset(root, rec->slave, stream); err = snd_pcm_direct_get_slave_ipc_offset(root, conf, stream);
if (err < 0) if (err < 0)
return err; return err;
rec->ipc_key += err; rec->ipc_key += err;