Skip to content

Commit d3709fa

Browse files
committed
right-justify 24 in 32 bit format.
1 parent 32316e3 commit d3709fa

2 files changed

Lines changed: 21 additions & 15 deletions

File tree

  • ports
    • espressif/common-hal/audioi2sin
    • raspberrypi/common-hal/audioi2sin

ports/espressif/common-hal/audioi2sin/I2SIn.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -142,18 +142,22 @@ static inline uint32_t i2sin_read_raw(const uint8_t *src, uint8_t in_depth) {
142142
return v;
143143
}
144144

145-
// Convert `raw` from `in_depth` to `out_depth` (shift-only semantics, sign-
146-
// preserving for signed) and write it to `buffer` at sample index `idx`.
145+
// Convert `raw` from `in_depth` to `out_depth` (sign-preserving for signed) and
146+
// write it to `buffer` at sample index `idx`. When upscaling, the value is
147+
// right-justified: the meaningful data stays in the low `in_depth` bits with the
148+
// upper bits carrying the sign, so a wider output uses a larger container without
149+
// scaling the magnitude up. (This means 24-bit-in-32-bit output is
150+
// right-justified)
147151
// Output element size: 1 byte at 8, 2 bytes at 16, 4 bytes at 24 or 32.
148152
static inline void i2sin_write_converted(void *buffer, uint32_t idx,
149153
uint32_t raw, uint8_t in_depth, uint8_t out_depth, bool samples_signed) {
150154
int32_t s = i2sin_normalize_signed(raw, in_depth);
151155
int32_t shifted;
152156
if (out_depth >= in_depth) {
153-
// Left-justify: place the input's bits in the high bits of the wider
154-
// output and leave the new low bits as zero. The API contract is that
155-
// for upscaled output the meaningful data is the high `in_depth` bits.
156-
shifted = s << (out_depth - in_depth);
157+
// Right-justify: keep the value as-is so the meaningful bits stay in the
158+
// low `in_depth` bits (upper bits already sign-extended). The wider
159+
// output just provides a larger container.
160+
shifted = s;
157161
} else {
158162
shifted = s >> (in_depth - out_depth);
159163
}

ports/raspberrypi/common-hal/audioi2sin/I2SIn.c

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -398,11 +398,13 @@ static inline int32_t i2sin_normalize_signed(uint32_t raw, uint8_t in_depth,
398398
}
399399

400400
// Write `raw` (input-depth bits, just-read FIFO sample) to `buffer` at sample
401-
// index `idx`, converting from `in_depth` to `out_depth` (shift-only
402-
// semantics, sign-preserving for signed) and (if needed) flipping the sign bit
403-
// for the unsigned-WAV convention. When upscaling, the input occupies the high
404-
// `in_depth` bits and the new low bits are left as zero. Output element size
405-
// follows `out_depth`: 1 byte at 8, 2 bytes at 16, 4 bytes at 24 or 32.
401+
// index `idx`, converting from `in_depth` to `out_depth` (sign-preserving for
402+
// signed) and (if needed) flipping the sign bit for the unsigned-WAV
403+
// convention. When upscaling, the value is right-justified: the meaningful data
404+
// stays in the low `in_depth` bits with the upper bits carrying the sign, so a
405+
// wider output simply uses a larger container without scaling the magnitude up.
406+
// (Note this means 24-bit-in-32-bit output is right-justified.) Output element size follows `out_depth`: 1 byte
407+
// at 8, 2 bytes at 16, 4 bytes at 24 or 32.
406408
//
407409
// For signed 24-bit output, the int32 slot holds the sign-extended value
408410
// (range -2^23 .. 2^23-1) — unlike the default `output_bit_depth=bit_depth=24`
@@ -414,10 +416,10 @@ static inline void i2sin_write_converted(void *buffer, uint32_t idx,
414416
int32_t s = i2sin_normalize_signed(raw, in_depth, left_justified);
415417
int32_t shifted;
416418
if (out_depth >= in_depth) {
417-
// Left-justify: place the input's bits in the high bits of the wider
418-
// output and leave the new low bits as zero. The API contract is that
419-
// for upscaled output the meaningful data is the high `in_depth` bits.
420-
shifted = s << (out_depth - in_depth);
419+
// Right-justify: keep the value as-is so the meaningful bits stay in the
420+
// low `in_depth` bits (upper bits already sign-extended). The wider
421+
// output just provides a larger container.
422+
shifted = s;
421423
} else {
422424
shifted = s >> (in_depth - out_depth);
423425
}

0 commit comments

Comments
 (0)