git.s-ol.nu hw/0x33.board/firmware / main
disable synth if synthio unavailable s-ol 8 days ago
3 changed file(s) with 73 addition(s) and 35 deletion(s). Raw diff Collapse all Expand all
00 from __future__ import annotations
11
22 import displayio
3 import audiomixer
4 import synthio
53 from adafruit_ticks import ticks_ms
64 from adafruit_midi.system_exclusive import SystemExclusive
75 from adafruit_midi.note_on import NoteOn
1311 dev_mode = storage.getmount("/").readonly
1412 except:
1513 dev_mode = False
14
15 try:
16 import audiomixer
17 import synthio
18 except:
19 synthio = None
1620
1721 from .core import Mode, Note
1822 from .matrix import Matrix
7478 self.i2c = None
7579
7680 self.audio_out = board.create_audio_out(self)
77 self.mixer = audiomixer.Mixer(
78 sample_rate=41100, buffer_size=5120, channel_count=1
79 )
80
81 self.synth = synthio.Synthesizer(sample_rate=41100)
82 self.filter = self.synth.low_pass_filter(2000, 0.8)
81
82 if synthio:
83 self.synth = synthio.Synthesizer(sample_rate=41100)
84 self.mixer = audiomixer.Mixer(
85 sample_rate=41100, buffer_size=5120, channel_count=1
86 )
87 self.filter = self.synth.low_pass_filter(2000, 0.8)
88 else:
89 self.synth = None
8390
8491 self.settings = Settings(
8592 {
297304 self.modes["base_shift"].update_display()
298305
299306 def on_synth_vol(self, v, last):
307 if not self.synth or not self.audio_out:
308 return
309
300310 if v == 0:
301311 self.audio_out.stop()
302312 else:
305315 self.mixer.voice[0].level = v * v / 10000
306316
307317 def on_synth_adsr(self, v, last):
318 if not self.synth:
319 return
320
308321 a = self.settings.get("synth_a").value
309322 d = self.settings.get("synth_d").value
310323 s = self.settings.get("synth_s").value
2020 import rtmidi
2121
2222 rtmidi_api = rtmidi.API_UNSPECIFIED
23 if rtmidi.API_UNIX_JACK in rtmidi.get_compiled_api():
24 rtmidi_api = rtmidi.API_UNIX_JACK
2523 except:
2624 rtmidi = None
2725
141139 self.board = board
142140 self.brightness = 1
143141 self.pixels = [0] * 52
142 self.put_coro = None
144143
145144 def __setitem__(self, key, value):
146145 self.pixels[key] = value
162161 return colors
163162
164163 def show(self):
165 return self.board.ws_queue.put(
164 self.put_coro = self.board.ws_queue.put(
166165 {
167166 "type": "pixels",
168167 "colors": self.hex_colors(),
169168 }
170169 )
170
171 async def wait(self):
172 await self.put_coro
171173
172174 return DummyNeopixels(board)
173175
380382 loop.create_task(self.run_main())
381383 loop.run_forever()
382384
385 def tick(self):
386 ticks = ticks_ms()
387 self.mode.tick(ticks)
388
389 for i, pressed in self.matrix.scan_for_changes():
390 if self.board.sysex_key_sync:
391 msg = SystemExclusive(b"\0s-", [i, pressed])
392 self.broadcast(msg)
393 mode = self.sticky_modes.pop(i, self.mode)
394 should_stick = mode.key_event(i, pressed)
395
396 if should_stick:
397 self.sticky_modes[i] = mode
398
399 if self.i2c:
400 self.i2c.tick()
401
402 msg = self.midi_usb.receive()
403 while msg:
404 if isinstance(msg, NoteOn):
405 note = Note(self, msg.note)
406 self.modes["base"].extra_notes[note.pitch] = note
407 elif isinstance(msg, NoteOff) and self.modes["base"].extra_notes:
408 del self.modes["base"].extra_notes[msg.note]
409
410 msg = self.midi_usb.receive()
411
412 self.mode.update_pixels(self.pixels)
413
414 self.pixels.show()
415 self.display.refresh()
416
383417 async def run_main(self):
384418 while True:
385 ticks = ticks_ms()
386 self.mode.tick(ticks)
387
388 for i, pressed in self.matrix.scan_for_changes():
389 mode = self.sticky_modes.pop(i, self.mode)
390 should_stick = mode.key_event(i, pressed)
391
392 if should_stick:
393 self.sticky_modes[i] = mode
394
395 if self.i2c:
396 self.i2c.tick()
397
398 self.mode.update_pixels(self.pixels)
399
400 await self.pixels.show()
401 self.display.refresh()
402
419 self.tick()
420 await self.pixels.wait()
403421 await asyncio.sleep(1 / 120)
404422
405423 def run_http(self):
00 from __future__ import annotations
11
22 import displayio
3 import synthio
43 from micropython import const
54 from colorsys import hsv_to_rgb
65 from adafruit_ticks import ticks_ms, ticks_diff
76 from adafruit_midi.note_on import NoteOn
87 from adafruit_midi.note_off import NoteOff
8
9 try:
10 import synthio
11 except:
12 synthio = None
913
1014
1115 def clamp_norm(v):
2731 self.end_tick = None
2832 self.expiry = 1.0
2933
30 self.note = synthio.Note(
31 synthio.midi_to_hz(self.pitch), filter=self.keyboard.filter
32 )
34 if self.keyboard.synth:
35 self.note = synthio.Note(
36 synthio.midi_to_hz(self.pitch), filter=self.keyboard.filter
37 )
3338
3439 def on(self, local=True):
3540 self.base.notes[self.pitch] = self
3641 self.base.notes_dirty = True
3742
38 self.keyboard.synth.press(self.note)
43 if self.keyboard.synth:
44 self.keyboard.synth.press(self.note)
3945
4046 msg = NoteOn(self.pitch, self.keyboard.velocity)
4147 self.keyboard.broadcast(msg)
5157 del self.base.notes[self.pitch]
5258 self.base.notes_dirty = True
5359
54 self.keyboard.synth.release(self.note)
60 if self.keyboard.synth:
61 self.keyboard.synth.release(self.note)
5562
5663 msg = NoteOff(self.pitch, self.keyboard.velocity)
5764 self.keyboard.broadcast(msg)