为什么我的pygame sndarray对象有这样扭曲?
我正在使用pygame里的sndarray来玩一些基本的声音合成。不过我遇到了一个问题,无论我怎么做,生成的声音总是有很严重的失真。
在我最后提供的代码中,你会看到一些来自不同地方的代码。其实,主要的部分来自我在网上找到的一个麻省理工学院的源代码,它使用Numeric来进行数学运算和处理数组。由于我现在无法安装这个库,所以我决定用Numpy来替代。
起初,我以为问题出在我的数组使用了整数格式,但当我把值转换成numpy.int16时,声音就没有了。
而且,我在谷歌上找不到关于pygame/sndarray出现这种情况的任何信息。
有没有什么想法呢?
谢谢!
代码:
global_sample_rate = 44100
def sine_array_onecycle(hz, peak):
length = global_sample_rate / float(hz)
omega = numpy.pi * 2 / length
xvalues = numpy.arange(int(length)) * omega
return (peak * numpy.sin(xvalues))
def zipstereo(f):
return numpy.array(zip (f , f))
def make_sound(arr, n_samples = global_sample_rate):
return pygame.sndarray.make_sound( zipstereo( numpy.resize(numpy.array(arr), (n_samples,)) ) )
def sine(hz, peak):
snd = make_sound(sine_array_onecycle(hz, peak), global_sample_rate)
return snd
=> '希望我没有犯什么低级错误,我对python还很陌生'
1 个回答
2
假设你有一些初始化的代码,比如:
pygame.mixer.pre_init(44100, -16, 2) # 44.1kHz, 16-bit signed, stereo
sndarray 这个函数希望你传入的是16位整数数组,而不是浮点数数组。
你的“峰值”需要与16位整数的表示方式相符。所以,如果你的浮点数数组的值在-1.0到+1.0之间,你需要把它乘以2的15次方,这样才能正确缩放。
为了更清楚,你可能需要进行这样的转换:
numpy.int16(float_array*(2**15))
我猜测你的情况是,你有一个浮点数数组,里面的峰值很低,比如1.0,所以当你把它转换成int16时,大部分值都变成了0或者+/-1,这样是听不见的。当你传递浮点数数组时,可能得到的只是一些随机的位(当它被当作16位整数解释时),所以听起来像是刺耳的噪音(我在实现这个功能的过程中也经历过这个阶段)。