3434
3535#include "py/mpstate.h"
3636
37+ static audio_dma_t * audio_dma_state [AUDIO_DMA_CHANNEL_COUNT ];
38+
39+ // This cannot be in audio_dma_state because it's volatile.
40+ static volatile bool audio_dma_pending [AUDIO_DMA_CHANNEL_COUNT ];
41+
3742uint32_t audiosample_sample_rate (mp_obj_t sample_obj ) {
3843 if (MP_OBJ_IS_TYPE (sample_obj , & audioio_rawsample_type )) {
3944 audioio_rawsample_obj_t * sample = MP_OBJ_TO_PTR (sample_obj );
@@ -70,7 +75,7 @@ uint8_t audiosample_channel_count(mp_obj_t sample_obj) {
7075 return 1 ;
7176}
7277
73- void audiosample_reset_buffer (mp_obj_t sample_obj , bool single_channel , uint8_t audio_channel ) {
78+ static void audiosample_reset_buffer (mp_obj_t sample_obj , bool single_channel , uint8_t audio_channel ) {
7479 if (MP_OBJ_IS_TYPE (sample_obj , & audioio_rawsample_type )) {
7580 audioio_rawsample_obj_t * sample = MP_OBJ_TO_PTR (sample_obj );
7681 audioio_rawsample_reset_buffer (sample , single_channel , audio_channel );
@@ -81,7 +86,10 @@ void audiosample_reset_buffer(mp_obj_t sample_obj, bool single_channel, uint8_t
8186 }
8287}
8388
84- bool audiosample_get_buffer (mp_obj_t sample_obj , bool single_channel , uint8_t channel , uint8_t * * buffer , uint32_t * buffer_length ) {
89+ static audioio_get_buffer_result_t audiosample_get_buffer (mp_obj_t sample_obj ,
90+ bool single_channel ,
91+ uint8_t channel ,
92+ uint8_t * * buffer , uint32_t * buffer_length ) {
8593 if (MP_OBJ_IS_TYPE (sample_obj , & audioio_rawsample_type )) {
8694 audioio_rawsample_obj_t * sample = MP_OBJ_TO_PTR (sample_obj );
8795 return audioio_rawsample_get_buffer (sample , single_channel , channel , buffer , buffer_length );
@@ -90,7 +98,7 @@ bool audiosample_get_buffer(mp_obj_t sample_obj, bool single_channel, uint8_t ch
9098 audioio_wavefile_obj_t * file = MP_OBJ_TO_PTR (sample_obj );
9199 return audioio_wavefile_get_buffer (file , single_channel , channel , buffer , buffer_length );
92100 }
93- return true ;
101+ return GET_BUFFER_DONE ;
94102}
95103
96104static void audiosample_get_buffer_structure (mp_obj_t sample_obj , bool single_channel ,
@@ -117,7 +125,6 @@ uint8_t find_free_audio_dma_channel(void) {
117125 return channel ;
118126}
119127
120- audio_dma_t * audio_dma_state [AUDIO_DMA_CHANNEL_COUNT ];
121128void audio_dma_convert_signed (audio_dma_t * dma , uint8_t * buffer , uint32_t buffer_length ,
122129 uint8_t * * output_buffer , uint32_t * output_buffer_length ,
123130 uint8_t * output_spacing ) {
@@ -163,15 +170,21 @@ void audio_dma_convert_signed(audio_dma_t* dma, uint8_t* buffer, uint32_t buffer
163170void audio_dma_load_next_block (audio_dma_t * dma ) {
164171 uint8_t * buffer ;
165172 uint32_t buffer_length ;
166- bool last_buffer = audiosample_get_buffer (dma -> sample , dma -> single_channel , dma -> audio_channel ,
167- & buffer , & buffer_length );
173+ audioio_get_buffer_result_t get_buffer_result =
174+ audiosample_get_buffer (dma -> sample , dma -> single_channel , dma -> audio_channel ,
175+ & buffer , & buffer_length );
168176
169177 DmacDescriptor * descriptor = dma -> second_descriptor ;
170178 if (dma -> first_descriptor_free ) {
171179 descriptor = dma_descriptor (dma -> dma_channel );
172180 }
173181 dma -> first_descriptor_free = !dma -> first_descriptor_free ;
174182
183+ if (get_buffer_result == GET_BUFFER_ERROR ) {
184+ audio_dma_stop (dma );
185+ return ;
186+ }
187+
175188 uint8_t * output_buffer ;
176189 uint32_t output_buffer_length ;
177190 uint8_t output_spacing ;
@@ -180,7 +193,7 @@ void audio_dma_load_next_block(audio_dma_t* dma) {
180193
181194 descriptor -> BTCNT .reg = output_buffer_length / dma -> beat_size / output_spacing ;
182195 descriptor -> SRCADDR .reg = ((uint32_t ) output_buffer ) + output_buffer_length ;
183- if (last_buffer ) {
196+ if (get_buffer_result == GET_BUFFER_DONE ) {
184197 if (dma -> loop ) {
185198 audiosample_reset_buffer (dma -> sample , dma -> single_channel , dma -> audio_channel );
186199 } else {
@@ -347,6 +360,7 @@ void audio_dma_init(audio_dma_t* dma) {
347360void audio_dma_reset (void ) {
348361 for (uint8_t i = 0 ; i < AUDIO_DMA_CHANNEL_COUNT ; i ++ ) {
349362 audio_dma_state [i ] = NULL ;
363+ audio_dma_pending [i ] = false;
350364 dma_disable_channel (i );
351365 dma_descriptor (i )-> BTCTRL .bit .VALID = false;
352366 MP_STATE_PORT (playing_audio )[i ] = NULL ;
@@ -367,8 +381,12 @@ bool audio_dma_get_playing(audio_dma_t* dma) {
367381
368382// WARN(tannewt): DO NOT print from here. Printing calls background tasks such as this and causes a
369383// stack overflow.
384+
370385void audio_dma_background (void ) {
371386 for (uint8_t i = 0 ; i < AUDIO_DMA_CHANNEL_COUNT ; i ++ ) {
387+ if (audio_dma_pending [i ]) {
388+ continue ;
389+ }
372390 audio_dma_t * dma = audio_dma_state [i ];
373391 if (dma == NULL ) {
374392 continue ;
@@ -379,6 +397,10 @@ void audio_dma_background(void) {
379397 continue ;
380398 }
381399
400+ // audio_dma_load_next_block() can call Python code, which can call audio_dma_background()
401+ // recursively at the next background processing time. So disallow recursive calls to here.
402+ audio_dma_pending [i ] = true;
382403 audio_dma_load_next_block (dma );
404+ audio_dma_pending [i ] = false;
383405 }
384406}
0 commit comments