MI BF API


REVISION HISTORY

Revision No.
Description
Date
1.0
  • Initial release
  • 09/12/2020
    1.1
  • Modified API
  • 10/15/2020
    1.2
  • 4 MIC Beamforming and modified API
  • 08/03/2021
    1.3
  • Add function IaaBf_SetArbitraryShape, IaaBf_GetArrayPosition, IaaBf_DynamicLoading, IaaBf_SetMode, IaaBf_SetAdaptiveIntensity, IaaBf_SetCallbackFunction
  • 12/05/2022
    1.4
  • Add function IaaBf_GetAPIVersion
  • 04/10/2023
    1.5
  • Add function IaaBf_SetPfFlow, IaaBf_SetCalibration, AIBF
  • 10/27/2023

    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)