Beispiel #1
0
def edit_scale(pad, verbose):
    global config

    rbank = int((pad - 1) / _PADS)
    rsubpad = pad - (_PADS * rbank) - 1

    menu = qprompt.Menu()
    x = 0
    for y in Scale._SCALE_PATTERNS:
        menu.add(str(x), y)
        x = x + 1
    stype = menu.show(hdr="Pad %d (Bank %s-%d):" %
                      (pad, chr(65 + rbank), rsubpad + 1),
                      msg="Scale",
                      returns="desc")

    root = qprompt.ask_int("Note",
                           vld=list(range(0, 128)),
                           dft=config[1][rbank][rsubpad]['note'])

    count = qprompt.ask_int("Count",
                            vld=[0] + list(range(1, _PTOTAL + 2 - pad)),
                            dft=0)

    scale = Scale.build_scale(Note.from_midi_num(root), stype)
    scale_lst = []
    for note in scale:
        scale_lst.append(note.midi_note_number())

    if count:
        while len(scale_lst) < count:
            root = scale_lst.pop()
            scale = Scale.build_scale(Note.from_midi_num(root), stype)
            for note in scale:
                scale_lst.append(note.midi_note_number())
    else:
        count = len(scale_lst)
        if pad + count > _PTOTAL:
            count = _PTOTAL + 1 - pad

    for note in scale_lst[:count]:
        bank = int((pad - 1) / _PADS)
        subpad = pad - (_PADS * bank) - 1

        config[1][bank][subpad]['note'] = note

        if verbose:
            print("Setting Pad %d (Bank %s-%d) to %d (%s)" %
                  (pad, chr(65 + bank), subpad + 1, note,
                   Note.from_midi_num(note)))
        pad = pad + 1
def test_scale_builder_e_maj():
    s = Scale.build_scale(Note('E', 4), 'maj')
    expected = [
        Note('E', 4),
        Note('F', 4, '#'),
        Note('G', 4, '#'),
        Note('A', 4),
        Note('B', 4),
        Note('C', 5, '#'),
        Note('D', 5, '#'),
        Note('E', 5)
    ]
    assert s == expected
def test_scale_builder_c_flat_nat_min():
    s = Scale.build_scale(Note('C', 5, 'b'), 'natural minor')
    expected = [
        Note('C', 5, 'b'),
        Note('D', 5, 'b'),
        Note('E', 5, 'bb'),
        Note('F', 5, 'b'),
        Note('G', 5, 'b'),
        Note('A', 5, 'bb'),
        Note('B', 5, 'bb'),
        Note('C', 6, 'b')
    ]
    assert s == expected
def test_scale_builder_b_sharp_nat_min():
    s = Scale.build_scale(Note('B', 4, '#'), 'nat min')
    expected = [
        Note('B', 4, '#'),
        Note('C', 5, '##'),
        Note('D', 5, '#'),
        Note('E', 5, '#'),
        Note('F', 5, '##'),
        Note('G', 5, '#'),
        Note('A', 5, '#'),
        Note('B', 5, '#')
    ]
    assert s == expected
def test_scale_builder_b_nat_min():
    s = Scale.build_scale(Note('B', 4), 'natural minor')
    expected = [
        Note('B', 4),
        Note('C', 5, '#'),
        Note('D', 5),
        Note('E', 5),
        Note('F', 5, '#'),
        Note('G', 5),
        Note('A', 5),
        Note('B', 5)
    ]
    assert s == expected
def test_scale_builder_a_nat_min():
    s = Scale.build_scale(Note('A', 4), 'nat min')
    expected = [
        Note('A', 4),
        Note('B', 4),
        Note('C', 5),
        Note('D', 5),
        Note('E', 5),
        Note('F', 5),
        Note('G', 5),
        Note('A', 5)
    ]
    assert s == expected
def test_scale_builder_b_flat_min():
    s = Scale.build_scale(Note('B', 4, 'b'), 'min')
    expected = [
        Note('B', 4, 'b'),
        Note('C', 5),
        Note('D', 5, 'b'),
        Note('E', 5, 'b'),
        Note('F', 5),
        Note('G', 5, 'b'),
        Note('A', 5),
        Note('B', 5, 'b')
    ]
    assert s == expected
def test_scale_builder_f_sharp_min():
    s = Scale.build_scale(Note('F', 4, '#'), 'minor')
    expected = [
        Note('F', 4, '#'),
        Note('G', 4, '#'),
        Note('A', 4),
        Note('B', 4),
        Note('C', 5, '#'),
        Note('D', 5),
        Note('E', 5, '#'),
        Note('F', 5, '#')
    ]
    assert s == expected
def test_scale_builder_c_flat_maj():
    s = Scale.build_scale(Note('C', 5, 'b'), 'maj')
    expected = [
        Note('C', 5, 'b'),
        Note('D', 5, 'b'),
        Note('E', 5, 'b'),
        Note('F', 5, 'b'),
        Note('G', 5, 'b'),
        Note('A', 5, 'b'),
        Note('B', 5, 'b'),
        Note('C', 6, 'b')
    ]
    assert s == expected
Beispiel #10
0
def edit_scale(pad, verbose):
    global config

    rbank = int((pad - 1) / _PADS)
    rsubpad = pad - (_PADS * rbank) - 1

    ptype = config[1][rbank][rsubpad]['type']
    if ptype == "BANK":
        qprompt.error("Pad %d (Bank %s-%d) is configured as a BANK" %
                      (pad, chr(65 + rbank), rsubpad + 1))
        return

    menu = qprompt.Menu()
    x = 0
    for y in Scale._SCALE_PATTERNS:
        menu.add(str(x), y)
        x = x + 1
    stype = menu.show(hdr="Pad %d (Bank %s-%d):" %
                      (pad, chr(65 + rbank), rsubpad + 1),
                      msg="Scale",
                      returns="desc")

    root = qprompt.ask_int("Note",
                           vld=list(range(0, 128)),
                           dft=config[1][rbank][rsubpad]['note'])

    count = qprompt.ask_int("Count",
                            vld=[0] + list(range(1, _PTOTAL + 2 - pad)),
                            dft=0)

    same = qprompt.ask_yesno(msg="Config all as per Pad %d?" % pad, dft='N')

    scale = Scale.build_scale(Note.from_midi_num(root), stype)
    scale_lst = []
    for note in scale:
        scale_lst.append(note.midi_note_number())

    if count:
        while len(scale_lst) < count:
            root = scale_lst.pop()
            scale = Scale.build_scale(Note.from_midi_num(root), stype)
            for note in scale:
                scale_lst.append(note.midi_note_number())
    else:
        count = len(scale_lst)
        if pad + count > _PTOTAL:
            count = _PTOTAL + 1 - pad

    for note in scale_lst[:count]:
        bank = int((pad - 1) / _PADS)
        subpad = pad - (_PADS * bank) - 1

        if same and ptype == "NOTE":
            config[1][bank][subpad]['type'] = config[1][rbank][rsubpad]['type']
            config[1][bank][subpad]['channel'] = config[1][rbank][rsubpad][
                'channel']
            config[1][bank][subpad]['trigger'] = config[1][rbank][rsubpad][
                'trigger']
            config[1][bank][subpad]['aftertouch'] = config[1][rbank][rsubpad][
                'aftertouch']

        if same and ptype == "PROG":
            config[1][bank][subpad]['type'] = config[1][rbank][rsubpad]['type']
            config[1][bank][subpad]['channel'] = config[1][rbank][rsubpad][
                'channel']

        if ptype == "NOTE":
            config[1][bank][subpad]['note'] = note
        else:
            config[1][bank][subpad]['program'] = note

        if verbose:
            print("Setting Pad %d (Bank %s-%d) to %d (%s)" %
                  (pad, chr(65 + bank), subpad + 1, note,
                   Note.from_midi_num(note)))
        pad = pad + 1
Beispiel #11
0
def edit_scale(pad, verbose):
    global config

    rbank = int((pad - 1) / _PADS)
    rsubpad = pad - (_PADS * rbank) - 1

    menu = qprompt.Menu()
    menu.add("0", "Note")
    menu.add("1", "Midi-CC")
    menu.add("2", "Program")
    ptype = menu.show(msg="Apply Scale to:", returns="desc", dft="0")

    menu = qprompt.Menu()
    x = 0
    for y in Scale._SCALE_PATTERNS:
        menu.add(str(x), y)
        x = x + 1
    stype = menu.show(hdr="Pad %d (Bank %s-%d):" %
                      (pad, chr(65 + rbank), rsubpad + 1),
                      msg="Scale",
                      returns="desc")

    same = None
    if ptype == "Note":
        root = qprompt.ask_int("Note",
                               vld=list(range(0, 128)),
                               dft=config[1][rbank][rsubpad]['note'])

        same = qprompt.ask_yesno(msg="Config all as per Pad %d?" % pad,
                                 dft='N')
    elif ptype == "Midi-CC":
        root = qprompt.ask_int("Midi-CC Value",
                               vld=list(range(0, 128)),
                               dft=config[1][rbank][rsubpad]['midicc'])
    else:
        root = qprompt.ask_int("Program Value",
                               vld=list(range(0, 128)),
                               dft=config[1][rbank][rsubpad]['prog'])

    count = qprompt.ask_int("Count",
                            vld=[0] + list(range(1, _PTOTAL + 2 - pad)),
                            dft=0)

    scale = Scale.build_scale(Note.from_midi_num(root), stype)
    scale_lst = []
    for note in scale:
        scale_lst.append(note.midi_note_number())

    if count:
        while len(scale_lst) < count:
            root = scale_lst.pop()
            scale = Scale.build_scale(Note.from_midi_num(root), stype)
            for note in scale:
                scale_lst.append(note.midi_note_number())
    else:
        count = len(scale_lst)
        if pad + count > _PTOTAL:
            count = _PTOTAL + 1 - pad

    for note in scale_lst[:count]:
        bank = int((pad - 1) / _PADS)
        subpad = pad - (_PADS * bank) - 1

        if same and ptype == "Note":
            config[1][bank][subpad]['trigger'] = config[1][rbank][rsubpad][
                'trigger']

        if ptype == "Note":
            config[1][bank][subpad]['note'] = note
        elif ptype == "Midi-CC":
            config[1][bank][subpad]['midicc'] = note
        else:
            config[1][bank][subpad]['prog'] = note

        if verbose:
            print("Setting Pad %d (Bank %s-%d) to %d (%s)" %
                  (pad, chr(65 + bank), subpad + 1, note,
                   Note.from_midi_num(note)))
        pad = pad + 1
Beispiel #12
0
from uno_synth import *

# Requires:
# https://github.com/charlottepierce/music_essentials
from music_essentials import Note, Scale

# build initial patch (basic triangle sound)
data = Patch.build({})

# now add a 'C Scale' to the sequence
scale = Scale.build_scale(Note.from_note_string("C4"), "major")

step = 1
# describe each step in full
for note in scale:
    data = data + Seq.build({
        "step":
        step,
        "count":
        1,
        "elements": [{
            "element": {
                "type": 2,
                "port": 0,
                "channel": 0
            },
            "data": {
                "note": Note.midi_note_number(note),
                "velocity": 127,
                "length": 1,
            }
def test_non_note_tonic_str():
    with pytest.raises(TypeError):
        Scale.build_scale('dlsfk', 'major')
def test_unsupported_scale_type():
    with pytest.raises(ValueError):
        Scale.build_scale(Note('C', 4), 'scale')
def test_non_note_tonic_int():
    with pytest.raises(TypeError):
        Scale.build_scale(1, 'major')