@@ -222,12 +222,71 @@ const mp_obj_property_t audiomixer_mixer_voice_obj = {
222222 (mp_obj_t )& mp_const_none_obj },
223223};
224224
225+ //| .. method:: play(sample, *, voice=0, loop=False)
226+ //|
227+ //| Plays the sample once when loop=False and continuously when loop=True.
228+ //| Does not block. Use `playing` to block.
229+ //|
230+ //| Sample must be an `audiocore.WaveFile`, `audiocore.RawSample`, or `audiomixer.Mixer`.
231+ //|
232+ //| The sample must match the Mixer's encoding settings given in the constructor.
233+ //|
234+ STATIC mp_obj_t audiomixer_mixer_obj_play (size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
235+ enum { ARG_sample , ARG_voice , ARG_loop };
236+ static const mp_arg_t allowed_args [] = {
237+ { MP_QSTR_sample , MP_ARG_OBJ | MP_ARG_REQUIRED },
238+ { MP_QSTR_voice , MP_ARG_INT | MP_ARG_KW_ONLY , {.u_int = 0 } },
239+ { MP_QSTR_loop , MP_ARG_BOOL | MP_ARG_KW_ONLY , {.u_bool = false} },
240+ };
241+ audiomixer_mixer_obj_t * self = MP_OBJ_TO_PTR (pos_args [0 ]);
242+ check_for_deinit (self );
243+ mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
244+ mp_arg_parse_all (n_args - 1 , pos_args + 1 , kw_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
245+
246+ uint8_t v = args [ARG_voice ].u_int ;
247+ if (v > (self -> voice_count - 1 )) {
248+ mp_raise_ValueError (translate ("Invalid voice" ));
249+ }
250+ audiomixer_mixervoice_obj_t * voice = MP_OBJ_TO_PTR (self -> voice [v ]);
251+ mp_obj_t sample = args [ARG_sample ].u_obj ;
252+ common_hal_audiomixer_mixervoice_play (voice , sample , args [ARG_loop ].u_bool );
253+
254+ return mp_const_none ;
255+ }
256+ MP_DEFINE_CONST_FUN_OBJ_KW (audiomixer_mixer_play_obj , 1 , audiomixer_mixer_obj_play );
257+
258+ //| .. method:: stop_voice(voice=0)
259+ //|
260+ //| Stops playback of the sample on the given voice.
261+ //|
262+ STATIC mp_obj_t audiomixer_mixer_obj_stop_voice (size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
263+ enum { ARG_voice };
264+ static const mp_arg_t allowed_args [] = {
265+ { MP_QSTR_voice , MP_ARG_INT , {.u_int = 0 } },
266+ };
267+ audiomixer_mixer_obj_t * self = MP_OBJ_TO_PTR (pos_args [0 ]);
268+ check_for_deinit (self );
269+ mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
270+ mp_arg_parse_all (n_args - 1 , pos_args + 1 , kw_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
271+
272+ uint8_t v = args [ARG_voice ].u_int ;
273+ if (v > (self -> voice_count - 1 )) {
274+ mp_raise_ValueError (translate ("Invalid voice" ));
275+ }
276+ audiomixer_mixervoice_obj_t * voice = MP_OBJ_TO_PTR (self -> voice [v ]);
277+ common_hal_audiomixer_mixervoice_stop (voice );
278+ return mp_const_none ;
279+ }
280+ MP_DEFINE_CONST_FUN_OBJ_KW (audiomixer_mixer_stop_voice_obj , 1 , audiomixer_mixer_obj_stop_voice );
281+
225282
226283STATIC const mp_rom_map_elem_t audiomixer_mixer_locals_dict_table [] = {
227284 // Methods
228285 { MP_ROM_QSTR (MP_QSTR_deinit ), MP_ROM_PTR (& audiomixer_mixer_deinit_obj ) },
229286 { MP_ROM_QSTR (MP_QSTR___enter__ ), MP_ROM_PTR (& default___enter___obj ) },
230287 { MP_ROM_QSTR (MP_QSTR___exit__ ), MP_ROM_PTR (& audiomixer_mixer___exit___obj ) },
288+ { MP_ROM_QSTR (MP_QSTR_play ), MP_ROM_PTR (& audiomixer_mixer_play_obj ) },
289+ { MP_ROM_QSTR (MP_QSTR_stop_voice ), MP_ROM_PTR (& audiomixer_mixer_stop_voice_obj ) },
231290
232291 // Properties
233292 { MP_ROM_QSTR (MP_QSTR_playing ), MP_ROM_PTR (& audiomixer_mixer_playing_obj ) },
0 commit comments