Dans cet article nous nous occuperons de générer des notes musicales. Nous utiliserons aussi toutes les techniques que nous avons appris jusqu’à ici (ouverture de fenêtre pygame, gestion des événements, dessin de figure). On ajoutera le fonctions en python et on dessinera un cercle au lieux d’un rectangle, pour varier et pour apprendre quelque chose de nouveau.
Je n’expliquerais pas la dynamique de la génération du son ni le maths que sont notamment nécessaires. Mais j’en parlerai ici en quelque mots. Ce qu’on va à faire c’est de
générer une séquence de valeurs que suivent une onde sinusoïdale (en réalité deux séquences, car on générera le son en stéréo), à la fréquence d’une note musicale à
choisir entre DO-4 (261,63 Hz) et DO-5 (523.25 Hz).
Combien de valeurs il nous faudra: ça dépends de la fréquence échantillonnage, c’est à dire de combien de fois par seconde il faut fournir une valeur et de la durée du son qu’on produira.
Pour la première fois nous utiliserons des fonctions. Ces dernières sont une instrument très puissant que nous permet de réutiliser des morceaux de code (des “sous-programmes”), en donnant les quelque paramétrés qui changent. Par exemple, ici on donnera à la fonction joue_note une note musicale de 0 a 7 (de DO-4 a DO-5) et on donnera la même aussi à la fonction dessin_figure qui nous dessinera un cercle dont note représentera la couleur.
Exercise 1: Modifiez le code de l’article précédent, pour générer une note aux hasards pour chaque carré dessiné sur l’écran.
import pygame
from pygame.locals import *
import math
import numpy
taille = (800, 600)
bits = 16
# les "channels" ici ne sont pas comme en
# http://www.pygame.org/docs/ref/mixer.html#pygame.mixer.get_num_channels
pygame.mixer.pre_init(44100, -bits, 2)
# Initialisons la plateforme de jeux
pygame.init()
# creeons une fenetre de jeux normale
gameDisplay = pygame.display.set_mode((800, 600))
# Notre titre pour le jeux...
pygame.display.set_caption("Produisons des notes musicales!")
duree = 0.2 # en secondes
# Frequences audio des notes musicales - ref: https://pages.mtu.edu/~suits/notefreqs.html
FREQUENCY_DO = 261.63
FREQUENCY_RE = 293.66
FREQUENCY_MI = 329.63
FREQUENCY_FA = 349.23
FREQUENCY_SOL = 392.00
FREQUENCY_LA = 440.00
FREQUENCY_SI = 493.88
FREQUENCY_DO2 = 523.25
# On les arrange dans une list pour faciliter l'utilisation.
frequences = [FREQUENCY_DO, FREQUENCY_RE, FREQUENCY_MI, FREQUENCY_FA, FREQUENCY_SOL, FREQUENCY_LA, FREQUENCY_SI, FREQUENCY_DO2]
# et on le fait aussi pour les couleurs.
couleurs = [Color("azure4"), Color("blanchedalmond"), Color("brown"), Color("darkblue"), Color("darkgreen"), Color("darkorange"), Color("darkred"), Color("deeppink")]
# Frequence d'echantillonage
echantillonage = 44100
# Nombre d'echantillons
echantillons = int(round(duree*echantillonage))
# One met a zero un array d'echantillons - le type est intier à 16 bits
buf = numpy.zeros((echantillons, 2), dtype = numpy.int16)
max_echantillon = 2**(bits - 1) - 1
# Fonction: ceci sert a jouer un son...
# Les maths sont un peu compliqué, n'y pensez pas pour le moment...
def joue_note(note):
for s in range(echantillons):
t = float(s)/echantillonage # en seconds
buf[s][0] = int(round(max_echantillon*math.sin(2*math.pi*frequences[note]*t))) # gauche
buf[s][1] = int(round(max_echantillon*0.5*math.sin(2*math.pi*frequences[note]*t))) # droite
# Produit Un son.
son = pygame.sndarray.make_sound(buf)
son.play(loops = 0)
# Fonction: ceci sert a dessinner une figure geometrique en couleur...
def dessin_figure(surface, note):
pygame.draw.circle(surface, couleurs[note], (400, 300), 50, 0)
# Condition de sortie
sortieDuJeux=False
while not sortieDuJeux :
for event in pygame.event.get():
if event.type == pygame.QUIT:
_running = False
break
if event.type == pygame.KEYDOWN:
note = -1
if event.key==K_1:
note = 0
if event.key==K_2:
note = 1
if event.key==K_3:
note = 2
if event.key==K_4:
note = 3
if event.key==K_5:
note = 4
if event.key==K_6:
note = 5
if event.key==K_7:
note = 6
if event.key==K_8:
note = 7
print(event)
if note > -1 :
# on joue la note correspondant à la touche
joue_note(note)
# on dessin une figure en couleur
dessin_figure(gameDisplay, note)
pygame.display.update()
pygame.quit()
Vous trouverez la référence pour les fréquences des notes musicales ici.



