【ESP32音视频传输】②通过I2S采集SPH0645麦克风音频数据并上传到服务端实时播放

这篇具有很好参考价值的文章主要介绍了【ESP32音视频传输】②通过I2S采集SPH0645麦克风音频数据并上传到服务端实时播放。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

本文章基于Arduino ESP32 2.07版本,因为2.04版本开始I2S驱动被更改了,所以相同代码可能效果不太同 本文主要参考了:https://atomic14.com/2020/09/12/esp32-audio-input.html


一、I2S型麦克风SPH0645

ESP32有多种方式从外置麦克风中读取数据:

①直接从内置模数转换器 (ADC) 读取数据
这对于一次性读数很有用,但不适用于高采样率。
②使用 I2S 通过 DMA 读取内置 ADC
适用于模拟麦克风,例如 MAX4466 和 MAX9814
使用 I2S 直接读取 I2S 兼容外设
适用于 SPH0645LM4H、INPM441、ICS43432 和 ICS43434 等麦克风
【ESP32音视频传输】②通过I2S采集SPH0645麦克风音频数据并上传到服务端实时播放

二、使用步骤

1.连线图

【ESP32音视频传输】②通过I2S采集SPH0645麦克风音频数据并上传到服务端实时播放
【ESP32音视频传输】②通过I2S采集SPH0645麦克风音频数据并上传到服务端实时播放
(上图均来自:https://diyi0t.com/i2s-sound-tutorial-for-esp32/)

①位时钟线

正式名称为“连续串行时钟 (SCK)”。通常写作“位时钟(BCLK)”。

② 字时钟线

正式的“单词选择(WS)”。通常称为“左右时钟 (LRCLK)”或“帧同步 (FS)”。

0 = 左声道,1 = 右声道

③数据线

正式名称为“串行数据 (SD)”,但可以称为 SDATA、SDIN、SDOUT、DACDAT、ADCDAT 等。

我的连线图是这样的
【ESP32音视频传输】②通过I2S采集SPH0645麦克风音频数据并上传到服务端实时播放
引脚对应为:

// i2s pins
i2s_pin_config_t i2sPins = {
    .bck_io_num = GPIO_NUM_15,
    .ws_io_num = GPIO_NUM_16,
    .data_out_num = I2S_PIN_NO_CHANGE,
    .data_in_num = GPIO_NUM_21};

2.Arduino主文件代码

工程代码的I2S操作SPH0645参考了:https://github.com/atomic14/esp32-walkie-talkie,原工程用的是HTTP stream,本例改成了AsyncUDP
主文件代码如下:

#include <Arduino.h>
#include <WiFi.h>

#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"
#include "esp_camera.h"

#include "configuration.h"
#include "I2SMEMSSampler.h"

#include "AsyncUDP.h"

const char * ssid = "your-ssid"; //WiFi名称
const char * password = "password";//wifi密码

IPAddress serverip = IPAddress(192,168,1,108);    //服务端的静态IP地址
uint16_t toport_sound = 8085;              //服务端的开放端口
const int SAMPLE_SIZE = 700;//udp一次最大发送的数据包大小,UDP最大发生有限制

AsyncUDP SoundUDP;


I2SSampler *i2sSampler = NULL;

void InitUDP(IPAddress ip, uint16_t toport_sound){

  if(SoundUDP.connect(ip, toport_sound)) {
      Serial.println("UDP connected");
      SoundUDP.onPacket([](AsyncUDPPacket packet) {
          Serial.print("UDP Packet Type: ");
          Serial.print(packet.isBroadcast()?"Broadcast":packet.isMulticast()?"Multicast":"Unicast");
          Serial.print(", From: ");
          Serial.print(packet.remoteIP());
          Serial.print(":");
          Serial.print(packet.remotePort());
          Serial.print(", To: ");
          Serial.print(packet.localIP());
          Serial.print(":");
          Serial.print(packet.localPort());
          Serial.print(", Length: ");
          Serial.print(packet.length());
          Serial.print(", Data: ");
          Serial.write(packet.data(), packet.length());
          Serial.println();
          //reply to the client
          packet.printf("S2 Got %u bytes of data", packet.length());
      });
      //Send unicast
      //SoundUDP.print("This is S2 Server");
  }  

}

// i2s config for reading from left channel of I2S
i2s_config_t i2sMemsConfigLeftChannel = {
    .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
    .sample_rate = 16000,
    .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,
    .channel_format = I2S_CHANNEL_FMT_ONLY_RIGHT,
    .communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_STAND_I2S),
    .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
    .dma_buf_count = 4,
    .dma_buf_len = 1024,
    .use_apll = false,
    .tx_desc_auto_clear = false,
    .fixed_mclk = 0};

// i2s pins
i2s_pin_config_t i2sPins = {
    .bck_io_num = GPIO_NUM_15,
    .ws_io_num = GPIO_NUM_16,
    .data_out_num = I2S_PIN_NO_CHANGE,
    .data_in_num = GPIO_NUM_21};



//      发送音频数据
void sendSoundData(uint8_t *bytes, size_t count, AsyncUDP* UDPClient = &SoundUDP, uint16_t the_port = toport_sound)
{
  // send them off to the server
  digitalWrite(2, HIGH);
  /*
  httpClient->begin(*wifiClient, url);
  httpClient->addHeader("content-type", "application/octet-stream");
  httpClient->POST(bytes, count);
  httpClient->end();
  */

 //这是向局域网内所有用户广播,若只发给连接的用户,要用UDPClient.write()
  UDPClient->broadcastTo(bytes, count,the_port);
  digitalWrite(2, LOW);
}

// Task to write samples to our server
void i2sMemsWriterTask(void *param)
{
  I2SSampler *sampler = (I2SSampler *)param;
  int16_t *samples = (int16_t *)malloc(sizeof(uint16_t) * SAMPLE_SIZE);
  if (!samples)
  {
    Serial.println("Failed to allocate memory for samples");
    return;
  }
  while (true)
  {
    int samples_read = sampler->read(samples, SAMPLE_SIZE);
    //sendSoundData((uint8_t *)samples, samples_read * sizeof(uint16_t));
    SoundUDP.write((uint8_t *)samples, samples_read * sizeof(uint16_t));
    //SoundUDP.broadcastTo((uint8_t *)samples, samples_read * sizeof(uint16_t),toport_sound);
  }
}

void setup()
{
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector
  Serial.begin(115200);
  //Serial.setDebugOutput(false);
  // launch WiFi
    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid, password);
    if (WiFi.waitForConnectResult() != WL_CONNECTED) {
        Serial.println("WiFi Failed");
        while(1) {
            delay(1000);
        }
    }

  // indicator LED
  pinMode(2, OUTPUT);

  InitUDP(serverip,toport_sound);

  // Direct i2s input from INMP441 or the SPH0645
  i2sSampler = new I2SMEMSSampler(I2S_NUM_1, i2sPins, i2sMemsConfigLeftChannel, false);
  i2sSampler->start();


  // set up the i2s sample writer task
  TaskHandle_t i2sMemsWriterTaskHandle;
  xTaskCreatePinnedToCore(i2sMemsWriterTask, "I2S Writer Task", 4096, i2sSampler, 1, &i2sMemsWriterTaskHandle, 1);

  // // start sampling from i2s device
}

void loop()
{
  // nothing to do here - everything is taken care of by tasks

}

该处使用的url网络请求的数据。

3.服务端利用UDP接收音频代码

import pyaudio
import socket

# 配置参数
chunk = 1400
sample_rate = 16000
duration = 5
udp_port = 8085

p = pyaudio.PyAudio()

# 打开音频流
stream = p.open(format=pyaudio.paInt16,
                channels=1,
                rate=sample_rate,
                output=True)

# 打开UDP套接字
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(('0.0.0.0', udp_port))

# 播放PCM音频数据
while True:
    data, addr = sock.recvfrom(chunk)
    print(f"Received message ")
    stream.write(data)

# 关闭音频流和UDP套接字
stream.stop_stream()
stream.close()
sock.close()
p.terminate()


Arduino完整程序

https://download.csdn.net/download/loveliveoil/87762126文章来源地址https://www.toymoban.com/news/detail-503032.html

到了这里,关于【ESP32音视频传输】②通过I2S采集SPH0645麦克风音频数据并上传到服务端实时播放的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32CubeMX+MDK通过I2S接口进行音频输入输出(全双工读写一个DMA回调)

    目前有一个关于通过STM32F411CEUx的I2S总线接口控制SSS1700芯片进行音频输入输出的研究。 SSS1700 是具有片上振荡器的 3S 高度集成的USB音频控制器芯片 。 SSS1700 功能支持96 KHz 24 位采样率,带外部音频编解码器(24 位/96KHz I2S 输入和输出)并具有内置立体声16/24位ADC、立体声16/24位

    2024年04月12日
    浏览(52)
  • Audio-音频传输接口(I2S、PCM、PDM)

    I2S和PCM(TDM)接口传输的数据是PCM编码格式的音频数据。 PDM接口传输的数据是PDM编码格式的音频数据。 I2S(Inter-IC Sound)总线有时候也写作 IIS,I2S 是飞利浦公司提出的一种用于数字音频设备之间进行音频数据传输的总线。和 I2C、SPI 这些常见的通信协议一样,I2S 总线用于主控制器

    2024年02月01日
    浏览(44)
  • STM32个人笔记-I2S

    现实存在的声音是模拟量,这对声音保存和长距离传输造成很大的困难,一般的做法是把模拟量转成对应的数字量保存,在需要还原声音的地方再把数字量的转成模拟量输出。 模拟量转换成数字量,3个过程:采样、量化和编码。 蓝线的距离就是采样信号的周期,即对应一个

    2024年02月10日
    浏览(46)
  • 使用STM32的I2S协议读取麦克风INMP441

    本文将详细介绍使用STM32的硬件I2S协议,从麦克风模块INMP441读取音频信号的步骤和避坑指南。 点这里,从Github下载工程文件 百度网盘: 链接:https://pan.baidu.com/s/1cglAGirn6bTQhIEpWDb7Ig?pwd=k9gh 提取码:k9gh INMP441模块: 主控芯片:我用的是STM32F103ZET6,可以在STM的选型手册上看到哪

    2024年02月02日
    浏览(60)
  • 音频I2S

    前言 基于网上资料对相关概念做整理汇总,部分内容引用自文后文章。 学习目标:简单了解相关概念、相关协议。 1 概述        数字音频接口DAI,即Digital Audio Interfaces,顾名思义,DAI表示在板级或板间传输数字音频信号的方式。相比于模拟接口,数字音频接口抗干扰能力

    2024年02月03日
    浏览(49)
  • 音频——I2S 标准模式(二)

    I2S 基本概念 飞利浦(I2S)标准模式 左(MSB)对齐标准模式 右(LSB)对齐标准模式 DSP 模式 TDM 模式 飞利浦 (I2S) 标准模式 数据在跟随 LRCLK 传输的 BCLK 的第二个上升沿时传输 MSB,其他位一直到 LSB 按顺序传 传输依赖于字长、BCLK 频率和采样率(BCLK=Fs x 声道数 x 采样位数) 在每个采样的

    2024年02月10日
    浏览(45)
  • 音频——I2S DSP 模式(五)

    I2S 基本概念 飞利浦(I2S)标准模式 左(MSB)对齐标准模式 右(LSB)对齐标准模式 DSP 模式 TDM 模式 DSP/PCMmode 分为 Mode-A 和 Mode-B 共 2 种模式。不同芯⽚有的称为 PCM mode 有的称为 DSP mode。PCM 只有⼀个起始信号,先传输左声道后传输右声道。 Mode-A 数据在第 1 个 BCLK 脉冲处 上升沿数据有

    2024年02月09日
    浏览(44)
  • 音频——I2S TDM 模式(六)

    I2S 基本概念 飞利浦(I2S)标准模式 左(MSB)对齐标准模式 右(LSB)对齐标准模式 DSP 模式 TDM 模式 TDM 一般有三种常用操作模式:TDM A mode ,TDM B mode 和 TDM C mode, 统称为TDM mode。 基于 TDM mode,可以配置支持 TDM(Time Division Multiplexing)数据传输。可以支持传输多个声道的数据,允许多个设

    2024年02月04日
    浏览(46)
  • 一文搞懂I2S通信总线

    目录 1、物理特性 2、常见的I2S数据格式 2.1、I2S Philips标准 2.2、左对齐(MSB)标准 2.3、右对齐(LSB)标准 之前我们讲过I2C通信总线,本篇博文将讲一讲I2C的变种:I2S总线。 I2C和I2S都是由Philips公司(2006年迁移到NXP)发布的串行总线,I2S是在I2C之后发布,I2S专为传输音频数据而

    2024年01月16日
    浏览(40)
  • 瑞芯微 | I2S-音频基础 -1

    最近调试音频驱动,顺便整理学习了一下i2s、alsa相关知识,整理成了几篇文章,后续会陆续更新。 喜欢嵌入式、Li怒晓得老铁可以关注一口君账号。 名称 含义 ADC(Analog to Digit Conversion) 模拟信号转换为数字信号 AEC(Acoustic Echo Cancellor) 回声消除 AGC(Automatic Gain Control) 自

    2024年03月14日
    浏览(60)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包