zoukankan      html  css  js  c++  java
  • pyaudio 读取麦克风阵列信号


    -- date: 2021/1/6
    -- author: longRookie
    -- title: pyaudio 读取麦克风阵列信号


    一、确定麦克风的设备号

    host_api_index可能是用于选择设备类型;

    get_host_api_info_by_index(host_api_index)

    get_device_info_by_host_api_device_index(host_api_index, host_api_device_index)

    import pyaudio
    
    p = pyaudio.PyAudio()
    info = p.get_host_api_info_by_index(0)
    numdevices = info.get('deviceCount')
    
    for i in range(0,numdevices):
        if (p.get_device_info_by_host_api_device_index(0,i).get('maxInputChannels')) > 0:
            print('Input Device id ',i,'-',p.get_device_info_by_host_api_device_index(0,i).get('name'))
    

    二、录制语音

    import pyaudio
    import pyaudio as py
    import wave
    import time
    
    # 录制音频采用回调模式
    
    # 缓存中存放帧数
    CHUNK = 1024
    # 量化位数为16位
    RESPEAKER_WIDTH = 2
    # 声道数,1声道为ASR处理语音,2-5声道为未经处理的麦克风单声道语音,6声道为合并语音(6声道未显示过)
    RESPEAKER_CHANNELS = 6
    # 对于语音信号的频率范围通常更窄(低于8000Hz),因此通常使用16000Hz的采样率;
    RESPEAKER_RATE = 16000
    # 采样时间
    RECORD_SECONDS = 5
    # 输出文件名称
    WAVE_OUTPUT_FILENAME = "output1.wav"
    # device index
    RESPEAKER_INDEX = 6
    
    # 初始化pyaudio,sets up the portaudio system
    p = py.PyAudio()
    c = 0
    
    # To record or play audio,open a stream on the desired device with the desired parameters
    # The function has the following signature callback(<input_data>, <frame_count>, <time_info>, <status_flag>)
    # and must return a tuple containing frame_count frames of audio data and a flag signifying
    # whether there are more frames to play/record.
    # 回调函数,调用在另一个单独的线程,其中包含了frame_count帧的语音数据
    # 在回调模式中,read是不能被调用的
    
    
    frames = []
    def callback(input_data, frame_count, time_info, status):
        global c ,CHUNK, RECORD_SECONDS
        global frames
        print("get the {}th {} frames input_data".format(c, frame_count))
        c += 1
        frames.append(input_data)
        # time.sleep(1)
        if c == RESPEAKER_RATE // CHUNK * RECORD_SECONDS:
            return (input_data,py.paComplete)
        return (input_data, py.paContinue)
    
    
    stream = p.open(
        # 采样率
        rate=RESPEAKER_RATE,
        # 量化位数
        format=p.get_format_from_width(RESPEAKER_WIDTH),
        # 语音通道数
        channels=RESPEAKER_CHANNELS,
        # 开启record
        input=True,
        # 具体输入设备
        input_device_index=RESPEAKER_INDEX,
        stream_callback=callback
    )
    # start the stream (4)
    stream.start_stream()
    
    # wait for stream to finish (5)
    while stream.is_active():
        time.sleep(0.1)
    
    # stop stream (6)
    stream.stop_stream()
    stream.close()
    
    # close PyAudio (7)
    p.terminate()
    wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
    wf.setnchannels(RESPEAKER_CHANNELS)
    wf.setsampwidth(p.get_sample_size(p.get_format_from_width(RESPEAKER_WIDTH)))
    wf.setframerate(RESPEAKER_RATE)
    wf.writeframes(b''.join(frames))
    wf.close()
    print("ok")
    

    关于代码的备注:

    这个代码主要是为了测试回调模式下,即非阻塞模式的录音方式,主要解答了几个困惑:

    1. 选择非阻塞模式的理由:因为要对语音数据进行实时处理,所以不能采用阻塞模式(blocking mode),在回调函数中完成对语音信号的处理。
    2. 在回调函数中,回调函数会单独开辟一个线程。
    3. 处理的逻辑:处理流程是stream是一个流,实时获取麦克风语音数据,而回调函数会每次当有新的语音数据,会调用回调函数,传入frame_count帧的语音数据,回调函数会处理,处理完毕后,返回frame_count的数据,以及是否继续的标志。如果继续,即返回paContinue,当stream流依然活着,就继续调用回调函数,传入的数据是现在stream中的frame_count帧的语音数据。可以理解为stream是一直流动的,而回调函数只从这流动的线中,截取当前的一段距离进行处理。
    4. 为了保证主线程不死,在主线程中不断休眠。
  • 相关阅读:
    在Apache下开启SSI配置
    ERROR 1290
    windows系统下Python环境的搭建
    php BC高精确度函数库
    mysql客户端(Navicat)远程登录操作遇到问题1142
    C与C++不同
    网易云课堂_C语言程序设计进阶_第七周:文件:文件访问、格式化输入输出、二进制输入输出
    面向对象程序设计-C++_课时30运算符重载——基本规则_课时31运算符重载——原型_课时32运算符重载——赋值_课时33运算符重载——类型转换
    面向对象程序设计-C++_课时28静态对象_课时29静态成员
    面向对象程序设计-C++_课时26拷贝构造Ⅰ_课时27拷贝构造Ⅱ
  • 原文地址:https://www.cnblogs.com/AccompanyingLight/p/15770574.html
Copyright © 2011-2022 走看看