当前位置: 首页 > news >正文

ESP32 + INMP441 + MAX98357A

INMP441 引脚 连接 ESP32 引脚 说明
VDD 3.3V 供电
GND GND 共地
SCK (BCLK) GPIO26 I²S BCLK
WS (LRCLK) GPIO25 I²S LRCLK
SD (DOUT) GPIO22 I²S 数据输出(麦到ESP32)
L/R GND 左声道(或接3.3V右声道)
CHIPEN 3.3V 常开
MAX98357A 引脚 连接 ESP32 引脚 说明
VIN 5V 功放电源(喇叭供电)
GND GND 共地
BCLK GPIO14 I²S BCLK
LRC GPIO12 I²S LRCLK
DIN GPIO27 I²S 数据输入(ESP32 到功放)
SD/EN 3.3V 常开(静音脚,低电平关机)
GAIN 悬空 默认增益 9dB

platformio.ini

[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200
upload_speed = 921600
; 可选:更安静的编译输出与更快的串口监视器
monitor_filters = time
; 如果遇到 I2S 兼容性问题,可尝试固定核心版本,例如:
; platform = espressif32@6.11.0

main.cpp

#include <Arduino.h>
#include "driver/i2s.h"/* -------- Pin Map -------- */
// INMP441 (I2S RX on I2S0)
#define I2S_RX_PORT     I2S_NUM_0
#define RX_BCLK         26
#define RX_LRCLK        25
#define RX_DOUT         22
#define CH_FMT_RX       I2S_CHANNEL_FMT_ONLY_LEFT   // L/R=GND=左;若接3V3则改为 ONLY_RIGHT// MAX98357A (I2S TX on I2S1)
#define I2S_TX_PORT     I2S_NUM_1
#define TX_BCLK         14
#define TX_LRCLK        12
#define TX_DIN          27// Amplifier SD/EN (mute control, HIGH=enable, LOW=shutdown)
#define AMP_SD_PIN      33/* -------- Audio Params -------- */
#define SAMPLE_RATE     16000                   // 可改 22050/32000/44100/48000(INMP441常用16k/48k)
#define RX_SAMPLES      512                     // 每次搬运的“单声道样本数”
#define BITS_PER_SAMPLE I2S_BITS_PER_SAMPLE_32BIT   // INMP441 24bit 装在 32bit 框
#define SOFT_GAIN_DB    0.0f                    // 简单软件增益(dB),负值为衰减,如 -6.0f
#define LIMIT_ENABLE    1                       // 开启简易限幅(避免溢出爆音)
#define HPF_ENABLE      1                       // 开启简易高通(去直流),一阶 IIR
#define HPF_ALPHA       0.999f                  // 0.99~0.999 间可调;越大越慢/* -------- Helpers -------- */
// 计算线性增益系数
static float db_to_gain(float db) {return powf(10.0f, db / 20.0f);
}// 将 32bit 框中的 24bit(位于[31:8])取出并符号扩展为 32bit
static inline int32_t unpack24_from32(int32_t x32) {int32_t s24 = x32 >> 8;if (s24 & 0x00800000) s24 |= 0xFF000000;return s24;
}// 把 24bit 有效位放回 32bit 框(左对齐至[31:8])
static inline int32_t pack24_to32(int32_t s) {// 限制到 24bit 范围if (s >  0x7FFFFF) s =  0x7FFFFF;if (s < -0x800000) s = -0x800000;return (s << 8);
}/* -------- I2S Init -------- */
static void i2s_rx_init() {i2s_config_t cfg = {.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),.sample_rate = SAMPLE_RATE,.bits_per_sample = BITS_PER_SAMPLE,.channel_format = CH_FMT_RX,                // 单声道(左或右).communication_format = I2S_COMM_FORMAT_I2S,.intr_alloc_flags = 0,.dma_buf_count = 6,.dma_buf_len = 256,                         // 每个 DMA 缓冲的样本数.use_apll = false,.tx_desc_auto_clear = false,.fixed_mclk = 0};i2s_pin_config_t pin = {.bck_io_num   = RX_BCLK,.ws_io_num    = RX_LRCLK,.data_out_num = -1,.data_in_num  = RX_DOUT};i2s_driver_install(I2S_RX_PORT, &cfg, 0, nullptr);i2s_set_pin(I2S_RX_PORT, &pin);i2s_set_clk(I2S_RX_PORT, SAMPLE_RATE, BITS_PER_SAMPLE, I2S_CHANNEL_MONO);
}static void i2s_tx_init() {i2s_config_t cfg = {.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX),.sample_rate = SAMPLE_RATE,.bits_per_sample = BITS_PER_SAMPLE,         // 给 MAX98357A 32bit frame(里头放 24bit).channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, // 立体声帧(我们 L=R).communication_format = I2S_COMM_FORMAT_I2S,.intr_alloc_flags = 0,.dma_buf_count = 6,.dma_buf_len = 256,.use_apll = false,.tx_desc_auto_clear = true,.fixed_mclk = 0};i2s_pin_config_t pin = {.bck_io_num   = TX_BCLK,.ws_io_num    = TX_LRCLK,.data_out_num = TX_DIN,.data_in_num  = -1};i2s_driver_install(I2S_TX_PORT, &cfg, 0, nullptr);i2s_set_pin(I2S_TX_PORT, &pin);i2s_set_clk(I2S_TX_PORT, SAMPLE_RATE, BITS_PER_SAMPLE, I2S_CHANNEL_STEREO);
}/* -------- Simple Audio Processing -------- */
// 直流阻断(单通道),y[n] = x[n] - x[n-1] + alpha*y[n-1]
typedef struct {float prev_x;float prev_y;
} DCBlocker;static DCBlocker dcblk = {0};static inline float dc_block(float x, float alpha) {float y = x - dcblk.prev_x + alpha * dcblk.prev_y;dcblk.prev_x = x;dcblk.prev_y = y;return y;
}void setup() {Serial.begin(115200);delay(300);// SD/EN 控制脚pinMode(AMP_SD_PIN, OUTPUT);digitalWrite(AMP_SD_PIN, HIGH);  // 先开机(如需开机静音可先 LOW,准备好后再 HIGH)i2s_rx_init();i2s_tx_init();Serial.println("ESP32 INMP441 -> MAX98357A passthrough ready.");
}void loop() {static int32_t rxBuf[RX_SAMPLES];       // I2S 读回的 32bit 框static int32_t txBuf[RX_SAMPLES * 2];   // 立体声 L=Rsize_t rxBytes = 0;// 读单声道样本esp_err_t er = i2s_read(I2S_RX_PORT, (void*)rxBuf, sizeof(rxBuf), &rxBytes, portMAX_DELAY);if (er != ESP_OK || rxBytes == 0) return;const size_t n = rxBytes / sizeof(int32_t);const float g  = db_to_gain(SOFT_GAIN_DB);// 处理并复制到双声道size_t j = 0;for (size_t i = 0; i < n; ++i) {int32_t s = unpack24_from32(rxBuf[i]);           // [-2^23, 2^23-1]float xf = (float)s;                              // 转浮点做处理// 简易高通去直流if (HPF_ENABLE) xf = dc_block(xf, HPF_ALPHA);// 软件增益xf *= g;// 限幅至 24bitif (LIMIT_ENABLE) {if (xf >  8388607.0f)  xf =  8388607.0f;if (xf < -8388608.0f)  xf = -8388608.0f;}int32_t s_proc = (int32_t)lrintf(xf);int32_t s32 = pack24_to32(s_proc);txBuf[j++] = s32;   // LefttxBuf[j++] = s32;   // Right}size_t txBytes = 0;i2s_write(I2S_TX_PORT, (const void*)txBuf, j * sizeof(int32_t), &txBytes, portMAX_DELAY);// (可选)打印一点信息// static uint32_t t0 = millis();// if (millis() - t0 > 1000) {//   Serial.printf("rx %u samp, tx %u bytes\n", (unsigned)n, (unsigned)txBytes);//   t0 = millis();// }
}
http://www.sczhlp.com/news/10421/

相关文章:

  • Windows Server 2012虚拟机 时间同步不生效
  • Jackknife
  • php 图片清理工具web版
  • 题解:洛谷 P5997 [PA 2014] Pakowanie
  • 【CAPL】自定义函数的四种类型
  • KubeSphere闭源风波下,Casibase容器云为何成为用户更迫切的需求?
  • 使用类正则语法创建spaCy匹配模式
  • (自适应手机端)水处理设备网站模板 净水设备网站源码下载
  • tray + tkinter
  • istio-Ingress 和 nginx-ingress 的差别
  • (自适应手机端)电气传感器pbootcms网站模板
  • 利用GNURadio让你听到Laurel和Yanny的声音
  • AI-Ready Data信息梳理
  • 题解:[GDCPC 2024] 图
  • 数字中国创新的底层密码:开源新基建
  • (自适应手机端)旅游博客网站模板 个人博客网站源码下载
  • 光隔离探头与传统探头的核心差异解析
  • 【译】Visual Studio 2015 停用:针对旧版本 Visual Studio 的支持提醒
  • 认证协议:OAuth 2.0 和 JWT的学习总结
  • (自适应手机端)厨余垃圾处理设备网站模板
  • mqtt+esp32公网控制PIn 2 led灯
  • 题解:P4350 [CERC2015] Export Estimate
  • Nouveau——第三方开源NVIDIA驱动
  • (自适应手机端)政府机构网站模板 组织协会网站源码下载
  • OpenCV入门(18):图像边缘检测
  • GNOME桌面自动隐藏顶栏
  • 文件已经删除但空间未释放排查记录
  • 用通俗的语言讲讲音频格式中的位深
  • (自适应手机端)家私家纺网站模板 床上用品网站源码下载
  • PKC7150 高频交直流电流探头在智能工厂电力监测项目中的应用方案