Skip to content

Commit ed4d4a6

Browse files
Merge pull request #8436 from PaintYourDragon/main
RP2040: fix 8-bit WAV playback
2 parents d179eb4 + 2fe0fa5 commit ed4d4a6

File tree

1 file changed

+11
-5
lines changed

1 file changed

+11
-5
lines changed

ports/raspberrypi/audio_dma.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,20 +64,26 @@ 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;
67+
output_length_used *= 2;
6868
if (output_length_used > output_length) {
6969
mp_raise_RuntimeError(translate("Internal audio buffer too small"));
7070
}
7171

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

7480
for (uint32_t i = 0; i < input_length; i += dma->sample_spacing) {
7581
if (dma->signed_to_unsigned) {
76-
((uint16_t *)output)[out_i] = ((uint16_t)((int8_t *)input)[i] + 0x80) << shift;
82+
((uint16_t *)output)[out_i] = (uint16_t)((((int8_t *)input)[i] + 0x80) * mul);
7783
} else if (dma->unsigned_to_signed) {
78-
((int16_t *)output)[out_i] = ((int16_t)((uint8_t *)input)[i] - 0x80) << shift;
84+
((int16_t *)output)[out_i] = (int16_t)(((uint8_t *)input)[i] * mul - offset);
7985
} else {
80-
((uint16_t *)output)[out_i] = ((uint16_t)((uint8_t *)input)[i]) << shift;
86+
((uint16_t *)output)[out_i] = (uint16_t)(((uint8_t *)input)[i] * mul);
8187
}
8288
out_i += 1;
8389
}

0 commit comments

Comments
 (0)