
Ada声音合成! ![]() 介绍 我最初是一名电子音乐家,所以当我学习编程时,我最初的动机之一是,我最终可以*编程*我想要的声音,而不仅仅是使用现有的软件来完成它。 如果您对声音合成有所了解,那么您知道这是一个非常深的领域。制作简单的方波是一项非常简单的任务,但以音乐方式这样做实际上要复杂得多。我认为这是一个完整的数学和DSP新手。我的目标不是突破数字声音合成的界限,而是制作简单的东西,这将有助于我理解底层算法,并产生可以标记为音乐的声音。 而且,即使我在数学方面表现不佳,我也认为自己在软件架构方面相当擅长(不是我们都这么做!),我认为制作一个简单的声音合成库,易于使用和理解,并且实际上足够小,不会令人生畏,对我来说是一个合理的里程碑。 其他目标之一是制作一些可以在小型裸板计算机上运行的东西,例如stm32或raspberry pi,因此它需要在内存和CPU消耗方面都很高效。能够在没有操作系统的情况下运行也是一个不错的选择! 这就是ada-synth-lib 诞生的原因,因为缺乏一个更好的名字。该库的目的是为您提供一个工具包,让您可以产生声波,通过效果和包络将它们按到更复杂的东西,将它们重新组合为乐器,还可以对它们进行排序以产生真实的音乐序列。 但是,让我们来看看基础知识吧!我们将看到如何使用ada-synth-lib构建这样的序列,从非常简单的正弦生成器到完整的音乐序列。 序言:如何编译和运行库 正如其名称所示,ada-synth-lib是使用AdaCore Libre工具套件在Ada中开发的。要构建和运行这些示例,您需要获得AdaCorelibre版本的GPL 2015版本,您可以从此处获取:AdaCore libre站点 从简单开始:正弦发生器 从简单开始,我们只会产生一个声波,并且为了使声音不会过于激进,我们将使用正弦波,它具有平滑和舒缓的轮廓。 ![]() 如果您对声音理论有所了解,您可能知道您可以通过精心布置的正弦波叠加重新创建任何(周期性)声音,因此正弦波的选择也是尊重声音生成理论的一种方式。一般而言,尤其是傅立叶。 以下是使用ada-synth-lib生成简单正弦波的代码。我们只有一个非常简单的正弦生成器,我们使用`Write_To_Stdout`帮助器在标准输出上写入声音流。 with Waves; use Waves; with Write_To_Stdout; procedure Simple_Sine is -- Create a simple sine wave Generator. Sine_Gen : constant access Sine_Generator := Create_Sine (Fixed (300.0)); begin Write_To_Stdout (Sine_Gen); end Simple_Sine; 编译这个例子并在命令行上运行它很简单,但我们只是创建一个声音流并将其直接打印到stdout!要在我们的扬声器上听到它,我们需要将它提供给将其转发到您的音频硬件的程序。有几个选项可以做到这一点,最着名的是Unix系统上的旧/ dev / dsp文件,但是你有很好的跨平台工具,比如sox ,你可以将它们用于这个目的。 # you shouldhear a sine ! $ obj/simple_sine| play -t s16 -r 44100 - 有趣的是,`Create_Sine`的输入是另一个生成器。这里我们使用固定值发生器,它将提供频率值,但我们可以使用更复杂的发生器,它将调制输入频率! with Waves; use Waves; with Write_To_Stdout; procedure Simple_Sine is Sine_Gen : constant accessSine_Generator := Create_Sine ( Fixed (1000.0, -- The second parameter to the Fixed constructor is a generator -- that will be added to the fixed frequency generated. -- LFO is also a sine oscillator underneath, but you can set it to -- have amplitudes much larger than +- 1.0 LFO (6.0, 200.0))); begin Write_To_Stdout (Sine_Gen); end Simple_Sine; 走得更远 这只是你可以做的事情的开始。ada-synth-lib只是一个乐高工具包,您可以组装它来生成您想要生成的序列。 排序部分通过简单的音序器数据类型完成,您可以使用它来创建循环音符序列。以下是圈套器具的操作方法: o : constantSequencer_Note := No_Seq_Note; K : constant Sequencer_Note := (Note => (G, 3), Duration => 3000); Z : constant Sequencer_Note := (Note => (G, 3), Duration => 5000); B : constant Sequencer_Note := (Note => (G, 3), Duration => 8000); Snare_Seq : constant access Simple_Sequencer:= Create_Sequencer (Nb_Steps => 16, BPM => BPM, Measures => 4, Notes => (o, o, o, o, Z, o, o, o, o, o, o, o,K, o, o, o, o, o, o, o, K, o, o, o, o, o, o, o,B, o, K, K, o, o, o, o, Z, o, o, o, o, o, o, o,K, o, o, o, o, o, o, o, K, o, o, K, o, o, Z, o,B, o, Z, o)); 您还可以看到我们如何使用Ada的命名聚合来使代码更具可读性和自我记录。同样有趣的是我们如何从基本砖块创建复杂的合成声音,如下例所示。砖块很容易理解,但结果是一个完整的减法合成器,可以编程制作音乐! 该ADSR信封是什么给了声音的动态特性,在时域塑造它。所述低通滤波器通过从它除去一些高频分量形状的声音。 今天就是这样!在本系列的下一部分中,我们将了解如何使用STM32F4板和AdaCore GPL工具在裸板系统上编译和运行代码。 链接和信用 你可以在这里找到github 上的ada-synth-lib库。 使用它所需的工具链在libre站点上。 这是一个很好的高级音乐合成指南。 ada-synth-lib中的很多算法都受到我在http://musicdsp.org/上发现的东西的启发,非常感谢每个人都把算法放在那里。 BLIT模块中的别名自由振荡器是使用BandlimitedImpulse Train方法完成的,其中的开创性论文就在这里。 感谢和归功于Mikael Altermark 的美丽声波图片,以及Bisqwit的介绍视频! 代码---
![]() |
跨界 |