lib_xcore_math 入门指南
概述
lib_xcore_math是一个专门用于嵌入式应用中各类数学运算的高效实现库,特别适用于处理向量或数组的操作,如向量化运算、线性滤波以及快速傅里叶变换等。
lib_xcore_math库由多个子API构成,这种操作的分组方式便于从概念上进行理解和索引。通常情况下,来自同一API的函数会共享一个前缀,用以指示该函数来源于哪个API,或其作用的对象类型。此外,这些API之间还存在一定的相互依赖性。
以下是lib_xcore_math提供的子API:
- 块浮点数(BFP)API1:一个高级API,提供对BFP向量的操作。这些函数负责管理输入和输出BFP向量的指数及其头部空间,从而避免出现溢出或下溢的情况。
- 向量(Vector)/数组 API:被BFP API大量使用的底层API。这个API中可用的操作与BFP API中的类似,但用户必须自己管理指数和头部空间。多数例程都是直接利用经过优化的汇编语言实现的,以便尽可能有效地利用硬件(VPU&Dual Issue)。
- 标量(Scalar) API:提供对标量对象的各种操作。尤其是,这些操作专注于非IEEE 754浮点对象的简单算术操作,以及应用于IEEE 7542浮点数的优化操作。
- 滤波器(Filter) API:提供线性滤波操作的访问,包括16位和32位FIR滤波器3以及32位的双二阶(biquad)滤波器4。
- 快速傅里叶变换(FFT)API5:提供底层(low-level)和块浮点数的FFT实现。为实数信号、实数信号对以及复数信号,提供了经过优化的FFT实现。
- 离散余弦变换(DCT)API6:提供实现类型 II("正向")和类型 III("逆向")DCT的函数,支持多种块长度。此外,还提供一个快速的 8x8 二维正向和逆向 DCT。
所有这些API都可以通过包含单个头文件来访问:
#include "xmath/xmath.h"
构建
此库使用CMake构建系统。在GitHub页面上可以获取源码,并了解如何将库包含到你的应用程序中。
同样,lib_xcore_math兼容XMake构建系统,可以快速地应用在多通道音频工程当中。
如果你无法正常访问github,你也可以在我们提供的lib_xcore_math镜像仓库中获取。
使用
以下部分旨在让读者对如何使用API有一个大致的了解。
BFP API
在BFP API中,BFP向量被表示为C的结构体,例如bfp_s16_t,bfp_s32_t或bfp_complex_s32_t。这些结构包含一个指向向量尾数(Mantissa)的指针,以及关于BFP向量长度、头部空间和指数的信息。
下面是来自xmath/types.h的bfp_s32_t结构的定义:
typedef struct {
int32_t* data; // 指向底层元素缓冲区的指针。
exponent_t exp; // 与向量相关联的指数。
headroom_t hr; // `data[]`中当前的头部空间。
unsigned length; // `data[]`的当前大小,以元素数量表示。
bfp_flags_e flags; // BFP向量标志。用户通常不应手动修改这些内容。
} bfp_s32_t;
在BFP API中的函数一般都有前缀bfp_。其中主要操作数为32位BFP向量的函数有前缀bfp_s32_,主要操作数为复16位BFP向量的函数有前缀bfp_complex_s16_,对其他BFP向量类型也是如此。
初始化BFP向量
在调用BFP API函数之前,必须先初始化由参数表示的BFP向量。对于bfp_s32_t,可以通过bfp_s32_init()来完成初始化。初始化需要提供足够大的缓冲区以存储尾数向量,还需要一个初始指数。如果BFP向量首次使用是作为输出,则指数无关紧要,但对象仍必须在使用前完成初始化。此外,向量的头部空间可以在初始化时计算,或者设置为0。
以下是初始化32位BFP向量的一个例子:
#define LEN (20)
// 表示BFP向量的对象
bfp_s32_t bfp_vect;
// 用于支持bfp_vect的缓冲区
int32_t data_buffer[LEN];
for (int i = 0; i < LEN; i++) data_buffer[i] = i;
// 与bfp_vect相关联的初始指数
exponent_t initial_exponent = 0;
// 如果非零,`bfp_s32_init()`将计算当前在data_buffer中存在的头部空间。
// 否则,头部空间初始化为0(这总是安全的,但可能不是最优的)
unsigned calculate_headroom = 1;
// 初始化向量对象
bfp_s32_init(&bfp_vec, data_buffer, initial_exponent, LEN, calculate_headroom);
// 使用bfp_vect做一些事情
...