Skip to content

Commit

Permalink
[MKS70] Hunt bits and bytes on why we cannot produce the same patches…
Browse files Browse the repository at this point in the history
… like the CTRL panel

(cherry picked from commit 5ec4280)
  • Loading branch information
christofmuc committed Nov 16, 2023
1 parent 703bfb8 commit 4c8ec07
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 23 deletions.
30 changes: 15 additions & 15 deletions adaptations/Roland_MKS70V4.py
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,7 @@ def calculateFingerprint(message):
"Chase Level": 54,
"Chase Time": 55,
"ChaseMode": (56, 2, 0),
"Chase On/Off": (57, 2, 0),
"Chase On/Off": (57, 1, 0),
}

bulk_mapping_patch = {
Expand All @@ -511,36 +511,37 @@ def calculateFingerprint(message):
"A/B Balance": 29,
"Dual Detune": 30,
"UpperSplitPT": 31,
"BendRange": [(32, 1, 3, 0), (40, 1, 2, 1), (62, 1, 1, 2)],
"Keymode": [(32, 1, 1, 0), (40, 1, 3, 1), (40, 1, 4, 2), (40, 1, 7, 3)],
"BendRange": [(32, 1, 2, 0), (40, 1, 1, 1), (62, 1, 0, 2)],
"Keymode": [(32, 1, 0, 1), (40, 1, 2, 2), (40, 1, 3, 3), (40, 1, 6, 0)],
"LowerSplitPT": 33,
"Porta Time": 34,
"Total Volume": 35,
"AT Vibrato": 36,
"AT Brilliance": 37,
"AT Volume": 38,
"A Tone Nr.": 39,
"A-Hold": (40, 1, 1),
"A-Hold": (40, 1, 0),
"A Chromatic Shift": 41,
"A Unison Detune": 42,
"A LFO Mod Dpth": 43,
"A Bender": 44,
"B Tone Nr.": 45,
"B Chromatic Shift": 46,
"B Unison Detune": 47,
"B-Hold": (48, 1, 3),
"A-Porta": (48, 1, 5),
"B-Hold": (48, 1, 2),
"A-Porta": (48, 1, 4),
"B LFO Mod Dpth": 49,
"B Bender": 50,
"Chase Level": 51,
"Chase Time": 52,
"A-Keyassign": [(53, 1, 6, 0), (53, 1, 7, 1), (56, 1, 3, 2)],
"B-Keyassign": [(54, 1, 6, 0), (54, 1, 7, 1), (56, 1, 2, 2)],
"A-Keyassign": [(53, 1, 5, 0), (53, 1, 6, 1), (56, 1, 1, 2)],
"B-Keyassign": [(54, 1, 5, 0), (54, 1, 6, 1), (56, 1, 0, 2)],
"B-Porta": (56, 1, 7),
"ChaseMode": [(56, 1, 4, 0), (56, 1, 5, 1)],
"Chase On/Off": [(63, 1, 2, 0), (63, 1, 5, 1)]
"ChaseMode": [(56, 1, 3, 1), (56, 1, 4, 0)],
"Chase On/Off": (63, 1, 2)
}


apr_mapping_patch = {
"Char1": 7,
"Char2": 8,
Expand All @@ -565,7 +566,7 @@ def calculateFingerprint(message):
"UpperSplitPT": 27,
"LowerSplitPT": 28,
"Porta Time": 29,
"BendRange": [(30, 2, 5, 0), (59, 1, 0, 2)],
"BendRange": [(30, 2, 6, 0), (59, 1, 0, 2)],
"Keymode": [(31, 2, 0, 0), (58, 2, 0, 2)],
"Total Volume": 32,
"AT Vibrato": 33,
Expand All @@ -588,11 +589,10 @@ def calculateFingerprint(message):
"B-Porta": (51, 1, 0),
"B Bender": 52,
"Chase Level": 54,
"Chase Time": 55,
"ChaseMode": (56, 2, 0),
"Chase On/Off": (57, 2, 0),
"ChaseMode": (55, 2, 0),
"Chase Time": 56,
"Chase On/Off": (57, 1, 0),
}

bulk_mapping_tone = {
"Char1": 9,
"Char2": 10,
Expand Down
71 changes: 63 additions & 8 deletions adaptations/test_Roland_MKS70_V4.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import pytest

from Roland_MKS70V4 import *
from knobkraft import list_compare

bulk_message_length = 66
bulk_0x37_message_length = 48
Expand Down Expand Up @@ -35,6 +36,32 @@ def test_saveParametersDoesntCrash():
]


@pytest.mark.parametrize("message_length, mapping_1", testdata1)
def test_no_double_mapping(message_length, mapping_1):
all_bits = [0] * message_length
for item in mapping_1:
index = mapping_1[item]
if isinstance(index, int):
# Standard, assume 7 bits blocked
for i in range(7):
if all_bits[index] & (1 << i) != 0:
raise Exception(f"Bit {i} of byte {index} has already been used - double mapping error!")
all_bits[index] = all_bits[index] | (1<<i)
elif isinstance(index, tuple):
map = mapping_1[item]
index = map[0]
width = map[1]
shift = map[2]
for i in range(width):
if all_bits[index] & (1 << (i + shift)) != 0:
raise Exception(f"Bit {i + shift} of byte {index} has already been used - double mapping error!")
all_bits[index] = all_bits[index] & (1<<(i+shift))
for i in range(message_length):
if all_bits[i] != 127:
pass
#assert(all_bits[i] == 127)


@pytest.mark.parametrize("message_length, mapping_1", testdata1)
def test_load_and_save(message_length, mapping_1):
for i in range(message_length): # Iterate over all bytes in the message
Expand All @@ -59,17 +86,17 @@ def test_load_and_save(message_length, mapping_1):


testdata2 = [
(apr_message_length, bulk_message_length, apr_mapping_patch, bulk_mapping_patch),
(bulk_message_length, apr_message_length, bulk_mapping_patch, apr_mapping_patch),
(apr_tone_message_length, bulk_tone_message_length, apr_mapping_tone, bulk_mapping_tone),
(bulk_tone_message_length, apr_tone_message_length, bulk_mapping_tone, apr_mapping_tone),
(apr_0x37_message_length, bulk_0x37_message_length, apr_mapping_patch_0x37, bulk_mapping_patch_0x37),
(bulk_0x37_message_length, apr_0x37_message_length, bulk_mapping_patch_0x37, apr_mapping_patch_0x37),
("Patch APR to BLD", apr_message_length, bulk_message_length, apr_mapping_patch, bulk_mapping_patch),
("Patch BLD to APR", bulk_message_length, apr_message_length, bulk_mapping_patch, apr_mapping_patch),
("Tone APR to BLD", apr_tone_message_length, bulk_tone_message_length, apr_mapping_tone, bulk_mapping_tone),
("Tone BLD to APR", bulk_tone_message_length, apr_tone_message_length, bulk_mapping_tone, apr_mapping_tone),
("Legacy APR to BLD", apr_0x37_message_length, bulk_0x37_message_length, apr_mapping_patch_0x37, bulk_mapping_patch_0x37),
("Legacy BLD to APR", bulk_0x37_message_length, apr_0x37_message_length, bulk_mapping_patch_0x37, apr_mapping_patch_0x37),
]


@pytest.mark.parametrize("src_message_length, dst_message_length, mapping_1, mapping_2", testdata2)
def test_conversion(src_message_length, dst_message_length, mapping_1, mapping_2):
@pytest.mark.parametrize("name, src_message_length, dst_message_length, mapping_1, mapping_2", testdata2)
def test_conversion(name, src_message_length, dst_message_length, mapping_1, mapping_2):
message_length = src_message_length
for i in range(message_length): # Iterate over all bytes in the message
for j in range(7): # Iterate over all bits in a byte
Expand All @@ -95,6 +122,11 @@ def test_conversion(src_message_length, dst_message_length, mapping_1, mapping_2
# Check that the original message is recovered
dst_msg = convert_message(src_msg, dst_message_length, mapping_1, mapping_2)
src_msg_back = convert_message(dst_msg, src_message_length, mapping_2, mapping_1)
print(f"\nSource values: {values}")
target_values = {}
for key in mapping_2.keys():
target_values[key] = load_parameter(dst_msg, mapping_2[key])
print(f"\nTarget values: {target_values}")
assert src_msg == src_msg_back, f"Conversion failed for byte {i}, bit {j}"

print("All conversions succeeded")
Expand All @@ -119,6 +151,29 @@ def test_single_tone_apr_0x38():
assert not isEditBufferDump2(single_apr)


def test_jx8p_import():
single_apr = knobkraft.sysex.stringToSyx(
"f0 41 35 00 21 20 01 4e 4f 20 45 53 43 41 50 45 20 20 36 7f 44 00 00 3c 7a 00 45 54 00 00 7f 7f 7f 40 40 71 52 7f 00 60 00 38 0f 00 2f 4c 20 60 54 00 2d 7f 00 66 00 54 45 5f 40 00 47 64 52 20 7f 7f f7"
)
assert isAprMessage(single_apr)


def test_compare_ctrlr_and_kk():
cr = ["F0 41 38 00 24 30 01 44 55 41 4C 20 50 55 4C 53 45 20 53 59 4E 43 20 20 20 3A 30 27 52 01 00 00 7F 1A 00 00 01 00 00 3F 01 37 00 01 00 02 00 00 41 01 3A 00 01 00 5A 02 1A 00 00 00 F7",
"F0 41 38 00 24 20 01 50 55 4C 53 45 53 59 4E 43 31 20 38 03 00 14 3A 7F 00 26 5D 17 53 00 20 5A 00 64 21 00 00 00 3E 21 7F 3C 6B 00 00 24 00 34 7F 52 6E 1A 7F 5E 00 7F 00 7F 00 7F 00 23 63 51 6D 16 41 71 38 00 00 00 40 20 40 20 40 40 00 20 40 60 40 00 00 00 00 40 00 20 50 50 20 10 50 20 60 40 20 40 10 00 10 10 00 10 00 00 F7",
"F0 41 38 00 24 20 02 50 55 4C 53 45 53 59 4E 43 32 20 38 03 00 68 45 7A 00 26 5D 17 5B 00 2C 5A 7F 64 21 00 00 00 3E 21 64 3C 6B 00 00 24 00 34 7F 55 70 1D 7F 5E 00 7F 00 7F 00 7F 00 23 63 51 6D 16 41 71 38 00 00 00 40 20 40 20 40 40 00 20 60 40 60 00 00 00 00 40 00 20 50 50 20 10 50 20 60 40 20 40 10 00 10 10 00 10 00 00 F7"]

print(nameFromDump(knobkraft.sysex.stringToSyx(cr[0])))
m = 0
bulk = convert_message(knobkraft.sysex.stringToSyx(cr[m]), bulk_message_length, apr_mapping_patch, bulk_mapping_patch)
kk = convert_message(bulk, apr_message_length, bulk_mapping_patch, apr_mapping_patch)
list_compare(kk[7:-1], knobkraft.sysex.stringToSyx(cr[m])[7:-1])
for m in range(2):
bulk = convert_message(knobkraft.sysex.stringToSyx(cr[m+1]), bulk_tone_message_length, apr_mapping_tone, bulk_mapping_tone)
kk = convert_message(bulk, apr_tone_message_length, bulk_mapping_tone, apr_mapping_tone)
list_compare(kk[7:-1], knobkraft.sysex.stringToSyx(cr[m+1])[7:-1])


def test_old_bank_format():
old_bank = knobkraft.load_sysex('testData/Roland_MKS70/MKS70_MKSSYNTH.SYX', False)
patches = extractPatchesFromAllBankMessages(old_bank)
Expand Down

0 comments on commit 4c8ec07

Please sign in to comment.