Пример #1
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
Пример #2
0
def test_connection_shorthand():
    p = Project()
    amp = p.new_module(m.Amplifier)
    gen = p.new_module(m.Generator)
    gen >> amp
    p.output << amp
    assert gen.index in p.module_connections[amp.index]
    assert amp.index in p.module_connections[p.output.index]
Пример #3
0
def hello_world():
    project = Project()
    fm = project.new_module(m.Fm, m_feedback=42)
    project.connect(fm, project.output)
    init(None, 44100, 2, 0)
    with Slot(project) as slot:
        slot.send_event(0, 42, 32, fm, 0, 0)
        print("Press Enter to close")
        input()
        slot.stop()
    deinit()
Пример #4
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)
Пример #5
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
Пример #6
0
def test_reflect():
    p = Project()
    amp1 = p.new_module(m.Amplifier)
    amp2 = p.new_module(m.Amplifier)
    mc = p.new_module(m.MultiCtl)
    mc >> amp1
    mc >> amp2
    mc.mappings.values[0].min = 32768
    mc.mappings.values[0].max = 0
    mc.mappings.values[0].controller = amp1.controllers["volume"].number
    mc.mappings.values[1].controller = amp2.controllers["volume"].number
    amp1.volume = 0
    mc.reflect(0)
    assert mc.value == 32768
    assert amp2.volume == 1024
Пример #7
0
def test_reflect():
    p = Project()
    amp1 = p.new_module(m.Amplifier)
    amp2 = p.new_module(m.Amplifier)
    mc = p.new_module(m.MultiCtl)
    mc >> amp1
    mc >> amp2
    mc.mappings.values[0].min = 32768
    mc.mappings.values[0].max = 0
    mc.mappings.values[0].controller = amp1.controllers["volume"].number
    mc.mappings.values[1].controller = amp2.controllers["volume"].number
    amp1.volume = 0
    mc.reflect(0)
    assert mc.value == 32768
    assert amp2.volume == 1024
Пример #8
0
def test_propagation_multisynth_transpose_rangelimit():
    p = Project()
    ms1 = p.new_module(m.MultiSynth)
    mc = p.new_module(m.MultiCtl)
    mc >> ms1
    mapping = mc.mappings.values[0]
    mapping.controller = ms1.controllers["transpose"].number
    mapping.min = 128
    mapping.max = 144
    mapping.gain = 256 + int(256 / 17)
    mc.value = 0
    assert ms1.transpose == 0
    mc.value = 16384
    assert ms1.transpose == 8
    mc.value = 32768
    assert ms1.transpose == 16
Пример #9
0
def dump(props, patch, output_dir, dirname):
    patch_dir = f"{output_dir}/{dirname}/{patch['name']}"
    os.makedirs(patch_dir, exist_ok=True)
    proj = Project()
    proj.initial_bpm = props["bpm"]
    proj.initial_tpl = props["tpl"]
    layout = module_layout(len(patch["modules"]))
    for i, mod in enumerate(reversed(patch["modules"][:-1])):
        mod.x, mod.y = layout[i]
        proj.attach_module(mod)
    for i in range(len(proj.modules) - 1):
        proj.connect(proj.modules[i + 1], proj.modules[i])
    proj.patterns.append(patch["pattern"])
    destfilename = f"{patch_dir}/{patch['x']}.sunvox"
    with open(destfilename, "wb") as f:
        proj.write_to(f)
Пример #10
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
Пример #11
0
def test_propagation_multisynth_transpose_rangelimit():
    p = Project()
    ms1 = p.new_module(m.MultiSynth)
    mc = p.new_module(m.MultiCtl)
    mc >> ms1
    mapping = mc.mappings.values[0]
    mapping.controller = ms1.controllers["transpose"].number
    mapping.min = 128
    mapping.max = 144
    mapping.gain = 256 + int(256 / 17)
    mc.value = 0
    assert ms1.transpose == 0
    mc.value = 16384
    assert ms1.transpose == 8
    mc.value = 32768
    assert ms1.transpose == 16
Пример #12
0
def dump(props, patch, output_dir, dirname):
    patch_dir = f"{output_dir}/{dirname}/{patch['name']}"
    os.makedirs(patch_dir, exist_ok=True)
    proj = Project()
    proj.initial_bpm = props["bpm"]
    proj.initial_tpl = props["tpl"]
    layout = module_layout(len(patch["modules"]))
    for i, mod in enumerate(reversed(patch["modules"][:-1])):
        mod.x, mod.y = layout[i]
        proj.attach_module(mod)
    for i in range(len(proj.modules) - 1):
        proj.connect(proj.modules[i + 1], proj.modules[i])
    proj.patterns.append(patch["pattern"])
    destfilename = f"{patch_dir}/{patch['x']}.sunvox"
    with open(destfilename, "wb") as f:
        proj.write_to(f)
Пример #13
0
def test_propagation_amp_volume():
    p = Project()
    amp1 = p.new_module(m.Amplifier)
    amp2 = p.new_module(m.Amplifier)
    mc = p.new_module(m.MultiCtl)
    mc >> amp1
    mc >> amp2
    mc.mappings.values[0].min = 32768
    mc.mappings.values[0].max = 0
    mc.mappings.values[0].controller = amp1.controllers["volume"].number
    mc.mappings.values[1].controller = amp2.controllers["volume"].number
    mc.value = 0
    assert amp1.volume == 1024
    assert amp2.volume == 0
    mc.value = 16384
    assert amp1.volume == 512
    assert amp2.volume == 512
    mc.value = 32768
    assert amp1.volume == 0
    assert amp2.volume == 1024
Пример #14
0
def test_propagation_amp_volume():
    p = Project()
    amp1 = p.new_module(m.Amplifier)
    amp2 = p.new_module(m.Amplifier)
    mc = p.new_module(m.MultiCtl)
    mc >> amp1
    mc >> amp2
    mc.mappings.values[0].min = 32768
    mc.mappings.values[0].max = 0
    mc.mappings.values[0].controller = amp1.controllers["volume"].number
    mc.mappings.values[1].controller = amp2.controllers["volume"].number
    mc.value = 0
    assert amp1.volume == 1024
    assert amp2.volume == 0
    mc.value = 16384
    assert amp1.volume == 512
    assert amp2.volume == 512
    mc.value = 32768
    assert amp1.volume == 0
    assert amp2.volume == 1024
Пример #15
0
def test_propagation_multisynth_transpose():
    p = Project()
    ms1 = p.new_module(m.MultiSynth)
    ms2 = p.new_module(m.MultiSynth)
    mc = p.new_module(m.MultiCtl)
    mc >> ms1
    mc >> ms2
    mc.mappings.values[0].min = 0
    mc.mappings.values[0].max = 256
    mc.mappings.values[0].controller = ms1.controllers["transpose"].number
    mc.mappings.values[1].min = 256
    mc.mappings.values[1].max = 0
    mc.mappings.values[1].controller = ms2.controllers["transpose"].number
    mc.value = 0
    assert ms1.transpose == -128
    assert ms2.transpose == 128
    mc.value = 16384
    assert ms1.transpose == 0
    assert ms2.transpose == 0
    mc.value = 32768
    assert ms1.transpose == 128
    assert ms2.transpose == -128
Пример #16
0
def test_propagation_multisynth_transpose():
    p = Project()
    ms1 = p.new_module(m.MultiSynth)
    ms2 = p.new_module(m.MultiSynth)
    mc = p.new_module(m.MultiCtl)
    mc >> ms1
    mc >> ms2
    mc.mappings.values[0].min = 0
    mc.mappings.values[0].max = 256
    mc.mappings.values[0].controller = ms1.controllers["transpose"].number
    mc.mappings.values[1].min = 256
    mc.mappings.values[1].max = 0
    mc.mappings.values[1].controller = ms2.controllers["transpose"].number
    mc.value = 0
    assert ms1.transpose == -128
    assert ms2.transpose == 128
    mc.value = 16384
    assert ms1.transpose == 0
    assert ms2.transpose == 0
    mc.value = 32768
    assert ms1.transpose == 128
    assert ms2.transpose == -128
Пример #17
0
def test_layout():
    p = Project()
    out = p.output
    gen1 = p.new_module(m.Generator)
    gen2 = p.new_module(m.Generator)
    amp = p.new_module(m.Amplifier)
    amp << [gen1, gen2]
    amp >> out
    assert [gen1.x, gen2.x, amp.x, out.x].count(512) == 4
    assert [gen1.y, gen2.y, amp.y, out.y].count(512) == 4
    p.layout()
    assert [gen1.x, gen2.x, amp.x, out.x].count(512) != 4
    assert [gen1.y, gen2.y, amp.y, out.y].count(512) != 4
Пример #18
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