一次播放大量声音 [英] Playing a Lot of Sounds at Once

查看:62
本文介绍了一次播放大量声音的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在 python 中创建一个程序,当按下某个键时播放特定的大键琴音符.我希望它保持响应,这样你就可以继续弹奏更多的音符(有点像普通的电钢琴.)但是,因为存储音符的 wav 文件大约有 7-10 秒长,我遇到了一些问题.我每秒至少可以按下 10 个键.因此,在一个音符的持续时间内,我可以同时播放大约 100 个不同的 wav 文件.我尝试使用 winsound,但无法一次播放多个 wav 文件.然后我转到 PyAudio 并且它有点工作.我发现实现我想要的唯一方法是:

I am attempting to create a program in python that plays a particular harpsichord note when a certain key is pressed. I want it to remain responsive so you can continue to play more notes (kind of like a normal electric piano.) However, because the wav files that the notes are stored in are about 7-10 seconds long I am experiencing some issues. I can press at least 10 keys per second. So, over the duration of one note I could have around 100 different wav files playing at once. I tried to use winsound, but it was unable to play multiple wav files at once. I then moved on to PyAudio and it works kind of. The only way that I found to accomplish what I wanted was this:

from msvcrt import getch
import pyaudio
import wave
import multiprocessing as mp

#This function is just code for playing a sound in PyAudio
def playNote(filename):

    CHUNK = 1024

    wf = wave.open(filename, 'rb')


    p = pyaudio.PyAudio()

    stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
                    channels=wf.getnchannels(),
                    rate=wf.getframerate(),
                    output=True)

    data = wf.readframes(CHUNK)

    while data != '':
        stream.write(data)
        data = wf.readframes(CHUNK)

    stream.stop_stream()
    stream.close()

    p.terminate()


if __name__ == "__main__":

    while True:
        #If the 'a' key is pressed: start a new process that calls playNote
        #and pass in the file name for a note. 
        if ord(getch()) == 97: #a

            mp.Process(target=playNote, args=("F:\Project Harpsichord\The wavs\A1.wav",)).start()

        #If the 's' key is pressed: start a new process that calls playNote
        #and pass in the file name for another note. 
        if ord(getch()) == 115: #s

            mp.Process(target=playNote, args=("F:\Project Harpsichord\The wavs\A0.wav",)).start()

基本上每当我想播放一个新的 wav 时,我都必须启动一个新进程来运行 playNote 函数中的代码.正如我已经说过的,我可以同时播放多达 100 个.我只想说,同时运行的 100 个 python 解释器副本几乎使我的计算机崩溃.我也尝试过类似的多线程方法,但遇到了同样的问题.

Basically whenever I want to play a new wav, I have to start a new process that runs the code in the playNote function. As I already stated I can potentially have up to 100 of these playing at once. Suffice it to say, one hundred copies of the python interpreter all running at once almost crashed my computer. I also tried a similar approach with multi-threading, but had the same problems.

这篇文章展示了一种混合方式多个 wav 文件放在一起,以便它们可以同时播放,但由于我的程序不一定会同时启动声音,我不确定这是否可行.我需要一种有效的方式来同时演奏多个音符.无论这是以另一个图书馆的形式出现,还是以不同的语言出现,我真的不在乎.

This post shows a way to mix multiple wav files together so they can be played at the same time, but since my program will not necessarily be starting the sounds at the same time I am unsure if this will work. I need an efficient way to play multiple notes at the same time. Whether this comes in the form of another library, or even a different language I really don't care.

推荐答案

我按照 J.F Sebastian 的建议检查了 pygame.它最终正是我所需要的.我将 pygame.mixer.Sound()pygame.mixer.set_num_channels().这是我想出来的.

I checked out pygame like J.F Sebastian suggested. It ended up being exactly what I needed. I used pygame.mixer.Sound() in conjunction with pygame.mixer.set_num_channels(). Here's what I came up with.

import pygame as pg
import time

pg.mixer.init()
pg.init()

a1Note = pg.mixer.Sound("F:\Project Harpsichord\The wavs\A1.wav")
a2Note = pg.mixer.Sound("F:\Project Harpsichord\The wavs\A0.wav")

pg.mixer.set_num_channels(50)

for i in range(25):
    a1Note.play()
    time.sleep(0.3)
    a2Note.play()
    time.sleep(0.3)

这篇关于一次播放大量声音的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆