嵌入式学习小组
直播中

李雨欣

7年用户 148经验值
私信 关注

怎么设计出吉他合成器?

怎么设计出吉他合成器?

回帖(1)

张晶

2021-6-2 14:32:50
  数字声音合成技术总让我这个业余爱好者感到着迷。一个有关Karplus-Strong吉他合成技术的维基网页更加激发了我的兴趣。它吸引我的地方是这种合成器设计非常简单。下面是来自维基网页的图形(图1):
  
  图1:来自维基的K-S方框图
  网页另外指出延迟L可按以下简单公式决定音调音质,
  
  式中的滤波器系数决定音调的‘粘性’。
  突发噪声?就是这样吗?肯定不对!不可能就这么简单!与所有业余爱好者一样,我立马开始着手实施。写代码只用了几个小时,然后我把DAC输出连接到示波器。可以看出与谐波叠加后大致呈正弦曲线,但是无法确定听起来会是什么样。
  在一阵翻箱倒柜之后,我连接了一对旧耳机。我没太高期望,大家都知道:对于初次尝试的项目来说,要么是一无所获,要么是背运情况下会看到它冒出一缕白烟(我宁愿把这看成是芯片的灵魂升入虚空)。在确实听到像拨弄吉他发出的声音之时着实让我吃了一惊。
  似乎有点对路了。先提醒一下,下面要讲到数学了。
  分析:
  让我们更深入地看看下图2:
  
  图2: K-S方框图–注释
  合成器的输出是低通滤波器输出与突发噪声的简单求和。在下面所有公式中,下标‘n’均为当前取样。
  f2.gif
  经过一番处理之后我们可以得到一个庞大的表达式:
  
  好在通过利用Excel扫描频率ω很容易就能求出幅值响应。
  取样速率设为44.1ksps(这是可扫描整个听觉范围的最小值)。
  如果从式1生成200Hz音调,延迟‘L’则为44100/200 = 220.5。
  由于我们的延迟为数字式,因此选择220这个接近值。我随意选择10KHz的低通滤波器极点值入手。此极点频率可确定上述‘a’与‘b’的值。
  
  图3:频率响应
  我们可以根据此响应明确看出我们是否传输宽带噪声信号(而我宁愿将其视为能量散布全部频率的信号),而您看到的输出是200Hz基频,随后是2x、3x、4x…谐波。这基本上就是实际吉他弹奏时的表现:基频随后是伴生泛音。
  
  图4:吉他泛音
  另一个值得注意的有趣现象是:当把滤波器极推向更低频率时会抑制更高阶谐波,同时音调也变得更‘纯净’。但是,声音听起来不太像吉他,而是很像音调很快消失的鼓声。
  
  图5:不同截止频率的频率响应
  另外有趣的是改变滤波器截止频率时音调频率会发生轻微偏移。基频附近的偏移不太明显,但是更高阶谐波由于与低通滤波器相关的相位损失而开始更显著地偏移。
  以下是在156Hz附近弹奏E调时获得的实际DSO波形的快速截屏。
  
  图6:E调波形采集——156Hz的基频
  
  图7:E调FFT——156Hz的基频
  频率峰值的分布符合预期;尽管幅度跌落与理论计算不一致,但是整体图像十分匹配。
  实现:
  实现方案完全在赛普拉斯半导体公司的PSoC5LP混合信号SoC内部完成。为了更加有趣,通过采用几个能够在触摸时弹奏不同音调的触摸按钮,我在系统中增加了一个用户界面。
  
  图8:系统级方框图
  采用CY8CKIT-050开发套件、用于触摸按钮的扩充板和我从卧室‘暂借’的几个精致的扬声器,整个系统配置大致如下:
  
  图9:吉他合成器配置
  Speaker output:扬声器输出;developer kit + expansion board:开发套件 + 扩充板
  
  图10:细节展示
  5 strings of a guitar:吉他的5跟弦;analog output to speaker:到扬声器的模拟输出;slider changes chords of guitar:滑片可改变吉他的和弦。
  总结:
  Karplus-Strong合成器可能是最简单的合成器编码算法,但是其输出音质出人意料地不错,即使是仅采用8位DAC(其严格来说对于音频再现而言有点功率不足)。唯一的缺陷是演奏低频音调时我们需要数值非常大的缓冲器。例如,演奏100Hz信号需要441缓冲器,取样速率为44.1Ksps。如果我们希望添加多个同时弦时就会带来问题,而且代码大小也成问题。
  此外,加入PSoC的灵活性也会带来众多新的选择,如:采用I2S接口把信号输出到标准音频DAC。将合成代码转移到数字滤波模块(DFB)可以释放主核,从而可以添加任何其它计算密集型进程。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分