数字音频101:从微控制器播放音频

2021-04-15 22:35:01

音频编程世界是一个广阔而美丽的。向您的Arduino项目添加音频可以使它们非常有趣。在本文中,我们将深入研究数字音频和amp的一些基本理论;尝试在微控制器上获得简单的音乐输出。

理论&本文中描述的功能不是特定于任何微控制器或开发框架(尽管我使用带KENDRYTE-Standalone-SDK的K210开发板)&不需要任何音频特定库。

那么音频/ und是什么?在最简单的术语中,声音的感觉是由压力波动引起的空气中的振动的结果。

扬声器是一种可用于播放音频的简单设备。扬声器具有音圈,永磁体&锥。当我们通过电力通过音圈时,它充当电磁铁和amp;基于电磁铁的极性,永磁体擦除或吸引音圈。音圈连接到锥体上,因此音圈本身的任何移动使锥体向内拉动或向外推动。锥体的这种运动在其周围的空气中产生压力变化,导致它振动产生声音。这是一个过于简化的解释,但足以让我们去。

就像我们刚刚讨论过的那样,音频是我们周围空气的压力变化的结果。这些压力变化可以是空气的压缩或稀疏。扬声器通过快速移动锥体来产生这些压缩和稀疏。锥体的幅度和方向通过改变提供给语音线圈的电压(和匝数电流)而变化。

产生的空气的压力变化或传递到扬声器的音圈以产生声音的音频信号可以在基于坐标的图表中表示,如上面的图像中所示,并且称为音频波形。

最简单的音频波形本质上是正弦波,表示由正弦函数给出的恒定幅度的周期性振荡的曲线。

事实上,单个音符是通过简单的谐波运动产生的恒定频率的正弦管。作为一个例子,这里是“a”的波形:

通过添加各个组件笔记的功能,创建了许多复杂的声音。

现在让我们看看一些元素&图表的属性,了解它们如何影响波形产生的声音。

正如您在上图所示,正弦音频波形具有以下属性:

幅度 - 幅度是从参考线或原点测量波形中的点的高度。幅度的增加导致声音强度的增加。强度增加的声音被认为是更响亮的。

频率 - 正弦曲线在自然中重复。循环在一秒钟重复的次数被称为波形的频率,并且在完成一个周期的时间是波形的时段。频率在赫兹(Hz)中测量。每秒一个周期是一个赫兹。频率增加的声音具有更高的间距,而较低频率的声音具有较低的间距。人类只能听到20Hz到20,000Hz(或20 kHz)的声音。

波长波长是连续重复波形中的两个相同点之间的距离。波长与频率间接成比例。因此,更高的波长导致较低的音调声音。

有更多的属性&可以在时域中表示的音频波形上进行测量。但为了简单起见,我们将在这里停止它。

同时使用电子产品&数字信号,我们通常使用直流。直流无法切换极性。数字信号只能有两个状态(1 - 高电压)或OFF(0 - 低电压)。一些微控制器已建立在DAC(数字到模拟转换器)中,将数字信号转换为模拟输出。我们也可以依靠外部DAC来做相同但布线DAC可以在微控制器上占用多个GPIO。我们也有几个其他选择。可以使用像AD9833BRMZ这样的可编程任意波形发生器。

这再次需要额外的布线和大量附加代码。要保持尽可能简单的东西,我们将使用称为脉冲宽度调制的技术。要了解脉冲宽度调制如何工作,请首先查看数字信号图。

在上述图像中,幅度表示数字信号的电压,并且在X轴上表示时间。如上所述,电压的变化几乎是瞬间,并且数字信号只能具有两个状态。

通过反复打开和关闭信号,我们可以控制随着时间的推移在线上输出的平均电压。这种信号保持在ON(高/ 1)状态的时间量称为其占空比。通过改变占空比,我们可以改变排出线的平均电压。

因此,如果信号保持在(高/ 1)只有50%的时间,那么平均电压或占空比仅为原始电源电压的50%。

PWM在数字信号处理中有许多用例。出于我们的目的,我们将使用PWM改变为我们主动蜂鸣器或扬声器提供的平均电压。

将扬声器或主动蜂鸣器连接到微控制器的电路是一个相当简单的电路。请注意,我正在使用0.5W扬声器,电压要求在1kHz处为1V,阻抗为8Ω。如果您的电压要求较高,则可以使用带有外部电源的晶体管来放大信号。两个图表如下。

如前所述,笔记是简单谐波运动的正弦波。以下是第4个Octave上的注释的频率列表。

为了在PWM中重新创建上述频率,让我们来看看一些示例代码。

以上代码主要是通用的,除了USEEP和GPIOHS_SET_PIN函数调用。您可以使用微控制器SDK特定功能替换这些函数调用以睡眠或延迟微秒(USLEEP)& GPIO数字控制(GPIOHS_SET_PIN)。上述代码中的这些功能特定于K210(Kendryte-Standalone-SDK)。

在上面的代码中,首先,我们将注意频率分配给双变量(Note_frice)。然后,我们计算该频率的每个周期的时段,将周期转换为微秒,并将其存储在另一个双变量(Note_period)中。计算周期的公式是时期(以sec)= 1 /频率(在Hz中)。

TONT_DURATION只不过是播放音符的持续时间。我们将每个循环的周期添加到总持续时间,并将其与所需持续时间值进行比较。

在循环中,我们首先将微控制器上的输出引脚设置为高(1),然后我们等待计算时期的一半。然后将输出引脚设置为低(0),然后再次等待计算时段的一半。这样,我们正在以50%的占空比运营。

您刚刚听到的音频是通过使用适当的暂停(由 - )播放以下注释而生成的。 您可以使用和弦和其他复杂的音频结构进行实验。 使您的Arduino项目更有趣的音频输出! :)欢呼。