Godtone
Joined 17 December 2020
→My Python 3 code: added this very useful default for checking if a neji is constant structure according to a val and what the highest-error interval mapped by the val is |
|||
| Line 1,090: | Line 1,090: | ||
def mulmediant(r, k): | def mulmediant(r, k): | ||
return (r[0]*k, r[1]*k) | return (r[0]*k, r[1]*k) | ||
</syntaxhighlight> | |||
== Novation Launchpad Pro MK3 isomorphic keyboard code == | |||
This code is licensed under the AGPLv3 (https://www.gnu.org/licenses/agpl-3.0.html), a version of the [[wikipedia:Affero General Public License|AGPL]] corresponding to the [[wikipedia:GNU General Public License#Version 3|GPLv3]]. | |||
<syntaxhighlight lang="python"> | |||
# this code is licensed under the AGPLv3 <https://www.gnu.org/licenses/agpl-3.0.html> | |||
import mido | |||
def basic_iso(vel=100): # y=10, x=1 | |||
midi_inputs = mido.get_output_names() | |||
print('midi inputs detected:') | |||
for mi in midi_inputs: | |||
print(mi) | |||
print('selecting:') | |||
launchpad = [mi for mi in midi_inputs if 'Launchpad Pro MK3' in mi][0] | |||
print(launchpad) | |||
# transform the launchpad pro mk3's midi input (mi) into custom midi output (mo) | |||
with mido.open_input(launchpad) as mi, mido.open_output() as mo: | |||
for msg in mi: # process midi msg from launchpad | |||
to_send = msg.copy() | |||
if 'control' in str(msg): # buttons not pressure-sensitive so use set velocity (i choose 100) | |||
to_send = mido.Message( 'note_on', channel=0, | |||
note=msg.control, velocity=vel if msg.value else 0 | |||
) | |||
if not 'clock' in str(to_send): | |||
print(to_send) | |||
mo.send(to_send) | |||
colmap17 = [120, 60, 84, 96, 109, 13, 98, 122, 25, 29, 37, 41, 45, 49, 81, 53, 57] | |||
def iso(x=5, y=1, bottomleftnote=10, note_to_col = lambda n: 1 if n>0 else 0, vel=105, half=40): | |||
midi_inputs = mido.get_output_names() | |||
print('midi inputs detected:') | |||
for mi in midi_inputs: | |||
print(mi) | |||
print('selecting:') | |||
launchpad = [mi for mi in midi_inputs if 'Launchpad Pro MK3' in mi][0] | |||
print(launchpad) | |||
def transform(midi_note): | |||
return (midi_note % 10) * x + (midi_note//10 - 1) * y + bottomleftnote | |||
note_state = dict() | |||
for k in range(10,99): | |||
note_state[transform(k)] = 0 | |||
with mido.open_output(launchpad) as col: # apply off colours | |||
for k in range(10,99): # for all keycodes... | |||
col.send(mido.Message('note_on', channel=0, note=k, velocity=note_to_col(-transform(k)))) | |||
# transform the launchpad pro mk3's midi input (mi) into custom midi output (mo) | |||
with mido.open_input(launchpad) as mi, mido.open_output() as mo, mido.open_output(launchpad) as col: | |||
for msg in mi: # process midi msg from launchpad | |||
to_send = msg.copy() | |||
k = 0 # what key is being pressed | |||
note_vel = 0 | |||
if 'control' in str(msg): | |||
k = msg.control | |||
note_vel = vel if msg.value else 0 | |||
elif 'note' in str(msg): | |||
k = msg.note | |||
note_vel = msg.velocity | |||
else: | |||
k = 0 | |||
note_vel = note_vel if note_vel > 4 else 0 | |||
if k>=10 and k<99: | |||
midi_note = transform(k) | |||
if note_vel: # if we're pressing a key | |||
note_vel = round( note_vel * 2**( -(midi_note-bottomleftnote)/half ) ) | |||
if note_state[midi_note]: # if one or more eqivalent keys are already held | |||
to_send = mido.Message('note_on', channel=0, note=midi_note, velocity=0) | |||
print(to_send) | |||
mo.send(to_send) # turn off equivalent midi note | |||
else: # light all equivalent keys | |||
for k in range(10,99): # for all keycodes... | |||
if transform(k)==midi_note: # if equivalent... light key | |||
col.send(mido.Message('note_on', channel=0, note=k, velocity=note_to_col(midi_note))) | |||
to_send = mido.Message('note_on', channel=0, note=midi_note, velocity=note_vel) | |||
print(to_send) | |||
mo.send(to_send) # turn on equivalent midi note | |||
note_state[midi_note] += 1 | |||
elif note_state[midi_note]: # if we're releasing a key and there are equivalent keys held | |||
note_state[midi_note] -= 1 | |||
if note_state[midi_note]==0: # if we turn off all keys as a result... turn off | |||
to_send = mido.Message('note_on', channel=0, note=midi_note, velocity=0) | |||
print(to_send) | |||
mo.send(to_send) # turn off equivalent midi note | |||
for k in range(10,99): # for all keycodes... | |||
if transform(k)==midi_note: # if equivalent... unlight key | |||
col.send(mido.Message('note_on', channel=0, note=k, velocity=note_to_col(-midi_note))) | |||
</syntaxhighlight> | </syntaxhighlight> | ||