系列文章目录

  • Delay Line 简介及其 C/C++ 实现
  • LFO 低频振荡器简介及其 C/C++ 实现

文章目录

  • 系列文章目录
  • 一、Delay 是什么
  • 二、Delay 原理
    • 2.1 The Basic Delay
    • 2.2 Delay With Feedback
    • 2.3 Wet & Dry
  • 三、Delay C/C++ 实现
  • 总结
  • 参考

一、Delay 是什么

Delay(延迟)是一种信号处理技术,它将输入信号纪录起来,然后过一段时间再播放。当延迟信号与当前信号混合时,会产生类似回声(Echo)的效果。大多数人都有过在大山中大喊的经历,声音在山谷之间传递,回声余音袅袅。没错,所谓的 Echo 就是这种感觉。看下面两个对比视频,加深对 Echo 的理解:

土拨鼠的尖叫

土拨鼠的尖叫-Echo

毫无疑问,Delay 是当今市场上最强大的音乐制作工具之一。我们听到的几乎所有的调制效果都是用特定的延时创造的。


二、Delay 原理

2.1 The Basic Delay

最简单 Delay,即输入信号与延迟信号叠加得到输出信号,差分方程如下:
y(n)=x(n)+x(n−D)(1)y(n)=x(n)+x(n-D) \tag{1} y(n)=x(n)+x(nD)(1)
其中 DDD 为延迟时间,更准确的说,表示延迟了 DDD 个采样点。下图是(1)的块状图。


我们对(1)进行 Z 变换,以此来探究 Basic Delay 对频率的影响:
y(n)=x(n)+x(n−D)Y(z)=X(z)+X(z)z−D=X(z)(1+z−D)H(z)=Y(z)X(z)=1+z−D(2)\begin{aligned} y(n) &=x(n)+x(n-D) \\ Y(z) &=X(z)+X(z) z^{-D} \\ &=X(z)\left(1+z^{-D}\right) \\ H(z) &=\frac{Y(z)}{X(z)}=1+z^{-D} \end{aligned} \tag{2} y(n)Y(z)H(z)=x(n)+x(nD)=X(z)+X(z)zD=X(z)(1+zD)=X(z)Y(z)=1+zD(2)
H(z)=1+z−DH(z) = 1+z^{-D}H(z)=1+zD 可以推断出它没有极点,只有 D 个零点。接下来求它的零点:
1+z−D=0z−D=−1\begin{aligned} 1+z^{-D} = 0 \\ z^{-D} = -1 \end{aligned} 1+zD=0zD=1
接下来就是复数次方根的求解了,这部分内容可以参考 「珂学原理」No.110「复数的n次方根」。这里就不在重复视频提到的方法,而是利用欧拉公式求解。

z=ejωz =e^{j \omega}z=ejω ,通过欧拉公式转换得到:
cos⁡(Dω)+jsin⁡(Dω)=−1\cos (D \omega)+j \sin (D \omega)=-1 cos(Dω)+jsin(Dω)=1
由于 −1-11 为实数,无复数部分,因此可得:
cos⁡(Dω)=−1ω=±kπDk=1,3,5,…,D\begin{aligned} \cos (D \omega) = -1 \\ \omega=\pm \frac{k \pi}{D} \quad k=1,3,5, \ldots, D \end{aligned} cos(Dω)=1ω=±Dkπk=1,3,5,,D
D=2D=2D=2 时,ω=±π2\omega=\pm \frac{\pi}{2}ω=±2π
D=4D=4D=4 时,ω=±π4,±3π4\omega=\pm \frac{\pi}{4}, \pm \frac{3\pi}{4}ω=±4π,±43π
D=5D=5D=5 时,ω=±π5,±3π5,±π\omega=\pm \frac{\pi}{5}, \pm \frac{3\pi}{5}, \pm \piω=±5π,±53π,±π
我们发现 D 个零点是平均分布在单位元上的,不同 D 的频谱响应如下图所示。

D=32D=32D=32 时可以看到频谱响应像是一把梳子一样,此类滤波器也被称为“梳妆滤波器”。

此外,我们还可以在 Audition 上使用 Basic Delay 对扫频信号进行处理,可以看到明显的梳妆特征。

处理前:

处理后:

2.2 Delay With Feedback

Basic Delay 只能产生单一的回声,应用比较有限。大多数 Delay 算法还会包含一个反馈控制,它将延迟后的信号以一定比例送回输入,如下图所示:

假设反馈控制那一条信号为 g(n)g(n)g(n),那么上图的差分方程为:
y(n)=x(n)+g(n)其中,g(n)=x(n−D)+fg(n−D)y(n) = x(n) + g(n)\\ \text{其中,} g(n) = x(n-D) + fg(n-D) y(n)=x(n)+g(n)其中,g(n)=x(nD)+fg(nD)
进一步推导有:
y(n−D)=x(n−D)+g(n−D)g(n−D)=y(n−D)−x(n−D)(3)\begin{aligned} y(n-D) &= x(n-D) + g(n-D) \\ g(n-D) &= y(n-D) - x(n-D)\\ \end{aligned}\tag{3} y(nD)g(nD)=x(nD)+g(nD)=y(nD)x(nD)(3)
g(n)=x(n−D)+fg(n−D)=x(n−D)+f(y(n−D)−x(n−D))=(1−f)x(n−D)+fy(n−D)因此y(n)=x(n)+g(n)=x(n)+(1−f)x(n−D)+fy(n−D)(4)\begin{aligned} g(n) &= x(n-D) + fg(n-D) \\ &= x(n-D) + f(y(n-D) - x(n-D)) \\ &= (1-f)x(n-D) + fy(n-D) \\ \text{因此} \\ y(n) &= x(n) + g(n) \\ &= x(n) + (1-f)x(n-D) + fy(n-D) \end{aligned}\tag{4} g(n)因此y(n)=x(nD)+fg(nD)=x(nD)+f(y(nD)x(nD))=(1f)x(nD)+fy(nD)=x(n)+g(n)=x(n)+(1f)x(nD)+fy(nD)(4)

对上述差分方程进行 Z 变换得:
Y(z)=X(z)+(1−f)z−DX(z)+fz−DY(z)(1−fz−D)Y(z)=(1+(1−f)z−D)X(z)(5)\begin{aligned} &Y(z) = X(z) + (1-f)z^{-D}X(z) + fz^{-D}Y(z) \\ &(1-fz^{-D})Y(z) = (1+(1-f)z^{-D})X(z) \\ \end{aligned} \tag{5} Y(z)=X(z)+(1f)zDX(z)+fzDY(z)(1fzD)Y(z)=(1+(1f)zD)X(z)(5)
H(z)=Y(z)X(z)=1+(1−f)z−D1−fz−D=zD+1−fzD−f(6)H(z) = \frac{Y(z)}{X(z)} = \frac{1+(1-f)z^{-D}}{1-fz^{-D}} = \frac{z^D + 1 - f}{z^D - f} \tag{6} H(z)=X(z)Y(z)=1fzD1+(1f)zD=zDfzD+1f(6)
从公式(6)可知该滤波器有 D 个零点和 D 个极点,平均分布在单位圆内。再一次,复数次方根求解请参考 「珂学原理」No.110「复数的n次方根」。不同 D 值的频响曲线和零极点分布图如下:

2.3 Wet & Dry

我们称处理后的信号为 “湿” 的信号,未经处理的信号为 “干”信号。一种更加实用的 Delay 算法将会 “湿” 信号和 “干” 信号进行 mix,并通过 Wet 和 Dry 两个系数来控制干湿比。其块状图如下:

差分方程为:
y(n)=dry∗x(n)+wet∗g(n)(7)y(n) = dry*x(n) + wet*g(n) \tag{7} y(n)=dryx(n)+wetg(n)(7)

z 变换推导和之前类似,不再赘述了。


三、Delay C/C++ 实现

说完原理,我们来说具体要如何实现。通常,Delay 使用 Delay Line 来实现,整体实现并不复杂,用一个函数就可以简单概况:

void process(AudioBuffer<float> *buffer,int delay_samples, float feedback, float dry, float wet) {for (size_t c = 0; c < buffer->getNumberChannels(); ++c) {float *channel = buffer->getWriterPointer(c);auto *dline = dlines_.getDelayLine(c);for (size_t i = 0; i < buffer->getNumberFrames(); ++i) {float in = channel[i];float d_y = dline->get(delay_samples);float d_x = in + feedback * d_y;dline->push(d_x);channel[i] = dry * in + wet * d_y;}}
}

上述代码中:

  1. buffer->getWriterPointer(c)dlines_.getDelayLine(c) ,分别获取当前声道数据和当前声道所使用的 Delay Line
  2. 在第二个 for 循环中,实现了公式(7)中的代码

具体更细节的代码内容请参考 Libaa - Delay


总结

以上就是今天的全部内容,我们首先介绍了 Delay 是什么,它可以产生 Echo,用于音效制作上;接着介绍了 Delay 的数学原理,从 Basic Delay 逐步发展到最终版本 Delay with Dry&Wet;最后还给出了 Delay 的 C/C++ 实现代码。


参考

  • 「珂学原理」No.110「复数的n次方根」
  • Libaa - Delay

【音效处理】Delay/Echo 简介相关推荐

  1. 【音效处理】Vibrato 简介

    系列文章目录 Delay Line 简介及其 C/C++ 实现 LFO 低频振荡器简介及其 C/C++ 实现 [音效处理]Delay/Echo 简介 文章目录 系列文章目录 一.Vibrato 是什么 ...

  2. Linux中的echo简介(自我总结)(44)

    2019独角兽企业重金招聘Python工程师标准>>> 能在echo中输出的字符:(注意运行这些字符时都要加-e选项.) Here are following escape sequ ...

  3. 【音效处理】Compressor 压缩器算法简介

    系列文章目录 Delay Line 简介及其 C/C++ 实现 LFO 低频振荡器简介及其 C/C++ 实现 [音效处理]Delay/Echo 算法简介 [音效处理]Vibrato 算法简介 [音效处 ...

  4. 【音频处理】Loudness Normalization 响度均衡算法简介

    系列文章目录 Delay Line 简介及其 C/C++ 实现 LFO 低频振荡器简介及其 C/C++ 实现 [音效处理]Delay/Echo 算法简介 [音效处理]Vibrato 算法简介 [音效处 ...

  5. 【音频处理】Channel Vocoder 算法简介

    系列文章目录 Delay Line 简介及其 C/C++ 实现 LFO 低频振荡器简介及其 C/C++ 实现 [音效处理]Delay/Echo 算法简介 [音效处理]Vibrato 算法简介 [音效处 ...

  6. 音频特效:Delay 和 Vibrato

    Delay line 延迟线 今天我们将讨论 Delay 和 Vibrato 两种音频特效的技术原理和实现细节. Delay 和 Vibrato 都是基于 Delay line 实现的.Delay l ...

  7. go初学者安装echo框架

    一.echo简介 Go语言中,web框架非常多,但是echo绝对是性能非常好的一种,下面是各种go框架的性能对比 中国有这个框架的翻译版本,不是非常全,但是也基本上差不多了,如果英文基础好的话可以查阅 ...

  8. 【产品体验】echo回声

    本人产品新人,学习中,希望大家用过该产品的给点意见,不吝赐教哦~~ 先来两张echo的界面图镇楼--        echo简介: "echo"是一款做声音社交的APP,在这里,你 ...

  9. linux脚本echo off,echo什么意思_@echo off的作用 - 编程语言及工具 - 电子发烧友网

    ECHO简介 英文原义:EchoProtocol中文释义:应答协议注解,主要用于调试和检测中.它可以基于TCP协议,服务器就在TCP端口7检测有无消息,如果使用UDP协议,基本过程和TCP一样,检测的 ...

最新文章

  1. Qt下一行代码就可以使用的稳定易用的日志log类
  2. CSS题目系列(3)- 实现文字切割效果
  3. 李世石宣布退役,高呼AI不可战胜:将举行史上首次让子人机大战
  4. WordPress 运行流程分析
  5. jqGrid列的统计
  6. 【转】功能测试的经验总结
  7. springmvc工作流程详解_SpringMVC工作原理详解
  8. 商务部部长助理黄海:中国服务外包产业发展势头良好
  9. python 安装pip和Django
  10. Python深度学习入门学习路线(简单速成不掉头发)
  11. android布局详解
  12. 我的编程之路点滴记录(三)
  13. nuc10黑苹果无法wifi上网
  14. wordpress footer.php,wordpress的get_footer( )函数功能详解
  15. LeetCode-初级算法-有效的数独 ( java )
  16. 第二章 项目经理评分
  17. SpringCloud Alibaba 实战之《配置中心:基于 Nacos 集中管理应用配置》
  18. 关于谷歌浏览器请求action两次
  19. HOME: First Word —— 字符串分割、正则表达式
  20. 教你检查Mac电池的健康度

热门文章

  1. 5_数据分析—数据可视化
  2. windows操作系统,python环境下django的自动安装
  3. 2019公需科目快速学完_3周考过科目二,是这样做到的!
  4. linux搭建python运行环境_centos运行.py centos5.5下搭建python开发运行环境 - Linux - 服务器之家...
  5. 简单人物画像_天天谈【用户画像】95%的人根本不知道自己在说什么
  6. c语言二维数组中的周边,【C语言】二维数组中的查找,杨氏矩阵
  7. mysql快速导入导出数据库_mysql快速导出与导入
  8. dockerfile、docker compose、k8s区别
  9. cadence 常见pcb电阻_高速PCB培训手记
  10. gps天线拆解图片_飞宇稳定器拆解:握杆的手,不怕颤抖