0

I need to make a function that when called a certains song must be played.

Here is the code:

import pyaudio  
import wave

chunk = 1024
p = pyaudio.PyAudio() 

beat = wave.open(r"D:/Escritorio/beat.wav","rb") 
stream = p.open(format = p.get_format_from_width(beat.getsampwidth()),  
                channels = beat.getnchannels(),  
                rate = beat.getframerate(),  
                output = True)  

def play_song(b, s, c):
    data = b.readframes(c)
    while data != '':
        s.write(data)
        data = b.readframes(c)
    b.rewind()
    s.stop_stream()

for _ in range(10):
    #Should play the audio file 10 times, but nothing happens
    play_song(beat, stream, chunk)

If I put beat and stream definitions inside the function it works well, but the time between each iteration must be as low as possible, and making so makes a delay of about 0.1 seconds, which is actually pretty bad for this purpose.

Garmekain
  • 664
  • 5
  • 18

1 Answers1

0

The answer here is to use a callback, which plays the audio asynchronously.

def callback(in_data, frame_count, time_info, status):
    data = beat.readframes(frame_count)
    return (data, pyaudio.paContinue)

#open stream  
stream = p.open(format = p.get_format_from_width(beat.getsampwidth()),  
                channels = beat.getnchannels(),  
                rate = beat.getframerate(),  
                output = True,
                stream_callback=callback)  

def play_song():
    stream.start_stream()
    while stream.is_active():
        True
    stream.stop_stream()
    beat.rewind()
Garmekain
  • 664
  • 5
  • 18