Source code for tsmakers.MusicSpecifierSequence

import collections

import abjad
import tsmakers
from abjadext import rmakers


[docs]class MusicSpecifierSequence(object): r""" A music specifier sequence. .. container:: example >>> sequence_a = tsmakers.MusicSpecifierSequence( ... music_specifiers='music', ... ) >>> print(abjad.storage(sequence_a)) tsmakers.MusicSpecifierSequence( music_specifiers=('music',), ) .. container:: example >>> sequence_b = tsmakers.MusicSpecifierSequence( ... application_rate='phrase', ... music_specifiers=['one', 'two', 'three'], ... ) >>> print(abjad.storage(sequence_b)) tsmakers.MusicSpecifierSequence( application_rate='phrase', music_specifiers=('one', 'two', 'three'), ) """ ### CLASS VARIABLES ### __slots__ = ( "_application_rate", "_music_specifiers", ) ### INITIALIZER ### def __init__( self, application_rate=None, music_specifiers=None, ): if application_rate is not None: application_rate = application_rate or "phrase" assert application_rate in ("division", "phrase") if music_specifiers is None: music_specifiers = [None] if not isinstance(music_specifiers, collections.Sequence) or isinstance( music_specifiers, str ): music_specifiers = [music_specifiers] music_specifiers = tuple(music_specifiers) # music_specifiers = abjad.CyclicTuple(music_specifiers) assert len(music_specifiers) self._application_rate = application_rate self._music_specifiers = music_specifiers
[docs] def __str__(self): return abjad.storage(self)
[docs] def __repr__(self): return abjad.storage(self)
### SPECIAL METHODS ###
[docs] def __call__( self, durations=None, layer=None, division_mask_seed=0, division_masks=None, padding=None, seed=None, start_offset=None, timespan_specifier=None, voice_name=None, ): timespans = abjad.TimespanList() timespan_specifier = timespan_specifier or tsmakers.TimespanSpecifier() seed = seed or 0 division_mask_seed = division_mask_seed or 0 durations = [_ for _ in durations if _] offsets = abjad.math.cumulative_sums(durations, start_offset) if not offsets: return timespans offset_pair_count = len(offsets) - 1 if offset_pair_count == 1: offset_pair_count = 2 # make patterns happy iterator = abjad.Sequence(offsets).nwise() for i, offset_pair in enumerate(iterator): start_offset, stop_offset = offset_pair music_specifier = self[seed % len(self)] timespan = tsmakers.PerformedTimespan( forbid_fusing=timespan_specifier.forbid_fusing, forbid_splitting=timespan_specifier.forbid_splitting, layer=layer, minimum_duration=timespan_specifier.minimum_duration, music_specifier=music_specifier, start_offset=start_offset, stop_offset=stop_offset, voice_name=voice_name, ) if not division_masks: timespans.append(timespan) else: output_mask = division_masks.get_matching_pattern( i, offset_pair_count + 1, rotation=division_mask_seed ) if output_mask is None: timespans.append(timespan) elif isinstance(output_mask, rmakers.SustainMask): timespans.append(timespan) elif isinstance(output_mask, rmakers.SilenceMask): pass division_mask_seed += 1 if self.application_rate == "division": seed += 1 if padding: silent_timespans = abjad.TimespanList() for shard in timespans.partition(True): silent_timespan_one = tsmakers.SilentTimespan( layer=layer, start_offset=shard.start_offset - padding, stop_offset=shard.start_offset, voice_name=voice_name, ) silent_timespans.append(silent_timespan_one) silent_timespan_two = tsmakers.SilentTimespan( layer=layer, start_offset=shard.stop_offset, stop_offset=shard.stop_offset + padding, voice_name=voice_name, ) silent_timespans.append(silent_timespan_two) silent_timespans.compute_logical_or() for timespan in timespans: silent_timespans - timespan timespans.extend(silent_timespans) timespans.sort() return timespans
[docs] def __getitem__(self, item): return self._music_specifiers[item]
[docs] def __len__(self): return len(self._music_specifiers)
### PUBLIC METHODS ###
[docs] def transpose(self, expr): music_specifiers = [_.transpose(expr) for _ in self.music_specifiers] return abjad.new( self, music_specifiers=music_specifiers, )
### PUBLIC PROPERTIES ### @property def application_rate(self): return self._application_rate @property def music_specifiers(self): return self._music_specifiers