1. Idée centrale : Faire comprendre la structure mélodique au code
La génération musicale par IA traditionnelle repose souvent sur les réseaux neuronaux (comme WaveNet, Music Transformer), mais ces méthodes sont souvent opaques et difficiles à déboguer et optimiser. Nous adoptons une approche par règles symboliques + mécanisme de machine à états pour construire un moteur musical flexible et contrôlable :
- Paramètres d'entrée pris en charge : tonalité (Do majeur/mineur), signatures rythmiques, templates de tempo
- Synthèse automatique des progressions harmoniques (I–IV–V–I)
- Simulation des contours mélodiques vocaux (montée/descente, contrôle des sauts)
- Exportation vers des fichiers MIDI pour édition ou lecture dans un DAW
Cette approche convient parfaitement à l'enseignement, aux expérimentations, voire au développement léger de plugins music!
2. Flux technique clé (version textuelle)
Démarrer → Configuration des paramètres → Initialisation de la gamme & séquence d'accords →
↓
Génération de la mélodie principale (basée sur des sauts probabilistes) →
↓
Insertion de l'accompagnement harmonique (points de rythme同步) →
↓
Exportation du fichier MIDI → Fin
L'ensemble du flux est claire et traçable, chaque module peut être testé et modifié indépendamment, augmentant considérablement l'efficacité d'itération.
3. Implémentation détaillée du code (Python + mido)
Étape 1 : Définition des relations de gamme et d'accords de base
from mido import MidiFile, MidiTrack, Message
import random
def construire_gamme(note_root='C', ton='majeur'):
"""Retourne la liste des notes pour la tonalité spécifiée"""
intervalles_majeur = [0, 2, 4, 5, 7, 9, 11] # Décalage en demi-tons
intervalles_mineur = [0, 2, 3, 5, 7, 8, 10]
intervalles = intervalles_majeur if ton == 'majeur' else intervalles_mineur
return [note_root + str(i//12) for i in intervalles]
# Exemple : Do majeur
gamme = construire_gamme('C', 'majeur')
print("Tonalité actuelle :", gamme)
Sortie :
Tonalité actuelle : ['C0', 'D0', 'E0', 'F0', 'G0', 'A0', 'B0']
Étape 2 : Construction de la progression d'accords (I–IV–V–I)
progression_accords = {
'I': [0, 4, 7], # Do Mi Sol
'IV': [3, 7, 10], # Fa La Do
'V': [4, 8, 11] # Sol Si Ré
}
def creer_accords(nb_mesures=4, sequence=['I','IV','V','I']):
accords = []
for idx_mesure, nom_accord in enumerate(sequence):
notes_base = progression_accords[nom_accord]
temps_debut = idx_mesure * 4 # 4 temps par mesure
for decalage_note in notes_base:
accords.append((temps_debut, decalage_note))
return accords
Étape 3 : Génération de la mélodie princiaple (avec limitation des sauts)
def creer_melodie(accords, notes_gamme, nb_notes=16):
melodie = []
note_courante = notes_gamme[0] # Note de départ = note fondamentale
for _ in range(nb_notes):
indice_precedent = notes_gamme.index(note_courante)
# Contrôle de la portée des sauts (±3 intervalles)
indice_min = max(0, indice_precedent - 3)
indice_max = min(len(notes_gamme)-1, indice_precedent + 3)
indice_suivant = random.randint(indice_min, indice_max)
note_courante = notes_gamme[indice_suivant]
# Ajout à la mélodie (une note par temps)
temps = len(melodie)
melodie.append((temps, note_courante))
return melodie
Étape 4 : Intégration en MIDI et sauvegarde
def exporter_midi(melodie, accords, nom_fichier="composition.mid"):
midi = MidiFile()
piste = MidiTrack()
midi.tracks.append(piste)
# Ajout des informations de tempo
piste.append(Message('set_tempo', tempo=500000))
# Ajout de la piste mélodique
for temps, note in melodie:
hauteur = convertir_note_midi(note)
piste.append(Message('note_on', note=hauteur, velocity=80, time=temps*480))
piste.append(Message('note_off', note=hauteur, velocity=64, time=480))
# Ajout de l'accompagnement harmonique (version simplifiée, note tenue)
for temps, decalage in accords:
hauteur = convertir_note_midi(gamme[decalage])
piste.append(Message('note_on', note=hauteur, velocity=60, time=temps*480))
piste.append(Message('note_off', note=hauteur, velocity=40, time=960))
midi.save(nom_fichier)
print(f"✅ Fichier MIDI sauvegardé : {nom_fichier}")
def convertir_note_midi(chaine_note):
"""Convertit une chaîne de note en numéro MIDI"""
correspondance_notes = {'C': 0, 'D': 2, 'E': 4, 'F': 5, 'G': 7, 'A': 9, 'B': 11}
octave = int(chaine_note[-1])
caractere_note = chaîne_note[:-1]
return 12 * octave + correspondance_notes[caractere_note]
# Exécution du流程
if __name__ == "__main__":
accords = creer_accords()
melodie = creer_melodie(accords, gamme)
exporter_midi(melodie, accords)
4. Démonstration des résultats et suggestions d'extension
Après avoir exécuté ce script, vous obtaindrez un fichier nommé composition.mid qu'il est possible d'ouvrir et écouter avec Ableton Live, MuseScore ou Logic Pro !
🔧 Comment améliorer davantage ?
| Fonctionnalité | Approche d'implémentation |
|---|---|
| Ajouter des rythmes de batterie | Utiliser mido pour ajouter des événements de percussion (Kick/Grosse Caisse) |
| Variations émotionnelles dynamiques | Introduire des种子aléatoires + ajustement des poids (ex: augmenter la fréquence des sauts dans les sections culminantes) |
| Interface utilisateur interactive | Combiner PyQt ou Tkinter pour créer une GUI permettant l'ajustement des paramètres en temps réel |
5. Conclusion : Le code est créativité, les règles sont liberté
Ceci n'est pas une simple « génération musicale », mais une plateforme expérimentale musicale ouverte. Vous pouvez l'intégrer dans des jeux, des animations web, des logiciels éducatifs, ou l'utiliser comme projet personnel pour vous exercer. L'aspect crucial : vous maîtrisez sa logique fondamentale, ce qui vous permet de modifier les règles à volonté pour qu'elles vous servent.
Ne regardez plus seulement ces modèles de深度学习 mystérieux. Parfois, une ligne de code Python élégante peut inspirer bien plus que des milliers de couches de réseaux neuronaux.
Commencez dès maintenant! Votre première mélodie née du code pourrait résonner dans la prochaine seconde! 🔥