gpt4 book ai didi

python - 在 "if"条件下录制音频会导致静态

转载 作者:太空宇宙 更新时间:2023-11-03 16:51:17 26 4
gpt4 key购买 nike

我的目标是在按下按钮时录制声音。

第一步实际上是录制音频。下面的脚本就像一个魅力:

import alsaaudio, wave, numpy

inp = alsaaudio.PCM(alsaaudio.PCM_CAPTURE, alsaaudio.PCM_NORMAL, "default:CARD=C525")
inp.setchannels(1)
inp.setrate(44100)
inp.setformat(alsaaudio.PCM_FORMAT_S16_LE)
inp.setperiodsize(1024)

w = wave.open('test.wav', 'w')
w.setnchannels(1)
w.setsampwidth(2)
w.setframerate(44100)

while True:
l, data = inp.read()
a = numpy.fromstring(data, dtype='int16')
print numpy.abs(a).mean()
w.writeframes(data)

test.wav 文件播放起来就像一个魅力,并且声音被正确录制。

现在我只想在按下按钮时录制音频。我正在使用带按钮的 GrovePi。该按钮效果很好。它检测到按下的按钮,生成 .wav 文件,但它生成的音频文件包含纯静态。

import time
import grovepi
import alsaaudio
import os
import wave
import numpy

button = 4 #grovepi D4
grovepi.pinMode(button,"INPUT")
inputSoundDevice = "default:CARD=C525"
path = os.path.realpath(__file__).rstrip(os.path.basename(__file__))

def start():
print "started"

while True:
if grovepi.digitalRead(button) == 1:
inp = alsaaudio.PCM(alsaaudio.PCM_CAPTURE, alsaaudio.PCM_NORMAL, inputSoundDevice)
inp.setchannels(1)
inp.setrate(44100)
inp.setformat(alsaaudio.PCM_FORMAT_S16_LE)
inp.setperiodsize(1024)
time.sleep(.5)
print "inp setup"

w = wave.open('test.wav', 'w')
w.setnchannels(1)
w.setsampwidth(2)
w.setframerate(44100)
print "wave setup"

while(grovepi.digitalRead(button) == 1):
l, data = inp.read()
a = numpy.fromstring(data, dtype='int16')
print numpy.abs(a).mean()
w.writeframes(data)

time.sleep(.5)
w.close()
inp = None
print "closed"

start()

有人能指出我正确的方向来解决这个问题吗?我无法弄清楚这一点。

测试:这些操作会生成相同的静态音频文件:

  • 按下按钮时终止脚本
  • 按下按钮一次后终止脚本
  • 按两次按钮后终止脚本
  • 用循环计数器代替按钮按下操作,并记录循环计数是否在 20 到 40 之间,以确保按钮不是问题所在。

numpy 错误

File "buttonWhilePressedLight.py", line 43, in <module>
start()
File "buttonWhilePressedLight.py", line 34, in start
a = numpy.fromstring(data, dtype='int16')
ValueError: string size must be a multiple of element size

循环中的“print l”,并注释掉 numpy

started
inp setup
wave setup
940
-32
940
-32
940
<-etc,etc,etc->
closed

最佳答案

您调用的读取速度不够快。 -32 是 unix 错误代码 -EPIPE* Alsa docs说:

-EPIPE

This error means xrun (underrun for playback or overrun for capture). ... The overrun can happen when an application does not take new captured samples in time from alsa-lib.

因此声音设备生成样本的速度比您使用它们的速度更快。将按钮 digitalRead 添加到您的工作循环中会使其速度减慢太多。您已将 ALSA 设置为以 44100 个样本/秒的速度生成 1024 个样本的 block ,这意味着您需要调用 read每 23 毫秒一次。我会对读取按钮的空循环进行计时,看看需要多长时间。

根据按钮代码的速度,有几种可能的解决方案。降低采样率肯定会降低您需要调用read的频率,但也会降低音频质量。增加周期大小将填充更大的缓冲区,这意味着您需要更少地读取它们。缺点是对按钮按下的响应较差。使用 8 位样本也可能会以质量为代价来减少处理负载。

一个结构性的解决方案是去掉这个循环中读取的按钮,而只监视一个事件,您可以在中断处理程序或监视 I/O 的独立线程中设置该事件。

*顺便说一句,这似乎是 pyalsaaudio documentation 中的一个缺口。 ,或实现中的错误。没有提到 read 函数可以返回错误代码。

关于python - 在 "if"条件下录制音频会导致静态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35825630/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com