class Module(BaseModule):
    """
    "Phase vocoder spectral delay"
    
    Description

    This module applies different delay times and feedbacks for
    each bin of a phase vocoder analysis. Delay times and
    feedbacks are specified via grapher functions.

    Sliders
    
        # Max Delay : 
            Maximum delay time per bin. Used to allocate memories.
            only available at initialization time
        # Dry / Wet : 
            Mix between the original signal and the delayed signals

    Graph Only

        # Overall Amplitude : 
            The amplitude curve applied on the total duration of the performance 
        # Bin Delays : 
            Controls the delay time for every bin, 
            from left (low freq) to right (high freq) on the graph
        # Bin Feedbacks : 
            Controls the feedback factor for every bin, from left to right on the graph
    
    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")

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

        self.dtab = DataTable(size=8192)
        self.tabscl = TableScale(self.delays, self.dtab, mul=frames)
        
        self.delsrc = Delay(self.snd, delay=self.size*self.oneOverSr)

        self.fin = PVAnal(self.snd, size=self.size, overlaps=self.olaps, wintype=wintype)
        self.dls = PVDelay(self.fin, self.dtab, self.feeds, maxdelay=self.maxd.get(), mode=1)
        self.fout = PVSynth(self.dls, wintype=wintype, mul=self.env)

        self.fade = SigTo(value=1, time=.05, init=1)
        self.out = Interp(self.delsrc*self.env, self.fout, self.mix, mul=self.fade)

    def fftsize(self, index, value):
        self.size = int(value)
        self.fade.value = 0
        time.sleep(.05)
        self.delsrc.delay = self.size*self.oneOverSr
        self.fin.size = self.size
        frames = int(self.maxd.get() * self.sr / (self.size / self.olaps))
        self.tabscl.mul = frames
        time.sleep(.05)
        self.fade.value = 1

    def overlaps(self, index, value):
        self.olaps = int(value)
        self.fade.value = 0
        time.sleep(.05)
        self.fin.overlaps = self.olaps
        frames = int(self.maxd.get() * self.sr / (self.size / self.olaps))
        self.tabscl.mul = frames
        time.sleep(.05)
        self.fade.value = 1

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

    def maxd_up(self, value):
        pass

Interface = [   csampler(name="snd"), 
                cgraph(name="env", label="Overall Amplitude", func=[(0,1),(1,1)], col="blue"),
                cgraph(name="delays", label="Bin Delays", table=True, size=8192, func=[(0,0),(1,0.5)], col="green"),
                cgraph(name="feeds", label="Bin Feedbacks", table=True, size=8192, func=[(0,0.25),(1,0.25)], col="orange"),
                cslider(name="maxd", label="Max delay", min=0.1, max=20, init=5, rel="lin", unit="secs", up=True),
                cslider(name="mix", label="Dry / Wet", min=0, max=1, init=1, rel="lin", unit="x", col="blue"),
                cpopup(name="fftsize", label="FFT Size", init="1024", value=["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", value=["1", "2", "4", "8", "16"]),
                cpoly()
          ]

