ESP32 005 MicroPython I2S 实现音频传输与播放

  • I²S(Inter-IC Sound) 是一种专用于数字音频传输的串行总线标准,广泛用于微控制器(如 ESP32)与音频 DAC(如 PCM5102)之间传输音频数据。

I2S 主要信号线

信号线名称 全称/别名 功能描述
BCLK Bit Clock / SCK 每一位数据的时钟,用于数据同步
LRCLK Left-Right Clock / WS 左右声道选择,High 表示右声道,Low 表示左声道
DATA Serial Data / SD / DIN 音频的实际数据流
MCLK Master Clock (可选) 主系统时钟(部分 DAC 可不接,PCM5102 内置 PLL 可省略)

上传 wav到 SPIFFS(Thonny)

  1. 打开 视图 > 文件
  2. 拖拽 ***.wav 到 MicroPython 设备(根目录)
  3. 等待上传成功

python函数接口说明

python 复制代码
# https://github.com/micropython/micropython/blob/master/ports/esp32/machine_i2s.c

from machine import I2S, Pin

audio = I2S(
    0,
    sck=Pin(9),
    ws=Pin(10),
    sd=Pin(11),
    mode=I2S.TX,
    bits=16,
    format=I2S.STEREO,
    rate=16000,
    ibuf=40000
)
函数/参数 说明
I2S(id, **kwargs) 创建 I2S 对象。id 一般为 0 或 1,参数通过关键字传入。
id I2S 外设编号。ESP32 通常支持 0 或 1(部分板子支持 2)。
sck / bck Bit Clock(位时钟)引脚,接到 DAC 的 BCK 引脚。
ws / lrck Word Select / LRCK 引脚,接到 DAC 的 LCK 引脚。
sd Serial Data,引脚接到 DAC 的 DIN。
mode I2S.TX(发送)或 I2S.RX(接收)。
bits 采样精度,常用值为 16、24、32。需与 WAV 文件位深一致。
format 通道格式:I2S.MONO 或 I2S.STEREO。
rate 采样率(Hz),例如 16000、44100、48000 等。需与音频文件一致。
ibuf 内部缓冲区大小(字节),越大越平稳但占用 RAM。

CODE实现

c 复制代码
from machine import Pin, I2S
import ustruct
import time

# ======== 配置 I2S ========
SCK_PIN = 9   # Bit Clock (BCK)
WS_PIN  = 10   # Word Select (LRCK)
SD_PIN  = 11   # Data (DIN)

audio_out = I2S(
    0,                         # I2S peripheral ID
    sck=Pin(SCK_PIN),
    ws=Pin(WS_PIN),
    sd=Pin(SD_PIN),
    mode=I2S.TX,
    bits=16,
    format=I2S.STEREO,         # I2S.STEREO 或 I2S.MONO,取决于 WAV 文件
    rate=16000,                # 与音频采样率一致
    ibuf=40000
)
# ===========================

# # ======== 解析 WAV 头部并跳过 ========
# def skip_wav_header(f):
#     # 跳过 WAV 文件头部,找到数据段
#     while True:
#         chunk_id = f.read(4)
#         if chunk_id == b'data':
#             data_size = ustruct.unpack('<I', f.read(4))[0]
#             return data_size
#         else:
#             f.read(ustruct.unpack('<I', f.read(4))[0])

import ustruct

def skip_wav_header(f):
    # Read RIFF header
    if f.read(4) != b'RIFF':
        raise ValueError('Invalid WAV file: missing RIFF')
    f.read(4)  # Chunk size
    if f.read(4) != b'WAVE':
        raise ValueError('Invalid WAV file: missing WAVE')

    # Search for 'data' chunk
    while True:
        chunk_id = f.read(4)
        if len(chunk_id) < 4:
            raise ValueError("Reached end of file before finding 'data' chunk")
        chunk_size_bytes = f.read(4)
        if len(chunk_size_bytes) < 4:
            raise ValueError("Corrupted WAV file")
        chunk_size = ustruct.unpack('<I', chunk_size_bytes)[0]

        if chunk_id == b'data':
            return chunk_size  # return data size
        else:
            # skip over this chunk
            f.read(chunk_size)


# ======== 播放 WAV 文件 ========
wav_file = "/music-16k-16bits-mono.wav"

with open(wav_file, "rb") as f:
#     header = f.read(44)  # 假设标准 44 字节 WAV header
#     data_size = skip_wav_header(f)
#     print("Data size:", data_size)
    data_size = skip_wav_header(f)  # 不要再提前读 44 字节
    print("Data size:", data_size)

    # 循环读取并播放音频数据
    while True:
        wav_data = f.read(1024)
        if not wav_data:
            break
        audio_out.write(wav_data)

# ======== 释放 I2S ========
audio_out.deinit()
相关推荐
Sayai1 小时前
ComfyUI+MiniMax H3 文生视频实测:12G 显存跑 21G 模型,5 分钟出片自带音效(附模型与工作流)
人工智能·aigc·音视频·文生视频·comfyui·minimax
技灵AI1 小时前
图生视频提示词怎么写:一张商品图生成整条演示视频
人工智能·aigc·音视频·提示词
我是海飞1 小时前
杰理 JL703N SDK 实现 AI 自动化调试:自动进入下载模式、下载、重启与日志抓取
人工智能·单片机·自动化·音视频·杰理
ck0135792 小时前
图片抠图怎么做?从背景去除到透明 PNG 的实用教程
人工智能·测试工具·音视频·媒体·视频
美狐美颜sdk2 小时前
直播APP接入第三方视频美颜SDK安全吗?数据处理与隐私问题分析
人工智能·音视频·美颜sdk·第三方美颜sdk·视频美颜sdk·美颜api
Anhty2 小时前
短视频音频降噪:2026 移动端剪辑工具怎么选
功能测试·智能手机·音视频
可信时间戳4 小时前
原创作品如何做版权认证申请?先备材料,再挑路径
服务器·音视频·可信时间戳·权利卫士
达之云*驭影4 小时前
用AI给视频一键更换文案、字幕与配音,需要哪些技术?
人工智能·音视频
美狐美颜SDK开放平台4 小时前
直播APP平台搭建需要哪些技术?视频美颜SDK只是其中一环
android·ios·音视频·直播美颜sdk·视频美颜sdk
martindelophy6 小时前
开源 AI 视频编辑器实战:用结构化命令连接视频生成、对话剪辑与浏览器导出
人工智能·编辑器·音视频