使用 pyaudio 播放的声音似乎正确但太短
Sound played with pyaudio seems correct but too short
我正在制作一个小程序来传送简单的调幅正弦声音。这种声音被称为 ASSR,它代表听觉稳态反应,这是一种可再生的大脑 activity 反应。我选择使用 pyaudio
,但它的文档很少。如果你知道任何其他库可以播放 numpy array/sound,我正在听 ;)
传递的声音是 1000 Hz 载波正弦声音,振幅调制为 40 Hz。我的问题如下:当我用pyaudio播放声音时; 它不会持续 1 秒。它仅持续约 500 毫秒。然而,数组 .signal
的长度为 44100 个元素,采样频率为 44100 Hz。此外,如果我使用 scipy
将数组保存到 .wav 文件,我会得到一个 1s 的录音,它听起来与 pyaudio 提供的 500 毫秒的声音完全相同。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import pyaudio
import numpy as np
from scipy.io.wavfile import write
class Sound:
def __init__(self, fs=44100, duration=1.0):
self.fs = int(fs)
self.duration = duration
self.t = np.linspace(0, duration, int(duration*fs), endpoint=False)
self.signal = None
def play(self):
p = pyaudio.PyAudio()
stream = p.open(format=pyaudio.paFloat32,
channels=1,
rate=self.fs,
output=True)
try:
stream.write(self.signal)
except:
raise
finally:
stream.stop_stream()
stream.close()
p.terminate()
def write(self, fname):
data = np.int16(self.signal/np.max(np.abs(self.signal)) * 32767) # Scale
write(fname, self.fs, data)
class ASSR(Sound):
def __init__(self, fc, fm, fs=44100, duration=1.0):
super().__init__(fs, duration)
self.fc = fc
self.fm = fm
def classical_AM(self):
self.assr_amplitude = (1-np.sin(2*np.pi*self.fm*self.t))
self.signal = self.assr_amplitude * np.sin(2*np.pi*self.fc*self.t)
self.signal = self.signal / np.max(self.signal) # Nomalized in [-1, 1]
self.signal = self.signal.astype(np.float32)
if __name__ == '__main__':
sound = ASSR(fc=1000, fm=40)
sound.classical_AM()
sound.play()
您可以在上面找到一个极简主义的可复制示例。我的代码有点长,因为我为声音实现了一些错误检查和一些替代方程。
我认为解决方案是将信号数组转换为字节。
stream.write(signal.tobytes())
如果有人有documentation/explanation支持此修复程序以增强对此修复程序的信心,请添加它。
我正在制作一个小程序来传送简单的调幅正弦声音。这种声音被称为 ASSR,它代表听觉稳态反应,这是一种可再生的大脑 activity 反应。我选择使用 pyaudio
,但它的文档很少。如果你知道任何其他库可以播放 numpy array/sound,我正在听 ;)
传递的声音是 1000 Hz 载波正弦声音,振幅调制为 40 Hz。我的问题如下:当我用pyaudio播放声音时; 它不会持续 1 秒。它仅持续约 500 毫秒。然而,数组 .signal
的长度为 44100 个元素,采样频率为 44100 Hz。此外,如果我使用 scipy
将数组保存到 .wav 文件,我会得到一个 1s 的录音,它听起来与 pyaudio 提供的 500 毫秒的声音完全相同。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import pyaudio
import numpy as np
from scipy.io.wavfile import write
class Sound:
def __init__(self, fs=44100, duration=1.0):
self.fs = int(fs)
self.duration = duration
self.t = np.linspace(0, duration, int(duration*fs), endpoint=False)
self.signal = None
def play(self):
p = pyaudio.PyAudio()
stream = p.open(format=pyaudio.paFloat32,
channels=1,
rate=self.fs,
output=True)
try:
stream.write(self.signal)
except:
raise
finally:
stream.stop_stream()
stream.close()
p.terminate()
def write(self, fname):
data = np.int16(self.signal/np.max(np.abs(self.signal)) * 32767) # Scale
write(fname, self.fs, data)
class ASSR(Sound):
def __init__(self, fc, fm, fs=44100, duration=1.0):
super().__init__(fs, duration)
self.fc = fc
self.fm = fm
def classical_AM(self):
self.assr_amplitude = (1-np.sin(2*np.pi*self.fm*self.t))
self.signal = self.assr_amplitude * np.sin(2*np.pi*self.fc*self.t)
self.signal = self.signal / np.max(self.signal) # Nomalized in [-1, 1]
self.signal = self.signal.astype(np.float32)
if __name__ == '__main__':
sound = ASSR(fc=1000, fm=40)
sound.classical_AM()
sound.play()
您可以在上面找到一个极简主义的可复制示例。我的代码有点长,因为我为声音实现了一些错误检查和一些替代方程。
我认为解决方案是将信号数组转换为字节。
stream.write(signal.tobytes())
如果有人有documentation/explanation支持此修复程序以增强对此修复程序的信心,请添加它。