我的问题与 Python 中的变调音频有关。我安装了当前模块:numpy、scipy、pygame 和 scikit“samplerate”api。
我的目标是获取立体声文件并以尽可能少的步骤以不同的音高进行播放。目前,我使用
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)
您的问题是 pygame 使用
numpy.int16
数组,但对 resample
的调用返回 numpy.float32
数组:
>>> snd_array.dtype
dtype('int16')
>>> snd_resample.dtype
dtype('float32')
您可以使用
resample
将 numpy.int16
结果转换为 astype
:
>>> snd_resample = resample(snd_array, 1.5, "sinc_fastest").astype(snd_array.dtype)
通过此修改,您的 python 脚本可以以较低的音调和较低的速度很好地播放
tone.wav
文件。
你最好的选择可能是使用 python audiere。
这是一个链接,我用它来做同样的事情,这很简单,只需阅读所有文档即可。
scikits.samplerate.resample 很可能“认为”您的音频是 16 位立体声以外的另一种格式。检查 scikits.samplerate 上的文档,了解在阵列中的何处选择正确的音频格式 - 如果它重新采样 16 位音频,将其视为 8 位垃圾,结果就是这样。
来自
scikits.samplerate.resample
文档:
如果输入的等级为 1,则使用所有数据,并假定来自单声道信号。如果等级为 2,则数字列将被假定为通道数。
所以我认为你需要做的是将立体声数据以它期望的格式传递给
resample
:
snd_array = snd_array.reshape((-1,2))
snd_resample = resample(snd_array, 1.5, "sinc_fastest")
snd_resample = snd_resample.reshape(-1) # Flatten it out again