-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSinefeld.py
69 lines (56 loc) · 3.97 KB
/
Sinefeld.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# Christoph Aurnhammer, 2023
# MIT License
# Six LFOs with increasing speed - inspired by Divkid/Instruo Ochd
# LFO2-6 speeds are integer multiples of LFO 1.
# Left knob + analogue in = global speed control
import math
from europi import *
from europi_script import EuroPiScript
class OledWrapper:
def __init__(self):
oled.fill(0)
self.is_inverted = False
def toggle_invert(self):
if self.is_inverted == False:
oled.invert(1)
self.is_inverted = True
else:
oled.invert(0)
self.is_inverted = False
def logo(self):
img = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00|\x10\x03\xf0\x01\xfc\x00\x01\xfe\x81\x00\x00\x00\x00\x00\x01\x9c\x00\x01\xf0\x00|\x00\x07\x8f\xbf\xc0\x00\x00\x00\x00\x07<\x01\x01\xf0\x00x\x00\x0e\x07\xdf\x80\x00\x00\x00\x00\x0f|\x00\x03\xe0\x00\xf8\x00\x1c\x03\x0f\x00\x00\x00\x00\x00\x1ep\x00\x03\xc0\x01\xf0\x00<\x0b\x00\x00\x00\x00\x00\x00>\x00\x00\'\xc0\x01\xf0\x00|"\x00\x00\x00\x00\x00\x00|\x00\x00\x07\x80\x01\xe0\x00~\x00\x00\x00\x00\x00\x00\x00x\x00\x00\x1f\x80\x03\xe0\x00\xff\x80\x00\x00\x00\x00\x00\x00\xf8\x00\x00\x1f\x00\x07\xc0\x00\xff\xc0\x7f\x0f\xc7\xc0?\x87\xfe\x03\xf0\x1f\x01\xe7\xc0\x00\x7f\xe0\x1f\x07\xd3\xe0\xe1\xc1\xf0\x1c8\x1e\x0e\x1f\x80\x00\x7f\xf0>\x07\x83\xc3\xc1\xc1\xe088>\x1e\x1f\x00\x00?\xf0>\x0f\x87\xc7\xc3\xc3\xe0\xf8x|<\x1f\x00\x00\x0f\xf0|\x0f\x87\x8f\x87\xc3\xc1\xf0x||\x1e\x00\x00#\xf0x\x1f\x0f\x8f\xff\x87\xc1\xff\xf1\xf8\xf8>\x00\x0c#\xe0\xf8\x1e\x0f\x1f\x00\x0f\x83\xe0\x02\xf9\xf8<\x00\x08#\xe0\xf0>\x1f?\x00\x0f\x83\xe0\x01\xf1\xf0|\x00\x18\x03\xc1\xf0<\x1e>\x01\x0f\x07\xc0\x01\xe1\xf0x\x00<\x17\x81\xe0|>>\x02\x1f\x07\xc0C\xe1\xe0\xf8\x00<\x0f\x03\xe0x<<\x04>\x07\x80\x83\xc1\xc1\xf0\x00o<\x03\xc0\xf8|\x1c\x10<\x03\x8b\x07\xc1\xc7\xf0\x00G\xf2\x1f\xf7\xfd\xfe\x0f\xc1\xff\x01\xfc\x1f\xe0\xf9\xf8\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00`\x00\x00\x00\x01\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc0\x00\x03\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
imgBA = bytearray(img)
imgFB = FrameBuffer(imgBA, 128, 32, MONO_HLSB)
oled.blit(imgFB,0,0)
oled.show()
class Sinefeld(EuroPiScript):
def __init__(self):
self.my_oled = OledWrapper()
def scale(self, lfo_states):
return [(x + 1) * 5 for x in lfo_states]
def get_states(self, freq_mults, t_vec, mode):
states = [math.sin(2 * math.pi * freq * t) for freq, t in zip(freq_mults, t_vec)]
if mode == "square":
square = {True: 1, False: -1} # To do: define just once at beginning. probably make part of object
states = [square[x > 0] for x in states]
return states
def cycle(self, freq_mults, t_vec, verbose = False):
speed = k1.read_position() + 0.01 + ain.percent() * 100 # smoothing to avoid mult by zero
lfo_states = self.scale(self.get_states(freq_mults, t_vec, mode="sine"))
if verbose:
print(lfo_states)
[cv.voltage(lfo) for cv, lfo in zip(cvs, lfo_states)]
t_vec = [t + speed / 10000 for t in t_vec]
for t in t_vec:
if t >= 1:
t = 0
return t_vec
def main(self):
freq_mults = [1, 2, 3, 4, 6, 8]
t_vec = [0, 0, 0, 0, 0, 0]
self.my_oled.logo()
while True:
t_vec = self.cycle(freq_mults, t_vec, verbose = False)
if __name__ == "__main__":
sinefeld = Sinefeld()
sinefeld.main()