예제 #1
0
    def addLabelAbbrToken(self, tok: str, timestamp: HumNumIn,
                          part: int, staff: int, voice: int,
                          maxPart: int) -> GridSlice:
        ts: HumNum = opFrac(timestamp)
        gs: GridSlice

        if not self.slices or self.slices[-1].timestamp < ts:
            # add a new GridSlice to an empty list or at end of list if timestamp
            # is after last entry in list.
            gs = GridSlice(self, ts, SliceType.LabelAbbrs, maxPart)
            gs.addToken(tok, part, staff, voice)
            self.slices.append(gs)
            return gs

        # search for existing line with same timestamp and the same slice type
        for gridSlice in self.slices:
            if gridSlice.timestamp == ts and gridSlice.isLabelAbbrSlice:
                gridSlice.addToken(tok, part, staff, voice)
                gs = gridSlice
                return gs

        # Couldn't find a place for the label abbr, so place at beginning of measure
        gs = GridSlice(self, ts, SliceType.LabelAbbrs, maxPart)
        gs.addToken(tok, part, staff, voice)
        self.slices.insert(0, gs)
        return gs
예제 #2
0
    def addLayoutParameter(self, associatedSlice: GridSlice,
                           partIndex: int, staffIndex: int, voiceIndex: int,
                           locomment: str) -> None:
        # add this '!LO:' string just before this associatedSlice
        if len(self.slices) == 0:
            # something strange happened: expecting at least one item in measure.
            # associatedSlice is supposed to already be in the measure.
            return

        associatedSliceIdx: t.Optional[int] = None
        if associatedSlice is None:
            # place at end of measure (associate with imaginary slice just off the end)
            associatedSliceIdx = len(self.slices)
        else:
            # find owning line (associatedSlice)
            foundIt: bool = False
            for associatedSliceIdx in range(len(self.slices) - 1, -1, -1):
                gridSlice: GridSlice = self.slices[associatedSliceIdx]
                if gridSlice is associatedSlice:
                    foundIt = True
                    break
            if not foundIt:
                # cannot find owning line (a.k.a. associatedSlice is not in this GridMeasure)
                return

        # see if the previous slice is a layout slice we can use
        prevIdx: int = associatedSliceIdx - 1
        prevSlice: GridSlice = self.slices[prevIdx]
        if prevSlice.isLocalLayoutSlice:
            prevStaff: GridStaff = prevSlice.parts[partIndex].staves[staffIndex]
            prevVoice: GridVoice = self._getIndexedVoice_AppendingIfNecessary(prevStaff.voices,
                                                                              voiceIndex)
            if prevVoice.token is None or prevVoice.token.text == '!':
                prevVoice.token = HumdrumToken(locomment)
                return

        # if we get here, we couldn't use the previous slice, so we need to insert
        # a new Layout slice to use, just before the associated slice.
        insertPoint: int = associatedSliceIdx
        newSlice: GridSlice

        if associatedSlice is not None:
            newSlice = GridSlice(self, associatedSlice.timestamp, SliceType.Layouts)
            newSlice.initializeBySlice(associatedSlice)
            self.slices.insert(insertPoint, newSlice)
        else:
            newSlice = GridSlice(self, self.timestamp + self.duration, SliceType.Layouts)
            newSlice.initializeBySlice(self.slices[-1])
            self.slices.append(newSlice)

        newStaff: GridStaff = newSlice.parts[partIndex].staves[staffIndex]
        newVoice: GridVoice = self._getIndexedVoice_AppendingIfNecessary(newStaff.voices,
                                                                         voiceIndex)
        newVoice.token = HumdrumToken(locomment)
예제 #3
0
    def addVerseLabels(self, associatedSlice: GridSlice,
                            partIndex: int, staffIndex: int,
                            verseLabels: t.List[t.Optional[HumdrumToken]]) -> None:
        # add these verse labels just before this associatedSlice
        if len(self.slices) == 0:
            # something strange happened: expecting at least one item in measure.
            # associatedSlice is supposed to already be in the measure.
            return

        associatedSliceIdx: t.Optional[int] = None
        if associatedSlice is None:
            # place at end of measure (associate with imaginary slice just off the end)
            associatedSliceIdx = len(self.slices)
        else:
            # find owning line (associatedSlice)
            foundIt: bool = False
            for associatedSliceIdx in range(len(self.slices) - 1, -1, -1):
                gridSlice: GridSlice = self.slices[associatedSliceIdx]
                if gridSlice is associatedSlice:
                    foundIt = True
                    break
            if not foundIt:
                # cannot find owning line (a.k.a. associatedSlice is not in this GridMeasure)
                return

        # see if the previous slice is a VerseLabels slice we can use
        prevIdx: int = associatedSliceIdx - 1
        prevSlice: GridSlice = self.slices[prevIdx]
        if prevSlice.isVerseLabelSlice:
            prevStaff: GridStaff = prevSlice.parts[partIndex].staves[staffIndex]
            if prevStaff.sides.verseCount == 0:
                for i, verseLabel in enumerate(verseLabels):
                    if verseLabel is not None:
                        prevStaff.sides.setVerse(i, verseLabel)
                return

        # if we get here, we couldn't use the previous slice, so we need to insert
        # a new Layout slice to use, just before the associated slice.
        insertPoint: int = associatedSliceIdx
        newSlice: GridSlice

        if associatedSlice is not None:
            newSlice = GridSlice(self, associatedSlice.timestamp, SliceType.VerseLabels)
            newSlice.initializeBySlice(associatedSlice)
            self.slices.insert(insertPoint, newSlice)
        else:
            newSlice = GridSlice(self, self.timestamp + self.duration, SliceType.VerseLabels)
            newSlice.initializeBySlice(self.slices[-1])
            self.slices.append(newSlice)

        newStaff: GridStaff = newSlice.parts[partIndex].staves[staffIndex]
        for i, verseLabel in enumerate(verseLabels):
            if verseLabel is not None:
                newStaff.sides.setVerse(i, verseLabel)
예제 #4
0
    def addDynamicsLayoutParameters(self, associatedSlice: GridSlice,
                                    partIndex: int, staffIndex: int,
                                    locomment: str):
        if len(self.slices) == 0:
            # something strange happened: expecting at least one item in measure.
            return  # associatedSlice is supposed to already be in the measure

        # find owning line (associatedSlice)
        foundIt: bool = False
        associatedSliceIdx: int = None
        for associatedSliceIdx in range(len(self.slices) - 1, -1,
                                        -1):  # loop in reverse index order
            gridSlice: GridSlice = self.slices[associatedSliceIdx]
            if gridSlice is associatedSlice:
                foundIt = True
                break
        if not foundIt:
            # cannot find owning line (a.k.a. associatedSlice is not in this GridMeasure)
            return

        # see if the previous slice is a layout slice we can use
        prevIdx: int = associatedSliceIdx - 1
        prevSlice: GridSlice = self.slices[prevIdx]
        if prevSlice.isLocalLayoutSlice:
            prevStaff: GridStaff = prevSlice.parts[partIndex].staves[
                staffIndex]
            if prevStaff.dynamics is None:
                prevStaff.dynamics = HumdrumToken(locomment)
                return

        # if we get here, we couldn't use the previous slice, so we need to insert
        # a new Layout slice to use, just before the associated slice.
        insertPoint: int = associatedSliceIdx
        newSlice: GridSlice = GridSlice(self, associatedSlice.timestamp,
                                        SliceType.Layouts)
        newSlice.initializeBySlice(associatedSlice)
        self.slices.insert(insertPoint, newSlice)

        newStaff: GridStaff = newSlice.parts[partIndex].staves[staffIndex]
        newStaff.dynamics = HumdrumToken(locomment)
예제 #5
0
    def addGraceToken(self, tok: str, timestamp: HumNum, part: int, staff: int,
                      voice: int, maxStaff: int,
                      graceNumber: int) -> GridSlice:
        if graceNumber < 1:
            raise HumdrumInternalError(
                'ERROR: graceNumber {} has to be larger than 0')

        gs: GridSlice = None
        if not self.slices:
            # add a new GridSlice to an empty list.
            gs = GridSlice(self, timestamp, SliceType.GraceNotes, maxStaff)
            gs.addToken(tok, part, staff, voice)
            self.slices.append(gs)
            return gs

        if timestamp > self.slices[-1].timestamp:
            # Grace note needs to be added at the end of a measure.
            idx: int = len(self.slices) - 1  # pointing at last slice
            counter: int = 0
            while idx >= 0:
                if self.slices[idx].isGraceSlice:
                    counter += 1
                    if counter == graceNumber:
                        # insert grace note into this slice
                        self.slices[idx].addToken(tok, part, staff, voice)
                        return self.slices[idx]
                elif self.slices[idx].isLocalLayoutSlice:
                    # skip over any layout parameter lines
                    idx -= 1
                    continue

                if self.slices[idx].isDataSlice:
                    # insert grace note after this note
                    gs = GridSlice(self, timestamp, SliceType.GraceNotes,
                                   maxStaff)
                    gs.addToken(tok, part, staff, voice)
                    self.slices.insert(idx + 1, gs)
                    return gs

                idx -= 1

            return None  # couldn't find anywhere to insert

        # search for existing line with same timestamp on a data slice:
        foundIndex: int = -1
        for idx, gridSlice in enumerate(self.slices):
            if timestamp < gridSlice.timestamp:
                raise HumdrumInternalError(
                    f'''STRANGE CASE 2 IN GRIDMEASURE::ADDGRACETOKEN
\tGRACE TIMESTAMP: {timestamp}
\tTEST  TIMESTAMP: {gridSlice.timestamp}''')

            if gridSlice.isDataSlice:
                if gridSlice.timestamp == timestamp:
                    foundIndex = idx
                    break

        idx: int = foundIndex - 1
        counter: int = 0
        while idx >= 0:
            if self.slices[idx].isGraceSlice:
                counter += 1
                if counter == graceNumber:
                    # insert grace note into this slice
                    self.slices[idx].addToken(tok, part, staff, voice)
                    return self.slices[idx]
            elif self.slices[idx].isLocalLayoutSlice:
                # skip over any layout parameter lines
                idx -= 1
                continue

            if self.slices[idx].isDataSlice:
                # insert grace note after this note
                gs = GridSlice(self, timestamp, SliceType.GraceNotes, maxStaff)
                gs.addToken(tok, part, staff, voice)
                self.slices.insert(idx + 1, gs)
                return gs

            idx -= 1

        # grace note should be added at start of measure
        gs = GridSlice(self, timestamp, SliceType.GraceNotes, maxStaff)
        gs.addToken(tok, part, staff, voice)
        self.slices.insert(0, gs)
        return gs
예제 #6
0
 def appendGlobalLayout(self, tok: str, timestamp: HumNum) -> GridSlice:
     gs: GridSlice = GridSlice(self, timestamp, SliceType.GlobalLayouts, 1)
     gs.addToken(tok, 0, 0, 0)
     gs.duration = HumNum(0)
     self.slices.append(gs)
     return gs
예제 #7
0
    def addGlobalComment(self, tok: str, timestamp: HumNum) -> GridSlice:
        gs: GridSlice = None
        if not self.slices or self.slices[-1].timestamp < timestamp:
            # add a new GridSlice to an empty list or at end of list if timestamp
            # is after last entry in list.
            gs = GridSlice(self, timestamp, SliceType.GlobalComments, 1)
            gs.addToken(tok, 0, 0, 0)
            self.slices.append(gs)
            return gs

        # search for existing data line (of any type) with the same timestamp
        for idx, gridSlice in enumerate(self.slices):
            # does it need to be before data slice or any slice?
            # if (((*iterator)->getTimestamp() == timestamp) && (*iterator)->isDataSlice())
            if gridSlice.timestamp == timestamp:
                # found the correct timestamp on a slice, so add the global comment
                # before the slice.  But don't add if the slice we found is a
                # global comment with the same text.
                if gridSlice.isGlobalComment:
                    if tok == gridSlice.parts[0].staves[0].voices[
                            0].token.text:
                        # do not insert duplicate global comments
                        gs = gridSlice
                        return gs

                gs = GridSlice(self, timestamp, SliceType.GlobalComments, 1)
                gs.addToken(tok, 0, 0, 0)
                self.slices.insert(idx, gs)
                return gs

            if gridSlice.timestamp > timestamp:
                # insert before this slice
                gs = GridSlice(self, timestamp, SliceType.GlobalComments, 1)
                gs.addToken(tok, 0, 0, 0)
                self.slices.insert(idx, gs)
                return gs

        return None  # I think we should put it at the beginning in this case --gregc
예제 #8
0
    def addTokenOfSliceType(self, tok: str, timestamp: HumNum,
                            sliceType: SliceType, part: int, staff: int,
                            voice: int, maxStaff: int) -> GridSlice:
        gs: GridSlice = None
        if not self.slices or self.slices[-1].timestamp < timestamp:
            # add a new GridSlice to an empty list or at end of list if timestamp
            # is after last entry in list.
            gs = GridSlice(self, timestamp, sliceType, maxStaff)
            gs.addToken(tok, part, staff, voice)
            self.slices.append(gs)
            return gs

        # search for existing line with same timestamp and the same slice type
        for idx, gridSlice in enumerate(self.slices):
            if gridSlice.timestamp == timestamp and gridSlice.sliceType == sliceType:
                gridSlice.addToken(tok, part, staff, voice)
                gs = gridSlice
                return gs

            if gridSlice.timestamp == timestamp and gridSlice.isDataSlice:
                # found the correct timestamp, but no slice of the right type at the
                # timestamp, so add the new slice before the data slice (eventually
                # keeping track of the order in which the other non-data slices should
                # be placed).
                gs = GridSlice(self, timestamp, sliceType, maxStaff)
                gs.addToken(tok, part, staff, voice)
                self.slices.insert(idx, gs)
                return gs

            if gridSlice.timestamp > timestamp:
                gs = GridSlice(self, timestamp, sliceType, maxStaff)
                gs.addToken(tok, part, staff, voice)
                self.slices.insert(idx, gs)
                return gs

        # Couldn't find a place for the token, so place at end of measure
        gs = GridSlice(self, timestamp, sliceType, maxStaff)
        gs.addToken(tok, part, staff, voice)
        self.slices.append(gs)
        return gs
예제 #9
0
    def addDataToken(self, tok: str, timestamp: HumNum, part: int, staff: int,
                     voice: int, maxStaff: int) -> GridSlice:
        gs: GridSlice = None
        if not self.slices or self.slices[-1].timestamp < timestamp:
            # add a new GridSlice to an empty list or at end of list if timestamp
            # is after last entry in list.
            gs = GridSlice(self, timestamp, SliceType.Notes, maxStaff)
            gs.addToken(tok, part, staff, voice)
            self.slices.append(gs)
            return gs

        # search for existing line with same timestamp and the same slice type
        for idx, gridSlice in enumerate(self.slices):
            if timestamp == gridSlice.timestamp and gridSlice.isGraceSlice:
                # skip grace notes with the right timestamp
                continue

            if not gridSlice.isDataSlice:
                continue

            if gridSlice.timestamp == timestamp:
                gridSlice.addToken(tok, part, staff, voice)
                gs = gridSlice
                return gs

            if gridSlice.timestamp > timestamp:
                gs = GridSlice(self, timestamp, SliceType.Notes, maxStaff)
                gs.addToken(tok, part, staff, voice)
                self.slices.insert(idx, gs)
                return gs

        # Couldn't find a place for it, so place at end of measure.
        gs = GridSlice(self, timestamp, SliceType.Notes, maxStaff)
        gs.addToken(tok, part, staff, voice)
        self.slices.append(gs)
        return gs