值列表到音频文件
我正在尝试用Python编写一个程序,把一组0到255之间的整数值转换成1500到2200赫兹的音调。时间信息(以1200赫兹为单位)由列表中的-1、-2和-3值提供。我已经创建了一个可以生成.wav文件的函数,然后用每个音调的参数调用这个函数。
我需要创建一个“流”,可以通过把很多单独的音调拼接成一个输出文件,或者以某种方式遍历整个列表并创建一个单独的文件,或者用我不知道的其他方法来实现……
时间信息的持续时间会有所不同,但信息位(0-255)都是固定长度的。
下面是列表的一个示例:
[-2, 3, 5, 7, 7, 7, 16, 9, 10, 21, 16, -1, 19, 13, 8, 8, 0, 5, 9, 21, 19, 11, -1, 11, 16, 19, 5, 21, 34, 39, 46, 58, 50, -1, 35, 46, 17, 28, 23, 19, 8, 2, 13, 12, -1, 9, 6, 8, 11, 2, 3, 2, 13, 14, 42, -1, 35, 41, 46, 55, 73, 69, 56, 47, 45, 26, -1, -3]
我现在想到的解决方案是打开文件,使用“if”语句检查列表中的下一个值,看看这个值是否是时间信息(负值),如果不是,就运行一个算法来确定需要生成的频率,并把这个音调添加到输出文件中。一直继续,直到遇到-3或者列表结束。
有没有人能指导我如何创建这个完整的输出文件,或者有什么建议……我刚开始学习编程,所以请多多指教。谢谢!
3 个回答
我不太确定我完全理解你在问什么,但我会尽量回答。
如果不是必要的话,我不会去碰低级的WAV格式。直接使用Audiolab就可以了。
- 先初始化一个空的
song
一维数组,使用NumPy。 - 打开你的数字文件。
- 用你提到的
if
语句来判断数字是正数还是负数。 - 根据你的公式生成一个“片段”音调(这个公式我不是很明白)。
- 首先生成一个时间基准,可以用类似
t = linspace(0,1,num=48000)
的代码。 - 然后用类似
a = sin(2*pi*f*t)
的代码生成音调。
- 首先生成一个时间基准,可以用类似
- 用类似
song = concatenate((song,a))
的代码把这个片段添加到数组的其余部分。 - 循环遍历文件,创建并添加每个片段。
- 使用类似
wavwrite(song, 'filename.wav', fs, enc)
的代码写入WAV文件。
这个音调和时序的格式是你自己想出来的,还是别人创造的?
你只需要把新数据加到你的wav文件的末尾就行了。如果你还没关闭文件,就继续写;如果已经关闭了,就用追加模式重新打开它(w = open(myfile, 'ba')
),然后写入新数据。
为了让声音听起来顺畅,不出现咔嗒声之类的,你需要确保波形在不同频率之间是连续的。假设你使用的是相同幅度的正弦波,你需要让每个正弦波的开始相位和上一个结束的相位保持一致。你可以通过调整波形的长度,确保每次都在零相位结束,然后再从零相位开始,或者直接在正弦波中包含相位信息来做到这一点。
看起来你想要重新发明轮子,得小心哦……
如果你想从数组生成音乐,可以看看pyaudiere,这是一个简单的库,基于audiere库。查看文档了解如何打开数组,应该是这样的:
import audiere
d = audiere.open_device()
s = d.open_array(buff,fs)
s.play()
这个调用的文档说明是:
open_array(buffer, fs):
这个函数用来打开一个声音缓冲区进行播放,并返回一个OutputStream对象。缓冲区应该是一个NumPy数组,里面的值是Float32类型,列数可以是1(单声道)或2(立体声)。第二个参数是采样频率。超出+-1范围的值会被截断。