nRF: PWMAudioOut: fix half-speed playback of stereo samples
The "spacing" of "buffer structure" is confusing, use the "channel count" instead. Testing performed on nrf52840 feather: Play stereo and mono, 8- and 16-bit, 8kHz RawSamples representing 333.33Hz square waves. Use both mono and stereo PWMAudioOut instances. Scope the RC-filtered signal and use the scope's frequency measurement function, verify the frequency is 333 or 334Hz in all tested cases. In the "stereo output" cases, verify both the L and R channels. Verify the output amplitude is the same in both channels. In the "stereo output" cases, run a second test where the L channel's amplitude is attenuated 50%. Verify the output amplitude is correct in each channel.
This commit is contained in:
parent
f5e913101c
commit
13620cc4db
@ -97,27 +97,28 @@ STATIC void fill_buffers(audiopwmio_pwmaudioout_obj_t *self, int buf) {
|
|||||||
common_hal_audiopwmio_pwmaudioout_stop(self);
|
common_hal_audiopwmio_pwmaudioout_stop(self);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uint32_t num_samples = buffer_length / self->bytes_per_sample / self->spacing;
|
uint32_t num_samples = buffer_length / self->bytes_per_sample / self->sample_channel_count;
|
||||||
|
uint16_t *end_dev_buffer = dev_buffer + 2 * num_samples;
|
||||||
|
|
||||||
if (self->bytes_per_sample == 1) {
|
if (self->bytes_per_sample == 1) {
|
||||||
uint8_t offset = self->signed_to_unsigned ? 0x80 : 0;
|
uint8_t offset = self->signed_to_unsigned ? 0x80 : 0;
|
||||||
uint16_t scale = self->scale;
|
uint16_t scale = self->scale;
|
||||||
for (uint32_t i=0; i<buffer_length/self->spacing; i++) {
|
while (dev_buffer < end_dev_buffer) {
|
||||||
uint8_t rawval = (*buffer++ + offset);
|
uint8_t rawval = (*buffer++ + offset);
|
||||||
uint16_t val = (uint16_t)(((uint32_t)rawval * (uint32_t)scale) >> 8);
|
uint16_t val = (uint16_t)(((uint32_t)rawval * (uint32_t)scale) >> 8);
|
||||||
*dev_buffer++ = val;
|
*dev_buffer++ = val;
|
||||||
if (self->spacing == 1)
|
if (self->sample_channel_count == 1)
|
||||||
*dev_buffer++ = val;
|
*dev_buffer++ = val;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
uint16_t offset = self->signed_to_unsigned ? 0x8000 : 0;
|
uint16_t offset = self->signed_to_unsigned ? 0x8000 : 0;
|
||||||
uint16_t scale = self->scale;
|
uint16_t scale = self->scale;
|
||||||
uint16_t *buffer16 = (uint16_t*)buffer;
|
uint16_t *buffer16 = (uint16_t*)buffer;
|
||||||
for (uint32_t i=0; i<buffer_length/2/self->spacing; i++) {
|
while (dev_buffer < end_dev_buffer) {
|
||||||
uint16_t rawval = (*buffer16++ + offset);
|
uint16_t rawval = (*buffer16++ + offset);
|
||||||
uint16_t val = (uint16_t)((rawval * (uint32_t)scale) >> 16);
|
uint16_t val = (uint16_t)((rawval * (uint32_t)scale) >> 16);
|
||||||
*dev_buffer++ = val;
|
*dev_buffer++ = val;
|
||||||
if (self->spacing == 1)
|
if (self->sample_channel_count == 1)
|
||||||
*dev_buffer++ = val;
|
*dev_buffer++ = val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -231,9 +232,12 @@ void common_hal_audiopwmio_pwmaudioout_play(audiopwmio_pwmaudioout_obj_t* self,
|
|||||||
self->bytes_per_sample = audiosample_bits_per_sample(sample) / 8;
|
self->bytes_per_sample = audiosample_bits_per_sample(sample) / 8;
|
||||||
|
|
||||||
uint32_t max_buffer_length;
|
uint32_t max_buffer_length;
|
||||||
|
uint8_t spacing;
|
||||||
audiosample_get_buffer_structure(sample, /* single channel */ false,
|
audiosample_get_buffer_structure(sample, /* single channel */ false,
|
||||||
&self->single_buffer, &self->signed_to_unsigned, &max_buffer_length,
|
&self->single_buffer, &self->signed_to_unsigned, &max_buffer_length,
|
||||||
&self->spacing);
|
&spacing);
|
||||||
|
self->sample_channel_count = audiosample_channel_count(sample);
|
||||||
|
|
||||||
if (max_buffer_length > UINT16_MAX) {
|
if (max_buffer_length > UINT16_MAX) {
|
||||||
mp_raise_ValueError_varg(translate("Buffer length %d too big. It must be less than %d"), max_buffer_length, UINT16_MAX);
|
mp_raise_ValueError_varg(translate("Buffer length %d too big. It must be less than %d"), max_buffer_length, UINT16_MAX);
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ typedef struct {
|
|||||||
|
|
||||||
uint8_t left_channel_number;
|
uint8_t left_channel_number;
|
||||||
uint8_t right_channel_number;
|
uint8_t right_channel_number;
|
||||||
uint8_t spacing;
|
uint8_t sample_channel_count;
|
||||||
uint8_t bytes_per_sample;
|
uint8_t bytes_per_sample;
|
||||||
|
|
||||||
bool playing;
|
bool playing;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user