Skip to content

Commit b26abb9

Browse files
committed
mixer: avoid forwarding the overread to the waveform callback
Because the RSP mixer ucode does overread (that is, it can read a bit past the waveform end), we need to make sure that those extra bytes are 0 (in case of a non looping waveform). Up until now, this was left to the waveform callback to implement. We can do better: just like for the looping case, we can have the mixer handle this internally by clearing up the extra samples, calling the callback only for actual samples. This better matches the waveform callback API too, and makes things easier. Moreover, the overread now is 100% an implementation detail of the mixer.
1 parent eb58381 commit b26abb9

File tree

1 file changed

+16
-2
lines changed

1 file changed

+16
-2
lines changed

src/audio/mixer.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -324,8 +324,20 @@ static void waveform_read(void *ctx, samplebuffer_t *sbuf, int wpos, int wlen, b
324324
waveform_t *wave = (waveform_t*)ctx;
325325

326326
if (!wave->loop_len) {
327-
// No loop defined: just call the waveform's read function.
328-
wave->read(wave->ctx, sbuf, wpos, wlen, seeking);
327+
// If we're asked to read past the waveform length (because overread),
328+
// call the underlying function only up to the actual length,
329+
// and then zero the rest of data.
330+
int len1 = wlen;
331+
if (wpos + wlen > wave->len)
332+
len1 = MAX(wave->len - wpos, 0);
333+
int len2 = wlen-len1;
334+
335+
if (len1 > 0)
336+
wave->read(wave->ctx, sbuf, wpos, len1, seeking);
337+
if (len2 > 0) {
338+
void *dest = samplebuffer_append(sbuf, len2);
339+
memset(dest, 0, len2 << SAMPLES_BPS_SHIFT(sbuf));
340+
}
329341
} else {
330342
// Calculate wrapped position
331343
if (wpos >= wave->len)
@@ -458,6 +470,8 @@ void mixer_ch_set_limits(int ch, int max_bits, float max_frequency, int max_buf_
458470
assert(max_bits == 0 || max_bits == 8 || max_bits == 16);
459471
assert(max_frequency >= 0);
460472
assert(max_buf_sz >= 0 && max_buf_sz % 8 == 0);
473+
assert(ch >= 0 && ch < MIXER_MAX_CHANNELS);
474+
assert(!mixer_ch_playing(ch));
461475
tracef("mixer_ch_set_limits: ch=%d bits=%d maxfreq:%.2f bufsz:%d\n", ch, max_bits, max_frequency, max_buf_sz);
462476

463477
Mixer.limits[ch] = (channel_limit_t){

0 commit comments

Comments
 (0)