feat: live fx/mix values from time/beats

This commit is contained in:
2026-11-02 13:07:02 +01:00
parent 009dd8dcb3
commit 3d50717dbe
3 changed files with 148 additions and 11 deletions
+3
View File
@@ -84,10 +84,13 @@ def __get_running_display(data: ForgeData) -> Image.Image:
draw2.text((45, 44), hex(data.frag_state(3))[2].upper(), fill="white", font=FONT_2)
draw2.text((103, 32), hex(data.frag_state(5))[2].upper(), fill="white", font=FONT_2)
# TODO print when random
# TODO print when inverted
draw2.text((74, 32), "K" if data.mix_mode_key else "M", fill="white", font=FONT_2)
# TODO show feedback
# TODO show blank out
# TODO show inverted out
return __xor(im, im_overlay)
+24 -11
View File
@@ -4,6 +4,7 @@ import typing
from .constants import FORGE_SAVE_BACKUP_PATH, FORGE_SAVE_PATH, MOCK_SAVE_PATH
from .enums import ForgeState
from .glsl_funcs import fract, magic, magic_trigger
class ForgeRawData:
@@ -77,13 +78,16 @@ class ForgeData:
def active(self, n: int) -> int:
return int(self.__data[f"active_{n}"])
def seed(self, n: int) -> int:
return int(self.__data[f"seed_{n}"])
@property
def time(self) -> float:
return self.__data["time"]
@property
def time_progress(self) -> float:
return self.time - int(self.time)
return fract(self.time)
@property
def tempo(self) -> float:
@@ -95,7 +99,7 @@ class ForgeData:
@property
def beat_progress(self) -> float:
return self.beats - int(self.beats)
return fract(self.beats)
@property
def page(self) -> int:
@@ -107,24 +111,33 @@ class ForgeData:
@property
def fxa_value(self) -> float:
# todo random and time based
return self.value(18)[0]
return magic(
self.time, self.beats, self.value(18), (1.0, 0.0, 0.0), self.seed(2)
)
@property
def fxb_value(self) -> float:
return self.value(25)[0]
@property
def mfx_value(self) -> float:
return self.value(32)[0]
return magic(
self.time, self.beats, self.value(25), (1.0, 0.0, 0.0), self.seed(3)
)
@property
def mix_value(self) -> float:
return self.value(34)[0]
return magic(
self.time, self.beats, self.value(34), (1.0, 0.0, 0.0), self.seed(4)
)
@property
def mix_mode_key(self) -> bool:
return self.value(33)[0] > 0.
return magic_trigger(
self.time, self.beats, (self.value(33)[0], 0.0, 0.0), self.seed(4) + 10.0
)
@property
def mfx_value(self) -> float:
return magic(
self.time, self.beats, self.value(32), (1.0, 0.0, 0.0), self.seed(5)
)
def mock(self) -> typing.Self:
self.__data.read(MOCK_SAVE_PATH)
+121
View File
@@ -0,0 +1,121 @@
from math import cos, floor, sin
# glsl base
PI = 3.1415927
def mod(x: float, y: float) -> float:
return x % y
def fract(x: float) -> float:
return mod(x, 1.0)
def mix(x: float, y: float, a: float) -> float:
if a <= 0.0:
return x
if a >= 1.0:
return y
return x + (y - x) * a
def step(edge: float, x: float) -> float:
if x < edge:
return 0.0
return 1.0
# inc_rand.glsl
RAND_C = 43758.5453
def rand(seed: float) -> float:
return fract(sin(seed) * RAND_C)
# inc_time.glsl
def rand_time(itime: float, ibeats: float, seed: float, beats: int = 4) -> float:
return rand(seed + floor(ibeats / beats))
def divider(x: float) -> float:
if x < 0.1:
return 0.0
if x < 0.2:
return 0.125
if x < 0.3:
return 0.25
if x < 0.4:
return 0.5
if x < 0.6:
return 1.0
if x < 0.8:
return 2.0
return 4.0
def mod_time(ibeats: float, k: float, k2: float = 1.0) -> float:
return mod(divider(k) * ibeats * k2 * 0.25, 1.0)
def cos_time(ibeats: float, k: float) -> float:
return cos(mod_time(ibeats, k, 5.0) * 2.0 * PI)
# inc_magic.glsl
def magic_f(
itime: float,
ibeats: float,
f: tuple[float, float, float],
b: tuple[float, float, float],
i: float,
) -> tuple[float, float]:
return (
mix(f[0], rand_time(itime, ibeats, i + 1.0), min(1.0, b[2])),
mix(f[1], rand_time(itime, ibeats, i + 2.0), min(1.0, b[2])),
)
def magic_b(
itime: float, ibeats: float, b: tuple[float, float, float], i: float
) -> tuple[float, float, float]:
return (
mix(b[0], step(0.2, rand_time(itime, ibeats, i + 3.0)), min(1.0, b[2])),
mix(b[1], step(0.5, rand_time(itime, ibeats, i + 4.0)), min(1.0, b[2])),
min(1.0, b[2]),
)
def magic_trigger(
itime: float, ibeats: float, b: tuple[float, float, float], i: float
) -> bool:
return magic_b(itime, ibeats, b, i)[0] > 0.0
def magic(
itime: float,
ibeats: float,
f: tuple[float, float, float],
b: tuple[float, float, float],
i: float,
) -> float:
mf = magic_f(itime, ibeats, f, b, i)
mb = magic_b(itime, ibeats, b, i)
return mix(
0.0,
mf[0]
* mix(
1.0 - mod_time(ibeats, mf[1]),
cos_time(ibeats, mf[1]) * 0.5 + 0.5,
mb[1],
),
mb[0],
)