Exemplo n.º 1
0
def psSetTransposer(chord, trans):
    """transposes an entire set by trans, no mod12
    retains oct info, micro info 

    >>> pcSetTransposer([3,4,5], 14)
    (5, 6, 7)
    """
    newSet = []
    for pc in chord:  ## works for negative or positive numbers
        newSet.append(pitchTools.psTransposer(pc, trans))
    return tuple(newSet)
Exemplo n.º 2
0
def psSetTransposer(chord, trans):
    """transposes an entire set by trans, no mod12
    retains oct info, micro info 

    >>> pcSetTransposer([3,4,5], 14)
    (5, 6, 7)
    """
    newSet = []
    for pc in chord:    ## works for negative or positive numbers
        newSet.append(pitchTools.psTransposer(pc, trans))
    return tuple(newSet)
Exemplo n.º 3
0
    def _scoreMain(self):
        """creates score

        >>> from athenaCL.libATH.libTM import texture
        >>> ti = texture.factory('lg')
        >>> ti.tmName == 'LineGroove'
        True
        >>> ti.loadDefault()
        >>> ti.score() == True
        True
        """
        # texture-wide time elements
        inst = self.getInst()
        tStart, tEnd = self.getTimeRange()
        tCurrent = tStart

        # texture-wide (self.textQ amd)options
        # used for optional parallel voices
        textParallelVoiceList = self.getTextStatic("pml", "transpositionList")
        textParallelDelayTime = self.getTextStatic("pml", "timeDelay")
        # get field, octave selection method value
        textFieldLevel = self.getTextStatic("lfm", "level")
        textOctaveLevel = self.getTextStatic("lom", "level")
        textPitchSelectorControl = self.getTextStatic("psc", "selectionString")

        # create a list of chords from the appropriate pitch mode
        for pathPos in self.getPathPos():
            chordCurrent = self.getPitchGroup(pathPos)
            multisetCurrent = self.getMultiset(pathPos)

            tStartSet, tEndSet = self.clockPoints()
            selectorChordPos = basePmtr.Selector(range(len(chordCurrent)), textPitchSelectorControl)
            tStartSetReal = copy.deepcopy(tCurrent)
            self.stateUpdate(tCurrent, chordCurrent, None, multisetCurrent, None, None)

            if textFieldLevel == "set":
                transCurrent = self.getField(tCurrent)  # choose PITCHFIELD
            if textOctaveLevel == "set":
                octCurrent = self.getOct(tCurrent)  # choose OCTAVE

            while 1:  # pitch in chord
                if tCurrent >= tEndSet:
                    break
                # choose pc from chord
                ps = chordCurrent[selectorChordPos()]  # get position w/n chord
                self.stateUpdate(tCurrent, chordCurrent, ps, multisetCurrent, None, None)

                if textFieldLevel == "event":
                    transCurrent = self.getField(tCurrent)  # choose PITCHFIELD
                if textOctaveLevel == "event":
                    octCurrent = self.getOct(tCurrent)  # choose OCTAVE
                psReal = pitchTools.psToTempered(ps, octCurrent, self.temperamentObj, transCurrent)
                self.stateUpdate(tCurrent, chordCurrent, ps, multisetCurrent, None, psReal)

                bpm, pulse, dur, sus, acc = self.getRhythm(tCurrent)
                if acc == 0 and not self.silenceMode:  # this is a rest
                    tCurrent = tCurrent + dur
                    continue

                amp = self.getAmp(tCurrent) * acc  # choose amp, pan
                pan = self.getPan(tCurrent)
                auxiliary = self.getAux(tCurrent)  # chooose AUX, pack into list
                eventDict = self.makeEvent(tCurrent, bpm, pulse, dur, sus, acc, amp, psReal, pan, auxiliary)
                self.storeEvent(eventDict)
                # Parallel transposition
                offset = 0
                for parallelVoice in textParallelVoiceList:
                    # offset to avoid amp problems, correct error w/ offset
                    tCurrent = tCurrent + textParallelDelayTime
                    offset = offset + textParallelDelayTime
                    psText = pitchTools.psTransposer(psReal, parallelVoice)
                    eventDict = self.makeEvent(tCurrent, bpm, pulse, dur, sus, acc, amp, psText, pan, auxiliary)
                    self.storeEvent(eventDict)
                # move clocks forward by dur unit
                tCurrent = (tCurrent + dur) - offset

            self.clockForward()  # advances path positon
        return 1
Exemplo n.º 4
0
    def _scoreMain(self):
        """creates score

        >>> from athenaCL.libATH.libTM import texture
        >>> ti = texture.factory('lg')
        >>> ti.tmName == 'LineGroove'
        True
        >>> ti.loadDefault()
        >>> ti.score() == True
        True
        """
        # texture-wide time elements
        inst = self.getInst()
        tStart, tEnd = self.getTimeRange()
        tCurrent = tStart

        #texture-wide (self.textQ amd)options 
        #used for optional parallel voices
        textParallelVoiceList = self.getTextStatic('pml', 'transpositionList') 
        textParallelDelayTime = self.getTextStatic('pml', 'timeDelay')       
        # get field, octave selection method value
        textFieldLevel = self.getTextStatic('lfm', 'level') 
        textOctaveLevel = self.getTextStatic('lom', 'level')        
        textPitchSelectorControl = self.getTextStatic('psc', 'selectionString') 

        # create a list of chords from the appropriate pitch mode
        for pathPos in self.getPathPos():
            chordCurrent = self.getPitchGroup(pathPos)
            multisetCurrent = self.getMultiset(pathPos)

            tStartSet, tEndSet = self.clockPoints()
            selectorChordPos = basePmtr.Selector(list(range(len(chordCurrent))),
                                                             textPitchSelectorControl)
            tStartSetReal = copy.deepcopy(tCurrent)
            self.stateUpdate(tCurrent, chordCurrent, None, 
                                  multisetCurrent, None, None)

            if textFieldLevel == 'set':
                transCurrent = self.getField(tCurrent) # choose PITCHFIELD
            if textOctaveLevel == 'set':
                octCurrent = self.getOct(tCurrent) # choose OCTAVE

            while 1: # pitch in chord 
                if tCurrent >= tEndSet: break
                # choose pc from chord
                ps = chordCurrent[selectorChordPos()] # get position w/n chord
                self.stateUpdate(tCurrent, chordCurrent, ps, 
                                      multisetCurrent, None, None)
                                      
                if textFieldLevel == 'event':
                    transCurrent = self.getField(tCurrent) # choose PITCHFIELD
                if textOctaveLevel == 'event':
                    octCurrent = self.getOct(tCurrent) # choose OCTAVE
                psReal = pitchTools.psToTempered(ps, octCurrent, 
                                      self.temperamentObj, transCurrent)                                      
                self.stateUpdate(tCurrent, chordCurrent, ps, 
                                      multisetCurrent, None, psReal)

                bpm, pulse, dur, sus, acc = self.getRhythm(tCurrent) 
                if acc == 0 and not self.silenceMode: # this is a rest
                    tCurrent = tCurrent + dur
                    continue

                amp = self.getAmp(tCurrent) * acc # choose amp, pan
                pan = self.getPan(tCurrent)
                auxiliary = self.getAux(tCurrent) # chooose AUX, pack into list
                eventDict = self.makeEvent(tCurrent, bpm, pulse, dur, sus, acc, 
                                                             amp, psReal, pan, auxiliary)
                self.storeEvent(eventDict)
                # Parallel transposition 
                offset = 0
                for parallelVoice in textParallelVoiceList:
                      #offset to avoid amp problems, correct error w/ offset
                    tCurrent = tCurrent + textParallelDelayTime          
                    offset = offset + textParallelDelayTime
                    psText = pitchTools.psTransposer(psReal, parallelVoice)
                    eventDict = self.makeEvent(tCurrent, bpm, pulse, dur, sus, 
                                                             acc, amp, psText, pan, auxiliary)
                    self.storeEvent(eventDict)
                # move clocks forward by dur unit
                tCurrent = (tCurrent + dur) - offset          

            self.clockForward() # advances path positon
        return 1
Exemplo n.º 5
0
    def psScale(self, pitchFormat, contourForm, psBase, microTone=.5):
        """translates a scale form in notation [0,-1,0,1] into various pitch
        representations. integers in the scale form are interpreted in three
        ways: as chromatic 1/2 steps, as diatonic scale pitches (either from
        the local
        set or the entire path), or as units of some microtonal size
        this returns a list representing the scale steps in relation to             
        psBase
        
        psBase needs to be found in terms of the path, 
        which may not consist only of ints
        
        returns a psCountourReference, which is alway tempered pitch values
        """
        # not sure this needs to be an int
        #assert drawer.isInt(psBase)

        octCurrent = self.pmtrObjDict['octQ'].currentValue
        transCurrent = self.pmtrObjDict['fieldQ'].currentValue
        #currentChord = self.stateCurrentChord

        # not needed for all forms, but myst always get
        if pitchFormat == 'set':
            pitchGroup = self.refDict['stateCurrentChord']
        elif pitchFormat == 'path':
            pitchGroup = self.refDict['statePathList']
        else:  # non given, but note used
            pitchGroup = self.refDict['stateCurrentChord']

        refScales, lowerUpper = extractNeighbors(pitchGroup, psBase)
        pcContourDict = mapNeighbors(refScales, psBase, contourForm)
        #print pcContourDict
        # get pitch scale
        # this has the mapping with the appropriate pitches
        # N.B: danger here of getting mistransposed values
        # previously was an error and corrected in _splitPch
        psContourRef = []
        if pitchFormat == 'chromatic':
            for entry in contourForm:
                # transpose before getting temperament
                pcSpace = pitchTools.psTransposer(psBase, entry)
                psReal = pitchTools.psToTempered(pcSpace, octCurrent,
                                                 self.temperamentObj,
                                                 transCurrent)

                psContourRef.append(psReal)  # transpose by half steps
        #   sets: derive scale from set
        elif pitchFormat == 'set' or pitchFormat == 'path':
            for entry in contourForm:
                pcSpace = pcContourDict[
                    entry]  # scale step is a key, gets pcSpace
                psReal = pitchTools.psToTempered(pcSpace, octCurrent,
                                                 self.temperamentObj,
                                                 transCurrent)

                psContourRef.append(psReal)  # transpose by half steps
        elif pitchFormat == 'microtone':  # microtonal
            for entry in contourForm:  # treat scale step as microtone scaler
                # must do transposition after converting to PCH
                if entry * microTone > entry * 2:
                    environment.printWarn([
                        lang.WARN,
                        'microtone large (%s)' % (entry * microTone)
                    ])
                trans = (transCurrent + (entry * microTone))
                psReal = pitchTools.psToTempered(psBase, octCurrent,
                                                 self.temperamentObj, trans)

                psContourRef.append(psReal)  # transpose by half steps
        else:
            raise ValueError('no such pitchFormat')
        # this now returns psReals, not pch values
        return psContourRef, refScales
Exemplo n.º 6
0
def extractNeighbors(pitchGroup, baseNote, scales=None):
    """takes a set, or a whole path, and derives a pc scale, 
    a pitch space scale, and provides the upper and lower note to 
    baseNote
    
    baseNote should be represented in the pitch group
    we need to know our current reference position in the pitchGroup
    pitchGroup has pitch pre-temperament; thus baseNote should be
    pre-temperament
    may be a psReal
    
    pitchGroup: from a refDict, containing stateCurrentChord, or statePathList
    will be a list of raw psReal values: could be floats, and could have micro
    specification
    """
    # if scales given and no pitchGroup is given
    if scales != None and pitchGroup == None:
        colPitchSpace = scales[0]
        colPitchClass = scales[1]
    else:  # given a set or path as pitchGroup
        if drawer.isNum(pitchGroup[0]):
            pitchGroup = [
                pitchGroup,
            ]  # make all look like paths
        colPitchSpace = []
        colPitchClass = []
        for set in pitchGroup:
            for entry in set:
                if entry not in colPitchSpace:
                    colPitchSpace.append(entry)
                # round; zero trans gets mod12
                entryPC = pitchTools.pcTransposer(entry, 0)
                if entryPC not in colPitchClass:
                    colPitchClass.append(entryPC)
        colPitchSpace.sort()
        colPitchClass.sort()
        scales = colPitchSpace, colPitchClass

    # use pitch class space to get neighbors
    # can use pitch space in the future? wrap around is strange
    octaveAdjust = 0
    baseOctMult, basePC = pitchTools.splitOctPs(baseNote)

    # although baseNote may be a float (already tempered)
    # basePC seems to    need to be an int, as it is used to find
    # a position in the scale; for this reason it seems like
    # the path positions value, and not the tempered pitch
    # should be coming in as the baseNote: tmerperament could cause
    # a rounding error and pass a pitch that is not in the scale at all

    #print _MOD, basePC, colPitchClass
    idx = None
    try:
        idx = colPitchClass.index(basePC)
    except ValueError:  # not in the collected pitches; try rounding
        for i in range(len(colPitchClass)):
            # compare rounded versions, as floats may not match
            if round(colPitchClass[i], 2) == round(basePC, 2):
                idx = i
                # print _MOD, 'found rounded match'
        if idx == None:
            idx = 0
            environment.printDebug(
                'no match between base pitch and collected pitches')

    idxL = idx - 1  # lower neighbor
    if idxL == -1:  # wrap index around
        idxL = len(colPitchClass) - 1
        octaveAdjust = -1
    idxU = idx + 1  # upper neighbor
    if idxU == len(colPitchClass):
        idxU = 0
        octaveAdjust = 1

    neighborL = colPitchClass[idxL]
    if octaveAdjust == -1:
        neighborL = pitchTools.psTransposer(neighborL, -12)

    neighborU = colPitchClass[idxU]
    if octaveAdjust == 1:
        neighborU = pitchTools.psTransposer(neighborU, 12)

    # do octave adjust ment relative to baseNote in pitch space
    neighborL = pitchTools.psTransposer(neighborL, (12 * baseOctMult))
    neighborU = pitchTools.psTransposer(neighborU, (12 * baseOctMult))
    lowerUpper = neighborL, neighborU

    return scales, lowerUpper
Exemplo n.º 7
0
    def _scoreMain(self):
        """creates score

        >>> from athenaCL.libATH.libTM import texture
        >>> ti = texture.factory('LineCluster')
        >>> ti.tmName == 'LineCluster'
        True
        >>> ti.loadDefault()
        >>> ti.score() == True
        True

        """
        # texture-wide PATH/PITCH elements
        # texture-wide time elements
        inst = self.getInst()
        tStart, tEnd = self.getTimeRange()
        tCurrent = tStart

        # texture-wide TEXTURE (self.textQ amd)options
        #used for optional parallel voices
        textParallelVoiceList = self.getTextStatic('pml', 'transpositionList') 
        textParallelDelayTime = self.getTextStatic('pml', 'timeDelay')       
        # get field, octave selection method value
        textFieldLevel = self.getTextStatic('lfp', 'level') 
        textOctaveLevel = self.getTextStatic('lop', 'level')        
        textPitchSelectorControl = self.getTextStatic('psc', 'selectionString') 
        #textNonRedundantSwitch = self.getTextStatic('nrs', 'onOff') 

        # create a list of chords from the appropriate pitch mode
        for pathPos in self.getPathPos():
            chordCurrent = self.getPitchGroup(pathPos)
            multisetCurrent = self.getMultiset(pathPos)

            tStartSet, tEndSet = self.clockPoints() 
#             if textNonRedundantSwitch == 'on': selectorControl = 'randomPermutate'
#             else: selectorControl = 'randomChoice'
            selectorChordPos = basePmtr.Selector(range(len(chordCurrent)),
                                                             textPitchSelectorControl)
            tStartSetReal = copy.deepcopy(tCurrent)
            self.stateUpdate(tCurrent, chordCurrent, None, 
                                  multisetCurrent, None, None)

            if textFieldLevel == 'set':
                transCurrent = self.getField(tCurrent) # choose PITCHFIELD
            if textOctaveLevel == 'set':
                octCurrent = self.getOct(tCurrent) # choose OCTAVE

            while 1: # PITCH in CHORD 
                if tCurrent >= tEndSet: break

                bpm, pulse, dur, sus, acc = self.getRhythm(tCurrent) # choose RHYTHM
                if acc == 0 and not self.silenceMode: # this is a rest
                    tCurrent = tCurrent + dur
                    continue

                # this ps should be used as ROOT;
                # this is _not_ implemented yet, however 
                # choose PC from CHORD 
                ps = chordCurrent[selectorChordPos()]   
                self.stateUpdate(tCurrent, chordCurrent, ps, 
                                      multisetCurrent, None, None)
                    
                if textFieldLevel == 'event':
                    transCurrent = self.getField(tCurrent) # choose PITCHFIELD
                if textOctaveLevel == 'event':
                    octCurrent = self.getOct(tCurrent) # choose OCTAVE
                    
                #subprocess psChord is a list of PCH's needed to make chord, 
                psChord = []
                for pitchSpace in chordCurrent:
                    if textFieldLevel == 'voice':
                        transCurrent = self.getField(tCurrent) # choose PITCHFIELD
                    if textOctaveLevel == 'voice':
                        octCurrent = self.getOct(tCurrent) # choose OCTAVE
                    psReal = pitchTools.psToTempered(pitchSpace, octCurrent, 
                                          self.temperamentObj, transCurrent)
                    psChord.append(psReal)
                    
                # amp and pan done for each chord, not voice
                amp = self.getAmp(tCurrent) * acc
                pan = self.getPan(tCurrent)

                #do this for each PCH in psChord, already transposed
                for psReal in psChord:
                    self.stateUpdate(tCurrent, chordCurrent, pitchSpace,
                                          multisetCurrent, None, psReal)
                    # choose aux for each voice
                    auxiliary = self.getAux(tCurrent)  
                    eventDict = self.makeEvent(tCurrent, bpm, pulse, dur, sus, 
                                                        acc, amp, psReal, pan, auxiliary)
                    self.storeEvent(eventDict)
                    # parellel transposition 
                    offset = 0
                    for parallelVoice in textParallelVoiceList:
                        #offset to avoid amp problems, correct error w/ offset
                        tCurrent = tCurrent + textParallelDelayTime          
                        offset = offset + textParallelDelayTime
                        psText = pitchTools.psTransposer(psReal, parallelVoice)
                        eventDict = self.makeEvent(tCurrent, bpm, pulse, dur, 
                                                     sus, acc, amp, psText, pan, auxiliary)
                        self.storeEvent(eventDict)

                #----------------------------
                # move clocks forward by dur unit
                tCurrent = (tCurrent + dur) - offset         

            self.clockForward() # advances path positon 
        # return value to check for errors   
        return 1
Exemplo n.º 8
0
    def _scoreMain(self):
        """creates score

        >>> from athenaCL.libATH.libTM import texture
        >>> ti = texture.factory('LineCluster')
        >>> ti.tmName == 'LineCluster'
        True
        >>> ti.loadDefault()
        >>> ti.score() == True
        True

        """
        # texture-wide PATH/PITCH elements
        # texture-wide time elements
        inst = self.getInst()
        tStart, tEnd = self.getTimeRange()
        tCurrent = tStart

        # texture-wide TEXTURE (self.textQ amd)options
        #used for optional parallel voices
        textParallelVoiceList = self.getTextStatic('pml', 'transpositionList')
        textParallelDelayTime = self.getTextStatic('pml', 'timeDelay')
        # get field, octave selection method value
        textFieldLevel = self.getTextStatic('lfp', 'level')
        textOctaveLevel = self.getTextStatic('lop', 'level')
        textPitchSelectorControl = self.getTextStatic('psc', 'selectionString')
        #textNonRedundantSwitch = self.getTextStatic('nrs', 'onOff')

        # create a list of chords from the appropriate pitch mode
        for pathPos in self.getPathPos():
            chordCurrent = self.getPitchGroup(pathPos)
            multisetCurrent = self.getMultiset(pathPos)

            tStartSet, tEndSet = self.clockPoints()
            #             if textNonRedundantSwitch == 'on': selectorControl = 'randomPermutate'
            #             else: selectorControl = 'randomChoice'
            selectorChordPos = basePmtr.Selector(
                list(range(len(chordCurrent))), textPitchSelectorControl)
            tStartSetReal = copy.deepcopy(tCurrent)
            self.stateUpdate(tCurrent, chordCurrent, None, multisetCurrent,
                             None, None)

            if textFieldLevel == 'set':
                transCurrent = self.getField(tCurrent)  # choose PITCHFIELD
            if textOctaveLevel == 'set':
                octCurrent = self.getOct(tCurrent)  # choose OCTAVE

            while 1:  # PITCH in CHORD
                if tCurrent >= tEndSet: break

                bpm, pulse, dur, sus, acc = self.getRhythm(
                    tCurrent)  # choose RHYTHM
                if acc == 0 and not self.silenceMode:  # this is a rest
                    tCurrent = tCurrent + dur
                    continue

                # this ps should be used as ROOT;
                # this is _not_ implemented yet, however
                # choose PC from CHORD
                ps = chordCurrent[selectorChordPos()]
                self.stateUpdate(tCurrent, chordCurrent, ps, multisetCurrent,
                                 None, None)

                if textFieldLevel == 'event':
                    transCurrent = self.getField(tCurrent)  # choose PITCHFIELD
                if textOctaveLevel == 'event':
                    octCurrent = self.getOct(tCurrent)  # choose OCTAVE

                #subprocess psChord is a list of PCH's needed to make chord,
                psChord = []
                for pitchSpace in chordCurrent:
                    if textFieldLevel == 'voice':
                        transCurrent = self.getField(
                            tCurrent)  # choose PITCHFIELD
                    if textOctaveLevel == 'voice':
                        octCurrent = self.getOct(tCurrent)  # choose OCTAVE
                    psReal = pitchTools.psToTempered(pitchSpace, octCurrent,
                                                     self.temperamentObj,
                                                     transCurrent)
                    psChord.append(psReal)

                # amp and pan done for each chord, not voice
                amp = self.getAmp(tCurrent) * acc
                pan = self.getPan(tCurrent)

                #do this for each PCH in psChord, already transposed
                for psReal in psChord:
                    self.stateUpdate(tCurrent, chordCurrent, pitchSpace,
                                     multisetCurrent, None, psReal)
                    # choose aux for each voice
                    auxiliary = self.getAux(tCurrent)
                    eventDict = self.makeEvent(tCurrent, bpm, pulse, dur, sus,
                                               acc, amp, psReal, pan,
                                               auxiliary)
                    self.storeEvent(eventDict)
                    # parellel transposition
                    offset = 0
                    for parallelVoice in textParallelVoiceList:
                        #offset to avoid amp problems, correct error w/ offset
                        tCurrent = tCurrent + textParallelDelayTime
                        offset = offset + textParallelDelayTime
                        psText = pitchTools.psTransposer(psReal, parallelVoice)
                        eventDict = self.makeEvent(tCurrent, bpm, pulse, dur,
                                                   sus, acc, amp, psText, pan,
                                                   auxiliary)
                        self.storeEvent(eventDict)

                #----------------------------
                # move clocks forward by dur unit
                tCurrent = (tCurrent + dur) - offset

            self.clockForward()  # advances path positon
        # return value to check for errors
        return 1
Exemplo n.º 9
0
    def psScale(self, pitchFormat, contourForm, psBase, microTone=.5):
        """translates a scale form in notation [0,-1,0,1] into various pitch
        representations. integers in the scale form are interpreted in three
        ways: as chromatic 1/2 steps, as diatonic scale pitches (either from
        the local
        set or the entire path), or as units of some microtonal size
        this returns a list representing the scale steps in relation to             
        psBase
        
        psBase needs to be found in terms of the path, 
        which may not consist only of ints
        
        returns a psCountourReference, which is alway tempered pitch values
        """
        # not sure this needs to be an int
        #assert drawer.isInt(psBase)
        
        octCurrent   = self.pmtrObjDict['octQ'].currentValue
        transCurrent = self.pmtrObjDict['fieldQ'].currentValue
        #currentChord = self.stateCurrentChord

        # not needed for all forms, but myst always get
        if pitchFormat == 'set':
            pitchGroup = self.refDict['stateCurrentChord']
        elif pitchFormat == 'path':
            pitchGroup = self.refDict['statePathList']
        else: # non given, but note used
            pitchGroup = self.refDict['stateCurrentChord']


        refScales, lowerUpper = extractNeighbors(pitchGroup, psBase)
        pcContourDict = mapNeighbors(refScales, psBase, contourForm)
        #print pcContourDict
        # get pitch scale
        # this has the mapping with the appropriate pitches
        # N.B: danger here of getting mistransposed values
        # previously was an error and corrected in _splitPch
        psContourRef = [] 
        if pitchFormat == 'chromatic':
            for entry in contourForm:
                # transpose before getting temperament
                pcSpace = pitchTools.psTransposer(psBase, entry) 
                psReal = pitchTools.psToTempered(pcSpace, octCurrent, 
                                      self.temperamentObj, transCurrent)

                psContourRef.append(psReal) # transpose by half steps
        #   sets: derive scale from set
        elif pitchFormat == 'set' or pitchFormat == 'path': 
            for entry in contourForm:
                pcSpace = pcContourDict[entry] # scale step is a key, gets pcSpace
                psReal = pitchTools.psToTempered(pcSpace, octCurrent, 
                                      self.temperamentObj, transCurrent)

                psContourRef.append(psReal) # transpose by half steps
        elif pitchFormat == 'microtone': # microtonal
            for entry in contourForm: # treat scale step as microtone scaler
                # must do transposition after converting to PCH
                if entry * microTone > entry * 2:
                    environment.printWarn([lang.WARN, 'microtone large (%s)' % (entry * microTone)])
                trans = (transCurrent + (entry * microTone))
                psReal = pitchTools.psToTempered(psBase, octCurrent, 
                                      self.temperamentObj, trans)

                psContourRef.append(psReal) # transpose by half steps
        else:
            raise ValueError, 'no such pitchFormat'
        # this now returns psReals, not pch values
        return psContourRef, refScales
Exemplo n.º 10
0
def extractNeighbors(pitchGroup, baseNote, scales=None):
    """takes a set, or a whole path, and derives a pc scale, 
    a pitch space scale, and provides the upper and lower note to 
    baseNote
    
    baseNote should be represented in the pitch group
    we need to know our current reference position in the pitchGroup
    pitchGroup has pitch pre-temperament; thus baseNote should be
    pre-temperament
    may be a psReal
    
    pitchGroup: from a refDict, containing stateCurrentChord, or statePathList
    will be a list of raw psReal values: could be floats, and could have micro
    specification
    """
    # if scales given and no pitchGroup is given
    if scales != None and pitchGroup == None:
        colPitchSpace = scales[0]
        colPitchClass = scales[1]
    else: # given a set or path as pitchGroup
        if drawer.isNum(pitchGroup[0]):
            pitchGroup = [pitchGroup, ] # make all look like paths
        colPitchSpace = []
        colPitchClass = []
        for set in pitchGroup:
            for entry in set:
                if entry not in colPitchSpace:
                    colPitchSpace.append(entry)
                # round; zero trans gets mod12
                entryPC = pitchTools.pcTransposer(entry, 0) 
                if entryPC not in colPitchClass:
                    colPitchClass.append(entryPC)
        colPitchSpace.sort()
        colPitchClass.sort()
        scales = colPitchSpace, colPitchClass

    # use pitch class space to get neighbors
    # can use pitch space in the future? wrap around is strange
    octaveAdjust = 0
    baseOctMult, basePC = pitchTools.splitOctPs(baseNote)
    
    # although baseNote may be a float (already tempered)
    # basePC seems to    need to be an int, as it is used to find
    # a position in the scale; for this reason it seems like
    # the path positions value, and not the tempered pitch
    # should be coming in as the baseNote: tmerperament could cause
    # a rounding error and pass a pitch that is not in the scale at all
    
    #print _MOD, basePC, colPitchClass
    idx = None
    try:
        idx = colPitchClass.index(basePC)
    except ValueError: # not in the collected pitches; try rounding
        for i in range(len(colPitchClass)):
            # compare rounded versions, as floats may not match
            if round(colPitchClass[i], 2) == round(basePC, 2):
                idx = i
                # print _MOD, 'found rounded match'
        if idx == None:
            idx = 0
            environment.printDebug('no match between base pitch and collected pitches')
        
    idxL = idx - 1 # lower neighbor
    if idxL == -1: # wrap index around 
        idxL = len(colPitchClass) - 1
        octaveAdjust = -1
    idxU = idx + 1 # upper neighbor
    if idxU == len(colPitchClass):
        idxU = 0
        octaveAdjust = 1

    neighborL = colPitchClass[idxL]
    if octaveAdjust == -1:
        neighborL = pitchTools.psTransposer(neighborL, -12)

    neighborU = colPitchClass[idxU]
    if octaveAdjust == 1:
        neighborU = pitchTools.psTransposer(neighborU, 12)

    # do octave adjust ment relative to baseNote in pitch space
    neighborL = pitchTools.psTransposer(neighborL, (12 * baseOctMult))
    neighborU = pitchTools.psTransposer(neighborU, (12 * baseOctMult))
    lowerUpper = neighborL, neighborU
        
    return scales, lowerUpper