使用scikits.samplerate.resample改变音频文件音调后,pygame输出杂音
我遇到的问题是关于在Python中改变音频音调的。我现在安装了这些模块:numpy、scipy、pygame,还有scikits的“samplerate”接口。
我的目标是把一个立体声文件以不同的音调播放,并尽量减少步骤。目前,我是先用pygame.sndarray
把文件加载到一个数组中,然后用scikits.samplerate.resample
进行采样率转换,最后再把输出转换回声音对象,以便用pygame播放。
但问题是,我的扬声器里播放出来的音频很糟糕。肯定是我漏掉了一些步骤(而且我对数学和音频也不太了解)。
import time, numpy, pygame.mixer, pygame.sndarray
from scikits.samplerate import resample
pygame.mixer.init(44100,-16,2,4096)
# choose a file and make a sound object
sound_file = "tone.wav"
sound = pygame.mixer.Sound(sound_file)
# load the sound into an array
snd_array = pygame.sndarray.array(sound)
# resample. args: (target array, ratio, mode), outputs ratio * target array.
# this outputs a bunch of garbage and I don't know why.
snd_resample = resample(snd_array, 1.5, "sinc_fastest")
# take the resampled array, make it an object and stop playing after 2 seconds.
snd_out = pygame.sndarray.make_sound(snd_resample)
snd_out.play()
time.sleep(2)
4 个回答
0
很可能,scikits.samplerate.resample这个工具认为你的音频格式不是16位立体声。你可以查看一下scikits.samplerate的文档,看看在哪里可以选择你数组中正确的音频格式。如果它把16位的音频当成8位的垃圾来处理,那出来的结果就会很糟糕。
3
你最好的选择可能是使用 Python 的 audiere 库。
这里有一个链接,我用它做过类似的事情,真的很简单,只要好好看看所有的文档就行。
11
你的问题是,pygame可以处理 numpy.int16
类型的数组,但你调用 resample
函数时返回的是 numpy.float32
类型的数组:
>>> snd_array.dtype
dtype('int16')
>>> snd_resample.dtype
dtype('float32')
你可以使用 astype
将 resample
的结果转换成 numpy.int16
类型:
>>> snd_resample = resample(snd_array, 1.5, "sinc_fastest").astype(snd_array.dtype)
通过这个修改,你的Python脚本可以很好地播放 tone.wav
文件,声音会变得更低、更慢。