3232
3333#define audio_source_iter MP_STATE_PORT(audio_source)
3434
35+ #define LOG_AUDIO_CHUNK_SIZE (5)
36+ #define AUDIO_CHUNK_SIZE (1 << LOG_AUDIO_CHUNK_SIZE)
3537#define DEFAULT_SAMPLE_RATE (7812)
3638#define BUFFER_EXPANSION (4) // smooth out the samples via linear interpolation
3739#define OUT_CHUNK_SIZE (BUFFER_EXPANSION * AUDIO_CHUNK_SIZE)
@@ -46,7 +48,7 @@ static uint8_t audio_output_buffer[OUT_CHUNK_SIZE];
4648static volatile audio_output_state_t audio_output_state ;
4749static volatile bool audio_fetcher_scheduled ;
4850
49- microbit_audio_frame_obj_t * microbit_audio_frame_make_new (void );
51+ microbit_audio_frame_obj_t * microbit_audio_frame_make_new (size_t size );
5052
5153static inline bool audio_is_running (void ) {
5254 return audio_source_iter != NULL ;
@@ -264,14 +266,21 @@ MP_REGISTER_MODULE(MP_QSTR_audio, audio_module);
264266STATIC mp_obj_t microbit_audio_frame_new (const mp_obj_type_t * type_in , mp_uint_t n_args , mp_uint_t n_kw , const mp_obj_t * args ) {
265267 (void )type_in ;
266268 (void )args ;
267- mp_arg_check_num (n_args , n_kw , 0 , 0 , false);
268- return microbit_audio_frame_make_new ();
269+ mp_arg_check_num (n_args , n_kw , 0 , 1 , false);
270+ size_t size = AUDIO_CHUNK_SIZE ;
271+ if (n_args == 1 ) {
272+ size = mp_obj_get_int (args [0 ]);
273+ if (size <= 0 ) {
274+ mp_raise_ValueError (MP_ERROR_TEXT ("size out of bounds" ));
275+ }
276+ }
277+ return microbit_audio_frame_make_new (size );
269278}
270279
271280STATIC mp_obj_t audio_frame_subscr (mp_obj_t self_in , mp_obj_t index_in , mp_obj_t value_in ) {
272281 microbit_audio_frame_obj_t * self = (microbit_audio_frame_obj_t * )self_in ;
273282 mp_int_t index = mp_obj_get_int (index_in );
274- if (index < 0 || index >= AUDIO_CHUNK_SIZE ) {
283+ if (index < 0 || index >= self -> size ) {
275284 mp_raise_ValueError (MP_ERROR_TEXT ("index out of bounds" ));
276285 }
277286 if (value_in == MP_OBJ_NULL ) {
@@ -291,10 +300,10 @@ STATIC mp_obj_t audio_frame_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t
291300}
292301
293302static mp_obj_t audio_frame_unary_op (mp_unary_op_t op , mp_obj_t self_in ) {
294- ( void )self_in ;
303+ microbit_audio_frame_obj_t * self = ( microbit_audio_frame_obj_t * )self_in ;
295304 switch (op ) {
296305 case MP_UNARY_OP_LEN :
297- return MP_OBJ_NEW_SMALL_INT (32 );
306+ return MP_OBJ_NEW_SMALL_INT (self -> size );
298307 default :
299308 return MP_OBJ_NULL ; // op not supported
300309 }
@@ -304,14 +313,15 @@ static mp_int_t audio_frame_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufin
304313 (void )flags ;
305314 microbit_audio_frame_obj_t * self = (microbit_audio_frame_obj_t * )self_in ;
306315 bufinfo -> buf = self -> data ;
307- bufinfo -> len = AUDIO_CHUNK_SIZE ;
316+ bufinfo -> len = self -> size ;
308317 bufinfo -> typecode = 'b' ;
309318 return 0 ;
310319}
311320
312321static void add_into (microbit_audio_frame_obj_t * self , microbit_audio_frame_obj_t * other , bool add ) {
313322 int mult = add ? 1 : -1 ;
314- for (int i = 0 ; i < AUDIO_CHUNK_SIZE ; i ++ ) {
323+ size_t size = MIN (self -> size , other -> size );
324+ for (int i = 0 ; i < size ; i ++ ) {
315325 unsigned val = (int )self -> data [i ] + mult * (other -> data [i ]- 128 );
316326 // Clamp to 0-255
317327 if (val > 255 ) {
@@ -322,8 +332,8 @@ static void add_into(microbit_audio_frame_obj_t *self, microbit_audio_frame_obj_
322332}
323333
324334static microbit_audio_frame_obj_t * copy (microbit_audio_frame_obj_t * self ) {
325- microbit_audio_frame_obj_t * result = microbit_audio_frame_make_new ();
326- for (int i = 0 ; i < AUDIO_CHUNK_SIZE ; i ++ ) {
335+ microbit_audio_frame_obj_t * result = microbit_audio_frame_make_new (self -> size );
336+ for (int i = 0 ; i < self -> size ; i ++ ) {
327337 result -> data [i ] = self -> data [i ];
328338 }
329339 return result ;
@@ -333,7 +343,7 @@ mp_obj_t copyfrom(mp_obj_t self_in, mp_obj_t other) {
333343 microbit_audio_frame_obj_t * self = (microbit_audio_frame_obj_t * )self_in ;
334344 mp_buffer_info_t bufinfo ;
335345 mp_get_buffer_raise (other , & bufinfo , MP_BUFFER_READ );
336- uint32_t len = bufinfo .len > AUDIO_CHUNK_SIZE ? AUDIO_CHUNK_SIZE : bufinfo . len ;
346+ uint32_t len = MIN ( bufinfo .len , self -> size ) ;
337347 for (uint32_t i = 0 ; i < len ; i ++ ) {
338348 self -> data [i ] = ((uint8_t * )bufinfo .buf )[i ];
339349 }
@@ -370,7 +380,7 @@ int32_t float_to_fixed(float f, uint32_t scale) {
370380
371381static void mult (microbit_audio_frame_obj_t * self , float f ) {
372382 int scaled = float_to_fixed (f , 15 );
373- for (int i = 0 ; i < AUDIO_CHUNK_SIZE ; i ++ ) {
383+ for (int i = 0 ; i < self -> size ; i ++ ) {
374384 unsigned val = ((((int )self -> data [i ]- 128 ) * scaled ) >> 15 )+ 128 ;
375385 if (val > 255 ) {
376386 val = (1 - (val >>31 ))* 255 ;
@@ -422,10 +432,11 @@ MP_DEFINE_CONST_OBJ_TYPE(
422432 locals_dict , & microbit_audio_frame_locals_dict
423433 );
424434
425- microbit_audio_frame_obj_t * microbit_audio_frame_make_new (void ) {
426- microbit_audio_frame_obj_t * res = m_new_obj (microbit_audio_frame_obj_t );
435+ microbit_audio_frame_obj_t * microbit_audio_frame_make_new (size_t size ) {
436+ microbit_audio_frame_obj_t * res = m_new_obj_var (microbit_audio_frame_obj_t , uint8_t , size );
427437 res -> base .type = & microbit_audio_frame_type ;
428- memset (res -> data , 128 , AUDIO_CHUNK_SIZE );
438+ res -> size = size ;
439+ memset (res -> data , 128 , size );
429440 return res ;
430441}
431442
0 commit comments