繁体   English   中英

从头开始创建 DSP 系统

[英]Creating a DSP system from scratch

我喜欢电子音乐,我对它的节奏很感兴趣。 我在可用于播放音频、过滤器等的库上的 Stack Overflow 上发现了很多有用的问题。但我真正好奇的是实际情况如何:数据是如何在效果器和振荡器之间传递的? 我已经对 dsp 的数学方面进行了研究,我已经解决了这个问题,但我不确定要使用什么缓冲系统等。最终目标是有一个简单的 object 效果和振荡器层次结构传递数据彼此之间(如果我最终没有拔出所有头发试图实现它,可能会使用多线程)。 它不会成为下一个 Propellerhead 原因,但我对它的工作原理很感兴趣,这更像是一种练习,而不是最终产品。

目前我使用 .net 和 C# 并且我最近学习了 F# (这可能会或可能不会导致一些有趣的方法来处理数据)但如果有必要,我可以学习另一个不适合工作的系统。

问题是:使用缓冲区通过程序获取大量信号数据的最佳方法是什么? 例如,使用队列、数组、链表等会更好吗? 每次我对系统应用效果时,我应该使样本不可变并创建一组新数据,还是只编辑缓冲区中的值? 我应该有一个调度程序/线程池样式 object 来组织传递数据,还是效果函数应该直接在彼此之间传递数据?

谢谢。

编辑:另一个相关的问题是我将如何使用 windows API 来播放这个数组? 我真的不想使用 DirectShow,因为微软现在几乎让它死了

EDIT2:感谢所有答案。 在查看了所有技术之后,我将使用 XNA 4(我花了一段时间在互联网上搜索并找到了解释如何操作的网站)或 NAudio 到 output 音乐......不确定哪一个,取决于有多先进系统最终成为。 当 C# 5.0 发布时,我将使用它的异步功能在此基础上创建效果架构。 我几乎平等地使用了每个人的答案,所以现在我有一个难题,谁应该给予赏金......

你看过 VST.NET (http://vstnet.codeplex.com/) 吗? 这是一个使用 C# 编写 VST 的库,它有一些示例。 您还可以考虑编写 VST,以便可以从任何主机应用程序使用您的代码(但即使您不想要,查看他们的代码也很有用)。

信号数据通常很大,需要大量处理。 不要使用链表,我知道的大多数库只是使用数组来放置所有音频数据(毕竟。这就是声卡所期望的)。

来自 VST.NET 示例:

    public override void Process(VstAudioBuffer[] inChannels, VstAudioBuffer[] outChannels)
    {
        VstAudioBuffer audioChannel = outChannels[0];

        for (int n = 0; n < audioChannel.SampleCount; n++)
        {
            audioChannel[n] = Delay.ProcessSample(inChannels[0][n]);
        }
    }

audioChannel 是一个非托管 float* 缓冲区的包装器。

您可能将样本存储在不可变数组中。 然后,当您想播放它们时,您复制 output 缓冲区中的数据(如果需要,更改频率)并在此缓冲区中执行效果。 请注意,您可以使用多个 output 缓冲区(或通道)并在最后对它们求和。

编辑

我知道播放阵列的两种低级方法:来自 Windows API 的 DirectSound 和 WaveOut。 C# 使用 DirectSound 的示例 C# 示例与 WaveOut 但是,您可能更喜欢使用外部更高级别的库,例如NAudio NAudio 便于 .NET 音频操作 - 请参阅此博客文章以向声卡发送正弦波。 你可以看到他们也在使用一个浮点数组,这是我推荐的(如果你使用字节进行计算,你最终会在声音中产生很多混叠)。

F# 在这里可能是一个不错的选择,因为它非常适合操作函数。 函数可能是信号创建和处理的良好构建块。

F# 通常也擅长操纵 collections,尤其是 arrays,这要归功于 Array 模块中的高阶函数。

这些品质使 F# 在金融领域很受欢迎,我猜对信号处理也很有用。

Visual F# 2010 for Technical Computing有一个专门介绍傅里叶变换的部分,这可能与您想做的事情相关。 不过,我想网上有很多关于转换的免费信息。

最后,要播放样本,您可以使用XNA 我认为API(4.0)的最新版本也允许录制,但我从未使用过。 Xbox 上有一个著名的音乐编辑应用程序,名为ezmuse+ Hamst3r Edition ,它使用 XNA,所以这绝对是可能的。

关于缓冲和异步/线程/同步问题,我建议您查看新的 TPL 数据流库。 凭借其块原语、并发数据结构、数据流网络、异步消息处理和 TPL 基于任务的抽象(可与 async/await C# 5 功能一起使用),它非常适合此类应用程序。

我不知道这是否真的是你想要的,但这是我在大学时的个人项目之一。 在我自己实现之前,我并没有真正理解声音和 DSP 是如何工作的。 我试图尽可能靠近扬声器,所以我只使用 libsndfile 来为我处理复杂的文件格式。

基本上,我的第一个项目是创建一个大型双精度数组,用正弦波填充它,然后使用 sf_writef_double() 将该数组写入文件以创建可以播放的内容,并在波形编辑器中查看结果。

接下来,我在 sine 调用和 write 调用之间添加了另一个 function 以添加效果。

这样您就可以开始使用非常低电平的振荡器和效果器,并且可以立即看到结果。 另外,只需很少的代码就可以让这样的东西工作。

就个人而言,我会从最简单的解决方案开始,然后慢慢添加。 尝试只写出一个文件并使用您的音频播放器播放它,这样您就不必处理音频 api。 只需使用单个数组即可启动并就地修改。 绝对从单线程开始。 随着项目的发展,您可以开始转向其他解决方案,例如管道而不是阵列、多线程处理或使用音频 API。

如果您想创建一个可以发布的项目,具体取决于它的具体内容,您可能必须转向更复杂的库,例如一些实时音频处理。 但是,当您达到这一点时,通过上述简单方法学习的基础知识肯定会有所帮助。

祝你好运!

我已经做了很多实时 DSP,虽然没有音频。 虽然您的任何一个想法(不可变缓冲区)与(已修改的可变缓冲区)都可以工作,但我更喜欢为信号路径中的每个链接创建一个永久缓冲区。 大多数效果不适合就地修改,因为每个输入样本都会影响多个 output 样本。 当您有重采样阶段时,每个链接的缓冲区技术特别有效。

在这里,当样本到达时,第一个缓冲区被覆盖。 然后第一个过滤器从它的输入缓冲区(第一个缓冲区)读取新数据并写入它的 output(第二个缓冲区)。 然后它调用第二个阶段从第二个缓冲区读取并写入第三个缓冲区。

这种模式完全消除了动态分配,允许每个阶段保留可变数量的历史(因为效果需要一些内存),并且在重新排列路径中的过滤器方面非常灵活。

好吧,那我也试试赏金吧:)

我实际上处于非常相似的情况。 我制作电子音乐已经很久了,但只是在过去的几年里,我才开始探索实际的音频处理。

你提到你研究过数学。 我认为这很关键。 我目前正在努力通过 Ken Steiglitz 的数字信号处理入门 - 应用到数字音频和计算机音乐。 如果您不知道复数和相量,那将非常困难。

我是 Linux 人,所以我开始在 C 中编写 LADSPA 插件。 我认为从基本层面开始,真正了解正在发生的事情是很好的。 如果我在 Windows 上,我会从 Steinberg 下载 VST SDK 并编写一个概念插件的快速证明,它只会增加噪音或其他任何东西。

选择 VST 或 LADSPA 等框架的另一个好处是,您可以立即在普通音频套件中使用插件。 将您的第一个自制插件应用于音轨的满足感是无与伦比的。 另外,您将能够与其他音乐家分享您的插件。

在 C#/F# 中可能有一些方法可以做到这一点,但如果你打算编写 VST 插件,我会推荐 C++,以避免任何不必要的开销。 这似乎是行业标准。

在缓冲方面,我一直在使用循环缓冲区(这里有一篇好文章: http://www.dspguide.com/ch28/2.htm )。 一个很好的练习是实现一个有限响应滤波器(Steiglitz 将其称为前馈滤波器)——它们依赖于缓冲并且玩起来很有趣。

我有一个关于 Github 的仓库,里面有一些非常基本的 LADSPA 插件。 除了架构差异之外,它们也可能对编写 VST 插件的人有用。 https://github.com/andreasjansson/my_ladspa_plugins

另一个很好的示例代码来源是 CSound 项目。 那里有大量的 DSP 代码,该软件主要针对音乐家。

你可以看看BYOND 它是 C# 中用于程序化音频/midi 乐器和效果创建的环境。 它可以独立使用,也可以作为 VST 乐器和效果器使用。

完全披露我是 BYOND 的开发者。

从阅读thisthis开始。

这会让你知道你必须做什么。

然后,学习 DirectShow 架构 - 并学习如何不这样做,而是尝试创建它的简化版本。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM