
根据硬件连线,代开这个文件
/*
This example plays a raw, headerless, mono 16b, 44.1 sample using the PWMAudio library on GPIO 1.
Released to the public domain by Earle F. Philhower, III <earlephilhower@yahoo.com>
*/
#include <PWMAudio.h>
#include "wav.h"
// The sample pointers
const int16_t *start = (const int16_t *)out_raw;
const int16_t *p = start;
// Create the PWM audio device on GPIO 1. Hook amp/speaker between GPIO1 and convenient GND.
PWMAudio pwm(1);
unsigned int count = 0;
void cb() {
while (pwm.availableForWrite()) {
pwm.write(*p++);
count += 2;
if (count >= sizeof(out_raw)) {
count = 0;
p = start;
}
}
}
void setup() {
pwm.onTransmit(cb);
pwm.begin(44100);
}
void loop() {
/* noop, everything is done in the CB */
}
播放原始音频 :
直接播放无文件头(headerless)的 16位单声道 PCM 音频数据 (存储在 out_raw 数组中,数据来自 wav.h 文件)。
- 硬件控制 :
通过 PWM 信号输出到 GPIO 1 ,需外接功放或扬声器(GPIO1 接正极,GND 接负极)。 - 实时性 :
使用回调函数 cb() 动态填充音频数据,避免阻塞主循环。
2. 代码逐段解析
(1)音频数据准备
const int16_t *start = (const int16_t *)out_raw; // 音频数据起始地址
const int16_t *p = start; // 当前播放位置指针
- `out_raw` 是存储在 `wav.h` 中的原始 PCM 数据数组(需提前转换为 `int16_t` 格式)。
- 数据格式: 16位有符号整数 ,采样率 44.1kHz ,单声道。
(2)PWM 音频初始化
PWMAudio pwm(1); // 初始化 PWM 音频输出,绑定到 GPIO 1
- `PWMAudio` 是第三方库(作者 Earle F. Philhower),支持高效 PWM 音频输出。
(3)回调函数 `cb()`
void cb() {
while (pwm.availableForWrite()) { // 检查缓冲区空间
pwm.write(*p++); // 写入当前音频样本
count += 2; // 移动计数(16位=2字节)
if (count >= sizeof(out_raw)) { // 循环播放
count = 0;
p = start;
}
}
}
- 动态填充数据 :当 PWM 缓冲区有空闲时,持续写入音频样本。
- 循环播放 :播放到音频末尾时,重置指针到起始位置。
(4)初始化和主循环
void setup() {
pwm.onTransmit(cb); // 设置回调函数
pwm.begin(44100); // 启动 PWM,采样率 44.1kHz
}
void loop() { /* noop */ } // 主循环无需操作,依赖回调
- `begin(44100)` 设置采样率与音频数据匹配。
- 所有操作在回调中完成,主循环为空。
原本以为还要搭建外围电路,没想到直接连接就可以了
硬件连接示例
[MCU GPIO1] → [低通滤波器(RC电路)] → [功放] → [扬声器]
↓
[GND]
省去了很多麻烦
全部评论