Пример #1
0
 def getKey(self):
     '''
     This returns a Key, not a KeySignature object
     '''
     myKey = self.src.rstrip(self.footerStrip)
     myKey = key.convertKeyStringToMusic21KeyString(myKey)
     return key.Key(myKey)
Пример #2
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
Пример #3
0
 def getKey(self):
     '''
     This returns a Key, not a KeySignature object
     '''
     myKey = self.src.rstrip(self.footerStrip)
     myKey = key.convertKeyStringToMusic21KeyString(myKey)
     return key.Key(myKey)
Пример #4
0
    def homeKeySig(self):
        '''
        gets the initial, or 'home', key signature by looking at the musictext and locating
        the key signature at the start of the S: rule.

        >>> s = romanText.clercqTemperley.CTSong(romanText.clercqTemperley.textString)
        >>> s.homeKeySig
        <music21.key.Key of A major>
        '''
        #look at 'S' Rule and grab the home key Signature
        if self.text and 'S:' in self.text:
            lines = self.text.split('\n')
            for line in lines:
                if line.startswith('S:'):
                    for atom in line.split()[1:3]:
                        if '[' not in atom:
                            self._homeKeySig = key.Key('C')
                            return self._homeKeySig
                        elif not '/' in atom:
                            m21keyStr = key.convertKeyStringToMusic21KeyString(atom[1:-1])
                            self._homeKeySig = key.Key(m21keyStr)
                            return self._homeKeySig
                        else:
                            pass
        return self._homeKeySig
Пример #5
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
def mixed_sequences(data_path, output_path):
    for (number, filename) in enumerate(os.listdir(data_path), start=1):
        try:
            full_path = os.path.join(data_path, filename)
            LOG.debug("Finding mixed sequences in piece {number}: {filename}.".format(**locals()))
            piece = parse(full_path)
            temp_abspath = os.path.join(output_path, TEMP_MIDI_NAME)
            piece.write('midi', temp_abspath)
            chord_per_measure = temperley.chord_per_measure(piece, temp_abspath)
            keys = temperley.key_sequence(temp_abspath)
            if len(set(keys)) > 1:
                continue  # more than one key in piece is complicated...
            else:
                key_string = convertKeyStringToMusic21KeyString(keys[0].replace('b','-'))
                key = Key()
                key_pitch = key.getPitches()[0]
            instrument = lambda x: x.getInstrument().instrumentName.lower()
            guitar_parts = (e for e in piece if isinstance (e, Part) and \
                                             ('guitar' in instrument(e) or \
                                             'gtr' in instrument(e)) and not \
                                             'bass' in instrument(e))
            for part in guitar_parts:
                current_sequence = None
                last_note = None
                measures = [elem for elem in part if isinstance(elem, Measure)]
                if len(chord_per_measure) != len(measures):
                    continue
                for chord, measure in zip(chord_per_measure, measures):
                    chord_pitch = music21.pitch.Pitch(convertKeyStringToMusic21KeyString(chord))
                    for element in measure:
                        if isinstance(element, Note):
                            if not last_note:
                                current_sequence = [(0, 0, notesToChromatic(key_pitch, element).semitones, key.mode, notesToChromatic(key_pitch, chord_pitch).semitones)]
                            else:
                                interval = notesToChromatic(last_note, element)
                                entry = (current_sequence[-1][1], interval.semitones, notesToChromatic(key_pitch, element).semitones, key.mode, notesToChromatic(key_pitch, chord_pitch).semitones)
                                current_sequence.append(entry)
                            last_note = element
                        elif isinstance(element, Rest) and element.quarterLength < 4:
                            pass
                        elif current_sequence:
                            yield current_sequence
                            current_sequence = None
                            last_note = None
        except Exception:
            LOG.warning('Encountered exception in {filename}'.format(**locals()))
Пример #7
0
 def _getHomeKeySig(self):
     #look at 'S' Rule and grab the home key Signature
     if self.text and 'S:' in self.text:
         lines = self.text.split('\n')
         for line in lines:
             if line.startswith('S:'):
                 for atom in line.split()[1:3]:
                     if '[' not in atom:
                         self._homeKeySig = key.Key('C')
                         return self._homeKeySig
                     elif not '/' in atom:
                         m21keyStr = key.convertKeyStringToMusic21KeyString(atom[1:-1])
                         self._homeKeySig = key.Key(m21keyStr)
                         return self._homeKeySig
                     else:
                         pass
     return self._homeKeySig
Пример #8
0
 def _getHomeKeySig(self):
     #look at 'S' Rule and grab the home key Signature
     if self.text and 'S:' in self.text:
         lines = self.text.split('\n')
         for line in lines:
             if line.startswith('S:'):
                 for atom in line.split()[1:3]:
                     if '[' not in atom:
                         self._homeKeySig = key.Key('C')
                         return self._homeKeySig
                     elif not '/' in atom:
                         m21keyStr = key.convertKeyStringToMusic21KeyString(
                             atom[1:-1])
                         self._homeKeySig = key.Key(m21keyStr)
                         return self._homeKeySig
                     else:
                         pass
     return self._homeKeySig
Пример #9
0
    def expand(self, ts=None, ks=None):
        '''
        The meat of it all -- expand one rule completely and return a list of Measure objects.
        '''
        if ts is None:
            ts = meter.TimeSignature('4/4')
        if ks is None:
            ks = key.Key('C')
        measures = []

        lastRegularAtom = None
        lastChord = None

        for content, sep, numReps in self._measureGroups():
            lastChordIsInSameMeasure = False
            if sep == "$":
                if content not in self.parent.rules:
                    raise CTRuleException(
                        "Cannot expand rule {0} in {2}".format(content, self))
                rule = self.parent.rules[content]
                for i in range(numReps):
                    returnedMeasures = rule.expand(ts, ks)
                    self.insertKsTs(returnedMeasures[0], ts, ks)
                    for m in returnedMeasures:
                        tsEs = m.iter.getElementsByClass('TimeSignature')
                        for returnedTs in tsEs:
                            if returnedTs is not ts:
                                # the TS changed mid-rule; create a new one for return.
                                ts = copy.deepcopy(ts)

                    measures.extend(returnedMeasures)
            elif sep == "|":
                m = stream.Measure()
                atoms = content.split()
                # key/timeSig pass...
                regularAtoms = []
                for atom in atoms:
                    if atom.startswith('['):
                        atomContent = atom[1:-1]
                        if atomContent == '0':
                            ts = meter.TimeSignature('4/4')
                            # irregular meter.  Cannot fully represent;
                            #TODO: replace w/ senza misura when possible.

                        elif '/' in atomContent:  # only one key / ts per measure.
                            ts = meter.TimeSignature(atomContent)
                        else:
                            ks = key.Key(
                                key.convertKeyStringToMusic21KeyString(
                                    atomContent))

                    elif atom == '.':
                        if lastRegularAtom is None:
                            raise CTRuleException(" . w/o previous atom: %s" %
                                                  self)
                        regularAtoms.append(lastRegularAtom)
                    elif atom in ("", None):
                        pass
                    else:
                        regularAtoms.append(atom)
                        lastRegularAtom = atom
                numAtoms = len(regularAtoms)
                if numAtoms == 0:
                    continue  # maybe just ts and ks setting

                self.insertKsTs(m, ts, ks)

                atomLength = common.opFrac(ts.barDuration.quarterLength /
                                           numAtoms)
                for atom in regularAtoms:
                    if atom == 'R':
                        rest = note.Rest(quarterLength=atomLength)
                        lastChord = None
                        lastChordIsInSameMeasure = False
                        m.append(rest)
                    else:
                        atom = self.fixupChordAtom(atom)
                        rn = roman.RomanNumeral(atom, ks)
                        if self.isSame(rn,
                                       lastChord) and lastChordIsInSameMeasure:
                            lastChord.duration.quarterLength += atomLength
                            m.elementsChanged()
                        else:
                            rn.duration.quarterLength = atomLength
                            self.addOptionalTieAndLyrics(rn, lastChord)
                            lastChord = rn
                            lastChordIsInSameMeasure = True
                            m.append(rn)
                measures.append(m)
                for i in range(1, numReps):
                    measures.append(copy.deepcopy(m))
            else:
                environLocal.warn(
                    "Rule found without | or $, ignoring: '{0}','{1}': in {2}".
                    format(content, sep, self.text))
                #pass
        if len(measures) > 0:
            for m in measures:
                noteIter = m.recurse().notes
                if (noteIter
                        and (self.parent is None
                             or self.parent.labelSubsectionsOnScore is True)
                        and self.LHS != 'S'):
                    rn = noteIter[0]
                    lyricNum = len(rn.lyrics) + 1
                    rn.lyrics.append(note.Lyric(self.LHS, number=lyricNum))
                    break

        return measures
Пример #10
0
    def expand(self, ts=None, ks=None):
        '''
        The meat of it all -- expand one rule completely and return a list of Measure objects.
        '''
        if ts is None:
            ts = meter.TimeSignature('4/4')
        if ks is None:
            ks = key.Key('C')
        measures = []

        lastRegularAtom = None
        lastChord = None
        
        for content, sep, numReps in self._measureGroups():
            lastChordIsInSameMeasure = False
            if sep == "$":
                if content not in self.parent.rules:
                    raise CTRuleException("Cannot expand rule {0} in {2}".format(content, self))
                rule = self.parent.rules[content]
                for i in range(numReps):
                    returnedMeasures = rule.expand(ts, ks)
                    self.insertKsTs(returnedMeasures[0], ts, ks)
                    for m in returnedMeasures:
                        tsEs = m.getElementsByClass('TimeSignature', returnStreamSubClass='list')
                        for returnedTs in tsEs:
                            if returnedTs is not ts:
                                ts = copy.deepcopy(ts) # the TS changed mid-rule; create a new one for return.
                    
                    measures.extend(returnedMeasures)
            elif sep == "|":
                m = stream.Measure()
                atoms = content.split()
                # key/timeSig pass...
                regularAtoms = []
                for atom in atoms:
                    if atom.startswith('['):
                        atomContent = atom[1:-1]
                        if atomContent == '0':
                            ts = meter.TimeSignature('4/4') # irregular meter.  Cannot fully represent; 
                            #TODO: replace w/ senza misura when possible. 
                                                        
                        elif '/' in atomContent: # only one key / ts per measure.
                            ts = meter.TimeSignature(atomContent)
                        else:
                            ks = key.Key(key.convertKeyStringToMusic21KeyString(atomContent))
                            
                    elif atom == '.':
                        if lastRegularAtom is None:
                            raise CTRuleException(" . w/o previous atom: %s" % self)
                        regularAtoms.append(lastRegularAtom)
                    elif atom in ("", None):
                        pass
                    else:
                        regularAtoms.append(atom)
                        lastRegularAtom = atom
                numAtoms = len(regularAtoms)
                if numAtoms == 0:
                    continue # maybe just ts and ks setting

                self.insertKsTs(m, ts, ks)
                
                atomLength = common.opFrac(ts.barDuration.quarterLength / numAtoms)            
                for atom in regularAtoms:
                    if atom == 'R':
                        rest = note.Rest(quarterLength=atomLength)
                        lastChord = None
                        lastChordIsInSameMeasure = False
                        m.append(rest)
                    else:
                        atom = self.fixupChordAtom(atom)
                        rn = roman.RomanNumeral(atom, ks)
                        if self.isSame(rn, lastChord) and lastChordIsInSameMeasure:
                            lastChord.duration.quarterLength += atomLength
                            m.elementsChanged()
                        else:
                            rn.duration.quarterLength = atomLength
                            self.addOptionalTieAndLyrics(rn, lastChord)
                            lastChord = rn
                            lastChordIsInSameMeasure = True
                            m.append(rn)
                measures.append(m)
                for i in range(1, numReps):
                    measures.append(copy.deepcopy(m))
            else:    
                environLocal.warn("Rule found without | or $, ignoring: '{0}','{1}': in {2}".format(
                                                                        content, sep, self.text))
                #pass
        if len(measures) > 0:
            for m in measures:
                noteIter = m.recurse().notes
                if noteIter and (self.parent is None or self.parent.labelSubsectionsOnScore is True) and self.LHS != 'S':
                    rn = noteIter[0]
                    lyricNum = len(rn.lyrics) + 1
                    rn.lyrics.append(note.Lyric(self.LHS, number=lyricNum))       
                    break                 
                
        return measures
Пример #11
0
def mixed_sequences(data_path, output_path):
    for (number, filename) in enumerate(os.listdir(data_path), start=1):
        try:
            full_path = os.path.join(data_path, filename)
            LOG.debug("Finding mixed sequences in piece {number}: {filename}.".
                      format(**locals()))
            piece = parse(full_path)
            temp_abspath = os.path.join(output_path, TEMP_MIDI_NAME)
            piece.write('midi', temp_abspath)
            chord_per_measure = temperley.chord_per_measure(
                piece, temp_abspath)
            keys = temperley.key_sequence(temp_abspath)
            if len(set(keys)) > 1:
                continue  # more than one key in piece is complicated...
            else:
                key_string = convertKeyStringToMusic21KeyString(
                    keys[0].replace('b', '-'))
                key = Key()
                key_pitch = key.getPitches()[0]
            instrument = lambda x: x.getInstrument().instrumentName.lower()
            guitar_parts = (e for e in piece if isinstance (e, Part) and \
                                             ('guitar' in instrument(e) or \
                                             'gtr' in instrument(e)) and not \
                                             'bass' in instrument(e))
            for part in guitar_parts:
                current_sequence = None
                last_note = None
                measures = [elem for elem in part if isinstance(elem, Measure)]
                if len(chord_per_measure) != len(measures):
                    continue
                for chord, measure in zip(chord_per_measure, measures):
                    chord_pitch = music21.pitch.Pitch(
                        convertKeyStringToMusic21KeyString(chord))
                    for element in measure:
                        if isinstance(element, Note):
                            if not last_note:
                                current_sequence = [
                                    (0, 0, notesToChromatic(
                                        key_pitch,
                                        element).semitones, key.mode,
                                     notesToChromatic(key_pitch,
                                                      chord_pitch).semitones)
                                ]
                            else:
                                interval = notesToChromatic(last_note, element)
                                entry = (current_sequence[-1][1],
                                         interval.semitones,
                                         notesToChromatic(key_pitch,
                                                          element).semitones,
                                         key.mode,
                                         notesToChromatic(
                                             key_pitch, chord_pitch).semitones)
                                current_sequence.append(entry)
                            last_note = element
                        elif isinstance(element,
                                        Rest) and element.quarterLength < 4:
                            pass
                        elif current_sequence:
                            yield current_sequence
                            current_sequence = None
                            last_note = None
        except Exception:
            LOG.warning(
                'Encountered exception in {filename}'.format(**locals()))
Пример #12
0
  def testExtractionOfKeySignatureAttributes(self):
    """Check the key, mode, tonic pitch class extraction from key signature."""
    num_to_major_key = {0: 'C',
                        1: 'G',
                        2: 'D',
                        3: 'A',
                        4: 'E',
                        5: 'B',
                        6: 'F#',
                        7: 'C#',
                        8: 'G#',
                        9: 'D#',
                        10: 'A#',
                        11: 'E#',
                        12: 'B#',
                        -2: 'Bb',
                        -12: 'Dbb',
                        -11: 'Abb',
                        -10: 'Ebb',
                        -9: 'Bbb',
                        -8: 'Fb',
                        -7: 'Cb',
                        -6: 'Gb',
                        -5: 'Db',
                        -4: 'Ab',
                        -3: 'Eb',
                        -1: 'F'}
    num_to_minor_key = {0: 'a',
                        1: 'e',
                        2: 'b',
                        3: 'f#',
                        4: 'c#',
                        5: 'g#',
                        6: 'd#',
                        7: 'a#',
                        8: 'e#',
                        9: 'b#',
                        10: 'f##',
                        11: 'c##',
                        12: 'g##',
                        -2: 'g',
                        -12: 'bbb',
                        -11: 'fb',
                        -10: 'cb',
                        -9: 'gb',
                        -8: 'db',
                        -7: 'ab',
                        -6: 'eb',
                        -5: 'bb',
                        -4: 'f',
                        -3: 'c',
                        -1: 'd'}

    for test_mode in ['major', 'minor']:
      for i in range(-12, 13):
        ks = key.KeySignature(i)
        ks.mode = test_mode
        if test_mode == 'major':
          key_map = num_to_major_key
        else:
          key_map = num_to_minor_key
        try:
          key_name, num_sharps, mode, tonic_pitchclass = (
              pretty_music21._extract_key_signature_attributes(ks))
        except pretty_music21.PrettyMusic21Error:
          self.assertTrue(i < 7 or i > 7)
          continue
        self.assertEqual(key_name, key_map[i])
        if mode == 'minor':
          self.assertEqual(
              key.sharpsToPitch(num_sharps + 3).name,
              key.convertKeyStringToMusic21KeyString(key_name).upper())
        else:
          self.assertEqual(
              key.sharpsToPitch(num_sharps).name,
              key.convertKeyStringToMusic21KeyString(key_name).upper())

        self.assertEqual(mode, ks.mode)
        check_pitch = pitch.Pitch(
            key.convertKeyStringToMusic21KeyString(key_map[i]))
        check_pitchclass = check_pitch.pitchClass
        self.assertEqual(tonic_pitchclass, check_pitchclass)
Пример #13
0
    def testExtractionOfKeySignatureAttributes(self):
        """Check the key, mode, tonic pitch class extraction from key signature."""
        num_to_major_key = {
            0: 'C',
            1: 'G',
            2: 'D',
            3: 'A',
            4: 'E',
            5: 'B',
            6: 'F#',
            7: 'C#',
            8: 'G#',
            9: 'D#',
            10: 'A#',
            11: 'E#',
            12: 'B#',
            -2: 'Bb',
            -12: 'Dbb',
            -11: 'Abb',
            -10: 'Ebb',
            -9: 'Bbb',
            -8: 'Fb',
            -7: 'Cb',
            -6: 'Gb',
            -5: 'Db',
            -4: 'Ab',
            -3: 'Eb',
            -1: 'F'
        }
        num_to_minor_key = {
            0: 'a',
            1: 'e',
            2: 'b',
            3: 'f#',
            4: 'c#',
            5: 'g#',
            6: 'd#',
            7: 'a#',
            8: 'e#',
            9: 'b#',
            10: 'f##',
            11: 'c##',
            12: 'g##',
            -2: 'g',
            -12: 'bbb',
            -11: 'fb',
            -10: 'cb',
            -9: 'gb',
            -8: 'db',
            -7: 'ab',
            -6: 'eb',
            -5: 'bb',
            -4: 'f',
            -3: 'c',
            -1: 'd'
        }

        for test_mode in ['major', 'minor']:
            for i in range(-12, 13):
                ks = key.KeySignature(i)
                ks.mode = test_mode
                if test_mode == 'major':
                    key_map = num_to_major_key
                else:
                    key_map = num_to_minor_key
                try:
                    key_name, num_sharps, mode, tonic_pitchclass = (
                        pretty_music21._extract_key_signature_attributes(ks))
                except pretty_music21.PrettyMusic21Error:
                    self.assertTrue(i < 7 or i > 7)
                    continue
                self.assertEqual(key_name, key_map[i])
                if mode == 'minor':
                    self.assertEqual(
                        key.sharpsToPitch(num_sharps + 3).name,
                        key.convertKeyStringToMusic21KeyString(
                            key_name).upper())
                else:
                    self.assertEqual(
                        key.sharpsToPitch(num_sharps).name,
                        key.convertKeyStringToMusic21KeyString(
                            key_name).upper())

                self.assertEqual(mode, ks.mode)
                check_pitch = pitch.Pitch(
                    key.convertKeyStringToMusic21KeyString(key_map[i]))
                check_pitchclass = check_pitch.pitchClass
                self.assertEqual(tonic_pitchclass, check_pitchclass)