9

这是我在堆栈上的第一篇文章。到目前为止,这个站点非常有帮助,但我是一个新手,需要对我的问题进行清晰的解释,这与 Python 中的音高转换音频有关。我安装了当前模块:numpy、scipy、pygame 和 scikits “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)
4

4 回答 4

11

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

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

您可以将resample结果转换为numpy.int16using astype

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

通过此修改,您的 python 脚本可以tone.wav以较低的音调和较低的速度很好地播放文件。

于 2011-12-21T22:32:42.683 回答
3

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

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

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

于 2011-12-15T18:14:39.187 回答
0

scikits.samplerate.resample 很可能“认为”您的音频是 16 位立体声以外的另一种格式。检查 scikits.samplerate 上的文档,了解在哪里选择阵列中正确的音频格式 - 如果它重新采样 16 位音频,将其视为 8 位垃圾,将会出现。

于 2011-12-14T12:45:42.977 回答
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
于 2011-12-15T20:46:31.077 回答