我目前正在尝试在 Python 中生成声音,我很好奇如何采用代表波形的 n 数组(采样率为 44100 Hz)并播放它。我在这里寻找纯Python,而不是依赖于仅支持.wav 格式的库。
或使用sounddevice模块。使用
pip install sounddevice
安装,但您首先需要这个:sudo apt-get install libportaudio2
绝对基础:
import numpy as np
import sounddevice as sd
sd.play(myarray)
#may need to be normalised like in below example
#myarray must be a numpy array. If not, convert with np.array(myarray)
更多选项:
import numpy as np
import sounddevice as sd
#variables
samplfreq = 100 #the sampling frequency of your data (mine=100Hz, yours=44100)
factor = 10 #incr./decr frequency (speed up / slow down by a factor) (normal speed = 1)
#data
print('..interpolating data')
arr = myarray
#normalise the data to between -1 and 1. If your data wasn't/isn't normalised it will be very noisy when played here
sd.play( arr / np.max(np.abs(arr)), samplfreq*factor)
您应该使用图书馆。用纯 Python 编写所有内容可能需要数千行代码才能与音频硬件交互!
有图书馆,例如audiere,就这么简单:
import audiere
ds = audiere.open_device()
os = ds.open_array(input_array, 44100)
os.play()
还有 pyglet、pygame 等等......
编辑:
audiere
上面提到的模块似乎不再维护,但我对依赖库的建议保持不变。在这里选择当前的项目:
https://wiki.python.org/moin/Audio/
https://pythonbasics.org/python-play-sound/
这里没有太多高级 stdlib“包含电池”的原因是因为与音频硬件的交互可能非常依赖于平台。
我想你可以看看这个清单 http://wiki.python.org/moin/PythonInMusic 它列出了许多用于处理声音的有用工具。
要播放给定 16 位样本数组 input_array 的声音。这是来自 pyadio 文档页面
的修改示例import pyaudio
# instantiate PyAudio (1)
p = pyaudio.PyAudio()
# open stream (2), 2 is size in bytes of int16
stream = p.open(format=p.get_format_from_width(2),
channels=1,
rate=44100,
output=True)
# play stream (3), blocking call
stream.write(input_array)
# stop stream (4)
stream.stop_stream()
stream.close()
# close PyAudio (5)
p.terminate()
这是取自 stackoverflow 答案的一段代码,并添加了一个播放 numpy 数组(scipy 加载的声音文件)的示例:
from wave import open as waveOpen
from ossaudiodev import open as ossOpen
from ossaudiodev import AFMT_S16_NE
import numpy as np
from scipy.io import wavfile
# from https://stackoverflow.com/questions/307305/play-a-sound-with-python/311634#311634
# run this: sudo modprobe snd-pcm-oss
s = waveOpen('example.wav','rb')
(nc,sw,fr,nf,comptype, compname) = s.getparams( )
dsp = ossOpen('/dev/dsp','w')
print(nc,sw,fr,nf,comptype, compname)
_, snp = wavfile.read('example.wav')
print(snp)
dsp.setparameters(AFMT_S16_NE, nc, fr)
data = s.readframes(nf)
s.close()
dsp.write(snp.tobytes())
dsp.write(data)
dsp.close()
基本上你只需调用 tobytes() 方法即可;然后可以播放返回的字节数组。
附注这个方法超级快