特定频率的简单 Pygame 音频
如何使用 Pygame 中的音频创建永远流畅播放的 440 Hz 声音?我认为这应该很容易,但我不想使用任何愚蠢的文件来完成任务。这样做的最终目的是在按住某个键的同时演奏一个音符,正如我在另一个问题中所问的那样。任何帮助将不胜感激,因为我浪费了大量时间试图找到这个问题的答案。
How can I create a 440 Hz sound that plays smoothly forever using audio with Pygame? I assume this should be easy enough, but I don't want to use any stupid files to accomplish the task. The final intent of this is to play a note while a key is being held down as I have asked in another question. Any help would be greatly appreciated as I have wasted great quantities of time trying to find an answer to this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在收到太多的“ValueError:数组深度必须与混合器通道数匹配”和其他类似错误之后,我发现了这个工作示例 http://www.mail-archive.com/[电子邮件受保护]/msg16140.html。它正确生成可与立体声混音器配合使用的多维 16 位整数数组。下面的最小工作示例,大部分是从上一个链接中提取的,并添加了必要的 pygame 位。在 Python 2.7.2 中使用 pygame.ver '1.9.1release' 进行了测试。
此示例将在立体声设置中从一个扬声器播放 440 Hz 音调,并从另一个扬声器播放 550 Hz 音调。经过一番玩弄持续时间后,我发现如果将“持续时间”变量设置为除整数之外的任何值,声音循环中会弹出可听见的咔嗒声。
After getting entirely too many "ValueError: Array depth must match number of mixer channels", and other similar errors, I discovered this working example http://www.mail-archive.com/[email protected]/msg16140.html. It properly generates a multi-dimensional 16 bit integer array that works with a stereo mixer. Minimum working example below, mostly lifted from the previous link with the necessary pygame bits thrown in. Tested in Python 2.7.2 with pygame.ver '1.9.1release'.
This example will play a 440 Hz tone out of one speaker and a 550 Hz tone out of the other speaker in a stereo setup. After a bit of playing with the duration I discovered that audible clicks will pop up in the sound loop if you set the "duration" variable to anything other than a whole number.
440Hz 是什么样的声音? “440 Hz”有多种类型的波:正弦波、锯齿波、方波等。您可以用长笛演奏 A,这也可能算在内。
假设您想要一个正弦波,看起来您可以使用 pygame.sndarray.samples 生成一个 Sound 对象。 (我还没有测试过这个)您可以使用以下内容创建样本:
这希望是基本的正弦波东西。
频率
是所需的频率,以Hz为单位。sample_rate
是生成的音频中每秒的样本数:44100 Hz 是典型值。duration_in_samples
是音频的长度。 (5 * 44100 == 5 秒,如果您的音频采样率为 44100 Hz。)看起来您可能必须先将
samples
转换为numpy.array
传递到 pygame.sndarray.samples 。文档表明音频应与 pygame.mixer.get_init 返回的格式匹配,因此适当调整样本,但这是基本思想。 (mixer.get_init
将告诉您上面的sample_rate
变量,以及您是否需要考虑立体声,以及是否需要调整波的幅度或移动它。 )将
samples
设置为整数个波长,并且它应该循环。What kind of 440 Hz sound? There are many types of waves at "440 Hz": sine, saw, square, etc. You could have a flute playing an A, and that might count too.
Assuming you want a sine wave, it looks like you can generate a Sound object with
pygame.sndarray.samples
. (I haven't tested this) You can create the samples with:This is hopefully basic sine wave stuff.
frequency
is the desired frequency, in Hz.sample_rate
is the number of samples / second in the generated audio: 44100 Hz is a typical value.duration_in_samples
is the length of the audio. (5 * 44100 == 5 seconds, if your audio is at a 44100 Hz sample rate.)It looks like you might have to convert
samples
to anumpy.array
before passing topygame.sndarray.samples
. The docs indicate that the audio should match the format returned bypygame.mixer.get_init
, so adjustsamples
appropriately, but that's the basic idea. (mixer.get_init
will tell you thesample_rate
variable above, and whether you need to account for stereo, and if you need to adjust the amplitude of the wave or shift it.)Make
samples
a integral number of waves long, and it should loop.