在Raspberry Pi上使用Python,我无法通过Thonny/terminal使用PyAudio录制音频

2024-06-01 04:56:53 发布

您现在位置:Python中文网/ 问答频道 /正文

使用以下示例:https://realpython.com/playing-and-recording-sound-python/#python-sounddevice_1,在使用Thonny时,我得到以下错误:“后端终止或断开连接。使用‘停止/重新启动’重新启动。”。当我在终端中运行程序时,得到的错误是:“OSError:[Errno-9981]输入溢出”。如果我修改示例代码,使其在溢出时不引发异常“data=stream.read(chunk,exception\u on\u overflow=False)”,则该示例代码(未线程化)可以在terminal和Thonny中工作,但在新线程中不工作。我还尝试将块大小更改为越来越大,越来越小,但没有效果。当线程版本出现溢出异常时,终端中会出现另一个错误:“分段错误”。我正在运行Raspbian10Buster和Python3.7.3,如果有人能测试/看看它是否有效,谢谢

import time
import board
import busio
import digitalio
from adafruit_mcp230xx.mcp23017 import MCP23017
from adafruit_debouncer import Debouncer
i2c = busio.I2C(board.SCL, board.SDA)
mcp = MCP23017(i2c)

import threading
import pyaudio
import wave
import sys
import subprocess

record = False

def background_audio_recording():
    
    #chunk = 1024  # Record in chunks of 1024 samples
    chunk = 1024
    sample_format = pyaudio.paInt16  # 16 bits per sample
    channels = 2
    fs = 44100  # Record at 44100 samples per second
    #seconds = 3
    filename = "output.wav"
    
    p = pyaudio.PyAudio()  # Create an interface to PortAudio
    
    stream = p.open(format=sample_format,
        channels=channels,
        rate=fs,
        frames_per_buffer=chunk,
        #input_device_index = 2,
        input=True)
    
    frames = []  # Initialize array to store frames
    
    while record:
        #data = stream.read(chunk, exception_on_overflow = False)
        data = stream.read(chunk)
        frames.append(data)
    '''
    for i in range(0, int(fs / chunk * seconds)):
        data = stream.read(chunk)
        frames.append(data)
    '''
    # Stop and close the stream 
    stream.stop_stream()
    stream.close()
    # Terminate the PortAudio interface
    p.terminate()
    
    print('Finished recording')
    
    # Save the recorded data as a WAV file
    wf = wave.open(filename, 'wb')
    wf.setnchannels(channels)
    wf.setsampwidth(p.get_sample_size(sample_format))
    wf.setframerate(fs)
    wf.writeframes(b''.join(frames))
    wf.close()

    print("File Saved")

    return

button1PinSetup = mcp.get_pin(0) # GPA0
button1PinSetup.direction = digitalio.Direction.INPUT
button1PinSetup.pull = digitalio.Pull.UP
button1Pin = Debouncer(button1PinSetup)

button2PinSetup = mcp.get_pin(1) # GPA1
button2PinSetup.direction = digitalio.Direction.INPUT
button2PinSetup.pull = digitalio.Pull.UP
button2Pin = Debouncer(button2PinSetup)

while True:
    button1Pin.update()
    button2Pin.update()
    if button1Pin.fell:
        print("Record")
        if record == True:
            print("Already Recording")
        else:
            record = True
            threading.Thread(target=background_audio_recording).start()
    if button2Pin.fell:
        print("Recording Stopped")
        record = False

Tags: sampleimportfalseformatreaddatastreamframes
1条回答
网友
1楼 · 发布于 2024-06-01 04:56:53

看起来,我需要将PyAudio对象创建为一个全局对象,以及在线程内(对于每次额外的录制尝试)。我用下面的代码工作

import pyaudio
import wave
import time
import threading

import board
import busio
import digitalio
from adafruit_mcp230xx.mcp23017 import MCP23017
from adafruit_debouncer import Debouncer
i2c = busio.I2C(board.SCL, board.SDA)
mcp = MCP23017(i2c)

form_1 = pyaudio.paInt16 # 16-bit resolution
chans = 2 # 1 channel
samp_rate = 44100 # 44.1kHz sampling rate
chunk = 4096 # 2^12 samples for buffer
#record_secs = 3 # seconds to record
dev_index = 2 # device index found by p.get_device_info_by_index(ii)
wav_output_filename = 'test1.wav' # name of .wav file

audio = pyaudio.PyAudio() # create pyaudio instantiation

record = False

def background_audio_recording():
    audio = pyaudio.PyAudio() # create pyaudio instantiation
    # create pyaudio stream
    stream = audio.open(format = form_1,rate = samp_rate,channels = chans, \
                    input_device_index = dev_index,input = True, \
                    frames_per_buffer=chunk)
    print("recording")
    frames = []

    # loop through stream and append audio chunks to frame array
    #for ii in range(0,int((samp_rate/chunk)*record_secs)):
    while record == True:
        data = stream.read(chunk)
        frames.append(data)

    print("finished recording")

    # stop the stream, close it, and terminate the pyaudio instantiation
    stream.stop_stream()
    stream.close()
    audio.terminate()
    
    # save the audio frames as .wav file
    wavefile = wave.open(wav_output_filename,'wb')
    wavefile.setnchannels(chans)
    wavefile.setsampwidth(audio.get_sample_size(form_1))
    wavefile.setframerate(samp_rate)
    wavefile.writeframes(b''.join(frames))
    wavefile.close()
    return


button1PinSetup = mcp.get_pin(0) # GPA0
button1PinSetup.direction = digitalio.Direction.INPUT
button1PinSetup.pull = digitalio.Pull.UP
button1Pin = Debouncer(button1PinSetup)

button2PinSetup = mcp.get_pin(1) # GPA1
button2PinSetup.direction = digitalio.Direction.INPUT
button2PinSetup.pull = digitalio.Pull.UP
button2Pin = Debouncer(button2PinSetup)

while True:
    button1Pin.update()
    button2Pin.update()
    if button1Pin.fell:
        print("Record")
        if record == True:
            print("Already Recording")
        else:
            record = True
            threading.Thread(target=background_audio_recording).start()
    if button2Pin.fell:
        print("Recording Stopped")
        record = False

相关问题 更多 >