Beispiel #1
0
    def __init__(self, bassNote = 'C3', notationString = None, fbScale = None, fbRules = rules.Rules(), numParts = 4, maxPitch = 'B5', listOfPitches = None):
        ''' 
        A Segment corresponds to a 1:1 realization of a bassNote and notationString of a :class:`~music21.figuredBass.realizer.FiguredBassLine`.
        It is created by passing six arguments: a :class:`~music21.figuredBass.realizerScale.FiguredBassScale`, a bassNote, a notationString,
        a :class:`~music21.figuredBass.rules.Rules` object, a number of parts and a maximum pitch. Realizations of a Segment are represented 
        as possibility tuples (see :mod:`~music21.figuredBass.possibility` for more details). 
        
        Methods in Python's `itertools <http://docs.python.org/library/itertools.html>`_ module are used extensively. Methods 
        which generate possibilities or possibility progressions return iterators, which are turned into lists in the examples 
        for display purposes only.
        
        if fbScale is None, a realizerScale.FiguredBassScale() is created

        if fbRules is None, a rules.Rules() instance is created.  Each Segment gets its own deepcopy of the one given.
        
        
        Here, a Segment is created using the default values: a FiguredBassScale in C, a bassNote of C3, an empty notationString, and a default
        Rules object.
        
        >>> from music21.figuredBass import segment
        >>> s1 = segment.Segment()
        >>> s1.bassNote
        <music21.note.Note C>
        >>> s1.numParts
        4
        >>> s1.pitchNamesInChord
        ['C', 'E', 'G']
        >>> [str(p) for p in s1.allPitchesAboveBass]
        ['C3', 'E3', 'G3', 'C4', 'E4', 'G4', 'C5', 'E5', 'G5']
        >>> s1.segmentChord
        <music21.chord.Chord C3 E3 G3 C4 E4 G4 C5 E5 G5>
        '''
        if common.isStr(bassNote):
            bassNote = note.Note(bassNote)
        if common.isStr(maxPitch):
            maxPitch = pitch.Pitch(maxPitch)
        
        if fbScale is None:
            global _defaultRealizerScale
            if _defaultRealizerScale is None:
                _defaultRealizerScale = realizerScale.FiguredBassScale()
            fbScale = _defaultRealizerScale # save making it
        
        if fbRules is None:
            self.fbRules = rules.Rules()
        else:
            self.fbRules = copy.deepcopy(fbRules)
        
        self.bassNote = bassNote
        self.numParts = numParts
        self._maxPitch = maxPitch
        if notationString == None and listOfPitches != None: #must be a chord symbol or roman numeral....
            self.pitchNamesInChord = listOfPitches
        #!---------- Added to accommodate harmony.ChordSymbol and roman.RomanNumeral objects --------!
        else:
            self.pitchNamesInChord = fbScale.getPitchNames(self.bassNote.pitch, notationString)
        
        self.allPitchesAboveBass = getPitches(self.pitchNamesInChord, self.bassNote.pitch, self._maxPitch)
        self.segmentChord = chord.Chord(self.allPitchesAboveBass, quarterLength = bassNote.quarterLength)
        self._environRules = environment.Environment(_MOD)
    def printDebug(self, msg, statusLevel=common.DEBUG_USER, debugFormat=None):
        '''
        Format one or more data elements into string, and print it 
        to stderr. The first arg can be a list of strings or a string; 
        lists are concatenated with common.formatStr(). 
        '''
        #if not common.isNum(statusLevel):
        #    raise EnvironmentException('bad statusLevel argument given: %s' % statusLevel)
#         if self.__getitem__('debug') >= statusLevel:
#             if common.isStr(msg):
#                 msg = [msg] # make into a list
#             if msg[0] != self.modNameParent and self.modNameParent != None:
#                 msg = [self.modNameParent + ':'] + msg
#             # pass list to common.formatStr
#             msg = common.formatStr(*msg, format=debugFormat)
#             sys.stderr.write(msg)

        if _environStorage['instance'].__getitem__('debug') >= statusLevel:
            if common.isStr(msg):
                msg = [msg] # make into a list
            if msg[0] != self.modNameParent and self.modNameParent != None:
                msg = [self.modNameParent + ':'] + msg
            # pass list to common.formatStr
            msg = common.formatStr(*msg, format=debugFormat)
            sys.stderr.write(msg)
Beispiel #3
0
    def parseData(self, tnData, number=None):
        '''Open TinyNotation data from a string or list

        >>> tnData = ["E4 r f# g=lastG trip{b-8 a g} c", "3/4"]
        >>> c = converter.subConverters.ConverterTinyNotation()
        >>> s = c.parseData(tnData)
        >>> c.stream.show('text')
        {0.0} <music21.meter.TimeSignature 3/4>
        {0.0} <music21.note.Note E>
        {1.0} <music21.note.Rest rest>
        {2.0} <music21.note.Note F#>
        {3.0} <music21.note.Note G>
        {4.0} <music21.note.Note B->
        {4.3333} <music21.note.Note A>
        {4.6667} <music21.note.Note G>
        {5.0} <music21.note.Note C>        
        '''
        if common.isStr(tnData):
            tnStr = tnData
            tnTs = None
        else:  # assume a 2 element sequence
            tnStr = tnData[0]
            tnTs = tnData[1]
        from music21 import tinyNotation
        self.stream = tinyNotation.TinyNotationStream(tnStr, tnTs)
Beispiel #4
0
def romanTextToStreamOpus(rtHandler, inputM21=None):
    '''The main processing routine for RomanText objects that may or may not
    be multi movement.
    
    Takes in a romanText.base.RTFile() object, or a string as rtHandler.
    
    Runs `romanTextToStreamScore()` as its main work.
    
    If inputM21 is None then it will create a Score or Opus object.
    
    Return either a Score object, or, if a multi-movement work is defined, an
    Opus object.
    '''
    from music21 import romanText as romanTextModule

    from music21 import stream
    if common.isStr(rtHandler):
        rtf = romanTextModule.RTFile()
        rtHandler = rtf.readstr(rtHandler) # return handler, processes tokens

    if rtHandler.definesMovements(): # create an opus
        if inputM21 == None:
            s = stream.Opus()
        else:
            s = inputM21
        # copy the common header to each of the sub-handlers
        handlerBundles = rtHandler.splitByMovement(duplicateHeader=True)
        # see if we have header information
        for h in handlerBundles:
            #print h, len(h)
            # append to opus
            s.append(romanTextToStreamScore(h))
        return s # an opus
    else: # create a Score
        return romanTextToStreamScore(rtHandler, inputM21=inputM21)
Beispiel #5
0
    def parseData(self, tnData, number=None):
        '''Open TinyNotation data from a string

        >>> tnData = "3/4 E4 r f# g=lastG trip{b-8 a g} c"
        >>> c = converter.subConverters.ConverterTinyNotation()
        >>> s = c.parseData(tnData)
        >>> c.stream.show('text')
        {0.0} <music21.stream.Measure 1 offset=0.0>
            {0.0} <music21.clef.TrebleClef>
            {0.0} <music21.meter.TimeSignature 3/4>
            {0.0} <music21.note.Note E>
            {1.0} <music21.note.Rest rest>
            {2.0} <music21.note.Note F#>
        {3.0} <music21.stream.Measure 2 offset=3.0>
            {0.0} <music21.note.Note G>
            {1.0} <music21.note.Note B->
            {1.3333} <music21.note.Note A>
            {1.6667} <music21.note.Note G>
            {2.0} <music21.note.Note C>
            {2.5} <music21.bar.Barline style=final>
        '''
        if common.isStr(tnData):
            tnStr = tnData
        else:  # assume a 2 element sequence
            raise SubConverterException(
                "TinyNotation no longer supports two-element calls; put the time signature in the stream"
            )
        from music21 import tinyNotation
        self.stream = tinyNotation.Converter(tnStr,
                                             **self.keywords).parse().stream
Beispiel #6
0
    def getDoc(self, partName):
        element = self.getElement(partName)

        if hasattr(self.srcNameEval, '_DOC_ATTR'):
            docAttr = self.srcNameEval._DOC_ATTR
        else:
            docAttr = {}

        match = None
                
        if partName in docAttr.keys():
            match = docAttr[partName]
        # if its an undocumented public attribute and basic python
        # data structure, we do not want to show that documentation
        elif (element.kind in ['data'] and (
            common.isStr(element.object) or 
            common.isListLike(element.object) or
            common.isNum(element.object)
            )):
            pass
        else:
            try:
                match = element.object.__doc__
            except AttributeError:
                match = None

        if match == None:
            return NO_DOC
        else:
            return match
    def _filterNodeId(self, id):
        '''Given a node id, return the edge coordinates.

        Node 1 is the first node, even though the edge coordinates are 'start' and 0.

        >>> edgeList = ['M2', 'M2', 'm2', 'M2', 'M2', 'M2', 'm2']
        >>> net = IntervalNetwork()
        >>> net.setEdges(edgeList)
        >>> net._filterNodeId(1)
        ('start', 0)
        >>> net._filterNodeId([3,4])
        (3, 4)
        >>> net._filterNodeId('last')
        (5, 'end')
        >>> net._filterNodeId('first')
        ('start', 0)
        '''
        if common.isNum(id):
            # assume counting nodes from 1
            return self._nodesOrdered[id-1 % len(self._nodesOrdered)]
        if common.isStr(id):
            if id.lower() in ['start', 'first']:
                return self._getFirstNode()
            elif id.lower() in ['end', 'last']:
                return self._getLastNode()

        else: # match coords
            if tuple(id) in self._nodesOrdered:
                return tuple(id)
Beispiel #8
0
    def printDebug(self, msg, statusLevel=common.DEBUG_USER, debugFormat=None):
        '''
        Format one or more data elements into string, and print it 
        to stderr. The first arg can be a list of strings or a string; 
        lists are concatenated with common.formatStr(). 
        '''
        #if not common.isNum(statusLevel):
        #    raise EnvironmentException('bad statusLevel argument given: %s' % statusLevel)
        #         if self.__getitem__('debug') >= statusLevel:
        #             if common.isStr(msg):
        #                 msg = [msg] # make into a list
        #             if msg[0] != self.modNameParent and self.modNameParent != None:
        #                 msg = [self.modNameParent + ':'] + msg
        #             # pass list to common.formatStr
        #             msg = common.formatStr(*msg, format=debugFormat)
        #             sys.stderr.write(msg)

        if _environStorage['instance'].__getitem__('debug') >= statusLevel:
            if common.isStr(msg):
                msg = [msg]  # make into a list
            if msg[0] != self.modNameParent and self.modNameParent != None:
                msg = [self.modNameParent + ':'] + msg
            # pass list to common.formatStr
            msg = common.formatStr(*msg, format=debugFormat)
            sys.stderr.write(msg)
Beispiel #9
0
def romanTextToStreamOpus(rtHandler, inputM21=None):
    '''The main processing routine for RomanText objects that may or may not
    be multi movement.
    
    Takes in a romanText.rtObjects.RTFile() object, or a string as rtHandler.
    
    Runs `romanTextToStreamScore()` as its main work.
    
    If inputM21 is None then it will create a Score or Opus object.
    
    Return either a Score object, or, if a multi-movement work is defined, an
    Opus object.
    '''
    from music21 import stream
    if common.isStr(rtHandler):
        rtf = rtObjects.RTFile()
        rtHandler = rtf.readstr(rtHandler)  # return handler, processes tokens

    if rtHandler.definesMovements():  # create an opus
        if inputM21 == None:
            s = stream.Opus()
        else:
            s = inputM21
        # copy the common header to each of the sub-handlers
        handlerBundles = rtHandler.splitByMovement(duplicateHeader=True)
        # see if we have header information
        for h in handlerBundles:
            #print h, len(h)
            # append to opus
            s.append(romanTextToStreamScore(h))
        return s  # an opus
    else:  # create a Score
        return romanTextToStreamScore(rtHandler, inputM21=inputM21)
Beispiel #10
0
def _getKeyAndPrefix(rtKeyOrString):
    '''Given an RTKey specification, return the Key and a string prefix based
    on the tonic:

    >>> romanText.translate._getKeyAndPrefix('c')
    (<music21.key.Key of c minor>, 'c: ')
    >>> romanText.translate._getKeyAndPrefix('F#')
    (<music21.key.Key of F# major>, 'F#: ')
    >>> romanText.translate._getKeyAndPrefix('Eb')
    (<music21.key.Key of E- major>, 'E-: ')
    >>> romanText.translate._getKeyAndPrefix('Bb')
    (<music21.key.Key of B- major>, 'B-: ')
    >>> romanText.translate._getKeyAndPrefix('bb')
    (<music21.key.Key of b- minor>, 'b-: ')
    >>> romanText.translate._getKeyAndPrefix('b#')
    (<music21.key.Key of b# minor>, 'b#: ')
    '''
    from music21 import key
    if common.isStr(rtKeyOrString):
        rtKeyOrString = key.convertKeyStringToMusic21KeyString(rtKeyOrString)
        k = key.Key(rtKeyOrString)
    else:
        k = rtKeyOrString.getKey()
    tonicName = k.tonic.name
    if k.mode == 'minor':
        tonicName = tonicName.lower()
    prefix = tonicName + ": "
    return k, prefix
Beispiel #11
0
    def parseData(self, tnData, number=None):
        '''Open TinyNotation data from a string

        >>> tnData = "3/4 E4 r f# g=lastG trip{b-8 a g} c"
        >>> c = converter.subConverters.ConverterTinyNotation()
        >>> s = c.parseData(tnData)
        >>> c.stream.show('text')
        {0.0} <music21.stream.Measure 1 offset=0.0>
            {0.0} <music21.clef.TrebleClef>
            {0.0} <music21.meter.TimeSignature 3/4>
            {0.0} <music21.note.Note E>
            {1.0} <music21.note.Rest rest>
            {2.0} <music21.note.Note F#>
        {3.0} <music21.stream.Measure 2 offset=3.0>
            {0.0} <music21.note.Note G>
            {1.0} <music21.note.Note B->
            {1.3333} <music21.note.Note A>
            {1.6667} <music21.note.Note G>
            {2.0} <music21.note.Note C>
            {2.5} <music21.bar.Barline style=final>
        '''
        if common.isStr(tnData):
            tnStr = tnData
        else: # assume a 2 element sequence
            raise SubConverterException(
                "TinyNotation no longer supports two-element calls; put the time signature " + 
                "in the stream")
        from music21 import tinyNotation
        self.stream = tinyNotation.Converter(tnStr, **self.keywords).parse().stream
Beispiel #12
0
    def parseData(self, tnData, number=None):
        '''Open TinyNotation data from a string or list

        >>> tnData = ["E4 r f# g=lastG trip{b-8 a g} c", "3/4"]
        >>> c = converter.subConverters.ConverterTinyNotation()
        >>> s = c.parseData(tnData)
        >>> c.stream.show('text')
        {0.0} <music21.meter.TimeSignature 3/4>
        {0.0} <music21.note.Note E>
        {1.0} <music21.note.Rest rest>
        {2.0} <music21.note.Note F#>
        {3.0} <music21.note.Note G>
        {4.0} <music21.note.Note B->
        {4.3333} <music21.note.Note A>
        {4.6667} <music21.note.Note G>
        {5.0} <music21.note.Note C>        
        '''
        if common.isStr(tnData):
            tnStr = tnData
            tnTs = None
        else: # assume a 2 element sequence
            tnStr = tnData[0]
            tnTs = tnData[1]
        from music21 import tinyNotation
        self.stream = tinyNotation.TinyNotationStream(tnStr, tnTs)
Beispiel #13
0
def _getKeyAndPrefix(rtKeyOrString):
    '''Given an RTKey specification, return the Key and a string prefix based
    on the tonic:

    >>> romanText.translate._getKeyAndPrefix('c')
    (<music21.key.Key of c minor>, 'c: ')
    >>> romanText.translate._getKeyAndPrefix('F#')
    (<music21.key.Key of F# major>, 'F#: ')
    >>> romanText.translate._getKeyAndPrefix('Eb')
    (<music21.key.Key of E- major>, 'E-: ')
    >>> romanText.translate._getKeyAndPrefix('Bb')
    (<music21.key.Key of B- major>, 'B-: ')
    >>> romanText.translate._getKeyAndPrefix('bb')
    (<music21.key.Key of b- minor>, 'b-: ')
    >>> romanText.translate._getKeyAndPrefix('b#')
    (<music21.key.Key of b# minor>, 'b#: ')
    '''
    from music21 import key
    if common.isStr(rtKeyOrString):
        rtKeyOrString = key.convertKeyStringToMusic21KeyString(rtKeyOrString)
        k = key.Key(rtKeyOrString)
    else:
        k = rtKeyOrString.getKey()
    tonicName = k.tonic.name
    if k.mode == 'minor':
        tonicName = tonicName.lower()
    prefix = tonicName + ": "
    return k, prefix
Beispiel #14
0
    def __init__(self, value = None):
        music21.Music21Object.__init__(self)

        if not common.isStr(value):
            # assume it is a number, try to convert
            value = dynamicStrFromDecimal(value)

        self.value = value

        if self.value in longNames:
            self.longName = longNames[self.value]
        else:
            self.longName = None

        if self.value in englishNames:
            self.englishName = englishNames[self.value]
        else:
            self.englishName = None

        # for position, as musicxml, all units are in tenths of interline space
        # position is needed as default positions are often incorrect
        self.posDefaultX = None
        self.posDefaultY = None
        self.posRelativeX = -36 # this value provides good 16th note alignment
        self.posRelativeY = None
        self.posPlacement = 'below' # attr in mxDirection, below or above
Beispiel #15
0
    def __init__(self, value=None):
        base.Music21Object.__init__(self)

        # the scalar is used to calculate the final output of a note
        # under this dynamic. if this property is set, it will override 
        # use of a default. 
        self._volumeScalar = None
        self.longName = None
        self.englishName = None
        self._value = None

        if not common.isStr(value):
            # assume it is a number, try to convert
            self._volumeScalar = value
            self.value = dynamicStrFromDecimal(value)
        else:
            self.value = value # will use property

        # for position, as musicxml, all units are in tenths of interline space
        # position is needed as default positions are often incorrect
        self._positionDefaultX = -36
        self._positionDefaultY = -80 # below top line
        # this value provides good 16th note alignment
        self._positionRelativeX = None
        self._positionRelativeY = None
        # this does not do anything if default y is defined
        self._positionPlacement = None
    def antiParallelMotion(self, simpleName = None):
        '''
        Returns true if the simple interval before is the same as the simple
        interval after and the motion is contrary. if simpleName is
        specified as an Interval object or a string then it only returns
        true if the simpleName of both intervals is the same as simpleName
        (i.e., use to find antiParallel fifths) 

        >>> from music21 import *
        >>> n11 = note.Note("C4")
        >>> n12 = note.Note("D3") # descending 7th
        >>> n21 = note.Note("G4")
        >>> n22 = note.Note("A4") # ascending 2nd
        >>> vlq1 = voiceLeading.VoiceLeadingQuartet(n11, n12, n21, n22)
        >>> vlq1.antiParallelMotion()
        True
        >>> vlq1.antiParallelMotion('M2')
        False
        >>> vlq1.antiParallelMotion('P5')
        True
        
        We can also use interval objects
        >>> p5Obj = interval.Interval("P5")
        >>> p8Obj = interval.Interval('P8')
        >>> vlq1.antiParallelMotion(p5Obj)
        True
        >>> p8Obj = interval.Interval('P8')
        >>> vlq1.antiParallelMotion(p8Obj)
        False

        >>> n1 = note.Note('G4')
        >>> n2 = note.Note('G4')
        >>> m1 = note.Note('G4')
        >>> m2 = note.Note('G3')
        >>> vl2 = VoiceLeadingQuartet(n1, n2, m1, m2)
        >>> vl2.antiParallelMotion()
        False
        '''
        if not self.contraryMotion():
            return False
        else:
            if self.vIntervals[0].simpleName == self.vIntervals[1].simpleName:
                if simpleName is None:
                    return True
                else:
                    if common.isStr(simpleName):
                        if self.vIntervals[0].simpleName == simpleName:
                            return True
                        else:
                            return False
                    else: # assume Interval object
                        if self.vIntervals[0].simpleName == simpleName.simpleName:
                            return True
                        else:
                            return False
            else:
                return False
Beispiel #17
0
def pitchToSharps(value, mode=None):
    '''Given a pitch or :class:`music21.pitch.Pitch` object, return the number of sharps found in the major key.

    The `mode` parameter can be None (=Major), 'major', or 'minor'.

    >>> from music21 import *

    >>> key.pitchToSharps('c')
    0
    >>> key.pitchToSharps('c', 'minor')
    -3
    >>> key.pitchToSharps('a', 'minor')
    0
    >>> key.pitchToSharps('d')
    2
    >>> key.pitchToSharps('e-')
    -3
    >>> key.pitchToSharps('a')
    3
    >>> key.pitchToSharps('e', 'minor')
    1
    >>> key.pitchToSharps('f#', 'major')
    6
    >>> key.pitchToSharps('g-', 'major')
    -6
    >>> key.pitchToSharps('c#')
    7
    >>> key.pitchToSharps('g#')
    8
    '''
    if common.isStr(value):
        p = pitch.Pitch(value)
    else:
        p = value
    # start at C and continue in both directions
    sharpSource = [0]
    for i in range(1,13):
        sharpSource.append(i)
        sharpSource.append(-i)

    minorShift = interval.Interval('-m3')

    # NOTE: this may not be the fastest approach
    match = None
    for i in sharpSource:
        pCandidate = sharpsToPitch(i)
        if mode in [None, 'major']:
            if pCandidate.name == p.name:
                match = i
                break
        else: # match minor pitch
            pMinor = pCandidate.transpose(minorShift)
            if pMinor.name == p.name:
                match = i
                break
    return match
Beispiel #18
0
 def warn(self, msg):
     '''To print a warning to the user, send a list of strings to this
     method. 
     '''
     if common.isStr(msg):
         msg = [msg] # make into a list
     if msg[0] != self.modNameParent and self.modNameParent != None:
         msg = [self.modNameParent + ': WARNING:'] + msg
     msg = common.formatStr(*msg)
     sys.stderr.write(msg)
Beispiel #19
0
 def __init__(self, text=None, number=1, syllabic=None):
     if not common.isStr(text):
         # do not want to do this unless we are sure this is not a string
         # possible might alter unicode or other string-like representations
         self.text = str(text)         
     else:
         self.text = text
     if not common.isNum(number):
         raise LyricException('Number best be number')
     self.number = number
     self.syllabic = syllabic # can be begin, middle, or end
    def __setitem__(self, key, value):
        '''Dictionary-like setting. Changes are made only to local dictionary.
        Must call write() to make permanent

        >>> from music21 import *
        >>> a = music21.environment.Environment()
        >>> a['debug'] = 1
        >>> a['graphicsPath'] = '/test&Encode'
        >>> a['graphicsPath']
        '/test&amp;Encode'
        >>> a['autoDownload'] = 'adsf'
        Traceback (most recent call last):
        EnvironmentException: adsf is not an acceptable value for preference: autoDownload
        >>> a['showFormat'] = 'adsf'
        Traceback (most recent call last):
        EnvironmentException: adsf is not an acceptable value for preference: showFormat
        >>> a['showFormat'] = 'musicxml'
        '''
        #saxutils.escape # used for escaping strings going to xml
        # with unicode encoding
        # http://www.xml.com/pub/a/2002/11/13/py-xml.html?page=2
        # saxutils.escape(msg).encode('UTF-8')

        if key not in self.ref.keys():
            raise EnvironmentException('no preference: %s' % key)
        if value == '':
            value = None # always replace '' with None

        valid = False
        if key == 'showFormat':
            value = value.lower()
            if value in common.VALID_SHOW_FORMATS:
                valid = True
        elif key == 'writeFormat':
            value = value.lower()
            if value in common.VALID_WRITE_FORMATS:
                valid = True
        elif key == 'debug':
          log.setLevel(logging.INFO)
        elif key == 'autoDownload':
            value = value.lower()
            if value in common.VALID_AUTO_DOWNLOAD:
                valid = True
        else: # temporarily not validating other preferences
            valid = True

        if not valid:
            raise EnvironmentException('%s is not an acceptable value for preference: %s' % (value, key))

        if common.isStr(value):
            value = xml.sax.saxutils.escape(value).encode('UTF-8')
        self.ref[key] = value
    def _filterPitchList(self, pitchTest):
        '''Given a list or one pitch, check if all are pitch objects; convert if necessary.
        '''
        if not common.isListLike(pitchTest):
            if common.isStr(pitchTest):
                pitchTest = pitch.Pitch(pitchTest)
            pitchTest = [pitchTest]
        else:
            # convert a list of string into pitch objects
            temp = []
            for p in pitchTest:
                if common.isStr(p):
                    temp.append(pitch.Pitch(p))
            if len(temp) == len(pitchTest):
                pitchTest = temp

        sortList = [(pitchTest[i].ps, i) for i in range(len(pitchTest))]
        sortList.sort()
        minPitch = pitchTest[sortList[0][1]] # first index
        maxPitch = pitchTest[sortList[-1][1]] # last index

        return pitchTest, minPitch, maxPitch
Beispiel #22
0
 def warn(self, msg, header=None):
     '''To print a warning to the user, send a list of strings to this
     method. Similar to printDebug but even if debug is off.
     '''
     if common.isStr(msg):
         msg = [msg] # make into a list
     if header == None:
         if msg[0] != self.modNameParent and self.modNameParent != None:
             msg = [self.modNameParent + ': WARNING:'] + msg
     else:
         msg = [header] + msg
     msg = common.formatStr(*msg)
     sys.stderr.write(msg)
Beispiel #23
0
    def __setitem__(self, key, value):

        #saxutils.escape # used for escaping strings going to xml
        # with unicode encoding
        # http://www.xml.com/pub/a/2002/11/13/py-xml.html?page=2
        # saxutils.escape(msg).encode('UTF-8')

        # add local corpus path as a key
        if key not in self._ref:
            if key != 'localCorpusPath':
                raise EnvironmentException('no preference: %s' % key)
        if value == '':
            value = None  # always replace '' with None

        valid = False
        if key == 'showFormat':
            value = value.lower()
            if value in common.VALID_SHOW_FORMATS:
                valid = True
        elif key == 'writeFormat':
            value = value.lower()
            if value in common.VALID_WRITE_FORMATS:
                valid = True
        elif key == 'autoDownload':
            value = value.lower()
            if value in common.VALID_AUTO_DOWNLOAD:
                valid = True
        elif key == 'localCorpusSettings':
            # needs to be a list of strings for now
            if common.isListLike(value):
                valid = True
        else:  # temporarily not validating other preferences
            valid = True

        if not valid:
            raise EnvironmentException(
                '%s is not an acceptable value for preference: %s' %
                (value, key))

        # need to escape problematic characters for xml storage
        if common.isStr(value):
            value = saxutils.escape(value).encode('UTF-8')
        # set value
        if key == 'localCorpusPath':
            # only add if unique
            if value not in self._ref['localCorpusSettings']:
                # check for malicious values here
                self._ref['localCorpusSettings'].append(value)
        else:
            self._ref[key] = value
Beispiel #24
0
 def printDebug(self, msg, statusLevel=common.DEBUG_USER):
     '''Format one or more data elements into string, and print it 
     to stderr. The first arg can be a list of string; lists are 
     concatenated with common.formatStr(). 
     '''
     if not common.isNum(statusLevel):
         raise EnvironmentException('bad statusLevel argument given: %s' % statusLevel)
     if self.__getitem__('debug') >= statusLevel:
         if common.isStr(msg):
             msg = [msg] # make into a list
         if msg[0] != self.modNameParent and self.modNameParent != None:
             msg = [self.modNameParent + ':'] + msg
 
         msg = common.formatStr(*msg)
         sys.stderr.write(msg)
Beispiel #25
0
    def parseData(self, tnData):
        '''Open TinyNotation data from a string or list

        >>> tnData = ["E4 r f# g=lastG trip{b-8 a g} c", "3/4"]
        >>> c = ConverterTinyNotation()
        >>> s = c.parseData(tnData)
        '''
        if common.isStr(tnData):
            tnStr = tnData
            tnTs = None
        else: # assume a 2 element sequence
            tnStr = tnData[0]
            tnTs = tnData[1]
    
        self.stream = tinyNotation.TinyNotationStream(tnStr, tnTs)
    def __setitem__(self, key, value):

        #saxutils.escape # used for escaping strings going to xml
        # with unicode encoding
        # http://www.xml.com/pub/a/2002/11/13/py-xml.html?page=2
        # saxutils.escape(msg).encode('UTF-8')

        # add local corpus path as a key
        if key not in self._ref:
            if key != 'localCorpusPath':
                raise EnvironmentException('no preference: %s' % key)
        if value == '':
            value = None # always replace '' with None

        valid = False
        if key == 'showFormat':
            value = value.lower()
            if value in common.VALID_SHOW_FORMATS:
                valid = True
        elif key == 'writeFormat':
            value = value.lower()
            if value in common.VALID_WRITE_FORMATS:
                valid = True
        elif key == 'autoDownload':
            value = value.lower()
            if value in common.VALID_AUTO_DOWNLOAD:
                valid = True
        elif key == 'localCorpusSettings':
            # needs to be a list of strings for now
            if common.isListLike(value):
                valid = True
        else: # temporarily not validating other preferences
            valid = True

        if not valid:
            raise EnvironmentException('%s is not an acceptable value for preference: %s' % (value, key))

        # need to escape problematic characters for xml storage
        if common.isStr(value):
            value = saxutils.escape(value).encode('UTF-8')
        # set value
        if key == 'localCorpusPath':
            # only add if unique
            if value not in self._ref['localCorpusSettings']:
                # check for malicious values here
                self._ref['localCorpusSettings'].append(value)
        else:
            self._ref[key] = value
Beispiel #27
0
 def warn(self, msg, header=None):
     '''
     To print a warning to the user, send a list of strings to this
     method. Similar to printDebug but even if debug is off.
     '''
     if common.isStr(msg):
         msg = [msg]  # make into a list
     elif isinstance(msg, dict):
         msg = [repr(msg)]
     if header == None:
         if msg[0] != self.modNameParent and self.modNameParent != None:
             msg = [self.modNameParent + ': WARNING:'] + msg
     else:
         msg = [header] + msg
     msg = common.formatStr(*msg)
     sys.stderr.write(msg)
Beispiel #28
0
    def load(self, value):
        '''Load values by string, datetime object, or Date object.

        >>> a = Date(year=1843, month=3, day=3)
        >>> b = Date()
        >>> b.load(a)
        >>> b.year
        1843
        '''

        if isinstance(value, datetime.datetime):
            self.loadDatetime(value)
        elif common.isStr(value):
            self.loadStr(value)
        elif isinstance(value, Date):
            self.loadOther(value)
        else:
            raise MetadataException('cannot load data: %s' % value)    
Beispiel #29
0
    def parseData(self, strData, number=None):
        '''Get musedata from a string representation.

        '''
        from music21 import musedata as musedataModule
        from music21.musedata import translate as musedataTranslate

        if common.isStr(strData):
            strDataList = [strData]
        else:
            strDataList = strData

        mdw = musedataModule.MuseDataWork()

        for strData in strDataList:
            mdw.addString(strData)

        musedataTranslate.museDataWorkToStreamScore(mdw, self.stream)
Beispiel #30
0
    def load(self, value):
        r'''
        Load values by string, datetime object, or Date object:

        >>> a = metadata.Date(year=1843, month=3, day=3)
        >>> b = metadata.Date()
        >>> b.load(a)
        >>> b.year
        1843
        '''
        if isinstance(value, datetime.datetime):
            self.loadDatetime(value)
        elif common.isStr(value):
            self.loadStr(value)
        elif isinstance(value, Date):
            self.loadOther(value)
        else:
            raise exceptions21.MetadataException('Cannot load data: %s' % value)
Beispiel #31
0
    def parseData(self, strData, number=None):
        '''Get musedata from a string representation.

        '''
        from music21 import musedata as musedataModule
        from music21.musedata import translate as musedataTranslate

        if common.isStr(strData):
            strDataList = [strData]
        else:
            strDataList = strData

        mdw = musedataModule.MuseDataWork()

        for strData in strDataList:
            mdw.addString(strData)

        musedataTranslate.museDataWorkToStreamScore(mdw, self.stream)
Beispiel #32
0
def ch1_basic_II_C(data, intervalShift):
    '''Function for C1, C2, C3, and C4
    '''
    from music21 import stream, common, chord
    ex = stream.Stream()
    for chunk in data:
        m = stream.Measure()    
        for e in chunk:
            if common.isStr(e):
                n1 = note.Note(e)
                n1.quarterLength = 4
                n2 = n1.transpose(intervalShift)
                m.append(chord.Chord([n1, n2])) # chord to show both
            else:
                m.append(e)
        m.timeSignature = m.bestTimeSignature()
        ex.append(m)
    return ex
Beispiel #33
0
    def _createPartBundles(self):
        '''
        Fill the _partBundles list with dictionaries, 
        each dictionary defining a name (part id or supplied), a color, and list of Parts that match.
        '''
        self._partBundles = []
        if self._partGroups is not None:
            for d in self._partGroups: # a list of dictionaries
                name, pColor, matches = d['name'], d['color'], d['match']
                sub = []
                for p in self._score.parts:
                    #environLocal.printDebug(['_createPartBundles: part.id', p.id])
                    # if matches is None, use group name
                    if matches is None:
                        matches = [name]
                    for m in matches: # strings or instruments
                        if common.isStr(m):
                            if str(p.id).lower().find(m.lower()) >= 0:
                                sub.append(p)
                                break
                        # TODO: match if m is Instrument class
                if sub == []:
                    continue
                data = {'pGroupId':name, 'color':pColor, 'parts':sub}
                self._partBundles.append(data)
        else: # manually creates    
            for p in self._score.parts:
                # store one or more Parts associated with an id
                data = {'pGroupId':p.id, 'color':'#666666', 'parts':[p]}
                self._partBundles.append(data)

        # create flat representation of all parts in a bundle
        for partBundle in self._partBundles:
            if len(partBundle['parts']) == 1:
                partBundle['parts.flat'] = partBundle['parts'][0].flat
            else:
                # align all parts and flatten
                # this takes a flat presentation of all parts
                s = stream.Stream()
                for p in partBundle['parts']:
                    s.insert(0, p)
                partBundle['parts.flat'] = s.flat
Beispiel #34
0
 def _setAccidental(self, value):
     '''
     Adds an accidental to the Note, given as an Accidental object.
     Also alters the name of the note
     
     >>> from music21 import *
     >>> a = note.Note()
     >>> a.step = "D"
     >>> a.name 
     'D'
     >>> b = pitch.Accidental("sharp")
     >>> a.setAccidental(b)
     >>> a.name 
     'D#'
     '''
     if common.isStr(value):
         accidental = pitch.Accidental(value)
     else: 
         accidental = value
     self.pitch.accidental = accidental
Beispiel #35
0
    def addLyric(self, text, lyricNumber = None):
        '''Adds a lyric, or an additional lyric, to a Note, Chord, or Rest's lyric list. If `lyricNumber` is not None, a specific line of lyric text can be set. 

        >>> from music21 import *
        >>> n1 = note.Note()
        >>> n1.addLyric("hello")
        >>> n1.lyrics[0].text
        'hello'
        >>> n1.lyrics[0].number
        1
        
        >>> # note that the option number specified gives the lyric number, not the list position
        >>> n1.addLyric("bye", 3)
        >>> n1.lyrics[1].text
        'bye'
        >>> n1.lyrics[1].number
        3
        
        >>> # replace existing lyric
        >>> n1.addLyric("ciao", 3)
        >>> n1.lyrics[1].text
        'ciao'
        >>> n1.lyrics[1].number
        3
        '''
        if not common.isStr(text):
            text = str(text)
        if lyricNumber is None:
            maxLyrics = len(self.lyrics) + 1
            self.lyrics.append(Lyric(text, maxLyrics))
        else:
            foundLyric = False
            for thisLyric in self.lyrics:
                if thisLyric.number == lyricNumber:
                    thisLyric.text = text
                    foundLyric = True
                    break
            if foundLyric is False:
                self.lyrics.append(Lyric(text, lyricNumber))
Beispiel #36
0
    def __init__(self, content=None):
        Expression.__init__(self)
        # numerous properties are inherited from TextFormat
        text.TextFormat.__init__(self)

        # the text string to be displayed; not that line breaks
        # are given in the xml with this non-printing character: (#)
        if not common.isStr(content):
            self._content = str(content)
        else:
            self._content = content

        self._enclosure = None

        # numerous parameters are inherited from text.TextFormat
        self._positionDefaultX = None
        self._positionDefaultY = 20  # two staff lines above
        # these values provided for musicxml compatibility
        self._positionRelativeX = None
        self._positionRelativeY = None
        # this does not do anything if default y is defined
        self._positionPlacement = None
Beispiel #37
0
    def load(self, value):
        r'''
        Load values by string, datetime object, or Date object:

        ::

            >>> from music21 import metadata
            >>> a = metadata.Date(year=1843, month=3, day=3)
            >>> b = metadata.Date()
            >>> b.load(a)
            >>> b.year
            1843

        '''
        if isinstance(value, datetime.datetime):
            self.loadDatetime(value)
        elif common.isStr(value):
            self.loadStr(value)
        elif isinstance(value, Date):
            self.loadOther(value)
        else:
            raise exceptions21.MetadataException('Cannot load data: %s' % value)
Beispiel #38
0
    def __init__(self, content=None):
        Expression.__init__(self)
        # numerous properties are inherited from TextFormat
        text.TextFormat.__init__(self)

        # the text string to be displayed; not that line breaks
        # are given in the xml with this non-printing character: (#)
        if not common.isStr(content):
            self._content = str(content)
        else:
            self._content = content

        self._enclosure = None

        # numerous parameters are inherited from text.TextFormat
        self._positionDefaultX = None
        self._positionDefaultY = 20 # two staff lines above
        # these values provided for musicxml compatibility
        self._positionRelativeX = None
        self._positionRelativeY = None
        # this does not do anything if default y is defined
        self._positionPlacement = None
Beispiel #39
0
def romanTextToStreamOpus(rtHandler, inputM21=None):
    '''Return either a Score object, or, if a multi-movement work is defined, an Opus object. 
    '''
    from music21 import stream
    if common.isStr(rtHandler):
        rtf = romanTextModule.RTFile()
        rtHandler = rtf.readstr(rtHandler) # return handler, processes tokens

    if rtHandler.definesMovements(): # create an opus
        if inputM21 == None:
            s = stream.Opus()
        else:
            s = inputM21
        # copy the common header to each of the sub-handlers
        handlerBundles = rtHandler.splitByMovement(duplicateHeader=True)
        # see if we have header information
        for h in handlerBundles:
            #print h, len(h)
            # append to opus
            s.append(romanTextToStreamScore(h))
        return s # an opus
    else: # create a Score
        return romanTextToStreamScore(rtHandler, inputM21=inputM21)
Beispiel #40
0
def romanTextToStreamScore(rtHandler, inputM21=None):
    '''The main processing module for single-movement RomanText works.

    Given a romanText handler or string, return or fill a Score Stream.
    '''
    # accept a string directly; mostly for testing
    from music21 import romanText as romanTextModule

    if common.isStr(rtHandler):
        rtf = romanTextModule.RTFile()
        rtHandler = rtf.readstr(rtHandler) # return handler, processes tokens

    # this could be just a Stream, but b/c we are creating metadata, perhaps better to match presentation of other scores. 

    from music21 import metadata
    from music21 import stream
    from music21 import note
    from music21 import meter
    from music21 import key
    from music21 import roman
    from music21 import tie

    if inputM21 == None:
        s = stream.Score()
    else:
        s = inputM21

    # metadata can be first
    md = metadata.Metadata()
    s.insert(0, md)

    p = stream.Part()
    # ts indication are found in header, and also found elsewhere
    tsCurrent = meter.TimeSignature('4/4') # create default 4/4
    tsSet = False # store if set to a measure
    lastMeasureToken = None
    lastMeasureNumber = 0
    previousRn = None
    keySigCurrent = None
    keySigSet = True  # set a keySignature
    foundAKeySignatureSoFar = False
    kCurrent, unused_prefixLyric = _getKeyAndPrefix('C') # default if none defined
    prefixLyric = ''

    repeatEndings = {}

    for t in rtHandler.tokens:
        try:

            # environLocal.printDebug(['token', t])
            if t.isTitle():
                md.title = t.data            

            elif t.isWork():
                md.alternativeTitle = t.data

            elif t.isPiece():
                md.alternativeTitle = t.data

            elif t.isComposer():
                md.composer = t.data

            elif t.isMovement():
                md.movementNumber = t.data
    
            elif t.isTimeSignature():
                tsCurrent = meter.TimeSignature(t.data)
                tsSet = False
                # environLocal.printDebug(['tsCurrent:', tsCurrent])

            elif t.isKeySignature():
                if t.data == "":
                    keySigCurrent = key.KeySignature(0)
                elif t.data == "Bb":
                    keySigCurrent = key.KeySignature(-1)
                else:
                    pass 
                    # better to print a message
                    # environLocal.printDebug(['still need to write a generic RomanText KeySignature routine.  this is just temporary'])
                    # raise RomanTextTranslateException("still need to write a generic RomanText KeySignature routine.  this is just temporary")
                keySigSet = False
                # environLocal.printDebug(['keySigCurrent:', keySigCurrent])
                foundAKeySignatureSoFar = True

            elif t.isMeasure():
                # environLocal.printDebug(['handling measure token:', t])
    
                if t.variantNumber is not None:
                    # environLocal.printDebug(['skipping variant: %s' % t])
                    continue
                if t.variantLetter is not None:
                    # environLocal.printDebug(['skipping variant: %s' % t])
                    continue
    
                # if this measure number is more than 1 greater than the last
                # defined measure number, and the previous chord is not None, 
                # then fill with copies of the last-defined measure
                if ((t.number[0] > lastMeasureNumber + 1) and 
                    (previousRn is not None)):
                    for i in range(lastMeasureNumber + 1, t.number[0]):
                        mFill = stream.Measure()
                        mFill.number = i
                        newRn = copy.deepcopy(previousRn)
                        newRn.lyric = ""
                        # set to entire bar duration and tie 
                        newRn.duration = copy.deepcopy(tsCurrent.barDuration)
                        if previousRn.tie is None:
                            previousRn.tie = tie.Tie('start')
                        else:
                            previousRn.tie.type = 'continue'
                        # set to stop for now; may extend on next iteration
                        newRn.tie = tie.Tie('stop')
                        previousRn = newRn
                        mFill.append(newRn)
                        appendMeasureToRepeatEndingsDict(lastMeasureToken, mFill, repeatEndings, i)
                        p.append(mFill)
                    lastMeasureNumber = t.number[0] - 1
                    lastMeasureToken = t

                # create a new measure or copy a past measure
                if len(t.number) == 1 and t.isCopyDefinition: # if not a range
                    m, kCurrent = _copySingleMeasure(t, p, kCurrent)
                    p.append(m)
                    lastMeasureNumber = m.number
                    lastMeasureToken = t
                    romans = m.getElementsByClass(roman.RomanNumeral)
                    if len(romans) > 0:
                        previousRn = romans[-1] 

                elif len(t.number) > 1:
                    measures, kCurrent = _copyMultipleMeasures(t, p, kCurrent)
                    p.append(measures)
                    lastMeasureNumber = measures[-1].number
                    lastMeasureToken = t
                    romans = measures[-1].getElementsByClass(roman.RomanNumeral)
                    if len(romans) > 0:
                        previousRn = romans[-1]

                else:       
                    m = stream.Measure()
                    m.number = t.number[0]
                    appendMeasureToRepeatEndingsDict(t, m, repeatEndings)                            
                    lastMeasureNumber = t.number[0]
                    lastMeasureToken = t
                    
                    if not tsSet:
                        m.timeSignature = tsCurrent
                        tsSet = True # only set when changed
                    if not keySigSet and keySigCurrent is not None:
                        m.insert(0, keySigCurrent)
                        keySigSet = True # only set when changed
        
                    o = 0.0 # start offsets at zero
                    previousChordInMeasure = None
                    pivotChordPossible = False
                    numberOfAtoms = len(t.atoms)
                    setKeyChangeToken = False # first RomanNumeral object after a key change should have this set to True
                    
                    for i, a in enumerate(t.atoms):
                        if isinstance(a, romanTextModule.RTKey) or \
                           ((foundAKeySignatureSoFar == False) and \
                            (isinstance(a, romanTextModule.RTAnalyticKey))): 
                            # found a change of Key+KeySignature or
                            # just found a change of analysis but no keysignature so far
                    
                            # environLocal.printDebug(['handling key token:', a])
                            try: # this sets the key and the keysignature
                                kCurrent, pl = _getKeyAndPrefix(a)
                                prefixLyric += pl
                            except:
                                raise RomanTextTranslateException('cannot get key from %s in line %s' % (a.src, t.src))
                            # insert at beginning of measure if at beginning -- for things like pickups.
                            if m.number < 2:
                                m.insert(0, kCurrent)
                            else:
                                m.insert(o, kCurrent)
                            foundAKeySignatureSoFar = True
                            setKeyChangeToken = True
    
                        elif isinstance(a, romanTextModule.RTKeySignature):
                            try: # this sets the keysignature but not the prefix text
                                thisSig = a.getKeySignature()
                            except:
                                raise RomanTextTranslateException('cannot get key from %s in line %s' % (a.src, t.src))
                            #insert at beginning of measure if at beginning -- for things like pickups.
                            if m.number < 2:
                                m.insert(0, thisSig)
                            else:
                                m.insert(o, thisSig)
                            foundAKeySignatureSoFar = True
    
                        elif isinstance(a, romanTextModule.RTAnalyticKey):
                            # just a change in analyzed key, not a change in anything else
                            #try: # this sets the key, not the keysignature
                                kCurrent, pl = _getKeyAndPrefix(a)
                                prefixLyric += pl
                                setKeyChangeToken = True

                            #except:
                            #    raise RomanTextTranslateException('cannot get key from %s in line %s' % (a.src, t.src))
    
                        elif isinstance(a, romanTextModule.RTBeat):
                            # set new offset based on beat
                            try:
                                o = a.getOffset(tsCurrent)
                            except ValueError:
                                raise RomanTextTranslateException("cannot properly get an offset from beat data %s under timeSignature %s in line %s" % (a.src, tsCurrent, t.src))
                            if (previousChordInMeasure is None and 
                                previousRn is not None and o > 0):
                                # setting a new beat before giving any chords
                                firstChord = copy.deepcopy(previousRn)
                                firstChord.quarterLength = o
                                firstChord.lyric = ""
                                if previousRn.tie == None:
                                    previousRn.tie = tie.Tie('start')
                                else:
                                    previousRn.tie.type = 'continue'    
                                firstChord.tie = tie.Tie('stop')
                                previousRn = firstChord
                                previousChordInMeasure = firstChord
                                m.insert(0, firstChord)
                            pivotChordPossible = False

                        elif isinstance(a, romanTextModule.RTNoChord):
                            # use source to evaluation roman 
                            rn = note.Rest()
                            if pivotChordPossible == False:
                                # probably best to find duration
                                if previousChordInMeasure is None:
                                    pass # use default duration
                                else: # update duration of previous chord in Measure
                                    oPrevious = previousChordInMeasure.getOffsetBySite(m)
                                    newQL = o - oPrevious
                                    if newQL <= 0:
                                        raise RomanTextTranslateException('too many notes in this measure: %s' % t.src)
                                    previousChordInMeasure.quarterLength = newQL                                                          
                                prefixLyric = ""
                                m.insert(o, rn)
                                previousChordInMeasure = rn
                                previousRn = rn
                                pivotChordPossible = False

                        elif isinstance(a, romanTextModule.RTChord):
                            # use source to evaluation roman 
                            try:
                                asrc = a.src
    #                            if kCurrent.mode == 'minor':
    #                                if asrc.lower().startswith('vi'): #vi or vii w/ or w/o o
    #                                    if asrc.upper() == a.src: # VI or VII to bVI or bVII
    #                                        asrc = 'b' + asrc
                                rn = roman.RomanNumeral(asrc, copy.deepcopy(kCurrent))
                                if setKeyChangeToken is True:
                                    rn.followsKeyChange = True
                                    setKeyChangeToken = False
                                else:
                                    rn.followsKeyChange = False
                            except (roman.RomanNumeralException, 
                                common.Music21CommonException): 
                                #environLocal.printDebug('cannot create RN from: %s' % a.src)
                                rn = note.Note() # create placeholder 

                            if pivotChordPossible == False:
                                # probably best to find duration
                                if previousChordInMeasure is None:
                                    pass # use default duration
                                else: # update duration of previous chord in Measure
                                    oPrevious = previousChordInMeasure.getOffsetBySite(m)
                                    newQL = o - oPrevious
                                    if newQL <= 0:
                                        raise RomanTextTranslateException('too many notes in this measure: %s' % t.src)
                                    previousChordInMeasure.quarterLength = newQL                          
                                
                                rn.addLyric(prefixLyric + a.src)
                                prefixLyric = ""
                                m.insert(o, rn)
                                previousChordInMeasure = rn
                                previousRn = rn
                                pivotChordPossible = True
                            else:
                                previousChordInMeasure.lyric += "//" + prefixLyric + a.src
                                previousChordInMeasure.pivotChord = rn
                                prefixLyric = ""
                                pivotChordPossible = False

                        elif isinstance(a, romanTextModule.RTRepeat):
                            if o == 0:
                                if isinstance(a, romanTextModule.RTRepeatStart):
                                    m.leftBarline = bar.Repeat(direction='start')
                                else:
                                    rtt = RomanTextUnprocessedToken(a)
                                    m.insert(o, rtt)
                            elif tsCurrent is not None and (tsCurrent.barDuration.quarterLength == o or i == numberOfAtoms - 1):
                                if isinstance(a, romanTextModule.RTRepeatStop):
                                    m.rightBarline = bar.Repeat(direction='end')
                                else:
                                    rtt = RomanTextUnprocessedToken(a)
                                    m.insert(o, rtt)
                            else: # mid measure repeat signs
                                rtt = RomanTextUnprocessedToken(a)
                                m.insert(o, rtt)

                        else:
                            rtt = RomanTextUnprocessedToken(a)
                            m.insert(o, rtt)
                            #environLocal.warn("Got an unknown token: %r" % a)
                    
                    # may need to adjust duration of last chord added
                    if tsCurrent is not None:
                        previousRn.quarterLength = tsCurrent.barDuration.quarterLength - o
                    p.append(m)

        except Exception:
            import traceback
            tracebackMessage = traceback.format_exc()
            raise RomanTextTranslateException("At line %d for token %r, an exception was raised: \n%s" % (t.lineNumber, t, tracebackMessage))

    fixPickupMeasure(p)
    p.makeBeams(inPlace=True)
    p.makeAccidentals(inPlace=True)
    _addRepeatsFromRepeatEndings(p, repeatEndings) # 1st and second endings...
    s.insert(0, p)

    return s
Beispiel #41
0
def getFrequenciesFromPartialAudioFile(waveFilenameOrHandle='temp',
                                       length=10.0,
                                       startSample=0):
    '''
    It calculates the fundamental frequency at every instant of time of an audio signal
    extracted either from the microphone or from an already recorded song.
    It uses a period of time defined by the variable "length" in seconds.

    It returns a list with the frequencies, a variable with the file descriptor, and the end sample position.

    >>> #_DOCS_SHOW readFile = 'pachelbel.wav'
    >>> import os #_DOCS_HIDE
    >>> readFile = common.getSourceFilePath() + os.path.sep + 'audioSearch' + os.path.sep + 'test_audio.wav' #_DOCS_HIDE
    >>> frequencyList, pachelbelFileHandle, currentSample  = audioSearch.getFrequenciesFromPartialAudioFile(readFile, length=1.0)
    >>> for i in range(5):
    ...     print(frequencyList[i])
    143.627689055
    99.0835452019
    211.004784689
    4700.31347962
    767.827403482
    >>> print(currentSample)  # should be near 44100, but probably not exact
    44032

    Now read the next 1 second...

    >>> frequencyList, pachelbelFileHandle, currentSample  = audioSearch.getFrequenciesFromPartialAudioFile(pachelbelFileHandle, length=1.0, startSample = currentSample)
    >>> for i in range(5):
    ...     print(frequencyList[i])
    187.798213268
    238.263483185
    409.700397349
    149.958733396
    101.989786226
    >>> print(currentSample)  # should be exactly double the previous
    88064
    '''
    if "numpy" in base._missingImport:
        raise AudioSearchException(
            "Cannot run getFrequenciesFromPartialAudioFile without numpy installed"
        )
    import numpy

    if waveFilenameOrHandle == 'temp':
        waveFilenameOrHandle = environLocal.getRootTempDir(
        ) + os.path.sep + 'temp.wav'

    if common.isStr(waveFilenameOrHandle):
        # waveFilenameOrHandle is a filename
        waveFilename = waveFilenameOrHandle
        try:
            waveHandle = wave.open(waveFilename, 'r')
        except IOError:
            raise AudioSearchException(
                "Cannot open %s for reading, does not exist" % waveFilename)
    else:
        # waveFilenameOrHandle is a filehandle
        waveHandle = waveFilenameOrHandle

    storedWaveSampleList = []

    environLocal.printDebug("* reading file from disk a part of the song")
    for i in range(
            int(math.floor(length * recordSampleRate / audioChunkLength))):
        startSample = startSample + audioChunkLength
        if startSample < waveHandle.getnframes():
            data = waveHandle.readframes(audioChunkLength)
            storedWaveSampleList.append(data)
    freqFromAQList = []

    for data in storedWaveSampleList:
        samps = numpy.fromstring(data, dtype=numpy.int16)
        freqFromAQList.append(autocorrelationFunction(samps, recordSampleRate))

    endSample = startSample
    return (freqFromAQList, waveHandle, endSample)
Beispiel #42
0
def romanTextToStreamScore(rtHandler, inputM21=None):
    '''The main processing module for single-movement RomanText works.

    Given a romanText handler or string, return or fill a Score Stream.
    '''
    # accept a string directly; mostly for testing
    if common.isStr(rtHandler):
        rtf = rtObjects.RTFile()
        rtHandler = rtf.readstr(rtHandler)  # return handler, processes tokens

    # this could be just a Stream, but b/c we are creating metadata, perhaps better to match presentation of other scores.

    from music21 import metadata
    from music21 import stream
    from music21 import note
    from music21 import meter
    from music21 import key
    from music21 import roman
    from music21 import tie

    if inputM21 == None:
        s = stream.Score()
    else:
        s = inputM21

    # metadata can be first
    md = metadata.Metadata()
    s.insert(0, md)

    p = stream.Part()
    # ts indication are found in header, and also found elsewhere
    tsCurrent = meter.TimeSignature('4/4')  # create default 4/4
    tsSet = False  # store if set to a measure
    lastMeasureToken = None
    lastMeasureNumber = 0
    previousRn = None
    keySigCurrent = None
    keySigSet = True  # set a keySignature
    foundAKeySignatureSoFar = False
    kCurrent, unused_prefixLyric = _getKeyAndPrefix(
        'C')  # default if none defined
    prefixLyric = ''

    repeatEndings = {}
    rnKeyCache = {}

    for t in rtHandler.tokens:
        try:

            # environLocal.printDebug(['token', t])
            if t.isTitle():
                md.title = t.data

            elif t.isWork():
                md.alternativeTitle = t.data

            elif t.isPiece():
                md.alternativeTitle = t.data

            elif t.isComposer():
                md.composer = t.data

            elif t.isMovement():
                md.movementNumber = t.data

            elif t.isTimeSignature():
                tsCurrent = meter.TimeSignature(t.data)
                tsSet = False
                # environLocal.printDebug(['tsCurrent:', tsCurrent])

            elif t.isKeySignature():
                if t.data == "":
                    keySigCurrent = key.KeySignature(0)
                elif t.data == "Bb":
                    keySigCurrent = key.KeySignature(-1)
                else:
                    pass
                    # better to print a message
                    # environLocal.printDebug(['still need to write a generic RomanText KeySignature routine.  this is just temporary'])
                    # raise RomanTextTranslateException("still need to write a generic RomanText KeySignature routine.  this is just temporary")
                keySigSet = False
                # environLocal.printDebug(['keySigCurrent:', keySigCurrent])
                foundAKeySignatureSoFar = True

            elif t.isMeasure():
                # environLocal.printDebug(['handling measure token:', t])
                #if t.number[0] % 10 == 0:
                #    print "at number " + str(t.number[0])
                if t.variantNumber is not None:
                    # environLocal.printDebug(['skipping variant: %s' % t])
                    continue
                if t.variantLetter is not None:
                    # environLocal.printDebug(['skipping variant: %s' % t])
                    continue

                # if this measure number is more than 1 greater than the last
                # defined measure number, and the previous chord is not None,
                # then fill with copies of the last-defined measure
                if ((t.number[0] > lastMeasureNumber + 1)
                        and (previousRn is not None)):
                    for i in range(lastMeasureNumber + 1, t.number[0]):
                        mFill = stream.Measure()
                        mFill.number = i
                        newRn = copy.deepcopy(previousRn)
                        newRn.lyric = ""
                        # set to entire bar duration and tie
                        newRn.duration = copy.deepcopy(tsCurrent.barDuration)
                        if previousRn.tie is None:
                            previousRn.tie = tie.Tie('start')
                        else:
                            previousRn.tie.type = 'continue'
                        # set to stop for now; may extend on next iteration
                        newRn.tie = tie.Tie('stop')
                        previousRn = newRn
                        mFill.append(newRn)
                        appendMeasureToRepeatEndingsDict(
                            lastMeasureToken, mFill, repeatEndings, i)
                        p._appendCore(mFill)
                    lastMeasureNumber = t.number[0] - 1
                    lastMeasureToken = t

                # create a new measure or copy a past measure
                if len(t.number) == 1 and t.isCopyDefinition:  # if not a range
                    p.elementsChanged()
                    m, kCurrent = _copySingleMeasure(t, p, kCurrent)
                    p._appendCore(m)
                    lastMeasureNumber = m.number
                    lastMeasureToken = t
                    romans = m.getElementsByClass(roman.RomanNumeral,
                                                  returnStreamSubClass='list')
                    if len(romans) > 0:
                        previousRn = romans[-1]

                elif len(t.number) > 1:
                    p.elementsChanged()
                    measures, kCurrent = _copyMultipleMeasures(t, p, kCurrent)
                    p.append(measures)  # appendCore does not work with list
                    lastMeasureNumber = measures[-1].number
                    lastMeasureToken = t
                    romans = measures[-1].getElementsByClass(
                        roman.RomanNumeral, returnStreamSubClass='list')
                    if len(romans) > 0:
                        previousRn = romans[-1]

                else:
                    m = stream.Measure()
                    m.number = t.number[0]
                    appendMeasureToRepeatEndingsDict(t, m, repeatEndings)
                    lastMeasureNumber = t.number[0]
                    lastMeasureToken = t

                    if not tsSet:
                        m.timeSignature = tsCurrent
                        tsSet = True  # only set when changed
                    if not keySigSet and keySigCurrent is not None:
                        m.insert(0, keySigCurrent)
                        keySigSet = True  # only set when changed

                    o = 0.0  # start offsets at zero
                    previousChordInMeasure = None
                    pivotChordPossible = False
                    numberOfAtoms = len(t.atoms)
                    setKeyChangeToken = False  # first RomanNumeral object after a key change should have this set to True

                    for i, a in enumerate(t.atoms):
                        if isinstance(a, rtObjects.RTKey) or \
                           ((foundAKeySignatureSoFar == False) and \
                            (isinstance(a, rtObjects.RTAnalyticKey))):
                            # found a change of Key+KeySignature or
                            # just found a change of analysis but no keysignature so far

                            # environLocal.printDebug(['handling key token:', a])
                            try:  # this sets the key and the keysignature
                                kCurrent, pl = _getKeyAndPrefix(a)
                                prefixLyric += pl
                            except:
                                raise RomanTextTranslateException(
                                    'cannot get key from %s in line %s' %
                                    (a.src, t.src))
                            # insert at beginning of measure if at beginning -- for things like pickups.
                            if m.number < 2:
                                m._insertCore(0, kCurrent)
                            else:
                                m._insertCore(o, kCurrent)
                            foundAKeySignatureSoFar = True
                            setKeyChangeToken = True

                        elif isinstance(a, rtObjects.RTKeySignature):
                            try:  # this sets the keysignature but not the prefix text
                                thisSig = a.getKeySignature()
                            except:
                                raise RomanTextTranslateException(
                                    'cannot get key from %s in line %s' %
                                    (a.src, t.src))
                            #insert at beginning of measure if at beginning -- for things like pickups.
                            if m.number < 2:
                                m._insertCore(0, thisSig)
                            else:
                                m._insertCore(o, thisSig)
                            foundAKeySignatureSoFar = True

                        elif isinstance(a, rtObjects.RTAnalyticKey):
                            # just a change in analyzed key, not a change in anything else
                            #try: # this sets the key, not the keysignature
                            kCurrent, pl = _getKeyAndPrefix(a)
                            prefixLyric += pl
                            setKeyChangeToken = True

                            #except:
                            #    raise RomanTextTranslateException('cannot get key from %s in line %s' % (a.src, t.src))

                        elif isinstance(a, rtObjects.RTBeat):
                            # set new offset based on beat
                            try:
                                o = a.getOffset(tsCurrent)
                            except ValueError:
                                raise RomanTextTranslateException(
                                    "cannot properly get an offset from beat data %s under timeSignature %s in line %s"
                                    % (a.src, tsCurrent, t.src))
                            if (previousChordInMeasure is None
                                    and previousRn is not None and o > 0):
                                # setting a new beat before giving any chords
                                firstChord = copy.deepcopy(previousRn)
                                firstChord.quarterLength = o
                                firstChord.lyric = ""
                                if previousRn.tie == None:
                                    previousRn.tie = tie.Tie('start')
                                else:
                                    previousRn.tie.type = 'continue'
                                firstChord.tie = tie.Tie('stop')
                                previousRn = firstChord
                                previousChordInMeasure = firstChord
                                m._insertCore(0, firstChord)
                            pivotChordPossible = False

                        elif isinstance(a, rtObjects.RTNoChord):
                            # use source to evaluation roman
                            rn = note.Rest()
                            if pivotChordPossible == False:
                                # probably best to find duration
                                if previousChordInMeasure is None:
                                    pass  # use default duration
                                else:  # update duration of previous chord in Measure
                                    oPrevious = previousChordInMeasure.getOffsetBySite(
                                        m)
                                    newQL = o - oPrevious
                                    if newQL <= 0:
                                        raise RomanTextTranslateException(
                                            'too many notes in this measure: %s'
                                            % t.src)
                                    previousChordInMeasure.quarterLength = newQL
                                prefixLyric = ""
                                m._insertCore(o, rn)
                                previousChordInMeasure = rn
                                previousRn = rn
                                pivotChordPossible = False

                        elif isinstance(a, rtObjects.RTChord):
                            # use source to evaluation roman
                            try:
                                asrc = a.src
                                #                            if kCurrent.mode == 'minor':
                                #                                if asrc.lower().startswith('vi'): #vi or vii w/ or w/o o
                                #                                    if asrc.upper() == a.src: # VI or VII to bVI or bVII
                                #                                        asrc = 'b' + asrc
                                cacheTuple = (asrc,
                                              kCurrent.tonicPitchNameWithCase)
                                if USE_RN_CACHE and cacheTuple in rnKeyCache:
                                    #print "Got a match: " + str(cacheTuple)
                                    # Problems with Caches not picking up pivot chords... Not faster, see below.
                                    rn = copy.deepcopy(rnKeyCache[cacheTuple])
                                else:
                                    #print "No match for: " + str(cacheTuple)
                                    rn = roman.RomanNumeral(
                                        asrc, copy.deepcopy(kCurrent))
                                    rnKeyCache[cacheTuple] = rn
                                # surprisingly, not faster... and more dangerous
                                #rn = roman.RomanNumeral(asrc, kCurrent)
                                ## SLOWEST!!!
                                #rn = roman.RomanNumeral(asrc, kCurrent.tonicPitchNameWithCase)

                                #>>> from timeit import timeit as t
                                #>>> t('roman.RomanNumeral("IV", "c#")', 'from music21 import roman', number=1000)
                                #45.75
                                #>>> t('roman.RomanNumeral("IV", k)', 'from music21 import roman, key; k = key.Key("c#")', number=1000)
                                #16.09
                                #>>> t('roman.RomanNumeral("IV", copy.deepcopy(k))', 'from music21 import roman, key; import copy; k = key.Key("c#")', number=1000)
                                #22.49
                                ## key cache, does not help much...
                                #>>> t('copy.deepcopy(r)', 'from music21 import roman; import copy; r = roman.RomanNumeral("IV", "c#")', number=1000)
                                #19.01

                                if setKeyChangeToken is True:
                                    rn.followsKeyChange = True
                                    setKeyChangeToken = False
                                else:
                                    rn.followsKeyChange = False
                            except (roman.RomanNumeralException,
                                    common.Music21CommonException):
                                #environLocal.printDebug('cannot create RN from: %s' % a.src)
                                rn = note.Note()  # create placeholder

                            if pivotChordPossible == False:
                                # probably best to find duration
                                if previousChordInMeasure is None:
                                    pass  # use default duration
                                else:  # update duration of previous chord in Measure
                                    oPrevious = previousChordInMeasure.getOffsetBySite(
                                        m)
                                    newQL = o - oPrevious
                                    if newQL <= 0:
                                        raise RomanTextTranslateException(
                                            'too many notes in this measure: %s'
                                            % t.src)
                                    previousChordInMeasure.quarterLength = newQL

                                rn.addLyric(prefixLyric + a.src)
                                prefixLyric = ""
                                m._insertCore(o, rn)
                                previousChordInMeasure = rn
                                previousRn = rn
                                pivotChordPossible = True
                            else:
                                previousChordInMeasure.lyric += "//" + prefixLyric + a.src
                                previousChordInMeasure.pivotChord = rn
                                prefixLyric = ""
                                pivotChordPossible = False

                        elif isinstance(a, rtObjects.RTRepeat):
                            if o == 0:
                                if isinstance(a, rtObjects.RTRepeatStart):
                                    m.leftBarline = bar.Repeat(
                                        direction='start')
                                else:
                                    rtt = RomanTextUnprocessedToken(a)
                                    m._insertCore(o, rtt)
                            elif tsCurrent is not None and (
                                    tsCurrent.barDuration.quarterLength == o
                                    or i == numberOfAtoms - 1):
                                if isinstance(a, rtObjects.RTRepeatStop):
                                    m.rightBarline = bar.Repeat(
                                        direction='end')
                                else:
                                    rtt = RomanTextUnprocessedToken(a)
                                    m._insertCore(o, rtt)
                            else:  # mid measure repeat signs
                                rtt = RomanTextUnprocessedToken(a)
                                m._insertCore(o, rtt)

                        else:
                            rtt = RomanTextUnprocessedToken(a)
                            m._insertCore(o, rtt)
                            #environLocal.warn("Got an unknown token: %r" % a)

                    # may need to adjust duration of last chord added
                    if tsCurrent is not None:
                        previousRn.quarterLength = tsCurrent.barDuration.quarterLength - o
                    m.elementsChanged()
                    p._appendCore(m)

        except Exception:
            import traceback
            tracebackMessage = traceback.format_exc()
            raise RomanTextTranslateException(
                "At line %d for token %r, an exception was raised: \n%s" %
                (t.lineNumber, t, tracebackMessage))

    p.elementsChanged()
    fixPickupMeasure(p)
    p.makeBeams(inPlace=True)
    p.makeAccidentals(inPlace=True)
    _addRepeatsFromRepeatEndings(p, repeatEndings)  # 1st and second endings...
    s.insert(0, p)

    return s
Beispiel #43
0
    def parseInputToPrimitive(self, inpVal):
        '''
        Determines what format a given input is in and returns a value in that format..
        First checks if it is the name of a variable defined in the parsedDataDict or the
        name of an allowable function. In either of these cases, it will return the actual value
        of the data or the actual function.
        
        Next, it will check if the string is an int, float, boolean, or none, returning the appropriate value.
        If it is a quoted string then it will remove the quotes on the ends and return it as a string.
        If it has square braces indicating a list, the inner elements will be parsed using this same function recursively.
        (Note that recursive lists like [1, 2, [3, 4]] are not yet supported
        
        If the input corresponds to none of these types, it is returned as a string.
        
        
        >>> agenda = webapps.Agenda()
        >>> agenda.addData("a",2)
        >>> agenda.addData("b",[1,2,3],"list")

        >>> processor = webapps.CommandProcessor(agenda)
        >>> processor.parseInputToPrimitive("a")
        2
        >>> processor.parseInputToPrimitive("b")
        [1, 2, 3]
        >>> processor.parseInputToPrimitive("1.0")
        1.0
        >>> processor.parseInputToPrimitive("2")
        2
        >>> processor.parseInputToPrimitive("True")
        True
        >>> processor.parseInputToPrimitive("False")
        False
        >>> processor.parseInputToPrimitive("None") == None
        True
        >>> processor.parseInputToPrimitive("'hi'")
        'hi'
        >>> processor.parseInputToPrimitive("'Madam I\'m Adam'")
        "Madam I'm Adam"
        >>> processor.parseInputToPrimitive("[1,2,3]")
        [1, 2, 3]
        >>> processor.parseInputToPrimitive("[1,'hi',3.0,True, a, justAStr]")
        [1, 'hi', 3.0, True, 2, 'justAStr']
        '''
        returnVal = None

        if common.isNum(inpVal):
            return inpVal

        if common.isListLike(inpVal):
            return [self.parseInputToPrimitive(element) for element in inpVal]

        if not common.isStr(inpVal):
            self.recordError("Unknown type for parseInputToPrimitive " +
                             str(inpVal))

        strVal = inpVal

        strVal = strVal.strip()  # removes whitespace on ends

        if strVal in self.parsedDataDict:  # Used to specify data via variable name
            returnVal = self.parsedDataDict[strVal]
        elif strVal in availableFunctions:  # Used to specify function via variable name
            returnVal = strVal
        else:
            try:
                returnVal = int(strVal)
            except:
                try:
                    returnVal = float(strVal)
                except:
                    if strVal == "True":
                        returnVal = True

                    elif strVal == "None":
                        returnVal = None

                    elif strVal == "False":
                        returnVal = False

                    elif strVal[0] == '"' and strVal[
                            -1] == '"':  # Double Quoted String
                        returnVal = strVal[1:-1]  # remove quotes

                    elif strVal[0] == "'" and strVal[
                            -1] == "'":  # Single Quoted String
                        returnVal = strVal[1:-1]  # remove quotes

                    elif strVal[0] == "[" and strVal[-1] == "]":  # List
                        listElements = strVal[1:-1].split(
                            ",")  # remove [] and split by commas
                        returnVal = [
                            self.parseInputToPrimitive(element)
                            for element in listElements
                        ]
                    else:
                        returnVal = cgi.escape(str(strVal))
        return returnVal
Beispiel #44
0
    def _parseData(self):
        '''
        Parses data specified as strings in self.dataDict into objects in self.parsedDataDict
        '''
        for (name, dataDictElement) in self.dataDict.iteritems():
            if 'data' not in dataDictElement:
                self.addError("no data specified for data element " +
                              unicode(dataDictElement))
                continue

            dataStr = dataDictElement['data']

            if 'fmt' in dataDictElement:
                fmt = dataDictElement['fmt']

                if name in self.parsedDataDict:
                    self.addError("duplicate definition for data named " +
                                  str(name) + " " + str(dataDictElement))
                    continue
                if fmt not in availableDataFormats:
                    self.addError("invalid data format for data element " +
                                  str(dataDictElement))
                    continue

                if fmt == 'string' or fmt == 'str':
                    if dataStr.count("'") == 2:  # Single Quoted String
                        data = dataStr.replace("'", "")  # remove excess quotes
                    elif dataStr.count("\"") == 2:  # Double Quoted String
                        data = dataStr.replace("\"",
                                               "")  # remove excess quotes
                    else:
                        self.addError(
                            "invalid string (not in quotes...) for data element "
                            + str(dataDictElement))
                        continue
                elif fmt == 'int':
                    try:
                        data = int(dataStr)
                    except:
                        self.addError("invalid integer for data element " +
                                      str(dataDictElement))
                        continue
                elif fmt in ['bool', 'boolean']:
                    if dataStr in ['true', 'True']:
                        data = True
                    elif dataStr in ['false', 'False']:
                        data = False
                    else:
                        self.addError("invalid boolean for data element " +
                                      str(dataDictElement))
                        continue
                elif fmt == 'list':
                    # in this case dataStr should actually be an list object.
                    if not common.isListLike(dataStr):
                        self.addError(
                            "list format must actually be a list structure " +
                            str(dataDictElement))
                        continue
                    data = []
                    for elementStr in dataStr:
                        if common.isStr(elementStr):
                            (matchFound, dataElement
                             ) = self.parseStringToPrimitive(elementStr)
                            if not matchFound:
                                self.addError(
                                    "format could not be detected for data element  "
                                    + str(elementStr))
                                continue
                        else:
                            dataElement = elementStr
                        data.append(dataElement)
                else:
                    if fmt in ['xml', 'musicxml']:
                        if dataStr.find("<!DOCTYPE") == -1:
                            dataStr = """<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 1.1 Partwise//EN" "http://www.musicxml.org/dtds/partwise.dtd">""" + dataStr
                        if dataStr.find("<?xml") == -1:
                            dataStr = """<?xml version="1.0" encoding="UTF-8"?>""" + dataStr
                    try:
                        data = converter.parseData(dataStr)
                    except converter.ConverterException as e:
                        #self.addError("Error parsing data variable "+name+": "+str(e)+"\n\n"+dataStr)
                        self.addError(
                            "Error parsing data variable " + name + ": " +
                            unicode(e) + "\n\n" + dataStr, e)
                        continue
            else:  # No format specified
                (matchFound, data) = self.parseStringToPrimitive(dataStr)
                if not matchFound:
                    self.addError(
                        "format could not be detected for data element  " +
                        str(dataDictElement))
                    continue

            self.parsedDataDict[name] = data
Beispiel #45
0
def pitchToSharps(value, mode=None):
    '''Given a pitch or :class:`music21.pitch.Pitch` object, 
    return the number of sharps found in that mode.

    The `mode` parameter can be 'major', 'minor', or most
    of the common church/jazz modes ('dorian', 'mixolydian', etc.)
    including Locrian.
    
    If `mode` is omitted or not found, the default mode is major.

    (extra points to anyone who can find the earliest reference to
    the Locrian mode in print.  David Cohen and I (MSC) have been
    looking for this for years).

    >>> key.pitchToSharps('c')
    0
    >>> key.pitchToSharps('c', 'minor')
    -3
    >>> key.pitchToSharps('a', 'minor')
    0
    >>> key.pitchToSharps('d')
    2
    >>> key.pitchToSharps('e-')
    -3
    >>> key.pitchToSharps('a')
    3
    >>> key.pitchToSharps('e', 'minor')
    1
    >>> key.pitchToSharps('f#', 'major')
    6
    >>> key.pitchToSharps('g-', 'major')
    -6
    >>> key.pitchToSharps('c#')
    7
    >>> key.pitchToSharps('g#')
    8
    >>> key.pitchToSharps('e', 'dorian')
    2
    >>> key.pitchToSharps('d', 'dorian')
    0
    >>> key.pitchToSharps('g', 'mixolydian')
    0
    >>> key.pitchToSharps('e-', 'lydian')
    -2
    >>> key.pitchToSharps('e-', 'lydian')
    -2
    >>> key.pitchToSharps('a', 'phrygian')
    -1
    >>> key.pitchToSharps('e', 'phrygian')
    0
    >>> key.pitchToSharps('f#')
    6
    >>> key.pitchToSharps('f-')
    -8
    >>> key.pitchToSharps('f--')
    -15
    >>> key.pitchToSharps('f--', 'locrian')
    -20
    
    But quarter tones don't work:
    
    >>> key.pitchToSharps('C~')
    Traceback (most recent call last):
    KeyException: Cannot determine sharps for quarter-tone keys! silly!
    
    '''
    if common.isStr(value):
        value = pitch.Pitch(value)
    elif 'Pitch' in value.classes:
        value = value
    elif 'Note' in value.classes:
        value = value.pitch
    else:
        raise KeyException('Cannot get a sharp number from value')

    # the -1 is because we begin with F not C.
    sharps = fifthsOrder.index(value.step) - 1
    if value.accidental is not None:
        if value.accidental.isTwelveTone() is False:
            raise KeyException(
                'Cannot determine sharps for quarter-tone keys! silly!')
        vaa = int(value.accidental.alter)
        sharps = sharps + 7 * vaa

    if mode is not None and mode in modeSharpsAlter:
        sharps += modeSharpsAlter[mode]

    return sharps
Beispiel #46
0
    def search(self, query, field=None):
        r'''
        Search one or all fields with a query, given either as a string or a
        regular expression match.

        >>> md = metadata.Metadata()
        >>> md.composer = 'Beethoven, Ludwig van'
        >>> md.title = 'Third Symphony'

        >>> md.search(
        ...     'beethoven',
        ...     field='composer',
        ...     )
        (True, 'composer')

        Note how the incomplete field name in the following example is still
        matched:

        >>> md.search(
        ...     'beethoven',
        ...     field='compose',
        ...     )
        (True, 'composer')

        >>> md.search(
        ...     'frank',
        ...     field='composer',
        ...     )
        (False, None)

        >>> md.search('frank')
        (False, None)

        >>> md.search('third')
        (True, 'title')

        >>> md.search(
        ...     'third',
        ...     field='composer',
        ...     )
        (False, None)

        >>> md.search(
        ...     'third',
        ...     field='title',
        ...     )
        (True, 'title')

        >>> md.search('third|fourth')
        (True, 'title')

        >>> md.search('thove(.*)')
        (True, 'composer')

        '''
        valueFieldPairs = []
        if field is not None:
            match = False
            try:
                value = getattr(self, field)
                valueFieldPairs.append((value, field))
                match = True
            except AttributeError:
                pass
            if not match:
                for searchAttribute in self._searchAttributes:
                    #environLocal.printDebug(['comparing fields:', f, field])
                    # look for partial match in all fields
                    if field.lower() in searchAttribute.lower():
                        value = getattr(self, searchAttribute)
                        valueFieldPairs.append((value, searchAttribute))
                        match = True
                        break
            # if cannot find a match for any field, return
            if not match:
                return False, None
        else:  # get all fields
            for field in self._searchAttributes:
                value = getattr(self, field)
                valueFieldPairs.append((value, field))
        # for now, make all queries strings
        # ultimately, can look for regular expressions by checking for
        # .search
        useRegex = False
        if hasattr(query, 'search'):
            useRegex = True
            reQuery = query  # already compiled
        # look for regex characters
        elif common.isStr(query) and \
            any(character in query for character in '*.|+?{}'):
            useRegex = True
            reQuery = re.compile(query, flags=re.I)
        if useRegex:
            for value, field in valueFieldPairs:
                # re.I makes case insensitive
                if common.isStr(value):
                    match = reQuery.search(value)
                    if match is not None:
                        return True, field
        elif callable(query):
            for value, field in valueFieldPairs:
                if query(value):
                    return True, field
        else:
            for value, field in valueFieldPairs:
                if common.isStr(value):
                    query = str(query)
                    if query.lower() in value.lower():
                        return True, field
                elif query == value:
                    return True, field
        return False, None
Beispiel #47
0
    def getObjByClass(self,
                      className,
                      serialReverseSearch=True,
                      callerFirst=None,
                      sortByCreationTime=False,
                      prioritizeActiveSite=False,
                      priorityTarget=None,
                      getElementMethod='getElementAtOrBefore',
                      memo=None):
        '''
        Return the most recently added reference based on className.  Class
        name can be a string or the class name.

        This will recursively search the sitesDicts of objects in Site objects in 
        the siteDict.

        The `callerFirst` parameters is simply used to pass a reference of the
        first caller; this is necessary if we are looking within a Stream for a
        flat offset position.

        If `priorityTarget` is specified, this location will be searched first.
        The `prioritizeActiveSite` is pased to to any recursively called
        getContextByClass() calls.

        The `getElementMethod` is a string that selects which Stream method is
        used to get elements for searching with getElementsByClass() calls.

        ::

            >>> import music21
            >>> class Mock(music21.Music21Object):
            ...     pass
            ...
            >>> import time
            >>> aObj = Mock()
            >>> bObj = Mock()
            >>> aSites = music21.Sites()
            >>> aSites.add(aObj)
            >>> aSites.add(bObj)
            >>> # we get the most recently added object first
            >>> aSites.getObjByClass('Mock', sortByCreationTime=True) == bObj
            True
        
        ::

            >>> aSites.getObjByClass(Mock, sortByCreationTime=True) == bObj
            True

        OMIT_FROM_DOCS
        TODO: not sure if memo is properly working: need a test case
        '''
        #if DEBUG_CONTEXT: print 'Y: first call'
        # in general, this should not be the first caller, as this method
        # is called from a Music21Object, not directly on the Sites
        # instance. Nonetheless, if this is the first caller, it is the first
        # caller.
        if callerFirst is None:  # this is the first caller
            callerFirst = self  # set Sites as caller first
        if memo is None:
            memo = {}  # intialize
        post = None
        #count = 0

        # search any defined contexts first
        # need to sort: look at most-recently added objs are first
        objs = self.get(
            locationsTrail=False,
            sortByCreationTime=sortByCreationTime,
            priorityTarget=priorityTarget,
            excludeNone=True,
        )
        #printMemo(memo, 'getObjByClass() called: looking at %s sites' % len(objs))
        classNameIsStr = common.isStr(className)
        for obj in objs:
            #environLocal.printDebug(['memo', memo])
            if classNameIsStr:
                if className in obj.classes:
                    post = obj
                    break
            elif isinstance(obj, className):
                post = obj
                break
        if post is not None:
            return post

        # all objs here are containers, as they are all locations
        # if we could be sure that these objs do not have their own locations
        # and do not have the target class, we can skip
        for obj in objs:
            #if DEBUG_CONTEXT: print '\tY: getObjByClass: iterating objs:', id(obj), obj
            if (classNameIsStr and obj.isFlat):
                #if DEBUG_CONTEXT: print '\tY: skipping flat stream that does not contain object:', id(obj), obj
                #environLocal.printDebug(['\tY: skipping flat stream that does not contain object:'])
                if obj.sites.getSiteCount(
                ) == 0:  # is top level; no more to search...
                    if not obj.hasElementOfClass(className, forceFlat=True):
                        continue  # skip, not in this stream

            # if after trying to match name, look in the defined contexts'
            # defined contexts [sic!]
            #if post is None: # no match yet
            # access public method to recurse
            if id(obj) not in memo:
                # if the object is a Musci21Object
                #if hasattr(obj, 'getContextByClass'):
                # store this object as having been searched
                memo[id(obj)] = obj
                post = obj.getContextByClass(
                    className,
                    serialReverseSearch=serialReverseSearch,
                    callerFirst=callerFirst,
                    sortByCreationTime=sortByCreationTime,
                    prioritizeActiveSite=prioritizeActiveSite,
                    getElementMethod=getElementMethod,
                    memo=memo)
                if post is not None:
                    break


#                 else: # this is not a music21 object
#                     pass
#environLocal.printDebug['cannot call getContextByClass on obj stored in DefinedContext:', obj]
#             else: # objec has already been searched
#                 pass
#environLocal.printDebug['skipping searching of object already searched:', obj]
#             else: # post is not None
#                 break
        return post
Beispiel #48
0
    def getAllByClass(self, className, found=None, idFound=None, memo=None):
        '''
        Return all known references of a given class found in any association
        with this Sites object.

        This will recursively search the defined contexts of existing defined
        contexts, and return a list of all objects that match the given class.

        ::

            >>> import music21
            >>> class Mock(music21.Music21Object):
            ...    pass
            ...
            >>> class Mocker(music21.Music21Object):
            ...    pass
            ...
            >>> aObj = Mock()
            >>> bObj = Mock()
            >>> cObj = Mocker()
            >>> dc = music21.Sites()
            >>> dc.add(aObj)
            >>> dc.add(bObj)
            >>> dc.add(cObj)
            >>> dc.getAllByClass(Mock) == [aObj, bObj]
            True

        '''
        if memo is None:
            memo = {}  # intialize
        if found is None:
            found = []
        if idFound is None:
            idFound = []

        objs = self.get(locationsTrail=False)
        for obj in objs:
            #environLocal.printDebug(['memo', memo])
            if obj is None:
                continue  # in case the reference is dead
            if common.isStr(className):
                if type(obj).__name__.lower() == className.lower():
                    found.append(obj)
                    idFound.append(id(obj))
            elif isinstance(obj, className):
                found.append(obj)
                idFound.append(id(obj))
        for obj in objs:
            if obj is None:
                continue  # in case the reference is dead
            # if after trying to match name, look in the defined contexts'
            # defined contexts [sic!]
            if id(obj) not in memo:
                # if the object is a Musci21Object
                #if hasattr(obj, 'getContextByClass'):
                # store this object as having been searched
                memo[id(obj)] = obj
                # will add values to found
                #environLocal.printDebug(['getAllByClass()', 'about to call getAllContextsByClass', 'found', found, 'obj', obj])
                obj.getAllContextsByClass(className,
                                          found=found,
                                          idFound=idFound,
                                          memo=memo)
        # returning found, but not necessary
        return found
Beispiel #49
0
 def _setContent(self, value):
     if not common.isStr(value):
         self._content = str(value)
     else:
         self._content = value
Beispiel #50
0
def samplesFromRecording(seconds=10.0,
                         storeFile=True,
                         recordFormat=None,
                         recordChannels=recordChannels,
                         recordSampleRate=recordSampleRate,
                         recordChunkLength=1024):
    '''
    records `seconds` length of sound in the given format (default Wave)
    and optionally stores it to disk using the filename of `storeFile`
    
    
    Returns a list of samples.
    '''

    try:
        import pyaudio  #@UnresolvedImport
        recordFormatDefault = pyaudio.paInt16
    except (ImportError, SystemExit):
        pyaudio = None
        environLocal.warn(
            "No Pyaudio found. Recording will probably not work.")
        recordFormatDefault = 8  # pyaudio.paInt16

    if recordFormat is None:
        recordFormat = recordFormatDefault

    if recordFormat == pyaudio.paInt8:
        raise RecordingException(
            "cannot perform freq_from_autocorr on 8-bit samples")

    p_audio = pyaudio.PyAudio()
    st = p_audio.open(format=recordFormat,
                      channels=recordChannels,
                      rate=recordSampleRate,
                      input=True,
                      frames_per_buffer=recordChunkLength)

    recordingLength = int(recordSampleRate * float(seconds) /
                          recordChunkLength)

    storedWaveSampleList = []

    #time_start = time.time()
    for i in range(recordingLength):
        data = st.read(recordChunkLength)
        storedWaveSampleList.append(data)
    #print 'Time elapsed: %.3f s\n' % (time.time() - time_start)
    st.close()
    p_audio.terminate()

    if storeFile != False:
        if common.isStr(storeFile):
            waveFilename = storeFile
        else:
            waveFilename = environLocal.getRootTempDir(
            ) + os.path.sep + 'recordingTemp.wav'
        ### write recording to disk
        data = ''.join(storedWaveSampleList)
        try:
            wf = wave.open(waveFilename, 'wb')
            wf.setnchannels(recordChannels)
            wf.setsampwidth(p_audio.get_sample_size(recordFormat))
            wf.setframerate(recordSampleRate)
            wf.writeframes(data)
            wf.close()
        except IOError:
            raise RecordingException("Cannot open %s for writing." %
                                     waveFilename)
    return storedWaveSampleList