import numpy as np
import librosa

def lpc_analysis(speech, L, S, order):
    '''
    Chop speech into frames, and compute LPC coefficients.
    You are allowed to use the following functions, which might be useful:
    librosa.util.frame (axis=0), librosa.lpc (axis=-1).

    @param:
    speech (T,) - input speech signal
    L (1,) - frame length in samples
    S (1,) - number of samples skipped between frame starts

    @return:
    frames (1+(T-L)//S,L) - frames of speech
    coefficients (1+(T-L)//S,order+1)
    '''
    raise NotImplementedError("You need to write this!")

def lpc_inverse(frames, A):
    '''
    Inverse filter speech frames to estimate the excitation signal.

    @param:
    frames (nframes,framelength) - speech frames
    A (nframes,order+1) - LPC coefficients (A[m,0]=1 always)

    @return:
    excitation (nframes,framelength-order) - linear prediction excitation frames
    '''
    raise NotImplementedError("You need to write this!")

def lpc_synthesis(e, A, S):
    '''
    Synthesize speech from LPC residual and coefficients.
    
    @param:
    e (duration,) - excitation signal
    A (nframes,order+1) - linear predictive coefficients from each frames
    S (1,) - frame skip, in samples
    
    @returns:
    synthesis (duration) - synthetic speech waveform
    '''
    raise NotImplementedError("You need to write this!")

def lpc_gain(excitation):
    '''
    Calculate the LPC filter gain for each frame.

    @param:
    excitation (nframes,framelength) - inverse-filtered speech signal

    @return:
    gain (nframes,) - gain[m] is the RMS energy of excitation[m,:]
    '''
    raise NotImplementedError("You need to write this!")

