def get_reson(self): my_event = calliope.Event( beats=self.init_beats, def_event=self, ) my_event.skip = True return my_event
def straight_bass( input_row, phrase_count=2, rhythm_tree=( (2, 2), (2, 2), ), input_start_beat=0, ): beat_counter = input_start_beat bass_line = ImaginaryLine() for i in range(phrase_count): bass_phrase = ImaginaryPhrase() for cell_r in rhythm_tree: bass_cell = ImaginaryCell() for r in cell_r: if r > 0: input_event = input_row.event_at_beat(beat_counter) # TO DO... think of being more flexifble to pull either cell/phrase, parent/grandparent input_node = input_event.parent.parent input_pitches = input_node.note_pitch_set my_pitch = chords.get_diatonic_root(input_pitches) - 24 else: my_pitch = "R" bass_cell.append(calliope.Event(beats=r, pitch=my_pitch)) beat_counter += abs(r) bass_phrase.append(bass_cell) bass_line.append(bass_phrase) return bass_line
def get_reson(self): my_event = calliope.Event( beats=self.beats, pitch=self.pitch if self.rest or self.skip else self.reson_pitch, ) include_tags = self.tags & RESON_TAGS my_event.tag(*include_tags) return my_event
def bookend_pad(self, beats_before=0, beats_after=0): # TO DO: DRY if beats_before: rest_event = calliope.Event(beats=0 - beats_before) first_parent = self.events[0].parent if first_grandparent := first_parent.parent: first_grandparent.insert(0, type(first_parent)(rest_event)) else: first_parent.insert(0, rest_event)
def get_branch(self, node, *args, **kwargs): my_events = [] beats_last_clang = 0 for event in node: clang_dict = self.get_clang(event.pitch) if clang_dict: beats_before = event.beats_before(node) space_beats = beats_before - beats_last_clang if space_beats > 0: self.info(space_beats) my_events.append( calliope.Event( pitch=None, beats=space_beats, )) my_events.append( calliope.Event( pitches=[[ p + event.pitch for p in clang_dict["intervals"] ]], rhythm=(event.beats, ), )) beats_last_clang += space_beats + event.beats # TO DO: this -1 below does NOT make sense??? remaining_beats = node.beats - beats_last_clang print(node.beats, remaining_beats) if remaining_beats > 0: my_events.append( calliope.Event( pitch=None, beats=remaining_beats, )) return calliope.Cell(*my_events)
def machine( self, machine, pad=(1, 0), machine_pad=(0.25, 0.25), with_repeat=False, ): if pad[0]: self.pad(pad[0]) if machine_pad[0]: machine.insert(0, calliope.Event(beats=machine_pad[0], pitch="S")) if machine_pad[1]: machine.append(calliope.Event(beats=machine_pad[1], pitch="S")) machine.events[0].tag("\\normalStaff") self.append(machine) if pad[1]: self.pad(pad[1]) if with_repeat: machine.events[0].tag("\\bar \".|:\"") return machine
def pad(self, beats=1, with_command=True): if beats > 0: floor_beats = math.floor(beats) remainder_beats = beats - floor_beats pad_cell = ImaginaryCell(rhythm=(1, ) * floor_beats, pitches=("S", ) * floor_beats) if remainder_beats: pad_cell.append( calliope.Event(beats=remainder_beats, pitch="S")) if with_command: pad_cell.events[0].tag("\\freePad") self.append(pad_cell) return pad_cell
def weave(self, staff, index=0, **kwargs): # TO DO: turn this into something more interesting # (based on selectable?) my_cell = calliope.Cell(*[ calliope.Event( beats = self.pulse_duration, pitch = self.get_pitch(index, i) ) for i in range(self.pulse_length) ]) return my_cell
def get_pluck(self): if self.rest or self.skip: my_event = calliope.Event( beats=self.beats, pitch=self.pitch, ) if self.allow_string_over_rest: my_event.tag(r"\pluckRestEvent") else: my_event = calliope.Event(beats=self.beats, pitch=self.pluck_piches, pluck_strings=self.pluck_strings) # TO DO: move gliss styling to the beginning only my_event.tag(r"\pluckNoteEvent") my_event.tag(r"""\set glissandoMap = #'(""" + " ".join([ "( %s . %s )" % (i, i) for i in range(self.string_def_event.string_count) ]) + ")") my_event.tag("!\\glissando") my_event.tag(*self.tags) return my_event
def get_pluck(self): my_event = calliope.Event( pitch=list(self.string_map.keys()), beats=self.init_beats, def_event=self, ) my_event.tag(*self.tags) my_event.tag( "bass", r"""\pluckShowReson \set glissandoMap = #'(""" + " ".join([ "( %s . %s)" % (i, v) for i, s in enumerate(self.string_map.items()) for v in self.string_map[s[0]] ]) + ")") my_event.tag("!\\glissando") return my_event
class LibraryMaterial(object): move_interval = 5 move_max_octaves = 1 # TO DO MAYBE: this would be a great general calliope Transform! # OR ON ANY MACHINE... ALSO could be replaced by separate methods below... # TO DO: replace with + throughout def ext(self, other): self.extend(other()) return self # TO DO: maybe this should just be on the selection def remove_nodes(self, *args): for node in args: parent = node.parent parent.remove(node) parent.remove_if_empty() return self def crop_chords(self, indices=(None, ), above=(None, ), below=(None, )): return self.transformed( calliope.CropChords(indices=indices, above=above, below=below)) def only_first(self, select_attr="select", count=1): return self.remove_nodes(*getattr(self, select_attr)[count:]) def only_last(self, select_attr="select", count=1): selection = getattr(self, select_attr) return self.remove_nodes(*selection[:len(selection) - count - 1]) def set_vals(self, **kwargs): for n, v in kwargs: setattr(self, n, v) return self def crop(self, select_attr="select", crop_start=0, crop_end=0): """ crops start or ending selections from the material """ if crop_start: self.remove_nodes(*getattr(self, select_attr)[:crop_start]) if crop_end: self.remove_nodes(*getattr(self, select_attr)[0 - crop_end:]) return self def pop_from(self, select_attr="select", *args): """ crops start or ending selections from the material """ return self.remove_nodes(*getattr(self, select_attr)[args]) # TO DO: this implementation of with_only will leave behind # nodes that are NOT of the select_attr type def with_only(self, select_attr="select", *args): nodes = list(getattr(self, select_attr).exclude(*args)) for node in nodes: parent = node.parent parent.remove(node) parent.remove_if_empty() return self def scramble(self, select_attr="select", *args): """ will reconfigure subselection in new order (inc able to repeat elements). arg indices must be integers (not names). will also remove any tree layers between self and the selection """ ret_self = self() ret_self.clear() ret_self.extend([getattr(self, select_attr)[a]() for a in args]) return ret_self def poke(self, select_attr="select", *args): """ poking (keeping only events by indices) """ getattr(self, select_attr).exclude(*args).note_events.setattrs(rest=True) return self def mask(self, select_attr="select", *args): """ poking (keeping only events by indices) """ getattr(self, select_attr)[args].note_events.setattrs(rest=True) return self def sc(self, scale=2): return self.transformed(calliope.ScaleRhythm(scale=scale)) def stack_p(self, intervals): return self.transformed(calliope.StackPitches(intervals=intervals)) def t(self, interval): """ shortcut for transposing, since used A LOT """ return self.transformed(calliope.Transpose(interval=interval)) def ts(self, steps, scale=None, new_scale=None): """ shortcut for transposing within scale, since used A LOT """ return self.transformed( calliope.TransposeWithinScale(steps=steps, scale=scale, new_scale=new_scale)) def fuse(self): self.transformed(artics.FuseRepeatedNotes()) return self def mul(self, times=2, wrap_in=None): my_mul = wrap_in(self) if wrap_in else self my_copy = my_mul() for i in range(times - 1): my_mul.ext(my_copy()) return my_mul def move_t(self, times=1, interval=None, max_octaves=None, wrap_in=None): """ repeats the material (within a wrapper machine), transposing by an interval each time (creates copies, does NOT alter original) """ max_octaves = max_octaves or self.move_max_octaves interval = interval if interval is not None else self.move_interval wrap_in = wrap_in or ImaginarySegment max_move = max_octaves * (12 if interval > 0 else -12) return wrap_in( self(), *[ self().transformed( calliope.Transpose(interval=(interval * (t + 1)) % max_move)) for t in range(times) ]) def slur_cells(self): self.transformed(calliope.SlurCells()) return self def bookend_pad(self, beats_before=0, beats_after=0): # TO DO: DRY if beats_before: rest_event = calliope.Event(beats=0 - beats_before) first_parent = self.events[0].parent if first_grandparent := first_parent.parent: first_grandparent.insert(0, type(first_parent)(rest_event)) else: first_parent.insert(0, rest_event) if beats_after: last_parent = self.events[-1].parent rest_event = calliope.Event(beats=0 - beats_after) if last_grandparent := last_parent.parent: last_grandparent.append(type(last_parent)(rest_event)) else: last_parent.append(rest_event)
import abjad, calliope from imaginary.scores import score class TestCell(calliope.Cell): init_rhythm = (2, 2) init_pitches = (2, 4) s = score.ImaginaryScore() for staff in s.staves: staff.append(calliope.Event(rest=True, beats=4)) calliope.illustrate(s)
def fabricate(self, machine, *args, **kwargs): self.ranges = self.ranges or self.get_pitch_ranges(*args, **kwargs) # these are the staves with content defined in functions: def_staves = [ attr_name[9:] for attr_name in dir(self) if attr_name[:9] == "_staves__" ] if self.only_staves: used_staves = self.only_staves else: used_staves = self.fabric_staves # add in any def_staves not already included used_staves += tuple(set(def_staves) - set(used_staves)) if self.mask_staves: used_staves = tuple( [s for s in used_staves if s not in self.mask_staves]) setattr(self, "used_staves", used_staves) for i, staff_name in enumerate(used_staves): my_staff = self.staves[staff_name] if staff_name in def_staves: my_machine = getattr(self, "_staves__" + staff_name)(my_staff, i) else: my_machine = self.weave(my_staff, i) if self.after_func: my_machine = self.after_func(my_machine) if self.after_funcs: my_machine = self.after_funcs[i % len( self.after_funcs)](my_machine) if self.tag_events: for n, t in self.tag_events.items(): # print(n,t,my_machine.events[n]) my_machine.events[n].tag(*t) if self.tag_all_note_events: my_machine.note_events.tag(*self.tag_all_note_events) if self.transposes and staff_name in self.transposes: my_machine.t(self.transposes[staff_name]) if self.wrap_in is not None: my_bubble = self.wrap_in() my_bubble.append(my_machine) else: # TO DO... adding this direcly to staff is funky my_bubble = my_machine if self.bookend_beats[0]: my_bubble.insert( 0, calliope.Event(beats=0 - self.bookend_beats[0])) if self.bookend_beats[1]: my_bubble.append( calliope.Event(beats=0 - self.bookend_beats[1])) my_staff.append(my_bubble) if self.remove_empty_staves: self.remove_empty(rests_count=True) if self.assign_pitches_from_selectable: self.assign_pitches( selectable=self.pitch_selectable, only_indices=self.assign_pitches_only_indices, )