import math as m
import matplotlib.pyplot as plt


def graphe(func,a,b) :
    N = 1000 # nombre de points
    lx = [a+i*(b-a)/N for i in range(N+1)]
    ly = [func(x) for x in lx]
    plt.plot(lx,ly)
    plt.show()


def imp_cos(freq,amp,phase,offset) :
    def out(t) :
        return offset+amp*m.cos(2*m.pi*freq*t+phase)
    return out


def trig(freq,amp,offset) :
    def out(t) :
        T = 1/freq
        t=t%T
        if t<=T/2 :
            return offset-amp+t*4*amp/T
        else :
            return offset+amp-(t-T/2)*4*amp/T
    return out


def can(func,fech,delta_t,n_bits) :
    l_float = []
    N = 2**n_bits
    v_min,v_max = func(0),func(0)
    for i in range(int(fech*delta_t)+1):
        v = func(i/fech)
        l_float.append(v)
        if v<v_min :
            v_min=v
        if v>v_max :
            v_max=v
    vm = max(abs(v_min),v_max)
    pas = 2*vm/(N-1)
    l_quant = [round(v/pas)*pas for v in l_float]
    return l_float,l_quant


def cna(l_quant,fech,delta_t) :
    def out(t) :
        i = round(t*fech)
        return l_quant[i]
    return out


def passe_bas(l_quant,fech,fc):
    n = len(l_quant)
    out = [0 for _ in range(n)]
    out[0] = 0
    for i in range(n-1):
        out[i+1]=out[i]*(1-2*m.pi*fc/fech)+l_quant[i]*2*m.pi*fc/fech
    return out


def passe_haut(l_quant,fech,fc):
    n = len(l_quant)
    out = [0 for _ in range(n)]
    out[0] = 0
    for i in range(n-1):
        out[i+1]=out[i]*(1-2*m.pi*fc/fech)+l_quant[i+1]-l_quant[i]
    return out



liste = can(trig(10,5,0),100,0.1,8)
print(liste)
l_trig = liste[1]
graphe(trig(10,5,0),0,0.1)
fnum_trig = cna(l_trig,100,0.1)
graphe(fnum_trig,0,0.1)



plt.figure()
liste = can(imp_cos(10,5,0,2),1000,1,16)
l_cos = liste[1]
graphe(imp_cos(10,5,0,2),0,1)
fnum_cos = cna(l_cos,1000,1)
graphe(fnum_cos,0,1)

l_cos_filtre = passe_bas(l_cos,1000,1)
fnum_cos_filtre = cna(l_cos_filtre,1000,1)
graphe(fnum_cos_filtre,0,1)
plt.title('passe-bas')














