Python:改变音频文件的音高

时间:2011-12-14 08:03:30

标签: python scipy pygame audio-processing

这是我在堆栈上的第一篇文章。到目前为止,这个网站非常有用,但我是一个新手,需要清楚解释我的问题,这与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)

4 个答案:

答案 0 :(得分:11)

您的问题是pygame适用于numpy.int16数组,但调用resample会返回numpy.float32数组:

>>> snd_array.dtype
dtype('int16')
>>> snd_resample.dtype
dtype('float32')

您可以使用resamplenumpy.int16结果转换为astype

>>> snd_resample = resample(snd_array, 1.5, "sinc_fastest").astype(snd_array.dtype)

通过这个修改,你的python脚本可以很好地播放tone.wav文件,音调更低,速度更低。

答案 1 :(得分:3)

你最好的选择可能是使用python audiere。

这是一个链接,我用它来做同样的事情,它很简单,只需阅读所有文档。

http://audiere.sourceforge.net/home.php

答案 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