Skip to content

Commit 5432257

Browse files
RP2040: fix 8-bit WAV "audio buffer too small" bug
Also subtly fixed 8- to 16-bit scaling math
1 parent 1c0155c commit 5432257

File tree

1 file changed

+11
-8
lines changed

1 file changed

+11
-8
lines changed

ports/raspberrypi/audio_dma.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -64,20 +64,23 @@ STATIC size_t audio_dma_convert_samples(audio_dma_t *dma, uint8_t *input, uint32
6464
if (dma->sample_resolution <= 8 && dma->output_resolution > 8) {
6565
// reading bytes, writing 16-bit words, so output buffer will be bigger.
6666

67-
output_length_used = output_length * 2;
68-
if (output_length_used > output_length) {
69-
mp_raise_RuntimeError(translate("Internal audio buffer too small"));
70-
}
67+
output_length_used *= 2;
7168

72-
size_t shift = dma->output_resolution - dma->sample_resolution;
69+
// Correct "rail-to-rail" scaling of arbitrary-depth input to output
70+
// requires more operations than this, but at least the vital 8- to
71+
// 16-bit cases are correctly scaled now. Prior code was only
72+
// considering 8-to-16 anyway, but had a slight DC offset in the
73+
// result, so this is no worse off WRT supported resolutions.
74+
uint16_t mul = ((1 << dma->output_resolution) - 1) / ((1 << dma->sample_resolution) - 1);
75+
uint16_t offset = (1 << dma->output_resolution) / 2;
7376

7477
for (uint32_t i = 0; i < input_length; i += dma->sample_spacing) {
7578
if (dma->signed_to_unsigned) {
76-
((uint16_t *)output)[out_i] = ((uint16_t)((int8_t *)input)[i] + 0x80) << shift;
79+
((uint16_t *)output)[out_i] = (uint16_t)((((int8_t *)input)[i] + 0x80) * mul);
7780
} else if (dma->unsigned_to_signed) {
78-
((int16_t *)output)[out_i] = ((int16_t)((uint8_t *)input)[i] - 0x80) << shift;
81+
((int16_t *)output)[out_i] = (int16_t)(((uint8_t *)input)[i] * mul - offset);
7982
} else {
80-
((uint16_t *)output)[out_i] = ((uint16_t)((uint8_t *)input)[i]) << shift;
83+
((uint16_t *)output)[out_i] = (uint16_t)(((uint8_t *)input)[i] * mul);
8184
}
8285
out_i += 1;
8386
}

0 commit comments

Comments
 (0)