【问题标题】:How would I be able to pan a sound in pygame?我如何能够在 pygame 中平移声音?
【发布时间】:2018-07-15 19:42:48
【问题描述】:

基本上,我想在这里完成的是一种在游戏运行时平移声音的方法。我想让音量(左右)根据播放器的位置而变化。现在我有一个简单的代码,我认为这将是一个很好的测试:

pygame.mixer.init()

self.sound = pygame.mixer.Sound("System Of A Down - DDevil #06.mp3")
print("I could get here")
self.music = self.sound.play()

self.music.set_volume(1.0, 0)

首先,我尝试了类似的方法,但使用了pygame.mixer.music,但我意识到无法以这种方式单独更改卷,或者我认为,然后我更改为此处提供的代码。 现在似乎无法加载该文件,我的猜测是该文件太大而无法在 pygame 中被视为声音。知道我如何能够完成这项工作吗?

【问题讨论】:

  • 您可能需要为此寻找另一个库。试试SoundDevice
  • 感谢您的建议,但似乎所有这些库对于我想要的来说都太慢了,也许我没有正确执行。

标签: python python-3.x audio pygame


【解决方案1】:

可能值得为此研究一个单独的音频库。一般来说,我会推荐 PortAudio(这是 C),但使用由PyAudio 提供的 python 绑定。这将使您能够更好地控制确切的音频流。

为了进一步简化这一点,有一个名为 PyDub 的库,它建立在 PyAudio 之上,用于高级接口(它甚至有一个特定的 pan 方法!)。


from pydub import AudioSegment
from pydub.playback import play

backgroundMusic = AudioSegment.from_wav("music.wav")

# pan the audio 15% to the right
panned_right = backgroundMusic.pan(+0.15)

# pan the audio 50% to the left
panned_left = backgroundMusic.pan(-0.50)

#Play audio
while True:
    try:
       play(panned_left)
      #play(panned_right)

如果这太慢或无法提供有效的实时实现,那么我肯定会尝试 PyAudio,因为您还将在此过程中学到更多关于音频处理的知识!

PS。如果您确实使用 PyAudio,请务必查看 callback techniques,以便您正在运行的游戏可以使用不同的 threads 继续并行运行。

【讨论】:

  • 似乎使用 pydub 加载了整个音乐,然后平移重新计算所有音乐并创建第二个要播放的文件,但这会消耗大量时间。您知道更改系统(Windows 或 Ubuntu)音量的方法吗?
  • 根据我的经验,我没有像纯 PortAudio 那样使用 PyDub,但界面似乎是一个不错的起点。环顾四周,我发现PySoundCard Library 的工作方式与 PyAudio 类似(使用 PortAudio),但看起来性能更高(至少乍一看)。如果您查看回调部分,您可以看到您可以修改 Numpy 数组中的音频。 IE。您应该能够在每个块通过时单独操作一个“列”音频(值得阅读线程)。如果可以的话,我会避免系统音量调整。
  • 感谢您的帮助,我设法以某种方式找到了问题所在。似乎无法将.mp3 文件加载到pygame.mixer.Sound(),所以我基本上将文件转换为.wav 格式。我也会更深入地研究 PyAudio,因为我对这种声音处理很感兴趣。
【解决方案2】:

您可以像这样在频道上平移:

from os import split, join
import pygame
import pygame.examples.aliens
pygame.init()
# get path to an example punch.wav file that comes with pygame.
sound_path = join(split(pygame.examples.aliens.__file__)[0], 'data', 'punch.wav')
sound = pygame.mixer.Sound(sound_path)
# mixer can mix several sounds together at once.
# Find a free channel to play the sound on.
channel = pygame.mixer.find_channel()
# pan volume full loudness on the left, and silent on right.
channel.set_volume(1.0, 0.0)
channel.play(sound)

https://www.pygame.org/docs/ref/mixer.html#pygame.mixer.Channel

【讨论】:

  • 你能解释一下第 5 行的作用吗?
  • 当然。添加了一些 cmets,并清理了一些代码。
【解决方案3】:

This answer当然可以帮到你。

基本上,你得到屏幕宽度,然后你根据player.pos.x / screen_width平移左侧,根据1 - player.pos.y / screen_width平移右侧:


伪代码:

channel = music.play() # we will pan the music through the use of a channel
screen_width = screen.get_surface().get_width()

[main loop]:
    right = player.pos.x / screen_width
    left =  player.pos.x / screen_width

    channel.set_volume(left, right)

文档:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    相关资源
    最近更新 更多