ESP32 + MicroPython + 录音 + 音频播放

功能:
  1. wav音频文件本地录音,并播放
  2. 录音模块:INMP441
  3. 音频模块:MAX98357
  4. 喇叭:3W

程序


from machine import I2S,SPI
from machine import Pin

import os, utime
import uos
import time

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

def start_in(sfile='s.wav', sampleRate=8000, bitsPerSample=16):
    bufSize=32768

    # 连接端口:3.3V SD->G21  WS->G22 SCK->G23  L/R-> 低电频
    #I2S所需管脚
    #数据时钟(INMP441模块SCK)
    sck_pin = Pin(23)
    #帧时钟(INMP441模块模块WS)
    ws_pin = Pin(22)
    #数据(INMP441模块模块SD)
    sd_pin = Pin(21)

    #创建用于音频录制的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)

    print("start ready.......")
    
    #休眠一点时间
    utime.sleep(2.0)
    
    
    # 检查文件是否存在
    if sfile in uos.listdir():
        # 删除文件
        print('del', sfile)
        uos.remove(sfile)
        utime.sleep(0.5)
        
    fin = open(sfile, 'wb')
    file_duration = 10 # 文件时长(秒)
    start_time = time.time()
    num_channels = 2
    
    f = True
    
    head = createWavHeader(sampleRate, bitsPerSample, num_channels, bufSize*file_duration)
    fin.write(head)
    
    print("in ready.......")
    while f:
        # 读取音频数据
        currByteCount = audioInI2S.readinto(readBuf)
        print('in ', len(readBuf))
        
        audio_data = bytearray()
        audio_data.extend(readBuf)
        fin.write(audio_data)

        # 检查是否到达文件时长
        if time.time() - start_time >= file_duration:
            f = False
            
    fin.close()
    print('in end')
    
def start_out(sfile='s.wav', sampleRate=8000, bitsPerSample=16):
    if not sfile in uos.listdir():
        print('not found ', sfile)
        return
    # 初始化引脚定义
    """
    GPIO13 -- DIN
    GPIO12 --- BCLK
    GPIO14 -- LRC
    GND -- GND
    5V或3.3V -- VCC
    """
    sck_pin = Pin(12) # 串行时钟输出
    ws_pin = Pin(14)  # 字时钟
    sd_pin = Pin(13)  # 串行数据输出
     

    # 初始化i2s
    audio_out = I2S(1, sck=sck_pin, ws=ws_pin, sd=sd_pin,
                    mode=I2S.TX, bits=bitsPerSample, format=I2S.STEREO,
                    rate=sampleRate, ibuf=20000)

    
    f = open(sfile,'rb')
 
    # 跳过文件的开头的44个字节,直到数据段的第1个字节
    pos = f.seek(44) 
 
    wav_samples = bytearray(1024)
    wav_samples_mv = memoryview(wav_samples)
     
    print("start out ...")
    
    #并将其写入I2S DAC
    while True:
        try:
            num_read = f.readinto(wav_samples_mv)
            
            # WAV文件结束
            if num_read == 0: 
                break
 
            # 直到所有样本都写入I2S外围设备
            num_written = 0
            while num_written < num_read:
                num_written += audio_out.write(wav_samples_mv[num_written:num_read])
                
        except Exception as ret:
            print("产生异常...", ret)
            break
    print(' out end')
          
print('start')
# 录音
start_in()
# 音频播放
start_out()
print('end')
运行日志
start
start ready.......
del s.wav
in ready.......
in  32768
in  32768
in  32768
in  32768
in  32768
in  32768
in  32768
in  32768
in end
start out ...
 out end
end

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值