# py/pyext - python script objects for PD and MaxMSP
#
# Copyright (c) 2002-2005 Thomas Grill (gr@grrrr.org)
# For information on usage and redistribution, and for a DISCLAIMER OF ALL
# WARRANTIES, see the file, "license.txt," in this distribution.  
#

from __future__ import division
try:
	import pyext
except:
	print "ERROR: This script must be loaded by the PD/Max pyext external"

import random
from copy import deepcopy

# helper function - determine whether argument is a numeric type
def isNumber(value):
	import types
	if type(value) in (types.FloatType, types.IntType, types.LongType):
		return 1
	else:
		return 0

class cluster(pyext._class):
	"""cluster getriggerd door velocity (in 2), hoe luider hoe meer noten in cluster
	(max 16, min 4, met kwarttonen - gemaakt voor Xy-automaat)
	eerste ingang (pitch) = middelste noot van cluster
	in1 = pitch
	in2 = velocity, triggert en bepaalt grootte van cluster
	in3 = toonhoogte van 1 vd 3 noten (36,37 of 38) die plaats in zin weergeeft (geen 4tonen, integer)
        hoe hoger, hoe langer de galm (duur cluster voor QT of aantal ticks)
	in4 = velocity van 1 vd 3 noten, 
	out1 tot 16 = pitch voor cluster Xy
	out17 tot 24 = list met pitch voor cluster Qt
	out25 = lengte van list
	out26 = list met gate voor cluster QT

	nog extra uitgang voor gate xy maken (om herhaalde noten mogelijk te maken?)
	(functie van in3 en in4 later msschn nog verfijnen, in4 (velocity) lengte v cluster laten bepalen
	en in3 (pitch/zinsdeel) welk akkoordalgoritme)
	"""

	# number of inlets and outlets
	_inlets=3
	_outlets=26

	# temporary storage
	tpitch=60
	tvel=40
        lengthclus=32 #lengte van clusters QT in ticks 

	# constructor
	def __init__(self,*args):
		if len(args) == 1: 
			if isNumber(args[0]):
				self.tmp = args[0]
			else:
				print "cluster: __init__ has superfluous arguments"

	# methods
	def float_1(self,a):
            self.tpitch = a

        def int_2(self,b):
            xypitch=[self.tpitch-0.5,self.tpitch,self.tpitch+0.5,self.tpitch+1]
            self._outlet(1,self.tpitch)
            self._outlet(2,self.tpitch + 0.5)
            self._outlet(3,self.tpitch - 0.5)
            self._outlet(4,self.tpitch + 1)
            if b > 10:
                self._outlet(5,self.tpitch - 1)
                xypitch.append(self.tpitch - 1)
            else:
                self._outlet(5,60) #midi pitch 60 is buiten tessituur Xy... doet niets dus, dit om te vermijden dat er nog meer uitgangen per sem nodig zouden zijn)
            if b > 20:
                self._outlet(6,self.tpitch + 1.5)
                xypitch.append(self.tpitch + 1.5)
            else:
                self._outlet(6,60)
            if b > 30:
                self._outlet(7,self.tpitch - 1.5)
                xypitch.append(self.tpitch - 1.5)
            else:
                self._outlet(7,60)
            if b > 40:
                self._outlet(8,self.tpitch + 2)
                xypitch.append(self.tpitch + 2)
            else:
                self._outlet(8,60)
            if b > 50:
                self._outlet(9,self.tpitch - 2)
                xypitch.append(self.tpitch - 2)
            else:
                self._outlet(9,60)
            if b > 60:
                self._outlet(10,self.tpitch + 2.5)
                xypitch.append(self.tpitch + 2.5)
            else:
                self._outlet(10,60)
            if b > 70:
                self._outlet(11,self.tpitch - 2.5)
                xypitch.append(self.tpitch - 2.5)
            else:
                self._outlet(11,60)
            if b > 80:
                self._outlet(12,self.tpitch + 3)
                xypitch.append(self.tpitch + 3)
            else:
                self._outlet(12,60)
            if b > 90:
                self._outlet(13,self.tpitch - 3)
                xypitch.append(self.tpitch - 3)
            else:
                self._outlet(13,60)
            if b > 100:
                self._outlet(14,self.tpitch + 3.5)
                xypitch.append(self.tpitch + 3.5)
            else:
                self._outlet(14,60)
            if b > 110:
                self._outlet(15,self.tpitch - 3.5)
                xypitch.append(self.tpitch - 3.5)
            else:
                self._outlet(15,60)
            if b > 120:
                self._outlet(16,self.tpitch + 4)
                xypitch.append(self.tpitch + 4)
            else:
                self._outlet(16,60)
            random.shuffle(xypitch)
            qtpitch=xypitch
            tmp1=[qtpitch[0]] * (self.lengthclus + 1) # list met pitch
            self._outlet(17,tmp1)
            tmp2=[qtpitch[1]] * (self.lengthclus + 1)
            self._outlet(18,tmp2)
            tmp3=[qtpitch[2]] * (self.lengthclus + 1)
            self._outlet(19,tmp3)
            tmp4=[qtpitch[3]] * (self.lengthclus + 1)
            self._outlet(20,tmp4)
            if b > 10:
                tmp5=[qtpitch[4]] * (self.lengthclus + 1)
                self._outlet(21,tmp5)
            if b > 20:
                tmp6=[qtpitch[5]] * (self.lengthclus + 1)
                self._outlet(22,tmp6)
            if b > 30:
                tmp7=[qtpitch[6]] * (self.lengthclus + 1)
                self._outlet(23,tmp7)
            if b > 40:
                tmp8=[qtpitch[7]] * (self.lengthclus + 1)
                self._outlet(24,tmp8)
            self._outlet(25,self.lengthclus + 1) # aantal ticks
            tmg=[70] * self.lengthclus + [0]# list met gates, constante velocity 70
            self._outlet(26,tmg)
      
        def int_3(self,c):
            self.lengthclus = c
          
                     

class gliss1(pyext._class):
	"""glissando die naar hoofdpitch gaat
	in1 = pitch (eindpunt glissando)
	in2 = velocity (>60 -> Xy, <60 -> Qt), triggert
	in3 = range voor glis (*2, wordt er boven en onder bijgeteld)
	in4 = bepaalt aantal hoofdpitch in glissando
	in5 = methode voor 'geheugen', 0 = n hoofdnoten, absoluut, 1 = wel hoofdnoten, absoluut
	                               2 = n hoofdnoten, relatief  3 = wel hoofdnoten, relatief
	in6 = kans/waarschijnlijkheid (t 0 en 100) voor het lezen van short memory (laatste 5 patronen)
	in7 = kans (ts 0 en 100) voor het lezen van long memory (heeft 'voorrang' op short memory)
	in8 = list met toonaard/modus
	out1 = lengte van list
	out2 = 0 voor Xy, 1 voor QT
	out3 = list met pitch
	out4 = list met gate
	"""

	# number of inlets and outlets
	_inlets=8
	_outlets=8 # 4 laatste om te kunnen debuggen/checken

	# temporary storage
	tpitch=60
        rangeglis=6
        numberglis=2
        shortmem1=[[0,0],[0,0],[0,0],[0,0],[0,0]] # short term memory for patterns
        # twee versch shortmem buffers om overgang van relatieve naar absolute pitch mogelijk te maken
        shortmemrel=[[0,0],[0,0],[0,0],[0,0],[0,0]] # short term memory for relative pitches
        longmem1=[[0,0,0]] # long term memory for paterns
        longmemrel=[[0,0,0]] # long term memory for reative pitches 
        meth = 0 #methode voor geheugen
        chshort = 0 #chance/kans op lezen van short memory 
        chlong = 0#chance/kans op lezen van long memory
        modus = [0,0.5,2,3.5,4,4,6,6.5,8.5,9,10,10.5]
        rmodus =  [0,1,0,0,2,0,0,3,5,0,0,0,6,7,0,0,0,8,9,0,10,11] # reversed/omgekeerde modus

	# constructor
	def __init__(self,*args):
		if len(args) == 1: 
			if isNumber(args[0]):
				self.tmp = args[0]
			else:
				print "ex11: __init__ has superfluous arguments"

	# methods
	def float_1(self,a):
            self.tpitch = self.rmodus[int((a%12)*2)]+(int(a/12)*12) # terug naar oorspronkelijke pitch, was aangepast in pd-patch

	def float_2(self,b):
            ins = 0
            if b < 60:
                ins = 1
            else:
                ins = 0
            tmprange=self.rangeglis
            listmainp=[0]* self.numberglis
            for i,v in enumerate(listmainp):
                listmainp[i]=random.randint(self.tpitch - tmprange,self.tpitch + tmprange) 
            listmainp.append(self.tpitch) #vb 57,62,64,60
            
            s1 = random.randint(0,100)
            s2 = random.randint(0,100)
            r1 = []
            r2 = []
            # nu noten uit geheugen toevoegen, de toevalsnoten in listmainp worden niet overschreven, er ontstaan dus altijd variaties, ook als s1 of s2 100 is
            # mogelijke verbetering: hij hoofdnoten veranderen (dus 1 en 3, hieronder) van list uit geheugen hoofdlijst (listmainp) maken met enkele random waardes rond die hoofdnoten als versiering
            if s1 <= self.chlong:   # uit lang geheugen
                if self.meth == 1: # hoofdnoten veranderen, absolute toonhoogte
                    r1 = random.sample(self.longmem1[0],random.randint(1,len(self.longmem1[0])))# random aantal noten uit long memory
                    for v in r1:
                        listmainp.insert(random.randint(0,(len(listmainp)-2)),v) # -2 omdat laatste noot zelfde moet blijven (is de hoofdnoot van input)
                if self.meth == 3: # hoofdnoten veranderen, relatieve toonhoogte
                    r1 = random.sample(self.longmemrel[0],random.randint(1,len(self.longmemrel[0])))
                    for v in r1:
                        listmainp.insert(random.randint(0,(len(listmainp)-2)),(v + self.tpitch))
            if s1 > self.chlong and s2 <= self.chshort:     # als niet uit lang geheugen komt, dan uit kort geheugen
                if self.meth == 1: # hoofdnoten veranderen, absolute toonhoogte
                    r1 = self.shortmem1[random.randint(0,(len(self.shortmem1)-1))] #geen random.sample, die returned list met lists
                    r2 = random.sample(r1,random.randint(1,len(r1)))
                    for v in r2:
                        listmainp.insert(random.randint(0,(len(listmainp)-2)),v) # -2 omdat laatste noot zelfde moet blijven (is de hoofdnoot van input)
                if self.meth == 3: # hoofdnoten veranderen, relatieve toonhoogte
                    r1 = self.shortmemrel[random.randint(0,(len(self.shortmemrel)-1))] #geen random.sample, die returned list met lists
                    r2 = random.sample(r1,random.randint(1,len(r1)))
                    for v in r2:
                        listmainp.insert(random.randint(0,(len(listmainp)-2)),(v + self.tpitch))# -2 omdat laatste noot zelfde moet blijven
            listmainpmod = [self.modus[x%12]+int(x/12)*12 for x in listmainp] #aanpassen in toonaard
            
            # vanaf nu tussenliggende noten berekenen
            difmainp=[]
            temp=0
            for v in listmainpmod:
                difmainp.append(v-temp)
                temp=v
            del difmainp[0] # 5,2,-4
            nrfillp=[]   # om duur/aantal ticks te berekenen
            for v in difmainp:
                nrfillp.append(v*2)#10,4,-8
            dur = 0
            for num in nrfillp:
                dur = abs(num) + dur
            nrfillpsign=[]  #wl of niet positief in nrfillp list
            for v in nrfillp:
                if v < 0:
                    nrfillpsign.append(-1)
                if v >= 0:
                    nrfillpsign.append(1)
            lister=[]
            listtemp1=[]
            for num,nr in zip(nrfillpsign,nrfillp):
                listtemp1=range(0,int(abs(nr)))
                for ns in listtemp1:
                    lister.append(ns * 0.5 * num)#0,0.5,1,1.5,...tot 10
            listtemp2=[]
            listtemp3=range(len(nrfillp))
            for nm,nr in zip(listtemp3,nrfillp):
                listtemp2=listtemp2 + [nm]*int(abs(nr)) #0,0,0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,2,2,2,2
            listendp=[]
            for i,v in enumerate(listmainpmod):
                for nm,nr in zip(listtemp2,lister):
                    if i == nm:
                        listendp.append(v + nr)
            
            gatedef=[] # vanaf hier enkel voor QT die wel noteoffs nodig heeft...
            pitchdef=[]
            for z in listendp: # hierna enkel juist voor geval van 2 ticks per noot (on en off)
                gatedef = gatedef + [1] + [0]
                pitchdef=pitchdef + [z]* 2
            dtmp = range(0,len(gatedef)-1)

            # nu voor notenuit kort of lang geheugen die niet in hoofdnoten veranderd worden
            if s1 <= self.chlong:   # uit lang geheugen
                if self.meth == 0: # noten in eindreeks veranderen, absolute toonhoogte
                    r1 = random.sample(self.longmem1[0],random.randint(1,len(self.longmem1[0])))# random aantal noten uit long memory
                    r1m = [self.modus[x%12]+int(x/12)*12 for x in r1] # in toonaard passen
                    #nu noten uit r1m in lijst van gates (1,0,1,0 ,...) zetten op random plaats
                    ctmp = []
                    ptmp = []
                    for x in r1m:
                        ctmp = ctmp + [[1]*3 + [0]] # noten iets langer -4 ticks- maken
                        ptmp = ptmp + [[x]*4]
                    random.shuffle(dtmp)
                    tip = []
                    for x in dtmp:
	                if gatedef[x-1] == 0: # na een 0 in gatedef plaatsen, anders overlappende noten
		            tip.append(x)
	                if len(tip) == len(r1m):
		            break
		    for x,y,z in zip(ptmp,ctmp,reversed(sorted(tip))):  #'tip' sorteren en omdraaien, anders kan tijdens de for-loop de indexen veranderd -> chaos
	                for v,w in zip(reversed(x),reversed(y)):
		            pitchdef.insert(z,v)
		            gatedef.insert(z,w)
                        
                if self.meth == 2: # noten in eindreeks veranderen, relatieve toonhoogte
                    r1 = random.sample(self.longmemrel[0],random.randint(1,len(self.longmemrel[0])))
                    r1m = [self.modus[(x + self.tpitch)%12] + int((x + self.tpitch)/12)*12 for x in r1]
                    ctmp = []
                    ptmp = []
                    for x in r1m:
                        ctmp = ctmp + [[1]*3 + [0]] # noten iets langer -4 ticks- maken
                        ptmp = ptmp + [[x]*4]
                    random.shuffle(dtmp)
                    tip = []
                    for x in dtmp:
	                if gatedef[x-1] == 0: # na een 0 in gatedef plaatsen, anders overlappende noten
		            tip.append(x)
	                if len(tip) == len(r1m):
		            break
		    for x,y,z in zip(ptmp,ctmp,reversed(sorted(tip))):  #'tip' sorteren en omdraaien, anders kan tijdens de for-loop de indexen veranderd -> chaos
	                for v,w in zip(reversed(x),reversed(y)):
		            pitchdef.insert(z,v)
		            gatedef.insert(z,w)
                    
            if s1 > self.chlong and s2 <= self.chshort:     # als niet uit lang geheugen komt, dan uit kort geheugen
                if self.meth == 0: # noten in eindreeks veranderen, absolute toonhoogte
                    r1 = self.shortmem1[random.randint(0,(len(self.shortmem1)-1))] #geen random.sample, die returned list met lists
                    r2 = random.sample(r1,random.randint(1,len(r1)))
                    r2m = [self.modus[x%12]+int(x/12)*12 for x in r2]
                    ctmp = []
                    ptmp = []
                    for x in r2m:
                        ctmp = ctmp + [[1]*3 + [0]] # noten iets langer -4 ticks- maken
                        ptmp = ptmp + [[x]*4]
                    random.shuffle(dtmp)
                    tip = []
                    for x in dtmp:
	                if gatedef[x-1] == 0: # na een 0 in gatedef plaatsen, anders overlappende noten
		            tip.append(x)
	                if len(tip) == len(r2m):
		            break
		    for x,y,z in zip(ptmp,ctmp,reversed(sorted(tip))):  #'tip' sorteren en omdraaien, anders kan tijdens de for-loop de indexen veranderd -> chaos
	                for v,w in zip(reversed(x),reversed(y)):
		            pitchdef.insert(z,v)
		            gatedef.insert(z,w)
                    
                if self.meth == 2: # noten in eindreeks veranderen, relatieve toonhoogte
                    r1 = self.shortmemrel[random.randint(0,(len(self.shortmemrel)-1))] #geen random.sample, die returned list met lists
                    r2 = random.sample(r1,random.randint(1,len(r1)))
                    r2m = [self.modus[(x + self.tpitch)%12] + int((x + self.tpitch)/12)*12 for x in r2]
                    ctmp = []
                    ptmp = []
                    for x in r2m:
                        ctmp = ctmp + [[1]*3 + [0]] # noten iets langer -4 ticks- maken
                        ptmp = ptmp + [[x]*4]
                    random.shuffle(dtmp)
                    tip = []
                    for x in dtmp:
	                if gatedef[x-1] == 0: # na een 0 in gatedef plaatsen, anders overlappende noten
		            tip.append(x)
	                if len(tip) == len(r2m):
		            break
		    for x,y,z in zip(ptmp,ctmp,reversed(sorted(tip))):  #'tip' sorteren en omdraaien, anders kan tijdens de for-loop de indexen veranderd -> chaos
	                for v,w in zip(reversed(x),reversed(y)):
		            pitchdef.insert(z,v)
		            gatedef.insert(z,w)
            # ev. verbeteren : voorgaande en nakomende noot kan nog dezelfde zijn als die uit geheugen
            
            # nu pas geheugenbuffer updaten, gewijzigde versies zitten hierin, feedback mechanisme mogelijk...
            self.shortmem1.append(listmainp)
            del self.shortmem1[0]
            listmainprel=[]
            for v in listmainp:
                listmainprel.append(v - listmainp[len(listmainp)-1]) #verschil met laatste noot in list (=input pitch)
            self.shortmemrel.append(listmainprel)
            del self.shortmemrel[0]
            # methode voor schrijven naar long memory, hier 1 kans op 20
            s3 = random.randint(0,100)
            if s3 <= 5:
                self.longmem1.append(listmainp)
                del self.longmem1[0]
                self.longmemrel.append(listmainprel)
                del self.longmemrel[0]
            
            self._outlet(1,len(gatedef))# aantal ticks/pitches dat uit outlet3 en 4 gaat komen 
            self._outlet(2,ins)#instr Xy of Qt
            self._outlet(3,pitchdef)
            self._outlet(4,gatedef)
            for v in self.shortmem1: # deze manier omdat list met lists niet naar outlet van pyext mag
                self._outlet(5,v)
            for v in self.shortmemrel:
                self._outlet(6,v)
            for v in self.longmem1:
                self._outlet(7,v)
            for v in self.longmemrel:
                self._outlet(8,v)

        def float_3(self,c):
            self.tsentpitch = 36 - int(round(c))

        def float_4(self,d):
            self.tsentvel = d

        def int_5(self,e):
            self.meth = e

        def int_6(self,f):
            self.chshort = f

        def int_7(self,g):
            self.chlong = g

        def list_8(self,*a):
            self.modus = a
            for i,v in enumerate(a):
	        self.rmodus[int(v*2)] = i


class chords1(pyext._class):
    """op basis van dichtsbijzijnde noot in akk tov melodienoot en vorig akk wordt akk gekozen
    in1= pitch input die alles triggert
    in2 = ondergrens (pitch) voor bereik van akkoord
    in3 = bereik voor akk (optellen bij in2 -> binnen dit bereik ligt akkoord)
    in4 = slider1 (0-127) voor aan/uit van bereik van akk (vanaf bas)
    in5 = slider 2 (0-127) voor aan/it van bereik van akk (vanaf hoogste noot)
    out1= akk noot1 van basisligging/akk
    out2=akknoot 2 van basisligging/akk
    out3=akknoot 3 van basisligging/akk
    out4=akknoot 4 als er 4 zijn van basisligging
    out5= gate 1 of 0 voor akknoot 4 van basisligging"""
    
    # number of inlets and outlets
    _inlets=5
    _outlets=17

    # temporary storage
    akkC=[[9,10.5,4],[8.5,10.5,2,4],[6.5,10.5,0,4],[6,10,2],[9,0.5,4],[9,10.5,2,6],[6.5,10,0.5]] # akk 0,1,2,3 en 4; elk akk moet tenminste 3 noten hebben, anders problemen: zie verder!
    previous=1
    opvolg=[[0,1,2,3,5,6],[0,2,3,6],[0,1,3,4,5,6],[0,1,5,6],[0,1,2,6],[0,1,2,3,6],[0,1,3]] # vanuit akk 0 mogelijk om naar akk 2,3 of 4 te gaan, niet naar 1
    pmin = 36
    prange = 12
    prevout6 = 37 #vorige gekozen laagste noot van akk binnen bereik
    prevout7 = 0 #vorige/actuele noteon/off voor laagste noot v akk binnen bereik
    prevout8 = 38 #tweede noot van akk binnen bereik
    prevout9 = 0 #vorige/actuele noteon/off voor tweede noot v akk binnen bereik
    prevout10 = 39 #derde noot van akk binnen bereik
    prevout11 = 0 #vorige/actuele noteon/off voor derde noot v akk binnen bereik
    prevout12 = 40 #vierde noot...
    prevout13 = 0 #vorige/actuele noteon/off voor vierde noot v akk binnen bereik
    prevout14 = 41 #5de noot...
    prevout15 = 0 #vorige/actuele noteon/off voor vijfde noot v akk binnen bereik
    prevout16 = 42 #6de noot...
    prevout17 = 0 #vorige/actuele noteon/off voor zesde noot v akk binnen bereik
    slideronoff = 1 #1 = slider1 meest recent, 2 = slider2 meest recent
    slider1 = 127
    slider2 = 0
    omgekeerdmodus=[0,1,1,1,2,2,3,3,4,4,4,4,6,7,7,7,8,8,9,9,10,11,11,11]#omgekeerde van modus tabel in glisclus.pd file, om akk te kunnen weergeven zoals het gespeeld wordt
    
    # constructor
    def __init__(self,*args):
            if len(args) == 1: 
                    if isNumber(args[0]):
                            self.tmp = args[0]
                    else:
                            print "previous1: __init__ has superfluous arguments"

    def argsortik(self,lista):
        '''eigen argsort functie; vertreklijst vb [4,12,1,6] geeft [1,3,0,2], oorspronkelijke lijst wordt gesorteerd maar enkel de oorspronkelijke index wordt weergegeven'''
        listsort=sorted(lista)
        listd=[]
        listi=[]
        for i,v in enumerate(listsort):
                for ii,vv in enumerate(listsort):
                        if v == vv and i!=ii:
                                del listsort[ii]
        for nr in listsort:
                for i,v in enumerate(lista):
                        if nr==v:
                                listd.append(i)
        return listd

    def identruebegin(self,lista):
        '''maakt nieuwe lijst met voor elke waarde van lijst 1 of 0 als die waarde al of niet nog voorkomt in die lijst'''
        liste=[]
        listc=[]
        listd=[]
        for i,v in enumerate(lista):
                for ii,vv in enumerate(lista):
                        if v == vv and i!=ii:
                                listc.append(1)
                        else:
                                listc.append(0)
                if sum(listc)>0:
                        liste.append(1)
                else:
                        liste.append(0)
                listc=[]
        for v,m in zip(liste,lista):
            if v == 1 and m == min(lista):
                listd.append(1)
            else:
                listd.append(0)
        return listd


    # methods
    def float_1(self,a): #vb noot midi 74
        voriglist=[]              
        voriglist=self.opvolg[self.previous]
        listt=range(len(self.akkC))
        listo=[]
        for v in voriglist:
            listo.append(self.akkC[v])
        b = a%12
        d = int(a/12)*12
        copyakkC=deepcopy(listo)
        for i,v in enumerate(copyakkC):
            for ii,m in enumerate(v):
                copyakkC[i][ii]=abs(b-m)#vb [[0, 4, 7], [2, 6, 9], [3, 7, 2], [5, 9, 0], [9, 0, 3]]
        listmin=[]
        for m in copyakkC:
            listmin.append(min(m))#[0, 2, 2, 0, 0]
        listnext1=self.argsortik(listmin)#[0, 3, 4, 1, 2] verwijst naar index v listmin en ook naar die van (copy)akkC lijst
        listidentrue=self.identruebegin(listmin)#[1, 0, 0, 1, 1]
        c=0
        for v,m in zip(listidentrue,listmin): #om bij verschillende mogelijkheden (dus identieke meest nabije waarden) herhaling te vermijden dat altijd eerste
            if v==1 and m==min(listmin):
                c=c+1         # c=3 in vb, dan zijn er drie mogelijkheden om uit te kiezen, als c=0 maar 1
        listend=[]
        if c == 0:
            listend=listnext1[:1]      
        else:
            listend=listnext1[:c]
        random.shuffle(listend)
        richord = []
        richord = self.akkC[self.opvolg[self.previous][listend[0]]] # list met enkel het gekozen akk, right chord
        self._outlet(1,self.omgekeerdmodus[int(listo[listend[0]][0]*2)] + d)# met aanpassing om akk weer te geven zoals het op toetsen gespeeld wordt, anders zou het zijn listo[listend[0]][0] + d
        self._outlet(2,self.omgekeerdmodus[int(listo[listend[0]][1]*2)] + d)
        self._outlet(3,self.omgekeerdmodus[int(listo[listend[0]][2]*2)] + d) #minimum aantal noten per akk van akk in akkC 3, anders klopt dit niet
        if len(richord) >= 4:
            self._outlet(4,self.omgekeerdmodus[int(listo[listend[0]][3]*2)] + d)
            self._outlet(5,1)
        else:
            self._outlet(5,0) #0 uitsturen als het akk maar 3 noten telt
        self.previous = self.opvolg[self.previous][listend[0]]#listend[0] verwijst naar index v listo moet naar self.opvolg verwijzen
        #vanaf hier verdeling/ligging van gekozen akk binnen bepaald bereik
        if self.prange > 24: # aantal noten in akk van te zoeken ligging van akkoord, kan ev. ook vast getal zijn, vb aantalnoteninakk = 3
            aantalnoteninakk = 6
        else:
            aantalnoteninakk = int(round(self.prange/4)) #!!VERBETER: want als akk bv do mi fa# la# is en range 1 octaaf(12) is aantalnoteninakk maar 3
        listallemog=[]
        listtel=range(3,9) #alle octaven van QT
        #eerst basnoot zoeken
        for x in richord:
                for y in listtel:
                        if y*12+x >= self.pmin and y*12+x <= self.pmin + self.prange:
                                listallemog.append(y*12+x)			
        endlist=[]
        endlist.append(random.choice([x for x in listallemog if x >= self.pmin and x <= self.pmin+(self.prange/aantalnoteninakk)]))
        #dan volgende akk noten
        countlist = range(1,aantalnoteninakk)
        for x in countlist:
                b = endlist[x-1] + (self.prange / aantalnoteninakk)#oorspronkelijk nog + (prange/6)
                copy2allemog = []
                copy2allemog = listallemog[:]
                del copy2allemog[copy2allemog.index(endlist[x-1])]
                copyallemog = []
                copyallemog = copy2allemog [:]
                for i,v in enumerate(copyallemog):
                        copyallemog[i]=abs(b-v)
                listminindex=[]
                for i,v in enumerate(copy2allemog):
                        if v ==  b + min(copyallemog) or v == b - min(copyallemog):
                               listminindex.append(i)
                random.shuffle(listminindex)#bij twee dezelfde minima neemt hij n automatisch de eerste waarde
                endlist.append(copy2allemog[listminindex[0]])
        endlist2=[]
        if self.slideronoff == 1:
            endlist2 = endlist[:(int(round(len(endlist) * (self.slider1/127))))]
        else:
            endlist.reverse()
            endlist2 = endlist[:(int(round(len(endlist) * ((127 -self.slider2)/127))))]
        
        # if slider1 /20 == 3, newendlist = endlist[:3]
        # variabele in geheugen met 1 of 2 die zegt of slider1 als 2 het recentst is
        # dus if tempslider == 2:
        #                        newendlist = endlist[:(127 - tempslide2 / 20)] 
        if len(endlist2) == 0: # dit is zo als slider1 bvb 0 is, dan is endlist2=[]
            self._outlet(7,0) #eerst alle vorige noten noteoff sturen (voor geval na akk met vb 6 noten, akk met maar 1 noot komt)
            self._outlet(9,0)
            self._outlet(11,0)
            self._outlet(13,0)
            self._outlet(15,0)
            self._outlet(17,0)
            self._outlet(6,self.prevout6)
            self._outlet(8,self.prevout8)
            self._outlet(10,self.prevout10)
            self._outlet(12,self.prevout12)
            self._outlet(14,self.prevout14)
            self._outlet(16,self.prevout16) #eerst vorige pitch met noteoff sturen
        if len(endlist2) == 1:
            self._outlet(7,0) #eerst alle vorige noten noteoff sturen (voor geval na akk met vb 6 noten, akk met maar 1 noot komt)
            self._outlet(9,0)
            self._outlet(11,0)
            self._outlet(13,0)
            self._outlet(15,0)
            self._outlet(17,0)
            self._outlet(6,self.prevout6)
            self._outlet(8,self.prevout8)
            self._outlet(10,self.prevout10)
            self._outlet(12,self.prevout12)
            self._outlet(14,self.prevout14)
            self._outlet(16,self.prevout16) #eerst vorige pitch met noteoff sturen
            self._outlet(7,50)#nieuwe gate, noteon 50 ipv 1, voor gemak QT
            self._outlet(6,endlist2[0]) #nieuwe pitch
            self.prevout6 = endlist2[0]
            self.prevout7 = 1 #noteon 50 ipv 1, voor gemak QT
            self.prevout9 = 0
            self.prevout11 = 0
            self.prevout13 = 0
            self.prevout15 = 0
            self.prevout17 = 0
        if len(endlist2) == 2:
            self._outlet(7,0)
            self._outlet(9,0)
            self._outlet(11,0)
            self._outlet(13,0)
            self._outlet(15,0)
            self._outlet(17,0)
            self._outlet(6,self.prevout6)
            self._outlet(8,self.prevout8)
            self._outlet(10,self.prevout10)
            self._outlet(12,self.prevout12)
            self._outlet(14,self.prevout14)
            self._outlet(16,self.prevout16)
            self._outlet(7,50)
            self._outlet(9,50)
            self._outlet(6,endlist2[0])
            self._outlet(8,endlist2[1])
            self.prevout6 = endlist2[0]
            self.prevout7 = 1
            self.prevout8 = endlist2[1]
            self.prevout9 = 1
            self.prevout11 = 0
            self.prevout13 = 0
            self.prevout15 = 0
            self.prevout17 = 0
        if len(endlist2) == 3:
            self._outlet(7,0)
            self._outlet(9,0)
            self._outlet(11,0)
            self._outlet(13,0)
            self._outlet(15,0)
            self._outlet(17,0)
            self._outlet(6,self.prevout6)
            self._outlet(8,self.prevout8)
            self._outlet(10,self.prevout10)
            self._outlet(12,self.prevout12)
            self._outlet(14,self.prevout14)
            self._outlet(16,self.prevout16)
            self._outlet(7,50)
            self._outlet(9,50)
            self._outlet(11,50)
            self._outlet(6,endlist2[0])
            self._outlet(8,endlist2[1])
            self._outlet(10,endlist2[2])
            self.prevout6 = endlist2[0]
            self.prevout7 = 1
            self.prevout8 = endlist2[1]
            self.prevout9 = 1
            self.prevout10 = endlist2[2]
            self.prevout11 = 1
            self.prevout13 = 0
            self.prevout15 = 0
            self.prevout17 = 0
        if len(endlist2) == 4:
            self._outlet(7,0)
            self._outlet(9,0)
            self._outlet(11,0)
            self._outlet(13,0)
            self._outlet(15,0)
            self._outlet(17,0)
            self._outlet(6,self.prevout6)
            self._outlet(8,self.prevout8)
            self._outlet(10,self.prevout10)
            self._outlet(12,self.prevout12)
            self._outlet(14,self.prevout14)
            self._outlet(16,self.prevout16)
            self._outlet(7,50)
            self._outlet(9,50)
            self._outlet(11,50)
            self._outlet(13,50)
            self._outlet(6,endlist2[0])
            self._outlet(8,endlist2[1])
            self._outlet(10,endlist2[2])
            self._outlet(12,endlist2[3])
            self.prevout6 = endlist2[0]
            self.prevout7 = 1
            self.prevout8 = endlist2[1]
            self.prevout9 = 1
            self.prevout10 = endlist2[2]
            self.prevout11 = 1
            self.prevout12 = endlist2[3]
            self.prevout13 = 1
            self.prevout15 = 0
            self.prevout17 = 0
        if len(endlist2) == 5:
            self._outlet(7,0)
            self._outlet(9,0)
            self._outlet(11,0)
            self._outlet(13,0)
            self._outlet(15,0)
            self._outlet(17,0)
            self._outlet(6,self.prevout6)
            self._outlet(8,self.prevout8)
            self._outlet(10,self.prevout10)
            self._outlet(12,self.prevout12)
            self._outlet(14,self.prevout14)
            self._outlet(16,self.prevout16)
            self._outlet(7,50)
            self._outlet(9,50)
            self._outlet(11,50)
            self._outlet(13,50)
            self._outlet(15,50)
            self._outlet(6,endlist2[0])
            self._outlet(8,endlist2[1])
            self._outlet(10,endlist2[2])
            self._outlet(12,endlist2[3])
            self._outlet(14,endlist2[4])
            self.prevout6 = endlist2[0]
            self.prevout7 = 1
            self.prevout8 = endlist2[1]
            self.prevout9 = 1
            self.prevout10 = endlist2[2]
            self.prevout11 = 1
            self.prevout12 = endlist2[3]
            self.prevout13 = 1
            self.prevout14 = endlist2[4]
            self.prevout15 = 1
            self.prevout17 = 0
        if len(endlist2) == 6:
            self._outlet(7,0)
            self._outlet(9,0)
            self._outlet(11,0)
            self._outlet(13,0)
            self._outlet(15,0)
            self._outlet(17,0)
            self._outlet(6,self.prevout6)
            self._outlet(8,self.prevout8)
            self._outlet(10,self.prevout10)
            self._outlet(12,self.prevout12)
            self._outlet(14,self.prevout14)
            self._outlet(16,self.prevout16)
            self._outlet(7,50)
            self._outlet(9,50)
            self._outlet(11,50)
            self._outlet(13,50)
            self._outlet(15,50)
            self._outlet(17,50)
            self._outlet(6,endlist2[0])
            self._outlet(8,endlist2[1])
            self._outlet(10,endlist2[2])
            self._outlet(12,endlist2[3])
            self._outlet(14,endlist2[4])
            self._outlet(16,endlist2[5])
            self.prevout6 = endlist2[0]
            self.prevout7 = 1
            self.prevout8 = endlist2[1]
            self.prevout9 = 1
            self.prevout10 = endlist2[2]
            self.prevout11 = 1
            self.prevout12 = endlist2[3]
            self.prevout13 = 1
            self.prevout14 = endlist2[4]
            self.prevout15 = 1
            self.prevout16 = endlist2[5]
            self.prevout17 = 1

    def int_2(self,a):
        self.pmin = a

    def int_3(self,a):
        self.prange = a
        
    def int_4(self,a):
        self.slider1 = a
        self.slideronoff = 1

    def int_5(self,a):
        self.slider2 = a
        self.slideronoff = 2
      
            
