class Module(BaseModule):
    """
    "Sampler-based harmonizer module with multiple voices"
    
    Description

    The input sound is mixed with five real-time, non-stretching,
    harmonization voices.

    Sliders
    
        # Transpo Voice 1 : 
            Pitch shift of the first voice
        # Gain Voice 1 : 
            Gain of the transposed first voice
        # Transpo Voice 2 : 
            Pitch shift of the second voice
        # Gain Voice 2 : 
            Gain of the transposed second voice
        # Transpo Voice 3 : 
            Pitch shift of the third voice
        # Gain Voice 3 : 
            Gain of the transposed third voice
        # Transpo Voice 4 : 
            Pitch shift of the fourth voice
        # Gain Voice 4 : 
            Gain of the transposed fourth voice
        # Transpo Voice 5 : 
            Pitch shift of the fifth voice
        # Gain Voice 5 : 
            Gain of the transposed fifth voice
        # Feedback : 
            Amount of transposed signal fed back into the harmonizers
            (feedback is voice independent)
        # Dry / Wet : 
            Mix between the original signal and the harmonized signals
    
    Graph Only
    
        # Overall Amplitude : 
            The amplitude curve applied on the total duration of the performance

    Popups & Toggles
    
        # Win Size :
            Harmonizer window size in seconds
        # Balance :
            Compression mode. Off, balanced with a fixed signal
            or balanced with the input source.
        # Voice Activation (1 --> 5)
            Mute or unmute each voice independently
        # 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.mul1 = DBToA(self.gain1, mul=self.onoffv1_value)
        self.mul2 = DBToA(self.gain2, mul=self.onoffv2_value)
        self.mul3 = DBToA(self.gain3, mul=self.onoffv3_value)
        self.mul4 = DBToA(self.gain4, mul=self.onoffv4_value)
        self.mul5 = DBToA(self.gain5, mul=self.onoffv5_value)
        self.harm1 = Harmonizer(input=self.snd, transpo=self.transp1, feedback=self.fb, winsize=float(self.winsize_value), mul=self.mul1*0.3)
        self.harm2 = Harmonizer(input=self.snd, transpo=self.transp2, feedback=self.fb, winsize=float(self.winsize_value), mul=self.mul2*0.3)
        self.harm3 = Harmonizer(input=self.snd, transpo=self.transp3, feedback=self.fb, winsize=float(self.winsize_value), mul=self.mul3*0.3)
        self.harm4 = Harmonizer(input=self.snd, transpo=self.transp4, feedback=self.fb, winsize=float(self.winsize_value), mul=self.mul4*0.3)
        self.harm5 = Harmonizer(input=self.snd, transpo=self.transp5, feedback=self.fb, winsize=float(self.winsize_value), mul=self.mul5*0.3)
        self.harms = self.harm1+self.harm2+self.harm3+self.harm4+self.harm5
        self.drydel = Delay(self.snd, delay=float(self.winsize_value)*0.5)
        self.deg = Interp(self.drydel, self.harms, 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 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
        
    def winsize(self, index, value):
        self.harm1.winsize = float(value)
        self.harm2.winsize = float(value)
        self.harm3.winsize = float(value)
        self.harm4.winsize = float(value)
        self.harm5.winsize = float(value)
        self.drydel.delay = float(value)*0.5

    def onoffv1(self, value):
        self.mul1.mul = value
    
    def onoffv2(self, value):
        self.mul2.mul = value
    
    def onoffv3(self, value):
        self.mul3.mul = value
    
    def onoffv4(self, value):
        self.mul4.mul = value
    
    def onoffv5(self, value):
        self.mul5.mul = value
        
Interface = [   csampler(name="snd"), 
                cgraph(name="env", label="Overall Amplitude", func=[(0,1),(1,1)], col="blue1"),
                cslider(name="transp1", label="Transpo Voice 1", min=-24, max=24, init=0, rel="lin", unit="semi", col="red1",half=True),
                cslider(name="gain1", label="Gain Voice 1", min=-48, max=18, init=0, rel="lin", unit="dB", col="red2",half=True),
                cslider(name="transp2", label="Transpo Voice 2", min=-24, max=24, init=3, rel="lin", unit="semi", col="purple1",half=True),
                cslider(name="gain2", label="Gain Voice 2", min=-48, max=18, init=0, rel="lin", unit="dB", col="purple2",half=True),
                cslider(name="transp3", label="Transpo Voice 3", min=-24, max=24, init=5, rel="lin", unit="semi", col="orange1",half=True),
                cslider(name="gain3", label="Gain Voice 3", min=-48, max=18, init=0, rel="lin", unit="dB", col="orange2",half=True),
                cslider(name="transp4", label="Transpo Voice 4", min=-24, max=24, init=-2, rel="lin", unit="semi", col="blue2",half=True),
                cslider(name="gain4", label="Gain Voice 4", min=-48, max=18, init=0, rel="lin", unit="dB", col="blue3",half=True),
                cslider(name="transp5", label="Transpo Voice 5", min=-24, max=24, init=-4, rel="lin", unit="semi", col="green1",half=True),
                cslider(name="gain5", label="Gain Voice 5", min=-48, max=18, init=0, rel="lin", unit="dB", col="green2",half=True),
                cslider(name="fb", label="Feedback", min=0, max=0.999, init=0, 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="winsize", label="Win Size", init="0.1", col="blue4", value=["0.025","0.05","0.1","0.15","0.2","0.25","0.5","0.75","1"]),
                cpopup(name="balance", label = "Balance", init= "Off", col="blue1", value=["Off","Compress", "Source"]),
                ctoggle(name="onoffv1", label="Voice Activation ( 1 --> 5 )", init=1, stack=True, col="green1"),
                ctoggle(name="onoffv2", label="", init=1, stack=True, col="green1"),
                ctoggle(name="onoffv3", label="", init=1, stack=True, col="green1"),
                ctoggle(name="onoffv4", label="", init=1, stack=True, col="green1"),
                ctoggle(name="onoffv5", label="", init=1, stack=True, col="green1"),
                cpoly()
          ]

