Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 17 additions & 6 deletions shared-bindings/audiocore/WaveFile.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,16 @@
//| ========================================================
//|
//| A .wav file prepped for audio playback. Only mono and stereo files are supported. Samples must
//| be 8 bit unsigned or 16 bit signed.
//| be 8 bit unsigned or 16 bit signed. If a buffer is provided, it will be used instead of allocating
//| an internal buffer.
//|
//| .. class:: WaveFile(file)
//| .. class:: WaveFile(file[, buffer])
//|
//| Load a .wav file for playback with `audioio.AudioOut` or `audiobusio.I2SOut`.
//|
//| :param typing.BinaryIO file: Already opened wave file
//| :param bytearray buffer: Optional pre-allocated buffer, that will be split in half and used for double-buffering of the data. If not provided, two 512 byte buffers are allocated internally.
//|
//|
//| Playing a wave file from flash::
//|
Expand All @@ -68,15 +71,23 @@
//| print("stopped")
//|
STATIC mp_obj_t audioio_wavefile_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
mp_arg_check_num(n_args, kw_args, 1, 1, false);
mp_arg_check_num(n_args, kw_args, 1, 2, false);

audioio_wavefile_obj_t *self = m_new_obj(audioio_wavefile_obj_t);
self->base.type = &audioio_wavefile_type;
if (MP_OBJ_IS_TYPE(args[0], &mp_type_fileio)) {
common_hal_audioio_wavefile_construct(self, MP_OBJ_TO_PTR(args[0]));
} else {
if (!MP_OBJ_IS_TYPE(args[0], &mp_type_fileio)) {
mp_raise_TypeError(translate("file must be a file opened in byte mode"));
}
uint8_t *buffer = NULL;
size_t buffer_size = 0;
if (n_args >= 2) {
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_WRITE);
buffer = bufinfo.buf;
buffer_size = bufinfo.len;
}
common_hal_audioio_wavefile_construct(self, MP_OBJ_TO_PTR(args[0]),
buffer, buffer_size);

return MP_OBJ_FROM_PTR(self);
}
Expand Down
2 changes: 1 addition & 1 deletion shared-bindings/audiocore/WaveFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
extern const mp_obj_type_t audioio_wavefile_type;

void common_hal_audioio_wavefile_construct(audioio_wavefile_obj_t* self,
pyb_file_obj_t* file);
pyb_file_obj_t* file, uint8_t *buffer, size_t buffer_size);

void common_hal_audioio_wavefile_deinit(audioio_wavefile_obj_t* self);
bool common_hal_audioio_wavefile_deinited(audioio_wavefile_obj_t* self);
Expand Down
33 changes: 22 additions & 11 deletions shared-module/audiocore/WaveFile.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ struct wave_format_chunk {
};

void common_hal_audioio_wavefile_construct(audioio_wavefile_obj_t* self,
pyb_file_obj_t* file) {
pyb_file_obj_t* file,
uint8_t *buffer,
size_t buffer_size) {
// Load the wave
self->file = file;
uint8_t chunk_header[16];
Expand Down Expand Up @@ -84,7 +86,6 @@ void common_hal_audioio_wavefile_construct(audioio_wavefile_obj_t* self,
}
// Get the sample_rate
self->sample_rate = format.sample_rate;
self->len = 256;
self->channel_count = format.num_channels;
self->bits_per_sample = format.bits_per_sample;

Expand All @@ -111,21 +112,31 @@ void common_hal_audioio_wavefile_construct(audioio_wavefile_obj_t* self,

// Try to allocate two buffers, one will be loaded from file and the other
// DMAed to DAC.
self->buffer = m_malloc(self->len, false);
if (self->buffer == NULL) {
common_hal_audioio_wavefile_deinit(self);
mp_raise_msg(&mp_type_MemoryError, translate("Couldn't allocate first buffer"));
}
if (buffer_size) {
self->len = buffer_size / 2;
self->buffer = buffer;
self->second_buffer = buffer + self->len;
} else {
self->len = 256;
self->buffer = m_malloc(self->len, false);
if (self->buffer == NULL) {
common_hal_audioio_wavefile_deinit(self);
mp_raise_msg(&mp_type_MemoryError,
translate("Couldn't allocate first buffer"));
}

self->second_buffer = m_malloc(self->len, false);
if (self->second_buffer == NULL) {
common_hal_audioio_wavefile_deinit(self);
mp_raise_msg(&mp_type_MemoryError, translate("Couldn't allocate second buffer"));
self->second_buffer = m_malloc(self->len, false);
if (self->second_buffer == NULL) {
common_hal_audioio_wavefile_deinit(self);
mp_raise_msg(&mp_type_MemoryError,
translate("Couldn't allocate second buffer"));
}
}
}

void common_hal_audioio_wavefile_deinit(audioio_wavefile_obj_t* self) {
self->buffer = NULL;
self->second_buffer = NULL;
}

bool common_hal_audioio_wavefile_deinited(audioio_wavefile_obj_t* self) {
Expand Down