espressif / esp-adf

Espressif Audio Development Framework
Other
1.53k stars 672 forks source link

Automatic recording according to the sound level (AUD-3226) #666

Closed cattleliu closed 2 years ago

cattleliu commented 3 years ago

I in the record_raw_HTTP base to do according to the sound level, automatic recording of the program, I encountered a problem is the first time can be normal recording, when the environment sound small stop recording. In the next time the environment sound is relatively loud when it can not normally start. I'll post the key code and error report

include

include

include "freertos/FreeRTOS.h"

include "freertos/task.h"

include "esp_log.h"

include "esp_wifi.h"

include "nvs_flash.h"

include "esp_http_client.h"

include "sdkconfig.h"

include "audio_element.h"

include "audio_pipeline.h"

include "audio_event_iface.h"

include "audio_common.h"

include "board.h"

include "http_stream.h"

include "i2s_stream.h"

include "wav_encoder.h"

include "esp_peripherals.h"

include "periph_button.h"

include "periph_wifi.h"

include "filter_resample.h"

include "input_key_service.h"

include "driver/gpio.h"

include "driver/adc.h"

include "esp_adc_cal.h"

static const char *TAG = "REC_RAW_HTTP";

define DEMO_EXIT_BIT (BIT0)

define DEFAULT_VREF 1100 //Use adc2_vref_to_gpio() to obtain a better estimate

define NO_OF_SAMPLES 64

static const adc_channel_t channel = ADC_CHANNEL_0; //GPIO36 static const adc_bits_width_t width = ADC_WIDTH_BIT_12; static const adc_atten_t atten = ADC_ATTEN_DB_6; static const adc_unit_t unit = ADC_UNIT_1; static esp_adc_cal_characteristics_t *adc_chars;

static audio_pipeline_handle_t pipeline; //static EventGroupHandle_t EXIT_FLAG; bool one_run_flag = true; bool pipling_state = false; esp_err_t _http_stream_event_handle(http_stream_event_msg_t *msg) { esp_http_client_handle_t http = (esp_http_client_handle_t)msg->http_client; char len_buf[16]; static int total_write = 0;

if (msg->event_id == HTTP_STREAM_PRE_REQUEST) {
    // set header
    ESP_LOGI(TAG, "[ + ] HTTP client HTTP_STREAM_PRE_REQUEST, lenght=%d", msg->buffer_len);
    esp_http_client_set_header(http, "x-audio-sample-rates", "11025");
    esp_http_client_set_header(http, "x-audio-bits", "16");
    esp_http_client_set_header(http, "x-audio-channel", "1");
    total_write = 0;
    return ESP_OK;
}

if (msg->event_id == HTTP_STREAM_ON_REQUEST) {
    // write data
    int wlen = sprintf(len_buf, "%x\r\n", msg->buffer_len);
    if (esp_http_client_write(http, len_buf, wlen) <= 0) {
        return ESP_FAIL;
    }
    if (esp_http_client_write(http, msg->buffer, msg->buffer_len) <= 0) {
        return ESP_FAIL;
    }
    if (esp_http_client_write(http, "\r\n", 2) <= 0) {
        return ESP_FAIL;
    }
    total_write += msg->buffer_len;
    printf("\033[A\33[2K\rTotal bytes written: %d\n", total_write);
    return msg->buffer_len;
}

if (msg->event_id == HTTP_STREAM_POST_REQUEST) {
    ESP_LOGI(TAG, "[ + ] HTTP client HTTP_STREAM_POST_REQUEST, write end chunked marker");
    if (esp_http_client_write(http, "0\r\n\r\n", 5) <= 0) {
        return ESP_FAIL;
    }
    return ESP_OK;
}

if (msg->event_id == HTTP_STREAM_FINISH_REQUEST) {
    ESP_LOGI(TAG, "[ + ] HTTP client HTTP_STREAM_FINISH_REQUEST");
    char *buf = calloc(1, 64);
    assert(buf);
    int read_len = esp_http_client_read(http, buf, 64);
    if (read_len <= 0) {
        free(buf);
        return ESP_FAIL;
    }
    buf[read_len] = 0;
    ESP_LOGI(TAG, "Got HTTP Response = %s", (char *)buf);
    free(buf);
    return ESP_OK;
}
return ESP_OK;

}

void app_main(void) { //check_efuse(); adc1_config_width(width); adc1_config_channel_atten(channel, atten); //Characterize ADC adc_chars = calloc(1, sizeof(esp_adc_cal_characteristics_t)); esp_adc_cal_value_t val_type = esp_adc_cal_characterize(unit, atten, width, DEFAULT_VREF, adc_chars); //print_char_val_type(val_type);

audio_element_handle_t http_stream_writer, i2s_stream_reader;

esp_log_level_set("*", ESP_LOG_WARN);
esp_log_level_set(TAG, ESP_LOG_INFO);

//EXIT_FLAG = xEventGroupCreate();

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_ERROR_CHECK(esp_netif_init());
ESP_LOGI(TAG, "[ 1 ] Initialize Button Peripheral & Connect to wifi network");
// Initialize peripherals management
esp_periph_config_t periph_cfg = DEFAULT_ESP_PERIPH_SET_CONFIG();
esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg);

periph_wifi_cfg_t wifi_cfg = {
    .ssid = CONFIG_WIFI_SSID,
    .password = CONFIG_WIFI_PASSWORD,
};
esp_periph_handle_t wifi_handle = periph_wifi_init(&wifi_cfg);

// Start wifi & button peripheral
esp_periph_start(set, wifi_handle);
periph_wifi_wait_for_connected(wifi_handle, portMAX_DELAY);

ESP_LOGI(TAG, "[ 2 ] Start codec chip");
audio_board_handle_t board_handle = audio_board_init();
audio_hal_ctrl_codec(board_handle->audio_hal, AUDIO_HAL_CODEC_MODE_ENCODE, AUDIO_HAL_CTRL_START);

ESP_LOGI(TAG, "[3.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(TAG, "[3.1] Create http stream to post data to server");

http_stream_cfg_t http_cfg = HTTP_STREAM_CFG_DEFAULT();
http_cfg.type = AUDIO_STREAM_WRITER;
http_cfg.event_handle = _http_stream_event_handle;
http_stream_writer = http_stream_init(&http_cfg);

ESP_LOGI(TAG, "[3.2] Create i2s stream to read audio data from codec chip");
i2s_stream_cfg_t i2s_cfg = I2S_STREAM_CFG_DEFAULT();
i2s_cfg.type = AUDIO_STREAM_READER;

if defined CONFIG_ESP_LYRAT_MINI_V1_1_BOARD

i2s_cfg.i2s_port = 1;

endif

i2s_stream_reader = i2s_stream_init(&i2s_cfg);

ESP_LOGI(TAG, "[3.3] Register all elements to audio pipeline");
audio_pipeline_register(pipeline, i2s_stream_reader, "i2s");
audio_pipeline_register(pipeline, http_stream_writer, "http");

ESP_LOGI(TAG, "[3.4] Link it together [codec_chip]-->i2s_stream->http_stream-->[http_server]");
const char *link_tag[2] = {"i2s", "http"};
audio_pipeline_link(pipeline, &link_tag[0], 2);

i2s_stream_set_clk(i2s_stream_reader, 11025, 16, 1);
while (1)
{
    uint32_t adc_reading = 0;
    //Multisampling
    for (int i = 0; i < NO_OF_SAMPLES; i++)
    {
        adc_reading += adc1_get_raw((adc1_channel_t)channel);   
    } 
    adc_reading /= NO_OF_SAMPLES;
    //Convert adc_reading to voltage in mV
    uint32_t voltage = esp_adc_cal_raw_to_voltage(adc_reading, adc_chars);
    printf("Raw: %d\tVoltage: %dmV\n", adc_reading, voltage);

    if (adc_reading > 250)
    {
       ESP_LOGI(TAG,"[ * ] pipeline run");
       audio_element_set_uri(http_stream_writer, CONFIG_SERVER_URI);
       audio_pipeline_run(pipeline);
      /* if (one_run_flag == true) {
            ESP_LOGI(TAG,"[ * ] pipeline run");
            audio_pipeline_run(pipeline);
            one_run_flag = false;
            pipling_state = true;
            }
            else 
            {

               //audio_pipeline_reset_elements(pipeline);
               //audio_pipeline_run(pipeline);
               if (pipling_state == false)
               {
                   ESP_LOGI(TAG,"[ * ] pipeline resume");
                   audio_pipeline_resume(pipeline);
                   pipling_state = true;

               }
            }*/
    }
    vTaskDelay(pdMS_TO_TICKS(10000));
    printf("Raw: %d\tVoltage: %dmV\n", adc_reading, voltage);
    if (adc_reading < 200)
    {
      // if (one_run_flag == false)
      // {
       //    if (pipling_state == true)
       //    {
            ESP_LOGI(TAG,"[ * ] pipeline pause");
            //audio_pipeline_pause(pipeline);
            audio_pipeline_stop(pipeline);
            audio_pipeline_wait_for_stop(pipeline);
            http_stream_restart(http_stream_writer);
           // pipling_state = false;

          // }
      // }
    }

}

ESP_LOGI(TAG, "[ 5 ] Stop audio_pipeline");
audio_pipeline_stop(pipeline);
audio_pipeline_wait_for_stop(pipeline);
audio_pipeline_terminate(pipeline);

audio_pipeline_unregister(pipeline, http_stream_writer);
audio_pipeline_unregister(pipeline, i2s_stream_reader);

/* Terminal the pipeline before removing the listener */
audio_pipeline_remove_listener(pipeline);

/* Stop all periph before removing the listener */
esp_periph_set_stop_all(set);

/* Release all resources */
audio_pipeline_deinit(pipeline);
audio_element_deinit(http_stream_writer);
audio_element_deinit(i2s_stream_reader);
esp_periph_set_destroy(set);

}

The following error message is displayed

I (31) boot: ESP-IDF v4.2-dirty 2nd stage bootloader I (31) boot: compile time 21:40:47 I (31) boot: chip revision: 3 I (34) boot_comm: chip revision: 3, min. bootloader chip revision: 0 I (42) boot.esp32: SPI Speed : 40MHz I (46) boot.esp32: SPI Mode : DIO I (51) boot.esp32: SPI Flash Size : 4MB I (55) boot: Enabling RNG early entropy source... I (60) boot: Partition Table: I (64) boot: ## Label Usage Type ST Offset Length I (71) boot: 0 nvs WiFi data 01 02 00009000 00006000 I (79) boot: 1 phy_init RF data 01 01 0000f000 00001000 I (86) boot: 2 factory factory app 00 00 00010000 00100000 I (94) boot: End of partition table I (98) boot_comm: chip revision: 3, min. application chip revision: 0 I (105) esp_image: segment 0: paddr=0x00010020 vaddr=0x3f400020 size=0x23134 (143668) map I (169) esp_image: segment 1: paddr=0x0003315c vaddr=0x3ffb0000 size=0x03918 ( 14616) load I (175) esp_image: segment 2: paddr=0x00036a7c vaddr=0x40080000 size=0x00404 ( 1028) load 0x40080000: _WindowOverflow4 at F:/Espressif/esp-idf/components/freertos/xtensa/xtensa_vectors.S:1730

I (176) esp_image: segment 3: paddr=0x00036e88 vaddr=0x40080404 size=0x09190 ( 37264) load I (201) esp_image: segment 4: paddr=0x00040020 vaddr=0x400d0020 size=0xa0590 (656784) map 0x400d0020: _stext at ??:?

I (451) esp_image: segment 5: paddr=0x000e05b8 vaddr=0x40089594 size=0x0d9bc ( 55740) load 0x40089594: prvInitialiseTaskLists at F:/Espressif/esp-idf/components/freertos/tasks.c:3603

I (488) boot: Loaded app from partition at offset 0x10000 I (488) boot: Disabling RNG early entropy source... I (489) cpu_start: Pro cpu up. I (492) cpu_start: Application information: I (497) cpu_start: Project name: record_raw_http I (503) cpu_start: App version: 1 I (507) cpu_start: Compile time: Jul 19 2021 21:40:32 I (513) cpu_start: ELF file SHA256: c56df8a8a287e408... I (519) cpu_start: ESP-IDF: v4.2-dirty I (525) cpu_start: Starting app cpu, entry point is 0x400819b0 0x400819b0: call_start_cpu1 at F:/Espressif/esp-idf/components/esp32/cpu_start.c:287

I (0) cpu_start: App cpu up. I (535) heap_init: Initializing. RAM available for dynamic allocation: I (542) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM I (548) heap_init: At 3FFB8008 len 00027FF8 (159 KiB): DRAM I (554) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM I (561) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM I (567) heap_init: At 40096F50 len 000090B0 (36 KiB): IRAM I (573) cpu_start: Pro cpu start user code I (591) spi_flash: detected chip: generic I (592) spi_flash: flash io: dio I (592) cpu_start: Starting scheduler on PRO CPU. I (0) cpu_start: Starting scheduler on APP CPU. I (676) REC_RAW_HTTP: [ 1 ] Initialize Button Peripheral & Connect to wifi network I (796) phy: phy_version: 4500, 0cd6843, Sep 17 2020, 15:37:07, 0, 0 W (1736) PERIPH_WIFI: WiFi Event cb, Unhandle event_base:WIFI_EVENT, event_id:4 I (2676) REC_RAW_HTTP: [ 2 ] Start codec chip E (2676) gpio: gpio_install_isr_service(438): GPIO isr service already installed I (2696) REC_RAW_HTTP: [3.0] Create audio pipeline for recording I (2706) REC_RAW_HTTP: [3.1] Create http stream to post data to server I (2706) REC_RAW_HTTP: [3.2] Create i2s stream to read audio data from codec chip I (2736) REC_RAW_HTTP: [3.3] Register all elements to audio pipeline I (2736) REC_RAW_HTTP: [3.4] Link it together [codec_chip]-->i2s_stream->http_stream-->[http_server] Raw: 2 Voltage: 108mV Raw: 2 Voltage: 108mV I (12776) REC_RAW_HTTP: [ ] pipeline pause W (12776) AUDIO_PIPELINE: Without stop, st:1 W (12776) AUDIO_PIPELINE: Without wait stop, st:1 Raw: 272 Voltage: 224mV I (12776) REC_RAW_HTTP: [ ] pipeline run I (12816) REC_RAW_HTTP: [ + ] HTTP client HTTP_STREAM_PRE_REQUEST, lenght=0 Total bytes written: 1024 Total bytes written: 2048 Total bytes written: 3072 Total bytes written: 4096 Total bytes written: 5120 Total bytes written: 6144 Total bytes written: 7168 Total bytes written: 8192 Total bytes written: 9216

Total bytes written: 200704 Total bytes written: 201728 Total bytes written: 202752 Total bytes written: 203776 Total bytes written: 204800 Total bytes written: 205824 Total bytes written: 206848 Total bytes written: 207872 Total bytes written: 208896 Total bytes written: 209920 Total bytes written: 210944 Total bytes written: 211968 Raw: 272 Voltage: 224mV Raw: 168 Voltage: 179mV Total bytes written: 212992 Total bytes written: 214016 Total bytes written: 215040

Total bytes written: 431104 Total bytes written: 432128 Total bytes written: 433152 Raw: 168 Voltage: 179mV I (32816) REC_RAW_HTTP: [ ] pipeline pause W (32816) AUDIO_ELEMENT: IN-[http] AEL_IO_ABORT I (32816) REC_RAW_HTTP: [ + ] HTTP client HTTP_STREAM_POST_REQUEST, write end chunked marker I (32896) REC_RAW_HTTP: [ + ] HTTP client HTTP_STREAM_FINISH_REQUEST I (32896) REC_RAW_HTTP: Got HTTP Response = File 20210816T131640Z_11025_16_1.wav was written, size 433152 Raw: 570 Voltage: 352mV I (32906) REC_RAW_HTTP: [ ] pipeline run I (32936) REC_RAW_HTTP: [ + ] HTTP client HTTP_STREAM_PRE_REQUEST, lenght=0 Total bytes written: 1024 Total bytes written: 2048 Total bytes written: 3072 Total bytes written: 4096 W (32966) AUDIO_ELEMENT: IN-[http] AEL_IO_ABORT I (32966) REC_RAW_HTTP: [ + ] HTTP client HTTP_STREAM_POST_REQUEST, write end chunked marker I (33096) REC_RAW_HTTP: [ + ] HTTP client HTTP_STREAM_FINISH_REQUEST I (33096) REC_RAW_HTTP: Got HTTP Response = File 20210816T131641Z_11025_16_1.wav was written, size 4096 W (33096) AUDIO_EVT: There is no space in external queue W (33426) AUDIO_ELEMENT: OUT-[i2s] AEL_IO_ABORT W (33426) AUDIO_ELEMENT: OUT-[i2s] AEL_IO_ABORT W (33426) AUDIO_ELEMENT: OUT-[i2s] AEL_IO_ABORT W (33436) AUDIO_ELEMENT: OUT-[i2s] AEL_IO_ABORT W (33436) AUDIO_EVT: There is no space in external queue Raw: 570 Voltage: 352mV Raw: 206 Voltage: 195mV Raw: 206 Voltage: 195mV Raw: 256 Voltage: 217mV I (52946) REC_RAW_HTTP: [ ] pipeline run W (52946) AUDIO_PIPELINE: Pipeline already started, state:2 Raw: 256 Voltage: 217mV Raw: 265 Voltage: 221mV I (62946) REC_RAW_HTTP: [ ] pipeline run W (62946) AUDIO_PIPELINE: Pipeline already started, state:2 Raw: 265 Voltage: 221mV Raw: 259 Voltage: 218mV I (72946) REC_RAW_HTTP: [ ] pipeline run W (72946) AUDIO_PIPELINE: Pipeline already started, state:2 Raw: 259 Voltage: 218mV Raw: 259 Voltage: 218mV I (82946) REC_RAW_HTTP: [ ] pipeline run W (82946) AUDIO_PIPELINE: Pipeline already started, state:2 Raw: 259 Voltage: 218mV Raw: 249 Voltage: 214mV Raw: 249 Voltage: 214mV Raw: 188 Voltage: 188mV

HengYongChao commented 3 years ago

Hi @cattleliu

I saw you were using ADC to get this threshold. I suggest you use VAD API to get the sound threshold.

cattleliu commented 3 years ago

Hi @cattleliu

I saw you were using ADC to get this threshold. I suggest you use VAD API to get the sound threshold.

Thanks for your suggestion, I will try, actually the key is how to restart after stopping Pipeling, restart always fails.

HengYongChao commented 3 years ago

Hi @cattleliu

start -- stop -- start -- stop
          |
          -- pause -- resume -- pause

If your problem has not been resolved, please briefly describe your problem and attach a log, thanks.