Skip to content

Commit d24ee08

Browse files
committed
gmf_ai_audio: Added function to set keep awake mode
The `esp_gmf_afe_keep_awake` function can be used to enable or disable the `keep awake` mode, when enabled, the wakeup state machine will remain in the `wakeup` state even if noise is detected, and it will not trigger the `ESP_GMF_AFE_EVT_WAKEUP_END` event
1 parent 799ec53 commit d24ee08

File tree

10 files changed

+162
-56
lines changed

10 files changed

+162
-56
lines changed

elements/gmf_ai_audio/CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
- Added `esp_gmf_afe_set_event_cb` API to register AFE element event callbacks
88
- Replaced the interface for decoder reconfiguration
99
- Introduced `esp_gmf_wn` element to support wake word detection
10-
- Corrected return value validation for *acq_write and *acq_release callback function implementations
10+
- Corrected return value validation for *acq_write* and *acq_release* callback function implementations
11+
- Added `esp_gmf_afe_keep_awake` API to enable/disable the keep awake feature
1112

1213
### Bug Fixes
1314

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
11
idf_component_register(SRCS "main.c"
2-
INCLUDE_DIRS "."
3-
REQUIRES gmf_setup cli)
2+
INCLUDE_DIRS ".")

elements/gmf_ai_audio/examples/aec_rec/main/idf_component.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@ dependencies:
1515
espressif/gmf_loader:
1616
version: "^0.6"
1717
espressif/gmf_app_utils:
18-
version: "^0.6"
18+
version: "^0.7"

elements/gmf_ai_audio/examples/aec_rec/main/main.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
#include "esp_err.h"
1111
#include "esp_log.h"
1212

13-
#include "esp_codec_dev.h"
1413
#include "esp_gmf_err.h"
1514
#include "esp_gmf_io_codec_dev.h"
1615
#include "esp_gmf_obj.h"
@@ -95,8 +94,6 @@ static esp_gmf_err_io_t pcm_buf_release_write(void *handle, esp_gmf_payload_t *l
9594

9695
void app_main(void)
9796
{
98-
esp_err_t ret = ESP_OK;
99-
10097
esp_log_level_set("*", ESP_LOG_INFO);
10198

10299
pcm_buffer = heap_caps_malloc(buf_size, MALLOC_CAP_SPIRAM);
@@ -174,7 +171,7 @@ void app_main(void)
174171
esp_gmf_io_codec_dev_set_dev(ESP_GMF_PIPELINE_GET_OUT_INSTANCE(play_pipe), esp_gmf_app_get_playback_handle());
175172

176173
esp_gmf_obj_handle_t bit_cvt = NULL;
177-
esp_gmf_pipeline_get_el_by_name(play_pipe, "aud_bit_cvt", &aud_bit_cvt);
174+
esp_gmf_pipeline_get_el_by_name(play_pipe, "aud_bit_cvt", &bit_cvt);
178175
esp_gmf_bit_cvt_set_dest_bits(bit_cvt, DAC_I2S_BITS);
179176
esp_gmf_obj_handle_t ch_cvt = NULL;
180177
esp_gmf_pipeline_get_el_by_name(play_pipe, "aud_ch_cvt", &ch_cvt);

elements/gmf_ai_audio/examples/wwe/CMakeLists.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
# CMakeLists in this exact order for cmake to work correctly
33
cmake_minimum_required(VERSION 3.5)
44

5-
set(EXTRA_COMPONENT_DIRS ${EXTRA_COMPONENT_DIRS} "../common")
6-
75
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
86

97
project(gmf_wwe_demo)

elements/gmf_ai_audio/examples/wwe/main/idf_component.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@ dependencies:
55
version: "^0.6"
66
espressif/gmf_io:
77
version: "^0.6"
8+
espressif/gmf_app_utils:
9+
version: "^0.7"

elements/gmf_ai_audio/examples/wwe/main/main.c

Lines changed: 67 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,15 @@
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

7+
#include <stdbool.h>
78
#include <stdio.h>
89
#include <string.h>
910

1011
#include "esp_err.h"
1112
#include "esp_log.h"
1213
#include "soc/soc_caps.h"
14+
#include "esp_console.h"
15+
#include "argtable3/argtable3.h"
1316

1417
#include "esp_gmf_io.h"
1518
#include "esp_gmf_pipeline.h"
@@ -23,7 +26,16 @@
2326
#if SOC_SDMMC_HOST_SUPPORTED == 1
2427
#define VOICE2FILE (true)
2528
#endif /* SOC_SDMMC_HOST_SUPPORTED == 1 */
29+
#ifdef CONFIG_GMF_AI_AUDIO_WAKEUP_ENABLE
2630
#define WAKENET_ENABLE (true)
31+
#else
32+
#define WAKENET_ENABLE (false)
33+
#endif /* CONFIG_GMF_AI_AUDIO_WAKEUP_ENABLE */
34+
#ifdef CONFIG_GMF_AI_AUDIO_VOICE_COMMAND_ENABLE
35+
#define VCMD_ENABLE (true)
36+
#else
37+
#define VCMD_ENABLE (false)
38+
#endif /* CONFIG_GMF_AI_AUDIO_VOICE_COMMAND_ENABLE */
2739
#define VAD_ENABLE (true)
2840
#define QUIT_CMD_FOUND (BIT0)
2941

@@ -47,41 +59,25 @@
4759
#endif /* defined CONFIG_IDF_TARGET_ESP32S3 */
4860

4961
#if AUDIO_BOARD == BOARD_KORVO_2
50-
#define AEC_ENABLE (true)
51-
#define VCMD_ENABLE (true)
52-
53-
#define ADC_I2S_PORT (0)
5462
#define ADC_I2S_CH (2)
5563
#define ADC_I2S_BITS (32)
5664
#define INPUT_CH_NUM (4)
5765
#define INPUT_CH_BITS (16) /* For board `ESP32-S3-Korvo-2`, the es7210 is configured as 32-bit,
5866
2-channel mode to accommodate 16-bit, 4-channel data */
5967
#define INPUT_CH_ALLOCATION ("RMNM")
6068
#elif AUDIO_BOARD == BOARD_LYRAT_MINI
61-
#define AEC_ENABLE (false)
62-
#define VCMD_ENABLE (false)
63-
64-
#define ADC_I2S_PORT (1)
6569
#define ADC_I2S_CH (2)
6670
#define ADC_I2S_BITS (16)
6771
#define INPUT_CH_NUM (ADC_I2S_CH)
6872
#define INPUT_CH_BITS (ADC_I2S_BITS)
6973
#define INPUT_CH_ALLOCATION ("RM")
7074
#elif AUDIO_BOARD == BOARD_XD_AIOT_C3
71-
#define AEC_ENABLE (false)
72-
#define VCMD_ENABLE (false)
73-
74-
#define ADC_I2S_PORT (0)
7575
#define ADC_I2S_CH (2)
7676
#define ADC_I2S_BITS (16)
7777
#define INPUT_CH_NUM (ADC_I2S_CH)
7878
#define INPUT_CH_BITS (ADC_I2S_BITS)
7979
#define INPUT_CH_ALLOCATION ("MR")
8080
#elif AUDIO_BOARD == BOARD_ESP_SPOT
81-
#define AEC_ENABLE (false)
82-
#define VCMD_ENABLE (false)
83-
84-
#define ADC_I2S_PORT (0)
8581
#define ADC_I2S_CH (2)
8682
#define ADC_I2S_BITS (16)
8783
#define INPUT_CH_NUM (ADC_I2S_CH)
@@ -102,6 +98,7 @@ static bool speeching = false;
10298
static bool wakeup = false;
10399
#endif /* WITH_AFE == true */
104100
static EventGroupHandle_t g_event_group = NULL;
101+
static esp_gmf_element_handle_t g_afe = NULL;
105102

106103
static esp_err_t _pipeline_event(esp_gmf_event_pkt_t *event, void *ctx)
107104
{
@@ -158,14 +155,6 @@ void esp_gmf_afe_event_cb(esp_gmf_obj_handle_t obj, esp_gmf_afe_evt_t *event, vo
158155
esp_gmf_afe_vcmd_info_t *info = event->event_data;
159156
ESP_LOGW(TAG, "Command %d, phrase_id %d, prob %f, str: %s",
160157
event->type, info->phrase_id, info->prob, info->str);
161-
/* Here use the first command to quit this demo
162-
* For Chinese model, the first default command is `ba xiao shi hou guan ji`
163-
* For English model, the first default command is `tell me a joke`
164-
* If user had modified the commands, please refer to the commands setting.
165-
*/
166-
if (event->type == 1) {
167-
xEventGroupSetBits(g_event_group, QUIT_CMD_FOUND);
168-
}
169158
break;
170159
}
171160
}
@@ -225,9 +214,58 @@ static esp_gmf_err_io_t outport_release_write(void *handle, esp_gmf_payload_t *l
225214
return ESP_GMF_IO_OK;
226215
}
227216

217+
static struct {
218+
struct arg_int *keep;
219+
struct arg_end *end;
220+
} keep_args;
221+
222+
static int keep_awake(int argc, char **argv)
223+
{
224+
int nerrors = arg_parse(argc, argv, (void **)&keep_args);
225+
if (nerrors != 0) {
226+
arg_print_errors(stderr, keep_args.end, argv[0]);
227+
return ESP_FAIL;
228+
}
229+
if (g_afe) {
230+
esp_gmf_afe_keep_awake(g_afe, keep_args.keep->ival[0]);
231+
printf("Keep awake: %d\n", keep_args.keep->ival[0]);
232+
} else {
233+
ESP_LOGE(TAG, "AFE not found");
234+
}
235+
return ESP_OK;
236+
}
237+
238+
static int quit(int argc, char **argv)
239+
{
240+
xEventGroupSetBits(g_event_group, QUIT_CMD_FOUND);
241+
return 0;
242+
}
243+
244+
static void wwe_cmds_register(void)
245+
{
246+
esp_console_cmd_t cmd_keep = {
247+
.command = "keep",
248+
.help = "keep awake",
249+
.hint = NULL,
250+
.func = &keep_awake,
251+
.argtable = &keep_args,
252+
};
253+
keep_args.keep = arg_int0(NULL, NULL, "<0 - 1>", "Keep awake");
254+
keep_args.end = arg_end(1);
255+
esp_console_cmd_register(&cmd_keep);
256+
257+
esp_console_cmd_t cmd_quit = {
258+
.command = "quit",
259+
.help = "quit",
260+
.hint = NULL,
261+
.func = &quit,
262+
.argtable = NULL,
263+
};
264+
esp_console_cmd_register(&cmd_quit);
265+
}
266+
228267
void app_main(void)
229268
{
230-
int ret = 0;
231269
esp_log_level_set("*", ESP_LOG_INFO);
232270
esp_gmf_app_codec_info_t codec_info = ESP_GMF_APP_CODEC_INFO_DEFAULT();
233271
codec_info.record_info.sample_rate = 16000;
@@ -255,9 +293,9 @@ void app_main(void)
255293
goto __quit;
256294
}
257295
esp_gmf_io_codec_dev_set_dev(ESP_GMF_PIPELINE_GET_IN_INSTANCE(pipe), esp_gmf_app_get_record_handle());
258-
esp_gmf_element_handle_t afe = NULL;
259-
esp_gmf_pipeline_get_el_by_name(pipe, "ai_afe", &afe);
260-
esp_gmf_afe_set_event_cb(afe, esp_gmf_afe_event_cb, NULL);
296+
#if WITH_AFE == true
297+
esp_gmf_pipeline_get_el_by_name(pipe, "ai_afe", &g_afe);
298+
esp_gmf_afe_set_event_cb(g_afe, esp_gmf_afe_event_cb, NULL);
261299
#else
262300
esp_gmf_element_handle_t wn = NULL;
263301
esp_gmf_pipeline_get_el_by_name(pipe, "ai_wn", &wn);
@@ -291,7 +329,7 @@ void app_main(void)
291329
esp_gmf_pipeline_set_event(pipe, _pipeline_event, NULL);
292330
esp_gmf_pipeline_run(pipe);
293331

294-
esp_gmf_app_cli_init("Audio >", NULL);
332+
esp_gmf_app_cli_init("Audio >", wwe_cmds_register);
295333

296334
while (1) {
297335
EventBits_t bits = xEventGroupWaitBits(g_event_group, QUIT_CMD_FOUND, pdTRUE, pdFALSE, portMAX_DELAY);

elements/gmf_ai_audio/include/esp_gmf_afe.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,24 @@ esp_gmf_err_t esp_gmf_afe_vcmd_detection_cancel(esp_gmf_element_handle_t handle)
160160
*/
161161
esp_gmf_err_t esp_gmf_afe_set_event_cb(esp_gmf_element_handle_t handle, esp_gmf_afe_event_cb_t cb, void *ctx);
162162

163+
/**
164+
* @brief Enable or disable keep-awake mode
165+
*
166+
* When keep-awake mode is enabled, the system will remain in the wake state
167+
* and prevent wakeup_end events from being triggered automatically
168+
* This is useful for scenarios where you want to keep the system active
169+
* without automatic timeout
170+
*
171+
* @param handle The handle to the AFE element
172+
* @param enable True to enable keep-awake mode, false to disable
173+
*
174+
* @return
175+
* - ESP_GMF_ERR_OK Success
176+
* - ESP_GMF_ERR_INVALID_ARG Invalid argument
177+
* - ESP_GMF_ERR_INVALID_STATE Config not exist
178+
*/
179+
esp_gmf_err_t esp_gmf_afe_keep_awake(esp_gmf_element_handle_t handle, bool enable);
180+
163181
#ifdef __cplusplus
164182
}
165183
#endif /* __cplusplus */

0 commit comments

Comments
 (0)