minor tweaks in speed and format setting routines.
don't stop exploring the feeders if a feeder fails to initialise.
This commit is contained in:
parent
cca900c66b
commit
f51ad0092e
@ -184,7 +184,7 @@ chn_wrfeed(struct pcm_channel *c)
|
||||
|
||||
amt = sndbuf_getfree(b);
|
||||
ret = (amt > 0)? sndbuf_feed(bs, b, c, c->feeder, amt) : ENOSPC;
|
||||
if (ret == 0)
|
||||
if (ret == 0 && sndbuf_getfree(b) < amt)
|
||||
chn_wakeup(c);
|
||||
/*
|
||||
if (!(irqc & 63) || (ret != 0))
|
||||
@ -724,9 +724,8 @@ chn_tryspeed(struct pcm_channel *c, int speed)
|
||||
c->speed = speed;
|
||||
sndbuf_setspd(bs, speed);
|
||||
RANGE(speed, chn_getcaps(c)->minspeed, chn_getcaps(c)->maxspeed);
|
||||
sndbuf_setspd(b, speed);
|
||||
DEB(printf("try speed %d, ", sndbuf_getspd(b)));
|
||||
sndbuf_setspd(b, CHANNEL_SETSPEED(c->methods, c->devinfo, sndbuf_getspd(b)));
|
||||
DEB(printf("try speed %d, ", speed));
|
||||
sndbuf_setspd(b, CHANNEL_SETSPEED(c->methods, c->devinfo, speed));
|
||||
DEB(printf("got speed %d, ", sndbuf_getspd(b)));
|
||||
|
||||
delta = sndbuf_getspd(b) - sndbuf_getspd(bs);
|
||||
@ -789,23 +788,17 @@ chn_tryformat(struct pcm_channel *c, u_int32_t fmt)
|
||||
struct snd_dbuf *b = c->bufhard;
|
||||
struct snd_dbuf *bs = c->bufsoft;
|
||||
int r;
|
||||
u_int32_t hwfmt;
|
||||
|
||||
CHN_LOCKASSERT(c);
|
||||
if (CANCHANGE(c)) {
|
||||
DEB(printf("want format %d\n", fmt));
|
||||
c->format = fmt;
|
||||
hwfmt = c->format;
|
||||
c->feederflags &= ~(1 << FEEDER_FMT);
|
||||
if (!fmtvalid(hwfmt, chn_getcaps(c)->fmtlist))
|
||||
c->feederflags |= 1 << FEEDER_FMT;
|
||||
r = chn_buildfeeder(c);
|
||||
if (r == 0) {
|
||||
hwfmt = c->feeder->desc->out;
|
||||
sndbuf_setfmt(b, hwfmt);
|
||||
sndbuf_setfmt(b, c->feeder->desc->out);
|
||||
sndbuf_setfmt(bs, fmt);
|
||||
chn_resetbuf(c);
|
||||
CHANNEL_SETFORMAT(c->methods, c->devinfo, hwfmt);
|
||||
CHANNEL_SETFORMAT(c->methods, c->devinfo, sndbuf_getfmt(b));
|
||||
r = chn_tryspeed(c, c->speed);
|
||||
}
|
||||
return r;
|
||||
@ -958,24 +951,33 @@ chn_buildfeeder(struct pcm_channel *c)
|
||||
{
|
||||
struct feeder_class *fc;
|
||||
struct pcm_feederdesc desc;
|
||||
u_int32_t tmp[2], src, dst, type, flags;
|
||||
u_int32_t tmp[2], type, flags;
|
||||
|
||||
CHN_LOCKASSERT(c);
|
||||
while (chn_removefeeder(c) == 0);
|
||||
KASSERT((c->feeder == NULL), ("feeder chain not empty"));
|
||||
|
||||
c->align = sndbuf_getalign(c->bufsoft);
|
||||
|
||||
fc = feeder_getclass(NULL);
|
||||
if (fc == NULL)
|
||||
if (fc == NULL) {
|
||||
DEB(printf("can't find root feeder\n"));
|
||||
return EINVAL;
|
||||
if (chn_addfeeder(c, fc, NULL))
|
||||
}
|
||||
if (chn_addfeeder(c, fc, NULL)) {
|
||||
DEB(printf("can't add root feeder\n"));
|
||||
return EINVAL;
|
||||
}
|
||||
c->feeder->desc->out = c->format;
|
||||
|
||||
flags = c->feederflags;
|
||||
src = c->feeder->desc->out;
|
||||
if ((c->flags & CHN_F_MAPPED) && (flags != 0))
|
||||
|
||||
if ((c->flags & CHN_F_MAPPED) && (flags != 0)) {
|
||||
DEB(printf("can't build feeder chain on mapped channel\n"));
|
||||
return EINVAL;
|
||||
DEB(printf("not mapped, flags %x, ", flags));
|
||||
}
|
||||
DEB(printf("not mapped, flags %x\n", flags));
|
||||
|
||||
for (type = FEEDER_RATE; type <= FEEDER_LAST; type++) {
|
||||
if (flags & (1 << type)) {
|
||||
desc.type = type;
|
||||
@ -985,33 +987,38 @@ chn_buildfeeder(struct pcm_channel *c)
|
||||
DEB(printf("find feeder type %d, ", type));
|
||||
fc = feeder_getclass(&desc);
|
||||
DEB(printf("got %p\n", fc));
|
||||
if (fc == NULL)
|
||||
if (fc == NULL) {
|
||||
DEB(printf("can't find required feeder type %d\n", type));
|
||||
return EINVAL;
|
||||
dst = fc->desc->in;
|
||||
if (src != dst) {
|
||||
DEB(printf("build fmtchain from %x to %x: ", src, dst));
|
||||
tmp[0] = dst;
|
||||
}
|
||||
|
||||
if (c->feeder->desc->out != fc->desc->in) {
|
||||
DEB(printf("build fmtchain from %x to %x: ", c->feeder->desc->out, fc->desc->in));
|
||||
tmp[0] = fc->desc->in;
|
||||
tmp[1] = 0;
|
||||
if (chn_fmtchain(c, tmp) == 0)
|
||||
if (chn_fmtchain(c, tmp) == 0) {
|
||||
DEB(printf("failed\n"));
|
||||
return EINVAL;
|
||||
}
|
||||
DEB(printf("ok\n"));
|
||||
}
|
||||
if (chn_addfeeder(c, fc, fc->desc))
|
||||
|
||||
if (chn_addfeeder(c, fc, fc->desc)) {
|
||||
DEB(printf("can't add feeder %p, output %x\n", fc, fc->desc->out));
|
||||
return EINVAL;
|
||||
src = fc->desc->out;
|
||||
DEB(printf("added feeder %p, output %x\n", fc, src));
|
||||
dst = 0;
|
||||
flags &= ~(1 << type);
|
||||
}
|
||||
DEB(printf("added feeder %p, output %x\n", fc, c->feeder->desc->out));
|
||||
}
|
||||
}
|
||||
if (!fmtvalid(src, chn_getcaps(c)->fmtlist)) {
|
||||
if (chn_fmtchain(c, chn_getcaps(c)->fmtlist) == 0)
|
||||
|
||||
if (!fmtvalid(c->feeder->desc->out, chn_getcaps(c)->fmtlist)) {
|
||||
if (chn_fmtchain(c, chn_getcaps(c)->fmtlist) == 0) {
|
||||
DEB(printf("can't build fmtchain from %x\n", c->feeder->desc->out));
|
||||
return EINVAL;
|
||||
DEB(printf("built fmtchain from %x to %x\n", src, c->feeder->desc->out));
|
||||
flags &= ~(1 << FEEDER_FMT);
|
||||
}
|
||||
DEB(printf("built fmtchain from %x\n", c->feeder->desc->out));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -69,6 +69,7 @@ feeder_register(void *p)
|
||||
|
||||
i = 0;
|
||||
while ((feedercnt < MAXFEEDERS) && (fc->desc[i].type > 0)) {
|
||||
printf("adding feeder %s, %x -> %x\n", fc->name, fc->desc[i].in, fc->desc[i].out);
|
||||
fte = malloc(sizeof(*fte), M_FEEDER, M_WAITOK | M_ZERO);
|
||||
fte->feederclass = fc;
|
||||
fte->desc = &fc->desc[i];
|
||||
@ -132,8 +133,10 @@ feeder_create(struct feeder_class *fc, struct pcm_feederdesc *desc)
|
||||
}
|
||||
f->data = fc->data;
|
||||
f->source = NULL;
|
||||
f->class = fc;
|
||||
err = FEEDER_INIT(f);
|
||||
if (err) {
|
||||
printf("feeder_init(%p) on %s returned %d\n", f, fc->name, err);
|
||||
feeder_destroy(f);
|
||||
return NULL;
|
||||
} else
|
||||
@ -230,9 +233,8 @@ feeder_fmtchain(u_int32_t *to, struct pcm_feeder *source, struct pcm_feeder *sto
|
||||
{
|
||||
struct feedertab_entry *fte;
|
||||
struct pcm_feeder *try, *ret;
|
||||
struct pcm_feederdesc trydesc;
|
||||
|
||||
/* printf("trying %s...\n", source->name); */
|
||||
/* printf("trying %s (%x -> %x)...\n", source->class->name, source->desc->in, source->desc->out); */
|
||||
if (fmtvalid(source->desc->out, to)) {
|
||||
/* printf("got it\n"); */
|
||||
return source;
|
||||
@ -241,27 +243,24 @@ feeder_fmtchain(u_int32_t *to, struct pcm_feeder *source, struct pcm_feeder *sto
|
||||
if (maxdepth < 0)
|
||||
return NULL;
|
||||
|
||||
trydesc.type = FEEDER_FMT;
|
||||
trydesc.in = source->desc->out;
|
||||
trydesc.out = 0;
|
||||
trydesc.flags = 0;
|
||||
trydesc.idx = -1;
|
||||
|
||||
SLIST_FOREACH(fte, &feedertab, link) {
|
||||
if ((fte->desc) && (fte->desc->in == source->desc->out)) {
|
||||
trydesc.out = fte->desc->out;
|
||||
trydesc.idx = fte->idx;
|
||||
try = feeder_create(fte->feederclass, &trydesc);
|
||||
if (try == NULL)
|
||||
return NULL;
|
||||
try->source = source;
|
||||
ret = chainok(try, stop)? feeder_fmtchain(to, try, stop, maxdepth - 1) : NULL;
|
||||
if (ret != NULL)
|
||||
return ret;
|
||||
feeder_destroy(try);
|
||||
if (fte->desc == NULL)
|
||||
goto no;
|
||||
if (fte->desc->type != FEEDER_FMT)
|
||||
goto no;
|
||||
if (fte->desc->in == source->desc->out) {
|
||||
try = feeder_create(fte->feederclass, fte->desc);
|
||||
if (try) {
|
||||
try->source = source;
|
||||
ret = chainok(try, stop)? feeder_fmtchain(to, try, stop, maxdepth - 1) : NULL;
|
||||
if (ret != NULL)
|
||||
return ret;
|
||||
feeder_destroy(try);
|
||||
}
|
||||
}
|
||||
no:
|
||||
}
|
||||
/* printf("giving up %s...\n", source->name); */
|
||||
/* printf("giving up %s...\n", source->class->name); */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -287,7 +286,7 @@ chn_fmtchain(struct pcm_channel *c, u_int32_t *to)
|
||||
#endif
|
||||
while (try && (try != stop)) {
|
||||
#ifdef FEEDER_DEBUG
|
||||
printf("%s [%d]", try->name, try->desc->idx);
|
||||
printf("%s [%d]", try->class->name, try->desc->idx);
|
||||
if (try->source)
|
||||
printf(" -> ");
|
||||
#endif
|
||||
@ -298,7 +297,7 @@ chn_fmtchain(struct pcm_channel *c, u_int32_t *to)
|
||||
try = try->source;
|
||||
}
|
||||
#ifdef FEEDER_DEBUG
|
||||
printf("%s [%d]\n", try->name, try->desc->idx);
|
||||
printf("%s [%d]\n", try->class->name, try->desc->idx);
|
||||
#endif
|
||||
return c->feeder->desc->out;
|
||||
}
|
||||
|
@ -33,14 +33,6 @@ struct pcm_feederdesc {
|
||||
int idx;
|
||||
};
|
||||
|
||||
struct pcm_feeder {
|
||||
KOBJ_FIELDS;
|
||||
int align;
|
||||
struct pcm_feederdesc *desc;
|
||||
void *data;
|
||||
struct pcm_feeder *source;
|
||||
};
|
||||
|
||||
struct feeder_class {
|
||||
KOBJ_CLASS_FIELDS;
|
||||
int align;
|
||||
@ -48,6 +40,15 @@ struct feeder_class {
|
||||
void *data;
|
||||
};
|
||||
|
||||
struct pcm_feeder {
|
||||
KOBJ_FIELDS;
|
||||
int align;
|
||||
struct pcm_feederdesc *desc;
|
||||
void *data;
|
||||
struct feeder_class *class;
|
||||
struct pcm_feeder *source;
|
||||
};
|
||||
|
||||
void feeder_register(void *p);
|
||||
struct feeder_class *feeder_getclass(struct pcm_feederdesc *desc);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user