为什么我的 pygame sndarray 对象会出现这样的扭曲?
我正在使用 pygame 中的 sndarray 来玩基本的声音合成。问题是无论我做什么,生成的声音都会严重失真。
在我将在问题末尾提供的代码中,您将看到一堆来自各处的代码。实际上,主要内容来自我在互联网上找到的 MIT 来源,该来源使用 Numeric 来执行数学操作和处理数组,由于我现在无法安装它,所以我决定使用 Numpy 来实现此目的。
首先,我认为问题出在数组的 Int 格式上,但如果我将值转换为 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的世界里还是个新手
I'm using sndarray from pygame to play with basic sound synthesis. The problem is Whatever I do, I have an awful distortion on the generated sound.
In the code I'll provide at the end of the question, you'll see a bunch of code coming from here and there. Actually, the main stuff comes from a MIT's source I found on the interweb which is using Numeric to do mathematic stuff and handling arrays, and since I can't install it for now, I decided to use Numpy for this.
First, I thought the problem was coming from the Int format of my arrays, but if I cast the values to numpy.int16, I don't have sound anymore.
Plus, I can't find anything on google about that kind of behavior from pygame / sndarray.
Any idea ?
Thanks !
Code :
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
=> 'hope I didn't make any lame mistake, I'm pretty new in the world of python
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
假设您有一些像 sndarray 这样的初始化代码
,希望您向其传递 16 位整数数组,而不是浮点数组。
考虑到 16 位整数表示形式,您的“峰值”值需要有意义。因此,如果浮点数组的值在 -1.0 到 +1.0 范围内,则需要乘以 2**15 才能对其进行适当缩放。
需要明确的是,您可能需要这样的转换:
我对这种情况的最好猜测是您有一个具有低峰值(如 1.0)的浮点数组,因此当将其转换为 int16 时,大多数所有内容都会转换为 0 或 +/-1 ,你听不到。当传递浮点数组时,您可能只是获得随机位(当解释为 16 位整数时),因此听起来像是刺耳的噪音(我在实现此功能的过程中偶然经历了这个阶段)。
Presuming you have some initialization code like
sndarray expects you to be passing it 16-bit integer arrays, not float arrays.
Your "peak" value needs to make sense given the 16-bit integer representation. So, if your float array has values in the range -1.0 to +1.0, then you need to multiply by 2**15 to get it scaled appropriately.
To be clear, you may want a conversion like:
My best guess of the situation is that you had a float array with a low peak value like 1.0, so when converting it to int16 most everything was getting converted to 0 or +/-1, which you wouldn't be able to hear. When passing the float array, you were probably just getting random bits (when interpreted as 16 bit integers) so then it sounded like harsh noise (I stumbled through this phase on my way to getting this working).