Playing a Lot of Sounds at Once
Question: 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()
    

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.

[This post](http://stackoverflow.com/questions/28743400/pyaudio-play-multiple-
sounds-at-once "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.


Answer: I checked out pygame like J.F Sebastian suggested. It ended up being exactly
what I needed. I used
[pygame.mixer.Sound()](https://www.pygame.org/docs/ref/mixer.html) in
conjunction with
[pygame.mixer.set_num_channels()](https://www.pygame.org/docs/ref/mixer.html#pygame.mixer.get_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)
    

