CMSIS-DSP实数FFT相关API(单精度浮点float)

news2024/12/23 4:09:47

目录

1. CMSIS-DSP的实数FFT

2. 频域上求模值

3. 如何求解相位

4. 对比python的求解过程

5. 在频域上以模和相角的方式还原信号

6. 求能量值


平台:STM32F407-Discovery+CMSIS-DSP-V1.6.0

1. CMSIS-DSP的实数FFT

文件:\CMSIS\DSP\Source\TransformFunctions\arm_rfft_fast_f32.c

函数原型

void arm_rfft_fast_f32(

arm_rfft_fast_instance_f32 * S,

float32_t * p, float32_t * pOut,

uint8_t ifftFlag)

函数功能

实数FFT的实现(浮点数)

参数

S:指针,指向实例arm_rfft_fast_instance_f32 structure.

p: 输入buffer(实序列).

pOut: 输出buffer.

IfftFlag:RFFT-0,RIFFT-1

返回值

Void

定义处(源文件)

声明处(头文件)

一般来说,实序列FFT转换到频域上后,就是复数序列,且具有对称性质,其中实部偶对称,虚部奇对称。比如64个点的时序列FFT后,得到的复数序列如下:注意直流分量和正频率分量所在的位置,这两个特殊的分量虚数部分都是0,下面的结果是用numpy的fft模块运行得到:

[
2016.  	+0.j          //直流分量
-32.	+651.374964j    
-32.	+324.9014524j
-32.	+215.72647697j  
-32.	+160.87486375j  
-32.	+127.75116108j
-32.	+105.48986269j  
-32. 	+89.43400872j  
-32. 	+77.254834j
-32. 	+67.65831544j  
-32. 	+59.86778918j  
-32. 	+53.38877458j
-32. 	+47.89138441j  
-32. 	+43.14700523j  
-32. 	+38.99211282j
-32. 	+35.30655922j  
-32. 	+32.j          
-32. 	+29.00310941j
-32. 	+26.26172131j  
-32. 	+23.73281748j  
-32. 	+21.38171641j
-32. 	+19.18006188j  
-32. 	+17.10435635j  
-32. 	+15.13487283j
-32. 	+13.254834j    
-32. 	+11.44978308j  
-32.  	+9.70709388j
-32.  	+8.01558273j  
-32.  	+6.36519576j  
-32.  	+4.7467516j
-32.  	+3.15172491j  
-32.  	+1.57205919j  //实部相同,虚部互反
-32.  	+0.j           //正频率分量(奈奎斯特频率分量)
-32.  	-1.57205919j   //实部相同,虚部互反
-32.  	-3.15172491j  
-32.  	-4.7467516j
-32.  	-6.36519576j  
-32.  	-8.01558273j  
-32.  	-9.70709388j
-32. 	-11.44978308j  
-32. 	-13.254834j    
-32. 	-15.13487283j
-32. 	-17.10435635j  
-32. 	-19.18006188j  
-32. 	-21.38171641j
-32. 	-23.73281748j  
-32. 	-26.26172131j  
-32. 	-29.00310941j
-32. 	-32.j          
-32. 	-35.30655922j  
-32. 	-38.99211282j
-32. 	-43.14700523j  
-32. 	-47.89138441j  
-32. 	-53.38877458j
-32. 	-59.86778918j  
-32. 	-67.65831544j  
-32. 	-77.254834j
-32. 	-89.43400872j  
-32.	-105.48986269j  
-32.	-127.75116108j
-32.	-160.87486375j  
-32.	-215.72647697j  
-32.	-324.9014524j
-32.	-651.374964j  
]

arm_rfft_fast_f32(,, out_buff, )的输出也具有类似的特点,同样是64个点的FFT,一样的输入,测试代码如下:

#define RFFT_LEN 64

static float32_t Input_f32[RFFT_LEN];
static float32_t Input_f32_bak[RFFT_LEN];
static float32_t Output_f32[RFFT_LEN];

void rfft_f32_test(void)
{
	uint16_t i;
	arm_rfft_fast_instance_f32 S;

	/* 初始化结构体S中的参数 */
	arm_rfft_fast_init_f32(&S, RFFT_LEN);

	for(i=0; i<RFFT_LEN; i++)
	{
		Input_f32[i] = i;
		Input_f32_bak[i] = Input_f32[i];
	}

	arm_rfft_fast_f32(&S, Input_f32, Output_f32, 0);

	for(i=0; i<RFFT_LEN; i++)
	{
		printf("[%d], %f\r\n", i, Output_f32[i]);
	}

}

输出:out_buff

[0], 2016.000000 //第一个点的实部和虚部
[1], -32.000000

[2], -32.000015 //第二个点的实部和虚部
[3], 651.374939

[4], -31.999990
[5], 324.901428

[6], -32.000008
[7], 215.726471
[8], -31.999998
[9], 160.874878
[10], -32.000000
[11], 127.751160
[12], -32.000004
[13], 105.489853
[14], -32.000015
[15], 89.433998
[16], -32.000000
[17], 77.254837
[18], -31.999998
[19], 67.658318
[20], -32.000004
[21], 59.867783
[22], -32.000000
[23], 53.388767
[24], -32.000000
[25], 47.891380
[26], -32.000004
[27], 43.147003
[28], -32.000008
[29], 38.992107
[30], -32.000008
[31], 35.306553
[32], -32.000000
[33], 32.000000
[34], -32.000008
[35], 29.003107
[36], -31.999992
[37], 26.261724
[38], -31.999996
[39], 23.732821
[40], -32.000000
[41], 21.381718
[42], -32.000000
[43], 19.180065
[44], -32.000008
[45], 17.104353
[46], -32.000000
[47], 15.134871
[48], -32.000000
[49], 13.254833
[50], -31.999996
[51], 11.449793
[52], -31.999994
[53], 9.707090
[54], -31.999989
[55], 8.015587
[56], -32.000004
[57], 6.365196
[58], -32.000008
[59], 4.746758
[60], -32.000011
[61], 3.151733
[62], -31.999983
[63], 1.572052  //最后是下标为31的点的信息,相当于只输出前31个复数点的信息
//64个实数点对应应该是64个复数点信息,但是有一半数据是对称的。

2. 频域上求模值

上面讲了对arm_rfft_fast_f32()的输出是顺序输出,得到实际的每个点的复数值,每个点有实部和虚部后就可以进行求模以及求解相位等计算。但是,如果逐个点进行计算的话,在计算量和存储上都会有浪费,CMSIS-DSP库里就有现成的API可用,这些API都极大地进行了优化。

文件:CMSIS\DSP\Source\ComplexMathFunctions\arm_cmplx_mag_f32.c

函数原型

void arm_cmplx_mag_f32(

  float32_t * pSrc,

  float32_t * pDst,

  uint32_t numSamples)

函数功能

求解复数序列的模值

参数

pSrc:输入的复数序列,注意排序!(实部+虚部)

pDst: 输出的buffer(实序列).

numSamples: 输入的复数序列的长度

返回值

Void

定义处(源文件)

声明处(头文件)

测试:

#define RFFT_LEN 64

static float32_t Input_f32[RFFT_LEN];
static float32_t Input_f32_bak[RFFT_LEN];
static float32_t Output_f32[RFFT_LEN];
static float32_t mag_f32[RFFT_LEN];

void rfft_f32_test(void)
{
	uint16_t i;
	arm_rfft_fast_instance_f32 S;

	/* 初始化结构体S中的参数 */
	arm_rfft_fast_init_f32(&S, RFFT_LEN);

	for(i=0; i<RFFT_LEN; i++)
	{
		Input_f32[i] = i;
		Input_f32_bak[i] = Input_f32[i];
	}

	arm_rfft_fast_f32(&S, Input_f32, Output_f32, 0);
	for(i=0; i<RFFT_LEN; i++)
	{
		printf("[%d], %f\r\n", i, Output_f32[i]);
	}

	printf("=====================================\r\n");
	arm_cmplx_mag_f32(Output_f32, mag_f32, RFFT_LEN);
	for(i=0; i<RFFT_LEN; i++)
	{
		printf("[%d], %f\r\n", i, mag_f32[i]);
	}
}

结果:

[17:15:17.081] 0, 2016.253906  //直流分量
[17:15:17.097] 1, 652.160522
[17:15:17.113] 2, 326.473480
[17:15:17.129] 3, 218.086929
[17:15:17.145] 4, 164.026596
[17:15:17.161] 5, 131.697983
[17:15:17.177] 6, 110.236603
[17:15:17.193] 7, 94.986534
[17:15:17.209] 8, 83.620033
[17:15:17.225] 9, 74.844154
[17:15:17.241] 10, 67.883369
[17:15:17.257] 11, 62.244362
[17:15:17.272] 12, 57.598473
[17:15:17.288] 13, 53.718376
[17:15:17.305] 14, 50.441895
[17:15:17.321] 15, 47.650322
[17:15:17.337] 16, 45.254833
[17:15:17.353] 17, 43.187737
[17:15:17.369] 18, 41.396591
[17:15:17.385] 19, 39.840263
[17:15:17.400] 20, 38.486073
[17:15:17.417] 21, 37.307838
[17:15:17.432] 22, 36.284424
[17:15:17.448] 23, 35.398647
[17:15:17.464] 24, 34.636551
[17:15:17.480] 25, 33.986725
[17:15:17.496] 26, 33.439907
[17:15:17.512] 27, 32.988617
[17:15:17.528] 28, 32.626923
[17:15:17.545] 29, 32.350151
[17:15:17.561] 30, 32.154846
[17:15:17.577] 31, 32.038574
[17:15:17.577] 32, 0.000000  //这里的值,对应的是N/2处的值
[17:15:17.593] 33, 0.000000  //后面的值,偶对称
[17:15:17.609] 34, 0.000000
[17:15:17.625] 35, 0.000000
[17:15:17.640] 36, 0.000000
[17:15:17.656] 37, 0.000000
[17:15:17.672] 38, 0.000000
[17:15:17.688] 39, 0.000000
[17:15:17.704] 40, 0.000000
[17:15:17.720] 41, 0.000000
[17:15:17.736] 42, 0.000000
[17:15:17.752] 43, 0.000000
[17:15:17.752] 44, 0.000000
[17:15:17.768] 45, 0.000000
[17:15:17.784] 46, 0.000000
[17:15:17.800] 47, 0.000000
[17:15:17.816] 48, 0.000000
[17:15:17.832] 49, 0.000000
[17:15:17.848] 50, 0.000000
[17:15:17.865] 51, 0.000000
[17:15:17.881] 52, 0.000000
[17:15:17.897] 53, 0.000000
[17:15:17.912] 54, 0.000000
[17:15:17.912] 55, 0.000000
[17:15:17.928] 56, 0.000000
[17:15:17.944] 57, 0.000000
[17:15:17.960] 58, 0.000000
[17:15:17.976] 59, 0.000000
[17:15:17.992] 60, 0.000000
[17:15:18.008] 61, 0.000000
[17:15:18.024] 62, 0.000000
[17:15:18.040] 63, 0.000000

从上面两个实验来看,FFT结果以及求模,都只会输出前一半的数据,且都是顺序交替输出。

3. 如何求解相位

相位的求解没有可用的API,只能根据定义去求解,求解出来的是弧度制:

phase=arctan(虚部/实部)

自己编写算法求解即可,完整测试代码:

#define RFFT_LEN 64

static float32_t Input_f32[RFFT_LEN];
static float32_t Input_f32_bak[RFFT_LEN];
static float32_t Output_f32[RFFT_LEN];
static float32_t mag_f32[RFFT_LEN];
static float32_t phase_f32[RFFT_LEN];

void cal_phase_f32(float32_t *in_buf, float32_t *phase, uint16_t _usFFTPoints)
{
	float32_t real, img;
	uint16_t i;

	for (i=0; i <_usFFTPoints; i++)
	{
		real= in_buf[2*i];  	 /* 实部 */
		img= in_buf[2*i + 1];    /* 虚部 */
		/* atan2求解的结果范围是(-pi, pi], 弧度制 */
 		phase[i] = atan2(img, real);
	}
}

void rfft_f32_test(void)
{
	uint16_t i;
	arm_rfft_fast_instance_f32 S;

	/* 初始化结构体S中的参数 */
	arm_rfft_fast_init_f32(&S, RFFT_LEN);

	for(i=0; i<RFFT_LEN; i++)
	{
		Input_f32[i] = i;
		Input_f32_bak[i] = Input_f32[i];
	}

	arm_rfft_fast_f32(&S, Input_f32, Output_f32, 0);
	for(i=0; i<RFFT_LEN; i++)
	{
		printf("[%d], %f\r\n", i, Output_f32[i]);
	}

	arm_cmplx_mag_f32(Output_f32, mag_f32, RFFT_LEN);
	printf("=====================================\r\n");
	for(i=0; i<RFFT_LEN; i++)
	{
		printf("[%d], %f\r\n", i, mag_f32[i]);
	}

	cal_phase_f32(Output_f32, phase_f32, RFFT_LEN);
	printf("=====================================\r\n");
	for(i=0; i<RFFT_LEN; i++)
	{
		printf("[%d], %f\r\n", i, phase_f32[i]);
	}
}

输出的相位信息:

[17:15:18.104] 0, 0.000000  //直流分量
[17:15:18.104] 1, 1.619884
[17:15:18.120] 2, 1.668971
[17:15:18.136] 3, 1.718058
[17:15:18.152] 4, 1.767146
[17:15:18.167] 5, 1.816233
[17:15:18.183] 6, 1.865321
[17:15:18.183] 7, 1.914408
[17:15:18.200] 8, 1.963495
[17:15:18.216] 9, 2.012583
[17:15:18.232] 10, 2.061670
[17:15:18.248] 11, 2.110758
[17:15:18.264] 12, 2.159845
[17:15:18.280] 13, 2.208932
[17:15:18.295] 14, 2.258020
[17:15:18.311] 15, 2.307107
[17:15:18.311] 16, 2.356194
[17:15:18.328] 17, 2.405282
[17:15:18.344] 18, 2.454369
[17:15:18.360] 19, 2.503457
[17:15:18.376] 20, 2.552544
[17:15:18.392] 21, 2.601631
[17:15:18.408] 22, 2.650719
[17:15:18.424] 23, 2.699806
[17:15:18.440] 24, 2.748893
[17:15:18.456] 25, 2.797981
[17:15:18.471] 26, 2.847068
[17:15:18.487] 27, 2.896156
[17:15:18.487] 28, 2.945243
[17:15:18.503] 29, 2.994330
[17:15:18.519] 30, 3.043418
[17:15:18.535] 31, 3.092505
[17:15:18.551] 32, 0.000000 //N/2
[17:15:18.567] 33, 0.000000
[17:15:18.583] 34, 0.000000
[17:15:18.600] 35, 0.000000
[17:15:18.616] 36, 0.000000
[17:15:18.632] 37, 0.000000
[17:15:18.647] 38, 0.000000
[17:15:18.647] 39, 0.000000
[17:15:18.663] 40, 0.000000
[17:15:18.679] 41, 0.000000
[17:15:18.695] 42, 0.000000
[17:15:18.711] 43, 0.000000
[17:15:18.727] 44, 0.000000
[17:15:18.743] 45, 0.000000
[17:15:18.759] 46, 0.000000
[17:15:18.775] 47, 0.000000
[17:15:18.792] 48, 0.000000
[17:15:18.808] 49, 0.000000
[17:15:18.808] 50, 0.000000
[17:15:18.824] 51, 0.000000
[17:15:18.840] 52, 0.000000
[17:15:18.855] 53, 0.000000
[17:15:18.871] 54, 0.000000
[17:15:18.887] 55, 0.000000
[17:15:18.903] 56, 0.000000
[17:15:18.919] 57, 0.000000
[17:15:18.935] 58, 0.000000
[17:15:18.951] 59, 0.000000
[17:15:18.968] 60, 0.000000
[17:15:18.983] 61, 0.000000
[17:15:18.983] 62, 0.000000
[17:15:18.999] 63, 0.000000

4. 对比python的求解过程

测试代码:

import numpy as np
signal=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63]
fftresult=np.fft.fft(signal)
print(fftresult)
magnitude=np.abs(fftresult)
print(magnitude)
phase=np.angle(fftresult)
print(phase)

FFT结果:

2016.  	+0.j          
-32.	+651.374964j    //20.355467625
-32.	+324.9014524j
-32.	+215.72647697j  
-32.	+160.87486375j  
-32.	+127.75116108j
-32.	+105.48986269j  
-32. 	+89.43400872j  
-32. 	+77.254834j
-32. 	+67.65831544j  
-32. 	+59.86778918j  
-32. 	+53.38877458j
-32. 	+47.89138441j  
-32. 	+43.14700523j  
-32. 	+38.99211282j
-32. 	+35.30655922j  
-32. 	+32.j          
-32. 	+29.00310941j
-32. 	+26.26172131j  
-32. 	+23.73281748j  
-32. 	+21.38171641j
-32. 	+19.18006188j  
-32. 	+17.10435635j  
-32. 	+15.13487283j
-32. 	+13.254834j    
-32. 	+11.44978308j  
-32.  	+9.70709388j
-32.  	+8.01558273j  
-32.  	+6.36519576j  
-32.  	+4.7467516j
-32.  	+3.15172491j  
-32.  	+1.57205919j  
-32.  	+0.j
-32.  	-1.57205919j  
-32.  	-3.15172491j  
-32.  	-4.7467516j
-32.  	-6.36519576j  
-32.  	-8.01558273j  
-32.  	-9.70709388j
-32. 	-11.44978308j  
-32. 	-13.254834j    
-32. 	-15.13487283j
-32. 	-17.10435635j  
-32. 	-19.18006188j  
-32. 	-21.38171641j
-32. 	-23.73281748j  
-32. 	-26.26172131j  
-32. 	-29.00310941j
-32. 	-32.j          
-32. 	-35.30655922j  
-32. 	-38.99211282j
-32. 	-43.14700523j  
-32. 	-47.89138441j  
-32. 	-53.38877458j
-32. 	-59.86778918j  
-32. 	-67.65831544j  
-32. 	-77.254834j
-32. 	-89.43400872j  
-32.	-105.48986269j  
-32.	-127.75116108j
-32.	-160.87486375j  
-32.	-215.72647697j  
-32.	-324.9014524j
-32.	-651.374964j 

模值:

2016.          
652.16051991  
326.4735116   
218.08693878  
164.02658866
131.69798464  
110.23661429   
94.98653544   
83.62002975   
74.84415574
67.8833719    
62.24436722   
57.59847828   
53.71837731   
50.4418959
47.65032134   
45.254834     
43.18773385   
41.39659414   
39.84026387
38.48607276   
37.30783797   
36.28441823   
35.39864935   
34.63655041
33.98672583   
33.43991136   
32.98862784   
32.62691706   
32.35014143
32.15483432   
32.03859189   
32.           
32.03859189   
32.15483432
32.35014143  
32.62691706   
32.98862784   
33.43991136   
33.98672583
34.63655041   
35.39864935   
36.28441823   
37.30783797   
38.48607276
39.84026387   
41.39659414   
43.18773385   
45.254834     
47.65032134
50.4418959    
53.71837731   
57.59847828   
62.24436722   
67.8833719
74.84415574   
83.62002975   
94.98653544  
110.23661429  
131.69798464
164.02658866  
218.08693878  
326.4735116   
652.16051991

相位:

0.          
1.61988371  
1.6689711   
1.71805848  
1.76714587  
1.81623325
1.86532064  
1.91440802  
1.96349541  
2.01258279  
2.06167018  
2.11075756
2.15984495  
2.20893233  
2.25801972  
2.3071071   
2.35619449  
2.40528188
2.45436926  
2.50345665  
2.55254403  
2.60163142  
2.6507188   
2.69980619
2.74889357  
2.79798096  
2.84706834  
2.89615573  
2.94524311  
2.9943305
3.04341788  
3.09250527
3.14159265 //python 的优化吗?这是
-3.09250527 
-3.04341788 
-2.9943305
-2.94524311 
-2.89615573 
-2.84706834 
-2.79798096 
-2.74889357 
-2.69980619
-2.6507188  
-2.60163142 
-2.55254403 
-2.50345665 
-2.45436926 
-2.40528188
-2.35619449 
-2.3071071  
-2.25801972 
-2.20893233 
-2.15984495 
-2.11075756
-2.06167018 
-2.01258279 
-1.96349541 
-1.91440802 
-1.86532064 
-1.81623325
-1.76714587 
-1.71805848 
-1.6689711  
-1.61988371

注:对比可以发现CMSIS针对嵌入式平台刻意做了计算量、存储等方面的优化。

5. 在频域上以模和相角的方式还原信号

对于逆变换,也只是需要一半的数据参与即可,将FFT的输出作为IFFT的输入,如下:

void rfft_f32_test(void)
{
	uint16_t i;
	arm_rfft_fast_instance_f32 S;

	/* 初始化结构体S中的参数 */
	arm_rfft_fast_init_f32(&S, RFFT_LEN);

	for(i=0; i<RFFT_LEN; i++)
	{
		Input_f32[i] = i;
		Input_f32_bak[i] = Input_f32[i];
	}

	arm_rfft_fast_f32(&S, Input_f32, Output_f32, 0);
	arm_rfft_fast_f32(&S, Output_f32, ifftOutput_f32, 1);
	printf("=====================================\r\n");
	for(i=0; i<RFFT_LEN; i++)
	{
		printf("[%d], %f  %f\r\n", i, Input_f32_bak[i], ifftOutput_f32[i]);
	}
}

频域上往往需要进行各种处理后,再进行逆变换,频域上以模和相位的方式重组复数点的实部虚部,再做逆变换。

理论推导:语音信号处理之预处理简述(二)_语音的帧数和帧长,帧移的关系式-CSDN博客

代码如下:

#define RFFT_LEN 64

static float32_t Input_f32[RFFT_LEN];
static float32_t Input_f32_bak[RFFT_LEN];
static float32_t Output_f32[RFFT_LEN];
static float32_t mag_f32[RFFT_LEN];
static float32_t phase_f32[RFFT_LEN];

static float32_t ifftInput_f32[RFFT_LEN];
static float32_t ifftOutput_f32[RFFT_LEN];

void cal_phase_f32(float32_t *in_buf, float32_t *phase, uint16_t _usFFTPoints)
{
	float32_t real, img;
	uint16_t i;

	for (i=0; i <_usFFTPoints; i++)
	{
		real= in_buf[2*i];  	 /* 实部 */
		img= in_buf[2*i + 1];    /* 虚部 */
		/* atan2求解的结果范围是(-pi, pi], 弧度制 */
 		phase[i] = atan2(img, real);
	}
}

void rfft_f32_test(void)
{
	uint16_t i;
	arm_rfft_fast_instance_f32 S;

	/* 初始化结构体S中的参数 */
	arm_rfft_fast_init_f32(&S, RFFT_LEN);

	for(i=0; i<RFFT_LEN; i++)
	{
		Input_f32[i] = i;
		Input_f32_bak[i] = Input_f32[i];
	}

	arm_rfft_fast_f32(&S, Input_f32, Output_f32, 0);
//	for(i=0; i<RFFT_LEN; i++)
//	{
//		printf("[%d], %f\r\n", i, Output_f32[i]);
//	}

	arm_cmplx_mag_f32(Output_f32, mag_f32, RFFT_LEN);
//	printf("=====================================\r\n");
//	for(i=0; i<RFFT_LEN; i++)
//	{
//		printf("[%d], %f\r\n", i, mag_f32[i]);
//	}

	cal_phase_f32(Output_f32, phase_f32, RFFT_LEN);
//	printf("=====================================\r\n");
//	for(i=0; i<RFFT_LEN; i++)
//	{
//		printf("[%d], %f\r\n", i, phase_f32[i]);
//	}


	for(i=0; i <RFFT_LEN/2; i++)
	{
		/* 实部 */
		ifftInput_f32[2*i]= mag_f32[i]*arm_cos_f32(phase_f32[i]);
		/* 虚部 */
		ifftInput_f32[2*i+1]= mag_f32[i]*arm_sin_f32(phase_f32[i]);
	}

	arm_rfft_fast_f32(&S, ifftInput_f32, ifftOutput_f32, 1);
	printf("=====================================\r\n");
	for(i=0; i<RFFT_LEN; i++)
	{
		printf("[%d], %f  %f\r\n", i, Input_f32_bak[i], ifftOutput_f32[i]);
	}
}

打印输出:

[0], 0.000000  -0.000479
[1], 1.000000  0.999496
[2], 2.000000  1.999522
[3], 3.000000  2.999496
[4], 4.000000  3.999519
[5], 5.000000  4.999496
[6], 6.000000  5.999519
[7], 7.000000  6.999498
[8], 8.000000  7.999521
[9], 9.000000  8.999496
[10], 10.000000  9.999523
[11], 11.000000  10.999493
[12], 12.000000  11.999523
[13], 13.000000  12.999498
[14], 14.000000  13.999523
[15], 15.000000  14.999496
[16], 16.000000  15.999520
[17], 17.000000  16.999496
[18], 18.000000  17.999519
[19], 19.000000  18.999496
[20], 20.000000  19.999523
[21], 21.000000  20.999496
[22], 22.000000  21.999519
[23], 23.000000  22.999496
[24], 24.000000  23.999521
[25], 25.000000  24.999496
[26], 26.000000  25.999519
[27], 27.000000  26.999500
[28], 28.000000  27.999519
[29], 29.000000  28.999496
[30], 30.000000  29.999519
[31], 31.000000  30.999496
[32], 32.000000  31.999519
[33], 33.000000  32.999496
[34], 34.000000  33.999516
[35], 35.000000  34.999496
[36], 36.000000  35.999519
[37], 37.000000  36.999496
[38], 38.000000  37.999519
[39], 39.000000  38.999496
[40], 40.000000  39.999519
[41], 41.000000  40.999496
[42], 42.000000  41.999519
[43], 43.000000  42.999500
[44], 44.000000  43.999519
[45], 45.000000  44.999496
[46], 46.000000  45.999519
[47], 47.000000  46.999496
[48], 48.000000  47.999519
[49], 49.000000  48.999496
[50], 50.000000  49.999519
[51], 51.000000  50.999496
[52], 52.000000  51.999516
[53], 53.000000  52.999496
[54], 54.000000  53.999519
[55], 55.000000  54.999496
[56], 56.000000  55.999519
[57], 57.000000  56.999496
[58], 58.000000  57.999516
[59], 59.000000  58.999493
[60], 60.000000  59.999516
[61], 61.000000  60.999496
[62], 62.000000  61.999516
[63], 63.000000  62.999496

注:short类型的音频数据和float互转,在某些场合下是不是要向上取整,以保证精度?

6. 求能量值

实际上就是求模值的平方。

文件:CMSIS\DSP\Source\ComplexMathFunctions\ arm_cmplx_mag_squared_f32.c

函数原型

void arm_cmplx_mag_squared_f32(

const float32_t * pSrc,

float32_t * pDst,

uint32_t numSamples)

函数功能

求解复数序列的模值

参数

pSrc:输入的复数序列,注意排序!(实部+虚部)

pDst: 输出的buffer(实序列).

numSamples: 输入的复数序列的长度

返回值

Void

定义处(源文件)

声明处(头文件)

示例代码:

void rfft_f32_test(void)
{
	uint16_t i;
	arm_rfft_fast_instance_f32 S;

	/* 初始化结构体S中的参数 */
	arm_rfft_fast_init_f32(&S, RFFT_LEN);

	for(i=0; i<RFFT_LEN; i++)
	{
		Input_f32[i] = i;
		Input_f32_bak[i] = Input_f32[i];
	}

	arm_rfft_fast_f32(&S, Input_f32, Output_f32, 0);
//	for(i=0; i<RFFT_LEN; i++)
//	{
//		printf("[%d], %f\r\n", i, Output_f32[i]);
//	}

	arm_cmplx_mag_f32(Output_f32, mag_f32, RFFT_LEN);
	printf("=====================================\r\n");
	for(i=0; i<RFFT_LEN; i++)
	{
		printf("[%d], %f\r\n", i, mag_f32[i]);
	}

	arm_cmplx_mag_squared_f32(Output_f32, mag_squared_f32, RFFT_LEN);
	printf("=====================================\r\n");
	for(i=0; i<RFFT_LEN; i++)
	{
		printf("[%d], %f\r\n", i, mag_squared_f32[i]);
	}
}

串口输出:

[16:15:51.866] =====================================
[16:15:51.914] [0], 2016.253906
[16:15:51.930] [1], 652.160522
[16:15:51.946] [2], 326.473480
[16:15:51.962] [3], 218.086929
[16:15:51.978] [4], 164.026596
[16:15:51.994] [5], 131.697983
[16:15:52.026] [6], 110.236603
[16:15:52.042] [7], 94.986534
[16:15:52.058] [8], 83.620033
[16:15:52.074] [9], 74.844154
[16:15:52.090] [10], 67.883369
[16:15:52.106] [11], 62.244362
[16:15:52.122] [12], 57.598473
[16:15:52.138] [13], 53.718376
[16:15:52.154] [14], 50.441895
[16:15:52.170] [15], 47.650322
[16:15:52.186] [16], 45.254833
[16:15:52.218] [17], 43.187737
[16:15:52.234] [18], 41.396591
[16:15:52.250] [19], 39.840263
[16:15:52.266] [20], 38.486073
[16:15:52.282] [21], 37.307838
[16:15:52.298] [22], 36.284424
[16:15:52.314] [23], 35.398647
[16:15:52.330] [24], 34.636551
[16:15:52.346] [25], 33.986725
[16:15:52.378] [26], 33.439907
[16:15:52.394] [27], 32.988617
[16:15:52.410] [28], 32.626923
[16:15:52.426] [29], 32.350151
[16:15:52.442] [30], 32.154846
[16:15:52.458] [31], 32.038574
[16:15:52.474] [32], 2.004150
[16:15:52.490] [33], 0.000000
[16:15:52.506] [34], 0.000000
[16:15:52.522] [35], 0.000000
[16:15:52.538] [36], 0.000000
[16:15:52.554] [37], 0.000000
[16:15:52.570] [38], 0.000000
[16:15:52.586] [39], 0.000000
[16:15:52.618] [40], 0.000000
[16:15:52.634] [41], 0.000000
[16:15:52.650] [42], 0.000000
[16:15:52.666] [43], 0.000000
[16:15:52.682] [44], 0.000000
[16:15:52.698] [45], 0.000000
[16:15:52.714] [46], 0.000000
[16:15:52.730] [47], 0.000000
[16:15:52.745] [48], 0.000000
[16:15:52.761] [49], 0.000000
[16:15:52.778] [50], 0.000000
[16:15:52.793] [51], 0.000000
[16:15:52.809] [52], 0.000000
[16:15:52.825] [53], 0.000000
[16:15:52.841] [54], 0.000000
[16:15:52.857] [55], 0.000000
[16:15:52.873] [56], 0.000000
[16:15:52.889] [57], 0.000000
[16:15:52.905] [58], 0.000000
[16:15:52.921] [59], 0.000000
[16:15:52.937] [60], 0.000000
[16:15:52.953] [61], 0.000000
[16:15:52.969] [62], 0.000000
[16:15:53.001] [63], 0.000000
[16:15:53.017] =====================================
[16:15:53.049] [0], 4065280.000000
[16:15:53.065] [1], 425313.312500
[16:15:53.097] [2], 106584.937500
[16:15:53.113] [3], 47561.910156
[16:15:53.129] [4], 26904.726563
[16:15:53.161] [5], 17344.359375
[16:15:53.177] [6], 12152.109375
[16:15:53.193] [7], 9022.441406
[16:15:53.209] [8], 6992.310059
[16:15:53.225] [9], 5601.647949
[16:15:53.258] [10], 4608.151367
[16:15:53.274] [11], 3874.360352
[16:15:53.290] [12], 3317.584229
[16:15:53.306] [13], 2885.664063
[16:15:53.322] [14], 2544.384766
[16:15:53.354] [15], 2270.553223
[16:15:53.370] [16], 2048.000000
[16:15:53.386] [17], 1865.180664
[16:15:53.402] [18], 1713.677734
[16:15:53.434] [19], 1587.246582
[16:15:53.450] [20], 1481.177856
[16:15:53.466] [21], 1391.874878
[16:15:53.482] [22], 1316.559326
[16:15:53.514] [23], 1253.064331
[16:15:53.530] [24], 1199.690552
[16:15:53.546] [25], 1155.097534
[16:15:53.562] [26], 1118.227295
[16:15:53.594] [27], 1088.248901
[16:15:53.610] [28], 1064.515991
[16:15:53.625] [29], 1046.532227
[16:15:53.642] [30], 1033.934204
[16:15:53.673] [31], 1026.470215
[16:15:53.689] [32], 4.016619
[16:15:53.705] [33], 0.000000
[16:15:53.721] [34], 0.000000
[16:15:53.737] [35], 0.000000
[16:15:53.753] [36], 0.000000
[16:15:53.769] [37], 0.000000
[16:15:53.785] [38], 0.000000
[16:15:53.801] [39], 0.000000
[16:15:53.817] [40], 0.000000
[16:15:53.833] [41], 0.000000
[16:15:53.849] [42], 0.000000
[16:15:53.865] [43], 0.000000
[16:15:53.881] [44], 0.000000
[16:15:53.897] [45], 0.000000
[16:15:53.913] [46], 0.000000
[16:15:53.929] [47], 0.000000
[16:15:53.945] [48], 0.000000
[16:15:53.961] [49], 0.000000
[16:15:53.993] [50], 0.000000
[16:15:54.009] [51], 0.000000
[16:15:54.025] [52], 0.000000
[16:15:54.041] [53], 0.000000
[16:15:54.057] [54], 0.000000
[16:15:54.073] [55], 0.000000
[16:15:54.089] [56], 0.000000
[16:15:54.105] [57], 0.000000
[16:15:54.121] [58], 0.000000
[16:15:54.137] [59], 0.000000
[16:15:54.153] [60], 0.000000
[16:15:54.169] [61], 0.000000
[16:15:54.185] [62], 0.000000
[16:15:54.201] [63], 0.000000

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1249917.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

模板初阶(1):函数模板,类模板

一、函数模板 1.1 概念 函数模板代表了一个函数家族&#xff0c;该函数模板与类型无关&#xff0c;在使用时被参数化&#xff0c;根据实参类型产生函数的特定类型版本。 格式&#xff1a; template <typename T>或template <class T> template <class T>…

蓝桥杯第597题 跑步锻炼 C++ 日期模板题(模拟经典)

题目 跑步锻炼https://www.lanqiao.cn/problems/597/learning/?page1&first_category_id1&name%E8%B7%91%E6%AD%A5%E9%94%BB%E7%82%BC 题目描述 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即可。 小蓝每天都锻炼身…

CTFUB-web前置技能-HTTP协议

burp抓包,抓第二次的 修改请求方式为CTFHUB

操作系统的基本特性--并发、共享、虚拟、异步

批处理系统具有高资源利用率和系统吞吐量&#xff1b;分时系统能够获得及时响应&#xff1b;实时系统具有实时特征。而这三种系统都具有并发、共享、虚拟和异步四个基本特征 一、并发 OS通过并发提高系统中的资源利用率&#xff0c;增加系统的吞吐量 1.并行和并发 并行&…

利用Nginx与php处理方式不同绕过Nginx_host实现SQL注入

目录 首先需要搭建环境 nginxphpmysql环境&#xff1a; 搭建网站 FILTER_VALIDATE_EMAIL 绕过 方法1&#xff1a;冒号号分割host字段 方法2&#xff1a;冒号号分割host字段 方法3&#xff1a;SNI扩展绕过 首先需要搭建环境 nginxphpmysql环境&#xff1a; php安装包&a…

从0开始学习JavaScript--深入了解JavaScript框架

JavaScript框架在现代Web开发中扮演着关键角色&#xff0c;为开发者提供了丰富的工具和抽象层&#xff0c;使得构建复杂的、高性能的Web应用变得更加容易。本文将深入探讨JavaScript框架的核心概念、常见框架的特点以及它们在实际应用中的使用。 JavaScript框架的作用 JavaSc…

算法-中等-链表-两数相加

记录一下算法题的学习11 两数相加 题目&#xff1a;给你两个非空的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照逆序的方式存储的&#xff0c;并且每个节点只能存储一位数字。请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。你可以假设除了数字…

Re54:读论文 How Context Affects Language Models‘ Factual Predictions

诸神缄默不语-个人CSDN博文目录 诸神缄默不语的论文阅读笔记和分类 论文名称&#xff1a;How Context Affects Language Models’ Factual Predictions ArXiv网址&#xff1a;https://arxiv.org/abs/2005.04611 2020年AKBC论文&#xff0c;作者来自脸书和UCL。 本文主要关注…

【Amazon】安装卸载AWS CLI操作流程(Windows 、Linux系统)

AWS 命令行界面&#xff08;AWS CLI&#xff09;是用于管理 AWS 产品的统一工具。只需要下载和配置一个工具&#xff0c;您就可以使用命令行控制多个 AWS 产品并利用脚本来自动执行这些服务。 AWS CLI v2 提供了多项新功能&#xff0c;包括改进的安装程序、新的配置选项&#…

亚马逊云科技向量数据库助力生成式AI成功落地实践探秘(一) ​

随着大语言模型效果明显提升&#xff0c;其相关的应用不断涌现呈现出越来越火爆的趋势。其中一种比较被广泛关注的技术路线是大语言模型&#xff08;LLM&#xff09;知识召回&#xff08;Knowledge Retrieval&#xff09;的方式&#xff0c;在私域知识问答方面可以很好的弥补通…

[HCIE] IPSec-VPN (手工模式)

概念&#xff1a; A. IPSec&#xff1a;是对IP的安全性补充&#xff0c;工作在IP层&#xff0c;为IP网络通信提供安全服务。 B.安全联盟SA&#xff1a;是通信对等体之间对某些要素的协定。 C. IPSec安全联盟简称 IPSec SA.通常成对建立&#xff08;inbound和outbound&#x…

Spring Boot - 瘦身大作战:优雅应对Spring Boot Fat Jar

文章目录 Fat Jar瘦身pom修改copy lib启动 -Dloader.path验证 源码分析前置阅读spring-boot-loader 依赖类继承关系PropertiesLauncher属性配置 附 pom.xml Fat Jar 【pom.xml】 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"ht…

人机交互2——任务型多轮对话的控制和生成

1.自然语言理解模块 2.对话管理模块 3.自然语言生成模块

【数据结构 —— 堆的实现(顺序表)】

数据结构 —— 堆的实现&#xff08;顺序表&#xff09; 一.堆1.1堆的定义及结构1.1.1.堆的定义1.1.2.堆的性质1.1.3.堆的结构 二.堆的实现2.1.头文件的实现 —— &#xff08;Heap.h&#xff09;2.2.源文件的实现 —— &#xff08;Heap.c&#xff09;2.2.1.小堆的源文件2.2.2…

【汉诺塔 —— (经典分治递归)】

汉诺塔 —— &#xff08;经典分治递归&#xff09; 一.汉诺塔介绍二.分治算法解决汉诺塔问题三.汉诺塔问题的代码实现四.主函数测试展示 一.汉诺塔介绍 汉诺塔问题源自印度一个古老的传说&#xff0c;印度教的“创造之神”梵天创造世界时做了 3 根金刚石柱&#xff0c;其中的一…

量子计算 | 解密著名量子算法Shor算法和Grover算法

专栏集锦&#xff0c;大佬们可以收藏以备不时之需 Spring Cloud实战专栏&#xff1a;https://blog.csdn.net/superdangbo/category_9270827.html Python 实战专栏&#xff1a;https://blog.csdn.net/superdangbo/category_9271194.html Logback 详解专栏&#xff1a;https:/…

Matplotlib自定义坐标刻度_Python数据分析与可视化

自定义坐标刻度 主次要刻度隐藏刻度与标签花哨的刻度格式格式生成器与定位器 虽然matplotlib默认的坐标轴定位器与格式生成器可以满足大部分需求&#xff0c;但是并非对每一幅图都合适。 主次要刻度 学习前最好有对matplotlib图形的对象层级较为了解&#xff0c;例如查看前面…

ZKP11.3 Correlation Intractability

ZKP学习笔记 ZK-Learning MOOC课程笔记 Lecture 11: From Practice to Theory (Guest Lecturer: Alex Lombardi) 11.3 What can we do without random oracle model Falsifiable Assumptions Prove security assuming that some concrete algorithmic task is infeasible: …

案例024:基于微信小程序的汽车保养系统

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…

【华为网络-配置-021】- MSTP 多实例配置及安全保护等

要求&#xff1a; 1、vlan 10 从红色链路转发。 2、vlan 20 从黄色链路转发。 一、基础配置 [SW1]vlan batch 10 20 [SW1]interface GigabitEthernet 0/0/1 [SW1-GigabitEthernet0/0/1]port link-type trunk [SW1-GigabitEthernet0/0/1]port trunk allow-pass vlan all [SW…