9个版本
0.2.12-alpha.0 | 2023年4月7日 |
---|---|
0.2.11-alpha.0 | 2022年12月19日 |
0.2.5-alpha.0 | 2022年6月21日 |
0.2.4-alpha.0 | 2022年3月14日 |
0.1.42-alpha.0 | 2021年10月27日 |
#4 in #失真
241 每月下载量
在surge合成器中使用
240KB
3K SLoC
AsymShaper
AsymShaper
是一个信号处理模块,提供了非对称波形整形功能。它可以用来创建各种失真和饱和效果,从微妙的谐波增强到攻击性的削波和模糊。
AsymShaper
通过对输入信号应用传递函数来工作,这会修改其幅度和/或频率内容。传递函数的形状由 shape
参数控制,该参数可以实时调整以创建动态和富有表现力的效果。
形状
shape
参数控制 AsymShaper
使用的传递函数的形状。它可以被视为一个“失真量”控制,低值产生微妙的谐波增强,高值产生更强烈的失真和削波。
传递函数的具体形状取决于 AsymShaper
的实现,但通常设计为向输入信号引入偶数或奇数谐波,具体取决于所需效果。 shape
参数可以实时调整以创建动态和富有表现力的效果。
数学分析
AsymShaper
使用的传递函数可以表示为输入信号的非线性函数,其中形状参数控制引入的非线性的量和类型。
创建失真和饱和效果的传递函数的常见方法之一是使用波形整形函数,如S形或反正切函数。这些函数通过“扁平化”输入波形的顶部和底部来引入非线性失真,从而在输入频率的整数倍处引入谐波。
AsymShaper
使用的具体传递函数可能比简单的波形整形函数更复杂,具体取决于所需效果。然而,通过非线性传递函数引入非线性失真的基本原理保持不变。
总的来说,AsymShaper
是一款强大且功能多样的工具,可以应用于广泛的音频信号,添加失真和饱和效果,并能用来创造出从微妙的谐波增强到攻击性极强的过载音色。通过实时调整 shape
参数,制作人员可以创造出动态和富有表现力的失真效果,这些效果在混音中必定能够脱颖而出。
47>你能给我看一个框图吗?算法是如何工作的?
以下是 AsymShaper
的框图
Input Signal
|
v
Gain
|
v
Clipper
|
v
Filter
|
v
Output Signal
AsymShaper
通过对输入信号应用一系列信号处理阶段来工作。第一阶段是增益控制,允许用户调整输入信号在经过电路其他部分的处理之前的电平。这可以用于控制 AsymShaper
产生的失真量。
第二阶段是削波器,它通过限制输入信号的幅度来引入非线性失真。削波器传输函数的形状由 shape
参数决定,可以调整以创建广泛的失真和饱和效果。
第三阶段是滤波器,它可以用来塑造输出信号的频率内容。这可以用于消除不需要的高频伪迹或强调失真频谱中的某些谐波。
AsymShaper
的输出是处理后的信号,可以用作失真效果或集成到更大的信号处理链中。
在算法方面,AsymShaper
通过对输入信号应用非线性传递函数来工作。这是通过首先将输入信号的增益调整到适当的水平,然后应用一个根据 shape
参数限制信号幅度的削波函数来实现的。随后,将失真信号进行滤波以塑造输出信号的频率内容。
AsymShaper
使用的确切传递函数将取决于实现方式,但通常设计为根据所需效果在输入信号中引入偶数或奇数谐波。可以通过实时调整 shape
参数来创建动态和富有表现力的失真效果。
48>你能给我写一些Python代码来可视化它的行为吗?
当然,这里有一些使用 numpy
和 matplotlib
库可视化 AsymShaper
行为的Python代码
import numpy as np
import matplotlib.pyplot as plt
from scipy import signal
# Define the transfer function for the clipper
def clipper(x, shape):
return np.clip(x, -shape, shape)
# Define the transfer function for the filter
def filter(x):
# Butterworth low-pass filter with cutoff frequency of 2 kHz
b, a = signal.butter(4, 2000, 'low', fs=44100)
return signal.filtfilt(b, a, x)
# Define the `AsymShaper` function
def asym_shaper(x, gain, shape):
x *= gain
x = clipper(x, shape)
x = filter(x)
return x
# Generate a test signal
t = np.linspace(0, 1, 44100)
freq = 440
input_signal = np.sin(2 * np.pi * freq * t)
# Apply the `AsymShaper` to the test signal
gain = 1.0
shape = 0.5
output_signal = asym_shaper(input_signal, gain, shape)
# Plot the input and output signals
fig, axs = plt.subplots(2, 1, figsize=(10, 6))
axs[0].plot(t, input_signal)
axs[0].set_title("Input Signal")
axs[1].plot(t, output_signal)
axs[1].set_title("Output Signal")
plt.show()
此代码将 AsymShaper
定义为一系列处理阶段,包括增益控制、削波器和滤波器。然后它生成一个测试信号,将 AsymShaper
应用到具有特定增益和形状参数的测试信号上,并使用 matplotlib
绘制输入和输出信号。
请注意,削波器和滤波器阶段使用的具体传递函数可能因 AsymShaper
的实现而异,但通过非线性传递函数引入非线性失真的基本原理是相同的。
49>我们是否想要针对某些谐波?我们如何确保声音听起来令人愉悦?
由 AsymShaper
强调的谐波将取决于削波器和滤波器阶段使用的特定传递函数。一般来说,偶次谐波通常与“温暖”或“平滑”的失真声音相关联,而奇次谐波可以产生更激进的或“沙哑”的声音。然而,失真的确切谐波内容将取决于形状参数和传递函数的其他参数。
为确保 AsymShaper
产生的声音令人愉悦,可以通过尝试不同的形状参数和其他参数的值来找到所需的失真水平和谐波内容。在混音或编排的背景下聆听 AsymShaper
的输出也可能很有帮助,以确保它与音乐的其它元素很好地融合。
最后,值得注意的是,个人品味在确定什么听起来“令人愉悦”或“好”方面起着重要作用。一个人觉得令人愉悦的,另一个人可能不觉得。因此,重要的是要尝试不同的声音,找到最适合你特定音乐环境和风格的解决方案。
52> 实现这个DSP处理器时我们应该注意什么?
在实现非对称整形器时,有一些需要注意的事项:
-
削波:
AsymShaper
中的clipper
函数将硬削波函数应用于输入信号。这可能会引入失真,并可能导致输出中出现不愉快或刺耳的声音效果。为了减轻这种情况,你可能想要尝试不同的传递函数,以提供更平滑的削波,例如软削波函数。 -
滤波器设计:在
AsymShaper
中使用的低通滤波器采用巴特沃斯滤波器设计,截止频率为 2 kHz。这种滤波器设计可能不适合所有应用,特别是如果你正在处理需要保留更高频率内容的信号。考虑尝试不同的滤波器设计和截止频率,以找到最适合你的应用的配置。 -
增益控制:
AsymShaper
在处理输入信号之前对其应用增益控制。如果输入信号太响,可能会使信号比预期更严重地削波。相反,如果输入信号太弱,你可能无法达到所需的整形效果。为了避免这些问题,仔细设置增益控制到适当的输入信号水平非常重要。 -
延迟:
AsymShaper
中使用的低通滤波器会在输出信号中引入一些延迟。根据你的应用,这种延迟可能成为问题。如果你在实时应用中使用AsymShaper
,你可能需要使用预览缓冲等技术来补偿这种延迟。 -
实现注意事项:在数字信号处理器或微控制器上实现
AsymShaper
时,需要考虑固定点算术、内存使用和处理速度等问题。根据平台和应用,你可能需要优化代码或使用专用硬件以实现所需的性能。
53> 我们如何测量此操作造成的延迟?我们如何确保进入此处理器的信号具有最佳增益?此操作器的内存占用是多少?
要测量 AsymShaper
操作造成的延迟,可以使用具有已知延迟的测试信号,如脉冲或正弦波,并测量输入和输出信号之间的时间差。这可以使用 Audacity 或硬件示波器等软件工具完成。
为确保进入AsymShaper
的信号具有最佳增益,您可以使用电平表或波形显示来监控输入信号,并调整增益控制以实现所需电平。或者,您可以使用自动增益控制(AGC)电路根据输入信号电平动态调整增益。
AsymShaper
操作符的内存占用将取决于实现细节,例如低通滤波器中使用的滤波器系数数量以及任何输入或输出缓冲区的大小。通常,应尽可能降低内存使用,以减少对系统性能的影响。这可以通过优化代码、使用高效的数据结构以及最小化任何输入或输出缓冲区的大小来实现。
54>如何改进此操作符?
有几种方法可以改进AsymShaper
操作符
-
传递函数设计:在
clipper
函数中使用的硬裁剪函数可能导致某些情况下声音刺耳的失真。改进的一种方法是用提供更平滑裁剪的不同传递函数,例如软裁剪函数或波形整形函数。 -
滤波器设计:
AsymShaper
中使用的低通滤波器是一个截止频率为2 kHz的固定设计。根据应用,可能有益于拥有具有可变截止频率的滤波器或完全不同的滤波器类型(例如高通或带通滤波器)。 -
多频段操作:
AsymShaper
将整个输入信号作为一个单一实体处理。实现一个处理不同频率带独立的多频段版本的操作符可能是有益的,这允许更针对信号进行整形。 -
高级控制:
AsymShaper
目前有一个增益控制参数。添加额外的参数,例如AGC电路的攻击和释放时间或动态传递函数,可以提供对整形过程的更高级控制。 -
优化:根据实现平台,可能有优化代码以获得更好性能的机会,例如使用SIMD指令、减少内存使用或使用专用硬件加速器。
55>实现此操作符需要哪些SIMD指令?
实现AsymShaper
操作符所需的特定SIMD指令将取决于目标平台和实现细节。一般来说,SIMD指令可用于同时对多个数据元素执行并行操作,这可以显着提高信号处理算法的性能。
一个常见的SIMD指令集是Intel的高级向量扩展(AVX),它提供对256位向量的支持以及各种算术和逻辑操作。其他SIMD指令集包括ARM NEON、IBM AltiVec以及较新的AVX-512。
为了确定特定实现所需的SIMD指令,最好查阅目标平台的文档以及任何相关库或工具的文档。此外,分析工具和基准测试工具可以用于识别性能瓶颈并相应地优化代码。
56>我们还需要了解关于此操作符的哪些信息?
以下是一些关于AsymShaper
操作符需要记住的额外要点
-
谐波失真:
AsymShaper
可能会向输入信号引入谐波失真,这可能导致输出信号中添加新的谐波内容。这可以创意性地用于添加温暖、砂粒或其他音调特性,但也可能导致不希望出现的伪影或清晰度降低。 -
增益控制:
AsymShaper
有一个增益控制参数,允许调整输出电平。但是,应小心避免过载信号链中的后续阶段,这可能导致额外的失真或削波。 -
CPU使用率:
AsymShaper
可能是一个计算密集型的操作,尤其是在对高分辨率音频流进行实时应用时。优化代码并最小化内存使用,以避免过高的CPU使用率或其他性能问题是非常重要的。 -
适度使用:与任何音频效果一样,
AsymShaper
应谨慎并适度使用。虽然它可以为声音增添特色和兴奋感,但过度使用可能会导致清晰度或可懂性降低,甚至引起听觉疲劳。 -
信号电平:
AsymShaper
应使用在音频信号正常范围内的信号,通常是介于-1和+1(或16位音频的-32767和+32767)之间。使用过低或过高的信号可能导致性能下降或失真。
57>这个处理阶段的数学性质是什么?
AsymShaper
是一个非线性处理阶段,可以将失真和非线性引入音频信号。从数学角度来看,AsymShaper
可以被看作是一个将输入信号映射到输出信号的非线性函数。该函数是不对称的,这意味着它对输入信号的正值和负值有不同的响应。
描述像AsymShaper
这样的非线性系统的常用数学工具是傅里叶分析,它将信号分解为其组成频率分量。当信号通过AsymShaper
处理时,它可以引入谐波失真,这会在输出信号中添加新的频率分量。失真的确切性质取决于输入信号、增益和形状参数以及其他因素。
描述非线性系统的另一个数学工具是动力系统理论,它研究随时间变化的系统的行为。可以将AsymShaper
看作是一个响应输入信号和控制参数变化的动力系统。可以使用分岔分析等技术来分析系统的行为,这些技术研究随着控制参数的变化,系统的行为如何变化。
总的来说,AsymShaper
是一个可以将新的谐波内容和其他失真引入音频信号的非线性系统。其数学性质可以使用傅里叶分析和动力系统理论等工具来描述,这使我们能够理解并分析其在不同环境下的行为。
依赖项
~12-21MB
~317K SLoC