【问题标题】:Play two sounds simultanously in PYTHON without pygame在没有 pygame 的 PYTHON 中同时播放两个声音
【发布时间】:2012-12-13 22:17:55
【问题描述】:

我正在做一个带有嵌入式计算机模块 EXM32 Starter Kit 的项目,我想模拟一架带有 8 个音符的钢琴。操作系统是 linux,我正在用 Python 编程。我的问题是 Python 的版本是 2.4,没有“pygame”库来同时播放两种声音。现在我在 python "os.system('aplay ./Do.wav')" 中使用从 linux 控制台播放声音。

简单的问题是:我可以使用另一个库来做同样的事情吗:

    snd1 =  pygame.mixer.Sound('./Do.wav')
    snd2 =  pygame.mixer.Sound('./Re.wav')

    snd1.play()
    snd2.play()

同时播放“Do”和“Re”?我可以使用“auidoop”和“wave”库。

我尝试使用线程,但问题是程序一直等到控制台命令完成。我可以使用的另一个库?或与'wave'或'audioop'有关的方法? (我相信这最后一个库仅用于操纵的声音文件) 完整代码为:

import termios, sys, os, time
TERMIOS = termios
#I wrote this method to simulate keyevent. I haven't got better libraries to do this
def getkey():
    fd = sys.stdin.fileno()
    old = termios.tcgetattr(fd)
    new = termios.tcgetattr(fd)
    new[3] = new[3] & ~TERMIOS.ICANON & ~TERMIOS.ECHO
    new[6][TERMIOS.VMIN] = 1
    new[6][TERMIOS.VTIME] = 0
    termios.tcsetattr(fd, TERMIOS.TCSANOW, new)
    key_pressed = None
    try:
            key_pressed = os.read(fd, 1)
    finally:
            termios.tcsetattr(fd, TERMIOS.TCSAFLUSH, old)
    return key_pressed

def keyspress(note):

    if note == DO:
            os.system('aplay  ./notas_musicales/Do.wav')
    elif note == RE:
            os.system('aplay ./notas_musicales/Re.wav')
    elif note == MI:
            os.system('aplay ./notas_musicales/Mi.wav')
    elif note == FA:
            os.system('aplay ./notas_musicales/Fa.wav')
    elif note == SOL:
            os.system('aplay ./notas_musicales/Sol.wav')
    elif note == LA:
            os.system('aplay ./notas_musicales/La.wav')
    elif note == SI:
            os.system('aplay ./notas_musicales/Si.wav')


DO = 'a'
RE = 's'
MI = 'd'
FA = 'f'
SOL = 'g'
LA = 'h'
SI = 'j'
key_pressed = ""
i = 1

#in each iteration the program enter into the other 'if' to doesn't interrupt
#the last sound.
while(key_pressed != 'n'):
    key_pressed = getkey()
    if i == 1:
        keyspress(key_pressed)
        i = 0
    elif i == 0:
        keyspress(key_pressed)
        i = 1
    print ord(key_pressed)

【问题讨论】:

  • 不能只更新python版本吗?
  • Python 2.4 远远落后于时代。您应该非常努力地升级,最好升级到 2.7。
  • 我知道,但不可能。

标签: python embedded audio


【解决方案1】:

由于默认 python 实现中的全局解释器锁(“GIL”),一次只能运行一个线程。所以在这种情况下,这对你没有多大帮助。

另外,os.system 等待命令完成,并生成一个额外的 shell 来运行命令。您应该使用 suprocess.Popen 代替,它会在启动程序后立即返回,默认情况下会返回不产生额外的外壳。下面的代码应该尽可能让两个玩家一起开始:

import subprocess

do = subprocess.Popen(['aplay', './notas_musicales/Do.wav'])
re = subprocess.Popen(['aplay', './notas_musicales/Re.wav'])

【讨论】:

  • 谢谢罗兰。问题已回答。
  • 其实os.system()只是创建了一个新进程,所以GIL完全没有问题。是的,您一次只能生成一个进程,但subprocess.Popen 也是如此。如果您同时需要一两个以上的声音,它只会产生相当多的开销。
【解决方案2】:

您的基本问题是您想要生成一个进程并且等待它的返回值。你不能用os.system() 做到这一点(你可以只产生几十个线程)。

您可以使用 subprocess 模块来做到这一点,该模块从 2.4 开始提供。有关示例,请参阅here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-20
    • 1970-01-01
    • 2011-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多