签到

05月06日
尚未签到

共有回帖数 0

    告别旧巷

    等级:
    我觉得这是个挺有意思的陷阱,于是简单写篇帖子骗骗分~



    昨天SB给我发了段代码,他用C写了个程序想生成一段变频正弦波存成wav:频率从20Hz线性地变到10000Hz。但是程序写出来遇到了一个问题:使用频谱分析软件发现,频率最终变到了20000Hz左右。
    https://github.com/m13253/sound-exp/blob/2cf918f8dfc7daedf1e18b1d588438a55fedc29f/sine-pitch/sine.c
    这是原来的代码。

    在sin前面加了行printf("%fn", freq);
    然后
    $ gcc sine.c
    $ ./a.out  log
    发现freq的确是从20变到10000。
    ---

    其实注意一下这行
    buf = sin((2*M_PI*freq+1)*i/SAMPLE_RATE);
    简化一下就是sin(2*pi*freq*t),我们很熟悉的freq频率的正弦波生成。但这里是不能这么用的。为什么呢?因为freq是在变的。
    我们也可以把这理解成是在t轴上缩放函数sin(2*pi*t)的图像,把它挤扁freq倍。
    但是如果变频的话,我们得边在t轴上跑边挤扁这个函数。注意直接更改freq,它是以y轴为中心挤扁图像的……于是就出现了不同步!
    所以……我们要变在t轴上往右边跑,边以t为中心把sin(2*pi*t)的图像挤扁freq倍。
    比较好实现的方法是,把2 * pi * freq * t抽出来,放到一个用来累加的变量里去。
    每次循环把这个变量的值+=2 * pi * freq,
    然后buf = sin(累加变量);


    最终修改成这样:
    https://github.com/m13253/sound-exp/blob/b74a121840c3f5cfdf4e8b14e1303eee17f2fb50/sine-pitch/sine.c



    楼主 2016-04-09 15:03 回复

共有回帖数 0
  • 回 帖
  • 表情 图片 视频
  • 发表

登录直线网账号

Copyright © 2010~2015 直线网 版权所有,All Rights Reserved.沪ICP备10039589号 意见反馈 | 关于直线 | 版权声明 | 会员须知