@@ -179,6 +179,42 @@ static mp_obj_t audiobusio_i2s_obj___exit__(size_t n_args, const mp_obj_t *args)
179179}
180180static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN (audiobusio_i2s___exit___obj , 4 , 4 , audiobusio_i2s_obj___exit__ ) ;
181181
182+ //| def record(self, destination: WriteableBuffer, destination_length: int) -> None:
183+ //| """Records destination_length bytes of samples to destination. This is
184+ //| blocking.
185+ //|
186+ //| An IOError may be raised when the destination is too slow to record the
187+ //| audio at the given rate. For internal flash, writing all 1s to the file
188+ //| before recording is recommended to speed up writes.
189+ //|
190+ //| :return: The number of samples recorded. If this is less than ``destination_length``,
191+ //| some samples were missed due to processing time."""
192+ //| ...
193+ static mp_obj_t audiobusio_i2s_obj_record (mp_obj_t self_obj , mp_obj_t destination , mp_obj_t destination_length ) {
194+ audiobusio_i2s_obj_t * self = MP_OBJ_TO_PTR (self_obj );
195+ check_for_deinit (self );
196+ uint32_t length = mp_arg_validate_type_int (destination_length , MP_QSTR_length );
197+ mp_arg_validate_length_min (length , 0 , MP_QSTR_length );
198+
199+ mp_buffer_info_t bufinfo ;
200+ if (mp_obj_is_type (destination , & mp_type_fileio )) {
201+ mp_raise_NotImplementedError (MP_ERROR_TEXT ("Cannot record to a file" ));
202+ } else if (mp_get_buffer (destination , & bufinfo , MP_BUFFER_WRITE )) {
203+ if (bufinfo .len / mp_binary_get_size ('@' , bufinfo .typecode , NULL ) < length ) {
204+ mp_raise_ValueError (MP_ERROR_TEXT ("Destination capacity is smaller than destination_length." ));
205+ }
206+ uint8_t bit_depth = common_hal_audiobusio_i2s_get_bits_per_sample (self );
207+ if (bufinfo .typecode != 'h' && bit_depth == 16 ) {
208+ mp_raise_ValueError (MP_ERROR_TEXT ("destination buffer must be an array of type 'h' for bit_depth = 16" ));
209+ } else if (bufinfo .typecode != 'B' && bufinfo .typecode != BYTEARRAY_TYPECODE && bit_depth == 8 ) {
210+ mp_raise_ValueError (MP_ERROR_TEXT ("destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" ));
211+ }
212+ // length is the buffer length in slots, not bytes.
213+ common_hal_audiobusio_i2s_record_to_buffer (self , bufinfo .buf , length );
214+ }
215+ return mp_const_none ;
216+ }
217+ MP_DEFINE_CONST_FUN_OBJ_3 (audiobusio_i2s_record_obj , audiobusio_i2s_obj_record );
182218
183219//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> None:
184220//| """Plays the sample once when loop=False and continuously when loop=True.
@@ -280,6 +316,7 @@ static const mp_rom_map_elem_t audiobusio_i2s_locals_dict_table[] = {
280316 { MP_ROM_QSTR (MP_QSTR_deinit ), MP_ROM_PTR (& audiobusio_i2s_deinit_obj ) },
281317 { MP_ROM_QSTR (MP_QSTR___enter__ ), MP_ROM_PTR (& default___enter___obj ) },
282318 { MP_ROM_QSTR (MP_QSTR___exit__ ), MP_ROM_PTR (& audiobusio_i2s___exit___obj ) },
319+ { MP_ROM_QSTR (MP_QSTR_record ), MP_ROM_PTR (& audiobusio_i2s_record_obj ) },
283320 { MP_ROM_QSTR (MP_QSTR_play ), MP_ROM_PTR (& audiobusio_i2s_play_obj ) },
284321 { MP_ROM_QSTR (MP_QSTR_stop ), MP_ROM_PTR (& audiobusio_i2s_stop_obj ) },
285322 { MP_ROM_QSTR (MP_QSTR_pause ), MP_ROM_PTR (& audiobusio_i2s_pause_obj ) },
0 commit comments