【发布时间】:2021-06-30 18:09:54
【问题描述】:
对于我的一个项目,我正在处理采样声音生成,我需要创建各种频率的各种波形。当波形是正弦时,一切都很好,但当波形是矩形时,问题就来了:听起来好像是八十年代的,随着频率的增加,音符听起来就错了。在第 8 个八度音阶上,每个音符听起来都像是来自某个较低八度音阶的随机音符。
无论我使用以下两种方法中的任何一种,不良影响都是一样的:
-
生成矩形波形的纯数学方法为
sample = sign( secondsPerHalfWave - (timeSeconds % secondsPerWave) )其中secondsPerWave = 1.0 / wavesPerSecond和secondsPerHalfWave = secondsPerWave / 2.0 -
我的首选方式是使用线段来描述波浪的一个周期并沿这些线进行插值。因此,矩形波形由在 y=1.0 处从 x=0 到 x=0.5 的水平线描述(不考虑采样率和频率),然后是在 y= 处从 x=0.5 到 x=1.0 的另一条水平线-1.0。
据我所知,文献认为这些波形生成方法“幼稚”,导致“混叠”,这是所有不良影响的原因。
当我查看生成的波形时,这一切实际上转化为每秒采样值不是每秒波形值的精确倍数,因此每个波形都没有偶数个样本,这反过来意味着1.0级的样本数往往不等于-1.0级的样本数。
我在这里找到了一个特定的解决方案:https://www.nayuki.io/page/band-limited-square-waves,它甚至包含 Java 源代码,听起来确实很棒:所有不良影响都消失了,每个音符听起来都很纯净且频率正确。但是,这个解决方案完全不适合我,因为它的计算成本非常高。 (即使我已经用比 Java 内置函数快十倍的近似值替换了 sin() 和 cos()。)此外,当我查看生成的波形时,它们看起来非常复杂,所以我想知道它们是否可以合法地称为矩形。
所以,我的问题是:
什么是最计算效率最高的方法来生成周期性波形,例如不受混叠伪影影响的矩形波形?
解决方案可能需要的示例:
-
在我看来,以离散时间间隔生成正确样本值来描述声波的计算机音频问题与在离散整数 x 坐标处生成正确整数 y 坐标以绘制线条的计算机图形问题有些相关。 Bresenham 线生成算法非常有效,(即使我们暂时忽略它正在处理整数数学的事实),它通过累积某个错误项来工作,该错误项在正确的时间会导致Y坐标。是否可以使用一些类似的机制来计算样本值?
-
采样的工作方式被理解为在特定的无限窄时间点读取模拟信号的值。也许更好的方法是考虑读取最后一个样本和当前样本之间的整个模拟信号切片的区域。这样,在矩形波形边缘之前采样 1.0 对采样值的贡献很小,而在边缘之后相当长时间采样 -1.0 会贡献很多,因此自然会产生一个介于两个极值之间的点.这能解决问题吗?这样的算法存在吗?有人试过吗?
请注意,我在这里发布了这个问题,而不是 dsp.stackexchange.com,因为我不想收到带有诸如频带限制、谐波和低通滤波器、拉格朗日插值、直流补偿等荒谬行话的答案.而且我不想要来自纯模拟世界或纯理论外太空的答案,并且没有机会使用数字计算机获得实用且有效的实现。
我是一名程序员,而不是音响工程师,在我这个小程序员的世界里,事情很简单:我有一个样本数组,它们必须都在 -1.0 和 1.0 之间,并且将以一定的速率播放 (44100每秒采样数。)我可以使用算术运算和三角函数,我可以描述线条并使用简单的线性插值,并且我需要非常有效地生成样本,因为同时生成十几个波形并将它们混合在一起消耗的 CPU 时间不得超过总 CPU 时间的 1%。
【问题讨论】:
-
由于这是一个 DSP 问题,我正准备推荐 dsp.stackexchange.com,直到我阅读了您避免它的原因。我仍然建议这是您的第一个停靠港。令人遗憾的是,社区似乎对行话有负面声誉,但是,如果你不问,你就得不到。您在这里缺少的一个关键术语是nyquist frequency,这是您获得的人工制品的来源。
-
这听起来像是同样无用的行话,但您可能想要查看的一种特定算法是 PolyBLEP 。阅读Antialiasing Oscillators in Subtractive Synthesis Published in: IEEE Signal Processing Magazine ( Volume: 24, Issue: 2, March 2007)。我可以看一下将其消化成答案,尽管在这种情况下您可能希望为您的问题添加语言标签。
-
我推荐 JUCE 论坛以及 DSP 的音乐实现 forum.juce.com
-
也感谢 IEEE 文章的链接。不幸的是,他们要 33 美元给我看。我故意避免添加语言标签,因为我不想限制问题的受众。我对 Java、C#、C++、C、Scala 甚至 Pascal 都很满意。如果你愿意,我也可以来一个 stackoverflow 聊天频道,或者交换电子邮件,我的地址是 michael at michael dot gr。非常感谢您的回复。
-
基本上任何over nyquist 都会反映导致额外伪影的原因。像完美方波这样的东西实际上是一个无限级数,所以根据定义,它不需要超过你的奈奎斯特。你可以应用一个过滤器来阻止它,只对有限数量的谐波 (resulting in gibbs) 或一些像 PolyBLEP 这样的诡计多端的游戏进行求和。奈奎斯特频率混叠应该为您产生更多结果。关于文章链接的道歉,我忘记了不是每个人都搞砸这些东西有时不是学术界。
标签: audio signal-processing sampling waveform