class Module(BaseModule):
    """
    "AM/FM modulated filter"

    Description
    
    The input sound is filtered by a variable type modulated filter.
    Speed, depth and shape can be modified for both AM and FM modulators.
    
    Sliders
    
        # Filter Mean Freq : 
            Mean frequency of the filter
        # Resonance : 
            Q factor of the filter
        # AM Depth : 
            Amplitude of the amplitude modulator
        # AM Freq : 
            Speed, in Hz, of the amplitude modulator 
        # FM Depth : 
            Amplitude of the frequency modulator
        # FM Freq : 
            Speed, in Hz, of the frequency modulator 
        # Mod Sharpness :
            Sharpness of waveforms used as modulators
        # Dry / Wet : 
            Mix between the original signal and the filtered signal
    
    Graph Only
    
        # Overall Amplitude : 
            The amplitude curve applied on the total duration of the performance

    Popups & Toggles
    
        # Filter Type : 
            Type of filter
        # AM Mod Type : 
            Shape of the amplitude modulator
        # FM Mod Type : 
            Shape of the frequency modulator
        # Balance :
            Compression mode. Off, balanced with a fixed signal
            or balanced with the input source.
        # Polyphony Voices : 
            Number of voices played simultaneously (polyphony), 
            only available at initialization time
        # Polyphony Spread : 
            Pitch variation between voices (chorus), 
            only available at initialization time
    
    """
    def __init__(self):
        BaseModule.__init__(self)
        self.snd = self.addSampler("snd")
        self.lfomodAM = LFO(freq=self.modfreqAM, sharp=self.modSharp, type=self.modtypeAM_index, mul=0.5, add=0.5)
        self.lfomodFM = LFO(freq=self.modfreqFM, sharp=self.modSharp, type=self.modtypeFM_index, mul=0.5, add=0.5)
        self.filt = Biquadx(input=self.snd, freq=self.centerfreq*(self.lfomodFM*(self.moddepthFM*2)+(1-self.moddepthFM))+50, q=self.filterq,
                                type=self.filttype_index, stages=2, mul=0.7 *(self.lfomodAM*self.moddepthAM+(1-self.moddepthAM)))
        self.deg = Interp(self.snd, self.filt, self.drywet, mul=self.env)

        self.osc = Sine(10000,mul=.1)
        self.balanced = Balance(self.deg, self.osc, freq=10)
        self.out = Interp(self.deg, self.balanced)

#INIT
        self.balance(self.balance_index, self.balance_value)

    def filttype(self, index, value):
        self.filt.type = index

    def modtypeFM(self, index, value):
        self.lfomodFM.type = (index - 1) % 8

    def modtypeAM(self, index, value):
        self.lfomodAM.type = (index - 1) % 8
        
    def balance(self,index,value):
        if index == 0:
            self.out.interp  = 0
        elif index == 1:
            self.out.interp  = 1
            self.balanced.input2 = self.osc
        elif index == 2:
            self.out.interp = 1
            self.balanced.input2 = self.snd
            
Interface = [   csampler(name="snd"), 
                cgraph(name="env", label="Overall Amplitude", func=[(0,1),(1,1)], col="blue1"),
                cslider(name="centerfreq", label="Filter Mean Freq", min=20, max=20000, init=2000, rel="log", unit="Hz", col="green1"),
                cslider(name="filterq", label="Resonance", min=0.5, max=10, init=0.707, rel="lin", unit="Q", col="green2"),
                cslider(name="moddepthAM", label="AM Depth", min=0.001, max=1, init=0.5, rel="lin", unit="x", col="red1", half=True),
                cslider(name="moddepthFM", label="FM Depth", min=0.001, max=1, init=0.85, rel="lin", unit="x", col="purple1", half=True),
                cslider(name="modfreqAM", label="AM Freq", min=0.01, max=2000, init=1, rel="log", unit="Hz", col="red2", half=True),
                cslider(name="modfreqFM", label="FM Freq", min=0.01, max=2000, init=10, rel="log", unit="Hz", col="purple2", half=True),
                cslider(name="modSharp", label="Mod Sharpness", min=0, max=1, init=0.5, rel="lin", unit="x", col="orange1"),
                cslider(name="drywet", label="Dry / Wet", min=0, max=1, init=1, rel="lin", unit="x", col="blue1"),
                cpopup(name="filttype", label="Filter Type", init="Bandpass", col="green1", value=["Lowpass","Highpass","Bandpass","Bandstop"]),
                cpopup(name="modtypeAM", label="AM Mod Type", init="Sine", col="red1", value=["Sine", "Saw Up", "Saw Down", "Square", "Triangle", "Pulse", "Bipolar Pulse",
                            "SAH"]),
                cpopup(name="modtypeFM", label="FM Mod Type", init="Sine", col="purple1", value=["Sine", "Saw Up", "Saw Down", "Square", "Triangle", "Pulse", "Bipolar Pulse",
                            "SAH"]),
                cpopup(name="balance", label = "Balance", init= "Off", col="blue1", value=["Off","Compress", "Source"]),

                cpoly()
          ]

