#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "freertos/timers.h"
#include "driver/gpio.h"
#include "esp_system.h"
#include "esp_log.h"
#include "board.h"
#include "audio_common.h"
#include "audio_pipeline.h"
#include "mp3_decoder.h"
#include "i2s_stream.h"
#include "raw_stream.h"
#include "filter_resample.h"
#include "esp_wn_iface.h"
#include "esp_wn_models.h"
#include "rec_eng_helper.h"
#include "esp_peripherals.h"
#include "periph_adc_button.h"
#include <sys/time.h>
#include "esp_wifi.h"
#include "nvs_flash.h"
#include "sdkconfig.h"
#include "audio_element.h"
#include "audio_event_iface.h"
#include "http_stream.h"
#include "periph_wifi.h"
#include "esp_http_client.h"
#include "baidu_access_token.h"
#define BAIDU_SR_ENDPOINT "https://vop.baidu.com/server_api"
#define CONFIG_BAIDU_ACCESS_KEY "xxxxxxxxxxxxxxxxxxxxxxx"
#define CONFIG_BAIDU_SECRET_KEY "xxxxxxxxxxxxxxxxxxxxxxxxxx"
static const char *TAG = "example_asr_keywords";
static const char *EVENT_TAG = "asr_event";
static char *baidu_access_token = NULL;
static char request_data[1024];
static char *buff = NULL;
static int lock = 0;
int _http_stream_event_handle(http_stream_event_msg_t *msg)
{
esp_http_client_handle_t http_client = (esp_http_client_handle_t)msg->http_client;
if (msg->event_id != HTTP_STREAM_PRE_REQUEST) {
return ESP_OK;
}
if (baidu_access_token == NULL) {
// Must freed `baidu_access_token` after used
baidu_access_token = baidu_get_access_token(CONFIG_BAIDU_ACCESS_KEY, CONFIG_BAIDU_SECRET_KEY);
}
if (baidu_access_token == NULL) {
ESP_LOGE(TAG, "Error issuing access token");
return ESP_FAIL;
}
while(1)
{
if(lock == 1)
break;
sleep(1);
}
//"http://vop.baidu.com/server_api?dev_pid=8001&cuid=ESP32_HanChenen521&token=24.5af78a8f13afcd9a592624865bbd5eac.2592000.1562320078.282335-15514068"
int data_len = snprintf(request_data, 1024, "dev_pid=8002&cuid=ESP32&token=%s", baidu_access_token);
/*
esp_http_client_set_post_field(http_client, request_data, data_len);
esp_http_client_set_method(http_client, HTTP_METHOD_POST);
*/
esp_http_client_set_method(http_client, HTTP_METHOD_POST);
esp_http_client_set_post_field(http_client, (const char *)buff, 1*sizeof(short));
esp_http_client_set_header(http_client, "Content-Type", "audio/pcm;rate=16000");
lock = 0;
return ESP_OK;
}
void app_main()
{
#if defined CONFIG_ESP_LYRAT_V4_3_BOARD
gpio_config_t gpio_conf = {
.pin_bit_mask = 1UL << get_green_led_gpio(),
.mode = GPIO_MODE_OUTPUT,
.pull_up_en = 0,
.pull_down_en = 0,
.intr_type = 0
};
gpio_config(&gpio_conf);
#endif
esp_log_level_set("*", ESP_LOG_WARN);
esp_log_level_set(TAG, ESP_LOG_INFO);
esp_log_level_set(EVENT_TAG, ESP_LOG_INFO);
/*
ESP_LOGI(TAG, "Initialize SR handle");
esp_wn_iface_t *wakenet;
model_coeff_getter_t *model_coeff_getter;
model_iface_data_t *model_data;
get_wakenet_iface(&wakenet);
get_wakenet_coeff(&model_coeff_getter);
model_data = wakenet->create(model_coeff_getter, DET_MODE_90);
int num = wakenet->get_word_num(model_data);
for (int i = 1; i <= num; i++) {
char *name = wakenet->get_word_name(model_data, i);
ESP_LOGI(TAG, "keywords: %s (index = %d)", name, i);
}
float threshold = wakenet->get_det_threshold(model_data, 1);
int sample_rate = wakenet->get_samp_rate(model_data);
int audio_chunksize = wakenet->get_samp_chunksize(model_data);
ESP_LOGI(EVENT_TAG, "keywords_num = %d, threshold = %f, sample_rate = %d, chunksize = %d, sizeof_uint16 = %d", num, threshold, sample_rate, audio_chunksize, sizeof(int16_t));
int16_t *buff = (int16_t *)malloc(audio_chunksize * sizeof(short));
if (NULL == buff) {
ESP_LOGE(EVENT_TAG, "Memory allocation failed!");
//wakenet->destroy(model_data);
//model_data = NULL;
return;
}
*/
#if 1
esp_err_t err = nvs_flash_init();
if (err == ESP_ERR_NVS_NO_FREE_PAGES) {
// NVS partition was truncated and needs to be erased
// Retry nvs_flash_init
ESP_ERROR_CHECK(nvs_flash_erase());
err = nvs_flash_init();
}
tcpip_adapter_init();
ESP_LOGI(TAG, "[ 0 ] Start and wait for Wi-Fi network");
esp_periph_config_t periph_cfg = DEFAULT_ESP_PERIPH_SET_CONFIG();
esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg);
ESP_LOGI(TAG, "[0.1] Initialize ADC Button peripheral");
periph_adc_button_cfg_t adc_button_cfg = { 0 };
adc_arr_t adc_btn_tag = ADC_DEFAULT_ARR();
adc_button_cfg.arr = &adc_btn_tag;
adc_button_cfg.arr_size = 1;
ESP_LOGI(TAG, "[0.2] Start ADC Button peripheral");
esp_periph_handle_t adc_button_periph = periph_adc_button_init(&adc_button_cfg);
esp_periph_start(set, adc_button_periph);
periph_wifi_cfg_t wifi_cfg = {
.ssid = "xxxxx",
.password = "xxxxxxxxx",
};
esp_periph_handle_t wifi_handle = periph_wifi_init(&wifi_cfg);
esp_periph_start(set, wifi_handle);
periph_wifi_wait_for_connected(wifi_handle, portMAX_DELAY);
#endif
/*
audio_pipeline_handle_t pipeline;
audio_element_handle_t i2s_stream_reader, filter, raw_read;
*/
audio_pipeline_handle_t pipeline;
audio_element_handle_t http_write, raw_read/*, i2s_stream_reader*/;
ESP_LOGI(EVENT_TAG, "[ 1 ] Start codec chip");
audio_board_handle_t board_handle = audio_board_init();
audio_hal_ctrl_codec(board_handle->audio_hal, AUDIO_HAL_CODEC_MODE_BOTH, AUDIO_HAL_CTRL_START);
ESP_LOGI(EVENT_TAG, "[ 2.0 ] Create audio pipeline for recording");
audio_pipeline_cfg_t pipeline_cfg = DEFAULT_AUDIO_PIPELINE_CONFIG();
pipeline = audio_pipeline_init(&pipeline_cfg);
mem_assert(pipeline);
/*
ESP_LOGI(EVENT_TAG, "[ 2.1 ] Create i2s stream to read audio data from codec chip");
i2s_stream_cfg_t i2s_cfg = I2S_STREAM_CFG_DEFAULT();
i2s_cfg.i2s_config.sample_rate = 48000;
i2s_cfg.type = AUDIO_STREAM_READER;
// Mini board record by I2S1 and play music by I2S0, no need to add resample element.
#if defined CONFIG_ESP_LYRAT_MINI_V1_1_BOARD
i2s_cfg.i2s_config.sample_rate = 16000;
i2s_cfg.i2s_port = 1;
i2s_cfg.i2s_config.channel_format = I2S_CHANNEL_FMT_ONLY_RIGHT;
i2s_stream_reader = i2s_stream_init(&i2s_cfg);
#else
i2s_stream_reader = i2s_stream_init(&i2s_cfg);
ESP_LOGI(EVENT_TAG, "[ 2.2 ] Create filter to resample audio data");
rsp_filter_cfg_t rsp_cfg = DEFAULT_RESAMPLE_FILTER_CONFIG();
rsp_cfg.src_rate = 48000;
rsp_cfg.src_ch = 2;
rsp_cfg.dest_rate = 16000;
rsp_cfg.dest_ch = 1;
rsp_cfg.type = AUDIO_CODEC_TYPE_ENCODER;
filter = rsp_filter_init(&rsp_cfg);
#endif
*/
ESP_LOGI(EVENT_TAG, "[ 2.2 ] Create raw to receive data");
raw_stream_cfg_t raw_cfg = {
.out_rb_size = 8 * 1024,
.type = AUDIO_STREAM_READER,
};
raw_read = raw_stream_init(&raw_cfg);
ESP_LOGI(TAG, "[2.4] Create http stream to write data");
http_stream_cfg_t http_cfg = HTTP_STREAM_CFG_DEFAULT();
http_cfg.event_handle = _http_stream_event_handle;
http_cfg.type = AUDIO_STREAM_WRITER;
http_write = http_stream_init(&http_cfg);
ESP_LOGI(EVENT_TAG, "[ 3 ] Register all elements to audio pipeline");
//audio_pipeline_register(pipeline, i2s_stream_reader, "i2s");
audio_pipeline_register(pipeline, raw_read, "raw");
//audio_pipeline_register(pipeline, filter, "filter");
audio_pipeline_register(pipeline, http_write, "http");
#if defined CONFIG_ESP_LYRAT_MINI_V1_1_BOARD
ESP_LOGI(EVENT_TAG, "[ 4 ] Link elements together [codec_chip]-->i2s_stream-->raw-->[SR]");
audio_pipeline_link(pipeline, (const char *[]) {"i2s", "raw"}, 2);
#else
//audio_pipeline_register(pipeline, filter, "filter");
ESP_LOGI(EVENT_TAG, "[ 4 ] Link elements together [codec_chip]-->i2s_stream-->filter-->raw-->[SR]");
//audio_pipeline_link(pipeline, (const char *[]) {"i2s", "filter", "raw"}, 3);
audio_pipeline_link(pipeline, (const char *[]) {"raw", /*"i2s","filter",*/ "http"}, 3);
#endif
ESP_LOGI(TAG, "[2.6] Set up uri (http as http_stream, mp3 as mp3 decoder, and default output is i2s)");
audio_element_set_uri(http_write, BAIDU_SR_ENDPOINT);
ESP_LOGI(TAG, "[ 4 ] Set up event listener");
audio_event_iface_cfg_t evt_cfg = AUDIO_EVENT_IFACE_DEFAULT_CFG();
audio_event_iface_handle_t evt = audio_event_iface_init(&evt_cfg);
ESP_LOGI(TAG, "[4.1] Listening event from all elements of pipeline");
audio_pipeline_set_listener(pipeline, evt);
ESP_LOGI(TAG, "[4.2] Listening event from peripherals");
audio_event_iface_set_listener(esp_periph_set_get_event_iface(set), evt);
ESP_LOGI(TAG, "[ 5 ] Start audio_pipeline");
audio_pipeline_run(pipeline);
i2s_stream_set_clk(i2s_stream_reader, 16000, 16, 1);
/*
ESP_LOGI(EVENT_TAG, "[ 5 ] Start audio_pipeline");
audio_pipeline_run(pipeline);*/
while (1) {
audio_event_iface_msg_t msg;
esp_err_t ret = audio_event_iface_listen(evt, &msg, portMAX_DELAY);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "[ * ] Event interface error : %d", ret);
continue;
}
if (msg.source_type == PERIPH_ID_ADC_BTN) {
int button_id = (int)msg.data; // button id is sent as data_len
int state = msg.cmd; // button state is sent as cmd
if(button_id == USER_KEY_ID2)//判断按下的是否为rec
{
free(buff);
buff = NULL;
buff = (char *)malloc(1*sizeof(short));
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, 1*sizeof(short));
ESP_LOGI(TAG,"HAHA...");
//}
lock = 1;
while(1)
{
if(lock == 0)
break;
sleep(1);
}
}
}
ESP_LOGI(TAG, "please press the key");
vTaskDelay(100);
}
ESP_LOGI(EVENT_TAG, "[ 6 ] Stop audio_pipeline");
audio_pipeline_terminate(pipeline);
/* Terminate the pipeline before removing the listener */
audio_pipeline_remove_listener(pipeline);
audio_pipeline_unregister(pipeline, raw_read);
//audio_pipeline_unregister(pipeline, i2s_stream_reader);
audio_pipeline_unregister(pipeline, http_write);
/* Release all resources */
audio_pipeline_deinit(pipeline);
audio_element_deinit(raw_read);
//audio_element_deinit(i2s_stream_reader);
audio_element_deinit(http_write);
ESP_LOGI(EVENT_TAG, "[ 7 ] Destroy model");
//wakenet->destroy(model_data);
//model_data = NULL;
free(buff);
buff = NULL;
}
离线
连接的那个函数最后一个参数是2,忘改了。关于raw流的代码开源的太少了。也不知道哪里出错了。
离线