Skip to content

Commit d8aa28e

Browse files
committed
Merge branch 'beta'
2 parents 36fdc45 + b51979e commit d8aa28e

File tree

2 files changed

+250
-11
lines changed

2 files changed

+250
-11
lines changed

device_Komplete Kontrol.py

Lines changed: 85 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,18 @@
2121
import math
2222

2323
# Imports the low-level threading module
24-
import _thread
24+
# threading module isn't supported by FL's interpreter but _thread does
25+
# However, using _thread makes FL crash eventually at launch on Windows and it isn't compatible with the macOS Python interpreter
26+
# Using _dummy_thread instead
27+
import sys
28+
29+
if sys.platform == "win32":
30+
print("Windows OS detected. Imported _thread module.")
31+
import _thread
32+
33+
if sys.platform == "darwin":
34+
print("macOS detected. Imported _dummy_thread module.")
35+
import lib._dummy_thread as _thread
2536

2637
######################################################################################################################
2738
# User-editable constants for script customization
@@ -145,6 +156,37 @@ def updateMixerTracks(dataType: str, selectedTrack: int):
145156
nihia.mixerSetGraph(x - trackFirst, "PAN", mixer.getTrackPan(x))
146157

147158

159+
# Checks the track group once more to clean up the last two tracks
160+
if trackGroup == 15:
161+
162+
if dataType == "NAME":
163+
nihia.mixerSendInfo("NAME", 7, info="")
164+
165+
# Track 7 --> Current
166+
if dataType == "VOLUME":
167+
nihia.mixerSendInfo("VOLUME", 6, info=" ")
168+
nihia.mixerSendInfo("VOLUME", 7, info=" ")
169+
170+
if dataType == "PAN":
171+
nihia.mixerSendInfo("PAN", 6, info=" ")
172+
nihia.mixerSendInfo("PAN", 7, info=" ")
173+
174+
if dataType == "IS_MUTE":
175+
nihia.mixerSendInfo("IS_MUTE", 6, value=0)
176+
nihia.mixerSendInfo("IS_MUTE", 7, value=0)
177+
178+
if dataType == "IS_SOLO":
179+
nihia.mixerSendInfo("IS_SOLO", 6, value=0)
180+
nihia.mixerSendInfo("IS_SOLO", 7, value=0)
181+
182+
if dataType == "VOLUME_GRAPH":
183+
nihia.mixerSetGraph(6, "VOLUME", 0)
184+
nihia.mixerSetGraph(7, "VOLUME", 0)
185+
186+
if dataType == "PAN_GRAPH":
187+
nihia.mixerSetGraph(6, "PAN", 0)
188+
nihia.mixerSetGraph(7, "PAN", 0)
189+
148190

149191
def updateMixer():
150192
""" Updates every property of the mixer of the deivce but the peak values. """
@@ -181,10 +223,10 @@ def adjustMixer(knob: int, dataType: str, action: str, selectedTrack: int):
181223

182224
if dataType == "VOLUME":
183225
if action == "INCREASE":
184-
mixer.setTrackVolume(trackFirst + knob, mixer.getTrackVolume(trackFirst + knob) + 0.01)
226+
mixer.setTrackVolume(trackFirst + knob, mixer.getTrackVolume(trackFirst + knob) + 0.02)
185227

186228
if action == "DECREASE":
187-
mixer.setTrackVolume(trackFirst + knob, mixer.getTrackVolume(trackFirst + knob) - 0.01)
229+
mixer.setTrackVolume(trackFirst + knob, mixer.getTrackVolume(trackFirst + knob) - 0.02)
188230

189231
if dataType == "PAN":
190232
if action == "INCREASE":
@@ -567,11 +609,19 @@ def OnMidiIn(event):
567609

568610
if event.data1 == nihia.knobs.get("KNOB_7A") and event.data2 == nihia.knobs.get("INCREASE"):
569611
event.handled = True
570-
adjustMixer(6, "VOLUME", "INCREASE", mixer.trackNumber())
612+
# Handles track group 15 exception
613+
if math.trunc(1/8 * mixer.trackNumber()) == 15:
614+
return
615+
else:
616+
adjustMixer(6, "VOLUME", "INCREASE", mixer.trackNumber())
571617

572618
if event.data1 == nihia.knobs.get("KNOB_8A") and event.data2 == nihia.knobs.get("INCREASE"):
573619
event.handled = True
574-
adjustMixer(7, "VOLUME", "INCREASE", mixer.trackNumber())
620+
# Handles track group 15 exception
621+
if math.trunc(1/8 * mixer.trackNumber()) == 15:
622+
return
623+
else:
624+
adjustMixer(7, "VOLUME", "INCREASE", mixer.trackNumber())
575625

576626
# Normal knobs - decrease values
577627
if event.data1 == nihia.knobs.get("KNOB_1A") and event.data2 == nihia.knobs.get("DECREASE"):
@@ -600,11 +650,19 @@ def OnMidiIn(event):
600650

601651
if event.data1 == nihia.knobs.get("KNOB_7A") and event.data2 == nihia.knobs.get("DECREASE"):
602652
event.handled = True
603-
adjustMixer(6, "VOLUME", "DECREASE", mixer.trackNumber())
653+
# Handles track group 15 exception
654+
if math.trunc(1/8 * mixer.trackNumber()) == 15:
655+
return
656+
else:
657+
adjustMixer(6, "VOLUME", "DECREASE", mixer.trackNumber())
604658

605659
if event.data1 == nihia.knobs.get("KNOB_8A") and event.data2 == nihia.knobs.get("DECREASE"):
606660
event.handled = True
607-
adjustMixer(7, "VOLUME", "DECREASE", mixer.trackNumber())
661+
# Handles track group 15 exception
662+
if math.trunc(1/8 * mixer.trackNumber()) == 15:
663+
return
664+
else:
665+
adjustMixer(7, "VOLUME", "DECREASE", mixer.trackNumber())
608666

609667

610668

@@ -635,11 +693,19 @@ def OnMidiIn(event):
635693

636694
if event.data1 == nihia.knobs.get("KNOB_7B") and event.data2 == nihia.knobs.get("INCREASE"):
637695
event.handled = True
638-
adjustMixer(6, "PAN", "INCREASE", mixer.trackNumber())
696+
# Handles track group 15 exception
697+
if math.trunc(1/8 * mixer.trackNumber()) == 15:
698+
return
699+
else:
700+
adjustMixer(6, "PAN", "INCREASE", mixer.trackNumber())
639701

640702
if event.data1 == nihia.knobs.get("KNOB_8B") and event.data2 == nihia.knobs.get("INCREASE"):
641703
event.handled = True
642-
adjustMixer(7, "PAN", "INCREASE", mixer.trackNumber())
704+
# Handles track group 15 exception
705+
if math.trunc(1/8 * mixer.trackNumber()) == 15:
706+
return
707+
else:
708+
adjustMixer(7, "PAN", "INCREASE", mixer.trackNumber())
643709

644710
# Shifted knobs - decrease values
645711
if event.data1 == nihia.knobs.get("KNOB_1B") and event.data2 == nihia.knobs.get("DECREASE"):
@@ -668,11 +734,19 @@ def OnMidiIn(event):
668734

669735
if event.data1 == nihia.knobs.get("KNOB_7B") and event.data2 == nihia.knobs.get("DECREASE"):
670736
event.handled = True
671-
adjustMixer(6, "PAN", "DECREASE", mixer.trackNumber())
737+
# Handles track group 15 exception
738+
if math.trunc(1/8 * mixer.trackNumber()) == 15:
739+
return
740+
else:
741+
adjustMixer(6, "PAN", "DECREASE", mixer.trackNumber())
672742

673743
if event.data1 == nihia.knobs.get("KNOB_8B") and event.data2 == nihia.knobs.get("DECREASE"):
674744
event.handled = True
675-
adjustMixer(7, "PAN", "DECREASE", mixer.trackNumber())
745+
# Handles track group 15 exception
746+
if math.trunc(1/8 * mixer.trackNumber()) == 15:
747+
return
748+
else:
749+
adjustMixer(7, "PAN", "DECREASE", mixer.trackNumber())
676750

677751
######################################################################################################################
678752
# Script logic

lib/_dummy_thread.py

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
# Copyright © 2001-2020 Python Software Foundation; All Rights Reserved
2+
3+
"""Drop-in replacement for the thread module.
4+
5+
Meant to be used as a brain-dead substitute so that threaded code does
6+
not need to be rewritten for when the thread module is not present.
7+
8+
Suggested usage is::
9+
10+
try:
11+
import _thread
12+
except ImportError:
13+
import _dummy_thread as _thread
14+
15+
"""
16+
# Exports only things specified by thread documentation;
17+
# skipping obsolete synonyms allocate(), start_new(), exit_thread().
18+
__all__ = ['error', 'start_new_thread', 'exit', 'get_ident', 'allocate_lock',
19+
'interrupt_main', 'LockType']
20+
21+
# A dummy value
22+
TIMEOUT_MAX = 2**31
23+
24+
# NOTE: this module can be imported early in the extension building process,
25+
# and so top level imports of other modules should be avoided. Instead, all
26+
# imports are done when needed on a function-by-function basis. Since threads
27+
# are disabled, the import lock should not be an issue anyway (??).
28+
29+
error = RuntimeError
30+
31+
def start_new_thread(function, args, kwargs={}):
32+
"""Dummy implementation of _thread.start_new_thread().
33+
34+
Compatibility is maintained by making sure that ``args`` is a
35+
tuple and ``kwargs`` is a dictionary. If an exception is raised
36+
and it is SystemExit (which can be done by _thread.exit()) it is
37+
caught and nothing is done; all other exceptions are printed out
38+
by using traceback.print_exc().
39+
40+
If the executed function calls interrupt_main the KeyboardInterrupt will be
41+
raised when the function returns.
42+
43+
"""
44+
if type(args) != type(tuple()):
45+
raise TypeError("2nd arg must be a tuple")
46+
if type(kwargs) != type(dict()):
47+
raise TypeError("3rd arg must be a dict")
48+
global _main
49+
_main = False
50+
try:
51+
function(*args, **kwargs)
52+
except SystemExit:
53+
pass
54+
except:
55+
import traceback
56+
traceback.print_exc()
57+
_main = True
58+
global _interrupt
59+
if _interrupt:
60+
_interrupt = False
61+
raise KeyboardInterrupt
62+
63+
def exit():
64+
"""Dummy implementation of _thread.exit()."""
65+
raise SystemExit
66+
67+
def get_ident():
68+
"""Dummy implementation of _thread.get_ident().
69+
70+
Since this module should only be used when _threadmodule is not
71+
available, it is safe to assume that the current process is the
72+
only thread. Thus a constant can be safely returned.
73+
"""
74+
return -1
75+
76+
def allocate_lock():
77+
"""Dummy implementation of _thread.allocate_lock()."""
78+
return LockType()
79+
80+
def stack_size(size=None):
81+
"""Dummy implementation of _thread.stack_size()."""
82+
if size is not None:
83+
raise error("setting thread stack size not supported")
84+
return 0
85+
86+
def _set_sentinel():
87+
"""Dummy implementation of _thread._set_sentinel()."""
88+
return LockType()
89+
90+
class LockType(object):
91+
"""Class implementing dummy implementation of _thread.LockType.
92+
93+
Compatibility is maintained by maintaining self.locked_status
94+
which is a boolean that stores the state of the lock. Pickling of
95+
the lock, though, should not be done since if the _thread module is
96+
then used with an unpickled ``lock()`` from here problems could
97+
occur from this class not having atomic methods.
98+
99+
"""
100+
101+
def __init__(self):
102+
self.locked_status = False
103+
104+
def acquire(self, waitflag=None, timeout=-1):
105+
"""Dummy implementation of acquire().
106+
107+
For blocking calls, self.locked_status is automatically set to
108+
True and returned appropriately based on value of
109+
``waitflag``. If it is non-blocking, then the value is
110+
actually checked and not set if it is already acquired. This
111+
is all done so that threading.Condition's assert statements
112+
aren't triggered and throw a little fit.
113+
114+
"""
115+
if waitflag is None or waitflag:
116+
self.locked_status = True
117+
return True
118+
else:
119+
if not self.locked_status:
120+
self.locked_status = True
121+
return True
122+
else:
123+
if timeout > 0:
124+
import time
125+
time.sleep(timeout)
126+
return False
127+
128+
__enter__ = acquire
129+
130+
def __exit__(self, typ, val, tb):
131+
self.release()
132+
133+
def release(self):
134+
"""Release the dummy lock."""
135+
# XXX Perhaps shouldn't actually bother to test? Could lead
136+
# to problems for complex, threaded code.
137+
if not self.locked_status:
138+
raise error
139+
self.locked_status = False
140+
return True
141+
142+
def locked(self):
143+
return self.locked_status
144+
145+
def __repr__(self):
146+
return "<%s %s.%s object at %s>" % (
147+
"locked" if self.locked_status else "unlocked",
148+
self.__class__.__module__,
149+
self.__class__.__qualname__,
150+
hex(id(self))
151+
)
152+
153+
# Used to signal that interrupt_main was called in a "thread"
154+
_interrupt = False
155+
# True when not executing in a "thread"
156+
_main = True
157+
158+
def interrupt_main():
159+
"""Set _interrupt flag to True to have start_new_thread raise
160+
KeyboardInterrupt upon exiting."""
161+
if _main:
162+
raise KeyboardInterrupt
163+
else:
164+
global _interrupt
165+
_interrupt = True

0 commit comments

Comments
 (0)