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

[raspberrypi 0w and respeaker 2mic]实时音频波形

0. 环境

ubuntu22主机,    192.168.8.162,
raspberry 0w,    192.168.8.220
路由器
 

1. 树莓派

# rpi - send.py
# 或者命令行:arecord -D plughw:1,0 -t wav -f cd -r 16000 -c 2 | nc 192.168.8.162 12345

import socket
import pyaudio

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
host = '192.168.8.162'
port = 12345

s.connect((host, port)) 

RESPEAKER_RATE = 16000
RESPEAKER_CHANNELS = 2
RESPEAKER_WIDTH = 2
RESPEAKER_INDEX = 0  # refer to input device id
CHUNK = 4096

p = pyaudio.PyAudio()

stream = p.open(
            rate=RESPEAKER_RATE,
            format=p.get_format_from_width(RESPEAKER_WIDTH),
            channels=RESPEAKER_CHANNELS,
            input=True,
            input_device_index=RESPEAKER_INDEX,
			frames_per_buffer=CHUNK,
			)

while True:
    data = stream.read(CHUNK, exception_on_overflow=False)
    s.sendall(data)
    #print("data.hex()", data.hex())
    print("len(data)", len(data))

stream.stop_stream()
stream.close()
s.close()

2. 电脑端

# ubuntu22主机:client - recv2micfft.py
import threading
import time
import socket
import pyaudio
import numpy as np
import matplotlib.pyplot as plt

host = '192.168.8.162'
port = 12345

RESPEAKER_RATE = 16000
RESPEAKER_CHANNELS = 2
RESPEAKER_WIDTH = 2
RESPEAKER_INDEX = 0  # refer to input device id
CHUNK = 4096
RECORD_SECONDS = 2

np_ch1 = None
np_ch2 = None


def audio_stream():
    global np_ch1
    global np_ch2
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    s.bind((host, port))
    print('server listening at',(host, (port)))

    s.listen(1)

    conn, addr = s.accept()

    p = pyaudio.PyAudio()

    stream = p.open(
        rate=RESPEAKER_RATE,
        format=p.get_format_from_width(RESPEAKER_WIDTH),
        channels=RESPEAKER_CHANNELS,
        output=True,
        input_device_index=RESPEAKER_INDEX,
        frames_per_buffer=CHUNK,
    )

    while True:
        data = conn.recv(CHUNK*RESPEAKER_CHANNELS*RESPEAKER_WIDTH)
        stream.write(data)

        np_data1 = np.fromstring(data, dtype=np.int16)[0::2]
        np_data2 = np.fromstring(data, dtype=np.int16)[1::2]

        if np_ch1 is None:
            np_ch1 = np_data1
            np_ch2 = np_data2
        elif np_ch1.shape[0] / RESPEAKER_RATE < RECORD_SECONDS:
            np_ch1 = np.append(np_ch1, np_data1)
            np_ch2 = np.append(np_ch2, np_data2)
        else:
            idx = []
            for i in range(len(np_data1)):
                idx.append(i)
            np_ch1 = np.delete(np_ch1, idx)
            np_ch2 = np.delete(np_ch2, idx)
            np_ch1 = np.append(np_ch1, np_data1)
            np_ch2 = np.append(np_ch2, np_data2)
            
    stream.stop_stream()
    stream.close()
    conn.close()
    s.close()


def fft_show():
    global np_ch1
    global np_ch2

    plt.ion()

    # fig, ax = plt.subplots()
    # 创建两个子图
    f, (ax1, ax2) = plt.subplots(2, 1)

    try:
        while True:
            if np_ch1 is None:
                continue
            # 将音频数据转换为NumPy数组
            #np_data1 = np.frombuffer(data, dtype=np.int16)[0::2]
            #np_data2 = np.frombuffer(data, dtype=np.int16)[1::2]

            # 计算频谱
            # freq_data1 = np.fft.fft(np_data1)
            # freq_data1 = np.abs(freq_data1)
            # freq_data2 = np.fft.fft(np_data2)
            # freq_data2 = np.abs(freq_data2)

            # 更新绘图
            ax1.clear()
            ax1.plot(np_ch1)
            ax2.clear()
            ax2.plot(np_ch2)

            plt.draw()
            plt.pause(0.01)

    except KeyboardInterrupt:
        print("实时频谱分析结束。")

    # 关闭绘图窗口
    plt.ioff()
    plt.close()

t1 = threading.Thread(target=audio_stream, args=())
t2 = threading.Thread(target=fft_show, args=())
t1.start()
t2.start()









相关文章:

  • UE5 运行时动态将玩家手部模型设置为相机的子物体
  • HTML视频和音频
  • springboot调用python文件,python文件使用其他dat文件,适配windows和linux,以及docker环境的方案
  • 2025年优秀的文件加密软件排名
  • PostgreSQL-容器运行时索引修复
  • 6.1es新特性解构赋值
  • spring常用的设计模式
  • MySQL基础命令
  • 【蓝桥杯】15届java研究生组E砍柴
  • UIMeter-UI自动化软件(产品级)
  • 2025前端面试题
  • C++中std::move()的正确使用相关例子
  • C语言个人笔记
  • 前端面试总结3
  • Lumion 与 Enscape 怎么选?附川翔云电脑适配指南
  • 在3ds Max中视口显示为黑色或深灰色
  • leetcode68.左右文本对齐
  • 《DeepSeek RAG 增强检索知识库系统》Ollama RAG 知识库上传、解析和验证之四
  • mysql 禁止 读 某个 表
  • 第18章:基于Global Context Vision Transformers(GCTx_unet)网络实现的oct图像中的黄斑水肿和裂孔分割
  • 做网站要用服务器吗/国内新闻最新消息今天
  • 做网站和app多少费用/网络推广的重要性与好处
  • 易语言做网站教程/产品关键词大全
  • 网站开发网络公司兼职/制作网页的软件
  • 城建公司建设网站基础资料/快速排名精灵
  • 衡阳网站建设公司电话/网站查询