[stage: 4/9]

- Rearrange FEEDER_* constants starting from 0 to 31, so the future
  additions will be much easier and consistent.
- Introduce FEEDER_SWAPLR. Few super broken hardwares (found on several
  extremely cheap uaudio stick, possibly others) mistakenly wired left
  and right channels wrongly, screwing output or input.
This commit is contained in:
Ariff Abdullah 2007-03-16 17:15:33 +00:00
parent e956c4e11f
commit c30ec7427a
4 changed files with 63 additions and 31 deletions

View File

@ -1795,7 +1795,7 @@ chn_buildfeeder(struct pcm_channel *c)
DEB(printf("feederflags %x\n", flags));
for (type = FEEDER_RATE; type <= FEEDER_LAST; type++) {
for (type = FEEDER_RATE; type < FEEDER_LAST; type++) {
if (flags & (1 << type)) {
desc.type = type;
desc.in = 0;

View File

@ -37,8 +37,40 @@ MALLOC_DEFINE(M_FEEDER, "feeder", "pcm feeder");
int feeder_buffersize = FEEDBUFSZ;
TUNABLE_INT("hw.snd.feeder_buffersize", &feeder_buffersize);
#ifdef SND_DEBUG
static int
sysctl_hw_snd_feeder_buffersize(SYSCTL_HANDLER_ARGS)
{
int i, err, val;
val = feeder_buffersize;
err = sysctl_handle_int(oidp, &val, sizeof(val), req);
if (err != 0 || req->newptr == NULL)
return err;
if (val < FEEDBUFSZ_MIN || val > FEEDBUFSZ_MAX)
return EINVAL;
i = 0;
while (val >> i)
i++;
i = 1 << i;
if (i > val && (i >> 1) > 0 && (i >> 1) >= ((val * 3) >> 2))
i >>= 1;
feeder_buffersize = i;
return err;
}
SYSCTL_PROC(_hw_snd, OID_AUTO, feeder_buffersize, CTLTYPE_INT | CTLFLAG_RW,
0, sizeof(int), sysctl_hw_snd_feeder_buffersize, "I",
"feeder buffer size");
#else
SYSCTL_INT(_hw_snd, OID_AUTO, feeder_buffersize, CTLFLAG_RD,
&feeder_buffersize, FEEDBUFSZ, "feeder buffer size");
#endif
struct feedertab_entry {
SLIST_ENTRY(feedertab_entry) link;
@ -824,10 +856,9 @@ feed_root(struct pcm_feeder *feeder, struct pcm_channel *ch, u_int8_t *buffer, u
offset, count, l, ch->feedcount);
if (ch->feedcount == 1) {
if (offset > 0)
memset(buffer,
sndbuf_zerodata(sndbuf_getfmt(src)),
offset);
memset(buffer,
sndbuf_zerodata(sndbuf_getfmt(src)),
offset);
if (l > 0)
sndbuf_dispose(src, buffer + offset, l);
else
@ -835,34 +866,32 @@ feed_root(struct pcm_feeder *feeder, struct pcm_channel *ch, u_int8_t *buffer, u
} else {
if (l > 0)
sndbuf_dispose(src, buffer, l);
if (offset > 0) {
#if 1
memset(buffer + l,
sndbuf_zerodata(sndbuf_getfmt(src)),
offset);
if (!(ch->flags & CHN_F_CLOSING))
ch->xruns++;
#else
if (l < 1 || (ch->flags & CHN_F_CLOSING)) {
memset(buffer + l,
sndbuf_zerodata(sndbuf_getfmt(src)),
offset);
if (!(ch->flags & CHN_F_CLOSING))
ch->xruns++;
#else
if (l < 1 || (ch->flags & CHN_F_CLOSING)) {
memset(buffer + l,
sndbuf_zerodata(sndbuf_getfmt(src)),
offset);
if (!(ch->flags & CHN_F_CLOSING))
ch->xruns++;
} else {
int cp, tgt;
} else {
int cp, tgt;
tgt = l;
while (offset > 0) {
cp = min(l, offset);
memcpy(buffer + tgt, buffer, cp);
offset -= cp;
tgt += cp;
}
ch->xruns++;
tgt = l;
while (offset > 0) {
cp = min(l, offset);
memcpy(buffer + tgt, buffer, cp);
offset -= cp;
tgt += cp;
}
#endif
ch->xruns++;
}
#endif
}
} else if (l > 0)
sndbuf_dispose(src, buffer, l);

View File

@ -74,13 +74,14 @@ static struct feeder_class feeder ## _class = { \
}; \
SYSINIT(feeder, SI_SUB_DRIVERS, SI_ORDER_ANY, feeder_register, &feeder ## _class);
#define FEEDER_ROOT 1
#define FEEDER_FMT 2
#define FEEDER_MIXER 3
#define FEEDER_RATE 4
#define FEEDER_FILTER 5
#define FEEDER_VOLUME 6
#define FEEDER_LAST FEEDER_VOLUME
#define FEEDER_ROOT 0
#define FEEDER_FMT 1
#define FEEDER_MIXER 2
#define FEEDER_RATE 3
#define FEEDER_FILTER 4
#define FEEDER_VOLUME 5
#define FEEDER_SWAPLR 6
#define FEEDER_LAST 32
#define FEEDRATE_SRC 1
#define FEEDRATE_DST 2

View File

@ -138,6 +138,8 @@ nomenclature:
#define SD_F_SIMPLEX 0x00000001
#define SD_F_AUTOVCHAN 0x00000002
#define SD_F_SOFTPCMVOL 0x00000004
#define SD_F_PSWAPLR 0x00000008
#define SD_F_RSWAPLR 0x00000010
#define SD_F_PRIO_RD 0x10000000
#define SD_F_PRIO_WR 0x20000000
#define SD_F_PRIO_SET (SD_F_PRIO_RD | SD_F_PRIO_WR)