Skip to content

Commit

Permalink
Starting Env: envelope/pitch detector as VCV Rack module.
Browse files Browse the repository at this point in the history
Beginning the panel design for a working VCV Rack module
based on Surge XT / Tree Monster's pitch and envelope detectors.
I'm not using their algorithm directly, but reading their code
for the basic idea:

Bandpass filter the input audio for each channel.
This rejects DC and other signals below audible range.
Also filter out very high frequencies to reject noise.

Count ascending and descending zero-crossing intervals,
called wavelengths. Convert wavelengths to pitch V/OCT.
  • Loading branch information
cosinekitty committed Jan 30, 2025
1 parent b7bf50d commit 2e14063
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 0 deletions.
9 changes: 9 additions & 0 deletions res/env.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/sapphire_panel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ namespace Sapphire
{"span_slider", { 30.480, 46.000}},
{"stif_slider", { 19.240, 46.000}},
}},
{ "env", {
{"_panel", { 30.480, 128.500}},
}},
{ "frolic", {
{"_panel", { 20.320, 128.500}},
{"chaos_atten", { 5.160, 68.000}},
Expand Down
19 changes: 19 additions & 0 deletions util/make_sapphire_svg.py
Original file line number Diff line number Diff line change
Expand Up @@ -1834,6 +1834,24 @@ def GenerateTubeUnit(cdict:Dict[str, ControlLayer], title:str, symbol:str) -> in

return 0


def GenerateEnvPitchPanel(cdict:Dict[str, ControlLayer], target:Target) -> int:
name = 'env'
PANEL_WIDTH = 6
svgFileName = SvgFileName(name, target)
panel = Panel(PANEL_WIDTH)
cdict[cdict_name(name, target)] = controls = ControlLayer(panel)
pl = Element('g', 'PanelLayer')
defs = Element('defs')
pl.append(defs)
panel.append(pl)
with Font(SAPPHIRE_FONT_FILENAME) as font:
pl.append(BorderRect(PANEL_WIDTH, SAPPHIRE_PANEL_COLOR, SAPPHIRE_BORDER_COLOR))
pl.append(CenteredGemstone(panel))
pl.append(ModelNamePath(panel, font, name))
return Save(panel, svgFileName)


if __name__ == '__main__':
cdict:Dict[str, ControlLayer] = {}
sys.exit(
Expand Down Expand Up @@ -1866,6 +1884,7 @@ def GenerateTubeUnit(cdict:Dict[str, ControlLayer], title:str, symbol:str) -> in
GeneratePopPanel(cdict) or
GenerateElastikaPanel(cdict, Target.VcvRack) or
GenerateElastikaPanel(cdict, Target.Lite) or
GenerateEnvPitchPanel(cdict, Target.VcvRack) or
GenerateTubeUnit(cdict, 'tube unit', 'tubeunit') or
GenerateTubeUnit(cdict, 'tube monster', 'tubemonster') or
SaveControls(cdict) or
Expand Down

0 comments on commit 2e14063

Please sign in to comment.