Finished K-Fêt config
This commit is contained in:
commit
6bcd0af329
36 changed files with 1334 additions and 0 deletions
9
eos_midi/__init__.py
Normal file
9
eos_midi/__init__.py
Normal file
|
@ -0,0 +1,9 @@
|
|||
"""Top-level module"""
|
||||
|
||||
__author__ = """soyouzpanda"""
|
||||
__email__ = 'soyouzpanda@soyouzpanda.fr'
|
||||
__version__ = '0.1.0'
|
||||
|
||||
from .eos_object import *
|
||||
from .eos import *
|
||||
from .pad import *
|
202
eos_midi/__main__.py
Normal file
202
eos_midi/__main__.py
Normal file
|
@ -0,0 +1,202 @@
|
|||
"""Main module."""
|
||||
from .eos import EOSConnection
|
||||
from .pad import Pad, EventHandler
|
||||
from .eos_object import FaderBank, Fader, Macro
|
||||
from lpminimk3 import LaunchpadMiniMk3, find_launchpads, ButtonEvent, Mode
|
||||
|
||||
COLORS = [3, 21, 37, 45, 81, 95, 5, 9]
|
||||
FOCUS_MACROS = [901, 902, 903, 906]
|
||||
SELECT_MACROS = [304, 303, 305, 302, 301]
|
||||
SELECT_COLORS = [78, 21, 13, 5, 3]
|
||||
|
||||
|
||||
class AbstractColorEventHandler(EventHandler):
|
||||
"""Abstract color event handler"""
|
||||
def __init__(self, launchpad: LaunchpadMiniMk3, line: int, column: int):
|
||||
super().__init__(f'{column}x{line}')
|
||||
self._launchpad = launchpad
|
||||
self._line = line
|
||||
self._column = column
|
||||
self._launchpad.panel.led(
|
||||
self.button_name).color = COLORS[self._column]
|
||||
|
||||
def flash(self):
|
||||
"""Flash only the current button on the line"""
|
||||
for color in range(8):
|
||||
self._launchpad.panel.led(
|
||||
f'{color}x{self._line}').color = COLORS[color]
|
||||
self._launchpad.panel.led(self.button_name).reset()
|
||||
self._launchpad.panel.led(self.button_name,
|
||||
mode='flash').color = COLORS[self._column]
|
||||
|
||||
|
||||
class ColorBumpEventHandler(AbstractColorEventHandler):
|
||||
"""Bump button Event handler"""
|
||||
def __init__(self, fader_bank: FaderBank,
|
||||
launchpad: LaunchpadMiniMk3, color_id: int):
|
||||
super().__init__(launchpad, 5, color_id)
|
||||
self._fader = fader_bank.fader(14, color_id + 1)
|
||||
|
||||
def on_press(self, _: ButtonEvent):
|
||||
self._fader.fire(1.0)
|
||||
|
||||
def on_release(self, _: ButtonEvent):
|
||||
self._fader.fire(0.0)
|
||||
|
||||
|
||||
class ColorFxEventHandler(AbstractColorEventHandler):
|
||||
"""FX button Event handler"""
|
||||
def __init__(self, fader_bank: FaderBank,
|
||||
launchpad: LaunchpadMiniMk3, color_id: int):
|
||||
super().__init__(launchpad, 6, color_id)
|
||||
self._fader = fader_bank.fader(17, color_id + 1)
|
||||
|
||||
def on_press(self, _: ButtonEvent):
|
||||
self.flash()
|
||||
self._fader.fire()
|
||||
|
||||
|
||||
class ColorEventHandler(AbstractColorEventHandler):
|
||||
"""Non-FX button Event handler"""
|
||||
def __init__(self, fader_bank: FaderBank,
|
||||
launchpad: LaunchpadMiniMk3, color_id: int):
|
||||
super().__init__(launchpad, 7, color_id)
|
||||
self._fader = fader_bank.fader(18, color_id + 1)
|
||||
|
||||
def on_press(self, _: ButtonEvent):
|
||||
self.flash()
|
||||
self._fader.fire()
|
||||
|
||||
|
||||
class FocusEventHandler(EventHandler):
|
||||
"""Focus event handler"""
|
||||
def __init__(self, eos: EOSConnection,
|
||||
launchpad: LaunchpadMiniMk3, column: int):
|
||||
super().__init__(f'{column}x2')
|
||||
self._macro = eos.macro(FOCUS_MACROS[column])
|
||||
self._launchpad = launchpad
|
||||
self._launchpad.panel.led(self.button_name).color = 5
|
||||
|
||||
def on_press(self, _: ButtonEvent):
|
||||
for col in range(4):
|
||||
self._launchpad.panel.led(f'{col}x2').color = 5
|
||||
self._launchpad.panel.led(self.button_name).reset()
|
||||
self._launchpad.panel.led(self.button_name,
|
||||
mode='flash').color = 5
|
||||
|
||||
self._macro.fire()
|
||||
|
||||
|
||||
class SimpleFaderEventHandler(EventHandler):
|
||||
"""Simple fader Event handler"""
|
||||
def __init__(self, fader: Fader,
|
||||
launchpad: LaunchpadMiniMk3,
|
||||
button: str, color: int):
|
||||
super().__init__(button)
|
||||
launchpad.panel.led(button).color = color
|
||||
self._fader = fader
|
||||
|
||||
def on_press(self, _: ButtonEvent):
|
||||
self._fader.fire(1.0)
|
||||
|
||||
def on_release(self, _: ButtonEvent):
|
||||
self._fader.fire(0.0)
|
||||
|
||||
|
||||
class SimpleMacroEventHandler(EventHandler):
|
||||
"""Simple macro Event handler"""
|
||||
def __init__(self, macro: Macro,
|
||||
launchpad: LaunchpadMiniMk3,
|
||||
button: str, color: int):
|
||||
super().__init__(button)
|
||||
launchpad.panel.led(button).color = color
|
||||
self._macro = macro
|
||||
|
||||
def on_press(self, _: ButtonEvent):
|
||||
self._macro.fire()
|
||||
|
||||
|
||||
class SelectEventHandler(EventHandler):
|
||||
"""Select Event handler"""
|
||||
def __init__(self, eos: EOSConnection,
|
||||
launchpad: LaunchpadMiniMk3,
|
||||
select_id: int):
|
||||
super().__init__(f'{select_id + 3}x0')
|
||||
self._launchpad = launchpad
|
||||
self._select_id = select_id
|
||||
self._macro = eos.macro(SELECT_MACROS[self._select_id])
|
||||
self._launchpad.panel.led(
|
||||
self.button_name).color = SELECT_COLORS[self._select_id]
|
||||
|
||||
def on_press(self, _: ButtonEvent):
|
||||
for i in range(3, 8):
|
||||
self._launchpad.panel.led(
|
||||
f'{i}x0').color = SELECT_COLORS[i - 3]
|
||||
self._launchpad.panel.led(
|
||||
self.button_name).reset()
|
||||
self._launchpad.panel.led(
|
||||
self.button_name,
|
||||
mode='flash').color = SELECT_COLORS[self._select_id]
|
||||
self._macro.fire()
|
||||
|
||||
|
||||
def main():
|
||||
"""main function"""
|
||||
launchpad = find_launchpads()[0]
|
||||
launchpad.open()
|
||||
launchpad.mode = Mode.PROG
|
||||
launchpad.panel.reset()
|
||||
launchpad.clear_event_queue()
|
||||
|
||||
eos = EOSConnection("192.168.50.36", 8000)
|
||||
faderbank = eos.fader_bank()
|
||||
|
||||
pad = Pad(launchpad)
|
||||
|
||||
# 6è-7è-8è ligne
|
||||
|
||||
for i in range(8):
|
||||
pad.add_event_handler(ColorBumpEventHandler(faderbank, launchpad, i))
|
||||
pad.add_event_handler(ColorFxEventHandler(faderbank, launchpad, i))
|
||||
pad.add_event_handler(ColorEventHandler(faderbank, launchpad, i))
|
||||
|
||||
# 3è ligne
|
||||
|
||||
for i in range(4):
|
||||
pad.add_event_handler(FocusEventHandler(eos, launchpad, i))
|
||||
pad.add_event_handler(SimpleFaderEventHandler(
|
||||
faderbank.fader(6, 7), launchpad, '4x2', 9))
|
||||
pad.add_event_handler(SimpleFaderEventHandler(
|
||||
faderbank.fader(5, 2), launchpad, '6x2', 4))
|
||||
pad.add_event_handler(SimpleFaderEventHandler(
|
||||
faderbank.fader(5, 4), launchpad, '7x2', 4))
|
||||
|
||||
# 2è ligne
|
||||
pad.add_event_handler(SimpleFaderEventHandler(
|
||||
faderbank.fader(5, 5), launchpad, '0x1', 21))
|
||||
pad.add_event_handler(SimpleFaderEventHandler(
|
||||
faderbank.fader(5, 6), launchpad, '1x1', 88))
|
||||
pad.add_event_handler(SimpleFaderEventHandler(
|
||||
faderbank.fader(7, 1), launchpad, '2x1', 78))
|
||||
pad.add_event_handler(SimpleFaderEventHandler(
|
||||
faderbank.fader(7, 2), launchpad, '3x1', 32))
|
||||
pad.add_event_handler(SimpleMacroEventHandler(
|
||||
eos.macro(401), launchpad, '5x1', 95))
|
||||
pad.add_event_handler(SimpleMacroEventHandler(
|
||||
eos.macro(402), launchpad, '6x1', 95))
|
||||
pad.add_event_handler(SimpleMacroEventHandler(
|
||||
eos.macro(403), launchpad, '7x1', 95))
|
||||
|
||||
# 1ère ligne
|
||||
|
||||
pad.add_event_handler(SimpleMacroEventHandler(
|
||||
eos.macro(6), launchpad, '0x0', 3))
|
||||
for i in range(5):
|
||||
pad.add_event_handler(SelectEventHandler(
|
||||
eos, launchpad, i))
|
||||
|
||||
pad.serve_forever()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
23
eos_midi/eos.py
Normal file
23
eos_midi/eos.py
Normal file
|
@ -0,0 +1,23 @@
|
|||
"""EOS"""
|
||||
from pythonosc.udp_client import SimpleUDPClient
|
||||
from .eos_object.fader import FaderBank
|
||||
from .eos_object.channel import Channel
|
||||
from .eos_object.macro import Macro
|
||||
|
||||
|
||||
class EOSConnection:
|
||||
"""EOS Connection"""
|
||||
def __init__(self, address: str, port: int):
|
||||
self.osc_client = SimpleUDPClient(address, port)
|
||||
|
||||
def fader_bank(self):
|
||||
"""Returns the FaderBank"""
|
||||
return FaderBank(self.osc_client)
|
||||
|
||||
def channel(self, channel_id: int):
|
||||
"""Returns the Channel {channel_id}"""
|
||||
return Channel(channel_id, self.osc_client)
|
||||
|
||||
def macro(self, macro_id: int):
|
||||
"""Returns the Macro {macro_id}"""
|
||||
return Macro(macro_id, self.osc_client)
|
3
eos_midi/eos_object/__init__.py
Normal file
3
eos_midi/eos_object/__init__.py
Normal file
|
@ -0,0 +1,3 @@
|
|||
from .channel import *
|
||||
from .fader import *
|
||||
from .macro import *
|
29
eos_midi/eos_object/channel.py
Normal file
29
eos_midi/eos_object/channel.py
Normal file
|
@ -0,0 +1,29 @@
|
|||
"""EOS Channel"""
|
||||
from pythonosc.udp_client import SimpleUDPClient
|
||||
|
||||
|
||||
class Channel:
|
||||
"""EOS Channel"""
|
||||
def __init__(self, channel_id: int, osc_client: SimpleUDPClient):
|
||||
self.channel_id = channel_id
|
||||
self.osc_client = osc_client
|
||||
|
||||
def full(self):
|
||||
"""Sets channel intensity to full"""
|
||||
self.osc_client.send_message(f"/eos/chan/{self.channel_id}/full", [])
|
||||
|
||||
def min(self):
|
||||
"""Sets channel intensity to min"""
|
||||
self.osc_client.send_message(f"/eos/chan/{self.channel_id}/min", [])
|
||||
|
||||
def max(self):
|
||||
"""Sets channel intensity to max"""
|
||||
self.osc_client.send_message(f"/eos/chan/{self.channel_id}/max", [])
|
||||
|
||||
def plus_10(self):
|
||||
"""Increases channel intensity by 10%"""
|
||||
self.osc_client.send_message(f"/eos/chan/{self.channel_id}/+%", [])
|
||||
|
||||
def minus_10(self):
|
||||
"""Decreases channel intensity by 10%"""
|
||||
self.osc_client.send_message(f"/eos/chan/{self.channel_id}/-%", [])
|
87
eos_midi/eos_object/fader.py
Normal file
87
eos_midi/eos_object/fader.py
Normal file
|
@ -0,0 +1,87 @@
|
|||
"""EOS Fader"""
|
||||
from typing import Optional
|
||||
from pythonosc.udp_client import SimpleUDPClient
|
||||
|
||||
|
||||
class FaderBank:
|
||||
"""EOS Fader bank"""
|
||||
def __init__(self, osc_client: SimpleUDPClient):
|
||||
self.osc_client = osc_client
|
||||
for i in range(1, 101):
|
||||
self.osc_client.send_message(
|
||||
f"/eos/fader/{i}/config/{i}/10", [])
|
||||
|
||||
def page(self, page: int):
|
||||
"""Returns the page {page}"""
|
||||
return FaderPage(page, self.osc_client)
|
||||
|
||||
def fader(self, page: int, fader: int):
|
||||
"""Returns the fader {fader} of page {page}"""
|
||||
return FaderPage(page, self.osc_client).fader(fader)
|
||||
|
||||
|
||||
class FaderPage:
|
||||
"""EOS Fader page"""
|
||||
def __init__(self, page: int, osc_client: SimpleUDPClient):
|
||||
self.page = page
|
||||
self.osc_client = osc_client
|
||||
|
||||
def fader(self, fader: int):
|
||||
"""Returns the fader {fader} of the page"""
|
||||
return Fader(self.page, fader, self.osc_client)
|
||||
|
||||
def next(self):
|
||||
"""Returns the next page"""
|
||||
return FaderPage(min(100, self.page + 1), self.osc_client)
|
||||
|
||||
def previous(self):
|
||||
"""Returns the previous page"""
|
||||
return FaderPage(max(1, self.page - 1), self.osc_client)
|
||||
|
||||
|
||||
class Fader:
|
||||
"""EOS Fader"""
|
||||
def __init__(self, page: int, fader: int,
|
||||
osc_client: SimpleUDPClient):
|
||||
self.page = page
|
||||
self.fader = fader
|
||||
self.osc_client = osc_client
|
||||
|
||||
def fire(self, value: Optional[float] = None):
|
||||
"""Starts effect of the fader"""
|
||||
if value:
|
||||
self.osc_client.send_message(
|
||||
f"/eos/fader/{self.page}/{self.fader}/fire", [value])
|
||||
else:
|
||||
self.osc_client.send_message(
|
||||
f"/eos/fader/{self.page}/{self.fader}/fire", [])
|
||||
|
||||
def stop(self):
|
||||
"""Stops effect of the fader"""
|
||||
self.osc_client.send_message(
|
||||
f"/eos/fader/{self.page}/{self.fader}/stop", [])
|
||||
|
||||
def full(self):
|
||||
"""Sets the fader to full"""
|
||||
self.osc_client.send_message(
|
||||
f"/eos/fader/{self.page}/{self.fader}/full", [])
|
||||
|
||||
def min(self):
|
||||
"""Sets the fader to minimum"""
|
||||
self.osc_client.send_message(
|
||||
f"/eos/fader/{self.page}/{self.fader}/min", [])
|
||||
|
||||
def max(self):
|
||||
"""Sets the fader to maximum"""
|
||||
self.osc_client.send_message(
|
||||
f"/eos/fader/{self.page}/{self.fader}/max", [])
|
||||
|
||||
def plus_10(self):
|
||||
"""Increases the fader by 10%"""
|
||||
self.osc_client.send_message(
|
||||
f"/eos/fader/{self.page}/{self.fader}/+%", [])
|
||||
|
||||
def minus_10(self):
|
||||
"""Decreases the fader by 10%"""
|
||||
self.osc_client.send_message(
|
||||
f"/eos/fader/{self.page}/{self.fader}/-%", [])
|
13
eos_midi/eos_object/macro.py
Normal file
13
eos_midi/eos_object/macro.py
Normal file
|
@ -0,0 +1,13 @@
|
|||
""""EOS Macro"""
|
||||
from pythonosc.udp_client import SimpleUDPClient
|
||||
|
||||
|
||||
class Macro:
|
||||
"""EOS Macro"""
|
||||
def __init__(self, macro_id: int, osc_client: SimpleUDPClient):
|
||||
self.macro_id = macro_id
|
||||
self.osc_client = osc_client
|
||||
|
||||
def fire(self):
|
||||
"""Fires macro"""
|
||||
self.osc_client.send_message(f"/eos/macro/{self.macro_id}/fire", [])
|
3
eos_midi/midi_controller.py
Normal file
3
eos_midi/midi_controller.py
Normal file
|
@ -0,0 +1,3 @@
|
|||
"""MIDI Controller, Launchpad Mini MK3"""
|
||||
from lpminimk3 import Mode, find_launchpad
|
||||
|
74
eos_midi/pad.py
Normal file
74
eos_midi/pad.py
Normal file
|
@ -0,0 +1,74 @@
|
|||
"""Launchpad"""
|
||||
from lpminimk3 import LaunchpadMiniMk3, ButtonEvent
|
||||
|
||||
VALID_BUTTONS = [
|
||||
'up', 'down', 'left', 'right', 'session', 'drums', 'keys', 'user',
|
||||
'scene_launch_1', 'scene_launch_2', 'scene_launch_3', 'scene_launch_4',
|
||||
'scene_launch_5', 'scene_launch_6', 'scene_launch_7', 'stop_solo_mute',
|
||||
]
|
||||
|
||||
|
||||
class EventHandler:
|
||||
"""Event handler for launchpad"""
|
||||
def __init__(self, button_name: str):
|
||||
self._button_name = button_name
|
||||
|
||||
@property
|
||||
def button_name(self):
|
||||
"""Returns button name"""
|
||||
return self._button_name
|
||||
|
||||
def on_press(self, _: ButtonEvent):
|
||||
"""On button pressed"""
|
||||
|
||||
def on_release(self, _: ButtonEvent):
|
||||
"""On button released"""
|
||||
|
||||
|
||||
class Pad:
|
||||
"""Pad Wrapper"""
|
||||
def __init__(self, launchpad: LaunchpadMiniMk3):
|
||||
self._launchpad = launchpad
|
||||
self._event_handlers: dict[str, list[EventHandler]] = {}
|
||||
|
||||
def _validate_button(self, button: str | tuple[int, int]) -> str:
|
||||
if isinstance(button, str):
|
||||
if button in VALID_BUTTONS:
|
||||
return button
|
||||
split = button.split('x')
|
||||
if len(split) == 2 and \
|
||||
split[0].isdigit() and split[1].isdigit() and \
|
||||
int(split[0]) >= 0 and int(split[0]) < 8 and \
|
||||
int(split[1]) >= 0 and int(split[1]) < 8:
|
||||
return button
|
||||
raise ValueError(button)
|
||||
if isinstance(button, tuple) and len(button) == 2 and \
|
||||
isinstance(button[0], int) and isinstance(button[1], int) and \
|
||||
button[0] >= 0 and button[0] < 8 and \
|
||||
button[1] >= 0 and button[1] < 8:
|
||||
return str(button[0]) + 'x' + str(button[1])
|
||||
raise ValueError(button)
|
||||
|
||||
def add_event_handler(self, handler: EventHandler):
|
||||
"""Adds a event handler"""
|
||||
button = self._validate_button(handler.button_name)
|
||||
lst = self._event_handlers.get(button)
|
||||
if lst:
|
||||
lst.append(handler)
|
||||
else:
|
||||
self._event_handlers[button] = [handler]
|
||||
|
||||
def serve_forever(self):
|
||||
"""Servers forever"""
|
||||
buttons = self._launchpad.panel.buttons()
|
||||
while True:
|
||||
event = buttons.poll_for_event()
|
||||
if isinstance(event, ButtonEvent):
|
||||
if event.type == ButtonEvent.PRESS:
|
||||
for handler in self._event_handlers.get(
|
||||
event.button.name, []):
|
||||
handler.on_press(event)
|
||||
elif event.type == ButtonEvent.RELEASE:
|
||||
for handler in self._event_handlers.get(
|
||||
event.button.name, []):
|
||||
handler.on_release(event)
|
Loading…
Add table
Add a link
Reference in a new issue