如何使用树莓派Pico创建具有频谱可视化和无RTOS的实时MIDI合成器
扫描二维码
随时随地手机看文章
树莓派Pico是一款非常流行且功能强大的MCU(微控制器)开发平台,基于树莓派的RP2040 MCU,价格仅为4美元。RP2040集成了两个133 MHz Arm的Cortex-M0+ CPU内核,264 kB SRAM和一个独特的可编程I/O系统。
本指南将通过几个软件组件的集成来创建一个具有频谱可视化和动画的MIDI播放器。我将探索如何在不使用RTOS的情况下创建一个具有实时音频合成,可视化和双核的复杂软件。
你可以在下面看到和听到结果的预览:
在单板上运行Demo
音频将使用来自pico-extras的PWM音频驱动程序生成,LCD将使用来自PIO pico-examples的LCD驱动程序控制(针对演示进行了修改)。
软件组件将使用CMSIS-Stream开源库进行集成。
MIDI组件来自Len Shustek的Playtune Synth项目,并经过大量修改以集成在此演示中。
本演示使用两个M0+内核。
数据流和CMSIS-Stream
这个演示使用了几个来自不同来源的软件组件:
•树莓公司开发的一些软件:PWM驱动和LCD驱动。
•来自Len Shustek的Playsynth_tune项目的一些组件用于音乐合成
•用于信号处理(频谱计算)的CMSIS-DSP组件
•为此演示开发的特定于应用程序的组件
•手臂- 2D用于最后的展示
这些组件必须连接起来,以达到预期的结果:实时音乐合成与动画显示。
对于流应用程序,将软件架构表示为突出显示数据流和数据依赖关系的图形是非常有用的。
这里有两个图表:
•一个在核心0上合成音乐:音频图。
•核心1上的一个处理和显示音乐:LCD图形。
(更高分辨率的图表可以在项目的github上看到)
实现这些图形有几个问题需要解决:
•图的不同部分使用不同的数据速率。例如,LCD的刷新率小于音频的刷新率。因此,图中的一些节点必须比其他节点执行得少得多。如果没有实时操作系统,我们如何轻松做到这一点?
•由于不同的数据速率以及一些节点在不同大小的缓冲区上工作,因此需要在节点之间引入fifo。我们如何确定fifo的大小?
•当节点在相同大小的缓冲区上工作时,我们仍然需要这些节点之间的临时缓冲区:我们如何最小化用于执行图的临时内存?
•我们如何在这样的系统中集成软件组件:连接到FIFO等……但开发人员的工作量最小
•所有这些问题都可以手工解决。它们并不难。但它们在开发流程中增加了摩擦。作为开发者,你必须考虑所有这些细节,而不是专注于产品的真正附加价值。
此外,这些问题使软件的模块化程度降低:图中的任何变化(数据速率、组件消耗或产生的缓冲区大小)都可能影响整个图的调度和许多fifo的大小。如果每次更改某些内容,就必须考虑并再次修改所有这些图形调度细节,这会使开发人员的工作变得更加困难。
CMSIS-Stream的开发是为了使开发人员的生活更容易处理所有这些细节:
图是用Python描述的。
CMSIS-Stream根据Python描述在构建时计算一个静态调度:
它是一个周期性的函数调用序列,考虑到不同的数据速率和缓冲区大小,它将生成/处理一个样本流。
CMSIS-Stream考虑计算的调度和节点消耗或产生的缓冲区大小来调整fifo的大小。
CMSIS-Stream尝试最小化缓冲区使用的临时内存。
软件组件集成在图中:
如果它们是纯函数就直接。
使用一个非常轻的c++包装器,它提供了标准的原始指针,用于访问FIFO组件
这些图形在python脚本create_audio_graph.py和create_lcd_graph.py中描述。
如果您想了解如何使用CMSIS-Stream并更改图形,请参阅CMSIS-Stream文档。
音频图
音频图表主要由来自Len Shustek的Playsynth_tune项目的组件制作而成。但是为了集成到这个演示中,它们已经被修改了很多(可能还引入了一些bug)。
相位增量的定点格式已被修改,以考虑到本演示中使用的音频速率。
波形振荡器的音频插值已被删除:它可以通过使用Pico HW插值器稍后重新引入。
生成音符命令的序列器是图形的一部分,不再从外部线程工作。必须更改逻辑以尊重图的同步行为:在节点完成当前调度迭代的执行之前,必须用注释命令尽可能多地加载序列器的输出通道。
向核心1发送数据的节点没有阻塞:音频比显示更重要。如果在核心1上运行的LCD图形太慢,它只会错过几个音频块。
LCD图形
这个演示使用的LCD只有240像素的宽度。如果目标刷新率为40ms,则意味着每40ms只显示240个样本。
但在40毫秒内产生的音频样本远远超过240个。音频信号必须经过滤波和抽取。LCD图形包含幅度和频谱部分的滤波和抽取节点。抽取因子是相当高的,所以高频将不可见的显示。
对于频谱,可以尝试使用更大的fft和更小的抽取因子来显示更高频率的内容。使用CMSIS-Stream的优点是,您可以通过更改描述LCD图形的Python中的几个参数轻松地进行这些实验。
您可能还需要更改抽取过滤器系数:这些系数在main.cpp中定义
光谱计算是标准的:
信号乘以汉宁窗。
它被转换成复数。
使用了一个复杂的FFT。
计算FFT的幅度,并应用一些缩放(用于显示)。
图形部分使用一些缓冲区生成器:缓冲区在不同的调度迭代之间重用。
振幅和频谱小部件被引入这些缓冲器。Arm-2D最后使用Pico HW插值器混合这些缓冲区。
CMSIS-DSP
使用开源计算库CMSIS-DSP进行音频通道的混合,并使用该库进行滤波和抽取,计算汉宁窗口和FFT。
在M0+上,CMSIS-DSP不能提供任何加速。但是通过使用CMSIS-DSP,您可以将您的软件移植到更强大的Cortex处理器(M和A)上,其中CMSIS-DSP将免费提供加速。
硬件设置
如果您使用的是没有预焊接头的树莓派Pico板,请按照MagPi的“如何将GPIO引脚接头焊接到树莓派Pico”指南并将接头焊接到板上。
LCD通过Pico四路扩展器连接,因此没有其他事情可做。
外部扬声器必须通过晶体管连接,否则会从Pico引脚产生过多的电流。
扬声器连接
电线的颜色编码与下图一致。不幸的是,我不得不使用我家里可用的东西,它迫使我使用红色或紫色的线进行接地连接,蓝色的线进行3V连接。
液晶显示器连接
LCD通过Pico四路扩展器连接,因此没有其他事情可做:
软件设置
设置Pico SDK环境
首先,您需要使用Raspberry Pi的Pico SDK和所需的工具链来设置计算机。
有关更多信息,请参阅“Raspberry Pi Pico入门”。
本指南的第2.1节可用于所有操作系统,接下来是具体操作部分:
Linux: 2.2节
macOS: 9.1节
Windows:第9.2节
你需要pico-sdk和pico-extras。
获取和编译PicoMusic演示
确保设置了PICO_SDK环境变量。
在终端窗口中,克隆git存储库并更改目录:
创建一个构建目录并更改目录:
运行cmake和make来编译:
按住板上的BOOTSEL按钮,同时用USB电缆将板插入计算机。
复制流。uf2文件到挂载的Raspberry Pi Pico启动盘:
测试
只需插入Pico,演示就会开始。你可以用LCD按钮控制它。
也可以通过USB从主机上的串行控制台控制它
结论
本指南介绍了如何使用带有LCD和外部扬声器的树莓派Pico板来创建实时音乐合成和频谱图可视化器。该项目使用了几个使用CMSIS-Stream库集成在项目中的组件。
树莓派RP2040的PIO, DMA和HW插值器是使这个演示成为可能的关键。
本文编译自hackster.io





