class Module(BaseModule):
    """
    "Phase Vocoder based frequency shifters"
    
    Description

    This module implements two voices that linearly moves the analysis bins 
    by the amount, in Hertz, specified by the the `Shift 1` and `Shift 2` 
    parameters.

    Sliders
    
        # Shift 1 : 
            Shifting, in Hertz, of the first voice
        # Shift 2 : 
            Shifting, in Hertz, of the second voice
        # Dry / Wet : 
            Mix between the original signal and the delayed signals
    
    Popups & Toggles

        # FFT Size : 
            Size, in samples, of the FFT
        # FFT Envelope : 
            Windowing shape of the FFT
        # FFT Overlaps : 
            Number of FFT overlaping analysis
        # 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")

        size = int(self.fftsize_value)
        olaps = int(self.overlaps_value)
        wintype = self.wtype_index
        self.oneOverSr = 1.0 / self.sr

        self.delsrc = Delay(self.snd, delay=size*self.oneOverSr)

        self.fin = PVAnal(self.snd, size=size, overlaps=olaps, wintype=wintype)
        self.tr1 = PVShift(self.fin, shift=self.shift1)
        self.tr2 = PVShift(self.fin, shift=self.shift2)
        self.fout1 = PVSynth(self.tr1, wintype=wintype)
        self.fout2 = PVSynth(self.tr2, wintype=wintype)
        self.fout = self.fout1 + self.fout2
        self.fade = SigTo(value=1, time=.05, init=1)
        self.out = Interp(self.delsrc*0.5, self.fout*0.4, self.mix, mul=self.fade*self.env)

    def fftsize(self, index, value):
        newsize = int(value)
        self.fade.value = 0
        time.sleep(.05)
        self.delsrc.delay = newsize*self.oneOverSr
        self.fin.size = newsize
        time.sleep(.05)
        self.fade.value = 1

    def overlaps(self, index, value):
        olaps = int(value)
        self.fade.value = 0
        time.sleep(.05)
        self.fin.overlaps = olaps
        time.sleep(.05)
        self.fade.value = 1

    def wtype(self, index, value):
        self.fin.wintype = index
        self.fout.wintype = index

Interface = [   csampler(name="snd"), 
                cgraph(name="env", label="Overall Amplitude", func=[(0,1),(1,1)], col="blue"),
                cslider(name="shift1", label="Shift 1", min=-8000, max=8000, init=250, rel="lin", unit="Hz", col="green1"),
                cslider(name="shift2", label="Shift 2", min=-8000, max=8000, init=500, rel="lin", unit="Hz", col="green2"),
                cslider(name="mix", label="Dry / Wet", min=0, max=1, init=0.5, rel="lin", unit="x", col="blue"),
                cpopup(name="fftsize", label="FFT Size", init="1024", value=["16", "32", "64", "128", "256", "512", "1024", "2048", "4096", "8192"], col="red"),
                cpopup(name="wtype", label="FFT Envelope", init="Hanning", col="red", value=["Rectangular", "Hamming", "Hanning", "Bartlett",
                            "Blackman 3", "Blackman 4", "Blackman 7", "Tuckey", "Sine"]),
                cpopup(name="overlaps", label="FFT Overlaps", init="4", col="red", value=["1", "2", "4", "8", "16"]),
                cpoly()
          ]

