【小程序】C语言吉他调音器-利用FFT傅里叶变换求频率实现

该博客介绍利用傅里叶变换实现吉他调音器的方法。通过求得音频数据频率,对比音高频率对照表,测试吉他弦与标准音差值。程序输入弦号开始录音,约10秒后显示结果。实现过程需注意获取有效采样点及6弦特殊情况,还给出样例代码和测试用例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

利用傅里叶变换求得音频数据的频率,根据音高频率对照表,可测试出吉他每根弦与标准音的差值,实现调音器效果。

目录

  • 程序效果
  • 实现过程
  • 样例代码
  • 测试用例
  • 参考资料

程序效果

截图1:程序效果

        输入需要调整的弦,即开始录音,弹对应的弦即可,录音时间大约10秒,10秒后短暂计算处理后会显示结果。

实现过程

截图2:流程图

主要步骤如上,需要注意的细节有: 

 1.如何获取有效的4096个采样数据点

截图3:有效数据前的杂音及静音数据

        本程序强行跳过前8000个采样数据点,并且用600进行边界判定,从第一个大于600的点开始采集。这要求使用的环境很安静才行,如果有其他声音干扰,对结果有较大影响。

2.6弦的特殊情况 :1-5弦使用正常时,6弦的频率值一直为正常值的2倍,无法定位问题情况下,强行将结果除以2,保证功能可以正常使用。

样例代码

1.下载链接:https://download.youkuaiyun.com/download/u013025955/11190369

部分主要代码

//傅里叶变换
void getFFTEnergy(double *data)
{
    double pr[DATASIZE], pi[DATASIZE], fr[DATASIZE], fi[DATASIZE];
    int i=0;

    //原始数据作为实部,虚部填0.0
    for (i=0; i<DATASIZE; i++)
    {
        pr[i] = *(data+i);
        pi[i] = 0.0;
    }

    /*
    入参解释:
    pr:采样数据的实部,对应PCM数据,返回傅里叶变换的模(能量)
    pi:采样数据的虚部,填0.0,返回傅里叶变换的幅角,本程序不使用
    DATASIZE:采样点数,这里对应4096
    12:采样点数4096对应是2的12次方
    fr:傅里叶变换后的实部
    fi:傅里叶变换后的虚部
    0:使用傅里叶变换功能,1为逆变换
    1:计算模和幅角,0的话不会计算,这里要注意
    */
    //调用FFT快速离散傅里叶变换函数
    kfft(pr, pi, DATASIZE, 12, fr, fi, 0, 1);

    //模(能量)返回
    for (i=0; i<DATASIZE; i++)
    {
        *(data+i) = pr[i];
    }
}

//换算频率
double getFrequence(double *data, int chooseStr)
{
    int locate; //能量值对应的横坐标
    int i;
    double frequence; //频率
    double max; //能量最大值

    max = *data;

    //求能量最大值对应的横坐标
    for (i=0; i<(DATASIZE/2); i++)
    {
        if (*(data+i) > max)
        {
            max = *(data+i);
            locate = i;
        }
    }

    //计算频率,频率=横坐标*(采样率/采样点数)
    frequence = locate*(8000.0/DATASIZE); 

    //6弦的特殊处理,除以2
    if (chooseStr == 6)
    {
        frequence = frequence/2.0;
    }

    return frequence;
}

测试用例

截图4:测试用例

参考资料

1.《常用算法程序集(C语言描述)》FFT快速离散傅里叶变换例程

2.深入浅出解释FFT(一)——用fft求频谱

https://blog.youkuaiyun.com/wordwarwordwar/article/details/68951388

3.fseek()用法 设定文件的当前读写位置

https://blog.youkuaiyun.com/Tian_fourpieces/article/details/79970098

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值