7

我正在使用 pygame 播放 .wav 文件,并希望随着游戏的每个级别的进行更改特定 .wav 文件的音高。解释一下,我的游戏几乎是旧 Oric1 计算机 OricMunch Pacman 游戏的复制品,每个关卡要咀嚼几百颗药丸,每咀嚼一颗药丸都会播放一个短促的声音,音高为每吃一颗/嚼一颗药丸,声音都会略有增加。

现在这是我尝试过的

1)我使用 pythons wave 模块创建了声音文件的多个副本,每个新创建的文件的音高略有增加(通过更改 params() 中的第三个参数帧速率,有时称为采样频率)每个for循环的循环。实现这一点后,我可以在循环中创建多个声音对象以添加到列表中,然后在列表中建立索引以在每个药丸被吃掉时播放声音。

问题是,即使我可以创建数百个文件(使用 wave 模块),在使用 windows 媒体播放器甚至 python 的 winsound 模块播放时,它们可以完美地播放它们自己独特的音高,pygame 似乎并没有解释音高的差异。

现在有趣的是,我已经下载了Power Sound Editor的免费试用版,它可以选择更改音高,因此我只创建了几个 .wav 文件进行测试,它们在 pygame 中播放时显然会使用不同的音高。

观察:通过在我的 for 循环中打印参数,我可以看到帧速率/频率正在按预期变化,因此显然这就是为什么声音通过 windows 媒体播放器和 winsound 按预期播放的原因。

在 pygame 中,我怀疑他们不使用不同音高演奏的原因是因为频率参数是固定的,无论是默认设置还是通过使用 pygame.mixer.pre_init,我确实已经尝试过。然后,我检查了 Power Sound Editor 创建的每个 .wav 文件的参数,并注意到即使音高发生了变化,频率也保持不变,这并不奇怪,因为您必须选择 3 个选项中的 1 个来保存文件,22050、44100 或 96000Hz

所以现在我想是时候检查一下音高和频率之间的差异,特别是与声音有关的差异,因为我认为它们是相同的。我发现声波似乎有两个主要方面:1)帧速率/频率和 2)基于该频率的多个波的变化幅度。现在我还没有清楚地理解这一点,但意识到 Power Sound Editor 必须通过操纵多个波的变化幅度来改变声音的形状/音高,上面的点 2),而不是通过改变基频,上面的点 1) .

我是 python、pygame 和一般编程的初学者,并且努力寻找一种简单的方法来更改声音文件以在不改变帧速率/基本频率的情况下逐渐增加音高。如果我可以导入一个模块来帮助我通过操纵多波的不同幅度来改变音高(而不是改变通常为 22050 或 44100Hz 的帧速率/采样频率),那么它需要相对没有时间如果为了不减慢游戏速度而在飞行中完成。如果潜在的模块打开,更改然后保存声音文件,而不是即时更改它们,那么我想它是否很慢并不重要,因为我只会创建声音文件,这样我就可以从中创建声音对象pygame 玩。

现在,如果在 pygame 中实现不减速的唯一方法是像我已经完成的那样从声音文件创建声音对象,然后播放它们,那么我需要一种像 Power Sound Editor 那样操作声音文件的方法(我再次强调不是通过更改通常为 22050 或 44100 的帧速率/采样频率),然后保存更改的文件。

我想简而言之,如果我可以神奇地自动化 Power Sound Editor 以生成 3 到 400 个声音文件,而无需我每次都单击更改音高选项然后保存,这就像拥有我自己的 python 做事方式它。

结论:假设从声音文件创建声音对象是不减慢游戏速度的唯一方法(我怀疑它可能是这样),那么我需要以下内容:

相当于 python wave 模块,但它像 Power Sound Editor 那样改变音高,而不是像 wave 模块那样改变基频。

请有人可以帮助我,让我知道是否有办法。

我正在使用 python 3.2.3 和 pygame 1.9.2

另外我只是使用pythons IDLE,我不熟悉使用其他编辑器。

我也知道 Numpy 和各种声音模块,但绝对不知道如何使用它们。此外,任何潜在的模块都需要使用上述版本的 python 和 pygame。

先感谢您。

加里汤森。

我对 Andbdrew 的第一个答案的回复如下:

谢谢您的帮助。

听起来我需要做的是更改波形文件数据而不是波形文件参数。这里的参考是我用来创建多个文件的代码:

framerate = 44100 #Original .wav file framerate/sample frequency

for x in range(0, 25):    
   file = wave.open ('MunchEatPill3Amp.wav')   
   nFrames = file.getnframes()
   wdata = file.readframes(nFrames) 
   params = file.getparams()     
   file.close()

   n = list(params)   
   n[0] = 2 
   n[2] = framerate

   framerate += 500 

   params = tuple(n)    
   name = 'PillSound' + str(x) + '.wav'     

   file = wave.open(name, 'wb')
   file.setparams(params)
   print(params)
   file.writeframes(wdata)
   file.close()

听起来编写不同的数据与 Power Sound Editor 更改音高的方式相同或相似。

所以请你告诉我你是否知道一种修改/操纵 wdata 以有效改变音高的方法,而不是改变 params() 中的采样率。这是否意味着从我的 .wav 文件中读取 wdata 后对它应用一些相对简单的操作。(我真的希望如此)我听说过使用 numpy 数组,但我不知道如何使用这些数组。

请注意,在上述代码中修改的任何 .wav 文件确实可以在 Python 中使用 winsound 或在 windows 媒体播放器中播放,音高增加听起来像预期的那样。只有在 Pygame 中他们没有。

正如我所提到的,似乎因为 Pygame 有一个设定频率(我猜这个频率也是采样率),这可能是音高听起来相同的原因,就好像它根本没有增加一样。而当使用 windows 媒体播放器播放时,采样率的变化确实会导致更高的音调。

我想我只需要通过更改文件数据而不是文件参数来实现相同的音高增加,所以如果你知道方法,请告诉我。

再次感谢您对此的帮助。

总结一下我最初的问题,这里又是:

如何通过使用 python 编程语言而不是某种单独的软件程序(例如 Power Sound Editor)来更改 .wav 文件的音高而不更改帧速率/采样频率?

再次感谢你。

4

2 回答 2

1

如果您只想创建多个文件并且使用的是 linux,请尝试SoX

#!/bin/bash
for i in `seq -20 10 20`; do
    sox 'input.wav' 'output_'$i'.wav' pitch $i;
done
于 2014-01-22T06:41:07.280 回答
1

您应该更改样本中波的频率,而不是更改采样率。似乎 python 正在以相同的采样率播放所有波形文件(这很好),因此您的更改不会反映。

采样率有点像声音文件的元信息。在http://en.m.wikipedia.org/wiki/Sampling_rate#mw-mf-search阅读它。

当您将连续波形转换为离散波形时,它会告诉您采样之间的时间量。尽管您(ab)使用它很酷,但最好通过以相同的采样率在不同文件中编码不同频率的声音来为您提供更好的服务。

我查看了 wave 模块的文档(http://docs.python.org/3.3/library/wave.html),看起来您应该在调用时将不同的数据写入音频文件

 Wave_write.writeframes(data)

这是实际将音频数据写入音频文件的方法。

您描述的方法负责写入有关音频文件本身的信息,而不是音频数据的内容。

 Wave_write.setparams(tuple)

“......元组应该在哪里(nchannels,sampwidth,framerate,nframes,comptype,compname),值对 set*() 方法有效。设置所有参数......“(也来自文档)

如果您发布代码,也许我们可以修复它。

于 2012-11-18T08:52:06.140 回答