wntrblm / sol Goto Github PK
View Code? Open in Web Editor NEWAn open-source MIDI-to-CV Eurorack module that runs CircuitPython
Home Page: https://wntr.dev/sol
An open-source MIDI-to-CV Eurorack module that runs CircuitPython
Home Page: https://wntr.dev/sol
I recently updated Sol to CircuitPython 7.30 and after doing so, the module stopped working (blinking green light) and after installing Mu, and opening a serial console, importing code.py
, it turned out that the .mpy
format changed from CircuitPython versions 6 to 7
I used the circup
python module to check which ones needed to be updated and two modules: adafruit_bus_device and neopixel needed to be updated, and I went ahead.
After restarting, there were still green flashing lights and I opened code.py on Mu and tried to run it and it gave the following error:
Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
Traceback (most recent call last):
File "code.py", line 84, in <module>
File "/lib/winterbloom_sol/__init__.py", line 40, in run
File "/lib/winterbloom_sol/sol.py", line 292, in __init__
File "/lib/winterbloom_sol/sol.py", line 187, in __init__
File "/lib/winterbloom_ad_dacs/_common.py", line 126, in soft_reset
File "/lib/winterbloom_ad_dacs/_common.py", line 122, in send_command
AttributeError: 'SPIDevice' object has no attribute 'spi'
I checked the call in _common.py
line 115:
spi_device = SPIDevice(spi, cs_io, polarity=0, phase=1, baudrate=5000000)
There doesn't seem to be a problem as the interface hasn't changed much:
# new version of spi_device.py
# https://github.com/adafruit/Adafruit_CircuitPython_BusDevice/blob/main/adafruit_bus_device/spi_device.py
def __init__(self, spi: SPI, chip_select: Optional[DigitalInOut] = None, *,
cs_active_value: bool = False,
baudrate: int = 100000,
polarity: int = 0,
phase: int = 0,
extra_clocks: int = 0
) -> None:
self.spi = spi
self.baudrate = baudrate
self.polarity = polarity
self.phase = phase
self.extra_clocks = extra_clocks
self.chip_select = chip_select
self.cs_active_value = cs_active_value
if self.chip_select:
self.chip_select.switch_to_output(value=True)
# old version used spi_device.py
# https://github.com/adafruit/Adafruit_CircuitPython_BusDevice/blob/cf7eabc4fa079a1443f548aed8ee2966af9b5fc1/adafruit_bus_device/spi_device.py
def __init__(self, spi, chip_select=None, *,
baudrate=100000, polarity=0, phase=0, extra_clocks=0):
self.spi = spi
self.baudrate = baudrate
self.polarity = polarity
self.phase = phase
self.extra_clocks = extra_clocks
self.chip_select = chip_select
if self.chip_select:
self.chip_select.switch_to_output(value=True)
I'm a bit stuck how to proceed. Can you please advice on what could be the fix, or if it's too much of pain (considering this module is discontinued) can you let me know how to downgrade to make it work again.
Thanks!
โจ
In process of working with the ADSR I noticed that the attack phase starting before the release phase was finished would lead to audio clicks when patching CV C -> CV of a VCA with a sound source going into that VCA. If I patched CV C through a slew limiter to delay the attack/release slightly the clicks stopped.
Some screenshots showing the difference between the waveforms:
without a slew limiter adsr set to c_adsr = sol.ADSR(attack=0.2, decay=0.2, sustain=0.7, release=1.0)
with a slew limiter:
Here is the midi clip I used for this example (90 bpm)
This is a snippet of the code I was using (minus some other stuff) that can recreate this issue. Please let me know if you have any problems reproducing this:
import winterbloom_sol as sol
cv_c = {
'attack': 0,
'knobs': [
(60, 'attack'),
],
}
c_adsr = sol.ADSR(
attack=0.5, # Seconds
decay=0.2, # Seconds
sustain=0.7, # Percentage - 0.0 to 1.0
release=1.0 # Seconds
)
def read_ccs(last, state):
global cv_c
for cc, val in cv_c['knobs']:
if last.cc(cc) != state.cc(cc):
cv_c['attack']= state.cc(cc) * 5
global c_adsr
c_adsr.attack = cv_c['attack']
def loop(last, state, outputs):
"""The loop is run over and over to process MIDI information
and translate it to outputs.
"last" holds the previous state, "state" holds the current state,
and "outputs" lets you control the output jacks.
You can read more about the state here: TODO.
And more about the outputs here: TODO.
"""
read_ccs(last, state)
# Whenever a new note message comes in, such as from
# a key being pressed or a sequencer sending a note,
# update the gate and trigger outputs.
if sol.was_key_pressed(state):
c_adsr.start()
if not state.note:
c_adsr.stop()
outputs.cv_c = c_adsr.output * 8.0
sol.run(loop)
Since state.clock
can remain the same value between subsequent calls to loop
, if the clock is slow enough loop will actually retrigger the output multiple times for a single clock.
A possible fix is to make it possible to "latch" Trigger
/Retrigger
objects - preventing them from triggering again until unlatched
.
Another possible fix is to make helpers.should_trigger_clock
memoize the last state.clock
value that it returned True
for and return False
if it sees it again.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.