ESP32开发(6)esp-adf:百度语音识别
前言
本例程基于官方例程esp-adf/example/speech_recognition/asr修改而来。asr例程是一个本地语音识别例程,已经帮助我们读取到了所需要的原始语音数据,我们只要稍作修改,将它通过HTTP协议上传到百度语音识别接口,就可以实现语音识别啦。
准备工作
开发环境:Linux-Ubuntu16 开发平台:ESP32_LyraT开发板。这款开发板上面的模组是ESP32-WROVER,额外带有4M RAM,可以用来缓存语音数据。
获取Access Token
在百度开发者平台上创建一个语音识别应用,具体操作参考,我这里语音识别和语音合成是一个应用,记录下API key和Secret Key。在Linux中创建一个shell脚本,输入以下命令:
#!/bin/bash curl -i -k https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=******&client_secret=****** >>receive_token.json
其中"client_id"是API key,"client secret"是Secret Key,执行脚本,在重定向生成的receive_token.json文件中找"access_token"这一项,记录下后面那一长串字符。注意:这个access_token只有一个月的有效期,需要定期更新。
实现思路
在实现之前,建议先阅读一下百度的官方语音识别文档,了解一下两种上传方式的区别,我们采用RAM方式上传,不用计算JSON,节省内存开销。 因为asr例程是本地语音识别,所以我们还需要往程序中添加一些其他组件,比如基本的wifi连接配置,HTTP客户端配置,这些我们就不做讨论了。我们直接来看改动的主要部分。
while (1)
{
if(get_key_value() == 0)
{
char *buff = (char *)heap_caps_malloc(96 * 1024, MALLOC_CAP_SPIRAM);
if (NULL == buff)
{
ESP_LOGE(EVENT_TAG, "Memory allocation failed!");
return;
}
memset(buff, 0, 96 * 1024);
ESP_LOGI(TAG, "have key");
for(size_t i = 0; i < 12; i++)
{
raw_stream_read(raw_read, (char *)buff + i * 8 * 1024, 8 * 1024);
}
esp_http_client_config_t config =
{
.url = "http://vop.baidu.com/server_api?dev_pid=1536&cuid=ESP32_HanChenen521&token=24.5af78a8f13afcd9a592624865bbd5eac.2592000.1562320078.282335-15514068",
.event_handler = _http_event_handler,
};
esp_http_client_handle_t client = esp_http_client_init(&config);
esp_http_client_set_method(client, HTTP_METHOD_POST);
esp_http_client_set_post_field(client, (const char *)buff, 96 * 1024);
esp_http_client_set_header(client, "Content-Type", "audio/pcm;rate=16000");
esp_err_t err = esp_http_client_perform(client);
if (err == ESP_OK)
{
ESP_LOGI(TAG, "HTTP POST Status = %d, content_length = %d",
esp_http_client_get_status_code(client),
esp_http_client_get_content_length(client));
}
else
{
ESP_LOGE(TAG, "HTTP POST request failed: %s", esp_err_to_name(err));
}
esp_http_client_cleanup(client);
free(buff);
buff = NULL;
}
ESP_LOGI(TAG, "please press the key");
vTaskDelay(100);
