3

是否有一种众所周知的合成弓弦乐器(例如小提琴)的算法?

我知道弹拨弦(例如吉他)有 karplus-strong 算法,我在过去已经成功实现过。

理想情况下,我想要一个描述用于生成/合成数字信号的计算机程序的算法。

例如,karplus-strong 算法可以总结如下:

  • 确定您要合成的频率的周期长度,并创建一个完全符合该大小的缓冲区

  • 用随机数填充缓冲区(白噪声)

  • 遍历缓冲区,每次平均每个点与下一个点,然后将其输出到输出流。

  • 重复所需的时间,同时应用一些阻尼

我想知道弓弦是否存在类似的东西。

脚注:

现在,我对弦如何产生声音的物理学一无所知,所以我不知道如何推导出这样的算法。对于karplus-strong算法,我只是简单的在原论文中阅读并“盲目”应用。我永远不会想到,从一阵噪音开始并不断地对其进行阻尼会产生与弹拨弦如此相似的声音。

编辑

像往常一样,近距离游行已经开始。

在投票结束此问题之前,请考虑以下事项:

  • 这个问题与物理无关。这与琴弦振动或与弓和空气相互作用产生声音的机制无关。

  • 这个问题是关于是否存在一种特定的众所周知的算法来合成声音。严格来说,这是一个关于编程的问题。

4

2 回答 2

3

奇怪的是,我能在斯坦福查克网站上找到一些关于这个的东西。

该代码是用一种名为 ChuckK 的语言编写的,该语言显然专用于音频编程。您必须运行才能使用此代码段。但这是它在chuck中的实现:

// patch
Bowed bow => dac;

// scale
[0, 2, 4, 7, 8, 11] @=> int scale[];

// infinite time loop
while( true )
{
    // set
    Math.random2f( 0, 1 ) => bow.bowPressure;
    Math.random2f( 0, 1 ) => bow.bowPosition;
    Math.random2f( 0, 12 ) => bow.vibratoFreq;
    Math.random2f( 0, 1 ) => bow.vibratoGain;
    Math.random2f( 0, 1 ) => bow.volume;

    // print
    <<< "---", "" >>>;
    <<< "bow pressure:", bow.bowPressure() >>>;
    <<< "bow position:", bow.bowPosition() >>>;
    <<< "vibrato freq:", bow.vibratoFreq() >>>;
    <<< "vibrato gain:", bow.vibratoGain() >>>;
    <<< "volume:", bow.volume() >>>;

    // set freq
    scale[Math.random2(0,scale.size()-1)] + 57 => Std.mtof => bow.freq;
    // go
    .8 => bow.noteOn;

    // advance time
    Math.random2f(.8, 2)::second => now;
}

编辑:以上只是实现,它的源文件在这里。

于 2021-11-29T00:24:07.180 回答
0

不是算法,但有一个开源库(在非常自由的许可下),它在 C++ 中为多种乐器实现合成算法,包括弓弦。

综合工具包 (STK)

官方主页:https ://ccrma.stanford.edu/software/stk/

Github 链接:https ://github.com/thestk/stk

带有与弓弦乐器合成相关的代码的文件:

代码中的注释引用了两篇论文:

Julius Smith 在他的(斯坦福)网站上也有关于弓弦合成的信息:

“物理音频信号处理”一书中的弓弦部分

MUS420 Lecture 弓弦的数字波导建模

于 2021-12-08T15:21:54.833 回答