channel.c:
(1) Fix DMA alignment, based on bytes per sample. feeder_rate.c: Handle strayed bytes (mostly caused by #1) better. This DMA alignment issues are extremely hard to reproduce unless the user happen to have a 32bit capable soundcards (ATI IXP) and knowledgeable enough to force it to operate under pure 32bit operations on both record and play directions.
This commit is contained in:
parent
4aec3469f3
commit
c934cfadd1
@ -34,8 +34,11 @@
|
||||
SND_DECLARE_FILE("$FreeBSD$");
|
||||
|
||||
#define MIN_CHUNK_SIZE 256 /* for uiomove etc. */
|
||||
#if 0
|
||||
#define DMA_ALIGN_THRESHOLD 4
|
||||
#define DMA_ALIGN_MASK (~(DMA_ALIGN_THRESHOLD - 1))
|
||||
#endif
|
||||
#define DMA_ALIGN_MASK(bps) (~((bps) - 1))
|
||||
|
||||
#define CANCHANGE(c) (!(c->flags & CHN_F_TRIGGERED))
|
||||
|
||||
@ -1253,7 +1256,10 @@ chn_getptr(struct pcm_channel *c)
|
||||
#if 1
|
||||
hwptr &= ~a ; /* Apply channel align mask */
|
||||
#endif
|
||||
#if 0
|
||||
hwptr &= DMA_ALIGN_MASK; /* Apply DMA align mask */
|
||||
#endif
|
||||
hwptr &= DMA_ALIGN_MASK(sndbuf_getbps(c->bufhard));
|
||||
return hwptr;
|
||||
}
|
||||
|
||||
|
@ -100,6 +100,7 @@ struct feed_rate_info {
|
||||
uint32_t alpha; /* interpolation distance */
|
||||
uint32_t pos, bpos; /* current sample / buffer positions */
|
||||
uint32_t bufsz; /* total buffer size */
|
||||
uint32_t stray; /* stray bytes */
|
||||
int32_t scale, roll; /* scale / roll factor */
|
||||
int16_t *buffer;
|
||||
uint32_t (*convert)(struct feed_rate_info *, int16_t *, uint32_t);
|
||||
@ -350,6 +351,7 @@ feed_rate_setup(struct pcm_feeder *f)
|
||||
info->pos = 2;
|
||||
info->bpos = 4;
|
||||
info->alpha = 0;
|
||||
info->stray = 0;
|
||||
feed_rate_reset(info);
|
||||
if (info->src == info->dst) {
|
||||
/*
|
||||
@ -710,12 +712,13 @@ feed_rate(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
|
||||
slot = (((info->gx * (count >> 1)) + info->gy - info->alpha - 1) / info->gy) << 1;
|
||||
RATE_TEST((slot & 1) == 0, ("%s: Slot count not sample integral (%d)\n",
|
||||
__func__, slot));
|
||||
slot &= ~1;
|
||||
/*
|
||||
* Optimize buffer feeding aggresively to ensure calculated slot
|
||||
* can be fitted nicely into available buffer free space, hence
|
||||
* avoiding multiple feeding.
|
||||
*/
|
||||
RATE_TEST(info->stray == 0, ("%s: [1] Stray bytes: %u\n",
|
||||
__func__,info->stray));
|
||||
if (info->pos != 2 && info->bpos - info->pos == 2 &&
|
||||
info->bpos + slot > info->bufsz) {
|
||||
/*
|
||||
@ -734,25 +737,31 @@ feed_rate(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
|
||||
i = 0;
|
||||
for (;;) {
|
||||
for (;;) {
|
||||
fetch = info->bufsz - info->bpos;
|
||||
fetch = (info->bufsz - info->bpos) << 1;
|
||||
fetch -= info->stray;
|
||||
RATE_ASSERT(fetch >= 0,
|
||||
("%s: [1] Buffer overrun: %d > %d\n",
|
||||
__func__, info->bpos, info->bufsz));
|
||||
if (slot < fetch)
|
||||
fetch = slot;
|
||||
fetch &= ~1;
|
||||
if ((slot << 1) < fetch)
|
||||
fetch = slot << 1;
|
||||
if (fetch > 0) {
|
||||
RATE_TEST((fetch & 1) == 0,
|
||||
("%s: Fetch size not sample integral (%d)\n",
|
||||
__func__, fetch));
|
||||
RATE_ASSERT(((info->bpos << 1) - info->stray) >= 0 &&
|
||||
((info->bpos << 1) - info->stray) < (info->bufsz << 1),
|
||||
("%s: DANGER - BUFFER OVERRUN! bufsz=%d, pos=%d\n", __func__,
|
||||
info->bufsz << 1, (info->bpos << 1) - info->stray));
|
||||
fetch = FEEDER_FEED(f->source, c,
|
||||
(uint8_t *)(info->buffer + info->bpos),
|
||||
fetch << 1, source);
|
||||
(uint8_t *)(info->buffer) + (info->bpos << 1) - info->stray,
|
||||
fetch, source);
|
||||
info->stray = 0;
|
||||
if (fetch == 0)
|
||||
break;
|
||||
RATE_TEST((fetch & 3) == 0,
|
||||
("%s: Fetch size not byte integral (%d)\n",
|
||||
__func__, fetch));
|
||||
info->stray += fetch & 3;
|
||||
RATE_TEST(info->stray == 0,
|
||||
("%s: Stray bytes detected (%d)\n",
|
||||
__func__, info->stray));
|
||||
fetch >>= 1;
|
||||
fetch &= ~1;
|
||||
info->bpos += fetch;
|
||||
@ -790,6 +799,7 @@ feed_rate(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
|
||||
* to beginning of buffer so next cycle can
|
||||
* interpolate using it.
|
||||
*/
|
||||
RATE_TEST(info->stray == 0, ("%s: [2] Stray bytes: %u\n", __func__, info->stray));
|
||||
info->buffer[0] = info->buffer[info->pos - 2];
|
||||
info->buffer[1] = info->buffer[info->pos - 1];
|
||||
info->bpos = 2;
|
||||
@ -798,7 +808,10 @@ feed_rate(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
|
||||
if (i == count)
|
||||
break;
|
||||
}
|
||||
#if 0
|
||||
RATE_TEST(count == i, ("Expect: %u , Got: %u\n", count << 1, i << 1));
|
||||
#endif
|
||||
RATE_TEST(info->stray == 0, ("%s: [3] Stray bytes: %u\n", __func__, info->stray));
|
||||
return i << 1;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user