Пример #1
0
 def run(self):
     env = self.state.document.settings.env
     if not hasattr(env, 'file_projects_patterns'):
         env.file_projects_patterns = defaultdict(project_patterns_map)
     src_path = self.state.document['source']
     varname, = self.arguments
     projname, patname = varname.split('.')
     p = env.file_projects[src_path]
     project = p[projname]
     pm = env.file_projects_modules[src_path]
     pp = env.file_projects_patterns[src_path]
     if patname == '*':
         # Register all project's patterns.
         for pat_idx, pat in enumerate(project.patterns):
             if pat is not None and not isinstance(pat, PatternClone):
                 patname = (pat.name or 'pat_{}'.format(pat_idx))
                 patname = patname.replace(' ', '_')
                 pp[patname] = pat
     else:
         mods = pm[projname]
         pat = Pattern()
         pat.x, pat.y = self.pattern_pos(self.options['pos'])
         modmap = dict(self.module_map(self.options['map'], mods))
         self.write_pattern(pat, self.content, modmap)
         project += pat
         pp[patname] = pat
     return []
Пример #2
0
def test_note_belongs_to_project_of_pattern():
    empty_pattern = Pattern(tracks=1, lines=4)
    note = empty_pattern.data[0][0]
    assert note.project is None
    project = Project()
    project.attach_pattern(empty_pattern)
    assert note.project is project
Пример #3
0
def test_pattern_cannot_be_attached_to_multiple_projects():
    empty_pattern = Pattern(tracks=1, lines=4)
    project = Project()
    project.attach_pattern(empty_pattern)
    project2 = Project()
    with pytest.raises(PatternOwnershipError):
        project2.attach_pattern(empty_pattern)
Пример #4
0
    def flatten(self):
        mods = sorted(list(self.keys()))
        index = [(mod, i) for mod in mods for i in range(self[mod].polyphony)]
        pat = Pattern(lines=self.lines, tracks=len(index))

        def notefn(track, i, j):
            mod, k = index[j]
            notes = self[mod][i]
            if k < len(notes):
                note = notes[k].clone()
                if note.module:
                    note.module += 1  # NB
                return note
            else:
                return Note()

        pat.set_via_fn(notefn)
        return pat
Пример #5
0
    def flatten(self):
        mods = sorted(list(self.keys()))
        index = [(mod, i) for mod in mods for i in range(self[mod].polyphony)]
        pat = Pattern(lines=self.lines, tracks=len(index))

        def notefn(track, i, j):
            mod, k = index[j]
            notes = self[mod][i]
            if k < len(notes):
                note = notes[k].clone()
                if note.module:
                    note.module += 1  # NB
                return note
            else:
                return Note()

        pat.set_via_fn(notefn)
        return pat
Пример #6
0
def project_from_timeline(timeline: Timeline) -> Project:
    """Render a Timeline to a SunVox project."""
    project = Project()
    # 120 BPM, 48 ticks per quarter note
    project.initial_bpm = 120 * 2
    project.initial_tpl = 1
    voice_modules = dict((voice, voice.sunvox_module()) for voice in set(
        part.voice for part in timeline.parts))
    modules = list(voice_modules.values())
    project += modules
    project.output << modules
    for placed_phrase in timeline:
        p = placed_phrase.phrase
        ticks = p.ticks
        for i, part in enumerate(p.parts):
            pattern = Pattern(
                tracks=16,
                x=placed_phrase.x,
                y=placed_phrase.y + i * 10,
                lines=ticks,
            )
            project += pattern
            reserved = set()
            module = voice_modules[part.voice]
            mm = module.index + 1
            for placed_note in p:
                if placed_note.part is part:
                    start_tick = p.placed_note_on_tick(placed_note)
                    stop_tick = p.placed_note_off_tick(placed_note)
                    for nn in placed_note.notes:
                        track = 0
                        while (start_tick, track) in reserved:
                            track += 1
                            assert track < 16, \
                                f'Track overflow at {start_tick}'
                        cell = pattern.data[start_tick][track]
                        if nn.pitch.sp_value is not None:
                            cell.note = SET_PITCH
                            cell.val = nn.pitch.sp_value
                        else:
                            cell.note = nn.pitch.sunvox_note
                        cell.module = mm
                        for tick in range(start_tick, stop_tick + 1):
                            if tick < ticks:
                                reserved.add((tick, track))
                        if stop_tick < ticks:
                            cell = pattern.data[stop_tick][track]
                            cell.note = NOTE_OFF
    return project
Пример #7
0
def test_note_mod_property():
    project = Project()
    pattern = Pattern(tracks=1, lines=4)
    project.attach_pattern(pattern)
    note = pattern.data[0][0]
    assert note.module == 0
    assert note.module_index is None
    assert note.mod is None
    mod: m.Generator = project.new_module(m.Generator)
    note.mod = mod
    assert note.mod is mod
    assert note.module_index == mod.index
    assert note.module == mod.index + 1
    note.module = 5
    assert note.mod is None
    assert note.module_index == 4
Пример #8
0
def test_pattern_starts_with_no_project():
    empty_pattern = Pattern(tracks=1, lines=4)
    assert empty_pattern.project is None
Пример #9
0
def test_note_belongs_to_pattern():
    empty_pattern = Pattern(tracks=1, lines=4)
    note = empty_pattern.data[0][0]
    assert note.pattern is empty_pattern
Пример #10
0
def test_pattern_project_is_set_after_attaching():
    empty_pattern = Pattern(tracks=1, lines=4)
    project = Project()
    project.attach_pattern(empty_pattern)
    assert empty_pattern.project is project