python - PyAudio:stream.write() 只播放它应该播放的长度的 1/4
问题描述
我这里有一个 pyAudio 流媒体类,播放可以连续播放多个单频声音。
import pyaudio
import numpy as np
class SingleFrequencyPlayer:
def __init__(self, fs=44100):
self.p = pyaudio.PyAudio()
self.samples=np.ones((0), dtype=np.float32)
self.log=[]
self.fs=fs #fs: sampling rate, Hz, must be integer
def add_samples(self, volume, duration, f):
#volume: range [0.0, 1.0]
#duration: in seconds, may be float
#f: sine frequency, Hz, may be float
# generate samples, note conversion to float32 array
samples = (np.sin(2*np.pi*np.arange(self.fs*duration)*f/self.fs)).astype(np.float32)
self.samples=np.append(self.samples,samples*volume)
self.log+=[[volume, duration, f]]
def play_sound(self):
# for paFloat32 sample values must be in range [-1.0, 1.0]
stream = self.p.open(format=pyaudio.paFloat32,
channels=1,
rate=self.fs,
output=True)
# play. May repeat with different volume values (if done interactively)
stream.write(self.samples)
stream.stop_stream()
stream.close()
但是,我遇到了问题。从 stream.write() 发出的声音只有给定持续时间的 1/4。但是,它仍然会播放给定的不同声音的正确持续时间。
例如,如果我告诉它播放 5 秒 500Hz,它只会播放 1.25 秒或 5/4 秒。如果我改为让它播放 5 秒 500Hz,然后播放 75 秒 900Hz,它将继续正确播放 500Hz 的前 5 秒,然后只播放 15 秒 900Hz,总共 20 秒。 80.
我不确定为什么会这样。我认为这是因为我使用的 pyaudio.paFloat32 格式一次读取 4 个字节。但是,如果我让它使用一次读取 1 个字节的格式,则声音不正确。此外,我写入流的数组具有正确的格式(np.float32)。所以,我不确定如何进行。我目前的解决方法是在其中添加 3 倍的样本长度,这样它就不会被播放。但显然,我们应该修复错误,而不是解决它们。
任何帮助将不胜感激!
解决方案
推荐阅读
- python - 使用 Python 转换 DataFrame
- aws-amplify - AWS Amplify 发布到自定义域
- google-apps-script - Google Sheets 脚本可在多页文档中打开最后修改的表单
- php - 如何更改 laravel 框架上的搜索地址?
- python - 如何使用 Python 测试是否在函数内部调用了实例方法?
- css - 为单选按钮添加无效的类 CSS
- c# - 已发布的 .NET 框架 3.5 程序在安装期间需要 .NET 框架 4.7.2
- javascript - jQuery for 循环仅获取第一项值
- c - 如何创建具有动态行和列大小的动态字符数组
- laravel-5.8 - 在 checkAdmin 和 CheckUser 中间件条件为真后,Laravel 页面无法正常工作