├── .gitignore ├── components ├── ac101_driver │ ├── component.mk │ ├── recoder.h │ ├── DriverUtil.h │ ├── AC101.h │ ├── uart.h │ ├── recoder.c │ ├── uart.c │ ├── DriverUtil.c │ └── AC101.c └── esp32_vad │ ├── webrtc │ ├── common_audio │ │ ├── rename.sh │ │ ├── rename.sh~ │ │ ├── vad │ │ │ ├── mock │ │ │ │ └── mock_vad.h │ │ │ ├── vad_gmm.h │ │ │ ├── include │ │ │ │ ├── vad.h │ │ │ │ └── webrtc_vad.h │ │ │ ├── vad.cc │ │ │ ├── vad_filterbank.h │ │ │ ├── vad_sp.h │ │ │ ├── vad_gmm.c │ │ │ ├── webrtc_vad.c │ │ │ ├── vad_core.h │ │ │ └── vad_sp.c │ │ └── signal_processing │ │ │ ├── energy.c │ │ │ ├── cross_correlation.c │ │ │ ├── get_scaling_square.c │ │ │ ├── resample_by_2_internal.h │ │ │ ├── downsample_fast.c │ │ │ ├── vector_scaling_operations_mips.c.mips │ │ │ ├── cross_correlation_neon.c.neon │ │ │ ├── include │ │ │ ├── spl_inl_armv7.h │ │ │ ├── real_fft.h │ │ │ ├── spl_inl.h │ │ │ └── spl_inl_mips.h │ │ │ ├── division_operations.c │ │ │ ├── spl_init.c │ │ │ ├── vector_scaling_operations.c │ │ │ ├── min_max_operations.c │ │ │ ├── cross_correlation_mips.c.mips │ │ │ ├── resample_48khz.c │ │ │ ├── resample_fractional.c │ │ │ ├── min_max_operations_neon.c.neon │ │ │ ├── downsample_fast_neon.c.neon │ │ │ └── downsample_fast_mips.c.mips │ ├── rtc_base │ │ ├── compile_assert_c.h │ │ ├── checks.cc │ │ ├── sanitizer.h │ │ ├── type_traits.h │ │ └── numerics │ │ │ └── safe_compare.h │ ├── system_wrappers │ │ └── include │ │ │ └── cpu_features_wrapper.h │ ├── typedefs_bck.h │ └── typedefs.h │ └── component.mk ├── Makefile ├── main ├── component.mk ├── simple_vad.h ├── simple_vad.c ├── common.h ├── Kconfig.projbuild └── main.c └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | /build/ 2 | /.settings/ 3 | /.cproject 4 | /.project 5 | -------------------------------------------------------------------------------- /components/ac101_driver/component.mk: -------------------------------------------------------------------------------- 1 | COMPONENT_ADD_INCLUDEDIRS := . 2 | 3 | -------------------------------------------------------------------------------- /components/ac101_driver/recoder.h: -------------------------------------------------------------------------------- 1 | #ifndef __RECODER_H 2 | #define __RECODER_H 3 | 4 | void recorder_task_setup(void); //建立录音处理任务 5 | 6 | 7 | 8 | #endif -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # This is a project Makefile. It is assumed the directory this Makefile resides in is a 3 | # project subdirectory. 4 | # 5 | 6 | include $(IDF_PATH)/make/project.mk 7 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/common_audio/rename.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | rename 's/mips\.c$/mips\.c\.mips/' signal_processing/*.c 3 | rename 's/neon\.c$/neon\.c\.neon/' signal_processing/*.c 4 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/common_audio/rename.sh~: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | rename 's/mips\.c$/mips\.c\.mips/' signal_processing/*.c 3 | rename 's/neon\.c$/neon\.c\.neon/' signal_processing/*.c 4 | -------------------------------------------------------------------------------- /main/component.mk: -------------------------------------------------------------------------------- 1 | # 2 | # "main" pseudo-component makefile. 3 | # 4 | # (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) 5 | 6 | 7 | -------------------------------------------------------------------------------- /components/esp32_vad/component.mk: -------------------------------------------------------------------------------- 1 | COMPONENT_ADD_INCLUDEDIRS += webrtc 2 | 3 | COMPONENT_PRIV_INCLUDEDIRS += webrtc/common_audio/vad/include \ 4 | webrtc/common_audio/signal_processing/include \ 5 | webrtc/system_wrappers/include 6 | 7 | COMPONENT_SRCDIRS += webrtc/common_audio/vad \ 8 | webrtc/common_audio/signal_processing \ 9 | webrtc/rtc_base 10 | 11 | -------------------------------------------------------------------------------- /components/ac101_driver/DriverUtil.h: -------------------------------------------------------------------------------- 1 | /* 2 | * DriverUtil.h 3 | * 4 | * Created on: 2017.1.23 5 | * Author: Jack 6 | */ 7 | 8 | 9 | #ifndef __DRIVER_UTIL_H 10 | #define __DRIVER_UTIL_H 11 | 12 | #include "stdint.h" 13 | #include "esp_log.h" 14 | uint8_t IIC_Write_One_Byte(uint8_t DevAddr,uint8_t RegAddr,uint8_t Data); 15 | uint8_t IIC_Write_two_Bytes(uint8_t DevAddr, uint8_t RegAddr, uint16_t Data); 16 | uint16_t IIC_read_two_Bytes(uint8_t DevAddr, uint8_t RegAddr); 17 | esp_err_t i2c_example_master_read_slave(uint8_t DevAddr, uint8_t reg,uint8_t* data_rd, size_t size); 18 | #endif 19 | -------------------------------------------------------------------------------- /components/ac101_driver/AC101.h: -------------------------------------------------------------------------------- 1 | /* 2 | * AC101.h 3 | * 4 | * Created on: 2018年1月9日 5 | * Author: ai-thinker 6 | */ 7 | 8 | #ifndef MAIN_AC101_H_ 9 | #define MAIN_AC101_H_ 10 | 11 | #include "stdint.h" 12 | #define AC101_ADDR 0X1a //0011010 13 | #define PA_EN_PIN 21 14 | #define PA_EN_PIN_SEL (1ULL< 11 | #include "stdbool.h" 12 | typedef struct 13 | { 14 | char *at_cmdName; 15 | int8_t at_cmdLen; 16 | void (*at_testCmd)(uint8_t id); 17 | void (*at_queryCmd)(uint8_t id); 18 | void (*at_setupCmd)(uint8_t id, char *pPara); 19 | void (*at_exeCmd)(uint8_t id); 20 | }at_funcationType; 21 | 22 | void echo_task(); //接收串口数据 23 | void at_recvTask(char *str); //处理接受到的串口数据,并相应对应的at命令 24 | void at_OTA(uint8_t id); //工作分区切换 25 | void ota_adress(uint8_t id, char *pPara); //固件升级 26 | void at_connect(uint8_t id, char *pPara);//连接到网络 27 | 28 | #endif /* MAIN_UART_H_ */ 29 | -------------------------------------------------------------------------------- /components/ac101_driver/recoder.c: -------------------------------------------------------------------------------- 1 | #include "recoder.h" 2 | #include "freertos/FreeRTOS.h" 3 | #include "freertos/task.h" 4 | #include "esp_log.h" 5 | #include "driver/i2s.h" 6 | #include "math.h" 7 | #include 8 | 9 | #define BUF_LEN 60 10 | char *buff; //存放从DMA获取到的原始IIS数据 11 | 12 | 13 | //读取一次数据,然后将数据打印出来,完成后删除线程 14 | void recoder_task(void) 15 | { 16 | char buff[BUF_LEN]; 17 | int recv_len=0; 18 | int i =0; 19 | unsigned short data; 20 | while(1) 21 | { 22 | recv_len = i2s_read_bytes(0,buff, BUF_LEN,portMAX_DELAY); 23 | i2s_write_bytes(0,buff,recv_len,portMAX_DELAY); 24 | } 25 | 26 | // vTaskDelete(xHandle); 27 | 28 | } 29 | 30 | /* 31 | 说明:创建录音处理任务 32 | 参数:无 33 | 返回值:无 34 | */ 35 | void recorder_task_setup(void) 36 | { 37 | xTaskCreate(&recoder_task, "recoder_task", 5000, NULL, 4, NULL); 38 | } 39 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/rtc_base/compile_assert_c.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef RTC_BASE_COMPILE_ASSERT_C_H_ 12 | #define RTC_BASE_COMPILE_ASSERT_C_H_ 13 | 14 | // Use this macro to verify at compile time that certain restrictions are met. 15 | // The argument is the boolean expression to evaluate. 16 | // Example: 17 | // RTC_COMPILE_ASSERT(sizeof(foo) < 128); 18 | // Note: In C++, use static_assert instead! 19 | #define RTC_COMPILE_ASSERT(expression) switch (0) {case 0: case expression:;} 20 | 21 | #endif // RTC_BASE_COMPILE_ASSERT_C_H_ 22 | -------------------------------------------------------------------------------- /main/simple_vad.h: -------------------------------------------------------------------------------- 1 | // 2 | // 包装webrtc 的gmm vad算法 3 | // 4 | // Created by fu on 3/6/18. 5 | // 6 | 7 | #ifndef VAD_DEMO_FILE_READ_H 8 | #define VAD_DEMO_FILE_READ_H 9 | 10 | #include 11 | #include 12 | #include 13 | #include "common.h" 14 | 15 | // 一个FRAME代表的时长。MULTI=1: 10ms;MULTI=2: 20ms;MULTI=3: 30ms; 16 | // FRAME_SIZE = 160 * MULTI = SAMPLE_RATE /1000 * MULTI , 17 | 18 | 19 | typedef VadInst simple_vad; 20 | 21 | /** 22 | * @brief 读取int16_t的数组 23 | * @param fp 24 | * @param output 25 | * @return 0 正常 1 文件结束 , 1000+ferror : 文件错误 26 | */ 27 | int read_int16_bytes(FILE *fp, int16_t *output); 28 | 29 | /** 30 | * @brief 31 | * @return NULL 创建失败 32 | */ 33 | simple_vad *simple_vad_create(); 34 | 35 | /** 36 | * @brief 37 | * @param inst 38 | * @param data 例如read_int16_bytes读取的数据 39 | * @return 40 | */ 41 | int process_vad(VadInst *inst, int16_t *data); 42 | 43 | /** 44 | * @brief 45 | * @param inst 46 | */ 47 | void simple_vad_free(simple_vad *inst); 48 | 49 | #endif //VAD_DEMO_FILE_READ_H 50 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/common_audio/vad/mock/mock_vad.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef COMMON_AUDIO_VAD_MOCK_MOCK_VAD_H_ 12 | #define COMMON_AUDIO_VAD_MOCK_MOCK_VAD_H_ 13 | 14 | #include "common_audio/vad/include/vad.h" 15 | #include "test/gmock.h" 16 | 17 | namespace webrtc { 18 | 19 | class MockVad : public Vad { 20 | public: 21 | virtual ~MockVad() { Die(); } 22 | MOCK_METHOD0(Die, void()); 23 | 24 | MOCK_METHOD3(VoiceActivity, 25 | enum Activity(const int16_t* audio, 26 | size_t num_samples, 27 | int sample_rate_hz)); 28 | MOCK_METHOD0(Reset, void()); 29 | }; 30 | 31 | } // namespace webrtc 32 | 33 | #endif // COMMON_AUDIO_VAD_MOCK_MOCK_VAD_H_ 34 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/common_audio/signal_processing/energy.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | 12 | /* 13 | * This file contains the function WebRtcSpl_Energy(). 14 | * The description header can be found in signal_processing_library.h 15 | * 16 | */ 17 | 18 | #include "common_audio/signal_processing/include/signal_processing_library.h" 19 | 20 | int32_t WebRtcSpl_Energy(int16_t* vector, 21 | size_t vector_length, 22 | int* scale_factor) 23 | { 24 | int32_t en = 0; 25 | size_t i; 26 | int scaling = 27 | WebRtcSpl_GetScalingSquare(vector, vector_length, vector_length); 28 | size_t looptimes = vector_length; 29 | int16_t *vectorptr = vector; 30 | 31 | for (i = 0; i < looptimes; i++) 32 | { 33 | en += (*vectorptr * *vectorptr) >> scaling; 34 | vectorptr++; 35 | } 36 | *scale_factor = scaling; 37 | 38 | return en; 39 | } 40 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/common_audio/signal_processing/cross_correlation.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #include "common_audio/signal_processing/include/signal_processing_library.h" 12 | 13 | /* C version of WebRtcSpl_CrossCorrelation() for generic platforms. */ 14 | void WebRtcSpl_CrossCorrelationC(int32_t* cross_correlation, 15 | const int16_t* seq1, 16 | const int16_t* seq2, 17 | size_t dim_seq, 18 | size_t dim_cross_correlation, 19 | int right_shifts, 20 | int step_seq2) { 21 | size_t i = 0, j = 0; 22 | 23 | for (i = 0; i < dim_cross_correlation; i++) { 24 | int32_t corr = 0; 25 | for (j = 0; j < dim_seq; j++) 26 | corr += (seq1[j] * seq2[j]) >> right_shifts; 27 | seq2 += step_seq2; 28 | *cross_correlation++ = corr; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /main/simple_vad.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by fu on 3/6/18. 3 | // 4 | 5 | #include "simple_vad.h" 6 | #include 7 | 8 | static int check_end_file(FILE *fp) { 9 | if (feof(fp)) { 10 | return 0; 11 | } 12 | return ferror(fp); 13 | } 14 | 15 | int read_int16_bytes(FILE *fp, int16_t *output) { 16 | if (feof(fp)) { 17 | return 1; 18 | } 19 | 20 | size_t readed = fread(output, sizeof(int16_t), FRAME_SIZE, fp); 21 | if (readed == 0) { 22 | int res = check_end_file(fp); 23 | return (res == 0) ? 1 : 1000 + res; 24 | } 25 | if (readed < FRAME_SIZE) { 26 | memset(output, 0, (FRAME_SIZE - readed) * sizeof(int16_t)); 27 | // printf("only %ld bits, will refill to %ld\n", readed, length); 28 | } 29 | return 0; 30 | 31 | } 32 | 33 | simple_vad *simple_vad_create() { 34 | VadInst *inst = WebRtcVad_Create(); 35 | int res = WebRtcVad_Init(inst); 36 | if (res != 0) { 37 | fprintf(stderr, "WebRtcVad_Init failed %d", res); 38 | return NULL; 39 | } 40 | res = WebRtcVad_set_mode(inst, WEBRTC_VAD_MODE); 41 | if (res != 0) { 42 | fprintf(stderr, "WebRtcVad_set_mode failed %d", res); 43 | WebRtcVad_Free(inst); 44 | return NULL; 45 | } 46 | return inst; 47 | } 48 | 49 | int process_vad(VadInst *inst, int16_t *data) { 50 | int res = WebRtcVad_Process(inst, SAMPLE_RATE, data, FRAME_SIZE); 51 | return res; 52 | } 53 | 54 | void simple_vad_free(simple_vad *inst) { 55 | WebRtcVad_Free(inst); 56 | } -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/common_audio/signal_processing/get_scaling_square.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | 12 | /* 13 | * This file contains the function WebRtcSpl_GetScalingSquare(). 14 | * The description header can be found in signal_processing_library.h 15 | * 16 | */ 17 | 18 | #include "common_audio/signal_processing/include/signal_processing_library.h" 19 | 20 | int16_t WebRtcSpl_GetScalingSquare(int16_t* in_vector, 21 | size_t in_vector_length, 22 | size_t times) 23 | { 24 | int16_t nbits = WebRtcSpl_GetSizeInBits((uint32_t)times); 25 | size_t i; 26 | int16_t smax = -1; 27 | int16_t sabs; 28 | int16_t *sptr = in_vector; 29 | int16_t t; 30 | size_t looptimes = in_vector_length; 31 | 32 | for (i = looptimes; i > 0; i--) 33 | { 34 | sabs = (*sptr > 0 ? *sptr++ : -*sptr++); 35 | smax = (sabs > smax ? sabs : smax); 36 | } 37 | t = WebRtcSpl_NormW32(WEBRTC_SPL_MUL(smax, smax)); 38 | 39 | if (smax == 0) 40 | { 41 | return 0; // Since norm(0) returns 0 42 | } else 43 | { 44 | return (t > nbits) ? 0 : nbits - t; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/common_audio/vad/vad_gmm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | // Gaussian probability calculations internally used in vad_core.c. 12 | 13 | #ifndef COMMON_AUDIO_VAD_VAD_GMM_H_ 14 | #define COMMON_AUDIO_VAD_VAD_GMM_H_ 15 | 16 | #include "typedefs.h" // NOLINT(build/include) 17 | 18 | // Calculates the probability for |input|, given that |input| comes from a 19 | // normal distribution with mean and standard deviation (|mean|, |std|). 20 | // 21 | // Inputs: 22 | // - input : input sample in Q4. 23 | // - mean : mean input in the statistical model, Q7. 24 | // - std : standard deviation, Q7. 25 | // 26 | // Output: 27 | // 28 | // - delta : input used when updating the model, Q11. 29 | // |delta| = (|input| - |mean|) / |std|^2. 30 | // 31 | // Return: 32 | // (probability for |input|) = 33 | // 1 / |std| * exp(-(|input| - |mean|)^2 / (2 * |std|^2)); 34 | int32_t WebRtcVad_GaussianProbability(int16_t input, 35 | int16_t mean, 36 | int16_t std, 37 | int16_t* delta); 38 | 39 | #endif // COMMON_AUDIO_VAD_VAD_GMM_H_ 40 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/system_wrappers/include/cpu_features_wrapper.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef SYSTEM_WRAPPERS_INCLUDE_CPU_FEATURES_WRAPPER_H_ 12 | #define SYSTEM_WRAPPERS_INCLUDE_CPU_FEATURES_WRAPPER_H_ 13 | 14 | #if defined(__cplusplus) || defined(c_plusplus) 15 | extern "C" { 16 | #endif 17 | 18 | #include "typedefs.h" // NOLINT(build/include) 19 | 20 | // List of features in x86. 21 | typedef enum { kSSE2, kSSE3 } CPUFeature; 22 | 23 | // List of features in ARM. 24 | enum { 25 | kCPUFeatureARMv7 = (1 << 0), 26 | kCPUFeatureVFPv3 = (1 << 1), 27 | kCPUFeatureNEON = (1 << 2), 28 | kCPUFeatureLDREXSTREX = (1 << 3) 29 | }; 30 | 31 | typedef int (*WebRtc_CPUInfo)(CPUFeature feature); 32 | 33 | // Returns true if the CPU supports the feature. 34 | extern WebRtc_CPUInfo WebRtc_GetCPUInfo; 35 | 36 | // No CPU feature is available => straight C path. 37 | extern WebRtc_CPUInfo WebRtc_GetCPUInfoNoASM; 38 | 39 | // Return the features in an ARM device. 40 | // It detects the features in the hardware platform, and returns supported 41 | // values in the above enum definition as a bitmask. 42 | extern uint64_t WebRtc_GetCPUFeaturesARM(void); 43 | 44 | #if defined(__cplusplus) || defined(c_plusplus) 45 | } // extern "C" 46 | #endif 47 | 48 | #endif // SYSTEM_WRAPPERS_INCLUDE_CPU_FEATURES_WRAPPER_H_ 49 | -------------------------------------------------------------------------------- /main/common.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by fu on 3/7/18. 3 | // 4 | 5 | #ifndef VAD_DEMO_COMMON_H 6 | #define VAD_DEMO_COMMON_H 7 | 8 | #include 9 | 10 | 11 | 12 | // MULTI = 1 2 3 webrtc vad可以设置分别为以10ms 20ms 30ms作为包 13 | #define MULTI 1 14 | 15 | // VAD 模式 Aggressiveness mode (0, 1, 2, or 3). 数值越大,判断越是粗略,连着的静音或者响声增多 16 | #define WEBRTC_VAD_MODE 3 17 | 18 | // 有声音的音频段,xxx 毫秒后,认为该音频段结束,不能为0 19 | #define FILE_CUT_SILENCE_AFTER_ACTIVE_MS 500 20 | 21 | // 静音的音频段,切分xxx毫秒给之后有声音的音频段 22 | #define FILE_CUT_SILENCE_BEFORE_ACTIVE_MS 300 23 | 24 | // 最小的音频切分长度,即每个切分后音频文件不少于这个时长,最后一个除外 25 | #define FILE_CUT_MIN_MS (10 * 1000) 26 | 27 | // 最大的音频切分长度,即每个切分后音频文件不多于这个时长 28 | #define FILE_CUT_MAX_MS (60 * 1000) 29 | 30 | // 16000 采样率固定,更改采样频率需要手动更新FRAME_SIZE 31 | #define SAMPLE_RATE 16000 32 | 33 | // 用于 period_format.h 34 | #define PERIODS_SIZE_INITIED 100 35 | 36 | /* 采样一帧数据的大小(即在10ms(20ms,30ms)内的采样次数) 10ms-->160; 20ms-->320; 30ms-->480; 37 | * 16000HZ * 10ms/1000 = 160 38 | * 16000HZ * 20ms/1000 = 320 39 | * 16000HZ * 30ms/1000 = 480 */ 40 | #define FRAME_SIZE (160 * MULTI) 41 | 42 | #define CAL_FRAME_BY_FRAME(frame) (MULTI * frame * 10) 43 | 44 | #define CAL_FRAME_BY_TIME(time) (time / (MULTI * 10)) 45 | 46 | // VAD 检测总次数 0.01s(0.02s,0.03s) * 2000 47 | #define VAD_TIME_TOTAL 2000 48 | 49 | // VAD 触发前缓存次数 0.01s(0.02s,0.03s) * 100 50 | #define START_CACHE_TIME 100 51 | 52 | // VAD 触发检测次数 0.01s(0.02s,0.03s) * 50 53 | #define START_TIME 50 54 | 55 | // VAD 结束检测次数 0.01s(0.02s,0.03s) * 100 56 | #define END_TIME 100 57 | 58 | /* 59 | uint64_t inline CAL_FRAME_BY_FRAME(int frame){ 60 | return MULTI * frame * 10; 61 | }; 62 | 63 | int inline CAL_FRAME_BY_TIME(uint64_t time){ 64 | return time / (MULTI * 10); 65 | }; 66 | */ 67 | #endif //VAD_DEMO_COMMON_H 68 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/common_audio/vad/include/vad.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef COMMON_AUDIO_VAD_INCLUDE_VAD_H_ 12 | #define COMMON_AUDIO_VAD_INCLUDE_VAD_H_ 13 | 14 | #include 15 | 16 | #include "common_audio/vad/include/webrtc_vad.h" 17 | #include "rtc_base/checks.h" 18 | #include "typedefs.h" // NOLINT(build/include) 19 | 20 | namespace webrtc { 21 | 22 | class Vad { 23 | public: 24 | enum Aggressiveness { 25 | kVadNormal = 0, 26 | kVadLowBitrate = 1, 27 | kVadAggressive = 2, 28 | kVadVeryAggressive = 3 29 | }; 30 | 31 | enum Activity { kPassive = 0, kActive = 1, kError = -1 }; 32 | 33 | virtual ~Vad() = default; 34 | 35 | // Calculates a VAD decision for the given audio frame. Valid sample rates 36 | // are 8000, 16000, and 32000 Hz; the number of samples must be such that the 37 | // frame is 10, 20, or 30 ms long. 38 | virtual Activity VoiceActivity(const int16_t* audio, 39 | size_t num_samples, 40 | int sample_rate_hz) = 0; 41 | 42 | // Resets VAD state. 43 | virtual void Reset() = 0; 44 | }; 45 | 46 | // Returns a Vad instance that's implemented on top of WebRtcVad. 47 | std::unique_ptr CreateVad(Vad::Aggressiveness aggressiveness); 48 | 49 | } // namespace webrtc 50 | 51 | #endif // COMMON_AUDIO_VAD_INCLUDE_VAD_H_ 52 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/common_audio/vad/vad.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #include "common_audio/vad/include/vad.h" 12 | 13 | #include 14 | 15 | #include "rtc_base/checks.h" 16 | 17 | namespace webrtc { 18 | 19 | namespace { 20 | 21 | class VadImpl final : public Vad { 22 | public: 23 | explicit VadImpl(Aggressiveness aggressiveness) 24 | : handle_(nullptr), aggressiveness_(aggressiveness) { 25 | Reset(); 26 | } 27 | 28 | ~VadImpl() override { WebRtcVad_Free(handle_); } 29 | 30 | Activity VoiceActivity(const int16_t* audio, 31 | size_t num_samples, 32 | int sample_rate_hz) override { 33 | int ret = WebRtcVad_Process(handle_, sample_rate_hz, audio, num_samples); 34 | switch (ret) { 35 | case 0: 36 | return kPassive; 37 | case 1: 38 | return kActive; 39 | default: 40 | RTC_NOTREACHED() << "WebRtcVad_Process returned an error."; 41 | return kError; 42 | } 43 | } 44 | 45 | void Reset() override { 46 | if (handle_) 47 | WebRtcVad_Free(handle_); 48 | handle_ = WebRtcVad_Create(); 49 | RTC_CHECK(handle_); 50 | RTC_CHECK_EQ(WebRtcVad_Init(handle_), 0); 51 | RTC_CHECK_EQ(WebRtcVad_set_mode(handle_, aggressiveness_), 0); 52 | } 53 | 54 | private: 55 | VadInst* handle_; 56 | Aggressiveness aggressiveness_; 57 | }; 58 | 59 | } // namespace 60 | 61 | std::unique_ptr CreateVad(Vad::Aggressiveness aggressiveness) { 62 | return std::unique_ptr(new VadImpl(aggressiveness)); 63 | } 64 | 65 | } // namespace webrtc 66 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/common_audio/vad/vad_filterbank.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | /* 12 | * This file includes feature calculating functionality used in vad_core.c. 13 | */ 14 | 15 | #ifndef COMMON_AUDIO_VAD_VAD_FILTERBANK_H_ 16 | #define COMMON_AUDIO_VAD_VAD_FILTERBANK_H_ 17 | 18 | #include "common_audio/vad/vad_core.h" 19 | #include "typedefs.h" // NOLINT(build/include) 20 | 21 | // Takes |data_length| samples of |data_in| and calculates the logarithm of the 22 | // energy of each of the |kNumChannels| = 6 frequency bands used by the VAD: 23 | // 80 Hz - 250 Hz 24 | // 250 Hz - 500 Hz 25 | // 500 Hz - 1000 Hz 26 | // 1000 Hz - 2000 Hz 27 | // 2000 Hz - 3000 Hz 28 | // 3000 Hz - 4000 Hz 29 | // 30 | // The values are given in Q4 and written to |features|. Further, an approximate 31 | // overall energy is returned. The return value is used in 32 | // WebRtcVad_GmmProbability() as a signal indicator, hence it is arbitrary above 33 | // the threshold |kMinEnergy|. 34 | // 35 | // - self [i/o] : State information of the VAD. 36 | // - data_in [i] : Input audio data, for feature extraction. 37 | // - data_length [i] : Audio data current_frame, in number of samples. 38 | // - features [o] : 10 * log10(energy in each frequency band), Q4. 39 | // - returns : Total energy of the signal (NOTE! This value is not 40 | // exact. It is only used in a comparison.) 41 | int16_t WebRtcVad_CalculateFeatures(VadInstT* self, const int16_t* data_in, 42 | size_t data_length, int16_t* features); 43 | 44 | #endif // COMMON_AUDIO_VAD_VAD_FILTERBANK_H_ 45 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/common_audio/signal_processing/resample_by_2_internal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | 12 | /* 13 | * This header file contains some internal resampling functions. 14 | * 15 | */ 16 | 17 | #ifndef COMMON_AUDIO_SIGNAL_PROCESSING_RESAMPLE_BY_2_INTERNAL_H_ 18 | #define COMMON_AUDIO_SIGNAL_PROCESSING_RESAMPLE_BY_2_INTERNAL_H_ 19 | 20 | #include "typedefs.h" // NOLINT(build/include) 21 | 22 | /******************************************************************* 23 | * resample_by_2_fast.c 24 | * Functions for internal use in the other resample functions 25 | ******************************************************************/ 26 | void WebRtcSpl_DownBy2IntToShort(int32_t *in, int32_t len, int16_t *out, 27 | int32_t *state); 28 | 29 | void WebRtcSpl_DownBy2ShortToInt(const int16_t *in, int32_t len, 30 | int32_t *out, int32_t *state); 31 | 32 | void WebRtcSpl_UpBy2ShortToInt(const int16_t *in, int32_t len, 33 | int32_t *out, int32_t *state); 34 | 35 | void WebRtcSpl_UpBy2IntToInt(const int32_t *in, int32_t len, int32_t *out, 36 | int32_t *state); 37 | 38 | void WebRtcSpl_UpBy2IntToShort(const int32_t *in, int32_t len, 39 | int16_t *out, int32_t *state); 40 | 41 | void WebRtcSpl_LPBy2ShortToInt(const int16_t* in, int32_t len, 42 | int32_t* out, int32_t* state); 43 | 44 | void WebRtcSpl_LPBy2IntToInt(const int32_t* in, int32_t len, int32_t* out, 45 | int32_t* state); 46 | 47 | #endif // COMMON_AUDIO_SIGNAL_PROCESSING_RESAMPLE_BY_2_INTERNAL_H_ 48 | -------------------------------------------------------------------------------- /main/Kconfig.projbuild: -------------------------------------------------------------------------------- 1 | menu "A2DP Example Configuration" 2 | 3 | choice A2DP_SINK_OUTPUT 4 | prompt "A2DP Sink Output" 5 | default A2DP_SINK_OUTPUT_EXTERNAL_I2S 6 | help 7 | Select to use Internal DAC or external I2S driver 8 | 9 | config A2DP_SINK_OUTPUT_INTERNAL_DAC 10 | bool "Internal DAC" 11 | help 12 | Select this to use Internal DAC sink output 13 | 14 | config A2DP_SINK_OUTPUT_EXTERNAL_I2S 15 | bool "External I2S Codec" 16 | help 17 | Select this to use External I2S sink output 18 | 19 | config A2DP_SINK_OUTPUT_EXTERNAL_I2S_AC101 20 | bool "External I2S Codec_ac101" 21 | help 22 | Select this to use External I2S sink output by AC101 23 | 24 | endchoice 25 | 26 | config I2S_LRCK_PIN 27 | int "I2S LRCK (WS) GPIO" 28 | default 22 29 | depends on A2DP_SINK_OUTPUT_EXTERNAL_I2S 30 | help 31 | GPIO number to use for I2S LRCK(WS) Driver. 32 | 33 | config I2S_BCK_PIN 34 | int "I2S BCK GPIO" 35 | default 26 36 | depends on A2DP_SINK_OUTPUT_EXTERNAL_I2S 37 | help 38 | GPIO number to use for I2S BCK Driver. 39 | 40 | config I2S_DATA_PIN 41 | int "I2S DATA GPIO" 42 | default 25 43 | depends on A2DP_SINK_OUTPUT_EXTERNAL_I2S 44 | help 45 | GPIO number to use for I2S Data Driver. 46 | 47 | config AC101_I2S_LRCK_PIN 48 | int "I2S LRCK (WS) GPIO" 49 | default 27 50 | depends on A2DP_SINK_OUTPUT_EXTERNAL_I2S_AC101 51 | help 52 | GPIO number to use for I2S LRCK(WS) Driver. 53 | 54 | config AC101_I2S_BCK_PIN 55 | int "I2S BCK GPIO" 56 | default 26 57 | depends on A2DP_SINK_OUTPUT_EXTERNAL_I2S_AC101 58 | help 59 | GPIO number to use for I2S BCK Driver. 60 | 61 | config AC101_I2S_DATA_PIN 62 | int "I2S DATA GPIO" 63 | default 25 64 | depends on A2DP_SINK_OUTPUT_EXTERNAL_I2S_AC101 65 | help 66 | GPIO number to use for I2S Data Driver. 67 | 68 | config AC101_I2S_MCLK_PIN 69 | int "I2S MCLK (CLK) GPIO" 70 | default 0 71 | depends on A2DP_SINK_OUTPUT_EXTERNAL_I2S_AC101 72 | help 73 | GPIO number to use for I2S MCLK(CLK) Driver. 74 | 75 | endmenu 76 | 77 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/common_audio/vad/vad_sp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | 12 | // This file includes specific signal processing tools used in vad_core.c. 13 | 14 | #ifndef COMMON_AUDIO_VAD_VAD_SP_H_ 15 | #define COMMON_AUDIO_VAD_VAD_SP_H_ 16 | 17 | #include "common_audio/vad/vad_core.h" 18 | #include "typedefs.h" // NOLINT(build/include) 19 | 20 | // Downsamples the signal by a factor 2, eg. 32->16 or 16->8. 21 | // 22 | // Inputs: 23 | // - signal_in : Input signal. 24 | // - in_length : Length of input signal in samples. 25 | // 26 | // Input & Output: 27 | // - filter_state : Current filter states of the two all-pass filters. The 28 | // |filter_state| is updated after all samples have been 29 | // processed. 30 | // 31 | // Output: 32 | // - signal_out : Downsampled signal (of length |in_length| / 2). 33 | void WebRtcVad_Downsampling(const int16_t* signal_in, 34 | int16_t* signal_out, 35 | int32_t* filter_state, 36 | size_t in_length); 37 | 38 | // Updates and returns the smoothed feature minimum. As minimum we use the 39 | // median of the five smallest feature values in a 100 frames long window. 40 | // As long as |handle->frame_counter| is zero, that is, we haven't received any 41 | // "valid" data, FindMinimum() outputs the default value of 1600. 42 | // 43 | // Inputs: 44 | // - feature_value : New feature value to update with. 45 | // - channel : Channel number. 46 | // 47 | // Input & Output: 48 | // - handle : State information of the VAD. 49 | // 50 | // Returns: 51 | // : Smoothed minimum value for a moving window. 52 | int16_t WebRtcVad_FindMinimum(VadInstT* handle, 53 | int16_t feature_value, 54 | int channel); 55 | 56 | #endif // COMMON_AUDIO_VAD_VAD_SP_H_ 57 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/common_audio/signal_processing/downsample_fast.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #include "common_audio/signal_processing/include/signal_processing_library.h" 12 | 13 | #include "rtc_base/checks.h" 14 | #include "rtc_base/sanitizer.h" 15 | 16 | // TODO(Bjornv): Change the function parameter order to WebRTC code style. 17 | // C version of WebRtcSpl_DownsampleFast() for generic platforms. 18 | int WebRtcSpl_DownsampleFastC(const int16_t* data_in, 19 | size_t data_in_length, 20 | int16_t* data_out, 21 | size_t data_out_length, 22 | const int16_t* __restrict coefficients, 23 | size_t coefficients_length, 24 | int factor, 25 | size_t delay) { 26 | int16_t* const original_data_out = data_out; 27 | size_t i = 0; 28 | size_t j = 0; 29 | int32_t out_s32 = 0; 30 | size_t endpos = delay + factor * (data_out_length - 1) + 1; 31 | 32 | // Return error if any of the running conditions doesn't meet. 33 | if (data_out_length == 0 || coefficients_length == 0 34 | || data_in_length < endpos) { 35 | return -1; 36 | } 37 | 38 | rtc_MsanCheckInitialized(coefficients, sizeof(coefficients[0]), 39 | coefficients_length); 40 | 41 | for (i = delay; i < endpos; i += factor) { 42 | out_s32 = 2048; // Round value, 0.5 in Q12. 43 | 44 | for (j = 0; j < coefficients_length; j++) { 45 | rtc_MsanCheckInitialized(&data_in[i - j], sizeof(data_in[0]), 1); 46 | out_s32 += coefficients[j] * data_in[i - j]; // Q12. 47 | } 48 | 49 | out_s32 >>= 12; // Q0. 50 | 51 | // Saturate and store the output. 52 | *data_out++ = WebRtcSpl_SatW32ToW16(out_s32); 53 | } 54 | 55 | RTC_DCHECK_EQ(original_data_out + data_out_length, data_out); 56 | rtc_MsanCheckInitialized(original_data_out, sizeof(original_data_out[0]), 57 | data_out_length); 58 | 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/common_audio/signal_processing/vector_scaling_operations_mips.c.mips: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | 12 | /* 13 | * This file contains implementations of the functions 14 | * WebRtcSpl_ScaleAndAddVectorsWithRound_mips() 15 | */ 16 | 17 | #include "common_audio/signal_processing/include/signal_processing_library.h" 18 | 19 | int WebRtcSpl_ScaleAndAddVectorsWithRound_mips(const int16_t* in_vector1, 20 | int16_t in_vector1_scale, 21 | const int16_t* in_vector2, 22 | int16_t in_vector2_scale, 23 | int right_shifts, 24 | int16_t* out_vector, 25 | size_t length) { 26 | int16_t r0 = 0, r1 = 0; 27 | int16_t *in1 = (int16_t*)in_vector1; 28 | int16_t *in2 = (int16_t*)in_vector2; 29 | int16_t *out = out_vector; 30 | size_t i = 0; 31 | int value32 = 0; 32 | 33 | if (in_vector1 == NULL || in_vector2 == NULL || out_vector == NULL || 34 | length == 0 || right_shifts < 0) { 35 | return -1; 36 | } 37 | for (i = 0; i < length; i++) { 38 | __asm __volatile ( 39 | "lh %[r0], 0(%[in1]) \n\t" 40 | "lh %[r1], 0(%[in2]) \n\t" 41 | "mult %[r0], %[in_vector1_scale] \n\t" 42 | "madd %[r1], %[in_vector2_scale] \n\t" 43 | "extrv_r.w %[value32], $ac0, %[right_shifts] \n\t" 44 | "addiu %[in1], %[in1], 2 \n\t" 45 | "addiu %[in2], %[in2], 2 \n\t" 46 | "sh %[value32], 0(%[out]) \n\t" 47 | "addiu %[out], %[out], 2 \n\t" 48 | : [value32] "=&r" (value32), [out] "+r" (out), [in1] "+r" (in1), 49 | [in2] "+r" (in2), [r0] "=&r" (r0), [r1] "=&r" (r1) 50 | : [in_vector1_scale] "r" (in_vector1_scale), 51 | [in_vector2_scale] "r" (in_vector2_scale), 52 | [right_shifts] "r" (right_shifts) 53 | : "hi", "lo", "memory" 54 | ); 55 | } 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # esp32_baidu_tts 2 | vad algorithm based on esp32 for mute detection 3 | 4 | /* 基于ESP32平台的说话人识别静音检测VAD算法,已实现VAD检测与语音截取 */ 5 | 6 | Speaker recognition mute detection VAD algorithm based on ESP32 platform has realized VAD detection and voice interception 7 | 8 | 9 | Hardware platform: Ai-Thinker ESP32-Aduio-Kit Audio Development Board 10 | 11 | https://item.taobao.com/item.htm?spm=a1z10.5-c-s.w4002-16491566042.12.510625e7rCXkuY&id=578317054056 12 | 13 | 14 | How to use Help: 15 | 16 | 1.To "make menuconfig" && "make -j2 flash monitor" 17 | 18 | 2.Speak to the microphone and realize voice interception 19 | 20 | 21 | You can see the effect below 22 | 23 | start vad detection 24 | 25 | 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 26 | 27 | To prepare the recording 20s 28 | 29 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 30 | 31 | play recording 32 | 33 | esp32_vad_task is over, thank you! 34 | 35 | 36 | This vad algorithm can also properly adjust the sensitivity, good luck far away 37 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/common_audio/vad/vad_gmm.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #include "common_audio/vad/vad_gmm.h" 12 | 13 | #include "common_audio/signal_processing/include/signal_processing_library.h" 14 | #include "typedefs.h" // NOLINT(build/include) 15 | 16 | static const int32_t kCompVar = 22005; 17 | static const int16_t kLog2Exp = 5909; // log2(exp(1)) in Q12. 18 | 19 | // For a normal distribution, the probability of |input| is calculated and 20 | // returned (in Q20). The formula for normal distributed probability is 21 | // 22 | // 1 / s * exp(-(x - m)^2 / (2 * s^2)) 23 | // 24 | // where the parameters are given in the following Q domains: 25 | // m = |mean| (Q7) 26 | // s = |std| (Q7) 27 | // x = |input| (Q4) 28 | // in addition to the probability we output |delta| (in Q11) used when updating 29 | // the noise/speech model. 30 | int32_t WebRtcVad_GaussianProbability(int16_t input, 31 | int16_t mean, 32 | int16_t std, 33 | int16_t* delta) { 34 | int16_t tmp16, inv_std, inv_std2, exp_value = 0; 35 | int32_t tmp32; 36 | 37 | // Calculate |inv_std| = 1 / s, in Q10. 38 | // 131072 = 1 in Q17, and (|std| >> 1) is for rounding instead of truncation. 39 | // Q-domain: Q17 / Q7 = Q10. 40 | tmp32 = (int32_t) 131072 + (int32_t) (std >> 1); 41 | inv_std = (int16_t) WebRtcSpl_DivW32W16(tmp32, std); 42 | 43 | // Calculate |inv_std2| = 1 / s^2, in Q14. 44 | tmp16 = (inv_std >> 2); // Q10 -> Q8. 45 | // Q-domain: (Q8 * Q8) >> 2 = Q14. 46 | inv_std2 = (int16_t)((tmp16 * tmp16) >> 2); 47 | // TODO(bjornv): Investigate if changing to 48 | // inv_std2 = (int16_t)((inv_std * inv_std) >> 6); 49 | // gives better accuracy. 50 | 51 | tmp16 = (input << 3); // Q4 -> Q7 52 | tmp16 = tmp16 - mean; // Q7 - Q7 = Q7 53 | 54 | // To be used later, when updating noise/speech model. 55 | // |delta| = (x - m) / s^2, in Q11. 56 | // Q-domain: (Q14 * Q7) >> 10 = Q11. 57 | *delta = (int16_t)((inv_std2 * tmp16) >> 10); 58 | 59 | // Calculate the exponent |tmp32| = (x - m)^2 / (2 * s^2), in Q10. Replacing 60 | // division by two with one shift. 61 | // Q-domain: (Q11 * Q7) >> 8 = Q10. 62 | tmp32 = (*delta * tmp16) >> 9; 63 | 64 | // If the exponent is small enough to give a non-zero probability we calculate 65 | // |exp_value| ~= exp(-(x - m)^2 / (2 * s^2)) 66 | // ~= exp2(-log2(exp(1)) * |tmp32|). 67 | if (tmp32 < kCompVar) { 68 | // Calculate |tmp16| = log2(exp(1)) * |tmp32|, in Q10. 69 | // Q-domain: (Q12 * Q10) >> 12 = Q10. 70 | tmp16 = (int16_t)((kLog2Exp * tmp32) >> 12); 71 | tmp16 = -tmp16; 72 | exp_value = (0x0400 | (tmp16 & 0x03FF)); 73 | tmp16 ^= 0xFFFF; 74 | tmp16 >>= 10; 75 | tmp16 += 1; 76 | // Get |exp_value| = exp(-|tmp32|) in Q10. 77 | exp_value >>= tmp16; 78 | } 79 | 80 | // Calculate and return (1 / s) * exp(-(x - m)^2 / (2 * s^2)), in Q20. 81 | // Q-domain: Q10 * Q10 = Q20. 82 | return inv_std * exp_value; 83 | } 84 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/common_audio/vad/include/webrtc_vad.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | 12 | /* 13 | * This header file includes the VAD API calls. Specific function calls are given below. 14 | */ 15 | 16 | #ifndef COMMON_AUDIO_VAD_INCLUDE_WEBRTC_VAD_H_ // NOLINT 17 | #define COMMON_AUDIO_VAD_INCLUDE_WEBRTC_VAD_H_ 18 | 19 | #include 20 | 21 | #include "typedefs.h" // NOLINT(build/include) 22 | 23 | typedef struct WebRtcVadInst VadInst; 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | // Creates an instance to the VAD structure. 30 | VadInst* WebRtcVad_Create(); 31 | 32 | // Frees the dynamic memory of a specified VAD instance. 33 | // 34 | // - handle [i] : Pointer to VAD instance that should be freed. 35 | void WebRtcVad_Free(VadInst* handle); 36 | 37 | // Initializes a VAD instance. 38 | // 39 | // - handle [i/o] : Instance that should be initialized. 40 | // 41 | // returns : 0 - (OK), 42 | // -1 - (null pointer or Default mode could not be set). 43 | int WebRtcVad_Init(VadInst* handle); 44 | 45 | // Sets the VAD operating mode. A more aggressive (higher mode) VAD is more 46 | // restrictive in reporting speech. Put in other words the probability of being 47 | // speech when the VAD returns 1 is increased with increasing mode. As a 48 | // consequence also the missed detection rate goes up. 49 | // 50 | // - handle [i/o] : VAD instance. 51 | // - mode [i] : Aggressiveness mode (0, 1, 2, or 3). 52 | // 53 | // returns : 0 - (OK), 54 | // -1 - (null pointer, mode could not be set or the VAD instance 55 | // has not been initialized). 56 | int WebRtcVad_set_mode(VadInst* handle, int mode); 57 | 58 | // Calculates a VAD decision for the |audio_frame|. For valid sampling rates 59 | // frame lengths, see the description of WebRtcVad_ValidRatesAndFrameLengths(). 60 | // 61 | // - handle [i/o] : VAD Instance. Needs to be initialized by 62 | // WebRtcVad_Init() before call. 63 | // - fs [i] : Sampling frequency (Hz): 8000, 16000, or 32000 64 | // - audio_frame [i] : Audio frame buffer. 65 | // - frame_length [i] : Length of audio frame buffer in number of samples. 66 | // 67 | // returns : 1 - (Active Voice), 68 | // 0 - (Non-active Voice), 69 | // -1 - (Error) 70 | int WebRtcVad_Process(VadInst* handle, int fs, const int16_t* audio_frame, 71 | size_t frame_length); 72 | 73 | // Checks for valid combinations of |rate| and |frame_length|. We support 10, 74 | // 20 and 30 ms frames and the rates 8000, 16000 and 32000 Hz. 75 | // 76 | // - rate [i] : Sampling frequency (Hz). 77 | // - frame_length [i] : Speech frame buffer length in number of samples. 78 | // 79 | // returns : 0 - (valid combination), -1 - (invalid combination) 80 | int WebRtcVad_ValidRateAndFrameLength(int rate, size_t frame_length); 81 | 82 | #ifdef __cplusplus 83 | } 84 | #endif 85 | 86 | #endif // COMMON_AUDIO_VAD_INCLUDE_WEBRTC_VAD_H_ // NOLINT 87 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/common_audio/signal_processing/cross_correlation_neon.c.neon: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #include "common_audio/signal_processing/include/signal_processing_library.h" 12 | 13 | #include 14 | 15 | static inline void DotProductWithScaleNeon(int32_t* cross_correlation, 16 | const int16_t* vector1, 17 | const int16_t* vector2, 18 | size_t length, 19 | int scaling) { 20 | size_t i = 0; 21 | size_t len1 = length >> 3; 22 | size_t len2 = length & 7; 23 | int64x2_t sum0 = vdupq_n_s64(0); 24 | int64x2_t sum1 = vdupq_n_s64(0); 25 | 26 | for (i = len1; i > 0; i -= 1) { 27 | int16x8_t seq1_16x8 = vld1q_s16(vector1); 28 | int16x8_t seq2_16x8 = vld1q_s16(vector2); 29 | #if defined(WEBRTC_ARCH_ARM64) 30 | int32x4_t tmp0 = vmull_s16(vget_low_s16(seq1_16x8), 31 | vget_low_s16(seq2_16x8)); 32 | int32x4_t tmp1 = vmull_high_s16(seq1_16x8, seq2_16x8); 33 | #else 34 | int32x4_t tmp0 = vmull_s16(vget_low_s16(seq1_16x8), 35 | vget_low_s16(seq2_16x8)); 36 | int32x4_t tmp1 = vmull_s16(vget_high_s16(seq1_16x8), 37 | vget_high_s16(seq2_16x8)); 38 | #endif 39 | sum0 = vpadalq_s32(sum0, tmp0); 40 | sum1 = vpadalq_s32(sum1, tmp1); 41 | vector1 += 8; 42 | vector2 += 8; 43 | } 44 | 45 | // Calculate the rest of the samples. 46 | int64_t sum_res = 0; 47 | for (i = len2; i > 0; i -= 1) { 48 | sum_res += WEBRTC_SPL_MUL_16_16(*vector1, *vector2); 49 | vector1++; 50 | vector2++; 51 | } 52 | 53 | sum0 = vaddq_s64(sum0, sum1); 54 | #if defined(WEBRTC_ARCH_ARM64) 55 | int64_t sum2 = vaddvq_s64(sum0); 56 | *cross_correlation = (int32_t)((sum2 + sum_res) >> scaling); 57 | #else 58 | int64x1_t shift = vdup_n_s64(-scaling); 59 | int64x1_t sum2 = vadd_s64(vget_low_s64(sum0), vget_high_s64(sum0)); 60 | sum2 = vadd_s64(sum2, vdup_n_s64(sum_res)); 61 | sum2 = vshl_s64(sum2, shift); 62 | vst1_lane_s32(cross_correlation, vreinterpret_s32_s64(sum2), 0); 63 | #endif 64 | } 65 | 66 | /* NEON version of WebRtcSpl_CrossCorrelation() for ARM32/64 platforms. */ 67 | void WebRtcSpl_CrossCorrelationNeon(int32_t* cross_correlation, 68 | const int16_t* seq1, 69 | const int16_t* seq2, 70 | size_t dim_seq, 71 | size_t dim_cross_correlation, 72 | int right_shifts, 73 | int step_seq2) { 74 | size_t i = 0; 75 | 76 | for (i = 0; i < dim_cross_correlation; i++) { 77 | const int16_t* seq1_ptr = seq1; 78 | const int16_t* seq2_ptr = seq2 + (step_seq2 * i); 79 | 80 | DotProductWithScaleNeon(cross_correlation, 81 | seq1_ptr, 82 | seq2_ptr, 83 | dim_seq, 84 | right_shifts); 85 | cross_correlation++; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/common_audio/vad/webrtc_vad.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #include "common_audio/vad/include/webrtc_vad.h" 12 | 13 | #include 14 | #include 15 | 16 | #include "common_audio/signal_processing/include/signal_processing_library.h" 17 | #include "common_audio/vad/vad_core.h" 18 | #include "typedefs.h" // NOLINT(build/include) 19 | 20 | static const int kInitCheck = 42; 21 | static const int kValidRates[] = { 8000, 16000, 32000, 48000 }; 22 | static const size_t kRatesSize = sizeof(kValidRates) / sizeof(*kValidRates); 23 | static const int kMaxFrameLengthMs = 30; 24 | 25 | VadInst* WebRtcVad_Create() { 26 | VadInstT* self = (VadInstT*)malloc(sizeof(VadInstT)); 27 | 28 | WebRtcSpl_Init(); 29 | self->init_flag = 0; 30 | 31 | return (VadInst*)self; 32 | } 33 | 34 | void WebRtcVad_Free(VadInst* handle) { 35 | free(handle); 36 | } 37 | 38 | // TODO(bjornv): Move WebRtcVad_InitCore() code here. 39 | int WebRtcVad_Init(VadInst* handle) { 40 | // Initialize the core VAD component. 41 | return WebRtcVad_InitCore((VadInstT*) handle); 42 | } 43 | 44 | // TODO(bjornv): Move WebRtcVad_set_mode_core() code here. 45 | int WebRtcVad_set_mode(VadInst* handle, int mode) { 46 | VadInstT* self = (VadInstT*) handle; 47 | 48 | if (handle == NULL) { 49 | return -1; 50 | } 51 | if (self->init_flag != kInitCheck) { 52 | return -1; 53 | } 54 | 55 | return WebRtcVad_set_mode_core(self, mode); 56 | } 57 | 58 | int WebRtcVad_Process(VadInst* handle, int fs, const int16_t* audio_frame, 59 | size_t frame_length) { 60 | int vad = -1; 61 | VadInstT* self = (VadInstT*) handle; 62 | 63 | if (handle == NULL) { 64 | return -1; 65 | } 66 | 67 | if (self->init_flag != kInitCheck) { 68 | return -1; 69 | } 70 | if (audio_frame == NULL) { 71 | return -1; 72 | } 73 | if (WebRtcVad_ValidRateAndFrameLength(fs, frame_length) != 0) { 74 | return -1; 75 | } 76 | 77 | if (fs == 48000) { 78 | vad = WebRtcVad_CalcVad48khz(self, audio_frame, frame_length); 79 | } else if (fs == 32000) { 80 | vad = WebRtcVad_CalcVad32khz(self, audio_frame, frame_length); 81 | } else if (fs == 16000) { 82 | vad = WebRtcVad_CalcVad16khz(self, audio_frame, frame_length); 83 | } else if (fs == 8000) { 84 | vad = WebRtcVad_CalcVad8khz(self, audio_frame, frame_length); 85 | } 86 | 87 | if (vad > 0) { 88 | vad = 1; 89 | } 90 | return vad; 91 | } 92 | 93 | int WebRtcVad_ValidRateAndFrameLength(int rate, size_t frame_length) { 94 | int return_value = -1; 95 | size_t i; 96 | int valid_length_ms; 97 | size_t valid_length; 98 | 99 | // We only allow 10, 20 or 30 ms frames. Loop through valid frame rates and 100 | // see if we have a matching pair. 101 | for (i = 0; i < kRatesSize; i++) { 102 | if (kValidRates[i] == rate) { 103 | for (valid_length_ms = 10; valid_length_ms <= kMaxFrameLengthMs; 104 | valid_length_ms += 10) { 105 | valid_length = (size_t)(kValidRates[i] / 1000 * valid_length_ms); 106 | if (frame_length == valid_length) { 107 | return_value = 0; 108 | break; 109 | } 110 | } 111 | break; 112 | } 113 | } 114 | 115 | return return_value; 116 | } 117 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/rtc_base/checks.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006 The WebRTC Project Authors. All rights reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | // Most of this was borrowed (with minor modifications) from V8's and Chromium's 12 | // src/base/logging.cc. 13 | 14 | #include 15 | #include 16 | #include 17 | //added by me 18 | #include "typedefs.h" 19 | #if defined(WEBRTC_ANDROID) 20 | #define RTC_LOG_TAG_ANDROID "rtc" 21 | #include // NOLINT 22 | #endif 23 | 24 | #if defined(WEBRTC_WIN) 25 | #include 26 | #endif 27 | 28 | #if defined(WEBRTC_WIN) 29 | #define LAST_SYSTEM_ERROR (::GetLastError()) 30 | #elif defined(__native_client__) && __native_client__ 31 | #define LAST_SYSTEM_ERROR (0) 32 | #elif defined(WEBRTC_POSIX) 33 | #include 34 | #define LAST_SYSTEM_ERROR (errno) 35 | #endif // WEBRTC_WIN 36 | 37 | #include "rtc_base/checks.h" 38 | #if defined(_MSC_VER) 39 | // Warning C4722: destructor never returns, potential memory leak. 40 | // FatalMessage's dtor very intentionally aborts. 41 | #pragma warning(disable:4722) 42 | #endif 43 | 44 | namespace rtc { 45 | namespace { 46 | 47 | void VPrintError(const char* format, va_list args) { 48 | #if defined(WEBRTC_ANDROID) 49 | __android_log_vprint(ANDROID_LOG_ERROR, RTC_LOG_TAG_ANDROID, format, args); 50 | #else 51 | vfprintf(stderr, format, args); 52 | #endif 53 | } 54 | 55 | #if defined(__GNUC__) 56 | void PrintError(const char* format, ...) 57 | __attribute__((__format__(__printf__, 1, 2))); 58 | #endif 59 | 60 | void PrintError(const char* format, ...) { 61 | va_list args; 62 | va_start(args, format); 63 | VPrintError(format, args); 64 | va_end(args); 65 | } 66 | 67 | } // namespace 68 | 69 | FatalMessage::FatalMessage(const char* file, int line) { 70 | Init(file, line); 71 | } 72 | 73 | FatalMessage::FatalMessage(const char* file, int line, std::string* result) { 74 | Init(file, line); 75 | stream_ << "Check failed: " << *result << std::endl << "# "; 76 | delete result; 77 | } 78 | 79 | NO_RETURN FatalMessage::~FatalMessage() { 80 | fflush(stdout); 81 | fflush(stderr); 82 | stream_ << std::endl << "#" << std::endl; 83 | PrintError("%s", stream_.str().c_str()); 84 | fflush(stderr); 85 | abort(); 86 | } 87 | 88 | void FatalMessage::Init(const char* file, int line) { 89 | stream_ << std::endl 90 | << std::endl 91 | << "#" << std::endl 92 | << "# Fatal error in " << file << ", line " << line << std::endl 93 | << "# last system error: " << LAST_SYSTEM_ERROR << std::endl 94 | << "# "; 95 | } 96 | 97 | // MSVC doesn't like complex extern templates and DLLs. 98 | #if !defined(COMPILER_MSVC) 99 | // Explicit instantiations for commonly used comparisons. 100 | template std::string* MakeCheckOpString( 101 | const int&, const int&, const char* names); 102 | template std::string* MakeCheckOpString( 103 | const unsigned long&, const unsigned long&, const char* names); 104 | template std::string* MakeCheckOpString( 105 | const unsigned long&, const unsigned int&, const char* names); 106 | template std::string* MakeCheckOpString( 107 | const unsigned int&, const unsigned long&, const char* names); 108 | template std::string* MakeCheckOpString( 109 | const std::string&, const std::string&, const char* name); 110 | #endif 111 | 112 | } // namespace rtc 113 | 114 | // Function to call from the C version of the RTC_CHECK and RTC_DCHECK macros. 115 | NO_RETURN void rtc_FatalMessage(const char* file, int line, const char* msg) { 116 | rtc::FatalMessage(file, line).stream() << msg; 117 | } 118 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/common_audio/signal_processing/include/spl_inl_armv7.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | 12 | /* This header file includes the inline functions for ARM processors in 13 | * the fix point signal processing library. 14 | */ 15 | 16 | #ifndef COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_SPL_INL_ARMV7_H_ 17 | #define COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_SPL_INL_ARMV7_H_ 18 | 19 | /* TODO(kma): Replace some assembly code with GCC intrinsics 20 | * (e.g. __builtin_clz). 21 | */ 22 | 23 | /* This function produces result that is not bit exact with that by the generic 24 | * C version in some cases, although the former is at least as accurate as the 25 | * later. 26 | */ 27 | static __inline int32_t WEBRTC_SPL_MUL_16_32_RSFT16(int16_t a, int32_t b) { 28 | int32_t tmp = 0; 29 | __asm __volatile ("smulwb %0, %1, %2":"=r"(tmp):"r"(b), "r"(a)); 30 | return tmp; 31 | } 32 | 33 | static __inline int32_t WEBRTC_SPL_MUL_16_16(int16_t a, int16_t b) { 34 | int32_t tmp = 0; 35 | __asm __volatile ("smulbb %0, %1, %2":"=r"(tmp):"r"(a), "r"(b)); 36 | return tmp; 37 | } 38 | 39 | // TODO(kma): add unit test. 40 | static __inline int32_t WebRtc_MulAccumW16(int16_t a, int16_t b, int32_t c) { 41 | int32_t tmp = 0; 42 | __asm __volatile ("smlabb %0, %1, %2, %3":"=r"(tmp):"r"(a), "r"(b), "r"(c)); 43 | return tmp; 44 | } 45 | 46 | static __inline int16_t WebRtcSpl_AddSatW16(int16_t a, int16_t b) { 47 | int32_t s_sum = 0; 48 | 49 | __asm __volatile ("qadd16 %0, %1, %2":"=r"(s_sum):"r"(a), "r"(b)); 50 | 51 | return (int16_t) s_sum; 52 | } 53 | 54 | static __inline int32_t WebRtcSpl_AddSatW32(int32_t l_var1, int32_t l_var2) { 55 | int32_t l_sum = 0; 56 | 57 | __asm __volatile ("qadd %0, %1, %2":"=r"(l_sum):"r"(l_var1), "r"(l_var2)); 58 | 59 | return l_sum; 60 | } 61 | 62 | static __inline int32_t WebRtcSpl_SubSatW32(int32_t l_var1, int32_t l_var2) { 63 | int32_t l_sub = 0; 64 | 65 | __asm __volatile ("qsub %0, %1, %2":"=r"(l_sub):"r"(l_var1), "r"(l_var2)); 66 | 67 | return l_sub; 68 | } 69 | 70 | static __inline int16_t WebRtcSpl_SubSatW16(int16_t var1, int16_t var2) { 71 | int32_t s_sub = 0; 72 | 73 | __asm __volatile ("qsub16 %0, %1, %2":"=r"(s_sub):"r"(var1), "r"(var2)); 74 | 75 | return (int16_t)s_sub; 76 | } 77 | 78 | static __inline int16_t WebRtcSpl_GetSizeInBits(uint32_t n) { 79 | int32_t tmp = 0; 80 | 81 | __asm __volatile ("clz %0, %1":"=r"(tmp):"r"(n)); 82 | 83 | return (int16_t)(32 - tmp); 84 | } 85 | 86 | static __inline int16_t WebRtcSpl_NormW32(int32_t a) { 87 | int32_t tmp = 0; 88 | 89 | if (a == 0) { 90 | return 0; 91 | } else if (a < 0) { 92 | a ^= 0xFFFFFFFF; 93 | } 94 | 95 | __asm __volatile ("clz %0, %1":"=r"(tmp):"r"(a)); 96 | 97 | return (int16_t)(tmp - 1); 98 | } 99 | 100 | static __inline int16_t WebRtcSpl_NormU32(uint32_t a) { 101 | int tmp = 0; 102 | 103 | if (a == 0) return 0; 104 | 105 | __asm __volatile ("clz %0, %1":"=r"(tmp):"r"(a)); 106 | 107 | return (int16_t)tmp; 108 | } 109 | 110 | static __inline int16_t WebRtcSpl_NormW16(int16_t a) { 111 | int32_t tmp = 0; 112 | int32_t a_32 = a; 113 | 114 | if (a_32 == 0) { 115 | return 0; 116 | } else if (a_32 < 0) { 117 | a_32 ^= 0xFFFFFFFF; 118 | } 119 | 120 | __asm __volatile ("clz %0, %1":"=r"(tmp):"r"(a_32)); 121 | 122 | return (int16_t)(tmp - 17); 123 | } 124 | 125 | // TODO(kma): add unit test. 126 | static __inline int16_t WebRtcSpl_SatW32ToW16(int32_t value32) { 127 | int32_t out = 0; 128 | 129 | __asm __volatile ("ssat %0, #16, %1" : "=r"(out) : "r"(value32)); 130 | 131 | return (int16_t)out; 132 | } 133 | 134 | #endif // COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_SPL_INL_ARMV7_H_ 135 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/rtc_base/sanitizer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 The WebRTC Project Authors. All rights reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef RTC_BASE_SANITIZER_H_ 12 | #define RTC_BASE_SANITIZER_H_ 13 | 14 | #include // for size_t 15 | 16 | #if defined(__has_feature) 17 | #if __has_feature(address_sanitizer) 18 | #define RTC_HAS_ASAN 1 19 | #endif 20 | #if __has_feature(memory_sanitizer) 21 | #define RTC_HAS_MSAN 1 22 | #endif 23 | #endif 24 | #ifndef RTC_HAS_ASAN 25 | #define RTC_HAS_ASAN 0 26 | #endif 27 | #ifndef RTC_HAS_MSAN 28 | #define RTC_HAS_MSAN 0 29 | #endif 30 | 31 | #if RTC_HAS_ASAN 32 | #include 33 | #endif 34 | #if RTC_HAS_MSAN 35 | #include 36 | #endif 37 | 38 | #ifdef __has_attribute 39 | #if __has_attribute(no_sanitize) 40 | #define RTC_NO_SANITIZE(what) __attribute__((no_sanitize(what))) 41 | #endif 42 | #endif 43 | #ifndef RTC_NO_SANITIZE 44 | #define RTC_NO_SANITIZE(what) 45 | #endif 46 | 47 | // Ask ASan to mark the memory range [ptr, ptr + element_size * num_elements) 48 | // as being unaddressable, so that reads and writes are not allowed. ASan may 49 | // narrow the range to the nearest alignment boundaries. 50 | static inline void rtc_AsanPoison(const volatile void* ptr, 51 | size_t element_size, 52 | size_t num_elements) { 53 | #if RTC_HAS_ASAN 54 | ASAN_POISON_MEMORY_REGION(ptr, element_size * num_elements); 55 | #endif 56 | } 57 | 58 | // Ask ASan to mark the memory range [ptr, ptr + element_size * num_elements) 59 | // as being addressable, so that reads and writes are allowed. ASan may widen 60 | // the range to the nearest alignment boundaries. 61 | static inline void rtc_AsanUnpoison(const volatile void* ptr, 62 | size_t element_size, 63 | size_t num_elements) { 64 | #if RTC_HAS_ASAN 65 | ASAN_UNPOISON_MEMORY_REGION(ptr, element_size * num_elements); 66 | #endif 67 | } 68 | 69 | // Ask MSan to mark the memory range [ptr, ptr + element_size * num_elements) 70 | // as being uninitialized. 71 | static inline void rtc_MsanMarkUninitialized(const volatile void* ptr, 72 | size_t element_size, 73 | size_t num_elements) { 74 | #if RTC_HAS_MSAN 75 | __msan_poison(ptr, element_size * num_elements); 76 | #endif 77 | } 78 | 79 | // Force an MSan check (if any bits in the memory range [ptr, ptr + 80 | // element_size * num_elements) are uninitialized the call will crash with an 81 | // MSan report). 82 | static inline void rtc_MsanCheckInitialized(const volatile void* ptr, 83 | size_t element_size, 84 | size_t num_elements) { 85 | #if RTC_HAS_MSAN 86 | __msan_check_mem_is_initialized(ptr, element_size * num_elements); 87 | #endif 88 | } 89 | 90 | #ifdef __cplusplus 91 | 92 | namespace rtc { 93 | 94 | template 95 | inline void AsanPoison(const T& mem) { 96 | rtc_AsanPoison(mem.data(), sizeof(mem.data()[0]), mem.size()); 97 | } 98 | 99 | template 100 | inline void AsanUnpoison(const T& mem) { 101 | rtc_AsanUnpoison(mem.data(), sizeof(mem.data()[0]), mem.size()); 102 | } 103 | 104 | template 105 | inline void MsanMarkUninitialized(const T& mem) { 106 | rtc_MsanMarkUninitialized(mem.data(), sizeof(mem.data()[0]), mem.size()); 107 | } 108 | 109 | template 110 | inline void MsanCheckInitialized(const T& mem) { 111 | rtc_MsanCheckInitialized(mem.data(), sizeof(mem.data()[0]), mem.size()); 112 | } 113 | 114 | } // namespace rtc 115 | 116 | #endif // __cplusplus 117 | 118 | #endif // RTC_BASE_SANITIZER_H_ 119 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/common_audio/signal_processing/division_operations.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | 12 | /* 13 | * This file contains implementations of the divisions 14 | * WebRtcSpl_DivU32U16() 15 | * WebRtcSpl_DivW32W16() 16 | * WebRtcSpl_DivW32W16ResW16() 17 | * WebRtcSpl_DivResultInQ31() 18 | * WebRtcSpl_DivW32HiLow() 19 | * 20 | * The description header can be found in signal_processing_library.h 21 | * 22 | */ 23 | 24 | #include "common_audio/signal_processing/include/signal_processing_library.h" 25 | #include "rtc_base/sanitizer.h" 26 | 27 | uint32_t WebRtcSpl_DivU32U16(uint32_t num, uint16_t den) 28 | { 29 | // Guard against division with 0 30 | if (den != 0) 31 | { 32 | return (uint32_t)(num / den); 33 | } else 34 | { 35 | return (uint32_t)0xFFFFFFFF; 36 | } 37 | } 38 | 39 | int32_t WebRtcSpl_DivW32W16(int32_t num, int16_t den) 40 | { 41 | // Guard against division with 0 42 | if (den != 0) 43 | { 44 | return (int32_t)(num / den); 45 | } else 46 | { 47 | return (int32_t)0x7FFFFFFF; 48 | } 49 | } 50 | 51 | int16_t WebRtcSpl_DivW32W16ResW16(int32_t num, int16_t den) 52 | { 53 | // Guard against division with 0 54 | if (den != 0) 55 | { 56 | return (int16_t)(num / den); 57 | } else 58 | { 59 | return (int16_t)0x7FFF; 60 | } 61 | } 62 | 63 | int32_t WebRtcSpl_DivResultInQ31(int32_t num, int32_t den) 64 | { 65 | int32_t L_num = num; 66 | int32_t L_den = den; 67 | int32_t div = 0; 68 | int k = 31; 69 | int change_sign = 0; 70 | 71 | if (num == 0) 72 | return 0; 73 | 74 | if (num < 0) 75 | { 76 | change_sign++; 77 | L_num = -num; 78 | } 79 | if (den < 0) 80 | { 81 | change_sign++; 82 | L_den = -den; 83 | } 84 | while (k--) 85 | { 86 | div <<= 1; 87 | L_num <<= 1; 88 | if (L_num >= L_den) 89 | { 90 | L_num -= L_den; 91 | div++; 92 | } 93 | } 94 | if (change_sign == 1) 95 | { 96 | div = -div; 97 | } 98 | return div; 99 | } 100 | 101 | int32_t RTC_NO_SANITIZE("signed-integer-overflow") // bugs.webrtc.org/5486 102 | WebRtcSpl_DivW32HiLow(int32_t num, int16_t den_hi, int16_t den_low) 103 | { 104 | int16_t approx, tmp_hi, tmp_low, num_hi, num_low; 105 | int32_t tmpW32; 106 | 107 | approx = (int16_t)WebRtcSpl_DivW32W16((int32_t)0x1FFFFFFF, den_hi); 108 | // result in Q14 (Note: 3FFFFFFF = 0.5 in Q30) 109 | 110 | // tmpW32 = 1/den = approx * (2.0 - den * approx) (in Q30) 111 | tmpW32 = (den_hi * approx << 1) + ((den_low * approx >> 15) << 1); 112 | // tmpW32 = den * approx 113 | 114 | tmpW32 = (int32_t)0x7fffffffL - tmpW32; // result in Q30 (tmpW32 = 2.0-(den*approx)) 115 | // UBSan: 2147483647 - -2 cannot be represented in type 'int' 116 | 117 | // Store tmpW32 in hi and low format 118 | tmp_hi = (int16_t)(tmpW32 >> 16); 119 | tmp_low = (int16_t)((tmpW32 - ((int32_t)tmp_hi << 16)) >> 1); 120 | 121 | // tmpW32 = 1/den in Q29 122 | tmpW32 = (tmp_hi * approx + (tmp_low * approx >> 15)) << 1; 123 | 124 | // 1/den in hi and low format 125 | tmp_hi = (int16_t)(tmpW32 >> 16); 126 | tmp_low = (int16_t)((tmpW32 - ((int32_t)tmp_hi << 16)) >> 1); 127 | 128 | // Store num in hi and low format 129 | num_hi = (int16_t)(num >> 16); 130 | num_low = (int16_t)((num - ((int32_t)num_hi << 16)) >> 1); 131 | 132 | // num * (1/den) by 32 bit multiplication (result in Q28) 133 | 134 | tmpW32 = num_hi * tmp_hi + (num_hi * tmp_low >> 15) + 135 | (num_low * tmp_hi >> 15); 136 | 137 | // Put result in Q31 (convert from Q28) 138 | tmpW32 = WEBRTC_SPL_LSHIFT_W32(tmpW32, 3); 139 | 140 | return tmpW32; 141 | } 142 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/common_audio/vad/vad_core.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | 12 | /* 13 | * This header file includes the descriptions of the core VAD calls. 14 | */ 15 | 16 | #ifndef COMMON_AUDIO_VAD_VAD_CORE_H_ 17 | #define COMMON_AUDIO_VAD_VAD_CORE_H_ 18 | 19 | #include "common_audio/signal_processing/include/signal_processing_library.h" 20 | #include "typedefs.h" // NOLINT(build/include) 21 | 22 | enum { kNumChannels = 6 }; // Number of frequency bands (named channels). 23 | enum { kNumGaussians = 2 }; // Number of Gaussians per channel in the GMM. 24 | enum { kTableSize = kNumChannels * kNumGaussians }; 25 | enum { kMinEnergy = 10 }; // Minimum energy required to trigger audio signal. 26 | 27 | typedef struct VadInstT_ { 28 | int vad; 29 | int32_t downsampling_filter_states[4]; 30 | WebRtcSpl_State48khzTo8khz state_48_to_8; 31 | int16_t noise_means[kTableSize]; 32 | int16_t speech_means[kTableSize]; 33 | int16_t noise_stds[kTableSize]; 34 | int16_t speech_stds[kTableSize]; 35 | // TODO(bjornv): Change to |frame_count|. 36 | int32_t frame_counter; 37 | int16_t over_hang; // Over Hang 38 | int16_t num_of_speech; 39 | // TODO(bjornv): Change to |age_vector|. 40 | int16_t index_vector[16 * kNumChannels]; 41 | int16_t low_value_vector[16 * kNumChannels]; 42 | // TODO(bjornv): Change to |median|. 43 | int16_t mean_value[kNumChannels]; 44 | int16_t upper_state[5]; 45 | int16_t lower_state[5]; 46 | int16_t hp_filter_state[4]; 47 | int16_t over_hang_max_1[3]; 48 | int16_t over_hang_max_2[3]; 49 | int16_t individual[3]; 50 | int16_t total[3]; 51 | 52 | int init_flag; 53 | } VadInstT; 54 | 55 | // Initializes the core VAD component. The default aggressiveness mode is 56 | // controlled by |kDefaultMode| in vad_core.c. 57 | // 58 | // - self [i/o] : Instance that should be initialized 59 | // 60 | // returns : 0 (OK), -1 (null pointer in or if the default mode can't be 61 | // set) 62 | int WebRtcVad_InitCore(VadInstT* self); 63 | 64 | /**************************************************************************** 65 | * WebRtcVad_set_mode_core(...) 66 | * 67 | * This function changes the VAD settings 68 | * 69 | * Input: 70 | * - inst : VAD instance 71 | * - mode : Aggressiveness degree 72 | * 0 (High quality) - 3 (Highly aggressive) 73 | * 74 | * Output: 75 | * - inst : Changed instance 76 | * 77 | * Return value : 0 - Ok 78 | * -1 - Error 79 | */ 80 | 81 | int WebRtcVad_set_mode_core(VadInstT* self, int mode); 82 | 83 | /**************************************************************************** 84 | * WebRtcVad_CalcVad48khz(...) 85 | * WebRtcVad_CalcVad32khz(...) 86 | * WebRtcVad_CalcVad16khz(...) 87 | * WebRtcVad_CalcVad8khz(...) 88 | * 89 | * Calculate probability for active speech and make VAD decision. 90 | * 91 | * Input: 92 | * - inst : Instance that should be initialized 93 | * - speech_frame : Input speech frame 94 | * - frame_length : Number of input samples 95 | * 96 | * Output: 97 | * - inst : Updated filter states etc. 98 | * 99 | * Return value : VAD decision 100 | * 0 - No active speech 101 | * 1-6 - Active speech 102 | */ 103 | int WebRtcVad_CalcVad48khz(VadInstT* inst, const int16_t* speech_frame, 104 | size_t frame_length); 105 | int WebRtcVad_CalcVad32khz(VadInstT* inst, const int16_t* speech_frame, 106 | size_t frame_length); 107 | int WebRtcVad_CalcVad16khz(VadInstT* inst, const int16_t* speech_frame, 108 | size_t frame_length); 109 | int WebRtcVad_CalcVad8khz(VadInstT* inst, const int16_t* speech_frame, 110 | size_t frame_length); 111 | 112 | #endif // COMMON_AUDIO_VAD_VAD_CORE_H_ 113 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/typedefs_bck.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | // This file contains platform-specific typedefs and defines. 12 | // Much of it is derived from Chromium's build/build_config.h. 13 | 14 | #ifndef TYPEDEFS_H_ 15 | #define TYPEDEFS_H_ 16 | 17 | // 参考BUILD.gn 以linux为例定义如下几个变量 18 | #define WEBRTC_POSIX 19 | #define WEBRTC_LINUX 20 | 21 | // Processor architecture detection. For more info on what's defined, see: 22 | // http://msdn.microsoft.com/en-us/library/b0084kay.aspx 23 | // http://www.agner.org/optimize/calling_conventions.pdf 24 | // or with gcc, run: "echo | gcc -E -dM -" 25 | #if defined(_M_X64) || defined(__x86_64__) 26 | #define WEBRTC_ARCH_X86_FAMILY 27 | #define WEBRTC_ARCH_X86_64 28 | #define WEBRTC_ARCH_64_BITS 29 | #define WEBRTC_ARCH_LITTLE_ENDIAN 30 | #elif defined(__aarch64__) 31 | #define WEBRTC_ARCH_ARM_FAMILY 32 | #define WEBRTC_ARCH_64_BITS 33 | #define WEBRTC_ARCH_LITTLE_ENDIAN 34 | #elif defined(_M_IX86) || defined(__i386__) 35 | #define WEBRTC_ARCH_X86_FAMILY 36 | #define WEBRTC_ARCH_X86 37 | #define WEBRTC_ARCH_32_BITS 38 | #define WEBRTC_ARCH_LITTLE_ENDIAN 39 | #elif defined(__ARMEL__) 40 | #define WEBRTC_ARCH_ARM_FAMILY 41 | #define WEBRTC_ARCH_32_BITS 42 | #define WEBRTC_ARCH_LITTLE_ENDIAN 43 | #elif defined(__MIPSEL__) 44 | #define WEBRTC_ARCH_MIPS_FAMILY 45 | #if defined(__LP64__) 46 | #define WEBRTC_ARCH_64_BITS 47 | #else 48 | #define WEBRTC_ARCH_32_BITS 49 | #endif 50 | #define WEBRTC_ARCH_LITTLE_ENDIAN 51 | #elif defined(__pnacl__) 52 | #define WEBRTC_ARCH_32_BITS 53 | #define WEBRTC_ARCH_LITTLE_ENDIAN 54 | #else 55 | #error Please add support for your architecture in typedefs.h 56 | #endif 57 | 58 | #if !(defined(WEBRTC_ARCH_LITTLE_ENDIAN) ^ defined(WEBRTC_ARCH_BIG_ENDIAN)) 59 | #error Define either WEBRTC_ARCH_LITTLE_ENDIAN or WEBRTC_ARCH_BIG_ENDIAN 60 | #endif 61 | 62 | // TODO(zhongwei.yao): WEBRTC_CPU_DETECTION is only used in one place; we should 63 | // probably just remove it. 64 | #if (defined(WEBRTC_ARCH_X86_FAMILY) && !defined(__SSE2__)) 65 | #define WEBRTC_CPU_DETECTION 66 | #endif 67 | 68 | #include 69 | 70 | // Annotate a function indicating the caller must examine the return value. 71 | // Use like: 72 | // int foo() RTC_WARN_UNUSED_RESULT; 73 | // To explicitly ignore a result, cast to void. 74 | // TODO(kwiberg): Remove when we can use [[nodiscard]] from C++17. 75 | #if defined(__clang__) 76 | #define RTC_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__)) 77 | #elif defined(__GNUC__) 78 | // gcc has a __warn_unused_result__ attribute, but you can't quiet it by 79 | // casting to void, so we don't use it. 80 | #define RTC_WARN_UNUSED_RESULT 81 | #else 82 | #define RTC_WARN_UNUSED_RESULT 83 | #endif 84 | 85 | // Put after a variable that might not be used, to prevent compiler warnings: 86 | // int result ATTRIBUTE_UNUSED = DoSomething(); 87 | // assert(result == 17); 88 | // Deprecated since it only works with GCC & clang. See RTC_UNUSED below. 89 | // TODO(terelius): Remove. 90 | #ifndef ATTRIBUTE_UNUSED 91 | #if defined(__GNUC__) || defined(__clang__) 92 | #define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) 93 | #else 94 | #define ATTRIBUTE_UNUSED 95 | #endif 96 | #endif 97 | 98 | #ifndef NO_RETURN 99 | // Annotate a function that will not return control flow to the caller. 100 | #if defined(_MSC_VER) 101 | #define NO_RETURN __declspec(noreturn) 102 | #elif defined(__GNUC__) 103 | #define NO_RETURN __attribute__ ((__noreturn__)) 104 | #else 105 | #define NO_RETURN 106 | #endif 107 | #endif 108 | 109 | // Prevent the compiler from warning about an unused variable. For example: 110 | // int result = DoSomething(); 111 | // assert(result == 17); 112 | // RTC_UNUSED(result); 113 | // Note: In most cases it is better to remove the unused variable rather than 114 | // suppressing the compiler warning. 115 | #ifndef RTC_UNUSED 116 | #define RTC_UNUSED(x) static_cast(x) 117 | #endif // RTC_UNUSED 118 | 119 | #endif // TYPEDEFS_H_ 120 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/typedefs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | // This file contains platform-specific typedefs and defines. 12 | // Much of it is derived from Chromium's build/build_config.h. 13 | 14 | #ifndef TYPEDEFS_H_ 15 | #define TYPEDEFS_H_ 16 | 17 | // 参考BUILD.gn 以linux为例定义如下几个变量 18 | #define WEBRTC_POSIX 19 | #define WEBRTC_LINUX 20 | 21 | #define __MIPSEL__ 22 | 23 | // Processor architecture detection. For more info on what's defined, see: 24 | // http://msdn.microsoft.com/en-us/library/b0084kay.aspx 25 | // http://www.agner.org/optimize/calling_conventions.pdf 26 | // or with gcc, run: "echo | gcc -E -dM -" 27 | #if defined(_M_X64) || defined(__x86_64__) 28 | #define WEBRTC_ARCH_X86_FAMILY 29 | #define WEBRTC_ARCH_X86_64 30 | #define WEBRTC_ARCH_64_BITS 31 | #define WEBRTC_ARCH_LITTLE_ENDIAN 32 | #elif defined(__aarch64__) 33 | #define WEBRTC_ARCH_ARM_FAMILY 34 | #define WEBRTC_ARCH_64_BITS 35 | #define WEBRTC_ARCH_LITTLE_ENDIAN 36 | #elif defined(_M_IX86) || defined(__i386__) 37 | #define WEBRTC_ARCH_X86_FAMILY 38 | #define WEBRTC_ARCH_X86 39 | #define WEBRTC_ARCH_32_BITS 40 | #define WEBRTC_ARCH_LITTLE_ENDIAN 41 | #elif defined(__ARMEL__) 42 | #define WEBRTC_ARCH_ARM_FAMILY 43 | #define WEBRTC_ARCH_32_BITS 44 | #define WEBRTC_ARCH_LITTLE_ENDIAN 45 | #elif defined(__MIPSEL__) 46 | #define WEBRTC_ARCH_MIPS_FAMILY 47 | #if defined(__LP64__) 48 | #define WEBRTC_ARCH_64_BITS 49 | #else 50 | #define WEBRTC_ARCH_32_BITS 51 | #endif 52 | #define WEBRTC_ARCH_LITTLE_ENDIAN 53 | #elif defined(__pnacl__) 54 | #define WEBRTC_ARCH_32_BITS 55 | #define WEBRTC_ARCH_LITTLE_ENDIAN 56 | #else 57 | #error Please add support for your architecture in typedefs.h 58 | #endif 59 | 60 | #if !(defined(WEBRTC_ARCH_LITTLE_ENDIAN) ^ defined(WEBRTC_ARCH_BIG_ENDIAN)) 61 | #error Define either WEBRTC_ARCH_LITTLE_ENDIAN or WEBRTC_ARCH_BIG_ENDIAN 62 | #endif 63 | 64 | // TODO(zhongwei.yao): WEBRTC_CPU_DETECTION is only used in one place; we should 65 | // probably just remove it. 66 | #if (defined(WEBRTC_ARCH_X86_FAMILY) && !defined(__SSE2__)) 67 | #define WEBRTC_CPU_DETECTION 68 | #endif 69 | 70 | #include 71 | 72 | // Annotate a function indicating the caller must examine the return value. 73 | // Use like: 74 | // int foo() RTC_WARN_UNUSED_RESULT; 75 | // To explicitly ignore a result, cast to void. 76 | // TODO(kwiberg): Remove when we can use [[nodiscard]] from C++17. 77 | #if defined(__clang__) 78 | #define RTC_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__)) 79 | #elif defined(__GNUC__) 80 | // gcc has a __warn_unused_result__ attribute, but you can't quiet it by 81 | // casting to void, so we don't use it. 82 | #define RTC_WARN_UNUSED_RESULT 83 | #else 84 | #define RTC_WARN_UNUSED_RESULT 85 | #endif 86 | 87 | // Put after a variable that might not be used, to prevent compiler warnings: 88 | // int result ATTRIBUTE_UNUSED = DoSomething(); 89 | // assert(result == 17); 90 | // Deprecated since it only works with GCC & clang. See RTC_UNUSED below. 91 | // TODO(terelius): Remove. 92 | #ifndef ATTRIBUTE_UNUSED 93 | #if defined(__GNUC__) || defined(__clang__) 94 | #define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) 95 | #else 96 | #define ATTRIBUTE_UNUSED 97 | #endif 98 | #endif 99 | 100 | #ifndef NO_RETURN 101 | // Annotate a function that will not return control flow to the caller. 102 | #if defined(_MSC_VER) 103 | #define NO_RETURN __declspec(noreturn) 104 | #elif defined(__GNUC__) 105 | #define NO_RETURN __attribute__ ((__noreturn__)) 106 | #else 107 | #define NO_RETURN 108 | #endif 109 | #endif 110 | 111 | // Prevent the compiler from warning about an unused variable. For example: 112 | // int result = DoSomething(); 113 | // assert(result == 17); 114 | // RTC_UNUSED(result); 115 | // Note: In most cases it is better to remove the unused variable rather than 116 | // suppressing the compiler warning. 117 | #ifndef RTC_UNUSED 118 | #define RTC_UNUSED(x) static_cast(x) 119 | #endif // RTC_UNUSED 120 | 121 | #endif // TYPEDEFS_H_ 122 | -------------------------------------------------------------------------------- /components/ac101_driver/uart.c: -------------------------------------------------------------------------------- 1 | #include "uart.h" 2 | #include "esp_err.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "freertos/FreeRTOS.h" 8 | #include "freertos/task.h" 9 | #include "esp_system.h" 10 | #include "nvs_flash.h" 11 | #include "driver/uart.h" 12 | #include "freertos/queue.h" 13 | #include "esp_log.h" 14 | #include "soc/uart_struct.h" 15 | #include "ctype.h" 16 | #include "esp_ota_ops.h" 17 | #include "esp_wifi.h" 18 | #include "esp_event_loop.h" 19 | #include "apps/dhcpserver_options.h" 20 | #include "lwip/dns.h" 21 | #include "lwip/netif.h" 22 | 23 | #define ECHO_TEST_TXD (1) 24 | #define ECHO_TEST_RXD (3) 25 | #define ECHO_TEST_RTS (UART_PIN_NO_CHANGE) 26 | #define ECHO_TEST_CTS (UART_PIN_NO_CHANGE) 27 | 28 | #define BUF_SIZE (128) 29 | int uart_num = UART_NUM_0; 30 | static const char *TAG = "uart"; 31 | 32 | void ota_adress(uint8_t id, char *pPara); 33 | #define MAKE_AT_FUNCTION(NAME, TEST_FUNCTION, QUERY_FUNCTION, SETUP_FUNCTION, EXEC_FUNCTION) \ 34 | { \ 35 | (NAME), \ 36 | sizeof(NAME) - 1, \ 37 | (TEST_FUNCTION),\ 38 | (QUERY_FUNCTION), \ 39 | (SETUP_FUNCTION), \ 40 | (EXEC_FUNCTION), \ 41 | } 42 | 43 | static at_funcationType at_custom_cmd[] = { 44 | MAKE_AT_FUNCTION("+OTA", at_OTA, NULL, NULL, NULL), 45 | }; 46 | 47 | #define MAKE_AT_COUNT (sizeof(at_custom_cmd) / sizeof(at_funcationType)) 48 | 49 | void print_err() { 50 | printf("error\r\n"); 51 | } 52 | //检测是否是字符串并且去除引号 53 | bool get_str(char *str) { 54 | if (str == NULL) 55 | return false; 56 | if ((str[0] == '"') && (str[strlen(str) - 1] = '"')) { 57 | 58 | for (int i = 0; i < strlen(str) - 1; i++) { 59 | str[i] = str[i + 1]; 60 | } 61 | str[strlen(str) - 2] = 0; 62 | printf("string=%s\r\n", str); 63 | return true; 64 | } else { 65 | return false; 66 | } 67 | 68 | } 69 | 70 | /*从字符串的中间截取n个字符*/ 71 | char mid(char *dst, char *src, int n, int m) /*n为长度,m为位置*/ 72 | { 73 | char *p = src; 74 | char *q = dst; 75 | int len = strlen(src); 76 | if (n > len) 77 | n = len - m; /*从第m个到最后*/ 78 | if (m < 0) 79 | m = 0; /*从第一个开始*/ 80 | if (m > len) 81 | return NULL; 82 | p += m; 83 | while (n--) 84 | *(q++) = *(p++); 85 | *(q++) = '\0'; /*有必要吗?很有必要*/ 86 | return dst; 87 | } 88 | 89 | 90 | void at_OTA(uint8_t id) 91 | { 92 | printf("PARTION_SET_OK\r\n"); 93 | } 94 | 95 | void echo_task() { 96 | /* Configure parameters of an UART driver, 97 | * communication pins and install the driver */ 98 | uart_config_t uart_config = { .baud_rate = 115200, .data_bits = 99 | UART_DATA_8_BITS, .parity = UART_PARITY_DISABLE, .stop_bits = 100 | UART_STOP_BITS_1, .flow_ctrl = UART_HW_FLOWCTRL_DISABLE }; 101 | uart_param_config(uart_num, &uart_config); 102 | uart_set_pin(uart_num, ECHO_TEST_TXD, ECHO_TEST_RXD, ECHO_TEST_RTS, 103 | ECHO_TEST_CTS); 104 | uart_driver_install(uart_num, BUF_SIZE * 2, 0, 0, NULL, 0); 105 | 106 | uint8_t *data = (uint8_t *) malloc(BUF_SIZE); 107 | while (1) { 108 | // Read data from the UART 109 | int len = uart_read_bytes(uart_num, data, BUF_SIZE, 110 | 20 / portTICK_RATE_MS); 111 | // Write data back to the UART 112 | if (len > 0) { 113 | uart_write_bytes(uart_num, (const char *) data, len); 114 | at_recvTask((const char*) data); 115 | } 116 | memset(data, 0, BUF_SIZE); 117 | } 118 | } 119 | 120 | void sendStr(char *str) { 121 | uart_write_bytes(uart_num, (const char*) str, strlen(str)); 122 | } 123 | 124 | 125 | void at_recvTask(char *str) { 126 | if ((str[strlen(str) - 1] == '\n') && (str[strlen(str) - 2] == '\r')) { 127 | if ((memcmp(str, "AT", 2) == 0)) { 128 | for (int i = 0; i < MAKE_AT_COUNT; i++) { 129 | if (strstr(str, at_custom_cmd[i].at_cmdName) != NULL) { 130 | if (str[2 + at_custom_cmd[i].at_cmdLen] == '=') { 131 | int len = 3 + at_custom_cmd[i].at_cmdLen; 132 | char *buf = (char *) malloc(64); 133 | mid(buf, str, strlen(str) - 2 - len, len); 134 | at_custom_cmd[i].at_setupCmd(123, buf); 135 | free(buf); 136 | return; 137 | } else if (str[2 + at_custom_cmd[i].at_cmdLen] != '=' 138 | && (str[2 + at_custom_cmd[i].at_cmdLen] != '?') 139 | && (at_custom_cmd[i].at_testCmd != NULL)) { 140 | at_custom_cmd[i].at_testCmd(132); 141 | return; 142 | } 143 | } 144 | } 145 | sendStr("error\r\n"); 146 | } else { 147 | sendStr("error\r\n"); 148 | } 149 | } else { 150 | sendStr("error\r\n"); 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/common_audio/signal_processing/include/real_fft.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_REAL_FFT_H_ 12 | #define COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_REAL_FFT_H_ 13 | 14 | #include "typedefs.h" // NOLINT(build/include) 15 | 16 | // For ComplexFFT(), the maximum fft order is 10; 17 | // for OpenMax FFT in ARM, it is 12; 18 | // WebRTC APM uses orders of only 7 and 8. 19 | enum {kMaxFFTOrder = 10}; 20 | 21 | struct RealFFT; 22 | 23 | #ifdef __cplusplus 24 | extern "C" { 25 | #endif 26 | 27 | struct RealFFT* WebRtcSpl_CreateRealFFT(int order); 28 | void WebRtcSpl_FreeRealFFT(struct RealFFT* self); 29 | 30 | // Compute an FFT for a real-valued signal of length of 2^order, 31 | // where 1 < order <= MAX_FFT_ORDER. Transform length is determined by the 32 | // specification structure, which must be initialized prior to calling the FFT 33 | // function with WebRtcSpl_CreateRealFFT(). 34 | // The relationship between the input and output sequences can 35 | // be expressed in terms of the DFT, i.e.: 36 | // x[n] = (2^(-scalefactor)/N) . SUM[k=0,...,N-1] X[k].e^(jnk.2.pi/N) 37 | // n=0,1,2,...N-1 38 | // N=2^order. 39 | // The conjugate-symmetric output sequence is represented using a CCS vector, 40 | // which is of length N+2, and is organized as follows: 41 | // Index: 0 1 2 3 4 5 . . . N-2 N-1 N N+1 42 | // Component: R0 0 R1 I1 R2 I2 . . . R[N/2-1] I[N/2-1] R[N/2] 0 43 | // where R[n] and I[n], respectively, denote the real and imaginary components 44 | // for FFT bin 'n'. Bins are numbered from 0 to N/2, where N is the FFT length. 45 | // Bin index 0 corresponds to the DC component, and bin index N/2 corresponds to 46 | // the foldover frequency. 47 | // 48 | // Input Arguments: 49 | // self - pointer to preallocated and initialized FFT specification structure. 50 | // real_data_in - the input signal. For an ARM Neon platform, it must be 51 | // aligned on a 32-byte boundary. 52 | // 53 | // Output Arguments: 54 | // complex_data_out - the output complex signal with (2^order + 2) 16-bit 55 | // elements. For an ARM Neon platform, it must be different 56 | // from real_data_in, and aligned on a 32-byte boundary. 57 | // 58 | // Return Value: 59 | // 0 - FFT calculation is successful. 60 | // -1 - Error with bad arguments (null pointers). 61 | int WebRtcSpl_RealForwardFFT(struct RealFFT* self, 62 | const int16_t* real_data_in, 63 | int16_t* complex_data_out); 64 | 65 | // Compute the inverse FFT for a conjugate-symmetric input sequence of length of 66 | // 2^order, where 1 < order <= MAX_FFT_ORDER. Transform length is determined by 67 | // the specification structure, which must be initialized prior to calling the 68 | // FFT function with WebRtcSpl_CreateRealFFT(). 69 | // For a transform of length M, the input sequence is represented using a packed 70 | // CCS vector of length M+2, which is explained in the comments for 71 | // WebRtcSpl_RealForwardFFTC above. 72 | // 73 | // Input Arguments: 74 | // self - pointer to preallocated and initialized FFT specification structure. 75 | // complex_data_in - the input complex signal with (2^order + 2) 16-bit 76 | // elements. For an ARM Neon platform, it must be aligned on 77 | // a 32-byte boundary. 78 | // 79 | // Output Arguments: 80 | // real_data_out - the output real signal. For an ARM Neon platform, it must 81 | // be different to complex_data_in, and aligned on a 32-byte 82 | // boundary. 83 | // 84 | // Return Value: 85 | // 0 or a positive number - a value that the elements in the |real_data_out| 86 | // should be shifted left with in order to get 87 | // correct physical values. 88 | // -1 - Error with bad arguments (null pointers). 89 | int WebRtcSpl_RealInverseFFT(struct RealFFT* self, 90 | const int16_t* complex_data_in, 91 | int16_t* real_data_out); 92 | 93 | #ifdef __cplusplus 94 | } 95 | #endif 96 | 97 | #endif // COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_REAL_FFT_H_ 98 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/rtc_base/type_traits.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 The WebRTC Project Authors. All rights reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef RTC_BASE_TYPE_TRAITS_H_ 12 | #define RTC_BASE_TYPE_TRAITS_H_ 13 | 14 | #include 15 | #include 16 | 17 | namespace rtc { 18 | 19 | // Determines if the given class has zero-argument .data() and .size() methods 20 | // whose return values are convertible to T* and size_t, respectively. 21 | template 22 | class HasDataAndSize { 23 | private: 24 | template < 25 | typename C, 26 | typename std::enable_if< 27 | std::is_convertible().data()), T*>::value && 28 | std::is_convertible().size()), 29 | std::size_t>::value>::type* = nullptr> 30 | static int Test(int); 31 | 32 | template 33 | static char Test(...); 34 | 35 | public: 36 | static constexpr bool value = std::is_same(0)), int>::value; 37 | }; 38 | 39 | namespace test_has_data_and_size { 40 | 41 | template 42 | struct Test1 { 43 | DR data(); 44 | SR size(); 45 | }; 46 | static_assert(HasDataAndSize, int>::value, ""); 47 | static_assert(HasDataAndSize, const int>::value, ""); 48 | static_assert(HasDataAndSize, const int>::value, ""); 49 | static_assert(!HasDataAndSize, int>::value, 50 | "implicit cast of const int* to int*"); 51 | static_assert(!HasDataAndSize, int>::value, 52 | "implicit cast of char* to int*"); 53 | 54 | struct Test2 { 55 | int* data; 56 | size_t size; 57 | }; 58 | static_assert(!HasDataAndSize::value, 59 | ".data and .size aren't functions"); 60 | 61 | struct Test3 { 62 | int* data(); 63 | }; 64 | static_assert(!HasDataAndSize::value, ".size() is missing"); 65 | 66 | class Test4 { 67 | int* data(); 68 | size_t size(); 69 | }; 70 | static_assert(!HasDataAndSize::value, 71 | ".data() and .size() are private"); 72 | 73 | } // namespace test_has_data_and_size 74 | 75 | namespace type_traits_impl { 76 | 77 | // Determines if the given type is an enum that converts implicitly to 78 | // an integral type. 79 | template 80 | struct IsIntEnum { 81 | private: 82 | // This overload is used if the type is an enum, and unary plus 83 | // compiles and turns it into an integral type. 84 | template ::value && 87 | std::is_integral())>::value>::type* = 88 | nullptr> 89 | static int Test(int); 90 | 91 | // Otherwise, this overload is used. 92 | template 93 | static char Test(...); 94 | 95 | public: 96 | static constexpr bool value = 97 | std::is_same::type>(0)), 98 | int>::value; 99 | }; 100 | 101 | } // namespace type_traits_impl 102 | 103 | // Determines if the given type is integral, or an enum that 104 | // converts implicitly to an integral type. 105 | template 106 | struct IsIntlike { 107 | private: 108 | using X = typename std::remove_reference::type; 109 | 110 | public: 111 | static constexpr bool value = 112 | std::is_integral::value || type_traits_impl::IsIntEnum::value; 113 | }; 114 | 115 | namespace test_enum_intlike { 116 | 117 | enum E1 { e1 }; 118 | enum { e2 }; 119 | enum class E3 { e3 }; 120 | struct S {}; 121 | 122 | static_assert(type_traits_impl::IsIntEnum::value, ""); 123 | static_assert(type_traits_impl::IsIntEnum::value, ""); 124 | static_assert(!type_traits_impl::IsIntEnum::value, ""); 125 | static_assert(!type_traits_impl::IsIntEnum::value, ""); 126 | static_assert(!type_traits_impl::IsIntEnum::value, ""); 127 | static_assert(!type_traits_impl::IsIntEnum::value, ""); 128 | 129 | static_assert(IsIntlike::value, ""); 130 | static_assert(IsIntlike::value, ""); 131 | static_assert(!IsIntlike::value, ""); 132 | static_assert(IsIntlike::value, ""); 133 | static_assert(!IsIntlike::value, ""); 134 | static_assert(!IsIntlike::value, ""); 135 | 136 | } // test_enum_intlike 137 | 138 | } // namespace rtc 139 | 140 | #endif // RTC_BASE_TYPE_TRAITS_H_ 141 | -------------------------------------------------------------------------------- /components/ac101_driver/DriverUtil.c: -------------------------------------------------------------------------------- 1 | /* 2 | * DriverUtil.c 3 | * 4 | * Created on: 2017.1.23 5 | * Author: Jack 6 | */ 7 | #include "driver/i2c.h" 8 | #include "freertos/FreeRTOS.h" 9 | #include "DriverUtil.h" 10 | 11 | const char *DU_TAG = "AC101"; 12 | 13 | #define WRITE_BIT I2C_MASTER_WRITE /*!< I2C master write */ 14 | #define READ_BIT I2C_MASTER_READ /*!< I2C master read */ 15 | #define ACK_CHECK_EN 0x1 /*!< I2C master will check ack from slave*/ 16 | #define ACK_CHECK_DIS 0x0 /*!< I2C master will not check ack from slave */ 17 | #define ACK_VAL 0x0 /*!< I2C ack value */ 18 | #define NACK_VAL 0x1 /*!< I2C nack value */ 19 | 20 | /* 21 | *I2C写一个字节 22 | */ 23 | uint8_t IIC_Write_One_Byte(uint8_t DevAddr, uint8_t RegAddr, uint8_t Data) { 24 | i2c_cmd_handle_t cmd = i2c_cmd_link_create(); 25 | 26 | int ret; 27 | 28 | ret = i2c_master_start(cmd); 29 | 30 | if (ret != ESP_OK) { 31 | ESP_LOGE(DU_TAG, "i2c_master_start failed! ret:%d", ret); 32 | return ret; 33 | } 34 | 35 | ret = i2c_master_write_byte(cmd, DevAddr & 0xFE, ACK_CHECK_EN); 36 | 37 | if (ret != ESP_OK) { 38 | ESP_LOGE(DU_TAG, "i2c_master_write_byte failed! ret:%d", ret); 39 | 40 | return ret; 41 | } 42 | 43 | //i2c_master_write_byte(cmd, DevAddr << 1 | WRITE_BIT, ACK_CHECK_EN); 44 | i2c_master_write_byte(cmd, RegAddr, ACK_CHECK_EN); 45 | 46 | if (ret != ESP_OK) { 47 | ESP_LOGE(DU_TAG, "i2c_master_write_byte failed 2! ret:%d", ret); 48 | 49 | return ret; 50 | } 51 | 52 | i2c_master_write_byte(cmd, Data, ACK_CHECK_EN); 53 | 54 | if (ret != ESP_OK) { 55 | ESP_LOGE(DU_TAG, "i2c_master_write_byte failed 3! ret:%d", ret); 56 | 57 | return ret; 58 | } 59 | 60 | ret = i2c_master_stop(cmd); 61 | 62 | if (ret != ESP_OK) { 63 | ESP_LOGE(DU_TAG, "i2c_master_stop failed! ret:%d", ret); 64 | 65 | return ret; 66 | } 67 | 68 | ret = i2c_master_cmd_begin(I2C_NUM_1, cmd, 1000 / portTICK_RATE_MS); 69 | 70 | if (ret != ESP_OK) { 71 | ESP_LOGE(DU_TAG, "i2c_master_cmd_begin failed! ret:%d", ret); 72 | 73 | return ret; 74 | } 75 | 76 | i2c_cmd_link_delete(cmd); 77 | return ESP_OK; 78 | } 79 | 80 | uint8_t IIC_Write_two_Bytes(uint8_t DevAddr, uint8_t RegAddr, uint16_t Data) { 81 | i2c_cmd_handle_t cmd = i2c_cmd_link_create(); 82 | int ret = i2c_master_start(cmd); 83 | if (ret != ESP_OK) { 84 | ESP_LOGE(DU_TAG, "i2c_master_start failed! ret:%d", ret); 85 | 86 | return ret; 87 | } 88 | 89 | ret = i2c_master_write_byte(cmd, DevAddr & 0xFE, ACK_CHECK_EN); 90 | 91 | if (ret != ESP_OK) { 92 | ESP_LOGE(DU_TAG, "i2c_master_write_byte failed! ret:%d", ret); 93 | 94 | return ret; 95 | } 96 | 97 | //i2c_master_write_byte(cmd, DevAddr << 1 | WRITE_BIT, ACK_CHECK_EN); 98 | i2c_master_write_byte(cmd, RegAddr, ACK_CHECK_EN); 99 | 100 | if (ret != ESP_OK) { 101 | ESP_LOGE(DU_TAG, "i2c_master_write_byte failed 2! ret:%d", ret); 102 | 103 | return ret; 104 | } 105 | 106 | //send Low data byte 107 | uint8_t High_Byte = Data >> 8; 108 | i2c_master_write_byte(cmd, High_Byte, ACK_CHECK_EN); 109 | if (ret != ESP_OK) { 110 | ESP_LOGE(DU_TAG, "i2c_master_write_byte failed 3! ret:%d", ret); 111 | return ret; 112 | } 113 | 114 | //send High data byte 115 | uint8_t Low_Byte = Data & 0x00ff; 116 | i2c_master_write_byte(cmd, Low_Byte, ACK_CHECK_EN); 117 | if (ret != ESP_OK) { 118 | ESP_LOGE(DU_TAG, "i2c_master_write_byte failed 3! ret:%d", ret); 119 | 120 | return ret; 121 | } 122 | ret = i2c_master_stop(cmd); 123 | 124 | if (ret != ESP_OK) { 125 | ESP_LOGE(DU_TAG, "i2c_master_stop failed! ret:%d", ret); 126 | 127 | return ret; 128 | } 129 | 130 | ret = i2c_master_cmd_begin(I2C_NUM_1, cmd, 1000 / portTICK_RATE_MS); 131 | 132 | if (ret != ESP_OK) { 133 | ESP_LOGE(DU_TAG, "i2c_master_cmd_begin failed! ret:%d", ret); 134 | 135 | return ret; 136 | } 137 | 138 | i2c_cmd_link_delete(cmd); 139 | return ESP_OK; 140 | } 141 | 142 | esp_err_t i2c_example_master_read_slave(uint8_t DevAddr, uint8_t reg,uint8_t* data_rd, size_t size) 143 | { 144 | if (size == 0) { 145 | return ESP_OK; 146 | } 147 | i2c_cmd_handle_t cmd = i2c_cmd_link_create(); 148 | i2c_master_start(cmd); 149 | i2c_master_write_byte(cmd, ( DevAddr << 1 ) | WRITE_BIT, ACK_CHECK_EN); 150 | i2c_master_write_byte(cmd, reg, ACK_CHECK_EN); 151 | i2c_master_start(cmd); 152 | i2c_master_write_byte(cmd, ( DevAddr << 1 ) | READ_BIT, ACK_CHECK_EN); 153 | if (size > 1) { 154 | i2c_master_read(cmd, data_rd, size - 1, ACK_VAL); 155 | } 156 | i2c_master_read_byte(cmd, data_rd + size - 1, NACK_VAL); 157 | i2c_master_stop(cmd); 158 | esp_err_t ret = i2c_master_cmd_begin(I2C_NUM_1, cmd, 1000 / portTICK_RATE_MS); 159 | i2c_cmd_link_delete(cmd); 160 | return ret; 161 | } 162 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/common_audio/signal_processing/spl_init.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | /* The global function contained in this file initializes SPL function 12 | * pointers, currently only for ARM platforms. 13 | * 14 | * Some code came from common/rtcd.c in the WebM project. 15 | */ 16 | 17 | #include "common_audio/signal_processing/include/signal_processing_library.h" 18 | #include "system_wrappers/include/cpu_features_wrapper.h" 19 | 20 | /* Declare function pointers. */ 21 | MaxAbsValueW16 WebRtcSpl_MaxAbsValueW16; 22 | MaxAbsValueW32 WebRtcSpl_MaxAbsValueW32; 23 | MaxValueW16 WebRtcSpl_MaxValueW16; 24 | MaxValueW32 WebRtcSpl_MaxValueW32; 25 | MinValueW16 WebRtcSpl_MinValueW16; 26 | MinValueW32 WebRtcSpl_MinValueW32; 27 | CrossCorrelation WebRtcSpl_CrossCorrelation; 28 | DownsampleFast WebRtcSpl_DownsampleFast; 29 | ScaleAndAddVectorsWithRound WebRtcSpl_ScaleAndAddVectorsWithRound; 30 | 31 | #if (!defined(WEBRTC_HAS_NEON)) && !defined(MIPS32_LE) 32 | /* Initialize function pointers to the generic C version. */ 33 | static void InitPointersToC() { 34 | WebRtcSpl_MaxAbsValueW16 = WebRtcSpl_MaxAbsValueW16C; 35 | WebRtcSpl_MaxAbsValueW32 = WebRtcSpl_MaxAbsValueW32C; 36 | WebRtcSpl_MaxValueW16 = WebRtcSpl_MaxValueW16C; 37 | WebRtcSpl_MaxValueW32 = WebRtcSpl_MaxValueW32C; 38 | WebRtcSpl_MinValueW16 = WebRtcSpl_MinValueW16C; 39 | WebRtcSpl_MinValueW32 = WebRtcSpl_MinValueW32C; 40 | WebRtcSpl_CrossCorrelation = WebRtcSpl_CrossCorrelationC; 41 | WebRtcSpl_DownsampleFast = WebRtcSpl_DownsampleFastC; 42 | WebRtcSpl_ScaleAndAddVectorsWithRound = 43 | WebRtcSpl_ScaleAndAddVectorsWithRoundC; 44 | } 45 | #endif 46 | 47 | #if defined(WEBRTC_HAS_NEON) 48 | /* Initialize function pointers to the Neon version. */ 49 | static void InitPointersToNeon() { 50 | WebRtcSpl_MaxAbsValueW16 = WebRtcSpl_MaxAbsValueW16Neon; 51 | WebRtcSpl_MaxAbsValueW32 = WebRtcSpl_MaxAbsValueW32Neon; 52 | WebRtcSpl_MaxValueW16 = WebRtcSpl_MaxValueW16Neon; 53 | WebRtcSpl_MaxValueW32 = WebRtcSpl_MaxValueW32Neon; 54 | WebRtcSpl_MinValueW16 = WebRtcSpl_MinValueW16Neon; 55 | WebRtcSpl_MinValueW32 = WebRtcSpl_MinValueW32Neon; 56 | WebRtcSpl_CrossCorrelation = WebRtcSpl_CrossCorrelationNeon; 57 | WebRtcSpl_DownsampleFast = WebRtcSpl_DownsampleFastNeon; 58 | WebRtcSpl_ScaleAndAddVectorsWithRound = 59 | WebRtcSpl_ScaleAndAddVectorsWithRoundC; 60 | } 61 | #endif 62 | 63 | #if defined(MIPS32_LE) 64 | /* Initialize function pointers to the MIPS version. */ 65 | static void InitPointersToMIPS() { 66 | WebRtcSpl_MaxAbsValueW16 = WebRtcSpl_MaxAbsValueW16_mips; 67 | WebRtcSpl_MaxValueW16 = WebRtcSpl_MaxValueW16_mips; 68 | WebRtcSpl_MaxValueW32 = WebRtcSpl_MaxValueW32_mips; 69 | WebRtcSpl_MinValueW16 = WebRtcSpl_MinValueW16_mips; 70 | WebRtcSpl_MinValueW32 = WebRtcSpl_MinValueW32_mips; 71 | WebRtcSpl_CrossCorrelation = WebRtcSpl_CrossCorrelation_mips; 72 | WebRtcSpl_DownsampleFast = WebRtcSpl_DownsampleFast_mips; 73 | #if defined(MIPS_DSP_R1_LE) 74 | WebRtcSpl_MaxAbsValueW32 = WebRtcSpl_MaxAbsValueW32_mips; 75 | WebRtcSpl_ScaleAndAddVectorsWithRound = 76 | WebRtcSpl_ScaleAndAddVectorsWithRound_mips; 77 | #else 78 | WebRtcSpl_MaxAbsValueW32 = WebRtcSpl_MaxAbsValueW32C; 79 | WebRtcSpl_ScaleAndAddVectorsWithRound = 80 | WebRtcSpl_ScaleAndAddVectorsWithRoundC; 81 | #endif 82 | } 83 | #endif 84 | 85 | static void InitFunctionPointers(void) { 86 | #if defined(WEBRTC_HAS_NEON) 87 | InitPointersToNeon(); 88 | #elif defined(MIPS32_LE) 89 | InitPointersToMIPS(); 90 | #else 91 | InitPointersToC(); 92 | #endif /* WEBRTC_HAS_NEON */ 93 | } 94 | 95 | #if defined(WEBRTC_POSIX) 96 | #include 97 | 98 | static void once(void (*func)(void)) { 99 | static pthread_once_t lock = PTHREAD_ONCE_INIT; 100 | pthread_once(&lock, func); 101 | } 102 | 103 | #elif defined(_WIN32) 104 | #include 105 | 106 | static void once(void (*func)(void)) { 107 | /* Didn't use InitializeCriticalSection() since there's no race-simple_vad_free context 108 | * in which to execute it. 109 | * 110 | * TODO(kma): Change to different implementation (e.g. 111 | * InterlockedCompareExchangePointer) to avoid issues similar to 112 | * http://code.google.com/p/webm/issues/detail?id=467. 113 | */ 114 | static CRITICAL_SECTION lock = {(void *)((size_t)-1), -1, 0, 0, 0, 0}; 115 | static int done = 0; 116 | 117 | EnterCriticalSection(&lock); 118 | if (!done) { 119 | func(); 120 | done = 1; 121 | } 122 | LeaveCriticalSection(&lock); 123 | } 124 | 125 | /* There's no fallback version as an #else block here to ensure thread safety. 126 | * In case of neither pthread for WEBRTC_POSIX nor _WIN32 is present, build 127 | * system should pick it up. 128 | */ 129 | #endif /* WEBRTC_POSIX */ 130 | 131 | void WebRtcSpl_Init() { 132 | once(InitFunctionPointers); 133 | } 134 | -------------------------------------------------------------------------------- /main/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "freertos/FreeRTOS.h" 6 | #include "freertos/task.h" 7 | #include "freertos/semphr.h" 8 | 9 | #include "driver/gpio.h" 10 | #include "driver/i2s.h" 11 | #include "../components/ac101_driver/AC101.h" 12 | #include "../components/ac101_driver/recoder.h" 13 | #include "../components/ac101_driver/uart.h" 14 | 15 | #include "nvs_flash.h" 16 | #include "sdkconfig.h" 17 | 18 | #include "common_audio/vad/include/webrtc_vad.h" 19 | #include "simple_vad.h" 20 | 21 | #define CONFIG_AC101_I2S_DATA_IN_PIN 35 22 | 23 | static void audio_recorder_AC101_init() 24 | { 25 | AC101_init(); 26 | 27 | i2s_config_t i2s_config = { 28 | .mode = I2S_MODE_MASTER |I2S_MODE_RX | I2S_MODE_TX, 29 | .sample_rate = 16000, 30 | .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, 31 | .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT, //1-channels 32 | .communication_format = I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB, 33 | .dma_buf_count = 32, 34 | .dma_buf_len = 32 *2, 35 | .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1 //Interrupt level 1 36 | }; 37 | 38 | i2s_pin_config_t pin_config_rx = { 39 | .bck_io_num = CONFIG_AC101_I2S_BCK_PIN, 40 | .ws_io_num = CONFIG_AC101_I2S_LRCK_PIN, 41 | .data_out_num = CONFIG_AC101_I2S_DATA_PIN, 42 | .data_in_num = CONFIG_AC101_I2S_DATA_IN_PIN 43 | }; 44 | 45 | int reg_val = REG_READ(PIN_CTRL); 46 | REG_WRITE(PIN_CTRL, 0xFFFFFFF0); 47 | reg_val = REG_READ(PIN_CTRL); 48 | PIN_FUNC_SELECT(GPIO_PIN_REG_0, 1); //GPIO0 as CLK_OUT1 49 | 50 | /* 注册i2s设备驱动 */ 51 | i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL); 52 | /* 设置i2s引脚 */ 53 | i2s_set_pin(I2S_NUM_0, &pin_config_rx); 54 | /* 停止i2s设备 */ 55 | i2s_stop(I2S_NUM_0); 56 | } 57 | 58 | //static void alexa__AC101_task(void *pvParameters) 59 | //{ 60 | // int recv_len=0; 61 | // int is_active; 62 | // int16_t data[FRAME_SIZE]; // FRAME_SIZE * 16bit/2 63 | // 64 | // simple_vad *vad = simple_vad_create(); //simple_vad_free(vad); 65 | // if (vad == NULL) { 66 | // vTaskDelete(NULL); 67 | // } 68 | // 69 | // i2s_start(I2S_NUM_0); 70 | // while(1) 71 | // { 72 | // recv_len=i2s_read_bytes(I2S_NUM_0,data,320,portMAX_DELAY); 73 | // is_active = process_vad(vad, data); 74 | // printf("%d \t",is_active); 75 | // i2s_write_bytes(I2S_NUM_0,data,recv_len,portMAX_DELAY); 76 | // } 77 | // i2s_stop(I2S_NUM_0); 78 | // simple_vad_free(vad); 79 | // vTaskDelete(NULL); 80 | //} 81 | 82 | /* 实际采集一定数据的时间(计算时间) < 说话人说话同等数据所花时间 */ 83 | static void esp32_vad_task(void *pvParameters) 84 | { 85 | int recv_len = 0; 86 | int is_active = 0; 87 | int count = 0; 88 | int16_t data[FRAME_SIZE]; // FRAME_SIZE * 16bit/2 89 | int16_t data_del[FRAME_SIZE]; 90 | 91 | simple_vad *vad = simple_vad_create(); 92 | if (vad == NULL) { 93 | vTaskDelete(NULL); 94 | } 95 | QueueHandle_t data_que = NULL; 96 | data_que = xQueueCreate(VAD_TIME_TOTAL, sizeof(int16_t) * FRAME_SIZE); // 625k内存 97 | 98 | i2s_start(I2S_NUM_0); 99 | printf("\nstart vad detection\n"); 100 | while(1) 101 | { 102 | recv_len=i2s_read_bytes(I2S_NUM_0,data,sizeof(int16_t) * FRAME_SIZE,portMAX_DELAY); 103 | xQueueSend(data_que, data, portMAX_DELAY); 104 | if (uxQueueMessagesWaiting(data_que) == START_CACHE_TIME + 1) // must +1 105 | { 106 | xQueueReceive(data_que,data_del,portMAX_DELAY); 107 | } 108 | is_active = process_vad(vad, data); 109 | printf("%d \t",is_active); 110 | if (is_active == 1) { 111 | count++; 112 | if (count == START_TIME) { // 1s 113 | count = 0; 114 | goto status_1; 115 | } 116 | } else { 117 | count = 0; 118 | } 119 | i2s_write_bytes(I2S_NUM_0,data,recv_len,portMAX_DELAY); 120 | } 121 | status_1: 122 | printf("\nTo prepare the recording %ds\n", (int)(VAD_TIME_TOTAL * 0.01)); 123 | for (int i = 0; i < VAD_TIME_TOTAL-START_CACHE_TIME; i++) // 0.01s * 2000 = 20s 124 | { 125 | recv_len=i2s_read_bytes(I2S_NUM_0,data,sizeof(int16_t) * FRAME_SIZE,portMAX_DELAY); 126 | xQueueSend(data_que, data, portMAX_DELAY); 127 | is_active = process_vad(vad, data); 128 | printf("%d \t", is_active); 129 | if (is_active == 0) { 130 | count++; 131 | if (count == END_TIME) { 132 | count = 0; 133 | goto status_2; 134 | } 135 | } else { 136 | count = 0; 137 | } 138 | i2s_write_bytes(I2S_NUM_0, data, recv_len, portMAX_DELAY); 139 | } 140 | status_2: 141 | printf("\nplay recording\n"); 142 | while(1) 143 | { 144 | if (uxQueueMessagesWaiting(data_que) == 0) 145 | break; 146 | else 147 | { 148 | xQueueReceive(data_que, data, portMAX_DELAY); 149 | i2s_write_bytes(I2S_NUM_0, data, recv_len, portMAX_DELAY);//recv_len=320 150 | } 151 | } 152 | printf("esp32_vad_task is over, thank you!\n"); 153 | i2s_stop(I2S_NUM_0); 154 | vQueueDelete(data_que); 155 | simple_vad_free(vad); 156 | vTaskDelete(NULL); 157 | } 158 | 159 | void app_main() { 160 | esp_err_t ret = nvs_flash_init(); 161 | if (ret == ESP_ERR_NVS_NO_FREE_PAGES 162 | || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { 163 | ESP_ERROR_CHECK(nvs_flash_erase()); 164 | ret = nvs_flash_init(); 165 | } 166 | ESP_ERROR_CHECK(ret); 167 | 168 | audio_recorder_AC101_init(); 169 | // xTaskCreatePinnedToCore(&alexa__AC101_task, "alexa__AC101_task", 8096, NULL, 170 | // 2, NULL, 1); 171 | xTaskCreatePinnedToCore(&esp32_vad_task, "esp32_vad_task", 40000, NULL, 172 | 2, NULL, 1); 173 | } 174 | 175 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/common_audio/signal_processing/vector_scaling_operations.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | 12 | /* 13 | * This file contains implementations of the functions 14 | * WebRtcSpl_VectorBitShiftW16() 15 | * WebRtcSpl_VectorBitShiftW32() 16 | * WebRtcSpl_VectorBitShiftW32ToW16() 17 | * WebRtcSpl_ScaleVector() 18 | * WebRtcSpl_ScaleVectorWithSat() 19 | * WebRtcSpl_ScaleAndAddVectors() 20 | * WebRtcSpl_ScaleAndAddVectorsWithRoundC() 21 | */ 22 | 23 | #include "common_audio/signal_processing/include/signal_processing_library.h" 24 | 25 | void WebRtcSpl_VectorBitShiftW16(int16_t *res, size_t length, 26 | const int16_t *in, int16_t right_shifts) 27 | { 28 | size_t i; 29 | 30 | if (right_shifts > 0) 31 | { 32 | for (i = length; i > 0; i--) 33 | { 34 | (*res++) = ((*in++) >> right_shifts); 35 | } 36 | } else 37 | { 38 | for (i = length; i > 0; i--) 39 | { 40 | (*res++) = ((*in++) * (1 << (-right_shifts))); 41 | } 42 | } 43 | } 44 | 45 | void WebRtcSpl_VectorBitShiftW32(int32_t *out_vector, 46 | size_t vector_length, 47 | const int32_t *in_vector, 48 | int16_t right_shifts) 49 | { 50 | size_t i; 51 | 52 | if (right_shifts > 0) 53 | { 54 | for (i = vector_length; i > 0; i--) 55 | { 56 | (*out_vector++) = ((*in_vector++) >> right_shifts); 57 | } 58 | } else 59 | { 60 | for (i = vector_length; i > 0; i--) 61 | { 62 | (*out_vector++) = ((*in_vector++) << (-right_shifts)); 63 | } 64 | } 65 | } 66 | 67 | void WebRtcSpl_VectorBitShiftW32ToW16(int16_t* out, size_t length, 68 | const int32_t* in, int right_shifts) { 69 | size_t i; 70 | int32_t tmp_w32; 71 | 72 | if (right_shifts >= 0) { 73 | for (i = length; i > 0; i--) { 74 | tmp_w32 = (*in++) >> right_shifts; 75 | (*out++) = WebRtcSpl_SatW32ToW16(tmp_w32); 76 | } 77 | } else { 78 | int left_shifts = -right_shifts; 79 | for (i = length; i > 0; i--) { 80 | tmp_w32 = (*in++) << left_shifts; 81 | (*out++) = WebRtcSpl_SatW32ToW16(tmp_w32); 82 | } 83 | } 84 | } 85 | 86 | void WebRtcSpl_ScaleVector(const int16_t *in_vector, int16_t *out_vector, 87 | int16_t gain, size_t in_vector_length, 88 | int16_t right_shifts) 89 | { 90 | // Performs vector operation: out_vector = (gain*in_vector)>>right_shifts 91 | size_t i; 92 | const int16_t *inptr; 93 | int16_t *outptr; 94 | 95 | inptr = in_vector; 96 | outptr = out_vector; 97 | 98 | for (i = 0; i < in_vector_length; i++) 99 | { 100 | *outptr++ = (int16_t)((*inptr++ * gain) >> right_shifts); 101 | } 102 | } 103 | 104 | void WebRtcSpl_ScaleVectorWithSat(const int16_t *in_vector, int16_t *out_vector, 105 | int16_t gain, size_t in_vector_length, 106 | int16_t right_shifts) 107 | { 108 | // Performs vector operation: out_vector = (gain*in_vector)>>right_shifts 109 | size_t i; 110 | const int16_t *inptr; 111 | int16_t *outptr; 112 | 113 | inptr = in_vector; 114 | outptr = out_vector; 115 | 116 | for (i = 0; i < in_vector_length; i++) { 117 | *outptr++ = WebRtcSpl_SatW32ToW16((*inptr++ * gain) >> right_shifts); 118 | } 119 | } 120 | 121 | void WebRtcSpl_ScaleAndAddVectors(const int16_t *in1, int16_t gain1, int shift1, 122 | const int16_t *in2, int16_t gain2, int shift2, 123 | int16_t *out, size_t vector_length) 124 | { 125 | // Performs vector operation: out = (gain1*in1)>>shift1 + (gain2*in2)>>shift2 126 | size_t i; 127 | const int16_t *in1ptr; 128 | const int16_t *in2ptr; 129 | int16_t *outptr; 130 | 131 | in1ptr = in1; 132 | in2ptr = in2; 133 | outptr = out; 134 | 135 | for (i = 0; i < vector_length; i++) 136 | { 137 | *outptr++ = (int16_t)((gain1 * *in1ptr++) >> shift1) + 138 | (int16_t)((gain2 * *in2ptr++) >> shift2); 139 | } 140 | } 141 | 142 | // C version of WebRtcSpl_ScaleAndAddVectorsWithRound() for generic platforms. 143 | int WebRtcSpl_ScaleAndAddVectorsWithRoundC(const int16_t* in_vector1, 144 | int16_t in_vector1_scale, 145 | const int16_t* in_vector2, 146 | int16_t in_vector2_scale, 147 | int right_shifts, 148 | int16_t* out_vector, 149 | size_t length) { 150 | size_t i = 0; 151 | int round_value = (1 << right_shifts) >> 1; 152 | 153 | if (in_vector1 == NULL || in_vector2 == NULL || out_vector == NULL || 154 | length == 0 || right_shifts < 0) { 155 | return -1; 156 | } 157 | 158 | for (i = 0; i < length; i++) { 159 | out_vector[i] = (int16_t)(( 160 | in_vector1[i] * in_vector1_scale + in_vector2[i] * in_vector2_scale + 161 | round_value) >> right_shifts); 162 | } 163 | 164 | return 0; 165 | } 166 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/common_audio/signal_processing/include/spl_inl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | 12 | // This header file includes the inline functions in 13 | // the fix point signal processing library. 14 | 15 | #ifndef COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_SPL_INL_H_ 16 | #define COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_SPL_INL_H_ 17 | 18 | #include "rtc_base/compile_assert_c.h" 19 | 20 | extern const int8_t kWebRtcSpl_CountLeadingZeros32_Table[64]; 21 | 22 | // Don't call this directly except in tests! 23 | static __inline int WebRtcSpl_CountLeadingZeros32_NotBuiltin(uint32_t n) { 24 | // Normalize n by rounding up to the nearest number that is a sequence of 0 25 | // bits followed by a sequence of 1 bits. This number has the same number of 26 | // leading zeros as the original n. There are exactly 33 such values. 27 | n |= n >> 1; 28 | n |= n >> 2; 29 | n |= n >> 4; 30 | n |= n >> 8; 31 | n |= n >> 16; 32 | 33 | // Multiply the modified n with a constant selected (by exhaustive search) 34 | // such that each of the 33 possible values of n give a product whose 6 most 35 | // significant bits are unique. Then look up the answer in the table. 36 | return kWebRtcSpl_CountLeadingZeros32_Table[(n * 0x8c0b2891) >> 26]; 37 | } 38 | 39 | // Don't call this directly except in tests! 40 | static __inline int WebRtcSpl_CountLeadingZeros64_NotBuiltin(uint64_t n) { 41 | const int leading_zeros = n >> 32 == 0 ? 32 : 0; 42 | return leading_zeros + WebRtcSpl_CountLeadingZeros32_NotBuiltin( 43 | (uint32_t)(n >> (32 - leading_zeros))); 44 | } 45 | 46 | // Returns the number of leading zero bits in the argument. 47 | static __inline int WebRtcSpl_CountLeadingZeros32(uint32_t n) { 48 | #ifdef __GNUC__ 49 | RTC_COMPILE_ASSERT(sizeof(unsigned int) == sizeof(uint32_t)); 50 | return n == 0 ? 32 : __builtin_clz(n); 51 | #else 52 | return WebRtcSpl_CountLeadingZeros32_NotBuiltin(n); 53 | #endif 54 | } 55 | 56 | // Returns the number of leading zero bits in the argument. 57 | static __inline int WebRtcSpl_CountLeadingZeros64(uint64_t n) { 58 | #ifdef __GNUC__ 59 | RTC_COMPILE_ASSERT(sizeof(unsigned long long) == sizeof(uint64_t)); // NOLINT 60 | return n == 0 ? 64 : __builtin_clzll(n); 61 | #else 62 | return WebRtcSpl_CountLeadingZeros64_NotBuiltin(n); 63 | #endif 64 | } 65 | 66 | #ifdef WEBRTC_ARCH_ARM_V7 67 | #include "common_audio/signal_processing/include/spl_inl_armv7.h" 68 | #else 69 | 70 | #if defined(MIPS32_LE) 71 | #include "common_audio/signal_processing/include/spl_inl_mips.h" 72 | #endif 73 | 74 | #if !defined(MIPS_DSP_R1_LE) 75 | static __inline int16_t WebRtcSpl_SatW32ToW16(int32_t value32) { 76 | int16_t out16 = (int16_t) value32; 77 | 78 | if (value32 > 32767) 79 | out16 = 32767; 80 | else if (value32 < -32768) 81 | out16 = -32768; 82 | 83 | return out16; 84 | } 85 | 86 | static __inline int32_t WebRtcSpl_AddSatW32(int32_t a, int32_t b) { 87 | // Do the addition in unsigned numbers, since signed overflow is undefined 88 | // behavior. 89 | const int32_t sum = (int32_t)((uint32_t)a + (uint32_t)b); 90 | 91 | // a + b can't overflow if a and b have different signs. If they have the 92 | // same sign, a + b also has the same sign iff it didn't overflow. 93 | if ((a < 0) == (b < 0) && (a < 0) != (sum < 0)) { 94 | // The direction of the overflow is obvious from the sign of a + b. 95 | return sum < 0 ? INT32_MAX : INT32_MIN; 96 | } 97 | return sum; 98 | } 99 | 100 | static __inline int32_t WebRtcSpl_SubSatW32(int32_t a, int32_t b) { 101 | // Do the subtraction in unsigned numbers, since signed overflow is undefined 102 | // behavior. 103 | const int32_t diff = (int32_t)((uint32_t)a - (uint32_t)b); 104 | 105 | // a - b can't overflow if a and b have the same sign. If they have different 106 | // signs, a - b has the same sign as a iff it didn't overflow. 107 | if ((a < 0) != (b < 0) && (a < 0) != (diff < 0)) { 108 | // The direction of the overflow is obvious from the sign of a - b. 109 | return diff < 0 ? INT32_MAX : INT32_MIN; 110 | } 111 | return diff; 112 | } 113 | 114 | static __inline int16_t WebRtcSpl_AddSatW16(int16_t a, int16_t b) { 115 | return WebRtcSpl_SatW32ToW16((int32_t) a + (int32_t) b); 116 | } 117 | 118 | static __inline int16_t WebRtcSpl_SubSatW16(int16_t var1, int16_t var2) { 119 | return WebRtcSpl_SatW32ToW16((int32_t) var1 - (int32_t) var2); 120 | } 121 | #endif // #if !defined(MIPS_DSP_R1_LE) 122 | 123 | #if !defined(MIPS32_LE) 124 | static __inline int16_t WebRtcSpl_GetSizeInBits(uint32_t n) { 125 | return 32 - WebRtcSpl_CountLeadingZeros32(n); 126 | } 127 | 128 | // Return the number of steps a can be left-shifted without overflow, 129 | // or 0 if a == 0. 130 | static __inline int16_t WebRtcSpl_NormW32(int32_t a) { 131 | return a == 0 ? 0 : WebRtcSpl_CountLeadingZeros32(a < 0 ? ~a : a) - 1; 132 | } 133 | 134 | // Return the number of steps a can be left-shifted without overflow, 135 | // or 0 if a == 0. 136 | static __inline int16_t WebRtcSpl_NormU32(uint32_t a) { 137 | return a == 0 ? 0 : WebRtcSpl_CountLeadingZeros32(a); 138 | } 139 | 140 | // Return the number of steps a can be left-shifted without overflow, 141 | // or 0 if a == 0. 142 | static __inline int16_t WebRtcSpl_NormW16(int16_t a) { 143 | const int32_t a32 = a; 144 | return a == 0 ? 0 : WebRtcSpl_CountLeadingZeros32(a < 0 ? ~a32 : a32) - 17; 145 | } 146 | 147 | static __inline int32_t WebRtc_MulAccumW16(int16_t a, int16_t b, int32_t c) { 148 | return (a * b + c); 149 | } 150 | #endif // #if !defined(MIPS32_LE) 151 | 152 | #endif // WEBRTC_ARCH_ARM_V7 153 | 154 | #endif // COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_SPL_INL_H_ 155 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/common_audio/signal_processing/min_max_operations.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | /* 12 | * This file contains the implementation of functions 13 | * WebRtcSpl_MaxAbsValueW16C() 14 | * WebRtcSpl_MaxAbsValueW32C() 15 | * WebRtcSpl_MaxValueW16C() 16 | * WebRtcSpl_MaxValueW32C() 17 | * WebRtcSpl_MinValueW16C() 18 | * WebRtcSpl_MinValueW32C() 19 | * WebRtcSpl_MaxAbsIndexW16() 20 | * WebRtcSpl_MaxIndexW16() 21 | * WebRtcSpl_MaxIndexW32() 22 | * WebRtcSpl_MinIndexW16() 23 | * WebRtcSpl_MinIndexW32() 24 | * 25 | */ 26 | 27 | #include 28 | 29 | #include "rtc_base/checks.h" 30 | #include "common_audio/signal_processing/include/signal_processing_library.h" 31 | 32 | // TODO(bjorn/kma): Consolidate function pairs (e.g. combine 33 | // WebRtcSpl_MaxAbsValueW16C and WebRtcSpl_MaxAbsIndexW16 into a single one.) 34 | // TODO(kma): Move the next six functions into min_max_operations_c.c. 35 | 36 | // Maximum absolute value of word16 vector. C version for generic platforms. 37 | int16_t WebRtcSpl_MaxAbsValueW16C(const int16_t* vector, size_t length) { 38 | size_t i = 0; 39 | int absolute = 0, maximum = 0; 40 | 41 | RTC_DCHECK_GT(length, 0); 42 | 43 | for (i = 0; i < length; i++) { 44 | absolute = abs((int)vector[i]); 45 | 46 | if (absolute > maximum) { 47 | maximum = absolute; 48 | } 49 | } 50 | 51 | // Guard the case for abs(-32768). 52 | if (maximum > WEBRTC_SPL_WORD16_MAX) { 53 | maximum = WEBRTC_SPL_WORD16_MAX; 54 | } 55 | 56 | return (int16_t)maximum; 57 | } 58 | 59 | // Maximum absolute value of word32 vector. C version for generic platforms. 60 | int32_t WebRtcSpl_MaxAbsValueW32C(const int32_t* vector, size_t length) { 61 | // Use uint32_t for the local variables, to accommodate the return value 62 | // of abs(0x80000000), which is 0x80000000. 63 | 64 | uint32_t absolute = 0, maximum = 0; 65 | size_t i = 0; 66 | 67 | RTC_DCHECK_GT(length, 0); 68 | 69 | for (i = 0; i < length; i++) { 70 | absolute = abs((int)vector[i]); 71 | if (absolute > maximum) { 72 | maximum = absolute; 73 | } 74 | } 75 | 76 | maximum = WEBRTC_SPL_MIN(maximum, WEBRTC_SPL_WORD32_MAX); 77 | 78 | return (int32_t)maximum; 79 | } 80 | 81 | // Maximum value of word16 vector. C version for generic platforms. 82 | int16_t WebRtcSpl_MaxValueW16C(const int16_t* vector, size_t length) { 83 | int16_t maximum = WEBRTC_SPL_WORD16_MIN; 84 | size_t i = 0; 85 | 86 | RTC_DCHECK_GT(length, 0); 87 | 88 | for (i = 0; i < length; i++) { 89 | if (vector[i] > maximum) 90 | maximum = vector[i]; 91 | } 92 | return maximum; 93 | } 94 | 95 | // Maximum value of word32 vector. C version for generic platforms. 96 | int32_t WebRtcSpl_MaxValueW32C(const int32_t* vector, size_t length) { 97 | int32_t maximum = WEBRTC_SPL_WORD32_MIN; 98 | size_t i = 0; 99 | 100 | RTC_DCHECK_GT(length, 0); 101 | 102 | for (i = 0; i < length; i++) { 103 | if (vector[i] > maximum) 104 | maximum = vector[i]; 105 | } 106 | return maximum; 107 | } 108 | 109 | // Minimum value of word16 vector. C version for generic platforms. 110 | int16_t WebRtcSpl_MinValueW16C(const int16_t* vector, size_t length) { 111 | int16_t minimum = WEBRTC_SPL_WORD16_MAX; 112 | size_t i = 0; 113 | 114 | RTC_DCHECK_GT(length, 0); 115 | 116 | for (i = 0; i < length; i++) { 117 | if (vector[i] < minimum) 118 | minimum = vector[i]; 119 | } 120 | return minimum; 121 | } 122 | 123 | // Minimum value of word32 vector. C version for generic platforms. 124 | int32_t WebRtcSpl_MinValueW32C(const int32_t* vector, size_t length) { 125 | int32_t minimum = WEBRTC_SPL_WORD32_MAX; 126 | size_t i = 0; 127 | 128 | RTC_DCHECK_GT(length, 0); 129 | 130 | for (i = 0; i < length; i++) { 131 | if (vector[i] < minimum) 132 | minimum = vector[i]; 133 | } 134 | return minimum; 135 | } 136 | 137 | // Index of maximum absolute value in a word16 vector. 138 | size_t WebRtcSpl_MaxAbsIndexW16(const int16_t* vector, size_t length) { 139 | // Use type int for local variables, to accomodate the value of abs(-32768). 140 | 141 | size_t i = 0, index = 0; 142 | int absolute = 0, maximum = 0; 143 | 144 | RTC_DCHECK_GT(length, 0); 145 | 146 | for (i = 0; i < length; i++) { 147 | absolute = abs((int)vector[i]); 148 | 149 | if (absolute > maximum) { 150 | maximum = absolute; 151 | index = i; 152 | } 153 | } 154 | 155 | return index; 156 | } 157 | 158 | // Index of maximum value in a word16 vector. 159 | size_t WebRtcSpl_MaxIndexW16(const int16_t* vector, size_t length) { 160 | size_t i = 0, index = 0; 161 | int16_t maximum = WEBRTC_SPL_WORD16_MIN; 162 | 163 | RTC_DCHECK_GT(length, 0); 164 | 165 | for (i = 0; i < length; i++) { 166 | if (vector[i] > maximum) { 167 | maximum = vector[i]; 168 | index = i; 169 | } 170 | } 171 | 172 | return index; 173 | } 174 | 175 | // Index of maximum value in a word32 vector. 176 | size_t WebRtcSpl_MaxIndexW32(const int32_t* vector, size_t length) { 177 | size_t i = 0, index = 0; 178 | int32_t maximum = WEBRTC_SPL_WORD32_MIN; 179 | 180 | RTC_DCHECK_GT(length, 0); 181 | 182 | for (i = 0; i < length; i++) { 183 | if (vector[i] > maximum) { 184 | maximum = vector[i]; 185 | index = i; 186 | } 187 | } 188 | 189 | return index; 190 | } 191 | 192 | // Index of minimum value in a word16 vector. 193 | size_t WebRtcSpl_MinIndexW16(const int16_t* vector, size_t length) { 194 | size_t i = 0, index = 0; 195 | int16_t minimum = WEBRTC_SPL_WORD16_MAX; 196 | 197 | RTC_DCHECK_GT(length, 0); 198 | 199 | for (i = 0; i < length; i++) { 200 | if (vector[i] < minimum) { 201 | minimum = vector[i]; 202 | index = i; 203 | } 204 | } 205 | 206 | return index; 207 | } 208 | 209 | // Index of minimum value in a word32 vector. 210 | size_t WebRtcSpl_MinIndexW32(const int32_t* vector, size_t length) { 211 | size_t i = 0, index = 0; 212 | int32_t minimum = WEBRTC_SPL_WORD32_MAX; 213 | 214 | RTC_DCHECK_GT(length, 0); 215 | 216 | for (i = 0; i < length; i++) { 217 | if (vector[i] < minimum) { 218 | minimum = vector[i]; 219 | index = i; 220 | } 221 | } 222 | 223 | return index; 224 | } 225 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/common_audio/signal_processing/cross_correlation_mips.c.mips: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #include "common_audio/signal_processing/include/signal_processing_library.h" 12 | 13 | void WebRtcSpl_CrossCorrelation_mips(int32_t* cross_correlation, 14 | const int16_t* seq1, 15 | const int16_t* seq2, 16 | size_t dim_seq, 17 | size_t dim_cross_correlation, 18 | int right_shifts, 19 | int step_seq2) { 20 | 21 | int32_t t0 = 0, t1 = 0, t2 = 0, t3 = 0, sum = 0; 22 | int16_t *pseq2 = NULL; 23 | int16_t *pseq1 = NULL; 24 | int16_t *pseq1_0 = (int16_t*)&seq1[0]; 25 | int16_t *pseq2_0 = (int16_t*)&seq2[0]; 26 | int k = 0; 27 | 28 | __asm __volatile ( 29 | ".set push \n\t" 30 | ".set noreorder \n\t" 31 | "sll %[step_seq2], %[step_seq2], 1 \n\t" 32 | "andi %[t0], %[dim_seq], 1 \n\t" 33 | "bgtz %[t0], 3f \n\t" 34 | " nop \n\t" 35 | "1: \n\t" 36 | "move %[pseq1], %[pseq1_0] \n\t" 37 | "move %[pseq2], %[pseq2_0] \n\t" 38 | "sra %[k], %[dim_seq], 1 \n\t" 39 | "addiu %[dim_cc], %[dim_cc], -1 \n\t" 40 | "xor %[sum], %[sum], %[sum] \n\t" 41 | "2: \n\t" 42 | "lh %[t0], 0(%[pseq1]) \n\t" 43 | "lh %[t1], 0(%[pseq2]) \n\t" 44 | "lh %[t2], 2(%[pseq1]) \n\t" 45 | "lh %[t3], 2(%[pseq2]) \n\t" 46 | "mul %[t0], %[t0], %[t1] \n\t" 47 | "addiu %[k], %[k], -1 \n\t" 48 | "mul %[t2], %[t2], %[t3] \n\t" 49 | "addiu %[pseq1], %[pseq1], 4 \n\t" 50 | "addiu %[pseq2], %[pseq2], 4 \n\t" 51 | "srav %[t0], %[t0], %[right_shifts] \n\t" 52 | "addu %[sum], %[sum], %[t0] \n\t" 53 | "srav %[t2], %[t2], %[right_shifts] \n\t" 54 | "bgtz %[k], 2b \n\t" 55 | " addu %[sum], %[sum], %[t2] \n\t" 56 | "addu %[pseq2_0], %[pseq2_0], %[step_seq2] \n\t" 57 | "sw %[sum], 0(%[cc]) \n\t" 58 | "bgtz %[dim_cc], 1b \n\t" 59 | " addiu %[cc], %[cc], 4 \n\t" 60 | "b 6f \n\t" 61 | " nop \n\t" 62 | "3: \n\t" 63 | "move %[pseq1], %[pseq1_0] \n\t" 64 | "move %[pseq2], %[pseq2_0] \n\t" 65 | "sra %[k], %[dim_seq], 1 \n\t" 66 | "addiu %[dim_cc], %[dim_cc], -1 \n\t" 67 | "beqz %[k], 5f \n\t" 68 | " xor %[sum], %[sum], %[sum] \n\t" 69 | "4: \n\t" 70 | "lh %[t0], 0(%[pseq1]) \n\t" 71 | "lh %[t1], 0(%[pseq2]) \n\t" 72 | "lh %[t2], 2(%[pseq1]) \n\t" 73 | "lh %[t3], 2(%[pseq2]) \n\t" 74 | "mul %[t0], %[t0], %[t1] \n\t" 75 | "addiu %[k], %[k], -1 \n\t" 76 | "mul %[t2], %[t2], %[t3] \n\t" 77 | "addiu %[pseq1], %[pseq1], 4 \n\t" 78 | "addiu %[pseq2], %[pseq2], 4 \n\t" 79 | "srav %[t0], %[t0], %[right_shifts] \n\t" 80 | "addu %[sum], %[sum], %[t0] \n\t" 81 | "srav %[t2], %[t2], %[right_shifts] \n\t" 82 | "bgtz %[k], 4b \n\t" 83 | " addu %[sum], %[sum], %[t2] \n\t" 84 | "5: \n\t" 85 | "lh %[t0], 0(%[pseq1]) \n\t" 86 | "lh %[t1], 0(%[pseq2]) \n\t" 87 | "mul %[t0], %[t0], %[t1] \n\t" 88 | "srav %[t0], %[t0], %[right_shifts] \n\t" 89 | "addu %[sum], %[sum], %[t0] \n\t" 90 | "addu %[pseq2_0], %[pseq2_0], %[step_seq2] \n\t" 91 | "sw %[sum], 0(%[cc]) \n\t" 92 | "bgtz %[dim_cc], 3b \n\t" 93 | " addiu %[cc], %[cc], 4 \n\t" 94 | "6: \n\t" 95 | ".set pop \n\t" 96 | : [step_seq2] "+r" (step_seq2), [t0] "=&r" (t0), [t1] "=&r" (t1), 97 | [t2] "=&r" (t2), [t3] "=&r" (t3), [pseq1] "=&r" (pseq1), 98 | [pseq2] "=&r" (pseq2), [pseq1_0] "+r" (pseq1_0), [pseq2_0] "+r" (pseq2_0), 99 | [k] "=&r" (k), [dim_cc] "+r" (dim_cross_correlation), [sum] "=&r" (sum), 100 | [cc] "+r" (cross_correlation) 101 | : [dim_seq] "r" (dim_seq), [right_shifts] "r" (right_shifts) 102 | : "hi", "lo", "memory" 103 | ); 104 | } 105 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/common_audio/vad/vad_sp.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #include "common_audio/vad/vad_sp.h" 12 | 13 | #include "rtc_base/checks.h" 14 | #include "common_audio/signal_processing/include/signal_processing_library.h" 15 | #include "common_audio/vad/vad_core.h" 16 | #include "typedefs.h" // NOLINT(build/include) 17 | 18 | // Allpass filter coefficients, upper and lower, in Q13. 19 | // Upper: 0.64, Lower: 0.17. 20 | static const int16_t kAllPassCoefsQ13[2] = { 5243, 1392 }; // Q13. 21 | static const int16_t kSmoothingDown = 6553; // 0.2 in Q15. 22 | static const int16_t kSmoothingUp = 32439; // 0.99 in Q15. 23 | 24 | // TODO(bjornv): Move this function to vad_filterbank.c. 25 | // Downsampling filter based on splitting filter and allpass functions. 26 | void WebRtcVad_Downsampling(const int16_t* signal_in, 27 | int16_t* signal_out, 28 | int32_t* filter_state, 29 | size_t in_length) { 30 | int16_t tmp16_1 = 0, tmp16_2 = 0; 31 | int32_t tmp32_1 = filter_state[0]; 32 | int32_t tmp32_2 = filter_state[1]; 33 | size_t n = 0; 34 | // Downsampling by 2 gives half length. 35 | size_t half_length = (in_length >> 1); 36 | 37 | // Filter coefficients in Q13, filter state in Q0. 38 | for (n = 0; n < half_length; n++) { 39 | // All-pass filtering upper branch. 40 | tmp16_1 = (int16_t) ((tmp32_1 >> 1) + 41 | ((kAllPassCoefsQ13[0] * *signal_in) >> 14)); 42 | *signal_out = tmp16_1; 43 | tmp32_1 = (int32_t)(*signal_in++) - ((kAllPassCoefsQ13[0] * tmp16_1) >> 12); 44 | 45 | // All-pass filtering lower branch. 46 | tmp16_2 = (int16_t) ((tmp32_2 >> 1) + 47 | ((kAllPassCoefsQ13[1] * *signal_in) >> 14)); 48 | *signal_out++ += tmp16_2; 49 | tmp32_2 = (int32_t)(*signal_in++) - ((kAllPassCoefsQ13[1] * tmp16_2) >> 12); 50 | } 51 | // Store the filter states. 52 | filter_state[0] = tmp32_1; 53 | filter_state[1] = tmp32_2; 54 | } 55 | 56 | // Inserts |feature_value| into |low_value_vector|, if it is one of the 16 57 | // smallest values the last 100 frames. Then calculates and returns the median 58 | // of the five smallest values. 59 | int16_t WebRtcVad_FindMinimum(VadInstT* self, 60 | int16_t feature_value, 61 | int channel) { 62 | int i = 0, j = 0; 63 | int position = -1; 64 | // Offset to beginning of the 16 minimum values in memory. 65 | const int offset = (channel << 4); 66 | int16_t current_median = 1600; 67 | int16_t alpha = 0; 68 | int32_t tmp32 = 0; 69 | // Pointer to memory for the 16 minimum values and the age of each value of 70 | // the |channel|. 71 | int16_t* age = &self->index_vector[offset]; 72 | int16_t* smallest_values = &self->low_value_vector[offset]; 73 | 74 | RTC_DCHECK_LT(channel, kNumChannels); 75 | 76 | // Each value in |smallest_values| is getting 1 loop older. Update |age|, and 77 | // remove old values. 78 | for (i = 0; i < 16; i++) { 79 | if (age[i] != 100) { 80 | age[i]++; 81 | } else { 82 | // Too old value. Remove from memory and shift larger values downwards. 83 | for (j = i; j < 16; j++) { 84 | smallest_values[j] = smallest_values[j + 1]; 85 | age[j] = age[j + 1]; 86 | } 87 | age[15] = 101; 88 | smallest_values[15] = 10000; 89 | } 90 | } 91 | 92 | // Check if |feature_value| is smaller than any of the values in 93 | // |smallest_values|. If so, find the |position| where to insert the new value 94 | // (|feature_value|). 95 | if (feature_value < smallest_values[7]) { 96 | if (feature_value < smallest_values[3]) { 97 | if (feature_value < smallest_values[1]) { 98 | if (feature_value < smallest_values[0]) { 99 | position = 0; 100 | } else { 101 | position = 1; 102 | } 103 | } else if (feature_value < smallest_values[2]) { 104 | position = 2; 105 | } else { 106 | position = 3; 107 | } 108 | } else if (feature_value < smallest_values[5]) { 109 | if (feature_value < smallest_values[4]) { 110 | position = 4; 111 | } else { 112 | position = 5; 113 | } 114 | } else if (feature_value < smallest_values[6]) { 115 | position = 6; 116 | } else { 117 | position = 7; 118 | } 119 | } else if (feature_value < smallest_values[15]) { 120 | if (feature_value < smallest_values[11]) { 121 | if (feature_value < smallest_values[9]) { 122 | if (feature_value < smallest_values[8]) { 123 | position = 8; 124 | } else { 125 | position = 9; 126 | } 127 | } else if (feature_value < smallest_values[10]) { 128 | position = 10; 129 | } else { 130 | position = 11; 131 | } 132 | } else if (feature_value < smallest_values[13]) { 133 | if (feature_value < smallest_values[12]) { 134 | position = 12; 135 | } else { 136 | position = 13; 137 | } 138 | } else if (feature_value < smallest_values[14]) { 139 | position = 14; 140 | } else { 141 | position = 15; 142 | } 143 | } 144 | 145 | // If we have detected a new small value, insert it at the correct position 146 | // and shift larger values up. 147 | if (position > -1) { 148 | for (i = 15; i > position; i--) { 149 | smallest_values[i] = smallest_values[i - 1]; 150 | age[i] = age[i - 1]; 151 | } 152 | smallest_values[position] = feature_value; 153 | age[position] = 1; 154 | } 155 | 156 | // Get |current_median|. 157 | if (self->frame_counter > 2) { 158 | current_median = smallest_values[2]; 159 | } else if (self->frame_counter > 0) { 160 | current_median = smallest_values[0]; 161 | } 162 | 163 | // Smooth the median value. 164 | if (self->frame_counter > 0) { 165 | if (current_median < self->mean_value[channel]) { 166 | alpha = kSmoothingDown; // 0.2 in Q15. 167 | } else { 168 | alpha = kSmoothingUp; // 0.99 in Q15. 169 | } 170 | } 171 | tmp32 = (alpha + 1) * self->mean_value[channel]; 172 | tmp32 += (WEBRTC_SPL_WORD16_MAX - alpha) * current_median; 173 | tmp32 += 16384; 174 | self->mean_value[channel] = (int16_t) (tmp32 >> 15); 175 | 176 | return self->mean_value[channel]; 177 | } 178 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/common_audio/signal_processing/resample_48khz.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | 12 | /* 13 | * This file contains resampling functions between 48 kHz and nb/wb. 14 | * The description header can be found in signal_processing_library.h 15 | * 16 | */ 17 | 18 | #include 19 | #include "common_audio/signal_processing/include/signal_processing_library.h" 20 | #include "common_audio/signal_processing/resample_by_2_internal.h" 21 | 22 | //////////////////////////// 23 | ///// 48 kHz -> 16 kHz ///// 24 | //////////////////////////// 25 | 26 | // 48 -> 16 resampler 27 | void WebRtcSpl_Resample48khzTo16khz(const int16_t* in, int16_t* out, 28 | WebRtcSpl_State48khzTo16khz* state, int32_t* tmpmem) 29 | { 30 | ///// 48 --> 48(LP) ///// 31 | // int16_t in[480] 32 | // int32_t out[480] 33 | ///// 34 | WebRtcSpl_LPBy2ShortToInt(in, 480, tmpmem + 16, state->S_48_48); 35 | 36 | ///// 48 --> 32 ///// 37 | // int32_t in[480] 38 | // int32_t out[320] 39 | ///// 40 | // copy state to and from input array 41 | memcpy(tmpmem + 8, state->S_48_32, 8 * sizeof(int32_t)); 42 | memcpy(state->S_48_32, tmpmem + 488, 8 * sizeof(int32_t)); 43 | WebRtcSpl_Resample48khzTo32khz(tmpmem + 8, tmpmem, 160); 44 | 45 | ///// 32 --> 16 ///// 46 | // int32_t in[320] 47 | // int16_t out[160] 48 | ///// 49 | WebRtcSpl_DownBy2IntToShort(tmpmem, 320, out, state->S_32_16); 50 | } 51 | 52 | // initialize state of 48 -> 16 resampler 53 | void WebRtcSpl_ResetResample48khzTo16khz(WebRtcSpl_State48khzTo16khz* state) 54 | { 55 | memset(state->S_48_48, 0, 16 * sizeof(int32_t)); 56 | memset(state->S_48_32, 0, 8 * sizeof(int32_t)); 57 | memset(state->S_32_16, 0, 8 * sizeof(int32_t)); 58 | } 59 | 60 | //////////////////////////// 61 | ///// 16 kHz -> 48 kHz ///// 62 | //////////////////////////// 63 | 64 | // 16 -> 48 resampler 65 | void WebRtcSpl_Resample16khzTo48khz(const int16_t* in, int16_t* out, 66 | WebRtcSpl_State16khzTo48khz* state, int32_t* tmpmem) 67 | { 68 | ///// 16 --> 32 ///// 69 | // int16_t in[160] 70 | // int32_t out[320] 71 | ///// 72 | WebRtcSpl_UpBy2ShortToInt(in, 160, tmpmem + 16, state->S_16_32); 73 | 74 | ///// 32 --> 24 ///// 75 | // int32_t in[320] 76 | // int32_t out[240] 77 | // copy state to and from input array 78 | ///// 79 | memcpy(tmpmem + 8, state->S_32_24, 8 * sizeof(int32_t)); 80 | memcpy(state->S_32_24, tmpmem + 328, 8 * sizeof(int32_t)); 81 | WebRtcSpl_Resample32khzTo24khz(tmpmem + 8, tmpmem, 80); 82 | 83 | ///// 24 --> 48 ///// 84 | // int32_t in[240] 85 | // int16_t out[480] 86 | ///// 87 | WebRtcSpl_UpBy2IntToShort(tmpmem, 240, out, state->S_24_48); 88 | } 89 | 90 | // initialize state of 16 -> 48 resampler 91 | void WebRtcSpl_ResetResample16khzTo48khz(WebRtcSpl_State16khzTo48khz* state) 92 | { 93 | memset(state->S_16_32, 0, 8 * sizeof(int32_t)); 94 | memset(state->S_32_24, 0, 8 * sizeof(int32_t)); 95 | memset(state->S_24_48, 0, 8 * sizeof(int32_t)); 96 | } 97 | 98 | //////////////////////////// 99 | ///// 48 kHz -> 8 kHz ///// 100 | //////////////////////////// 101 | 102 | // 48 -> 8 resampler 103 | void WebRtcSpl_Resample48khzTo8khz(const int16_t* in, int16_t* out, 104 | WebRtcSpl_State48khzTo8khz* state, int32_t* tmpmem) 105 | { 106 | ///// 48 --> 24 ///// 107 | // int16_t in[480] 108 | // int32_t out[240] 109 | ///// 110 | WebRtcSpl_DownBy2ShortToInt(in, 480, tmpmem + 256, state->S_48_24); 111 | 112 | ///// 24 --> 24(LP) ///// 113 | // int32_t in[240] 114 | // int32_t out[240] 115 | ///// 116 | WebRtcSpl_LPBy2IntToInt(tmpmem + 256, 240, tmpmem + 16, state->S_24_24); 117 | 118 | ///// 24 --> 16 ///// 119 | // int32_t in[240] 120 | // int32_t out[160] 121 | ///// 122 | // copy state to and from input array 123 | memcpy(tmpmem + 8, state->S_24_16, 8 * sizeof(int32_t)); 124 | memcpy(state->S_24_16, tmpmem + 248, 8 * sizeof(int32_t)); 125 | WebRtcSpl_Resample48khzTo32khz(tmpmem + 8, tmpmem, 80); 126 | 127 | ///// 16 --> 8 ///// 128 | // int32_t in[160] 129 | // int16_t out[80] 130 | ///// 131 | WebRtcSpl_DownBy2IntToShort(tmpmem, 160, out, state->S_16_8); 132 | } 133 | 134 | // initialize state of 48 -> 8 resampler 135 | void WebRtcSpl_ResetResample48khzTo8khz(WebRtcSpl_State48khzTo8khz* state) 136 | { 137 | memset(state->S_48_24, 0, 8 * sizeof(int32_t)); 138 | memset(state->S_24_24, 0, 16 * sizeof(int32_t)); 139 | memset(state->S_24_16, 0, 8 * sizeof(int32_t)); 140 | memset(state->S_16_8, 0, 8 * sizeof(int32_t)); 141 | } 142 | 143 | //////////////////////////// 144 | ///// 8 kHz -> 48 kHz ///// 145 | //////////////////////////// 146 | 147 | // 8 -> 48 resampler 148 | void WebRtcSpl_Resample8khzTo48khz(const int16_t* in, int16_t* out, 149 | WebRtcSpl_State8khzTo48khz* state, int32_t* tmpmem) 150 | { 151 | ///// 8 --> 16 ///// 152 | // int16_t in[80] 153 | // int32_t out[160] 154 | ///// 155 | WebRtcSpl_UpBy2ShortToInt(in, 80, tmpmem + 264, state->S_8_16); 156 | 157 | ///// 16 --> 12 ///// 158 | // int32_t in[160] 159 | // int32_t out[120] 160 | ///// 161 | // copy state to and from input array 162 | memcpy(tmpmem + 256, state->S_16_12, 8 * sizeof(int32_t)); 163 | memcpy(state->S_16_12, tmpmem + 416, 8 * sizeof(int32_t)); 164 | WebRtcSpl_Resample32khzTo24khz(tmpmem + 256, tmpmem + 240, 40); 165 | 166 | ///// 12 --> 24 ///// 167 | // int32_t in[120] 168 | // int16_t out[240] 169 | ///// 170 | WebRtcSpl_UpBy2IntToInt(tmpmem + 240, 120, tmpmem, state->S_12_24); 171 | 172 | ///// 24 --> 48 ///// 173 | // int32_t in[240] 174 | // int16_t out[480] 175 | ///// 176 | WebRtcSpl_UpBy2IntToShort(tmpmem, 240, out, state->S_24_48); 177 | } 178 | 179 | // initialize state of 8 -> 48 resampler 180 | void WebRtcSpl_ResetResample8khzTo48khz(WebRtcSpl_State8khzTo48khz* state) 181 | { 182 | memset(state->S_8_16, 0, 8 * sizeof(int32_t)); 183 | memset(state->S_16_12, 0, 8 * sizeof(int32_t)); 184 | memset(state->S_12_24, 0, 8 * sizeof(int32_t)); 185 | memset(state->S_24_48, 0, 8 * sizeof(int32_t)); 186 | } 187 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/rtc_base/numerics/safe_compare.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 The WebRTC Project Authors. All rights reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | // This file defines six constexpr functions: 12 | // 13 | // rtc::SafeEq // == 14 | // rtc::SafeNe // != 15 | // rtc::SafeLt // < 16 | // rtc::SafeLe // <= 17 | // rtc::SafeGt // > 18 | // rtc::SafeGe // >= 19 | // 20 | // They each accept two arguments of arbitrary types, and in almost all cases, 21 | // they simply call the appropriate comparison operator. However, if both 22 | // arguments are integers, they don't compare them using C++'s quirky rules, 23 | // but instead adhere to the true mathematical definitions. It is as if the 24 | // arguments were first converted to infinite-range signed integers, and then 25 | // compared, although of course nothing expensive like that actually takes 26 | // place. In practice, for signed/signed and unsigned/unsigned comparisons and 27 | // some mixed-signed comparisons with a compile-time constant, the overhead is 28 | // zero; in the remaining cases, it is just a few machine instructions (no 29 | // branches). 30 | 31 | #ifndef RTC_BASE_NUMERICS_SAFE_COMPARE_H_ 32 | #define RTC_BASE_NUMERICS_SAFE_COMPARE_H_ 33 | 34 | #include 35 | #include 36 | 37 | #include 38 | #include 39 | 40 | #include "rtc_base/type_traits.h" 41 | 42 | namespace rtc { 43 | 44 | namespace safe_cmp_impl { 45 | 46 | template 47 | struct LargerIntImpl : std::false_type {}; 48 | template <> 49 | struct LargerIntImpl : std::true_type { 50 | using type = int16_t; 51 | }; 52 | template <> 53 | struct LargerIntImpl : std::true_type { 54 | using type = int32_t; 55 | }; 56 | template <> 57 | struct LargerIntImpl : std::true_type { 58 | using type = int64_t; 59 | }; 60 | 61 | // LargerInt::value is true iff there's a signed type that's larger 62 | // than T1 (and no larger than the larger of T2 and int*, for performance 63 | // reasons); and if there is such a type, LargerInt::type is an alias 64 | // for it. 65 | template 66 | struct LargerInt 67 | : LargerIntImpl {}; 70 | 71 | template 72 | constexpr typename std::make_unsigned::type MakeUnsigned(T a) { 73 | return static_cast::type>(a); 74 | } 75 | 76 | // Overload for when both T1 and T2 have the same signedness. 77 | template ::value == 81 | std::is_signed::value>::type* = nullptr> 82 | constexpr bool Cmp(T1 a, T2 b) { 83 | return Op::Op(a, b); 84 | } 85 | 86 | // Overload for signed - unsigned comparison that can be promoted to a bigger 87 | // signed type. 88 | template ::value && 92 | std::is_unsigned::value && 93 | LargerInt::value>::type* = nullptr> 94 | constexpr bool Cmp(T1 a, T2 b) { 95 | return Op::Op(a, static_cast::type>(b)); 96 | } 97 | 98 | // Overload for unsigned - signed comparison that can be promoted to a bigger 99 | // signed type. 100 | template ::value && 104 | std::is_signed::value && 105 | LargerInt::value>::type* = nullptr> 106 | constexpr bool Cmp(T1 a, T2 b) { 107 | return Op::Op(static_cast::type>(a), b); 108 | } 109 | 110 | // Overload for signed - unsigned comparison that can't be promoted to a bigger 111 | // signed type. 112 | template ::value && 116 | std::is_unsigned::value && 117 | !LargerInt::value>::type* = nullptr> 118 | constexpr bool Cmp(T1 a, T2 b) { 119 | return a < 0 ? Op::Op(-1, 0) : Op::Op(safe_cmp_impl::MakeUnsigned(a), b); 120 | } 121 | 122 | // Overload for unsigned - signed comparison that can't be promoted to a bigger 123 | // signed type. 124 | template ::value && 128 | std::is_signed::value && 129 | !LargerInt::value>::type* = nullptr> 130 | constexpr bool Cmp(T1 a, T2 b) { 131 | return b < 0 ? Op::Op(0, -1) : Op::Op(a, safe_cmp_impl::MakeUnsigned(b)); 132 | } 133 | 134 | #define RTC_SAFECMP_MAKE_OP(name, op) \ 135 | struct name { \ 136 | template \ 137 | static constexpr bool Op(T1 a, T2 b) { \ 138 | return a op b; \ 139 | } \ 140 | }; 141 | RTC_SAFECMP_MAKE_OP(EqOp, ==) 142 | RTC_SAFECMP_MAKE_OP(NeOp, !=) 143 | RTC_SAFECMP_MAKE_OP(LtOp, <) 144 | RTC_SAFECMP_MAKE_OP(LeOp, <=) 145 | RTC_SAFECMP_MAKE_OP(GtOp, >) 146 | RTC_SAFECMP_MAKE_OP(GeOp, >=) 147 | #undef RTC_SAFECMP_MAKE_OP 148 | 149 | } // namespace safe_cmp_impl 150 | 151 | #define RTC_SAFECMP_MAKE_FUN(name) \ 152 | template \ 153 | constexpr \ 154 | typename std::enable_if::value && IsIntlike::value, \ 155 | bool>::type Safe##name(T1 a, T2 b) { \ 156 | /* Unary plus here turns enums into real integral types. */ \ 157 | return safe_cmp_impl::Cmp(+a, +b); \ 158 | } \ 159 | template \ 160 | constexpr \ 161 | typename std::enable_if::value || !IsIntlike::value, \ 162 | bool>::type Safe##name(const T1& a, \ 163 | const T2& b) { \ 164 | return safe_cmp_impl::name##Op::Op(a, b); \ 165 | } 166 | RTC_SAFECMP_MAKE_FUN(Eq) 167 | RTC_SAFECMP_MAKE_FUN(Ne) 168 | RTC_SAFECMP_MAKE_FUN(Lt) 169 | RTC_SAFECMP_MAKE_FUN(Le) 170 | RTC_SAFECMP_MAKE_FUN(Gt) 171 | RTC_SAFECMP_MAKE_FUN(Ge) 172 | #undef RTC_SAFECMP_MAKE_FUN 173 | 174 | } // namespace rtc 175 | 176 | #endif // RTC_BASE_NUMERICS_SAFE_COMPARE_H_ 177 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/common_audio/signal_processing/include/spl_inl_mips.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | 12 | // This header file includes the inline functions in 13 | // the fix point signal processing library. 14 | 15 | #ifndef COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_SPL_INL_MIPS_H_ 16 | #define COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_SPL_INL_MIPS_H_ 17 | 18 | static __inline int32_t WEBRTC_SPL_MUL_16_16(int32_t a, 19 | int32_t b) { 20 | int32_t value32 = 0; 21 | int32_t a1 = 0, b1 = 0; 22 | 23 | __asm __volatile( 24 | #if defined(MIPS32_R2_LE) 25 | "seh %[a1], %[a] \n\t" 26 | "seh %[b1], %[b] \n\t" 27 | #else 28 | "sll %[a1], %[a], 16 \n\t" 29 | "sll %[b1], %[b], 16 \n\t" 30 | "sra %[a1], %[a1], 16 \n\t" 31 | "sra %[b1], %[b1], 16 \n\t" 32 | #endif 33 | "mul %[value32], %[a1], %[b1] \n\t" 34 | : [value32] "=r" (value32), [a1] "=&r" (a1), [b1] "=&r" (b1) 35 | : [a] "r" (a), [b] "r" (b) 36 | : "hi", "lo"); 37 | return value32; 38 | } 39 | 40 | static __inline int32_t WEBRTC_SPL_MUL_16_32_RSFT16(int16_t a, 41 | int32_t b) { 42 | int32_t value32 = 0, b1 = 0, b2 = 0; 43 | int32_t a1 = 0; 44 | 45 | __asm __volatile( 46 | #if defined(MIPS32_R2_LE) 47 | "seh %[a1], %[a] \n\t" 48 | #else 49 | "sll %[a1], %[a], 16 \n\t" 50 | "sra %[a1], %[a1], 16 \n\t" 51 | #endif 52 | "andi %[b2], %[b], 0xFFFF \n\t" 53 | "sra %[b1], %[b], 16 \n\t" 54 | "sra %[b2], %[b2], 1 \n\t" 55 | "mul %[value32], %[a1], %[b1] \n\t" 56 | "mul %[b2], %[a1], %[b2] \n\t" 57 | "addiu %[b2], %[b2], 0x4000 \n\t" 58 | "sra %[b2], %[b2], 15 \n\t" 59 | "addu %[value32], %[value32], %[b2] \n\t" 60 | : [value32] "=&r" (value32), [b1] "=&r" (b1), [b2] "=&r" (b2), 61 | [a1] "=&r" (a1) 62 | : [a] "r" (a), [b] "r" (b) 63 | : "hi", "lo"); 64 | return value32; 65 | } 66 | 67 | #if defined(MIPS_DSP_R1_LE) 68 | static __inline int16_t WebRtcSpl_SatW32ToW16(int32_t value32) { 69 | __asm __volatile( 70 | "shll_s.w %[value32], %[value32], 16 \n\t" 71 | "sra %[value32], %[value32], 16 \n\t" 72 | : [value32] "+r" (value32) 73 | :); 74 | int16_t out16 = (int16_t)value32; 75 | return out16; 76 | } 77 | 78 | static __inline int16_t WebRtcSpl_AddSatW16(int16_t a, int16_t b) { 79 | int32_t value32 = 0; 80 | 81 | __asm __volatile( 82 | "addq_s.ph %[value32], %[a], %[b] \n\t" 83 | : [value32] "=r" (value32) 84 | : [a] "r" (a), [b] "r" (b) ); 85 | return (int16_t)value32; 86 | } 87 | 88 | static __inline int32_t WebRtcSpl_AddSatW32(int32_t l_var1, int32_t l_var2) { 89 | int32_t l_sum; 90 | 91 | __asm __volatile( 92 | "addq_s.w %[l_sum], %[l_var1], %[l_var2] \n\t" 93 | : [l_sum] "=r" (l_sum) 94 | : [l_var1] "r" (l_var1), [l_var2] "r" (l_var2) ); 95 | 96 | return l_sum; 97 | } 98 | 99 | static __inline int16_t WebRtcSpl_SubSatW16(int16_t var1, int16_t var2) { 100 | int32_t value32; 101 | 102 | __asm __volatile( 103 | "subq_s.ph %[value32], %[var1], %[var2] \n\t" 104 | : [value32] "=r" (value32) 105 | : [var1] "r" (var1), [var2] "r" (var2) ); 106 | 107 | return (int16_t)value32; 108 | } 109 | 110 | static __inline int32_t WebRtcSpl_SubSatW32(int32_t l_var1, int32_t l_var2) { 111 | int32_t l_diff; 112 | 113 | __asm __volatile( 114 | "subq_s.w %[l_diff], %[l_var1], %[l_var2] \n\t" 115 | : [l_diff] "=r" (l_diff) 116 | : [l_var1] "r" (l_var1), [l_var2] "r" (l_var2) ); 117 | 118 | return l_diff; 119 | } 120 | #endif 121 | 122 | static __inline int16_t WebRtcSpl_GetSizeInBits(uint32_t n) { 123 | int bits = 0; 124 | int i32 = 32; 125 | 126 | __asm __volatile( 127 | "clz %[bits], %[n] \n\t" 128 | "subu %[bits], %[i32], %[bits] \n\t" 129 | : [bits] "=&r" (bits) 130 | : [n] "r" (n), [i32] "r" (i32) ); 131 | 132 | return (int16_t)bits; 133 | } 134 | 135 | static __inline int16_t WebRtcSpl_NormW32(int32_t a) { 136 | int zeros = 0; 137 | 138 | __asm __volatile( 139 | ".set push \n\t" 140 | ".set noreorder \n\t" 141 | "bnez %[a], 1f \n\t" 142 | " sra %[zeros], %[a], 31 \n\t" 143 | "b 2f \n\t" 144 | " move %[zeros], $zero \n\t" 145 | "1: \n\t" 146 | "xor %[zeros], %[a], %[zeros] \n\t" 147 | "clz %[zeros], %[zeros] \n\t" 148 | "addiu %[zeros], %[zeros], -1 \n\t" 149 | "2: \n\t" 150 | ".set pop \n\t" 151 | : [zeros]"=&r"(zeros) 152 | : [a] "r" (a) ); 153 | 154 | return (int16_t)zeros; 155 | } 156 | 157 | static __inline int16_t WebRtcSpl_NormU32(uint32_t a) { 158 | int zeros = 0; 159 | 160 | __asm __volatile( 161 | "clz %[zeros], %[a] \n\t" 162 | : [zeros] "=r" (zeros) 163 | : [a] "r" (a) ); 164 | 165 | return (int16_t)(zeros & 0x1f); 166 | } 167 | 168 | static __inline int16_t WebRtcSpl_NormW16(int16_t a) { 169 | int zeros = 0; 170 | int a0 = a << 16; 171 | 172 | __asm __volatile( 173 | ".set push \n\t" 174 | ".set noreorder \n\t" 175 | "bnez %[a0], 1f \n\t" 176 | " sra %[zeros], %[a0], 31 \n\t" 177 | "b 2f \n\t" 178 | " move %[zeros], $zero \n\t" 179 | "1: \n\t" 180 | "xor %[zeros], %[a0], %[zeros] \n\t" 181 | "clz %[zeros], %[zeros] \n\t" 182 | "addiu %[zeros], %[zeros], -1 \n\t" 183 | "2: \n\t" 184 | ".set pop \n\t" 185 | : [zeros]"=&r"(zeros) 186 | : [a0] "r" (a0) ); 187 | 188 | return (int16_t)zeros; 189 | } 190 | 191 | static __inline int32_t WebRtc_MulAccumW16(int16_t a, 192 | int16_t b, 193 | int32_t c) { 194 | int32_t res = 0, c1 = 0; 195 | __asm __volatile( 196 | #if defined(MIPS32_R2_LE) 197 | "seh %[a], %[a] \n\t" 198 | "seh %[b], %[b] \n\t" 199 | #else 200 | "sll %[a], %[a], 16 \n\t" 201 | "sll %[b], %[b], 16 \n\t" 202 | "sra %[a], %[a], 16 \n\t" 203 | "sra %[b], %[b], 16 \n\t" 204 | #endif 205 | "mul %[res], %[a], %[b] \n\t" 206 | "addu %[c1], %[c], %[res] \n\t" 207 | : [c1] "=r" (c1), [res] "=&r" (res) 208 | : [a] "r" (a), [b] "r" (b), [c] "r" (c) 209 | : "hi", "lo"); 210 | return (c1); 211 | } 212 | 213 | #endif // COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_SPL_INL_MIPS_H_ 214 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/common_audio/signal_processing/resample_fractional.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | 12 | /* 13 | * This file contains the resampling functions between 48, 44, 32 and 24 kHz. 14 | * The description headers can be found in signal_processing_library.h 15 | * 16 | */ 17 | 18 | #include "common_audio/signal_processing/include/signal_processing_library.h" 19 | 20 | // interpolation coefficients 21 | static const int16_t kCoefficients48To32[2][8] = { 22 | {778, -2050, 1087, 23285, 12903, -3783, 441, 222}, 23 | {222, 441, -3783, 12903, 23285, 1087, -2050, 778} 24 | }; 25 | 26 | static const int16_t kCoefficients32To24[3][8] = { 27 | {767, -2362, 2434, 24406, 10620, -3838, 721, 90}, 28 | {386, -381, -2646, 19062, 19062, -2646, -381, 386}, 29 | {90, 721, -3838, 10620, 24406, 2434, -2362, 767} 30 | }; 31 | 32 | static const int16_t kCoefficients44To32[4][9] = { 33 | {117, -669, 2245, -6183, 26267, 13529, -3245, 845, -138}, 34 | {-101, 612, -2283, 8532, 29790, -5138, 1789, -524, 91}, 35 | {50, -292, 1016, -3064, 32010, 3933, -1147, 315, -53}, 36 | {-156, 974, -3863, 18603, 21691, -6246, 2353, -712, 126} 37 | }; 38 | 39 | // Resampling ratio: 2/3 40 | // input: int32_t (normalized, not saturated) :: current_frame 3 * K 41 | // output: int32_t (shifted 15 positions to the left, + offset 16384) :: current_frame 2 * K 42 | // K: number of blocks 43 | 44 | void WebRtcSpl_Resample48khzTo32khz(const int32_t *In, int32_t *Out, size_t K) 45 | { 46 | ///////////////////////////////////////////////////////////// 47 | // Filter operation: 48 | // 49 | // Perform resampling (3 input samples -> 2 output samples); 50 | // process in sub blocks of current_frame 3 samples. 51 | int32_t tmp; 52 | size_t m; 53 | 54 | for (m = 0; m < K; m++) 55 | { 56 | tmp = 1 << 14; 57 | tmp += kCoefficients48To32[0][0] * In[0]; 58 | tmp += kCoefficients48To32[0][1] * In[1]; 59 | tmp += kCoefficients48To32[0][2] * In[2]; 60 | tmp += kCoefficients48To32[0][3] * In[3]; 61 | tmp += kCoefficients48To32[0][4] * In[4]; 62 | tmp += kCoefficients48To32[0][5] * In[5]; 63 | tmp += kCoefficients48To32[0][6] * In[6]; 64 | tmp += kCoefficients48To32[0][7] * In[7]; 65 | Out[0] = tmp; 66 | 67 | tmp = 1 << 14; 68 | tmp += kCoefficients48To32[1][0] * In[1]; 69 | tmp += kCoefficients48To32[1][1] * In[2]; 70 | tmp += kCoefficients48To32[1][2] * In[3]; 71 | tmp += kCoefficients48To32[1][3] * In[4]; 72 | tmp += kCoefficients48To32[1][4] * In[5]; 73 | tmp += kCoefficients48To32[1][5] * In[6]; 74 | tmp += kCoefficients48To32[1][6] * In[7]; 75 | tmp += kCoefficients48To32[1][7] * In[8]; 76 | Out[1] = tmp; 77 | 78 | // update pointers 79 | In += 3; 80 | Out += 2; 81 | } 82 | } 83 | 84 | // Resampling ratio: 3/4 85 | // input: int32_t (normalized, not saturated) :: current_frame 4 * K 86 | // output: int32_t (shifted 15 positions to the left, + offset 16384) :: current_frame 3 * K 87 | // K: number of blocks 88 | 89 | void WebRtcSpl_Resample32khzTo24khz(const int32_t *In, int32_t *Out, size_t K) 90 | { 91 | ///////////////////////////////////////////////////////////// 92 | // Filter operation: 93 | // 94 | // Perform resampling (4 input samples -> 3 output samples); 95 | // process in sub blocks of current_frame 4 samples. 96 | size_t m; 97 | int32_t tmp; 98 | 99 | for (m = 0; m < K; m++) 100 | { 101 | tmp = 1 << 14; 102 | tmp += kCoefficients32To24[0][0] * In[0]; 103 | tmp += kCoefficients32To24[0][1] * In[1]; 104 | tmp += kCoefficients32To24[0][2] * In[2]; 105 | tmp += kCoefficients32To24[0][3] * In[3]; 106 | tmp += kCoefficients32To24[0][4] * In[4]; 107 | tmp += kCoefficients32To24[0][5] * In[5]; 108 | tmp += kCoefficients32To24[0][6] * In[6]; 109 | tmp += kCoefficients32To24[0][7] * In[7]; 110 | Out[0] = tmp; 111 | 112 | tmp = 1 << 14; 113 | tmp += kCoefficients32To24[1][0] * In[1]; 114 | tmp += kCoefficients32To24[1][1] * In[2]; 115 | tmp += kCoefficients32To24[1][2] * In[3]; 116 | tmp += kCoefficients32To24[1][3] * In[4]; 117 | tmp += kCoefficients32To24[1][4] * In[5]; 118 | tmp += kCoefficients32To24[1][5] * In[6]; 119 | tmp += kCoefficients32To24[1][6] * In[7]; 120 | tmp += kCoefficients32To24[1][7] * In[8]; 121 | Out[1] = tmp; 122 | 123 | tmp = 1 << 14; 124 | tmp += kCoefficients32To24[2][0] * In[2]; 125 | tmp += kCoefficients32To24[2][1] * In[3]; 126 | tmp += kCoefficients32To24[2][2] * In[4]; 127 | tmp += kCoefficients32To24[2][3] * In[5]; 128 | tmp += kCoefficients32To24[2][4] * In[6]; 129 | tmp += kCoefficients32To24[2][5] * In[7]; 130 | tmp += kCoefficients32To24[2][6] * In[8]; 131 | tmp += kCoefficients32To24[2][7] * In[9]; 132 | Out[2] = tmp; 133 | 134 | // update pointers 135 | In += 4; 136 | Out += 3; 137 | } 138 | } 139 | 140 | // 141 | // fractional resampling filters 142 | // Fout = 11/16 * Fin 143 | // Fout = 8/11 * Fin 144 | // 145 | 146 | // compute two inner-products and store them to output array 147 | static void WebRtcSpl_ResampDotProduct(const int32_t *in1, const int32_t *in2, 148 | const int16_t *coef_ptr, int32_t *out1, 149 | int32_t *out2) 150 | { 151 | int32_t tmp1 = 16384; 152 | int32_t tmp2 = 16384; 153 | int16_t coef; 154 | 155 | coef = coef_ptr[0]; 156 | tmp1 += coef * in1[0]; 157 | tmp2 += coef * in2[-0]; 158 | 159 | coef = coef_ptr[1]; 160 | tmp1 += coef * in1[1]; 161 | tmp2 += coef * in2[-1]; 162 | 163 | coef = coef_ptr[2]; 164 | tmp1 += coef * in1[2]; 165 | tmp2 += coef * in2[-2]; 166 | 167 | coef = coef_ptr[3]; 168 | tmp1 += coef * in1[3]; 169 | tmp2 += coef * in2[-3]; 170 | 171 | coef = coef_ptr[4]; 172 | tmp1 += coef * in1[4]; 173 | tmp2 += coef * in2[-4]; 174 | 175 | coef = coef_ptr[5]; 176 | tmp1 += coef * in1[5]; 177 | tmp2 += coef * in2[-5]; 178 | 179 | coef = coef_ptr[6]; 180 | tmp1 += coef * in1[6]; 181 | tmp2 += coef * in2[-6]; 182 | 183 | coef = coef_ptr[7]; 184 | tmp1 += coef * in1[7]; 185 | tmp2 += coef * in2[-7]; 186 | 187 | coef = coef_ptr[8]; 188 | *out1 = tmp1 + coef * in1[8]; 189 | *out2 = tmp2 + coef * in2[-8]; 190 | } 191 | 192 | // Resampling ratio: 8/11 193 | // input: int32_t (normalized, not saturated) :: current_frame 11 * K 194 | // output: int32_t (shifted 15 positions to the left, + offset 16384) :: current_frame 8 * K 195 | // K: number of blocks 196 | 197 | void WebRtcSpl_Resample44khzTo32khz(const int32_t *In, int32_t *Out, size_t K) 198 | { 199 | ///////////////////////////////////////////////////////////// 200 | // Filter operation: 201 | // 202 | // Perform resampling (11 input samples -> 8 output samples); 203 | // process in sub blocks of current_frame 11 samples. 204 | int32_t tmp; 205 | size_t m; 206 | 207 | for (m = 0; m < K; m++) 208 | { 209 | tmp = 1 << 14; 210 | 211 | // first output sample 212 | Out[0] = ((int32_t)In[3] << 15) + tmp; 213 | 214 | // sum and accumulate filter coefficients and input samples 215 | tmp += kCoefficients44To32[3][0] * In[5]; 216 | tmp += kCoefficients44To32[3][1] * In[6]; 217 | tmp += kCoefficients44To32[3][2] * In[7]; 218 | tmp += kCoefficients44To32[3][3] * In[8]; 219 | tmp += kCoefficients44To32[3][4] * In[9]; 220 | tmp += kCoefficients44To32[3][5] * In[10]; 221 | tmp += kCoefficients44To32[3][6] * In[11]; 222 | tmp += kCoefficients44To32[3][7] * In[12]; 223 | tmp += kCoefficients44To32[3][8] * In[13]; 224 | Out[4] = tmp; 225 | 226 | // sum and accumulate filter coefficients and input samples 227 | WebRtcSpl_ResampDotProduct(&In[0], &In[17], kCoefficients44To32[0], &Out[1], &Out[7]); 228 | 229 | // sum and accumulate filter coefficients and input samples 230 | WebRtcSpl_ResampDotProduct(&In[2], &In[15], kCoefficients44To32[1], &Out[2], &Out[6]); 231 | 232 | // sum and accumulate filter coefficients and input samples 233 | WebRtcSpl_ResampDotProduct(&In[3], &In[14], kCoefficients44To32[2], &Out[3], &Out[5]); 234 | 235 | // update pointers 236 | In += 11; 237 | Out += 8; 238 | } 239 | } 240 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/common_audio/signal_processing/min_max_operations_neon.c.neon: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #include 12 | #include 13 | 14 | #include "rtc_base/checks.h" 15 | #include "common_audio/signal_processing/include/signal_processing_library.h" 16 | 17 | // Maximum absolute value of word16 vector. C version for generic platforms. 18 | int16_t WebRtcSpl_MaxAbsValueW16Neon(const int16_t* vector, size_t length) { 19 | int absolute = 0, maximum = 0; 20 | 21 | RTC_DCHECK_GT(length, 0); 22 | 23 | const int16_t* p_start = vector; 24 | size_t rest = length & 7; 25 | const int16_t* p_end = vector + length - rest; 26 | 27 | int16x8_t v; 28 | uint16x8_t max_qv; 29 | max_qv = vdupq_n_u16(0); 30 | 31 | while (p_start < p_end) { 32 | v = vld1q_s16(p_start); 33 | // Note vabs doesn't change the value of -32768. 34 | v = vabsq_s16(v); 35 | // Use u16 so we don't lose the value -32768. 36 | max_qv = vmaxq_u16(max_qv, vreinterpretq_u16_s16(v)); 37 | p_start += 8; 38 | } 39 | 40 | #ifdef WEBRTC_ARCH_ARM64 41 | maximum = (int)vmaxvq_u16(max_qv); 42 | #else 43 | uint16x4_t max_dv; 44 | max_dv = vmax_u16(vget_low_u16(max_qv), vget_high_u16(max_qv)); 45 | max_dv = vpmax_u16(max_dv, max_dv); 46 | max_dv = vpmax_u16(max_dv, max_dv); 47 | 48 | maximum = (int)vget_lane_u16(max_dv, 0); 49 | #endif 50 | 51 | p_end = vector + length; 52 | while (p_start < p_end) { 53 | absolute = abs((int)(*p_start)); 54 | 55 | if (absolute > maximum) { 56 | maximum = absolute; 57 | } 58 | p_start++; 59 | } 60 | 61 | // Guard the case for abs(-32768). 62 | if (maximum > WEBRTC_SPL_WORD16_MAX) { 63 | maximum = WEBRTC_SPL_WORD16_MAX; 64 | } 65 | 66 | return (int16_t)maximum; 67 | } 68 | 69 | // Maximum absolute value of word32 vector. NEON intrinsics version for 70 | // ARM 32-bit/64-bit platforms. 71 | int32_t WebRtcSpl_MaxAbsValueW32Neon(const int32_t* vector, size_t length) { 72 | // Use uint32_t for the local variables, to accommodate the return value 73 | // of abs(0x80000000), which is 0x80000000. 74 | 75 | uint32_t absolute = 0, maximum = 0; 76 | size_t i = 0; 77 | size_t residual = length & 0x7; 78 | 79 | RTC_DCHECK_GT(length, 0); 80 | 81 | const int32_t* p_start = vector; 82 | uint32x4_t max32x4_0 = vdupq_n_u32(0); 83 | uint32x4_t max32x4_1 = vdupq_n_u32(0); 84 | 85 | // First part, unroll the loop 8 times. 86 | for (i = 0; i < length - residual; i += 8) { 87 | int32x4_t in32x4_0 = vld1q_s32(p_start); 88 | p_start += 4; 89 | int32x4_t in32x4_1 = vld1q_s32(p_start); 90 | p_start += 4; 91 | in32x4_0 = vabsq_s32(in32x4_0); 92 | in32x4_1 = vabsq_s32(in32x4_1); 93 | // vabs doesn't change the value of 0x80000000. 94 | // Use u32 so we don't lose the value 0x80000000. 95 | max32x4_0 = vmaxq_u32(max32x4_0, vreinterpretq_u32_s32(in32x4_0)); 96 | max32x4_1 = vmaxq_u32(max32x4_1, vreinterpretq_u32_s32(in32x4_1)); 97 | } 98 | 99 | uint32x4_t max32x4 = vmaxq_u32(max32x4_0, max32x4_1); 100 | #if defined(WEBRTC_ARCH_ARM64) 101 | maximum = vmaxvq_u32(max32x4); 102 | #else 103 | uint32x2_t max32x2 = vmax_u32(vget_low_u32(max32x4), vget_high_u32(max32x4)); 104 | max32x2 = vpmax_u32(max32x2, max32x2); 105 | 106 | maximum = vget_lane_u32(max32x2, 0); 107 | #endif 108 | 109 | // Second part, do the remaining iterations (if any). 110 | for (i = residual; i > 0; i--) { 111 | absolute = abs((int)(*p_start)); 112 | if (absolute > maximum) { 113 | maximum = absolute; 114 | } 115 | p_start++; 116 | } 117 | 118 | // Guard against the case for 0x80000000. 119 | maximum = WEBRTC_SPL_MIN(maximum, WEBRTC_SPL_WORD32_MAX); 120 | 121 | return (int32_t)maximum; 122 | } 123 | 124 | // Maximum value of word16 vector. NEON intrinsics version for 125 | // ARM 32-bit/64-bit platforms. 126 | int16_t WebRtcSpl_MaxValueW16Neon(const int16_t* vector, size_t length) { 127 | int16_t maximum = WEBRTC_SPL_WORD16_MIN; 128 | size_t i = 0; 129 | size_t residual = length & 0x7; 130 | 131 | RTC_DCHECK_GT(length, 0); 132 | 133 | const int16_t* p_start = vector; 134 | int16x8_t max16x8 = vdupq_n_s16(WEBRTC_SPL_WORD16_MIN); 135 | 136 | // First part, unroll the loop 8 times. 137 | for (i = 0; i < length - residual; i += 8) { 138 | int16x8_t in16x8 = vld1q_s16(p_start); 139 | max16x8 = vmaxq_s16(max16x8, in16x8); 140 | p_start += 8; 141 | } 142 | 143 | #if defined(WEBRTC_ARCH_ARM64) 144 | maximum = vmaxvq_s16(max16x8); 145 | #else 146 | int16x4_t max16x4 = vmax_s16(vget_low_s16(max16x8), vget_high_s16(max16x8)); 147 | max16x4 = vpmax_s16(max16x4, max16x4); 148 | max16x4 = vpmax_s16(max16x4, max16x4); 149 | 150 | maximum = vget_lane_s16(max16x4, 0); 151 | #endif 152 | 153 | // Second part, do the remaining iterations (if any). 154 | for (i = residual; i > 0; i--) { 155 | if (*p_start > maximum) 156 | maximum = *p_start; 157 | p_start++; 158 | } 159 | return maximum; 160 | } 161 | 162 | // Maximum value of word32 vector. NEON intrinsics version for 163 | // ARM 32-bit/64-bit platforms. 164 | int32_t WebRtcSpl_MaxValueW32Neon(const int32_t* vector, size_t length) { 165 | int32_t maximum = WEBRTC_SPL_WORD32_MIN; 166 | size_t i = 0; 167 | size_t residual = length & 0x7; 168 | 169 | RTC_DCHECK_GT(length, 0); 170 | 171 | const int32_t* p_start = vector; 172 | int32x4_t max32x4_0 = vdupq_n_s32(WEBRTC_SPL_WORD32_MIN); 173 | int32x4_t max32x4_1 = vdupq_n_s32(WEBRTC_SPL_WORD32_MIN); 174 | 175 | // First part, unroll the loop 8 times. 176 | for (i = 0; i < length - residual; i += 8) { 177 | int32x4_t in32x4_0 = vld1q_s32(p_start); 178 | p_start += 4; 179 | int32x4_t in32x4_1 = vld1q_s32(p_start); 180 | p_start += 4; 181 | max32x4_0 = vmaxq_s32(max32x4_0, in32x4_0); 182 | max32x4_1 = vmaxq_s32(max32x4_1, in32x4_1); 183 | } 184 | 185 | int32x4_t max32x4 = vmaxq_s32(max32x4_0, max32x4_1); 186 | #if defined(WEBRTC_ARCH_ARM64) 187 | maximum = vmaxvq_s32(max32x4); 188 | #else 189 | int32x2_t max32x2 = vmax_s32(vget_low_s32(max32x4), vget_high_s32(max32x4)); 190 | max32x2 = vpmax_s32(max32x2, max32x2); 191 | 192 | maximum = vget_lane_s32(max32x2, 0); 193 | #endif 194 | 195 | // Second part, do the remaining iterations (if any). 196 | for (i = residual; i > 0; i--) { 197 | if (*p_start > maximum) 198 | maximum = *p_start; 199 | p_start++; 200 | } 201 | return maximum; 202 | } 203 | 204 | // Minimum value of word16 vector. NEON intrinsics version for 205 | // ARM 32-bit/64-bit platforms. 206 | int16_t WebRtcSpl_MinValueW16Neon(const int16_t* vector, size_t length) { 207 | int16_t minimum = WEBRTC_SPL_WORD16_MAX; 208 | size_t i = 0; 209 | size_t residual = length & 0x7; 210 | 211 | RTC_DCHECK_GT(length, 0); 212 | 213 | const int16_t* p_start = vector; 214 | int16x8_t min16x8 = vdupq_n_s16(WEBRTC_SPL_WORD16_MAX); 215 | 216 | // First part, unroll the loop 8 times. 217 | for (i = 0; i < length - residual; i += 8) { 218 | int16x8_t in16x8 = vld1q_s16(p_start); 219 | min16x8 = vminq_s16(min16x8, in16x8); 220 | p_start += 8; 221 | } 222 | 223 | #if defined(WEBRTC_ARCH_ARM64) 224 | minimum = vminvq_s16(min16x8); 225 | #else 226 | int16x4_t min16x4 = vmin_s16(vget_low_s16(min16x8), vget_high_s16(min16x8)); 227 | min16x4 = vpmin_s16(min16x4, min16x4); 228 | min16x4 = vpmin_s16(min16x4, min16x4); 229 | 230 | minimum = vget_lane_s16(min16x4, 0); 231 | #endif 232 | 233 | // Second part, do the remaining iterations (if any). 234 | for (i = residual; i > 0; i--) { 235 | if (*p_start < minimum) 236 | minimum = *p_start; 237 | p_start++; 238 | } 239 | return minimum; 240 | } 241 | 242 | // Minimum value of word32 vector. NEON intrinsics version for 243 | // ARM 32-bit/64-bit platforms. 244 | int32_t WebRtcSpl_MinValueW32Neon(const int32_t* vector, size_t length) { 245 | int32_t minimum = WEBRTC_SPL_WORD32_MAX; 246 | size_t i = 0; 247 | size_t residual = length & 0x7; 248 | 249 | RTC_DCHECK_GT(length, 0); 250 | 251 | const int32_t* p_start = vector; 252 | int32x4_t min32x4_0 = vdupq_n_s32(WEBRTC_SPL_WORD32_MAX); 253 | int32x4_t min32x4_1 = vdupq_n_s32(WEBRTC_SPL_WORD32_MAX); 254 | 255 | // First part, unroll the loop 8 times. 256 | for (i = 0; i < length - residual; i += 8) { 257 | int32x4_t in32x4_0 = vld1q_s32(p_start); 258 | p_start += 4; 259 | int32x4_t in32x4_1 = vld1q_s32(p_start); 260 | p_start += 4; 261 | min32x4_0 = vminq_s32(min32x4_0, in32x4_0); 262 | min32x4_1 = vminq_s32(min32x4_1, in32x4_1); 263 | } 264 | 265 | int32x4_t min32x4 = vminq_s32(min32x4_0, min32x4_1); 266 | #if defined(WEBRTC_ARCH_ARM64) 267 | minimum = vminvq_s32(min32x4); 268 | #else 269 | int32x2_t min32x2 = vmin_s32(vget_low_s32(min32x4), vget_high_s32(min32x4)); 270 | min32x2 = vpmin_s32(min32x2, min32x2); 271 | 272 | minimum = vget_lane_s32(min32x2, 0); 273 | #endif 274 | 275 | // Second part, do the remaining iterations (if any). 276 | for (i = residual; i > 0; i--) { 277 | if (*p_start < minimum) 278 | minimum = *p_start; 279 | p_start++; 280 | } 281 | return minimum; 282 | } 283 | 284 | -------------------------------------------------------------------------------- /components/ac101_driver/AC101.c: -------------------------------------------------------------------------------- 1 | /* 2 | * AC101.c 3 | * 4 | * Created on: 2018年1月9日 5 | * Author: ai-thinker 6 | */ 7 | 8 | #include 9 | #include 10 | #include "freertos/FreeRTOS.h" 11 | #include "freertos/task.h" 12 | #include "esp_system.h" 13 | #include "esp_log.h" 14 | #include "DriverUtil.h" 15 | #include "driver/i2s.h" 16 | #include "driver/i2c.h" 17 | #include "driver/gpio.h" 18 | #include "AC101.h" 19 | #define I2C_MASTER_SCL_IO 32 /*!< gpio number for I2C master clock */ 20 | #define I2C_MASTER_SDA_IO 33 /*!< gpio number for I2C master data */ 21 | #define I2C_MASTER_NUM I2C_NUM_1 /*!< I2C port number for master dev */ 22 | #define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master do not need buffer */ 23 | #define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master do not need buffer */ 24 | #define I2C_MASTER_FREQ_HZ 100000 /*!< I2C master clock frequency */ 25 | #define I2S_NUM (0) 26 | #define ACK_CHECK_EN 0x1 /*!< I2C master will check ack from slave*/ 27 | static char *AC101_TAG = "AC101"; 28 | #define I2C_CHECK(a, str) if((a)) { \ 29 | ESP_LOGE(AC101_TAG,"%s:%d (%s):%d", __FILE__, __LINE__, __FUNCTION__, str); \ 30 | } 31 | 32 | #define SPKOUT_CTRL 0x58 33 | 34 | void AC101_i2c_master_init() { 35 | int i2c_master_port = I2C_MASTER_NUM; 36 | i2c_config_t conf; 37 | conf.mode = I2C_MODE_MASTER; 38 | conf.sda_io_num = (gpio_num_t) I2C_MASTER_SDA_IO; 39 | conf.sda_pullup_en = GPIO_PULLUP_ENABLE; 40 | conf.scl_io_num = (gpio_num_t) I2C_MASTER_SCL_IO; 41 | conf.scl_pullup_en = GPIO_PULLUP_ENABLE; 42 | conf.master.clk_speed = I2C_MASTER_FREQ_HZ; 43 | i2c_param_config((i2c_port_t) i2c_master_port, &conf); 44 | i2c_driver_install((i2c_port_t) i2c_master_port, conf.mode, 45 | I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0); 46 | } 47 | 48 | uint16_t AC101_read_Reg(uint8_t reg) { 49 | uint16_t val = 0; 50 | uint8_t data_rd[2]; 51 | i2c_example_master_read_slave(AC101_ADDR,reg, data_rd, 2); 52 | ESP_LOGI(AC101_TAG, "reg=%x,data_rd[0]=%x,data_rd[1]=%x\r\n",reg, data_rd[0], 53 | data_rd[1]); 54 | val=(data_rd[0]<<8)+data_rd[1]; 55 | return val; 56 | } 57 | esp_err_t AC101_Write_Reg(uint8_t reg, uint16_t val) 58 | { 59 | i2c_cmd_handle_t cmd = i2c_cmd_link_create(); 60 | uint8_t send_buff[4]; 61 | send_buff[0] = (AC101_ADDR << 1); 62 | send_buff[1] = reg; 63 | send_buff[2] = (val>>8) & 0xff; 64 | send_buff[3] = val & 0xff; 65 | i2c_master_start(cmd); 66 | i2c_master_write(cmd, send_buff, 4, ACK_CHECK_EN); 67 | i2c_master_stop(cmd); 68 | esp_err_t ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_RATE_MS); 69 | i2c_cmd_link_delete(cmd); 70 | return ret; 71 | } 72 | esp_err_t ac101_set_spk_volume(uint8_t volume) 73 | { 74 | uint16_t res; 75 | esp_err_t ret; 76 | volume = volume/2; 77 | res = AC101_read_Reg(SPKOUT_CTRL); 78 | res &= (~0x1f); 79 | volume &= 0x1f; 80 | res |= volume; 81 | ret = AC101_Write_Reg(SPKOUT_CTRL,res); 82 | return ret; 83 | } 84 | 85 | 86 | int AC101_init() { 87 | AC101_i2c_master_init(); 88 | esp_err_t Res; 89 | Res = AC101_Write_Reg(0x0, 0x123); //soft reset AC101 90 | if (ESP_OK != Res) { 91 | printf("CODEC ERR\r\n"); 92 | return 1; //reset failed, WM8978 exception 93 | } else { 94 | printf("CODEC OK\r\n"); 95 | } 96 | vTaskDelay(1000 / portTICK_PERIOD_MS); 97 | I2C_CHECK(AC101_Write_Reg(0x58, 0xe880),1); 98 | 99 | //Enable the PLL from 256*44.1KHz MCLK source 100 | I2C_CHECK(AC101_Write_Reg(0x01, 0x014f), 2); 101 | I2C_CHECK(AC101_Write_Reg(0x02, 0x8120), 3); 102 | 103 | //Clocking system 104 | I2C_CHECK(AC101_Write_Reg(0x03, 0x8b08), 4); 105 | I2C_CHECK(AC101_Write_Reg(0x04, 0x800c), 5); 106 | I2C_CHECK(AC101_Write_Reg(0x05, 0x800c), 6); 107 | I2C_CHECK(AC101_Write_Reg(0x06, 0x3000), 7); 108 | 109 | //AIF config 110 | I2C_CHECK(AC101_Write_Reg(0x10, 0x8850), 8); 111 | I2C_CHECK(AC101_Write_Reg(0x11, 0xc000), 9); // 112 | I2C_CHECK(AC101_Write_Reg(0x12, 0xc000), 9); 113 | I2C_CHECK(AC101_Write_Reg(0x13, 0x2200), 9); // 114 | 115 | I2C_CHECK(AC101_Write_Reg(0x52, 0xc444), 10); 116 | I2C_CHECK(AC101_Write_Reg(0x51, 0x2000), 11); 117 | //I2C_CHECK(AC101_Write_Reg(0x51, 0x3060), 11); 118 | I2C_CHECK(AC101_Write_Reg(0x40, 0x8000), 12); 119 | I2C_CHECK(AC101_Write_Reg(0x50, 0xbbc0), 14); 120 | 121 | //Path Configuration 122 | I2C_CHECK(AC101_Write_Reg(0x4c, 0xcc00), 10); 123 | I2C_CHECK(AC101_Write_Reg(0x48, 0x8000), 11); 124 | I2C_CHECK(AC101_Write_Reg(0x54, 0x0081), 12); 125 | I2C_CHECK(AC101_Write_Reg(0x53, 0xf080), 13); 126 | 127 | //* Enable Headphoe output 注意使用耳机时,最后开以下寄存器 128 | I2C_CHECK(AC101_Write_Reg(0x53, 0xff80), 14); 129 | I2C_CHECK(AC101_Write_Reg(0x56, 0xc3c1), 15); 130 | I2C_CHECK(AC101_Write_Reg(0x56, 0xcb00), 16); 131 | vTaskDelay(100 / portTICK_PERIOD_MS); 132 | I2C_CHECK(AC101_Write_Reg(0x56, 0xfbc0), 17); 133 | 134 | //* Enable Speaker output 135 | I2C_CHECK(AC101_Write_Reg(0x58, 0xeabd), 18); 136 | // I2C_CHECK(AC101_Write_Reg(0x4a, 0x0040), 18); 137 | ac101_set_spk_volume(20); 138 | init_gpio_PA(1); 139 | 140 | return 0; 141 | } 142 | 143 | int AC101_init_16k() { 144 | AC101_i2c_master_init(); 145 | esp_err_t Res; 146 | Res = AC101_Write_Reg(0x0, 0x123); //soft reset AC101 147 | if (ESP_OK != Res) { 148 | printf("CODEC ERR\r\n"); 149 | return 1; //reset failed, WM8978 exception 150 | } else { 151 | printf("CODEC OK\r\n"); 152 | } 153 | vTaskDelay(1000 / portTICK_PERIOD_MS); 154 | I2C_CHECK(AC101_Write_Reg(0x58, 0xe880),1); 155 | 156 | //Enable the PLL from 256*44.1KHz MCLK source 157 | I2C_CHECK(AC101_Write_Reg(0x01, 0x014f), 2); 158 | I2C_CHECK(AC101_Write_Reg(0x02, 0x8120), 3); 159 | 160 | //Clocking system 161 | I2C_CHECK(AC101_Write_Reg(0x03, 0x8b08), 4); 162 | I2C_CHECK(AC101_Write_Reg(0x04, 0x800c), 5); 163 | I2C_CHECK(AC101_Write_Reg(0x05, 0x800c), 6); 164 | I2C_CHECK(AC101_Write_Reg(0x06, 0x3000), 7); 165 | 166 | //AIF config 167 | I2C_CHECK(AC101_Write_Reg(0x10, 0x8850), 8); 168 | I2C_CHECK(AC101_Write_Reg(0x11, 0xc000), 9); // 169 | I2C_CHECK(AC101_Write_Reg(0x12, 0xc000), 9); 170 | I2C_CHECK(AC101_Write_Reg(0x13, 0x2200), 9); // 171 | 172 | I2C_CHECK(AC101_Write_Reg(0x52, 0xccc4), 10); 173 | I2C_CHECK(AC101_Write_Reg(0x51, 0x2020), 11); 174 | //I2C_CHECK(AC101_Write_Reg(0x51, 0x3060), 11); 175 | I2C_CHECK(AC101_Write_Reg(0x40, 0x8000), 12); 176 | I2C_CHECK(AC101_Write_Reg(0x50, 0xbbc3), 14); 177 | 178 | //Path Configuration 179 | I2C_CHECK(AC101_Write_Reg(0x4c, 0xcc00), 10); 180 | I2C_CHECK(AC101_Write_Reg(0x48, 0x8000), 11); 181 | I2C_CHECK(AC101_Write_Reg(0x54, 0x0081), 12); 182 | I2C_CHECK(AC101_Write_Reg(0x53, 0xf080), 13); 183 | 184 | //* Enable Headphoe output 注意使用耳机时,最后开以下寄存器 185 | I2C_CHECK(AC101_Write_Reg(0x53, 0xff80), 14); 186 | I2C_CHECK(AC101_Write_Reg(0x56, 0xc3c1), 15); 187 | I2C_CHECK(AC101_Write_Reg(0x56, 0xcb00), 16); 188 | vTaskDelay(100 / portTICK_PERIOD_MS); 189 | I2C_CHECK(AC101_Write_Reg(0x56, 0xfbc0), 17); 190 | 191 | //* Enable Speaker output 192 | I2C_CHECK(AC101_Write_Reg(0x58, 0xeabd), 18); 193 | // I2C_CHECK(AC101_Write_Reg(0x4a, 0x0040), 18); 194 | init_gpio_PA(1); 195 | return 0; 196 | } 197 | 198 | void mic_init(void) 199 | { 200 | AC101_i2c_master_init(); 201 | esp_err_t Res; 202 | Res = AC101_Write_Reg(0x0, 0x123); //soft reset AC101 203 | if (ESP_OK != Res) { 204 | printf("CODEC_ERR\r\n"); 205 | return; //reset failed, WM8978 exception 206 | } else { 207 | printf("CODEC_OK\r\n"); 208 | } 209 | vTaskDelay(1000 / portTICK_PERIOD_MS); 210 | I2C_CHECK(AC101_Write_Reg(0x58, 0xe880),1); 211 | //Enable the PLL from 256*44.1KHz MCLK source 212 | I2C_CHECK(AC101_Write_Reg(0x01, 0x014f), 2); 213 | I2C_CHECK(AC101_Write_Reg(0x02, 0x8120), 3); 214 | //Clocking system 215 | I2C_CHECK(AC101_Write_Reg(0x03, 0x8b08), 4); 216 | I2C_CHECK(AC101_Write_Reg(0x04, 0x8008), 5); 217 | I2C_CHECK(AC101_Write_Reg(0x05, 0x8008), 6); 218 | I2C_CHECK(AC101_Write_Reg(0x06, 0x3000), 7); 219 | //AIF config 220 | I2C_CHECK(AC101_Write_Reg(0x10, 0x8850), 8); 221 | I2C_CHECK(AC101_Write_Reg(0x11, 0xc000), 9); 222 | I2C_CHECK(AC101_Write_Reg(0x13, 0x2200), 9); 223 | //Path Configuration 224 | I2C_CHECK(AC101_Write_Reg(0x52, 0xccc4), 10); 225 | I2C_CHECK(AC101_Write_Reg(0x51, 0x2020), 11); //MIC1 2 226 | 227 | I2C_CHECK(AC101_Write_Reg(0x40, 0x8000), 12); 228 | I2C_CHECK(AC101_Write_Reg(0x50, 0xbbc3), 14); 229 | } 230 | 231 | void init_gpio_PA(int en) 232 | { 233 | gpio_config_t io_conf; 234 | io_conf.intr_type = GPIO_PIN_INTR_DISABLE; 235 | //set as output mode 236 | io_conf.mode = GPIO_MODE_OUTPUT; 237 | //bit mask of the pins that you want to set,e.g.GPIO18/19 238 | io_conf.pin_bit_mask = PA_EN_PIN_SEL; 239 | //disable pull-down mode 240 | io_conf.pull_down_en = 0; 241 | //disable pull-up mode 242 | io_conf.pull_up_en = 0; 243 | //configure GPIO with the given settings 244 | gpio_config(&io_conf); 245 | //gpio_set_level(PA_EN_PIN, 0); 246 | enable_PA(en); 247 | } 248 | void enable_PA(int en) 249 | { 250 | if(en > 0) 251 | { 252 | gpio_set_level(PA_EN_PIN, 1); 253 | }else 254 | { 255 | gpio_set_level(PA_EN_PIN, 0); 256 | } 257 | } 258 | 259 | void codec_mute(int en) 260 | { 261 | enable_PA(en); 262 | uint16_t reg_val = AC101_read_Reg(0x56); 263 | 264 | if(en >0) 265 | { 266 | enable_PA(0); 267 | reg_val &= (~(3<<12)); 268 | } 269 | else 270 | { 271 | enable_PA(1); 272 | reg_val |= (3 << 12); 273 | } 274 | AC101_Write_Reg(0x56,reg_val); 275 | } 276 | 277 | 278 | 279 | 280 | 281 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/common_audio/signal_processing/downsample_fast_neon.c.neon: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #include "common_audio/signal_processing/include/signal_processing_library.h" 12 | 13 | #include 14 | 15 | // NEON intrinsics version of WebRtcSpl_DownsampleFast() 16 | // for ARM 32-bit/64-bit platforms. 17 | int WebRtcSpl_DownsampleFastNeon(const int16_t* data_in, 18 | size_t data_in_length, 19 | int16_t* data_out, 20 | size_t data_out_length, 21 | const int16_t* __restrict coefficients, 22 | size_t coefficients_length, 23 | int factor, 24 | size_t delay) { 25 | size_t i = 0; 26 | size_t j = 0; 27 | int32_t out_s32 = 0; 28 | size_t endpos = delay + factor * (data_out_length - 1) + 1; 29 | size_t res = data_out_length & 0x7; 30 | size_t endpos1 = endpos - factor * res; 31 | 32 | // Return error if any of the running conditions doesn't meet. 33 | if (data_out_length == 0 || coefficients_length == 0 34 | || data_in_length < endpos) { 35 | return -1; 36 | } 37 | 38 | // First part, unroll the loop 8 times, with 3 subcases 39 | // (factor == 2, 4, others). 40 | switch (factor) { 41 | case 2: { 42 | for (i = delay; i < endpos1; i += 16) { 43 | // Round value, 0.5 in Q12. 44 | int32x4_t out32x4_0 = vdupq_n_s32(2048); 45 | int32x4_t out32x4_1 = vdupq_n_s32(2048); 46 | 47 | #if defined(WEBRTC_ARCH_ARM64) 48 | // Unroll the loop 2 times. 49 | for (j = 0; j < coefficients_length - 1; j += 2) { 50 | int32x2_t coeff32 = vld1_dup_s32((int32_t*)&coefficients[j]); 51 | int16x4_t coeff16x4 = vreinterpret_s16_s32(coeff32); 52 | int16x8x2_t in16x8x2 = vld2q_s16(&data_in[i - j - 1]); 53 | 54 | // Mul and accumulate low 64-bit data. 55 | int16x4_t in16x4_0 = vget_low_s16(in16x8x2.val[0]); 56 | int16x4_t in16x4_1 = vget_low_s16(in16x8x2.val[1]); 57 | out32x4_0 = vmlal_lane_s16(out32x4_0, in16x4_0, coeff16x4, 1); 58 | out32x4_0 = vmlal_lane_s16(out32x4_0, in16x4_1, coeff16x4, 0); 59 | 60 | // Mul and accumulate high 64-bit data. 61 | // TODO: vget_high_s16 need extra cost on ARM64. This could be 62 | // replaced by vmlal_high_lane_s16. But for the interface of 63 | // vmlal_high_lane_s16, there is a bug in gcc 4.9. 64 | // This issue need to be tracked in the future. 65 | int16x4_t in16x4_2 = vget_high_s16(in16x8x2.val[0]); 66 | int16x4_t in16x4_3 = vget_high_s16(in16x8x2.val[1]); 67 | out32x4_1 = vmlal_lane_s16(out32x4_1, in16x4_2, coeff16x4, 1); 68 | out32x4_1 = vmlal_lane_s16(out32x4_1, in16x4_3, coeff16x4, 0); 69 | } 70 | 71 | for (; j < coefficients_length; j++) { 72 | int16x4_t coeff16x4 = vld1_dup_s16(&coefficients[j]); 73 | int16x8x2_t in16x8x2 = vld2q_s16(&data_in[i - j]); 74 | 75 | // Mul and accumulate low 64-bit data. 76 | int16x4_t in16x4_0 = vget_low_s16(in16x8x2.val[0]); 77 | out32x4_0 = vmlal_lane_s16(out32x4_0, in16x4_0, coeff16x4, 0); 78 | 79 | // Mul and accumulate high 64-bit data. 80 | // TODO: vget_high_s16 need extra cost on ARM64. This could be 81 | // replaced by vmlal_high_lane_s16. But for the interface of 82 | // vmlal_high_lane_s16, there is a bug in gcc 4.9. 83 | // This issue need to be tracked in the future. 84 | int16x4_t in16x4_1 = vget_high_s16(in16x8x2.val[0]); 85 | out32x4_1 = vmlal_lane_s16(out32x4_1, in16x4_1, coeff16x4, 0); 86 | } 87 | #else 88 | // On ARMv7, the loop unrolling 2 times results in performance 89 | // regression. 90 | for (j = 0; j < coefficients_length; j++) { 91 | int16x4_t coeff16x4 = vld1_dup_s16(&coefficients[j]); 92 | int16x8x2_t in16x8x2 = vld2q_s16(&data_in[i - j]); 93 | 94 | // Mul and accumulate. 95 | int16x4_t in16x4_0 = vget_low_s16(in16x8x2.val[0]); 96 | int16x4_t in16x4_1 = vget_high_s16(in16x8x2.val[0]); 97 | out32x4_0 = vmlal_lane_s16(out32x4_0, in16x4_0, coeff16x4, 0); 98 | out32x4_1 = vmlal_lane_s16(out32x4_1, in16x4_1, coeff16x4, 0); 99 | } 100 | #endif 101 | 102 | // Saturate and store the output. 103 | int16x4_t out16x4_0 = vqshrn_n_s32(out32x4_0, 12); 104 | int16x4_t out16x4_1 = vqshrn_n_s32(out32x4_1, 12); 105 | vst1q_s16(data_out, vcombine_s16(out16x4_0, out16x4_1)); 106 | data_out += 8; 107 | } 108 | break; 109 | } 110 | case 4: { 111 | for (i = delay; i < endpos1; i += 32) { 112 | // Round value, 0.5 in Q12. 113 | int32x4_t out32x4_0 = vdupq_n_s32(2048); 114 | int32x4_t out32x4_1 = vdupq_n_s32(2048); 115 | 116 | // Unroll the loop 4 times. 117 | for (j = 0; j < coefficients_length - 3; j += 4) { 118 | int16x4_t coeff16x4 = vld1_s16(&coefficients[j]); 119 | int16x8x4_t in16x8x4 = vld4q_s16(&data_in[i - j - 3]); 120 | 121 | // Mul and accumulate low 64-bit data. 122 | int16x4_t in16x4_0 = vget_low_s16(in16x8x4.val[0]); 123 | int16x4_t in16x4_2 = vget_low_s16(in16x8x4.val[1]); 124 | int16x4_t in16x4_4 = vget_low_s16(in16x8x4.val[2]); 125 | int16x4_t in16x4_6 = vget_low_s16(in16x8x4.val[3]); 126 | out32x4_0 = vmlal_lane_s16(out32x4_0, in16x4_0, coeff16x4, 3); 127 | out32x4_0 = vmlal_lane_s16(out32x4_0, in16x4_2, coeff16x4, 2); 128 | out32x4_0 = vmlal_lane_s16(out32x4_0, in16x4_4, coeff16x4, 1); 129 | out32x4_0 = vmlal_lane_s16(out32x4_0, in16x4_6, coeff16x4, 0); 130 | 131 | // Mul and accumulate high 64-bit data. 132 | // TODO: vget_high_s16 need extra cost on ARM64. This could be 133 | // replaced by vmlal_high_lane_s16. But for the interface of 134 | // vmlal_high_lane_s16, there is a bug in gcc 4.9. 135 | // This issue need to be tracked in the future. 136 | int16x4_t in16x4_1 = vget_high_s16(in16x8x4.val[0]); 137 | int16x4_t in16x4_3 = vget_high_s16(in16x8x4.val[1]); 138 | int16x4_t in16x4_5 = vget_high_s16(in16x8x4.val[2]); 139 | int16x4_t in16x4_7 = vget_high_s16(in16x8x4.val[3]); 140 | out32x4_1 = vmlal_lane_s16(out32x4_1, in16x4_1, coeff16x4, 3); 141 | out32x4_1 = vmlal_lane_s16(out32x4_1, in16x4_3, coeff16x4, 2); 142 | out32x4_1 = vmlal_lane_s16(out32x4_1, in16x4_5, coeff16x4, 1); 143 | out32x4_1 = vmlal_lane_s16(out32x4_1, in16x4_7, coeff16x4, 0); 144 | } 145 | 146 | for (; j < coefficients_length; j++) { 147 | int16x4_t coeff16x4 = vld1_dup_s16(&coefficients[j]); 148 | int16x8x4_t in16x8x4 = vld4q_s16(&data_in[i - j]); 149 | 150 | // Mul and accumulate low 64-bit data. 151 | int16x4_t in16x4_0 = vget_low_s16(in16x8x4.val[0]); 152 | out32x4_0 = vmlal_lane_s16(out32x4_0, in16x4_0, coeff16x4, 0); 153 | 154 | // Mul and accumulate high 64-bit data. 155 | // TODO: vget_high_s16 need extra cost on ARM64. This could be 156 | // replaced by vmlal_high_lane_s16. But for the interface of 157 | // vmlal_high_lane_s16, there is a bug in gcc 4.9. 158 | // This issue need to be tracked in the future. 159 | int16x4_t in16x4_1 = vget_high_s16(in16x8x4.val[0]); 160 | out32x4_1 = vmlal_lane_s16(out32x4_1, in16x4_1, coeff16x4, 0); 161 | } 162 | 163 | // Saturate and store the output. 164 | int16x4_t out16x4_0 = vqshrn_n_s32(out32x4_0, 12); 165 | int16x4_t out16x4_1 = vqshrn_n_s32(out32x4_1, 12); 166 | vst1q_s16(data_out, vcombine_s16(out16x4_0, out16x4_1)); 167 | data_out += 8; 168 | } 169 | break; 170 | } 171 | default: { 172 | for (i = delay; i < endpos1; i += factor * 8) { 173 | // Round value, 0.5 in Q12. 174 | int32x4_t out32x4_0 = vdupq_n_s32(2048); 175 | int32x4_t out32x4_1 = vdupq_n_s32(2048); 176 | 177 | for (j = 0; j < coefficients_length; j++) { 178 | int16x4_t coeff16x4 = vld1_dup_s16(&coefficients[j]); 179 | int16x4_t in16x4_0 = vld1_dup_s16(&data_in[i - j]); 180 | in16x4_0 = vld1_lane_s16(&data_in[i + factor - j], in16x4_0, 1); 181 | in16x4_0 = vld1_lane_s16(&data_in[i + factor * 2 - j], in16x4_0, 2); 182 | in16x4_0 = vld1_lane_s16(&data_in[i + factor * 3 - j], in16x4_0, 3); 183 | int16x4_t in16x4_1 = vld1_dup_s16(&data_in[i + factor * 4 - j]); 184 | in16x4_1 = vld1_lane_s16(&data_in[i + factor * 5 - j], in16x4_1, 1); 185 | in16x4_1 = vld1_lane_s16(&data_in[i + factor * 6 - j], in16x4_1, 2); 186 | in16x4_1 = vld1_lane_s16(&data_in[i + factor * 7 - j], in16x4_1, 3); 187 | 188 | // Mul and accumulate. 189 | out32x4_0 = vmlal_lane_s16(out32x4_0, in16x4_0, coeff16x4, 0); 190 | out32x4_1 = vmlal_lane_s16(out32x4_1, in16x4_1, coeff16x4, 0); 191 | } 192 | 193 | // Saturate and store the output. 194 | int16x4_t out16x4_0 = vqshrn_n_s32(out32x4_0, 12); 195 | int16x4_t out16x4_1 = vqshrn_n_s32(out32x4_1, 12); 196 | vst1q_s16(data_out, vcombine_s16(out16x4_0, out16x4_1)); 197 | data_out += 8; 198 | } 199 | break; 200 | } 201 | } 202 | 203 | // Second part, do the rest iterations (if any). 204 | for (; i < endpos; i += factor) { 205 | out_s32 = 2048; // Round value, 0.5 in Q12. 206 | 207 | for (j = 0; j < coefficients_length; j++) { 208 | out_s32 = WebRtc_MulAccumW16(coefficients[j], data_in[i - j], out_s32); 209 | } 210 | 211 | // Saturate and store the output. 212 | out_s32 >>= 12; 213 | *data_out++ = WebRtcSpl_SatW32ToW16(out_s32); 214 | } 215 | 216 | return 0; 217 | } 218 | -------------------------------------------------------------------------------- /components/esp32_vad/webrtc/common_audio/signal_processing/downsample_fast_mips.c.mips: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #include "common_audio/signal_processing/include/signal_processing_library.h" 12 | 13 | // Version of WebRtcSpl_DownsampleFast() for MIPS platforms. 14 | int WebRtcSpl_DownsampleFast_mips(const int16_t* data_in, 15 | size_t data_in_length, 16 | int16_t* data_out, 17 | size_t data_out_length, 18 | const int16_t* __restrict coefficients, 19 | size_t coefficients_length, 20 | int factor, 21 | size_t delay) { 22 | int i; 23 | int j; 24 | int k; 25 | int32_t out_s32 = 0; 26 | size_t endpos = delay + factor * (data_out_length - 1) + 1; 27 | 28 | int32_t tmp1, tmp2, tmp3, tmp4, factor_2; 29 | int16_t* p_coefficients; 30 | int16_t* p_data_in; 31 | int16_t* p_data_in_0 = (int16_t*)&data_in[delay]; 32 | int16_t* p_coefficients_0 = (int16_t*)&coefficients[0]; 33 | #if !defined(MIPS_DSP_R1_LE) 34 | int32_t max_16 = 0x7FFF; 35 | int32_t min_16 = 0xFFFF8000; 36 | #endif // #if !defined(MIPS_DSP_R1_LE) 37 | 38 | // Return error if any of the running conditions doesn't meet. 39 | if (data_out_length == 0 || coefficients_length == 0 40 | || data_in_length < endpos) { 41 | return -1; 42 | } 43 | #if defined(MIPS_DSP_R2_LE) 44 | __asm __volatile ( 45 | ".set push \n\t" 46 | ".set noreorder \n\t" 47 | "subu %[i], %[endpos], %[delay] \n\t" 48 | "sll %[factor_2], %[factor], 1 \n\t" 49 | "1: \n\t" 50 | "move %[p_data_in], %[p_data_in_0] \n\t" 51 | "mult $zero, $zero \n\t" 52 | "move %[p_coefs], %[p_coefs_0] \n\t" 53 | "sra %[j], %[coef_length], 2 \n\t" 54 | "beq %[j], $zero, 3f \n\t" 55 | " andi %[k], %[coef_length], 3 \n\t" 56 | "2: \n\t" 57 | "lwl %[tmp1], 1(%[p_data_in]) \n\t" 58 | "lwl %[tmp2], 3(%[p_coefs]) \n\t" 59 | "lwl %[tmp3], -3(%[p_data_in]) \n\t" 60 | "lwl %[tmp4], 7(%[p_coefs]) \n\t" 61 | "lwr %[tmp1], -2(%[p_data_in]) \n\t" 62 | "lwr %[tmp2], 0(%[p_coefs]) \n\t" 63 | "lwr %[tmp3], -6(%[p_data_in]) \n\t" 64 | "lwr %[tmp4], 4(%[p_coefs]) \n\t" 65 | "packrl.ph %[tmp1], %[tmp1], %[tmp1] \n\t" 66 | "packrl.ph %[tmp3], %[tmp3], %[tmp3] \n\t" 67 | "dpa.w.ph $ac0, %[tmp1], %[tmp2] \n\t" 68 | "dpa.w.ph $ac0, %[tmp3], %[tmp4] \n\t" 69 | "addiu %[j], %[j], -1 \n\t" 70 | "addiu %[p_data_in], %[p_data_in], -8 \n\t" 71 | "bgtz %[j], 2b \n\t" 72 | " addiu %[p_coefs], %[p_coefs], 8 \n\t" 73 | "3: \n\t" 74 | "beq %[k], $zero, 5f \n\t" 75 | " nop \n\t" 76 | "4: \n\t" 77 | "lhu %[tmp1], 0(%[p_data_in]) \n\t" 78 | "lhu %[tmp2], 0(%[p_coefs]) \n\t" 79 | "addiu %[p_data_in], %[p_data_in], -2 \n\t" 80 | "addiu %[k], %[k], -1 \n\t" 81 | "dpa.w.ph $ac0, %[tmp1], %[tmp2] \n\t" 82 | "bgtz %[k], 4b \n\t" 83 | " addiu %[p_coefs], %[p_coefs], 2 \n\t" 84 | "5: \n\t" 85 | "extr_r.w %[out_s32], $ac0, 12 \n\t" 86 | "addu %[p_data_in_0], %[p_data_in_0], %[factor_2] \n\t" 87 | "subu %[i], %[i], %[factor] \n\t" 88 | "shll_s.w %[out_s32], %[out_s32], 16 \n\t" 89 | "sra %[out_s32], %[out_s32], 16 \n\t" 90 | "sh %[out_s32], 0(%[data_out]) \n\t" 91 | "bgtz %[i], 1b \n\t" 92 | " addiu %[data_out], %[data_out], 2 \n\t" 93 | ".set pop \n\t" 94 | : [tmp1] "=&r" (tmp1), [tmp2] "=&r" (tmp2), [tmp3] "=&r" (tmp3), 95 | [tmp4] "=&r" (tmp4), [p_data_in] "=&r" (p_data_in), 96 | [p_data_in_0] "+r" (p_data_in_0), [p_coefs] "=&r" (p_coefficients), 97 | [j] "=&r" (j), [out_s32] "=&r" (out_s32), [factor_2] "=&r" (factor_2), 98 | [i] "=&r" (i), [k] "=&r" (k) 99 | : [coef_length] "r" (coefficients_length), [data_out] "r" (data_out), 100 | [p_coefs_0] "r" (p_coefficients_0), [endpos] "r" (endpos), 101 | [delay] "r" (delay), [factor] "r" (factor) 102 | : "memory", "hi", "lo" 103 | ); 104 | #else // #if defined(MIPS_DSP_R2_LE) 105 | __asm __volatile ( 106 | ".set push \n\t" 107 | ".set noreorder \n\t" 108 | "sll %[factor_2], %[factor], 1 \n\t" 109 | "subu %[i], %[endpos], %[delay] \n\t" 110 | "1: \n\t" 111 | "move %[p_data_in], %[p_data_in_0] \n\t" 112 | "addiu %[out_s32], $zero, 2048 \n\t" 113 | "move %[p_coefs], %[p_coefs_0] \n\t" 114 | "sra %[j], %[coef_length], 1 \n\t" 115 | "beq %[j], $zero, 3f \n\t" 116 | " andi %[k], %[coef_length], 1 \n\t" 117 | "2: \n\t" 118 | "lh %[tmp1], 0(%[p_data_in]) \n\t" 119 | "lh %[tmp2], 0(%[p_coefs]) \n\t" 120 | "lh %[tmp3], -2(%[p_data_in]) \n\t" 121 | "lh %[tmp4], 2(%[p_coefs]) \n\t" 122 | "mul %[tmp1], %[tmp1], %[tmp2] \n\t" 123 | "addiu %[p_coefs], %[p_coefs], 4 \n\t" 124 | "mul %[tmp3], %[tmp3], %[tmp4] \n\t" 125 | "addiu %[j], %[j], -1 \n\t" 126 | "addiu %[p_data_in], %[p_data_in], -4 \n\t" 127 | "addu %[tmp1], %[tmp1], %[tmp3] \n\t" 128 | "bgtz %[j], 2b \n\t" 129 | " addu %[out_s32], %[out_s32], %[tmp1] \n\t" 130 | "3: \n\t" 131 | "beq %[k], $zero, 4f \n\t" 132 | " nop \n\t" 133 | "lh %[tmp1], 0(%[p_data_in]) \n\t" 134 | "lh %[tmp2], 0(%[p_coefs]) \n\t" 135 | "mul %[tmp1], %[tmp1], %[tmp2] \n\t" 136 | "addu %[out_s32], %[out_s32], %[tmp1] \n\t" 137 | "4: \n\t" 138 | "sra %[out_s32], %[out_s32], 12 \n\t" 139 | "addu %[p_data_in_0], %[p_data_in_0], %[factor_2] \n\t" 140 | #if defined(MIPS_DSP_R1_LE) 141 | "shll_s.w %[out_s32], %[out_s32], 16 \n\t" 142 | "sra %[out_s32], %[out_s32], 16 \n\t" 143 | #else // #if defined(MIPS_DSP_R1_LE) 144 | "slt %[tmp1], %[max_16], %[out_s32] \n\t" 145 | "movn %[out_s32], %[max_16], %[tmp1] \n\t" 146 | "slt %[tmp1], %[out_s32], %[min_16] \n\t" 147 | "movn %[out_s32], %[min_16], %[tmp1] \n\t" 148 | #endif // #if defined(MIPS_DSP_R1_LE) 149 | "subu %[i], %[i], %[factor] \n\t" 150 | "sh %[out_s32], 0(%[data_out]) \n\t" 151 | "bgtz %[i], 1b \n\t" 152 | " addiu %[data_out], %[data_out], 2 \n\t" 153 | ".set pop \n\t" 154 | : [tmp1] "=&r" (tmp1), [tmp2] "=&r" (tmp2), [tmp3] "=&r" (tmp3), 155 | [tmp4] "=&r" (tmp4), [p_data_in] "=&r" (p_data_in), [k] "=&r" (k), 156 | [p_data_in_0] "+r" (p_data_in_0), [p_coefs] "=&r" (p_coefficients), 157 | [j] "=&r" (j), [out_s32] "=&r" (out_s32), [factor_2] "=&r" (factor_2), 158 | [i] "=&r" (i) 159 | : [coef_length] "r" (coefficients_length), [data_out] "r" (data_out), 160 | [p_coefs_0] "r" (p_coefficients_0), [endpos] "r" (endpos), 161 | #if !defined(MIPS_DSP_R1_LE) 162 | [max_16] "r" (max_16), [min_16] "r" (min_16), 163 | #endif // #if !defined(MIPS_DSP_R1_LE) 164 | [delay] "r" (delay), [factor] "r" (factor) 165 | : "memory", "hi", "lo" 166 | ); 167 | #endif // #if defined(MIPS_DSP_R2_LE) 168 | return 0; 169 | } 170 | --------------------------------------------------------------------------------