Python & Elektrik
Elektrik Elektrik
I've been tinkering with generating rhythmic patterns from circuit signals and thought a Python script could make it real‑time. Want to hear the prototype?
Python Python
Sounds cool, just share the script and we can walk through the logic and maybe tweak the timing loop for smoother beats.
Elektrik Elektrik
Here’s a quick prototype that pulls a simple sine wave from a simulated voltage readout and plays it back in real time. Feel free to swap out the `read_voltage()` placeholder for your actual ADC routine and tweak the phase increments to get the groove you want. ```python import numpy as np import sounddevice as sd import time # ---- Settings ---- fs = 44100 # sampling rate (Hz) duration = 5.0 # seconds to stream freq = 110.0 # base tone (A2) amp = 0.5 # amplitude (0.0‑1.0) block_size = 1024 # samples per callback # ---- Dummy voltage source (replace with real ADC) ---- def read_voltage(): # Simulate a slowly varying voltage (0‑5V) that will drive the phase return 2.5 + 2.5 * np.sin(2 * np.pi * 0.1 * time.time()) # ---- Audio callback ---- phase = 0.0 def audio_callback(outdata, frames, time_info, status): global phase # Get the current voltage and map it to a phase speed (rad/s) v = read_voltage() speed = (v / 5.0) * 2 * np.pi * freq # scale 0‑5V to 0‑2π*freq t = np.arange(frames) / fs # Generate samples with dynamic phase out = amp * np.sin(phase + speed * t) outdata[:, 0] = out phase += speed * frames / fs # ---- Stream ---- with sd.OutputStream(channels=1, samplerate=fs, callback=audio_callback, blocksize=block_size): print(f"Streaming for {duration}s – press Ctrl‑C to stop") time.sleep(duration) ```
Python Python
Nice skeleton—just a couple of tweaks. Use a local phase variable inside the callback instead of a global, or reset it when the stream starts, to avoid drift. Also, calculating `speed` every frame from a slowly changing voltage can introduce a jump; maybe interpolate between frames. And remember to handle the case where `status` is set, so you can catch buffer under‑/overflows. Overall, it’s a good start.
Elektrik Elektrik
Got it—let’s tighten it up and keep the phase local to the callback. I’ll also smooth the speed with a simple moving average and add a status check so we can spot any buffer issues. Here’s the updated snippet: ```python import numpy as np import sounddevice as sd import time from collections import deque fs = 44100 duration = 5.0 freq = 110.0 amp = 0.5 block_size = 1024 vol_window = deque([2.5]*10, maxlen=10) # holds recent voltage samples def read_voltage(): return 2.5 + 2.5 * np.sin(2 * np.pi * 0.1 * time.time()) def audio_callback(outdata, frames, time_info, status): if status: print(f"Status: {status}") # catch under/overflows v = read_voltage() vol_window.append(v) avg_v = sum(vol_window) / len(vol_window) # simple interpolation speed = (avg_v / 5.0) * 2 * np.pi * freq t = np.arange(frames) / fs phase = audio_callback.phase out = amp * np.sin(phase + speed * t) outdata[:, 0] = out audio_callback.phase = phase + speed * frames / fs audio_callback.phase = 0.0 # initialize local phase with sd.OutputStream(channels=1, samplerate=fs, callback=audio_callback, blocksize=block_size): print(f"Streaming for {duration}s – press Ctrl‑C to stop") time.sleep(duration) ``` Now the phase stays with the callback, the voltage influence is smoothed, and any stream hiccups get logged. Happy tweaking!
Python Python
Looks solid—just a tiny tweak: `deque` already gives you a moving window, so you could use `np.mean(vol_window)` instead of summing each time. And if you hit a status warning, maybe pause the stream for a split second before resuming to give the audio buffer a breather. Overall, good job!
Elektrik Elektrik
Nice catch on the mean—switching to `np.mean(vol_window)` keeps it clean. And that little pause on a status warning is a smart buffer‑breather. All set, time to crank up the beat and see how it vibes live.