Browse Source

Noise Plethora (v2.1.0) (#31)

* Noise Plethora
  * Initial release
* Chopping Kinky
  * Upgraded to use improved DC blocker
* Spring Reverb
  * Added bypass
* Kickall
  * Allow trigger input and button to work independently
* EvenVCO
  * Fix to remove pop when number of polyphony engines changes (Fixes #33 )
* Muxlicer
  * Chaining using reset now works correctly (Fixes #32 )
tags/v2.1.0^0
Ewan GitHub 3 years ago
parent
commit
0cff3b0281
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
96 changed files with 13672 additions and 351 deletions
  1. +17
    -2
      CHANGELOG.md
  2. +35
    -0
      LICENSE-dist.md
  3. +1
    -0
      Makefile
  4. +241
    -230
      plugin.json
  5. +95
    -0
      res/components/Davies1900hLargeLightGrey.svg
  6. +98
    -0
      res/components/Davies1900hLargeLightGrey_bg.svg
  7. +154
    -0
      res/components/SwitchNarrowHoriz_0.svg
  8. +149
    -0
      res/components/SwitchNarrowHoriz_1.svg
  9. +151
    -42
      res/components/SwitchNarrow_1.svg
  10. +42
    -0
      res/components/SwitchNarrow_2.svg
  11. +94
    -0
      res/fonts/OFL.txt
  12. BIN
      res/fonts/Segment7Standard.otf
  13. +2564
    -0
      res/panels/NoisePlethora.svg
  14. +17
    -0
      src/ABC.cpp
  15. +4
    -2
      src/ChoppingKinky.cpp
  16. +12
    -10
      src/EvenVCO.cpp
  17. +10
    -2
      src/HexmixVCA.cpp
  18. +7
    -3
      src/Kickall.cpp
  19. +59
    -27
      src/Muxlicer.cpp
  20. +905
    -0
      src/NoisePlethora.cpp
  21. +0
    -28
      src/PulseGenerator_4.hpp
  22. +0
    -1
      src/Rampage.cpp
  23. +12
    -2
      src/SpringReverb.cpp
  24. +3
    -0
      src/noise-plethora/LICENSE.md
  25. +17
    -0
      src/noise-plethora/README.md
  26. +112
    -0
      src/noise-plethora/plugins/Banks.cpp
  27. +44
    -0
      src/noise-plethora/plugins/Banks.hpp
  28. +53
    -0
      src/noise-plethora/plugins/Banks_Def.hpp
  29. +90
    -0
      src/noise-plethora/plugins/NoisePlethoraPlugin.hpp
  30. +70
    -0
      src/noise-plethora/plugins/P_Atari.hpp
  31. +92
    -0
      src/noise-plethora/plugins/P_BasuraTotal.hpp
  32. +119
    -0
      src/noise-plethora/plugins/P_CrossModRing.hpp
  33. +265
    -0
      src/noise-plethora/plugins/P_FibonacciCluster.hpp
  34. +245
    -0
      src/noise-plethora/plugins/P_PrimeCluster.hpp
  35. +248
    -0
      src/noise-plethora/plugins/P_PrimeCnoise.hpp
  36. +258
    -0
      src/noise-plethora/plugins/P_Rwalk_BitCrushPW.hpp
  37. +156
    -0
      src/noise-plethora/plugins/P_Rwalk_LFree.hpp
  38. +199
    -0
      src/noise-plethora/plugins/P_Rwalk_SineFMFlange.hpp
  39. +65
    -0
      src/noise-plethora/plugins/P_S_H.hpp
  40. +64
    -0
      src/noise-plethora/plugins/P_TeensyAlt.hpp
  41. +85
    -0
      src/noise-plethora/plugins/P_TestPlugin.hpp
  42. +168
    -0
      src/noise-plethora/plugins/P_TriFMcluster.hpp
  43. +305
    -0
      src/noise-plethora/plugins/P_WalkingFilomena.hpp
  44. +49
    -0
      src/noise-plethora/plugins/P_WhiteNoise.hpp
  45. +80
    -0
      src/noise-plethora/plugins/P_XModRingSine.hpp
  46. +137
    -0
      src/noise-plethora/plugins/P_arrayOnTheRocks.hpp
  47. +108
    -0
      src/noise-plethora/plugins/P_basurilla.hpp
  48. +206
    -0
      src/noise-plethora/plugins/P_clusterSaw.hpp
  49. +135
    -0
      src/noise-plethora/plugins/P_crCluster2.hpp
  50. +146
    -0
      src/noise-plethora/plugins/P_existencelsPain.hpp
  51. +91
    -0
      src/noise-plethora/plugins/P_grainGlitch.hpp
  52. +78
    -0
      src/noise-plethora/plugins/P_grainGlitchII.hpp
  53. +74
    -0
      src/noise-plethora/plugins/P_grainGlitchIII.hpp
  54. +249
    -0
      src/noise-plethora/plugins/P_partialCluster.hpp
  55. +294
    -0
      src/noise-plethora/plugins/P_phasingCluster.hpp
  56. +139
    -0
      src/noise-plethora/plugins/P_pwCluster.hpp
  57. +99
    -0
      src/noise-plethora/plugins/P_radioOhNo.hpp
  58. +95
    -0
      src/noise-plethora/plugins/P_resonoise.hpp
  59. +74
    -0
      src/noise-plethora/plugins/P_satanWorkout.hpp
  60. +168
    -0
      src/noise-plethora/plugins/P_sineFMcluster.hpp
  61. +148
    -0
      src/noise-plethora/plugins/P_whoKnows.hpp
  62. +71
    -0
      src/noise-plethora/plugins/P_xModRingSqr.hpp
  63. +123
    -0
      src/noise-plethora/plugins/ProgramSelector.hpp
  64. BIN
      src/noise-plethora/teensy-audio-device.png
  65. BIN
      src/noise-plethora/teensy-gui.png
  66. +21
    -0
      src/noise-plethora/teensy/TeensyAudioReplacements.hpp
  67. +180
    -0
      src/noise-plethora/teensy/audio_core.hpp
  68. +356
    -0
      src/noise-plethora/teensy/dspinst.h
  69. +90
    -0
      src/noise-plethora/teensy/effect_bitcrusher.cpp
  70. +58
    -0
      src/noise-plethora/teensy/effect_bitcrusher.h
  71. +72
    -0
      src/noise-plethora/teensy/effect_combine.cpp
  72. +53
    -0
      src/noise-plethora/teensy/effect_combine.hpp
  73. +228
    -0
      src/noise-plethora/teensy/effect_flange.cpp
  74. +53
    -0
      src/noise-plethora/teensy/effect_flange.h
  75. +193
    -0
      src/noise-plethora/teensy/effect_freeverb.cpp
  76. +90
    -0
      src/noise-plethora/teensy/effect_freeverb.hpp
  77. +222
    -0
      src/noise-plethora/teensy/effect_granular.cpp
  78. +77
    -0
      src/noise-plethora/teensy/effect_granular.hpp
  79. +48
    -0
      src/noise-plethora/teensy/effect_multiply.cpp
  80. +35
    -0
      src/noise-plethora/teensy/effect_multiply.h
  81. +49
    -0
      src/noise-plethora/teensy/effect_wavefolder.cpp
  82. +32
    -0
      src/noise-plethora/teensy/effect_wavefolder.hpp
  83. +163
    -0
      src/noise-plethora/teensy/filter_variable.cpp
  84. +108
    -0
      src/noise-plethora/teensy/filter_variable.hpp
  85. +140
    -0
      src/noise-plethora/teensy/mixer.hpp
  86. +201
    -0
      src/noise-plethora/teensy/synth_dc.hpp
  87. +147
    -0
      src/noise-plethora/teensy/synth_pinknoise.cpp
  88. +59
    -0
      src/noise-plethora/teensy/synth_pinknoise.hpp
  89. +89
    -0
      src/noise-plethora/teensy/synth_pwm.cpp
  90. +61
    -0
      src/noise-plethora/teensy/synth_pwm.hpp
  91. +188
    -0
      src/noise-plethora/teensy/synth_sine.hpp
  92. +553
    -0
      src/noise-plethora/teensy/synth_waveform.hpp
  93. +71
    -0
      src/noise-plethora/teensy/synth_whitenoise.cpp
  94. +51
    -0
      src/noise-plethora/teensy/synth_whitenoise.hpp
  95. +1
    -0
      src/plugin.cpp
  96. +94
    -2
      src/plugin.hpp

+ 17
- 2
CHANGELOG.md View File

@@ -1,9 +1,24 @@
# Change Log

## v2.0.0 (unreleased)
## v2.1.0
* Noise Plethora
* Initial release
* Chopping Kinky
* Upgraded to use improved DC blocker
* Spring Reverb
* Added bypass
* Kickall
* Allow trigger input and button to work independently
* EvenVCO
* Fix to remove pop when number of polyphony engines changes
* Muxlicer
* Chaining using reset now works correctly

## v2.0.0
* update to Rack 2 API (added tooltips, bypass, removed boilerplate etc)
* UI overhaul

## v1.2.0 (unreleased)
## v1.2.0

* Released new modules: Muxlicer, Mex, Morphader, VC ADSR, Sampling Modulator, ST Mix
* Removed DC offset from EvenVCO pulse output


+ 35
- 0
LICENSE-dist.md View File

@@ -0,0 +1,35 @@
# Licenses of libraries used in Befaco for VCV Rack

## Teensy

```
Audio Library for Teensy 3.X
Copyright (c) 2014, Paul Stoffregen, paul@pjrc.com

Development of this audio library was funded by PJRC.COM, LLC by sales of
Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop
open source software by purchasing Teensy or other PJRC products.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice, development funding notice, and this permission
notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

```

## Befaco

Original Noise Plethora plugins were licensed under GPL v3 or later, see LICENSE-GPLv3.txt.

+ 1
- 0
Makefile View File

@@ -1,6 +1,7 @@
RACK_DIR ?= ../..

SOURCES += $(wildcard src/*.cpp)
SOURCES += $(wildcard src/noise-plethora/*/*.cpp)

DISTRIBUTABLES += $(wildcard LICENSE*) res



+ 241
- 230
plugin.json View File

@@ -1,231 +1,242 @@
{
"slug": "Befaco",
"version": "2.0.0",
"license": "GPL-3.0-or-later",
"name": "Befaco",
"brand": "Befaco",
"author": "VCV, Ewan Hemingway",
"authorEmail": "support@vcvrack.com",
"pluginUrl": "https://vcvrack.com/Befaco",
"authorUrl": "https://vcvrack.com/",
"sourceUrl": "https://github.com/VCVRack/Befaco",
"changelogUrl": "https://github.com/VCVRack/Befaco/blob/v1/CHANGELOG.md",
"modules": [
{
"slug": "EvenVCO",
"name": "Even VCO",
"description": "Oscillator including even-harmonic waveform",
"manualUrl": "https://www.befaco.org/even-vco/",
"modularGridUrl": "https://www.modulargrid.net/e/befaco-even-vco-",
"tags": [
"VCO",
"Hardware clone",
"Polyphonic"
]
},
{
"slug": "Rampage",
"name": "Rampage",
"description": "Dual ramp generator",
"manualUrl": "https://www.befaco.org/rampage-2/",
"modularGridUrl": "https://www.modulargrid.net/e/befaco-rampage",
"tags": [
"Function Generator",
"Logic",
"Slew Limiter",
"Envelope Follower",
"Dual",
"Hardware clone",
"Polyphonic"
]
},
{
"slug": "ABC",
"name": "A*B+C",
"description": "Dual four-quadrant multiplier with VC offset",
"manualUrl": "https://www.befaco.org/abc/",
"modularGridUrl": "https://www.modulargrid.net/e/befaco-a-b-c",
"tags": [
"Ring Modulator",
"Attenuator",
"Dual",
"Hardware clone",
"Polyphonic"
]
},
{
"slug": "SpringReverb",
"name": "Spring Reverb",
"description": "Spring reverb tank driver",
"manualUrl": "https://www.befaco.org/spring-reverb/",
"modularGridUrl": "https://www.modulargrid.net/e/befaco-spring-reverb-",
"tags": [
"Reverb",
"Hardware clone"
]
},
{
"slug": "Mixer",
"name": "Mixer",
"description": "Four-channel mixer for audio or CV",
"manualUrl": "https://www.befaco.org/mixer-2/",
"modularGridUrl": "https://www.modulargrid.net/e/befaco-mixer-",
"tags": [
"Mixer",
"Hardware clone",
"Polyphonic"
]
},
{
"slug": "SlewLimiter",
"name": "Slew Limiter",
"description": "Voltage controlled slew limiter, AKA lag processor",
"manualUrl": "https://www.befaco.org/slew-limiter/",
"modularGridUrl": "https://www.modulargrid.net/e/befaco-vc-slew-limiter-",
"tags": [
"Slew Limiter",
"Envelope Follower",
"Hardware clone",
"Polyphonic"
]
},
{
"slug": "DualAtenuverter",
"name": "Dual Atenuverter",
"description": "Attenuates, inverts, and applies offset to a signal",
"manualUrl": "https://www.befaco.org/dual-atenuverter/",
"modularGridUrl": "https://www.modulargrid.net/e/befaco-dual-atenuverter-",
"tags": [
"Attenuator",
"Dual",
"Hardware clone",
"Polyphonic"
]
},
{
"slug": "Percall",
"name": "Percall",
"description": "Percussive Envelope Generator",
"manualUrl": "http://www.befaco.org/percall/",
"modularGridUrl": "https://www.modulargrid.net/e/befaco-percall",
"tags": [
"Envelope generator",
"Mixer",
"Polyphonic",
"Hardware clone",
"Quad"
]
},
{
"slug": "HexmixVCA",
"name": "Hex Mix VCA",
"description": "Six channel VCA with response curve range from logarithmic to linear and to exponential",
"manualUrl": "https://www.befaco.org/hexmix-vca/",
"modularGridUrl": "https://www.modulargrid.net/e/befaco-hexmix-vca",
"tags": [
"Mixer",
"Hardware clone",
"Polyphonic",
"VCA"
]
},
{
"slug": "ChoppingKinky",
"name": "Chopping Kinky",
"description": "Voltage controllable, dual channel wavefolder",
"manualUrl": "https://www.befaco.org/chopping-kinky/",
"modularGridUrl": "https://www.modulargrid.net/e/befaco-chopping-kinky",
"tags": [
"Dual",
"Hardware clone",
"Voltage-controlled amplifier",
"Waveshaper"
]
},
{
"slug": "Kickall",
"name": "Kickall",
"description": "Bassdrum module, with pitch and volume envelopes",
"manualUrl": "https://www.befaco.org/kickall-2/",
"modularGridUrl": "https://www.modulargrid.net/e/befaco-kickall",
"tags": [
"Drum",
"Hardware clone",
"Synth voice"
]
},
{
"slug": "SamplingModulator",
"name": "Sampling Modulator",
"description": "Multi-function module that lies somewhere between a VCO, a Sample & Hold, and an 8 step trigger sequencer",
"manualUrl": "https://www.befaco.org/sampling-modulator/",
"modularGridUrl": "https://www.modulargrid.net/e/befaco-sampling-modulator-",
"tags": [
"Clock generator",
"Hardware clone",
"Oscillator",
"Sample and hold"
]
},
{
"slug": "Morphader",
"name": "Morphader",
"description": "Multichannel CV/Audio crossfader",
"manualUrl": "https://www.befaco.org/morphader-2/",
"modularGridUrl": "https://www.modulargrid.net/e/befaco-morphader",
"tags": [
"Controller",
"Hardware clone",
"Mixer",
"Polyphonic",
"Quad"
]
},
{
"slug": "ADSR",
"name": "ADSR",
"description": "ADSR envelope generator with gate output on each stage, plus variable shape",
"manualUrl": "https://www.befaco.org/vc-adsr/",
"modularGridUrl": "https://www.modulargrid.net/e/befaco-vc-adsr",
"tags": [
"Envelope generator",
"Hardware clone"
]
},
{
"slug": "STMix",
"name": "STMix",
"description": "A compact 4 channel stereo mixer with an auxiliary input",
"manualUrl": "https://www.befaco.org/stmix/",
"modularGridUrl": "https://www.modulargrid.net/e/befaco-stmix-",
"tags": [
"Hardware clone",
"Mixer",
"Polyphonic"
]
},
{
"slug": "Muxlicer",
"name": "Muxlicer",
"description": "VC adressable sequential switch and sequencer",
"manualUrl": "https://www.befaco.org/muxlicer-2/",
"modularGridUrl": "https://www.modulargrid.net/e/befaco-muxlicer",
"tags": [
"Clock generator",
"Hardware clone",
"Polyphonic",
"Sequencer",
"Switch"
]
},
{
"slug": "Mex",
"name": "Mex",
"description": "Gate Expander for Befaco Muxlicer",
"tags": [
"Expander",
"Hardware clone"
]
}
]
{
"slug": "Befaco",
"version": "2.1.0",
"license": "GPL-3.0-or-later",
"name": "Befaco",
"brand": "Befaco",
"author": "VCV, Ewan Hemingway",
"authorEmail": "support@vcvrack.com",
"pluginUrl": "https://vcvrack.com/Befaco",
"authorUrl": "https://vcvrack.com/",
"sourceUrl": "https://github.com/VCVRack/Befaco",
"changelogUrl": "https://github.com/VCVRack/Befaco/blob/v2/CHANGELOG.md",
"modules": [
{
"slug": "EvenVCO",
"name": "Even VCO",
"description": "Oscillator including even-harmonic waveform",
"manualUrl": "https://www.befaco.org/even-vco/",
"modularGridUrl": "https://www.modulargrid.net/e/befaco-even-vco-",
"tags": [
"VCO",
"Hardware clone",
"Polyphonic"
]
},
{
"slug": "Rampage",
"name": "Rampage",
"description": "Dual ramp generator",
"manualUrl": "https://www.befaco.org/rampage-2/",
"modularGridUrl": "https://www.modulargrid.net/e/befaco-rampage",
"tags": [
"Function Generator",
"Logic",
"Slew Limiter",
"Envelope Follower",
"Dual",
"Hardware clone",
"Polyphonic"
]
},
{
"slug": "ABC",
"name": "A*B+C",
"description": "Dual four-quadrant multiplier with VC offset",
"manualUrl": "https://www.befaco.org/abc/",
"modularGridUrl": "https://www.modulargrid.net/e/befaco-a-b-c",
"tags": [
"Ring Modulator",
"Attenuator",
"Dual",
"Hardware clone",
"Polyphonic"
]
},
{
"slug": "SpringReverb",
"name": "Spring Reverb",
"description": "Spring reverb tank driver",
"manualUrl": "https://www.befaco.org/spring-reverb/",
"modularGridUrl": "https://www.modulargrid.net/e/befaco-spring-reverb-",
"tags": [
"Reverb",
"Hardware clone"
]
},
{
"slug": "Mixer",
"name": "Mixer",
"description": "Four-channel mixer for audio or CV",
"manualUrl": "https://www.befaco.org/mixer-2/",
"modularGridUrl": "https://www.modulargrid.net/e/befaco-mixer-",
"tags": [
"Mixer",
"Hardware clone",
"Polyphonic"
]
},
{
"slug": "SlewLimiter",
"name": "Slew Limiter",
"description": "Voltage controlled slew limiter, AKA lag processor",
"manualUrl": "https://www.befaco.org/slew-limiter/",
"modularGridUrl": "https://www.modulargrid.net/e/befaco-vc-slew-limiter-",
"tags": [
"Slew Limiter",
"Envelope Follower",
"Hardware clone",
"Polyphonic"
]
},
{
"slug": "DualAtenuverter",
"name": "Dual Atenuverter",
"description": "Attenuates, inverts, and applies offset to a signal",
"manualUrl": "https://www.befaco.org/dual-atenuverter/",
"modularGridUrl": "https://www.modulargrid.net/e/befaco-dual-atenuverter-",
"tags": [
"Attenuator",
"Dual",
"Hardware clone",
"Polyphonic"
]
},
{
"slug": "Percall",
"name": "Percall",
"description": "Percussive Envelope Generator",
"manualUrl": "http://www.befaco.org/percall/",
"modularGridUrl": "https://www.modulargrid.net/e/befaco-percall",
"tags": [
"Envelope generator",
"Mixer",
"Polyphonic",
"Hardware clone",
"Quad"
]
},
{
"slug": "HexmixVCA",
"name": "Hex Mix VCA",
"description": "Six channel VCA with response curve range from logarithmic to linear and to exponential",
"manualUrl": "https://www.befaco.org/hexmix-vca/",
"modularGridUrl": "https://www.modulargrid.net/e/befaco-hexmix-vca",
"tags": [
"Mixer",
"Hardware clone",
"Polyphonic",
"VCA"
]
},
{
"slug": "ChoppingKinky",
"name": "Chopping Kinky",
"description": "Voltage controllable, dual channel wavefolder",
"manualUrl": "https://www.befaco.org/chopping-kinky/",
"modularGridUrl": "https://www.modulargrid.net/e/befaco-chopping-kinky",
"tags": [
"Dual",
"Hardware clone",
"Voltage-controlled amplifier",
"Waveshaper"
]
},
{
"slug": "Kickall",
"name": "Kickall",
"description": "Bassdrum module, with pitch and volume envelopes",
"manualUrl": "https://www.befaco.org/kickall-2/",
"modularGridUrl": "https://www.modulargrid.net/e/befaco-kickall",
"tags": [
"Drum",
"Hardware clone",
"Synth voice"
]
},
{
"slug": "SamplingModulator",
"name": "Sampling Modulator",
"description": "Multi-function module that lies somewhere between a VCO, a Sample & Hold, and an 8 step trigger sequencer",
"manualUrl": "https://www.befaco.org/sampling-modulator/",
"modularGridUrl": "https://www.modulargrid.net/e/befaco-sampling-modulator-",
"tags": [
"Clock generator",
"Hardware clone",
"Oscillator",
"Sample and hold"
]
},
{
"slug": "Morphader",
"name": "Morphader",
"description": "Multichannel CV/Audio crossfader",
"manualUrl": "https://www.befaco.org/morphader-2/",
"modularGridUrl": "https://www.modulargrid.net/e/befaco-morphader",
"tags": [
"Controller",
"Hardware clone",
"Mixer",
"Polyphonic",
"Quad"
]
},
{
"slug": "ADSR",
"name": "ADSR",
"description": "ADSR envelope generator with gate output on each stage, plus variable shape",
"manualUrl": "https://www.befaco.org/vc-adsr/",
"modularGridUrl": "https://www.modulargrid.net/e/befaco-vc-adsr",
"tags": [
"Envelope generator",
"Hardware clone"
]
},
{
"slug": "STMix",
"name": "STMix",
"description": "A compact 4 channel stereo mixer with an auxiliary input",
"manualUrl": "https://www.befaco.org/stmix/",
"modularGridUrl": "https://www.modulargrid.net/e/befaco-stmix-",
"tags": [
"Hardware clone",
"Mixer",
"Polyphonic"
]
},
{
"slug": "Muxlicer",
"name": "Muxlicer",
"description": "VC adressable sequential switch and sequencer",
"manualUrl": "https://www.befaco.org/muxlicer-2/",
"modularGridUrl": "https://www.modulargrid.net/e/befaco-muxlicer",
"tags": [
"Clock generator",
"Hardware clone",
"Polyphonic",
"Sequencer",
"Switch"
]
},
{
"slug": "Mex",
"name": "Mex",
"description": "Gate Expander for Befaco Muxlicer",
"tags": [
"Expander",
"Hardware clone"
]
},
{
"slug": "NoisePlethora",
"name": "Noise Plethora",
"description": "Multitimbral noise monster",
"tags": [
"Dual",
"Filter",
"Hardware clone",
"Noise"
]
}
]
}

+ 95
- 0
res/components/Davies1900hLargeLightGrey.svg View File

@@ -0,0 +1,95 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.0"
id="svg16908"
x="0px"
y="0px"
width="54px"
height="54.0024px"
viewBox="0 0 54 54.0024"
enable-background="new 0 0 54 54.0024"
xml:space="preserve"
sodipodi:docname="Davies1900hLargeLightGrey.svg"
inkscape:version="1.0.2-2 (e86c870879, 2021-01-15)"><metadata
id="metadata20"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs18" />
<sodipodi:namedview
bordercolor="#666666"
borderopacity="1.0"
fit-margin-bottom="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-top="0"
id="base"
inkscape:current-layer="svg16908"
inkscape:cx="-10.751444"
inkscape:cy="-11.595852"
inkscape:document-rotation="0"
inkscape:document-units="mm"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:window-height="1361"
inkscape:window-maximized="1"
inkscape:window-width="2560"
inkscape:window-x="-9"
inkscape:window-y="-9"
inkscape:zoom="7.919596"
pagecolor="#ffffff"
showgrid="false"
units="px">
</sodipodi:namedview>
<path
opacity="0.47"
fill="#5C5C5C"
enable-background="new "
d="M27.02268,0.73659v2.03027 c1.27875,0.00146,2.53516,0.104,3.75995,0.29834c0.46338,0.07373,0.85632,0.36035,1.12384,0.74561 c2.21851,3.19629,6.10315,5.08032,9.98499,4.84155c0.52692-0.03223,1.05591,0.10986,1.44531,0.46606 c1.80054,1.64844,3.35272,3.56396,4.5885,5.68701c0.26941,0.46289,0.29169,1.0188,0.13892,1.53223 c-1.12714,3.78711-0.12201,8.07324,2.58411,10.9585c0.32593,0.34741,0.52509,0.802,0.49414,1.27759 c-0.16333,2.51123-0.70642,4.91748-1.57739,7.1604c-0.17554,0.4519-0.55823,0.78076-1.01154,0.95312 c-3.80048,1.44556-6.62811,5.00684-7.17157,9.03711c-0.06476,0.48096-0.29797,0.92871-0.69806,1.20312 c-1.9472,1.33643-4.09882,2.39307-6.3974,3.11743c-0.52441,0.16504-1.08594,0.05493-1.55981-0.22363 c-3.47559-2.04443-7.97785-2.04443-11.45343,0c-0.47388,0.27856-1.0354,0.38867-1.55981,0.22363 c-2.2984-0.72388-4.44958-1.78076-6.39502-3.11694c-0.40002-0.2749-0.63318-0.72266-0.6983-1.20361 c-0.54541-4.03027-3.37311-7.5918-7.17151-9.03711c-0.45312-0.17236-0.83563-0.50098-1.01105-0.95288 c-0.87109-2.24292-1.41443-4.64942-1.57953-7.16065c-0.03131-0.47559,0.16766-0.93018,0.49359-1.27759 c2.7063-2.88525,3.71338-7.17139,2.58453-10.9585c-0.15302-0.51343-0.13086-1.06958,0.13861-1.53223 c1.23566-2.1228,2.78772-4.03857,4.58807-5.68652c0.38959-0.35669,0.91882-0.49878,1.44611-0.46655 c3.88336,0.23877,7.76623-1.64526,9.98456-4.84155c0.26746-0.38525,0.66058-0.67188,1.12396-0.74536 c1.22595-0.19458,2.48102-0.29712,3.75989-0.29858V0.73659C12.48216,0.74879,0.736,12.50416,0.736,27.00001 c0,14.50562,11.75848,26.26636,26.26398,26.26636c14.50562,0,26.2641-11.76074,26.2641-26.26636 C53.26408,12.50441,41.51774,0.74879,27.02268,0.73659z"
id="path3" />
<g
id="path109720_00000161623284270420770010000002804528334434327450_"
inkscape:connector-curvature="0"
opacity="0.25"
enable-background="new ">
<g
id="g7">
<path
fill="#1F1F1F"
d="M26.99993,3.51607c1.22003,0,2.45315,0.09756,3.66509,0.28996 c0.31782,0.05046,0.52821,0.29271,0.62533,0.43263c2.21967,3.19763,6.02818,5.18403,9.93928,5.18403 c0.23562,0,0.47189-0.00719,0.70781-0.02171c0.03308-0.00203,0.06617-0.00306,0.0992-0.00306 c0.31888,0,0.60076,0.09727,0.7937,0.27389c1.75971,1.61091,3.2558,3.46506,4.44672,5.51095 c0.20056,0.34455,0.12889,0.73739,0.06831,0.94091c-1.2006,4.03361-0.11887,8.62042,2.75585,11.68545 c0.2017,0.21505,0.30843,0.47598,0.29281,0.71591c-0.15568,2.39318-0.66981,4.72728-1.52811,6.93746 c-0.08791,0.22636-0.29897,0.41728-0.57905,0.52381c-4.06512,1.54603-7.06721,5.32912-7.64818,9.63787 c-0.04012,0.2975-0.17833,0.54719-0.37921,0.68505c-1.9082,1.30967-3.99364,2.32585-6.1984,3.02034 c-0.09016,0.0284-0.18601,0.0428-0.28489,0.0428c-0.21794,0-0.44938-0.06837-0.66929-0.19772 c-1.82046-1.07078-3.9322-1.63676-6.10694-1.63676s-4.28649,0.56598-6.10696,1.63676 c-0.21992,0.12935-0.45137,0.19772-0.6693,0.19772c-0.09888,0-0.19474-0.0144-0.28492-0.04281 c-2.20529-0.69465-4.28985-1.71067-6.19578-3.01983c-0.201-0.13808-0.3394-0.38806-0.3797-0.68586 c-0.58306-4.30856-3.5851-8.09152-7.64805-9.63754c-0.27988-0.1065-0.49079-0.2973-0.57863-0.52349 c-0.85789-2.20901-1.37275-4.5434-1.53028-6.93834c-0.01577-0.23977,0.09076-0.5005,0.29228-0.71534 c2.87636-3.06649,3.95825-7.65344,2.75622-11.6858c-0.06065-0.20347-0.13247-0.59625,0.06806-0.94072 c1.19086-2.04576,2.68682-3.89977,4.44634-5.51054c0.19313-0.1768,0.47526-0.27417,0.79441-0.27417 c0.03302,0,0.06611,0.00103,0.09922,0.00307c0.23627,0.01452,0.47211,0.0217,0.70804,0.0217 c3.91094,0,7.7192-1.98642,9.93865-5.18406c0.09708-0.13986,0.30741-0.38202,0.62539-0.43248 C24.54806,3.61367,25.78114,3.51607,26.99993,3.51607 M26.99993,2.76607c-1.28691,0-2.54927,0.10367-3.78251,0.29935 c-0.46337,0.07352-0.85647,0.36013-1.12399,0.74556c-2.09207,3.01413-5.66515,4.86171-9.32252,4.86171 c-0.2206,0-0.44111-0.0067-0.66202-0.02029c-0.04843-0.00298-0.09689-0.00448-0.14524-0.00448 c-0.47806,0-0.94699,0.14704-1.30084,0.47097c-1.80037,1.64817-3.35239,3.56364-4.58809,5.68643 c-0.26946,0.46289-0.29163,1.01901-0.13862,1.53229c1.12885,3.78689,0.12182,8.07323-2.5845,10.95844 c-0.32595,0.34749-0.52491,0.80227-0.49364,1.27767c0.16517,2.51117,0.70847,4.91771,1.57953,7.16062 c0.1755,0.45189,0.55795,0.78055,1.01104,0.95295c3.79847,1.44538,6.62614,5.00687,7.17154,9.03715 c0.06508,0.48089,0.29829,0.92872,0.69829,1.20348c1.94542,1.33629,4.09663,2.39298,6.39509,3.11698 c0.16765,0.0528,0.33909,0.07746,0.51025,0.07746c0.36421,0,0.72715-0.11164,1.04953-0.30125 c1.73779-1.02215,3.73227-1.53323,5.72673-1.53323s3.98891,0.51107,5.7267,1.53322 c0.32237,0.18962,0.68531,0.30126,1.04953,0.30126c0.17116,0,0.3426-0.02466,0.51024-0.07746 c2.29866-0.72406,4.45023-1.78086,6.39746-3.11731c0.40004-0.27456,0.63323-0.72235,0.69807-1.20319 c0.54342-4.03026,3.37107-7.59172,7.17152-9.03709c0.45332-0.17241,0.83599-0.5012,1.01157-0.95331 c0.87096-2.24279,1.41405-4.64924,1.5774-7.16028c0.03094-0.47545-0.16824-0.93016-0.49419-1.27768 c-2.70606-2.8852-3.71122-7.17153-2.58406-10.95841c0.15279-0.51329,0.13046-1.06934-0.13896-1.53218 c-1.23578-2.12296-2.78795-4.03857-4.58848-5.68684c-0.35365-0.32374-0.82233-0.4707-1.30013-0.4707 c-0.04836,0-0.0968,0.00151-0.14524,0.00449c-0.22057,0.01357-0.44147,0.02029-0.66176,0.02029 c-3.65639,0-7.23074-1.84738-9.32317-4.86171c-0.26755-0.38543-0.66045-0.6721-1.12384-0.74567 C29.55049,2.8697,28.28661,2.76607,26.99993,2.76607L26.99993,2.76607z"
id="path5" />
</g>
</g>
<g
id="path109720_00000155831737055662349650000008503574696319157933_"
inkscape:connector-curvature="0"
opacity="0.36">
<path
fill="#808080"
d="M27,6.02426c0.74651,0,1.50209,0.04102,2.24578,0.12207c0.75726,0.08252,1.48725,0.50586,2.05547,1.19214 c2.05435,2.48169,5.19908,3.96314,8.41215,3.96314c0.0855,0,0.17151-0.00098,0.25709-0.00317l0.0519-0.00073 c0.55985,0,1.09537,0.22046,1.50799,0.62061c1.22828,1.19067,2.30643,2.52637,3.20454,3.97021 c0.31184,0.50122,0.40833,1.10767,0.26473,1.66406c-0.87377,3.3855-0.00654,7.13867,2.26324,9.79517 c0.38327,0.44849,0.56183,1.0271,0.50277,1.62891c-0.15583,1.58838-0.49282,3.15357-1.00161,4.65186 c-0.22486,0.66211-0.73924,1.20801-1.4483,1.53687c-3.1218,1.44751-5.46496,4.44238-6.11509,7.81592 c-0.1266,0.65698-0.4899,1.20532-1.02308,1.54346c-1.34915,0.85645-2.79754,1.55688-4.30498,2.08154 c-0.23154,0.08057-0.47222,0.12134-0.71536,0.12134c-0.35114,0-0.69938-0.0874-1.00722-0.25293 c-1.55588-0.83618-3.33667-1.27832-5.14985-1.27832c-1.81336,0-3.59429,0.44214-5.15021,1.27856 c-0.30769,0.16528-0.65592,0.25269-1.00703,0.25269c-0.2432,0-0.48391-0.04077-0.71553-0.12134 c-1.50687-0.52466-2.95429-1.22437-4.30217-2.08032c-0.5335-0.33887-0.8973-0.8877-1.02441-1.54541 c-0.65173-3.37329-2.99482-6.36792-6.11475-7.81519c-0.70874-0.32886-1.22286-0.87451-1.44767-1.53638 c-0.50884-1.4978-0.84639-3.06372-1.00326-4.65381c-0.05846-0.59253,0.1244-1.18579,0.50175-1.6272 c2.27122-2.65747,3.13872-6.41089,2.26394-9.79565c-0.14378-0.55615-0.04739-1.16284,0.2645-1.66406 c0.8978-1.44336,1.97575-2.77905,3.20377-3.96973c0.41301-0.40039,0.94897-0.62085,1.50918-0.62085l0.05194,0.00073 c0.08578,0.0022,0.17141,0.00317,0.25713,0.00317c3.21307,0,6.35757-1.48169,8.41153-3.96314 c0.56791-0.68628,1.29773-1.10938,2.05501-1.19189C25.49921,6.06552,26.25492,6.02426,27,6.02426 M27,5.27426 c-0.78646,0-1.56266,0.04346-2.32729,0.12671c-1.01355,0.11035-1.90151,0.67383-2.55159,1.45923 c-1.90757,2.30469-4.83893,3.69141-7.83377,3.69141c-0.07956,0-0.15904-0.00098-0.23867-0.00293 c-0.02348-0.00049-0.04697-0.00098-0.07039-0.00098c-0.75951,0-1.48426,0.30225-2.03115,0.83228 c-1.26579,1.22729-2.38271,2.60742-3.31866,4.11206c-0.41827,0.67236-0.55193,1.48144-0.35377,2.24805 c0.81537,3.15479,0.00987,6.64258-2.10796,9.12061c-0.51749,0.60547-0.75618,1.39551-0.67799,2.18823 c0.1648,1.67041,0.51766,3.28516,1.0395,4.82129c0.30273,0.89136,0.98827,1.57935,1.8421,1.97559 c2.91277,1.35107,5.08415,4.12012,5.69408,7.2771c0.16186,0.83765,0.63857,1.57886,1.35878,2.03613 c1.38668,0.88062,2.88077,1.60669,4.45763,2.15552c0.31282,0.10889,0.63809,0.16309,0.96207,0.16309 c0.47051,0,0.93836-0.11426,1.36209-0.34204c1.4747-0.79272,3.13502-1.18921,4.79515-1.18921 c1.66013,0,3.32007,0.39624,4.79477,1.18896c0.42374,0.22778,0.89176,0.34229,1.36229,0.34229 c0.32398,0,0.64912-0.0542,0.96195-0.16309c1.57748-0.54907,3.0723-1.27539,4.46034-2.15649 c0.71982-0.45679,1.19625-1.19751,1.35759-2.03491c0.6084-3.15698,2.77983-5.92603,5.69413-7.27734 c0.85425-0.39624,1.54018-1.08447,1.84297-1.97607c0.52152-1.53589,0.87403-3.1499,1.03786-4.81983 c0.07782-0.79321-0.16123-1.5835-0.67899-2.18945c-2.11739-2.47803-2.92142-5.96582-2.10724-9.12036 c0.19786-0.7666,0.06405-1.57568-0.35413-2.2478c-0.93609-1.50488-2.05325-2.88525-3.31932-4.11255 c-0.54657-0.53003-1.27095-0.83203-2.03001-0.83203c-0.02345,0-0.04689,0.00049-0.0704,0.00098 c-0.07942,0.00195-0.15924,0.00293-0.23859,0.00293c-2.99408,0-5.92635-1.38647-7.83442-3.69141 c-0.65026-0.7854-1.5383-1.34912-2.55204-1.45947C28.56251,5.31747,27.78602,5.27426,27,5.27426L27,5.27426z"
id="path10" />
</g>
<path
id="path109722_00000132790347987467418750000015594545222572185506_"
inkscape:connector-curvature="0"
fill="#E3E3E3"
d=" M27.95065,1.74111c0,0.52557-0.42744,0.94836-0.95066,0.94836s-0.94833-0.42279-0.94833-0.94836 c0-0.52555,0.42511-0.94835,0.94833-0.94835S27.95065,1.21556,27.95065,1.74111" />
<path
opacity="0.64"
fill="#4A4A4A"
enable-background="new "
d="M27.00003,6.02426c-0.74512,0-1.5008,0.04126-2.24616,0.12231 c-0.75726,0.08252-1.48706,0.50562-2.05499,1.19189c-2.05395,2.48145-5.19842,3.96314-8.4115,3.96314 c-0.08575,0-0.17139-0.00098-0.25714-0.00317l-0.05194-0.00073c-0.56018,0-1.09619,0.22046-1.50916,0.62085 c-1.22802,1.19067-2.30595,2.52637-3.20379,3.96973c-0.31189,0.50122-0.40826,1.10791-0.26447,1.66406 c0.87476,3.38477,0.00727,7.13818-2.26397,9.79565c-0.37733,0.44141-0.5602,1.03467-0.50177,1.6272 c0.15691,1.59009,0.49444,3.15601,1.00329,4.65381c0.22478,0.66187,0.73889,1.20752,1.44763,1.53638 c3.11993,1.44727,5.46307,4.44189,6.11475,7.81519c0.12714,0.65771,0.49091,1.20654,1.02441,1.54541 c1.3479,0.85596,2.79535,1.55566,4.30219,2.08032c0.23163,0.08057,0.47235,0.12134,0.71552,0.12134 c0.35114,0,0.69934-0.0874,1.00702-0.25269c1.55597-0.83643,3.33686-1.27856,5.15027-1.27856 c1.81317,0,3.59393,0.44214,5.14984,1.27832c0.3078,0.16553,0.65607,0.25293,1.0072,0.25293 c0.24317,0,0.48383-0.04077,0.71534-0.12134c1.50744-0.52466,2.95587-1.2251,4.30499-2.08154 c0.5332-0.33813,0.89648-0.88647,1.02307-1.54346c0.65015-3.37354,2.99329-6.36841,6.11511-7.81592 c0.70905-0.32886,1.22345-0.87476,1.44831-1.53687c0.50879-1.49829,0.84576-3.06348,1.00158-4.65186 c0.05909-0.60181-0.1195-1.18042-0.50274-1.62891c-2.26978-2.65649-3.13703-6.40967-2.26325-9.79517 c0.14362-0.5564,0.04712-1.16284-0.26471-1.66406c-0.89813-1.44385-1.97625-2.77954-3.20459-3.97021 c-0.4126-0.40015-0.94812-0.62061-1.50793-0.62061l-0.05194,0.00073c-0.08557,0.0022-0.17157,0.00317-0.25708,0.00317 c-3.21308,0-6.35779-1.48145-8.41217-3.96314c-0.56818-0.68628-1.29816-1.10962-2.05542-1.19214 C28.5021,6.06527,27.74655,6.02426,27.00003,6.02426L27.00003,6.02426z"
id="path14"
style="fill:#878787;fill-opacity:1" />
<path
id="path109724_00000046337844363982079960000015404365734540027067_"
inkscape:connector-curvature="0"
fill="#E3E3E3"
d=" M27.18946,27.00234h-0.37662c-0.42039,0-0.76119-0.3408-0.76119-0.76119V7.28285c0-0.42039,0.3408-0.76119,0.76119-0.76119h0.37662 c0.42039,0,0.76119,0.3408,0.76119,0.76119v18.9583C27.95065,26.66154,27.60986,27.00234,27.18946,27.00234z" />
</svg>

+ 98
- 0
res/components/Davies1900hLargeLightGrey_bg.svg View File

@@ -0,0 +1,98 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.0"
id="svg16908"
x="0px"
y="0px"
width="54px"
height="54.0024px"
viewBox="0 0 54 54.0024"
enable-background="new 0 0 54 54.0024"
xml:space="preserve"
sodipodi:docname="Davies1900hLargeLightGrey_bg.svg"
inkscape:version="1.0.2-2 (e86c870879, 2021-01-15)"><metadata
id="metadata19"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs17" />
<sodipodi:namedview
bordercolor="#666666"
borderopacity="1.0"
fit-margin-bottom="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-top="0"
id="base"
inkscape:current-layer="svg16908"
inkscape:cx="52.324654"
inkscape:cy="47.546467"
inkscape:document-rotation="0"
inkscape:document-units="mm"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:window-height="1361"
inkscape:window-maximized="1"
inkscape:window-width="2560"
inkscape:window-x="-9"
inkscape:window-y="-9"
inkscape:zoom="8"
pagecolor="#ffffff"
showgrid="false"
units="px">
</sodipodi:namedview>
<linearGradient
id="path109718_1_"
gradientUnits="userSpaceOnUse"
x1="27"
y1="8.8817842e-16"
x2="27"
y2="54.00236">
<stop
offset="0"
style="stop-color:#c8c6c6;stop-opacity:1"
id="stop3" />
<stop
offset="1"
style="stop-color:#878787;stop-opacity:1"
id="stop5" />
</linearGradient>
<path
id="path109718_00000041986084651045777730000015174648132872021642_"
inkscape:connector-curvature="0"
fill="url(#path109718_1_)"
d=" M54,26.99999c0,14.91202-12.08797,27.00237-27.00001,27.00237S0,41.91201,0,26.99999C0,12.09032,12.08796,0,26.99999,0 S54,12.09032,54,26.99999"
style="fill:url(#path109718_1_)" />
<linearGradient
id="SVGID_1_"
gradientUnits="userSpaceOnUse"
x1="120.93008"
y1="216.11739"
x2="120.93398"
y2="239.55823"
gradientTransform="matrix(-1 0 0 0.50871 147.93398 -99.80668)">
<stop
offset="0"
style="stop-color:#ffffff;stop-opacity:1"
id="stop9" />
<stop
offset="1"
style="stop-color:#fcfeff;stop-opacity:0"
id="stop11" />
</linearGradient>
<ellipse
opacity="0.4"
fill="url(#SVGID_1_)"
cx="27"
cy="16.07793"
rx="12.03752"
ry="5.98187"
id="ellipse14"
style="fill:url(#SVGID_1_)" />
</svg>

+ 154
- 0
res/components/SwitchNarrowHoriz_0.svg View File

@@ -0,0 +1,154 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.0"
id="svg56722"
inkscape:version="1.0.2-2 (e86c870879, 2021-01-15)"
x="0px"
y="0px"
width="20.641029"
height="10"
viewBox="0 0 20.641029 10"
enable-background="new 0 0 10 20.64111"
xml:space="preserve"
sodipodi:docname="SwitchNarrowHoriz_0.svg"><metadata
id="metadata32"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs30" />
<sodipodi:namedview
bordercolor="#666666"
borderopacity="1.0"
fit-margin-bottom="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-top="0"
id="base"
inkscape:current-layer="svg56722"
inkscape:cx="3.4909301"
inkscape:cy="3.9708842"
inkscape:document-rotation="0"
inkscape:document-units="mm"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:window-height="1292"
inkscape:window-maximized="0"
inkscape:window-width="2559"
inkscape:window-x="0"
inkscape:window-y="101"
inkscape:zoom="31.678384"
pagecolor="#ffffff"
showgrid="false"
units="px">
</sodipodi:namedview>




<g
id="g1501"
transform="rotate(90,10.353775,10.353775)"><path
id="path5785_1_"
inkscape:connector-curvature="0"
d="M 0,1.5416 C 0,0.73117 0.66471,0.06652 1.47514,0.06652 H 8.52486 C 9.33523,0.06652 10,0.7313 10,1.5416 v 17.69189 c 0,0.81043 -0.66471,1.47406 -1.47514,1.47406 H 1.47514 C 0.66477,20.70754 0,20.04391 0,19.23348 Z" /><g
id="g5795_1_"
opacity="0.54">
<g
id="g5797_1_">
<linearGradient
id="path5805_00000026147093842360495760000000346361381535047831_"
gradientUnits="userSpaceOnUse"
x1="4.9991698"
y1="1.39937"
x2="4.9991698"
y2="19.52606">
<stop
offset="0"
style="stop-color:#3B3B3B"
id="stop4" />
<stop
offset="1"
style="stop-color:#242424"
id="stop6" />
</linearGradient>
<path
id="path5805_1_"
inkscape:connector-curvature="0"
fill="url(#path5805_00000026147093842360495760000000346361381535047831_)"
d="m 2.19312,1.39937 c -0.48687,0 -0.88421,0.39734 -0.88421,0.88421 v 0 16.35726 c 0,0.48687 0.3974,0.88522 0.88421,0.88522 v 0 h 5.61312 c 0.48477,0 0.88319,-0.39848 0.88319,-0.88522 v 0 -16.35726 c 0,-0.48687 -0.39842,-0.88421 -0.88319,-0.88421 v 0 z"
style="fill:url(#path5805_00000026147093842360495760000000346361381535047831_)" />
</g>
</g><rect
x="1.30993"
y="18.65077"
fill="none"
width="0.68290001"
height="0.89523"
id="rect12" /><rect
x="0.99908"
y="0.88112998"
opacity="0.3"
width="8.0001898"
height="1.71664"
id="rect14" /><g
id="g27">
<linearGradient
id="path5815_00000176018740175221449750000008623012870990731937_"
gradientUnits="userSpaceOnUse"
x1="4.9991698"
y1="10.67955"
x2="4.9991698"
y2="19.52606">
<stop
offset="0.00559"
style="stop-color:#3D3B3B"
id="stop16" />
<stop
offset="1"
style="stop-color:#2D2C2C"
id="stop18" />
</linearGradient>
<path
id="path5815_4_"
inkscape:connector-curvature="0"
fill="url(#path5815_00000176018740175221449750000008623012870990731937_)"
d="m 1.30891,10.67955 h 7.38052 v 8.84651 H 1.30891 Z"
style="fill:url(#path5815_00000176018740175221449750000008623012870990731937_)" />
<path
id="path5817_4_"
inkscape:connector-curvature="0"
fill="#5e5e5e"
d="m 1.30891,14.22647 h 7.38052 v 0.87738 H 1.30891 Z" />
<path
id="path5819_4_"
inkscape:connector-curvature="0"
fill="#5e5e5e"
d="m 1.30891,17.77339 h 7.38052 v 0.87738 H 1.30891 Z" />
<path
id="path5821_4_"
inkscape:connector-curvature="0"
fill="#5e5e5e"
d="m 1.30891,16.00079 h 7.38052 v 0.87738 H 1.30891 Z" />
<path
id="path5823_4_"
inkscape:connector-curvature="0"
fill="#5e5e5e"
d="m 1.30891,12.45307 h 7.38052 v 0.87738 H 1.30891 Z" />
<path
id="path5825_4_"
inkscape:connector-curvature="0"
fill="#797979"
d="m 1.30891,10.67955 h 7.38052 v 0.87738 H 1.30891 Z"
style="fill:#5e5e5e;fill-opacity:1" />
</g></g>
</svg>

+ 149
- 0
res/components/SwitchNarrowHoriz_1.svg View File

@@ -0,0 +1,149 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.0"
id="svg56722"
inkscape:version="1.0.2-2 (e86c870879, 2021-01-15)"
x="0px"
y="0px"
width="20.64102"
height="10"
viewBox="0 0 20.64102 10"
enable-background="new 0 0 10 20.64111"
xml:space="preserve"
sodipodi:docname="SwitchNarrowHoriz_1.svg"><metadata
id="metadata919"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs917" />
<sodipodi:namedview
bordercolor="#666666"
borderopacity="1.0"
fit-margin-bottom="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-top="0"
id="base"
inkscape:current-layer="svg56722"
inkscape:cx="17.685308"
inkscape:cy="15.724034"
inkscape:document-rotation="0"
inkscape:document-units="mm"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:window-height="1393"
inkscape:window-maximized="0"
inkscape:window-width="2560"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:zoom="15.839192"
pagecolor="#ffffff"
showgrid="false"
units="px">
</sodipodi:namedview>




<path
id="path5785"
inkscape:connector-curvature="0"
d="m 19.16594,0 c 0.81043,0 1.47508,0.66471 1.47508,1.47514 V 8.52486 C 20.64102,9.33523 19.97624,10 19.16594,10 H 1.47406 C 0.66363,10 0,9.33529 0,8.52486 V 1.47514 C 0,0.66477 0.66363,0 1.47406,0 Z" /><g
id="g5795"
opacity="0.54"
transform="rotate(90,10.32053,10.32053)">
<g
id="g5797">
<linearGradient
id="path5805_00000083768858156117840380000007545053210476265646_"
gradientUnits="userSpaceOnUse"
x1="4.9991698"
y1="1.33289"
x2="4.9991698"
y2="19.459579">
<stop
offset="0"
style="stop-color:#3B3B3B"
id="stop891" />
<stop
offset="1"
style="stop-color:#242424"
id="stop893" />
</linearGradient>
<path
id="path5805"
inkscape:connector-curvature="0"
fill="url(#path5805_00000083768858156117840380000007545053210476265646_)"
d="m 2.19312,1.33289 c -0.48687,0 -0.88421,0.39734 -0.88421,0.88421 v 0 16.35726 c 0,0.48687 0.3974,0.88522 0.88421,0.88522 v 0 h 5.61312 c 0.48477,0 0.88319,-0.39848 0.88319,-0.88522 v 0 V 2.2171 c 0,-0.48687 -0.39842,-0.88421 -0.88319,-0.88421 v 0 z"
style="fill:url(#path5805_00000083768858156117840380000007545053210476265646_)" />
</g>
</g><rect
x="1.30993"
y="-2.0567706"
fill="none"
width="0.68290001"
height="0.89523"
id="rect899"
transform="rotate(90)" /><g
id="g914"
transform="rotate(90,10.32053,10.32053)">
<linearGradient
id="path5815_00000170964631234716849240000010152055143087385985_"
gradientUnits="userSpaceOnUse"
x1="5.0001898"
y1="1.33289"
x2="5.0001898"
y2="10.17941">
<stop
offset="0.00559"
style="stop-color:#3D3B3B"
id="stop903" />
<stop
offset="1"
style="stop-color:#2D2C2C"
id="stop905" />
</linearGradient>
<path
id="path5815"
inkscape:connector-curvature="0"
fill="url(#path5815_00000170964631234716849240000010152055143087385985_)"
d="M 1.30993,1.33289 H 8.69045 V 10.1794 H 1.30993 Z"
style="fill:url(#path5815_00000170964631234716849240000010152055143087385985_)" />
<path
id="path5817"
inkscape:connector-curvature="0"
fill="#5e5e5e"
d="M 1.30993,4.87982 H 8.69045 V 5.7572 H 1.30993 Z" />
<path
id="path5819"
inkscape:connector-curvature="0"
fill="#5e5e5e"
d="M 1.30993,8.42674 H 8.69045 V 9.30412 H 1.30993 Z" />
<path
id="path5821"
inkscape:connector-curvature="0"
fill="#5e5e5e"
d="M 1.30993,6.65414 H 8.69045 V 7.53152 H 1.30993 Z" />
<path
id="path5823"
inkscape:connector-curvature="0"
fill="#5e5e5e"
d="M 1.30993,3.10641 H 8.69045 V 3.98379 H 1.30993 Z" />
<path
id="path5825"
inkscape:connector-curvature="0"
fill="#797979"
d="M 1.30993,1.33289 H 8.69045 V 2.21027 H 1.30993 Z"
style="fill:#5e5e5e;fill-opacity:1" />
</g>
</svg>

+ 151
- 42
res/components/SwitchNarrow_1.svg View File

@@ -1,42 +1,151 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 25.4.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.0"
id="svg56722" inkscape:version="1.0.2-2 (e86c870879, 2021-01-15)" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="10px" height="20.64111px"
viewBox="0 0 10 20.64111" enable-background="new 0 0 10 20.64111" xml:space="preserve">
<sodipodi:namedview bordercolor="#666666" borderopacity="1.0" fit-margin-bottom="0" fit-margin-left="0" fit-margin-right="0" fit-margin-top="0" id="base" inkscape:current-layer="layer1" inkscape:cx="-7.1500998" inkscape:cy="8.220078" inkscape:document-rotation="0" inkscape:document-units="mm" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:window-height="1393" inkscape:window-maximized="0" inkscape:window-width="2560" inkscape:window-x="0" inkscape:window-y="0" inkscape:zoom="31.678384" pagecolor="#ffffff" showgrid="false" units="px">
</sodipodi:namedview>
<path id="path5785" inkscape:connector-curvature="0" d="M0,1.47512c0-0.81043,0.66471-1.47508,1.47514-1.47508h7.04972
C9.33523,0.00004,10,0.66482,10,1.47512V19.167c0,0.81043-0.66471,1.47406-1.47514,1.47406H1.47514
C0.66477,20.64106,0,19.97743,0,19.167V1.47512z"/>
<g id="g5795" opacity="0.54">
<g id="g5797">
<linearGradient id="path5805_00000083768858156117840380000007545053210476265646_" gradientUnits="userSpaceOnUse" x1="4.99917" y1="1.33289" x2="4.99917" y2="19.45958">
<stop offset="0" style="stop-color:#3B3B3B"/>
<stop offset="1" style="stop-color:#242424"/>
</linearGradient>
<path id="path5805" inkscape:connector-curvature="0" fill="url(#path5805_00000083768858156117840380000007545053210476265646_)" d="
M2.19312,1.33289c-0.48687,0-0.88421,0.39734-0.88421,0.88421l0,0v16.35726c0,0.48687,0.3974,0.88522,0.88421,0.88522l0,0h5.61312
c0.48477,0,0.88319-0.39848,0.88319-0.88522l0,0V2.2171c0-0.48687-0.39842-0.88421-0.88319-0.88421l0,0H2.19312z"/>
</g>
</g>
<rect x="1.30993" y="18.58429" fill="none" width="0.6829" height="0.89523"/>
<rect x="0.99908" y="9.84516" opacity="0.44" width="8.00019" height="3.54676"/>
<g>
<linearGradient id="path5815_00000170964631234716849240000010152055143087385985_" gradientUnits="userSpaceOnUse" x1="5.00019" y1="1.33289" x2="5.00019" y2="10.17941">
<stop offset="0.00559" style="stop-color:#3D3B3B"/>
<stop offset="1" style="stop-color:#2D2C2C"/>
</linearGradient>
<path id="path5815" inkscape:connector-curvature="0" fill="url(#path5815_00000170964631234716849240000010152055143087385985_)" d="
M1.30993,1.33289h7.38052v8.84651H1.30993V1.33289z"/>
<path id="path5817" inkscape:connector-curvature="0" fill="#5E5E5E" d="M1.30993,4.87982h7.38052v0.87738H1.30993V4.87982z"/>
<path id="path5819" inkscape:connector-curvature="0" fill="#5E5E5E" d="M1.30993,8.42674h7.38052v0.87738H1.30993V8.42674z"/>
<path id="path5821" inkscape:connector-curvature="0" fill="#5E5E5E" d="M1.30993,6.65414h7.38052v0.87738H1.30993V6.65414z"/>
<path id="path5823" inkscape:connector-curvature="0" fill="#5E5E5E" d="M1.30993,3.10641h7.38052v0.87738H1.30993V3.10641z"/>
<path id="path5825" inkscape:connector-curvature="0" fill="#797979" d="M1.30993,1.33289h7.38052v0.87738H1.30993V1.33289z"/>
</g>
</svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.0"
id="svg56722"
inkscape:version="1.0.2-2 (e86c870879, 2021-01-15)"
x="0px"
y="0px"
width="10px"
height="20.64111px"
viewBox="0 0 10 20.64111"
enable-background="new 0 0 10 20.64111"
xml:space="preserve"
sodipodi:docname="SwitchNarrow_1.svg"><metadata
id="metadata32"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs30" />
<sodipodi:namedview
bordercolor="#666666"
borderopacity="1.0"
fit-margin-bottom="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-top="0"
id="base"
inkscape:current-layer="svg56722"
inkscape:cx="-7.1500998"
inkscape:cy="10.745459"
inkscape:document-rotation="0"
inkscape:document-units="mm"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:window-height="906"
inkscape:window-maximized="0"
inkscape:window-width="1779"
inkscape:window-x="2646"
inkscape:window-y="289"
inkscape:zoom="31.678384"
pagecolor="#ffffff"
showgrid="false"
units="px">
</sodipodi:namedview>
<path
id="path5785"
inkscape:connector-curvature="0"
d="M0,1.47512c0-0.81043,0.66471-1.47508,1.47514-1.47508h7.04972 C9.33523,0.00004,10,0.66482,10,1.47512V19.167c0,0.81043-0.66471,1.47406-1.47514,1.47406H1.47514 C0.66477,20.64106,0,19.97743,0,19.167V1.47512z" />
<g
id="g5795"
opacity="0.54">
<g
id="g5797">
<linearGradient
id="path5805_00000083768858156117840380000007545053210476265646_"
gradientUnits="userSpaceOnUse"
x1="4.99917"
y1="1.33289"
x2="4.99917"
y2="19.45958">
<stop
offset="0"
style="stop-color:#3B3B3B"
id="stop4" />
<stop
offset="1"
style="stop-color:#242424"
id="stop6" />
</linearGradient>
<path
id="path5805"
inkscape:connector-curvature="0"
fill="url(#path5805_00000083768858156117840380000007545053210476265646_)"
d=" M2.19312,1.33289c-0.48687,0-0.88421,0.39734-0.88421,0.88421l0,0v16.35726c0,0.48687,0.3974,0.88522,0.88421,0.88522l0,0h5.61312 c0.48477,0,0.88319-0.39848,0.88319-0.88522l0,0V2.2171c0-0.48687-0.39842-0.88421-0.88319-0.88421l0,0H2.19312z" />
</g>
</g>
<rect
x="1.30993"
y="18.58429"
fill="none"
width="0.6829"
height="0.89523"
id="rect12" />
<rect
x="0.99908"
y="13.750457"
opacity="0.44"
width="8.0001898"
height="3.5467601"
id="rect14" />
<g
id="g27"
transform="translate(0,4.64009)">
<linearGradient
id="path5815_00000170964631234716849240000010152055143087385985_"
gradientUnits="userSpaceOnUse"
x1="5.0001898"
y1="1.33289"
x2="5.0001898"
y2="10.17941">
<stop
offset="0.00559"
style="stop-color:#3D3B3B"
id="stop16" />
<stop
offset="1"
style="stop-color:#2D2C2C"
id="stop18" />
</linearGradient>
<path
id="path5815"
inkscape:connector-curvature="0"
fill="url(#path5815_00000170964631234716849240000010152055143087385985_)"
d="M 1.30993,1.33289 H 8.69045 V 10.1794 H 1.30993 Z"
style="fill:url(#path5815_00000170964631234716849240000010152055143087385985_)" />
<path
id="path5817"
inkscape:connector-curvature="0"
fill="#5e5e5e"
d="M 1.30993,4.87982 H 8.69045 V 5.7572 H 1.30993 Z" />
<path
id="path5819"
inkscape:connector-curvature="0"
fill="#5e5e5e"
d="M 1.30993,8.42674 H 8.69045 V 9.30412 H 1.30993 Z" />
<path
id="path5821"
inkscape:connector-curvature="0"
fill="#5e5e5e"
d="M 1.30993,6.65414 H 8.69045 V 7.53152 H 1.30993 Z" />
<path
id="path5823"
inkscape:connector-curvature="0"
fill="#5e5e5e"
d="M 1.30993,3.10641 H 8.69045 V 3.98379 H 1.30993 Z" />
<path
id="path5825"
inkscape:connector-curvature="0"
fill="#797979"
d="M 1.30993,1.33289 H 8.69045 V 2.21027 H 1.30993 Z" />
</g>
</svg>

+ 42
- 0
res/components/SwitchNarrow_2.svg View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 25.4.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.0"
id="svg56722" inkscape:version="1.0.2-2 (e86c870879, 2021-01-15)" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="10px" height="20.64111px"
viewBox="0 0 10 20.64111" enable-background="new 0 0 10 20.64111" xml:space="preserve">
<sodipodi:namedview bordercolor="#666666" borderopacity="1.0" fit-margin-bottom="0" fit-margin-left="0" fit-margin-right="0" fit-margin-top="0" id="base" inkscape:current-layer="layer1" inkscape:cx="-7.1500998" inkscape:cy="8.220078" inkscape:document-rotation="0" inkscape:document-units="mm" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:window-height="1393" inkscape:window-maximized="0" inkscape:window-width="2560" inkscape:window-x="0" inkscape:window-y="0" inkscape:zoom="31.678384" pagecolor="#ffffff" showgrid="false" units="px">
</sodipodi:namedview>
<path id="path5785" inkscape:connector-curvature="0" d="M0,1.47512c0-0.81043,0.66471-1.47508,1.47514-1.47508h7.04972
C9.33523,0.00004,10,0.66482,10,1.47512V19.167c0,0.81043-0.66471,1.47406-1.47514,1.47406H1.47514
C0.66477,20.64106,0,19.97743,0,19.167V1.47512z"/>
<g id="g5795" opacity="0.54">
<g id="g5797">
<linearGradient id="path5805_00000083768858156117840380000007545053210476265646_" gradientUnits="userSpaceOnUse" x1="4.99917" y1="1.33289" x2="4.99917" y2="19.45958">
<stop offset="0" style="stop-color:#3B3B3B"/>
<stop offset="1" style="stop-color:#242424"/>
</linearGradient>
<path id="path5805" inkscape:connector-curvature="0" fill="url(#path5805_00000083768858156117840380000007545053210476265646_)" d="
M2.19312,1.33289c-0.48687,0-0.88421,0.39734-0.88421,0.88421l0,0v16.35726c0,0.48687,0.3974,0.88522,0.88421,0.88522l0,0h5.61312
c0.48477,0,0.88319-0.39848,0.88319-0.88522l0,0V2.2171c0-0.48687-0.39842-0.88421-0.88319-0.88421l0,0H2.19312z"/>
</g>
</g>
<rect x="1.30993" y="18.58429" fill="none" width="0.6829" height="0.89523"/>
<rect x="0.99908" y="9.84516" opacity="0.44" width="8.00019" height="3.54676"/>
<g>
<linearGradient id="path5815_00000170964631234716849240000010152055143087385985_" gradientUnits="userSpaceOnUse" x1="5.00019" y1="1.33289" x2="5.00019" y2="10.17941">
<stop offset="0.00559" style="stop-color:#3D3B3B"/>
<stop offset="1" style="stop-color:#2D2C2C"/>
</linearGradient>
<path id="path5815" inkscape:connector-curvature="0" fill="url(#path5815_00000170964631234716849240000010152055143087385985_)" d="
M1.30993,1.33289h7.38052v8.84651H1.30993V1.33289z"/>
<path id="path5817" inkscape:connector-curvature="0" fill="#5E5E5E" d="M1.30993,4.87982h7.38052v0.87738H1.30993V4.87982z"/>
<path id="path5819" inkscape:connector-curvature="0" fill="#5E5E5E" d="M1.30993,8.42674h7.38052v0.87738H1.30993V8.42674z"/>
<path id="path5821" inkscape:connector-curvature="0" fill="#5E5E5E" d="M1.30993,6.65414h7.38052v0.87738H1.30993V6.65414z"/>
<path id="path5823" inkscape:connector-curvature="0" fill="#5E5E5E" d="M1.30993,3.10641h7.38052v0.87738H1.30993V3.10641z"/>
<path id="path5825" inkscape:connector-curvature="0" fill="#797979" d="M1.30993,1.33289h7.38052v0.87738H1.30993V1.33289z"/>
</g>
</svg>

+ 94
- 0
res/fonts/OFL.txt View File

@@ -0,0 +1,94 @@
Copyright (c) 2014, Cedric Knight <fonts@cedders.com>,
with Reserved Font Name "Segment7".
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

BIN
res/fonts/Segment7Standard.otf View File


+ 2564
- 0
res/panels/NoisePlethora.svg
File diff suppressed because it is too large
View File


+ 17
- 0
src/ABC.cpp View File

@@ -45,6 +45,23 @@ struct ABC : Module {
configParam(C1_LEVEL_PARAM, -1.0, 1.0, 0.0, "C1 Level");
configParam(B2_LEVEL_PARAM, -1.0, 1.0, 0.0, "B2 Level");
configParam(C2_LEVEL_PARAM, -1.0, 1.0, 0.0, "C2 Level");

configInput(A1_INPUT, "A1");
configInput(B1_INPUT, "B1");
configInput(C1_INPUT, "C1");
configInput(A2_INPUT, "A2");
configInput(B2_INPUT, "B2");
configInput(C2_INPUT, "C2");
getInputInfo(B1_INPUT)->description = "Normalled to 5V";
getInputInfo(C1_INPUT)->description = "Normalled to 10V";
getInputInfo(B2_INPUT)->description = "Normalled to 5V";
getInputInfo(C2_INPUT)->description = "Normalled to 10V";
configOutput(OUT1_OUTPUT, "Out 1");
configOutput(OUT2_OUTPUT, "Out 2");
getOutputInfo(OUT1_OUTPUT)->description = "Normalled to Out 2";
}

void processSection(const ProcessArgs& args, int& lastChannels, float_4* lastOut, ParamIds levelB, ParamIds levelC, InputIds inputA, InputIds inputB, InputIds inputC, OutputIds output, LightIds outLight) {


+ 4
- 2
src/ChoppingKinky.cpp View File

@@ -50,7 +50,7 @@ struct ChoppingKinky : Module {
chowdsp::VariableOversampling<> oversampler[NUM_CHANNELS];
int oversamplingIndex = 2; // default is 2^oversamplingIndex == x4 oversampling

dsp::BiquadFilter blockDCFilter;
DCBlocker blockDCFilter;
bool blockDC = false;

ChoppingKinky() {
@@ -68,6 +68,8 @@ struct ChoppingKinky : Module {
configInput(CV_B_INPUT, "CV B (with attenuator)");
configInput(VCA_CV_B_INPUT, "CV B");

getInputInfo(CV_B_INPUT)->description = "Normalled to CV A (with attenuator) Input";

configOutput(OUT_CHOPP_OUTPUT, "Chopp");
configOutput(OUT_A_OUTPUT, "A");
configOutput(OUT_B_OUTPUT, "B");
@@ -81,7 +83,7 @@ struct ChoppingKinky : Module {
void onSampleRateChange() override {
float sampleRate = APP->engine->getSampleRate();

blockDCFilter.setParameters(dsp::BiquadFilter::HIGHPASS, 10.3f / sampleRate, M_SQRT1_2, 1.0f);
blockDCFilter.setFrequency(22.05 / sampleRate);

for (int channel_idx = 0; channel_idx < NUM_CHANNELS; channel_idx++) {
oversampler[channel_idx].setOversamplingIndex(oversamplingIndex);


+ 12
- 10
src/EvenVCO.cpp View File

@@ -120,8 +120,10 @@ struct EvenVCO : Module {
phase[c / 4] += deltaPhase[c / 4];
}

// the next block can't be done with SIMD instructions:
for (int c = 0; c < channels; c++) {
// the next block can't be done with SIMD instructions, but should at least be completed with
// blocks of 4 (otherwise popping artfifacts are generated from invalid phase/oldPhase/deltaPhase)
const int channelsRoundedUpNearestFour = (1 + (channels - 1) / 4) * 4;
for (int c = 0; c < channelsRoundedUpNearestFour; c++) {

if (oldPhase[c / 4].s[c % 4] < 0.5 && phase[c / 4].s[c % 4] >= 0.5) {
float crossing = -(phase[c / 4].s[c % 4] - 0.5) / deltaPhase[c / 4].s[c % 4];
@@ -161,20 +163,13 @@ struct EvenVCO : Module {
float_4 square[4] = {};
float_4 triOut[4] = {};

for (int c = 0; c < channels; c++) {
for (int c = 0; c < channelsRoundedUpNearestFour; c++) {
triSquareMinBlepOut[c / 4].s[c % 4] = triSquareMinBlep[c].process();
doubleSawMinBlepOut[c / 4].s[c % 4] = doubleSawMinBlep[c].process();
sawMinBlepOut[c / 4].s[c % 4] = sawMinBlep[c].process();
squareMinBlepOut[c / 4].s[c % 4] = squareMinBlep[c].process();
}

// Outputs
outputs[TRI_OUTPUT].setChannels(channels);
outputs[SINE_OUTPUT].setChannels(channels);
outputs[EVEN_OUTPUT].setChannels(channels);
outputs[SAW_OUTPUT].setChannels(channels);
outputs[SQUARE_OUTPUT].setChannels(channels);

for (int c = 0; c < channels; c += 4) {

triSquare[c / 4] = simd::ifelse((phase[c / 4] < 0.5f), -1.f, +1.f);
@@ -208,6 +203,13 @@ struct EvenVCO : Module {
outputs[SAW_OUTPUT].setVoltageSimd(saw[c / 4], c);
outputs[SQUARE_OUTPUT].setVoltageSimd(square[c / 4], c);
}

// Outputs
outputs[TRI_OUTPUT].setChannels(channels);
outputs[SINE_OUTPUT].setChannels(channels);
outputs[EVEN_OUTPUT].setChannels(channels);
outputs[SAW_OUTPUT].setChannels(channels);
outputs[SQUARE_OUTPUT].setChannels(channels);
}
};



+ 10
- 2
src/HexmixVCA.cpp View File

@@ -42,8 +42,16 @@ struct HexmixVCA : Module {
HexmixVCA() {
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
for (int i = 0; i < numRows; ++i) {
configParam(SHAPE_PARAM + i, -1.f, 1.f, 0.f, string::f("Channel %d VCA response", i));
configParam(VOL_PARAM + i, 0.f, 1.f, 1.f, string::f("Channel %d output level", i));
configParam(SHAPE_PARAM + i, -1.f, 1.f, 0.f, string::f("Channel %d VCA response", i + 1));
configParam(VOL_PARAM + i, 0.f, 1.f, 1.f, string::f("Channel %d output level", i + 1));
configInput(IN_INPUT + i, string::f("Channel %d", i + 1));
configInput(CV_INPUT + i, string::f("Gain %d", i + 1));
configOutput(OUT_OUTPUT + i, string::f("Channel %d", i + 1));
getInputInfo(CV_INPUT + i)->description = "Normalled to 10V";
configBypass(IN_INPUT + i, OUT_OUTPUT + i);
}
cvDivider.setDivision(16);


+ 7
- 3
src/Kickall.cpp View File

@@ -40,7 +40,8 @@ struct Kickall : Module {
ADEnvelope volume;
ADEnvelope pitch;
dsp::SchmittTrigger trigger;
dsp::SchmittTrigger gateTrigger;
dsp::BooleanTrigger buttonTrigger;
static const int UPSAMPLE = 8;
chowdsp::Oversampling<UPSAMPLE> oversampler;
@@ -69,7 +70,7 @@ struct Kickall : Module {
configOutput(OUT_OUTPUT, "Kick");
configLight(ENV_LIGHT, "Volume envelope");
// calculate up/downsampling rates
onSampleRateChange();
}
@@ -80,7 +81,10 @@ struct Kickall : Module {
void process(const ProcessArgs& args) override {
// TODO: check values
if (trigger.process(inputs[TRIGG_INPUT].getVoltage() / 2.0f + params[TRIGG_BUTTON_PARAM].getValue() * 10.0)) {
const bool risingEdgeGate = gateTrigger.process(inputs[TRIGG_INPUT].getVoltage() / 2.0f);
const bool buttonTriggered = buttonTrigger.process(params[TRIGG_BUTTON_PARAM].getValue());
// can be triggered by either rising edge on trigger in, or a button press
if (risingEdgeGate || buttonTriggered) {
volume.trigger();
pitch.trigger();
}


+ 59
- 27
src/Muxlicer.cpp View File

@@ -254,9 +254,21 @@ struct Muxlicer : Module {

uint32_t runIndex; // which step are we on (0 to 7)
uint32_t addressIndex = 0;
bool playHeadHasReset = false;
bool tapped = false;

enum ResetStatus {
RESET_NOT_REQUESTED,
RESET_AND_PLAY_ONCE,
RESET_AND_PLAY
};
// Used to track if a reset has been triggered. Can be from the CV input, or the momentary switch. Note
// that behaviour depends on if the Muxlicer is clocked or not. If clocked, the playhead resets but waits
// for the next clock tick to start. If not clocked, then the sequence will start immediately (i.e. the
// internal clock will be synced at the point where `resetIsRequested` is first true.
ResetStatus resetRequested = RESET_NOT_REQUESTED;
// used to detect when `resetRequested` first becomes active
dsp::BooleanTrigger detectResetTrigger;

// used to track the clock (e.g. if external clock is not connected). NOTE: this clock
// is defined _prior_ to any clock division/multiplication logic
float internalClockProgress = 0.f;
@@ -266,7 +278,6 @@ struct Muxlicer : Module {
dsp::SchmittTrigger inputClockTrigger; // to detect incoming clock pulses
dsp::BooleanTrigger mainClockTrigger; // to detect when divided/multiplied version of the clock signal has rising edge
dsp::SchmittTrigger resetTrigger; // to detect the reset signal
dsp::PulseGenerator resetTimer; // leave a grace period before advancing the step
dsp::PulseGenerator endOfCyclePulse; // fire a signal at the end of cycle
dsp::BooleanTrigger tapTempoTrigger; // to only trigger tap tempo when push is first detected
MultDivClock mainClockMultDiv; // to produce a divided/multiplied version of the (internal or external) clock signal
@@ -430,7 +441,21 @@ struct Muxlicer : Module {
internalClockLength = tapTime;
}
tapTime = 0;
internalClockProgress = 0;
internalClockProgress = 0.f;
}

// If we get a reset signal (which can come from CV or various modes of the switch), and the clock has only
// just started to tick (internalClockProgress < 1ms), we assume that the reset signal is slightly delayed
// due to the 1 sample delay that Rack introduces. If this is the case, the internal clock trigger detector,
// `detectResetTrigger`, which advances the sequence, will not be "primed" to detect a rising edge for another
// whole clock tick, meaning the first step is repeated. See: https://github.com/VCVRack/Befaco/issues/32
// Also see https://vcvrack.com/manual/VoltageStandards#Timing for 0.001 seconds justification.
if (detectResetTrigger.process(resetRequested != RESET_NOT_REQUESTED) && internalClockProgress < 1e-3) {
// NOTE: the sequence must also be stopped for this to come into effect. In hardware, if the Nth step Gate Out
// is patched back into the reset, that step should complete before the sequence restarts.
if (playState == STATE_STOPPED) {
mainClockTrigger.state = false;
}
}
tapTime += args.sampleTime;
internalClockProgress += args.sampleTime;
@@ -451,20 +476,33 @@ struct Muxlicer : Module {
// so we must use a BooleanTrigger on the divided/mult'd signal in order to detect rising edge / when to advance the sequence
const bool dividedMultipliedClockPulseReceived = mainClockTrigger.process(mainClockMultDiv.process(args.sampleTime, clockPulseReceived));

// see https://vcvrack.com/manual/VoltageStandards#Timing
const bool resetGracePeriodActive = resetTimer.process(args.sampleTime);

if (dividedMultipliedClockPulseReceived) {
if (isAddressInRunMode && !resetGracePeriodActive && playState != STATE_STOPPED) {

if (resetRequested != RESET_NOT_REQUESTED) {
runIndex = 7;

if (resetRequested == RESET_AND_PLAY) {
playState = STATE_PLAY;
}
else if (resetRequested == RESET_AND_PLAY_ONCE) {
playState = STATE_PLAY_ONCE;

}
}

if (isAddressInRunMode && playState != STATE_STOPPED) {

runIndex++;

if (runIndex >= SEQUENCE_LENGTH) {

runIndex = 0;

// the sequence resets by placing the play head at the final step (so that the next clock pulse
// ticks over onto the first step) - so if we are on the final step _because_ we've reset,
// then don't fire EOC
if (playHeadHasReset) {
playHeadHasReset = false;
runIndex = 0;
// then don't fire EOC, just clear the reset status
if (resetRequested != RESET_NOT_REQUESTED) {
resetRequested = RESET_NOT_REQUESTED;
}
// otherwise we've naturally arrived at the last step so do fire EOC etc
else {
@@ -474,12 +512,10 @@ struct Muxlicer : Module {
if (playState == STATE_PLAY_ONCE) {
playState = STATE_STOPPED;
}
else {
runIndex = 0;
}
}
}
}

multiClock.reset(mainClockMultDiv.getEffectiveClockLength());

if (isAddressInRunMode) {
@@ -569,13 +605,12 @@ struct Muxlicer : Module {

const bool resetPulseInReceived = resetTrigger.process(rescale(inputs[RESET_INPUT].getVoltage(), 0.1f, 2.f, 0.f, 1.f));
if (resetPulseInReceived) {
playHeadHasReset = true;
runIndex = 8;

if (playState == STATE_STOPPED) {
playState = STATE_PLAY_ONCE;
switch (playState) {
case STATE_STOPPED: resetRequested = RESET_AND_PLAY_ONCE; break;
case STATE_PLAY_ONCE: resetRequested = RESET_AND_PLAY_ONCE; break;
case STATE_PLAY: resetRequested = RESET_AND_PLAY; break;
}
resetTimer.trigger();
}

// if the play switch has effectively been activated for the first time,
@@ -583,19 +618,17 @@ struct Muxlicer : Module {
const bool switchIsActive = params[PLAY_PARAM].getValue() != STATE_STOPPED;
if (playStateTrigger.process(switchIsActive) && switchIsActive) {

// if we were stopped, check for activation (normal or one-shot)
// if we were stopped, check for activation (normal, up or one-shot, down)
if (playState == STATE_STOPPED) {
if (params[PLAY_PARAM].getValue() == STATE_PLAY) {
playState = STATE_PLAY;
resetRequested = RESET_AND_PLAY;
}
else if (params[PLAY_PARAM].getValue() == STATE_PLAY_ONCE) {
playState = STATE_PLAY_ONCE;
runIndex = 8;
playHeadHasReset = true;
resetRequested = RESET_AND_PLAY_ONCE;
}
}
// otherwise we are in play mode (and we've not just held onto the play switch),
// so check for stop or reset
// so check for stop (switch up) or reset (switch down)
else {

// top switch will stop
@@ -604,8 +637,7 @@ struct Muxlicer : Module {
}
// bottom will reset
else if (params[PLAY_PARAM].getValue() == STATE_PLAY_ONCE) {
playHeadHasReset = true;
runIndex = 8;
resetRequested = RESET_AND_PLAY_ONCE;
}
}
}


+ 905
- 0
src/NoisePlethora.cpp View File

@@ -0,0 +1,905 @@
#include "plugin.hpp"
#include "noise-plethora/plugins/NoisePlethoraPlugin.hpp"
#include "noise-plethora/plugins/ProgramSelector.hpp"

enum FilterMode {
LOWPASS,
HIGHPASS,
BANDPASS,
NUM_TYPES
};


// Zavalishin 2018, "The Art of VA Filter Design", http://www.native-instruments.com/fileadmin/ni_media/downloads/pdf/VAFilterDesign_2.0.0a.pdf
// Section 6.7, adopted from BogAudio Saturator https://github.com/bogaudio/BogaudioModules/blob/master/src/dsp/signal.cpp
struct Saturator {

// saturate input at around ~[-1, +1] with soft clipping
static float process(float sample) {

if (sample < 0.0f) {
return -saturation(-sample);
}
return saturation(sample);
}
private:

static float saturation(float sample) {

const float limit = 1.05f;
const float y1 = 0.98765f; // (2*x - 1)/x**2 where x is 0.9.
// correction so that saturation(0) = 0
const float offset = 0.0062522; // -0.5f + sqrtf(0.5f * 0.5f) / y1;

float x = sample / limit;
float x1 = (x + 1.0f) * 0.5f;

return limit * (offset + x1 - std::sqrt(x1 * x1 - y1 * x) * (1.0f / y1));
}
};

// based on Chapter 4 of THE ART OF VA FILTER DESIGN and
// Chap 12.4 of "Designing Audio Effect Plugins in C++" Will Pirkle
class StateVariableFilter2ndOrder {
public:

StateVariableFilter2ndOrder() {
setParameters(0.f, M_SQRT1_2);
}

void setParameters(float fc, float q) {
// avoid repeated evaluations of tanh if not needed
if (fc != fcCached || q != qCached) {

fcCached = fc;
qCached = q;

const double g = std::tan(M_PI * fc);
const double R = 1.0f / (2 * q);

alpha0 = 1.0 / (1.0 + 2.0 * R * g + g * g);
alpha = g;
rho = 2.0 * R + g;
}
}

void process(float input) {
hp = (input - rho * mem1 - mem2) * alpha0;
bp = alpha * hp + mem1;
lp = alpha * bp + mem2;
mem1 = alpha * hp + bp;
mem2 = alpha * bp + lp;
}

float output(FilterMode mode) {
switch (mode) {
case LOWPASS: return lp;
case HIGHPASS: return hp;
case BANDPASS: return bp;
default: return 0.0;
}
}

private:
float alpha, alpha0, rho;

float fcCached = -1.f, qCached = -1.f;

float hp = 0.0f, bp = 0.0f, lp = 0.0f, mem1 = 0.0f, mem2 = 0.0f;
};

class StateVariableFilter4thOrder {

public:
StateVariableFilter4thOrder() {

}

void setParameters(float fc, float q) {
float rootQ = std::sqrt(q);
stage1.setParameters(fc, rootQ);
stage2.setParameters(fc, rootQ);
}

float process(float input, FilterMode mode) {
stage1.process(input);
float s1 = stage1.output(mode);

stage2.process(s1);
float s2 = stage2.output(mode);

return s2;
}

private:
StateVariableFilter2ndOrder stage1, stage2;
};


struct NoisePlethora : Module {
enum ParamIds {
// A params
X_A_PARAM,
Y_A_PARAM,
CUTOFF_A_PARAM,
RES_A_PARAM,
CUTOFF_CV_A_PARAM,
FILTER_TYPE_A_PARAM,
// misc
PROGRAM_PARAM,
// B params
X_B_PARAM,
Y_B_PARAM,
CUTOFF_B_PARAM,
RES_B_PARAM,
CUTOFF_CV_B_PARAM,
FILTER_TYPE_B_PARAM,
// C params
GRIT_PARAM,
RES_C_PARAM,
CUTOFF_C_PARAM,
CUTOFF_CV_C_PARAM,
FILTER_TYPE_C_PARAM,
SOURCE_C_PARAM,
NUM_PARAMS
};
enum InputIds {
X_A_INPUT,
Y_A_INPUT,
CUTOFF_A_INPUT,
PROG_A_INPUT,
PROG_B_INPUT,
CUTOFF_B_INPUT,
X_B_INPUT,
Y_B_INPUT,
GRIT_INPUT,
CUTOFF_C_INPUT,
NUM_INPUTS
};
enum OutputIds {
A_OUTPUT,
B_OUTPUT,
GRITTY_OUTPUT,
FILTERED_OUTPUT,
WHITE_OUTPUT,
NUM_OUTPUTS
};
enum LightIds {
BANK_LIGHT,
NUM_LIGHTS
};

enum Section {
SECTION_A,
SECTION_B,
SECTION_C,
NUM_SECTIONS
};

enum ProgramKnobMode {
PROGRAM_MODE,
BANK_MODE
};
ProgramKnobMode programKnobMode = PROGRAM_MODE;
// one full turn of the program knob corresponds to an increment of dialResolution to the bank/program
static constexpr int dialResolution = 8;
// variable to store what the program knob was prior to the start of dragging (used to calculate deltas)
float programKnobReferenceState = 0.f;

// section A/B
bool bypassFilters = false;
std::shared_ptr<NoisePlethoraPlugin> algorithm[2]; // pointer to actual algorithm
std::string algorithmName[2]; // variable to cache which algorithm is active (after program CV applied)

// filters for A/B
StateVariableFilter2ndOrder svfFilter[2];
bool blockDC = true;
DCBlocker blockDCFilter[3];

ProgramSelector programSelector; // tracks banks and programs for both sections A/B, including which is the "active" section
ProgramSelector programSelectorWithCV; // as above, but also with CV for program applied as an offset - works like Plaits Model CV input
// UI / UX for A/B
std::string textDisplayA = " ", textDisplayB = " ";
bool isDisplayActiveA = false, isDisplayActiveB = false;
bool programButtonHeld = false;
bool programButtonDragged = false;
dsp::BooleanTrigger programHoldTrigger;
dsp::Timer programHoldTimer;

dsp::PulseGenerator updateParamsTimer;
const float updateTimeSecs = 0.0029f;

// section C
AudioSynthNoiseWhiteFloat whiteNoiseSource;
AudioSynthNoiseGritFloat gritNoiseSource;
StateVariableFilter4thOrder svfFilterC;
FilterMode typeMappingSVF[3] = {LOWPASS, BANDPASS, HIGHPASS};

NoisePlethora() {
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
configParam(X_A_PARAM, 0.f, 1.f, 0.5f, "XA");
configParam(RES_A_PARAM, 0.f, 1.f, 0.f, "Resonance A");
configParam(CUTOFF_A_PARAM, 0.f, 1.f, 1.f, "Cutoff A");
configParam(Y_A_PARAM, 0.f, 1.f, 0.5f, "YA");
configParam(CUTOFF_CV_A_PARAM, 0.f, 1.f, 0.f, "Cutoff CV A");
configSwitch(FILTER_TYPE_A_PARAM, 0.f, 2.f, 0.f, "Filter type", {"Lowpass", "Bandpass", "Highpass"});
configParam(PROGRAM_PARAM, -INFINITY, +INFINITY, 0.f, "Program/Bank selection");
configSwitch(FILTER_TYPE_B_PARAM, 0.f, 2.f, 0.f, "Filter type", {"Lowpass", "Bandpass", "Highpass"});
configParam(CUTOFF_CV_B_PARAM, 0.f, 1.f, 0.f, "Cutoff B");
configParam(X_B_PARAM, 0.f, 1.f, 0.5f, "XB");
configParam(CUTOFF_B_PARAM, 0.f, 1.f, 1.f, "Cutoff CV B");
configParam(RES_B_PARAM, 0.f, 1.f, 0.f, "Resonance B");
configParam(Y_B_PARAM, 0.f, 1.f, 0.5f, "YB");
configSwitch(FILTER_TYPE_C_PARAM, 0.f, 2.f, 0.f, "Filter type", {"Lowpass", "Bandpass", "Highpass"});
configParam(CUTOFF_C_PARAM, 0.f, 1.f, 1.f, "Cutoff C");
configParam(GRIT_PARAM, 0.f, 1.f, 0.f, "Grit Quantity");
configParam(RES_C_PARAM, 0.f, 1.f, 0.f, "Resonance C");
configParam(CUTOFF_CV_C_PARAM, 0.f, 1.f, 0.f, "Cutoff CV C");
configSwitch(SOURCE_C_PARAM, 0.f, 1.f, 0.f, "Filter source", {"Gritty", "White"});

configInput(X_A_INPUT, "XA CV");
configInput(Y_A_INPUT, "YA CV");
configInput(CUTOFF_A_INPUT, "Cutoff CV A");
configInput(PROG_A_INPUT, "Program select A");
configInput(PROG_B_INPUT, "Program select B");
configInput(CUTOFF_B_INPUT, "Cutoff CV B");
configInput(X_B_INPUT, "XB CV");
configInput(Y_B_INPUT, "YB CV");
configInput(GRIT_INPUT, "Grit Quantity CV");
configInput(CUTOFF_C_INPUT, "Cutoff CV C");

configOutput(A_OUTPUT, "Algorithm A");
configOutput(B_OUTPUT, "Algorithm B");
configOutput(GRITTY_OUTPUT, "Gritty noise");
configOutput(FILTERED_OUTPUT, "Filtered noise");
configOutput(WHITE_OUTPUT, "White noise");

configLight(BANK_LIGHT, "Bank mode");

getInputInfo(PROG_A_INPUT)->description = "CV sums with active program (0.5V increments)";
getInputInfo(PROG_B_INPUT)->description = "CV sums with active program (0.5V increments)";

setAlgorithm(SECTION_B, "radioOhNo");
setAlgorithm(SECTION_A, "radioOhNo");
onSampleRateChange();
}

void onReset(const ResetEvent& e) override {
setAlgorithm(SECTION_B, "radioOhNo");
setAlgorithm(SECTION_A, "radioOhNo");
Module::onReset(e);
}

void onSampleRateChange() override {
// set ~20Hz DC blocker
const float fc = 22.05f / APP->engine->getSampleRate();

blockDCFilter[SECTION_A].setFrequency(fc);
blockDCFilter[SECTION_B].setFrequency(fc);
blockDCFilter[SECTION_C].setFrequency(fc);

if (algorithm[SECTION_A]) {
algorithm[SECTION_A]->init();
}
if (algorithm[SECTION_B]) {
algorithm[SECTION_B]->init();
}
}

void process(const ProcessArgs& args) override {

// we only periodically update parameters of each algorithm (once per block, ~2.9ms at 44100Hz)
bool updateParams = false;
if (!updateParamsTimer.process(args.sampleTime)) {
updateParams = true;
updateParamsTimer.trigger(updateTimeSecs);
}

// process A, B and C
processTopSection(SECTION_A, X_A_PARAM, Y_A_PARAM,
FILTER_TYPE_A_PARAM, CUTOFF_A_PARAM, CUTOFF_CV_A_PARAM, RES_A_PARAM,
PROG_A_INPUT, X_A_INPUT, Y_A_INPUT, CUTOFF_A_INPUT, A_OUTPUT, args, updateParams);
processTopSection(SECTION_B, X_B_PARAM, Y_B_PARAM,
FILTER_TYPE_B_PARAM, CUTOFF_B_PARAM, CUTOFF_CV_B_PARAM, RES_B_PARAM,
PROG_B_INPUT, X_B_INPUT, Y_B_INPUT, CUTOFF_B_INPUT, B_OUTPUT, args, updateParams);
processBottomSection(args);

// UI
updateDataForLEDDisplay();
processProgramBankKnobLogic(args);
}

// process CV for section, specifically: work out the offset relative to the current
// program and see if this is a new algorithm
void processCVOffsets(Section SECTION, InputIds PROG_INPUT) {

const int offset = 2 * inputs[PROG_INPUT].getVoltage();

const int bank = programSelector.getSection(SECTION).getBank();
const int numProgramsForBank = getBankForIndex(bank).getSize();

const int programWithoutCV = programSelector.getSection(SECTION).getProgram();
const int programWithCV = unsigned_modulo(programWithoutCV + offset, numProgramsForBank);

// duplicate key settings to programSelectorWithCV (expect modified program)
programSelectorWithCV.setMode(programSelector.getMode());
programSelectorWithCV.getSection(SECTION).setBank(bank);
programSelectorWithCV.getSection(SECTION).setProgram(programWithCV);

const std::string newAlgorithmName = programSelectorWithCV.getSection(SECTION).getCurrentProgramName();

// this is just a caching check to avoid constantly re-initialisating the algorithms
if (newAlgorithmName != algorithmName[SECTION]) {

algorithm[SECTION] = MyFactory::Instance()->Create(newAlgorithmName);
algorithmName[SECTION] = newAlgorithmName;

if (algorithm[SECTION]) {
algorithm[SECTION]->init();
}
else {
DEBUG("WARNING: Failed to initialise %s in programSelector", newAlgorithmName.c_str());
}
}
}

// exactly the same for A and B
void processTopSection(Section SECTION, ParamIds X_PARAM, ParamIds Y_PARAM, ParamIds FILTER_TYPE_PARAM,
ParamIds CUTOFF_PARAM, ParamIds CUTOFF_CV_PARAM, ParamIds RES_PARAM,
InputIds PROG_INPUT, InputIds X_INPUT, InputIds Y_INPUT, InputIds CUTOFF_INPUT, OutputIds OUTPUT,
const ProcessArgs& args, bool updateParams) {

// periodically work out how CV should modify the current sections algorithm
if (updateParams) {
processCVOffsets(SECTION, PROG_INPUT);
}

float out = 0.f;
if (algorithm[SECTION] && outputs[OUTPUT].isConnected()) {
float cvX = params[X_PARAM].getValue() + rescale(inputs[X_INPUT].getVoltage(), -10.f, +10.f, -1.f, 1.f);
float cvY = params[Y_PARAM].getValue() + rescale(inputs[Y_INPUT].getVoltage(), -10.f, +10.f, -1.f, 1.f);

// update parameters of the algorithm
if (updateParams) {
algorithm[SECTION]->process(clamp(cvX, 0.f, 1.f), clamp(cvY, 0.f, 1.f));
}
// process the audio graph
out = algorithm[SECTION]->processGraph();
// each algorithm has a specific gain factor
out = out * programSelectorWithCV.getSection(SECTION).getCurrentProgramGain();

// if filters are active
if (!bypassFilters) {

// set parameters
const float freqCV = std::pow(params[CUTOFF_CV_PARAM].getValue(), 2) * inputs[CUTOFF_INPUT].getVoltage();
const float pitch = rescale(params[CUTOFF_PARAM].getValue(), 0, 1, -5.5, +5.5) + freqCV;
const float cutoff = clamp(dsp::FREQ_C4 * std::pow(2.f, pitch), 1.f, 20000.);
const float cutoffNormalised = clamp(cutoff / args.sampleRate, 0.f, 0.49f);
const float q = M_SQRT1_2 + std::pow(params[RES_PARAM].getValue(), 2) * 10.f;
const FilterMode mode = typeMappingSVF[(int) params[FILTER_TYPE_PARAM].getValue()];
svfFilter[SECTION].setParameters(cutoffNormalised, q);

// apply filter
svfFilter[SECTION].process(out);
// and retrieve relevant output
out = svfFilter[SECTION].output(mode);
}

if (blockDC) {
// cascaded Biquad (4th order highpass at ~20Hz)
out = blockDCFilter[SECTION].process(out);
}
}

outputs[OUTPUT].setVoltage(Saturator::process(out) * 5.f);
}

// process section C
void processBottomSection(const ProcessArgs& args) {

float gritCv = rescale(clamp(inputs[GRIT_INPUT].getVoltage(), -10.f, 10.f), -10.f, 10.f, -1.f, 1.f);
float gritAmount = clamp(1.f - params[GRIT_PARAM].getValue() - gritCv, 0.f, 1.f);
float gritFrequency = 0.1 + std::pow(gritAmount, 2) * 20000;
gritNoiseSource.setDensity(gritFrequency);
float gritNoise = gritNoiseSource.process(args.sampleTime);
outputs[GRITTY_OUTPUT].setVoltage(gritNoise * 5.f);

float whiteNoise = whiteNoiseSource.process();
outputs[WHITE_OUTPUT].setVoltage(whiteNoise * 5.f);

float out = 0.f;
if (outputs[FILTERED_OUTPUT].isConnected() && !bypassFilters) {

const float freqCV = std::pow(params[CUTOFF_CV_C_PARAM].getValue(), 2) * inputs[CUTOFF_C_INPUT].getVoltage();
const float pitch = rescale(params[CUTOFF_C_PARAM].getValue(), 0, 1, -5.f, +6.4f) + freqCV;
const float cutoff = clamp(dsp::FREQ_C4 * std::pow(2.f, pitch), 1.f, 44100. / 2.f);
const float cutoffNormalised = clamp(cutoff / args.sampleRate, 0.f, 0.49f);
const float Q = 0.5 + std::pow(params[RES_C_PARAM].getValue(), 2) * 20.f;
const FilterMode mode = typeMappingSVF[(int) params[FILTER_TYPE_C_PARAM].getValue()];
svfFilterC.setParameters(cutoffNormalised, Q);

float toFilter = params[SOURCE_C_PARAM].getValue() ? whiteNoise : gritNoise;
out = svfFilterC.process(toFilter, mode);

// assymetric saturator, to get those lovely even harmonics
out = Saturator::process(out + 0.33);

if (blockDC) {
// cascaded Biquad (4th order highpass at ~20Hz)
out = blockDCFilter[SECTION_C].process(out);
}
}
else if (bypassFilters) {
out = params[SOURCE_C_PARAM].getValue() ? whiteNoise : gritNoise;
}

outputs[FILTERED_OUTPUT].setVoltage(out * 5.f);
}

// set which text NoisePlethoraWidget should display on the 7 segment display
void updateDataForLEDDisplay() {

if (programKnobMode == PROGRAM_MODE) {
textDisplayA = std::to_string(programSelectorWithCV.getA().getProgram());
}
else if (programKnobMode == BANK_MODE) {
textDisplayA = 'A' + programSelectorWithCV.getA().getBank();
}
isDisplayActiveA = programSelectorWithCV.getMode() == SECTION_A;

if (programKnobMode == PROGRAM_MODE) {
textDisplayB = std::to_string(programSelectorWithCV.getB().getProgram());
}
else if (programKnobMode == BANK_MODE) {
textDisplayB = 'A' + programSelectorWithCV.getB().getBank();
}
isDisplayActiveB = programSelectorWithCV.getMode() == SECTION_B;
}

// handle convoluted logic for the multifunction Program knob
void processProgramBankKnobLogic(const ProcessArgs& args) {

// program knob will either change program for current bank...
if (programButtonDragged) {
// work out the change (in discrete increments) since the program/bank knob started being dragged
const int delta = (int)(dialResolution * (params[PROGRAM_PARAM].getValue() - programKnobReferenceState));

if (programKnobMode == PROGRAM_MODE) {
const int numProgramsForCurrentBank = getBankForIndex(programSelector.getCurrent().getBank()).getSize();

if (delta != 0) {
const int newProgramFromKnob = unsigned_modulo(programSelector.getCurrent().getProgram() + delta, numProgramsForCurrentBank);
programKnobReferenceState = params[PROGRAM_PARAM].getValue();
setAlgorithmViaProgram(newProgramFromKnob);
}
}
// ...or change bank, (trying to) keep program the same
else {

if (delta != 0) {
const int newBankFromKnob = unsigned_modulo(programSelector.getCurrent().getBank() + delta, numBanks);
programKnobReferenceState = params[PROGRAM_PARAM].getValue();
setAlgorithmViaBank(newBankFromKnob);
}
}
}

// if we have a new "press" on the knob, time it
if (programHoldTrigger.process(programButtonHeld)) {
programHoldTimer.reset();
}

// but cancel if it's actually a knob drag
if (programButtonDragged) {
programHoldTimer.reset();
programButtonHeld = false;
}
else {
if (programButtonHeld) {
programHoldTimer.process(args.sampleTime);

// if we've held for at least 0.5 seconds, switch into "bank mode"
if (programHoldTimer.time > 0.5f) {
programButtonHeld = false;
programHoldTimer.reset();

if (programKnobMode == PROGRAM_MODE) {
programKnobMode = BANK_MODE;
}
else {
programKnobMode = PROGRAM_MODE;
}

lights[BANK_LIGHT].setBrightness(programKnobMode == BANK_MODE);
}
}
// no longer held, but has been held for non-zero time (without being dragged), toggle "active" section (A or B),
// this is effectively just a "click"
else if (programHoldTimer.time > 0.f) {
programSelector.setMode(!programSelector.getMode());
programHoldTimer.reset();
}
}

if (!programButtonDragged) {
programKnobReferenceState = params[PROGRAM_PARAM].getValue();
}
}

void setAlgorithmViaProgram(int newProgram) {

const int currentBank = programSelector.getCurrent().getBank();
const std::string algorithmName = getBankForIndex(currentBank).getProgramName(newProgram);
const int section = programSelector.getMode();

setAlgorithm(section, algorithmName);
}

void setAlgorithmViaBank(int newBank) {
newBank = clamp(newBank, 0, numBanks - 1);
const int currentProgram = programSelector.getCurrent().getProgram();
// the new bank may not have as many algorithms
const int currentProgramInNewBank = clamp(currentProgram, 0, getBankForIndex(newBank).getSize() - 1);
const std::string algorithmName = getBankForIndex(newBank).getProgramName(currentProgramInNewBank);
const int section = programSelector.getMode();

setAlgorithm(section, algorithmName);
}

void setAlgorithm(int section, std::string algorithmName) {

if (section > 1) {
return;
}

for (int bank = 0; bank < numBanks; ++bank) {
for (int program = 0; program < getBankForIndex(bank).getSize(); ++program) {
if (getBankForIndex(bank).getProgramName(program) == algorithmName) {
programSelector.setMode(section);
programSelector.getCurrent().setBank(bank);
programSelector.getCurrent().setProgram(program);

return;
}
}
}

DEBUG("WARNING: Didn't find %s in programSelector", algorithmName.c_str());
}

void dataFromJson(json_t* rootJ) override {
json_t* bankAJ = json_object_get(rootJ, "algorithmA");
if (bankAJ) {
setAlgorithm(SECTION_A, json_string_value(bankAJ));
}

json_t* bankBJ = json_object_get(rootJ, "algorithmB");
if (bankBJ) {
setAlgorithm(SECTION_B, json_string_value(bankBJ));
}

json_t* bypassFiltersJ = json_object_get(rootJ, "bypassFilters");
if (bypassFiltersJ) {
bypassFilters = json_boolean_value(bypassFiltersJ);
}

json_t* blockDCJ = json_object_get(rootJ, "blockDC");
if (blockDCJ) {
blockDC = json_boolean_value(blockDCJ);
}
}

json_t* dataToJson() override {
json_t* rootJ = json_object();

json_object_set_new(rootJ, "algorithmA", json_string(programSelector.getA().getCurrentProgramName().c_str()));
json_object_set_new(rootJ, "algorithmB", json_string(programSelector.getB().getCurrentProgramName().c_str()));

json_object_set_new(rootJ, "bypassFilters", json_boolean(bypassFilters));
json_object_set_new(rootJ, "blockDC", json_boolean(blockDC));

return rootJ;
}
};


struct BefacoTinyKnobSnapPress : BefacoTinyKnobBlack {
BefacoTinyKnobSnapPress() { }

// this seems convoluted but I can't see how to achieve the following (say) with onAction:
// a) need to support standard knob dragging behaviour
// b) need to support click detection (not drag)
// c) need to distinguish short click from long click
//
// To achieve this we have 2 state variables, held and dragged. The Module thread will
// time how long programButtonHeld is "true" and switch between bank and program mode if
// longer than X secs. A drag, as measured here as a displacement greater than Y, will cancel
// this timer and we're back to normal param mode. See processProgramBankKnobLogic(...) for details
void onDragStart(const DragStartEvent& e) override {
NoisePlethora* noisePlethoraModule = static_cast<NoisePlethora*>(module);
if (noisePlethoraModule) {
noisePlethoraModule->programButtonHeld = true;
noisePlethoraModule->programButtonDragged = false;
}

pos = Vec(0, 0);
Knob::onDragStart(e);
}

void onDragMove(const DragMoveEvent& e) override {
pos += e.mouseDelta;
NoisePlethora* noisePlethoraModule = static_cast<NoisePlethora*>(module);

// cancel if we're doing a drag
if (noisePlethoraModule && std::sqrt(pos.square()) > 5) {
noisePlethoraModule->programButtonHeld = false;
noisePlethoraModule->programButtonDragged = true;
}

Knob::onDragMove(e);
}

void onDragEnd(const DragEndEvent& e) override {

NoisePlethora* noisePlethoraModule = static_cast<NoisePlethora*>(module);
if (noisePlethoraModule) {
noisePlethoraModule->programButtonHeld = false;
}

Knob::onDragEnd(e);
}

// suppress double click
void onDoubleClick(const DoubleClickEvent& e) override {}

Vec pos;
};

// dervied from https://github.com/countmodula/VCVRackPlugins/blob/v2.0.0/src/components/CountModulaLEDDisplay.hpp
struct NoisePlethoraLEDDisplay : LightWidget {
float fontSize = 28;
Vec textPos = Vec(2, 25);
int numChars = 1;
bool activeDisplay = true;
NoisePlethora* module;
NoisePlethora::Section section = NoisePlethora::SECTION_A;
ui::Tooltip* tooltip;

NoisePlethoraLEDDisplay() {
box.size = mm2px(Vec(7.236, 10));
}

void onEnter(const EnterEvent& e) override {
LightWidget::onEnter(e);
setTooltip();
}

void setTooltip() {
std::string activeName = module->programSelector.getSection(section).getCurrentProgramName();
tooltip = new ui::Tooltip;
tooltip->text = activeName;
APP->scene->addChild(tooltip);
}

void onHover(const event::Hover& e) override {
LightWidget::onHover(e);
e.consume(this);
}

void onLeave(const event::Leave& e) override {
LightWidget::onLeave(e);

APP->scene->removeChild(tooltip);
this->tooltip->requestDelete();
this->tooltip = NULL;
}

void setCentredPos(Vec pos) {
box.pos.x = pos.x - box.size.x / 2;
box.pos.y = pos.y - box.size.y / 2;
}

void drawBackground(const DrawArgs& args) override {
// Background
NVGcolor backgroundColor = nvgRGB(0x24, 0x14, 0x14);
NVGcolor borderColor = nvgRGB(0x10, 0x10, 0x10);
nvgBeginPath(args.vg);
nvgRoundedRect(args.vg, 0.0, 0.0, box.size.x, box.size.y, 2.0);
nvgFillColor(args.vg, backgroundColor);
nvgFill(args.vg);
nvgStrokeWidth(args.vg, 1.0);
nvgStrokeColor(args.vg, borderColor);
nvgStroke(args.vg);
}

void drawLight(const DrawArgs& args) override {
// Background
NVGcolor backgroundColor = nvgRGB(0x24, 0x14, 0x14);
NVGcolor borderColor = nvgRGB(0x10, 0x10, 0x10);
NVGcolor textColor = nvgRGB(0xaa, 0x20, 0x20);

// use slightly different LED colour if CV is connected as visual cue
if (module) {
NoisePlethora::InputIds inputId = (section == NoisePlethora::SECTION_A) ? NoisePlethora::PROG_A_INPUT : NoisePlethora::PROG_B_INPUT;
if (module->inputs[inputId].isConnected()) {
textColor = nvgRGB(0xff, 0x40, 0x40);
}
}

nvgBeginPath(args.vg);
nvgRoundedRect(args.vg, 0.0, 0.0, box.size.x, box.size.y, 2.0);
nvgFillColor(args.vg, backgroundColor);
nvgFill(args.vg);
nvgStrokeWidth(args.vg, 1.0);
nvgStrokeColor(args.vg, borderColor);
nvgStroke(args.vg);

std::shared_ptr<Font> font = APP->window->loadFont(asset::plugin(pluginInstance, "res/fonts/Segment7Standard.otf"));

if (font && font->handle >= 0) {

std::string text = "A"; // fallback if module not yet defined
if (module) {
text = (section == NoisePlethora::SECTION_A) ? module->textDisplayA : module->textDisplayB;
}
char buffer[numChars + 1];
int l = text.size();
if (l > numChars)
l = numChars;

nvgGlobalTint(args.vg, color::WHITE);

text.copy(buffer, l);
buffer[numChars] = '\0';

nvgFontSize(args.vg, fontSize);
nvgFontFaceId(args.vg, font->handle);
nvgTextLetterSpacing(args.vg, 1);

// render the "off" segments
nvgFillColor(args.vg, nvgTransRGBA(textColor, 18));
nvgText(args.vg, textPos.x, textPos.y, "8", NULL);

// render the "on segments"
nvgFillColor(args.vg, textColor);

nvgText(args.vg, textPos.x, textPos.y, buffer, NULL);
}

if (module) {
const bool isSectionDisplayActive = (section == NoisePlethora::SECTION_A) ? module->isDisplayActiveA : module->isDisplayActiveB;

// active bank dot
nvgBeginPath(args.vg);
nvgCircle(args.vg, 18, 26, 1.5);
nvgFillColor(args.vg, isSectionDisplayActive ? textColor : nvgTransRGBA(textColor, 18));
nvgFill(args.vg);
}
}
};

struct NoisePlethoraWidget : ModuleWidget {
NoisePlethoraWidget(NoisePlethora* module) {
setModule(module);
setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/panels/NoisePlethora.svg")));

addChild(createWidget<Knurlie>(Vec(RACK_GRID_WIDTH, 0)));
addChild(createWidget<Knurlie>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, 0)));
addChild(createWidget<Knurlie>(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
addChild(createWidget<Knurlie>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));

// A params
addParam(createParamCentered<BefacoTinyKnobDarkGrey>(mm2px(Vec(22.325, 16.09)), module, NoisePlethora::X_A_PARAM));
addParam(createParamCentered<BefacoTinyKnobDarkGrey>(mm2px(Vec(22.325, 30.595)), module, NoisePlethora::Y_A_PARAM));
addParam(createParamCentered<Davies1900hLargeGreyKnob>(mm2px(Vec(43.248, 23.058)), module, NoisePlethora::CUTOFF_A_PARAM));
addParam(createParamCentered<BefacoTinyKnobDarkGrey>(mm2px(Vec(63.374, 16.09)), module, NoisePlethora::RES_A_PARAM));
addParam(createParamCentered<BefacoTinyKnobDarkGrey>(mm2px(Vec(63.374, 30.595)), module, NoisePlethora::CUTOFF_CV_A_PARAM));
addParam(createParam<CKSSNarrow3>(mm2px(Vec(41.494, 38.579)), module, NoisePlethora::FILTER_TYPE_A_PARAM));

// (bank)
addParam(createParamCentered<BefacoTinyKnobSnapPress>(mm2px(Vec(30.866, 49.503)), module, NoisePlethora::PROGRAM_PARAM));

// B params
addParam(createParamCentered<BefacoTinyKnobLightGrey>(mm2px(Vec(22.345, 68.408)), module, NoisePlethora::X_B_PARAM));
addParam(createParamCentered<BefacoTinyKnobLightGrey>(mm2px(Vec(22.345, 82.695)), module, NoisePlethora::Y_B_PARAM));
addParam(createParamCentered<Davies1900hLargeLightGreyKnob>(mm2px(Vec(43.248, 75.551)), module, NoisePlethora::CUTOFF_B_PARAM));
addParam(createParamCentered<BefacoTinyKnobLightGrey>(mm2px(Vec(63.383, 82.686)), module, NoisePlethora::RES_B_PARAM));
addParam(createParamCentered<BefacoTinyKnobLightGrey>(mm2px(Vec(63.36, 68.388)), module, NoisePlethora::CUTOFF_CV_B_PARAM));
addParam(createParam<CKSSNarrow3>(mm2px(Vec(41.494, 53.213)), module, NoisePlethora::FILTER_TYPE_B_PARAM));

// C params
addParam(createParamCentered<BefacoTinyKnobBlack>(mm2px(Vec(7.6, 99.584)), module, NoisePlethora::GRIT_PARAM));
addParam(createParamCentered<BefacoTinyKnobDarkGrey>(mm2px(Vec(22.366, 99.584)), module, NoisePlethora::RES_C_PARAM));
addParam(createParamCentered<Davies1900hDarkGreyKnob>(mm2px(Vec(47.536, 98.015)), module, NoisePlethora::CUTOFF_C_PARAM));
addParam(createParamCentered<BefacoTinyKnobDarkGrey>(mm2px(Vec(63.36, 99.584)), module, NoisePlethora::CUTOFF_CV_C_PARAM));
addParam(createParam<CKSSNarrow3>(mm2px(Vec(33.19, 92.506)), module, NoisePlethora::FILTER_TYPE_C_PARAM));
addParam(createParam<CKSSHoriz2>(mm2px(Vec(31.707, 104.225)), module, NoisePlethora::SOURCE_C_PARAM));

addInput(createInputCentered<BefacoInputPort>(mm2px(Vec(6.431, 16.102)), module, NoisePlethora::X_A_INPUT));
addInput(createInputCentered<BefacoInputPort>(mm2px(Vec(6.431, 29.959)), module, NoisePlethora::Y_A_INPUT));
addInput(createInputCentered<BefacoInputPort>(mm2px(Vec(52.845, 42.224)), module, NoisePlethora::CUTOFF_A_INPUT));
addInput(createInputCentered<BefacoInputPort>(mm2px(Vec(6.431, 43.212)), module, NoisePlethora::PROG_A_INPUT));
addInput(createInputCentered<BefacoInputPort>(mm2px(Vec(6.431, 55.801)), module, NoisePlethora::PROG_B_INPUT));
addInput(createInputCentered<BefacoInputPort>(mm2px(Vec(52.845, 56.816)), module, NoisePlethora::CUTOFF_B_INPUT));
addInput(createInputCentered<BefacoInputPort>(mm2px(Vec(6.431, 68.398)), module, NoisePlethora::X_B_INPUT));
addInput(createInputCentered<BefacoInputPort>(mm2px(Vec(6.431, 82.729)), module, NoisePlethora::Y_B_INPUT));
addInput(createInputCentered<BefacoInputPort>(mm2px(Vec(7.555, 114.8)), module, NoisePlethora::GRIT_INPUT));
addInput(createInputCentered<BefacoInputPort>(mm2px(Vec(63.36, 114.8)), module, NoisePlethora::CUTOFF_C_INPUT));

addOutput(createOutputCentered<BefacoOutputPort>(mm2px(Vec(64.909, 44.397)), module, NoisePlethora::A_OUTPUT));
addOutput(createOutputCentered<BefacoOutputPort>(mm2px(Vec(64.915, 54.608)), module, NoisePlethora::B_OUTPUT));

addOutput(createOutputCentered<BefacoOutputPort>(mm2px(Vec(22.345, 114.852)), module, NoisePlethora::GRITTY_OUTPUT));
addOutput(createOutputCentered<BefacoOutputPort>(mm2px(Vec(34.981, 114.852)), module, NoisePlethora::FILTERED_OUTPUT));
addOutput(createOutputCentered<BefacoOutputPort>(mm2px(Vec(47.536, 114.852)), module, NoisePlethora::WHITE_OUTPUT));

addChild(createLightCentered<MediumLight<RedLight>>(mm2px(Vec(30.866, 37.422)), module, NoisePlethora::BANK_LIGHT));


NoisePlethoraLEDDisplay* displayA = createWidget<NoisePlethoraLEDDisplay>(mm2px(Vec(13.106, 38.172)));
displayA->module = module;
displayA->section = NoisePlethora::SECTION_A;
addChild(displayA);

NoisePlethoraLEDDisplay* displayB = createWidget<NoisePlethoraLEDDisplay>(mm2px(Vec(13.106, 50.712)));
displayB->module = module;
displayB->section = NoisePlethora::SECTION_B;
addChild(displayB);
}

void appendContextMenu(Menu* menu) override {
NoisePlethora* module = dynamic_cast<NoisePlethora*>(this->module);
assert(module);

// build the two algorithm selection menus programmatically
menu->addChild(createMenuLabel("Algorithms"));
std::vector<std::string> bankAliases = {"Textures", "HH Clusters", "Harsh & Wild", "Test"};
char programNames[] = "AB";
for (int sectionId = 0; sectionId < 2; ++sectionId) {

menu->addChild(createSubmenuItem(string::f("Program %c", programNames[sectionId]), "",
[ = ](Menu * menu) {
for (int i = 0; i < numBanks; i++) {
const int currentBank = module->programSelector.getSection(sectionId).getBank();
const int currentProgram = module->programSelector.getSection(sectionId).getProgram();

menu->addChild(createSubmenuItem(string::f("Bank %d: %s", i + 1, bankAliases[i].c_str()), currentBank == i ? CHECKMARK_STRING : "", [ = ](Menu * menu) {
for (int j = 0; j < getBankForIndex(i).getSize(); ++j) {
const bool currentProgramAndBank = (currentProgram == j) && (currentBank == i);
const std::string algorithmName = getBankForIndex(i).getProgramName(j);

bool implemented = false;
for (auto item : MyFactory::Instance()->factoryFunctionRegistry) {
if (item.first == algorithmName) {
implemented = true;
break;
}
}

if (implemented) {
menu->addChild(createMenuItem(algorithmName, currentProgramAndBank ? CHECKMARK_STRING : "",
[ = ]() {
module->setAlgorithm(sectionId, algorithmName);
}));
}
else {
// placeholder text (greyed out)
menu->addChild(createMenuLabel(algorithmName));
}
}
}));
}
}));


}

menu->addChild(createMenuLabel("Filters"));
menu->addChild(createBoolPtrMenuItem("Remove DC", "", &module->blockDC));
menu->addChild(createBoolPtrMenuItem("Bypass Filters", "", &module->bypassFilters));
}
};


Model* modelNoisePlethora = createModel<NoisePlethora, NoisePlethoraWidget>("NoisePlethora");

+ 0
- 28
src/PulseGenerator_4.hpp View File

@@ -1,28 +0,0 @@
#pragma once
#include <rack.hpp>


/** When triggered, holds a high value for a specified time before going low again */
struct PulseGenerator_4 {
simd::float_4 remaining = 0.f;

/** Immediately disables the pulse */
void reset() {
remaining = 0.f;
}

/** Advances the state by `deltaTime`. Returns whether the pulse is in the HIGH state. */
simd::float_4 process(float deltaTime) {

simd::float_4 mask = (remaining > 0.f);

remaining -= ifelse(mask, deltaTime, 0.f);
return ifelse(mask, simd::float_4::mask(), 0.f);
}

/** Begins a trigger with the given `duration`. */
void trigger(simd::float_4 mask, float duration = 1e-3f) {
// Keep the previous pulse if the existing pulse will be held longer than the currently requested one.
remaining = ifelse(mask & (duration > remaining), duration, remaining);
}
};

+ 0
- 1
src/Rampage.cpp View File

@@ -1,5 +1,4 @@
#include "plugin.hpp"
#include "PulseGenerator_4.hpp"

using simd::float_4;



+ 12
- 2
src/SpringReverb.cpp View File

@@ -71,6 +71,16 @@ struct SpringReverb : Module {
delete convolver;
}

void processBypass(const ProcessArgs& args) override {
float in1 = inputs[IN1_INPUT].getVoltageSum();
float in2 = inputs[IN2_INPUT].getVoltageSum();

float dry = clamp(in1 + in2, -10.0f, 10.0f);

outputs[WET_OUTPUT].setVoltage(dry);
outputs[MIX_OUTPUT].setVoltage(dry);
}

void process(const ProcessArgs& args) override {
float in1 = inputs[IN1_INPUT].getVoltageSum();
float in2 = inputs[IN2_INPUT].getVoltageSum();
@@ -129,9 +139,9 @@ struct SpringReverb : Module {
outputs[WET_OUTPUT].setVoltage(clamp(wet, -10.0f, 10.0f));
outputs[MIX_OUTPUT].setVoltage(clamp(mix, -10.0f, 10.0f));

// process VU lights
// process VU lights
vuFilter.process(args.sampleTime, wet);
// process peak light
// process peak light
lightFilter.process(args.sampleTime, dry * 50.0);

if (lightRefreshClock.process()) {


+ 3
- 0
src/noise-plethora/LICENSE.md View File

@@ -0,0 +1,3 @@
Plugins in subdirectory `./plugins` have been derived from source files from https://github.com/Befaco/Noise_plethora/ (prefix `P_*.hpp`) licensed under GPL-3.0-or-later (see https://github.com/Befaco/Noise_plethora/blob/master/README.md).

The audio components in subdirectory `./teensy` include modified versions of the [Teensy Audio library](https://github.com/PaulStoffregen/Audio), licensed under the MIT License.

+ 17
- 0
src/noise-plethora/README.md View File

@@ -0,0 +1,17 @@
Technical Notes
===============

The Noise Plethora module consists of a number of plugins designed to run on the Teensy microcontroller, and specifically using the powerful [Teensy audio library](https://www.pjrc.com/teensy/td_libs_Audio.html). This consists of a number of oscillators, filters, noise sources, effects etc. Unfortunately these are designed to run directly on the Teensy, and target ARM processors. A small subset of the library that is required for NoisePlethora has been ported (see `./teensy`), with minor adaptions:

* any parts that only have ARM instructions have been reimplemented (generally with slower versions)
* Teensy fixes the sample rate at 44100Hz, so parts have been updated to allow arbitrary sample rates
* Teensy uses a simple graph based processing approach, where blocks are processed in the order in which they are _declared_ in the C/C++ code. The code to produce and process this graph is too complex to port, so I've instead modify each Teensy unit's `process()` call to take audio blocks as input/output where appropriate, and manually constructed the computation graph by inspection. (In both the original library and the port, every element in the graph is processed once per loop, and some results stored for the next computation where needed).

The VCV plugin will generate 1 block's worth of audio (~2.9ms at 44100Hz), store this in a buffer, and play back sample by sample until the buffer empties and the process is repeated.

An example Teensy plugin is shown below:
![Example plugin](./teensy-gui.png)

I used my own Teensy to debug and try out things quickly in VCV. Teensy provides a usb audio device which Rack trivially recognises (this is useful to allow rapid dev + it decouples Teensy logic from Noise Plethora's filters):
![Example plugin](./teensy-audio-device.png)


+ 112
- 0
src/noise-plethora/plugins/Banks.cpp View File

@@ -0,0 +1,112 @@
#include "Banks.hpp"
#include "Banks_Def.hpp"

const Bank::BankElem Bank::defaultElem = {"", 1.0};

Bank::Bank() {
programs.fill(defaultElem);
}

Bank::Bank(const BankElem& p1, const BankElem& p2, const BankElem& p3,
const BankElem& p4, const BankElem& p5, const BankElem& p6,
const BankElem& p7, const BankElem& p8, const BankElem& p9,
const BankElem& p10)
: programs{p1, p2, p3, p4, p5, p6, p7, p8, p9, p10}
{ }

const std::string Bank::getProgramName(int i) {
if (i >= 0 && i < programsPerBank) {
return programs[i].name;
}
return "";
}

float Bank::getProgramGain(int i) {
if (i >= 0 && i < programsPerBank) {
return programs[i].gain;
}
return 1.0;
}

int Bank::getSize() {
int size = 0;
for (auto it = programs.begin(); it != programs.end(); it++) {
if ((*it).name == "") {
break;
}
size++;
}
return size;
}



// Bank A:
#include "P_radioOhNo.hpp"
#include "P_Rwalk_SineFMFlange.hpp"
#include "P_xModRingSqr.hpp"
#include "P_XModRingSine.hpp"
#include "P_CrossModRing.hpp"
#include "P_resonoise.hpp"
#include "P_grainGlitch.hpp"
#include "P_grainGlitchII.hpp"
#include "P_grainGlitchIII.hpp"
#include "P_basurilla.hpp"

// Bank B: HH clusters
#include "P_clusterSaw.hpp"
#include "P_pwCluster.hpp"
#include "P_crCluster2.hpp"
#include "P_sineFMcluster.hpp"
#include "P_TriFMcluster.hpp"
#include "P_PrimeCluster.hpp"
#include "P_PrimeCnoise.hpp"
#include "P_FibonacciCluster.hpp"
#include "P_partialCluster.hpp"
#include "P_phasingCluster.hpp"

// Bank C: harsh and wild
#include "P_BasuraTotal.hpp"
#include "P_Atari.hpp"
#include "P_WalkingFilomena.hpp"
#include "P_S_H.hpp"
#include "P_arrayOnTheRocks.hpp"
#include "P_existencelsPain.hpp"
#include "P_whoKnows.hpp"
#include "P_satanWorkout.hpp"
#include "P_Rwalk_BitCrushPW.hpp"
#include "P_Rwalk_LFree.hpp"

// Bank D: Test / other
//#include "P_TestPlugin.hpp"
//#include "P_TeensyAlt.hpp"
//#include "P_WhiteNoise.hpp"
//#include "P_Rwalk_LBit.hpp"
//#include "P_Rwalk_SineFM.hpp"
//#include "P_VarWave.hpp"
//#include "P_RwalkVarWave.hpp"
//#include "P_Rwalk_ModWave.hpp"
//#include "P_Rwalk_WaveTwist.hpp"


static const Bank bank1 BANKS_DEF_1; // Banks_Def.hpp
static const Bank bank2 BANKS_DEF_2;
static const Bank bank3 BANKS_DEF_3;
//static const Bank bank4 BANKS_DEF_4;
//static const Bank bank5 BANKS_DEF_5;
static std::array<Bank, numBanks> banks { bank1, bank2, bank3 }; //, bank5 };

// static const Bank bank6 BANKS_DEF_6;
// static const Bank bank7 BANKS_DEF_7;
// static const Bank bank8 BANKS_DEF_8;
// static const Bank bank9 BANKS_DEF_9;
// static const Bank bank10 BANKS_DEF_10;
// static std::array<Bank, programsPerBank> banks { bank1, bank2, bank3, bank4, bank5, bank6, bank7, bank8, bank9, bank10 };

Bank& getBankForIndex(int i) {
if (i < 0)
i = 0;
if (i >= programsPerBank)
i = (programsPerBank - 1);
return banks[i];
}

+ 44
- 0
src/noise-plethora/plugins/Banks.hpp View File

@@ -0,0 +1,44 @@
#pragma once

#include <string>
#include <memory>
#include <array>

static const int programsPerBank = 10;
static const int numBanks = 3;

struct Bank {

struct BankElem {
BankElem() {};

BankElem(std::string n, float g = 1.0)
: name{n}
, gain{g}
{}

std::string name = "";
float gain = 1.0;
};

static const BankElem defaultElem;

Bank();
Bank(const BankElem& p1, const BankElem& p2 = defaultElem,
const BankElem& p3 = defaultElem, const BankElem& p4 = defaultElem,
const BankElem& p5 = defaultElem, const BankElem& p6 = defaultElem,
const BankElem& p7 = defaultElem, const BankElem& p8 = defaultElem,
const BankElem& p9 = defaultElem, const BankElem& p10 = defaultElem);

const std::string getProgramName(int i);
float getProgramGain(int i);

int getSize();

private:

std::array<BankElem, programsPerBank> programs;

};

Bank& getBankForIndex(int i);

+ 53
- 0
src/noise-plethora/plugins/Banks_Def.hpp View File

@@ -0,0 +1,53 @@
#pragma once

#define BANKS_DEF_1 { \
{ "radioOhNo", 1.0 }, \
{ "Rwalk_SineFMFlange", 1.0 }, \
{ "xModRingSqr", 1.0 }, \
{ "XModRingSine", 1.0 }, \
{ "CrossModRing", 1.0 }, \
{ "resonoise", 1.0 }, \
{ "grainGlitch", 1.0 }, \
{ "grainGlitchII", 1.0 }, \
{ "grainGlitchIII", 1.0 }, \
{ "basurilla", 1.0 } \
}

#define BANKS_DEF_2 { \
{ "clusterSaw", 1.0 }, \
{ "pwCluster", 1.0 }, \
{ "crCluster2", 1.0 }, \
{ "sineFMcluster", 1.0 }, \
{ "TriFMcluster", 1.0 }, \
{ "PrimeCluster", 0.8 }, \
{ "PrimeCnoise", 0.8 }, \
{ "FibonacciCluster", 1.0 }, \
{ "partialCluster", 1.0 }, \
{ "phasingCluster", 1.0 } \
}

#define BANKS_DEF_3 { \
{ "BasuraTotal", 1.0 }, \
{ "Atari", 1.0 }, \
{ "WalkingFilomena", 1.0 }, \
{ "S_H", 1.0 }, \
{ "arrayOnTheRocks", 1.0 }, \
{ "existencelsPain", 1.0 }, \
{ "whoKnows", 1.0 }, \
{ "satanWorkout", 1.0 }, \
{ "Rwalk_BitCrushPW", 1.0 }, \
{ "Rwalk_LFree", 1.0 } \
}

#define BANKS_DEF_4 { \
{ "TestPlugin", 1.0 }, \
{ "WhiteNoise", 1.0 }, \
{ "TeensyAlt", 1.0 } \
}
#define BANKS_DEF_5

// #define BANKS_DEF_6
// #define BANKS_DEF_7
// #define BANKS_DEF_8
// #define BANKS_DEF_9
// #define BANKS_DEF_10

+ 90
- 0
src/noise-plethora/plugins/NoisePlethoraPlugin.hpp View File

@@ -0,0 +1,90 @@
#pragma once

#include <rack.hpp>
#include <memory>
#include <string> // string might not be allowed
#include <functional>
#include <map>

#include "../teensy/TeensyAudioReplacements.hpp"


class NoisePlethoraPlugin {

public:
NoisePlethoraPlugin() { }
virtual ~NoisePlethoraPlugin() {}

NoisePlethoraPlugin(const NoisePlethoraPlugin&) = delete;
NoisePlethoraPlugin& operator=(const NoisePlethoraPlugin&) = delete;

virtual void init() {};
// equivelent to arduino void loop()
virtual void process(float k1, float k2) {};

// called once-per sample, will consume a buffer of length AUDIO_BLOCK_SAMPLES (128)
// then request that the buffer be refilled, returns values in range [-1, 1]
float processGraph() {

if (blockBuffer.empty()) {
processGraphAsBlock(blockBuffer);
}

return int16_to_float_1v(blockBuffer.shift());
}

virtual AudioStream& getStream() = 0;
virtual unsigned char getPort() = 0;

protected:

// subclass should process the audio graph and fill the supplied buffer
virtual void processGraphAsBlock(TeensyBuffer& blockBuffer) = 0;

TeensyBuffer blockBuffer;
};


class MyFactory {
public:
static MyFactory* Instance() {
static MyFactory factory;
return &factory;
}

std::shared_ptr<NoisePlethoraPlugin> Create(std::string name) {
NoisePlethoraPlugin* instance = nullptr;

// find name in the registry and call factory method.
auto it = factoryFunctionRegistry.find(name);
if (it != factoryFunctionRegistry.end()) {
instance = it->second();
}

// wrap instance in a shared ptr and return
if (instance != nullptr) {
return std::shared_ptr<NoisePlethoraPlugin>(instance);
}
else {
return nullptr;
}
}

void RegisterFactoryFunction(std::string name, std::function<NoisePlethoraPlugin*(void)> classFactoryFunction) {
// register the class factory function
factoryFunctionRegistry[name] = classFactoryFunction;
}

std::map<std::string, std::function<NoisePlethoraPlugin*(void)>> factoryFunctionRegistry;
};

template<class T> class Registrar {
public:
Registrar(std::string className) {
// register the class factory function
MyFactory::Instance()->RegisterFactoryFunction(className,
[](void) -> NoisePlethoraPlugin * { return new T();});
}
};

#define REGISTER_PLUGIN(NAME) static Registrar<NAME> NAME ##_reg(#NAME)

+ 70
- 0
src/noise-plethora/plugins/P_Atari.hpp View File

@@ -0,0 +1,70 @@
#pragma once

#include "NoisePlethoraPlugin.hpp"

class Atari : public NoisePlethoraPlugin {

public:

Atari()
//:patchCord1(waveformMod1, 0, waveformMod2, 1),
//patchCord3(waveformMod2, 0, waveformMod1, 0)
{ }

~Atari() override {}

Atari(const Atari&) = delete;
Atari& operator=(const Atari&) = delete;

void init() override {
int masterVolume = 1;
waveformMod1.begin(WAVEFORM_SQUARE);
waveformMod2.begin(WAVEFORM_PULSE);
waveformMod1.offset(1);
waveformMod1.amplitude(masterVolume);
waveformMod2.amplitude(masterVolume);

}

void process(float k1, float k2) override {
float knob_1 = k1;
float knob_2 = k2;
float pitch1 = pow(knob_1, 2);
// float pitch2 = pow(knob_2, 2);
waveformMod1.frequency(10 + (pitch1 * 50));
waveformMod2.frequency(10 + (knob_2 * 200));
waveformMod1.frequencyModulation(knob_2 * 8 + 3);
}

void processGraphAsBlock(TeensyBuffer& blockBuffer) override {

// waveformMod1 has FM from waveformMod2
waveformMod1.update(&output2, nullptr, &output1);

// waveformMod2 has PWM from waveformMod1
waveformMod2.update(nullptr, &output1, &output2);

blockBuffer.pushBuffer(output2.data, AUDIO_BLOCK_SAMPLES);
}

AudioStream& getStream() override {
return waveformMod2;
}
unsigned char getPort() override {
return 0;
}

private:
audio_block_t output1, output2;

AudioSynthWaveformModulated waveformMod1;
AudioSynthWaveformModulated waveformMod2;

//AudioSynthWaveformModulated waveformMod1; //xy=334,349
//AudioSynthWaveformModulated waveformMod2; //xy=616,284
//AudioConnection patchCord1;
//AudioConnection patchCord3;

};

REGISTER_PLUGIN(Atari);

+ 92
- 0
src/noise-plethora/plugins/P_BasuraTotal.hpp View File

@@ -0,0 +1,92 @@
#pragma once
#include "NoisePlethoraPlugin.hpp"
class BasuraTotal : public NoisePlethoraPlugin {
public:
BasuraTotal()
// : patchCord1(waveformMod1, freeverb1)
{}
~BasuraTotal() override {}
BasuraTotal(const BasuraTotal&) = delete;
BasuraTotal& operator=(const BasuraTotal&) = delete;
dsp::Timer timer;
void init() override {
freeverb1.roomsize(0);
timer.reset();
waveformMod1.begin(1, 500, WAVEFORM_SINE);
}
void process(float k1, float k2) override {
float knob_1 = k1;
float knob_2 = k2;
float pitch1 = pow(knob_1, 2);
float pitch2 = pow(knob_2, 2);
float timeMicros = timer.time * 1000000;
if (timeMicros > 100000 * pitch2) { // Changing this value changes the frequency.
timer.reset();
waveformMod1.begin(1, 500, WAVEFORM_SQUARE);
waveformMod1.frequency(generateNoise() * (200 + (pitch1 * 5000))) ;
freeverb1.roomsize(1);
}
}
void processGraphAsBlock(TeensyBuffer& blockBuffer) override {
const float blockTime = APP->engine->getSampleTime() * AUDIO_BLOCK_SAMPLES;
timer.process(blockTime);
waveformMod1.update(nullptr, nullptr, &waveformOut);
freeverb1.update(&waveformOut, &freeverbOut);
blockBuffer.pushBuffer(freeverbOut.data, AUDIO_BLOCK_SAMPLES);
}
AudioStream& getStream() override {
return freeverb1;
}
unsigned char getPort() override {
return 0;
}
private:
static unsigned int generateNoise() {
// See https://en.wikipedia.org/wiki/Linear_feedback_shift_register#Galois_LFSRs
/* initialize with any 32 bit non-zero unsigned long value. */
static unsigned long int lfsr = 0xfeddfaceUL; /* 32 bit init, nonzero */
static unsigned long mask = ((unsigned long)(1UL << 31 | 1UL << 15 | 1UL << 2 | 1UL << 1));
/* If the output bit is 1, apply toggle mask.
* The value has 1 at bits corresponding
* to taps, 0 elsewhere. */
if (lfsr & 1) {
lfsr = (lfsr >> 1) ^ mask;
return (1);
}
else {
lfsr >>= 1;
return (0);
}
}
audio_block_t waveformOut, freeverbOut;
AudioSynthWaveformModulated waveformMod1; //xy=216.88888549804688,217.9999988898635
AudioEffectFreeverb freeverb1; //xy=374.8888854980469,153.88888549804688
// AudioConnection patchCord1;
// unsigned long lastClick;
};
REGISTER_PLUGIN(BasuraTotal);

+ 119
- 0
src/noise-plethora/plugins/P_CrossModRing.hpp View File

@@ -0,0 +1,119 @@
#pragma once

#include "NoisePlethoraPlugin.hpp"

class CrossModRing : public NoisePlethoraPlugin {

public:

CrossModRing()
// :patchCord1(waveformMod3, 0, multiply2, 0),
// patchCord2(waveformMod3, 0, waveformMod4, 0),
// patchCord3(waveformMod1, 0, multiply1, 0),
// patchCord4(waveformMod1, 0, waveformMod2, 0),
// patchCord5(waveformMod4, 0, multiply2, 1),
// patchCord6(waveformMod4, 0, waveformMod1, 0),
// patchCord7(waveformMod2, 0, multiply1, 1),
// patchCord8(waveformMod2, 0, waveformMod3, 0),
// patchCord9(multiply2, 0, multiply3, 1),
// patchCord10(multiply1, 0, multiply3, 0)
{ }

~CrossModRing() override {}

CrossModRing(const CrossModRing&) = delete;
CrossModRing& operator=(const CrossModRing&) = delete;

void init() override {
WaveformType masterWaveform = WAVEFORM_SQUARE;
float masterVolume = 0.8;

waveformMod1.begin(masterWaveform);
waveformMod2.begin(masterWaveform);
waveformMod3.begin(WAVEFORM_SAWTOOTH);
waveformMod3.offset(1);

waveformMod4.begin(masterWaveform);

waveformMod1.amplitude(masterVolume);
waveformMod2.amplitude(masterVolume);
waveformMod3.amplitude(masterVolume);
waveformMod4.amplitude(masterVolume);


waveformMod1.frequency(1100);
waveformMod2.frequency(1367);
waveformMod3.frequency(345);
waveformMod4.frequency(686);

}

void process(float k1, float k2) override {
float knob_1 = k1;
float knob_2 = k2;
float pitch1 = pow(knob_1, 2);

waveformMod1.frequency(20 + (pitch1 * 807));
waveformMod2.frequency(11 + (knob_1 * 21));
waveformMod3.frequency(1 + (pitch1 * 29));
waveformMod4.frequency(1 + (knob_1 * 7) * -1);

float masterOctaves = 8 * knob_2 + 2;

waveformMod1.frequencyModulation(masterOctaves);
waveformMod2.frequencyModulation(masterOctaves);
waveformMod3.frequencyModulation(masterOctaves);
waveformMod4.frequencyModulation(masterOctaves);

}

void processGraphAsBlock(TeensyBuffer& blockBuffer) override {
// NOTE: buffer is zero indexed, waveformMod names are not!!
// NOTE: each waveform is modulated by previous
waveformMod3.update(&waveformModOut[1], nullptr, &waveformModOut[2]);
waveformMod1.update(&waveformModOut[3], nullptr, &waveformModOut[0]);
waveformMod4.update(&waveformModOut[2], nullptr, &waveformModOut[3]);
waveformMod2.update(&waveformModOut[0], nullptr, &waveformModOut[1]);

// multiply
multiply1.update(&waveformModOut[0], &waveformModOut[1], &multiplyOut[0]);
multiply2.update(&waveformModOut[2], &waveformModOut[3], &multiplyOut[1]);
multiply3.update(&multiplyOut[0], &multiplyOut[1], &multiplyOut[2]);

blockBuffer.pushBuffer(multiplyOut[2].data, AUDIO_BLOCK_SAMPLES);
}

AudioStream& getStream() override {
return multiply3;
}
unsigned char getPort() override {
return 0;
}

private:

audio_block_t waveformModOut[4] = {}, multiplyOut[3] = {};

AudioSynthWaveformModulated waveformMod3; //xy=287.99999618530273,420
AudioSynthWaveformModulated waveformMod1; //xy=288.99999618530273,197
AudioSynthWaveformModulated waveformMod4; //xy=290.99999618530273,541
AudioSynthWaveformModulated waveformMod2; //xy=291.99999618530273,318
AudioEffectMultiply multiply2; //xy=484.99999618530273,474
AudioEffectMultiply multiply1; //xy=485.99999618530273,251
AudioEffectMultiply multiply3; //xy=655.9999961853027,356


// AudioConnection patchCord1(waveformMod3, 0, multiply2, 0);
// AudioConnection patchCord2(waveformMod3, 0, waveformMod4, 0);
// AudioConnection patchCord3(waveformMod1, 0, multiply1, 0);
// AudioConnection patchCord4(waveformMod1, 0, waveformMod2, 0);
// AudioConnection patchCord5(waveformMod4, 0, multiply2, 1);
// AudioConnection patchCord6(waveformMod4, 0, waveformMod1, 0);
// AudioConnection patchCord7(waveformMod2, 0, multiply1, 1);
// AudioConnection patchCord8(waveformMod2, 0, waveformMod3, 0);
// AudioConnection patchCord9(multiply2, 0, multiply3, 1);
// AudioConnection patchCord10(multiply1, 0, multiply3, 0);

};

REGISTER_PLUGIN(CrossModRing);

+ 265
- 0
src/noise-plethora/plugins/P_FibonacciCluster.hpp View File

@@ -0,0 +1,265 @@
#pragma once

#include "NoisePlethoraPlugin.hpp"

class FibonacciCluster : public NoisePlethoraPlugin {

public:

FibonacciCluster()
// : patchCord1(noise1, 0, waveform1, 0)
// , patchCord2(noise1, 0, waveform2, 0)
// , patchCord3(noise1, 0, waveform3, 0)
// , patchCord4(noise1, 0, waveform4, 0)
// , patchCord5(noise1, 0, waveform5, 0)
// , patchCord6(noise1, 0, waveform6, 0)
// , patchCord7(noise1, 0, waveform7, 0)
// , patchCord8(noise1, 0, waveform8, 0)
// , patchCord9(noise1, 0, waveform9, 0)
// , patchCord10(noise1, 0, waveform10, 0)
// , patchCord11(noise1, 0, waveform11, 0)
// , patchCord12(noise1, 0, waveform12, 0)
// , patchCord13(noise1, 0, waveform13, 0)
// , patchCord14(noise1, 0, waveform14, 0)
// , patchCord15(noise1, 0, waveform15, 0)
// , patchCord16(noise1, 0, waveform16, 0)
// , patchCord17(waveform16, 0, mixer4, 3)
// , patchCord18(waveform14, 0, mixer4, 1)
// , patchCord19(waveform15, 0, mixer4, 2)
// , patchCord20(waveform13, 0, mixer4, 0)
// , patchCord21(waveform8, 0, mixer2, 3)
// , patchCord22(waveform6, 0, mixer2, 1)
// , patchCord23(waveform7, 0, mixer2, 2)
// , patchCord24(waveform12, 0, mixer3, 3)
// , patchCord25(waveform5, 0, mixer2, 0)
// , patchCord26(waveform10, 0, mixer3, 1)
// , patchCord27(waveform11, 0, mixer3, 2)
// , patchCord28(waveform9, 0, mixer3, 0)
// , patchCord29(waveform4, 0, mixer1, 3)
// , patchCord30(waveform2, 0, mixer1, 1)
// , patchCord31(waveform3, 0, mixer1, 2)
// , patchCord32(waveform1, 0, mixer1, 0)
// , patchCord33(mixer4, 0, mixer5, 3)
// , patchCord34(mixer3, 0, mixer5, 2)
// , patchCord35(mixer2, 0, mixer5, 1)
// , patchCord36(mixer1, 0, mixer5, 0)
{}

~FibonacciCluster() override {}

FibonacciCluster(const FibonacciCluster&) = delete;
FibonacciCluster& operator=(const FibonacciCluster&) = delete;

void init() override {
mixer1.gain(0, 1);
mixer1.gain(1, 1);
mixer1.gain(2, 1);
mixer1.gain(3, 1);
mixer2.gain(0, 1);
mixer2.gain(1, 1);
mixer2.gain(2, 1);
mixer2.gain(3, 1);
mixer3.gain(0, 1);
mixer3.gain(1, 1);
mixer3.gain(2, 1);
mixer3.gain(3, 1);
mixer4.gain(0, 1);
mixer4.gain(1, 1);
mixer4.gain(2, 1);
mixer4.gain(3, 1);
mixer5.gain(0, 1);
mixer5.gain(1, 1);
mixer5.gain(2, 1);
mixer5.gain(3, 1);

int masterWaveform = WAVEFORM_SAWTOOTH;
float masterVolume = 0.2;

waveform1.begin(masterVolume, 794, masterWaveform);
waveform2.begin(masterVolume, 647, masterWaveform);
waveform3.begin(masterVolume, 524, masterWaveform);
waveform4.begin(masterVolume, 444, masterWaveform);
waveform5.begin(masterVolume, 368, masterWaveform);
waveform6.begin(masterVolume, 283, masterWaveform);
waveform7.begin(masterVolume, 283, masterWaveform);
waveform8.begin(masterVolume, 283, masterWaveform);
waveform9.begin(masterVolume, 283, masterWaveform);
waveform10.begin(masterVolume, 283, masterWaveform);
waveform11.begin(masterVolume, 283, masterWaveform);
waveform12.begin(masterVolume, 283, masterWaveform);
waveform13.begin(masterVolume, 283, masterWaveform);
waveform14.begin(masterVolume, 283, masterWaveform);
waveform15.begin(masterVolume, 283, masterWaveform);
waveform16.begin(masterVolume, 283, masterWaveform);
}

void process(float k1, float k2) override {
float knob_1 = k1;
float knob_2 = k2;

float pitch1 = pow(knob_1, 2);
float pitch2 = pow(knob_2, 2);
float spread = pitch2 / 2 + 0.1;

float f1 = 40 + pitch1 * 5000;
float f2 = f1 * (2 * spread + 1);
float f3 = f1 + f2 * spread;
float f4 = f2 + f3 * spread;
float f5 = f3 + f4 * spread;
float f6 = f4 + f5 * spread;
float f7 = f5 + f6 * spread;
float f8 = f6 + f7 * spread;
float f9 = f7 + f8 * spread;
float f10 = f8 + f9 * spread;
float f11 = f9 + f10 * spread;
float f12 = f10 + f11 * spread;
float f13 = f11 + f12 * spread;
float f14 = f12 + f13 * spread;
float f15 = f13 + f14 * spread;
float f16 = f14 + f15 * spread;

waveform1.frequency(f1);
waveform2.frequency(f2);
waveform3.frequency(f3);
waveform4.frequency(f4);
waveform5.frequency(f5);
waveform6.frequency(f6);
waveform7.frequency(f7);
waveform8.frequency(f8);
waveform9.frequency(f9);
waveform10.frequency(f10);
waveform11.frequency(f11);
waveform12.frequency(f12);
waveform13.frequency(f13);
waveform14.frequency(f14);
waveform15.frequency(f15);
waveform16.frequency(f16);
}

void processGraphAsBlock(TeensyBuffer& blockBuffer) override {

noise1.update(&noiseOut);

// FM from single noise source
waveform1.update(&noiseOut, nullptr, &waveformOut[0]);
waveform2.update(&noiseOut, nullptr, &waveformOut[1]);
waveform3.update(&noiseOut, nullptr, &waveformOut[2]);
waveform4.update(&noiseOut, nullptr, &waveformOut[3]);
waveform5.update(&noiseOut, nullptr, &waveformOut[4]);
waveform6.update(&noiseOut, nullptr, &waveformOut[5]);
waveform7.update(&noiseOut, nullptr, &waveformOut[6]);
waveform8.update(&noiseOut, nullptr, &waveformOut[7]);
waveform9.update(&noiseOut, nullptr, &waveformOut[8]);
waveform10.update(&noiseOut, nullptr, &waveformOut[9]);
waveform11.update(&noiseOut, nullptr, &waveformOut[10]);
waveform12.update(&noiseOut, nullptr, &waveformOut[11]);
waveform13.update(&noiseOut, nullptr, &waveformOut[12]);
waveform14.update(&noiseOut, nullptr, &waveformOut[13]);
waveform15.update(&noiseOut, nullptr, &waveformOut[14]);
waveform16.update(&noiseOut, nullptr, &waveformOut[15]);

mixer1.update(&waveformOut[0], &waveformOut[1], &waveformOut[2], &waveformOut[3], &mixerOut[0]);
mixer2.update(&waveformOut[4], &waveformOut[5], &waveformOut[6], &waveformOut[7], &mixerOut[1]);
mixer3.update(&waveformOut[8], &waveformOut[9], &waveformOut[10], &waveformOut[11], &mixerOut[2]);
mixer4.update(&waveformOut[12], &waveformOut[13], &waveformOut[14], &waveformOut[15], &mixerOut[3]);

mixer5.update(&mixerOut[0], &mixerOut[1], &mixerOut[2], &mixerOut[3], &mixerOut[4]);

blockBuffer.pushBuffer(mixerOut[4].data, AUDIO_BLOCK_SAMPLES);
}

AudioStream& getStream() override {
return mixer5;
}
unsigned char getPort() override {
return 0;
}

private:

audio_block_t noiseOut, waveformOut[16] = {}, mixerOut[5] = {};

AudioSynthNoiseWhite noise1; //xy=306.20001220703125,530
AudioSynthWaveformModulated waveform16; //xy=591.2000122070312,906
AudioSynthWaveformModulated waveform14; //xy=593.2000122070312,801
AudioSynthWaveformModulated waveform15; //xy=593.2000122070312,846
AudioSynthWaveformModulated waveform13; //xy=594.2000122070312,759
AudioSynthWaveformModulated waveform8; //xy=601.2000122070312,486
AudioSynthWaveformModulated waveform6; //xy=603.2000122070312,381
AudioSynthWaveformModulated waveform7; //xy=603.2000122070312,426
AudioSynthWaveformModulated waveform12; //xy=602.2000122070312,697
AudioSynthWaveformModulated waveform5; //xy=604.2000122070312,339
AudioSynthWaveformModulated waveform10; //xy=604.2000122070312,592
AudioSynthWaveformModulated waveform11; //xy=604.2000122070312,637
AudioSynthWaveformModulated waveform9; //xy=605.2000122070312,550
AudioSynthWaveformModulated waveform4; //xy=609.2000122070312,271
AudioSynthWaveformModulated waveform2; //xy=611.2000122070312,166
AudioSynthWaveformModulated waveform3; //xy=611.2000122070312,211
AudioSynthWaveformModulated waveform1; //xy=612.2000122070312,123
AudioMixer4 mixer4; //xy=811.2000122070312,850
AudioMixer4 mixer3; //xy=822.2000122070312,641
AudioMixer4 mixer2; //xy=828.2000122070312,430
AudioMixer4 mixer1; //xy=829.2000122070312,215
AudioMixer4 mixer5; //xy=1076.2000122070312,427

// AudioSynthWaveformModulated waveform16; //xy=581.75,1167.5
// AudioSynthWaveformModulated waveform14; //xy=583.75,1062.5
// AudioSynthWaveformModulated waveform15; //xy=583.75,1107.5
// AudioSynthWaveformModulated waveform13; //xy=584.75,1020
// AudioSynthWaveformModulated waveform8; //xy=591.75,747.5
// AudioSynthWaveformModulated waveform6; //xy=593.75,642.5
// AudioSynthWaveformModulated waveform7; //xy=593.75,687.5
// AudioSynthWaveformModulated waveform12; //xy=592.75,958.5
// AudioSynthWaveformModulated waveform5; //xy=594.75,600
// AudioSynthWaveformModulated waveform10; //xy=594.75,853.5
// AudioSynthWaveformModulated waveform11; //xy=594.75,898.5
// AudioSynthWaveformModulated waveform9; //xy=595.75,811
// AudioSynthWaveformModulated waveform4; //xy=599.75,532.25
// AudioSynthWaveformModulated waveform2; //xy=601.75,427.25
// AudioSynthWaveformModulated waveform3; //xy=601.75,472.25
// AudioSynthWaveformModulated waveform1; //xy=602.75,384.75
// AudioMixer4 mixer4; //xy=801.75,1111.25
// AudioMixer4 mixer3; //xy=812.75,902.25
// AudioMixer4 mixer2; //xy=818.75,691.25
// AudioMixer4 mixer1; //xy=819.75,476
// AudioMixer4 mixer5; //xy=1066.75,688
// AudioConnection patchCord1;
// AudioConnection patchCord2;
// AudioConnection patchCord3;
// AudioConnection patchCord4;
// AudioConnection patchCord5;
// AudioConnection patchCord6;
// AudioConnection patchCord7;
// AudioConnection patchCord8;
// AudioConnection patchCord9;
// AudioConnection patchCord10;
// AudioConnection patchCord11;
// AudioConnection patchCord12;
// AudioConnection patchCord13;
// AudioConnection patchCord14;
// AudioConnection patchCord15;
// AudioConnection patchCord16;
// AudioConnection patchCord17;
// AudioConnection patchCord18;
// AudioConnection patchCord19;
// AudioConnection patchCord20;
// AudioConnection patchCord21;
// AudioConnection patchCord22;
// AudioConnection patchCord23;
// AudioConnection patchCord24;
// AudioConnection patchCord25;
// AudioConnection patchCord26;
// AudioConnection patchCord27;
// AudioConnection patchCord28;
// AudioConnection patchCord29;
// AudioConnection patchCord30;
// AudioConnection patchCord31;
// AudioConnection patchCord32;
// AudioConnection patchCord33;
// AudioConnection patchCord34;
// AudioConnection patchCord35;
// AudioConnection patchCord36;

};

REGISTER_PLUGIN(FibonacciCluster);

+ 245
- 0
src/noise-plethora/plugins/P_PrimeCluster.hpp View File

@@ -0,0 +1,245 @@
#pragma once

#include "NoisePlethoraPlugin.hpp"

class PrimeCluster : public NoisePlethoraPlugin {

public:

PrimeCluster()
// : patchCord1(noise1, 0, waveform1, 0)
// , patchCord2(noise1, 0, waveform2, 0)
// , patchCord3(noise1, 0, waveform3, 0)
// , patchCord4(noise1, 0, waveform4, 0)
// , patchCord5(noise1, 0, waveform5, 0)
// , patchCord6(noise1, 0, waveform6, 0)
// , patchCord7(noise1, 0, waveform7, 0)
// , patchCord8(noise1, 0, waveform8, 0)
// , patchCord9(noise1, 0, waveform9, 0)
// , patchCord10(noise1, 0, waveform10, 0)
// , patchCord11(noise1, 0, waveform11, 0)
// , patchCord12(noise1, 0, waveform12, 0)
// , patchCord13(noise1, 0, waveform13, 0)
// , patchCord14(noise1, 0, waveform14, 0)
// , patchCord15(noise1, 0, waveform15, 0)
// , patchCord16(noise1, 0, waveform16, 0)
// , patchCord17(waveform16, 0, mixer4, 3)
// , patchCord18(waveform14, 0, mixer4, 1)
// , patchCord19(waveform15, 0, mixer4, 2)
// , patchCord20(waveform13, 0, mixer4, 0)
// , patchCord21(waveform8, 0, mixer2, 3)
// , patchCord22(waveform6, 0, mixer2, 1)
// , patchCord23(waveform7, 0, mixer2, 2)
// , patchCord24(waveform12, 0, mixer3, 3)
// , patchCord25(waveform5, 0, mixer2, 0)
// , patchCord26(waveform10, 0, mixer3, 1)
// , patchCord27(waveform11, 0, mixer3, 2)
// , patchCord28(waveform9, 0, mixer3, 0)
// , patchCord29(waveform4, 0, mixer1, 3)
// , patchCord30(waveform2, 0, mixer1, 1)
// , patchCord31(waveform3, 0, mixer1, 2)
// , patchCord32(waveform1, 0, mixer1, 0)
// , patchCord33(mixer4, 0, mixer5, 3)
// , patchCord34(mixer3, 0, mixer5, 2)
// , patchCord35(mixer2, 0, mixer5, 1)
// , patchCord36(mixer1, 0, mixer5, 0)
{}

~PrimeCluster() override {}

PrimeCluster(const PrimeCluster&) = delete;
PrimeCluster& operator=(const PrimeCluster&) = delete;

void init() override {
mixer1.gain(0, 1);
mixer1.gain(1, 1);
mixer1.gain(2, 1);
mixer1.gain(3, 1);
mixer2.gain(0, 1);
mixer2.gain(1, 1);
mixer2.gain(2, 1);
mixer2.gain(3, 1);
mixer3.gain(0, 1);
mixer3.gain(1, 1);
mixer3.gain(2, 1);
mixer3.gain(3, 1);
mixer4.gain(0, 1);
mixer4.gain(1, 1);
mixer4.gain(2, 1);
mixer4.gain(3, 1);
mixer5.gain(0, 1);
mixer5.gain(1, 1);
mixer5.gain(2, 1);
mixer5.gain(3, 1);

int masterWaveform = WAVEFORM_TRIANGLE_VARIABLE;
float masterVolume = 0.3;

waveform1.begin(masterVolume, 200, masterWaveform);
waveform2.begin(masterVolume, 647, masterWaveform);
waveform3.begin(masterVolume, 524, masterWaveform);
waveform4.begin(masterVolume, 444, masterWaveform);
waveform5.begin(masterVolume, 368, masterWaveform);
waveform6.begin(masterVolume, 283, masterWaveform);
waveform7.begin(masterVolume, 283, masterWaveform);
waveform8.begin(masterVolume, 283, masterWaveform);
waveform9.begin(masterVolume, 283, masterWaveform);
waveform10.begin(masterVolume, 283, masterWaveform);
waveform11.begin(masterVolume, 283, masterWaveform);
waveform12.begin(masterVolume, 283, masterWaveform);
waveform13.begin(masterVolume, 283, masterWaveform);
waveform14.begin(masterVolume, 283, masterWaveform);
waveform15.begin(masterVolume, 283, masterWaveform);
waveform16.begin(masterVolume, 283, masterWaveform);
}

void process(float k1, float k2) override {
float multfactor = k1 * 10 + 0.5;

waveform1.frequency(53 * multfactor);
waveform2.frequency(127 * multfactor);
waveform3.frequency(199 * multfactor);
waveform4.frequency(283 * multfactor);
waveform5.frequency(383 * multfactor);
waveform6.frequency(467 * multfactor);
waveform7.frequency(577 * multfactor);
waveform8.frequency(661 * multfactor);
waveform9.frequency(769 * multfactor);
waveform10.frequency(877 * multfactor);
waveform11.frequency(983 * multfactor);
waveform12.frequency(1087 * multfactor);
waveform13.frequency(1193 * multfactor);
waveform14.frequency(1297 * multfactor);
waveform15.frequency(1429 * multfactor);
waveform16.frequency(1523 * multfactor);

noise1.amplitude(k2 * 0.2);
}

void processGraphAsBlock(TeensyBuffer& blockBuffer) override {

noise1.update(&noiseOut);

// FM from single noise source
waveform1.update(&noiseOut, nullptr, &waveformOut[0]);
waveform2.update(&noiseOut, nullptr, &waveformOut[1]);
waveform3.update(&noiseOut, nullptr, &waveformOut[2]);
waveform4.update(&noiseOut, nullptr, &waveformOut[3]);
waveform5.update(&noiseOut, nullptr, &waveformOut[4]);
waveform6.update(&noiseOut, nullptr, &waveformOut[5]);
waveform7.update(&noiseOut, nullptr, &waveformOut[6]);
waveform8.update(&noiseOut, nullptr, &waveformOut[7]);
waveform9.update(&noiseOut, nullptr, &waveformOut[8]);
waveform10.update(&noiseOut, nullptr, &waveformOut[9]);
waveform11.update(&noiseOut, nullptr, &waveformOut[10]);
waveform12.update(&noiseOut, nullptr, &waveformOut[11]);
waveform13.update(&noiseOut, nullptr, &waveformOut[12]);
waveform14.update(&noiseOut, nullptr, &waveformOut[13]);
waveform15.update(&noiseOut, nullptr, &waveformOut[14]);
waveform16.update(&noiseOut, nullptr, &waveformOut[15]);

mixer1.update(&waveformOut[0], &waveformOut[1], &waveformOut[2], &waveformOut[3], &mixerOut[0]);
mixer2.update(&waveformOut[4], &waveformOut[5], &waveformOut[6], &waveformOut[7], &mixerOut[1]);
mixer3.update(&waveformOut[8], &waveformOut[9], &waveformOut[10], &waveformOut[11], &mixerOut[2]);
mixer4.update(&waveformOut[12], &waveformOut[13], &waveformOut[14], &waveformOut[15], &mixerOut[3]);

mixer5.update(&mixerOut[0], &mixerOut[1], &mixerOut[2], &mixerOut[3], &mixerOut[4]);

blockBuffer.pushBuffer(mixerOut[4].data, AUDIO_BLOCK_SAMPLES);
}

AudioStream& getStream() override {
return mixer5;
}
unsigned char getPort() override {
return 0;
}

private:

audio_block_t noiseOut, waveformOut[16] = {}, mixerOut[5] = {};

AudioSynthNoiseWhite noise1; //xy=306.20001220703125,530
AudioSynthWaveformModulated waveform16; //xy=591.2000122070312,906
AudioSynthWaveformModulated waveform14; //xy=593.2000122070312,801
AudioSynthWaveformModulated waveform15; //xy=593.2000122070312,846
AudioSynthWaveformModulated waveform13; //xy=594.2000122070312,759
AudioSynthWaveformModulated waveform8; //xy=601.2000122070312,486
AudioSynthWaveformModulated waveform6; //xy=603.2000122070312,381
AudioSynthWaveformModulated waveform7; //xy=603.2000122070312,426
AudioSynthWaveformModulated waveform12; //xy=602.2000122070312,697
AudioSynthWaveformModulated waveform5; //xy=604.2000122070312,339
AudioSynthWaveformModulated waveform10; //xy=604.2000122070312,592
AudioSynthWaveformModulated waveform11; //xy=604.2000122070312,637
AudioSynthWaveformModulated waveform9; //xy=605.2000122070312,550
AudioSynthWaveformModulated waveform4; //xy=609.2000122070312,271
AudioSynthWaveformModulated waveform2; //xy=611.2000122070312,166
AudioSynthWaveformModulated waveform3; //xy=611.2000122070312,211
AudioSynthWaveformModulated waveform1; //xy=612.2000122070312,123
AudioMixer4 mixer4; //xy=811.2000122070312,850
AudioMixer4 mixer3; //xy=822.2000122070312,641
AudioMixer4 mixer2; //xy=828.2000122070312,430
AudioMixer4 mixer1; //xy=829.2000122070312,215
AudioMixer4 mixer5; //xy=1076.2000122070312,427

// AudioSynthWaveformModulated waveform16; //xy=581.75,1167.5
// AudioSynthWaveformModulated waveform14; //xy=583.75,1062.5
// AudioSynthWaveformModulated waveform15; //xy=583.75,1107.5
// AudioSynthWaveformModulated waveform13; //xy=584.75,1020
// AudioSynthWaveformModulated waveform8; //xy=591.75,747.5
// AudioSynthWaveformModulated waveform6; //xy=593.75,642.5
// AudioSynthWaveformModulated waveform7; //xy=593.75,687.5
// AudioSynthWaveformModulated waveform12; //xy=592.75,958.5
// AudioSynthWaveformModulated waveform5; //xy=594.75,600
// AudioSynthWaveformModulated waveform10; //xy=594.75,853.5
// AudioSynthWaveformModulated waveform11; //xy=594.75,898.5
// AudioSynthWaveformModulated waveform9; //xy=595.75,811
// AudioSynthWaveformModulated waveform4; //xy=599.75,532.25
// AudioSynthWaveformModulated waveform2; //xy=601.75,427.25
// AudioSynthWaveformModulated waveform3; //xy=601.75,472.25
// AudioSynthWaveformModulated waveform1; //xy=602.75,384.75
// AudioMixer4 mixer4; //xy=801.75,1111.25
// AudioMixer4 mixer3; //xy=812.75,902.25
// AudioMixer4 mixer2; //xy=818.75,691.25
// AudioMixer4 mixer1; //xy=819.75,476
// AudioMixer4 mixer5; //xy=1066.75,688
// AudioConnection patchCord1;
// AudioConnection patchCord2;
// AudioConnection patchCord3;
// AudioConnection patchCord4;
// AudioConnection patchCord5;
// AudioConnection patchCord6;
// AudioConnection patchCord7;
// AudioConnection patchCord8;
// AudioConnection patchCord9;
// AudioConnection patchCord10;
// AudioConnection patchCord11;
// AudioConnection patchCord12;
// AudioConnection patchCord13;
// AudioConnection patchCord14;
// AudioConnection patchCord15;
// AudioConnection patchCord16;
// AudioConnection patchCord17;
// AudioConnection patchCord18;
// AudioConnection patchCord19;
// AudioConnection patchCord20;
// AudioConnection patchCord21;
// AudioConnection patchCord22;
// AudioConnection patchCord23;
// AudioConnection patchCord24;
// AudioConnection patchCord25;
// AudioConnection patchCord26;
// AudioConnection patchCord27;
// AudioConnection patchCord28;
// AudioConnection patchCord29;
// AudioConnection patchCord30;
// AudioConnection patchCord31;
// AudioConnection patchCord32;
// AudioConnection patchCord33;
// AudioConnection patchCord34;
// AudioConnection patchCord35;
// AudioConnection patchCord36;

};

REGISTER_PLUGIN(PrimeCluster);

+ 248
- 0
src/noise-plethora/plugins/P_PrimeCnoise.hpp View File

@@ -0,0 +1,248 @@
#pragma once

#include "NoisePlethoraPlugin.hpp"

class PrimeCnoise : public NoisePlethoraPlugin {

public:

PrimeCnoise()
// : patchCord1(noise1, 0, waveform1, 0)
// , patchCord2(noise1, 0, waveform2, 0)
// , patchCord3(noise1, 0, waveform3, 0)
// , patchCord4(noise1, 0, waveform4, 0)
// , patchCord5(noise1, 0, waveform5, 0)
// , patchCord6(noise1, 0, waveform6, 0)
// , patchCord7(noise1, 0, waveform7, 0)
// , patchCord8(noise1, 0, waveform8, 0)
// , patchCord9(noise1, 0, waveform9, 0)
// , patchCord10(noise1, 0, waveform10, 0)
// , patchCord11(noise1, 0, waveform11, 0)
// , patchCord12(noise1, 0, waveform12, 0)
// , patchCord13(noise1, 0, waveform13, 0)
// , patchCord14(noise1, 0, waveform14, 0)
// , patchCord15(noise1, 0, waveform15, 0)
// , patchCord16(noise1, 0, waveform16, 0)
// , patchCord17(waveform16, 0, mixer4, 3)
// , patchCord18(waveform14, 0, mixer4, 1)
// , patchCord19(waveform15, 0, mixer4, 2)
// , patchCord20(waveform13, 0, mixer4, 0)
// , patchCord21(waveform8, 0, mixer2, 3)
// , patchCord22(waveform6, 0, mixer2, 1)
// , patchCord23(waveform7, 0, mixer2, 2)
// , patchCord24(waveform12, 0, mixer3, 3)
// , patchCord25(waveform5, 0, mixer2, 0)
// , patchCord26(waveform10, 0, mixer3, 1)
// , patchCord27(waveform11, 0, mixer3, 2)
// , patchCord28(waveform9, 0, mixer3, 0)
// , patchCord29(waveform4, 0, mixer1, 3)
// , patchCord30(waveform2, 0, mixer1, 1)
// , patchCord31(waveform3, 0, mixer1, 2)
// , patchCord32(waveform1, 0, mixer1, 0)
// , patchCord33(mixer4, 0, mixer5, 3)
// , patchCord34(mixer3, 0, mixer5, 2)
// , patchCord35(mixer2, 0, mixer5, 1)
// , patchCord36(mixer1, 0, mixer5, 0)
{}

~PrimeCnoise() override {}

PrimeCnoise(const PrimeCnoise&) = delete;
PrimeCnoise& operator=(const PrimeCnoise&) = delete;

void init() override {
mixer1.gain(0, 1);
mixer1.gain(1, 1);
mixer1.gain(2, 1);
mixer1.gain(3, 1);
mixer2.gain(0, 1);
mixer2.gain(1, 1);
mixer2.gain(2, 1);
mixer2.gain(3, 1);
mixer3.gain(0, 1);
mixer3.gain(1, 1);
mixer3.gain(2, 1);
mixer3.gain(3, 1);
mixer4.gain(0, 1);
mixer4.gain(1, 1);
mixer4.gain(2, 1);
mixer4.gain(3, 1);
mixer5.gain(0, 1);
mixer5.gain(1, 1);
mixer5.gain(2, 1);
mixer5.gain(3, 1);

int masterWaveform = WAVEFORM_TRIANGLE_VARIABLE;
float masterVolume = 100;

waveform1.begin(masterVolume, 200, masterWaveform);
waveform2.begin(masterVolume, 647, masterWaveform);
waveform3.begin(masterVolume, 524, masterWaveform);
waveform4.begin(masterVolume, 444, masterWaveform);
waveform5.begin(masterVolume, 368, masterWaveform);
waveform6.begin(masterVolume, 283, masterWaveform);
waveform7.begin(masterVolume, 283, masterWaveform);
waveform8.begin(masterVolume, 283, masterWaveform);
waveform9.begin(masterVolume, 283, masterWaveform);
waveform10.begin(masterVolume, 283, masterWaveform);
waveform11.begin(masterVolume, 283, masterWaveform);
waveform12.begin(masterVolume, 283, masterWaveform);
waveform13.begin(masterVolume, 283, masterWaveform);
waveform14.begin(masterVolume, 283, masterWaveform);
waveform15.begin(masterVolume, 283, masterWaveform);
waveform16.begin(masterVolume, 283, masterWaveform);
}

void process(float k1, float k2) override {
float knob_1 = k1;
float knob_2 = k2;

float pitch1 = pow(knob_1, 2);

float multfactor = pitch1 * 12 + 0.5;

waveform1.frequency(53 * multfactor);
waveform2.frequency(127 * multfactor);
waveform3.frequency(199 * multfactor);
waveform4.frequency(283 * multfactor);
waveform5.frequency(383 * multfactor);
waveform6.frequency(467 * multfactor);
waveform7.frequency(577 * multfactor);
waveform8.frequency(661 * multfactor);
waveform9.frequency(769 * multfactor);
waveform10.frequency(877 * multfactor);
waveform11.frequency(983 * multfactor);
waveform12.frequency(1087 * multfactor);
waveform13.frequency(1193 * multfactor);
waveform14.frequency(1297 * multfactor);
waveform15.frequency(1429 * multfactor);
waveform16.frequency(1523 * multfactor);

noise1.amplitude(knob_2 * 0.2);
}

void processGraphAsBlock(TeensyBuffer& blockBuffer) override {
noise1.update(&noiseOut);

// FM from single noise source
waveform1.update(&noiseOut, nullptr, &waveformOut[0]);
waveform2.update(&noiseOut, nullptr, &waveformOut[1]);
waveform3.update(&noiseOut, nullptr, &waveformOut[2]);
waveform4.update(&noiseOut, nullptr, &waveformOut[3]);
waveform5.update(&noiseOut, nullptr, &waveformOut[4]);
waveform6.update(&noiseOut, nullptr, &waveformOut[5]);
waveform7.update(&noiseOut, nullptr, &waveformOut[6]);
waveform8.update(&noiseOut, nullptr, &waveformOut[7]);
waveform9.update(&noiseOut, nullptr, &waveformOut[8]);
waveform10.update(&noiseOut, nullptr, &waveformOut[9]);
waveform11.update(&noiseOut, nullptr, &waveformOut[10]);
waveform12.update(&noiseOut, nullptr, &waveformOut[11]);
waveform13.update(&noiseOut, nullptr, &waveformOut[12]);
waveform14.update(&noiseOut, nullptr, &waveformOut[13]);
waveform15.update(&noiseOut, nullptr, &waveformOut[14]);
waveform16.update(&noiseOut, nullptr, &waveformOut[15]);

mixer1.update(&waveformOut[0], &waveformOut[1], &waveformOut[2], &waveformOut[3], &mixerOut[0]);
mixer2.update(&waveformOut[4], &waveformOut[5], &waveformOut[6], &waveformOut[7], &mixerOut[1]);
mixer3.update(&waveformOut[8], &waveformOut[9], &waveformOut[10], &waveformOut[11], &mixerOut[2]);
mixer4.update(&waveformOut[12], &waveformOut[13], &waveformOut[14], &waveformOut[15], &mixerOut[3]);

mixer5.update(&mixerOut[0], &mixerOut[1], &mixerOut[2], &mixerOut[3], &mixerOut[4]);

blockBuffer.pushBuffer(mixerOut[4].data, AUDIO_BLOCK_SAMPLES);
}

AudioStream& getStream() override {
return mixer5;
}
unsigned char getPort() override {
return 0;
}

private:

audio_block_t noiseOut, waveformOut[16] = {}, mixerOut[5] = {};

AudioSynthNoiseWhite noise1; //xy=306.20001220703125,530
AudioSynthWaveformModulated waveform16; //xy=591.2000122070312,906
AudioSynthWaveformModulated waveform14; //xy=593.2000122070312,801
AudioSynthWaveformModulated waveform15; //xy=593.2000122070312,846
AudioSynthWaveformModulated waveform13; //xy=594.2000122070312,759
AudioSynthWaveformModulated waveform8; //xy=601.2000122070312,486
AudioSynthWaveformModulated waveform6; //xy=603.2000122070312,381
AudioSynthWaveformModulated waveform7; //xy=603.2000122070312,426
AudioSynthWaveformModulated waveform12; //xy=602.2000122070312,697
AudioSynthWaveformModulated waveform5; //xy=604.2000122070312,339
AudioSynthWaveformModulated waveform10; //xy=604.2000122070312,592
AudioSynthWaveformModulated waveform11; //xy=604.2000122070312,637
AudioSynthWaveformModulated waveform9; //xy=605.2000122070312,550
AudioSynthWaveformModulated waveform4; //xy=609.2000122070312,271
AudioSynthWaveformModulated waveform2; //xy=611.2000122070312,166
AudioSynthWaveformModulated waveform3; //xy=611.2000122070312,211
AudioSynthWaveformModulated waveform1; //xy=612.2000122070312,123
AudioMixer4 mixer4; //xy=811.2000122070312,850
AudioMixer4 mixer3; //xy=822.2000122070312,641
AudioMixer4 mixer2; //xy=828.2000122070312,430
AudioMixer4 mixer1; //xy=829.2000122070312,215
AudioMixer4 mixer5; //xy=1076.2000122070312,427

// AudioSynthWaveformModulated waveform16; //xy=581.75,1167.5
// AudioSynthWaveformModulated waveform14; //xy=583.75,1062.5
// AudioSynthWaveformModulated waveform15; //xy=583.75,1107.5
// AudioSynthWaveformModulated waveform13; //xy=584.75,1020
// AudioSynthWaveformModulated waveform8; //xy=591.75,747.5
// AudioSynthWaveformModulated waveform6; //xy=593.75,642.5
// AudioSynthWaveformModulated waveform7; //xy=593.75,687.5
// AudioSynthWaveformModulated waveform12; //xy=592.75,958.5
// AudioSynthWaveformModulated waveform5; //xy=594.75,600
// AudioSynthWaveformModulated waveform10; //xy=594.75,853.5
// AudioSynthWaveformModulated waveform11; //xy=594.75,898.5
// AudioSynthWaveformModulated waveform9; //xy=595.75,811
// AudioSynthWaveformModulated waveform4; //xy=599.75,532.25
// AudioSynthWaveformModulated waveform2; //xy=601.75,427.25
// AudioSynthWaveformModulated waveform3; //xy=601.75,472.25
// AudioSynthWaveformModulated waveform1; //xy=602.75,384.75
// AudioMixer4 mixer4; //xy=801.75,1111.25
// AudioMixer4 mixer3; //xy=812.75,902.25
// AudioMixer4 mixer2; //xy=818.75,691.25
// AudioMixer4 mixer1; //xy=819.75,476
// AudioMixer4 mixer5; //xy=1066.75,688
// AudioConnection patchCord1;
// AudioConnection patchCord2;
// AudioConnection patchCord3;
// AudioConnection patchCord4;
// AudioConnection patchCord5;
// AudioConnection patchCord6;
// AudioConnection patchCord7;
// AudioConnection patchCord8;
// AudioConnection patchCord9;
// AudioConnection patchCord10;
// AudioConnection patchCord11;
// AudioConnection patchCord12;
// AudioConnection patchCord13;
// AudioConnection patchCord14;
// AudioConnection patchCord15;
// AudioConnection patchCord16;
// AudioConnection patchCord17;
// AudioConnection patchCord18;
// AudioConnection patchCord19;
// AudioConnection patchCord20;
// AudioConnection patchCord21;
// AudioConnection patchCord22;
// AudioConnection patchCord23;
// AudioConnection patchCord24;
// AudioConnection patchCord25;
// AudioConnection patchCord26;
// AudioConnection patchCord27;
// AudioConnection patchCord28;
// AudioConnection patchCord29;
// AudioConnection patchCord30;
// AudioConnection patchCord31;
// AudioConnection patchCord32;
// AudioConnection patchCord33;
// AudioConnection patchCord34;
// AudioConnection patchCord35;
// AudioConnection patchCord36;
};

REGISTER_PLUGIN(PrimeCnoise);

+ 258
- 0
src/noise-plethora/plugins/P_Rwalk_BitCrushPW.hpp View File

@@ -0,0 +1,258 @@
#pragma once

#include "NoisePlethoraPlugin.hpp"

class Rwalk_BitCrushPW : public NoisePlethoraPlugin {

public:

Rwalk_BitCrushPW()
//: patchCord4(waveform8, 0, mixer2, 3)
//, patchCord6(waveform9, 0, mixer3, 0)
//, patchCord9(waveform7, 0, mixer2, 2)
//, patchCord11(waveform4, 0, mixer1, 3)
//, patchCord12(waveform5, 0, mixer2, 0)
//, patchCord13(waveform6, 0, mixer2, 1)
//, patchCord14(waveform3, 0, mixer1, 2)
//, patchCord15(waveform1, 0, mixer1, 0)
//, patchCord16(waveform2, 0, mixer1, 1)
//, patchCord17(mixer2, 0, mixer5, 2)
//, patchCord18(mixer1, 0, mixer5, 1)
//, patchCord19(mixer3, 0, mixer6, 1)
//, patchCord21(mixer6, freeverb1)
//, patchCord22(mixer5, bitcrusher1)
//, patchCord23(bitcrusher1, 0, mixer7, 1)
//, patchCord24(freeverb1, 0, mixer7, 2)
{ }
~Rwalk_BitCrushPW() override {}

// delete copy constructors
Rwalk_BitCrushPW(const Rwalk_BitCrushPW&) = delete;
Rwalk_BitCrushPW& operator=(const Rwalk_BitCrushPW&) = delete;

void init() override {

L = 600; // Size of box: maximum frequency
v_0 = 30; // speed: size of step in frequency units.

mixer1.gain(0, 1);
mixer1.gain(1, 1);
mixer1.gain(2, 1);
mixer1.gain(3, 1);
mixer2.gain(0, 1);
mixer2.gain(1, 1);
mixer2.gain(2, 1);
mixer2.gain(3, 1);
// mixer3.gain(0, 1);
// mixer3.gain(1, 1);
// mixer3.gain(2, 1);
// mixer3.gain(3, 1);

// SINE
int masterWaveform = WaveformType::WAVEFORM_PULSE;

waveform1.pulseWidth(0.2);
waveform1.begin(1, 794, masterWaveform);

waveform2.pulseWidth(0.2);
waveform2.begin(1, 647, masterWaveform);

waveform3.pulseWidth(0.2);
waveform3.begin(1, 524, masterWaveform);

waveform4.pulseWidth(0.2);
waveform4.begin(1, 444, masterWaveform);

waveform5.pulseWidth(0.2);
waveform5.begin(1, 368, masterWaveform);

waveform6.pulseWidth(0.2);
waveform6.begin(1, 283, masterWaveform);

waveform7.pulseWidth(0.2);
waveform7.begin(1, 283, masterWaveform);

waveform8.pulseWidth(0.2);
waveform8.begin(1, 283, masterWaveform);

waveform9.pulseWidth(0.2);
waveform9.begin(1, 283, masterWaveform);


// random walk initial conditions
for (int i = 0; i < 9; i++) {
// velocities: initial conditions in -pi : +pi
theta = M_PI * (random::uniform() * 2.0 - 1.0);
vx[i] = std::cos(theta);
vy[i] = std::sin(theta);
// positions: random in [0,L] x [0, L]
x[i] = random::uniform() * L;
y[i] = random::uniform() * L;

}
}

void process(float k1, float k2) override {

float knob_1 = k1;
float knob_2 = k2;

float dL;

dL = L + 100;

v_var = v_0;

bc_01 = (knob_1 - 0) * (0.75 - 0.2) / (1 - 0) + 0.2; // funciĂłn para recortar intervalo de 0.1 a 0.9


bitcrusher1.bits(1);

fv = knob_2;
freeverb1.roomsize(fv);

// loop to "walk" randomly
for (int i = 0; i < 9; i++) {
theta = M_PI * (random::uniform() * 2.0 - 1.0);

posx = std::cos(theta);
vx[i] = posx;

posy = std::sin(theta);
vy[i] = posy;

// Update new position
xn = x[i] + v_var * vx[i];
yin = y[i] + v_var * vy[i];

// periodic boundary conditions
if (xn < 50)
//xn += dL;
xn += 10;
else if (xn > dL)
//xn -= dL;
xn -= 10;

if (yin < 0.01)
yin += dL;
else if (yin > dL)
yin -= dL;
x[i] = xn;
y[i] = yin;

}



waveform1.frequency(x[0]);
waveform2.frequency(x[1]);
waveform3.frequency(x[2]);
waveform4.frequency(x[3]);
waveform5.frequency(x[4]);
waveform6.frequency(x[5]);
waveform7.frequency(x[6]);
waveform8.frequency(x[7]);
waveform9.frequency(x[8]);

waveform1.pulseWidth(bc_01);
waveform2.pulseWidth(bc_01);
waveform3.pulseWidth(bc_01);
waveform4.pulseWidth(bc_01);
waveform5.pulseWidth(bc_01);
waveform6.pulseWidth(bc_01);
waveform7.pulseWidth(bc_01);
waveform8.pulseWidth(bc_01);
waveform9.pulseWidth(bc_01);

}


void processGraphAsBlock(TeensyBuffer& blockBuffer) override {
// sum first block of oscillators
waveform1.update(&waveformBlock[0]);
waveform2.update(&waveformBlock[1]);
waveform3.update(&waveformBlock[2]);
waveform4.update(&waveformBlock[3]);
mixer1.update(&waveformBlock[0], &waveformBlock[1], &waveformBlock[2], &waveformBlock[3], &mixerBlock[0]);

// sum second block of oscillators
waveform5.update(&waveformBlock[4]);
waveform6.update(&waveformBlock[5]);
waveform7.update(&waveformBlock[6]);
waveform8.update(&waveformBlock[7]);
mixer2.update(&waveformBlock[4], &waveformBlock[5], &waveformBlock[6], &waveformBlock[7], &mixerBlock[1]);

// sum two blocks and feed into bitcrusher
mixer5.update(&mixerBlock[0], &mixerBlock[1], nullptr, nullptr, &mixerBlock[2]);
bitcrusher1.update(&mixerBlock[2], &bitcrushBlock);

waveform9.update(&waveformBlock[8]);
// mixer3/6 are just one-input + unit gain so just skip to freeverb
freeverb1.update(&waveformBlock[8], &freeverbBlock);

// finally sum bitcrush and freeverb
mixer7.update(&bitcrushBlock, &freeverbBlock, nullptr, nullptr, &mixerBlock[3]);

blockBuffer.pushBuffer(mixerBlock[3].data, AUDIO_BLOCK_SAMPLES);
}

AudioStream& getStream() override {
return mixer7;
}
unsigned char getPort() override {
return 0;
}

private:

audio_block_t waveformBlock[9], mixerBlock[4], bitcrushBlock, freeverbBlock;

/* will be filled in */
// GUItool: begin automatically generated code
AudioSynthWaveform waveform8; //xy=519.75,577.75
AudioSynthWaveform waveform9; //xy=519.75,614.75
AudioSynthWaveform waveform7; //xy=520.75,541.75
AudioSynthWaveform waveform4; //xy=521.75,427.75
AudioSynthWaveform waveform5; //xy=521.75,466.75
AudioSynthWaveform waveform6; //xy=521.75,504.75
AudioSynthWaveform waveform3; //xy=522.75,391.75
AudioSynthWaveform waveform1; //xy=523.75,316.75
AudioSynthWaveform waveform2; //xy=523.75,354.75
AudioMixer4 mixer2; //xy=713.75,528.75
AudioMixer4 mixer1; //xy=714.75,377.75
//AudioMixer4 mixer3; //xy=716.75,664.75
//AudioMixer4 mixer6; //xy=1248,561

AudioMixer4 mixer5; //xy=961.75,589.75

AudioEffectBitcrusher bitcrusher1; //xy=1439,393
AudioEffectFreeverb freeverb1; //xy=923.5,281.5
AudioMixer4 mixer7; //xy=1650,448

//AudioOutputI2S i2s1; //xy=1227.75,604.75
// AudioConnection patchCord4(waveform8, 0, mixer2, 3);
// AudioConnection patchCord6(waveform9, 0, mixer3, 0);
// AudioConnection patchCord9(waveform7, 0, mixer2, 2);
// AudioConnection patchCord11(waveform4, 0, mixer1, 3);
// AudioConnection patchCord12(waveform5, 0, mixer2, 0);
// AudioConnection patchCord13(waveform6, 0, mixer2, 1);
// AudioConnection patchCord14(waveform3, 0, mixer1, 2);
// AudioConnection patchCord15(waveform1, 0, mixer1, 0);
// AudioConnection patchCord16(waveform2, 0, mixer1, 1);
// AudioConnection patchCord17(mixer2, 0, mixer5, 2);
// AudioConnection patchCord18(mixer1, 0, mixer5, 1);
// AudioConnection patchCord19(mixer3, 0, mixer6, 1);
// AudioConnection patchCord21(mixer6, freeverb1);
// AudioConnection patchCord22(mixer5, bitcrusher1);
// AudioConnection patchCord23(bitcrusher1, 0, mixer7, 1);
// AudioConnection patchCord24(freeverb1, 0, mixer7, 2);


int L; //, i, t;
float theta, posx, posy, xn, yin;
float v_0, v_var, bc_01, fv;//pw = pulse width
float x[9], y[9], vx[9], vy[9]; // number depends on waveforms declared

};

REGISTER_PLUGIN(Rwalk_BitCrushPW); // this is important, so that we can include the plugin in a bank

+ 156
- 0
src/noise-plethora/plugins/P_Rwalk_LFree.hpp View File

@@ -0,0 +1,156 @@
#pragma once

#include "NoisePlethoraPlugin.hpp"

class Rwalk_LFree : public NoisePlethoraPlugin {

public:

Rwalk_LFree()
// : patchCord1(pwm2, 0, mixer5, 1)
// , patchCord2(pwm1, 0, mixer5, 0)
// , patchCord3(pwm3, 0, mixer5, 2)
// , patchCord4(pwm4, 0, mixer5, 3)
// , patchCord5(mixer5, freeverb1)
{ }

~Rwalk_LFree() override {}

// delete copy constructors
Rwalk_LFree(const Rwalk_LFree&) = delete;
Rwalk_LFree& operator=(const Rwalk_LFree&) = delete;

void init() override {

L = 500; // Size of box: maximum frequency
v_0 = 5; // speed: size of step in frequency units.

mixer5.gain(0, 1);
mixer5.gain(1, 1);
mixer5.gain(2, 1);
mixer5.gain(3, 1);


pwm1.frequency(794);
pwm1.amplitude(1);

pwm2.frequency(647);
pwm2.amplitude(1);

pwm3.frequency(524);
pwm3.amplitude(1);

pwm4.frequency(444);
pwm4.amplitude(1);

// random walk initial conditions
for (int i = 0; i < 4; i++) {
// velocities: initial conditions in -pi : +pi
theta = M_PI * (random::uniform() * 2.0 - 1.0);
vx[i] = std::cos(theta);
vy[i] = std::sin(theta);
// positions: random in [0,L] x [0, L]
x[i] = random::uniform() * L;
y[i] = random::uniform() * L;
}
}

void process(float k1, float k2) override {

float knob_1 = k1;
float knob_2 = k2;
float dL, fv;

dL = knob_1 * L + 50;

v_var = v_0;

fv = knob_2;
freeverb1.roomsize(fv);

// loop to "walk" randomly
for (int i = 0; i < 4; i++) {
theta = M_PI * (random::uniform() * 2.0 - 1.0);

posx = std::cos(theta);
vx[i] = posx;

posy = std::sin(theta);
vy[i] = posy;

// Update new position
xn = x[i] + v_var * vx[i];
yin = y[i] + v_var * vy[i];

// periodic boundary conditions
if (xn < 40)
//xn += dL;
xn += 10;
else if (xn > dL)
//xn -= dL;
xn -= 10;

if (yin < 0.01)
yin += dL;
else if (yin > dL)
yin -= dL;
x[i] = xn;
y[i] = yin;
}
pwm1.frequency(x[0]);
pwm2.frequency(x[1]);
pwm3.frequency(x[2]);
pwm4.frequency(x[3]);
}

void processGraphAsBlock(TeensyBuffer& blockBuffer) override {

pwm1.update(nullptr, &pwmBlock[0]);
pwm2.update(nullptr, &pwmBlock[1]);
pwm3.update(nullptr, &pwmBlock[2]);
pwm4.update(nullptr, &pwmBlock[3]);

mixer5.update(&pwmBlock[0], &pwmBlock[1], &pwmBlock[2], &pwmBlock[3], &mixerBlock);
freeverb1.update(&mixerBlock, &freeverbBlock);

blockBuffer.pushBuffer(freeverbBlock.data, AUDIO_BLOCK_SAMPLES);
}

AudioStream& getStream() override {
return freeverb1;
}
unsigned char getPort() override {
return 0;
}

private:

audio_block_t pwmBlock[4], mixerBlock, freeverbBlock;

/* will be filled in */
// GUItool: begin automatically generated code

AudioMixer4 mixer5; //xy=961.75,589.75

AudioSynthWaveformPWM pwm2; //xy=588.5,279.5
AudioSynthWaveformPWM pwm1; //xy=589.5,228.5
AudioSynthWaveformPWM pwm3; //xy=593.5,331.5
AudioSynthWaveformPWM pwm4; //xy=596.5,375.5

AudioEffectFreeverb freeverb1;

//AudioOutputI2S i2s1; //xy=1227.75,604.75
//AudioConnection patchCord1;
//AudioConnection patchCord2;
//AudioConnection patchCord3;
//AudioConnection patchCord4;
//AudioConnection patchCord5;

int L; //, i, t;
float theta, posx, posy, xn, yin;
float v_0, v_var;//pw = pulse width
float x[4], y[4], vx[4], vy[4]; // number depends on waveforms declared

};

REGISTER_PLUGIN(Rwalk_LFree); // this is important, so that we can include the plugin in a bank

+ 199
- 0
src/noise-plethora/plugins/P_Rwalk_SineFMFlange.hpp View File

@@ -0,0 +1,199 @@
#pragma once

#include "NoisePlethoraPlugin.hpp"

#define FLANGE_DELAY_LENGTH (2*AUDIO_BLOCK_SAMPLES)

class Rwalk_SineFMFlange : public NoisePlethoraPlugin {

public:

Rwalk_SineFMFlange()
// : patchCord1(waveform4, sine_fm3)
// , patchCord2(waveform3, sine_fm4)
// , patchCord3(waveform2, sine_fm2)
// , patchCord4(waveform1, sine_fm1)
// , patchCord5(sine_fm3, 0, mixer1, 3)
// , patchCord6(sine_fm2, 0, mixer1, 1)
// , patchCord7(sine_fm1, 0, mixer1, 0)
// , patchCord8(sine_fm4, 0, mixer1, 2)
// , patchCord9(mixer1, flange1)
{ }

~Rwalk_SineFMFlange() override {}

// delete copy constructors
Rwalk_SineFMFlange(const Rwalk_SineFMFlange&) = delete;
Rwalk_SineFMFlange& operator=(const Rwalk_SineFMFlange&) = delete;

void init() override {

L = 600; // Size of box: maximum frequency
v_0 = 30; // speed: size of step in frequency units.

mixer1.gain(0, 1);
mixer1.gain(2, 1);

sine_fm1.amplitude(1);
sine_fm2.amplitude(1);
sine_fm3.amplitude(1);
sine_fm4.amplitude(1);

flange1.begin(l_delayline, FLANGE_DELAY_LENGTH, s_idx, s_depth, s_freq);

int masterWaveform = WAVEFORM_PULSE;


waveform1.pulseWidth(0.2);
waveform1.begin(1, 794, masterWaveform);

waveform2.pulseWidth(0.2);
waveform2.begin(1, 647, masterWaveform);

waveform3.pulseWidth(0.2);
waveform3.begin(1, 750, masterWaveform);

waveform4.pulseWidth(0.2);
waveform4.begin(1, 200, masterWaveform);


// random walk initial conditions
for (int i = 0; i < 4; i++) {
// velocities: initial conditions in -pi : +pi
theta = M_PI * (random::uniform() * (2.0) - 1.0);
vx[i] = cos(theta);
vy[i] = sin(theta);
// positions: random in [0,L] x [0, L]
x[i] = random::uniform() * (L);
y[i] = random::uniform() * (L);
}
}

void process(float k1, float k2) override {


float knob_1 = k1;
float knob_2 = k2;
float dL;

dL = L + 100;

v_var = v_0;

snfm = knob_1 * 500 + 10;

mod_freq = knob_2 * 3;


// loop to "walk" randomly
for (int i = 0; i < 4; i++) {
theta = M_PI * (random::uniform() * (2.0) - 1.0);

posx = cos(theta);
vx[i] = posx;

posy = sin(theta);
vy[i] = posy;

// Update new position
xn = x[i] + v_var * vx[i];
yin = y[i] + v_var * vy[i];

// periodic boundary conditions
if (xn < 50)
//xn += dL;
xn += 10;
else if (xn > dL)
//xn -= dL;
xn -= 10;

if (yin < 0.01)
yin += dL;
else if (yin > dL)
yin -= dL;
x[i] = xn;
y[i] = yin;
}
sine_fm1.frequency(snfm);
sine_fm2.frequency(snfm + 55);
sine_fm3.frequency(snfm + 65);
sine_fm4.frequency(snfm + 75);

flange1.voices(s_idx, s_depth, mod_freq);


waveform1.frequency(x[0]);
waveform2.frequency(x[1]);
waveform3.frequency(x[2]);
waveform4.frequency(x[3]);
}


void processGraphAsBlock(TeensyBuffer& blockBuffer) override {

waveform1.update(&waveformBlock[0]);
waveform2.update(&waveformBlock[1]);
waveform3.update(&waveformBlock[2]);
waveform4.update(&waveformBlock[3]);

sine_fm1.update(&waveformBlock[0], &sineFMBlock[0]);
sine_fm2.update(&waveformBlock[1], &sineFMBlock[1]);
sine_fm3.update(&waveformBlock[2], &sineFMBlock[2]);
sine_fm4.update(&waveformBlock[3], &sineFMBlock[3]);

mixer1.update(&sineFMBlock[0], &sineFMBlock[1], &sineFMBlock[2], &sineFMBlock[3], &mixerBlock);
flange1.update(&mixerBlock, &flangeBlock);

blockBuffer.pushBuffer(flangeBlock.data, AUDIO_BLOCK_SAMPLES);
}

AudioStream& getStream() override {
return flange1;
}
unsigned char getPort() override {
return 0;
}

private:

audio_block_t waveformBlock[4], sineFMBlock[4], flangeBlock, mixerBlock;

AudioSynthWaveform waveform1;
AudioSynthWaveform waveform2;
AudioSynthWaveform waveform3;
AudioSynthWaveform waveform4;
AudioSynthWaveformSineModulated sine_fm3;
AudioSynthWaveformSineModulated sine_fm2;
AudioSynthWaveformSineModulated sine_fm1;
AudioSynthWaveformSineModulated sine_fm4;

AudioEffectFlange flange1;
AudioMixer4 mixer1;


// AudioConnection patchCord1;
// AudioConnection patchCord2;
// AudioConnection patchCord3;
// AudioConnection patchCord4;
// AudioConnection patchCord5;
// AudioConnection patchCord6;
// AudioConnection patchCord7;
// AudioConnection patchCord8;
// AudioConnection patchCord9;


int L; //, i, t;
float theta, posx, posy, xn, yin;
float v_0, v_var, snfm;//pw = pulse width
float x[4], y[4], vx[4], vy[4]; // number depends on waveforms declared

/*Variables for flange effect*/
short l_delayline[FLANGE_DELAY_LENGTH]; //left channel
int s_idx = 2 * FLANGE_DELAY_LENGTH / 4;
int s_depth = FLANGE_DELAY_LENGTH / 4;
double s_freq = 3;
double mod_freq;

};

REGISTER_PLUGIN(Rwalk_SineFMFlange); // this is important, so that we can include the plugin in a bank

+ 65
- 0
src/noise-plethora/plugins/P_S_H.hpp View File

@@ -0,0 +1,65 @@
#pragma once

#include "NoisePlethoraPlugin.hpp"

class S_H : public NoisePlethoraPlugin {

public:

S_H()
//: patchCord1(waveformMod1, 0, mixer1, 0)
//, patchCord2(waveformMod1, freeverb1)
//, patchCord3(freeverb1, 0, mixer1, 1)
{ }

~S_H() override {}

S_H(const S_H&) = delete;
S_H& operator=(const S_H&) = delete;

void init() override {
waveformMod1.begin(1, 200, WAVEFORM_SAMPLE_HOLD);
waveformMod1.frequencyModulation(10);

freeverb1.damping(1);
freeverb1.roomsize(0.5);

mixer1.gain(0, 1);
mixer1.gain(1, 0);
}

void process(float k1, float k2) override {
waveformMod1.frequency(5000 * k1 + 15);
mixer1.gain(0, 1 - k2);
mixer1.gain(1, k2 * 4);
}

void processGraphAsBlock(TeensyBuffer& blockBuffer) override {
waveformMod1.update(nullptr, nullptr, &waveformModBlock);
freeverb1.update(&waveformModBlock, &freeverbBlock);
mixer1.update(&waveformModBlock, &freeverbBlock, nullptr, nullptr, &mixerBlock);

blockBuffer.pushBuffer(mixerBlock.data, AUDIO_BLOCK_SAMPLES);
}

AudioStream& getStream() override {
return mixer1;
}
unsigned char getPort() override {
return 0;
}

private:

audio_block_t waveformModBlock, mixerBlock, freeverbBlock;

AudioSynthWaveformModulated waveformMod1; //xy=517.5666656494141,413.99998474121094
AudioEffectFreeverb freeverb1; //xy=711.5666656494141,465.99998474121094
AudioMixer4 mixer1; //xy=868.5666656494141,399.99998474121094
//AudioConnection patchCord1(waveformMod1, 0, mixer1, 0);
//AudioConnection patchCord2(waveformMod1, freeverb1);
//AudioConnection patchCord3(freeverb1, 0, mixer1, 1);

};

REGISTER_PLUGIN(S_H);

+ 64
- 0
src/noise-plethora/plugins/P_TeensyAlt.hpp View File

@@ -0,0 +1,64 @@
#pragma once
#include "NoisePlethoraPlugin.hpp"
class TeensyAlt : public NoisePlethoraPlugin {
public:
TeensyAlt()
//:patchCord1(waveformMod1, 0, waveformMod2, 1),
//patchCord3(waveformMod2, 0, waveformMod1, 0)
{ }
~TeensyAlt() override {}
TeensyAlt(const TeensyAlt&) = delete;
TeensyAlt& operator=(const TeensyAlt&) = delete;
void init() override {
waveform1.begin(1, 200, WAVEFORM_SAMPLE_HOLD);
filter1.resonance(5);
DEBUG("init finished");
}
void process(float k1, float k2) override {
float knob_1 = k1;
float knob_2 = k2;
(void) knob_2;
float pitch1 = pow(knob_1, 2);
// float pitch2 = pow(knob_2, 2);
waveform1.frequency(50 + (pitch1 * 5000));
}
void processGraphAsBlock(TeensyBuffer& blockBuffer) override {
waveform1.update(&output1);
filter1.update(&output1, nullptr, &filterOutLP, &filterOutBP, &filterOutHP);
blockBuffer.pushBuffer(filterOutBP.data, AUDIO_BLOCK_SAMPLES);
}
AudioStream& getStream() override {
return filter1;
}
unsigned char getPort() override {
return 0;
}
private:
audio_block_t output1 = {};
audio_block_t filterOutLP, filterOutBP, filterOutHP;
AudioSynthWaveform waveform1; //xy=829.0908737182617,499.54540252685547
AudioFilterStateVariable filter1; //xy=1062.2726001739502,460.8181266784668
};
REGISTER_PLUGIN(TeensyAlt);

+ 85
- 0
src/noise-plethora/plugins/P_TestPlugin.hpp View File

@@ -0,0 +1,85 @@
#pragma once
#include <rack.hpp>
#include "NoisePlethoraPlugin.hpp"
class TestPlugin : public NoisePlethoraPlugin {
public:
TestPlugin()
//: patchCord1(waveformMod1, 0, waveformMod2, 1),
//patchCord3(waveformMod2, 0, waveformMod1, 0)
{ }
~TestPlugin() override {}
TestPlugin(const TestPlugin&) = delete;
TestPlugin& operator=(const TestPlugin&) = delete;
void init() override {
//test.begin(WaveformType::WAVEFORM_SQUARE);
//test.offset(1);
/*
int masterVolume= 1;
waveformMod1.begin(WAVEFORM_SQUARE);
waveformMod2.begin(WAVEFORM_PULSE);
waveformMod1.offset(1);
waveformMod1.amplitude(masterVolume);
waveformMod2.amplitude(masterVolume);
*/
waveform1.amplitude(1.0);
}
void process(float k1, float k2) override {
float knob_1 = k1;
float knob_2 = k2;
float pitch1 = std::pow(knob_1, 2);
waveform1.frequency((pitch1 * 10000));
if (knob_2 > 0.5) {
waveform1.begin((knob_2 > 0.75) ? WAVEFORM_SQUARE : WAVEFORM_SINE);
}
else {
waveform1.begin((knob_2 > 0.25) ? WAVEFORM_TRIANGLE : WAVEFORM_SAWTOOTH);
}
//waveformMod1.frequency(10+(pitch1*50));
//waveformMod2.frequency(10+(knob_2*200));
//waveformMod1.frequencyModulation(knob_2*8+3);
//DEBUG(string::f("%g %d %g %g", waveform1.frequency, waveform1.tone_type, k1, k2).c_str());
}
void processGraphAsBlock(TeensyBuffer& blockBuffer) override {
// waveformMod1
waveform1.update(nullptr, nullptr, &waveformOut);
blockBuffer.pushBuffer(waveformOut.data, AUDIO_BLOCK_SAMPLES);
}
AudioStream& getStream() override {
return waveform1;
}
unsigned char getPort() override {
return 0;
}
private:
audio_block_t waveformOut;
AudioSynthWaveformModulated waveform1;
//AudioSynthWaveformModulated waveformMod1; //xy=334,349
//AudioSynthWaveformModulated waveformMod2; //xy=616,284
//AudioConnection patchCord1;
//AudioConnection patchCord3;
};
REGISTER_PLUGIN(TestPlugin);

+ 168
- 0
src/noise-plethora/plugins/P_TriFMcluster.hpp View File

@@ -0,0 +1,168 @@
#pragma once

#include "NoisePlethoraPlugin.hpp"

class TriFMcluster : public NoisePlethoraPlugin {

public:

TriFMcluster()
// : patchCord1(modulator1, 0, waveform1, 0),
// patchCord2(modulator3, 0, waveform3, 0),
// patchCord3(modulator2, 0, waveform2, 0),
// patchCord4(modulator5, 0, waveform5, 0),
// patchCord5(modulator4, 0, waveform4, 0),
// patchCord6(modulator6, 0, waveform6, 0),
// patchCord7(waveform1, 0, mixer1, 0),
// patchCord8(waveform4, 0, mixer1, 3),
// patchCord9(waveform2, 0, mixer1, 1),
// patchCord10(waveform3, 0, mixer1, 2),
// patchCord11(waveform6, 0, mixer2, 1),
// patchCord12(waveform5, 0, mixer2, 0),
// patchCord13(mixer2, 0, mixer5, 1),
// patchCord14(mixer1, 0, mixer5, 0)
{ }

~TriFMcluster() override {}

TriFMcluster(const TriFMcluster&) = delete;
TriFMcluster& operator=(const TriFMcluster&) = delete;

void init() override {
mixer1.gain(0, 1);
mixer1.gain(1, 1);
mixer1.gain(2, 1);
mixer1.gain(3, 1);
mixer2.gain(0, 1);
mixer2.gain(1, 1);
mixer2.gain(2, 1);
mixer2.gain(3, 1);
mixer5.gain(0, 1);
mixer5.gain(1, 1);
mixer5.gain(2, 1);
mixer5.gain(3, 1);

int masterWaveform = WAVEFORM_TRIANGLE;
float masterVolume = 0.25;

waveform1.begin(masterVolume, 794, masterWaveform);
waveform2.begin(masterVolume, 647, masterWaveform);
waveform3.begin(masterVolume, 524, masterWaveform);
waveform4.begin(masterVolume, 444, masterWaveform);
waveform5.begin(masterVolume, 368, masterWaveform);
waveform6.begin(masterVolume, 283, masterWaveform);

modulator1.begin(1, 1000, WAVEFORM_SINE);
modulator2.begin(1, 1000, WAVEFORM_SINE);
modulator3.begin(1, 1000, WAVEFORM_SINE);
modulator4.begin(1, 1000, WAVEFORM_SINE);
modulator5.begin(1, 1000, WAVEFORM_SINE);
modulator6.begin(1, 1000, WAVEFORM_SINE);
}

void process(float k1, float k2) override {
float knob_1 = k1;
float knob_2 = k2;
float pitch1 = pow(knob_1, 2);

float f1 = 300 + pitch1 * 8000;
float f2 = f1 * 1.227;
float f3 = f2 * 1.24;
float f4 = f3 * 1.17;
float f5 = f4 * 1.2;
float f6 = f5 * 1.3;

float index = knob_2 * 0.9 + 0.1;
float indexFreq = 0.07;

modulator1.amplitude(index);
modulator2.amplitude(index);
modulator3.amplitude(index);
modulator4.amplitude(index);
modulator5.amplitude(index);
modulator6.amplitude(index);


modulator1.frequency(f1 * indexFreq);
modulator2.frequency(f2 * indexFreq);
modulator3.frequency(f3 * indexFreq);
modulator4.frequency(f4 * indexFreq);
modulator5.frequency(f5 * indexFreq);
modulator6.frequency(f6 * indexFreq);


waveform1.frequency(f1);
waveform2.frequency(f2);
waveform3.frequency(f3);
waveform4.frequency(f4);
waveform5.frequency(f5);
waveform6.frequency(f6);
}

void processGraphAsBlock(TeensyBuffer& blockBuffer) override {
// modulators for the 6 oscillators
modulator1.update(&waveformOut[0]);
modulator2.update(&waveformOut[1]);
modulator3.update(&waveformOut[2]);
modulator4.update(&waveformOut[3]);
modulator5.update(&waveformOut[4]);
modulator6.update(&waveformOut[5]);

// FM for the 6 oscillators from modulators
waveform1.update(&waveformOut[0], nullptr, &waveformModOut[0]);
waveform2.update(&waveformOut[1], nullptr, &waveformModOut[1]);
waveform3.update(&waveformOut[2], nullptr, &waveformModOut[2]);
waveform4.update(&waveformOut[3], nullptr, &waveformModOut[3]);
waveform5.update(&waveformOut[4], nullptr, &waveformModOut[4]);
waveform6.update(&waveformOut[5], nullptr, &waveformModOut[5]);

mixer1.update(&waveformModOut[0], &waveformModOut[1], &waveformModOut[2], &waveformModOut[3], &mixerOut[0]);
mixer2.update(&waveformModOut[4], &waveformModOut[5], nullptr, nullptr, &mixerOut[1]);
mixer5.update(&mixerOut[0], &mixerOut[1], nullptr, nullptr, &mixerOut[2]);

blockBuffer.pushBuffer(mixerOut[2].data, AUDIO_BLOCK_SAMPLES);
}

AudioStream& getStream() override {
return mixer5;
}
unsigned char getPort() override {
return 0;
}

private:
audio_block_t waveformOut[6] = {}, waveformModOut[6] = {}, mixerOut[3] = {};

AudioSynthWaveform modulator1; //xy=236.88888549804688,262.55556869506836
AudioSynthWaveform modulator3; //xy=238.88890075683594,366.555606842041
AudioSynthWaveform modulator2; //xy=239.88890075683594,313.5556392669678
AudioSynthWaveform modulator5; //xy=239.88890075683594,485.5555810928345
AudioSynthWaveform modulator4; //xy=240.88890075683594,428.55560970306396
AudioSynthWaveform modulator6; //xy=242.8888931274414,541.5555143356323
AudioSynthWaveformModulated waveform1; //xy=459.88890075683594,268.6667013168335
AudioSynthWaveformModulated waveform4; //xy=459.8888854980469,433.6666889190674
AudioSynthWaveformModulated waveform2; //xy=461.88890838623047,322.66671657562256
AudioSynthWaveformModulated waveform3; //xy=461.8888854980469,373.6666889190674
AudioSynthWaveformModulated waveform6; //xy=461.88890838623047,546.6666688919067
AudioSynthWaveformModulated waveform5; //xy=462.88888931274414,492.66670417785645
AudioMixer4 mixer2; //xy=663.8888053894043,520.6666412353516
AudioMixer4 mixer1; //xy=667.888916015625,349.6667251586914
AudioMixer4 mixer5; //xy=853.8889122009277,448.6667900085449
// AudioConnection patchCord1;
// AudioConnection patchCord2;
// AudioConnection patchCord3;
// AudioConnection patchCord4;
// AudioConnection patchCord5;
// AudioConnection patchCord6;
// AudioConnection patchCord7;
// AudioConnection patchCord8;
// AudioConnection patchCord9;
// AudioConnection patchCord10;
// AudioConnection patchCord11;
// AudioConnection patchCord12;
// AudioConnection patchCord13;
// AudioConnection patchCord14;

};

REGISTER_PLUGIN(TriFMcluster);

+ 305
- 0
src/noise-plethora/plugins/P_WalkingFilomena.hpp View File

@@ -0,0 +1,305 @@
#pragma once
#include <cmath>

#include "NoisePlethoraPlugin.hpp"

class WalkingFilomena : public NoisePlethoraPlugin {

public:

WalkingFilomena()
// : patchCord1(waveform12, 0, mixer3, 3)
// , patchCord2(waveform16, 0, mixer4, 3)
// , patchCord3(waveform11, 0, mixer3, 2)
// , patchCord4(waveform8, 0, mixer2, 3)
// , patchCord5(waveform15, 0, mixer4, 2)
// , patchCord6(waveform9, 0, mixer3, 0)
// , patchCord7(waveform10, 0, mixer3, 1)
// , patchCord8(waveform13, 0, mixer4, 0)
// , patchCord9(waveform7, 0, mixer2, 2)
// , patchCord10(waveform14, 0, mixer4, 1)
// , patchCord11(waveform4, 0, mixer1, 3)
// , patchCord12(waveform5, 0, mixer2, 0)
// , patchCord13(waveform6, 0, mixer2, 1)
// , patchCord14(waveform3, 0, mixer1, 2)
// , patchCord15(waveform1, 0, mixer1, 0)
// , patchCord16(waveform2, 0, mixer1, 1)
// , patchCord17(mixer2, 0, mixer5, 1)
// , patchCord18(mixer1, 0, mixer5, 0)
// , patchCord19(mixer3, 0, mixer5, 2)
// , patchCord20(mixer4, 0, mixer5, 3)
// //patchCord21(mixer5, 0, i2s1, 0);
{ }
~WalkingFilomena() override {}

// delete copy constructors
WalkingFilomena(const WalkingFilomena&) = delete;
WalkingFilomena& operator=(const WalkingFilomena&) = delete;

void init() override {

L = 1800; // Size of box: maximum frequency
v_0 = 10; // speed: size of step in frequency units.

mixer1.gain(0, 1);
mixer1.gain(1, 1);
mixer1.gain(2, 1);
mixer1.gain(3, 1);
mixer2.gain(0, 1);
mixer2.gain(1, 1);
mixer2.gain(2, 1);
mixer2.gain(3, 1);
mixer3.gain(0, 1);
mixer3.gain(1, 1);
mixer3.gain(2, 1);
mixer3.gain(3, 1);
mixer4.gain(0, 1);
mixer4.gain(1, 1);
mixer4.gain(2, 1);
mixer4.gain(3, 1);
mixer5.gain(0, 1);
mixer5.gain(1, 1);
mixer5.gain(2, 1);
mixer5.gain(3, 1);

// SINE
WaveformType masterWaveform = WAVEFORM_PULSE;

waveform1.pulseWidth(0.5);
waveform1.begin(1, 794, masterWaveform);

waveform2.pulseWidth(0.5);
waveform2.begin(1, 647, masterWaveform);

waveform3.pulseWidth(0.5);
waveform3.begin(1, 524, masterWaveform);

waveform4.pulseWidth(0.5);
waveform4.begin(1, 444, masterWaveform);

waveform5.pulseWidth(0.5);
waveform5.begin(1, 368, masterWaveform);

waveform6.pulseWidth(0.5);
waveform6.begin(1, 283, masterWaveform);

waveform7.pulseWidth(0.5);
waveform7.begin(1, 283, masterWaveform);

waveform8.pulseWidth(0.5);
waveform8.begin(1, 283, masterWaveform);

waveform9.pulseWidth(0.5);
waveform9.begin(1, 283, masterWaveform);

waveform10.pulseWidth(0.5);
waveform10.begin(1, 283, masterWaveform);

waveform11.pulseWidth(0.5);
waveform11.begin(1, 283, masterWaveform);

waveform12.pulseWidth(0.5);
waveform12.begin(1, 283, masterWaveform);

waveform13.pulseWidth(0.5);
waveform13.begin(1, 283, masterWaveform);

waveform14.pulseWidth(0.5);
waveform14.begin(1, 283, masterWaveform);

waveform15.pulseWidth(0.5);
waveform15.begin(1, 283, masterWaveform);

waveform16.pulseWidth(0.5);
waveform16.begin(1, 283, masterWaveform);

// random walk initial conditions
for (int i = 0; i < 16; i++) {
// velocities: initial conditions in -pi : +pi
theta = M_PI * (random::uniform() * 2.0 - 1.0);
vx[i] = std::cos(theta);
vy[i] = std::sin(theta);
// positions: random in [0,L] x [0, L]
x[i] = random::uniform() * L;
y[i] = random::uniform() * L;

}
}

void process(float k1, float k2) override {



float knob_1 = k1;
float knob_2 = k2;
float pw;
float dL;

dL = knob_1 * L + 200;

v_var = v_0;

pw = (knob_2 - 0) * (0.9 - 0.1) / (1 - 0) + 0.1; // funciĂłn para recortar intervalo de 0.1 a 0.9

// loop to "walk" randomly
for (int i = 0; i < 16; i++) {
theta = M_PI * (random::uniform() * 2.0 - 1.0);

posx = std::cos(theta);
vx[i] = posx;

posy = std::sin(theta);
vy[i] = posy;

// Update new position
xn = x[i] + v_var * vx[i];
yin = y[i] + v_var * vy[i];

// periodic boundary conditions
if (xn < 100)
//xn += dL;
xn += 10;
else if (xn > dL)
//xn -= dL;
xn -= 10;

if (yin < 0.01)
yin += dL;
else if (yin > dL)
yin -= dL;
x[i] = xn;
y[i] = yin;

}

waveform1.pulseWidth(pw);
waveform2.pulseWidth(pw);
waveform3.pulseWidth(pw);
waveform4.pulseWidth(pw);
waveform5.pulseWidth(pw);
waveform6.pulseWidth(pw);
waveform7.pulseWidth(pw);
waveform8.pulseWidth(pw);

waveform9.pulseWidth(pw);
waveform10.pulseWidth(pw);
waveform11.pulseWidth(pw);
waveform12.pulseWidth(pw);
waveform13.pulseWidth(pw);
waveform14.pulseWidth(pw);
waveform15.pulseWidth(pw);
waveform16.pulseWidth(pw);

waveform1.frequency(x[0]);
waveform2.frequency(x[1]);
waveform3.frequency(x[2]);
waveform4.frequency(x[3]);
waveform5.frequency(x[4]);
waveform6.frequency(x[5]);
waveform7.frequency(x[6]);
waveform8.frequency(x[7]);
waveform9.frequency(x[8]);
waveform10.frequency(x[9]);
waveform11.frequency(x[10]);
waveform12.frequency(x[11]);
waveform13.frequency(x[12]);
waveform14.frequency(x[13]);
waveform15.frequency(x[14]);
waveform16.frequency(x[15]);


}

void processGraphAsBlock(TeensyBuffer& blockBuffer) override {

waveform1.update(&waveformBlock[0]);
waveform2.update(&waveformBlock[1]);
waveform3.update(&waveformBlock[2]);
waveform4.update(&waveformBlock[3]);
waveform5.update(&waveformBlock[4]);
waveform6.update(&waveformBlock[5]);
waveform7.update(&waveformBlock[6]);
waveform8.update(&waveformBlock[7]);
waveform9.update(&waveformBlock[8]);
waveform10.update(&waveformBlock[9]);
waveform11.update(&waveformBlock[10]);
waveform12.update(&waveformBlock[11]);
waveform13.update(&waveformBlock[12]);
waveform14.update(&waveformBlock[13]);
waveform15.update(&waveformBlock[14]);
waveform16.update(&waveformBlock[15]);

mixer1.update(&waveformBlock[0], &waveformBlock[1], &waveformBlock[2], &waveformBlock[3], &mixBlock[0]);
mixer2.update(&waveformBlock[4], &waveformBlock[5], &waveformBlock[6], &waveformBlock[7], &mixBlock[1]);
mixer3.update(&waveformBlock[8], &waveformBlock[9], &waveformBlock[10], &waveformBlock[11], &mixBlock[2]);
mixer4.update(&waveformBlock[12], &waveformBlock[13], &waveformBlock[14], &waveformBlock[15], &mixBlock[3]);

mixer5.update(&mixBlock[0], &mixBlock[1], &mixBlock[2], &mixBlock[3], &mixBlock[4]);
blockBuffer.pushBuffer(mixBlock[4].data, AUDIO_BLOCK_SAMPLES);
}

AudioStream& getStream() override {
return mixer5;
}
unsigned char getPort() override {
return 0;
}

private:

audio_block_t waveformBlock[16], mixBlock[5];

/* will be filled in */
// GUItool: begin automatically generated code
AudioSynthWaveform waveform12; //xy=517.75,725.75
AudioSynthWaveform waveform16; //xy=517.75,874.75
AudioSynthWaveform waveform11; //xy=518.75,689.75
AudioSynthWaveform waveform8; //xy=519.75,577.75
AudioSynthWaveform waveform15; //xy=518.75,838.75
AudioSynthWaveform waveform9; //xy=519.75,614.75
AudioSynthWaveform waveform10; //xy=519.75,652.75
AudioSynthWaveform waveform13; //xy=519.75,763.75
AudioSynthWaveform waveform7; //xy=520.75,541.75
AudioSynthWaveform waveform14; //xy=519.75,801.75
AudioSynthWaveform waveform4; //xy=521.75,427.75
AudioSynthWaveform waveform5; //xy=521.75,466.75
AudioSynthWaveform waveform6; //xy=521.75,504.75
AudioSynthWaveform waveform3; //xy=522.75,391.75
AudioSynthWaveform waveform1; //xy=523.75,316.75
AudioSynthWaveform waveform2; //xy=523.75,354.75
AudioMixer4 mixer2; //xy=713.75,528.75
AudioMixer4 mixer1; //xy=714.75,377.75
AudioMixer4 mixer3; //xy=716.75,664.75
AudioMixer4 mixer4; //xy=717.75,792.75
AudioMixer4 mixer5; //xy=961.75,589.75
//AudioOutputI2S i2s1; //xy=1227.75,604.75
// AudioConnection patchCord1;
// AudioConnection patchCord2;
// AudioConnection patchCord3;
// AudioConnection patchCord4;
// AudioConnection patchCord5;
// AudioConnection patchCord6;
// AudioConnection patchCord7;
// AudioConnection patchCord8;
// AudioConnection patchCord9;
// AudioConnection patchCord10;
// AudioConnection patchCord11;
// AudioConnection patchCord12;
// AudioConnection patchCord13;
// AudioConnection patchCord14;
// AudioConnection patchCord15;
// AudioConnection patchCord16;
// AudioConnection patchCord17;
// AudioConnection patchCord18;
// AudioConnection patchCord19;
// AudioConnection patchCord20;
//AudioConnection patchCord21(mixer5, 0, i2s1, 0);
//AudioControlSGTL5000 audioOut; //xy=1016.75,846.75
int L; //, i, t;
float theta, posx, posy, xn, yin;
float v_0, v_var;//pw = pulse width
float x[16], y[16], vx[16], vy[16]; // number depends on waveforms declared

};

REGISTER_PLUGIN(WalkingFilomena); // this is important, so that we can include the plugin in a bank

+ 49
- 0
src/noise-plethora/plugins/P_WhiteNoise.hpp View File

@@ -0,0 +1,49 @@
#pragma once
#include "NoisePlethoraPlugin.hpp"
#include <rack.hpp>
class WhiteNoise : public NoisePlethoraPlugin {
public:
WhiteNoise()
//: patchCord1(waveformMod1, 0, waveformMod2, 1),
//patchCord3(waveformMod2, 0, waveformMod1, 0)
{ }
~WhiteNoise() override {}
WhiteNoise(const WhiteNoise&) = delete;
WhiteNoise& operator=(const WhiteNoise&) = delete;
void init() override {
noise1.amplitude(1);
}
void process(float k1, float k2) override {
}
void processGraphAsBlock(TeensyBuffer& blockBuffer) override {
noise1.update(&noiseOut);
blockBuffer.pushBuffer(noiseOut.data, AUDIO_BLOCK_SAMPLES);
}
AudioStream& getStream() override {
return noise1;
}
unsigned char getPort() override {
return 0;
}
private:
TeensyBuffer buffer;
audio_block_t noiseOut;
AudioSynthNoiseWhite noise1;
};
REGISTER_PLUGIN(WhiteNoise);

+ 80
- 0
src/noise-plethora/plugins/P_XModRingSine.hpp View File

@@ -0,0 +1,80 @@

#pragma once

#include "NoisePlethoraPlugin.hpp"


class XModRingSine : public NoisePlethoraPlugin {

public:
XModRingSine()
// : patchCord1(sine_fm1, sine_fm2),
// patchCord2(sine_fm1, 0, multiply1, 0),
// patchCord3(sine_fm2, sine_fm1),
// patchCord4(sine_fm2, 0, multiply1, 1)
// // patchCord5(multiply1, 0, i2s1, 0)
{ }
~XModRingSine() override {}

// delete copy constructors
XModRingSine(const XModRingSine&) = delete;
XModRingSine& operator=(const XModRingSine&) = delete;


void init() override {
sine_fm1.frequency(1100);
sine_fm2.frequency(1367);

sine_fm1.amplitude(1);
sine_fm2.amplitude(1);
}
void process(float k1, float k2) override {
// Read CV and knobs,sum them and scale to 0-1.0
float knob_1 = k1;
float knob_2 = k2;

float pitch1 = pow(knob_1, 2);
float pitch2 = pow(knob_2, 2);


sine_fm1.frequency(100 + (pitch1 * 8000));
sine_fm2.frequency(60 + (pitch2 * 3000));


//Serial.print(knob_2*0.5);
}

void processGraphAsBlock(TeensyBuffer& blockBuffer) override {

sine_fm1.update(&sineModOut[1], &sineModOut[0]);
sine_fm2.update(&sineModOut[0], &sineModOut[1]);

multiply1.update(&sineModOut[0], &sineModOut[1], &multiplyOut);

blockBuffer.pushBuffer(multiplyOut.data, AUDIO_BLOCK_SAMPLES);
}


AudioStream& getStream() override {
return multiply1;
}

unsigned char getPort() override {
return 0;
}

private:

audio_block_t sineModOut[2] = {}, multiplyOut;

AudioSynthWaveformSineModulated sine_fm1; //xy=360,220
AudioSynthWaveformSineModulated sine_fm2; //xy=363,404
AudioEffectMultiply multiply1; //xy=569,311

// AudioConnection patchCord1;
// AudioConnection patchCord2;
// AudioConnection patchCord3;
// AudioConnection patchCord4;
};

REGISTER_PLUGIN(XModRingSine); // this is important, so that we can include the plugin in a bank

+ 137
- 0
src/noise-plethora/plugins/P_arrayOnTheRocks.hpp View File

@@ -0,0 +1,137 @@
#pragma once

#include "NoisePlethoraPlugin.hpp"



class arrayOnTheRocks: public NoisePlethoraPlugin {
public:

arrayOnTheRocks()
// : patchCord1(waveform1, 0, waveformMod1, 0)
{}
~arrayOnTheRocks() override {}

// delete copy constructors
arrayOnTheRocks(const arrayOnTheRocks&) = delete;
arrayOnTheRocks& operator=(const arrayOnTheRocks&) = delete;


void init() override {

//noise1.amplitude(1);

waveformMod1.arbitraryWaveform(myWaveform, 172.0);

waveformMod1.begin(1, 250, WAVEFORM_ARBITRARY);
waveform1.begin(1, 500, WAVEFORM_SINE);

/*test=random(-28000, 28000);

myWaveform = {0, 1895, 3748, 5545, 7278, 8934, 10506, 11984, 13362, 14634,
test, 16840, 17769, 18580, 19274, 19853, 20319, 20678, 20933, 21093,
21163, 21153, 21072, 20927, 20731, 20492, 20221, test, 19625, 19320,
19022, 18741, 18486, 18263, 18080, 17942, 17853, 17819, 17841, 17920,
18058, 18254, 18507, 18813, 19170, 19573, 20017, 20497, 21006, test,
test, test, test, 23753, 24294, 24816, 25314, 25781, 26212, 26604,
26953, test, test, 27718, 27876, 27986, test, test, test, 27989,
27899, 27782, 27644, 27490, test, test, test, test, test, 26582,
26487, 26423, test, test, test, test, test, 26812, 27012, 27248,
27514, 27808, 28122, test, 28787, test, 29451, 29762, 30045, 30293,
test, 30643, 30727, 30738, 30667, test, 30254, 29897, test, 28858,
28169, 27363, 26441, 25403, 24251, 22988, 21620, 20150, 18587, 16939,
15214, 13423, 11577, 9686, 7763, 5820, 3870, 1926, 0, -1895,
-3748, -5545, -7278, -8934,-10506, test,-13362,-14634,-15794,-16840,
-17769,-18580,-19274,-19853,-20319,-20678,-20933,-21093,-21163,-21153,
-21072,-20927,-test,-20492,-20221,-19929,-19625,-19320,-19022,-18741,
-test,-18263,-18080,-17942,-17853,-test,-17841,-17920,-18058,-18254,
-18507,-18813,-19170,-19573,-test,-20497,-21006,-21538,-22085,-22642,
-23200,-23753,-test,-test,-25314,-25781,-26212,-26604,-26953,-27256,
-27511,-27718,-test,-test,-test,-28068,-28047,-test,-27899,-27782,
-27644,-27490,-27326,-test,-26996,-26841,-26701,-26582,-26487,-test,
-26392,-26397,-26441,-26525,-test,-26812,-test,-27248,-27514,-27808,
-28122,-28451,-test,-test,-test,-29762,-test,-test,-test,-test,
-test,-test,-test,-test,-test,-test,-test,test,-28169,-27363,
-test,-test,-test,-test,-test,-test,-test,-test,-test,test,
-test, -test, -test, -test, -test, -test};*/
}

void process(float k1, float k2) override {
float knob_1 = k1;
float knob_2 = k2;

float pitch1 = pow(knob_1, 2);
// float pitch2 = pow(knob_2, 2);

waveformMod1.frequency(10 + (pitch1 * 10000));
waveform1.frequency(100 + (pitch1 * 500));

waveform1.amplitude(knob_2);
}

void processGraphAsBlock(TeensyBuffer& blockBuffer) override {
waveform1.update(&waveformBlock);
waveformMod1.update(&waveformBlock, nullptr, &waveformModBlock);

blockBuffer.pushBuffer(waveformModBlock.data, AUDIO_BLOCK_SAMPLES);
}

AudioStream& getStream() override {
return waveformMod1;
}
unsigned char getPort() override {
return 0;
}

private:

audio_block_t waveformBlock, waveformModBlock;

// GUItool: begin automatically generated code
AudioSynthWaveform waveform1; //xy=305.3333282470703,648.3333358764648
AudioSynthWaveformModulated waveformMod1; //xy=475.88893127441406,517.2221565246582
// AudioConnection patchCord1;

const int16_t test = 8622; // (int16_t)random(-28000, 28000);
const int16_t myWaveform[256] = {0, 1895, 3748, 5545, 7278, 8934, 10506, 11984, 13362, 14634,
test, 16840, 17769, 18580, 19274, 19853, 20319, 20678, 20933, 21093,
21163, 21153, 21072, 20927, 20731, 20492, 20221, test, 19625, 19320,
19022, 18741, 18486, 18263, 18080, 17942, 17853, 17819, 17841, 17920,
18058, 18254, 18507, 18813, 19170, 19573, 20017, 20497, 21006, test,
test, test, test, 23753, 24294, 24816, 25314, 25781, 26212, 26604,
26953, test, test, 27718, 27876, 27986, test, test, test, 27989,
27899, 27782, 27644, 27490, test, test, test, test, test, 26582,
26487, 26423, test, test, test, test, test, 26812, 27012, 27248,
27514, 27808, 28122, test, 28787, test, 29451, 29762, 30045, 30293,
test, 30643, 30727, 30738, 30667, test, 30254, 29897, test, 28858,
28169, 27363, 26441, 25403, 24251, 22988, 21620, 20150, 18587, 16939,
15214, 13423, 11577, 9686, 7763, 5820, 3870, 1926, 0, -1895,
-3748, -5545, -7278, -8934, -10506, test, -13362, -14634, -15794, -16840,
-17769, -18580, -19274, -19853, -20319, -20678, -20933, -21093, -21163, -21153,
-21072, -20927, (int16_t) - test, -20492, -20221, -19929, -19625, -19320, -19022, -18741,
(int16_t) - test, -18263, -18080, -17942, -17853, (int16_t) - test, -17841, -17920, -18058, -18254,
-18507, -18813, -19170, -19573, (int16_t) - test, -20497, -21006, -21538, -22085, -22642,
-23200, -23753, (int16_t) - test, (int16_t) - test, -25314, -25781, -26212, -26604, -26953, -27256,
-27511, -27718, (int16_t) - test, (int16_t) - test, (int16_t) - test, -28068, -28047, (int16_t) - test, -27899, -27782,
-27644, -27490, -27326, (int16_t) - test, -26996, -26841, -26701, -26582, -26487, (int16_t) - test,
-26392, -26397, -26441, -26525, (int16_t) - test, -26812, (int16_t) - test, -27248, -27514, -27808,
-28122, -28451, (int16_t) - test, (int16_t) - test, (int16_t) - test, -29762, (int16_t) - test, (int16_t) - test, (int16_t) - test, (int16_t) - test,
(int16_t) - test, (int16_t) - test, (int16_t) - test, (int16_t) - test, (int16_t) - test, (int16_t) - test, (int16_t) - test, test, -28169, -27363,
(int16_t) - test, (int16_t) - test, (int16_t) - test, (int16_t) - test, (int16_t) - test, (int16_t) - test, (int16_t) - test, (int16_t) - test, (int16_t) - test, test,
(int16_t) - test, (int16_t) - test, (int16_t) - test, (int16_t) - test, (int16_t) - test, (int16_t) - test
};

// int current_waveform = 0;

/* PREGUNTA A DIEGO ÂżEste sobra? */
//extern const int16_t myWaveform[256]; // defined in myWaveform.ino


};






REGISTER_PLUGIN(arrayOnTheRocks); // this is important, so that we can include the plugin in a bank

+ 108
- 0
src/noise-plethora/plugins/P_basurilla.hpp View File

@@ -0,0 +1,108 @@
#pragma once
#include "NoisePlethoraPlugin.hpp"
class basurilla : public NoisePlethoraPlugin {
public:
basurilla()
// : patchCord1(noise1, 0, multiply1, 0),
// patchCord2(noise1, 0, multiply2, 0),
// patchCord3(noise1, 0, multiply3, 0),
// patchCord6(waveform3, 0, multiply3, 1),
// patchCord7(waveform2, 0, multiply2, 1),
// patchCord8(waveform1, 0, multiply1, 1),
// patchCord9(multiply2, 0, mixer1, 1),
// patchCord10(multiply1, 0, mixer1, 0),
// patchCord11(multiply3, 0, mixer1, 2)
{}
~basurilla() override {}
basurilla(const basurilla&) = delete;
basurilla& operator=(const basurilla&) = delete;
void init() override {
waveform1.begin(1, 100, WAVEFORM_PULSE);
waveform1.offset(1);
waveform1.pulseWidth(0.5);
waveform2.begin(0, 77, WAVEFORM_PULSE);
waveform2.offset(1);
waveform2.pulseWidth(0.5);
waveform3.begin(0, 77, WAVEFORM_PULSE);
waveform3.offset(1);
waveform3.pulseWidth(0.5);
noise1.amplitude(1);
}
void process(float k1, float k2) override {
float knob_1 = k1;
float knob_2 = k2;
float pitch = pow(knob_1, 2);
waveform1.frequency(pitch * 100 + 10);
waveform1.pulseWidth(knob_2 * 0.95);
noise1.amplitude(knob_2 * -1 + 2);
waveform2.frequency(pitch * 0.1);
waveform2.pulseWidth(knob_2 * 0.5 + 0.2);
waveform3.frequency(pitch * 0.7 - 500);
waveform3.pulseWidth(knob_2 * 0.5);
}
void processGraphAsBlock(TeensyBuffer& blockBuffer) override {
noise1.update(&noiseOut);
// NOTE: 2,3 not actually used, as volume is 0 in init()!
// waveform3.update(&waveformOut[2]);
// waveform2.update(&waveformOut[1]);
waveform1.update(&waveformOut[0]);
multiply1.update(&noiseOut, &waveformOut[0], &multiplyOut[0]);
// NOTE: 2,3 not actually used, as volume is 0 in init()!
// multiply2.update(&noiseOut, &waveformOut[1], &multiplyOut[1]);
// multiply3.update(&noiseOut, &waveformOut[2], &multiplyOut[2]);
// NOTE: 2,3 not actually used, as volume is 0 in init()!
// mixer1.update(&multiplyOut[0], &multiplyOut[1], &multiplyOut[2], nullptr, &mixerOut);
blockBuffer.pushBuffer(multiplyOut[0].data, AUDIO_BLOCK_SAMPLES);
}
AudioStream& getStream() override {
return mixer1;
}
unsigned char getPort() override {
return 0;
}
private:
audio_block_t noiseOut, waveformOut[3] = {}, multiplyOut[3] = {};
AudioSynthNoiseWhite noise1; //xy=240,621
AudioSynthWaveform waveform3; //xy=507,823
AudioSynthWaveform waveform2; //xy=522,657
AudioSynthWaveform waveform1; //xy=545,475
AudioEffectMultiply multiply2; //xy=615,596
AudioEffectMultiply multiply1; //xy=634,340
AudioEffectMultiply multiply3; //xy=635,753
AudioMixer4 mixer1; //xy=863,612
// AudioConnection patchCord1;
// AudioConnection patchCord2;
// AudioConnection patchCord3;
// AudioConnection patchCord6;
// AudioConnection patchCord7;
// AudioConnection patchCord8;
// AudioConnection patchCord9;
// AudioConnection patchCord10;
// AudioConnection patchCord11;
//
};
REGISTER_PLUGIN(basurilla);

+ 206
- 0
src/noise-plethora/plugins/P_clusterSaw.hpp View File

@@ -0,0 +1,206 @@
#pragma once
#include "NoisePlethoraPlugin.hpp"
class clusterSaw : public NoisePlethoraPlugin {
public:
clusterSaw()
// : patchCord18(waveform16, 0, mixer4, 3),
// patchCord19(waveform14, 0, mixer4, 1),
// patchCord20(waveform15, 0, mixer4, 2),
// patchCord21(waveform13, 0, mixer4, 0),
// patchCord22(waveform8, 0, mixer2, 3),
// patchCord23(waveform6, 0, mixer2, 1),
// patchCord24(waveform7, 0, mixer2, 2),
// patchCord25(waveform12, 0, mixer3, 3),
// patchCord26(waveform5, 0, mixer2, 0),
// patchCord27(waveform10, 0, mixer3, 1),
// patchCord28(waveform11, 0, mixer3, 2),
// patchCord29(waveform9, 0, mixer3, 0),
// patchCord30(waveform4, 0, mixer1, 3),
// patchCord31(waveform2, 0, mixer1, 1),
// patchCord32(waveform3, 0, mixer1, 2),
// patchCord33(waveform1, 0, mixer1, 0),
// patchCord34(mixer4, 0, mixer5, 3),
// patchCord35(mixer2, 0, mixer5, 1),
// patchCord36(mixer1, 0, mixer5, 0),
// patchCord37(mixer3, 0, mixer5, 2)
{ }
~clusterSaw() override {}
clusterSaw(const clusterSaw&) = delete;
clusterSaw& operator=(const clusterSaw&) = delete;
void init() override {
mixer1.gain(0, 1);
mixer1.gain(1, 1);
mixer1.gain(2, 1);
mixer1.gain(3, 1);
mixer2.gain(0, 1);
mixer2.gain(1, 1);
mixer2.gain(2, 1);
mixer2.gain(3, 1);
mixer3.gain(0, 1);
mixer3.gain(1, 1);
mixer3.gain(2, 1);
mixer3.gain(3, 1);
mixer4.gain(0, 1);
mixer4.gain(1, 1);
mixer4.gain(2, 1);
mixer4.gain(3, 1);
mixer5.gain(0, 1);
mixer5.gain(1, 1);
mixer5.gain(2, 1);
mixer5.gain(3, 1);
WaveformType masterWaveform = WAVEFORM_SAWTOOTH;
float masterVolume = 0.25;
waveform1.begin(masterVolume, 0, masterWaveform);
waveform2.begin(masterVolume, 0, masterWaveform);
waveform3.begin(masterVolume, 0, masterWaveform);
waveform4.begin(masterVolume, 0, masterWaveform);
waveform5.begin(masterVolume, 0, masterWaveform);
waveform6.begin(masterVolume, 0, masterWaveform);
waveform7.begin(masterVolume, 0, masterWaveform);
waveform8.begin(masterVolume, 0, masterWaveform);
waveform9.begin(masterVolume, 0, masterWaveform);
waveform10.begin(masterVolume, 0, masterWaveform);
waveform11.begin(masterVolume, 0, masterWaveform);
waveform12.begin(masterVolume, 0, masterWaveform);
waveform13.begin(masterVolume, 0, masterWaveform);
waveform14.begin(masterVolume, 0, masterWaveform);
waveform15.begin(masterVolume, 0, masterWaveform);
waveform16.begin(masterVolume, 0, masterWaveform);
}
void process(float k1, float k2) override {
float knob_1 = k1;
float knob_2 = k2;
float pitch1 = pow(knob_1, 2);
float pitch2 = pow(knob_2, 2);
float multFactor = 1.01 + (pitch2 * 0.9);
float f1 = 20 + pitch1 * 1000;
float f2 = f1 * multFactor;
float f3 = f2 * multFactor;
float f4 = f3 * multFactor;
float f5 = f4 * multFactor;
float f6 = f5 * multFactor;
float f7 = f6 * multFactor;
float f8 = f7 * multFactor;
float f9 = f8 * multFactor;
float f10 = f9 * multFactor;
float f11 = f10 * multFactor;
float f12 = f11 * multFactor;
float f13 = f12 * multFactor;
float f14 = f13 * multFactor;
float f15 = f14 * multFactor;
float f16 = f15 * multFactor;
waveform1.frequency(f1);
waveform2.frequency(f2);
waveform3.frequency(f3);
waveform4.frequency(f4);
waveform5.frequency(f5);
waveform6.frequency(f6);
waveform7.frequency(f7);
waveform8.frequency(f8);
waveform9.frequency(f9);
waveform10.frequency(f10);
waveform11.frequency(f11);
waveform12.frequency(f12);
waveform13.frequency(f13);
waveform14.frequency(f14);
waveform15.frequency(f15);
waveform16.frequency(f16);
}
void processGraphAsBlock(TeensyBuffer& blockBuffer) override {
// update waveforms
// FM from single noise source
waveform1.update(nullptr, nullptr, &waveformOut[0]);
waveform2.update(nullptr, nullptr, &waveformOut[1]);
waveform3.update(nullptr, nullptr, &waveformOut[2]);
waveform4.update(nullptr, nullptr, &waveformOut[3]);
waveform5.update(nullptr, nullptr, &waveformOut[4]);
waveform6.update(nullptr, nullptr, &waveformOut[5]);
waveform7.update(nullptr, nullptr, &waveformOut[6]);
waveform8.update(nullptr, nullptr, &waveformOut[7]);
waveform9.update(nullptr, nullptr, &waveformOut[8]);
waveform10.update(nullptr, nullptr, &waveformOut[9]);
waveform11.update(nullptr, nullptr, &waveformOut[10]);
waveform12.update(nullptr, nullptr, &waveformOut[11]);
waveform13.update(nullptr, nullptr, &waveformOut[12]);
waveform14.update(nullptr, nullptr, &waveformOut[13]);
waveform15.update(nullptr, nullptr, &waveformOut[14]);
waveform16.update(nullptr, nullptr, &waveformOut[15]);
// update mixers
mixer1.update(&waveformOut[0], &waveformOut[1], &waveformOut[2], &waveformOut[3], &mixerOut[0]);
mixer2.update(&waveformOut[4], &waveformOut[5], &waveformOut[6], &waveformOut[7], &mixerOut[1]);
mixer3.update(&waveformOut[8], &waveformOut[9], &waveformOut[10], &waveformOut[11], &mixerOut[2]);
mixer4.update(&waveformOut[12], &waveformOut[13], &waveformOut[14], &waveformOut[15], &mixerOut[3]);
// mixer of mixers
mixer5.update(&mixerOut[0], &mixerOut[1], &mixerOut[2], &mixerOut[3], &mixerOut[4]);
blockBuffer.pushBuffer(mixerOut[4].data, AUDIO_BLOCK_SAMPLES);
}
AudioStream& getStream() override {
return mixer5;
}
unsigned char getPort() override {
return 0;
}
private:
audio_block_t waveformOut[16] = {}, mixerOut[5] = {};
AudioSynthWaveformModulated waveform16; //xy=360.00000381469727,1486.0000076293945
AudioSynthWaveformModulated waveform14; //xy=362.00000381469727,1381.0000076293945
AudioSynthWaveformModulated waveform15; //xy=362.00000381469727,1426.0000076293945
AudioSynthWaveformModulated waveform13; //xy=363.00000381469727,1339.0000076293945
AudioSynthWaveformModulated waveform8; //xy=370.00000381469727,1066.0000076293945
AudioSynthWaveformModulated waveform6; //xy=372.00000381469727,961.0000076293945
AudioSynthWaveformModulated waveform7; //xy=372.00000381469727,1006.0000076293945
AudioSynthWaveformModulated waveform12; //xy=371.00000381469727,1277.0000076293945
AudioSynthWaveformModulated waveform5; //xy=373.00000381469727,919.0000076293945
AudioSynthWaveformModulated waveform10; //xy=373.00000381469727,1172.0000076293945
AudioSynthWaveformModulated waveform11; //xy=373.00000381469727,1217.0000076293945
AudioSynthWaveformModulated waveform9; //xy=374.00000381469727,1130.0000076293945
AudioSynthWaveformModulated waveform4; //xy=378.00000381469727,851.0000076293945
AudioSynthWaveformModulated waveform2; //xy=380.00000381469727,746.0000076293945
AudioSynthWaveformModulated waveform3; //xy=380.00000381469727,791.0000076293945
AudioSynthWaveformModulated waveform1; //xy=381.00000381469727,703.0000076293945
AudioMixer4 mixer4; //xy=546.0000038146973,1408.0000381469727
AudioMixer4 mixer2; //xy=554.9999923706055,984.0000381469727
AudioMixer4 mixer1; //xy=556.9999885559082,771.0000076293945
AudioMixer4 mixer3; //xy=557.0000114440918,1196.0000228881836
AudioMixer4 mixer5; //xy=755.0000267028809,1082.9999923706055
// AudioConnection patchCord18;
// AudioConnection patchCord19;
// AudioConnection patchCord20;
// AudioConnection patchCord21;
// AudioConnection patchCord22;
// AudioConnection patchCord23;
// AudioConnection patchCord24;
// AudioConnection patchCord25;
// AudioConnection patchCord26;
// AudioConnection patchCord27;
// AudioConnection patchCord28;
// AudioConnection patchCord29;
// AudioConnection patchCord30;
// AudioConnection patchCord31;
// AudioConnection patchCord32;
// AudioConnection patchCord33;
// AudioConnection patchCord34;
// AudioConnection patchCord35;
// AudioConnection patchCord36;
// AudioConnection patchCord37;
};
REGISTER_PLUGIN(clusterSaw);

+ 135
- 0
src/noise-plethora/plugins/P_crCluster2.hpp View File

@@ -0,0 +1,135 @@
#pragma once
#include "NoisePlethoraPlugin.hpp"
class crCluster2 : public NoisePlethoraPlugin {
public:
crCluster2() // :
// patchCord1(modulator, 0, waveform1, 0),
// patchCord2(modulator, 0, waveform2, 0),
// patchCord3(modulator, 0, waveform3, 0),
// patchCord4(modulator, 0, waveform4, 0),
// patchCord5(modulator, 0, waveform5, 0),
// patchCord6(modulator, 0, waveform6, 0),
// patchCord7(waveform6, 0, mixer2, 1),
// patchCord8(waveform5, 0, mixer2, 0),
// patchCord9(waveform4, 0, mixer1, 3),
// patchCord10(waveform2, 0, mixer1, 1),
// patchCord11(waveform3, 0, mixer1, 2),
// patchCord12(waveform1, 0, mixer1, 0),
// patchCord13(mixer2, 0, mixer5, 1),
// patchCord14(mixer1, 0, mixer5, 0)
{ }
~crCluster2() override {}
crCluster2(const crCluster2&) = delete;
crCluster2& operator=(const crCluster2&) = delete;
void init() override {
mixer1.gain(0, 1);
mixer1.gain(1, 1);
mixer1.gain(2, 1);
mixer1.gain(3, 1);
mixer2.gain(0, 1);
mixer2.gain(1, 1);
mixer2.gain(2, 1);
mixer2.gain(3, 1);
mixer5.gain(0, 1);
mixer5.gain(1, 1);
mixer5.gain(2, 1);
mixer5.gain(3, 1);
int masterWaveform = WAVEFORM_SINE;
float masterVolume = 0.2;
waveform1.begin(masterVolume, 794, masterWaveform);
waveform2.begin(masterVolume, 647, masterWaveform);
waveform3.begin(masterVolume, 524, masterWaveform);
waveform4.begin(masterVolume, 444, masterWaveform);
waveform5.begin(masterVolume, 368, masterWaveform);
waveform6.begin(masterVolume, 283, masterWaveform);
modulator.begin(1, 1000, WAVEFORM_SINE);
}
void process(float k1, float k2) override {
float knob_1 = k1;
float knob_2 = k2;
float pitch1 = pow(knob_1, 2);
float f1 = 40 + pitch1 * 8000;
float f2 = f1 * 1.227;
float f3 = f2 * 1.24;
float f4 = f3 * 1.17;
float f5 = f4 * 1.2;
float f6 = f5 * 1.3;
modulator.amplitude(knob_2);
modulator.frequency(f1 * 2.7);
waveform1.frequency(f1);
waveform2.frequency(f2);
waveform3.frequency(f3);
waveform4.frequency(f4);
waveform5.frequency(f5);
waveform6.frequency(f6);
}
void processGraphAsBlock(TeensyBuffer& blockBuffer) override {
modulator.update(&waveformOut);
// FM from modulator for the 6 oscillators
waveform1.update(&waveformOut, nullptr, &waveformModOut[0]);
waveform2.update(&waveformOut, nullptr, &waveformModOut[1]);
waveform3.update(&waveformOut, nullptr, &waveformModOut[2]);
waveform4.update(&waveformOut, nullptr, &waveformModOut[3]);
waveform5.update(&waveformOut, nullptr, &waveformModOut[4]);
waveform6.update(&waveformOut, nullptr, &waveformModOut[5]);
mixer1.update(&waveformModOut[0], &waveformModOut[1], &waveformModOut[2], &waveformModOut[3], &mixerOut[0]);
mixer2.update(&waveformModOut[4], &waveformModOut[5], nullptr, nullptr, &mixerOut[1]);
mixer5.update(&mixerOut[0], &mixerOut[1], nullptr, nullptr, &mixerOut[2]);
blockBuffer.pushBuffer(mixerOut[2].data, AUDIO_BLOCK_SAMPLES);
}
AudioStream& getStream() override {
return mixer5;
}
unsigned char getPort() override {
return 0;
}
private:
audio_block_t waveformOut, waveformModOut[6] = {}, mixerOut[3] = {};
AudioSynthWaveform modulator; //xy=135.88888549804688,405.55555725097656
AudioSynthWaveformModulated waveform6; //xy=453.8888854980469,543.6666889190674
AudioSynthWaveformModulated waveform5; //xy=454.8888854980469,501.6666889190674
AudioSynthWaveformModulated waveform4; //xy=459.8888854980469,433.6666889190674
AudioSynthWaveformModulated waveform2; //xy=461.8888854980469,328.6666889190674
AudioSynthWaveformModulated waveform3; //xy=461.8888854980469,373.6666889190674
AudioSynthWaveformModulated waveform1; //xy=462.8888854980469,285.6666889190674
AudioMixer4 mixer2; //xy=678.8888778686523,495.66669845581055
AudioMixer4 mixer1; //xy=679.8888854980469,377.6666889190674
AudioMixer4 mixer5; //xy=883.8888854980469,446.66675567626953
// AudioConnection patchCord1;
// AudioConnection patchCord2;
// AudioConnection patchCord3;
// AudioConnection patchCord4;
// AudioConnection patchCord5;
// AudioConnection patchCord6;
// AudioConnection patchCord7;
// AudioConnection patchCord8;
// AudioConnection patchCord9;
// AudioConnection patchCord10;
// AudioConnection patchCord11;
// AudioConnection patchCord12;
// AudioConnection patchCord13;
// AudioConnection patchCord14;
};
REGISTER_PLUGIN(crCluster2);

+ 146
- 0
src/noise-plethora/plugins/P_existencelsPain.hpp View File

@@ -0,0 +1,146 @@
#pragma once

#include "NoisePlethoraPlugin.hpp"

class existencelsPain : public NoisePlethoraPlugin {

public:

existencelsPain()
// : patchCord1(waveform1, 0, filter1, 0)
// , patchCord2(waveform1, 0, filter2, 0)
// , patchCord3(waveform1, 0, filter3, 0)
// , patchCord4(waveform1, 0, filter4, 0)
// , patchCord5(waveformMod1, 0, filter1, 1)
// , patchCord6(waveformMod2, 0, filter2, 1)
// , patchCord7(waveformMod4, 0, filter4, 1)
// , patchCord8(waveformMod3, 0, filter3, 1)
// , patchCord9(filter1, 1, mixer1, 0)
// , patchCord10(filter2, 1, mixer1, 1)
// , patchCord11(filter3, 1, mixer1, 2)
// , patchCord12(filter4, 1, mixer1, 3)
{ }

~existencelsPain() override {}

// delete copy constructors
existencelsPain(const existencelsPain&) = delete;
existencelsPain& operator=(const existencelsPain&) = delete;

void init() override {

//noise1.amplitude(1);

mixer1.gain(0, 0.8);
mixer1.gain(1, 0.8);
mixer1.gain(2, 0.8);
mixer1.gain(3, 0.8);


waveformMod1.begin(1, 11, WAVEFORM_TRIANGLE);
waveformMod2.begin(1, 70, WAVEFORM_TRIANGLE);
waveformMod3.begin(1, 23, WAVEFORM_TRIANGLE);
waveformMod4.begin(1, 0.01, WAVEFORM_TRIANGLE);

waveform1.begin(1, 5, WAVEFORM_SAMPLE_HOLD);
//waveform1.pulseWidth(0.1);

filter1.resonance(5);
filter1.octaveControl(7);

filter2.resonance(5);
filter2.octaveControl(7);

filter3.resonance(5);
filter3.octaveControl(7);

filter4.resonance(5);
filter4.octaveControl(7);
}

void process(float k1, float k2) override {


float knob_1 = k1;
float knob_2 = k2;

float pitch1 = pow(knob_1, 2);
// float pitch2 = pow(knob_2, 2);


waveform1.frequency(50 + (pitch1 * 5000));

float octaves = knob_2 * 3 + 0.3;

/*filter1.resonance(resonanceLevel);
filter2.resonance(resonanceLevel);
filter3.resonance(resonanceLevel);
filter4.resonance(resonanceLevel);*/

filter1.octaveControl(octaves);
filter2.octaveControl(octaves);
filter3.octaveControl(octaves);
filter4.octaveControl(octaves);
}

void processGraphAsBlock(TeensyBuffer& blockBuffer) override {
// waveform to filter
waveform1.update(&waveformOut);

waveformMod1.update(nullptr, nullptr, &waveformModOut[0]);
waveformMod2.update(nullptr, nullptr, &waveformModOut[1]);
waveformMod3.update(nullptr, nullptr, &waveformModOut[2]);
waveformMod4.update(nullptr, nullptr, &waveformModOut[3]);

// SVF needs LP, BP and HP (even if we only use one)
filter1.update(&waveformOut, &waveformModOut[0], &filterOutLP[0], &filterOutBP[0], &filterOutHP[0]);
filter2.update(&waveformOut, &waveformModOut[1], &filterOutLP[1], &filterOutBP[1], &filterOutHP[1]);
filter3.update(&waveformOut, &waveformModOut[2], &filterOutLP[2], &filterOutBP[2], &filterOutHP[2]);
filter4.update(&waveformOut, &waveformModOut[3], &filterOutLP[3], &filterOutBP[3], &filterOutHP[3]);

// sum up
mixer1.update(&filterOutBP[0], &filterOutBP[1], &filterOutBP[2], &filterOutBP[3], &mixerOut);

blockBuffer.pushBuffer(mixerOut.data, AUDIO_BLOCK_SAMPLES);
}

AudioStream& getStream() override {
return mixer1;
}
unsigned char getPort() override {
return 0;
}

private:

audio_block_t waveformModOut[4];
audio_block_t filterOutLP[4], filterOutBP[4], filterOutHP[4];
audio_block_t waveformOut, mixerOut;

// GUItool: begin automatically generated code
AudioSynthWaveform waveform1; //xy=283,566
AudioSynthWaveformModulated waveformMod1; //xy=363.888916015625,321.2221794128418
AudioSynthWaveformModulated waveformMod2; //xy=368,380.3332633972168
AudioSynthWaveformModulated waveformMod4; //xy=374,689.3332633972168
AudioSynthWaveformModulated waveformMod3; //xy=378,638.3332633972168
AudioFilterStateVariable filter1; //xy=578.888916015625,420.8889274597168
AudioFilterStateVariable filter2; //xy=579,486.0000114440918
AudioFilterStateVariable filter3; //xy=581,549.0000114440918
AudioFilterStateVariable filter4; //xy=581,614.0000114440918
AudioMixer4 mixer1; //xy=752,520.0000114440918
// AudioConnection patchCord1;
// AudioConnection patchCord2;
// AudioConnection patchCord3;
// AudioConnection patchCord4;
// AudioConnection patchCord5;
// AudioConnection patchCord6;
// AudioConnection patchCord7;
// AudioConnection patchCord8;
// AudioConnection patchCord9;
// AudioConnection patchCord10;
// AudioConnection patchCord11;
// AudioConnection patchCord12;

};

REGISTER_PLUGIN(existencelsPain); // this is important, so that we can include the plugin in a bank

+ 91
- 0
src/noise-plethora/plugins/P_grainGlitch.hpp View File

@@ -0,0 +1,91 @@
#pragma once

#include "NoisePlethoraPlugin.hpp"
#define GRANULAR_MEMORY_SIZE 12800 // enough for 290 ms at 44.1 kHz

class grainGlitch : public NoisePlethoraPlugin {

public:

grainGlitch()
// : patchCord1(granular1, 0, waveformMod1, 0),
// patchCord2(granular1, 0, combine1, 0),
// patchCord3(waveformMod1, granular1),
// patchCord4(waveformMod1, 0, combine1, 1)
{ }

~grainGlitch() override {}

grainGlitch(const grainGlitch&) = delete;
grainGlitch& operator=(const grainGlitch&) = delete;

void init() override {

// combine1.AudioEffectDigitalCombine::XOR;


waveformMod1.begin(1, 1000, WAVEFORM_SQUARE);

// the Granular effect requires memory to operate
granular1.begin(granularMemory, GRANULAR_MEMORY_SIZE);

float msec = 150.0;
granular1.beginFreeze(msec);

}

void process(float k1, float k2) override {
float knob_1 = k1;
float knob_2 = k2;

float pitch1 = pow(knob_1, 2);

waveformMod1.frequencyModulation(knob_2 * 2);

float msec2 = 25.0 + (knob_2 * 75.0);

granular1.beginPitchShift(msec2);
waveformMod1.frequency(pitch1 * 5000 + 500);

float ratio;

ratio = powf(2.0, knob_2 * 6.0 - 3.0);
granular1.setSpeed(ratio);
}

void processGraphAsBlock(TeensyBuffer& blockBuffer) override {

granular1.update(&waveformMod1Out, &granularOut);

waveformMod1.update(&granularOut, nullptr, &waveformMod1Out);

combine1.update(&granularOut, &waveformMod1Out, &combine1Out);

blockBuffer.pushBuffer(combine1Out.data, AUDIO_BLOCK_SAMPLES);
}

AudioStream& getStream() override {
return combine1;
}
unsigned char getPort() override {
return 0;
}

private:
AudioEffectGranular granular1; //xy=885.75,359.9999985694885
AudioSynthWaveformModulated waveformMod1; //xy=889.75,480.74999871477485
AudioEffectDigitalCombine combine1; //xy=1111.7500114440918,295.74999809265137
// AudioConnection patchCord1;
// AudioConnection patchCord2;
// AudioConnection patchCord3;
// AudioConnection patchCord4;

int16_t granularMemory[GRANULAR_MEMORY_SIZE];


audio_block_t granularOut;
audio_block_t waveformMod1Out;
audio_block_t combine1Out;
};

REGISTER_PLUGIN(grainGlitch);

+ 78
- 0
src/noise-plethora/plugins/P_grainGlitchII.hpp View File

@@ -0,0 +1,78 @@
#pragma once

#include "NoisePlethoraPlugin.hpp"
#define GRANULAR_MEMORY_SIZE 12800 // enough for 290 ms at 44.1 kHz

class grainGlitchII : public NoisePlethoraPlugin {

public:

grainGlitchII()
// : patchCord1(granular1, 0, waveformMod1, 0),
// patchCord2(granular1, amp1),
// patchCord3(waveformMod1, granular1)
{ }

~grainGlitchII() override {}

grainGlitchII(const grainGlitchII&) = delete;
grainGlitchII& operator=(const grainGlitchII&) = delete;

void init() override {

float msec = 150.0;
waveformMod1.begin(1, 1000, WAVEFORM_SQUARE);
amp1.gain(32000);
// the Granular effect requires memory to operate
granular1.begin(granularMemory, GRANULAR_MEMORY_SIZE);
granular1.beginFreeze(msec);
}

void process(float k1, float k2) override {
float knob_1 = k1;
float knob_2 = k2;

float pitch1 = pow(knob_1, 2);
float msec2 = 25.0 + (knob_2 * 75.0);
float ratio;

waveformMod1.frequencyModulation(knob_2 * 2);
granular1.beginPitchShift(msec2);

waveformMod1.frequency(pitch1 * 5000 + 500);
ratio = powf(2.0, knob_2 * 6.0 - 3.0); // 0.125 to 8.0 -- uncomment for far too much range!
granular1.setSpeed(ratio);

}

void processGraphAsBlock(TeensyBuffer& blockBuffer) override {

granular1.update(&waveformMod1Out, &granularOut);

waveformMod1.update(&granularOut, nullptr, &waveformMod1Out);

amp1.update(&granularOut);

blockBuffer.pushBuffer(granularOut.data, AUDIO_BLOCK_SAMPLES);
}

AudioStream& getStream() override {
return amp1;
}
unsigned char getPort() override {
return 0;
}

private:
AudioEffectGranular granular1; //xy=369,297
AudioSynthWaveformModulated waveformMod1; //xy=376,406
AudioAmplifier amp1; //xy=602,359
// AudioConnection patchCord1;
// AudioConnection patchCord2;
// AudioConnection patchCord3;
int16_t granularMemory[GRANULAR_MEMORY_SIZE];

audio_block_t granularOut, waveformMod1Out;
};

REGISTER_PLUGIN(grainGlitchII);

+ 74
- 0
src/noise-plethora/plugins/P_grainGlitchIII.hpp View File

@@ -0,0 +1,74 @@
#pragma once

#include "NoisePlethoraPlugin.hpp"
#define GRANULAR_MEMORY_SIZE 12800

class grainGlitchIII : public NoisePlethoraPlugin {

public:

grainGlitchIII()
//:patchCord2(granular1, 0, waveformMod1, 0),
// patchCord3(waveformMod1, granular1)
{ }

~grainGlitchIII() override {}

grainGlitchIII(const grainGlitchIII&) = delete;
grainGlitchIII& operator=(const grainGlitchIII&) = delete;

void init() override {
float msec = 150.0;

waveformMod1.begin(1, 1000, WAVEFORM_SAWTOOTH);
// the Granular effect requires memory to operate
granular1.begin(granularMemory, GRANULAR_MEMORY_SIZE);
granular1.beginFreeze(msec);

}

void process(float k1, float k2) override {
float knob_1 = k1;
float knob_2 = k2;

float pitch1 = pow(knob_1, 2);
// float pitch2 = pow(knob_2, 2);
float msec2 = 25.0 + (knob_2 * 55.0);
float ratio;


waveformMod1.frequencyModulation(knob_2 * 2);
granular1.beginPitchShift(msec2);
waveformMod1.frequency(pitch1 * 5000 + 400);
ratio = powf(2.0, knob_2 * 6.0 - 3.0);
granular1.setSpeed(ratio);

}

void processGraphAsBlock(TeensyBuffer& blockBuffer) override {
granular1.update(&waveformMod1Previous, &granularOut);

waveformMod1.update(&granularOut, nullptr, &waveformMod1Previous);

blockBuffer.pushBuffer(granularOut.data, AUDIO_BLOCK_SAMPLES);
}

AudioStream& getStream() override {
return granular1;
}
unsigned char getPort() override {
return 0;
}

private:
AudioEffectGranular granular1; //xy=885.75,359.9999985694885
AudioSynthWaveformModulated waveformMod1; //xy=889.75,480.74999871477485
//AudioConnection patchCord2;
//AudioConnection patchCord3;
int16_t granularMemory[GRANULAR_MEMORY_SIZE];

audio_block_t granularOut;
audio_block_t waveformMod1Previous;
};

REGISTER_PLUGIN(grainGlitchIII);

+ 249
- 0
src/noise-plethora/plugins/P_partialCluster.hpp View File

@@ -0,0 +1,249 @@
#pragma once

#include "NoisePlethoraPlugin.hpp"

class partialCluster : public NoisePlethoraPlugin {

public:

partialCluster()
// :
// patchCord1(noise1, 0, waveform1, 0),
// patchCord2(noise1, 0, waveform2, 0),
// patchCord3(noise1, 0, waveform3, 0),
// patchCord4(noise1, 0, waveform4, 0),
// patchCord5(noise1, 0, waveform5, 0),
// patchCord6(noise1, 0, waveform6, 0),
// patchCord7(noise1, 0, waveform7, 0),
// patchCord8(noise1, 0, waveform8, 0),
// patchCord9(noise1, 0, waveform9, 0),
// patchCord10(noise1, 0, waveform10, 0),
// patchCord11(noise1, 0, waveform11, 0),
// patchCord12(noise1, 0, waveform12, 0),
// patchCord13(noise1, 0, waveform13, 0),
// patchCord14(noise1, 0, waveform14, 0),
// patchCord15(noise1, 0, waveform15, 0),
// patchCord16(noise1, 0, waveform16, 0),
// patchCord17(waveform16, 0, mixer4, 3),
// patchCord18(waveform14, 0, mixer4, 1),
// patchCord19(waveform15, 0, mixer4, 2),
// patchCord20(waveform13, 0, mixer4, 0),
// patchCord21(waveform8, 0, mixer2, 3),
// patchCord22(waveform6, 0, mixer2, 1),
// patchCord23(waveform7, 0, mixer2, 2),
// patchCord24(waveform12, 0, mixer3, 3),
// patchCord25(waveform5, 0, mixer2, 0),
// patchCord26(waveform10, 0, mixer3, 1),
// patchCord27(waveform11, 0, mixer3, 2),
// patchCord28(waveform9, 0, mixer3, 0),
// patchCord29(waveform4, 0, mixer1, 3),
// patchCord30(waveform2, 0, mixer1, 1),
// patchCord31(waveform3, 0, mixer1, 2),
// patchCord32(waveform1, 0, mixer1, 0),
// patchCord33(mixer4, 0, mixer5, 3),
// patchCord34(mixer3, 0, mixer5, 2),
// patchCord35(mixer2, 0, mixer5, 1),
// patchCord36(mixer1, 0, mixer5, 0)
{ }

~partialCluster() override {}

partialCluster(const partialCluster&) = delete;
partialCluster& operator=(const partialCluster&) = delete;

void init() override {
mixer1.gain(0, 1);
mixer1.gain(1, 1);
mixer1.gain(2, 1);
mixer1.gain(3, 1);
mixer2.gain(0, 1);
mixer2.gain(1, 1);
mixer2.gain(2, 1);
mixer2.gain(3, 1);
mixer3.gain(0, 1);
mixer3.gain(1, 1);
mixer3.gain(2, 1);
mixer3.gain(3, 1);
mixer4.gain(0, 1);
mixer4.gain(1, 1);
mixer4.gain(2, 1);
mixer4.gain(3, 1);
mixer5.gain(0, 1);
mixer5.gain(1, 1);
mixer5.gain(2, 1);
mixer5.gain(3, 1);

int masterWaveform = WAVEFORM_SAWTOOTH;
float masterVolume = 0.25;

waveform1.begin(masterVolume, 794, masterWaveform);
waveform2.begin(masterVolume, 647, masterWaveform);
waveform3.begin(masterVolume, 524, masterWaveform);
waveform4.begin(masterVolume, 444, masterWaveform);
waveform5.begin(masterVolume, 368, masterWaveform);
waveform6.begin(masterVolume, 283, masterWaveform);
waveform7.begin(masterVolume, 283, masterWaveform);
waveform8.begin(masterVolume, 283, masterWaveform);
waveform9.begin(masterVolume, 283, masterWaveform);
waveform10.begin(masterVolume, 283, masterWaveform);
waveform11.begin(masterVolume, 283, masterWaveform);
waveform12.begin(masterVolume, 283, masterWaveform);
waveform13.begin(masterVolume, 283, masterWaveform);
waveform14.begin(masterVolume, 283, masterWaveform);
waveform15.begin(masterVolume, 283, masterWaveform);
waveform16.begin(masterVolume, 283, masterWaveform);

}

void process(float k1, float k2) override {
float knob_1 = k1;
float knob_2 = k2;
float pitch1 = pow(knob_1, 2);
// float pitch2 = pow(knob_2, 2);

float spread = knob_2 * 1.1 + 1.01;

float fundamental = 50 + pitch1 * 1000;

float f1 = 1;
float f2 = f1 * spread;
float f3 = f2 * spread;
float f4 = f3 * spread;
float f5 = f4 * spread;
float f6 = f5 * spread;
float f7 = f6 * spread;
float f8 = f7 * spread;
float f9 = f8 * spread;
float f10 = f9 * spread;
float f11 = f10 * spread;
float f12 = f11 * spread;
float f13 = f12 * spread;
float f14 = f13 * spread;
float f15 = f14 * spread;
float f16 = f15 * spread;


waveform1.frequency(fundamental);
waveform2.frequency(f2 * fundamental);
waveform3.frequency(f3 * fundamental);
waveform4.frequency(f4 * fundamental);
waveform5.frequency(f5 * fundamental);
waveform6.frequency(f6 * fundamental);
waveform7.frequency(f7 * fundamental);
waveform8.frequency(f8 * fundamental);
waveform9.frequency(f9 * fundamental);
waveform10.frequency(f10 * fundamental);
waveform11.frequency(f11 * fundamental);
waveform12.frequency(f12 * fundamental);
waveform13.frequency(f13 * fundamental);
waveform14.frequency(f14 * fundamental);
waveform15.frequency(f15 * fundamental);
waveform16.frequency(f16 * fundamental);

}

void processGraphAsBlock(TeensyBuffer& blockBuffer) override {

noise1.update(&noiseOut);

// FM from single noise source
waveform1.update(&noiseOut, nullptr, &waveformOut[0]);
waveform2.update(&noiseOut, nullptr, &waveformOut[1]);
waveform3.update(&noiseOut, nullptr, &waveformOut[2]);
waveform4.update(&noiseOut, nullptr, &waveformOut[3]);
waveform5.update(&noiseOut, nullptr, &waveformOut[4]);
waveform6.update(&noiseOut, nullptr, &waveformOut[5]);
waveform7.update(&noiseOut, nullptr, &waveformOut[6]);
waveform8.update(&noiseOut, nullptr, &waveformOut[7]);
waveform9.update(&noiseOut, nullptr, &waveformOut[8]);
waveform10.update(&noiseOut, nullptr, &waveformOut[9]);
waveform11.update(&noiseOut, nullptr, &waveformOut[10]);
waveform12.update(&noiseOut, nullptr, &waveformOut[11]);
waveform13.update(&noiseOut, nullptr, &waveformOut[12]);
waveform14.update(&noiseOut, nullptr, &waveformOut[13]);
waveform15.update(&noiseOut, nullptr, &waveformOut[14]);
waveform16.update(&noiseOut, nullptr, &waveformOut[15]);

mixer1.update(&waveformOut[0], &waveformOut[1], &waveformOut[2], &waveformOut[3], &mixerOut[0]);
mixer2.update(&waveformOut[4], &waveformOut[5], &waveformOut[6], &waveformOut[7], &mixerOut[1]);
mixer3.update(&waveformOut[8], &waveformOut[9], &waveformOut[10], &waveformOut[11], &mixerOut[2]);
mixer4.update(&waveformOut[12], &waveformOut[13], &waveformOut[14], &waveformOut[15], &mixerOut[3]);

mixer5.update(&mixerOut[0], &mixerOut[1], &mixerOut[2], &mixerOut[3], &mixerOut[4]);

blockBuffer.pushBuffer(mixerOut[4].data, AUDIO_BLOCK_SAMPLES);
}

AudioStream& getStream() override {
return mixer5;
}
unsigned char getPort() override {
return 0;
}

private:

audio_block_t noiseOut, waveformOut[16] = {}, mixerOut[5] = {};

AudioSynthNoiseWhite noise1; //xy=296.75,791.75
AudioSynthWaveformModulated waveform16; //xy=581.75,1167.5
AudioSynthWaveformModulated waveform14; //xy=583.75,1062.5
AudioSynthWaveformModulated waveform15; //xy=583.75,1107.5
AudioSynthWaveformModulated waveform13; //xy=584.75,1020
AudioSynthWaveformModulated waveform8; //xy=591.75,747.5
AudioSynthWaveformModulated waveform6; //xy=593.75,642.5
AudioSynthWaveformModulated waveform7; //xy=593.75,687.5
AudioSynthWaveformModulated waveform12; //xy=592.75,958.5
AudioSynthWaveformModulated waveform5; //xy=594.75,600
AudioSynthWaveformModulated waveform10; //xy=594.75,853.5
AudioSynthWaveformModulated waveform11; //xy=594.75,898.5
AudioSynthWaveformModulated waveform9; //xy=595.75,811
AudioSynthWaveformModulated waveform4; //xy=599.75,532.25
AudioSynthWaveformModulated waveform2; //xy=601.75,427.25
AudioSynthWaveformModulated waveform3; //xy=601.75,472.25
AudioSynthWaveformModulated waveform1; //xy=602.75,384.75
AudioMixer4 mixer4; //xy=801.75,1111.25
AudioMixer4 mixer3; //xy=812.75,902.25
AudioMixer4 mixer2; //xy=818.75,691.25
AudioMixer4 mixer1; //xy=819.75,476
AudioMixer4 mixer5; //xy=1066.75,688
// AudioConnection patchCord1;
// AudioConnection patchCord2;
// AudioConnection patchCord3;
// AudioConnection patchCord4;
// AudioConnection patchCord5;
// AudioConnection patchCord6;
// AudioConnection patchCord7;
// AudioConnection patchCord8;
// AudioConnection patchCord9;
// AudioConnection patchCord10;
// AudioConnection patchCord11;
// AudioConnection patchCord12;
// AudioConnection patchCord13;
// AudioConnection patchCord14;
// AudioConnection patchCord15;
// AudioConnection patchCord16;
// AudioConnection patchCord17;
// AudioConnection patchCord18;
// AudioConnection patchCord19;
// AudioConnection patchCord20;
// AudioConnection patchCord21;
// AudioConnection patchCord22;
// AudioConnection patchCord23;
// AudioConnection patchCord24;
// AudioConnection patchCord25;
// AudioConnection patchCord26;
// AudioConnection patchCord27;
// AudioConnection patchCord28;
// AudioConnection patchCord29;
// AudioConnection patchCord30;
// AudioConnection patchCord31;
// AudioConnection patchCord32;
// AudioConnection patchCord33;
// AudioConnection patchCord34;
// AudioConnection patchCord35;
// AudioConnection patchCord36;

};

REGISTER_PLUGIN(partialCluster);

+ 294
- 0
src/noise-plethora/plugins/P_phasingCluster.hpp View File

@@ -0,0 +1,294 @@
#pragma once

#include "NoisePlethoraPlugin.hpp"

class phasingCluster : public NoisePlethoraPlugin {

public:

phasingCluster()
// : patchCord1(modulator13, 0, waveform13, 0),
// patchCord2(modulator14, 0, waveform14, 0),
// patchCord3(modulator15, 0, waveform15, 0),
// patchCord4(modulator2, 0, waveform2, 0),
// patchCord5(modulator4, 0, waveform4, 0),
// patchCord6(modulator1, 0, waveform1, 0),
// patchCord7(modulator16, 0, waveform16, 0),
// patchCord8(modulator12, 0, waveform12, 0),
// patchCord9(modulator11, 0, waveform11, 0),
// patchCord10(modulator3, 0, waveform3, 0),
// patchCord11(modulator5, 0, waveform5, 0),
// patchCord12(modulator6, 0, waveform6, 0),
// patchCord13(modulator7, 0, waveform7, 0),
// patchCord14(modulator10, 0, waveform10, 0),
// patchCord15(modulator8, 0, waveform8, 0),
// patchCord16(modulator9, 0, waveform9, 0),
// patchCord17(waveform16, 0, mixer4, 3),
// patchCord18(waveform14, 0, mixer4, 1),
// patchCord19(waveform15, 0, mixer4, 2),
// patchCord20(waveform13, 0, mixer4, 0),
// patchCord21(waveform8, 0, mixer2, 3),
// patchCord22(waveform6, 0, mixer2, 1),
// patchCord23(waveform7, 0, mixer2, 2),
// patchCord24(waveform12, 0, mixer3, 3),
// patchCord25(waveform5, 0, mixer2, 0),
// patchCord26(waveform10, 0, mixer3, 1),
// patchCord27(waveform11, 0, mixer3, 2),
// patchCord28(waveform9, 0, mixer3, 0),
// patchCord29(waveform4, 0, mixer1, 3),
// patchCord30(waveform2, 0, mixer1, 1),
// patchCord31(waveform3, 0, mixer1, 2),
// patchCord32(waveform1, 0, mixer1, 0),
// patchCord33(mixer4, 0, mixer5, 3),
// patchCord34(mixer3, 0, mixer5, 2),
// patchCord35(mixer2, 0, mixer5, 1),
// patchCord36(mixer1, 0, mixer5, 0)
{ }

~phasingCluster() override {}

phasingCluster(const phasingCluster&) = delete;
phasingCluster& operator=(const phasingCluster&) = delete;


void init() override {
mixer1.gain(0, 1);
mixer1.gain(1, 1);
mixer1.gain(2, 1);
mixer1.gain(3, 1);
mixer2.gain(0, 1);
mixer2.gain(1, 1);
mixer2.gain(2, 1);
mixer2.gain(3, 1);
mixer3.gain(0, 1);
mixer3.gain(1, 1);
mixer3.gain(2, 1);
mixer3.gain(3, 1);
mixer4.gain(0, 1);
mixer4.gain(1, 1);
mixer4.gain(2, 1);
mixer4.gain(3, 1);
mixer5.gain(0, 1);
mixer5.gain(1, 1);
mixer5.gain(2, 1);
mixer5.gain(3, 1);

int masterWaveform = WAVEFORM_SQUARE;
float masterVolume = 0.1;
int indexWaveform = WAVEFORM_TRIANGLE;
float index = 0.005;

waveform1.begin(masterVolume, 794, masterWaveform);
waveform2.begin(masterVolume, 647, masterWaveform);
waveform3.begin(masterVolume, 524, masterWaveform);
waveform4.begin(masterVolume, 444, masterWaveform);
waveform5.begin(masterVolume, 368, masterWaveform);
waveform6.begin(masterVolume, 283, masterWaveform);
waveform7.begin(masterVolume, 283, masterWaveform);
waveform8.begin(masterVolume, 283, masterWaveform);
waveform9.begin(masterVolume, 283, masterWaveform);
waveform10.begin(masterVolume, 283, masterWaveform);
waveform11.begin(masterVolume, 283, masterWaveform);
waveform12.begin(masterVolume, 283, masterWaveform);
waveform13.begin(masterVolume, 283, masterWaveform);
waveform14.begin(masterVolume, 283, masterWaveform);
waveform15.begin(masterVolume, 283, masterWaveform);
waveform16.begin(masterVolume, 283, masterWaveform);

modulator1.begin(index, 10, indexWaveform);
modulator2.begin(index, 11, indexWaveform);
modulator3.begin(index, 15, indexWaveform);
modulator4.begin(index, 1, indexWaveform);
modulator5.begin(index, 1, indexWaveform);
modulator6.begin(index, 3, indexWaveform);
modulator7.begin(index, 17, indexWaveform);
modulator8.begin(index, 14, indexWaveform);
modulator9.begin(index, 0.11, indexWaveform);
modulator10.begin(index, 5, indexWaveform);
modulator11.begin(index, 2, indexWaveform);
modulator12.begin(index, 7, indexWaveform);
modulator13.begin(index, 1, indexWaveform);
modulator14.begin(index, 0.1, indexWaveform);
modulator15.begin(index, 0.7, indexWaveform);
modulator16.begin(index, 0.5, indexWaveform);
}

void process(float k1, float k2) override {
float knob_1 = k1;
float knob_2 = k2;
float pitch1 = pow(knob_1, 2);


float spread = knob_2 * 0.5 + 1;

float f1 = 30 + pitch1 * 5000;
float f2 = f1 * spread;
float f3 = f2 * spread;
float f4 = f3 * spread;
float f5 = f4 * spread;
float f6 = f5 * spread;
float f7 = f6 * spread;
float f8 = f7 * spread;
float f9 = f8 * spread;
float f10 = f9 * spread;
float f11 = f10 * spread;
float f12 = f11 * spread;
float f13 = f12 * spread;
float f14 = f13 * spread;
float f15 = f14 * spread;
float f16 = f15 * spread;

waveform1.frequency(f1);
waveform2.frequency(f2);
waveform3.frequency(f3);
waveform4.frequency(f4);
waveform5.frequency(f5);
waveform6.frequency(f6);
waveform7.frequency(f7);
waveform8.frequency(f8);
waveform9.frequency(f9);
waveform10.frequency(f10);
waveform11.frequency(f11);
waveform12.frequency(f12);
waveform13.frequency(f13);
waveform14.frequency(f14);
waveform15.frequency(f15);
waveform16.frequency(f16);
}

void processGraphAsBlock(TeensyBuffer& blockBuffer) override {

// first update modulators
modulator1.update(&waveformOut[0]);
modulator2.update(&waveformOut[1]);
modulator3.update(&waveformOut[2]);
modulator4.update(&waveformOut[3]);
modulator5.update(&waveformOut[4]);
modulator6.update(&waveformOut[5]);
modulator7.update(&waveformOut[6]);
modulator8.update(&waveformOut[7]);
modulator9.update(&waveformOut[8]);
modulator10.update(&waveformOut[9]);
modulator11.update(&waveformOut[10]);
modulator12.update(&waveformOut[11]);
modulator13.update(&waveformOut[12]);
modulator14.update(&waveformOut[13]);
modulator15.update(&waveformOut[14]);
modulator16.update(&waveformOut[15]);

// FM from each of the modulators
waveform1.update(&waveformOut[0], nullptr, &waveformModOut[0]);
waveform2.update(&waveformOut[1], nullptr, &waveformModOut[1]);
waveform3.update(&waveformOut[2], nullptr, &waveformModOut[2]);
waveform4.update(&waveformOut[3], nullptr, &waveformModOut[3]);
waveform5.update(&waveformOut[4], nullptr, &waveformModOut[4]);
waveform6.update(&waveformOut[5], nullptr, &waveformModOut[5]);
waveform7.update(&waveformOut[6], nullptr, &waveformModOut[6]);
waveform8.update(&waveformOut[7], nullptr, &waveformModOut[7]);
waveform9.update(&waveformOut[8], nullptr, &waveformModOut[8]);
waveform10.update(&waveformOut[9], nullptr, &waveformModOut[9]);
waveform11.update(&waveformOut[10], nullptr, &waveformModOut[10]);
waveform12.update(&waveformOut[11], nullptr, &waveformModOut[11]);
waveform13.update(&waveformOut[12], nullptr, &waveformModOut[12]);
waveform14.update(&waveformOut[13], nullptr, &waveformModOut[13]);
waveform15.update(&waveformOut[14], nullptr, &waveformModOut[14]);
waveform16.update(&waveformOut[15], nullptr, &waveformModOut[15]);

mixer1.update(&waveformModOut[0], &waveformModOut[1], &waveformModOut[2], &waveformModOut[3], &mixerOut[0]);
mixer2.update(&waveformModOut[4], &waveformModOut[5], &waveformModOut[6], &waveformModOut[7], &mixerOut[1]);
mixer3.update(&waveformModOut[8], &waveformModOut[9], &waveformModOut[10], &waveformModOut[11], &mixerOut[2]);
mixer4.update(&waveformModOut[12], &waveformModOut[13], &waveformModOut[14], &waveformModOut[15], &mixerOut[3]);

mixer5.update(&mixerOut[0], &mixerOut[1], &mixerOut[2], &mixerOut[3], &mixerOut[4]);

blockBuffer.pushBuffer(mixerOut[4].data, AUDIO_BLOCK_SAMPLES);
}

AudioStream& getStream() override {
return mixer5;
}
unsigned char getPort() override {
return 0;
}

private:

audio_block_t waveformOut[16] = {}, waveformModOut[16] = {}, mixerOut[5] = {};

AudioSynthWaveform modulator13; //xy=331.3333435058594,888.6666870117188
AudioSynthWaveform modulator14; //xy=331.3333435058594,935.6666870117188
AudioSynthWaveform modulator15; //xy=331.3333435058594,976.6666870117188
AudioSynthWaveform modulator2; //xy=335.3333435058594,243.6666717529297
AudioSynthWaveform modulator4; //xy=336.3333435058594,349.6666564941406
AudioSynthWaveform modulator1; //xy=337.33335876464844,198.6666660308838
AudioSynthWaveform modulator16; //xy=334.3333435058594,1026.6666259765625
AudioSynthWaveform modulator12; //xy=335.3333435058594,823.6666870117188
AudioSynthWaveform modulator11; //xy=337.3333435058594,753.6666870117188
AudioSynthWaveform modulator3; //xy=339.3333435058594,293.6666564941406
AudioSynthWaveform modulator5; //xy=339.3333435058594,414.6666564941406
AudioSynthWaveform modulator6; //xy=341.3333435058594,467.6666564941406
AudioSynthWaveform modulator7; //xy=344.3333435058594,522.6666870117188
AudioSynthWaveform modulator10; //xy=344.3333435058594,687.6666870117188
AudioSynthWaveform modulator8; //xy=346.3333435058594,569.6666870117188
AudioSynthWaveform modulator9; //xy=350.3333435058594,624.6666870117188
AudioSynthWaveformModulated waveform16; //xy=532.3333282470703,986.8888931274414
AudioSynthWaveformModulated waveform14; //xy=534.3333282470703,881.8888931274414
AudioSynthWaveformModulated waveform15; //xy=534.3333282470703,926.8888931274414
AudioSynthWaveformModulated waveform13; //xy=535.3333282470703,839.8888931274414
AudioSynthWaveformModulated waveform8; //xy=542.3333282470703,566.8888931274414
AudioSynthWaveformModulated waveform6; //xy=544.3333282470703,461.8888931274414
AudioSynthWaveformModulated waveform7; //xy=544.3333282470703,506.8888931274414
AudioSynthWaveformModulated waveform12; //xy=543.3333282470703,777.8888931274414
AudioSynthWaveformModulated waveform5; //xy=545.3333282470703,419.8888931274414
AudioSynthWaveformModulated waveform10; //xy=545.3333282470703,672.8888931274414
AudioSynthWaveformModulated waveform11; //xy=545.3333282470703,717.8888931274414
AudioSynthWaveformModulated waveform9; //xy=546.3333282470703,630.8888931274414
AudioSynthWaveformModulated waveform4; //xy=550.3333282470703,351.8888931274414
AudioSynthWaveformModulated waveform2; //xy=552.3333282470703,246.8888931274414
AudioSynthWaveformModulated waveform3; //xy=552.3333282470703,291.8888931274414
AudioSynthWaveformModulated waveform1; //xy=553.3333282470703,203.8888931274414
AudioMixer4 mixer4; //xy=752.3333282470703,930.8888931274414
AudioMixer4 mixer3; //xy=763.3333282470703,721.8888931274414
AudioMixer4 mixer2; //xy=769.3333282470703,510.8888931274414
AudioMixer4 mixer1; //xy=770.3333282470703,295.8888931274414
AudioMixer4 mixer5; //xy=1017.3333282470703,507.8888931274414

// AudioConnection patchCord1;
// AudioConnection patchCord2;
// AudioConnection patchCord3;
// AudioConnection patchCord4;
// AudioConnection patchCord5;
// AudioConnection patchCord6;
// AudioConnection patchCord7;
// AudioConnection patchCord8;
// AudioConnection patchCord9;
// AudioConnection patchCord10;
// AudioConnection patchCord11;
// AudioConnection patchCord12;
// AudioConnection patchCord13;
// AudioConnection patchCord14;
// AudioConnection patchCord15;
// AudioConnection patchCord16;
// AudioConnection patchCord17;
// AudioConnection patchCord18;
// AudioConnection patchCord19;
// AudioConnection patchCord20;
// AudioConnection patchCord21;
// AudioConnection patchCord22;
// AudioConnection patchCord23;
// AudioConnection patchCord24;
// AudioConnection patchCord25;
// AudioConnection patchCord26;
// AudioConnection patchCord27;
// AudioConnection patchCord28;
// AudioConnection patchCord29;
// AudioConnection patchCord30;
// AudioConnection patchCord31;
// AudioConnection patchCord32;
// AudioConnection patchCord33;
// AudioConnection patchCord34;
// AudioConnection patchCord35;
// AudioConnection patchCord36;
};

REGISTER_PLUGIN(phasingCluster);

+ 139
- 0
src/noise-plethora/plugins/P_pwCluster.hpp View File

@@ -0,0 +1,139 @@
#pragma once
#include "NoisePlethoraPlugin.hpp"
class pwCluster : public NoisePlethoraPlugin {
public:
pwCluster()
//:
//patchCord1(dc1, 0, waveform1, 1),
//patchCord2(dc1, 0, waveform2, 1),
//patchCord3(dc1, 0, waveform3, 1),
//patchCord4(dc1, 0, waveform4, 1),
//patchCord5(dc1, 0, waveform5, 1),
//patchCord6(dc1, 0, waveform6, 1),
//patchCord7(waveform6, 0, mixer2, 1),
//patchCord8(waveform5, 0, mixer2, 0),
//patchCord9(waveform4, 0, mixer1, 3),
//patchCord10(waveform2, 0, mixer1, 1),
//patchCord11(waveform3, 0, mixer1, 2),
//patchCord12(waveform1, 0, mixer1, 0),
//patchCord13(mixer1, 0, mixer5, 0),
//patchCord14(mixer2, 0, mixer5, 1)
{
DEBUG("pwCluster initialised");
}
~pwCluster() override {
DEBUG("pwCluster destroyed");
}
pwCluster(const pwCluster&) = delete;
pwCluster& operator=(const pwCluster&) = delete;
void init() override {
mixer1.gain(0, 1);
mixer1.gain(1, 1);
mixer1.gain(2, 1);
mixer1.gain(3, 1);
mixer2.gain(0, 1);
mixer2.gain(1, 1);
mixer2.gain(2, 1);
mixer2.gain(3, 1);
mixer5.gain(0, 1);
mixer5.gain(1, 1);
mixer5.gain(2, 1);
mixer5.gain(3, 1);
int masterWaveform = WAVEFORM_PULSE;
float masterVolume = 0.7;
waveform1.begin(masterVolume, 794, masterWaveform);
waveform2.begin(masterVolume, 647, masterWaveform);
waveform3.begin(masterVolume, 524, masterWaveform);
waveform4.begin(masterVolume, 444, masterWaveform);
waveform5.begin(masterVolume, 368, masterWaveform);
waveform6.begin(masterVolume, 283, masterWaveform);
}
void process(float k1, float k2) override {
float knob_1 = k1;
float knob_2 = k2;
float pitch1 = std::pow(knob_1, 2);
float f1 = 40 + pitch1 * 8000;
float f2 = f1 * 1.227;
float f3 = f2 * 1.24;
float f4 = f3 * 1.17;
float f5 = f4 * 1.2;
float f6 = f5 * 1.3;
dc1.amplitude(1 - (knob_2 * 0.97));
waveform1.frequency(f1);
waveform2.frequency(f2);
waveform3.frequency(f3);
waveform4.frequency(f4);
waveform5.frequency(f5);
waveform6.frequency(f6);
}
void processGraphAsBlock(TeensyBuffer& blockBuffer) override {
dc1.update(&dcOut);
// pulsewidth from dc1 for the 6 oscillators
waveform1.update(nullptr, &dcOut, &waveformOut[0]);
waveform2.update(nullptr, &dcOut, &waveformOut[1]);
waveform3.update(nullptr, &dcOut, &waveformOut[2]);
waveform4.update(nullptr, &dcOut, &waveformOut[3]);
waveform5.update(nullptr, &dcOut, &waveformOut[4]);
waveform6.update(nullptr, &dcOut, &waveformOut[5]);
mixer1.update(&waveformOut[0], &waveformOut[1], &waveformOut[2], &waveformOut[3], &mixerOut[0]);
mixer2.update(&waveformOut[4], &waveformOut[5], nullptr, nullptr, &mixerOut[1]);
mixer5.update(&mixerOut[0], &mixerOut[1], nullptr, nullptr, &mixerOut[2]);
blockBuffer.pushBuffer(mixerOut[2].data, AUDIO_BLOCK_SAMPLES);
}
AudioStream& getStream() override {
return mixer5;
}
unsigned char getPort() override {
return 0;
}
private:
audio_block_t dcOut, waveformOut[6] = {}, mixerOut[3] = {};
AudioSynthWaveformDc dc1; //xy=305.8888854980469,1069.1111450195312
AudioSynthWaveformModulated waveform6; //xy=482.8888854980469,800.1111450195312
AudioSynthWaveformModulated waveform5; //xy=483.8888854980469,758.1111450195312
AudioSynthWaveformModulated waveform4; //xy=488.8888854980469,690.1111450195312
AudioSynthWaveformModulated waveform2; //xy=490.8888854980469,585.1111450195312
AudioSynthWaveformModulated waveform3; //xy=490.8888854980469,630.1111450195312
AudioSynthWaveformModulated waveform1; //xy=491.8888854980469,542.1111450195312
AudioMixer4 mixer1; //xy=708.8888854980469,634.1111450195312
AudioMixer4 mixer2; //xy=719.8888854980469,789.1111450195312
AudioMixer4 mixer5; //xy=955.8888854980469,846.1111450195312
// AudioConnection patchCord1;
// AudioConnection patchCord2;
// AudioConnection patchCord3;
// AudioConnection patchCord4;
// AudioConnection patchCord5;
// AudioConnection patchCord6;
// AudioConnection patchCord7;
// AudioConnection patchCord8;
// AudioConnection patchCord9;
// AudioConnection patchCord10;
// AudioConnection patchCord11;
// AudioConnection patchCord12;
// AudioConnection patchCord13;
// AudioConnection patchCord14;
};
REGISTER_PLUGIN(pwCluster);

+ 99
- 0
src/noise-plethora/plugins/P_radioOhNo.hpp View File

@@ -0,0 +1,99 @@
#pragma once

#include "NoisePlethoraPlugin.hpp"

class radioOhNo : public NoisePlethoraPlugin {

public:

radioOhNo()
//: patchCord1(dc1, 0, waveformMod1, 1),
// patchCord2(dc1, 0, waveformMod2, 1),
// patchCord3(dc1, 0, waveformMod3, 1),
// patchCord4(dc1, 0, waveformMod4, 1),
// patchCord5(waveformMod2, 0, waveformMod1, 0),
// patchCord6(waveformMod1, 0, waveformMod2, 0),
// patchCord7(waveformMod1, 0, mixer1, 0),
// patchCord8(waveformMod3, 0, waveformMod4, 0),
// patchCord9(waveformMod3, 0, mixer1, 1),
// patchCord10(waveformMod4, 0, waveformMod3, 0)
{ }

~radioOhNo() override {}

radioOhNo(const radioOhNo&) = delete;
radioOhNo& operator=(const radioOhNo&) = delete;

void init() override {
waveformMod1.begin(0.8, 500, WAVEFORM_PULSE);
waveformMod2.begin(0.8, 1500, WAVEFORM_PULSE);
waveformMod3.begin(0.8, 600, WAVEFORM_PULSE);
waveformMod4.begin(0.8, 1600, WAVEFORM_PULSE);
}

void process(float k1, float k2) override {
float knob_1 = k1;
float knob_2 = k2;
float pitch1 = pow(knob_1, 2);
// float pitch2 = pow(knob_2, 2);


waveformMod1.frequency(2500 * pitch1 + 20);
waveformMod2.frequency(1120 - (1100 * pitch1));
waveformMod3.frequency(2900 * pitch1 + 20);
waveformMod4.frequency(8020 - (8000 * pitch1 + 20));
waveformMod1.frequencyModulation(5);
waveformMod2.frequencyModulation(5);
waveformMod1.frequencyModulation(5);
waveformMod2.frequencyModulation(5);
dc1.amplitude(knob_2);

}

void processGraphAsBlock(TeensyBuffer& blockBuffer) override {
dc1.update(&dcPrevious);

waveformMod2.update(&waveformModPrevious[1], &dcPrevious, &waveformModPrevious[2]);
waveformMod1.update(&waveformModPrevious[2], &dcPrevious, &waveformModPrevious[1]);

waveformMod3.update(&waveformModPrevious[4], &dcPrevious, &waveformModPrevious[3]);
waveformMod4.update(&waveformModPrevious[3], &dcPrevious, &waveformModPrevious[4]);

mixer1.update(&waveformModPrevious[1], &waveformModPrevious[3], nullptr, nullptr, &mixerOut);

blockBuffer.pushBuffer(mixerOut.data, AUDIO_BLOCK_SAMPLES);

}

AudioStream& getStream() override {
return mixer1;
}
unsigned char getPort() override {
return 0;
}

private:

audio_block_t waveformModPrevious[5];
audio_block_t dcPrevious;
audio_block_t mixerOut;

AudioSynthWaveformDc dc1; //xy=179.75,710.75
AudioSynthWaveformModulated waveformMod2; //xy=464.75,614.75
AudioSynthWaveformModulated waveformMod1; //xy=466.75,490.75
AudioSynthWaveformModulated waveformMod3; //xy=468.75,729.75
AudioSynthWaveformModulated waveformMod4; //xy=470.75,848.75
AudioMixer4 mixer1; //xy=676.750057220459,680.7500286102295
// AudioConnection patchCord1;
// AudioConnection patchCord2;
// AudioConnection patchCord3;
// AudioConnection patchCord4;
// AudioConnection patchCord5;
// AudioConnection patchCord6;
// AudioConnection patchCord7;
// AudioConnection patchCord8;
// AudioConnection patchCord9;
// AudioConnection patchCord10;
};

REGISTER_PLUGIN(radioOhNo);

+ 95
- 0
src/noise-plethora/plugins/P_resonoise.hpp View File

@@ -0,0 +1,95 @@
#pragma once

#include "NoisePlethoraPlugin.hpp"

class resonoise : public NoisePlethoraPlugin {

public:

resonoise()
// : patchCord1(waveformMod1, sine_fm1)
// , patchCord2(noise1, 0, filter1, 0)
// , patchCord3(sine_fm1, 0, wavefolder1, 0)
// , patchCord4(dc1, 0, wavefolder1, 1)
// , patchCord5(wavefolder1, 0, filter1, 1)
{ }

~resonoise() override {}

// delete copy constructors
resonoise(const resonoise&) = delete;
resonoise& operator=(const resonoise&) = delete;

void init() override {

noise1.amplitude(1);

sine_fm1.frequency(1100);


sine_fm1.amplitude(1);
waveformMod1.begin(1, 500, WAVEFORM_SQUARE);

filter1.resonance(3);
filter1.octaveControl(5);
}

void process(float k1, float k2) override {


float knob_1 = k1;
float knob_2 = k2;

float pitch1 = pow(knob_1, 2);

dc1.amplitude(knob_2 * 0.2 + 0.03, 1);

sine_fm1.frequency(20 + (pitch1 * 10000));
waveformMod1.frequency(20 + (pitch1 * 7777));

}


void processGraphAsBlock(TeensyBuffer& blockBuffer) override {

waveformMod1.update(nullptr, nullptr, &waveformMod1Block);
sine_fm1.update(&waveformMod1Block, &sineFMBlock);

dc1.update(&dcBlock);
wavefolder1.update(&sineFMBlock, &dcBlock, &wavefolderBlock);

noise1.update(&noiseBlock);
filter1.update(&noiseBlock, &wavefolderBlock, &filterOutLP, &filterOutBP, &filterOutHP);

blockBuffer.pushBuffer(filterOutLP.data, AUDIO_BLOCK_SAMPLES);
}

AudioStream& getStream() override {
return filter1;
}
unsigned char getPort() override {
return 0;
}

private:
// GUItool: begin automatically generated code
AudioSynthWaveformModulated waveformMod1; //xy=245.88888549804688,699.2222213745117
AudioSynthNoiseWhite noise1; //xy=271.8888854980469,354.8888854980469
AudioSynthWaveformSineModulated sine_fm1; //xy=303.88890838623047,455.8889751434326
AudioSynthWaveformDc dc1; //xy=436.8888854980469,646.1111145019531
AudioEffectWaveFolder wavefolder1; //xy=469.8888854980469,520.1111145019531
AudioFilterStateVariable filter1; //xy=559.8888854980469,410.88891983032227

audio_block_t noiseBlock, waveformMod1Block, sineFMBlock, wavefolderBlock, dcBlock;
audio_block_t filterOutLP, filterOutBP, filterOutHP;


// AudioConnection patchCord1;
// AudioConnection patchCord2;
// AudioConnection patchCord3;
// AudioConnection patchCord4;
// AudioConnection patchCord5;

};

REGISTER_PLUGIN(resonoise); // this is important, so that we can include the plugin in a bank

+ 74
- 0
src/noise-plethora/plugins/P_satanWorkout.hpp View File

@@ -0,0 +1,74 @@
#pragma once

#include "NoisePlethoraPlugin.hpp"

class satanWorkout : public NoisePlethoraPlugin {

public:

satanWorkout()
//: patchCord1(pink1, pwm1)
//, patchCord2(pwm1, freeverb1)
{ }

~satanWorkout() override {}

// delete copy constructors
satanWorkout(const satanWorkout&) = delete;
satanWorkout& operator=(const satanWorkout&) = delete;

void init() override {

pink1.amplitude(1);
pwm1.amplitude(1);
freeverb1.damping(-5);

}

void process(float k1, float k2) override {


float knob_1 = k1;
float knob_2 = k2;

float pitch1 = pow(knob_1, 2);
// float pitch2 = pow(knob_2, 2);

pwm1.frequency(8 + pitch1 * 6000);

freeverb1.roomsize(0.001 + knob_2 * 4);


//Serial.print(pitch1 * 10000 + 20);
//Serial.println();
}

void processGraphAsBlock(TeensyBuffer& blockBuffer) override {
pink1.update(&noiseBlock);
pwm1.update(&noiseBlock, &pwmBlock);
freeverb1.update(&pwmBlock, &freeverbBlock);

blockBuffer.pushBuffer(freeverbBlock.data, AUDIO_BLOCK_SAMPLES);
}

AudioStream& getStream() override {
return freeverb1;
}
unsigned char getPort() override {
return 0;
}

private:
audio_block_t noiseBlock, pwmBlock, freeverbBlock;

// GUItool: begin automatically generated code
AudioSynthNoisePink pink1; //xy=927.6667137145996,1712.0000095367432
AudioSynthWaveformPWM pwm1; //xy=1065.6666564941406,1795.666675567627
AudioEffectFreeverb freeverb1; //xy=1152.6666564941406,1739.6666746139526
//AudioConnection patchCord1;
//AudioConnection patchCord2;


};

REGISTER_PLUGIN(satanWorkout); // this is important, so that we can include the plugin in a bank

+ 168
- 0
src/noise-plethora/plugins/P_sineFMcluster.hpp View File

@@ -0,0 +1,168 @@
#pragma once
#include "NoisePlethoraPlugin.hpp"
class sineFMcluster : public NoisePlethoraPlugin {
public:
sineFMcluster()
// : patchCord1(modulator1, 0, waveform1, 0),
// patchCord2(modulator3, 0, waveform3, 0),
// patchCord3(modulator2, 0, waveform2, 0),
// patchCord4(modulator5, 0, waveform5, 0),
// patchCord5(modulator4, 0, waveform4, 0),
// patchCord6(modulator6, 0, waveform6, 0),
// patchCord7(waveform1, 0, mixer1, 0),
// patchCord8(waveform4, 0, mixer1, 3),
// patchCord9(waveform2, 0, mixer1, 1),
// patchCord10(waveform3, 0, mixer1, 2),
// patchCord11(waveform6, 0, mixer2, 1),
// patchCord12(waveform5, 0, mixer2, 0),
// patchCord13(mixer2, 0, mixer5, 1),
// patchCord14(mixer1, 0, mixer5, 0)
{ }
~sineFMcluster() override {}
sineFMcluster(const sineFMcluster&) = delete;
sineFMcluster& operator=(const sineFMcluster&) = delete;
void init() override {
mixer1.gain(0, 1);
mixer1.gain(1, 1);
mixer1.gain(2, 1);
mixer1.gain(3, 1);
mixer2.gain(0, 1);
mixer2.gain(1, 1);
mixer2.gain(2, 1);
mixer2.gain(3, 1);
mixer5.gain(0, 1);
mixer5.gain(1, 1);
mixer5.gain(2, 1);
mixer5.gain(3, 1);
int masterWaveform = WAVEFORM_TRIANGLE;
float masterVolume = 0.25;
waveform1.begin(masterVolume, 794, masterWaveform);
waveform2.begin(masterVolume, 647, masterWaveform);
waveform3.begin(masterVolume, 524, masterWaveform);
waveform4.begin(masterVolume, 444, masterWaveform);
waveform5.begin(masterVolume, 368, masterWaveform);
waveform6.begin(masterVolume, 283, masterWaveform);
modulator1.begin(1, 1000, WAVEFORM_SINE);
modulator2.begin(1, 1000, WAVEFORM_SINE);
modulator3.begin(1, 1000, WAVEFORM_SINE);
modulator4.begin(1, 1000, WAVEFORM_SINE);
modulator5.begin(1, 1000, WAVEFORM_SINE);
modulator6.begin(1, 1000, WAVEFORM_SINE);
}
void process(float k1, float k2) override {
float knob_1 = k1;
float knob_2 = k2;
float pitch1 = pow(knob_1, 2);
float f1 = 300 + pitch1 * 8000;
float f2 = f1 * 1.227;
float f3 = f2 * 1.24;
float f4 = f3 * 1.17;
float f5 = f4 * 1.2;
float f6 = f5 * 1.3;
float index = knob_2 * 0.9 + 0.1;
float indexFreq = 0.333;
modulator1.amplitude(index);
modulator2.amplitude(index);
modulator3.amplitude(index);
modulator4.amplitude(index);
modulator5.amplitude(index);
modulator6.amplitude(index);
modulator1.frequency(f1 * indexFreq);
modulator2.frequency(f2 * indexFreq);
modulator3.frequency(f3 * indexFreq);
modulator4.frequency(f4 * indexFreq);
modulator5.frequency(f5 * indexFreq);
modulator6.frequency(f6 * indexFreq);
waveform1.frequency(f1);
waveform2.frequency(f2);
waveform3.frequency(f3);
waveform4.frequency(f4);
waveform5.frequency(f5);
waveform6.frequency(f6);
}
void processGraphAsBlock(TeensyBuffer& blockBuffer) override {
// modulators for the 6 oscillators
modulator1.update(&waveformOut[0]);
modulator2.update(&waveformOut[1]);
modulator3.update(&waveformOut[2]);
modulator4.update(&waveformOut[3]);
modulator5.update(&waveformOut[4]);
modulator6.update(&waveformOut[5]);
// FM for the 6 oscillators from modulators
waveform1.update(&waveformOut[0], nullptr, &waveformModOut[0]);
waveform2.update(&waveformOut[1], nullptr, &waveformModOut[1]);
waveform3.update(&waveformOut[2], nullptr, &waveformModOut[2]);
waveform4.update(&waveformOut[3], nullptr, &waveformModOut[3]);
waveform5.update(&waveformOut[4], nullptr, &waveformModOut[4]);
waveform6.update(&waveformOut[5], nullptr, &waveformModOut[5]);
mixer1.update(&waveformModOut[0], &waveformModOut[1], &waveformModOut[2], &waveformModOut[3], &mixerOut[0]);
mixer2.update(&waveformModOut[4], &waveformModOut[5], nullptr, nullptr, &mixerOut[1]);
mixer5.update(&mixerOut[0], &mixerOut[1], nullptr, nullptr, &mixerOut[2]);
blockBuffer.pushBuffer(mixerOut[2].data, AUDIO_BLOCK_SAMPLES);
}
AudioStream& getStream() override {
return mixer5;
}
unsigned char getPort() override {
return 0;
}
private:
audio_block_t waveformOut[6] = {}, waveformModOut[6] = {}, mixerOut[3] = {};
AudioSynthWaveform modulator1; //xy=236.88888549804688,262.55556869506836
AudioSynthWaveform modulator3; //xy=238.88890075683594,366.555606842041
AudioSynthWaveform modulator2; //xy=239.88890075683594,313.5556392669678
AudioSynthWaveform modulator5; //xy=239.88890075683594,485.5555810928345
AudioSynthWaveform modulator4; //xy=240.88890075683594,428.55560970306396
AudioSynthWaveform modulator6; //xy=242.8888931274414,541.5555143356323
AudioSynthWaveformModulated waveform1; //xy=459.88890075683594,268.6667013168335
AudioSynthWaveformModulated waveform4; //xy=459.8888854980469,433.6666889190674
AudioSynthWaveformModulated waveform2; //xy=461.88890838623047,322.66671657562256
AudioSynthWaveformModulated waveform3; //xy=461.8888854980469,373.6666889190674
AudioSynthWaveformModulated waveform6; //xy=461.88890838623047,546.6666688919067
AudioSynthWaveformModulated waveform5; //xy=462.88888931274414,492.66670417785645
AudioMixer4 mixer2; //xy=663.8888053894043,520.6666412353516
AudioMixer4 mixer1; //xy=667.888916015625,349.6667251586914
AudioMixer4 mixer5; //xy=853.8889122009277,448.6667900085449
// AudioConnection patchCord1;
// AudioConnection patchCord2;
// AudioConnection patchCord3;
// AudioConnection patchCord4;
// AudioConnection patchCord5;
// AudioConnection patchCord6;
// AudioConnection patchCord7;
// AudioConnection patchCord8;
// AudioConnection patchCord9;
// AudioConnection patchCord10;
// AudioConnection patchCord11;
// AudioConnection patchCord12;
// AudioConnection patchCord13;
// AudioConnection patchCord14;
};
REGISTER_PLUGIN(sineFMcluster);

+ 148
- 0
src/noise-plethora/plugins/P_whoKnows.hpp View File

@@ -0,0 +1,148 @@
#pragma once

#include "NoisePlethoraPlugin.hpp"

class whoKnows : public NoisePlethoraPlugin {

public:

whoKnows()
// : patchCord1(waveform1, 0, filter1, 0)
// , patchCord2(waveform1, 0, filter2, 0)
// , patchCord3(waveform1, 0, filter3, 0)
// , patchCord4(waveform1, 0, filter4, 0)
// , patchCord5(waveformMod1, 0, filter1, 1)
// , patchCord6(waveformMod2, 0, filter2, 1)
// , patchCord7(waveformMod4, 0, filter4, 1)
// , patchCord8(waveformMod3, 0, filter3, 1)
// , patchCord9(filter1, 1, mixer1, 0)
// , patchCord10(filter2, 1, mixer1, 1)
// , patchCord11(filter3, 1, mixer1, 2)
// , patchCord12(filter4, 1, mixer1, 3)
{ }

~whoKnows() override {}

// delete copy constructors
whoKnows(const whoKnows&) = delete;
whoKnows& operator=(const whoKnows&) = delete;

void init() override {

//noise1.amplitude(1);

mixer1.gain(0, 0.8);
mixer1.gain(1, 0.8);
mixer1.gain(2, 0.8);
mixer1.gain(3, 0.8);


waveformMod1.begin(1, 21, WAVEFORM_TRIANGLE);
waveformMod2.begin(1, 70, WAVEFORM_TRIANGLE);
waveformMod3.begin(1, 90, WAVEFORM_TRIANGLE);
waveformMod4.begin(1, 77, WAVEFORM_TRIANGLE);

waveform1.begin(1, 5, WAVEFORM_PULSE);
waveform1.pulseWidth(0.1);

filter1.resonance(7);
filter1.octaveControl(7);

filter2.resonance(7);
filter2.octaveControl(7);

filter3.resonance(7);
filter3.octaveControl(7);

filter4.resonance(7);
filter4.octaveControl(7);
}

void process(float k1, float k2) override {


float knob_1 = k1;
float knob_2 = k2;

float pitch1 = pow(knob_1, 2);
// float pitch2 = pow(knob_2, 2);


waveform1.frequency(15 + (pitch1 * 500));

float octaves = knob_2 * 6 + 0.3;

/*filter1.resonance(resonanceLevel);
filter2.resonance(resonanceLevel);
filter3.resonance(resonanceLevel);
filter4.resonance(resonanceLevel);*/

filter1.octaveControl(octaves);
filter2.octaveControl(octaves);
filter3.octaveControl(octaves);
filter4.octaveControl(octaves);

}

void processGraphAsBlock(TeensyBuffer& blockBuffer) override {

// waveform to filter
waveform1.update(&waveformOut);

waveformMod1.update(nullptr, nullptr, &waveformModOut[0]);
waveformMod2.update(nullptr, nullptr, &waveformModOut[1]);
waveformMod3.update(nullptr, nullptr, &waveformModOut[2]);
waveformMod4.update(nullptr, nullptr, &waveformModOut[3]);

filter1.update(&waveformOut, &waveformModOut[0], &filterOutLP[0], &filterOutBP[0], &filterOutHP[0]);
filter2.update(&waveformOut, &waveformModOut[1], &filterOutLP[1], &filterOutBP[1], &filterOutHP[1]);
filter3.update(&waveformOut, &waveformModOut[2], &filterOutLP[2], &filterOutBP[2], &filterOutHP[2]);
filter4.update(&waveformOut, &waveformModOut[3], &filterOutLP[3], &filterOutBP[3], &filterOutHP[3]);

// sum up
mixer1.update(&filterOutBP[0], &filterOutBP[1], &filterOutBP[2], &filterOutBP[3], &mixerOut);

blockBuffer.pushBuffer(mixerOut.data, AUDIO_BLOCK_SAMPLES);
}


AudioStream& getStream() override {
return mixer1;
}
unsigned char getPort() override {
return 0;
}

private:


audio_block_t filterOutLP[4], filterOutBP[4], filterOutHP[4], waveformModOut[4], waveformOut, mixerOut;


// GUItool: begin automatically generated code
AudioSynthWaveform waveform1; //xy=283,566
AudioSynthWaveformModulated waveformMod1; //xy=363.888916015625,321.2221794128418
AudioSynthWaveformModulated waveformMod2; //xy=368,380.3332633972168
AudioSynthWaveformModulated waveformMod4; //xy=374,689.3332633972168
AudioSynthWaveformModulated waveformMod3; //xy=378,638.3332633972168
AudioFilterStateVariable filter1; //xy=578.888916015625,420.8889274597168
AudioFilterStateVariable filter2; //xy=579,486.0000114440918
AudioFilterStateVariable filter3; //xy=581,549.0000114440918
AudioFilterStateVariable filter4; //xy=581,614.0000114440918
AudioMixer4 mixer1; //xy=752,520.0000114440918
// AudioConnection patchCord1;
// AudioConnection patchCord2;
// AudioConnection patchCord3;
// AudioConnection patchCord4;
// AudioConnection patchCord5;
// AudioConnection patchCord6;
// AudioConnection patchCord7;
// AudioConnection patchCord8;
// AudioConnection patchCord9;
// AudioConnection patchCord10;
// AudioConnection patchCord11;
// AudioConnection patchCord12;

};

REGISTER_PLUGIN(whoKnows); // this is important, so that we can include the plugin in a bank

+ 71
- 0
src/noise-plethora/plugins/P_xModRingSqr.hpp View File

@@ -0,0 +1,71 @@
#pragma once

#include "NoisePlethoraPlugin.hpp"

class xModRingSqr : public NoisePlethoraPlugin {

public:

xModRingSqr()
// : patchCord1(waveformMod2, 0, multiply1, 1),
// patchCord2(waveformMod2, 0, waveformMod1, 0),
// patchCord3(waveformMod1, 0, multiply1, 0),
// patchCord4(waveformMod1, 0, waveformMod2, 0)
{ }

~xModRingSqr() override {}

xModRingSqr(const xModRingSqr&) = delete;
xModRingSqr& operator=(const xModRingSqr&) = delete;

void init() override {
waveformMod1.begin(0.8, 500, WAVEFORM_SQUARE);
waveformMod2.begin(0.8, 500, WAVEFORM_SQUARE);

waveformMod1.frequencyModulation(1);
waveformMod2.frequencyModulation(1);

}

void process(float k1, float k2) override {
float knob_1 = k1;
float knob_2 = k2;
float pitch1 = pow(knob_1, 2);
float pitch2 = pow(knob_2, 2);


waveformMod1.frequency(100 + (pitch1 * 5000));
waveformMod2.frequency(20 + (pitch2 * 1000));

}

void processGraphAsBlock(TeensyBuffer& blockBuffer) override {
waveformMod2.update(&waveformModOut[0], nullptr, &waveformModOut[1]);
waveformMod1.update(&waveformModOut[1], nullptr, &waveformModOut[0]);

multiply1.update(&waveformModOut[0], &waveformModOut[1], &multiplyOut);

blockBuffer.pushBuffer(multiplyOut.data, AUDIO_BLOCK_SAMPLES);
}

AudioStream& getStream() override {
return multiply1;
}
unsigned char getPort() override {
return 0;
}

private:
audio_block_t waveformModOut[2] = {}, multiplyOut;

AudioSynthWaveformModulated waveformMod2; //xy=464,422
AudioSynthWaveformModulated waveformMod1; //xy=472,319
AudioEffectMultiply multiply1; //xy=682,361
// AudioConnection patchCord1;
// AudioConnection patchCord2;
// AudioConnection patchCord3;
// AudioConnection patchCord4;

};

REGISTER_PLUGIN(xModRingSqr);

+ 123
- 0
src/noise-plethora/plugins/ProgramSelector.hpp View File

@@ -0,0 +1,123 @@
#pragma once

#include "Banks.hpp"

#define CLAMP(x, a, b) (x) < (a) ? (a) : (x) > (b) ? (b) : (x);

enum {
PROG_A = 0,
PROG_B
};

class Selection {

public:

Selection(int numPrograms = programsPerBank)
: value(0)
, min(0)
, max(numPrograms - 1)
{}

int getValue() {
return value;
}

int setValue(int val, int numValues = -1) {
if (numValues == -1) {
numValues = max + 1;
}
val = CLAMP(val, min, numValues - 1);
value = val;
return value;
}

void setMin(int v) {
min = v;
}

void setMax(int v) {
max = v;
}

private:

int value;
int min;
int max;

};

class ProgramSelection {

public:

int getBank() {
return bank.getValue();
}
int getProgram() {
return program.getValue();
}
int setBank(int b) {
if (getBankForIndex(b).getSize()) { // assumed that only top bank can be empty
return bank.setValue(b);
}
return getBank();
}
int setProgram(int p) {
return program.setValue(p, getBankForIndex(getBank()).getSize());
}

const std::string getCurrentProgramName() {
return getBankForIndex(getBank()).getProgramName(getProgram());
}

float getCurrentProgramGain() {
return getBankForIndex(getBank()).getProgramGain(getProgram());
}

private:

Selection bank{numBanks};
Selection program;

};

class ProgramSelector {

public:

ProgramSelector()
: currentProgram(PROG_A)
{}

~ProgramSelector() {}

ProgramSelection& getCurrent() {
return currentProgram == PROG_A ? progA : progB;
}
ProgramSelection& getA() {
return progA;
}
ProgramSelection& getB() {
return progB;
}

ProgramSelection& getSection(unsigned int program) {
return program ? progB : progA;
}

unsigned int getMode() {
return currentProgram;
}
void setMode(unsigned int current) {
currentProgram = current ? PROG_B : PROG_A;
}

private:

ProgramSelection progA;
ProgramSelection progB;
unsigned int currentProgram;

};

BIN
src/noise-plethora/teensy-audio-device.png View File

Before After
Width: 1373  |  Height: 451  |  Size: 230KB

BIN
src/noise-plethora/teensy-gui.png View File

Before After
Width: 1688  |  Height: 1087  |  Size: 175KB

+ 21
- 0
src/noise-plethora/teensy/TeensyAudioReplacements.hpp View File

@@ -0,0 +1,21 @@
#pragma once
#include <rack.hpp>
#include "../../plugin.hpp"
#include "audio_core.hpp"
#include "effect_bitcrusher.h"
#include "effect_combine.hpp"
#include "effect_freeverb.hpp"
#include "effect_flange.h"
#include "effect_granular.hpp"
#include "effect_multiply.h"
#include "effect_wavefolder.hpp"
#include "filter_variable.hpp"
#include "mixer.hpp"
#include "synth_dc.hpp"
#include "synth_sine.hpp"
#include "synth_waveform.hpp"
#include "synth_whitenoise.hpp"
#include "synth_pinknoise.hpp"
#include "synth_pwm.hpp"

+ 180
- 0
src/noise-plethora/teensy/audio_core.hpp View File

@@ -0,0 +1,180 @@
#pragma once
#include <rack.hpp>
#include "dspinst.h"
class AudioStream {
public:
AudioStream(int num_inputs_) : num_inputs(num_inputs_) {}
const int num_inputs;
};
#define AUDIO_BLOCK_SAMPLES 128
// even if rack sample rate is different, we don't want Teensy to behave differently
// w.r.t. aliasing etc - this generally used to put upper bounds on frequencies etc
#define AUDIO_SAMPLE_RATE_EXACT 44100.0f
typedef rack::dsp::RingBuffer<int16_t, AUDIO_BLOCK_SAMPLES> TeensyBuffer;
typedef struct audio_block_struct {
// uint8_t ref_count;
// uint8_t reserved1;
// uint16_t memory_pool_index;
int16_t data[AUDIO_BLOCK_SAMPLES] = {};
// initialises data to zeroes
void zeroAudioBlock() {
memset(data, 0, sizeof(int16_t) * AUDIO_BLOCK_SAMPLES);
}
static void copyBlock(const audio_block_struct* src, audio_block_struct* dst) {
if (src && dst) {
memcpy(&(dst->data), &(src->data), AUDIO_BLOCK_SAMPLES);
}
}
} audio_block_t;
enum WaveformType {
WAVEFORM_SINE,
WAVEFORM_SAWTOOTH,
WAVEFORM_SQUARE,
WAVEFORM_TRIANGLE,
WAVEFORM_ARBITRARY,
WAVEFORM_PULSE,
WAVEFORM_SAWTOOTH_REVERSE,
WAVEFORM_SAMPLE_HOLD,
WAVEFORM_TRIANGLE_VARIABLE,
WAVEFORM_BANDLIMIT_SAWTOOTH,
WAVEFORM_BANDLIMIT_SAWTOOTH_REVERSE,
WAVEFORM_BANDLIMIT_SQUARE,
WAVEFORM_BANDLIMIT_PULSE,
};
const int16_t AudioWaveformSine[257] = {
0, 804, 1608, 2410, 3212, 4011, 4808, 5602, 6393, 7179,
7962, 8739, 9512, 10278, 11039, 11793, 12539, 13279, 14010, 14732,
15446, 16151, 16846, 17530, 18204, 18868, 19519, 20159, 20787, 21403,
22005, 22594, 23170, 23731, 24279, 24811, 25329, 25832, 26319, 26790,
27245, 27683, 28105, 28510, 28898, 29268, 29621, 29956, 30273, 30571,
30852, 31113, 31356, 31580, 31785, 31971, 32137, 32285, 32412, 32521,
32609, 32678, 32728, 32757, 32767, 32757, 32728, 32678, 32609, 32521,
32412, 32285, 32137, 31971, 31785, 31580, 31356, 31113, 30852, 30571,
30273, 29956, 29621, 29268, 28898, 28510, 28105, 27683, 27245, 26790,
26319, 25832, 25329, 24811, 24279, 23731, 23170, 22594, 22005, 21403,
20787, 20159, 19519, 18868, 18204, 17530, 16846, 16151, 15446, 14732,
14010, 13279, 12539, 11793, 11039, 10278, 9512, 8739, 7962, 7179,
6393, 5602, 4808, 4011, 3212, 2410, 1608, 804, 0, -804,
-1608, -2410, -3212, -4011, -4808, -5602, -6393, -7179, -7962, -8739,
-9512, -10278, -11039, -11793, -12539, -13279, -14010, -14732, -15446, -16151,
-16846, -17530, -18204, -18868, -19519, -20159, -20787, -21403, -22005, -22594,
-23170, -23731, -24279, -24811, -25329, -25832, -26319, -26790, -27245, -27683,
-28105, -28510, -28898, -29268, -29621, -29956, -30273, -30571, -30852, -31113,
-31356, -31580, -31785, -31971, -32137, -32285, -32412, -32521, -32609, -32678,
-32728, -32757, -32767, -32757, -32728, -32678, -32609, -32521, -32412, -32285,
-32137, -31971, -31785, -31580, -31356, -31113, -30852, -30571, -30273, -29956,
-29621, -29268, -28898, -28510, -28105, -27683, -27245, -26790, -26319, -25832,
-25329, -24811, -24279, -23731, -23170, -22594, -22005, -21403, -20787, -20159,
-19519, -18868, -18204, -17530, -16846, -16151, -15446, -14732, -14010, -13279,
-12539, -11793, -11039, -10278, -9512, -8739, -7962, -7179, -6393, -5602,
-4808, -4011, -3212, -2410, -1608, -804, 0
};
namespace teensy {
static uint32_t seed;
inline int32_t random_teensy(void) {
int32_t hi, lo, x;
// the algorithm used in avr-libc 1.6.4
x = seed;
if (x == 0)
x = 123459876;
hi = x / 127773;
lo = x % 127773;
x = 16807 * lo - 2836 * hi;
if (x < 0)
x += 0x7FFFFFFF;
seed = x;
return x;
}
inline uint32_t random_teensy(uint32_t howbig) {
if (howbig == 0)
return 0;
return random_teensy() % howbig;
}
inline int32_t random_teensy(int32_t howsmall, int32_t howbig) {
if (howsmall >= howbig)
return howsmall;
int32_t diff = howbig - howsmall;
return random_teensy(diff) + howsmall;
}
}
class AudioSynthNoiseWhiteFloat : public AudioStream {
public:
AudioSynthNoiseWhiteFloat() : AudioStream(0) { }
void amplitude(float level) {
level_ = level;
}
// uniform on [-1, 1]
float process() {
return level_ * ((rand31pm_next() / 2147483647.0) * 2.f - 1.f);
}
// uniform on [0, 1]
float processNonnegative() {
return level_ * (rand31pm_next() / 2147483647.0);
}
long unsigned int rand31pm_next() {
double const a = 16807;
double const m = 2147483647.0 ;
return (seed31pm = (long)(fmod((seed31pm * a), m)));
}
private:
float level_ = 1.0;
long unsigned int seed31pm = 1;
};
class AudioSynthNoiseGritFloat : public AudioStream {
public:
AudioSynthNoiseGritFloat() : AudioStream(0) { }
void setDensity(float density) {
density_ = density;
}
float process(float sampleTime) {
float threshold = density_ * sampleTime;
float scale = threshold > 0.f ? 2.f / threshold : 0.f;
float z = white.processNonnegative();
if (z < threshold) {
return z * scale - 1.0f;
}
else {
return 0.f;
}
}
private:
float density_ = 0.f;
AudioSynthNoiseWhiteFloat white;
};

+ 356
- 0
src/noise-plethora/teensy/dspinst.h View File

@@ -0,0 +1,356 @@
/* Audio Library for Teensy 3.X
* Copyright (c) 2014, Paul Stoffregen, paul@pjrc.com
*
* Development of this audio library was funded by PJRC.COM, LLC by sales of
* Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop
* open source software by purchasing Teensy or other PJRC products.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice, development funding notice, and this permission
* notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#ifndef dspinst_h_
#define dspinst_h_

#include <stdint.h>

#define KINETISL

static inline float int16_to_float_1v(const int16_t& toConvert) {
return toConvert / 32767.f;
}

// computes limit((val >> rshift), 2**bits)
static inline int32_t signed_saturate_rshift(int32_t val, int bits, int rshift) __attribute__((always_inline, unused));
static inline int32_t signed_saturate_rshift(int32_t val, int bits, int rshift) {
#if defined (__ARM_ARCH_7EM__)
int32_t out;
asm volatile("ssat %0, %1, %2, asr %3" : "=r"(out) : "I"(bits), "r"(val), "I"(rshift));
return out;
#elif defined(KINETISL)
int32_t out, max;
out = val >> rshift;
max = 1 << (bits - 1);
if (out >= 0) {
if (out > max - 1)
out = max - 1;
}
else {
if (out < -max)
out = -max;
}
return out;
#endif
}

// computes limit(val, 2**bits)
static inline int16_t saturate16(int32_t val) __attribute__((always_inline, unused));
static inline int16_t saturate16(int32_t val) {
#if defined (__ARM_ARCH_7EM__)
int16_t out;
int32_t tmp;
asm volatile("ssat %0, %1, %2" : "=r"(tmp) : "I"(16), "r"(val));
out = (int16_t)(tmp);
return out;
#else
if (val > 32767)
val = 32767;
else if (val < -32768)
val = -32768;
return val;
#endif
}

// computes ((a[31:0] * b[15:0]) >> 16)
static inline int32_t signed_multiply_32x16b(int32_t a, uint32_t b) __attribute__((always_inline, unused));
static inline int32_t signed_multiply_32x16b(int32_t a, uint32_t b) {
#if defined (__ARM_ARCH_7EM__)
int32_t out;
asm volatile("smulwb %0, %1, %2" : "=r"(out) : "r"(a), "r"(b));
return out;
#elif defined(KINETISL)
return ((int64_t)a * (int16_t)(b & 0xFFFF)) >> 16;
#endif
}

// computes ((a[31:0] * b[31:16]) >> 16)
static inline int32_t signed_multiply_32x16t(int32_t a, uint32_t b) __attribute__((always_inline, unused));
static inline int32_t signed_multiply_32x16t(int32_t a, uint32_t b) {
#if defined (__ARM_ARCH_7EM__)
int32_t out;
asm volatile("smulwt %0, %1, %2" : "=r"(out) : "r"(a), "r"(b));
return out;
#elif defined(KINETISL)
return ((int64_t)a * (int16_t)(b >> 16)) >> 16;
#endif
}

// computes (((int64_t)a[31:0] * (int64_t)b[31:0]) >> 32)
static inline int32_t multiply_32x32_rshift32(int32_t a, int32_t b) __attribute__((always_inline, unused));
static inline int32_t multiply_32x32_rshift32(int32_t a, int32_t b) {
#if defined (__ARM_ARCH_7EM__)
int32_t out;
asm volatile("smmul %0, %1, %2" : "=r"(out) : "r"(a), "r"(b));
return out;
#elif defined(KINETISL)
return ((int64_t)a * (int64_t)b) >> 32;
#endif
}

// computes (((int64_t)a[31:0] * (int64_t)b[31:0] + 0x8000000) >> 32)
static inline int32_t multiply_32x32_rshift32_rounded(int32_t a, int32_t b) __attribute__((always_inline, unused));
static inline int32_t multiply_32x32_rshift32_rounded(int32_t a, int32_t b) {
#if defined (__ARM_ARCH_7EM__)
int32_t out;
asm volatile("smmulr %0, %1, %2" : "=r"(out) : "r"(a), "r"(b));
return out;
#elif defined(KINETISL)
return (((int64_t)a * (int64_t)b) + 0x8000000) >> 32;
#endif
}

// computes sum + (((int64_t)a[31:0] * (int64_t)b[31:0] + 0x8000000) >> 32)
static inline int32_t multiply_accumulate_32x32_rshift32_rounded(int32_t sum, int32_t a, int32_t b) __attribute__((always_inline, unused));
static inline int32_t multiply_accumulate_32x32_rshift32_rounded(int32_t sum, int32_t a, int32_t b) {
#if defined (__ARM_ARCH_7EM__)
int32_t out;
asm volatile("smmlar %0, %2, %3, %1" : "=r"(out) : "r"(sum), "r"(a), "r"(b));
return out;
#elif defined(KINETISL)
return sum + ((((int64_t)a * (int64_t)b) + 0x8000000) >> 32);
#endif
}

// computes sum - (((int64_t)a[31:0] * (int64_t)b[31:0] + 0x8000000) >> 32)
static inline int32_t multiply_subtract_32x32_rshift32_rounded(int32_t sum, int32_t a, int32_t b) __attribute__((always_inline, unused));
static inline int32_t multiply_subtract_32x32_rshift32_rounded(int32_t sum, int32_t a, int32_t b) {
#if defined (__ARM_ARCH_7EM__)
int32_t out;
asm volatile("smmlsr %0, %2, %3, %1" : "=r"(out) : "r"(sum), "r"(a), "r"(b));
return out;
#elif defined(KINETISL)
return sum - ((((int64_t)a * (int64_t)b) + 0x8000000) >> 32);
#endif
}


// computes (a[31:16] | (b[31:16] >> 16))
static inline uint32_t pack_16t_16t(int32_t a, int32_t b) __attribute__((always_inline, unused));
static inline uint32_t pack_16t_16t(int32_t a, int32_t b) {
#if defined (__ARM_ARCH_7EM__)
int32_t out;
asm volatile("pkhtb %0, %1, %2, asr #16" : "=r"(out) : "r"(a), "r"(b));
return out;
#elif defined(KINETISL)
return (a & 0xFFFF0000) | ((uint32_t)b >> 16);
#endif
}

// computes (a[31:16] | b[15:0])
static inline uint32_t pack_16t_16b(int32_t a, int32_t b) __attribute__((always_inline, unused));
static inline uint32_t pack_16t_16b(int32_t a, int32_t b) {
#if defined (__ARM_ARCH_7EM__)
int32_t out;
asm volatile("pkhtb %0, %1, %2" : "=r"(out) : "r"(a), "r"(b));
return out;
#elif defined(KINETISL)
return (a & 0xFFFF0000) | (b & 0x0000FFFF);
#endif
}

// computes ((a[15:0] << 16) | b[15:0])
static inline uint32_t pack_16b_16b(int32_t a, int32_t b) __attribute__((always_inline, unused));
static inline uint32_t pack_16b_16b(int32_t a, int32_t b) {
#if defined (__ARM_ARCH_7EM__)
int32_t out;
asm volatile("pkhbt %0, %1, %2, lsl #16" : "=r"(out) : "r"(b), "r"(a));
return out;
#elif defined(KINETISL)
return (a << 16) | (b & 0x0000FFFF);
#endif
}

// computes ((a[15:0] << 16) | b[15:0])
/*
static inline uint32_t pack_16x16(int32_t a, int32_t b) __attribute__((always_inline, unused));
static inline uint32_t pack_16x16(int32_t a, int32_t b)
{
int32_t out;
asm volatile("pkhbt %0, %1, %2, lsl #16" : "=r" (out) : "r" (b), "r" (a));
return out;
}
*/
#if defined (__ARM_ARCH_7EM__)
// computes (((a[31:16] + b[31:16]) << 16) | (a[15:0 + b[15:0])) (saturates)
static inline uint32_t signed_add_16_and_16(uint32_t a, uint32_t b) __attribute__((always_inline, unused));
static inline uint32_t signed_add_16_and_16(uint32_t a, uint32_t b) {
int32_t out;
asm volatile("qadd16 %0, %1, %2" : "=r"(out) : "r"(a), "r"(b));
return out;
}

// computes (((a[31:16] - b[31:16]) << 16) | (a[15:0 - b[15:0])) (saturates)
static inline int32_t signed_subtract_16_and_16(int32_t a, int32_t b) __attribute__((always_inline, unused));
static inline int32_t signed_subtract_16_and_16(int32_t a, int32_t b) {
int32_t out;
asm volatile("qsub16 %0, %1, %2" : "=r"(out) : "r"(a), "r"(b));
return out;
}

// computes out = (((a[31:16]+b[31:16])/2) <<16) | ((a[15:0]+b[15:0])/2)
static inline int32_t signed_halving_add_16_and_16(int32_t a, int32_t b) __attribute__((always_inline, unused));
static inline int32_t signed_halving_add_16_and_16(int32_t a, int32_t b) {
int32_t out;
asm volatile("shadd16 %0, %1, %2" : "=r"(out) : "r"(a), "r"(b));
return out;
}

// computes out = (((a[31:16]-b[31:16])/2) <<16) | ((a[15:0]-b[15:0])/2)
static inline int32_t signed_halving_subtract_16_and_16(int32_t a, int32_t b) __attribute__((always_inline, unused));
static inline int32_t signed_halving_subtract_16_and_16(int32_t a, int32_t b) {
int32_t out;
asm volatile("shsub16 %0, %1, %2" : "=r"(out) : "r"(a), "r"(b));
return out;
}

// computes (sum + ((a[31:0] * b[15:0]) >> 16))
static inline int32_t signed_multiply_accumulate_32x16b(int32_t sum, int32_t a, uint32_t b) __attribute__((always_inline, unused));
static inline int32_t signed_multiply_accumulate_32x16b(int32_t sum, int32_t a, uint32_t b) {
int32_t out;
asm volatile("smlawb %0, %2, %3, %1" : "=r"(out) : "r"(sum), "r"(a), "r"(b));
return out;
}

// computes (sum + ((a[31:0] * b[31:16]) >> 16))
static inline int32_t signed_multiply_accumulate_32x16t(int32_t sum, int32_t a, uint32_t b) __attribute__((always_inline, unused));
static inline int32_t signed_multiply_accumulate_32x16t(int32_t sum, int32_t a, uint32_t b) {
int32_t out;
asm volatile("smlawt %0, %2, %3, %1" : "=r"(out) : "r"(sum), "r"(a), "r"(b));
return out;
}

// computes logical and, forces compiler to allocate register and use single cycle instruction
static inline uint32_t logical_and(uint32_t a, uint32_t b) __attribute__((always_inline, unused));
static inline uint32_t logical_and(uint32_t a, uint32_t b) {
asm volatile("and %0, %1" : "+r"(a) : "r"(b));
return a;
}

// computes ((a[15:0] * b[15:0]) + (a[31:16] * b[31:16]))
static inline int32_t multiply_16tx16t_add_16bx16b(uint32_t a, uint32_t b) __attribute__((always_inline, unused));
static inline int32_t multiply_16tx16t_add_16bx16b(uint32_t a, uint32_t b) {
int32_t out;
asm volatile("smuad %0, %1, %2" : "=r"(out) : "r"(a), "r"(b));
return out;
}

// computes ((a[15:0] * b[31:16]) + (a[31:16] * b[15:0]))
static inline int32_t multiply_16tx16b_add_16bx16t(uint32_t a, uint32_t b) __attribute__((always_inline, unused));
static inline int32_t multiply_16tx16b_add_16bx16t(uint32_t a, uint32_t b) {
int32_t out;
asm volatile("smuadx %0, %1, %2" : "=r"(out) : "r"(a), "r"(b));
return out;
}

// // computes sum += ((a[15:0] * b[15:0]) + (a[31:16] * b[31:16]))
static inline int64_t multiply_accumulate_16tx16t_add_16bx16b(int64_t sum, uint32_t a, uint32_t b) {
asm volatile("smlald %Q0, %R0, %1, %2" : "+r"(sum) : "r"(a), "r"(b));
return sum;
}

// // computes sum += ((a[15:0] * b[31:16]) + (a[31:16] * b[15:0]))
static inline int64_t multiply_accumulate_16tx16b_add_16bx16t(int64_t sum, uint32_t a, uint32_t b) {
asm volatile("smlaldx %Q0, %R0, %1, %2" : "+r"(sum) : "r"(a), "r"(b));
return sum;
}

// computes ((a[15:0] * b[15:0])
static inline int32_t multiply_16bx16b(uint32_t a, uint32_t b) __attribute__((always_inline, unused));
static inline int32_t multiply_16bx16b(uint32_t a, uint32_t b) {
int32_t out;
asm volatile("smulbb %0, %1, %2" : "=r"(out) : "r"(a), "r"(b));
return out;
}

// computes ((a[15:0] * b[31:16])
static inline int32_t multiply_16bx16t(uint32_t a, uint32_t b) __attribute__((always_inline, unused));
static inline int32_t multiply_16bx16t(uint32_t a, uint32_t b) {
int32_t out;
asm volatile("smulbt %0, %1, %2" : "=r"(out) : "r"(a), "r"(b));
return out;
}

// computes ((a[31:16] * b[15:0])
static inline int32_t multiply_16tx16b(uint32_t a, uint32_t b) __attribute__((always_inline, unused));
static inline int32_t multiply_16tx16b(uint32_t a, uint32_t b) {
int32_t out;
asm volatile("smultb %0, %1, %2" : "=r"(out) : "r"(a), "r"(b));
return out;
}

// computes ((a[31:16] * b[31:16])
static inline int32_t multiply_16tx16t(uint32_t a, uint32_t b) __attribute__((always_inline, unused));
static inline int32_t multiply_16tx16t(uint32_t a, uint32_t b) {
int32_t out;
asm volatile("smultt %0, %1, %2" : "=r"(out) : "r"(a), "r"(b));
return out;
}

// computes (a - b), result saturated to 32 bit integer range
static inline int32_t substract_32_saturate(uint32_t a, uint32_t b) __attribute__((always_inline, unused));
static inline int32_t substract_32_saturate(uint32_t a, uint32_t b) {
int32_t out;
asm volatile("qsub %0, %1, %2" : "=r"(out) : "r"(a), "r"(b));
return out;
}

// Multiply two S.31 fractional integers, and return the 32 most significant
// bits after a shift left by the constant z.
// This comes from rockbox.org

static inline int32_t FRACMUL_SHL(int32_t x, int32_t y, int z) {
int32_t t, t2;
asm("smull %[t], %[t2], %[a], %[b]\n\t"
"mov %[t2], %[t2], asl %[c]\n\t"
"orr %[t], %[t2], %[t], lsr %[d]\n\t"
: [t] "=&r"(t), [t2] "=&r"(t2)
: [a] "r"(x), [b] "r"(y),
[c] "Mr"((z) + 1), [d] "Mr"(31 - (z)));
return t;
}

#endif

//get Q from PSR
static inline uint32_t get_q_psr(void) __attribute__((always_inline, unused));
static inline uint32_t get_q_psr(void) {
uint32_t out;
asm("mrs %0, APSR" : "=r"(out));
return (out & 0x8000000) >> 27;
}

//clear Q BIT in PSR
static inline void clr_q_psr(void) __attribute__((always_inline, unused));
static inline void clr_q_psr(void) {
uint32_t t;
asm("mov %[t],#0\n"
"msr APSR_nzcvq,%0\n" : [t] "=&r"(t)::"cc");
}


#endif

+ 90
- 0
src/noise-plethora/teensy/effect_bitcrusher.cpp View File

@@ -0,0 +1,90 @@
/* Audio Library for Teensy 3.X
* Copyright (c) 2014, Jonathan Payne (jon@jonnypayne.com)
* Based on Effect_Fade by Paul Stoffregen
* Also samplerate reduction based on Pete Brown's bitcrusher here:
* http://10rem.net/blog/2013/01/13/a-simple-bitcrusher-and-sample-rate-reducer-in-cplusplus-for-a-windows-store-app
*
* Development of this audio library was funded by PJRC.COM, LLC by sales of
* Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop
* open source software by purchasing Teensy or other PJRC products.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice, development funding notice, and this permission
* notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#include "effect_bitcrusher.h"

void AudioEffectBitcrusher::update(const audio_block_t* inputBlock, audio_block_t* outputBlock) {
uint32_t i;
uint32_t sampleSquidge, sampleSqueeze; //squidge is bitdepth, squeeze is for samplerate

if (!inputBlock || !outputBlock) {
return;
}

if (crushBits == 16 && sampleStep <= 1) {
// nothing to do. Output is sent through clean, then exit the function
audio_block_t::copyBlock(inputBlock, outputBlock);
}

if (sampleStep <= 1) { //no sample rate mods, just crush the bitdepth.
for (i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {
// shift bits right to cut off fine detail sampleSquidge is a
// uint32 so sign extension will not occur, fills with zeroes.
sampleSquidge = inputBlock->data[i] >> (16 - crushBits);
// shift bits left again to regain the volume level.
// fills with zeroes.
outputBlock->data[i] = sampleSquidge << (16 - crushBits);
}
}
else if (crushBits == 16) { //bitcrusher not being used, samplerate mods only.
i = 0;
while (i < AUDIO_BLOCK_SAMPLES) {
// save the root sample. this will pick up a root
// sample every _sampleStep_ samples.
sampleSqueeze = inputBlock->data[i];
for (int j = 0; j < sampleStep && i < AUDIO_BLOCK_SAMPLES; j++) {
// for each repeated sample, paste in the current
// root sample, then move onto the next step.
outputBlock->data[i] = sampleSqueeze;
i++;
}
}
}
else { //both being used. crush those bits and mash those samples.
i = 0;
while (i < AUDIO_BLOCK_SAMPLES) {
// save the root sample. this will pick up a root sample
// every _sampleStep_ samples.
sampleSqueeze = inputBlock->data[i];
for (int j = 0; j < sampleStep && i < AUDIO_BLOCK_SAMPLES; j++) {
// shift bits right to cut off fine detail sampleSquidge
// is a uint32 so sign extension will not occur, fills
// with zeroes.
sampleSquidge = sampleSqueeze >> (16 - crushBits);
// shift bits left again to regain the volume level.
// fills with zeroes. paste into buffer sample +
// sampleStep offset.
outputBlock->data[i] = sampleSquidge << (16 - crushBits);
i++;
}
}
}
}



+ 58
- 0
src/noise-plethora/teensy/effect_bitcrusher.h View File

@@ -0,0 +1,58 @@
/* Audio Library for Teensy 3.X
* Copyright (c) 2014, Jonathan Payne (jon@jonnypayne.com)
* Based on Effect_Fade by Paul Stoffregen

* Development of this audio library was funded by PJRC.COM, LLC by sales of
* Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop
* open source software by purchasing Teensy or other PJRC products.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice, development funding notice, and this permission
* notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#pragma once

#include "audio_core.hpp"

class AudioEffectBitcrusher : public AudioStream {
public:
AudioEffectBitcrusher(void)
: AudioStream(1) {}
void bits(uint8_t b) {
if (b > 16)
b = 16;
else if (b == 0)
b = 1;
crushBits = b;
}
void sampleRate(float hz) {
// modification to account for Rack sample rate
int n = (APP->engine->getSampleRate() / hz) + 0.5f;
if (n < 1)
n = 1;
else if (n > 64)
n = 64;
sampleStep = n;
}
virtual void update(const audio_block_t* inputBlock, audio_block_t* block);

private:
uint8_t crushBits; // 16 = off
uint8_t sampleStep; // the number of samples to double up. This simple technique only allows a few stepped positions.
};


+ 72
- 0
src/noise-plethora/teensy/effect_combine.cpp View File

@@ -0,0 +1,72 @@
/* Copyright (c) 2018 John-Michael Reed
* bleeplabs.com
*
* Development of this audio library was funded by PJRC.COM, LLC by sales of
* Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop
* open source software by purchasing Teensy or other PJRC products.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice, development funding notice, and this permission
* notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* Combine analog signals with bitwise expressions like XOR.
* Combining two simple oscillators results in interesting new waveforms,
* Combining white noise or dynamic incoming audio results in aggressive digital distortion.
*/

#include "effect_combine.hpp"


void AudioEffectDigitalCombine::update(const audio_block_t* blocka, const audio_block_t* blockb, audio_block_t* output) {
uint32_t* pa, *pb, *end, *pout;
uint32_t a12, a34; //, a56, a78;
uint32_t b12, b34; //, b56, b78;

if (!blocka || !blockb || !output) {
return;
}

pa = (uint32_t*)(blocka->data);
pb = (uint32_t*)(blockb->data);
pout = (uint32_t*)(output->data);
end = pa + AUDIO_BLOCK_SAMPLES / 2;

while (pa < end) {
a12 = *pa++;
a34 = *pa++;
b12 = *pb++;
b34 = *pb++;
if (mode_sel == OR) {
a12 = a12 | b12;
a34 = a34 | b34;
}
if (mode_sel == XOR) {
a12 = a12 ^ b12;
a34 = a34 ^ b34;
}
if (mode_sel == AND) {
a12 = a12 & b12;
a34 = a34 & b34;
}
if (mode_sel == MODULO) {
a12 = a12 % b12;
a34 = a34 % b34;
}
*pout++ = a12;
*pout++ = a34;
}
}

+ 53
- 0
src/noise-plethora/teensy/effect_combine.hpp View File

@@ -0,0 +1,53 @@
/* Copyright (c) 2018 John-Michael Reed
* bleeplabs.com
*
* Development of this audio library was funded by PJRC.COM, LLC by sales of
* Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop
* open source software by purchasing Teensy or other PJRC products.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice, development funding notice, and this permission
* notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* Combine analog signals with bitwise expressions like XOR.
* Combining two simple oscillators results in interesting new waveforms,
* Combining white noise or dynamic incoming audio results in aggressive digital distortion.
*/

#pragma once

#include "audio_core.hpp"

class AudioEffectDigitalCombine : public AudioStream {
public:
enum combineMode {
OR = 0,
XOR = 1,
AND = 2,
MODULO = 3,
};
AudioEffectDigitalCombine() : AudioStream(2), mode_sel(OR) { }
void setCombineMode(int mode_in) {
if (mode_in > 3) {
mode_in = 3;
}
mode_sel = mode_in;
}
virtual void update(const audio_block_t* blocka, const audio_block_t* blockb, audio_block_t* output);
private:
short mode_sel;
};

+ 228
- 0
src/noise-plethora/teensy/effect_flange.cpp View File

@@ -0,0 +1,228 @@
/* Audio Library for Teensy 3.X
* Copyright (c) 2014, Pete (El Supremo)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/


#include "effect_flange.h"


int16_t sin16_C(uint16_t theta) {
static const uint16_t base[] =
{ 0, 6393, 12539, 18204, 23170, 27245, 30273, 32137 };
static const uint8_t slope[] =
{ 49, 48, 44, 38, 31, 23, 14, 4 };

uint16_t offset = (theta & 0x3FFF) >> 3; // 0..2047
if (theta & 0x4000)
offset = 2047 - offset;

uint8_t section = offset / 256; // 0..7
uint16_t b = base[section];
uint8_t m = slope[section];

uint8_t secoffset8 = (uint8_t)(offset) / 2;

uint16_t mx = m * secoffset8;
int16_t y = mx + b;

if (theta & 0x8000)
y = -y;

return y;
}

/******************************************************************/
// A u d i o E f f e c t F l a n g e
// Written by Pete (El Supremo) Jan 2014
// 140529 - change to handle mono stream and change modify() to voices()
// 140207 - fix calculation of delay_rate_incr which is expressed as
// a fraction of 2*PI
// 140207 - cosmetic fix to begin()
// 140219 - correct the calculation of "frac"

// circular addressing indices for left and right channels
//short AudioEffectFlange::l_circ_idx;
//short AudioEffectFlange::r_circ_idx;

//short * AudioEffectFlange::l_delayline = NULL;
//short * AudioEffectFlange::r_delayline = NULL;

// User-supplied offset for the delayed sample
// but start with passthru
//int AudioEffectFlange::delay_offset_idx = FLANGE_DELAY_PASSTHRU;
//int AudioEffectFlange::delay_length;

//int AudioEffectFlange::delay_depth;
//int AudioEffectFlange::delay_rate_incr;
//unsigned int AudioEffectFlange::l_delay_rate_index;
//unsigned int AudioEffectFlange::r_delay_rate_index;
// fails if the user provides unreasonable values but will
// coerce them and go ahead anyway. e.g. if the delay offset
// is >= CHORUS_DELAY_LENGTH, the code will force it to
// CHORUS_DELAY_LENGTH-1 and return false.
// delay_rate is the rate (in Hz) of the sine wave modulation
// delay_depth is the maximum variation around delay_offset
// i.e. the total offset is delay_offset + delay_depth * sin(delay_rate)
bool AudioEffectFlange::begin(short* delayline, int d_length, int delay_offset, int d_depth, float delay_rate) {
bool all_ok = true;

delay_length = d_length / 2;
l_delayline = delayline;

delay_depth = d_depth;
// initial index
l_delay_rate_index = 0;
l_circ_idx = 0;
delay_rate_incr = (delay_rate * 2147483648.0) / APP->engine->getSampleRate();


delay_offset_idx = delay_offset;
// Allow the passthru code to go through
if (delay_offset_idx < -1) {
delay_offset_idx = 0;
all_ok = false;
}
if (delay_offset_idx >= delay_length) {
delay_offset_idx = delay_length - 1;
all_ok = false;
}
return (all_ok);
}


bool AudioEffectFlange::voices(int delay_offset, int d_depth, float delay_rate) {
bool all_ok = true;

delay_depth = d_depth;

delay_rate_incr = (delay_rate * 2147483648.0) / APP->engine->getSampleRate();

delay_offset_idx = delay_offset;
// Allow the passthru code to go through
if (delay_offset_idx < -1) {
delay_offset_idx = 0;
all_ok = false;
}
if (delay_offset_idx >= delay_length) {
delay_offset_idx = delay_length - 1;
all_ok = false;
}
l_delay_rate_index = 0;
l_circ_idx = 0;
return (all_ok);
}

void AudioEffectFlange::update(const audio_block_t* inputBlock, audio_block_t* outputBlock) {

int idx;
const short* inbp;
short* outbp;
short frac;
int idx1;

if (l_delayline == NULL)
return;

// do passthru
if (delay_offset_idx == FLANGE_DELAY_PASSTHRU) {
// Just passthrough

if (inputBlock) {
inbp = inputBlock->data;
// fill the delay line
for (int i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {
l_circ_idx++;
if (l_circ_idx >= delay_length) {
l_circ_idx = 0;
}
l_delayline[l_circ_idx] = *inbp++;
}
// transmit the unmodified block
audio_block_t::copyBlock(inputBlock, outputBlock);
}
return;
}

// L E F T C H A N N E L
if (inputBlock && outputBlock) {
inbp = inputBlock->data;
outbp = outputBlock->data;
for (int i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {
// increment the index into the circular delay line buffer
l_circ_idx++;
// wrap the index around if necessary
if (l_circ_idx >= delay_length) {
l_circ_idx = 0;
}
// store the current sample in the delay line
l_delayline[l_circ_idx] = *inbp++;
// The argument to the arm_sin_q15 function is NOT in radians. It is
// actually, in effect, the fraction remaining after the division
// of radians/(2*PI) which is then expressed as a positive Q15
// fraction in the interval [0 , +1) - this is l_delay_rate_index.
// l_delay_rate_index should probably be called l_delay_rate_phase
// (sorry about that!)
// It is a Q31 positive number of which the high order 16 bits are
// used when calculating the sine. idx will have a value in the
// interval [-1 , +1)
frac = sin16_C(((l_delay_rate_index >> 16) & 0x7fff));
// multiply the sin by the delay depth
idx = (frac * delay_depth) >> 15;
//Serial.println(idx);
// Calculate the offset into the buffer
idx = l_circ_idx - (delay_offset_idx + idx);
// and adjust idx to point into the circular buffer
if (idx < 0) {
idx += delay_length;
}
if (idx >= delay_length) {
idx -= delay_length;
}

// Here we interpolate between two indices but if the sine was negative
// then we interpolate between idx and idx-1, otherwise the
// interpolation is between idx and idx+1
if (frac < 0)
idx1 = idx - 1;
else
idx1 = idx + 1;
// adjust idx1 in the circular buffer
if (idx1 < 0) {
idx1 += delay_length;
}
if (idx1 >= delay_length) {
idx1 -= delay_length;
}
// Do the interpolation
frac = (l_delay_rate_index >> 1) & 0x7fff;
frac = (((int)(l_delayline[idx1] - l_delayline[idx]) * frac) >> 15);
*outbp++ = (l_delayline[l_circ_idx] + l_delayline[idx] + frac) / 2;

l_delay_rate_index += delay_rate_incr;
if (l_delay_rate_index & 0x80000000) {
l_delay_rate_index &= 0x7fffffff;
}
}
}
}




+ 53
- 0
src/noise-plethora/teensy/effect_flange.h View File

@@ -0,0 +1,53 @@
/* Audio Library for Teensy 3.X
* Copyright (c) 2014, Pete (El Supremo)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#pragma once
#include "audio_core.hpp"

/******************************************************************/
// A u d i o E f f e c t F l a n g e
// Written by Pete (El Supremo) Jan 2014
// 140529 - change to handle mono stream and change modify() to voices()

#define FLANGE_DELAY_PASSTHRU 0

class AudioEffectFlange :
public AudioStream {
public:
AudioEffectFlange(void):
AudioStream(1) {
}

bool begin(short* delayline, int d_length, int delay_offset, int d_depth, float delay_rate);
bool voices(int delay_offset, int d_depth, float delay_rate);
virtual void update(const audio_block_t* inputBlock, audio_block_t* outputBlock);

private:

short* l_delayline;
int delay_length;
short l_circ_idx;
int delay_depth;
int delay_offset_idx;
int delay_rate_incr;
unsigned int l_delay_rate_index;
};

+ 193
- 0
src/noise-plethora/teensy/effect_freeverb.cpp View File

@@ -0,0 +1,193 @@
/* Audio Library for Teensy 3.X
* Copyright (c) 2018, Paul Stoffregen, paul@pjrc.com
*
* Development of this audio library was funded by PJRC.COM, LLC by sales of
* Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop
* open source software by purchasing Teensy or other PJRC products.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice, development funding notice, and this permission
* notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
// A fixed point implementation of Freeverb by Jezar at Dreampoint
// http://blog.bjornroche.com/2012/06/freeverb-original-public-domain-code-by.html
// https://music.columbia.edu/pipermail/music-dsp/2001-October/045433.html
#include "effect_freeverb.hpp"
AudioEffectFreeverb::AudioEffectFreeverb() : AudioStream(1) {
memset(comb1buf, 0, sizeof(comb1buf));
memset(comb2buf, 0, sizeof(comb2buf));
memset(comb3buf, 0, sizeof(comb3buf));
memset(comb4buf, 0, sizeof(comb4buf));
memset(comb5buf, 0, sizeof(comb5buf));
memset(comb6buf, 0, sizeof(comb6buf));
memset(comb7buf, 0, sizeof(comb7buf));
memset(comb8buf, 0, sizeof(comb8buf));
comb1index = 0;
comb2index = 0;
comb3index = 0;
comb4index = 0;
comb5index = 0;
comb6index = 0;
comb7index = 0;
comb8index = 0;
comb1filter = 0;
comb2filter = 0;
comb3filter = 0;
comb4filter = 0;
comb5filter = 0;
comb6filter = 0;
comb7filter = 0;
comb8filter = 0;
combdamp1 = 6553;
combdamp2 = 26215;
combfeeback = 27524;
memset(allpass1buf, 0, sizeof(allpass1buf));
memset(allpass2buf, 0, sizeof(allpass2buf));
memset(allpass3buf, 0, sizeof(allpass3buf));
memset(allpass4buf, 0, sizeof(allpass4buf));
allpass1index = 0;
allpass2index = 0;
allpass3index = 0;
allpass4index = 0;
}
// cleaner sat16 by http://www.moseleyinstruments.com/
__attribute__((unused))
static int16_t sat16(int32_t n, int rshift) {
// we should always round towards 0
// to avoid recirculating round-off noise
//
// a 2s complement positive number is always
// rounded down, so we only need to take
// care of negative numbers
if (n < 0) {
n = n + (~(0xFFFFFFFFUL << rshift));
}
n = n >> rshift;
if (n > 32767) {
return 32767;
}
if (n < -32768) {
return -32768;
}
return n;
}
void AudioEffectFreeverb::update(const audio_block_t* block, audio_block_t* outblock) {
int i;
int16_t input, bufout, output;
int32_t sum;
if (!block || !outblock) {
return;
}
for (i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {
// TODO: scale numerical range depending on roomsize & damping
input = sat16(block->data[i] * 8738, 17); // for numerical headroom
sum = 0;
bufout = comb1buf[comb1index];
sum += bufout;
comb1filter = sat16(bufout * combdamp2 + comb1filter * combdamp1, 15);
comb1buf[comb1index] = sat16(input + sat16(comb1filter * combfeeback, 15), 0);
if (++comb1index >= sizeof(comb1buf) / sizeof(int16_t))
comb1index = 0;
bufout = comb2buf[comb2index];
sum += bufout;
comb2filter = sat16(bufout * combdamp2 + comb2filter * combdamp1, 15);
comb2buf[comb2index] = sat16(input + sat16(comb2filter * combfeeback, 15), 0);
if (++comb2index >= sizeof(comb2buf) / sizeof(int16_t))
comb2index = 0;
bufout = comb3buf[comb3index];
sum += bufout;
comb3filter = sat16(bufout * combdamp2 + comb3filter * combdamp1, 15);
comb3buf[comb3index] = sat16(input + sat16(comb3filter * combfeeback, 15), 0);
if (++comb3index >= sizeof(comb3buf) / sizeof(int16_t))
comb3index = 0;
bufout = comb4buf[comb4index];
sum += bufout;
comb4filter = sat16(bufout * combdamp2 + comb4filter * combdamp1, 15);
comb4buf[comb4index] = sat16(input + sat16(comb4filter * combfeeback, 15), 0);
if (++comb4index >= sizeof(comb4buf) / sizeof(int16_t))
comb4index = 0;
bufout = comb5buf[comb5index];
sum += bufout;
comb5filter = sat16(bufout * combdamp2 + comb5filter * combdamp1, 15);
comb5buf[comb5index] = sat16(input + sat16(comb5filter * combfeeback, 15), 0);
if (++comb5index >= sizeof(comb5buf) / sizeof(int16_t))
comb5index = 0;
bufout = comb6buf[comb6index];
sum += bufout;
comb6filter = sat16(bufout * combdamp2 + comb6filter * combdamp1, 15);
comb6buf[comb6index] = sat16(input + sat16(comb6filter * combfeeback, 15), 0);
if (++comb6index >= sizeof(comb6buf) / sizeof(int16_t))
comb6index = 0;
bufout = comb7buf[comb7index];
sum += bufout;
comb7filter = sat16(bufout * combdamp2 + comb7filter * combdamp1, 15);
comb7buf[comb7index] = sat16(input + sat16(comb7filter * combfeeback, 15), 0);
if (++comb7index >= sizeof(comb7buf) / sizeof(int16_t))
comb7index = 0;
bufout = comb8buf[comb8index];
sum += bufout;
comb8filter = sat16(bufout * combdamp2 + comb8filter * combdamp1, 15);
comb8buf[comb8index] = sat16(input + sat16(comb8filter * combfeeback, 15), 0);
if (++comb8index >= sizeof(comb8buf) / sizeof(int16_t))
comb8index = 0;
output = sat16(sum * 31457, 17);
bufout = allpass1buf[allpass1index];
allpass1buf[allpass1index] = output + (bufout >> 1);
output = sat16(bufout - output, 1);
if (++allpass1index >= sizeof(allpass1buf) / sizeof(int16_t))
allpass1index = 0;
bufout = allpass2buf[allpass2index];
allpass2buf[allpass2index] = output + (bufout >> 1);
output = sat16(bufout - output, 1);
if (++allpass2index >= sizeof(allpass2buf) / sizeof(int16_t))
allpass2index = 0;
bufout = allpass3buf[allpass3index];
allpass3buf[allpass3index] = output + (bufout >> 1);
output = sat16(bufout - output, 1);
if (++allpass3index >= sizeof(allpass3buf) / sizeof(int16_t))
allpass3index = 0;
bufout = allpass4buf[allpass4index];
allpass4buf[allpass4index] = output + (bufout >> 1);
output = sat16(bufout - output, 1);
if (++allpass4index >= sizeof(allpass4buf) / sizeof(int16_t))
allpass4index = 0;
outblock->data[i] = sat16(output * 30, 0);
}
}

+ 90
- 0
src/noise-plethora/teensy/effect_freeverb.hpp View File

@@ -0,0 +1,90 @@
/* Audio Library for Teensy 3.X
* Copyright (c) 2018, Paul Stoffregen, paul@pjrc.com
*
* Development of this audio library was funded by PJRC.COM, LLC by sales of
* Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop
* open source software by purchasing Teensy or other PJRC products.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice, development funding notice, and this permission
* notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#pragma once
#include "audio_core.hpp"
class AudioEffectFreeverb : public AudioStream {
public:
AudioEffectFreeverb();
virtual void update(const audio_block_t* block, audio_block_t* outblock);
void roomsize(float n) {
if (n > 1.0f)
n = 1.0f;
else if (n < 0.0f)
n = 0.0f;
combfeeback = (int)(n * 9175.04f) + 22937;
}
void damping(float n) {
if (n > 1.0f)
n = 1.0f;
else if (n < 0.0f)
n = 0.0f;
int x1 = (int)(n * 13107.2f);
int x2 = 32768 - x1;
//__disable_irq();
combdamp1 = x1;
combdamp2 = x2;
//__enable_irq();
}
private:
int16_t comb1buf[1116];
int16_t comb2buf[1188];
int16_t comb3buf[1277];
int16_t comb4buf[1356];
int16_t comb5buf[1422];
int16_t comb6buf[1491];
int16_t comb7buf[1557];
int16_t comb8buf[1617];
uint16_t comb1index;
uint16_t comb2index;
uint16_t comb3index;
uint16_t comb4index;
uint16_t comb5index;
uint16_t comb6index;
uint16_t comb7index;
uint16_t comb8index;
int16_t comb1filter;
int16_t comb2filter;
int16_t comb3filter;
int16_t comb4filter;
int16_t comb5filter;
int16_t comb6filter;
int16_t comb7filter;
int16_t comb8filter;
int16_t combdamp1;
int16_t combdamp2;
int16_t combfeeback;
int16_t allpass1buf[556];
int16_t allpass2buf[441];
int16_t allpass3buf[341];
int16_t allpass4buf[225];
uint16_t allpass1index;
uint16_t allpass2index;
uint16_t allpass3index;
uint16_t allpass4index;
};

+ 222
- 0
src/noise-plethora/teensy/effect_granular.cpp View File

@@ -0,0 +1,222 @@
/*
* Copyright (c) 2018 John-Michael Reed
* bleeplabs.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/


#include "effect_granular.hpp"

void AudioEffectGranular::begin(int16_t* sample_bank_def, int16_t max_len_def) {
max_sample_len = max_len_def;
grain_mode = 0;
read_head = 0;
write_head = 0;
prev_input = 0;
playpack_rate = 65536;
accumulator = 0;
allow_len_change = true;
sample_loaded = false;
sample_bank = sample_bank_def;
}

void AudioEffectGranular::beginFreeze_int(int grain_samples) {
//__disable_irq();
grain_mode = 1;
if (grain_samples < max_sample_len) {
freeze_len = grain_samples;
}
else {
freeze_len = grain_samples;
}
sample_loaded = false;
write_en = false;
sample_req = true;
//__enable_irq();
}

void AudioEffectGranular::beginPitchShift_int(int grain_samples) {
//__disable_irq();
grain_mode = 2;
if (allow_len_change) {
if (grain_samples < 100)
grain_samples = 100;
int maximum = (max_sample_len - 1) / 3;
if (grain_samples > maximum)
grain_samples = maximum;
glitch_len = grain_samples;
}
sample_loaded = false;
write_en = false;
sample_req = true;
//__enable_irq();
}


void AudioEffectGranular::stop() {
grain_mode = 0;
allow_len_change = true;
}

void AudioEffectGranular::update(const audio_block_t* input_block, audio_block_t* output_block) {


if (sample_bank == NULL) {
/* block = receiveReadOnly(0);
if (block)
release(block);
*/
return;
}

// block = receiveWritable(0);
if (!output_block || !input_block)
return;

if (grain_mode == 0) {
// passthrough, no granular effect
memcpy(output_block->data, input_block->data, AUDIO_BLOCK_SAMPLES);

// prev_input = block->data[AUDIO_BLOCK_SAMPLES - 1];
}
else if (grain_mode == 1) {
// Freeze - sample 1 grain, then repeatedly play it back
for (int j = 0; j < AUDIO_BLOCK_SAMPLES; j++) {
if (sample_req) {
// only begin capture on zero cross
int16_t current_input = input_block->data[j];
if ((current_input < 0 && prev_input >= 0) ||
(current_input >= 0 && prev_input < 0)) {
write_en = true;
write_head = 0;
read_head = 0;
sample_req = false;
}
else {
prev_input = current_input;
}
}
if (write_en) {
sample_bank[write_head++] = input_block->data[j];
if (write_head >= freeze_len) {
sample_loaded = true;
}
if (write_head >= max_sample_len) {
write_en = false;
}
}
if (sample_loaded) {
// was "if (playpack_rate >= 0)", always true for uint
if (true) {
accumulator += playpack_rate;
read_head = accumulator >> 16;
}
if (read_head >= freeze_len) {
accumulator = 0;
read_head = 0;
}
output_block->data[j] = sample_bank[read_head];
}
}
}
else if (grain_mode == 2) {
//GLITCH SHIFT
//basic granular synth thingy
// the shorter the sample the max_sample_len the more tonal it is.
// Longer it has more definition. It's a bit roboty either way which
// is obv great and good enough for noise music.

for (int k = 0; k < AUDIO_BLOCK_SAMPLES; k++) {
// only start recording when the audio is crossing zero to minimize pops
if (sample_req) {
int16_t current_input = input_block->data[k];
if ((current_input < 0 && prev_input >= 0) ||
(current_input >= 0 && prev_input < 0)) {
write_en = true;
}
else {
prev_input = current_input;
}
}

if (write_en) {
sample_req = false;
allow_len_change = true; // Reduces noise by not allowing the
// length to change after the sample has been
// recored. Kind of not too much though
if (write_head >= glitch_len) {
write_head = 0;
sample_loaded = true;
write_en = false;
allow_len_change = false;
}
sample_bank[write_head] = input_block->data[k];
write_head++;
}

if (sample_loaded) {
//move it to the middle third of the bank.
//3 "seperate" banks are used
float fade_len = 20.00;
int16_t m2 = fade_len;

for (int m = 0; m < 2; m++) {
// I'm off by one somewhere? why is there a tick at the
// beginning of this only when it's combined with the
// fade out???? ooor am i osbserving that incorrectly
// either wait it works enough
sample_bank[m + glitch_len] = 0;
}

for (int m = 2; m < glitch_len - m2; m++) {
sample_bank[m + glitch_len] = sample_bank[m];
}

for (int m = glitch_len - m2; m < glitch_len; m++) {
// fade out the end. You can just make fadet=0
// but it's a little too daleky
float fadet = sample_bank[m] * (m2 / fade_len);
sample_bank[m + glitch_len] = (int16_t)fadet;
m2--;
}
sample_loaded = false;
prev_input = output_block->data[k];
sample_req = true;
}

accumulator += playpack_rate;
read_head = (accumulator >> 16);

if (read_head >= glitch_len) {
read_head -= glitch_len;
accumulator = 0;

for (int m = 0; m < glitch_len; m++) {
sample_bank[m + (glitch_len * 2)] = sample_bank[m + glitch_len];
// sample_bank[m + (glitch_len*2)] = (m%20)*1000;
}
}
output_block->data[k] = sample_bank[read_head + (glitch_len * 2)];
}
}
//transmit(block);
//release(block);
}


+ 77
- 0
src/noise-plethora/teensy/effect_granular.hpp View File

@@ -0,0 +1,77 @@
/*
* Copyright (c) 2018 John-Michael Reed
* bleeplabs.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#pragma once

#include "audio_core.hpp"

class AudioEffectGranular : public AudioStream {
public:
AudioEffectGranular(void): AudioStream(1) { }

void begin(int16_t* sample_bank_def, int16_t max_len_def);

void setSpeed(float ratio) {
if (ratio < 0.125f)
ratio = 0.125f;
else if (ratio > 8.0f)
ratio = 8.0f;
playpack_rate = ratio * 65536.0f + 0.499f;
}

void beginFreeze(float grain_length) {
if (grain_length <= 0.0f)
return;
beginFreeze_int(grain_length * (APP->engine->getSampleRate() * 0.001f) + 0.5f);
}

void beginPitchShift(float grain_length) {
if (grain_length <= 0.0f)
return;
beginPitchShift_int(grain_length * (APP->engine->getSampleRate() * 0.001f) + 0.5f);
}

void stop();

void update(const audio_block_t* input_block, audio_block_t* output_block);

private:

void beginFreeze_int(int grain_samples);
void beginPitchShift_int(int grain_samples);

int16_t* sample_bank;
uint32_t playpack_rate;
uint32_t accumulator;
int16_t max_sample_len;
int16_t write_head;
int16_t read_head;
int16_t grain_mode;
int16_t freeze_len;
int16_t prev_input;
int16_t glitch_len;
bool allow_len_change;
bool sample_loaded;
bool write_en;
bool sample_req;
};


+ 48
- 0
src/noise-plethora/teensy/effect_multiply.cpp View File

@@ -0,0 +1,48 @@
/* Audio Library for Teensy 3.X
* Copyright (c) 2014, Paul Stoffregen, paul@pjrc.com
*
* Development of this audio library was funded by PJRC.COM, LLC by sales of
* Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop
* open source software by purchasing Teensy or other PJRC products.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice, development funding notice, and this permission
* notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#include "effect_multiply.h"


void AudioEffectMultiply::update(const audio_block_t* blocka, const audio_block_t* blockb, audio_block_t* blockout) {

const int16_t* pa, *pb, *end;
int16_t* out = blockout->data;

if (!blocka || ! blockb || !blockout) {
return;
}

pa = (blocka->data);
pb = (blockb->data);
end = pa + AUDIO_BLOCK_SAMPLES;

while (pa < end) {
*out++ = (int16_t) signed_saturate_rshift(int32_t (*pa++) * int32_t (*pb++), 16, 15);
}

}


+ 35
- 0
src/noise-plethora/teensy/effect_multiply.h View File

@@ -0,0 +1,35 @@
/* Audio Library for Teensy 3.X
* Copyright (c) 2014, Paul Stoffregen, paul@pjrc.com
*
* Development of this audio library was funded by PJRC.COM, LLC by sales of
* Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop
* open source software by purchasing Teensy or other PJRC products.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice, development funding notice, and this permission
* notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#pragma once

#include "audio_core.hpp"

class AudioEffectMultiply : public AudioStream {
public:
AudioEffectMultiply() : AudioStream(2) { }
virtual void update(const audio_block_t* blocka, const audio_block_t* blockb, audio_block_t* blockout);
};

+ 49
- 0
src/noise-plethora/teensy/effect_wavefolder.cpp View File

@@ -0,0 +1,49 @@
/* Wavefolder effect for Teensy Audio library
*
* Copyright (c) 2020, Mark Tillotson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice, development funding notice, and this permission
* notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#include "effect_wavefolder.hpp"

void AudioEffectWaveFolder::update(const audio_block_t* blocka, const audio_block_t* blockb, audio_block_t* output) {

if (!blocka || !blockb || !output) {
return;
}

const int16_t* pa = blocka->data ;
const int16_t* pb = blockb->data ;
int16_t* po = output->data ;

for (int i = 0 ; i < AUDIO_BLOCK_SAMPLES ; i++) {
int32_t a12 = pa[i];
int32_t b12 = pb[i];

// scale upto 16 times input, so that can fold upto 16 times in each polarity
int32_t s1 = (a12 * b12 + 0x400) >> 11 ;
// if in a band where the sense needs to be reverse, detect this
bool flip1 = ((s1 + 0x8000) >> 16) & 1 ;
// reverse and truncate to 16 bits
s1 = 0xFFFF & (flip1 ? ~s1 : +s1) ;

po[i] = s1;
}
}

+ 32
- 0
src/noise-plethora/teensy/effect_wavefolder.hpp View File

@@ -0,0 +1,32 @@
/* Wavefolder effect for Teensy Audio library
*
* Copyright (c) 2020, Mark Tillotson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice, development funding notice, and this permission
* notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#pragma once

#include "audio_core.hpp"

class AudioEffectWaveFolder : public AudioStream {
public:
AudioEffectWaveFolder() : AudioStream(2) {}
virtual void update(const audio_block_t* blocka, const audio_block_t* blockb, audio_block_t* output);
};

+ 163
- 0
src/noise-plethora/teensy/filter_variable.cpp View File

@@ -0,0 +1,163 @@
/* Audio Library for Teensy 3.X
* Copyright (c) 2014, Paul Stoffregen, paul@pjrc.com
*
* Development of this audio library was funded by PJRC.COM, LLC by sales of
* Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop
* open source software by purchasing Teensy or other PJRC products.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice, development funding notice, and this permission
* notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#include "filter_variable.hpp"

// State Variable Filter (Chamberlin) with 2X oversampling
// http://www.musicdsp.org/showArchiveComment.php?ArchiveID=92

// The fast 32x32 with rshift32 discards 2 bits, which probably
// never matter.
//#define MULT(a, b) (int32_t)(((int64_t)(a) * (b)) >> 30)
#define MULT(a, b) (multiply_32x32_rshift32_rounded(a, b) << 2)

// It's very unlikely anyone could hear any difference, but if you
// care deeply about numerical precision in seldom-used cases,
// uncomment this to improve the control signal accuracy
//#define IMPROVE_HIGH_FREQUENCY_ACCURACY

// This increases the exponential approximation accuracy from
// about 0.341% error to only 0.012% error, which probably makes
// no audible difference.
//#define IMPROVE_EXPONENTIAL_ACCURACY


void AudioFilterStateVariable::update_fixed(const int16_t* in, int16_t* lp, int16_t* bp, int16_t* hp) {
const int16_t* end = in + AUDIO_BLOCK_SAMPLES;
int32_t input, inputprev;
int32_t lowpass, bandpass, highpass;
int32_t lowpasstmp, bandpasstmp, highpasstmp;
int32_t fmult, damp;

fmult = setting_fmult;
damp = setting_damp;
inputprev = state_inputprev;
lowpass = state_lowpass;
bandpass = state_bandpass;
do {
input = (*in++) << 12;
lowpass = lowpass + MULT(fmult, bandpass);
highpass = ((input + inputprev) >> 1) - lowpass - MULT(damp, bandpass);
inputprev = input;
bandpass = bandpass + MULT(fmult, highpass);
lowpasstmp = lowpass;
bandpasstmp = bandpass;
highpasstmp = highpass;
lowpass = lowpass + MULT(fmult, bandpass);
highpass = input - lowpass - MULT(damp, bandpass);
bandpass = bandpass + MULT(fmult, highpass);
lowpasstmp = signed_saturate_rshift(lowpass + lowpasstmp, 16, 13);
bandpasstmp = signed_saturate_rshift(bandpass + bandpasstmp, 16, 13);
highpasstmp = signed_saturate_rshift(highpass + highpasstmp, 16, 13);
*lp++ = lowpasstmp;
*bp++ = bandpasstmp;
*hp++ = highpasstmp;
} while (in < end);
state_inputprev = inputprev;
state_lowpass = lowpass;
state_bandpass = bandpass;
}


void AudioFilterStateVariable::update_variable(const int16_t* in, const int16_t* ctl, int16_t* lp, int16_t* bp, int16_t* hp) {
const int16_t* end = in + AUDIO_BLOCK_SAMPLES;
int32_t input, inputprev, control;
int32_t lowpass, bandpass, highpass;
int32_t lowpasstmp, bandpasstmp, highpasstmp;
int32_t fcenter, fmult, damp, octavemult;
int32_t n;

fcenter = setting_fcenter;
octavemult = setting_octavemult;
damp = setting_damp;
inputprev = state_inputprev;
lowpass = state_lowpass;
bandpass = state_bandpass;
do {
// compute fmult using control input, fcenter and octavemult
control = *ctl++; // signal is always 15 fractional bits
control *= octavemult; // octavemult range: 0 to 28671 (12 frac bits)
n = control & 0x7FFFFFF; // 27 fractional control bits
#ifdef IMPROVE_EXPONENTIAL_ACCURACY
// exp2 polynomial suggested by Stefan Stenzel on "music-dsp"
// mail list, Wed, 3 Sep 2014 10:08:55 +0200
int32_t x = n << 3;
n = multiply_accumulate_32x32_rshift32_rounded(536870912, x, 1494202713);
int32_t sq = multiply_32x32_rshift32_rounded(x, x);
n = multiply_accumulate_32x32_rshift32_rounded(n, sq, 1934101615);
n = n + (multiply_32x32_rshift32_rounded(sq,
multiply_32x32_rshift32_rounded(x, 1358044250)) << 1);
n = n << 1;
#else
// exp2 algorithm by Laurent de Soras
// https://www.musicdsp.org/en/latest/Other/106-fast-exp2-approximation.html
n = (n + 134217728) << 3;
n = multiply_32x32_rshift32_rounded(n, n);
n = multiply_32x32_rshift32_rounded(n, 715827883) << 3;
n = n + 715827882;
#endif
n = n >> (6 - (control >> 27)); // 4 integer control bits
fmult = multiply_32x32_rshift32_rounded(fcenter, n);
if (fmult > 5378279)
fmult = 5378279;
fmult = fmult << 8;
// fmult is within 0.4% accuracy for all but the top 2 octaves
// of the audio band. This math improves accuracy above 5 kHz.
// Without this, the filter still works fine for processing
// high frequencies, but the filter's corner frequency response
// can end up about 6% higher than requested.
#ifdef IMPROVE_HIGH_FREQUENCY_ACCURACY
// From "Fast Polynomial Approximations to Sine and Cosine"
// Charles K Garrett, http://krisgarrett.net/
fmult = (multiply_32x32_rshift32_rounded(fmult, 2145892402) +
multiply_32x32_rshift32_rounded(
multiply_32x32_rshift32_rounded(fmult, fmult),
multiply_32x32_rshift32_rounded(fmult, -1383276101))) << 1;
#endif
// now do the state variable filter as normal, using fmult
input = (*in++) << 12;
lowpass = lowpass + MULT(fmult, bandpass);
highpass = ((input + inputprev) >> 1) - lowpass - MULT(damp, bandpass);
inputprev = input;
bandpass = bandpass + MULT(fmult, highpass);
lowpasstmp = lowpass;
bandpasstmp = bandpass;
highpasstmp = highpass;
lowpass = lowpass + MULT(fmult, bandpass);
highpass = input - lowpass - MULT(damp, bandpass);
bandpass = bandpass + MULT(fmult, highpass);
lowpasstmp = signed_saturate_rshift(lowpass + lowpasstmp, 16, 13);
bandpasstmp = signed_saturate_rshift(bandpass + bandpasstmp, 16, 13);
highpasstmp = signed_saturate_rshift(highpass + highpasstmp, 16, 13);
*lp++ = lowpasstmp;
*bp++ = bandpasstmp;
*hp++ = highpasstmp;
} while (in < end);
state_inputprev = inputprev;
state_lowpass = lowpass;
state_bandpass = bandpass;
}


+ 108
- 0
src/noise-plethora/teensy/filter_variable.hpp View File

@@ -0,0 +1,108 @@
/* Audio Library for Teensy 3.X
* Copyright (c) 2014, Paul Stoffregen, paul@pjrc.com
*
* Development of this audio library was funded by PJRC.COM, LLC by sales of
* Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop
* open source software by purchasing Teensy or other PJRC products.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice, development funding notice, and this permission
* notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#pragma once

#include "audio_core.hpp"

class AudioFilterStateVariable: public AudioStream {
public:
AudioFilterStateVariable() : AudioStream(2) {
frequency(1000);
octaveControl(1.0); // default values
resonance(0.707);
state_inputprev = 0;
state_lowpass = 0;
state_bandpass = 0;
}
void frequency(float freq) {
// for reproducibility, max frequency cuts out at 2/5 Teensy sample rate
// (unless we're running at very low sample rates, in which case make sure we don't allow unstable f_c)
const float minFrequency = 20.f;
const float maxFrequency = std::min(AUDIO_SAMPLE_RATE_EXACT, APP->engine->getSampleRate()) / 2.5f;

if (freq < minFrequency) {
freq = minFrequency;
}
else if (freq > maxFrequency) {
freq = maxFrequency;
}
setting_fcenter = (freq * (3.141592654f / (APP->engine->getSampleRate() * 2.0f)))
* 2147483647.0f;
// TODO: should we use an approximation when freq is not a const,
// so the sinf() function isn't linked?
setting_fmult = sinf(freq * (3.141592654f / (APP->engine->getSampleRate() * 2.0f)))
* 2147483647.0f;
}
void resonance(float q) {
if (q < 0.7f)
q = 0.7f;
else if (q > 5.0f)
q = 5.0f;
// TODO: allow lower Q when frequency is lower
setting_damp = (1.0f / q) * 1073741824.0f;
}
void octaveControl(float n) {
// filter's corner frequency is Fcenter * 2^(control * N)
// where "control" ranges from -1.0 to +1.0
// and "N" allows the frequency to change from 0 to 7 octaves
if (n < 0.0f)
n = 0.0f;
else if (n > 6.9999f)
n = 6.9999f;
setting_octavemult = n * 4096.0f;
}

void update(const audio_block_t* input_block, const audio_block_t* control_block,
audio_block_t* lowpass_block, audio_block_t* bandpass_block, audio_block_t* highpass_block) {

if (control_block) {
update_variable(input_block->data,
control_block->data,
lowpass_block->data,
bandpass_block->data,
highpass_block->data);
}
else {
update_fixed(input_block->data,
lowpass_block->data,
bandpass_block->data,
highpass_block->data);
}
return;
}

private:
void update_fixed(const int16_t* in, int16_t* lp, int16_t* bp, int16_t* hp);
void update_variable(const int16_t* in, const int16_t* ctl, int16_t* lp, int16_t* bp, int16_t* hp);
int32_t setting_fcenter;
int32_t setting_fmult;
int32_t setting_octavemult;
int32_t setting_damp;
int32_t state_inputprev;
int32_t state_lowpass;
int32_t state_bandpass;
};

+ 140
- 0
src/noise-plethora/teensy/mixer.hpp View File

@@ -0,0 +1,140 @@
/* Audio Library for Teensy 3.X
* Copyright (c) 2014, Paul Stoffregen, paul@pjrc.com
*
* Development of this audio library was funded by PJRC.COM, LLC by sales of
* Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop
* open source software by purchasing Teensy or other PJRC products.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice, development funding notice, and this permission
* notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#pragma once

#include "audio_core.hpp"

#define MULTI_UNITYGAIN 256

static void applyGain(int16_t* data, int32_t mult) {
const int16_t* end = data + AUDIO_BLOCK_SAMPLES;

do {
int32_t val = *data * mult;
*data++ = signed_saturate_rshift(val, 16, 0);
} while (data < end);
}

static void applyGainThenAdd(int16_t* dst, const int16_t* src, int32_t mult) {
const int16_t* end = dst + AUDIO_BLOCK_SAMPLES;

if (mult == MULTI_UNITYGAIN) {
do {
int32_t val = *dst + *src++;
*dst++ = signed_saturate_rshift(val, 16, 0);
} while (dst < end);
}
else {
do {
int32_t val = *dst + ((*src++ * mult) >> 8); // overflow possible??
*dst++ = signed_saturate_rshift(val, 16, 0);
} while (dst < end);
}
}

class AudioMixer4 : public AudioStream {
public:
AudioMixer4(void) : AudioStream(4) {
for (int i = 0; i < 4; i++)
multiplier[i] = 256;
}

void update(const audio_block_t* in1, const audio_block_t* in2, const audio_block_t* in3, const audio_block_t* in4, audio_block_t* out) {

if (!out) {
return;
}
else {
// zero buffer before processing
out->zeroAudioBlock();
}

if (in1) {
applyGainThenAdd(out->data, in1->data, multiplier[0]);
}
if (in2) {
applyGainThenAdd(out->data, in2->data, multiplier[1]);
}
if (in3) {
applyGainThenAdd(out->data, in3->data, multiplier[2]);
}
if (in4) {
applyGainThenAdd(out->data, in4->data, multiplier[3]);
}
}

void gain(unsigned int channel, float gain) {
if (channel >= 4)
return;
if (gain > 127.0f)
gain = 127.0f;
else if (gain < -127.0f)
gain = -127.0f;
multiplier[channel] = gain * 256.0f; // TODO: proper roundoff?
}
private:
int16_t multiplier[4];
};


class AudioAmplifier : public AudioStream {
public:
AudioAmplifier(void) : AudioStream(1), multiplier(65536) {
}

// acts in place
void update(audio_block_t* block) {
if (!block) {
return;
}

int32_t mult = multiplier;

if (mult == 0) {
// zero gain, discard any input and transmit nothing
memset(block->data, 0, sizeof(int16_t) * AUDIO_BLOCK_SAMPLES);
}
else if (mult == MULTI_UNITYGAIN) {
// unity gain, pass input to output without any change
return;
}
else {
// apply gain to signal
applyGain(block->data, mult);
}
}

void gain(float n) {
if (n > 32767.0f)
n = 32767.0f;
else if (n < -32767.0f)
n = -32767.0f;
multiplier = n * 65536.0f;
}
private:
int32_t multiplier;
};

+ 201
- 0
src/noise-plethora/teensy/synth_dc.hpp View File

@@ -0,0 +1,201 @@
/* Audio Library for Teensy 3.X
* Copyright (c) 2014, Paul Stoffregen, paul@pjrc.com
*
* Development of this audio library was funded by PJRC.COM, LLC by sales of
* Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop
* open source software by purchasing Teensy or other PJRC products.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice, development funding notice, and this permission
* notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#pragma once

#include "audio_core.hpp"

// compute (a - b) / c ... handling 32 bit interger overflow without slow 64 bit math
static inline int32_t substract_int32_then_divide_int32(int32_t a, int32_t b, int32_t c) __attribute__((always_inline, unused));
static inline int32_t substract_int32_then_divide_int32(int32_t a, int32_t b, int32_t c) {
uint32_t diff;
uint8_t negative;

if (a >= 0) {
if (b >= 0) {
return (a - b) / c; // no overflow if both a & b are positive
}
else {
diff = a + (b * -1); // assumes 0x80000000 * -1 == 0x80000000
negative = 0;
}
}
else {
if (b >= 0) {
diff = (a * -1) + b; // assumes 0x80000000 * -1 == 0x80000000
negative = 1;
}
else {
return (a - b) / c; // no overflow if both a & b are negative
}
}
if (c >= 0) {
diff = diff / (uint32_t)c;
}
else {
diff = diff / (uint32_t)(c * -1);
negative ^= 1;
}
if (negative) {
if (diff > 0x7FFFFFFF)
return 0x80000000;
return (int32_t)diff * -1;
}
else {
if (diff > 0x7FFFFFFF)
return 0x7FFFFFFF;
return (int32_t)diff;
}
}


class AudioSynthWaveformDc : public AudioStream {
public:
AudioSynthWaveformDc() : AudioStream(0), state(0), magnitude(0) {}
// immediately jump to the new DC level
void amplitude(float n) {
if (n > 1.0f)
n = 1.0f;
else if (n < -1.0f)
n = -1.0f;
int32_t m = (int32_t)(n * 2147418112.0f);
magnitude = m;
state = 0;
}
// slowly transition to the new DC level
void amplitude(float n, float milliseconds) {
if (milliseconds <= 0.0f) {
amplitude(n);
return;
}
if (n > 1.0f)
n = 1.0f;
else if (n < -1.0f)
n = -1.0f;
int32_t c = (int32_t)(milliseconds * (AUDIO_SAMPLE_RATE_EXACT / 1000.0f));
if (c == 0) {
amplitude(n);
return;
}
int32_t t = (int32_t)(n * 2147418112.0f);
target = t;
if (target == magnitude) {
state = 0;
return;
}
increment = substract_int32_then_divide_int32(target, magnitude, c);
if (increment == 0) {
increment = (target > magnitude) ? 1 : -1;
}
state = 1;
}
float read(void) {
int32_t m = magnitude;
return (float)m * (float)(1.0 / 2147418112.0);
}
void update(audio_block_t* block) {
uint32_t* p, *end, val;
int32_t count, t1, t2, t3, t4;

if (!block) {
return;
}
p = (uint32_t*)(block->data);
end = p + AUDIO_BLOCK_SAMPLES / 2;

if (state == 0) {
// steady DC output, simply fill the buffer with fixed value
val = pack_16t_16t(magnitude, magnitude);
do {
*p++ = val;
*p++ = val;
*p++ = val;
*p++ = val;
*p++ = val;
*p++ = val;
*p++ = val;
*p++ = val;
} while (p < end);
}
else {
// transitioning to a new DC level
//count = (target - magnitude) / increment;
count = substract_int32_then_divide_int32(target, magnitude, increment);
if (count >= AUDIO_BLOCK_SAMPLES) {
// this update will not reach the target
do {
magnitude += increment;
t1 = magnitude;
magnitude += increment;
t1 = pack_16t_16t(magnitude, t1);
magnitude += increment;
t2 = magnitude;
magnitude += increment;
t2 = pack_16t_16t(magnitude, t2);
magnitude += increment;
t3 = magnitude;
magnitude += increment;
t3 = pack_16t_16t(magnitude, t3);
magnitude += increment;
t4 = magnitude;
magnitude += increment;
t4 = pack_16t_16t(magnitude, t4);
*p++ = t1;
*p++ = t2;
*p++ = t3;
*p++ = t4;
} while (p < end);
}
else {
// this update reaches the target
while (count >= 2) {
count -= 2;
magnitude += increment;
t1 = magnitude;
magnitude += increment;
t1 = pack_16t_16t(magnitude, t1);
*p++ = t1;
}
if (count) {
t1 = pack_16t_16t(target, magnitude + increment);
*p++ = t1;
}
magnitude = target;
state = 0;
val = pack_16t_16t(magnitude, magnitude);
while (p < end) {
*p++ = val;
}
}
}
}

private:
uint8_t state; // 0=steady output, 1=transitioning
int32_t magnitude; // current output
int32_t target; // designed output (while transitiong)
int32_t increment; // adjustment per sample (while transitiong)
};

+ 147
- 0
src/noise-plethora/teensy/synth_pinknoise.cpp View File

@@ -0,0 +1,147 @@
/* Audio Library for Teensy 3.X
* Copyright (c) 2014, Paul Stoffregen, paul@pjrc.com
*
* Development of this audio library was funded by PJRC.COM, LLC by sales of
* Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop
* open source software by purchasing Teensy or other PJRC products.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice, development funding notice, and this permission
* notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

// http://stenzel.waldorfmusic.de/post/pink/
// https://github.com/Stenzel/newshadeofpink
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// New Shade of Pink
// (c) 2014 Stefan Stenzel
// stefan at waldorfmusic.de
//
// Terms of use:
// Use for any purpose. If used in a commercial product, you should give me one.
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


#include "synth_pinknoise.hpp"

int16_t AudioSynthNoisePink::instance_cnt = 0;

// Let preprocessor and compiler calculate two lookup tables for 12-tap FIR Filter
// with these coefficients: 1.190566, 0.162580, 0.002208, 0.025475, -0.001522,
// 0.007322, 0.001774, 0.004529, -0.001561, 0.000776, -0.000486, 0.002017
#define Fn(cf,m,shift) (2048*cf*(2*((m)>>shift&1)-1))
#define FA(n) (int32_t)(Fn(1.190566,n,0)+Fn(0.162580,n,1)+Fn(0.002208,n,2)+\
Fn(0.025475,n,3)+Fn(-0.001522,n,4)+Fn(0.007322,n,5))
#define FB(n) (int32_t)(Fn(0.001774,n,0)+Fn(0.004529,n,1)+Fn(-0.001561,n,2)+\
Fn(0.000776,n,3)+Fn(-0.000486,n,4)+Fn(0.002017,n,5))
#define FA8(n) FA(n),FA(n+1),FA(n+2),FA(n+3),FA(n+4),FA(n+5),FA(n+6),FA(n+7)
#define FB8(n) FB(n),FB(n+1),FB(n+2),FB(n+3),FB(n+4),FB(n+5),FB(n+6),FB(n+7)
const int32_t AudioSynthNoisePink::pfira[64] = // 1st FIR lookup table
{FA8(0), FA8(8), FA8(16), FA8(24), FA8(32), FA8(40), FA8(48), FA8(56)};
const int32_t AudioSynthNoisePink::pfirb[64] = // 2nd FIR lookup table
{FB8(0), FB8(8), FB8(16), FB8(24), FB8(32), FB8(40), FB8(48), FB8(56)};

// bitreversed lookup table
#define PM16(n) n,0x80,0x40,0x80,0x20,0x80,0x40,0x80,0x10,0x80,0x40,0x80,0x20,0x80,0x40,0x80
const uint8_t AudioSynthNoisePink::pnmask[256] = {
PM16(0), PM16(8), PM16(4), PM16(8), PM16(2), PM16(8), PM16(4), PM16(8),
PM16(1), PM16(8), PM16(4), PM16(8), PM16(2), PM16(8), PM16(4), PM16(8)
};

#define PINT(bitmask, out) /* macro for processing: */\
bit = lfsr >> 31; /* spill random to all bits */\
dec &= ~bitmask; /* blank old decrement bit */\
lfsr <<= 1; /* shift lfsr */\
dec |= inc & bitmask; /* copy increment to decrement bit */\
inc ^= bit & bitmask; /* new random bit */\
accu += inc - dec; /* integrate */\
lfsr ^= bit & taps; /* update lfsr */\
out = accu + /* save output */\
pfira[lfsr & 0x3F] + /* add 1st half precalculated FIR */\
pfirb[lfsr >> 6 & 0x3F] /* add 2nd half, also correts bias */

void AudioSynthNoisePink::update(audio_block_t* block) {
uint32_t* p, *end;
int32_t n1, n2;
int32_t gain;
int32_t inc, dec, accu, bit, lfsr;
int32_t taps;

gain = level;
if (gain == 0)
return;

if (!block)
return;
p = (uint32_t*)(block->data);
end = p + AUDIO_BLOCK_SAMPLES / 2;
taps = 0x46000001;
inc = pinc;
dec = pdec;
accu = paccu;
lfsr = plfsr;
do {
int32_t mask = pnmask[pncnt++];
PINT(mask, n1);
n1 = signed_multiply_32x16b(gain, n1);
PINT(0x0800, n2);
n2 = signed_multiply_32x16b(gain, n2);
*p++ = pack_16b_16b(n2, n1);
PINT(0x0400, n1);
n1 = signed_multiply_32x16b(gain, n1);
PINT(0x0800, n2);
n2 = signed_multiply_32x16b(gain, n2);
*p++ = pack_16b_16b(n2, n1);
PINT(0x0200, n1);
n1 = signed_multiply_32x16b(gain, n1);
PINT(0x0800, n2);
n2 = signed_multiply_32x16b(gain, n2);
*p++ = pack_16b_16b(n2, n1);
PINT(0x0400, n1);
n1 = signed_multiply_32x16b(gain, n1);
PINT(0x0800, n2);
n2 = signed_multiply_32x16b(gain, n2);
*p++ = pack_16b_16b(n2, n1);
PINT(0x0100, n1);
n1 = signed_multiply_32x16b(gain, n1);
PINT(0x0800, n2);
n2 = signed_multiply_32x16b(gain, n2);
*p++ = pack_16b_16b(n2, n1);
PINT(0x0400, n1);
n1 = signed_multiply_32x16b(gain, n1);
PINT(0x0800, n2);
n2 = signed_multiply_32x16b(gain, n2);
*p++ = pack_16b_16b(n2, n1);
PINT(0x0200, n1);
n1 = signed_multiply_32x16b(gain, n1);
PINT(0x0800, n2);
n2 = signed_multiply_32x16b(gain, n2);
*p++ = pack_16b_16b(n2, n1);
PINT(0x0400, n1);
n1 = signed_multiply_32x16b(gain, n1);
PINT(0x0800, n2);
n2 = signed_multiply_32x16b(gain, n2);
*p++ = pack_16b_16b(n2, n1);
} while (p < end);
pinc = inc;
pdec = dec;
paccu = accu;
plfsr = lfsr;
}




+ 59
- 0
src/noise-plethora/teensy/synth_pinknoise.hpp View File

@@ -0,0 +1,59 @@
/* Audio Library for Teensy 3.X
* Copyright (c) 2014, Paul Stoffregen, paul@pjrc.com
*
* Development of this audio library was funded by PJRC.COM, LLC by sales of
* Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop
* open source software by purchasing Teensy or other PJRC products.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice, development funding notice, and this permission
* notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#pragma once

#include "audio_core.hpp"

class AudioSynthNoisePink : public AudioStream {
public:
AudioSynthNoisePink() : AudioStream(0) {
plfsr = 0x5EED41F5 + instance_cnt++;
paccu = 0;
pncnt = 0;
pinc = 0x0CCC;
pdec = 0x0CCC;
}
void amplitude(float n) {
if (n < 0.0f)
n = 0.0;
else if (n > 1.0f)
n = 1.0f;
level = (int32_t)(n * 65536.0f);
}
virtual void update(audio_block_t* block);
private:
static const uint8_t pnmask[256];
static const int32_t pfira[64];
static const int32_t pfirb[64];
static int16_t instance_cnt;
int32_t plfsr; // linear feedback shift register
int32_t pinc; // increment for all noise sources (bits)
int32_t pdec; // decrement for all noise sources
int32_t paccu; // accumulator
uint8_t pncnt; // overflowing counter as index to pnmask[]
int32_t level; // 0=off, 65536=max
};

+ 89
- 0
src/noise-plethora/teensy/synth_pwm.cpp View File

@@ -0,0 +1,89 @@
/* Audio Library for Teensy 3.X
* Copyright (c) 2017, Paul Stoffregen, paul@pjrc.com
*
* Development of this audio library was funded by PJRC.COM, LLC by sales of
* Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop
* open source software by purchasing Teensy or other PJRC products.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice, development funding notice, and this permission
* notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#include "synth_pwm.hpp"
#include "dspinst.h"


void AudioSynthWaveformPWM::update(const audio_block_t* modinput, audio_block_t* block) {
uint32_t i;
int32_t out;

if (!block) {
return;
}
else if (magnitude == 0) {
block->zeroAudioBlock();
}

if (modinput) {
const uint32_t _duration = duration;
uint32_t _elapsed = elapsed;
int32_t _magnitude = magnitude;
for (i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {
_elapsed += 65536;
int32_t in = modinput->data[i];
if (_magnitude < 0)
in = -in;
uint32_t dur = ((uint64_t)(in + 32768) * _duration) >> 15;
if (_elapsed < dur) {
out = _magnitude;
}
else {
int32_t e = _elapsed - dur;
signed_saturate_rshift(e, 17, 0);
if (e < 0)
e = 0;
_elapsed = e;
// elapsed must be 0 to 65535
// magnitude must be -32767 to +32767
out = _magnitude - ((_magnitude * _elapsed) >> 15);
_magnitude = -_magnitude;
}
block->data[i] = out;
}
elapsed = _elapsed;
magnitude = _magnitude;

}
else {
for (i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {
elapsed += 65536;
if (elapsed < duration) {
out = magnitude;
}
else {
elapsed -= duration;
// elapsed must be 0 to 65535
// magnitude must be -32767 to +32767
out = magnitude - ((magnitude * elapsed) >> 15);
magnitude = -magnitude;
}
block->data[i] = out;
}
}
}


+ 61
- 0
src/noise-plethora/teensy/synth_pwm.hpp View File

@@ -0,0 +1,61 @@
/* Audio Library for Teensy 3.X
* Copyright (c) 2017, Paul Stoffregen, paul@pjrc.com
*
* Development of this audio library was funded by PJRC.COM, LLC by sales of
* Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop
* open source software by purchasing Teensy or other PJRC products.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice, development funding notice, and this permission
* notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#pragma once

#include "audio_core.hpp"

class AudioSynthWaveformPWM : public AudioStream {
public:
AudioSynthWaveformPWM() : AudioStream(1), magnitude(0), elapsed(0) {}
void frequency(float freq) {

// for reproducibility, max frequency cuts out at 1/2 Teensy sample rate
// (unless we're running at very low sample rates, in which case use those to limit range)
const float maxFrequency = std::min(AUDIO_SAMPLE_RATE_EXACT, APP->engine->getSampleRate()) / 4.0f;

if (freq < 1.0) {
freq = 1.0;
}
else if (freq > maxFrequency) {
freq = maxFrequency;
}
//phase_increment = freq * (4294967296.0f / AUDIO_SAMPLE_RATE_EXACT);
duration = (APP->engine->getSampleRate() * 65536.0f + freq) / (freq * 2.0f);
}
void amplitude(float n) {
if (n < 0.0f)
n = 0;
else if (n > 1.0f)
n = 1.0f;
magnitude = n * 32767.0f;
}
virtual void update(const audio_block_t* modinput, audio_block_t* block);
private:
uint32_t duration; // samples per half cycle (when 50% duty) * 65536
int32_t magnitude;
uint32_t elapsed;
};

+ 188
- 0
src/noise-plethora/teensy/synth_sine.hpp View File

@@ -0,0 +1,188 @@
/* Audio Library for Teensy 3.X
* Copyright (c) 2014, Paul Stoffregen, paul@pjrc.com
*
* Development of this audio library was funded by PJRC.COM, LLC by sales of
* Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop
* open source software by purchasing Teensy or other PJRC products.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice, development funding notice, and this permission
* notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#pragma once

#include "audio_core.hpp"


// TODO: investigate making a high resolution sine wave
// using Taylor series expansion.
// http://www.musicdsp.org/showone.php?id=13

class AudioSynthWaveformSine : public AudioStream {
public:
AudioSynthWaveformSine() : AudioStream(0), magnitude(16384) {}
void frequency(float freq) {
// for reproducibility, max frequency cuts out at 1/2 Teensy sample rate
// (unless we're running at very low sample rates, in which case use those to limit range)
const float maxFrequency = std::min(AUDIO_SAMPLE_RATE_EXACT, APP->engine->getSampleRate()) / 2.0f;

if (freq < 0.0f)
freq = 0.0;
else if (freq > maxFrequency)
freq = maxFrequency;
phase_increment = freq * (4294967296.0f / APP->engine->getSampleRate());
}
void phase(float angle) {
if (angle < 0.0f)
angle = 0.0f;
else if (angle > 360.0f) {
angle = angle - 360.0f;
if (angle >= 360.0f)
return;
}
phase_accumulator = angle * (float)(4294967296.0 / 360.0);
}
void amplitude(float n) {
if (n < 0.0f)
n = 0;
else if (n > 1.0f)
n = 1.0f;
magnitude = n * 65536.0f;
}
void update(audio_block_t* block) {
uint32_t i, ph, inc, index, scale;
int32_t val1, val2;

if (magnitude) {
if (block) {
ph = phase_accumulator;
inc = phase_increment;
for (i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {
index = ph >> 24;
val1 = AudioWaveformSine[index];
val2 = AudioWaveformSine[index + 1];
scale = (ph >> 8) & 0xFFFF;
val2 *= scale;
val1 *= 0x10000 - scale;
block->data[i] = (((val1 + val2) >> 16) * magnitude) >> 16;
ph += inc;
}
phase_accumulator = ph;
return;
}
}
phase_accumulator += phase_increment * AUDIO_BLOCK_SAMPLES;
}
private:
uint32_t phase_accumulator;
uint32_t phase_increment;
int32_t magnitude;
};




class AudioSynthWaveformSineModulated : public AudioStream {
public:
AudioSynthWaveformSineModulated() : AudioStream(1), magnitude(16384) {}
// maximum unmodulated carrier frequency is 11025 Hz
// input = +1.0 doubles carrier
// input = -1.0 DC output
void frequency(float freq) {

// for reproducibility, max frequency cuts out at 1/4 Teensy sample rate
// (unless we're running at very low sample rates, in which case use those to limit range)
const float maxFrequency = std::min(AUDIO_SAMPLE_RATE_EXACT, APP->engine->getSampleRate()) / 4.0f;

if (freq < 0.0f)
freq = 0.0f;
else if (freq > maxFrequency)
freq = maxFrequency;
phase_increment = freq * (4294967296.0f / APP->engine->getSampleRate());
}
void phase(float angle) {
if (angle < 0.0f)
angle = 0.0;
else if (angle > 360.0f) {
angle = angle - 360.0f;
if (angle >= 360.0f)
return;
}
phase_accumulator = angle * (float)(4294967296.0 / 360.0);
}

void amplitude(float n) {
if (n < 0.0f)
n = 0;
else if (n > 1.0f)
n = 1.0f;
magnitude = n * 65536.0f;
}

void update(const audio_block_t* modinput, audio_block_t* block) {

uint32_t i, ph, inc, index, scale;
int32_t val1, val2;
int16_t mod;

ph = phase_accumulator;
inc = phase_increment;
if (!block) {
// unable to allocate memory, so we'll send nothing
return;
}
if (modinput) {
for (i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {
index = ph >> 24;
val1 = AudioWaveformSine[index];
val2 = AudioWaveformSine[index + 1];
scale = (ph >> 8) & 0xFFFF;
val2 *= scale;
val1 *= 0x10000 - scale;
//block->data[i] = (((val1 + val2) >> 16) * magnitude) >> 16;
block->data[i] = multiply_32x32_rshift32(val1 + val2, magnitude);
// -32768 = no phase increment
// 32767 = double phase increment
mod = modinput->data[i];
ph += inc + (multiply_32x32_rshift32(inc, mod << 16) << 1);
//ph += inc + (((int64_t)inc * (mod << 16)) >> 31);
}
}
else {
ph = phase_accumulator;
inc = phase_increment;
for (i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {
index = ph >> 24;
val1 = AudioWaveformSine[index];
val2 = AudioWaveformSine[index + 1];
scale = (ph >> 8) & 0xFFFF;
val2 *= scale;
val1 *= 0x10000 - scale;
block->data[i] = multiply_32x32_rshift32(val1 + val2, magnitude);
ph += inc;
}
}
phase_accumulator = ph;
}
private:
uint32_t phase_accumulator;
uint32_t phase_increment;
int32_t magnitude;
};


+ 553
- 0
src/noise-plethora/teensy/synth_waveform.hpp View File

@@ -0,0 +1,553 @@
#pragma once
#include "audio_core.hpp"
class AudioSynthWaveform : public AudioStream {
public:
AudioSynthWaveform(void) : AudioStream(0),
phase_accumulator(0), phase_increment(0), phase_offset(0),
magnitude(0), pulse_width(0x40000000),
arbdata(NULL), sample(0), tone_type(WAVEFORM_SINE),
tone_offset(0) {
}
void frequency(float freq) {
// for reproducibility, max frequency cuts out at 1/2 Teensy sample rate
// (unless we're running at very low sample rates, in which case use those to limit range)
const float maxFrequency = std::min(AUDIO_SAMPLE_RATE_EXACT, APP->engine->getSampleRate()) / 2.0f;
if (freq < 0.0f) {
freq = 0.0;
}
else if (freq > maxFrequency) {
freq = maxFrequency;
}
phase_increment = freq * (4294967296.0f / APP->engine->getSampleRate());
if (phase_increment > 0x7FFE0000u)
phase_increment = 0x7FFE0000;
}
void phase(float angle) {
if (angle < 0.0f) {
angle = 0.0;
}
else if (angle > 360.0f) {
angle = angle - 360.0f;
if (angle >= 360.0f)
return;
}
phase_offset = angle * (float)(4294967296.0 / 360.0);
}
void amplitude(float n) { // 0 to 1.0
if (n < 0) {
n = 0;
}
else if (n > 1.0f) {
n = 1.0;
}
magnitude = n * 65536.0f;
}
void offset(float n) {
if (n < -1.0f) {
n = -1.0f;
}
else if (n > 1.0f) {
n = 1.0f;
}
tone_offset = n * 32767.0f;
}
void pulseWidth(float n) { // 0.0 to 1.0
if (n < 0) {
n = 0;
}
else if (n > 1.0f) {
n = 1.0f;
}
pulse_width = n * 4294967296.0f;
}
void begin(short t_type) {
phase_offset = 0;
tone_type = t_type;
}
void begin(float t_amp, float t_freq, short t_type) {
amplitude(t_amp);
frequency(t_freq);
phase_offset = 0;
begin(t_type);
}
void arbitraryWaveform(const int16_t* data, float maxFreq) {
arbdata = data;
}
void update(audio_block_t* block) {
int16_t* bp, *end;
int32_t val1, val2;
int16_t magnitude15;
uint32_t i, ph, index, index2, scale;
const uint32_t inc = phase_increment;
ph = phase_accumulator + phase_offset;
if (magnitude == 0) {
phase_accumulator += inc * AUDIO_BLOCK_SAMPLES;
return;
}
if (!block) {
phase_accumulator += inc * AUDIO_BLOCK_SAMPLES;
return;
}
bp = block->data;
switch (tone_type) {
case WAVEFORM_SINE:
for (i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {
index = ph >> 24;
val1 = AudioWaveformSine[index];
val2 = AudioWaveformSine[index + 1];
scale = (ph >> 8) & 0xFFFF;
val2 *= scale;
val1 *= 0x10000 - scale;
*bp++ = multiply_32x32_rshift32(val1 + val2, magnitude);
ph += inc;
}
break;
case WAVEFORM_ARBITRARY:
if (!arbdata) {
phase_accumulator += inc * AUDIO_BLOCK_SAMPLES;
return;
}
// len = 256
for (i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {
index = ph >> 24;
index2 = index + 1;
if (index2 >= 256)
index2 = 0;
val1 = *(arbdata + index);
val2 = *(arbdata + index2);
scale = (ph >> 8) & 0xFFFF;
val2 *= scale;
val1 *= 0x10000 - scale;
*bp++ = multiply_32x32_rshift32(val1 + val2, magnitude);
ph += inc;
}
break;
case WAVEFORM_SQUARE:
magnitude15 = signed_saturate_rshift(magnitude, 16, 1);
for (i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {
if (ph & 0x80000000) {
*bp++ = -magnitude15;
}
else {
*bp++ = magnitude15;
}
ph += inc;
}
break;
case WAVEFORM_SAWTOOTH:
for (i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {
*bp++ = signed_multiply_32x16t(magnitude, ph);
ph += inc;
}
break;
case WAVEFORM_SAWTOOTH_REVERSE:
for (i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {
*bp++ = signed_multiply_32x16t(0xFFFFFFFFu - magnitude, ph);
ph += inc;
}
break;
case WAVEFORM_TRIANGLE:
for (i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {
uint32_t phtop = ph >> 30;
if (phtop == 1 || phtop == 2) {
*bp++ = ((0xFFFF - (ph >> 15)) * magnitude) >> 16;
}
else {
*bp++ = (((int32_t)ph >> 15) * magnitude) >> 16;
}
ph += inc;
}
break;
case WAVEFORM_TRIANGLE_VARIABLE:
do {
uint32_t rise = 0xFFFFFFFF / (pulse_width >> 16);
uint32_t fall = 0xFFFFFFFF / (0xFFFF - (pulse_width >> 16));
for (i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {
if (ph < pulse_width / 2) {
uint32_t n = (ph >> 16) * rise;
*bp++ = ((n >> 16) * magnitude) >> 16;
}
else if (ph < 0xFFFFFFFF - pulse_width / 2) {
uint32_t n = 0x7FFFFFFF - (((ph - pulse_width / 2) >> 16) * fall);
*bp++ = (((int32_t)n >> 16) * magnitude) >> 16;
}
else {
uint32_t n = ((ph + pulse_width / 2) >> 16) * rise + 0x80000000;
*bp++ = (((int32_t)n >> 16) * magnitude) >> 16;
}
ph += inc;
}
} while (0);
break;
case WAVEFORM_PULSE:
magnitude15 = signed_saturate_rshift(magnitude, 16, 1);
for (i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {
if (ph < pulse_width) {
*bp++ = magnitude15;
}
else {
*bp++ = -magnitude15;
}
ph += inc;
}
break;
case WAVEFORM_SAMPLE_HOLD:
for (i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {
*bp++ = sample;
uint32_t newph = ph + inc;
if (newph < ph) {
sample = teensy::random_teensy(magnitude) - (magnitude >> 1);
}
ph = newph;
}
break;
}
phase_accumulator = ph - phase_offset;
if (tone_offset) {
bp = block->data;
end = bp + AUDIO_BLOCK_SAMPLES;
do {
val1 = *bp;
*bp++ = signed_saturate_rshift(val1 + tone_offset, 16, 0);
} while (bp < end);
}
}
private:
uint32_t phase_accumulator;
uint32_t phase_increment;
uint32_t phase_offset;
int32_t magnitude;
uint32_t pulse_width;
const int16_t* arbdata;
int16_t sample; // for WAVEFORM_SAMPLE_HOLD
short tone_type;
int16_t tone_offset;
};
class AudioSynthWaveformModulated : public AudioStream {
public:
AudioSynthWaveformModulated(void) : AudioStream(2),
phase_accumulator(0), phase_increment(0), modulation_factor(32768),
magnitude(0), arbdata(NULL), sample(0), tone_offset(0),
tone_type(WAVEFORM_SINE), modulation_type(0) {
}
void frequency(float freq) {
// for reproducibility, max frequency cuts out at 1/2 Teensy sample rate
// (unless we're running at very low sample rates, in which case use those to limit range)
const float maxFrequency = std::min(AUDIO_SAMPLE_RATE_EXACT, APP->engine->getSampleRate()) / 2.0f;
if (freq < 0.0f) {
freq = 0.0;
}
else if (freq > maxFrequency) {
freq = maxFrequency;
}
phase_increment = freq * (4294967296.0f / APP->engine->getSampleRate());
if (phase_increment > 0x7FFE0000u)
phase_increment = 0x7FFE0000;
}
void amplitude(float n) { // 0 to 1.0
if (n < 0) {
n = 0;
}
else if (n > 1.0f) {
n = 1.0f;
}
magnitude = n * 65536.0f;
}
void offset(float n) {
if (n < -1.0f) {
n = -1.0f;
}
else if (n > 1.0f) {
n = 1.0f;
}
tone_offset = n * 32767.0f;
}
void begin(short t_type) {
tone_type = t_type;
// band-limited waveforms not used
}
void begin(float t_amp, float t_freq, short t_type) {
amplitude(t_amp);
frequency(t_freq);
begin(t_type) ;
}
void arbitraryWaveform(const int16_t* data, float maxFreq) {
arbdata = data;
}
void frequencyModulation(float octaves) {
if (octaves > 12.0f) {
octaves = 12.0f;
}
else if (octaves < 0.1f) {
octaves = 0.1f;
}
modulation_factor = octaves * 4096.0f;
modulation_type = 0;
}
void phaseModulation(float degrees) {
if (degrees > 9000.0f) {
degrees = 9000.0f;
}
else if (degrees < 30.0f) {
degrees = 30.0f;
}
modulation_factor = degrees * (float)(65536.0 / 180.0);
modulation_type = 1;
}
void update(audio_block_t* moddata, audio_block_t* shapedata, audio_block_t* block) {
int16_t* bp, *end;
int32_t val1, val2;
int16_t magnitude15;
uint32_t i, ph, index, index2, scale, priorphase;
const uint32_t inc = phase_increment;
if (!block) {
return;
}
// Pre-compute the phase angle for every output sample of this update
ph = phase_accumulator;
priorphase = phasedata[AUDIO_BLOCK_SAMPLES - 1];
if (moddata && modulation_type == 0) {
// Frequency Modulation
bp = moddata->data;
for (i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {
int32_t n = (*bp++) * modulation_factor; // n is # of octaves to mod
int32_t ipart = n >> 27; // 4 integer bits
n &= 0x7FFFFFF; // 27 fractional bits
#ifdef IMPROVE_EXPONENTIAL_ACCURACY
// exp2 polynomial suggested by Stefan Stenzel on "music-dsp"
// mail list, Wed, 3 Sep 2014 10:08:55 +0200
int32_t x = n << 3;
n = multiply_accumulate_32x32_rshift32_rounded(536870912, x, 1494202713);
int32_t sq = multiply_32x32_rshift32_rounded(x, x);
n = multiply_accumulate_32x32_rshift32_rounded(n, sq, 1934101615);
n = n + (multiply_32x32_rshift32_rounded(sq,
multiply_32x32_rshift32_rounded(x, 1358044250)) << 1);
n = n << 1;
#else
// exp2 algorithm by Laurent de Soras
// https://www.musicdsp.org/en/latest/Other/106-fast-exp2-approximation.html
n = (n + 134217728) << 3;
n = multiply_32x32_rshift32_rounded(n, n);
n = multiply_32x32_rshift32_rounded(n, 715827883) << 3;
n = n + 715827882;
#endif
uint32_t scale = n >> (14 - ipart);
uint64_t phstep = (uint64_t)inc * scale;
uint32_t phstep_msw = phstep >> 32;
if (phstep_msw < 0x7FFE) {
ph += phstep >> 16;
}
else {
ph += 0x7FFE0000;
}
phasedata[i] = ph;
}
}
else if (moddata) {
// Phase Modulation
bp = moddata->data;
for (i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {
// more than +/- 180 deg shift by 32 bit overflow of "n"
uint32_t n = ((uint32_t)(*bp++)) * modulation_factor;
phasedata[i] = ph + n;
ph += inc;
}
}
else {
// No Modulation Input
for (i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {
phasedata[i] = ph;
ph += inc;
}
}
phase_accumulator = ph;
bp = block->data;
// Now generate the output samples using the pre-computed phase angles
switch (tone_type) {
case WAVEFORM_SINE:
for (i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {
ph = phasedata[i];
index = ph >> 24;
val1 = AudioWaveformSine[index];
val2 = AudioWaveformSine[index + 1];
scale = (ph >> 8) & 0xFFFF;
val2 *= scale;
val1 *= 0x10000 - scale;
*bp++ = multiply_32x32_rshift32(val1 + val2, magnitude);
}
break;
case WAVEFORM_ARBITRARY:
if (!arbdata) {
block->zeroAudioBlock();
return;
}
// len = 256
for (i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {
ph = phasedata[i];
index = ph >> 24;
index2 = index + 1;
if (index2 >= 256)
index2 = 0;
val1 = *(arbdata + index);
val2 = *(arbdata + index2);
scale = (ph >> 8) & 0xFFFF;
val2 *= scale;
val1 *= 0x10000 - scale;
*bp++ = multiply_32x32_rshift32(val1 + val2, magnitude);
}
break;
case WAVEFORM_PULSE:
if (shapedata) {
magnitude15 = signed_saturate_rshift(magnitude, 16, 1);
for (i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {
uint32_t width = ((shapedata->data[i] + 0x8000) & 0xFFFF) << 16;
if (phasedata[i] < width) {
*bp++ = magnitude15;
}
else {
*bp++ = -magnitude15;
}
}
break;
} // else fall through to orginary square without shape modulation
// fall through
case WAVEFORM_SQUARE:
magnitude15 = signed_saturate_rshift(magnitude, 16, 1);
for (i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {
if (phasedata[i] & 0x80000000) {
*bp++ = -magnitude15;
}
else {
*bp++ = magnitude15;
}
}
break;
case WAVEFORM_SAWTOOTH:
for (i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {
*bp++ = signed_multiply_32x16t(magnitude, phasedata[i]);
}
break;
case WAVEFORM_SAWTOOTH_REVERSE:
for (i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {
*bp++ = signed_multiply_32x16t(0xFFFFFFFFu - magnitude, phasedata[i]);
}
break;
case WAVEFORM_TRIANGLE_VARIABLE:
if (shapedata) {
for (i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {
uint32_t width = (shapedata->data[i] + 0x8000) & 0xFFFF;
uint32_t rise = 0xFFFFFFFF / width;
uint32_t fall = 0xFFFFFFFF / (0xFFFF - width);
uint32_t halfwidth = width << 15;
uint32_t n;
ph = phasedata[i];
if (ph < halfwidth) {
n = (ph >> 16) * rise;
*bp++ = ((n >> 16) * magnitude) >> 16;
}
else if (ph < 0xFFFFFFFF - halfwidth) {
n = 0x7FFFFFFF - (((ph - halfwidth) >> 16) * fall);
*bp++ = (((int32_t)n >> 16) * magnitude) >> 16;
}
else {
n = ((ph + halfwidth) >> 16) * rise + 0x80000000;
*bp++ = (((int32_t)n >> 16) * magnitude) >> 16;
}
ph += inc;
}
break;
} // else fall through to orginary triangle without shape modulation
// fall through
case WAVEFORM_TRIANGLE:
for (i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {
ph = phasedata[i];
uint32_t phtop = ph >> 30;
if (phtop == 1 || phtop == 2) {
*bp++ = ((0xFFFF - (ph >> 15)) * magnitude) >> 16;
}
else {
*bp++ = (((int32_t)ph >> 15) * magnitude) >> 16;
}
}
break;
case WAVEFORM_SAMPLE_HOLD:
for (i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {
ph = phasedata[i];
if (ph < priorphase) { // does not work for phase modulation
sample = teensy::random_teensy(magnitude) - (magnitude >> 1);
}
priorphase = ph;
*bp++ = sample;
}
break;
}
if (tone_offset) {
bp = block->data;
end = bp + AUDIO_BLOCK_SAMPLES;
do {
val1 = *bp;
*bp++ = signed_saturate_rshift(val1 + tone_offset, 16, 0);
} while (bp < end);
}
/*
if (shapedata)
release(shapedata);
transmit(block, 0);
release(block);
*/
}
private:
uint32_t phase_accumulator;
uint32_t phase_increment;
uint32_t modulation_factor;
int32_t magnitude;
const int16_t* arbdata;
uint32_t phasedata[AUDIO_BLOCK_SAMPLES];
int16_t sample; // for WAVEFORM_SAMPLE_HOLD
int16_t tone_offset;
uint8_t tone_type;
uint8_t modulation_type;
};

+ 71
- 0
src/noise-plethora/teensy/synth_whitenoise.cpp View File

@@ -0,0 +1,71 @@
/* Audio Library for Teensy 3.X
* Copyright (c) 2014, Paul Stoffregen, paul@pjrc.com
*
* Development of this audio library was funded by PJRC.COM, LLC by sales of
* Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop
* open source software by purchasing Teensy or other PJRC products.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice, development funding notice, and this permission
* notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/


#include "synth_whitenoise.hpp"

// Park-Miller-Carta Pseudo-Random Number Generator
// http://www.firstpr.com.au/dsp/rand31/

void AudioSynthNoiseWhite::update(audio_block_t* block) {
uint32_t* p, *end;
int32_t n1, n2, gain;
uint32_t lo, hi;

gain = level;
if (gain == 0)
return;

if (!block)
return;
p = (uint32_t*)(block->data);
end = p + AUDIO_BLOCK_SAMPLES / 2;
lo = seed;
do {
uint32_t val1;

hi = 16807 * (lo >> 16);
lo = 16807 * (lo & 0xFFFF);
lo += (hi & 0x7FFF) << 16;
lo += hi >> 15;
lo = (lo & 0x7FFFFFFF) + (lo >> 31);
n1 = signed_multiply_32x16b(gain, lo);
hi = 16807 * (lo >> 16);
lo = 16807 * (lo & 0xFFFF);
lo += (hi & 0x7FFF) << 16;
lo += hi >> 15;
lo = (lo & 0x7FFFFFFF) + (lo >> 31);
n2 = signed_multiply_32x16b(gain, lo);
val1 = pack_16b_16b(n2, n1);
*p++ = val1;

} while (p < end);
seed = lo;
}

uint16_t AudioSynthNoiseWhite::instance_count = 0;



+ 51
- 0
src/noise-plethora/teensy/synth_whitenoise.hpp View File

@@ -0,0 +1,51 @@
/* Audio Library for Teensy 3.X
* Copyright (c) 2014, Paul Stoffregen, paul@pjrc.com
*
* Development of this audio library was funded by PJRC.COM, LLC by sales of
* Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop
* open source software by purchasing Teensy or other PJRC products.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice, development funding notice, and this permission
* notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#ifndef synth_whitenoise_h_
#define synth_whitenoise_h_
#include "audio_core.hpp"

class AudioSynthNoiseWhite : public AudioStream {
public:
AudioSynthNoiseWhite() : AudioStream(0) {
level = 0;
seed = 1 + instance_count++;
}
void amplitude(float n) {
if (n < 0.0f)
n = 0.0;
else if (n > 1.0f)
n = 1.0f;
level = (int32_t)(n * 65536.0f);
}
virtual void update(audio_block_t* block);
private:
int32_t level; // 0=off, 65536=max
uint32_t seed; // must start at 1
static uint16_t instance_count;
};

#endif

+ 1
- 0
src/plugin.cpp View File

@@ -23,4 +23,5 @@ void init(rack::Plugin *p) {
p->addModel(modelSTMix);
p->addModel(modelMuxlicer);
p->addModel(modelMex);
p->addModel(modelNoisePlethora);
}

+ 94
- 2
src/plugin.hpp View File

@@ -24,7 +24,7 @@ extern Model* modelADSR;
extern Model* modelSTMix;
extern Model* modelMuxlicer;
extern Model* modelMex;
extern Model* modelNoisePlethora;

struct Knurlie : SvgScrew {
Knurlie() {
@@ -106,7 +106,7 @@ using BefacoInputPort = BananutBlack;
struct CKSSNarrow : app::SvgSwitch {
CKSSNarrow() {
addFrame(Svg::load(asset::plugin(pluginInstance, "res/components/SwitchNarrow_0.svg")));
addFrame(Svg::load(asset::plugin(pluginInstance, "res/components/SwitchNarrow_1.svg")));
addFrame(Svg::load(asset::plugin(pluginInstance, "res/components/SwitchNarrow_2.svg")));
}
};

@@ -131,6 +131,31 @@ struct BefacoSwitchHorizontal : app::SvgSwitch {
}
};

struct CKSSHoriz2 : app::SvgSwitch {
CKSSHoriz2() {
addFrame(Svg::load(asset::plugin(pluginInstance, "res/components/SwitchNarrowHoriz_0.svg")));
addFrame(Svg::load(asset::plugin(pluginInstance, "res/components/SwitchNarrowHoriz_1.svg")));
}
};

struct CKSSNarrow3 : app::SvgSwitch {
CKSSNarrow3() {
addFrame(Svg::load(asset::plugin(pluginInstance, "res/components/SwitchNarrow_0.svg")));
addFrame(Svg::load(asset::plugin(pluginInstance, "res/components/SwitchNarrow_1.svg")));
addFrame(Svg::load(asset::plugin(pluginInstance, "res/components/SwitchNarrow_2.svg")));
}
};

struct Davies1900hLargeLightGreyKnob : Davies1900hKnob {
Davies1900hLargeLightGreyKnob() {
setSvg(Svg::load(asset::plugin(pluginInstance, "res/components/Davies1900hLargeLightGrey.svg")));
bg->setSvg(Svg::load(asset::plugin(pluginInstance, "res/components/Davies1900hLargeLightGrey_bg.svg")));
}
};

inline int unsigned_modulo(int a, int b) {
return ((a % b) + b) % b;
}

template <typename T>
T sin2pi_pade_05_5_4(T x) {
@@ -199,4 +224,71 @@ struct ADEnvelope {

private:
float envLinear = 0.f;
};

// Creates a Butterworth 2*Nth order highpass filter for blocking DC
template<int N>
struct DCBlockerT {

DCBlockerT() {
setFrequency(0.1f);
}

// set frequency (in normalised units, 0 < fc < 1)
void setFrequency(float fc) {
fc_ = fc;
recalculateCoefficients();
}

float process(float x) {

x = blockDCFilter[0].process(x);
return blockDCFilter[1].process(x);
}

private:

// https://www.earlevel.com/main/2016/09/29/cascading-filters/
void recalculateCoefficients() {

float poleInc = M_PI / order;
float firstAngle = poleInc / 2;

for (int idx = 0; idx < N; idx++) {
float Q = 1.0f / (2.0f * std::cos(firstAngle + idx * poleInc));
blockDCFilter[idx].setParameters(dsp::BiquadFilter::HIGHPASS, fc_, Q, 1.0f);
}
}

float fc_;
static const int order = 2 * N;

dsp::BiquadFilter blockDCFilter[N];
};

typedef DCBlockerT<2> DCBlocker;

/** When triggered, holds a high value for a specified time before going low again */
struct PulseGenerator_4 {
simd::float_4 remaining = 0.f;

/** Immediately disables the pulse */
void reset() {
remaining = 0.f;
}

/** Advances the state by `deltaTime`. Returns whether the pulse is in the HIGH state. */
simd::float_4 process(float deltaTime) {

simd::float_4 mask = (remaining > 0.f);

remaining -= ifelse(mask, deltaTime, 0.f);
return ifelse(mask, simd::float_4::mask(), 0.f);
}

/** Begins a trigger with the given `duration`. */
void trigger(simd::float_4 mask, float duration = 1e-3f) {
// Keep the previous pulse if the existing pulse will be held longer than the currently requested one.
remaining = ifelse(mask & (duration > remaining), duration, remaining);
}
};

Loading…
Cancel
Save