打印

请教如果在单片机上利用fft实现音频频谱测量?

[复制链接]
4384|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
像见|  楼主 | 2007-12-4 17:28 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
computer00| | 2007-12-4 18:59 | 只看该作者

你去DSP版块找找我以前发的关于FFT含义的帖子。

使用特权

评论回复
板凳
x_tin| | 2007-12-4 19:04 | 只看该作者

自己写FFT程序或者用库函数!

普通的单片机算起来有点慢 呵呵,要搞那种DSP结构的。算出来后 把得到的值显示到LCD,横坐标是 频率 纵坐标是 幅度! 每个点算出来的幅值 还要经过调整,然后每个点 对应的频率也要 算一下。  如果用那种黑白的LCD刷新一次显示估计也好慢,这样就不好跟踪音频信号是实时 频谱了! 呵呵 俺就了解这么多! 那个发明这个变换的人 怎么就知道算算 就能算出频率的幅度喃! 太高手了!! 神啊!!

使用特权

评论回复
地板
computer00| | 2007-12-4 19:52 | 只看该作者

一秒刷新几次也就差不多了。

使用特权

评论回复
5
chuangong| | 2007-12-4 20:50 | 只看该作者

FFT对RAM要求特高,哈哈!!

FFT对RAM要求特高,即使用2N fft 516 byte的Ram分辨率也不高,如果做不好用到浮点运算,也会占用ROM2-3Kbyte哈哈。
但是等待你的好消息。

使用特权

评论回复
6
IceAge| | 2007-12-4 22:38 | 只看该作者

如果仅仅是显示

那么应该用 DFT , 而不是 FFT, 因为你仅仅需要几个特定频率点, DFT 可以得到独个频率点的幅值。mcu 速度应该勉强够了。

使用特权

评论回复
7
像见|  楼主 | 2007-12-4 23:20 | 只看该作者

在0-20k之间只需要26个频点就可以了?

在0-20k之间只需要26个频点就可以了?
单片机可以应付算出它的频点和幅度值?

使用特权

评论回复
8
dragon_hn| | 2007-12-4 23:47 | 只看该作者

要看楼主的要求

楼主要的频点数,频点幅度级数,音频信号的采样频率等.
本人做过一个类似的PC软件,楼主有兴趣可以参考一下,网址如下:
http://www.dragon-2008.com/dragon/FileListA01.htm

使用特权

评论回复
9
dragon_hn| | 2007-12-4 23:53 | 只看该作者

单片机建议楼主用汇编语言写

用义隆或是AVR单片机,速度较快,其他单片机速度大多不行.
以前某大厂复读机就用义隆的做语音变速(含STFT变换)和ADPCM,优化后速度肯定没问题.C语言效率太低,不适合这种耗CPU速度的要求

使用特权

评论回复
10
IceAge| | 2007-12-5 00:03 | 只看该作者

26个频点似乎过于精细了

你见过 26 柱频谱显示的机器么?

贴一个 Excel 里用的 DFT class: 

Dim dft_Sin() As Double
Dim dft_Cos() As Double
Dim buffer() As Double

Dim n As Integer, PI As Double, temp As Double
Dim m_R As Double, m_I As Double
Dim counter As Integer

Public Sub Initialize(sample As Integer, harmonic As Integer)
    Dim j As Integer
    n = sample
    m_R = 0
    m_I = 0
    ReDim dft_Sin(n)
    ReDim dft_Cos(n)
    ReDim buffer(n)
    For j = 0 To n - 1
        dft_Sin(j) = Sqr(2) * Sin(2 * harmonic * PI * j / n) / n
        dft_Cos(j) = Sqr(2) * Cos(2 * harmonic * PI * j / n) / n
        buffer(j) = 0
    Next j
    counter = 0
End Sub
Public Property Get R() As Double
    R = m_R
End Property

Public Property Get i() As Double
    i = m_I
End Property

Public Property Get Magnitude() As Double
    Magnitude = Sqr(m_R * m_R + m_I * m_I)
End Property

Private Sub Class_Initialize()
    PI = 3.1415927
End Sub

Public Function DoDFT(v As Double) As Integer
    counter = counter Mod n
    temp = v - buffer(counter)
    m_R = m_R + temp * dft_Cos(counter)
    m_I = m_I + temp * dft_Sin(counter)
    buffer(counter) = v
    counter = counter + 1
    DoDFT = counter
End Function
 

使用特权

评论回复
11
teddeng| | 2007-12-5 00:41 | 只看该作者

楼主琢磨这问题大半年了吧?

会者不难,

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

20

主题

56

帖子

0

粉丝