我需要在Python中生成正弦波音效,而且还需要能够控制频率、持续时间和相对音量。所谓“生成”,是指我想立即通过扬声器播放它,而不是保存到文件中。
什么是最简单的方法?
什么是最简单的方法?
使用numpy的版本:
import time
import numpy as np
import pyaudio
p = pyaudio.PyAudio()
volume = 0.5 # range [0.0, 1.0]
fs = 44100 # sampling rate, Hz, must be integer
duration = 5.0 # in seconds, may be float
f = 440.0 # sine frequency, Hz, may be float
# generate samples, note conversion to float32 array
samples = (np.sin(2 * np.pi * np.arange(fs * duration) * f / fs)).astype(np.float32)
# per @yahweh comment explicitly convert to bytes sequence
output_bytes = (volume * samples).tobytes()
# for paFloat32 sample values must be in range [-1.0, 1.0]
stream = p.open(format=pyaudio.paFloat32,
channels=1,
rate=fs,
output=True)
# play. May repeat with different volume values (if done interactively)
start_time = time.time()
stream.write(output_bytes)
print("Played sound for {:.2f} seconds".format(time.time() - start_time))
stream.stop_stream()
stream.close()
p.terminate()
没有使用numpy的版本:
import array
import math
import time
import pyaudio
p = pyaudio.PyAudio()
volume = 0.5 # range [0.0, 1.0]
fs = 44100 # sampling rate, Hz, must be integer
duration = 5.0 # in seconds, may be float
f = 440.0 # sine frequency, Hz, may be float
# generate samples, note conversion to float32 array
num_samples = int(fs * duration)
samples = [volume * math.sin(2 * math.pi * k * f / fs) for k in range(0, num_samples)]
# per @yahweh comment explicitly convert to bytes sequence
output_bytes = array.array('f', samples).tobytes()
# for paFloat32 sample values must be in range [-1.0, 1.0]
stream = p.open(format=pyaudio.paFloat32,
channels=1,
rate=fs,
output=True)
# play. May repeat with different volume values (if done interactively)
start_time = time.time()
stream.write(output_bytes)
print("Played sound for {:.2f} seconds".format(time.time() - start_time))
stream.stop_stream()
stream.close()
p.terminate()
SystemError: 必须为 '#' 格式定义 PY_SSIZE_T_CLEAN 宏
- Tomasz Gandorivan-onys给出了一个很好的答案,但是还有一点需要补充: 该脚本将产生比预期短4倍的声音,因为Pyaudio write方法需要float32类型的字符串数据,但是当你将numpy数组传递给该方法时,它会将整个数组转换为字符串实体,因此你必须自己将numpy数组中的数据转换为字节序列,像这样:
samples = (np.sin(2*np.pi*np.arange(fs*duration)*f/fs)).astype(np.float32).tobytes()
而且你也必须更改这一行:
stream.write(samples)
在Python中,处理声音的一种比较稳定且易于安装的方式是使用Pygame多媒体库。
我建议使用它 - 有pygame.sndarray子模块,可以允许您操作数据向量中的数字,这些数字将成为高级声音对象,可以在pygame.mixer模块中播放。
pygame.org网站上的文档足以使用sndarray模块。
对于 Python 3.5+,最好的方法是安装开发人员推荐的包。
http://people.csail.mit.edu/hubert/pyaudio/
对于 Debian,请执行以下操作:
sudo apt-get install python3-all-dev portaudio19-dev
在尝试安装Pyaudio之前
stream.write((volume*samples).tobytes())