STM32音乐频谱分析要点.docx
- 文档编号:16814907
- 上传时间:2023-07-17
- 格式:DOCX
- 页数:14
- 大小:400.98KB
STM32音乐频谱分析要点.docx
《STM32音乐频谱分析要点.docx》由会员分享,可在线阅读,更多相关《STM32音乐频谱分析要点.docx(14页珍藏版)》请在冰点文库上搜索。
STM32音乐频谱分析要点
STM32音乐频谱分析
2011-12-1103:
06:
03| 分类:
制作类| 标签:
|举报|字号大中小 订阅
呵呵,在昨天的基础上,进行了改进。
采样频率为12.3Khz,256点FFT。
视频:
其实这玩意不难做,音频信号采集,我的方法是将电脑出来的信号用TDA2822放大,然后给单片机AD口,剩下就是软件上的了。
说起TDA2822,还是挺不错的一款功率放大芯片,本只想用来做信号放大用的,但baidu了下它和看它的数据手册,
都多用来做小功率功放。
呵呵,那就也做一个吧。
TDA2822的典型应用电路如下:
这电路很普通,没什么特别,参数也不用调整,直接搭出来,就正常的工作。
接下来就是将放大后的信号给单片机,这里问题就来了,电路中C4,C5是干什么,给单片机的话要不要加?
于是开始baidu,google,但没找到合适解答,于是翻了翻模电书,里面还真讲到功率放大器,,
TDA2822是OTL功放,输出电容起耦合作用,因为OTL功放在在静态时输出端都会有Vcc/2伏的输出,这样会搞坏喇叭,
所以需要加个电容,隔离。
单片机处理的话就不用输出电容了。
如果用示波器一看,结果就很明显,如下图,下面的信号是加了电容,上面是没加。
做好电路后理所当然的准备将功放输出端接到单片机上,但突然一想,不对啊,功放我给11.1V供电,那输出不就有5V左右电压?
而STM32是3.3V!
不烧了才怪!
幸好TDA2822工作电压范围在1.8~12V间,所以就给它3.3V行了。
这样一来基本就没问题了。
第二个的输出电容还是保留,作个对比。
好了,接下来就是程序了。
首先就得确定采样率,就是间隔多久采一个点。
刚开始不是很懂,用的40kHz,也成,但要是做音频频谱分析没必要那么高了。
这里有些资料:
音频的频率范围及表现力度
音频的频率范围、音质的评价标准一般认为20Hz-20kHz是人耳听觉频带,称为“声频”。
这个频段的声音称为“可闻声”,高于20kHz的称为“超声”,低于20Hz的称为“次声“。
所谓声音的质量,是指经传输、处理后音频信号的保真度。
目前,业界公认的声音质量标准分为4级,即:
数字激光唱盘CD-DA质量,其信号带宽为10Hz~20kHz;
调频广播FM质量,其信号带宽为20Hz~15kHz;
调幅广播AM质量,其信号带宽为50Hz~7kHz;
电话的话音质量,其信号带宽为200Hz~3400Hz。
可见,数字激光唱盘的声音质量最高,电话的话音质量最低。
除了频率范围外,人们往往还用其它方法和指标来进一步描述不同用途的音质标准。
音频频率范围一般可以分为四个频段,即:
低频段(30—150HZ);
中低频段(30—150HZ);
中低频(150—500HZ);
中高频段(500—5000HZ);
高频段(5000—20kHZ)。
30—150HZ频段:
能够表现音乐的低频成分,使欣赏者感受到强劲有力的动感。
150—500HZ频段:
能够表现单个打击乐器在音乐中的表现力,是低频中表达力度的部分。
500—5000HZ频段:
主要表达演唱者或语言的清淅度及弦乐的表现力。
5000—20kHZ频段:
主要表达音乐的明亮度,但过多会使声音发破。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
所以我选则12kHz左右的采样率。
下面的DSP_Lib文件夹就是ST公司提供的DSP库。
FFT,PID等都是用汇编写的。
将ST提供的FFT表加载到内存中,速度是快一些,1024点只需1.7ms左右,我觉得效率算是蛮高了。
接下来就是代码了:
#include
#include
#include"stm32_dsp.h"
#include"table_fft.h"
#include"sys.h"
#include"usart.h"
#include"delay.h"
#include"timer.h"
#include"LED.h"
#include"ADC.h"
#include"3264LED.h"
#defineNPT256 //FFTpoint
#defineFAST 1 //指示条下落速度
#defineSLOW 50//绿点下落速度
#defineSTOP 35 //绿点停顿速度
u16TableFFT[];
u16AD_Count=0;
u16time,time2;
voidpowerMag(void); //计算幅值
u32Data_IN[NPT]; /*Complexinputvector*/
u32Data_OUT[NPT]; /*Complexoutputvector*/
u32lBUFMAG[NPT/2]; /*保存幅值*/
u16Result[64]; //最终结果
u8 Pos[64]={0}; //绿点位置
u8 Dot[64]={0}; //记录每点停顿时间
u32TMP;
intmain(void)
{
u16i,k;
s16tmp;
Stm32_Clock_Init(9); //系统时钟设置72Mhz
delay_init(72); //延时初始化
Timer3_Init(5,7199); //0.6ms中断一次 LED显示
Timer4_Init(7,760); //约74us中断一次, AD采集
LED_Init();
LEDs_Init(); //点阵初始化
Adc_Init();
time=time2=0;
AD_Count=0;
while
(1)
{
cr4_fft_256_stm32(Data_OUT,Data_IN,NPT); //做256点fft运算
powerMag(); //算幅值
for(i=1;i<65;i++) //点平移,去除静态波动
{
tmp=lBUFMAG[i]/2-5; //显示幅值为实际幅值的一半并减去5,这样效果较好
if(tmp<0)tmp=0;
elseif(tmp>31)tmp=31;
if(tmp>=Result[i-1])
{
Result[i-1]=tmp; //得到每列上绿点的高度
if(Result[i-1]>=Pos[i-1])
{Dot[i-1]=0;Pos[i-1]=Result[i-1];} //更新绿点高度
}
}
for(i=0;i<64;i++)
{
for(k=0;k<32;k++) //画红点
{
if(k elseDraw_Point(i,k,0,0); } Draw_Point(i,Pos[i],GREEN,2); //画绿点 if(time2>FAST&&Result[i]>=1)Result[i]--; if(Dot[i]>=STOP) //停顿判断 {if(time>SLOW&&Pos[i]>=1)Pos[i]--;} Dot[i]++; if(Dot[i]>=250)Dot[i]=250; } if(time>SLOW) time=0; if(time2>FAST)time2=0; elsetime2++; } } /* ********************************************************************************************************* * Calculatepowermag * 计算各次谐波幅值 * 先将lBUFOUT分解成实部(X)和虚部(Y),然后计算幅值(sqrt(X*X+Y*Y) ********************************************************************************************************* */ voidpowerMag(void) { s32lX,lY; u32i; floatX,Y,Mag; for(i=0;i<65;i++)//只显示64个点,所以计算得到前面65个点的幅值就行了。 { lX =(Data_OUT[i]<<16)>>16; lY =(Data_OUT[i]>>16); X = ((float)lX)/64; Y = ((float)lY)/64; Mag=sqrt(X*X+Y*Y)/NPT; lBUFMAG[i] =(u32)(Mag*65536); } } voidTIM4_IRQHandler(void) //定时器4中断服务程序 约74us中断一次 { ADC1->SQR3&=0XFFFFFFE0; //规则序列1 ADC1->SQR3|=2; //通道2采集 ADC1->CR2|=1<<22; //启动规则转换通道 TMP=ADC1->DR; Data_IN[AD_Count]=TMP<<16; AD_Count++; if(AD_Count>255)AD_Count=0; TIM4->SR&=~(1<<0); //清除中断标志位 } voidTIM3_IRQHandler(void)//定时器3中断服务程序 { u16i; if(TIM3->SR&0X0001) //溢出中断 { oe=0; //关显示 for(i=0;i<64;i++)//移出缓存区的上半屏一行数据 wr_595(SBF[Line][i]); for(i=0;i<64;i++)//移出缓存区的下半屏一行数据 wr_595(SBF[Line+16][i]); out_595(); //锁存数据 GPIOC->ODR&=0x00FF; GPIOC->ODR|=(15-Line)<<10; oe=1; //开显示 Line++; if(Line>15)Line=0; time++; } TIM3->SR&=~(1<<0); //清除中断标志位 } OK,程序也不复杂,这样一来就可以实现音乐频谱分析了,呵呵。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- STM32 音乐 频谱 分析 要点