mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-12-19 08:57:08 -05:00
Add preamble value configuration for iec958 plugin
The preamble values can be defined in iec958 plugin configuration. As default, Z/Y/X=8/4/2 is used. CMI8338 has different values, so override in its configuration.
This commit is contained in:
parent
0256e1e8c9
commit
73aa2549d9
2 changed files with 63 additions and 6 deletions
|
|
@ -95,6 +95,9 @@ CMI8338-SWIEC.pcm.iec958.0 {
|
||||||
device 2
|
device 2
|
||||||
}
|
}
|
||||||
status [ $AES0 $AES1 $AES2 $AES3 ]
|
status [ $AES0 $AES1 $AES2 $AES3 ]
|
||||||
|
preamble.z 3
|
||||||
|
preamble.y 5
|
||||||
|
preamble.x 9
|
||||||
}
|
}
|
||||||
capture.pcm {
|
capture.pcm {
|
||||||
type hw
|
type hw
|
||||||
|
|
|
||||||
|
|
@ -59,8 +59,11 @@ struct snd_pcm_iec958 {
|
||||||
unsigned int counter;
|
unsigned int counter;
|
||||||
unsigned char status[24];
|
unsigned char status[24];
|
||||||
unsigned int byteswap;
|
unsigned int byteswap;
|
||||||
|
unsigned char preamble[3]; /* B/M/W or Z/X/Y */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum { PREAMBLE_Z, PREAMBLE_X, PREAMBLE_Y };
|
||||||
|
|
||||||
#endif /* DOC_HIDDEN */
|
#endif /* DOC_HIDDEN */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -114,11 +117,11 @@ static inline u_int32_t iec958_subframe(snd_pcm_iec958_t *iec, u_int32_t data, i
|
||||||
|
|
||||||
/* Preamble */
|
/* Preamble */
|
||||||
if (! iec->counter)
|
if (! iec->counter)
|
||||||
data |= 0x03; /* Block start, 'Z' */
|
data |= iec->preamble[PREAMBLE_Z]; /* Block start, 'Z' */
|
||||||
else if (! channel)
|
else if (! channel)
|
||||||
data |= 0x05; /* odd sub frame, 'Y' */
|
data |= iec->preamble[PREAMBLE_Y]; /* odd sub frame, 'Y' */
|
||||||
else
|
else
|
||||||
data |= 0x09; /* even sub frame, 'X' */
|
data |= iec->preamble[PREAMBLE_X]; /* even sub frame, 'X' */
|
||||||
|
|
||||||
if (iec->byteswap)
|
if (iec->byteswap)
|
||||||
data = bswap_32(data);
|
data = bswap_32(data);
|
||||||
|
|
@ -437,7 +440,10 @@ static snd_pcm_ops_t snd_pcm_iec958_ops = {
|
||||||
* of compatibility reasons. The prototype might be freely
|
* of compatibility reasons. The prototype might be freely
|
||||||
* changed in future.
|
* changed in future.
|
||||||
*/
|
*/
|
||||||
int snd_pcm_iec958_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sformat, snd_pcm_t *slave, int close_slave, const unsigned char *status_bits)
|
int snd_pcm_iec958_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sformat,
|
||||||
|
snd_pcm_t *slave, int close_slave,
|
||||||
|
const unsigned char *status_bits,
|
||||||
|
const unsigned char *preamble_vals)
|
||||||
{
|
{
|
||||||
snd_pcm_t *pcm;
|
snd_pcm_t *pcm;
|
||||||
snd_pcm_iec958_t *iec;
|
snd_pcm_iec958_t *iec;
|
||||||
|
|
@ -473,6 +479,8 @@ int snd_pcm_iec958_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sfo
|
||||||
else
|
else
|
||||||
memcpy(iec->status, default_status_bits, sizeof(default_status_bits));
|
memcpy(iec->status, default_status_bits, sizeof(default_status_bits));
|
||||||
|
|
||||||
|
memcpy(iec->preamble, preamble_vals, 3);
|
||||||
|
|
||||||
err = snd_pcm_new(&pcm, SND_PCM_TYPE_IEC958, name, slave->stream, slave->mode);
|
err = snd_pcm_new(&pcm, SND_PCM_TYPE_IEC958, name, slave->stream, slave->mode);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
free(iec);
|
free(iec);
|
||||||
|
|
@ -508,6 +516,12 @@ pcm.name {
|
||||||
pcm { } # Slave PCM definition
|
pcm { } # Slave PCM definition
|
||||||
}
|
}
|
||||||
[status status-bytes] # IEC958 status bits (given in byte array)
|
[status status-bytes] # IEC958 status bits (given in byte array)
|
||||||
|
# IEC958 preamble bits definitions
|
||||||
|
# B/M/W or Z/X/Y, B = block start, M = even subframe, W = odd subframe
|
||||||
|
# As default, Z = 0x08, Y = 0x04, X = 0x02
|
||||||
|
[preamble.z or preamble.b val]
|
||||||
|
[preamble.x or preamble.m val]
|
||||||
|
[preamble.y or preamble.w val]
|
||||||
}
|
}
|
||||||
\endcode
|
\endcode
|
||||||
|
|
||||||
|
|
@ -541,9 +555,12 @@ int _snd_pcm_iec958_open(snd_pcm_t **pcmp, const char *name,
|
||||||
int err;
|
int err;
|
||||||
snd_pcm_t *spcm;
|
snd_pcm_t *spcm;
|
||||||
snd_config_t *slave = NULL, *sconf;
|
snd_config_t *slave = NULL, *sconf;
|
||||||
snd_config_t *status = NULL;
|
snd_config_t *status = NULL, *preamble = NULL;
|
||||||
snd_pcm_format_t sformat;
|
snd_pcm_format_t sformat;
|
||||||
unsigned char status_bits[24];
|
unsigned char status_bits[24];
|
||||||
|
unsigned char preamble_vals[3] = {
|
||||||
|
0x08, 0x02, 0x04 /* Z, X, Y */
|
||||||
|
};
|
||||||
|
|
||||||
snd_config_for_each(i, next, conf) {
|
snd_config_for_each(i, next, conf) {
|
||||||
snd_config_t *n = snd_config_iterator_entry(i);
|
snd_config_t *n = snd_config_iterator_entry(i);
|
||||||
|
|
@ -564,6 +581,14 @@ int _snd_pcm_iec958_open(snd_pcm_t **pcmp, const char *name,
|
||||||
status = n;
|
status = n;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (strcmp(id, "preamble") == 0) {
|
||||||
|
if (snd_config_get_type(n) != SND_CONFIG_TYPE_COMPOUND) {
|
||||||
|
SNDERR("Invalid type for %s", id);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
preamble = n;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
SNDERR("Unknown field %s", id);
|
SNDERR("Unknown field %s", id);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
@ -590,6 +615,33 @@ int _snd_pcm_iec958_open(snd_pcm_t **pcmp, const char *name,
|
||||||
}
|
}
|
||||||
// fprintf(stderr, "STATUS bits: %02x %02x %02x %02x\n", status_bits[0], status_bits[1], status_bits[2], status_bits[3]);
|
// fprintf(stderr, "STATUS bits: %02x %02x %02x %02x\n", status_bits[0], status_bits[1], status_bits[2], status_bits[3]);
|
||||||
}
|
}
|
||||||
|
if (preamble) {
|
||||||
|
snd_config_iterator_t i, inext;
|
||||||
|
snd_config_for_each(i, inext, status) {
|
||||||
|
long val;
|
||||||
|
snd_config_t *n = snd_config_iterator_entry(i);
|
||||||
|
const char *id;
|
||||||
|
int idx;
|
||||||
|
if (snd_config_get_id(n, &id) < 0)
|
||||||
|
continue;
|
||||||
|
if (strcmp(id, "b") == 0 || strcmp(id, "z") == 0)
|
||||||
|
idx = PREAMBLE_Z;
|
||||||
|
else if (strcmp(id, "m") == 0 || strcmp(id, "x") == 0)
|
||||||
|
idx = PREAMBLE_X;
|
||||||
|
else if (strcmp(id, "w") == 0 || strcmp(id, "y") == 0)
|
||||||
|
idx = PREAMBLE_Y;
|
||||||
|
else {
|
||||||
|
SNDERR("invalid IEC958 preamble type %s", id);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
err = snd_config_get_integer(n, &val);
|
||||||
|
if (err < 0) {
|
||||||
|
SNDERR("invalid IEC958 preamble value");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
preamble_vals[idx] = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!slave) {
|
if (!slave) {
|
||||||
SNDERR("slave is not defined");
|
SNDERR("slave is not defined");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
@ -609,7 +661,9 @@ int _snd_pcm_iec958_open(snd_pcm_t **pcmp, const char *name,
|
||||||
snd_config_delete(sconf);
|
snd_config_delete(sconf);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
err = snd_pcm_iec958_open(pcmp, name, sformat, spcm, 1, status ? status_bits : NULL);
|
err = snd_pcm_iec958_open(pcmp, name, sformat, spcm, 1,
|
||||||
|
status ? status_bits : NULL,
|
||||||
|
preamble_vals);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
snd_pcm_close(spcm);
|
snd_pcm_close(spcm);
|
||||||
return err;
|
return err;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue