Skip to content

ElectronicDrums5: a five-channel electronic drum kit - #20

Closed
bdbarnett wants to merge 4 commits into
inst/rhythm78from
inst/electronic_drums5
Closed

bdbarnett wants to merge 4 commits into
inst/rhythm78from
inst/electronic_drums5

Conversation

@bdbarnett

@bdbarnett bdbarnett commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

Adds ElectronicDrums5, a five-channel electronic drum kit with swept tones, inspired by the Simmons SDS-V. Stacked on #19 (Rhythm78), which stacks on #18, #17 and #16. Review the commits after inst/rhythm78, and merge those four first.

Each channel (bass drum, snare and three toms) is one ElectronicDrums5Voice on the shared swept-oscillator drum core: a tone that bends down from the strike, a filtered noise and a click. Every channel has its own pitch, bend, decay, tone, noise, click and filter, and a sensitivity trim sets how far velocity moves its level and bend. SweptOscillatorDrumCore gains a tone mix level and a configurable noise filter. Its defaults are pinned by a test, so the Rhythm909 is unchanged. There are five patches. The Rhythm808, Rhythm606, Rhythm909 and Rhythm78 traits stay at 0 moved.

Local proof:

  • Tests: scoped pytest (the five machines, the drums cores, the kit, the adapter, allocation) has 509 passed, and test_traits -k "rhythm or electronic_drums5" has 5 passed. MicroPython tests/mpy/run.py runs 230 tests with 0 failures; its ElectronicDrums5 tests check each channel's tone, noise, click and decay, velocity and sensitivity, volume and the tom macros. Ruff check and format are clean.

  • Traits: 152, accepted in tests/traits/electronic_drums5.json.

  • Parity: CPython and MicroPython agree within 0.03 dB on the kick and toms, and within 0.25 dB on the snare, whose noise comes from a different generator on each interpreter.

  • DC: 0.0 at every pad's tail.

  • Real time, all five sounds struck and re-struck:

    Frames CPython MicroPython
    128 2.11x (1.93x under load) 5.18x (4.22x under load)
    64 1.16x (0.75x under load) 2.65x (2.42x under load)
  • Fixed in review:

    • The noise envelope took the tone's 40 dB fall time as its time constant, so every noise tail rang 4.6 times too long. The snare took about a second to fall 40 dB; it now takes 262 ms. The traits are re-accepted with that change.
    • The docs said a re-strike has no click. It does: the click sounds again over the ringing tone, which keeps its phase, and the docs now say so.
    • t1_bend and t1_decay wrote one value to all three toms. They now set tom 1 to the knob's value and move the other two by the same amount, so a patch's per-tom offsets survive; a tom that reaches 0 or 10 stops there and returns to its offset when the knob comes back. No current patch has such offsets, so the traits stay at 0 moved.
    • New tests cover every channel's controls, the decay ranges, velocity and sensitivity, every patch and macro, re-strike phase, clipping, DC and how long the key is held.
  • Planted faults, each caught by a test: a control ignored (tone, noise, click, filter, pitch, decay, volume), the bend inverted, sensitivity or velocity ignored, the noise decay bug, an allocation in the voice's block, an oscillator reset on re-strike, t1_decay moving one tom, the tom macros writing one value to every tom (on both interpreters), volume ignored on MicroPython, and a change to the shared core's defaults.

  • Demo: examples/electronic_drums5_demo.py runs 55 s over five sections, with 0 clipped samples and a section RMS spread of 4.9 dB.

Limitations.

  • CPython is at the edge of real time at 64 frames.
  • The filter, pitch and bend checks run on CPython only.
  • Nothing here has been judged by ear yet.

Leave this open until CI can run it.

@bdbarnett

Copy link
Copy Markdown
Contributor Author

Replaced by #31

@bdbarnett bdbarnett closed this Oct 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant