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.