def from_selection(cls, selection, item_class=None, name=None): r'''Initialize pitch segment from component selection: :: >>> staff_1 = Staff("c'4 <d' fs' a'>4 b2") >>> staff_2 = Staff("c4. r8 g2") >>> selection = select((staff_1, staff_2)) >>> pitchtools.PitchSegment.from_selection(selection) PitchSegment(["c'", "d'", "fs'", "a'", 'b', 'c', 'g']) Returns pitch segment. ''' from abjad.tools import iterationtools from abjad.tools import pitchtools from abjad.tools import selectiontools if not isinstance(selection, selectiontools.Selection): selection = selectiontools.select(selection) named_pitches = [] for component in iterationtools.iterate_notes_and_chords_in_expr( selection): if hasattr(component, 'written_pitches'): named_pitches.extend(component.written_pitches) elif hasattr(component, 'written_pitch'): named_pitches.append(component.written_pitch) return cls( tokens=named_pitches, item_class=item_class, name=name, )
def iterate_out_of_range_notes_and_chords(expr): '''Iterates notes and chords in `expr` outside traditional instrument ranges: :: >>> staff = Staff("c'8 r8 <d fs>8 r8") >>> violin = instrumenttools.Violin() >>> attach(violin, staff) Violin()(Staff{4}) :: >>> list( ... instrumenttools.iterate_out_of_range_notes_and_chords( ... staff)) [Chord('<d fs>8')] Returns generator. ''' from abjad.tools import instrumenttools from abjad.tools import iterationtools for note_or_chord in iterationtools.iterate_notes_and_chords_in_expr(expr): instrument = note_or_chord._get_effective_context_mark( instrumenttools.Instrument) if instrument is None: raise MissingInstrumentError if note_or_chord not in instrument._default_pitch_range: yield note_or_chord
def select_notes_and_chords(self): r'''Selects notes and chords in container. .. container:: example :: >>> container.select_notes_and_chords() Selection(Note("c'8"), Note("d'8"), Note("e'8")) Returns leaf selection. ''' from abjad.tools import iterationtools from abjad.tools import selectiontools generator = iterationtools.iterate_notes_and_chords_in_expr(self) return selectiontools.Selection(generator)
def notes_and_chords_are_in_range(expr): '''True when notes and chords in `expr` are within traditional instrument ranges. :: >>> staff = Staff("c'8 r8 <d' fs'>8 r8") >>> violin = instrumenttools.Violin() >>> attach(violin, staff) Violin()(Staff{4}) :: >>> instrumenttools.notes_and_chords_are_in_range(staff) True False otherwise: :: >>> staff = Staff("c'8 r8 <d fs>8 r8") >>> violin = instrumenttools.Violin() >>> attach(violin, staff) Violin()(Staff{4}) :: >>> instrumenttools.notes_and_chords_are_in_range(staff) False Returns boolean. ''' from abjad.tools import instrumenttools for note_or_chord in iterationtools.iterate_notes_and_chords_in_expr(expr): instrument = note_or_chord._get_effective_context_mark( instrumenttools.Instrument) if note_or_chord not in instrument._default_pitch_range: return False else: return True
def __call__(self, expr, offset=0, skip_first=0, skip_last=0): articulation_lists = datastructuretools.CyclicList(self.articulation_lists) notes_and_chords = \ list(iterationtools.iterate_notes_and_chords_in_expr(expr)) notes_and_chords = notes_and_chords[skip_first:] if skip_last: notes_and_chords = notes_and_chords[:-skip_last] for i, note_or_chord in enumerate(notes_and_chords): articulation_list = articulation_lists[offset+i] articulation_list = [ marktools.Articulation(x) for x in articulation_list ] if self.minimum_duration is not None: if note_or_chord.duration.prolated < self.minimum_duration: continue if self.maximum_duration is not None: if self.maximum_duration < note_or_chord.duration.prolated: continue if self.minimum_written_pitch is not None: if isinstance(note_or_chord, notetools.Note): minimum_written_pitch = note_or_chord.pitch else: minimum_written_pitch = note_or_chord.pitches[0] if minimum_written_pitch < self.minimum_written_pitch: continue if self.maximum_written_pitch is not None: if isinstance(note_or_chord, notetools.Note): maximum_written_pitch = note_or_chord.pitch else: maximum_written_pitch = note_or_chord.pitches[-1] if self.maximum_written_pitch < maximum_written_pitch: continue for articulation in articulation_list: new_articulation = copy.copy(articulation) attach(new_articulation, note_or_chord) return expr
def __call__(self, expr): for note_or_chord in iterationtools.iterate_notes_and_chords_in_expr(expr): # contexttools.DynamicMark(self.dynamic_name)(note_or_chord) command = marktools.LilyPondCommandMark(self.dynamic_name, "right") attach(command, note_or_chord) return expr
def iterate_pitched_tie_chains_in_expr(expr, reverse=False): r'''Iterate pitched tie chains forward in `expr`: :: >>> staff = Staff(r"c'4 ~ \times 2/3 { c'16 d'8 }") >>> staff.extend(r"e'8 r8 f'8 ~ f'16 r8.") .. doctest:: >>> f(staff) \new Staff { c'4 ~ \times 2/3 { c'16 d'8 } e'8 r8 f'8 ~ f'16 r8. } :: >>> for x in iterationtools.iterate_pitched_tie_chains_in_expr(staff): ... x ... TieChain(Note("c'4"), Note("c'16")) TieChain(Note("d'8"),) TieChain(Note("e'8"),) TieChain(Note("f'8"), Note("f'16")) Iterate pitched tie chains backward in `expr`: :: >>> for x in iterationtools.iterate_pitched_tie_chains_in_expr( ... staff, reverse=True): ... x ... TieChain(Note("f'8"), Note("f'16")) TieChain(Note("e'8"),) TieChain(Note("d'8"),) TieChain(Note("c'4"), Note("c'16")) Tie chains are pitched if they comprise notes or chords. Tie chains are not pitched if they comprise rests or skips. Returns generator. ''' from abjad.tools import iterationtools from abjad.tools import spannertools spanner_classes = (spannertools.TieSpanner,) if not reverse: for leaf in iterationtools.iterate_notes_and_chords_in_expr(expr): tie_spanners = leaf._get_spanners(spanner_classes) if not tie_spanners or \ tuple(tie_spanners)[0]._is_my_last_leaf(leaf): yield leaf._get_tie_chain() else: for leaf in iterationtools.iterate_notes_and_chords_in_expr( expr, reverse=True): tie_spanners = leaf._get_spanners(spanner_classes) if not tie_spanners or \ tuple(tie_spanners)[0]._is_my_first_leaf(leaf): yield leaf._get_tie_chain()
def transpose_from_sounding_pitch_to_written_pitch(expr): r'''Transpose notes and chords in `expr` from sounding pitch to written pitch: :: >>> staff = Staff("<c' e' g'>4 d'4 r4 e'4") >>> clarinet = instrumenttools.BFlatClarinet() >>> attach(clarinet, staff) BFlatClarinet()(Staff{4}) .. doctest:: >>> f(staff) \new Staff { \set Staff.instrumentName = \markup { Clarinet in B-flat } \set Staff.shortInstrumentName = \markup { Cl. in B-flat } <c' e' g'>4 d'4 r4 e'4 } :: >>> instrumenttools.transpose_from_sounding_pitch_to_written_pitch(staff) .. doctest:: >>> f(staff) \new Staff { \set Staff.instrumentName = \markup { Clarinet in B-flat } \set Staff.shortInstrumentName = \markup { Cl. in B-flat } <d' fs' a'>4 e'4 r4 fs'4 } Returns none. ''' from abjad.tools import instrumenttools for note_or_chord in iterationtools.iterate_notes_and_chords_in_expr(expr): if not note_or_chord.written_pitch_indication_is_at_sounding_pitch: continue instrument = note_or_chord._get_effective_context_mark( instrumenttools.Instrument) if not instrument: continue sounding_pitch = instrument.sounding_pitch_of_written_middle_c t_n = pitchtools.NamedPitch('C4') - sounding_pitch t_n *= -1 if isinstance(note_or_chord, notetools.Note): note_or_chord.written_pitch = pitchtools.transpose_pitch_carrier_by_interval( note_or_chord.written_pitch, t_n) note_or_chord.written_pitch_indication_is_at_sounding_pitch = False elif isinstance(note_or_chord, scoretools.Chord): pitches = [pitchtools.transpose_pitch_carrier_by_interval(pitch, t_n) for pitch in note_or_chord.written_pitches] note_or_chord.written_pitches = pitches note_or_chord.written_pitch_indication_is_at_sounding_pitch = False