esp32 -s3 通过pdm麦克风实现tcp传输音频数据

复制代码
#include "driver/i2s_pdm.h"
#include "Arduino.h"
#include <WiFi.h>

const char *ssid = "123";
const char *password = "12345678";
const char* server_ip = "192.168.107.97";
const int server_port = 8888;
WiFiClient client;

#define PDM_CLK_GPIO 4
#define PDM_DIN_GPIO 5
i2s_chan_handle_t rx_chan = nullptr;

void setup() {
  Serial.begin(115200);
  
  // **关键:先配置I2S,再启动WiFi**
  configure_i2s();
  
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) delay(500);
  Serial.println("WiFi已连接");
  
  // **降低WiFi功率(修正版)**
  WiFi.setTxPower(WIFI_POWER_8_5dBm);
  // **删除错误行:WIFI_MODEM_SLEEP不存在**
  // WiFi.setSleep(WIFI_MODEM_SLEEP);  // ❌ 删除或改为下面这行
  
  // 可选:启用轻度休眠模式(降低干扰)
  // WiFi.setSleepMode(WIFI_PS_MIN_MODEM, WIFI_PS_MIN_MODEM);
  
  // **GPIO降噪配置**
  gpio_set_drive_capability((gpio_num_t)PDM_CLK_GPIO, GPIO_DRIVE_CAP_1);
  gpio_set_drive_capability((gpio_num_t)PDM_DIN_GPIO, GPIO_DRIVE_CAP_1);
  gpio_set_pull_mode((gpio_num_t)PDM_DIN_GPIO, GPIO_PULLUP_ONLY);
}

void configure_i2s() {
  i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER);
  chan_cfg.dma_desc_num = 16;  // 最大DMA缓冲区
  chan_cfg.dma_frame_num = 1024;
  ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, nullptr, &rx_chan));

  i2s_pdm_rx_config_t pdm_cfg = {
      .clk_cfg  = I2S_PDM_RX_CLK_DEFAULT_CONFIG(16000),
      .slot_cfg = I2S_PDM_RX_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO),
      .gpio_cfg = { .clk = (gpio_num_t)PDM_CLK_GPIO, .din = (gpio_num_t)PDM_DIN_GPIO,
                    .invert_flags = { .clk_inv = false } },
  };
  ESP_ERROR_CHECK(i2s_channel_init_pdm_rx_mode(rx_chan, &pdm_cfg));
  ESP_ERROR_CHECK(i2s_channel_enable(rx_chan));
}

void loop() {
  if (!client.connected()) {
    if (client.connect(server_ip, server_port)) {
      Serial.println("TCP流已建立");
    } else {
      delay(1000);
    }
    return;
  }

  static int16_t buf[512];
  size_t bytes_read = 0;
  
  // **纯流式发送,无帧头**
  if (i2s_channel_read(rx_chan, buf, sizeof(buf), &bytes_read, portMAX_DELAY) == ESP_OK) {
    client.write((uint8_t*)buf, bytes_read);
  }
}

下面是py代码使用方法在终端中python "C:\Users\LHJ32\Desktop\pdmtcp.py"打开该文件,然后连接是TCP就开始录制,按 Ctrl+C 结束,并自动把最后一段数据写成 .raw 供 Audacity 复查

复制代码
import socket

TCP_IP = "0.0.0.0"
TCP_PORT = 8888

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((TCP_IP, TCP_PORT))
sock.listen(1)

print(f"等待TCP连接 {TCP_PORT}...")
conn, addr = sock.accept()
print(f"客户端已连接: {addr}")

raw_data = bytearray()
try:
    while True:
        data = conn.recv(8192)
        if not data: break
        raw_data.extend(data)
        print(f"已接收 {len(raw_data)} 字节", end="\r")
except KeyboardInterrupt:
    print("\n手动停止录制...")

conn.close()

if raw_data:
    with open("audio.raw", "wb") as f:
        f.write(raw_data)
    print(f"\n已保存audio.raw ({len(raw_data)} 字节)")
else:
    print("未接收到任何数据!")
相关推荐
上海合宙LuatOS4 小时前
LuatOS核心库API——【audio 】
java·网络·单片机·嵌入式硬件·物联网·音视频·硬件工程
Android系统攻城狮5 小时前
Android16进阶之音频播放定位MediaPlayer.seekTo调用流程与实战(二百二十七)
音视频·mediaplayer·android16·音频进阶·音频性能实战
三水不滴6 小时前
有 HTTP 了为什么还要有 RPC?
经验分享·笔记·网络协议·计算机网络·http·rpc
晚霞的不甘6 小时前
Flutter for OpenHarmony 可视化教学:A* 寻路算法的交互式演示
人工智能·算法·flutter·架构·开源·音视频
听麟7 小时前
HarmonyOS 6.0+ 跨端智慧政务服务平台开发实战:多端协同办理与电子证照管理落地
笔记·华为·wpf·音视频·harmonyos·政务
宝塔面板7 小时前
AllinSSL 一站式搞定 SSL 自动续期:永久免费,开源可自托管
网络·网络协议·ssl
csdn今天倒闭了吗7 小时前
飞牛lucky配置ipv6 ddns+ssl+反向代理
网络·网络协议·ssl
JavinLu7 小时前
ios 配置了代理且使用 chls.pro/ssl 下载不了证书,无法弹出下载证书的提示问题
网络协议·ios·ssl
晚霞的不甘7 小时前
Flutter for OpenHarmony 实现计算几何:Graham Scan 凸包算法的可视化演示
人工智能·算法·flutter·架构·开源·音视频
菜鸟特工0078 小时前
javax.net.ssl.SSLPeerUnverifiedException 异常如何处理
网络协议·.net·ssl