@@ -10,6 +10,12 @@ extern "C"
10
10
{
11
11
#include " mpy_m5mic.h"
12
12
#include " mic_config_t.h"
13
+ #include " format_wav.h"
14
+ #include " extmod/vfs_fat.h"
15
+ #include " py/builtin.h"
16
+ #include " py/runtime.h"
17
+ #include " py/stream.h"
18
+ #include " py/mphal.h"
13
19
14
20
namespace m5
15
21
{
@@ -284,5 +290,77 @@ namespace m5
284
290
return mp_obj_new_bool (ret);
285
291
}
286
292
293
+ mp_obj_t mic_recordWavFile (size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
294
+ enum {ARG_path, ARG_rate, ARG_time, ARG_stereo};
295
+ const mp_arg_t allowed_args[] = {
296
+ /* *FORMAT-OFF* */
297
+ { MP_QSTR_path, MP_ARG_OBJ | MP_ARG_REQUIRED, { .u_obj = MP_OBJ_NULL } },
298
+ { MP_QSTR_rate, MP_ARG_INT, { .u_int = 16000 } },
299
+ { MP_QSTR_time, MP_ARG_INT, { .u_int = 5 } },
300
+ { MP_QSTR_stereo, MP_ARG_BOOL, { .u_bool = false } },
301
+ /* *FORMAT-ON* */
302
+ };
303
+ mp_arg_val_t args[MP_ARRAY_SIZE (allowed_args)];
304
+ // The first parameter is the Power object, parse from second parameter.
305
+ mp_arg_parse_all (n_args - 1 , pos_args + 1 , kw_args, MP_ARRAY_SIZE (allowed_args), allowed_args, args);
306
+
307
+ const char *file_path = mp_obj_str_get_str (args[ARG_path].u_obj );
308
+ uint32_t rate = args[ARG_rate].u_int ;
309
+ uint32_t rec_time = args[ARG_time].u_int ;
310
+ bool stereo = args[ARG_stereo].u_bool ;
311
+ uint16_t channels = stereo ? 2 : 1 ;
312
+
313
+ char ftype[5 ] = {0 };
314
+ for (size_t i = 0 ; i < 4 ; i++) {
315
+ ftype[i] = tolower ((char )file_path[i + strlen (file_path) - 4 ]);
316
+ }
317
+ ftype[4 ] = ' \0 ' ;
318
+
319
+ mp_obj_t file_args[2 ];
320
+ file_args[0 ] = args[ARG_path].u_obj ;
321
+ file_args[1 ] = mp_obj_new_str (" wb+" , strlen (" wb+" ));
322
+ mp_obj_t wav_file = mp_vfs_open (2 , file_args, (mp_map_t *)&mp_const_empty_map);
323
+ if (wav_file == mp_const_none) {
324
+ mp_raise_OSError (MP_ENOENT);
325
+ // mp_raise_ValueError(MP_ERROR_TEXT("open file failed"));
326
+ }
327
+
328
+ int flash_wr_size = 0 ;
329
+ uint32_t byte_rate = rate * 2 * channels; // bit sample size = 16bit, byte rate = sample rate * (bit sample size / 8) * channel
330
+ uint32_t flash_rec_time = byte_rate * rec_time;
331
+
332
+ wav_header_t wav_header = WAV_HEADER_PCM_DEFAULT (flash_rec_time, 16 , rate, channels);
333
+
334
+ int rlen = mp_stream_posix_write (wav_file, &wav_header, sizeof (wav_header_t ));
335
+ if (rlen != sizeof (wav_header_t )) {
336
+ mp_stream_close (wav_file);
337
+ mp_raise_msg (&mp_type_OSError, MP_ERROR_TEXT (" File is too short" ));
338
+ }
339
+
340
+ Mic_Class *Mic = getMic (&pos_args[0 ]);
341
+
342
+ constexpr const size_t buf_size = 1024 ;
343
+ int16_t rec_data[512 ];
344
+
345
+ // mp_printf(&mp_plat_print, "flash_rec_time: %d\n", flash_rec_time);
346
+
347
+ while (flash_wr_size < flash_rec_time) {
348
+ bool ret = Mic->record (rec_data, buf_size >> 1 , rate, stereo);
349
+
350
+ while (Mic->isRecording () != 0 ) {
351
+ mp_hal_delay_ms (1 );
352
+ }
353
+ size_t remain = flash_rec_time - flash_wr_size;
354
+ size_t len = remain > buf_size ? buf_size : remain;
355
+ int wlen = mp_stream_posix_write (wav_file, rec_data, len);
356
+ if (wlen != len) {
357
+ mp_stream_close (wav_file);
358
+ mp_raise_msg (&mp_type_OSError, MP_ERROR_TEXT (" File is too short" ));
359
+ }
360
+ flash_wr_size += wlen;
361
+ }
362
+ mp_stream_close (wav_file);
363
+ return mp_obj_new_bool (true );
364
+ }
287
365
}
288
366
}
0 commit comments