🥥声波的时域和频域Python实现示例
声波 | Python | Matplotlib | 傅里叶变换 | Numpy | 时域 | 频域
简介
傅里叶变换
傅立叶变换(FT)是一种数学变换,它可以将函数(通常是时间的函数或信号)分解为其组成频率,例如根据其组成音符的音量和频率来表达和弦。 术语傅立叶变换既指频域表示,也指将频域表示与时间函数相关联的数学运算。
时间函数的傅立叶变换是频率的复数值函数,其幅度(绝对值)表示原始函数中存在的该频率的量,并且其自变量是该频率中基本正弦波的相位偏移。 傅里叶变换不限于时间的函数,而是原始函数的域通常被称为时域。 傅立叶反演定理证明,还有一个傅立叶逆变换可从其频域表示中数学合成原始函数。
在一个域(时间或频率)中执行的线性运算在另一域中具有相应的运算,有时更容易执行。 时域中的微分运算对应于乘以频率,因此一些微分方程在频域中更易于分析。 同样,时域中的卷积对应于频域中的普通乘法。 执行所需的操作后,可以将结果转换回时域。 谐波分析是对频域和时域之间的关系的系统研究,其中包括彼此之间“较简单”的功能或运算的种类,并且与现代数学的许多领域都有着深厚的联系。
加法合成
加法合成是一种声音合成技术,通过将正弦波加在一起来创建音色。
可以根据傅立叶理论将乐器的音色考虑为由多个谐波或非谐波部分或泛音组成。 每个部分都是具有不同频率和幅度的正弦波,由于来自ADSR包络或低频振荡器的调制,该正弦波随时间而膨胀和衰减。
加法合成通过将多个正弦波发生器的输出相加,最直接地产生声音。替代实施方式可以使用预先计算的波表或逆快速傅立叶变换。
减法合成
减法合成是声音合成的一种方法,其中音频信号的一部分(通常一个富含谐波)被滤波器衰减以改变声音的音色。 尽管减法合成可以应用于任何源音频信号,但与该技术最相关的声音是1960年代和1970年代的模拟合成器,其中,简单的谐波(例如锯齿波,脉冲或方波)通过压控谐振低通滤波器衰减。 许多数字,虚拟模拟和软件合成器使用减法合成,有时与声音合成的其他方法结合使用。
振荡器
此处描述的波形中只有三个,锯齿形,正方形和三角形,用于振荡器输出。 在调制部分,所有这五个都用于低频振荡器。 振荡器的输入是以赫兹(Hz)为单位的频率,该频率是在一秒钟内波形完全重复的次数。 下面描述的所有波形及其频谱的基本频率均为100 Hz,并以44.1 kHz的采样率执行。
这些数字都是使用Faber Acoustical的SignalSuite和SignalScope软件制作的。
锯齿振荡器具有全套谐波。
三角波振荡器再次仅具有奇数次谐波,但是它们的衰变速率比方波中快得多。
有趣的知识:
第一个波形是斜波而不是锯齿波,但是,它们的频谱相同,因为波形之间只有180度的相移。
22 kHz处的频谱折叠/混叠是Shannon / Nyquist采样定理的伪影,不会使全部或奇数次谐波的频谱内容无效。
滤波器
它通常是一个低通滤波器,它会急剧衰减高于其截止频率的频率,而使低于此频率的频率保持不变。
滤波器特点:
截止频率以上的信号衰减大
有关截止频率的信号发生共振或加重
滤波器斜率(Q)表示衰减率,通常以-dBV /倍频程表示
注意,截止频率通常被认为是发生低于主平坦响应的-3dBV衰减的点。
不常使用其他类型的滤波器,包括“完全如他们所说的那样”的高通,带通和带阻滤波器。 所有的通滤波器都不会衰减频率,但是会引起输入和输出之间的相移。
根据过滤器是否涉及将输出反馈到输入中来进一步分类:
有限脉冲响应(FIR)滤波器没有反馈
无限冲激响应(IIR)滤波器涉及反馈
放大器
放大器控制声音的最终输出电平,该电平可能会受到包络发生器和调制器的影响。
包络发生器
总体动态,声波如何累积和消逝,由放大器包络发生器控制。
它具有上面显示的四个阶段
起音阶段-从按下琴键到达到最大输出电平所需的时间
衰减阶段-达到维持水平所需的时间
延音级别—直到释放琴键为止,音符保持的音量
释放阶段-释放键后达到零输出级别的时间
并在按键开/关门的控制下被称为幅度ADSR包络发生器。
调制器
调制使用低频范围(0–30 Hz)中的低频振荡器来修改三个核心模块中的波形。 可以使用振荡器部分中的任何波形。
Python实现
该项目将开发模拟减法综合器的核心模块,并对每个模块进行音频监控,使您能够
改变振荡器和混频器的频率和波形
更改低通滤波器的截止频率和滤波器斜率
改变放大器的输出音量
改变放大器包络发生器的起伏,衰减,维持和释放
更改低频调制的速率和数量
使用数字信号处理,将进一步开发时域和频域显示,以分别显示振荡器,滤波器和放大器输出的波形和频谱内容。
合成器的图形用户界面(GUI)将在所有平台上通用的“ tkinter”工具箱中的这些小部件中构建。 如下:
在根级别的GUI中,将有支持的框架
振荡器的频率和脉冲宽度调制量将由列表菜单确定,它们之间的混合由系统颜色选择器图形元素中的鼠标位置决定
过滤器的截止和斜率将成为列表菜单项
整体音量将由滑块控制
幅度包络发生器上的ADSR设置将通过滑块
调制速率和调制量将通过列表菜单进行设置,其目的地将通过单选框(关闭,颤音或颤音)进行设置
振荡器,滤波器和放大器输出的显示将由开/关复选框控制
振荡器和混频器
插入以下Python测试程序,将其另存为“ waves.py”
其输出是锯齿波(红色),三角形(蓝色)和正方形(绿色)振荡器的单波,以重复存储在各自的“ .wav”文件中,然后输出一秒钟,然后输出其中两个或三个的混合波形,最后读回波形并按比例混合。
该代码分为五个部分,每个部分以突出显示的注释开头。
第一部分给出了一些pyplot命令的示例,这些命令用于绘制振荡器的波形。 plt.plot后跟该行的x和y坐标的两个数组。 如果仅给出一个数组,则假定为y坐标。 后面的字符串给出了线条的颜色和外观,并可选地跟随着描述线条宽度的参数。 输出仅在调用plt.show()函数之后显示。 这将显示三个振荡器中每个振荡器的单个波形。
第二部分构造了这些波形,将其重复freqNote时间并将其输出写入“ .wav”文件。 没有理由为什么采样频率freqSamp必须与回放频率相同,但是这样做避免了麻烦的插值例程。 使用44100 Hz的CD采样频率,从而使Nyquist的频率为22050 Hz,刚好高于人类的听觉范围。 44100 =23572 具有79个因数(请参阅http://factornumber.com/?page= 44100),可以为频率选择整数分解,并具有偶数个重复次数,从而可以构造平方和 三角波形。 这些频率是
allowFreqs=[22050,11025,7350,4410,3675,3150,2450,2205,1575,1470,1225,1050,882,735,630,525,490,450,441,350,315,294,245,225,210,180,175,150,147,126,105,98,90,75,70,63,60,50,45,42,35,30]
因此覆盖了人类30 Hz→20 kHz的频率范围。 linspace在多个点的范围内执行线性插值,其中False表示不包括端点。 变量test1说明了该操作。 append连接两个数组以形成一个更长的数组。 变量test2说明了该操作。 首先使用numRpts形成一个副本,然后附加freqNote副本以形成一秒钟音符,从而构建波形。 对于方波和三角波,第一阶段必须将两个半波附加在一起。 最后,使用所构建的波形数据,以freqSamp的速率将其放入“ .wav”文件中。显然这里有很多重复,将在最终代码中剔除。
锯齿波,方波和三角波的Audacity显示如下所示:
第三部分显示如何将波形成对混合并对其进行归一化,然后再将其绘出。 锯齿波和方波,方波和三角波以及锯齿波和三角形波形的混合后的Audacity显示如下所示:
第四和第五部分显示所有三个波形的均等和比例混合,以及如何读取“ .wav”文件。 下图显示了等比例混合的Audacity显示,并演示了仅通过单独混合即可实现的音色变化。
低通滤波
滤波器用于去除信号中不需要的部分,例如高次谐波,而其余部分则保持不变。 在一系列时间步长上取平均值的滤波器为低通滤波器提供了基础。 这可以有两种形式,其中x(n)和y(n)分别是时间n的输入和输出
有限脉冲响应(FIR),其中输出纯粹是输入的函数。 一个简单的例子是移动窗口平均滤波器,例如y(n)=15i=04x(n-i)
无限冲激响应(IIR)是输入和输出先前值的反馈的函数。 一个简单的例子是alpha过滤器y(n)=x(n)+(1-)y(n-1)
插入以下Python测试程序,将其另存为'alpha.py
该代码分为四个部分,每个部分以突出显示的注释开头。
第一部分读取原始三个振荡器的未混合副本
第二部分通过假设y(-1)= 0,为过滤后的输出分配数组空间,为过滤器设置alpha并设置初始输出。
第三部分是阿alpha滤波器,y(n)=α·x(n)+(1 −α)·y(n −1)。
最后一部分写出过滤后的值,将它们打印出来以进行比较。 尽管Alpha滤波器是用于执行锁孔手术的钝器,但它已“舍入”了如下所示的锯齿形,方形和三角形波形中的尖角。 如三角形频谱所示,滤波器截止频率约为6000 Hz。 这种组合效果产生的声音比原始声音更柔和,更温暖,更暗。 最终代码中将使用scipy.signal软件包中的更精细的过滤器。
实现巴特沃思低通滤波器
作为更精细控制的示例,可以实现一个截止频率为5000 Hz的十二阶Butterworth滤波器,将其保存为“ butter.py”
5个红色字体行说明:
奈奎斯特频率是采样率的一半
对于数字滤波器,归一化为[0,1],其中1是奈奎斯特频率
巴特沃思设计返回IIR滤波器的分子(b)和分母(a)多项式的元组
计算滤波器的初始状态
根据给定的设计和初始条件执行滤波
对于每种新的滤波器类型(例如scipy.signal.cheby1),需要执行最后三个阶段
该滤波器的Audacity频谱在截止处呈现出尖锐的“肩”形,应与上面的alpha滤波器进行比较。
振幅包络产生
乐器声音随时间的动态变化由振幅包络发生器控制。
插入以下Python测试程序,将其另存为“ ADSR.py”
该代码分为三个部分,每个部分以突出显示的注释为标题。
第一部分读取未混合振荡器的滤波版本,并将时间标准设置为一毫秒。
第二部分设置每个包络分量的持续时间和输出持续水平。
第三部分使用linspace内插包络的四个部分,之后使用append将它们连接在一起。 然后,将这个包络乘以波形以说明正和负段。 下面显示了经过滤波的锯齿波,方波和三角波的输出文件。
低频振荡器和调制
低频振荡器(LFO)以次频率(0 Hz→30 Hz)工作产生信号来调制三个主要模块之一,即电压控制振荡器,滤波器和放大器(VCO,VCF和VCA)。 频率采样率为44100 Hz时,允许以Hz为单位的以下任何频率。
allowMods=[30,25,21,18,15,14,10,9,7,6,5,3,2,1]
插入以下Python测试程序,将其另存为“ sinemod.py”。
上述代码标注两处红字字体行。
除不使用线性空间和手动内插正弦波外,第一部分的组装过程与以前相同。 其他调制波形,如锯齿,锯齿,正方形和三角形都可以用如上所述的linspace制成。
第二部分将振幅调制(AM)应用于VCA以产生颤音。
图示为应用于已滤波和包络三角波的5 Hz正弦波和颤音。
分析显示
分析显示将允许显示单个波形(在时域中)及其谐波,频谱含量(在频域中)。
插入以下Python测试程序,将其另存为“ display.py”。
该代码很简单,但是突出了几个重要的新概念:
scipy.fftpack包含有效执行从时域到频域的离散傅立叶变换的函数。 此变换使用快速傅立叶变换(FFT)。
plt.ion在IPython窗口中键入%matplotlib来设置交互式图形。
接下来的三行在一个图形中设置了多个子图
下一行使用数组切片绘制单个波形
最后两行使用比例为[0,1]的实际FFT产生频率显示
最终显示带有用于平移和缩放的交互式控件,如下图:
GUI
混频器将通过VCO框架内的按钮调用。 输入以下代码并保存为“ mixer.py”
颜色作为嵌套元组处理。 请注意,该程序包含在root.mainloop()GUI事件循环中,必须通过退出Spyder使其停止。
混频器按钮将调用此调色板,以按比例混合锯齿(红色),三角形(蓝色)和正方形(绿色)振荡器。 以下是苹果电脑上GUI显示示例。
因此,项目Python代码是上述小节的组合,并进行了适当的修改以适应GUI。 各个部分将封装在函数中,声音文件数据是它们之间主要使用的参数。 它开发了合成器,VCO,VCF和VCA的三个主要功能单元,以及两个辅助单元AEG和LFO,以及显示和声音存储功能。
Python代码
输入以下代码并保存为‘main3.py’:
振荡器和混频器
在VCO内,振荡器(锯齿形,正方形和三角形)提供声音生成功能,混频器将混频器组合成单个声音数据以进行进一步处理
输入音符,混频器的频率,输出混合振荡器的声音数据:
输入以下代码并保存为‘main3.py’:
滤波器
VCF是合成器内的主要声音整形器,其频率取决于滤波器的阶数,以衰减截止频率以上的频率
输入声音数据,巴特沃斯滤波器的截止频率和阶数,输出滤波后的声音数据
输入以下代码并保存为‘main3.py’
幅度包络发生器(AEG)
AEG根据包络线控制合成器声音的整体动力学。
输入声音数据,“起音”,“衰减”,“持续”和“释放”值,输出动态成形的声音数据
输入以下代码并保存为‘main3.py’
调制器
低频振荡器(LFO)允许通过低频波形调制声音。
输入声音数据,LFO频率和深度,输出调制声音数据
输入以下代码并保存为‘main3.py’
放大器
VCA控制声音输出的整体音量。
输入声音数据,音量水平,输出放大的声音数据
输入以下代码并保存为‘main3.py’
显示和输出
时间(以样本数为单位)和频率(以Hz为单位)可以从VCO,VCF或VCA的声音数据生成显示,然后将该声音数据存储在文件中。
输入声音数据,输出文件输出无。
输入以下代码并保存为‘main3.py’
用户界面
完整的合成器只需要以嵌套方式调用上述函数即可,如下所示:
带有或不带有默认参数值。 根据要监视的输出,可以在VCO,VCF或VCA之前插入显示屏。 完整的GUI需要上述小部件以及Mixer GUI支持功能
在ipython控制台中使用默认值和%matplotlib,结果是:
其中放大每条主要频谱线的幅度显示了5 Hz LFO调制的效果,并且可能也是在没有窗口功能的情况下执行实际FFT的伪像。 谐波(谱线)的不同高度反映了锯齿波,方波和三角波的混合。
然后,您可以做的是在VCA和VCO最外部功能之间以任意顺序混合使用不同的组合和多个VCF,AEG和LFO。所有这些都来自非常简单的综合功能。
Last updated