“Don’t Use a Comment When You Can Use a Function or a Variable”
Robert C. Martin, Clean Code: A Handbook of Agile Software Craftsmanship
Related Stack Overflow questions:
PyGame has 2 different modules for playing sound and music, the pygame.mixer module and the pygame.mixer.music module. This module contains classes for loading Sound objects and controlling playback. The difference is explained in the documentation:
The difference between the music playback and regular Sound playback is that the music is streamed, and never actually loaded all at once. The mixer system only supports a single music stream at once.
Related Stack Overflow questions:
how to play wav file in python?
Pygame, sounds don’t play
PyGame sound keeps repeating
📁 Minimal example - Play sound 1
If you want to play a single wav file, you have to initialize the module and create a pygame.mixer.Sound()
object from the file. Invoke play()
to start playing the file. Finally, you have to wait for the file to play.
Use get_length()
to get the length of the sound in seconds and wait for the sound to finish:
(The argument to pygame.time.wait()
is in milliseconds)
import pygame
pygame.mixer.init()
my_sound = pygame.mixer.Sound('my_sound.wav')
my_sound.play()
pygame.time.wait(int(my_sound.get_length() * 1000))
Alternatively you can use pygame.mixer.get_busy
to test if a sound is being mixed. Query the status of the mixer continuously in a loop.
In the loop, you need to delay the time by either pygame.time.delay
or pygame.time.Clock.tick
. In addition, you need to handle the events in the application loop. See pygame.event.get()
respectively pygame.event.pump()
:
For each frame of your game, you will need to make some sort of call to the event queue. This ensures your program can internally interact with the rest of the operating system.
import pygame
pygame.init()
pygame.mixer.init()
my_sound = pygame.mixer.Sound('my_sound.wav')
my_sound.play()
while pygame.mixer.get_busy():
pygame.time.delay(10)
pygame.event.poll()
Related Stack Overflow questions:
Numpy arrays can be loaded directly to a pygame.mixer.Sound
object and play
it:
import pygame
import numpy as np
pygame.mixer.init()
buffer = np.sin(2 * np.pi * np.arange(44100) * 440 / 44100).astype(np.float32)
sound = pygame.mixer.Sound(buffer)
sound.play(0)
pygame.time.wait(int(sound.get_length() * 1000))
Creates a new array for the sound data and copies the samples. The array will always be in the format returned from
pygame.mixer.get_init()
.
In your case, for some reason, the mixer seems to have created a stereo sound format with 2 channels. You can verify that by
print(pygame.mixer.get_init())
Use numpy.reshape
to convert the one-dimensional array to a two-dimensional 44100x1 array. Then use numpy.repeat to convert the 44100x1 array to a 44100x2 array, with the 1st channel copied to the 2nd channel:
import pygame
import numpy as np
pygame.mixer.init(frequency=44100, size=-16, channels=1)
size = 44100
buffer = np.random.randint(-32768, 32767, size)
buffer = np.repeat(buffer.reshape(size, 1), 2, axis = 1)
sound = pygame.sndarray.make_sound(buffer)
sound.play()
pygame.time.wait(int(sound.get_length() * 1000))
Alternatively, you can create a random sound for each channel separately:
import pygame
import numpy as np
pygame.mixer.init(frequency=44100, size=-16, channels=1)
size = 44100
buffer = np.random.randint(-32768, 32767, size*2)
buffer = buffer.reshape(size, 2)
sound = pygame.sndarray.make_sound(buffer)
sound.play()
pygame.time.wait(int(sound.get_length() * 1000))
Related Stack Overflow questions:
How to get out of the while loop in pygame when after playing the music?
📁 Minimal example - Play music 1
📁 Minimal example - Play music 2
If you want to play a mp3 file, you need to initialize the module. Load the file with pygame.mixer.music.load
. Invoke pygame.mixer.music.play()
to start playback of the music stream. Finally, you have to wait for the file to play.
Use pygame.mixer.music.get_busy()
to test if a sound is being mixed. Query the status of the mixer continuously in a loop.
In the loop, you need to delay the time by either pygame.time.delay
or pygame.time.Clock.tick
. In addition, you need to handle the events in the application loop. See pygame.event.get()
respectively pygame.event.pump()
:
For each frame of your game, you will need to make some sort of call to the event queue. This ensures your program can internally interact with the rest of the operating system.
import pygame
pygame.init()
pygame.mixer.init()
pygame.mixer.music.load('my_music.mp3')
pygame.mixer.music.play()
clock = pygame.time.Clock()
while pygame.mixer.music.get_busy():
clock.tick(60)
pygame.event.poll()
The unit of the time parameter to pygame.mixer.music.fadeout()
is milliseconds. 1 second is 1000 milliseconds:
pygame.mixer.music.load(audio1)
pygame.mixer.music.play()
# play for 12.5 seconds
pygame.time.wait(12500)
# fade out for 10 seconds
pygame.mixer.music.fadeout(10000)
pygame.time.wait(10000)
Related Stack Overflow questions:
Related Stack Overflow questions:
Related Stack Overflow questions:
Related Stack Overflow questions:
Related Stack Overflow questions:
Related Stack Overflow questions:
Related Stack Overflow questions: