跳转至

SGS VAD 算法使用参考


REVISION HISTORY

Revision No.
Description
Date
1.0
  • Initial release
  • 03/27/2024
    1.01
  • Add Json API description
  • 12/09/2024
    1.02
  • Update file description and copyright
  • 04/25/2025
    1.03
  • Add note of sampling rate
  • 05/08/2025
    1.04
  • Remove copyright
  • 05/14/2025
    1.05
  • Corrected format
  • 10/28/2025
    1.1
  • Modified API return value and update description of Chapter 1
  • 11/25/2025
    1.2
  • Add IaaVad_GetResult API and remove vad_result param from IaaVad_Run
  • 12/03/2025

    1. 概述

    1.1. 算法说明

    语音活动检测算法(Voice Activity Detection, VAD)算法是通过对输入语音进行处理,检测当前输入是否有语音活动的功能。


    1.2. 基本结构

    当VAD算法配置好内存、完成参数初始化与设定后,VAD只需要输入讯号Buffer,并将输入讯号Buffer按设定参数与算法处理后,将侦测结果输出到VAD输出结果指针。


    1.3. 功能介绍

    语音检测 :

    检测声音中含有语音活动的区间。


    1.4. 应用场景

    在通讯系统中,可以判断用户是否正在讲话,在静音时降低带宽使用量等低功耗应用。抑或者可以透过判断是否为语音片段来降低处理音频的运算量,只处理真正有语音的片段。


    1.5. 芯片差异说明

    在不同系列芯片,目前VAD算法效果上没有差异。


    1.6. 实例介绍

    使用VAD API获取VAD算法运行需要的内存大小、初始化VAD算法handle、配置参数至VAD算法handle、配置运行模式至VAD算法handle、运行VAD算法与释放VAD算法资源。

        #include <stdio.h>
        #include <string.h>
        #include <time.h>
        #include <stdlib.h>
        #ifndef OS_WINDOWS
        #include <sys/ioctl.h>
        #endif
        #include <sys/types.h>
        #include <sys/stat.h>
        #include <sys/time.h>
    
        #include "AudioVadProcess.h"
    
    
        #define USE_MALLOC   (1)
        unsigned int WorkingBuffer2[1] = {0};
    
        typedef unsigned char               uint8;
        typedef unsigned short              uint16;
        typedef unsigned long               uint32;
    
        float AVERAGE_RUN(int a)
        {
            static unsigned int num = 0;
            static float avg = 0;
            if(num == 0) avg = 0;
            num++;
            avg = avg + ((float)a - avg) / ((float)num);
            return avg;
        }
        unsigned int _OsCounterGetMs(void)
        {
            struct  timeval t1;
            gettimeofday(&t1,NULL);
            unsigned int T = ( (1000000 * t1.tv_sec)+ t1.tv_usec );
            return T;
        }
    
    
        int main(int argc, char *argv[])
        {
            short input[1024];
            char input_file[512];
            unsigned int T0, T1;
            float avg = 0;
            int counter=0;
            int mode = 1;
            int vad_result=0;
        #if USE_MALLOC
            char *working_buf_ptr = (char*)malloc(IaaVad_GetBufferSize());
        #else
            char working_buf_ptr[512*100*2];
        #endif
    
            FILE * fin;
            int ret1;
    
            VAD_HANDLE handle;
            VadInit vad_init;
            VadConfig vad_config;
    
            int PN=128;
    
            vad_init.point_number = PN;
            vad_init.channel = 1;
            vad_init.sample_rate = IAA_VAD_SAMPLE_RATE_8000;
    
            vad_config.vote_frame = 100;
            vad_config.sensitivity = VAD_SEN_HIGH;
            handle = IaaVad_Init((char *)working_buf_ptr, &vad_init);
            if(handle==NULL)
            {
                printf("VAD init error\r\n");
                return -1;
            }
            else
            {
                printf("VAD init succeed\r\n");
            }
    
            if(IaaVad_Config(handle, &vad_config))
            {
                printf("Config Error!");
                return -1;
            }
            if(IaaVad_SetMode(handle, mode))
            {
                printf("Config Error!");
                return -1;
            }
            if(argc < 2)
                sprintf(input_file,"%s","./../sample/data/merge_test3.wav");
            else
                strcpy(input_file, argv[1]);
    
            fin = fopen(input_file, "rb");
            if(!fin)
            {
                printf("the input file %s could not be open\n",input_file);
                return -1;
            }
            fread(input, sizeof(char), 44, fin); // read header 44 bytes
            while(fread(input, sizeof(short), vad_init.point_number*vad_init.channel, fin))
            {
    
                counter++;
                T0  = (long)_OsCounterGetMs();
                ret1 = IaaVad_Run(handle, input);
                IaaVad_GetResult(handle, &vad_result);
                T1  = (long)_OsCounterGetMs();
                avg += (T1 - T0);
    
                if(counter%1000== 999)
                {
                    printf("counter = %d\n", counter);
                    printf("current time = %f\t", (float)counter*PN/vad_init.sample_rate);
                    printf("vad result = %d\t",vad_result);
                    printf("process time = %lu(us)\n",(long)(T1 - T0));
                }
    
                if(ret1 < 0)
                {
                    printf("Error occured in Voice Activity Detection\n");
                    break;
                }
    
            }
            avg /= counter;
            printf("AVG is %.2f us\n",avg);
            IaaVad_Free(handle);
            free(working_buf_ptr);
            fclose(fin);
    
            printf("Done\n");
        return 0;
        }
    

    使用VAD API读取VAD json档参数、获取VAD算法运行需要的内存大小、初始化VAD算法handle、配置参数至VAD算法handle、配置运行模式至VAD算法handle、运行VAD算法与释放VAD算法资源。

        #include <stdio.h>
        #include <string.h>
        #include <time.h>
        #include <stdlib.h>
        #ifndef OS_WINDOWS
        #include <sys/ioctl.h>
        #endif
        #include <sys/types.h>
        #include <sys/stat.h>
        #include <sys/time.h>
    
        #include "AudioVadProcess.h"
    
    
        #define USE_MALLOC   (1)
        unsigned int WorkingBuffer2[1] = {0};
    
        typedef unsigned char               uint8;
        typedef unsigned short              uint16;
        typedef unsigned long               uint32;
    
        float AVERAGE_RUN(int a)
        {
            static unsigned int num = 0;
            static float avg = 0;
            if(num == 0) avg = 0;
            num++;
            avg = avg + ((float)a - avg) / ((float)num);
            return avg;
        }
        unsigned int _OsCounterGetMs(void)
        {
            struct  timeval t1;
            gettimeofday(&t1,NULL);
            unsigned int T = ( (1000000 * t1.tv_sec)+ t1.tv_usec );
            return T;
        }
    
    
        int main(int argc, char *argv[])
        {
            short input[1024];
            char input_file[512];
            char output_file[512];
            unsigned int T0, T1;
            float avg = 0;
            int counter=0;
            FILE *fin, *fout;
            int ret1;
            int vad_result;
    
            VAD_HANDLE handle;
            VadInit vad_init;
            VadConfig vad_config;
            VadOption vad_option;
            char vad_para_json_file[512];
            sprintf(vad_para_json_file,"%s","./../sample/data/VadParamJson.json");
            unsigned int vad_para_buffersize = IaaVad_GetJsonFileSize(vad_para_json_file);
    
        #if USE_MALLOC
            char *working_buf_ptr = (char*)malloc(IaaVad_GetBufferSize());
            char *vad_para_json_buf_ptr = (char*)malloc(vad_para_buffersize);
        #else
            char working_buf_ptr[512*100*2];
            char vad_para_json_buf_ptr[512*100*2];
        #endif
    
            memset(&vad_init,0,sizeof(VadInit));
            memset(&vad_config,0,sizeof(VadConfig));
            memset(&vad_option,0,sizeof(VadOption));
            ret1 = IaaVad_InitReadFromJson(&vad_init, vad_para_json_buf_ptr, vad_para_json_file, vad_para_buffersize);
            ret1 = IaaVad_ConfigReadFromJson(&vad_config, vad_para_json_buf_ptr, vad_para_json_file, vad_para_buffersize);
            ret1 = IaaVad_OptionReadFromJson(&vad_option, vad_para_json_buf_ptr, vad_para_json_file, vad_para_buffersize);
    
    
            handle = IaaVad_Init((char *)working_buf_ptr, &vad_init);
            if(handle==NULL)
            {
                printf("VAD init error\r\n");
                return -1;
            }
            else
            {
                printf("VAD init succeed\r\n");
            }
    
            if(IaaVad_Config(handle, &vad_config))
            {
                printf("Config Error!");
                return -1;
            }
            if(IaaVad_SetMode(handle, vad_option.mode))
            {
                printf("Config Error!");
                return -1;
            }
            if(argc < 2)
                sprintf(input_file,"%s","./../sample/data/merge_test3.wav");
            else
                strcpy(input_file, argv[1]);
    
            sprintf(output_file,"%s","./../sample/data/VAD_result.txt");
    
            fin = fopen(input_file, "rb");
            if(!fin)
            {
                printf("the input file %s could not be open\n",input_file);
                return -1;
            }
    
            fout = fopen(output_file, "w");
                if(!fin)
            {
                printf("the output file %s could not be open\n",output_file);
                return -1;
            }
    
            fread(input, sizeof(char), 44, fin); // read header 44 bytes
            fprintf(fout,"%s\t%s\n","time","vad result");
            while(fread(input, sizeof(short), vad_init.point_number*vad_init.channel, fin))
            {
    
            counter++;
            T0  = (long)_OsCounterGetMs();
            ret1 = IaaVad_Run(handle, input);
            IaaVad_GetResult(handle, &vad_result);
            T1  = (long)_OsCounterGetMs();
            avg += (T1 - T0);
    
            if(counter%1000== 999)
            {
                printf("counter = %d\n", counter);
                printf("current time = %f\t", (float)counter*vad_init.point_number/vad_init.sample_rate);
                printf("vad result = %d\t",vad_result);
                printf("process time = %lu(us)\n",(long)(T1 - T0));
            }
    
            fprintf(fout,"%f\t%d\n",(float)counter*vad_init.point_number/vad_init.sample_rate,vad_result);
    
            if(ret1 < 0)
            {
                printf("Error occured in Voice Activity Detection\n");
                break;
            }
    
            }
            avg /= counter;
            printf("AVG is %.2f us\n",avg);
            IaaVad_Free(handle);
            free(working_buf_ptr);
            fclose(fin);
            fclose(fout);
            printf("Done\n");
        return 0;
        }
    

    2. API 参考

    API名称 功能
    IaaVad_GetBufferSize 获取VAD算法运行需要的内存大小
    IaaVad_Init 初始化VAD算法
    IaaVad_Config 设置VAD算法参数
    IaaVad_Run VAD算法处理
    IaaVad_Free 释放VAD算法资源
    IaaVad_SetMode VAD运行模式设定
    IaaVad_GetJsonFileSize VAD运行模式设定
    IaaVad_InitReadFromJson 配置Json参数到VAD算法的初始化结构体指针
    IaaVad_ConfigReadFromJson 配置Json参数到VAD算法的参数结构体指针
    IaaVad_OptionReadFromJson 配置Json参数到VAD算法的Option结构体指
    IaaVad_GetResult 获取VAD算法结果

    2.1. IaaVad_GetBufferSize

    • 功能

      获取VAD算法运行所需要的内存大小。

    • 语法

      unsigned int IaaVad_GetBufferSize(void);
      
    • 形参

      参数名称 描述 输入/输出
      N/A
    • 返回值

      返回值为VAD算法运行所需要的内存大小。

    • 依赖

      • 头文件: AudioVadProcess.h

      • 库文件: libVAD_LINUX.so/ libVAD_LINUX.a

    • 注意

      该接口仅返回需要的内存大小,申请和释放内存的动作需应用来处理。

    • 举例

      请参考实例介绍

    2.2. IaaVad_Init

    • 功能

      初始化VAD算法。

    • 语法

      VAD_HANDLE IaaVad_Init(char* const working_buffer_address, VadInit *vad_init);
      
    • 形参

      参数名称 描述 输入/输出
      working_buffer_address VAD算法使用的内存地址 输入
      vad_init VAD算法的初始化结构体指针 输入
    • 返回值

      返回值 结果
      非NULL 成功
      NULL 失败
    • 依赖

      • 头文件: AudioVadProcess.h

      • 库文件: libVAD_LINUX.so/ libVAD_LINUX.a

    • 举例

      请参考实例介绍

    2.3. IaaVad_Config

    • 功能

      设置VAD算法参数。

    • 语法

      ALGO_VAD_RET IaaVad_Config(VAD_HANDLE handle, VadConfig *vad_config);
      
    • 形参

      参数名称 描述 输入/输出
      handle VAD算法handle 输入
      vad_config VAD算法参数设置结构体 输入
    • 返回值

      返回值 结果
      0 成功
      非0 失败,参照错误码
    • 依赖

      • 头文件: AudioVadProcess.h

      • 库文件: libVAD_LINUX.so/ libVAD_LINUX.a

    • 举例

      请参考实例介绍

    2.4. IaaVad_Run

    • 功能

      VAD算法处理函数。

    • 语法

      ALGO_VAD_RET IaaVad_Run(VAD_HANDLE handle,short* pss_audio_in);
      
    • 形参

      参数名称 描述 输入/输出
      handle 算法handle 输入
      pss_audio_in 输入数据指针 输入
    • 返回值

      返回值 结果
      0 成功
      非0 失败,参照错误码
    • 依赖

      • 头文件: AudioVadProcess.h

      • 库文件: libVAD_LINUX.so/ libVAD_LINUX.a

    • 举例

      请参考实例介绍

    2.5. IaaVad_Free

    • 功能

      释放VAD算法的资源。

    • 语法

      ALGO_VAD_RET IaaVad_Free(VAD_HANDLE handle);
      
    • 形参

      参数名称 描述 输入/输出
      handle VAD算法handle 输入
    • 返回值

      返回值 结果
      0 成功
      非0 失败,参照错误码
    • 依赖

      • 头文件: AudioVadProcess.h

      • 库文件: libVAD_LINUX.so/ libVAD_LINUX.a

    • 注意

      必须先调用IaaVad_Free,再释放供VAD算法所使用的内存。

    • 举例

      请参考实例介绍

    2.6. IaaVad_SetMode

    • 功能

      VAD算法运行模式设定。

    • 语法

      ALGO_VAD_RET IaaVad_SetMode(VAD_HANDLE handle, int mode);
      
    • 形参

      参数名称 描述 输入/输出
      handle VAD算法handle 输入
      mode 不同的VAD算法。 01为不同的传统侦测人声算法。23为使用深度学习的人声侦测方式 输入
    • 返回值

      返回值 结果
      0 成功
      非0 失败,参照错误码
    • 依赖

      • 头文件: AudioVadProcess.h

      • 库文件: libVAD_LINUX.so/ libVAD_LINUX.a

    • 举例

      请参考实例介绍

    2.7. IaaVad_GetJsonFileSize

    • 功能

      VAD获取解析Json文件内容所需要的内存大小

    • 语法

      unsigned int IaaVad_GetJsonFileSize(char* jsonfile);
      
    • 形参

      参数名称 描述 输入/输出
      jsonfile Json檔名 输入
    • 返回值

      返回值为解析Json文件内容所需要的内存大小

    • 依赖

      • 头文件: AudioVadrocess.h

      • 库文件: libVAD_LINUX.so/ libVAD_LINUX.a

    • 注意

      无。

    • 举例

      无。

    2.8. IaaVad_InitReadFromJson

    • 功能

      配置Json参数到VAD算法的初始化结构体指针

    • 语法

      ALGO_VAD_RET IaaVad_InitReadFromJson(VadInit* vad_init, char* jsonBuffer, char* jsonfile, unsigned int buffSize);
      
    • 形参

      参数名称 描述 输入/输出
      vad_init VAD算法Init 输入
      jsonBuffer 解析Json文件内容所使用的内存地址 输入
      jsonfile Json檔名 输入
      buffSize 解析Json文件内容所需要的内存大小 输入
    • 返回值

      返回值 结果
      0 成功
      非0 失败,参照错误码
    • 依赖

      • 头文件: AudioVadProcess.h

      • 库文件: libVAD_LINUX.so/ libVAD_LINUX.a

    • 注意

      无。

    • 举例

      无。

    2.9. IaaVad_ConfigReadFromJson

    • 功能

      配置Json参数到VAD算法的参数结构体指针

    • 语法

      ALGO_VAD_RET IaaVad_ConfigReadFromJson(VadConfig* vad_config, char* jsonBuffer, char* jsonfile, unsigned int buffSize);
      
    • 形参

      参数名称 描述 输入/输出
      vad_config VAD算法Config 输入
      jsonBuffer 解析Json文件内容所使用的内存地址 输入
      jsonfile Json檔名 输入
      buffSize 解析Json文件内容所需要的内存大小 输入
    • 返回值

      返回值 结果
      0 成功
      非0 失败,参照错误码
    • 依赖

      • 头文件: AudioVadProcess.h

      • 库文件: libVAD_LINUX.so/ libVAD_LINUX.a

    • 注意

      无。

    • 举例

      无。

    2.10. IaaVad_OptionReadFromJson

    • 功能

      配置Json参数到VAD算法的Option结构体指针

    • 语法

      ALGO_VAD_RET IaaVad_OptionReadFromJson(VadOption* vad_option, char* jsonBuffer, char* jsonfile, unsigned int buffSize);
      
    • 形参

      参数名称 描述 输入/输出
      vad_option VAD算法Option 输入
      jsonBuffer 解析Json文件内容所使用的内存地址 输入
      jsonfile Json檔名 输入
      buffSize 解析Json文件内容所需要的内存大小 输入
    • 返回值

      返回值 结果
      0 成功
      非0 失败,参照错误码
    • 依赖

      • 头文件: AudioVadProcess.h

      • 库文件: libVAD_LINUX.so/ libVAD_LINUX.a

    • 注意

      无。

    • 举例

      无。

    2.11. IaaVad_GetResult

    • 功能

      获取VAD算法结果

    • 语法

      ALGO_VAD_RET IaaVad_GetResult(VAD_HANDLE handle, int* vad_result);
      
    • 形参

      参数名称 描述 输入/输出
      handle VAD算法handle 输入
      vad_result 语音活动检测结果。 0为无检测到语音活动,1为有检测到语音活动。 输出
    • 返回值

      返回值 结果
      0 成功
      非0 失败,参照错误码
    • 依赖

      • 头文件: AudioVadProcess.h

      • 库文件: libVAD_LINUX.so/ libVAD_LINUX.a

    • 注意

      无。

    • 举例

      请参考实例介绍

    3. VAD 数据类型

    VAD模块相关数据类型定义如下:

    数据类型 定义
    IAA_VAD_SAMPLE_RATE VAD算法的测采样率类型
    VadSensitivity VAD算法的灵敏度类型
    VadInit VAD算法初始化数据结构体类型
    VadConfig VAD算法参数设置结构体类型
    VAD_HANDLE VAD算法句柄类型
    VadOption VAD算法option设置结构体类型

    3.1. IAA_VAD_SAMPLE_RATE

    • 说明

      定义VAD算法的测采样率类型。

    • 定义

      typedef enum {
      
          IAA_VAD_SAMPLE_RATE_8000  =  8000,
      
          IAA_VAD_SAMPLE_RATE_16000 = 16000,
      
          IAA_VAD_SAMPLE_RATE_48000 = 48000,
      
      }IAA_VAD_SAMPLE_RATE;
      
    • 成员

      成员名称 描述
      IAA_VAD_SAMPLE_RATE_8000 采样率8000Hz
      IAA_VAD_SAMPLE_RATE_16000 采样率16000Hz
      IAA_VAD_SAMPLE_RATE_48000 采样率48000Hz
    • 注意事项

      MODE2 及 MODE3 仅支援 8000Hz 采样率。

    • 相关数据类型及接口

      VadInit

    3.2. VadSensitivity

    • 说明

      定义VAD算法的灵敏度类型。

    • 定义

      typedef enum {
      
          VAD_SEN_LOW,
      
          VAD_SEN_MID,
      
          VAD_SEN_HIGH,
      
      }VadSensitivity;
      
    • 成员

      成员名称 描述
      VAD_SEN_LOW 低灵敏度, 较不容易发报
      VAD_SEN_MID 中灵敏度
      VAD_SEN_HIGH 高灵敏度, 较容易发报
    • 注意事项

      无。

    • 相关数据类型及接口

      VadConfig

    3.3. VadInit

    • 说明

      定义VAD算法的初始化参数类型。

    • 定义

      typedef struct
      
      {
      
          unsigned int point_number;
      
          unsigned int channel;
      
          IAA_VAD_SAMPLE_RATE sample_rate;
      
      }VadInit;
      
    • 成员

      成员名称 描述
      point_number VAD算法处理一次的采样点数
      channel 通道数
      sample_rate 采样率,目前支持8k/16k/48k
    • 注意事项

      无。

    • 相关数据类型及接口

      IaaVad_Init

      IaaVad_InitReadFromJson

    3.4. VadConfig

    • 说明

      定义VAD算法的配置参数结构体类型。

    • 定义

      typedef struct
      
      {
      
          unsigned int vote_frame;
      
          VadSensitivity sensitivity;
      
      }VadConfig;
      
    • 成员

      成员名称 描述
      vote_frame 在 mode 0 下,最终估算结果所需长度,即延迟帧数。其他模式不受此参数影响。
      sensitivity 灵敏度设置
    • 相关数据类型及接口

      IaaVad_Config

      IaaVad_ConfigReadFromJson

    3.5. VAD_HANDLE

    3.6. VadOption

    • 说明

      VAD算法Option设置结构体类型

    • 定义

      typedef struct{
      
          int mode;
      
      }VadOption;
      
    • 成员

      成员名称 描述
      mode 设置VAD运行之算法,用于 IaaVad_SetMode
    • 注意事项

      无。

    • 相关数据类型及接口

      IaaVad_OptionReadFromJson

    4. ERROR CODE

    VAD API 错误码如表下所示:

    错误码 宏定义 描述
    0x00000000 ALGO_VAD_RET_SUCCESS VAD 运行成功
    0x10000901 ALGO_VAD_RET_INIT_ERROR VAD 尚未初始化
    0x10000902 ALGO_VAD_RET_INVALID_HANDLE VAD HANDLE HANDLE无效
    0x10000903 ALGO_VAD_RET_INVALID_SAMPLE_RATE 取样频率不支持
    0x10000904 ALGO_VAD_RET_INVALID_POINT_NUMBER 每帧点数不支持
    0x10000905 ALGO_VAD_RET_INVALID_CHANNEL 通道数不支持
    0x10000906 ALGO_VAD_RET_INVALID_CONFIG 错误参数设定
    0x10000907 ALGO_VAD_RET_INVALID_MODE VAD 运行模式设定无效
    0x10000908 ALGO_VAD_RET_API_CONFLICT 其他API正在运行
    0x10000909 ALGO_VAD_RET_INVALID_CALLING 呼叫API顺序错误
    0x10000910 ALGO_VAD_RET_INVALID_JSONFILE VAD 读取Json档失败