From d2015edcefc713a22e9c1072ca524911e5df1bfa Mon Sep 17 00:00:00 2001 From: moon2 <moon2protonmail@protonmail.com> Date: Tue, 19 Sep 2023 21:54:43 +0000 Subject: [PATCH] shoegaze: enable chord borrowing from chord organ harmonic demo: rename to chord organ in flow3r.toml only, add "tones_readonly" chord tone information to savefile --- docs/badge/usage.rst | 8 +- python_payload/apps/demo_harmonic/__init__.py | 1 + python_payload/apps/demo_harmonic/flow3r.toml | 2 +- python_payload/apps/shoegaze/__init__.py | 140 +++++++++--------- 4 files changed, 79 insertions(+), 72 deletions(-) diff --git a/docs/badge/usage.rst b/docs/badge/usage.rst index 7eb4192ade..e982b59151 100644 --- a/docs/badge/usage.rst +++ b/docs/badge/usage.rst @@ -88,7 +88,7 @@ We ship some noise-making apps by default: shoegaze ^^^^^^^^ -Electric guitar simulator with fuzz and reverb. Tilt for wiggle stick. App button middle switches between render modes: Lo Fi has lower framerate, default has slower input response time. App button left turns delay on and off. Top petals play notes in chord, bottom petals change chord. +Electric guitar simulator with fuzz and reverb. Tilt for wiggle stick. Top petals play notes in chord, bottom petals change chord. App button left turns delay on and off, app button right checks for chords in the savefile of chord organ and toggles between them if found. Otamatone ^^^^^^^^^ @@ -112,8 +112,8 @@ be reset when passing it, if they're "open" they let the sequencer pass through Your beat is saved in flash at ``/sys/gay_drums.json`` when exiting gay drums! Make sure to wait until the menu screen appears before turning the power off though :D! -harmonic demo -^^^^^^^^^^^^^ +chord organ +^^^^^^^^^^^ A chord organ! The top petals always play the 5 notes of the selected chord. @@ -146,7 +146,7 @@ Samples are saved in flash at ``/sys/samples/tiny_sample_*.wav``. .. _usage_apps: -Applications +Apps ------------ Audio passthrough diff --git a/python_payload/apps/demo_harmonic/__init__.py b/python_payload/apps/demo_harmonic/__init__.py index 160e38bec0..a995239d35 100644 --- a/python_payload/apps/demo_harmonic/__init__.py +++ b/python_payload/apps/demo_harmonic/__init__.py @@ -305,6 +305,7 @@ class HarmonicApp(Application): chord["nine"] = self.chords[i].nine chord["root"] = self.chords[i].root chord["voicing"] = self.chords[i].voicing + chord["tones_readonly"] = self.chords[i].notes if not file_is_different: user_chord = user_settings["chords"][i] if self._file_settings is None: diff --git a/python_payload/apps/demo_harmonic/flow3r.toml b/python_payload/apps/demo_harmonic/flow3r.toml index 4b20e89b97..863bc6dedd 100644 --- a/python_payload/apps/demo_harmonic/flow3r.toml +++ b/python_payload/apps/demo_harmonic/flow3r.toml @@ -1,5 +1,5 @@ [app] -name = "harmonic demo" +name = "chord organ" menu = "Music" [entry] diff --git a/python_payload/apps/shoegaze/__init__.py b/python_payload/apps/shoegaze/__init__.py index aac0dfa0ca..fb2064d9a6 100644 --- a/python_payload/apps/shoegaze/__init__.py +++ b/python_payload/apps/shoegaze/__init__.py @@ -5,6 +5,7 @@ from st3m.input import InputState from ctx import Context import json +import errno import math import captouch import bl00mbox @@ -33,7 +34,7 @@ class ShoegazeApp(Application): self.blm: Optional[bl00mbox.Channel] = None self.chord_index = 0 self.chord: List[int] = [] - self._set_chord(3) + self._organ_chords = [None] * 5 self._tilt_bias = 0.0 self._detune_prev = 0.0 self._git_string_tuning = [0] * 4 @@ -43,8 +44,8 @@ class ShoegazeApp(Application): self._rand_limit = 16 self._rand_rot = 0.0 self.delay_on = True - self.fuzz_on = True - self._lofi = False + self.organ_on = False + self._set_chord(3) def _build_synth(self) -> None: if self.blm is None: @@ -95,51 +96,64 @@ class ShoegazeApp(Application): self.main_mixer.signals.gain = 2000 self.main_lp.signals.reso = 2000 + + self.bass_lp.signals.gain = 32767 + self.git_lp.signals.gain = 32767 + self.main_lp.signals.freq = 2500 + self.main_lp.signals.gain = 2000 + self.git_mixer.signals.gain = 4000 + self.main_lp.signals.input = self.main_fuzz.signals.output self._update_connections() def _update_connections(self) -> None: if self.blm is None: return - if self.fuzz_on: - self.bass_lp.signals.gain = 32767 - self.git_lp.signals.gain = 32767 - self.main_lp.signals.freq = 2500 - self.main_lp.signals.gain = 2000 - self.git_mixer.signals.gain = 4000 - self.main_lp.signals.input = self.main_fuzz.signals.output - if self.delay_on: - self.git_delay.signals.input = self.git_fuzz.signals.output - self.main_mixer.signals.input0 = self.git_delay.signals.output - else: - self.main_mixer.signals.input0 = self.git_fuzz.signals.output + if self.delay_on: + self.git_delay.signals.input = self.git_fuzz.signals.output + self.main_mixer.signals.input0 = self.git_delay.signals.output else: - self.bass_lp.signals.gain = 2000 - self.git_lp.signals.gain = 2000 - self.main_lp.signals.freq = 6000 - self.main_lp.signals.gain = 4000 - self.git_mixer.signals.gain = 500 - self.main_lp.signals.input = self.main_mixer.signals.output - if self.delay_on: - self.git_delay.signals.input = self.git_lp.signals.output - self.main_mixer.signals.input0 = self.git_delay.signals.output - else: - self.main_mixer.signals.input0 = self.git_lp.signals.output - - def fuzz_toggle(self) -> None: - self.fuzz_on = not self.fuzz_on - self._update_connections() + self.main_mixer.signals.input0 = self.git_fuzz.signals.output + + def _try_load_settings(self, path): + try: + with open(path, "r") as f: + return json.load(f) + except OSError as e: + if e.errno != errno.ENOENT: + raise # ignore file not found + + def _load_settings(self): + settings_path = "/flash/harmonic_demo.json" + + settings = self._try_load_settings(settings_path) + if settings is not None: + for i, chord in enumerate(settings["chords"]): + if i > 4: + break + self._organ_chords[i] = chord["tones_readonly"] + + def organ_toggle(self) -> None: + self.organ_on = not self.organ_on + if self.organ_on and self._organ_chords[0] is None: + self._load_settings() + if self._organ_chords[0] is None: + self.organ_on = False + self._set_chord(self.chord_index, force_update=True) def delay_toggle(self) -> None: self.delay_on = not self.delay_on self._update_connections() - def _set_chord(self, i: int) -> None: + def _set_chord(self, i: int, force_update=False) -> None: hue = int(54 * (i + 0.5)) % 360 - if i != self.chord_index: + if i != self.chord_index or force_update: self.chord_index = i leds.set_all_hsv(hue, 1, 0.2) leds.update() - self.chord = chords[i] + if self.organ_on and self._organ_chords[i] is not None: + self.chord = self._organ_chords[i] + else: + self.chord = chords[i] def draw(self, ctx: Context) -> None: ctx.text_align = ctx.CENTER @@ -159,38 +173,46 @@ class ShoegazeApp(Application): ctx.text("bass") rot = self._spinny # + self._detune_prev - ctx.rgb(0, 0.5, 0.5) ctx.rotate(rot + self._rand_rot) - ctx.move_to(0, -10) - ctx.text("shoegazeshoegazeshoe") - ctx.move_to(0, 10) - ctx.text("gazeshoegazeshoegaze") + if self.organ_on: + ctx.rgb(0.5, 0, 0.6) + ctx.rotate(0.69) + ctx.move_to(0, -10) + ctx.text("chordorganchordorganchord") + ctx.move_to(0, 10) + ctx.text("organchordorganchordorgan") + ctx.rotate(4.20 + 0.69) + else: + ctx.rgb(0, 0.5, 0.5) + ctx.move_to(0, -10) + ctx.text("shoegazeshoegazeshoe") + ctx.move_to(0, 10) + ctx.text("gazeshoegazeshoegaze") ctx.rotate(-2.2 * (rot + self._rand_rot) - 0.5) + if self.organ_on: + rgb = (0.7, 0.7, 0) + else: + rgb = (0, 0.8, 0) + ctx.move_to(40, 40) + if self.delay_on: - ctx.rgb(0, 0.8, 0) + ctx.rgb(*rgb) ctx.text("delay ON!") else: - ctx.rgb(0, 0.6, 0) + ctx.rgb(*tuple([x * 0.75 for x in rgb])) ctx.text("delay off") + ctx.rgb(*rgb) ctx.rotate(0.2 + self._rand_rot) - ctx.move_to(50, -50) detune = "detune: " + str(int(self._detune_prev * 100)) - ctx.rgb(0, 0.8, 0) + ctx.rgb(*rgb) ctx.text(detune) - ctx.rotate(-2.5 * (rot + 4 * self._rand_rot)) - ctx.move_to(-50, 50) - if self.fuzz_on: - ctx.rgb(0, 0.8, 0) - ctx.text("fuzz ON!") - else: - ctx.rgb(0, 0.6, 0) - ctx.text("fuzz off") + ctx.text("fuzz ON!") def think(self, ins: InputState, delta_ms: int) -> None: super().think(ins, delta_ms) @@ -208,10 +230,7 @@ class ShoegazeApp(Application): if buttons.app.right.pressed: self.delay_toggle() if buttons.app.left.pressed: - pass - # self.fuzz_toggle() - if buttons.app.middle.pressed: - self.lofi = not self.lofi + self.organ_toggle() for i in range(1, 10, 2): if petals[i].whole.pressed: @@ -235,21 +254,8 @@ class ShoegazeApp(Application): self.bass_string.decay = 1000 self.bass_string.signals.trigger.start() - @property - def lofi(self): - return self._lofi - - @lofi.setter - def lofi(self, val): - self._lofi = bool(val) - if self._lofi: - sys_display.set_mode(2313) - else: - sys_display.set_mode(912) - def on_enter(self, vm: Optional[ViewManager]) -> None: super().on_enter(vm) - self.lofi = self.lofi if self.blm is None: self._build_synth() self.blm.foreground = True -- GitLab