Skip to content

Commit 022f440

Browse files
committed
codal_port/modaudio: Use mp_sched_schedule_node for audio fetcher.
This is more efficient than mp_sched_schedule(), and can never fail. Signed-off-by: Damien George <[email protected]>
1 parent a20fe2a commit 022f440

File tree

2 files changed

+7
-16
lines changed

2 files changed

+7
-16
lines changed

src/codal_port/modaudio.c

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ typedef enum {
4747

4848
static uint8_t audio_output_buffer[AUDIO_CHUNK_SIZE];
4949
static volatile audio_output_state_t audio_output_state;
50-
static volatile bool audio_fetcher_scheduled;
5150
static size_t audio_raw_offset;
5251
static uint32_t audio_current_sound_level;
52+
static mp_sched_node_t audio_data_fetcher_sched_node;
5353

5454
static inline bool audio_is_running(void) {
5555
return audio_source_frame != NULL || audio_source_iter != MP_OBJ_NULL;
@@ -73,9 +73,7 @@ static void audio_buffer_ready(void) {
7373
}
7474
}
7575

76-
static void audio_data_fetcher(void) {
77-
audio_fetcher_scheduled = false;
78-
76+
static void audio_data_fetcher(mp_sched_node_t *node) {
7977
if (audio_source_frame != NULL) {
8078
// An existing AudioFrame is being played, see if there's any data left.
8179
if (audio_raw_offset >= audio_source_frame->used_size) {
@@ -146,12 +144,6 @@ static void audio_data_fetcher(void) {
146144
audio_buffer_ready();
147145
}
148146

149-
static mp_obj_t audio_data_fetcher_wrapper(mp_obj_t arg) {
150-
audio_data_fetcher();
151-
return mp_const_none;
152-
}
153-
static MP_DEFINE_CONST_FUN_OBJ_1(audio_data_fetcher_wrapper_obj, audio_data_fetcher_wrapper);
154-
155147
void microbit_hal_audio_raw_ready_callback(void) {
156148
if (audio_output_state == AUDIO_OUTPUT_STATE_DATA_READY) {
157149
// there is data ready to send out to the audio pipeline, so send it
@@ -161,14 +153,12 @@ void microbit_hal_audio_raw_ready_callback(void) {
161153
// no data ready, need to call this function later when data is ready
162154
audio_output_state = AUDIO_OUTPUT_STATE_IDLE;
163155
}
164-
if (!audio_fetcher_scheduled) {
165-
// schedule audio_data_fetcher to be executed to prepare the next buffer
166-
audio_fetcher_scheduled = mp_sched_schedule(MP_OBJ_FROM_PTR(&audio_data_fetcher_wrapper_obj), mp_const_none);
167-
}
156+
157+
// schedule audio_data_fetcher to be executed to prepare the next buffer
158+
mp_sched_schedule_node(&audio_data_fetcher_sched_node, audio_data_fetcher);
168159
}
169160

170161
static void audio_init(uint32_t sample_rate) {
171-
audio_fetcher_scheduled = false;
172162
audio_output_state = AUDIO_OUTPUT_STATE_IDLE;
173163
microbit_hal_audio_raw_init(sample_rate);
174164
}
@@ -239,7 +229,7 @@ void microbit_audio_play_source(mp_obj_t src, mp_obj_t pin_select, bool wait, ui
239229
// Start the audio running.
240230
// The scheduler must be locked because audio_data_fetcher() can also be called from the scheduler.
241231
mp_sched_lock();
242-
audio_data_fetcher();
232+
audio_data_fetcher(&audio_data_fetcher_sched_node);
243233
mp_sched_unlock();
244234

245235
if (wait) {

src/codal_port/mpconfigport.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
#define MICROPY_MODULE_BUILTIN_INIT (1)
6262
#define MICROPY_USE_INTERNAL_ERRNO (1)
6363
#define MICROPY_ENABLE_SCHEDULER (1)
64+
#define MICROPY_SCHEDULER_STATIC_NODES (1)
6465

6566
// Fine control over Python builtins, classes, modules, etc
6667
#define MICROPY_PY_BUILTINS_STR_UNICODE (1)

0 commit comments

Comments
 (0)