""" piano_python3.py
"""
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# importation du programme depuis :
# https://openclassrooms.com/forum/sujet/python-realisation-d-un-piano
# http://theremin.music.uiowa.edu/MISpiano.html : fichiers aiff (inutile de les convertir en wav)
#
# recherche d'un air :
# cailloux et coquillages
# SI3 MI4 MI4 MIb4 MI4 SOLb4 SOL4 MI4 SOL4 SOLb4 MI4 RE4 DO4 DO4 SI3
# Adagio
# MI4 RE4 DO4 SI3 LA3 LA3 LAb3 FA4 MI4 RE4 DO4 SI3 SI3 LA3 \
# LA4 SOL4 LA4 FA4 SOL4 MI4 FA4 SOL4 FA4 SOL4 MI4 FA4 RE4 MI4 \
# MI4 FA4 MI4 FA4 RE4 MI4 DO4 RE4 SI3 MI4 RE4 MI4 \
# LA4 SOL4 LA4 FA4 SOL4 MI4 FA4 RE4 SOL4 FA4 SOL4 MI4 FA4 RE4 MI4
# Arlésienne
# FA4 DO4 FA4 SOL4 LAb4 SOL4 LAb4 FA4 DO5 LAb4 SIb4 DO5 \
# REb5 DO5 SIb4 LAb4 SOL4 DO5 FA4 


import pygame # Importation du module pygame
# mes propres imports :
import tkinter # python 3
import time
import numpy as np

tab_noms_notes_fr = [ 'DO', 'REb', 'RE', 'MIb', 'MI', 'FA', 'SOLb', 'SOL', 'LAb', 'LA', 'SIb', 'SI' ]
tab_noms_notes_en = [ 'C', 'Db', 'D', 'Eb', 'E', 'F', 'Gb', 'G', 'Ab', 'A', 'Bb', 'B' ]
# pygame sert uniquement à jouer les notes :
# key = pygame.key.get_pressed()  # checking pressed keys
# if key[pygame.K_a]:

pygame.init()
pygame.mixer.init(frequency=44100, size=-16, channels=1)

# Fréquence de référence : LA4 = 440 Hz
def get_frequency(note, octave):
    semitone = tab_noms_notes_fr.index(note)
    n = semitone + 12 * (octave - 4)
    return 440 * 2**((n - 9) / 12)

# Génère une onde sinusoïdale pour une note donnée
def generate_sound(note, octave, duration=1.0, volume=0.5):
    sample_rate = 44100
    freq = get_frequency(note, octave)
    t = np.linspace(0, duration, int(sample_rate * duration), False)
    waveform = 32767 * np.sin(2 * np.pi * freq * t) * volume
    sound = np.array(waveform, dtype=np.int16)
    return pygame.mixer.Sound(buffer=sound)

# Dictionnaire de notes synthétisées
print("# génération des sons synthétiques")
notes = {}
for i in range(3):  # octaves 3 à 5
    octave = i + 3
    for note in tab_noms_notes_fr:
        note_fr = note + str(octave)
        notes[note_fr] = generate_sound(note, octave)

# Fonctions de gestion des sons
enregistrement = []

def jouerNote(note):
    global enregistrement
    print(note, end=' ')
    s = notes[note]
    s.play(maxtime=1000)
    # stockage de la note jouée
    enregistrement.append(note)
    return

def replay() :
    print()
    for note in enregistrement :
        print(note, end=' ')
        s = notes[note]
        s.play(maxtime=1000)
        time.sleep(0.5)
    return

def effacer() :
    # efface la dernière note
    # efface les n dernières notes en appuyant n fois
    global enregistrement
    if enregistrement:
        enregistrement.pop()

def effacer_tout():
    global enregistrement
    enregistrement = []

def imprime() :
    # imprime les notes en cours (sans les notes effacées)
    print()
    for note in enregistrement:
        print(note, end=' ')
    print()

# GUI avec tkinter # Fenetre principale
Fenetre = tkinter.Tk()
Fenetre.title("Clavier Piano Synthétique") # Definition du nom de la fenetre
# creation du cadre avec une grille
frame = tkinter.Frame(Fenetre)
frame.grid()

# Boutons : touches du clavier
print("# création des touches")
for ligne in range(3):  # octaves 3, 4, 5
    octave = ligne + 3
    tab_bouton = [None for _ in tab_noms_notes_fr]
    for position, note in enumerate(tab_noms_notes_fr):
        note_fr = note + str(octave)
        couleur = "gray" if "b" in note else "white"
        hauteur = 8 if "b" in note else 15
        largeur = 4 if "b" in note else 8
        bouton = tkinter.Button(frame, height=hauteur, width=largeur,
                                text=note_fr, bg=couleur, fg="black",
                                command=lambda x=note_fr: jouerNote(x))
        bouton.grid(row=ligne, column=position, sticky="ns")

# Boutons d'action
tkinter.Button(frame, height=2, width=8, text="replay", bg="white", fg="black", command=replay).grid(row=3, column=0)
tkinter.Button(frame, height=2, width=8, text="effacer\nla dernière\nnote", bg="white", fg="black", command=effacer).grid(row=3, column=2)
tkinter.Button(frame, height=2, width=8, text="effacer\ntout", bg="white", fg="black", command=effacer_tout).grid(row=3, column=4)
tkinter.Button(frame, height=2, width=8, text="imprime", bg="white", fg="black", command=imprime).grid(row=3, column=5)

Fenetre.mainloop()
"""
"""