summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcg <cg@FreeBSD.org>2001-04-08 20:20:52 +0000
committercg <cg@FreeBSD.org>2001-04-08 20:20:52 +0000
commitf9db4ec2f7caac8d7765b3c64c6f06f9fe0e01df (patch)
tree42a528c13d069dea8cfd4ebce9fa8577021cf268
parentae6962d6df1aadf8c67606ad9b5bc54a36026878 (diff)
downloadFreeBSD-src-f9db4ec2f7caac8d7765b3c64c6f06f9fe0e01df.zip
FreeBSD-src-f9db4ec2f7caac8d7765b3c64c6f06f9fe0e01df.tar.gz
minor tweaks in speed and format setting routines.
don't stop exploring the feeders if a feeder fails to initialise.
-rw-r--r--sys/dev/sound/pcm/channel.c77
-rw-r--r--sys/dev/sound/pcm/feeder.c43
-rw-r--r--sys/dev/sound/pcm/feeder.h11
3 files changed, 69 insertions, 62 deletions
diff --git a/sys/dev/sound/pcm/channel.c b/sys/dev/sound/pcm/channel.c
index 12e97cd..83a98d1 100644
--- a/sys/dev/sound/pcm/channel.c
+++ b/sys/dev/sound/pcm/channel.c
@@ -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;
}
-
-
diff --git a/sys/dev/sound/pcm/feeder.c b/sys/dev/sound/pcm/feeder.c
index bfa9aba..6da2622 100644
--- a/sys/dev/sound/pcm/feeder.c
+++ b/sys/dev/sound/pcm/feeder.c
@@ -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;
}
diff --git a/sys/dev/sound/pcm/feeder.h b/sys/dev/sound/pcm/feeder.h
index c3910e5..2866813 100644
--- a/sys/dev/sound/pcm/feeder.h
+++ b/sys/dev/sound/pcm/feeder.h
@@ -33,19 +33,20 @@ struct pcm_feederdesc {
int idx;
};
-struct pcm_feeder {
- KOBJ_FIELDS;
+struct feeder_class {
+ KOBJ_CLASS_FIELDS;
int align;
struct pcm_feederdesc *desc;
void *data;
- struct pcm_feeder *source;
};
-struct feeder_class {
- KOBJ_CLASS_FIELDS;
+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);
OpenPOWER on IntegriCloud