version 1.29, 2009/08/21 16:48:03 |
version 1.30, 2009/09/27 11:51:20 |
|
|
{ |
{ |
struct file *f; |
struct file *f; |
|
|
DPRINTF("dev_loopdone:\n"); |
|
|
|
dev_sub->refs--; |
dev_sub->refs--; |
dev_sub = NULL; |
dev_sub = NULL; |
dev_mix->refs--; |
dev_mix->refs--; |
|
|
if (f == NULL) |
if (f == NULL) |
return 0; |
return 0; |
if (dipar) { |
if (dipar) { |
#ifdef DEBUG |
|
if (debug_level > 0) { |
|
fprintf(stderr, "dev_init: hw recording "); |
|
aparams_print(dipar); |
|
fprintf(stderr, "\n"); |
|
} |
|
#endif |
|
dev_rate = dipar->rate; |
dev_rate = dipar->rate; |
} |
} |
if (dopar) { |
if (dopar) { |
#ifdef DEBUG |
|
if (debug_level > 0) { |
|
fprintf(stderr, "dev_init: hw playing "); |
|
aparams_print(dopar); |
|
fprintf(stderr, "\n"); |
|
} |
|
#endif |
|
dev_rate = dopar->rate; |
dev_rate = dopar->rate; |
} |
} |
ibufsz = obufsz = dev_bufsz; |
ibufsz = obufsz = dev_bufsz; |
|
|
* Append a converter, if needed. |
* Append a converter, if needed. |
*/ |
*/ |
if (!aparams_eqenc(dipar, &ipar)) { |
if (!aparams_eqenc(dipar, &ipar)) { |
conv = dec_new("subin", dipar); |
conv = dec_new("rec", dipar); |
aproc_setin(conv, buf); |
aproc_setin(conv, buf); |
buf = abuf_new(nfr, &ipar); |
buf = abuf_new(nfr, &ipar); |
aproc_setout(conv, buf); |
aproc_setout(conv, buf); |
|
|
/* |
/* |
* Append a "sub" to which clients will connect. |
* Append a "sub" to which clients will connect. |
*/ |
*/ |
dev_sub = sub_new("sub", nfr); |
dev_sub = sub_new("rec", nfr); |
dev_sub->refs++; |
dev_sub->refs++; |
aproc_setin(dev_sub, buf); |
aproc_setin(dev_sub, buf); |
} else { |
} else { |
|
|
* Append a converter, if needed. |
* Append a converter, if needed. |
*/ |
*/ |
if (!aparams_eqenc(&opar, dopar)) { |
if (!aparams_eqenc(&opar, dopar)) { |
conv = enc_new("mixout", dopar); |
conv = enc_new("play", dopar); |
aproc_setout(conv, buf); |
aproc_setout(conv, buf); |
buf = abuf_new(nfr, &opar); |
buf = abuf_new(nfr, &opar); |
aproc_setin(conv, buf); |
aproc_setin(conv, buf); |
|
|
/* |
/* |
* Append a "mix" to which clients will connect. |
* Append a "mix" to which clients will connect. |
*/ |
*/ |
dev_mix = mix_new("mix", nfr); |
dev_mix = mix_new("play", nfr); |
dev_mix->refs++; |
dev_mix->refs++; |
aproc_setout(dev_mix, buf); |
aproc_setout(dev_mix, buf); |
} else { |
} else { |
|
|
dev_mix = NULL; |
dev_mix = NULL; |
} |
} |
dev_bufsz = (dopar) ? obufsz : ibufsz; |
dev_bufsz = (dopar) ? obufsz : ibufsz; |
DPRINTF("dev_init: using %u fpb\n", dev_bufsz); |
|
dev_midi = ctl_new("ctl"); |
dev_midi = ctl_new("ctl"); |
dev_midi->refs++; |
dev_midi->refs++; |
dev_start(); |
dev_start(); |
|
|
{ |
{ |
struct file *f; |
struct file *f; |
|
|
DPRINTF("dev_done: dev_mix = %p, dev_sub = %p\n", dev_mix, dev_sub); |
|
dev_midi->refs--; |
dev_midi->refs--; |
aproc_del(dev_midi); |
aproc_del(dev_midi); |
dev_midi = NULL; |
dev_midi = NULL; |
|
|
ibuf = *sibuf; |
ibuf = *sibuf; |
for (;;) { |
for (;;) { |
if (!ibuf || !ibuf->rproc) { |
if (!ibuf || !ibuf->rproc) { |
DPRINTF("dev_getep: reader desappeared\n"); |
|
return 0; |
return 0; |
} |
} |
if (ibuf->rproc == dev_mix) |
if (ibuf->rproc == dev_mix) |
|
|
obuf = *sobuf; |
obuf = *sobuf; |
for (;;) { |
for (;;) { |
if (!obuf || !obuf->wproc) { |
if (!obuf || !obuf->wproc) { |
DPRINTF("dev_getep: writer desappeared\n"); |
|
return 0; |
return 0; |
} |
} |
if (obuf->wproc == dev_sub) |
if (obuf->wproc == dev_sub) |
|
|
rbuf->bpf * (pbuf->abspos + pbuf->used) - |
rbuf->bpf * (pbuf->abspos + pbuf->used) - |
pbuf->bpf * rbuf->abspos; |
pbuf->bpf * rbuf->abspos; |
delta /= pbuf->bpf * rbuf->bpf; |
delta /= pbuf->bpf * rbuf->bpf; |
DPRINTF("dev_sync: delta = %d, ppos = %u, pused = %u, rpos = %u\n", |
|
delta, pbuf->abspos, pbuf->used, rbuf->abspos); |
|
|
|
if (delta > 0) { |
if (delta > 0) { |
/* |
/* |
* If the play chain is ahead (most cases) drop some of |
* If the play chain is ahead (most cases) drop some of |
|
|
*/ |
*/ |
ibuf->silence += -delta * ibuf->bpf; |
ibuf->silence += -delta * ibuf->bpf; |
abuf_opos(ibuf, delta); |
abuf_opos(ibuf, delta); |
} else |
} |
DPRINTF("dev_sync: nothing to do\n"); |
|
} |
} |
|
|
/* |
/* |
|
|
void |
void |
dev_setvol(struct abuf *ibuf, int vol) |
dev_setvol(struct abuf *ibuf, int vol) |
{ |
{ |
DPRINTF("dev_setvol: %p\n", ibuf); |
|
if (!dev_getep(&ibuf, NULL)) { |
if (!dev_getep(&ibuf, NULL)) { |
DPRINTF("dev_setvol: not connected yet\n"); |
|
return; |
return; |
} |
} |
ibuf->mixvol = vol; |
ibuf->mixvol = vol; |
DPRINTF("dev_setvol: %p -> %d\n", ibuf, vol); |
|
} |
} |
|
|
/* |
/* |
|
|
struct abuf *buf; |
struct abuf *buf; |
|
|
if (dev_mix) { |
if (dev_mix) { |
if (!LIST_EMPTY(&dev_mix->ibuflist)) { |
|
fprintf(stderr, "dev_clear: mixer not idle\n"); |
|
abort(); |
|
} |
|
buf = LIST_FIRST(&dev_mix->obuflist); |
buf = LIST_FIRST(&dev_mix->obuflist); |
while (buf) { |
while (buf) { |
abuf_clear(buf); |
abuf_clear(buf); |
|
|
mix_clear(dev_mix); |
mix_clear(dev_mix); |
} |
} |
if (dev_sub) { |
if (dev_sub) { |
if (!LIST_EMPTY(&dev_sub->obuflist)) { |
|
fprintf(stderr, "dev_suspend: demux not idle\n"); |
|
abort(); |
|
} |
|
buf = LIST_FIRST(&dev_sub->ibuflist); |
buf = LIST_FIRST(&dev_sub->ibuflist); |
while (buf) { |
while (buf) { |
abuf_clear(buf); |
abuf_clear(buf); |