"""
TP Électronique 9
EFFET D'UN FILTRE SUR UN SIGNAL

Script à compléter
"""

import numpy as np
import matplotlib.pyplot as plt


### ============================================================================
### DÉFINITION DES FONCTIONS
### ============================================================================

def spectre_creneau(freq, ampl, offset, Nharm):
    """
    Renvoie le spectre d'un signal créneau
    freq : fréquence
    ampl : amplitude crête-à-crête
    offset : composante continue
    Nharm : nombre d'harmoniques à considérer en plus de la composante continue
    """
    f = [0] # composante continue
    A = [offset]
    phi = [0]

    for n in range(Nharm):
        f.append( (2*n+1)*freq )
        A.append( 2*ampl/(np.pi * (2*n+1)) )
        phi.append(-np.pi/2)
    
    return f, A, phi

def spectre_triangle(freq, ampl, offset, Nharm):
    """
    Renvoie le spectre d'un signal triangle
    freq : fréquence
    ampl : amplitude crête-à-crête
    offset : composante continue
    Nharm : nombre d'harmoniques à considérer en plus de la composante continue
    """
    f = [0] # composante continue
    A = [offset]
    phi = [0]

    for n in range(Nharm):
        f.append( (2*n+1)*freq )
        A.append( 8*ampl/(np.pi**2 * (2*n+1)**2) )
        phi.append(0)
    
    return f, A, phi

def spectre_to_signal(sp):
    """
    Renvoie le signal temporel sur trois périodes associé au spectre sp
    sp : liste à trois éléments f (fréquence des harmoniques), 
    A (amplitude des harmoniques) et phi (phase des harmoniques)
    """
    f, A, phi = sp

    # Fréquence du fondamental et période du signal
    # (pour distinguer une éventuelle composante continue)
    if f[0] < 1e-12:
        T = 1/f[1]
    else :
        T = 1/f[0]

    # Construction harmonique par harmonique du signal de sortie
    t = np.linspace(0,3*T,1000)
    s = np.zeros_like(t)

    ### à compléter
    
    return t,s

def H_PBas1(f, H0, fc, Q=None):
    """
    Fonction de transfert d'un passe-bas d'ordre 1
    f : fréquence du signal d'entrée
    H0 : gain statique
    fc : fréquence de coupure
    Q : aucun rôle
    """
    x = f/fc
    return H0/(1+1j*x)

def H_PHaut1(f, H0, fc, Q=None):
    """
    Fonction de transfert d'un passe-haut d'ordre 1
    f : fréquence du signal d'entrée
    H0 : gain en haute fréquence
    fc : fréquence de coupure
    Q : aucun rôle
    """
    x = f/fc
    return H0*1j*x/(1+1j*x)

def H_PBas2(f, H0, f0, Q):
    """
    Fonction de transfert d'un passe-bande d'ordre 2
    f : fréquence du signal d'entrée
    H0 : gain à la résonance
    f0 : fréquence propre
    Q : facteur de qualité
    """
    x = f/f0
    return H0/(1 - x**2 + 1j*x/Q)

def H_PBande(f, H0, f0, Q):
    """
    Fonction de transfert d'un passe-bande d'ordre 2
    f : fréquence du signal d'entrée
    H0 : gain à la résonance
    f0 : fréquence de résonance
    Q : facteur de qualité
    """
    x = f/f0
    return H0/(1+1j*Q*(x-1/x))

def calc_spectre_sortie(sp, H, H0, fc, Q=None):
    """
    Renvoie le spectre de sortie d'un filtre connaissant le spectre d'entrée
    sp : spectre d'entrée
    H : fonction permettant de calculer la fonction de transfert du filtre
        doit être une des fonctions définies ci-dessus
    H0, fc, Q : arguments à fournir à la fonction de transfert du filtre
    """
    f, Ae, phi_e = sp

    As = []
    phi_s = []

    ### à compléter
    
    return f, As, phi_s

def affiche_spectre(sp):
    f, A, phi = sp
    w = (f[2] - f[1])/8
    plt.bar(f, A, width=.8*w)

### ================================================================================
### PROGRAMME UTILISANT LES FONCTIONS DÉFNIES CI-DESSUS
### ================================================================================







