@@ -106,7 +106,7 @@ STATIC mp_obj_t audioio_mixer_make_new(const mp_obj_type_t *type, size_t n_args,
106106 if (bits_per_sample != 8 && bits_per_sample != 16 ) {
107107 mp_raise_ValueError (translate ("bits_per_sample must be 8 or 16" ));
108108 }
109- audioio_mixer_obj_t * self = m_new_obj_var (audioio_mixer_obj_t , audioio_mixer_voice_t , voice_count );
109+ audioio_mixer_obj_t * self = m_new_obj_var (audioio_mixer_obj_t , audioio_mixer_voice_obj_t , voice_count );
110110 self -> base .type = & audioio_mixer_type ;
111111 common_hal_audioio_mixer_construct (self , voice_count , args [ARG_buffer_size ].u_int , bits_per_sample , args [ARG_samples_signed ].u_bool , channel_count , sample_rate );
112112
@@ -190,13 +190,190 @@ STATIC mp_obj_t audioio_mixer_obj_stop_voice(size_t n_args, const mp_obj_t *pos_
190190}
191191MP_DEFINE_CONST_FUN_OBJ_KW (audioio_mixer_stop_voice_obj , 1 , audioio_mixer_obj_stop_voice );
192192
193+ //| .. attribute:: playing
194+ //|
195+ //| True when any voice is being output. (read-only)
196+ //|
197+ STATIC mp_obj_t audioio_mixer_obj_get_playing (mp_obj_t self_in ) {
198+ audioio_mixer_obj_t * self = MP_OBJ_TO_PTR (self_in );
199+ raise_error_if_deinited (common_hal_audioio_mixer_deinited (self ));
200+ return mp_obj_new_bool (common_hal_audioio_mixer_get_playing (self ));
201+ }
202+ MP_DEFINE_CONST_FUN_OBJ_1 (audioio_mixer_get_playing_obj , audioio_mixer_obj_get_playing );
203+
204+ const mp_obj_property_t audioio_mixer_playing_obj = {
205+ .base .type = & mp_type_property ,
206+ .proxy = {(mp_obj_t )& audioio_mixer_get_playing_obj ,
207+ (mp_obj_t )& mp_const_none_obj ,
208+ (mp_obj_t )& mp_const_none_obj },
209+ };
210+
211+ //| .. attribute:: sample_rate
212+ //|
213+ //| 32 bit value that dictates how quickly samples are played in Hertz (cycles per second).
214+ //|
215+ STATIC mp_obj_t audioio_mixer_obj_get_sample_rate (mp_obj_t self_in ) {
216+ audioio_mixer_obj_t * self = MP_OBJ_TO_PTR (self_in );
217+ raise_error_if_deinited (common_hal_audioio_mixer_deinited (self ));
218+ return MP_OBJ_NEW_SMALL_INT (common_hal_audioio_mixer_get_sample_rate (self ));
219+ }
220+ MP_DEFINE_CONST_FUN_OBJ_1 (audioio_mixer_get_sample_rate_obj , audioio_mixer_obj_get_sample_rate );
221+
222+ const mp_obj_property_t audioio_mixer_sample_rate_obj = {
223+ .base .type = & mp_type_property ,
224+ .proxy = {(mp_obj_t )& audioio_mixer_get_sample_rate_obj ,
225+ (mp_obj_t )& mp_const_none_obj ,
226+ (mp_obj_t )& mp_const_none_obj },
227+ };
228+
229+ //| .. currentmodule:: audioio
230+ //|
231+ //| :class:`Mixer` -- Mixes one or more audio samples together
232+ //| ===========================================================
233+ //|
234+ //| Mixer mixes multiple samples into one sample.
235+ //|
236+ //| .. class:: Mixer(channel_count=2, buffer_size=1024)
237+ //|
238+ //| Create a Mixer object that can mix multiple channels with the same sample rate.
239+ //|
240+ //| :param int channel_count: The maximum number of samples to mix at once
241+ //| :param int buffer_size: The total size in bytes of the buffers to mix into
242+ //|
243+ STATIC mp_obj_t audioio_mixer_voice_make_new (const mp_obj_type_t * type , size_t n_args , size_t n_kw , const mp_obj_t * pos_args ) {
244+ #if 0
245+ mp_arg_check_num (n_args , n_kw , 0 , 2 , true);
246+ mp_map_t kw_args ;
247+ mp_map_init_fixed_table (& kw_args , n_kw , pos_args + n_args );
248+ enum { ARG_voice_count , ARG_buffer_size , ARG_channel_count , ARG_bits_per_sample , ARG_samples_signed , ARG_sample_rate };
249+ static const mp_arg_t allowed_args [] = {
250+ { MP_QSTR_voice_count , MP_ARG_INT | MP_ARG_KW_ONLY , {.u_int = 2 } },
251+ { MP_QSTR_buffer_size , MP_ARG_INT | MP_ARG_KW_ONLY , {.u_int = 1024 } },
252+ { MP_QSTR_channel_count , MP_ARG_INT | MP_ARG_KW_ONLY , {.u_int = 2 } },
253+ { MP_QSTR_bits_per_sample , MP_ARG_INT | MP_ARG_KW_ONLY , {.u_int = 16 } },
254+ { MP_QSTR_samples_signed , MP_ARG_BOOL | MP_ARG_KW_ONLY , {.u_bool = true} },
255+ { MP_QSTR_sample_rate , MP_ARG_INT | MP_ARG_KW_ONLY , {.u_int = 8000 } },
256+ };
257+ mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
258+ mp_arg_parse_all (n_args , pos_args , & kw_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
259+
260+ mp_int_t voice_count = args [ARG_voice_count ].u_int ;
261+ if (voice_count < 1 || voice_count > 255 ) {
262+ mp_raise_ValueError (translate ("Invalid voice count" ));
263+ }
264+
265+ mp_int_t channel_count = args [ARG_channel_count ].u_int ;
266+ if (channel_count < 1 || channel_count > 2 ) {
267+ mp_raise_ValueError (translate ("Invalid channel count" ));
268+ }
269+ mp_int_t sample_rate = args [ARG_sample_rate ].u_int ;
270+ if (sample_rate < 1 ) {
271+ mp_raise_ValueError (translate ("Sample rate must be positive" ));
272+ }
273+ mp_int_t bits_per_sample = args [ARG_bits_per_sample ].u_int ;
274+ if (bits_per_sample != 8 && bits_per_sample != 16 ) {
275+ mp_raise_ValueError (translate ("bits_per_sample must be 8 or 16" ));
276+ }
277+ audioio_mixer_obj_t * self = m_new_obj_var (audioio_mixer_obj_t , audioio_mixer_voice_obj_t , voice_count );
278+ self -> base .type = & audioio_mixer_type ;
279+ common_hal_audioio_mixer_construct (self , voice_count , args [ARG_buffer_size ].u_int , bits_per_sample , args [ARG_samples_signed ].u_bool , channel_count , sample_rate );
280+
281+ return MP_OBJ_FROM_PTR (self );
282+ #endif
283+ return mp_const_none ;
284+ }
285+
286+ //| .. method:: deinit()
287+ //|
288+ //| Deinitialises the Voice and releases any hardware resources for reuse.
289+ //|
290+ STATIC mp_obj_t audioio_mixer_voice_deinit (mp_obj_t self_in ) {
291+ #if 0
292+ audioio_mixer_voice_obj_t * self = MP_OBJ_TO_PTR (self_in );
293+ common_hal_audioio_mixer_voice_deinit (self );
294+ #endif
295+ return mp_const_none ;
296+ }
297+ STATIC MP_DEFINE_CONST_FUN_OBJ_1 (audioio_mixer_voice_deinit_obj , audioio_mixer_voice_deinit );
298+
299+ //| .. method:: __enter__()
300+ //|
301+ //| No-op used by Context Managers.
302+ //|
303+ // Provided by context manager helper.
304+
305+ //| .. method:: __exit__()
306+ //|
307+ //| Automatically deinitializes the hardware when exiting a context. See
308+ //| :ref:`lifetime-and-contextmanagers` for more info.
309+ //|
310+ STATIC mp_obj_t audioio_mixer_voice_obj___exit__ (size_t n_args , const mp_obj_t * args ) {
311+ #if 0
312+ (void )n_args ;
313+ common_hal_audioio_mixer_voice_deinit (args [0 ]);
314+ #endif
315+ return mp_const_none ;
316+ }
317+ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN (audioio_mixer_voice___exit___obj , 4 , 4 , audioio_mixer_voice_obj___exit__ );
318+
319+
320+ //| .. method:: play(sample, *, loop=False)
321+ //|
322+ //| Plays the sample once when loop=False and continuously when loop=True.
323+ //| Does not block. Use `playing` to block.
324+ //|
325+ //| Sample must be an `audioio.WaveFile`, `audioio.Mixer` or `audioio.RawSample`.
326+ //|
327+ //| The sample must match the Mixer's encoding settings given in the constructor.
328+ //|
329+ STATIC mp_obj_t audioio_mixer_voice_obj_play (size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
330+ #if 0
331+ enum { ARG_sample , ARG_loop };
332+ static const mp_arg_t allowed_args [] = {
333+ { MP_QSTR_sample , MP_ARG_OBJ | MP_ARG_REQUIRED },
334+ { MP_QSTR_loop , MP_ARG_BOOL | MP_ARG_KW_ONLY , {.u_bool = false} },
335+ };
336+ audioio_mixer_voice_obj_t * self = MP_OBJ_TO_PTR (pos_args [0 ]);
337+ raise_error_if_deinited (common_hal_audioio_mixer_voice_deinited (self ));
338+ mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
339+ mp_arg_parse_all (n_args - 1 , pos_args + 1 , kw_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
340+
341+ mp_obj_t sample = args [ARG_sample ].u_obj ;
342+ common_hal_audioio_mixer_play (self , sample , self -> u_int , args [ARG_loop ].u_ool );
343+ #endif
344+ return mp_const_none ;
345+ }
346+ MP_DEFINE_CONST_FUN_OBJ_KW (audioio_mixer_voice_play_obj , 1 , audioio_mixer_voice_obj_play );
347+
348+ //| .. method:: stop_voice()
349+ //|
350+ //| Stops playback of the sample on this voice.
351+ //|
352+ STATIC mp_obj_t audioio_mixer_voice_obj_stop (size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
353+ #if 0
354+ enum { ARG_voice };
355+ static const mp_arg_t allowed_args [] = {
356+ { MP_QSTR_voice , MP_ARG_INT , {.u_int = 0 } },
357+ };
358+ audioio_mixer_voice_obj_t * self = MP_OBJ_TO_PTR (pos_args [0 ]);
359+ raise_error_if_deinited (common_hal_audioio_mixer_deinited (self ));
360+ mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
361+ mp_arg_parse_all (n_args - 1 , pos_args + 1 , kw_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
362+
363+ common_hal_audioio_mixer_stop_voice (self , args [ARG_voice ].u_int );
364+ #endif
365+ return mp_const_none ;
366+ }
367+ MP_DEFINE_CONST_FUN_OBJ_KW (audioio_mixer_voice_stop_obj , 1 , audioio_mixer_voice_obj_stop );
368+
193369//| .. method:: set_gain(voice, gain)
194370//|
195371//| Set the gain of a voice.
196372//|
197373//| gain must be a floating point number between 0 and 1
198374//|
199- STATIC mp_obj_t audioio_mixer_obj_set_gain (size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
375+ STATIC mp_obj_t audioio_mixer_voice_obj_set_gain (size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
376+ #if 0
200377 enum { ARG_voice , ARG_gain };
201378 static const mp_arg_t allowed_args [] = {
202379 { MP_QSTR_voice , MP_ARG_INT | MP_ARG_REQUIRED },
@@ -218,44 +395,35 @@ STATIC mp_obj_t audioio_mixer_obj_set_gain(size_t n_args, const mp_obj_t *pos_ar
218395 }
219396
220397 common_hal_audioio_mixer_set_gain (self ,args [ARG_voice ].u_int , gain );
221-
398+ #endif
222399 return mp_const_none ;
223400}
224- MP_DEFINE_CONST_FUN_OBJ_KW (audioio_mixer_set_gain_obj , 1 , audioio_mixer_obj_set_gain );
401+ MP_DEFINE_CONST_FUN_OBJ_KW (audioio_mixer_voice_set_gain_obj , 1 , audioio_mixer_voice_obj_set_gain );
225402
226- //| .. attribute:: playing
227- //|
228- //| True when any voice is being output. (read-only)
229- //|
230- STATIC mp_obj_t audioio_mixer_obj_get_playing (mp_obj_t self_in ) {
231- audioio_mixer_obj_t * self = MP_OBJ_TO_PTR (self_in );
232- raise_error_if_deinited (common_hal_audioio_mixer_deinited (self ));
233- return mp_obj_new_bool (common_hal_audioio_mixer_get_playing (self ));
234- }
235- MP_DEFINE_CONST_FUN_OBJ_1 (audioio_mixer_get_playing_obj , audioio_mixer_obj_get_playing );
236-
237- const mp_obj_property_t audioio_mixer_playing_obj = {
403+ const mp_obj_property_t audioio_mixer_voice_gain_obj = {
238404 .base .type = & mp_type_property ,
239- .proxy = {(mp_obj_t )& audioio_mixer_get_playing_obj ,
240- (mp_obj_t )& mp_const_none_obj ,
405+ .proxy = {(mp_obj_t )& mp_const_none_obj ,
406+ (mp_obj_t )& audioio_mixer_voice_set_gain_obj ,
241407 (mp_obj_t )& mp_const_none_obj },
242408};
243409
244- //| .. attribute:: sample_rate
410+ //| .. attribute:: playing
245411//|
246- //| 32 bit value that dictates how quickly samples are played in Hertz (cycles per second).
412+ //| True when any voice is being output. (read-only)
247413//|
248- STATIC mp_obj_t audioio_mixer_obj_get_sample_rate (mp_obj_t self_in ) {
414+ STATIC mp_obj_t audioio_mixer_voice_obj_get_playing (mp_obj_t self_in ) {
415+ #if 0
249416 audioio_mixer_obj_t * self = MP_OBJ_TO_PTR (self_in );
250417 raise_error_if_deinited (common_hal_audioio_mixer_deinited (self ));
251- return MP_OBJ_NEW_SMALL_INT (common_hal_audioio_mixer_get_sample_rate (self ));
418+ return mp_obj_new_bool (common_hal_audioio_mixer_get_playing (self ));
419+ #endif
420+ return mp_const_none ;
252421}
253- MP_DEFINE_CONST_FUN_OBJ_1 (audioio_mixer_get_sample_rate_obj , audioio_mixer_obj_get_sample_rate );
254-
422+ MP_DEFINE_CONST_FUN_OBJ_1 (audioio_mixer_voice_get_playing_obj , audioio_mixer_voice_obj_get_playing );
255423
256- const mp_obj_property_t audioio_mixer_sample_rate_obj = {
424+ const mp_obj_property_t audioio_mixer_voice_playing_obj = {
257425 .base .type = & mp_type_property ,
258- .proxy = {(mp_obj_t )& audioio_mixer_get_sample_rate_obj ,
426+ .proxy = {(mp_obj_t )& audioio_mixer_voice_get_playing_obj ,
259427 (mp_obj_t )& mp_const_none_obj ,
260428 (mp_obj_t )& mp_const_none_obj },
261429};
@@ -267,7 +435,6 @@ STATIC const mp_rom_map_elem_t audioio_mixer_locals_dict_table[] = {
267435 { MP_ROM_QSTR (MP_QSTR___exit__ ), MP_ROM_PTR (& audioio_mixer___exit___obj ) },
268436 { MP_ROM_QSTR (MP_QSTR_play ), MP_ROM_PTR (& audioio_mixer_play_obj ) },
269437 { MP_ROM_QSTR (MP_QSTR_stop_voice ), MP_ROM_PTR (& audioio_mixer_stop_voice_obj ) },
270- { MP_ROM_QSTR (MP_QSTR_set_gain ), MP_ROM_PTR (& audioio_mixer_set_gain_obj ) },
271438
272439 // Properties
273440 { MP_ROM_QSTR (MP_QSTR_playing ), MP_ROM_PTR (& audioio_mixer_playing_obj ) },
@@ -281,3 +448,24 @@ const mp_obj_type_t audioio_mixer_type = {
281448 .make_new = audioio_mixer_make_new ,
282449 .locals_dict = (mp_obj_dict_t * )& audioio_mixer_locals_dict ,
283450};
451+
452+ STATIC const mp_rom_map_elem_t audioio_mixer_voice_locals_dict_table [] = {
453+ // Methods
454+ { MP_ROM_QSTR (MP_QSTR_deinit ), MP_ROM_PTR (& audioio_mixer_voice_deinit_obj ) },
455+ { MP_ROM_QSTR (MP_QSTR___enter__ ), MP_ROM_PTR (& default___enter___obj ) },
456+ { MP_ROM_QSTR (MP_QSTR___exit__ ), MP_ROM_PTR (& audioio_mixer_voice___exit___obj ) },
457+ { MP_ROM_QSTR (MP_QSTR_play ), MP_ROM_PTR (& audioio_mixer_voice_play_obj ) },
458+ { MP_ROM_QSTR (MP_QSTR_stop ), MP_ROM_PTR (& audioio_mixer_voice_stop_obj ) },
459+
460+ // Properties
461+ { MP_ROM_QSTR (MP_QSTR_playing ), MP_ROM_PTR (& audioio_mixer_voice_playing_obj ) },
462+ { MP_ROM_QSTR (MP_QSTR_gain ), MP_ROM_PTR (& audioio_mixer_voice_gain_obj ) },
463+ };
464+ STATIC MP_DEFINE_CONST_DICT (audioio_mixer_voice_locals_dict , audioio_mixer_voice_locals_dict_table );
465+
466+ const mp_obj_type_t audioio_mixer_voice_type = {
467+ { & mp_type_type },
468+ .name = MP_QSTR_Mixer_Voice ,
469+ .make_new = audioio_mixer_voice_make_new ,
470+ .locals_dict = (mp_obj_dict_t * )& audioio_mixer_voice_locals_dict ,
471+ };
0 commit comments