这是我在堆栈上的第一篇文章。到目前为止,这个网站非常有用,但我是一个新手,需要清楚解释我的问题,这与Python中的音调转换音频有关。我安装了当前的模块:numpy,scipy,pygame和scikits“samplerate”api。
我的目标是拍摄一个立体声文件,并以尽可能少的步骤以不同的音高播放。目前,我使用pygame.sndarray将文件加载到数组中,然后使用scikits.samplerate.resample应用samplerate转换,然后将输出转换回声音对象以使用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)
答案 0 :(得分:11)
您的问题是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
文件,音调更低,速度更低。
答案 1 :(得分:3)
答案 2 :(得分:0)
scikits.samplerate.resample很可能是“思考”你的音频采用的是另一种格式而不是16位立体声。查看scikits.samplerate上的文档,了解在阵列中选择正确音频格式的位置 - 如果它重新采样16位音频,将其视为8位垃圾就会出现。
答案 3 :(得分:0)
来自scikits.samplerate.resample
文档:
如果输入的等级为1,则使用所有数据,并假设它来自单声道信号。如果rank为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