我正在做一个带有嵌入式计算机模块的项目,EXM32入门套件,我想模拟一个带有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)
答案 0 :(得分:3)
您的基本问题是您想要生成一个进程而不等待它的返回值。你不能用os.system()
做到这一点(你可以产生几十个线程)。
您可以使用自{2.4}以来偶然可用的subprocess模块执行此操作。有关示例,请参阅here。
答案 1 :(得分:3)
由于默认python实现中的全局解释器锁(“GIL”),一次只能运行一个线程。在这种情况下,这对你没什么帮助。
此外,os.system
等待命令完成,并生成一个额外的shell来运行命令。您应该使用suprocess.Popen
代替,它将在启动程序后立即返回,并且默认情况下不会产生额外的shell。以下代码应尽可能紧密地启动两个玩家:
import subprocess
do = subprocess.Popen(['aplay', './notas_musicales/Do.wav'])
re = subprocess.Popen(['aplay', './notas_musicales/Re.wav'])