用Python生成/合成声音?

53

Python是否可以生成简单的正弦波声音?

是否有可用的模块来实现这个功能?如果没有,如何创建自己的模块?

此外,需要一些主机环境才能运行python来播放声音吗?还是只需从终端发出调用就可以实现?

如果答案与操作系统相关,则我使用的是Mac。


6
哦,多么讽刺啊,经过一整天用不同的关键词搜索后,这是第一个谷歌搜索结果。 - user3717756
我会推荐你去看看Pyo。这里有一个不错的起始示例:链接 - mobeets
7个回答

44

我也在寻找同样的东西,最终我写出了这段代码,它可以正常运行。

import math        #import needed modules
import pyaudio     #sudo apt-get install python-pyaudio

PyAudio = pyaudio.PyAudio     #initialize pyaudio

#See https://en.wikipedia.org/wiki/Bit_rate#Audio
BITRATE = 16000     #number of frames per second/frameset.      

FREQUENCY = 500     #Hz, waves per second, 261.63=C4-note.
LENGTH = 1     #seconds to play sound

BITRATE = max(BITRATE, FREQUENCY+100)

NUMBEROFFRAMES = int(BITRATE * LENGTH)
RESTFRAMES = NUMBEROFFRAMES % BITRATE
WAVEDATA = ''    

#generating wawes
for x in xrange(NUMBEROFFRAMES):
 WAVEDATA = WAVEDATA+chr(int(math.sin(x/((BITRATE/FREQUENCY)/math.pi))*127+128))    

for x in xrange(RESTFRAMES): 
 WAVEDATA = WAVEDATA+chr(128)

p = PyAudio()
stream = p.open(format = p.get_format_from_width(1), 
                channels = 1, 
                rate = BITRATE, 
                output = True)

stream.write(WAVEDATA)
stream.stop_stream()
stream.close()
p.terminate()

4
这个方法可行,但在播放结束时会产生很大的“噼啪”声。 - Cerin
3
为什么我们需要将这些整数转换为 ASCII 字符? - Null Salad
11
@Cerin 这是因为它输出的最后一个样本距离零非常远,然后您的扬声器在单个样本内突然返回到零,这会产生相当大的噪音。如果您在录制结尾时提供一些渐弱至零的样本或确保您的波形已回到(接近)零,您将获得更清晰的结尾。 - Robert Mock
3
请问什么是“RESTRAMES”,为什么需要在“WAVEDATA + chr(128)”后添加内容? - jtschoonhoven
1
如果 p = PyAudio() 返回 attempt to connect to server failed,则您需要先运行 jack_server_control - K. Frank
显示剩余4条评论

21

我知道我来晚了,但这是一个非常棒的Python项目,用于合成和音频作曲:https://github.com/hecanjog/pippi

它仍在积极开发中,但已经进行了一段时间。


9
未来五年,它仍在积极开发中。 :O - lelloman

7

在浪费时间后,我发现了Python模块wavebender,它可以生成单个或多个通道的正弦、方波和组合波。结果可以写入波形文件或sys.stdout,从那里可以被aplay实时直接解释。一些有用的示例在这里进行了说明,并包含在项目的GitHub页面中。


3
你好 - 我是《pippi》的作者。它已经发布了一段时间,但我正在努力实现一个稳定的1.0版本。如果你有时间在 GitHub 上提交关于你遇到的问题的错误报告,我将不胜感激。谢谢! - user5564
谢谢,我很乐意再次研究一下,并看看我能否有所贡献。 很高兴听到它还活着! - J. Katzwinkel
不幸的是,Wavebender 仍然似乎是无法正常工作且未得到维护。 - Cerin

6

5
我正在开发一个强大的Python合成器。我使用自定义函数直接将数据写入.wav文件,也可以使用内置函数实现此目的。您需要修改.wav文件头以反映采样率、每个采样的位数、通道数量和合成时长。
这是早期版本的正弦波生成器,它输出一系列值,经过bytearray处理后可写入wave文件数据参数。[编辑]在应用bytearray之前,需要进行转换,将列表转换为小端十六进制值。有关.wav规范的详细信息,请参见下面的WAVE PCM声音文件格式链接。[/编辑]
def sin_basic(freq, time=1, amp=1, phase=0, samplerate=44100, bitspersample=16):
    bytelist = []
    import math
    TwoPiDivSamplerate = 2*math.pi/samplerate
    increment = TwoPiDivSamplerate * freq
    incadd = phase*increment
    for i in range(int(samplerate*time)):
        if incadd > (2**(bitspersample - 1) - 1):
            incadd = (2**(bitspersample - 1) - 1) - (incadd - (2**(bitspersample - 1) - 1))
        elif incadd < -(2**(bitspersample - 1) - 1):
            incadd = -(2**(bitspersample - 1) - 1) + (-(2**(bitspersample - 1) - 1) - incadd)
        bytelist.append(int(round(amp*(2**(bitspersample - 1) - 1)*math.sin(incadd))))
        incadd += increment
    return bytelist

新版本可以使用波形来调制波形参数的频率、振幅和相位。数据格式使得混合和连接波形变得十分简单。如果您对此感兴趣,可以查看 WAVE PCM音频文件格式


3

我喜欢PyAudiere,它可以让您将numpy数组作为声音播放...我想这与我的Matlab背景非常契合。我相信它是跨平台的。我认为scikits.audiolab也可以做到同样的事情,并且可能更为先进/得到更好的支持...对我来说似乎比尝试将东西保存为wav文件或将它们写入缓冲区并使用Python的内置声音库要容易。


4
据我所见,似乎无法从 pypi 下载 Audiere。他们的 pyaudiere.org 网站现在变成了某个随机的广告页面。 - Mads Skjern
是的,看起来所有这些声音库在几个月后都被放弃了。这成为了一个真正的问题。也许PyGame是正确的选择。它似乎有点过头了,但至少得到了良好的支持。 - rdchambers

3

我发现这两个Python仓库非常有用,你可能想看一下...

python https://github.com/JeremyCCHsu/Python-Wrapper-for-World-Vocoder

ipythonhttps://timsainb.github.io/spectrograms-mfccs-and-inversion-in-python.html

[编辑]正如指出的那样,这是两个链接的解释

python似乎有一个错误,但很多人都能够运行它,所以我不确定。 ipython 运行得非常好,所以希望你能运行它。

这两个链接都应该将音频作为输入,最好是.wav文件。使用FFT:512、步长=512/8对其进行特征提取,以获得声谱图(甚至可以可视化)。这是一个二维矩阵,然后使用表示原始音频的矩阵来训练您的机器学习对象或执行您想要的任何操作。如果您想,在任何时候,了解这些向量表示什么,您也可以将音频重新合成。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接