atmel-samd: Fix AudioOut buffer playback by supporting bytes_per_sample.
Thanks to @ntoll for finding this bug!
This commit is contained in:
parent
5e231bd8f9
commit
f878bc4efc
@ -104,6 +104,7 @@ void audioout_reset(void) {
|
|||||||
void audioout_background(void) {
|
void audioout_background(void) {
|
||||||
if (MP_STATE_VM(audioout_block_counter) != NULL &&
|
if (MP_STATE_VM(audioout_block_counter) != NULL &&
|
||||||
active_audioout != NULL &&
|
active_audioout != NULL &&
|
||||||
|
active_audioout->second_buffer != NULL &&
|
||||||
active_audioout->last_loaded_block < tc_get_count_value(MP_STATE_VM(audioout_block_counter))) {
|
active_audioout->last_loaded_block < tc_get_count_value(MP_STATE_VM(audioout_block_counter))) {
|
||||||
uint8_t* buffer;
|
uint8_t* buffer;
|
||||||
if (tc_get_count_value(MP_STATE_VM(audioout_block_counter)) % 2 == 1) {
|
if (tc_get_count_value(MP_STATE_VM(audioout_block_counter)) % 2 == 1) {
|
||||||
@ -133,6 +134,7 @@ void audioout_background(void) {
|
|||||||
descriptor = active_audioout->second_descriptor;
|
descriptor = active_audioout->second_descriptor;
|
||||||
}
|
}
|
||||||
descriptor->BTCNT.reg = length_read / active_audioout->bytes_per_sample;
|
descriptor->BTCNT.reg = length_read / active_audioout->bytes_per_sample;
|
||||||
|
descriptor->SRCADDR.reg = ((uint32_t) buffer) + length_read;
|
||||||
descriptor->DESCADDR.reg = 0;
|
descriptor->DESCADDR.reg = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -349,7 +351,8 @@ static void shared_construct(audioio_audioout_obj_t* self, const mcu_pin_obj_t*
|
|||||||
void common_hal_audioio_audioout_construct_from_buffer(audioio_audioout_obj_t* self,
|
void common_hal_audioio_audioout_construct_from_buffer(audioio_audioout_obj_t* self,
|
||||||
const mcu_pin_obj_t* pin,
|
const mcu_pin_obj_t* pin,
|
||||||
uint16_t* buffer,
|
uint16_t* buffer,
|
||||||
uint32_t len) {
|
uint32_t len,
|
||||||
|
uint8_t bytes_per_sample) {
|
||||||
self->pin = pin;
|
self->pin = pin;
|
||||||
if (pin != &pin_PA02) {
|
if (pin != &pin_PA02) {
|
||||||
mp_raise_ValueError("Invalid pin");
|
mp_raise_ValueError("Invalid pin");
|
||||||
@ -361,8 +364,8 @@ void common_hal_audioio_audioout_construct_from_buffer(audioio_audioout_obj_t* s
|
|||||||
|
|
||||||
self->buffer = (uint8_t*) buffer;
|
self->buffer = (uint8_t*) buffer;
|
||||||
self->second_buffer = NULL;
|
self->second_buffer = NULL;
|
||||||
// Input len is a count. Internal len is in bytes.
|
self->bytes_per_sample = bytes_per_sample;
|
||||||
self->len = 2 * len;
|
self->len = len;
|
||||||
self->frequency = 8000;
|
self->frequency = 8000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "lib/utils/context_manager_helpers.h"
|
#include "lib/utils/context_manager_helpers.h"
|
||||||
|
#include "py/binary.h"
|
||||||
#include "py/objproperty.h"
|
#include "py/objproperty.h"
|
||||||
#include "py/runtime.h"
|
#include "py/runtime.h"
|
||||||
#include "shared-bindings/microcontroller/Pin.h"
|
#include "shared-bindings/microcontroller/Pin.h"
|
||||||
@ -62,11 +63,11 @@
|
|||||||
//|
|
//|
|
||||||
//| # Generate one period of sine wav.
|
//| # Generate one period of sine wav.
|
||||||
//| length = 8000 // 440
|
//| length = 8000 // 440
|
||||||
//| b = array.array("H", [0] * length)
|
//| sine_wave = array.array("H", [0] * length)
|
||||||
//| for i in range(length):
|
//| for i in range(length):
|
||||||
//| b[i] = int(math.sin(math.pi * 2 * i / 18) * (2 ** 15) + 2 ** 15)
|
//| sine_wave[i] = int(math.sin(math.pi * 2 * i / 18) * (2 ** 15) + 2 ** 15)
|
||||||
//|
|
//|
|
||||||
//| sample = audioio.AudioOut(board.SPEAKER, sin_wave)
|
//| sample = audioio.AudioOut(board.SPEAKER, sine_wave)
|
||||||
//| sample.play(loop=True)
|
//| sample.play(loop=True)
|
||||||
//| time.sleep(1)
|
//| time.sleep(1)
|
||||||
//| sample.stop()
|
//| sample.stop()
|
||||||
@ -106,12 +107,15 @@ STATIC mp_obj_t audioio_audioout_make_new(const mp_obj_type_t *type, size_t n_ar
|
|||||||
if (MP_OBJ_IS_TYPE(args[1], &fatfs_type_fileio)) {
|
if (MP_OBJ_IS_TYPE(args[1], &fatfs_type_fileio)) {
|
||||||
common_hal_audioio_audioout_construct_from_file(self, pin, MP_OBJ_TO_PTR(args[1]));
|
common_hal_audioio_audioout_construct_from_file(self, pin, MP_OBJ_TO_PTR(args[1]));
|
||||||
} else if (mp_get_buffer(args[1], &bufinfo, MP_BUFFER_READ)) {
|
} else if (mp_get_buffer(args[1], &bufinfo, MP_BUFFER_READ)) {
|
||||||
if (bufinfo.len % 2 == 1) {
|
uint8_t bytes_per_sample = 1;
|
||||||
mp_raise_ValueError("sample_source must be an even number of bytes (two per sample)");
|
if (bufinfo.typecode == 'H') {
|
||||||
|
bytes_per_sample = 2;
|
||||||
|
} else if (bufinfo.typecode != 'B' && bufinfo.typecode != BYTEARRAY_TYPECODE) {
|
||||||
|
mp_raise_ValueError("sample_source buffer must be a bytearray or array of type 'H' or 'B'");
|
||||||
}
|
}
|
||||||
common_hal_audioio_audioout_construct_from_buffer(self, pin, ((uint16_t*)bufinfo.buf), bufinfo.len / 2);
|
common_hal_audioio_audioout_construct_from_buffer(self, pin, ((uint16_t*)bufinfo.buf), bufinfo.len, bytes_per_sample);
|
||||||
} else {
|
} else {
|
||||||
mp_raise_TypeError("sample_source must be a file or bytes-like object.");
|
mp_raise_TypeError("sample_source must be a file or bytes-like object");
|
||||||
}
|
}
|
||||||
|
|
||||||
return MP_OBJ_FROM_PTR(self);
|
return MP_OBJ_FROM_PTR(self);
|
||||||
|
@ -33,8 +33,10 @@
|
|||||||
|
|
||||||
extern const mp_obj_type_t audioio_audioout_type;
|
extern const mp_obj_type_t audioio_audioout_type;
|
||||||
|
|
||||||
void common_hal_audioio_audioout_construct_from_buffer(audioio_audioout_obj_t* self, const mcu_pin_obj_t* pin, uint16_t* buffer, uint32_t len);
|
void common_hal_audioio_audioout_construct_from_buffer(audioio_audioout_obj_t* self,
|
||||||
void common_hal_audioio_audioout_construct_from_file(audioio_audioout_obj_t* self, const mcu_pin_obj_t* pin, pyb_file_obj_t* file);
|
const mcu_pin_obj_t* pin, uint16_t* buffer, uint32_t len, uint8_t bytes_per_sample);
|
||||||
|
void common_hal_audioio_audioout_construct_from_file(audioio_audioout_obj_t* self,
|
||||||
|
const mcu_pin_obj_t* pin, pyb_file_obj_t* file);
|
||||||
|
|
||||||
void common_hal_audioio_audioout_deinit(audioio_audioout_obj_t* self);
|
void common_hal_audioio_audioout_deinit(audioio_audioout_obj_t* self);
|
||||||
void common_hal_audioio_audioout_play(audioio_audioout_obj_t* self, bool loop);
|
void common_hal_audioio_audioout_play(audioio_audioout_obj_t* self, bool loop);
|
||||||
|
Loading…
Reference in New Issue
Block a user