Skip to content

Instantly share code, notes, and snippets.

@todbot
Created November 14, 2023 18:35
Show Gist options
  • Save todbot/e63cbda6ae5fbd544abade17e3dafdc0 to your computer and use it in GitHub Desktop.
Save todbot/e63cbda6ae5fbd544abade17e3dafdc0 to your computer and use it in GitHub Desktop.
phase accumulation oscillator experiment in circuitpython
# phase accumulation oscillator experiment
# 13 Nov 2023 - @todbot
# basically just copying
# https://github.com/wntrblm/Sol/blob/master/firmware/winterbloom_sol/lfo.py
#
import time
import math
from supervisor import ticks_ms
class LFO:
def __init__(self, frequency):
self.frequency = frequency
self._phase = 0
self._last_millis = ticks_ms()
def _phase_accumulate(self):
now = ticks_ms()
time_delta = now - self._last_millis
self._last_millis = now
phase_accum = (time_delta/1000) * self.frequency
self._phase = (self._phase + phase_accum) % 1.0
@property
def value(self):
"""Output the LFO value, defaults to sine wave"""
self._phase_accumulate()
return math.sin(math.pi * 2 * self._phase)
class TriangleLFO(LFO):
@property
def value(self):
self._phase_accumulate()
return (abs(self._phase - 0.5) * 4.0) - 1.0
class SampleLFO(LFO):
def __init__(self, frequency, sample):
super().__init__(frequency)
self._sample = sample
@property
def value(self):
self._phase_accumulate()
i = int(self._phase * len(self._sample))
return self._sample[i]
sample_length = 16
cos_wave = [
math.cos(math.pi * 2 * i / sample_length)
for i in range(sample_length)
]
my_sample = cos_wave
o1 = LFO(frequency=0.6)
o2 = TriangleLFO(frequency=0.1)
o3 = SampleLFO(frequency=0.6, sample=my_sample)
while True:
print("%+.2f %+.2f %+.2f" % (o1.value, o2.value, o3.value) )
time.sleep(0.05)
@todbot
Copy link
Author

todbot commented Nov 14, 2023

output looks like:
Screenshot 2023-11-14 at 8 54 36 AM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment