Last active
March 14, 2022 09:46
-
-
Save ohsqueezy/6540433 to your computer and use it in GitHub Desktop.
Play a 440 Hz tone in Pygame
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Generate a 440 Hz square waveform in Pygame by building an array of samples and play | |
# it for 5 seconds. Change the hard-coded 440 to another value to generate a different | |
# pitch. | |
# | |
# Run with the following command: | |
# python pygame-play-tone.py | |
from array import array | |
from time import sleep | |
import pygame | |
from pygame.mixer import Sound, get_init, pre_init | |
class Note(Sound): | |
def __init__(self, frequency, volume=.1): | |
self.frequency = frequency | |
Sound.__init__(self, self.build_samples()) | |
self.set_volume(volume) | |
def build_samples(self): | |
period = int(round(get_init()[0] / self.frequency)) | |
samples = array("h", [0] * period) | |
amplitude = 2 ** (abs(get_init()[1]) - 1) - 1 | |
for time in range(period): | |
if time < period / 2: | |
samples[time] = amplitude | |
else: | |
samples[time] = -amplitude | |
return samples | |
if __name__ == "__main__": | |
pre_init(44100, -16, 1, 1024) | |
pygame.init() | |
Note(440).play(-1) | |
sleep(5) |
This snippet won't produce a sine wave but rather a square wave (which sounds much sharper). For the sine wave replace build_samples
with something like:
def build_samples(self):
sample_rate = pygame.mixer.get_init()[0]
period = int(round(sample_rate / self.frequency))
amplitude = 2 ** (abs(pygame.mixer.get_init()[1]) - 1) - 1
def frame_value(i):
return amplitude * numpy.sin(2.0 * numpy.pi * frequency * i / sample_rate)
return numpy.array([frame_value(x) for x in range(0, period)]).astype(numpy.int16)
Or use a simpler approach without inheriting Sound
class.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
As per this answer on StackOverflow, if the snippet doesn't work and you are running it on Windows, the problem might be the need for a screen on Windows. Creating a screen as follows before the call to
Note()
resolved it for me,