BF算法使用参考


1. 概述

1.1. 算法说明

BF(beamforming)波束形成是一种用于传感器阵列传输或接收的定向信号处理技术,通过空间滤波法搭配传感器阵列实现特定角度的信号强化,并压抑其他方向的信号。波束形成可用于发射端和接收端实现空间选择性。

1.2. 关键词说明

1.2.1. 噪音阀值

Noise Gate(dBFS),BF的滤波器只有在录制音量低于噪音阀值才会做为噪声部份进行更新。若设置太高,可能造成语音失真。若设置太低,BF无法更新滤波器,会使用过去的滤波器进行空间滤波。应小心处理此值设定。此参数必须考虑实际麦克风所录制的音量大小,若麦克风录制音量太小且此值设定较大,则该帧会当成噪声部分处理,此值范围为[-80,0],建议值为-20,步长为1。

1.2.2. 对角负载

透过在矩阵的对角线元素增加对角负载(Diagonal loading),可以保证反矩阵必定存在达成正则化,因而提升BF滤波器的强健性。应小心处理此值设定,若设置太高,会影响算法效果,若设置太低,容易造成语音失真,此值范围为[100,1],建议值为10,步长为1。

1.3. 注意

1.3.1. 使用

为方便调试和确认算法效果,需要使用者应用自行实现替换算法参数和抓取音频数据的逻辑。

1.3.2. 搭配

此模块搭配音频处理链APC(Audio Process Chain)会有最佳的信号加强、压制干扰的效果。

1.3.3. 区分

不同通道数会对应到不同参考库。用户需要自行确认是否使用正确的通道数及对应的参考库。

2. 规格

  • 麦克风个数必须至少两颗或以上。

  • 必须使用同规格的麦克风。

  • 麦克风增益必须相同。

  • 在安静的背景环境,可以达到最好的效果。

  • 使用音档作为声源时,必须确保音文件中没有发生信号剪裁,如图一所示:

    图一 信号剪裁示意图

3. 阵列系统及坐标系

3.1. 多麦克风阵列

多麦克风阵列相较于双麦克风阵列,拥有更好的带宽分辨率以及更多组麦克风权重,可以提升定位以及空间滤波的表现而达到更好的特定角度加强效果,其中特定角度即为声音方向的角度。常见的多麦克风阵列主要有两类,分别是均匀线性阵列以及均匀圆形阵列。以下皆为二维示意图(无高度差的影响)。

3.1.1. 均匀线性阵列及坐标系

均匀线性阵列为一直线排列,且相邻麦克风的间距皆相同,并且由于其具有对称性,加强角度仅考虑上半平面(-90度至90度)。图二为均匀线性阵列于空间坐标系的示意图。声音方向的角度定义为与阵列中心及x轴的夹角。逆时钟方向为正。间距单位为公分,建议至少大于 5cm 或 6cm。

图二 均匀线性阵列及其坐标系

3.1.2. 均匀圆形阵列及坐标系

均匀圆形阵列为一圆形排列,且相邻麦克风与阵列中心的夹角皆相同,麦克风间距即为圆形的直径,由于不具对称性,加强角度可以为整个平面,图三为均匀圆形阵列于空间坐标系的示意图。声音方向的角度定义为与阵列中心及x轴的夹角。逆时钟方向为正。间距为圆形的直径。单位为公分。建议至少大于6cm。

图三 均匀圆形阵列及其坐标系

4. API 参考

4.1. 功能模块API

API名 功能
IaaBf_GetBufferSize 获取Bf算法运行需要的内存大小
IaaBf_Init 初始化Bf算法
IaaBf_SetConfig 配置Bf算法
IaaBf_GetConfig 获取Bf算法当前的配置参数信息
IaaBf_SetShape Bf指派麦克风阵列形状
IaaBf_Run Bf算法处理
IaaBf_Reset 重新初始化Bf算法
IaaBf_Free 释放Bf算法资源
IaaBf_SetArbitraryShape Bf指派任意麦克风阵列形状
IaaBf_GetArrayPosition Bf获取设定的麦克风阵列位置
IaaBf_DynamicLoading Bf指定带宽大小及对应对角负载强度
IaaBf_SetMode Bf指定使用模式
IaaBf_SetAdaptiveIntensity Bf指定模式0、模式3或模式4迭代的强度
IaaBf_SetCallbackFunction Bf算法对Ikayaki芯片的授权管控
IaaBf_GetAPIVersion 返回当前Bf算法版号
IaaBf_SetPfFlow Bf指定后滤波器应用位置
IaaBf_SetCalibration Bf校正麦克风间音量差异

4.2. IaaBf_GetBufferSize

  • 功能

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

  • 语法

    unsigned int IaaBf_GetBufferSize(void);
    
  • 返回值

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

  • 依赖

    • 头文件: AudioBfProcess.h

    • 库文件: libBF_2MIC_LINUX.so/ libBF_2MIC_LINUX.a/ libBF_4MIC_LINUX.so/libBF_4MIC_LINUX.a

  • 注意

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

  • 举例

    请参考IaaBf_Run举例部分。

4.3. IaaBf_Init

  • 功能

    初始化Bf算法。

  • 语法

    BF_HANDLE IaaBf_Init(char* working_buffer,AudioBfInit* bf_init);
    
  • 形参

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

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

    • 头文件: AudioBfProcess.h

    • 库文件: libBF_2MIC_LINUX.so/ libBF_2MIC_LINUX.a/ libBF_4MIC_LINUX.so/libBF_4MIC_LINUX.a

  • 举例

    请参考IaaBf_Run举例部分。

4.4. IaaBf_SetConfig

  • 功能

    配置Bf算法。

  • 语法

    ALGO_BF_RET IaaBf_SetConfig(BF_HANDLE handle,AudioBfConfig* bf_config);
    
  • 形参

    参数名称 描述 输入/输出
    handle Bf算法handle 输入
    bf_config Bf算法的配置结构体指针 输入
  • 返回值

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

    • 头文件: AudioBfProcess.h

    • 库文件: libBF_2MIC_LINUX.so/ libBF_2MIC_LINUX.a/ libBF_4MIC_LINUX.so/libBF_4MIC_LINUX.a

  • 举例

    请参考IaaBf_Run举例部分。

4.5. IaaBf_GetConfig

  • 功能

    获取Bf算法当前的配置参数。

  • 语法

    ALGO_BF_RET IaaBf_GetConfig(BF_HANDLE handle,AudioBfConfig* bf_config);
    
  • 形参

    参数名称 描述 输入/输出
    handle Bf算法handle 输入
    bf_config Bf算法的配置结构体指针 输出
  • 返回值

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

    • 头文件: AudioBfProcess.h

    • 库文件: libBF_2MIC_LINUX.so/ libBF_2MIC_LINUX.a/ libBF_4MIC_LINUX.so/libBF_4MIC_LINUX.a

  • 举例

    请参考IaaBf_Run举例部分。

4.6. IaaBf_SetShape

  • 功能

    Bf指派麦克风阵列形状。

  • 语法

    ALGO_BF_RET IaaBf_Setshape(BF_HANDLE handle,int shape);
    
  • 形参

    参数名称 描述 输入/输出
    handle Bf算法handle 输入
    shape 指派阵列形状。0:均匀线性阵列,1:均匀圆形阵列 输入
  • 返回值

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

    • 头文件: AudioBfProcess.h

    • 库文件: libBF_2MIC_LINUX.so/ libBF_2MIC_LINUX.a/ libBF_4MIC_LINUX.so/libBF_4MIC_LINUX.a

  • 注意

    • 仅提供均匀线性阵列及均匀圆型阵列(示意图请看图一及图二),客户有特殊阵列需求,需告知修改

    • 麦克风个数为2个时,只存在线性阵列,其间距即为所设定麦克风间距

    • 阵列位置设定会强烈影响波束形成效果,因此设定的阵列位置必须与真实阵列位置相同

  • 举例

    请参考IaaBf_Run举例部分。

4.7. IaaBf_Run

  • 功能

    BF算法处理。

  • 语法

    ALGO_BF_RET IaaBf_Run(BF_HANDLE handle, short* microphone_input, short* microphone_output,float* microphone_doa);
    
  • 形参

    参数名称 描述 输入/输出
    handle Bf算法handle 输入
    microphone_input 待进行声源定位的数据指针 输入
    microphone_output 经过算法后的数据输出指针 输出
    microphone_doa Beamforming处理的角度。此参数可由用户设定(较为直观),也可由SSL计算(SSL会计算接收信号的时间差,还需要一个转换才能换至角度)。如果声音来自正前方,可输入0。如果声音来自左右两侧,可输入90或-90 输入
  • 返回值

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

    • 头文件: AudioBfProcess.h

    • 库文件: libBF_2MIC_LINUX.so/ libBF_2MIC_LINUX.a/ libBF_4MIC_LINUX.so/libBF_4MIC_LINUX.a

  • 注意

    • 对于两颗麦克风阵列(双声道音频可以负荷),microphone_input指向的数据应以采样点为最小单位,按照左->右->左->右的格式摆放,数据长度必须和IaaBf_Init中设定的point_number(即多少个采样点进行一次beamforming处理)相对应。请参考范例一

    • 对于多颗麦克风阵列(麦克风数多于两颗,双声道音频无法负荷)的情况,各个麦克风音频须为单声道,microphone_input指向的数据仍应已采样点为最小单位,并按照麦克风于阵列的相对位置,由左至右的格式摆放,例如4颗线性麦克风阵列,摆放的方式为 [左一→左二→右二→右一],数据长度必须和IaaBf_Init中设定的point_number(即多少个采样点进行一次beamforming处理)相对应。请参考范例二

    • microphone_output数据长度必须和IaaBf_Init中设定的Point_number相对应。

      若Point_number为128点,则4颗阵列的microphone_input长度为128x4=512点,输出microphone_output为128点。

  • 举例

    • 范例一:两颗麦克风阵列(麦克风输入为双声道音频)

      #include <stdio.h>
      #include <unistd.h>
      #include <fcntl.h>
      #include <string.h>
      #include <sys/time.h>
      #include <sys/ioctl.h>
      #include <stdlib.h>
      #include "AudioBfProcess.h"
      
      #define USE_MALLOC   (1)
      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 ) / 1000;
          return T;
      }
      
      int main(int argc, char *argv[])
      {
          short input[256];
          short output[128];
          char infileName[512];
          char outfileName[512];
      
          FILE * fin, * fout;
          ALGO_BF_RET ret;
          int shape = 0;
          float direction = 0.0;
          int delay_sample = 0;
          float avg = 0;
          int counter = 0;
          unsigned int T0,T1;
          AudioBfInit bf_init;
          AudioBfConfig bf_config;
          BF_HANDLE handle;
          bf_init.mic_distance = 8.0;
          bf_init.point_number = 128;
          bf_init.sample_rate = 16000;
          bf_init.channel = 2;
          bf_config.noise_gate_dbfs = -20;
          bf_config.temperature = 20;
          bf_config.noise_estimation = 0;
          bf_config.output_gain = 0.7;
              bf_config.vad_enable = 0;
          bf_config.diagonal_loading = 10;
      #if USE_MALLOC
          char *WorkingBuffer2;
          WorkingBuffer2 = (char*)malloc(IaaBf_GetBufferSize());
      #endif
          handle = IaaBf_Init((char*)WorkingBuffer2, &bf_init);
          if (handle==NULL)
          {
              printf("BF init error\r\n");
              return -1;
          }
          else
          {
              printf("BF init succeed\r\n");
          }
          ret = IaaBf_SetConfig(handle,&bf_config);
          if (ret)
          {
              printf("Error occured in Config\n");
              return -1;
          }
          ret = IaaBf_SetShape(handle,shape);
          if (ret)
          {
              printf("Error occured in Array shape\n");
              return -1;
          }
          sprintf(infileName,"%s","./../sample/data/Chn-14.wav");
          sprintf(outfileName,"%s","./BFOut.pcm");
      
          fin = fopen(infileName, "rb");
          if(!fin)
          {       printf("the input file could not be open\n");
              return -1;
          }
      
          fout = fopen(outfileName, "wb");
          if(!fout)
          {
              printf("the output file could not be open\n");
              return -1;
          }
      
          fread(input, sizeof(char), 44, fin); // read header 44 bytes
          fwrite(input, sizeof(char),44, fout); // write 44 bytes output
          // int delay_sample = 0;
          while(fread(input, sizeof(short), bf_init.point_number*bf_init.channel, fin))
          {
              counter++;
              T0  = (long)_OsCounterGetMs();
              ret = IaaBf_Run(handle,input,output,&direction);
              T1  = (long)_OsCounterGetMs();
              avg += (T1 - T0);
              if(ret)
              {
                  printf("Error occured in Run\n");
                  return -1;
              }
              fwrite(output, sizeof(short), bf_init.point_number, fout);
          }
          avg /= counter;
          printf("AVG is %.2f ms\n",avg);
          IaaBf_Free(handle);
          fclose(fin);
          fclose(fout);
          free(WorkingBuffer2);
          printf("Done\n");
          return 0;
      }
      
    • 范例二:多颗麦克风阵列(麦克风输入为4个单声道音讯)

      #include <stdio.h>
      #include <unistd.h>
      #include <fcntl.h>
      #include <string.h>
      #include <sys/time.h>
      #include <sys/ioctl.h>
      #include <stdlib.h>
      #include "AudioBfProcess.h"
      
      #define MIC_NUM (4)
      #define USE_MALLOC   (1)
      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 ) / 1000;
          return T;
      }
      
      int main(int argc, char *argv[])
      {
          /*********Input file init*******/
          short input[512];
          short output[128];
          short input_tmp1[128],input_tmp2[128],input_tmp3[128],input_tmp4[128];
          FILE * fin0, * fin1, * fin2, * fin3, * fout;
      
          char infileName[MIC_NUM][512];
          char outfileName[512];
          ALGO_BF_RET ret;
          int k;
          float avg = 0;
          int counter = 0;
          unsigned int T0, T1;
          /********common setting between SSL and BF********/
          int point_number = 128;
          float microphone_distance = 4.0;
          int temperature = 20;
          int sample_rate = 16000;
          int shape =  0;
          // int delay_sample[MIC_NUM-1] = {0,0,0}; //channel-1
          float direction = 0.0;
          /*******BF data init*********/
      #if USE_MALLOC
          char *WorkingBuffer_BF;
          WorkingBuffer_BF = (char*)malloc(IaaBf_GetBufferSize());
      #endif
      
          AudioBfInit bf_init;
          AudioBfConfig bf_config;
          BF_HANDLE bf_handle;
          bf_init.mic_distance = microphone_distance;
          bf_init.point_number = point_number;
          bf_init.sample_rate = sample_rate;
          bf_init.channel = MIC_NUM;
          bf_config.noise_gate_dbfs = -20;
          bf_config.temperature = temperature;
          bf_config.noise_estimation = 0;
          bf_config.output_gain = 0.7;
          bf_config.vad_enable = 0;
          bf_config.diagonal_loading = 10;
          bf_handle = IaaBf_Init((char*)WorkingBuffer_BF, &bf_init);
          if (bf_handle==NULL)
          {
              printf("BF init error\r\n");
              return -1;
          }
          else
          {
              printf("BF init succeed\r\n");
          }
          ret = IaaBf_SetConfig(bf_handle,&bf_config);
          if (ret)
          {
              printf("Error occured in Config\n");
              return -1;
          }
          ret = IaaBf_SetShape(bf_handle,shape);
          if (ret)
          {
              printf("Error occured in Array shape\n");
              return -1;
          }
          /********open input file and output file*****/
          sprintf(infileName[0],"%s","./../sample/data/Chn-01.wav");
          sprintf(infileName[1],"%s","./../sample/data/Chn-02.wav");
          sprintf(infileName[2],"%s","./../sample/data/Chn-03.wav");
          sprintf(infileName[3],"%s","./../sample/data/Chn-04.wav");
          sprintf(outfileName,"%s","./BFOut.pcm");
      
          fin0 = fopen(infileName[0], "rb");
          if(!fin0)
          {
              printf("the input file 0 could not be open\n");
              return -1;
          }
      
          fin1 = fopen(infileName[1], "rb");
          if(!fin1)
          {
              printf("the input file 1 could not be open\n");
              return -1;
          }
          fin2 = fopen(infileName[2], "rb");
          if(!fin2)
          {
              printf("the input file 2 could not be open\n");
              return -1;
          }
          fin3 = fopen(infileName[3], "rb");
          if(!fin3)
          {
              printf("the input file 3 could not be open\n");
              return -1;
          }
          fout = fopen(outfileName, "wb");
          if(!fout)
          {
              printf("the output file could not be open\n");
              return -1;
          }
          fread(input, sizeof(char), 44, fin0);
          fread(input, sizeof(char), 44, fin1);
          fread(input, sizeof(char), 44, fin2);
          fread(input, sizeof(char), 44, fin3);
          fwrite(input, sizeof(char),44, fout);
          short * input_ptr;
      
          while(fread(input_tmp1, sizeof(short), bf_init.point_number, fin0))
          {
              fread(input_tmp2, sizeof(short), bf_init.point_number, fin1);
              fread(input_tmp3, sizeof(short), bf_init.point_number, fin2);
              fread(input_tmp4, sizeof(short), bf_init.point_number, fin3);
              input_ptr = input;
              for(k=0;k<point_number;k++)
              {
                  *input_ptr =  input_tmp1[k];
                  input_ptr++;
                  *input_ptr =  input_tmp2[k];
                  input_ptr++;
                  *input_ptr =  input_tmp3[k];
                  input_ptr++;
                  *input_ptr =  input_tmp4[k];
                  input_ptr++;
              }
              counter++;
              T0  = (long)_OsCounterGetMs();
              ret = IaaBf_Run(bf_handle,input,output,&direction);
              T1  = (long)_OsCounterGetMs();
              avg += (T1 - T0);
              if(ret)
              {
                  printf("Error occured in Run\n");
                  return -1;
              }
              fwrite(output, sizeof(short),point_number, fout);
          }
          avg /= counter;
          printf("AVG is %.2f ms\n",avg);
          IaaBf_Free(bf_handle);
          fclose(fin0);
          fclose(fin1);
          fclose(fin2);
          fclose(fin3);
          fclose(fout);
          free(WorkingBuffer_BF);
          printf("Done\n");
      
          return 0;
      }
      

4.8. IaaBf_Reset

  • 功能

    重新初始化Bf算法。

  • 语法

    BF_HANDLE IaaBf_Reset(BF_HANDLE working_buffer,AudioBfInit* bf_init);
    
  • 形参

    参数名称 描述 输入/输出
    working_buffer Bf算法运行的内存地址 输入
    bf_init Bf算法的初始化参数结构体指针 输入
  • 返回值

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

    • 头文件: AudioBfProcess.h

    • 库文件: libBF_2MIC_LINUX.so/ libBF_2MIC_LINUX.a/ libBF_4MIC_LINUX.so/libBF_4MIC_LINUX.a

4.9. IaaBf_Free

  • 功能

    释放Bf算法资源。

  • 语法

    ALGO_BF_RET IaaBf_Free(BF_HANDLE handle);
    
  • 形参

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

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

    • 头文件: AudioBfProcess.h

    • 库文件: libBF_2MIC_LINUX.so/ libBF_2MIC_LINUX.a/ libBF_4MIC_LINUX.so/libBF_4MIC_LINUX.a

  • 举例

    请参考IaaBf_Run举例部分。

4.10. IaaBf_SetArbitraryShape

  • 功能

    Bf指派任意麦克风阵列形状

  • 语法

    ALGO_BF_RET IaaBf_SetArbitraryShape(BF_HANDLE handle, float* array_pos);
    
  • 形参

    参数名称 描述 输入/输出
    handle Bf算法handle 输入
    array_pos 输入的阵列位置指针,单位:公分 输入
  • 返回值

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

    • 头文件: AudioBfProcess.h

    • 库文件: libBF_2MIC_LINUX.so/ libBF_2MIC_LINUX.a/ libBF_4MIC_LINUX.so/libBF_4MIC_LINUX.a

  • 注意

    • 此功能帮助用户设定任意的阵列形状。如果此功能于IaaBf_SetShape后呼叫,则会覆写原本IaaBf_SetShape定义的矩阵形状,反之亦然。

    • 输入阵列为卡式坐标系下的[X,Y]坐标,因此必须包含(麦克风个数 * 2) 个元素,阵列中心定义为输入的麦克风阵列分别沿着 X及Y 轴的平均值。

    • 各麦克风位置定义为阵列中心指向各麦克风位置的向量,声音方向的角度(microphone_doa)仍定义为与阵列中心及x轴的夹角。逆时钟方向为正。

    • 以四颗麦克风为例,如果给定 array_pos:{-4,-2,-1,-3,2,3,4,2},阵列中心[X=0.25,Y=0], Mic1[X=-4.25,Y=-2],Mic2 [X=-1.25,Y=-3], Mic3 [X=1.75,Y=3], Mic4 [X=3.75,Y=2].

4.11. IaaBf_GetArrayPosition

  • 功能

    Bf获取设定的麦克风阵列位置。

  • 语法

    ALGO_BF_RET IaaBf_GetArrayPosition(BF_HANDLE handle,float* array_pos);
    
  • 形参

    参数名称 描述 输入/输出
    handle Bf算法handle 输入
    array_pos 输入的阵列位置指针,单位:公分 输入/输出
  • 返回值

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

    • 头文件: AudioBfProcess.h

    • 库文件: libBF_2MIC_LINUX.so/ libBF_2MIC_LINUX.a/ libBF_4MIC_LINUX.so/libBF_4MIC_LINUX.a

  • 注意

    • 输出为代表卡式坐标系的三维坐标,依序为X,Y,Z 坐标,其Z坐标皆为0,因此阵列必须要含有(麦克风个数 * 3)个元素

    • 如果此功能在IaaBf_SetShape后呼叫,输出的麦克风顺序如章节3.1(由左至右)

    • 如果此功能在IaaBf_SetArbitraryShape后呼叫,输出的麦克风顺序如同IaaBf_SetArbitraryShape的输入顺序

    • 此功能仅作为辅助功能回传麦克风阵列位置,并不影响算法本身。

4.12. IaaBf_DynamicLoading

  • 功能

    Bf指定带宽大小及对应对角负载强度。

  • 语法

    ALGO_BF_RET IaaBf_DynamicLoading(BF_HANDLE handle,int* band, int* dl_intensity, int* is_dynamic);
    
  • 形参

    参数名称 描述 输入/输出
    handle Bf算法handle 输入
    band 频率范围指针,范围:[1,128],步长:1 输入
    dl_intensity 对角负载强度指针,
    范围:[1,1000],步长:1
    输入
    is_dynamic 是否使用,范围:[0,1],0:关闭 1:启用 输入
  • 返回值

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

    • 头文件: AudioBfProcess.h

    • 库文件: libBF_2MIC_LINUX.so/ libBF_2MIC_LINUX.a/ libBF_4MIC_LINUX.so/libBF_4MIC_LINUX.a

  • 注意

    • 使用此功能前必须先执行IaaBf_SetConfig才能使用,并且只有在is_dynamic为1时才会应用至算法中

    • band为频率范围指针,只有前六个元素会被使用并且后一个元素必须大于等于前一个元素。

    • 当前采样率对应的最高频率平均分成128份,频率范围则是对应多少份组成一个频带。

    • 如:当前采样率为16K,对应的最大频率为8K,每一份为8000 / 128 ≈ 62.5Hz。如在{4,6,36, 49,50,51}的设定下,频率范围为{0~4 * 62.5Hz, 4~6 * 62.5Hz, 6~36 * 62.5Hz, 36~49 * 62.5Hz, 49~50 * 62.5Hz, 50~51 * 62.5Hz, 51-127 * 62.5Hz} = {0~250Hz, 250~375Hz, 375~2250Hz, 2250~3062.5Hz, 3062.5~3125Hz, 3125~3187.5Hz, 3187.5Hz~8000Hz}。因此会切出七个频带。

    • dl_intensity为对角负载强度指针,只有前七个元素会被使用并且会在自己所属的各频带(由band所定义的频带)上对AudioBfConfig的对角负载做放大。

    • 此功能并不一定要呼叫,预设为关闭。算法会根据设定的AudioBfConfig执行。

4.13. IaaBf_SetMode

  • 功能

    Bf指定使用模式。

  • 语法

    ALGO_BF_RET IaaBf_SetMode(BF_HANDLE handle,float choose_doa, int mode);
    
  • 形参

    参数名称 描述 输入/输出
    handle Bf算法handle 输入
    choose_doa Beamforming处理的角度, 如果声音来自正前方,可输入0。如果声音来自左右两侧,可输入90或-90 输入
    mode 使用的BF模式,范围:[0,4],步长:1 输入
  • 返回值

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

    • 头文件: AudioBfProcess.h

    • 库文件: libBF_2MIC_LINUX.so/ libBF_2MIC_LINUX.a/ libBF_4MIC_LINUX.so/libBF_4MIC_LINUX.a

  • 注意

    • 目前算法库支持模式 0~4。 0: 迭代式波束形成,1: 固定式波束形成,2: 广义旁瓣相消式波束形成,3: 强化型迭代波束形成,4: AI强化型波束形成。若无呼叫此功能,BF默认使用 0: 迭代式波束形成。

    • 算法速度: Mode 1 > Mode 2 > Mode 0 > Mode 3 > Mode 4,降噪及空间滤波效果: Mode 4 > Mode 3 > Mode 0 > Mode 2 > Mode 1。

    • Mode 3 降噪效果较佳但会有些微失真,可设定不同的欲加强方向。不同加强方向之间不具有可旋转的关系,与阵列的物理特性有关。

    • 当Mode 3 或 Mode 4 与APC一起使用且AudioAnrConfig 的 anr_filter_mode 为 5(深度学习降噪)时,必须在APC使用以下的特定API: IaaApc_EnhanceNNBFMode。

    • Mode 3 与 Mode 4 同为 Mode 0的后置滤波器,可透过 IaaBf_SetPfFlow 设定此滤波器于算法流程下之位置。目前可设定在音频流程图中的两个位置,(1):直接作用于BF输出,(2):搭配APC作用于APC输出。

    • Mode 4 仅支持线性阵列及16KHz的取样率,并且不可设定角度(固定加强正前方)。半功率波束宽度设计为+-35度。对于在此波束宽度外的声源,会进行压抑。

    • 当使用Mode 4时,最好使用间距5公分的线性阵列(不保证其他间距效果)。并且Mode 4仅提供LINUX静态库。

4.14. IaaBf_SetAdaptiveIntensity

  • 功能

    Bf指派模式0、模式3或模式4迭代的强度。

  • 语法

    ALGO_BF_RET IaaBf_SetAdaptiveIntensity(BF_HANDLE handle,int intensity);
    
  • 形参

    参数名称 描述 输入/输出
    handle Bf算法handle 输入
    intensity 范围:[0,4],步长:1。
    0: 低强度; 1,2: 一般强度; 3,4: 高强度
    输入
  • 返回值

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

    • 头文件: AudioBfProcess.h

    • 库文件: libBF_2MIC_LINUX.so/ libBF_2MIC_LINUX.a/ libBF_4MIC_LINUX.so/libBF_4MIC_LINUX.a

  • 注意

    • 此功能会指定迭代式波束形成(如:模式0、模式3、模式4) 的强度。设定的强度越强,方向性干扰抑制效果越好但可能伴随较多失真,尤其是强化型迭代波束形成以及AI强化型波束形成。

    • 若未使用此功能,默认为使用一般强度。

4.15. IaaBf_SetCallbackFunction

  • 功能

    BF算法对Ikayaki芯片的授权管控

  • 语法

    ALGO_BF_RET IaaBf_SetCallbackFunction(int(*log)(const char *szFmt, ...),int(*envSet)(char *key, char *par),int(*envGetString)(char *var, char *buf, unsigned int size),int(*envSave)(void),int(*readUuid)(unsigned long long *u64Uuid));
    
  • 形参

    参数名称 描述 输入/输出
    log 打印debug 讯息的函式指针 输入
    envSet 设置环境变量的函式指针(目前还没有实际作用) 输入
    envGetString 获取环境变量中的授权信息的函式指针 输入
    envsave 保存计算出来的授权码讯息至环境变量的函式指针(目前没有实际作用) 输入
    readUuid 读取等待授权板子的Uuid 的函式指针 输入
  • 返回值

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

    • 头文件: AudioBfProcess.h

    • 库文件: libBF_2MIC_LINUX.so/ libBF_2MIC_LINUX.a/ libBF_4MIC_LINUX.so/libBF_4MIC_LINUX.a

  • 注意

    • 此为Bf对Ikayaki芯片的授权管控,其余芯片不受影响
    • 若使用Ikayaki芯片,根据授权成功与否会有其对应的使用时间

4.16. IaaBf_GetAPIVersion

  • 功能

    返回当前Bf算法版号

  • 语法

    ALGO_BF_RET IaaBf_GetAPIVersion(unsigned short* major, unsigned short* minor);
    
  • 形参

    参数名称 描述 输入/输出
    major 主版号 输入/输出
    minor 副版号 输入/输出
  • 返回值

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

    • 头文件: AudioBfProcess.h

    • 库文件: libBF_2MIC_LINUX.so/ libBF_2MIC_LINUX.a/ libBF_4MIC_LINUX.so/libBF_4MIC_LINUX.a

4.17. IaaBf_SetPfFlow

  • 功能

    Bf指定后滤波器应用位置

  • 语法

    ALGO_BF_RET IaaBf_SetPfFlow(BF_HANDLE handle, BF_WORKFLOW bf_workflow);
    
  • 形参

    参数名称 描述 输入/输出
    handle Bf算法handle 输入
    bf_workflow 后滤波器之使用位置 输入
  • 返回值

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

    • 头文件: AudioBfProcess.h

    • 库文件: libBF_2MIC_LINUX.so/ libBF_2MIC_LINUX.a/ libBF_4MIC_LINUX.so/libBF_4MIC_LINUX.a

  • 注意

    • 目前算法库支持后滤波器位置为 0~1。 0: 应用在APC输出,1: 应用在BF输出,若无呼叫此功能,默认使用 1。

    • 当 bf_workflow 设置为0,后滤波器会应用在APC输出,此时BF内建的传统降噪会关闭由APC进行代替,可在APC端进行调整降噪的方法或强度。

    • 当 bf_workflow 设置为1,后滤波器会应用在BF输出,此时BF内建的传统降噪会开启,后端APC的降噪部分建议关闭,避免过度压抑噪音导致失真。

4.18. IaaBf_SetCalibration

  • 功能

    Bf校正麦克风间音量差异

  • 语法

    ALGO_BF_RET IaaBf_SetCalibration(BF_HANDLE handle, BF_CALIBRATION calibration_flag);
    
  • 形参

    参数名称 描述 输入/输出
    handle Bf算法handle 输入
    calibration_flag 是否需要校正 输入
  • 返回值

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

    • 头文件: AudioBfProcess.h

    • 库文件: libBF_2MIC_LINUX.so/ libBF_2MIC_LINUX.a/ libBF_4MIC_LINUX.so/libBF_4MIC_LINUX.a

  • 注意

    • 此算法为人工校正麦克风间的音量差异。 0: 无校正音量,1: 校正麦克风间音量差异,若无呼叫此功能,默认使用 0。

5. BF 数据类型

5.1. BF模块相关数据类型定义

数据类型 定义
AudioBfInit Bf算法初始化参数结构体类型
AudioBfConfig Bf算法配置参数结构体类型
BF_HANDLE Bf算法句柄类型
BF_WORKFLOW 定义Bf算法后滤波器的位置
BF_CALIBRATION Bf算法音量校正旗帜

5.2. AudioBfInit

  • 说明

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

  • 定义

    typedef struct
    
    {
    
        unsigned int point_number;
    
        unsigned int sample_rate;
    
        float mic_distance;
    
        unsigned int channel;
    
    }AudioBfInit;
    
  • 成员

    成员名称 描述
    point_number Bf算法处理一次的采样点数,仅支持128点
    sample_rate 采样率,目前支持8k/16k/32k/48k
    mic_distance 相邻麦克风的间的间距,单位为cm,建议为5cm 或6cm
    channel 通道数。仅支持两颗或四颗麦克风
  • 相关数据类型及接口

    IaaBf_Init

    IaaBf_Reset

5.3. AudioBfConfig

  • 说明

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

  • 定义

    typedef struct
    
    {
    
        unsigned int temperature;
    
        int noise_gate_dbfs;
    
        int noise_estimation;
    
        float output_gain;
    
        int vad_enable;
    
        int diagonal_loading;
    
    }AudioBfConfig;
    
  • 成员

    成员名称 描述
    temperature 环境温度(摄氏度) 摄氏度=(5/9)*(华氏度-32) 步长为1
    noise_gate_dbfs 噪音阀值(dB) 低于此值将会把该帧作为噪声部分处理。 应小心处理此值。 此参数必须考虑实际麦克风所录制的音量大小。 若设置太高,容易造成语音失真。 若设定置太低,会影响BF的效果。 建议值为 -20,步长为1。
    noise_estimation 噪声的估计模式,输入值为0或1。 0为自适应模式 1为平均模式 一般状况下推荐使用0
    output_gain 输出增益,范围[0,1]。 设定为0.7为正常情况,设定为1,会增加4dB 建议值为0.7,不增加任何增益
    vad_enable 语音活检测(VAD)模式是否开启,输入值为0或1。 若开启此设定,则利用VAD来计算每帧是否进入噪音估计处理。 若关闭此设定,则利用上述所设定的noise_gate_dbfs来决定是否视为噪音处理。
    diagonal_loading 对角负载(Diagonal loading),应小心处理此值设定 若设置太高,会影响算法效果。 若设置太低,容易造成语音失真。 建议值为10 。
  • 相关数据类型及接口

    IaaBf_SetConfig

    IaaBf_GetConfig

5.4. BF_HANDLE

5.5. BF_WORKFLOW

  • 说明

    定义Bf算法后滤波器之位置。

  • 定义

    typedef enum {
    
        BF_WORKFLOW_AFTER_APC = 0,
    
        BF_WORKFLOW_AFTER_BF = 1,
    
    }BF_WORKFLOW;
    
  • 成员

    成员名称 描述
    BF_WORKFLOW_AFTER_APC 在APC后应用后滤波器
    BF_WORKFLOW_AFTER_BF 在BF后应用后滤波器
  • 注意事项

    无。

  • 相关数据类型及接口

    IaaBf_SetPfFlow

5.6. BF_CALIBRATION

  • 说明

    Bf算法音量校正旗帜。

  • 定义

    typedef enum {
    
        BF_CALIBRATION_DISABLE = 0,
    
        BF_CALIBRATION_ENABLE  = 1,
    
    }BF_CALIBRATION;
    
  • 成员

    成员名称 描述
    BF_CALIBRATION_DISABLE 不校正音量直接进行Bf算法
    BF_CALIBRATION_ENABLE 在进行Bf算法前校正音量
  • 注意事项

    无。

  • 相关数据类型及接口

    IaaBf_SetCalibration

6. 错误码

BF API 错误码如下表所示:

错误码 宏定义 描述
0x00000000 ALGO_BF_RET_SUCCESS BF执行成功
0x10000301 ALGO_BF_RET_INIT_ERROR BF初始化错误
0x10000302 ALGO_BF_RET_INVALID_CONFIG BF Config无效
0x10000303 ALGO_BF_RET_INVALID_HANDLE BF Handle无效
0x10000304 ALGO_BF_RET_INVALID_NOISE_ESTIMATION BF噪音估计模式设置无效
0x10000305 ALGO_BF_RET_INVALID_VAD_ENABLE BF VAD模式设置无效
0x10000306 ALGO_BF_RET_INVALID_OUTPUT_GAIN BF 输出增益设置无效
0x10000307 ALGO_BF_RET_INVALID_INPUT_POINTER BF输入指标无效
0x10000308 ALGO_BF_RET_INVALID_SAMPLERATE BF采样率无效
0x10000309 ALGO_BF_RET_INVALID_POINTNUMBER BF采样点数无效
0x10000310 ALGO_BF_RET_INVALID_CHANNEL BF通道数无效
0x10000311 ALGO_BF_RET_INVALID_CALLING BF呼叫API顺序错误
0x10000312 ALGO_BF_RET_API_CONFLICT 有其他API正在运行
0x10000313 ALGO_BF_RET_INVALID_GEOMETRY_TYPE BF指派阵列形状错误
0x10000314 ALGO_BF_RET_INVALID_MIC_DISTANCE BF指派麦克风间距错误
0x10000315 ALGO_BF_RET_INVALLD_DYNAMIC_BAND BF指派动态带宽及对角加载强度错误
0x10000316 ALGO_BF_RET_INVALID_SETMODE BF指派模式错误
0x10000317 ALGO_BF_RET_INVALID_GETPOSITION BF获取阵列位置错误
0x10000318 ALGO_BF_RET_INVALID_SETINTENSITY BF 指派迭代式波束形成强度错误
0x10000319 ALGO_BF_RET_INVALID_SETCALLBACK 警告:BF授权失败
0x10000320 ALGO_BF_RET_INVALID_SETPFFLOW BF设定后滤波器位置失败
0x10000321 ALGO_BF_RET_INVALID_CALIBRATION BF校正音量失败

7. 流程图

图四 Beamforming 流程图

8. 与APC之串接关系

图五 Beamforming-APC 流程图(有呼叫 IaaApc_EnhanceNNBFMode)

图六 Beamforming-APC 流程图(未呼叫 IaaApc_EnhanceNNBFMode)