Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
  • Loading branch information
simonalveteg authored Aug 12, 2018
1 parent 110acf4 commit 6ef6465
Show file tree
Hide file tree
Showing 2 changed files with 216 additions and 0 deletions.
116 changes: 116 additions & 0 deletions SynthesiaKontrol-MK1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# The MIT License
#
# Copyright (c) 2018 Olivier Jacques
#
# Synthesia Kontrol: an app to light the keys of Native Instruments
# Komplete Kontrol MK2 keyboard, driven by Synthesia


# Modified to work with MK1 keyboards

import hid
import mido
from msvcrt import getch


numkeys = 88 #change this to the number of keys on your keyboard
offset = -(108-numkeys+1)
pid = 0x1410 #change this to the product id of your keyboard

def init():
"""Connect to the keyboard, switch all lights off"""
global bufferC # Buffer with the full key/lights mapping
global device

device=hid.device()
# 0x17cc: Native Instruments. 0x1410: KK S88 MK1
device.open(0x17cc, pid)
device.write([0xa0])

bufferC = [0x00] * numkeys
notes_off()

return True

def notes_off():
"""Turn off lights for all notes"""
bufferC = [0x00] * numkeys
device.write([0x82] + bufferC)

def accept_notes(port):
"""Only let note_on and note_off messages through."""
for message in port:
if message.type in ('note_on', 'note_off'):
yield message
if message.type == 'control_change' and message.channel == 0 and message.control == 16:
if (message.value & 4):
print ("User is playing")
if (message.value & 1):
print ("Playing Right Hand")
if (message.value & 2):
print ("Playing Left Hand")
notes_off()

def LightNote(note, status, channel, velocity):
"""Light a note ON or OFF"""
key = (note + offset)

if key < 0 or key >= numkeys:
return

# Determine color
left = [0x00] + [0x00] + [0xFF] # Blue
left_thumb = [0x00] + [0x00] + [0x80] # Lighter Blue
right = [0x00] + [0xFF] + [0x00] # Green
right_thumb = [0x00] + [0x80] + [0x00] # Lighter Green
default = right
color = default

# Finger based channel protocol from Synthesia
# Reference: https://www.synthesiagame.com/forum/viewtopic.php?p=43585#p43585
if channel == 0:
# we don't know who or what this note belongs to, but light something up anyway
color = default
if channel >= 1 and channel <= 5:
# left hand fingers, thumb through pinky
if channel == 1:
color = left_thumb
else:
color = left
if channel >= 6 and channel <= 10:
# right hand fingers, thumb through pinky
if channel == 6:
color = right_thumb
else:
color = right
if channel == 11:
# left hand, unknown finger
color = left
if channel == 12:
# right hand, unknown finger
color = right

black = [0x00] * 3
if status == 'note_on' :
colors[3*key:3*key+3]=color #set the three colorvalues of the key to desired color
if status == 'note_off' :
colors[3*key:3*key+3]=black #set the key back to black
device.write([0x82] + colors) #changes the color of pressed key

if __name__ == '__main__':
"""Main: connect to keyboard, open midi input port, listen to midi"""
print ("Connecting to Komplete Kontrol Keyboard")
connected = init()
if connected:
print ("Opening LoopBe input port")
ports = mido.get_input_names()
for port in ports:
if "LoopBe" in port:
portName = port
print ("Listening to Midi")
with mido.open_input(portName) as midiPort:
black = [0x00] * 3 #color, R + G + B (in this case black)
colors = black * numkeys #sets the color to all 88 keys (when it gets written to kontrol)
for message in accept_notes(midiPort):
print('Received {}'.format(message))
LightNote(message.note, message.type, message.channel, message.velocity)
100 changes: 100 additions & 0 deletions lightguidekontrol.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import pywinusb.hid as pyhid
import mido
import time
import hid
#from msvcrt import getch
'''
Based on the work of anykey, jasonbrent and OlvierJ. Feel free to modify in any way.
A small script to have the lights on the keyboard light up only when the corresponding key gets pressed.
Problem right now: only one key can light up at a time :/
Made for Komplete Kontrol S88 MK1
'''


numkeys = 88 #my keyboard has 88 keys
pid = 0x1410 #product ID of your keyboard
offset = 108 - numkeys + 1 #this is based on the fact that my 88 keys has an offset of 21, and Olivier's 61 key has an offset of 48. 20+88=108, 60+48=108.


def init():
#Connect to keyboard and switch lights off
global bufferC
global kontrol

kontrol = hid.device()
# filter connected HID devices and check if keyboard is connected
# 0x17cc: Native Instruments. 0x1410: KK S88 MK1.
filter = pyhid.HidDeviceFilter(vendor_id = 0x17cc, product_id = pid).get_devices()
if filter:
print("Komplete Kontrol Found!")
kontrol.open(0x17cc, pid)
kontrol.write([0xa0]) # activates the device
notes_off()
print("Lights turned off..")
midi_connection()
else:
print("Could not find keyboard :c")

def notes_off():
#sets keylights to black
bufferC = [0x00] * 3 * numkeys
kontrol.write([0x82] + bufferC)
#code below sets other buttons to a dimmed white, not really neccesary
'''bufferC = [0x0F] * 24
kontrol.write([0x80] + bufferC)'''


def accept_notes(port):
"""Only let note_on and note_off messages through."""
for message in port:
if message.type in ('note_on', 'note_off'):
yield message

#anykeys demosweep, not necessary but it's nice
def CoolDemoSweep(loopcount):
speed = 0.01
for loop in range(0,loopcount):
for x in range(0, numkeys):
bufferC = [0x00] * 3 * numkeys
bufferC[0] = 0x82
bufferC[x*3-2] = 0xFF
kontrol.write(bufferC)
time.sleep(speed)
for x in range(numkeys, 0,-1):
bufferC = [0x00] * 3 * numkeys
bufferC[0] = 0x82
bufferC[x*3-2] = 0xFF
kontrol.write(bufferC)
time.sleep(speed)
notes_off()

def midi_connection():
ports = mido.get_input_names()
for port in ports: #cycle through all ports until Komplete Kontrol is found
CoolDemoSweep(1) # Sweep 1x Red on the keys for fun
if "Komplete Kontrol" in port:
portName = port
print ("Listening to Midi")
with mido.open_input(portName) as midiPort:
black = [0x00] * 3 #color, R + G + B (in this case black)
colors = black * numkeys #sets the color to all 88 keys (when it gets written to kontrol)
#the color has to be sent in to the input function for multiple keys to light up at the same time
for message in accept_notes(midiPort): #detects input on KK
print('Received {}'.format(message))
input(message.note, message.type, message.velocity, colors)

def input(note,status,velocity,colors):
key = note-offset
black = [0x00] * 3
color = [0xFF] + [0x00] + [0x00] #the color to give the pressed key
#print(colors) #for troubleshooting
if status == 'note_on' :
colors[3*key:3*key+3]=color #set the three colorvalues of the key to desired color
if status == 'note_off' :
colors[3*key:3*key+3]=black #set the key back to black
kontrol.write([0x82] + colors) #changes the color of pressed key

init()

0 comments on commit 6ef6465

Please sign in to comment.