aneforge/dsp.py has windows, FIR/IIR filters, STFT/spectrogram, correlate, and Welch PSD, but no waveform generators. Add three standard ones (host-side numpy generators, matching the existing window-function style like hann/kaiser near the top of the file):
sawtooth(t, width=1.0) -- rising ramp; width sets the rise/fall split (width=1 -> pure rising sawtooth, width=0.5 -> triangle).
square(t, duty=0.5) -- square wave with the given duty cycle.
chirp(t, f0, t1, f1, method="linear") -- frequency sweep from f0 (at t=0) to f1 (at t1); linear method is enough to start (log/quadratic optional).
Oracle: scipy.signal.sawtooth, scipy.signal.square, scipy.signal.chirp. Add cases to dsp.py's _selftest comparing against scipy over a sample vector (a relerr helper _relerr already exists in the file).
Testing: these are pure numpy generators, so the self-test runs off-device; python -c "import aneforge.dsp as d; d._selftest()" should pass without a Mac. Note in the PR whether you ran the full battery.
aneforge/dsp.pyhas windows, FIR/IIR filters, STFT/spectrogram, correlate, and Welch PSD, but no waveform generators. Add three standard ones (host-side numpy generators, matching the existing window-function style likehann/kaisernear the top of the file):sawtooth(t, width=1.0)-- rising ramp;widthsets the rise/fall split (width=1 -> pure rising sawtooth, width=0.5 -> triangle).square(t, duty=0.5)-- square wave with the given duty cycle.chirp(t, f0, t1, f1, method="linear")-- frequency sweep fromf0(at t=0) tof1(att1); linear method is enough to start (log/quadratic optional).Oracle:
scipy.signal.sawtooth,scipy.signal.square,scipy.signal.chirp. Add cases todsp.py's_selftestcomparing against scipy over a sample vector (a relerr helper_relerralready exists in the file).Testing: these are pure numpy generators, so the self-test runs off-device;
python -c "import aneforge.dsp as d; d._selftest()"should pass without a Mac. Note in the PR whether you ran the full battery.