ESP32之使用I2S实现录音功能 (INMP411,MAX4466介绍)- 基于Arduino

esp32是买的某宝模块

#设备采集音频代码
# 连接端口:SD->G21  WS->G22 SCK->G23  L/R-> 低电频

from machine import I2S,SPI
from machine import Pin

import os,utime
import network
import socket

def createWavHeader(sampleRate, bitsPerSample, num_channels, datasize):    
    o = bytes("RIFF",'ascii')                                                   # (4byte) Marks file as RIFF
    o += (datasize + 36).to_bytes(4,'little')                                   # (4byte) File size in bytes excluding this and RIFF marker
    o += bytes("WAVE",'ascii')                                                  # (4byte) File type
    o += bytes("fmt ",'ascii')                                                  # (4byte) Format Chunk Marker
    o += (16).to_bytes(4,'little')                                              # (4byte) Length of above format data
    o += (1).to_bytes(2,'little')                                               # (2byte) Format type (1 - PCM)
    o += (num_channels).to_bytes(2,'little')                                    # (2byte)
    o += (sampleRate).to_bytes(4,'little')                                      # (4byte)
    o += (sampleRate * num_channels * bitsPerSample // 8).to_bytes(4,'little')  # (4byte)
    o += (num_channels * bitsPerSample // 8).to_bytes(2,'little')               # (2byte)
    o += (bitsPerSample).to_bytes(2,'little')                                   # (2byte)
    o += bytes("data",'ascii')                                                  # (4byte) Data Chunk Marker
    o += (datasize).to_bytes(4,'little')                                        # (4byte) Data size in bytes
    return o

#音频文件采样率
sampleRate=8000
#每音频采样比特数
bitsPerSample=16
#缓冲字节数
bufSize=32768
#一次录音数据的总字节数
datasize=bufSize*4

#I2S所需管脚
#数据时钟(某宝INMP441模块SCK)
sck_pin = Pin(23)
#帧时钟(某宝INMP441模块模块WS)
ws_pin = Pin(22)
#数据(某宝INMP441模块模块SD)
sd_pin = Pin(21)


# 设置服务器的IP地址和端口
server_ip = '192.168.3.11'  # 服务端IP
server_port = 12345        # 服务端端口

# 连接到WiFi
def connect_to_wifi():
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    wlan.connect('HUAWEI-51EL07', '123456')
    while not wlan.isconnected():
        pass
    print("Connected to WiFi")

# 创建socket连接
def create_socket():
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client_socket.settimeout(5)  # 设置超时时间
    try:
        client_socket.connect((server_ip, server_port))
        return client_socket
    except:
        return None

# 连接WiFi
connect_to_wifi()

#创建用于音频录制的I2S对象
audioInI2S = I2S(0,
   sck=sck_pin, ws=ws_pin, sd=sd_pin,
   mode=I2S.RX,
   bits=bitsPerSample,
   format=I2S.STEREO,
   rate=sampleRate,
   ibuf=bufSize)
#音频数据读取缓冲
readBuf = bytearray(bufSize)


#SPI 1的使能端口
cs=Pin(14,Pin.OUT)
#使用SPI
spi=SPI(1,baudrate=8000000,sck=Pin(25),mosi=Pin(26),miso=Pin(27))

#创建音频文件的文件头
headData=createWavHeader(sampleRate, bitsPerSample, 2, datasize)

print("ready.......")
#休眠一点时间
utime.sleep(2.0)


# 计算音频数据的均值
def calculate_audio_mean(audio_data):
    total = sum(audio_data)
    mean = total / len(audio_data)
    return mean
# 设置阈值
sound_threshold = 1000

# 休眠一点时间
utime.sleep(2.0)


# 循环录制音频并发送
client_socket = None
try:
    while True:
        if not client_socket:
            client_socket = create_socket()
            if not client_socket:
                print("Reconnecting...")
                utime.sleep(5)
                continue
        try:
            # 读取音频数据
            currByteCount = audioInI2S.readinto(readBuf)
            audio_mean = calculate_audio_mean(readBuf)
            print("音频均值:", audio_mean)
            # 发送音频数据
            client_socket.send(readBuf)
        except Exception as e:
            print("发生异常:", e)
            print("连接断开,尝试重新连接")
            client_socket.close()
            client_socket = None
except Exception as e:
    print("发生异常:", e)
finally:
    if client_socket:
        client_socket.close()
    audioInI2S.deinit()
    print("录音结束")


```python
接收端代码, 把录音数据保存到磁盘
import socket
import wave
import time
import os


def create_wav_file(filename, audio_data, sample_rate, num_channels, bits_per_sample):
    with wave.open(filename, 'wb') as wav_file:
        wav_file.setnchannels(num_channels)
        wav_file.setsampwidth(bits_per_sample // 8)
        wav_file.setframerate(sample_rate)
        wav_file.writeframes(audio_data)


def start_server(host='0.0.0.0', port=12345, output_dir='E:/111'):
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind((host, port))
    server_socket.listen(1)

    print(f"Listening on {host}:{port}...")

    conn, addr = server_socket.accept()
    print(f"Connected by {addr}")

    # 设置音频参数
    sample_rate = 8000
    num_channels = 2
    bits_per_sample = 16

    # 时间相关变量
    file_duration = 30  # 文件时长(秒)
    start_time = time.time()

    audio_data = bytearray()
    file_count = 0

    try:
        while True:
            data = conn.recv(4096)
            if not data:
                break
            audio_data.extend(data)
            # 检查是否到达文件时长
            if time.time() - start_time >= file_duration:
                # 保存文件
                file_count += 1
                filename = os.path.join(output_dir, f"audio_{file_count}.wav")
                create_wav_file(filename, audio_data, sample_rate, num_channels, bits_per_sample)
                print(f"Audio data saved to {filename}")

                # 重置变量
                start_time = time.time()
                audio_data = bytearray()
    finally:
        conn.close()


if __name__ == '__main__':
    start_server()

在这里插入图片描述
在这里插入图片描述
录制音频数据
在这里插入图片描述


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/413544.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

STM32通用定时器输入捕获

通用定时器输入捕获部分框图介绍 通用定时器输入捕获脉宽测量原理 要测量脉宽的高电平的时间:t2-t1(脉宽下降沿时间点-脉宽上升沿时间点) 假设:递增计数模式 ARR:自动重装载寄存器的值 CCRx1:t1时间点CCRx…

后台管理系统: 权限管理

权限管理 角色:一家企业而言:BOSS、运维、销售、程序员 权限:超级管理员(BOSS),是有权利操作整个项目的所有的模块 test(新媒体),只能首页、商品管理者一部分菜单数据 admin:…

微信小程序的医院体检预约管理系统springboot+uniapp+python

本系统设计的目的是建立一个简化信息管理工作、便于操作的体检导引平台。共有以下四个模块: uni-app框架:使用Vue.js开发跨平台应用的前端框架,编写一套代码,可编译到Android、小程序等平台。 语言:pythonjavanode.js…

OpenCV 16 - Qt使用opencv视觉库

1 下载好opencv视觉库 不知道怎么下载和编译opencv视觉库的可以直接使用这个 : opencvcv_3.4.2_qt 2 解压opencv包 3 打开opencv的安装目录 4.打开x86/bin 复制里面所有的dll文件,黏贴到C/windows/syswow64里面 5 新建Qt项目 6 修改pro文件:添加对应的头文件和库文件…

实验室储样瓶耐强酸强碱PFA材质试剂瓶适用新材料半导体

PFA,全名可溶性聚四氟乙烯,试剂瓶又叫取样瓶、样品瓶、广口瓶、储样瓶等。主要用于痕量分析、同位素分析等实验室,广泛应用于新兴的半导体、新材料、多晶硅、硅材、微电子等行业。 规格参考:30ml、60ml、100ml、125ml、250ml、30…

Ant for Blazor做单个表的增删查改

Ant for Blazor做单个表的增删查改 2024年02月27日花了一天时间弄出来了,基本弄好了,vs2022blazor servernet8,引用的AntDesign版本是0.17.4 代码里的model和repository是用自己牛腩代码生成器生成的东西,sqlsugar的,记得在prog…

【第二十五课】动态规划:01背包问题(acwing-2 / 思路 / c++代码 (二维数组))

目录 前言 acwing-2 01背包问题 思路 思路误区(可跳) 代码 嗯,,在网上搜了一下蓝桥杯动态规划好像出题比较多,也没有任何其他建议,现在进度可能比较慢,所以就想着先学动态规划再看数论吧,不知道对不…

【STM32备忘录】【STM32WB系列的BLE低功耗蓝牙】一、测试广播配置搜不到信号的注意事项

文章目录 一、预备知识:二、准备工具:三、FUS和无线协议栈更新流程四、广播例程测试五、DEBUG输出调试 一、预备知识: WB系列是双核单片机,用户写M4,无线协议栈使用M0新买到手的单片机,需要自己刷入使用的…

栈的概念及应用

目录 一. 概念 二. 栈的使用 三. 栈的模拟实现 四. 栈的应用 1. 改变元素的序列 2. 将递归转化为循环 3. 括号匹配 链接 4. 逆波兰表达式求值 链接 5. 出栈入栈次序匹配 链接 6. 最小栈 链接 一. 概念 栈 :一种特殊的线性表,其 只允许在固定的…

书生·浦语大模型图文对话Demo搭建

前言 本节我们先来搭建几个Demo来感受一下书生浦语大模型 InternLM-Chat-7B 智能对话 Demo 我们将使用 InternStudio 中的 A100(1/4) 机器和 InternLM-Chat-7B 模型部署一个智能对话 Demo 环境准备 在 InternStudio 平台中选择 A100(1/4) 的配置,如下图所示镜像…

使用Docker部署Nacos集群和Nginx高可用负载(9节点集群部署)

文章目录 🔊博主介绍🥤本文内容部署Nacos集群Nginx高可用负载 📢文章总结📥博主目标 🔊博主介绍 🌟我是廖志伟,一名Java开发工程师、Java领域优质创作者、CSDN博客专家、51CTO专家博主、阿里云专…

C#,动态规划(DP)N皇后问题(N Queen Problem)的回溯(Backtracking)算法与源代码

1 N皇后问题(N Queen Problem) 在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。 2 回溯算法 回溯算法实际上一个类似枚…

我把steam游戏搬砖当副业,一个月赚7K+想给有梦想的人提个醒

假如你不工作了,还有收入吗?去掉日常的开销,还剩多少呢?可以靠steam游戏搬砖项目翻身吗?总以为,只要卖力工作,努力赚钱,就能实现财富自由。殊不知, 你的死工资&#xff0…

如何在Linux Ubuntu系统使用Docker快速部署MongoDB并公网访问

文章目录 前言1. 安装Docker2. 使用Docker拉取MongoDB镜像3. 创建并启动MongoDB容器4. 本地连接测试5. 公网远程访问本地MongoDB容器5.1 内网穿透工具安装5.2 创建远程连接公网地址5.3 使用固定TCP地址远程访问 前言 本文主要介绍如何在Linux Ubuntu系统使用Docker快速部署Mon…

TypeScript 用起来真是太痛苦了

此前我写了几篇文章,关于 Electron,关于 Vue,创建项目的时候,我都默认选择了使用 TypeScript 的模板,不过我都加了一句话,初学者如果不想自己找麻烦的话,最好不要使用 TypeScript。原因呢&#…

QT-Day5

思维导图 #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);if(!db.contains("stuInfo.db")){//说明数据库不存在db QSqlDatabase::addDatabase("…

TikTok矩阵系统的功能展示:深入解析与源代码分享!

今天我来和大家说说TikTok矩阵系统,在当今数字化时代,社交媒体平台已成为人们获取信息、交流思想和娱乐放松的重要渠道,其中,TikTok作为一款全球知名的短视频社交平台,凭借其独特的创意内容和强大的算法推荐系统&#…

20. 【Linux教程】emacs 编辑器

前面小节介绍了如何使用 vim 编辑器和 nano 编辑器,本小节介绍 emacs 编辑器,emacs 编辑器最开始是作为控制台的编辑器,并且 emacs 编辑器仍然提供最早的命令行模式。 1. 检查 Linux 系统中是否安装 emacs 编辑器 使用如何命令检查 emacs 编…

小主机折腾记22

最近总是心不在焉,于是决定把家里的海景房机箱升级下,顺便把之前剩的x99散热器,蓝宝石RX590,内存硬盘等利用上 咸鱼买了一个长城G6 淘宝买了一张X99D4M4(4相8倍供电那款) 今天主板到了,开整 先测…

DO-248C:Do-178C和Do-278A的支持信息-常见问题解答 (FAQ) (2)

3.0 常见问题解答 (FAQ) FREQUENTLY ASKED QUESTIONS (FAQ) 本节汇总了 DO-178C 和 DO-278A 常见问题解答。 常见问题解答的目的是对业界经常提出的有关 DO-178C 和/或 DO-278A 材料的问题提供简短而简洁的答复。 这些问题经常向认证机构或提供 DO-178C 和/或 DO-278A 解释的其…
最新文章