首页 > 解决方案 > 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 倍的样本长度,这样它就不会被播放。但显然,我们应该修复错误,而不是解决它们。

任何帮助将不胜感激!

标签: pythonpyaudio

解决方案


推荐阅读