why isn't pygame playing the audio files the correct amount of times?

Question:

Sorry if I just did something stupid, I have never used pygame before.
I’m trying to make pygame play morse code by looking at a string and playing the sound accordingly, although when I run it, it only plays the short beep 3 times and the long beep once. is this because multiple beeps are playing at the same time? can someone help, because I have no experience whatsoever with pygame.
Here is my code:

from pygame import mixer
import os
import time
CURR_DIR = os.path.dirname(os.path.realpath(__file__))
mixer.init()
l = ".... . .-.. ---"
h = list(l)
print(h)
def play(CURR_DIR, l):
    for i in l:
        if i == ".":
            mixer.music.load(CURR_DIR + "short beep.mp3")
            mixer.music.set_volume(0.7)
            mixer.music.play()
            print(".")
        elif i == "-":
            mixer.music.load(CURR_DIR + "long beep.mp3")
            mixer.music.set_volume(0.7)
            mixer.music.play()
            print("-")
        elif i == " ":
            time.sleep(1)
            print(" ")
play(CURR_DIR, l)
Asked By: Synt4xErr0r 7

||

Answers:

I think I found a solution that does what you are trying to do in another SO question. It requires pygame.mixer.Channel and its set_endevent() function.

https://stackoverflow.com/a/61068408/11620108

In their example:

horn     = pygame.mixer.Sound( 'car-horn2.ogg' )      # converted from MP3 to OGG
quack    = pygame.mixer.Sound( 'duck-quack.ogg' )
ca_ching = pygame.mixer.Sound( 'cash-register.ogg' )
bark     = pygame.mixer.Sound( 'dog-bark.ogg' )
ding     = pygame.mixer.Sound( 'single-ding.ogg' )
gobble   = pygame.mixer.Sound( 'turkey-gobble.ogg' )

You could assign a variable for each sound. For the pause, you can use your long beep with the volume set to 0.

Example:

morse_dot = pygame.mixer.Sound('short_beep.mp3')

morse_dash = pygame.mixer.Sound('long_beep.mp3')

morse_pause = pygame.mixer.Sound('long_beep.mp3')
morse_pause.set_volume(0)

You could then convert a morse code string into a list of the corresponding sounds by their variable name:

sound_list =[]
for c in morse_code:
    if c == ".":
        sound_list.append(morse_dot)
    elif c == "-":
        sound_list.append(morse_dash)
    elif c == " ":
        sound_list.append(morse_pause)

and play it using the advice found in the other SO answer.

Answered By: N.Stevenson

You have to wait until the music has finished playing with pygame.mixer.music.get_busy(). e.g.:

import os
import pygame
CURR_DIR = os.path.dirname(os.path.realpath(__file__))

pygame.mixer.init()
clock = pygame.time.Clock()

l = ".... . .-.. ---"
i = 0
pause = False
pause_end = 0
run = True
while run:
    clock.tick(100)
    if pause:
        if pygame.time.get_ticks() > pause_end:
            pause = False
    elif not pygame.mixer.music.get_busy():
        if i < len(l):
            if l[i] == ".":
                pygame.mixer.music.load(CURR_DIR + "/short beep.mp3")
                pygame.mixer.music.play(0)
                print(".")
            elif l[i] == "-":
                pygame.mixer.music.load(CURR_DIR + "/long beep.mp3")
                pygame.mixer.music.play(0)
                print("_")
            elif l[i] == " ":
                pause_end = pygame.time.get_ticks() + 1000
                pause = True
                print(" ")
            i += 1    
        else:
            run = False
    
pygame.quit()
exit()
Answered By: Rabbid76
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.