值列表到音频文件

0 投票
3 回答
2065 浏览
提问于 2025-04-15 12:52

我正在尝试用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 个回答

0

我不太确定我完全理解你在问什么,但我会尽量回答。

如果不是必要的话,我不会去碰低级的WAV格式。直接使用Audiolab就可以了。

  1. 先初始化一个空的 song 一维数组,使用NumPy。
  2. 打开你的数字文件。
  3. 用你提到的 if 语句来判断数字是正数还是负数。
  4. 根据你的公式生成一个“片段”音调(这个公式我不是很明白)。
    1. 首先生成一个时间基准,可以用类似 t = linspace(0,1,num=48000) 的代码。
    2. 然后用类似 a = sin(2*pi*f*t) 的代码生成音调。
  5. 用类似 song = concatenate((song,a)) 的代码把这个片段添加到数组的其余部分。
  6. 循环遍历文件,创建并添加每个片段。
  7. 使用类似 wavwrite(song, 'filename.wav', fs, enc) 的代码写入WAV文件。

这个音调和时序的格式是你自己想出来的,还是别人创造的?

0

你只需要把新数据加到你的wav文件的末尾就行了。如果你还没关闭文件,就继续写;如果已经关闭了,就用追加模式重新打开它(w = open(myfile, 'ba')),然后写入新数据。

为了让声音听起来顺畅,不出现咔嗒声之类的,你需要确保波形在不同频率之间是连续的。假设你使用的是相同幅度的正弦波,你需要让每个正弦波的开始相位和上一个结束的相位保持一致。你可以通过调整波形的长度,确保每次都在零相位结束,然后再从零相位开始,或者直接在正弦波中包含相位信息来做到这一点。

2

看起来你想要重新发明轮子,得小心哦……

如果你想从数组生成音乐,可以看看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范围的值会被截断。

撰写回答