Skip to content
Snippets Groups Projects
Commit 5c4d4f27 authored by moon2's avatar moon2 :speech_balloon:
Browse files

v9: patchified + new blm api

parent be18624d
No related branches found
No related tags found
No related merge requests found
......@@ -10,27 +10,92 @@ import random
from st3m.ui import colours
# bad hack to figure out which bl00mbox version is running
fm_broken = False
from st3m import processors
if "ProcessorMidldeware" in dir(processors) and \
len(processors.ProcessorMidldeware.PROCESSORS):
fm_broken = True
# stolen from future flow3r 1.4, import from utils instead when released
def mkdir_recursive(path):
if path[0] != "/":
raise ValueError("path must be absolute")
path.rstrip("/")
splt = path.split("/")
for x in range(len(splt)):
subpath = "/".join(splt[: (x + 1)])
if not os.path.exists(subpath):
os.mkdir(subpath)
elif not os.path.isdir(subpath):
raise FileExistsError
from st3m.utils import mkdir_recursive
class Flute(bl00mbox.Patch):
def __init__(self, chan):
super().__init__(chan)
mp = self.new(bl00mbox.plugins.multipitch, 3)
mp.signals.max_pitch.value = 32767
mp.signals.min_pitch.value = -32767
# noise channel
noise_src = self.new(bl00mbox.plugins.noise)
noise_env = self.new(bl00mbox.plugins.env_adsr)
noise_comb = self.new(bl00mbox.plugins.flanger)
noise_env.signals.input << noise_src.signals.output
noise_env.signals.gain.dB = -34
noise_env.signals.attack.value = 70
noise_env.signals.release.value = 100
noise_env.signals.sustain.value = 20000
noise_comb.signals.input << noise_env.signals.output
noise_comb.signals.resonance.mult = 3
noise_comb.signals.mix.value = -16384
noise_env.signals.trigger << mp.signals.trigger_thru
noise_comb.signals.manual << mp.signals.output[0]
mp.signals.shift[0].tone = 0
# osc channel
osc = self.new(bl00mbox.plugins.osc)
osc_noise = self.new(bl00mbox.plugins.noise)
osc_noise_lp = self.new(bl00mbox.plugins.filter)
osc_env = self.new(bl00mbox.plugins.env_adsr)
osc_dist = self.new(bl00mbox.plugins.mixer, 2)
osc_noise_lp.signals.input << osc_noise.signals.output
osc_dist.signals.input[1] << osc_noise_lp.signals.output
osc_dist.signals.input[0] << noise_comb.signals.output
osc_dist.signals.gain.mult = 0.08
osc.signals.fm << osc_dist.signals.output
osc_noise_lp.signals.cutoff << mp.signals.output[2]
mp.signals.shift[2].tone = -24
mp.signals.min_pitch = -32767
osc_noise_lp.signals.reso.mult = 1.5
osc_noise_lp.signals.gain.dB = -12
osc_noise_lp.signals.mode.switch.LOWPASS = True
osc.signals.pitch << mp.signals.thru
osc.signals.waveform.switch.TRI = True
osc_env = self.new(bl00mbox.plugins.env_adsr)
osc_env.signals.trigger << mp.signals.trigger_thru
osc_env.signals.attack.value = 150
osc_env.signals.sustain.value = 32767
osc_env.signals.release.value = 200
osc_env.signals.decay.value = 0
osc_env.signals.input << osc.signals.output
# main mixer
main_mixer = self.new(bl00mbox.plugins.mixer, 2)
main_lp = self.new(bl00mbox.plugins.filter)
main_mixer.signals.input[0] << osc_env.signals.output
main_mixer.signals.input[1] << noise_comb.signals.output
main_mixer.signals.input_gain[1].dB = 0
main_mixer.signals.block_dc.switch.ON = True
main_lp.signals.mix.value = 32767
main_lp.signals.cutoff << mp.signals.output[1]
mp.signals.shift[1].tone = 48
main_lp.signals.input << main_mixer.signals.output
main_lp.signals.gain.dB = 6
main_lp.signals.mode.switch.LOWPASS = True
# eq
eq_bp = self.new(bl00mbox.plugins.filter)
eq_lp = self.new(bl00mbox.plugins.filter)
eq_bp.signals.input << main_lp.signals.output
eq_lp.signals.input << eq_bp.signals.output
eq_bp.signals.cutoff.value = 800
# bug: introduces DC, bypassing for now
eq_bp.signals.mix.value = 0
eq_bp.signals.mode.switch.BANDPASS = True
eq_lp.signals.cutoff.value = 4000
eq_lp.signals.mix.value = 12000
eq_lp.signals.mode.switch.LOWPASS = True
self.signals.output = eq_lp.signals.output
self.signals.trigger = mp.signals.trigger_in
self.signals.pitch = mp.signals.input
self.signals.mod_in = mp.signals.mod_in
self.signals.gain = main_mixer.signals.gain
self.signals.fm_noise = osc_dist.signals.input_gain[0]
self.signals.cutoff = mp.signals.shift[1]
class BinaryFluteApp(Application):
def __init__(self, app_ctx) -> None:
......@@ -111,91 +176,15 @@ class BinaryFluteApp(Application):
settings["code"] = "gray" if self.gray else "bin"
utils.save_file_if_changed(self.dirpath + self.settings_file, json.dumps(settings))
def _build_synth(self):
self.blm = bl00mbox.Channel("flute")
self.blm.volume = 32767
self.multipitch = self.blm.new(bl00mbox.plugins.multipitch, 10)
self.multipitch.signals.max_pitch = 32767
self.multipitch.signals.min_pitch = -32767
# noise channel
self.noise_src = self.blm.new(bl00mbox.plugins.noise)
self.noise_env = self.blm.new(bl00mbox.plugins.env_adsr)
self.noise_comb = self.blm.new(bl00mbox.plugins.flanger)
self.noise_env.signals.input = self.noise_src.signals.output
self.noise_env.signals.gain.dB = -34
self.noise_env.signals.attack = 70
self.noise_env.signals.release = 100
self.noise_env.signals.sustain = 20000
self.noise_comb.signals.input = self.noise_env.signals.output
self.noise_comb.signals.resonance = 24000
self.noise_comb.signals.mix = -16384
self.noise_env.signals.trigger = self.multipitch.signals.trigger_thru
self.noise_comb.signals.manual = self.multipitch.signals.output[0]
self.multipitch.signals.shift[0].tone = 0
# osc channel
self.osc = self.blm.new(bl00mbox.plugins.osc)
self.osc_noise = self.blm.new(bl00mbox.plugins.noise)
self.osc_noise_lp = self.blm.new(bl00mbox.plugins.filter)
self.osc_env = self.blm.new(bl00mbox.plugins.env_adsr)
self.osc_dist = self.blm.new(bl00mbox.plugins.mixer, 2)
self.osc_noise_lp.signals.input = self.osc_noise.signals.output
self.osc_dist.signals.input[1] = self.osc_noise_lp.signals.output
self.osc_dist.signals.input[0] = self.noise_comb.signals.output
self.osc_dist.signals.gain.mult = 0.08
if fm_broken:
self.osc_dist.signals.gain.mult = 0
print("skipping fm noise, please update to dev firmware for nicer sound")
self.osc.signals.fm = self.osc_dist.signals.output
self.osc_noise_lp.signals.cutoff = self.multipitch.signals.output[2]
self.multipitch.signals.shift[2].tone = -24
self.multipitch.signals.min_pitch = -32767
self.osc_noise_lp.signals.reso = 12000
self.osc_noise_lp.signals.gain.dB = -12
self.osc_noise_lp.signals.mode.switch.LOWPASS = True
self.osc.signals.pitch = self.multipitch.signals.thru
self.osc.signals.waveform.switch.TRI = True
self.osc_env = self.blm.new(bl00mbox.plugins.env_adsr)
self.osc_env.signals.trigger = self.multipitch.signals.trigger_thru
self.osc_env.signals.attack = 150
self.osc_env.signals.sustain = 32767
self.osc_env.signals.release = 200
self.osc_env.signals.decay = 0
self.osc_env.signals.input = self.osc.signals.output
# main mixer
self.main_mixer = self.blm.new(bl00mbox.plugins.mixer, 2)
self.main_lp = self.blm.new(bl00mbox.plugins.filter)
self.main_mixer.signals.input[0] = self.osc_env.signals.output
self.main_mixer.signals.input[1] = self.noise_comb.signals.output
self.main_mixer.signals.input_gain[1].dB = 0
self.main_mixer.signals.block_dc.switch.ON = True
self.main_lp.signals.mix = 32767
self.main_lp.signals.cutoff = self.multipitch.signals.output[1]
self.multipitch.signals.shift[1].tone = 48
self.main_lp.signals.input = self.main_mixer.signals.output
self.main_lp.signals.gain = 16000
self.main_lp.signals.mode.switch.LOWPASS = True
# eq
self.eq_bp = self.blm.new(bl00mbox.plugins.filter)
self.eq_lp = self.blm.new(bl00mbox.plugins.filter)
self.eq_bp.signals.input = self.main_lp.signals.output
self.eq_lp.signals.input = self.eq_bp.signals.output
self.eq_bp.signals.cutoff = 800
# bug: introduces DC, bypassing for now
self.eq_bp.signals.mix = 0
self.eq_bp.signals.mode.switch.BANDPASS = True
self.eq_lp.signals.cutoff = 4000
self.eq_lp.signals.mix = 12000
self.eq_lp.signals.mode.switch.LOWPASS = True
self.blm.mixer = self.eq_lp.signals.output
def build_synth(self):
self.blm = bl00mbox.Channel("binary flute")
self.flute = self.blm.new(Flute)
self.blm.gain_dB = 0
self.blm.signals.line_out << self.flute.signals.output
def on_enter(self, vm):
super().on_enter(vm)
self._build_synth()
self.build_synth()
self.enter_done = False
self.full_redraw = True
self.sound_active = False
......@@ -222,10 +211,7 @@ class BinaryFluteApp(Application):
def on_exit(self):
super().on_exit()
if self.blm is not None:
self.blm.clear()
self.blm.free = True
self.blm = None
self.blm.delete()
def draw(self, ctx):
if not self.enter_done:
......@@ -383,10 +369,10 @@ class BinaryFluteApp(Application):
if self.sound_active != sound_active:
if sound_active:
self.multipitch.signals.trigger_in.start()
self.flute.signals.trigger.start()
self.play_note(self.valves, glide = False)
else:
self.multipitch.signals.trigger_in.stop()
self.flute.signals.trigger.stop()
self.sound_active = sound_active
new_captouch_data = False
......@@ -408,7 +394,7 @@ class BinaryFluteApp(Application):
if valves == self.valves_candidate:
self.valves = valves
if self.sound_active:
self.multipitch.signals.trigger_in.start()
self.flute.signals.trigger.start()
self.play_note(self.valves)
else:
self.valves_candidate = valves
......@@ -422,21 +408,21 @@ class BinaryFluteApp(Application):
vol = 0.5 - vol
self.vol += (vol - self.vol) * (1-decay_slow)
self.vol = max(0, min(1, self.vol))
self.main_mixer.signals.gain.dB = -32 + 12 * self.vol
self.multipitch.signals.shift[1].tone = 12 + 12 * self.vol
self.osc_dist.signals.input_gain[0].mult = 1 + 2 * max(self.vol-0.5, 0)
self.flute.signals.gain.dB = -32 + 12 * self.vol
self.flute.signals.cutoff.tone = 12 + 12 * self.vol
self.flute.signals.fm_noise.mult = 1 + 2 * max(self.vol-0.5, 0)
else:
self.vol = 0
note_delta = self.target_note - self.current_note
self.current_note += note_delta * (1 - (0.9**delta_ms))
self.multipitch.signals.input.tone = self.current_note
self.flute.signals.pitch.tone = self.current_note
pitch_mod = ins.imu.acc[2] * 60
if self.pitch_mod_bias is None:
self.pitch_mod_bias = pitch_mod
self.pitch_mod_bias += (pitch_mod - self.pitch_mod_bias) * (1 - decay_slow)
self.multipitch.signals.mod_in = pitch_mod - self.pitch_mod_bias
self.flute.signals.mod_in = pitch_mod - self.pitch_mod_bias
def play_note(self, valves, glide = True):
def gray_to_binary(gy):
......
......@@ -11,15 +11,8 @@ author = "moon2"
license = "CC0-1.0"
description = "flute emulator"
url = "https://git.flow3r.garden/moon2/binary-flute"
version = 8
version = 9
[style]
background = "rgb(0.5, 0.5, 1.0)"
[[style.floaties]]
symbol = "flow3r"
color = "rgba(1.0, 1.0, 1.0, 0.5)"
[[style.floaties]]
symbol = "cat"
color = "rgba(1.0, 1.0, 1.0, 0.5)"
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment