Skip to content

Commit 4ee02fb

Browse files
Add experimental adc_mic.c
1 parent a4e167d commit 4ee02fb

1 file changed

Lines changed: 83 additions & 0 deletions

File tree

c_mpos/src/adc_mic.c

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
#include "py/obj.h"
2+
#include "py/runtime.h"
3+
#include "py/mphal.h"
4+
#include "esp_heap_caps.h"
5+
#include "esp_codec_dev.h"
6+
#include "adc_mic.h" // Include for audio_codec_adc_cfg_t, audio_codec_new_adc_data, etc.
7+
8+
static mp_obj_t adc_mic_read(void) {
9+
// Configure for mono ADC on GPIO1 (ADC1_CHANNEL_0) at 16kHz
10+
audio_codec_adc_cfg_t cfg = DEFAULT_AUDIO_CODEC_ADC_MONO_CFG(ADC_CHANNEL_0, 16000);
11+
const audio_codec_data_if_t *adc_if = audio_codec_new_adc_data(&cfg);
12+
if (adc_if == NULL) {
13+
mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("Failed to initialize ADC data interface"));
14+
}
15+
16+
// Create codec device for input
17+
esp_codec_dev_cfg_t codec_dev_cfg = {
18+
.dev_type = ESP_CODEC_DEV_TYPE_IN,
19+
.data_if = adc_if,
20+
};
21+
esp_codec_dev_handle_t dev = esp_codec_dev_new(&codec_dev_cfg);
22+
if (dev == NULL) {
23+
audio_codec_delete_adc_data(adc_if);
24+
mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("Failed to create codec device"));
25+
}
26+
27+
// Set sample info: 16kHz, mono, 16-bit
28+
esp_codec_dev_sample_info_t fs = {
29+
.sample_rate = 16000,
30+
.channel = 1,
31+
.bits_per_sample = 16,
32+
};
33+
if (esp_codec_dev_open(dev, &fs) != ESP_OK) {
34+
esp_codec_dev_del(dev);
35+
audio_codec_delete_adc_data(adc_if);
36+
mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("Failed to open codec device"));
37+
}
38+
39+
// Allocate buffer for 16000 samples (16-bit, so 32000 bytes)
40+
const size_t buf_size = 16000 * sizeof(uint16_t);
41+
uint8_t *audio_buffer = (uint8_t *)heap_caps_malloc(buf_size, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
42+
if (audio_buffer == NULL) {
43+
esp_codec_dev_close(dev);
44+
esp_codec_dev_del(dev);
45+
audio_codec_delete_adc_data(adc_if);
46+
mp_raise_OSError(MP_ENOMEM);
47+
}
48+
49+
// Read the data (blocking until buffer is filled)
50+
int ret = esp_codec_dev_read(dev, audio_buffer, buf_size);
51+
if (ret < 0) {
52+
heap_caps_free(audio_buffer);
53+
esp_codec_dev_close(dev);
54+
esp_codec_dev_del(dev);
55+
audio_codec_delete_adc_data(adc_if);
56+
mp_raise_msg_varg(&mp_type_RuntimeError, MP_ERROR_TEXT("Failed to read audio data: %d"), ret);
57+
}
58+
59+
// Create MicroPython bytes object from the buffer
60+
mp_obj_t buf_obj = mp_obj_new_bytes(audio_buffer, ret);
61+
62+
// Cleanup
63+
heap_caps_free(audio_buffer);
64+
esp_codec_dev_close(dev);
65+
esp_codec_dev_del(dev);
66+
audio_codec_delete_adc_data(adc_if);
67+
68+
return buf_obj;
69+
}
70+
MP_DEFINE_CONST_FUN_OBJ_0(adc_mic_read_obj, adc_mic_read);
71+
72+
static const mp_rom_map_elem_t adc_mic_module_globals_table[] = {
73+
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_adc_mic) },
74+
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&adc_mic_read_obj) },
75+
};
76+
static MP_DEFINE_CONST_DICT(adc_mic_module_globals, adc_mic_module_globals_table);
77+
78+
const mp_obj_module_t adc_mic_user_cmodule = {
79+
.base = { &mp_type_module },
80+
.globals = (mp_obj_dict_t *)&adc_mic_module_globals,
81+
};
82+
83+
MP_REGISTER_MODULE(MP_QSTR_adc_mic, adc_mic_user_cmodule);

0 commit comments

Comments
 (0)