From: Takashi Iwai Date: Wed, 15 Dec 2004 15:17:36 +0000 (+0000) Subject: Add preamble value configuration for iec958 plugin X-Git-Tag: v1.0.8~26 X-Git-Url: https://git.alsa-project.org/?a=commitdiff_plain;h=73aa2549d9c6ad623159674f5cbb53dabf9c28d5;p=alsa-lib.git 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. --- diff --git a/src/conf/cards/CMI8338-SWIEC.conf b/src/conf/cards/CMI8338-SWIEC.conf index 5e89505a..d7ed2099 100644 --- a/src/conf/cards/CMI8338-SWIEC.conf +++ b/src/conf/cards/CMI8338-SWIEC.conf @@ -95,6 +95,9 @@ CMI8338-SWIEC.pcm.iec958.0 { device 2 } status [ $AES0 $AES1 $AES2 $AES3 ] + preamble.z 3 + preamble.y 5 + preamble.x 9 } capture.pcm { type hw diff --git a/src/pcm/pcm_iec958.c b/src/pcm/pcm_iec958.c index 23dd1b97..a87846c0 100644 --- a/src/pcm/pcm_iec958.c +++ b/src/pcm/pcm_iec958.c @@ -59,8 +59,11 @@ struct snd_pcm_iec958 { unsigned int counter; unsigned char status[24]; unsigned int byteswap; + unsigned char preamble[3]; /* B/M/W or Z/X/Y */ }; +enum { PREAMBLE_Z, PREAMBLE_X, PREAMBLE_Y }; + #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 */ if (! iec->counter) - data |= 0x03; /* Block start, 'Z' */ + data |= iec->preamble[PREAMBLE_Z]; /* Block start, 'Z' */ else if (! channel) - data |= 0x05; /* odd sub frame, 'Y' */ + data |= iec->preamble[PREAMBLE_Y]; /* odd sub frame, 'Y' */ else - data |= 0x09; /* even sub frame, 'X' */ + data |= iec->preamble[PREAMBLE_X]; /* even sub frame, 'X' */ if (iec->byteswap) 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 * 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_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 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); if (err < 0) { free(iec); @@ -508,6 +516,12 @@ pcm.name { pcm { } # Slave PCM definition } [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 @@ -541,9 +555,12 @@ int _snd_pcm_iec958_open(snd_pcm_t **pcmp, const char *name, int err; snd_pcm_t *spcm; snd_config_t *slave = NULL, *sconf; - snd_config_t *status = NULL; + snd_config_t *status = NULL, *preamble = NULL; snd_pcm_format_t sformat; 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_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; 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); 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]); } + 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) { SNDERR("slave is not defined"); return -EINVAL; @@ -609,7 +661,9 @@ int _snd_pcm_iec958_open(snd_pcm_t **pcmp, const char *name, snd_config_delete(sconf); if (err < 0) 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) snd_pcm_close(spcm); return err;