├── .gitignore ├── LICENSE.txt ├── Makefile ├── README.md ├── playeroscs ├── noisepink.wav ├── noisewhite.wav ├── osc1.wav ├── osc2.wav ├── osc3.wav ├── osc4.wav ├── osc5.wav ├── osc6.wav ├── osc7.wav ├── osc8.wav └── saw.wav ├── plugin.json ├── res ├── ALGEBRA.svg ├── ArialBlack.ttf ├── BUFFER.svg ├── CHOKE.svg ├── CUBE.svg ├── CUTS.svg ├── DAVE.svg ├── DISTO.svg ├── DejaVu-LICENSE.txt ├── DejaVuSansMono.ttf ├── EACH.svg ├── FOUR.svg ├── FUNKTION.svg ├── L.svg ├── L3DS3Q.svg ├── LABEL.svg ├── LEDCalculator.ttf ├── LEDS.svg ├── LEDSEQ.svg ├── Ldown.svg ├── MASTER.svg ├── METRO.svg ├── MONO.svg ├── PATCH.svg ├── PEAK.svg ├── PLAY.svg ├── PLAYER.svg ├── PadButton.svg ├── PadButtonDown.svg ├── SLIDERSEQ.svg ├── STEPS.svg ├── STEREO.svg ├── SUB.svg ├── Segment7Standard.ttf ├── VARIABLE.svg ├── cach.svg ├── cfBigKnob-bg.svg ├── cfBigKnob.svg ├── cfTrimpot-bg.svg ├── cfTrimpot.svg ├── distocach.svg ├── downButton.svg ├── downButtonDown.svg ├── plusButton.svg ├── trSEQ.svg ├── upButton.svg └── upButtonDown.svg ├── screens ├── cf064.png ├── cf064b.png ├── clock.png ├── cube1.png ├── four1.png ├── four2.png ├── four3.png ├── mixer.png ├── peak1.png ├── peak2.png ├── player1.png ├── player2.png ├── steps1.png ├── steps2.png ├── trseq1.png ├── trseq2.png └── trseq3.png └── src ├── ALGEBRA.cpp ├── BUFFER.cpp ├── CHOKE.cpp ├── CUBE.cpp ├── CUTS.cpp ├── DAVE.cpp ├── DISTO.cpp ├── EACH.cpp ├── FOUR.cpp ├── FUNKTION.cpp ├── L3DS3Q.cpp ├── LABEL.cpp ├── LEDSEQ.cpp ├── MASTER.cpp ├── METRO.cpp ├── MONO.cpp ├── PATCH.cpp ├── PEAK.cpp ├── PLAY.cpp ├── PLAYER.cpp ├── SLIDERSEQ.cpp ├── STEPS.cpp ├── STEREO.cpp ├── SUB.cpp ├── VARIABLE.cpp ├── dr_wav.h ├── plugin.cpp ├── plugin.hpp └── trSEQ.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | build/ 3 | 4 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | Copyright (c) 2019, Clement Foulc 3 | All rights reserved. 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | * Redistributions of source code must retain the above copyright notice, this 7 | list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright notice, 9 | this list of conditions and the following disclaimer in the documentation 10 | and/or other materials provided with the distribution. 11 | * Neither the name of the copyright holder nor the names of its 12 | contributors may be used to endorse or promote products derived from 13 | this software without specific prior written permission. 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | SOURCES += $(wildcard src/*.cpp) 2 | 3 | DISTRIBUTABLES += $(wildcard LICENSE*) res 4 | DISTRIBUTABLES += $(wildcard LICENSE*) playeroscs 5 | 6 | RACK_DIR ?= ../.. 7 | include $(RACK_DIR)/plugin.mk 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ![alt text](/screens/cf064.png) 4 | 5 | 6 | **trSEQ : tr style 16 steps SEQ with trig input per step** 7 | 8 |   main functions : cf. Fundamental/SEQ3 9 | 10 |   steps :   each step can be turned on/off manually by clicking it or can be automated 11 | 12 |               and/or externally controlled thru its own trig input 13 | 14 |               you can use an external keyboard, pad controller, or third party app to use your computer keyboard 15 | 16 |               as a midi keyboard, via Core/midi-trigger-to-CV or Core/midi-to-CV 17 | 18 |               or any CV/trigger source/modifier like Audible/Bernouilli's gate for randomness 19 | 20 |   tap in :  input notes by clicking on the pad or sending trigs or sustained gates to the corresponding input 21 | 22 |               (cf. steps) 23 | 24 |   clear :   same as "tap in" but for deleting notes 25 | 26 | ![alt text](/screens/trseq1.png) 27 | 28 | ![alt text](/screens/trseq2.png) 29 | 30 | ![alt text](/screens/trseq3.png) 31 | 32 | 33 | 34 | 35 | 36 | **STEPS : variable quantiser** 37 | 38 |     originally conceived as a companion for PLAYER, 39 | 40 |     used between a LFO or a SEQ CV out and PLAYER's start input 41 | 42 |     it will quantize 0 to 10 Volts CV to regular steps, 43 | 44 |     allowing for regular slicing of breakbeat loops or anything else 45 | 46 | ![alt text](/screens/steps1.png) 47 | 48 | ![alt text](/screens/steps2.png) 49 | 50 | 51 | 52 | 53 | 54 | **PLAYER : sampler [mod from Bidoo's OUAIve]** 55 | 56 |   use right click menu to select a .wav or .aif sample (some hi-res or compressed ones won't open) 57 | 58 |   gate :      the sample will be played while the gate is open (i.e. input > 0 V.) 59 | 60 |                 try retrigger mode (right click menu) with most seq's 61 | 62 |                 or use an enveloppe or ML gate delay to have a correct gate for your needs 63 | 64 |   start :     use knob to choose start point and/or attenuverted CV input 65 | 66 |                 (don't forget to "open" the attenuverter) 67 | 68 |   speed :   same as start but for speed, very low setting will play reverse (from start point) 69 | 70 |   trick :     use a square fast LFO on gate input and a saw LFO on start input to get dirty time stretch 71 | 72 | ![alt text](/screens/player1.png) 73 | 74 | ![alt text](/screens/player2.png) 75 | 76 | 77 | 78 | 79 | 80 | **PEAK : Peak limiter** 81 | 82 |   threshold :   turn it down from 10 V. to 0 V. until it lights up as the limiter acts 83 | 84 |   make up :    turn it up to adjust gain, lights up when signal gets over 10 V. 85 | 86 | 87 |   trick :     if input is unplugged, PEAK will output screen's voltage 88 | 89 |                 it can also be use as an attenu/amp. 90 | 91 | ![alt text](/screens/peak1.png) 92 | 93 | ![alt text](/screens/peak2.png) 94 | 95 | 96 | 97 | 98 | 99 | **CUBE : a blank panel turned weird module** 100 | 101 |   inputs :  each input receives CV to controle the rotation speed on a different axis 102 | 103 |               modulate with a LFO, or any other signal 104 | 105 |   output :  is Z coordinate of one of the points of the cube 106 | 107 |               found it quite unpredictable, especially when inputs are modulated 108 | 109 |               Pretty and experimental :) 110 | 111 | ![alt text](/screens/cube1.png) 112 | 113 | 114 | 115 | **FOUR : 4 trigged solos/mutes** 116 | 117 |   each signal "line" can be turned on/off or soloed, manually and/or triggered thru its own trig input 118 | 119 |               you can use an external keyboard, pad controller, or third party app to use your computer keyboard 120 | 121 |               as a midi keyboard, via Core/midi-trigger-to-CV or Core/midi-to-CV 122 | 123 |               or any CV/trigger source/modifier like Audible/Bernouilli's gate for randomness 124 | 125 | ![alt text](/screens/four1.png) 126 | 127 | ![alt text](/screens/four2.png) 128 | 129 | ![alt text](/screens/four3.png) 130 | 131 | 132 | 133 | 134 | 135 | **MONO STEREO MASTER : modular mixer** 136 | 137 |   you can use them in combination to make a mixer 138 | 139 |   with any number of mono and/or stereo channels, sub groups, etc. 140 | 141 | 142 | 143 |   in :        gets your mono or stero signal in 144 | 145 |   out :       on MONO, duplicates the signal post gain, post on and solo, 146 | 147 |                 for redirection to an FX (reverb, delay, ...) or any other use 148 | 149 | 150 |   gain :      multiplies the in signal by 0 to 2, 1 is at 12 o'clock/reset position 151 | 152 |                 beware of your levels, a red light will bright up over 10 V. 153 | 154 |   gain input : over-rides gain knob and turns 0 to 10 V. input 155 | 156 |                 into 0 to 2 multiplier (1 being 5 V.) 157 | 158 |                 for automation and/or external control 159 | 160 | 161 |   on :        switches the signal of this channel on/off 162 | 163 |   on input :  inverts on state on trig 164 | 165 |                 for automation and/or external control 166 | 167 | 168 | 169 |   solo :      turns off un-soloed channels in a solo-group, cf. solo-link 170 | 171 |   solo input : inverts solo state on trig 172 | 173 |                 for automation and/or external control 174 | 175 | 176 | 177 |   pan :       attenuates one side of the stereo signal 178 | 179 |   pan input : over-rides pan knob and turns 0 to 10 V. input into left to right (5 being center) 180 | 181 |                 for automation and/or external control 182 | 183 | 184 | 185 |   stereo bus : stereo signal gets in 186 | 187 |                 adds gained & pan'ed input signal 188 | 189 |                 stereo signal gets out to next channel or master 190 | 191 | 192 |   S-L :       solo link, make a solo group so that solo'ing a channel or many will turn off others 193 | 194 |                 by linking them so they can communicate, 195 | 196 |                 don't forget to link the last to the first. 197 | 198 | ![alt text](/screens/mixer.png) 199 | 200 | 201 | 202 | 203 | 204 | 205 | **METRO : master clock and metronome** 206 | 207 |   BPM :        sets the beat per minute tempo 208 | 209 |   BPM input :   over-rides BPM knob 210 | 211 |                  turns 0 to 10 V. into 0 to 300 bpm 212 | 213 |   on :         turns METRO on/off, starts on first beat (most of the times) 214 | 215 |   on input :    turns METRO on/off on trig 216 | 217 |   reset :      sets METRO back to 1st beat without stoping it 218 | 219 |                  use to reset dividers and seqs on the fly 220 | 221 |   mes. light : will light up on 1st beat out of 4 222 | 223 |   beat light : will light up on every beat 224 | 225 |   head speaker : outputs audio metronome 226 | 227 |                  TOC-toc-toc-toc-TOC-toc-toc-toc-TOC-toc... 228 | 229 |   start :      will output a trig on start or reset 230 | 231 |   x 12 :      will output 12 trigs per beat 232 | 233 | 234 | 235 | 236 | 237 | **EACH : clock divider** 238 | 239 |   left circuit 'start' will receive and duplicate 240 | 241 |                start/reset trigs to its ouputs 242 | 243 |   right circuit 'x 12' will receive and duplicate 244 | 245 |                trigs stream ('x 12' from METRO) to its output 246 | 247 |                and 1 out of DIV. (knob/screen) trig to the middle output 248 | 249 |                allow sync'ing of seqs 250 | 251 |                3 will give you 1/4 of beat, 4 triolets, 6 half beat and so on 252 | 253 |   DIV. input : over-rides DIV. knob 254 | 255 |                turns 0 to 10 V. to 1 to 12 divs 256 | 257 |   trick :    chain EACHs to trig events every mesure, 4 mesures or 16 mesures 258 | 259 | 260 | ![alt text](/screens/clock.png) 261 | 262 | 263 | 264 | 265 | **PATCH : patch bay** 266 | 267 |   mainly here to take cables out of the view 268 | 269 |   signals follow the lines between inputs and outputs 270 | 271 | 272 | 273 | 274 | **DAVE : blank panel** 275 | 276 | 277 | please, [DONATE](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=3CSNFE349G99Q) so i can buy other devs'modules, and thanks to those who already did :) 278 | -------------------------------------------------------------------------------- /playeroscs/noisepink.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cfoulc/cf/9509b744621b200d96bc8136d126d5e8090da74f/playeroscs/noisepink.wav -------------------------------------------------------------------------------- /playeroscs/noisewhite.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cfoulc/cf/9509b744621b200d96bc8136d126d5e8090da74f/playeroscs/noisewhite.wav -------------------------------------------------------------------------------- /playeroscs/osc1.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cfoulc/cf/9509b744621b200d96bc8136d126d5e8090da74f/playeroscs/osc1.wav -------------------------------------------------------------------------------- /playeroscs/osc2.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cfoulc/cf/9509b744621b200d96bc8136d126d5e8090da74f/playeroscs/osc2.wav -------------------------------------------------------------------------------- /playeroscs/osc3.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cfoulc/cf/9509b744621b200d96bc8136d126d5e8090da74f/playeroscs/osc3.wav -------------------------------------------------------------------------------- /playeroscs/osc4.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cfoulc/cf/9509b744621b200d96bc8136d126d5e8090da74f/playeroscs/osc4.wav -------------------------------------------------------------------------------- /playeroscs/osc5.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cfoulc/cf/9509b744621b200d96bc8136d126d5e8090da74f/playeroscs/osc5.wav -------------------------------------------------------------------------------- /playeroscs/osc6.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cfoulc/cf/9509b744621b200d96bc8136d126d5e8090da74f/playeroscs/osc6.wav -------------------------------------------------------------------------------- /playeroscs/osc7.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cfoulc/cf/9509b744621b200d96bc8136d126d5e8090da74f/playeroscs/osc7.wav -------------------------------------------------------------------------------- /playeroscs/osc8.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cfoulc/cf/9509b744621b200d96bc8136d126d5e8090da74f/playeroscs/osc8.wav -------------------------------------------------------------------------------- /playeroscs/saw.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cfoulc/cf/9509b744621b200d96bc8136d126d5e8090da74f/playeroscs/saw.wav -------------------------------------------------------------------------------- /plugin.json: -------------------------------------------------------------------------------- 1 | { 2 | "slug": "cf", 3 | "version": "2.0.2", 4 | "license": "BSD-3-Clause", 5 | "name": "cf", 6 | "brand": "cf", 7 | "author": "clement foulc", 8 | "authorEmail": "c.foulc@gmail.com", 9 | "pluginUrl": "https://github.com/cfoulc/cf", 10 | "authorUrl": "https://github.com/cfoulc", 11 | "manualUrl": "https://github.com/cfoulc/cf", 12 | "sourceUrl": "https://github.com/cfoulc/cf", 13 | "changelogUrl": "https://github.com/cfoulc/cf", 14 | "donateUrl": "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=3CSNFE349G99Q", 15 | "modules": [ 16 | { 17 | "slug": "METRO", 18 | "name": "Metro", 19 | "description": "Clock", 20 | "manualUrl": "https://github.com/cfoulc/cf", 21 | "tags": [ 22 | "Clock generator" 23 | ] 24 | }, 25 | { 26 | "slug": "EACH", 27 | "name": "Each", 28 | "description": "Clock divider", 29 | "manualUrl": "https://github.com/cfoulc/cf", 30 | "tags": [ 31 | "Clock modulator" 32 | ] 33 | }, 34 | { 35 | "slug": "trSEQ", 36 | "name": "trSeq", 37 | "description": "sequencer with per step inputs", 38 | "manualUrl": "https://github.com/cfoulc/cf", 39 | "tags": [ 40 | "Sequencer" 41 | ] 42 | }, 43 | { 44 | "slug": "LEDSEQ", 45 | "name": "ledSeq", 46 | "description": "5x16 triggers sequencer", 47 | "manualUrl": "https://github.com/cfoulc/cf", 48 | "tags": [ 49 | "Sequencer" 50 | ] 51 | }, 52 | { 53 | "slug": "L3DS3Q", 54 | "name": "l3dS3q", 55 | "description": "5x16 triggers sequencer", 56 | "manualUrl": "https://github.com/cfoulc/cf", 57 | "tags": [ 58 | "Sequencer" 59 | ] 60 | }, 61 | { 62 | "slug": "SLIDERSEQ", 63 | "name": "SliderSeq", 64 | "description": "16 CVs sequencer", 65 | "manualUrl": "https://github.com/cfoulc/cf", 66 | "tags": [ 67 | "Sequencer" 68 | ] 69 | }, 70 | { 71 | "slug": "PLAYER", 72 | "name": "Player", 73 | "description": "Sample player", 74 | "manualUrl": "https://github.com/cfoulc/cf", 75 | "tags": [ 76 | "Sampler" 77 | ] 78 | }, 79 | { 80 | "slug": "PLAY", 81 | "name": "Play", 82 | "description": "Mini sample player", 83 | "manualUrl": "https://github.com/cfoulc/cf", 84 | "tags": [ 85 | "Sampler" 86 | ] 87 | }, 88 | { 89 | "slug": "MONO", 90 | "name": "Mono", 91 | "description": "Modular mixer Mono Channel", 92 | "manualUrl": "https://github.com/cfoulc/cf", 93 | "tags": [ 94 | "Mixer" 95 | ] 96 | }, 97 | { 98 | "slug": "STEREO", 99 | "name": "Stereo", 100 | "description": "Modular mixer Stereo Channel", 101 | "manualUrl": "https://github.com/cfoulc/cf", 102 | "tags": [ 103 | "Mixer" 104 | ] 105 | }, 106 | { 107 | "slug": "SUB", 108 | "name": "Sub", 109 | "description": "Modular mixer Sends", 110 | "manualUrl": "https://github.com/cfoulc/cf", 111 | "tags": [ 112 | "Mixer" 113 | ] 114 | }, 115 | { 116 | "slug": "MASTER", 117 | "name": "Master", 118 | "description": "Modular mixer Master", 119 | "manualUrl": "https://github.com/cfoulc/cf", 120 | "tags": [ 121 | "Mixer" 122 | ] 123 | }, 124 | { 125 | "slug": "VARIABLE", 126 | "name": "Variable", 127 | "description": "Sample & Hold", 128 | "manualUrl": "https://github.com/cfoulc/cf", 129 | "tags": [ 130 | "Utility" 131 | ] 132 | }, 133 | { 134 | "slug": "ALGEBRA", 135 | "name": "Algebra", 136 | "description": "2 signals math", 137 | "manualUrl": "https://github.com/cfoulc/cf", 138 | "tags": [ 139 | "Utility" 140 | ] 141 | }, 142 | { 143 | "slug": "FUNKTION", 144 | "name": "Funktion", 145 | "description": "1 signal math", 146 | "manualUrl": "https://github.com/cfoulc/cf", 147 | "tags": [ 148 | "Utility" 149 | ] 150 | }, 151 | { 152 | "slug": "CHOKE", 153 | "name": "Choke", 154 | "description": "hi hat style choker", 155 | "manualUrl": "https://github.com/cfoulc/cf", 156 | "tags": [ 157 | "Utility" 158 | ] 159 | }, 160 | { 161 | "slug": "FOUR", 162 | "name": "Four", 163 | "description": "4 x solo/mute", 164 | "manualUrl": "https://github.com/cfoulc/cf", 165 | "tags": [ 166 | "Utility" 167 | ] 168 | }, 169 | { 170 | "slug": "STEPS", 171 | "name": "Steps", 172 | "description": "quantiser", 173 | "manualUrl": "https://github.com/cfoulc/cf", 174 | "tags": [ 175 | "Utility" 176 | ] 177 | }, 178 | { 179 | "slug": "PEAK", 180 | "name": "Peak", 181 | "description": "limiter", 182 | "manualUrl": "https://github.com/cfoulc/cf", 183 | "tags": [ 184 | "Limiter" 185 | ] 186 | }, 187 | { 188 | "slug": "CUTS", 189 | "name": "Cuts", 190 | "description": "dirty HP & LP filters", 191 | "manualUrl": "https://github.com/cfoulc/cf", 192 | "tags": [ 193 | "Filter" 194 | ] 195 | }, 196 | { 197 | "slug": "BUFFER", 198 | "name": "Buffer", 199 | "description": "dirty delay buffer/filter", 200 | "manualUrl": "https://github.com/cfoulc/cf", 201 | "tags": [ 202 | "Delay" 203 | ] 204 | }, 205 | { 206 | "slug": "DISTO", 207 | "name": "Disto", 208 | "description": "dirty distortion", 209 | "manualUrl": "https://github.com/cfoulc/cf", 210 | "tags": [ 211 | "Distortion" 212 | ] 213 | }, 214 | { 215 | "slug": "CUBE", 216 | "name": "Cube", 217 | "description": "weird lfo", 218 | "manualUrl": "https://github.com/cfoulc/cf", 219 | "tags": [ 220 | "Low-frequency oscillator" 221 | ] 222 | }, 223 | { 224 | "slug": "PATCH", 225 | "name": "Patch", 226 | "description": "patch bay", 227 | "manualUrl": "https://github.com/cfoulc/cf", 228 | "tags": [ 229 | "Utility" 230 | ] 231 | }, 232 | { 233 | "slug": "LABEL", 234 | "name": "LABEL", 235 | "description": "label", 236 | "manualUrl": "https://github.com/cfoulc/cf", 237 | "tags": [ 238 | "Visual" 239 | ] 240 | }, 241 | { 242 | "slug": "DAVE", 243 | "name": "Dave", 244 | "description": "blank panel", 245 | "manualUrl": "https://github.com/cfoulc/cf", 246 | "tags": [ 247 | "Blank" 248 | ] 249 | } 250 | ] 251 | } 252 | -------------------------------------------------------------------------------- /res/ALGEBRA.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 27 | 32 | 33 | 34 | 37 | 38 | 39 | 45 | 46 | 47 | 49 | 50 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /res/ArialBlack.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cfoulc/cf/9509b744621b200d96bc8136d126d5e8090da74f/res/ArialBlack.ttf -------------------------------------------------------------------------------- /res/CHOKE.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 27 | 32 | 33 | 36 | 38 | 40 | 41 | 43 | 46 | 49 | 56 | 57 | 58 | 60 | 63 | 66 | 73 | 74 | 76 | 79 | 80 | -------------------------------------------------------------------------------- /res/DejaVu-LICENSE.txt: -------------------------------------------------------------------------------- 1 | Fonts are (c) Bitstream (see below). DejaVu changes are in public domain. 2 | Glyphs imported from Arev fonts are (c) Tavmjong Bah (see below) 3 | 4 | Bitstream Vera Fonts Copyright 5 | ------------------------------ 6 | 7 | Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is 8 | a trademark of Bitstream, Inc. 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of the fonts accompanying this license ("Fonts") and associated 12 | documentation files (the "Font Software"), to reproduce and distribute the 13 | Font Software, including without limitation the rights to use, copy, merge, 14 | publish, distribute, and/or sell copies of the Font Software, and to permit 15 | persons to whom the Font Software is furnished to do so, subject to the 16 | following conditions: 17 | 18 | The above copyright and trademark notices and this permission notice shall 19 | be included in all copies of one or more of the Font Software typefaces. 20 | 21 | The Font Software may be modified, altered, or added to, and in particular 22 | the designs of glyphs or characters in the Fonts may be modified and 23 | additional glyphs or characters may be added to the Fonts, only if the fonts 24 | are renamed to names not containing either the words "Bitstream" or the word 25 | "Vera". 26 | 27 | This License becomes null and void to the extent applicable to Fonts or Font 28 | Software that has been modified and is distributed under the "Bitstream 29 | Vera" names. 30 | 31 | The Font Software may be sold as part of a larger software package but no 32 | copy of one or more of the Font Software typefaces may be sold by itself. 33 | 34 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 35 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, 36 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, 37 | TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME 38 | FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING 39 | ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, 40 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 41 | THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE 42 | FONT SOFTWARE. 43 | 44 | Except as contained in this notice, the names of Gnome, the Gnome 45 | Foundation, and Bitstream Inc., shall not be used in advertising or 46 | otherwise to promote the sale, use or other dealings in this Font Software 47 | without prior written authorization from the Gnome Foundation or Bitstream 48 | Inc., respectively. For further information, contact: fonts at gnome dot 49 | org. 50 | 51 | Arev Fonts Copyright 52 | ------------------------------ 53 | 54 | Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved. 55 | 56 | Permission is hereby granted, free of charge, to any person obtaining 57 | a copy of the fonts accompanying this license ("Fonts") and 58 | associated documentation files (the "Font Software"), to reproduce 59 | and distribute the modifications to the Bitstream Vera Font Software, 60 | including without limitation the rights to use, copy, merge, publish, 61 | distribute, and/or sell copies of the Font Software, and to permit 62 | persons to whom the Font Software is furnished to do so, subject to 63 | the following conditions: 64 | 65 | The above copyright and trademark notices and this permission notice 66 | shall be included in all copies of one or more of the Font Software 67 | typefaces. 68 | 69 | The Font Software may be modified, altered, or added to, and in 70 | particular the designs of glyphs or characters in the Fonts may be 71 | modified and additional glyphs or characters may be added to the 72 | Fonts, only if the fonts are renamed to names not containing either 73 | the words "Tavmjong Bah" or the word "Arev". 74 | 75 | This License becomes null and void to the extent applicable to Fonts 76 | or Font Software that has been modified and is distributed under the 77 | "Tavmjong Bah Arev" names. 78 | 79 | The Font Software may be sold as part of a larger software package but 80 | no copy of one or more of the Font Software typefaces may be sold by 81 | itself. 82 | 83 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 84 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 85 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 86 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL 87 | TAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 88 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 89 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 90 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 91 | OTHER DEALINGS IN THE FONT SOFTWARE. 92 | 93 | Except as contained in this notice, the name of Tavmjong Bah shall not 94 | be used in advertising or otherwise to promote the sale, use or other 95 | dealings in this Font Software without prior written authorization 96 | from Tavmjong Bah. For further information, contact: tavmjong @ free 97 | . fr. 98 | 99 | $Id: LICENSE 2133 2007-11-28 02:46:28Z lechimp $ 100 | -------------------------------------------------------------------------------- /res/DejaVuSansMono.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cfoulc/cf/9509b744621b200d96bc8136d126d5e8090da74f/res/DejaVuSansMono.ttf -------------------------------------------------------------------------------- /res/FUNKTION.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 27 | 32 | 33 | 34 | 40 | 41 | 42 | 43 | 45 | 46 | 47 | 48 | 49 | 52 | 53 | 55 | 56 | -------------------------------------------------------------------------------- /res/L.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /res/LABEL.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 26 | 31 | 32 | 34 | 35 | 36 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /res/LEDCalculator.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cfoulc/cf/9509b744621b200d96bc8136d126d5e8090da74f/res/LEDCalculator.ttf -------------------------------------------------------------------------------- /res/LEDS.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | 11 | 12 | 16 | 21 | 22 | 23 | 24 | 25 | 27 | 32 | 37 | 38 | 39 | 41 | 46 | 47 | 51 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /res/Ldown.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /res/PATCH.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 21 | 26 | 27 | 28 | 29 | 30 | 31 | 36 | 39 | 40 | 44 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /res/PLAY.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 27 | 32 | 33 | 34 | 35 | 36 | 38 | 40 | 41 | 45 | 46 | 49 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /res/PadButton.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | 11 | 13 | 14 | -------------------------------------------------------------------------------- /res/PadButtonDown.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | 11 | 13 | 14 | -------------------------------------------------------------------------------- /res/Segment7Standard.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cfoulc/cf/9509b744621b200d96bc8136d126d5e8090da74f/res/Segment7Standard.ttf -------------------------------------------------------------------------------- /res/VARIABLE.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 27 | 32 | 33 | 35 | 36 | 37 | 40 | 41 | 42 | 44 | 48 | 49 | 54 | 55 | 56 | 58 | 64 | 65 | 69 | 70 | 71 | 73 | 76 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /res/cach.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 13 | 14 | 17 | 19 | 20 | -------------------------------------------------------------------------------- /res/cfBigKnob.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 44 | 46 | 47 | 49 | image/svg+xml 50 | 52 | 53 | 54 | 55 | 56 | 61 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /res/cfTrimpot-bg.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 38 | 44 | 52 | 56 | 60 | 61 | 67 | 75 | 79 | 83 | 84 | 90 | 97 | 104 | 109 | -------------------------------------------------------------------------------- /res/cfTrimpot.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21 | 22 | 23 | 24 | 42 | 61 | 62 | -------------------------------------------------------------------------------- /res/distocach.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | 12 | 14 | 16 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /res/downButton.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | 11 | 12 | 13 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /res/downButtonDown.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | 11 | 12 | 13 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /res/plusButton.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21 | 26 | 50 | 55 | 56 | 58 | 61 | 62 | 69 | 124 | -------------------------------------------------------------------------------- /res/upButton.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /res/upButtonDown.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /screens/cf064.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cfoulc/cf/9509b744621b200d96bc8136d126d5e8090da74f/screens/cf064.png -------------------------------------------------------------------------------- /screens/cf064b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cfoulc/cf/9509b744621b200d96bc8136d126d5e8090da74f/screens/cf064b.png -------------------------------------------------------------------------------- /screens/clock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cfoulc/cf/9509b744621b200d96bc8136d126d5e8090da74f/screens/clock.png -------------------------------------------------------------------------------- /screens/cube1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cfoulc/cf/9509b744621b200d96bc8136d126d5e8090da74f/screens/cube1.png -------------------------------------------------------------------------------- /screens/four1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cfoulc/cf/9509b744621b200d96bc8136d126d5e8090da74f/screens/four1.png -------------------------------------------------------------------------------- /screens/four2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cfoulc/cf/9509b744621b200d96bc8136d126d5e8090da74f/screens/four2.png -------------------------------------------------------------------------------- /screens/four3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cfoulc/cf/9509b744621b200d96bc8136d126d5e8090da74f/screens/four3.png -------------------------------------------------------------------------------- /screens/mixer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cfoulc/cf/9509b744621b200d96bc8136d126d5e8090da74f/screens/mixer.png -------------------------------------------------------------------------------- /screens/peak1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cfoulc/cf/9509b744621b200d96bc8136d126d5e8090da74f/screens/peak1.png -------------------------------------------------------------------------------- /screens/peak2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cfoulc/cf/9509b744621b200d96bc8136d126d5e8090da74f/screens/peak2.png -------------------------------------------------------------------------------- /screens/player1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cfoulc/cf/9509b744621b200d96bc8136d126d5e8090da74f/screens/player1.png -------------------------------------------------------------------------------- /screens/player2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cfoulc/cf/9509b744621b200d96bc8136d126d5e8090da74f/screens/player2.png -------------------------------------------------------------------------------- /screens/steps1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cfoulc/cf/9509b744621b200d96bc8136d126d5e8090da74f/screens/steps1.png -------------------------------------------------------------------------------- /screens/steps2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cfoulc/cf/9509b744621b200d96bc8136d126d5e8090da74f/screens/steps2.png -------------------------------------------------------------------------------- /screens/trseq1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cfoulc/cf/9509b744621b200d96bc8136d126d5e8090da74f/screens/trseq1.png -------------------------------------------------------------------------------- /screens/trseq2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cfoulc/cf/9509b744621b200d96bc8136d126d5e8090da74f/screens/trseq2.png -------------------------------------------------------------------------------- /screens/trseq3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cfoulc/cf/9509b744621b200d96bc8136d126d5e8090da74f/screens/trseq3.png -------------------------------------------------------------------------------- /src/ALGEBRA.cpp: -------------------------------------------------------------------------------- 1 | #include "plugin.hpp" 2 | 3 | 4 | 5 | using namespace std; 6 | 7 | 8 | struct ALGEBRA : Module { 9 | enum ParamIds { 10 | ENUMS(OP_PARAM, 6), 11 | NUM_PARAMS 12 | }; 13 | enum InputIds { 14 | IN1_INPUT, 15 | IN2_INPUT, 16 | NUM_INPUTS 17 | }; 18 | enum OutputIds { 19 | OUT_OUTPUT, 20 | NUM_OUTPUTS 21 | }; 22 | enum LightIds { 23 | NUM_LIGHTS 24 | }; 25 | 26 | int OP_STATE = 0 ; 27 | dsp::SchmittTrigger trTrigger[6]; 28 | 29 | ALGEBRA() { 30 | config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); 31 | configInput(IN1_INPUT,"a"); 32 | configInput(IN2_INPUT,"b"); 33 | configOutput(OUT_OUTPUT,"Result"); 34 | configButton(OP_PARAM + 0,"+"); 35 | configButton(OP_PARAM + 1,"-"); 36 | configButton(OP_PARAM + 2,"x"); 37 | configButton(OP_PARAM + 3,"/"); 38 | configButton(OP_PARAM + 4,"Max"); 39 | configButton(OP_PARAM + 5,"Min"); 40 | configBypass(IN1_INPUT, OUT_OUTPUT); 41 | 42 | } 43 | 44 | 45 | json_t *dataToJson() override { 46 | json_t *rootJ = json_object(); 47 | 48 | 49 | json_object_set_new(rootJ, "opstate", json_integer(OP_STATE)); 50 | return rootJ; 51 | } 52 | 53 | void dataFromJson(json_t *rootJ) override { 54 | 55 | 56 | json_t *opstateJ = json_object_get(rootJ, "opstate"); 57 | if (opstateJ) 58 | OP_STATE = json_integer_value(opstateJ); 59 | 60 | } 61 | 62 | 63 | 64 | 65 | 66 | void process(const ProcessArgs &args) override { 67 | for (int i=0; i<6; i++) { 68 | if (trTrigger[i].process(params[OP_PARAM+i].getValue())) OP_STATE= i; 69 | } 70 | 71 | if (OP_STATE==0) outputs[OUT_OUTPUT].setVoltage(inputs[IN1_INPUT].getVoltage() + inputs[IN2_INPUT].getVoltage()); 72 | if (OP_STATE==1) outputs[OUT_OUTPUT].setVoltage(inputs[IN1_INPUT].getVoltage() - inputs[IN2_INPUT].getVoltage()); 73 | if (OP_STATE==2) outputs[OUT_OUTPUT].setVoltage(inputs[IN1_INPUT].getVoltage() * inputs[IN2_INPUT].getVoltage()); 74 | if ((OP_STATE==3) & (inputs[IN2_INPUT].getVoltage()!=0)) outputs[OUT_OUTPUT].setVoltage(inputs[IN1_INPUT].getVoltage() / inputs[IN2_INPUT].getVoltage()); 75 | if (OP_STATE==4) { 76 | if (inputs[IN1_INPUT].getVoltage()>=inputs[IN2_INPUT].getVoltage()) outputs[OUT_OUTPUT].setVoltage(inputs[IN1_INPUT].getVoltage()); 77 | else outputs[OUT_OUTPUT].setVoltage(inputs[IN2_INPUT].getVoltage()); 78 | } 79 | if (OP_STATE==5) { 80 | if (inputs[IN1_INPUT].getVoltage()<=inputs[IN2_INPUT].getVoltage()) outputs[OUT_OUTPUT].setVoltage(inputs[IN1_INPUT].getVoltage()); 81 | else outputs[OUT_OUTPUT].setVoltage(inputs[IN2_INPUT].getVoltage()); 82 | } 83 | 84 | } 85 | }; 86 | 87 | struct plusButton : app::SvgSwitch { 88 | plusButton() { 89 | momentary = true; 90 | shadow->opacity = 0; 91 | addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/plusButton.svg"))); 92 | } 93 | }; 94 | 95 | 96 | struct ALGDisplay : TransparentWidget { 97 | ALGEBRA *module; 98 | std::string fileDesc = "+"; 99 | int numero =0; 100 | int frame = 0; 101 | 102 | 103 | ALGDisplay() { 104 | 105 | }; 106 | 107 | void draw(const DrawArgs &args) override { 108 | std::shared_ptr font = APP->window->loadFont(asset::plugin(pluginInstance, "res/ArialBlack.ttf")); 109 | 110 | // if (font) { 111 | nvgFontFaceId(args.vg, font->handle); 112 | nvgFontSize(args.vg, 20); 113 | nvgTextLetterSpacing(args.vg, 0); 114 | nvgFillColor(args.vg, nvgRGBA(0x00, 0x00, 0x00, 0xff)); 115 | nvgTextBox(args.vg, 5, 5,350, fileDesc.c_str(), NULL); 116 | // } 117 | } 118 | 119 | void drawLayer(const DrawArgs &args, int layer) override { 120 | std::shared_ptr font = APP->window->loadFont(asset::plugin(pluginInstance, "res/ArialBlack.ttf")); 121 | // if (font) { 122 | if (layer ==1) { 123 | float val = module ? module->OP_STATE : 0; 124 | 125 | if (val==numero){ 126 | nvgFontFaceId(args.vg, font->handle); 127 | nvgFontSize(args.vg, 20); 128 | nvgTextLetterSpacing(args.vg, 0); 129 | nvgFillColor(args.vg, nvgRGBA(0x4c, 0xc7, 0xf3, 0xff)); 130 | nvgTextBox(args.vg, 5, 5,350, fileDesc.c_str(), NULL); 131 | } 132 | } 133 | // } 134 | Widget::drawLayer(args, layer); 135 | } 136 | }; 137 | 138 | struct ALGEBRAWidget : ModuleWidget { 139 | ALGEBRAWidget(ALGEBRA *module){ 140 | setModule(module); 141 | setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/ALGEBRA.svg"))); 142 | 143 | addChild(createWidget(Vec(15, 0))); 144 | addChild(createWidget(Vec(box.size.x-30, 365))); 145 | 146 | 147 | addInput(createInput(Vec(3, 31), module, ALGEBRA::IN1_INPUT)); 148 | addInput(createInput(Vec(3, 95), module, ALGEBRA::IN2_INPUT)); 149 | 150 | int i = 0; 151 | addParam(createParam(Vec(6, i*24+136), module, ALGEBRA::OP_PARAM + i)); i=i+1; 152 | addParam(createParam(Vec(6, i*24+136), module, ALGEBRA::OP_PARAM + i)); i=i+1; 153 | addParam(createParam(Vec(6, i*24+136), module, ALGEBRA::OP_PARAM + i)); i=i+1; 154 | addParam(createParam(Vec(6, i*24+136), module, ALGEBRA::OP_PARAM + i)); i=i+1; 155 | addParam(createParam(Vec(6, i*24+136), module, ALGEBRA::OP_PARAM + i)); i=i+1; 156 | addParam(createParam(Vec(6, i*24+136), module, ALGEBRA::OP_PARAM + i)); 157 | 158 | 159 | 160 | 161 | addOutput(createOutput(Vec(3, 321), module, ALGEBRA::OUT_OUTPUT)); 162 | 163 | { 164 | ALGDisplay *plusdisplay = new ALGDisplay(); 165 | plusdisplay->box.pos = Vec(6, 145); 166 | plusdisplay->module = module; 167 | plusdisplay->fileDesc = "+"; 168 | plusdisplay->numero = 0; 169 | addChild(plusdisplay); 170 | } 171 | { 172 | ALGDisplay *moinsdisplay = new ALGDisplay(); 173 | moinsdisplay->box.pos = Vec(9, 145+24-1); 174 | moinsdisplay->module = module; 175 | moinsdisplay->fileDesc = "-"; 176 | moinsdisplay->numero = 1; 177 | addChild(moinsdisplay); 178 | } 179 | { 180 | ALGDisplay *foisdisplay = new ALGDisplay(); 181 | foisdisplay->box.pos = Vec(6, 145+24*2-1); 182 | foisdisplay->module = module; 183 | foisdisplay->fileDesc = "x"; 184 | foisdisplay->numero = 2; 185 | addChild(foisdisplay); 186 | } 187 | { 188 | ALGDisplay *divdisplay = new ALGDisplay(); 189 | divdisplay->box.pos = Vec(9, 145+24*3); 190 | divdisplay->module = module; 191 | divdisplay->fileDesc = "/"; 192 | divdisplay->numero = 3; 193 | addChild(divdisplay); 194 | } 195 | { 196 | ALGDisplay *maxdisplay = new ALGDisplay(); 197 | maxdisplay->box.pos = Vec(4, 145+24*4); 198 | maxdisplay->module = module; 199 | maxdisplay->fileDesc = "M"; 200 | maxdisplay->numero = 4; 201 | addChild(maxdisplay); 202 | } 203 | { 204 | ALGDisplay *mindisplay = new ALGDisplay(); 205 | mindisplay->box.pos = Vec(4, 145+24*5-1); 206 | mindisplay->module = module; 207 | mindisplay->fileDesc = "m"; 208 | mindisplay->numero = 5; 209 | addChild(mindisplay); 210 | } 211 | 212 | } 213 | }; 214 | 215 | 216 | Model *modelALGEBRA = createModel("ALGEBRA"); 217 | -------------------------------------------------------------------------------- /src/BUFFER.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "plugin.hpp" 3 | 4 | 5 | 6 | struct BUFFER : Module { 7 | enum ParamIds { 8 | MODE_PARAM, 9 | LENGTH_PARAM, 10 | FB_PARAM, 11 | NUM_PARAMS 12 | }; 13 | enum InputIds { 14 | IN_INPUT, 15 | FB_INPUT, 16 | LENGTH_INPUT, 17 | NUM_INPUTS 18 | 19 | }; 20 | enum OutputIds { 21 | X_OUTPUT, 22 | NUM_OUTPUTS 23 | }; 24 | enum LightIds { 25 | MODE_LIGHT, 26 | NUM_LIGHTS 27 | }; 28 | 29 | 30 | float buf[10000] ={}; 31 | float x = 0; 32 | int pos = 0; 33 | int length = 0; 34 | float l_gain ; 35 | int l_affi ; 36 | 37 | bool MODE_STATE = false ; 38 | dsp::SchmittTrigger modeTrigger; 39 | 40 | 41 | BUFFER() { 42 | config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); 43 | configButton(MODE_PARAM,"Pseudofilter mode"); 44 | configParam(FB_PARAM, 0.0f, 1.0f, 0.5f, "Feedback"); 45 | configParam(LENGTH_PARAM, 0.0f, 1.0f, 0.5f, "Length"); 46 | configInput(IN_INPUT, "Signal"); 47 | configInput(FB_INPUT, "Signal feedback"); 48 | configInput(LENGTH_INPUT, "Length control"); 49 | configOutput(X_OUTPUT, "Signal"); 50 | configBypass(IN_INPUT, X_OUTPUT); 51 | 52 | } 53 | 54 | 55 | json_t *dataToJson() override { 56 | json_t *rootJ = json_object(); 57 | 58 | 59 | json_object_set_new(rootJ, "modestate", json_integer(MODE_STATE)); 60 | return rootJ; 61 | } 62 | 63 | void dataFromJson(json_t *rootJ) override { 64 | 65 | 66 | json_t *modestateJ = json_object_get(rootJ, "modestate"); 67 | if (modestateJ) 68 | MODE_STATE = json_integer_value(modestateJ); 69 | 70 | } 71 | 72 | 73 | 74 | 75 | 76 | void process(const ProcessArgs &args) override { 77 | 78 | if (modeTrigger.process(params[MODE_PARAM].getValue())) 79 | {if (MODE_STATE == 0) MODE_STATE = 1; else MODE_STATE = 0;} 80 | 81 | lights[MODE_LIGHT].setBrightness(MODE_STATE); 82 | 83 | if (!inputs[LENGTH_INPUT].isConnected()) { 84 | length = int(params[LENGTH_PARAM].getValue()*9998.0f)+1; 85 | l_affi =0;l_gain = params[LENGTH_PARAM].getValue()*10; 86 | } 87 | else { 88 | length = clamp(int(inputs[LENGTH_INPUT].getVoltage()*999.8f),0,9998)+1; 89 | l_gain = clamp(inputs[LENGTH_INPUT].getVoltage(),0.0f,10.0f); 90 | l_affi = 1; 91 | } 92 | 93 | if (MODE_STATE) length = (int(length/10))+2; 94 | 95 | buf[pos]=(inputs[IN_INPUT].getVoltage()+inputs[FB_INPUT].getVoltage()*params[FB_PARAM].getValue()) ; // /(1.0+params[FB_PARAM].getValue()); 96 | 97 | x = float(pos) ; 98 | if (pos<9999) pos=pos+1; else pos=0; 99 | 100 | if (!MODE_STATE) { 101 | if ((pos-length)>0) 102 | outputs[X_OUTPUT].setVoltage(clamp(buf[pos-length],-10.0f,10.0f)); 103 | else 104 | outputs[X_OUTPUT].setVoltage(clamp(buf[9999+pos-length],-10.0f,10.0f)); 105 | } else { 106 | float som = 0.0; 107 | for (int i = 1 ; i < length ; i++) { 108 | if ((pos-i)>0) 109 | som=som+buf[pos-i]; 110 | else 111 | som=som+buf[9999+pos-i]; 112 | } 113 | 114 | outputs[X_OUTPUT].setVoltage(clamp((inputs[FB_INPUT].getVoltage()*params[FB_PARAM].getValue() - (som / float(length-1))),-10.0f,10.0f)); 115 | } 116 | 117 | 118 | } 119 | 120 | }; 121 | 122 | struct BUFFERDisplay : TransparentWidget { 123 | BUFFER *module; 124 | 125 | BUFFERDisplay() { 126 | 127 | 128 | } 129 | 130 | void drawLayer(const DrawArgs &args, int layer) override { 131 | 132 | if (module) { 133 | if (layer ==1) { 134 | nvgStrokeWidth(args.vg,1.2); 135 | nvgStrokeColor(args.vg, nvgRGBA(0x28, 0xb0, 0xf3, 0xff )); 136 | { 137 | nvgBeginPath(args.vg); 138 | nvgMoveTo(args.vg, clamp(module->buf[int(module->x)]*4.0f,-45.0f,45.0f),0.0f); 139 | for (int i=1;ilength; i++) {if ((module->x-i)>0) nvgLineTo(args.vg, clamp(module->buf[int(module->x)-i]*4.0f,-45.0f,45.0f), -200.0*(i+1)/(module->length)); 140 | else nvgLineTo(args.vg, clamp(module->buf[9999+int(module->x)-i]*4.0f,-45.0f,45.0f), -200.0*(i+1)/(module->length)); 141 | } 142 | } 143 | nvgLineCap(args.vg, NVG_ROUND); 144 | nvgMiterLimit(args.vg, 20.0f); 145 | nvgGlobalCompositeOperation(args.vg, NVG_LIGHTER); 146 | nvgStroke(args.vg); 147 | 148 | } 149 | }; 150 | Widget::drawLayer(args, layer); 151 | } 152 | }; 153 | 154 | struct MBDisplay : TransparentWidget { 155 | BUFFER *module; 156 | 157 | MBDisplay() { 158 | 159 | } 160 | 161 | void draw(const DrawArgs &args) override { 162 | //nvgGlobalTint(args.vg, color::WHITE); 163 | float gainX = module ? module->l_gain : 1.0f; 164 | //int affich = module ? module->l_affi : 0; 165 | float d=8; 166 | 167 | //if (affich==1) { 168 | float xx = d*sin(-(gainX*0.17+0.15)*M_PI) ; 169 | float yy = d*cos((gainX*0.17+0.15)*M_PI) ; 170 | float xx0 = (d-6)*sin(-(gainX*0.17+0.15)*M_PI) ; 171 | float yy0 = (d-6)*cos((gainX*0.17+0.15)*M_PI) ; 172 | 173 | 174 | //nvgBeginPath(args.vg); 175 | //nvgCircle(args.vg, 0,0, d); 176 | //nvgFillColor(args.vg, nvgRGBA(0x00, 0x00, 0x00, 0xff)); 177 | //nvgFill(args.vg); 178 | 179 | nvgStrokeWidth(args.vg,2); 180 | nvgStrokeColor(args.vg, nvgRGBA(0xff, 0xff, 0xff, 0x88)); 181 | { 182 | nvgBeginPath(args.vg); 183 | nvgMoveTo(args.vg, xx0,yy0); 184 | nvgLineTo(args.vg, xx,yy); 185 | nvgClosePath(args.vg); 186 | } 187 | nvgStroke(args.vg); 188 | //} 189 | 190 | } 191 | }; 192 | 193 | 194 | /////////////////// 195 | 196 | struct BUFFERWidget : ModuleWidget { 197 | BUFFERWidget(BUFFER *module) { 198 | setModule(module); 199 | setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/BUFFER.svg"))); 200 | 201 | 202 | addChild(createWidget(Vec(15, 0))); 203 | addChild(createWidget(Vec(box.size.x-30, 0))); 204 | addChild(createWidget(Vec(15, 365))); 205 | addChild(createWidget(Vec(box.size.x-30, 365))); 206 | 207 | { 208 | BUFFERDisplay *bdisplay = new BUFFERDisplay(); 209 | bdisplay->box.pos = Vec(60, 270); 210 | bdisplay->module = module ; 211 | addChild(bdisplay); 212 | } 213 | 214 | 215 | addParam(createParam(Vec(19, 35), module, BUFFER::MODE_PARAM)); 216 | addChild(createLight>(Vec(23.4, 39.4), module, BUFFER::MODE_LIGHT)); 217 | 218 | addInput(createInput(Vec(15, 321), module, BUFFER::IN_INPUT)); 219 | 220 | addInput(createInput(Vec(47, 321), module, BUFFER::FB_INPUT)); 221 | addParam(createParam(Vec(50.4, 284), module, BUFFER::FB_PARAM)); 222 | 223 | addInput(createInput(Vec(80, 321), module, BUFFER::LENGTH_INPUT)); 224 | addParam(createParam(Vec(83.4, 284), module, BUFFER::LENGTH_PARAM)); 225 | { 226 | MBDisplay *pdisplay = new MBDisplay(); 227 | pdisplay->box.pos = Vec(92.4, 293); 228 | pdisplay->module = module; 229 | addChild(pdisplay); 230 | } 231 | addOutput(createOutput(Vec(80, 31), module, BUFFER::X_OUTPUT)); 232 | 233 | } 234 | }; 235 | 236 | Model *modelBUFFER = createModel("BUFFER"); -------------------------------------------------------------------------------- /src/CHOKE.cpp: -------------------------------------------------------------------------------- 1 | #include "plugin.hpp" 2 | 3 | 4 | 5 | using namespace std; 6 | 7 | 8 | struct CHOKE : Module { 9 | enum ParamIds { 10 | PAN_PARAM, 11 | NUM_PARAMS 12 | }; 13 | enum InputIds { 14 | TRIG1_INPUT, 15 | TRIG2_INPUT, 16 | IN1_INPUT, 17 | IN2_INPUT, 18 | NUM_INPUTS 19 | }; 20 | enum OutputIds { 21 | OUT_OUTPUT, 22 | NUM_OUTPUTS 23 | }; 24 | enum LightIds { 25 | L1_LIGHT, 26 | L2_LIGHT, 27 | NUM_LIGHTS 28 | }; 29 | 30 | bool play = false; 31 | dsp::SchmittTrigger tr1Trigger; 32 | dsp::SchmittTrigger tr2Trigger; 33 | 34 | CHOKE() { 35 | config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); 36 | configParam(PAN_PARAM, -1.0f, 1.0f, 0.0f, "Mix"); 37 | configInput(TRIG1_INPUT, "Select signal 1 trigger"); 38 | configInput(TRIG2_INPUT, "Select signal 2 trigger"); 39 | configInput(IN1_INPUT, "Signal 1"); 40 | configInput(IN2_INPUT, "Signal 2"); 41 | configOutput(OUT_OUTPUT, "Signal"); 42 | configBypass(IN1_INPUT, OUT_OUTPUT); 43 | } 44 | 45 | 46 | void process(const ProcessArgs &args) override { 47 | 48 | if (tr1Trigger.process(inputs[TRIG1_INPUT].getVoltage())) 49 | { 50 | play = false ; 51 | 52 | }; 53 | if (tr2Trigger.process(inputs[TRIG2_INPUT].getVoltage())) 54 | { 55 | play = true ; 56 | 57 | }; 58 | if (play) 59 | outputs[OUT_OUTPUT].setVoltage(inputs[IN2_INPUT].getVoltage()*(1-clamp(-params[PAN_PARAM].getValue(),0.0f,1.0f))); 60 | else outputs[OUT_OUTPUT].setVoltage(inputs[IN1_INPUT].getVoltage()*(1-clamp(params[PAN_PARAM].getValue(),0.0f,1.0f))); 61 | 62 | lights[L1_LIGHT].setBrightness(!play); 63 | lights[L2_LIGHT].setBrightness(play); 64 | } 65 | }; 66 | 67 | 68 | 69 | struct CHOKEWidget : ModuleWidget { 70 | CHOKEWidget(CHOKE *module) { 71 | setModule(module); 72 | 73 | setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/CHOKE.svg"))); 74 | 75 | 76 | addChild(createWidget(Vec(15, 0))); 77 | addChild(createWidget(Vec(box.size.x-30, 365))); 78 | 79 | addParam(createParam(Vec(6, 298), module, CHOKE::PAN_PARAM)); 80 | 81 | addInput(createInput(Vec(3, 61), module, CHOKE::IN1_INPUT)); 82 | addInput(createInput(Vec(3, 91), module, CHOKE::TRIG1_INPUT)); 83 | 84 | addInput(createInput(Vec(3, 181), module, CHOKE::IN2_INPUT)); 85 | addInput(createInput(Vec(3, 211), module, CHOKE::TRIG2_INPUT)); 86 | 87 | addChild(createLight>(Vec(8, 136), module, CHOKE::L1_LIGHT)); 88 | addChild(createLight>(Vec(8, 256), module, CHOKE::L2_LIGHT)); 89 | 90 | 91 | addOutput(createOutput(Vec(3, 321), module, CHOKE::OUT_OUTPUT)); 92 | 93 | } 94 | }; 95 | 96 | 97 | Model *modelCHOKE = createModel("CHOKE"); 98 | -------------------------------------------------------------------------------- /src/CUBE.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "plugin.hpp" 3 | 4 | 5 | 6 | struct CUBE : Module { 7 | enum ParamIds { 8 | 9 | NUM_PARAMS 10 | }; 11 | enum InputIds { 12 | X_INPUT, 13 | Y_INPUT, 14 | NUM_INPUTS 15 | 16 | }; 17 | enum OutputIds { 18 | X_OUTPUT, 19 | NUM_OUTPUTS 20 | }; 21 | 22 | float frameX = 0.0; 23 | float frameY = 0.0; 24 | 25 | float xx[12] = {-1.0, 1.0, 1.0,-1.0,-1.0, 1.0, 1.0,-1.0}; 26 | float yy[12] = {-1.0,-1.0, 1.0, 1.0,-1.0,-1.0, 1.0, 1.0}; 27 | float zz[12] = {-1.0,-1.0,-1.0,-1.0, 1.0, 1.0, 1.0, 1.0}; 28 | 29 | float x[8] = {}; 30 | float y[8] = {}; 31 | float z[8] = {}; 32 | 33 | float d = 0.0; 34 | float theta= 0.0 ; 35 | float gainX = 1.0; 36 | float gainY = 1.0; 37 | 38 | 39 | CUBE() { 40 | config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS); 41 | configInput(X_INPUT, "X speed control"); 42 | configInput(Y_INPUT, "Y speed control"); 43 | configOutput(X_OUTPUT, "Result"); 44 | } 45 | 46 | 47 | void process(const ProcessArgs &args) override { 48 | gainX = 0.5f; gainY = 0.5f; 49 | if (inputs[X_INPUT].isConnected()) gainX=inputs[X_INPUT].getVoltage(); 50 | if (inputs[Y_INPUT].isConnected()) gainY=inputs[Y_INPUT].getVoltage(); 51 | 52 | for(int i=0; i<8; i++) 53 | { 54 | d = sqrt(yy[i]*yy[i] + zz[i]*zz[i]); 55 | theta = atan2(yy[i],zz[i])+frameX; 56 | x[i] = xx[i]; 57 | y[i] = d * sin(theta); 58 | z[i] = d * cos(theta); 59 | 60 | d = sqrt(x[i]*x[i] + z[i]*z[i]); 61 | theta = atan2(x[i],z[i])+frameY; 62 | x[i] = d * sin(theta); 63 | y[i] = y[i]; 64 | z[i] = d * cos(theta); 65 | } 66 | 67 | if (frameX<100) frameX=frameX+gainX* args.sampleTime; else frameX=0; 68 | if (frameY<100) frameY=frameY+gainY* args.sampleTime; else frameY=0; 69 | 70 | 71 | outputs[X_OUTPUT].setVoltage(z[0]*5.0); 72 | }; 73 | }; 74 | 75 | struct CUBEDisplay : TransparentWidget { 76 | CUBE *module; 77 | 78 | 79 | CUBEDisplay() { 80 | 81 | } 82 | 83 | void drawLayer(const DrawArgs &args, int layer) override { 84 | 85 | if (module) { 86 | if (layer ==1) { 87 | nvgStrokeColor(args.vg, nvgRGBA(0x28, 0xb0, 0xf3, 0xff)); 88 | { 89 | nvgBeginPath(args.vg); 90 | nvgMoveTo(args.vg, module->x[0]*20,module->y[0]*20); 91 | nvgLineTo(args.vg, module->x[1]*20,module->y[1]*20); 92 | nvgLineTo(args.vg, module->x[2]*20,module->y[2]*20); 93 | nvgLineTo(args.vg, module->x[3]*20,module->y[3]*20); 94 | nvgClosePath(args.vg); 95 | } 96 | nvgStroke(args.vg); 97 | 98 | { 99 | nvgBeginPath(args.vg); 100 | nvgMoveTo(args.vg, module->x[4]*20,module->y[4]*20); 101 | nvgLineTo(args.vg, module->x[5]*20,module->y[5]*20); 102 | nvgLineTo(args.vg, module->x[6]*20,module->y[6]*20); 103 | nvgLineTo(args.vg, module->x[7]*20,module->y[7]*20); 104 | nvgClosePath(args.vg); 105 | } 106 | nvgStroke(args.vg); 107 | 108 | { 109 | nvgBeginPath(args.vg); 110 | nvgMoveTo(args.vg, module->x[0]*20,module->y[0]*20); 111 | nvgLineTo(args.vg, module->x[4]*20,module->y[4]*20); 112 | nvgClosePath(args.vg); 113 | } 114 | nvgStroke(args.vg); 115 | 116 | { 117 | nvgBeginPath(args.vg); 118 | nvgMoveTo(args.vg, module->x[1]*20,module->y[1]*20); 119 | nvgLineTo(args.vg, module->x[5]*20,module->y[5]*20); 120 | nvgClosePath(args.vg); 121 | } 122 | nvgStroke(args.vg); 123 | 124 | { 125 | nvgBeginPath(args.vg); 126 | nvgMoveTo(args.vg, module->x[2]*20,module->y[2]*20); 127 | nvgLineTo(args.vg, module->x[6]*20,module->y[6]*20); 128 | nvgClosePath(args.vg); 129 | } 130 | nvgStroke(args.vg); 131 | 132 | { 133 | nvgBeginPath(args.vg); 134 | nvgMoveTo(args.vg, module->x[3]*20,module->y[3]*20); 135 | nvgLineTo(args.vg, module->x[7]*20,module->y[7]*20); 136 | nvgClosePath(args.vg); 137 | } 138 | nvgStroke(args.vg); 139 | 140 | };}; 141 | Widget::drawLayer(args, layer); 142 | } 143 | }; 144 | 145 | 146 | 147 | struct CUBEWidget : ModuleWidget { 148 | CUBEWidget(CUBE *module) { 149 | setModule(module); 150 | setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/CUBE.svg"))); 151 | 152 | addChild(createWidget(Vec(15, 0))); 153 | addChild(createWidget(Vec(box.size.x-30, 0))); 154 | addChild(createWidget(Vec(15, 365))); 155 | addChild(createWidget(Vec(box.size.x-30, 365))); 156 | 157 | { 158 | CUBEDisplay *display = new CUBEDisplay(); 159 | display->box.pos = Vec(60, 120); 160 | display->module = module; 161 | addChild(display); 162 | } 163 | 164 | addInput(createInput(Vec(15, 321), module, CUBE::X_INPUT)); 165 | addInput(createInput(Vec(47, 321), module, CUBE::Y_INPUT)); 166 | addOutput(createOutput(Vec(80, 321), module, CUBE::X_OUTPUT)); 167 | 168 | } 169 | }; 170 | 171 | Model *modelCUBE = createModel("CUBE"); -------------------------------------------------------------------------------- /src/CUTS.cpp: -------------------------------------------------------------------------------- 1 | #include "plugin.hpp" 2 | 3 | 4 | 5 | struct CUTS : Module { 6 | enum ParamIds { 7 | POTF_PARAM, 8 | POTR_PARAM, 9 | LINK_PARAM, 10 | POLE_PARAM, 11 | BPOTF_PARAM, 12 | BPOTR_PARAM, 13 | NUM_PARAMS 14 | }; 15 | enum InputIds { 16 | IN_INPUT, 17 | IN2_INPUT, 18 | F_INPUT, 19 | R_INPUT, 20 | NUM_INPUTS 21 | }; 22 | enum OutputIds { 23 | OUT_OUTPUT, 24 | OUT2_OUTPUT, 25 | NUM_OUTPUTS 26 | }; 27 | enum LightIds { 28 | LINK_LIGHT, 29 | NUM_LIGHTS 30 | }; 31 | 32 | int poles = 4; 33 | 34 | float prevf1[8]; 35 | float prevf2[8]; 36 | float prevf3[8]; 37 | float prevf4[8]; 38 | 39 | float delta=0.0; 40 | float temp1=0.0; 41 | float temp2=0.0; 42 | float temp3=0.0; 43 | float temp4=0.0; 44 | 45 | float rin=0; 46 | bool rv =false; 47 | float fin=0; 48 | bool fv =false; 49 | 50 | bool LINK_STATE =false; 51 | float link_delta; 52 | dsp::SchmittTrigger linkTrigger; 53 | 54 | CUTS() { 55 | config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); 56 | configButton(LINK_PARAM, "Link"); 57 | configParam(POLE_PARAM, 1.0f, 8.0f, 4.0f, "Pole"); 58 | configParam(POTR_PARAM, 0.0f, 1.0f, 0.0f, "Low cut freq"); 59 | configParam(POTF_PARAM, 0.0f, 1.0f, 1.0f, "Hi cut freq"); 60 | configParam(BPOTR_PARAM, 0.0f, 1.0f, 0.0f, "Low cut freq"); 61 | configParam(BPOTF_PARAM, 0.0f, 1.0f, 1.0f, "Hi cut freq"); 62 | configInput(IN_INPUT, "Left"); 63 | configInput(IN2_INPUT, "Right"); 64 | configInput(F_INPUT, "Hi cut freq control"); 65 | configInput(R_INPUT, "Low cut freq control"); 66 | configOutput(OUT_OUTPUT, "Left"); 67 | configOutput(OUT2_OUTPUT, "Right"); 68 | configBypass(IN_INPUT, OUT_OUTPUT); 69 | configBypass(IN2_INPUT, OUT2_OUTPUT); 70 | onReset(); 71 | } 72 | 73 | 74 | json_t *dataToJson() override { 75 | json_t *rootJ = json_object(); 76 | 77 | 78 | json_object_set_new(rootJ, "linkstate", json_integer(LINK_STATE)); 79 | json_object_set_new(rootJ, "linkdelta", json_real(link_delta)); 80 | return rootJ; 81 | } 82 | 83 | void dataFromJson(json_t *rootJ) override { 84 | 85 | 86 | json_t *linkstateJ = json_object_get(rootJ, "linkstate"); 87 | if (linkstateJ) 88 | LINK_STATE = json_integer_value(linkstateJ); 89 | 90 | json_t *ldJ = json_object_get(rootJ, "linkdelta"); 91 | if (ldJ) 92 | link_delta = json_real_value(ldJ); 93 | 94 | } 95 | 96 | 97 | 98 | void process(const ProcessArgs &args) override { 99 | 100 | poles = int(params[POLE_PARAM].getValue()); 101 | 102 | if (linkTrigger.process(params[LINK_PARAM].getValue())) 103 | {if (LINK_STATE == 0) {LINK_STATE = 1; link_delta = fin-rin;} else LINK_STATE = 0;} 104 | lights[LINK_LIGHT].setBrightness(LINK_STATE); 105 | 106 | if (inputs[R_INPUT].isConnected()) { 107 | rv = true; 108 | rin = clamp(inputs[R_INPUT].getVoltage(),0.0,10.0)/10.0; 109 | params[BPOTR_PARAM].setValue(rin); 110 | } else { 111 | rv = false; 112 | rin = params[POTR_PARAM].getValue(); 113 | } 114 | 115 | if (!LINK_STATE) { 116 | if (inputs[F_INPUT].isConnected()) { 117 | fv = true; 118 | fin = clamp(inputs[F_INPUT].getVoltage(),0.0,10.0)/10.0; 119 | params[BPOTF_PARAM].setValue(fin); 120 | } else { 121 | fv = false; 122 | fin = params[POTF_PARAM].getValue(); 123 | } 124 | } else { 125 | if (inputs[R_INPUT].isConnected()) { 126 | fv = true; 127 | fin = clamp(inputs[R_INPUT].getVoltage()/10.0+link_delta,0.0f,1.0f); 128 | params[BPOTF_PARAM].setValue(fin); 129 | ////////////////////params[BPOTR_PARAM].setValue(fin); 130 | } else { 131 | if (inputs[F_INPUT].isConnected()) { 132 | rv = true; 133 | rin = clamp(inputs[F_INPUT].getVoltage()/10-link_delta,0.0f,1.0f); 134 | params[BPOTR_PARAM].setValue(rin); 135 | fv = true; 136 | fin = clamp(inputs[F_INPUT].getVoltage()/10,0.0f,1.0f); 137 | params[BPOTF_PARAM].setValue(fin); 138 | } else { 139 | fv = true; 140 | fin = clamp(params[POTR_PARAM].getValue()+link_delta,0.0f,1.0f); 141 | params[BPOTF_PARAM].setValue(fin); 142 | } 143 | } 144 | } 145 | 146 | if (inputs[IN_INPUT].isConnected()) { 147 | temp1 = inputs[IN_INPUT].getVoltage(); 148 | 149 | for (int i=0;iwindow->loadSvg(asset::plugin(pluginInstance, "res/CUTS.svg"))); 203 | 204 | addChild(createWidget(Vec(15, 0))); 205 | addChild(createWidget(Vec(15, 365))); 206 | 207 | 208 | addInput(createInput(Vec(3, 308), module, CUTS::IN_INPUT)); 209 | addInput(createInput(Vec(3, 334), module, CUTS::IN2_INPUT)); 210 | 211 | addOutput(createOutput(Vec(32, 308), module, CUTS::OUT_OUTPUT)); 212 | addOutput(createOutput(Vec(32, 334), module, CUTS::OUT2_OUTPUT)); 213 | 214 | addParam(createParam(Vec(15.5, 54), module, CUTS::POLE_PARAM)); 215 | 216 | //addParam(createParam(Vec(5, 131), module, CUTS::POTR_PARAM)); 217 | srParam = createParam(Vec(5, 131), module, CUTS::POTR_PARAM); 218 | addParam(srParam); 219 | addInput(createInput(Vec(3, 252), module, CUTS::R_INPUT)); 220 | //addParam(createParam(Vec(35, 131), module, CUTS::POTF_PARAM)); 221 | sfParam = createParam(Vec(35, 131), module, CUTS::POTF_PARAM); 222 | addParam(sfParam); 223 | addInput(createInput(Vec(32, 252), module, CUTS::F_INPUT)); 224 | 225 | 226 | bsrParam = createParam(Vec(5, 131), module, CUTS::BPOTR_PARAM); 227 | addParam(bsrParam); 228 | bsfParam = createParam(Vec(35, 131), module, CUTS::BPOTF_PARAM); 229 | addParam(bsfParam); 230 | 231 | addParam(createParam(Vec(21.5, 104), module, CUTS::LINK_PARAM)); 232 | addChild(createLight>(Vec(25.9, 108.4), module, CUTS::LINK_LIGHT)); 233 | 234 | } 235 | void step() override { 236 | CUTS *module = dynamic_cast(this->module); 237 | 238 | if (module) { 239 | bsfParam->visible = module->fv; 240 | bsrParam->visible = module->rv; 241 | sfParam->visible = !module->fv; 242 | srParam->visible = !module->rv; 243 | } 244 | 245 | ModuleWidget::step(); 246 | } 247 | }; 248 | 249 | Model *modelCUTS = createModel("CUTS"); 250 | -------------------------------------------------------------------------------- /src/DAVE.cpp: -------------------------------------------------------------------------------- 1 | #include "plugin.hpp" 2 | 3 | 4 | struct DAVE : Module { 5 | enum ParamIds { 6 | 7 | NUM_PARAMS 8 | }; 9 | enum InputIds { 10 | 11 | NUM_INPUTS 12 | }; 13 | enum OutputIds { 14 | 15 | NUM_OUTPUTS 16 | }; 17 | 18 | 19 | DAVE() { 20 | config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS); 21 | } 22 | 23 | }; 24 | 25 | 26 | 27 | struct DAVEWidget : ModuleWidget { 28 | DAVEWidget(DAVE *module) { 29 | setModule(module); 30 | setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/DAVE.svg"))); 31 | } 32 | }; 33 | 34 | 35 | Model *modelDAVE = createModel("DAVE"); 36 | -------------------------------------------------------------------------------- /src/DISTO.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "plugin.hpp" 3 | 4 | 5 | 6 | struct DISTO : Module { 7 | enum ParamIds { 8 | FOLD_PARAM, 9 | GAIN_PARAM, 10 | NUM_PARAMS 11 | }; 12 | enum InputIds { 13 | IN_INPUT, 14 | GAIN_INPUT, 15 | FOLD_INPUT, 16 | NUM_INPUTS 17 | 18 | }; 19 | enum OutputIds { 20 | X_OUTPUT, 21 | NUM_OUTPUTS 22 | }; 23 | 24 | 25 | float x = 0; 26 | float y = 0; 27 | int length = 0; 28 | float fold_gain ; 29 | int fold_affi ; 30 | float gain_gain ; 31 | int gain_affi ; 32 | 33 | DISTO(){ 34 | config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS); 35 | configParam(GAIN_PARAM, 0.0f, 10.0f, 0.2f, "Gain"); 36 | configParam(FOLD_PARAM, 0.0f, 10.0f, 0.0f, "Fold"); 37 | configInput(IN_INPUT, "Signal"); 38 | configInput(GAIN_INPUT, "Gain control"); 39 | configInput(FOLD_INPUT, "Fold control"); 40 | configOutput(X_OUTPUT, "Signal"); 41 | configBypass(IN_INPUT, X_OUTPUT); 42 | } 43 | 44 | 45 | void process(const ProcessArgs &args) override { 46 | 47 | if (inputs[FOLD_INPUT].isConnected()) { 48 | fold_affi =true; fold_gain = clamp(inputs[FOLD_INPUT].getVoltage(),-0.001,10.001) ;} 49 | else {fold_affi =false; fold_gain = params[FOLD_PARAM].getValue() ;} 50 | 51 | if (inputs[GAIN_INPUT].isConnected()) { 52 | gain_affi =true; gain_gain = clamp(inputs[GAIN_INPUT].getVoltage(),-0.001,10.001) ;} 53 | else {gain_affi =false; gain_gain = params[GAIN_PARAM].getValue() ;} 54 | 55 | //////////DISTO 56 | x=inputs[IN_INPUT].getVoltage()*5.0f*gain_gain; 57 | 58 | if (abs(x)>5) y = clamp((abs(x)-5)/2.2f,0.0f,58.0f); else y=0; 59 | 60 | for (int i =0; i<100; i++) { if (x<-5.0f) x=-5.0f+(-x-5.0f)*fold_gain/5.0; 61 | if (x>5.0f) x=5.0f-(x-5.0f)*fold_gain/5.0; 62 | if ((x>=-5.0) & (x<=5.0)) i=1000; if (i==99) x=0;} 63 | 64 | 65 | //float fold; 66 | //const float bias = (x < 0) ? -5.f : 5.f; 67 | //int phase = int((x + bias) / 10.f); 68 | //bool isEven = !(phase & 1); 69 | //if (isEven) { 70 | // fold = x - 10.f * phase; 71 | //} else { 72 | // fold = -x + 10.f * phase; 73 | //} 74 | 75 | //x = ((int(x/5.0)%2)*2-1)*(x%5) + (int(x/5.0)%2)*5.0 ; 76 | 77 | //int xa ; float xb, xc; 78 | //xa=int(x/5.0) ; 79 | //xb=int(xa-2.0*int(xa/2.0)) ; 80 | //if (xb == 0) xc = (x-5*xa) ; else xc= xb*5.0 - abs(xb)*(x-5*xa) ; //+5.0*(2*xb-1) ; 81 | 82 | outputs[X_OUTPUT].setVoltage(x); //clamp(x,-5.0f,5.0f); 83 | 84 | } 85 | }; 86 | 87 | struct cachecl : SvgScrew { 88 | cachecl() { 89 | setSvg(APP->window->loadSvg(asset::plugin(pluginInstance, "res/distocach.svg"))); 90 | box.size = sw->box.size; 91 | } 92 | }; 93 | 94 | struct DISTODisplay : TransparentWidget { 95 | DISTO *module; 96 | 97 | float bu[10] = {}; 98 | int ind = 0; 99 | 100 | 101 | DISTODisplay() { 102 | 103 | } 104 | void draw(const DrawArgs &args) override { 105 | for (int i = 0 ; i<5 ; i++){ 106 | if (bu[i]>=27) 107 | {//nvgStrokeColor(args.vg, nvgRGBA(0x28, 0xb0, 0xf3, 0xff)); 108 | nvgBeginPath(args.vg); 109 | nvgCircle(args.vg, 0,0, bu[i]); 110 | nvgFillColor(args.vg, nvgRGBA(0x28, 0xb0, 0xf3, 0xaa)); 111 | nvgGlobalCompositeOperation(args.vg, NVG_LIGHTER); 112 | nvgFill(args.vg); 113 | nvgClosePath(args.vg); 114 | } 115 | } 116 | } 117 | 118 | void drawLayer(const DrawArgs &args, int layer) override { 119 | 120 | 121 | float xxxx = module ? module->y : 1.0f; 122 | 123 | for (int i = 4 ; i>0 ; i--){bu[i] = bu[i-1] ;} 124 | bu[0] = xxxx ; 125 | if (layer ==1) { 126 | for (int i = 0 ; i<5 ; i++){ 127 | if (bu[i]<27) 128 | {//nvgStrokeColor(args.vg, nvgRGBA(0x28, 0xb0, 0xf3, 0xff)); 129 | nvgBeginPath(args.vg); 130 | nvgCircle(args.vg, 0,0, bu[i]); 131 | nvgFillColor(args.vg, nvgRGBA(0x28, 0xb0, 0xf3, 0xaa)); 132 | nvgGlobalCompositeOperation(args.vg, NVG_LIGHTER); 133 | nvgFill(args.vg); 134 | nvgClosePath(args.vg); 135 | }else 136 | {//nvgStrokeColor(args.vg, nvgRGBA(0x28, 0xb0, 0xf3, 0xff)); 137 | nvgBeginPath(args.vg); 138 | nvgCircle(args.vg, 0,0, 27); 139 | nvgFillColor(args.vg, nvgRGBA(0x28, 0xb0, 0xf3, 0xaa)); 140 | nvgGlobalCompositeOperation(args.vg, NVG_LIGHTER); 141 | nvgFill(args.vg); 142 | nvgClosePath(args.vg); 143 | } 144 | } 145 | //nvgStroke(args.vg); 146 | } 147 | Widget::drawLayer(args, layer); 148 | }; 149 | }; 150 | 151 | struct MOGAINDisplay : TransparentWidget { 152 | DISTO *module; 153 | 154 | MOGAINDisplay() { 155 | 156 | } 157 | 158 | void draw(const DrawArgs &args) override { 159 | //nvgGlobalTint(args.vg, color::WHITE); 160 | float gainX = module ? module->gain_gain : 1.0f; 161 | //int affich = module ? module->gain_affi : 0; 162 | float d=8; 163 | 164 | //if (affich==1) { 165 | float xx = d*sin(-(gainX*0.17+0.15)*M_PI) ; 166 | float yy = d*cos((gainX*0.17+0.15)*M_PI) ; 167 | float xx0 = (d-6)*sin(-(gainX*0.17+0.15)*M_PI) ; 168 | float yy0 = (d-6)*cos((gainX*0.17+0.15)*M_PI) ; 169 | 170 | //nvgBeginPath(args.vg); 171 | //nvgCircle(args.vg, 0,0, d); 172 | //nvgFillColor(args.vg, nvgRGBA(0x00, 0x00, 0x00, 0xff)); 173 | //nvgFill(args.vg); 174 | 175 | nvgStrokeWidth(args.vg,2); 176 | nvgStrokeColor(args.vg, nvgRGBA(0xff, 0xff, 0xff, 0x88)); 177 | { 178 | nvgBeginPath(args.vg); 179 | nvgMoveTo(args.vg, xx0,yy0); 180 | nvgLineTo(args.vg, xx,yy); 181 | nvgClosePath(args.vg); 182 | } 183 | nvgStroke(args.vg); 184 | //} 185 | 186 | } 187 | }; 188 | 189 | struct MOFOLDDisplay : TransparentWidget { 190 | DISTO *module; 191 | 192 | MOFOLDDisplay() { 193 | 194 | } 195 | 196 | void draw(const DrawArgs &args) override { 197 | //nvgGlobalTint(args.vg, color::WHITE); 198 | float gainX = module ? module->fold_gain : 1.0f; 199 | //int affich = module ? module->fold_affi : 0; 200 | float d=8; 201 | 202 | //if (affich==1) { 203 | float xx = d*sin(-(gainX*0.17+0.15)*M_PI) ; 204 | float yy = d*cos((gainX*0.17+0.15)*M_PI) ; 205 | float xx0 = (d-6)*sin(-(gainX*0.17+0.15)*M_PI) ; 206 | float yy0 = (d-6)*cos((gainX*0.17+0.15)*M_PI) ; 207 | 208 | 209 | //nvgBeginPath(args.vg); 210 | //nvgCircle(args.vg, 0,0, d); 211 | //nvgFillColor(args.vg, nvgRGBA(0x00, 0x00, 0x00, 0xff)); 212 | //nvgFill(args.vg); 213 | 214 | nvgStrokeWidth(args.vg,2); 215 | nvgStrokeColor(args.vg, nvgRGBA(0xff, 0xff, 0xff, 0x88)); 216 | { 217 | nvgBeginPath(args.vg); 218 | nvgMoveTo(args.vg, xx0,yy0); 219 | nvgLineTo(args.vg, xx,yy); 220 | nvgClosePath(args.vg); 221 | } 222 | nvgStroke(args.vg); 223 | //} 224 | 225 | } 226 | }; 227 | 228 | struct DISTOWidget : ModuleWidget { 229 | DISTOWidget(DISTO *module){ 230 | setModule(module); 231 | setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/DISTO.svg"))); 232 | 233 | 234 | addChild(createWidget(Vec(15, 0))); 235 | addChild(createWidget(Vec(box.size.x-30, 0))); 236 | addChild(createWidget(Vec(15, 365))); 237 | addChild(createWidget(Vec(box.size.x-30, 365))); 238 | 239 | { 240 | DISTODisplay *distdisplay = new DISTODisplay(); 241 | distdisplay->box.pos = Vec(60, 170); 242 | distdisplay->module = module ; 243 | addChild(distdisplay); 244 | } 245 | 246 | addInput(createInput(Vec(15, 321), module, DISTO::IN_INPUT)); 247 | 248 | addInput(createInput(Vec(47, 321), module, DISTO::GAIN_INPUT)); 249 | addParam(createParam(Vec(50.4, 284), module, DISTO::GAIN_PARAM)); 250 | { 251 | MOGAINDisplay *gaindisplay = new MOGAINDisplay(); 252 | gaindisplay->box.pos = Vec(59.4, 293); 253 | gaindisplay->module = module; 254 | addChild(gaindisplay); 255 | } 256 | addInput(createInput(Vec(80, 321), module, DISTO::FOLD_INPUT)); 257 | addParam(createParam(Vec(83.4, 284), module, DISTO::FOLD_PARAM)); 258 | { 259 | MOFOLDDisplay *folddisplay = new MOFOLDDisplay(); 260 | folddisplay->box.pos = Vec(92.4, 293); 261 | folddisplay->module = module; 262 | addChild(folddisplay); 263 | } 264 | addOutput(createOutput(Vec(80, 31), module, DISTO::X_OUTPUT)); 265 | addChild(createWidget(Vec(0, 0))); 266 | } 267 | }; 268 | 269 | Model *modelDISTO = createModel("DISTO"); -------------------------------------------------------------------------------- /src/EACH.cpp: -------------------------------------------------------------------------------- 1 | #include "plugin.hpp" 2 | 3 | 4 | struct EACH : Module { 5 | enum ParamIds { 6 | DIV_PARAM, 7 | BEAT_PARAM, 8 | NUM_PARAMS 9 | }; 10 | enum InputIds { 11 | DOUZE_INPUT, 12 | START_INPUT, 13 | ON_INPUT, 14 | DIV_INPUT, 15 | NUM_INPUTS 16 | }; 17 | enum OutputIds { 18 | DOUZE_OUTPUT, 19 | RESET_OUTPUT, 20 | BEAT_OUTPUT, 21 | START_OUTPUT, 22 | NUM_OUTPUTS 23 | }; 24 | enum LightIds { 25 | BEAT_LIGHT, 26 | NUM_LIGHTS 27 | }; 28 | 29 | int max_EACH = 3 ; 30 | int stepa = 0 ; 31 | int lum = 0 ; 32 | int note = 0; 33 | dsp::SchmittTrigger stTrigger; 34 | dsp::SchmittTrigger dzTrigger; 35 | float or_gain =0.0; 36 | 37 | 38 | 39 | EACH() { 40 | config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); 41 | configButton(BEAT_PARAM,"Beat"); 42 | configParam(DIV_PARAM, 1.0f, 48.1f, 3.1f, "Divisions"); 43 | configInput(DIV_INPUT,"Divisions control"); 44 | 45 | configInput(DOUZE_INPUT,"12 ppn"); 46 | configOutput(DOUZE_OUTPUT,"12 ppn"); 47 | configInput(START_INPUT,"Start/reset"); 48 | configOutput(START_OUTPUT,"Start/reset"); 49 | 50 | configOutput(RESET_OUTPUT,"Start/reset"); 51 | configOutput(BEAT_OUTPUT,"Divided"); 52 | } 53 | 54 | 55 | void process(const ProcessArgs &args) override { 56 | if (!inputs[DIV_INPUT].isConnected()) { 57 | max_EACH = floor(params[DIV_PARAM].getValue()); 58 | or_gain = max_EACH/4.8; 59 | } else { 60 | max_EACH = round(clamp((inputs[DIV_INPUT].getVoltage() * 4.8)+1,1.0f,48.0f)); 61 | or_gain = (clamp(inputs[DIV_INPUT].getVoltage(),0.0f,10.0f)); 62 | } 63 | 64 | if (inputs[START_INPUT].isConnected()) { 65 | outputs[START_OUTPUT].setVoltage(inputs[START_INPUT].getVoltage()); 66 | outputs[RESET_OUTPUT].setVoltage(inputs[START_INPUT].getVoltage()); 67 | if (dzTrigger.process(inputs[START_INPUT].getVoltage())) stepa = max_EACH-1 ; 68 | } 69 | 70 | if (stTrigger.process(inputs[DOUZE_INPUT].getVoltage())) stepa = stepa +1 ; 71 | 72 | if (inputs[DOUZE_INPUT].isConnected()) { 73 | 74 | if (stepa == max_EACH) { 75 | note = 50; 76 | stepa = 0; 77 | lum = 2000; 78 | } 79 | outputs[DOUZE_OUTPUT].setVoltage(inputs[DOUZE_INPUT].getVoltage()); 80 | } 81 | if (note >0) {outputs[BEAT_OUTPUT].setVoltage(10.f);note = note -1;} else outputs[BEAT_OUTPUT].setVoltage(0.f); 82 | if (lum>0) {lights[BEAT_LIGHT].setBrightness(1);lum = lum -1;} else lights[BEAT_LIGHT].setBrightness(0); 83 | }; 84 | 85 | }; 86 | 87 | struct NuDisp : TransparentWidget { 88 | EACH *module; 89 | 90 | //std::shared_ptr font; 91 | 92 | NuDisp() { 93 | //font = APP->window->loadFont(asset::plugin(pluginInstance, "res/Segment7Standard.ttf")); 94 | }; 95 | 96 | void drawLayer(const DrawArgs &args, int layer) override { 97 | if (layer ==1) { 98 | std::shared_ptr font = APP->window->loadFont(asset::plugin(pluginInstance, "res/Segment7Standard.ttf")); 99 | int val = module ? module->max_EACH : 3; 100 | 101 | // Background 102 | NVGcolor backgroundColor = nvgRGB(0x44, 0x44, 0x44); 103 | NVGcolor borderColor = nvgRGB(0x10, 0x10, 0x10); 104 | nvgBeginPath(args.vg); 105 | nvgRoundedRect(args.vg, 0.0, 0.0, box.size.x, box.size.y, 4.0); 106 | nvgFillColor(args.vg, backgroundColor); 107 | nvgFill(args.vg); 108 | nvgStrokeWidth(args.vg, 1.0); 109 | nvgStrokeColor(args.vg, borderColor); 110 | nvgStroke(args.vg); 111 | 112 | nvgFontSize(args.vg, 18); 113 | nvgFontFaceId(args.vg, font->handle); 114 | nvgTextLetterSpacing(args.vg, 2.5); 115 | 116 | std::string to_display = std::to_string(val); 117 | 118 | 119 | while(to_display.length()<3) to_display = ' ' + to_display; 120 | 121 | Vec textPos = Vec(6.0f, 17.0f); 122 | 123 | NVGcolor textColor = nvgRGB(0xdf, 0xd2, 0x2c); 124 | nvgFillColor(args.vg, nvgTransRGBA(textColor, 16)); 125 | nvgText(args.vg, textPos.x, textPos.y, "~~~", NULL); 126 | 127 | textColor = nvgRGB(0xda, 0xe9, 0x29); 128 | 129 | nvgFillColor(args.vg, nvgTransRGBA(textColor, 16)); 130 | nvgText(args.vg, textPos.x, textPos.y, "\\\\\\", NULL); 131 | 132 | 133 | textColor = nvgRGB(0x28, 0xb0, 0xf3); 134 | nvgFillColor(args.vg, textColor); 135 | nvgText(args.vg, textPos.x, textPos.y, to_display.c_str(), NULL); 136 | } 137 | Widget::drawLayer(args, layer); 138 | } 139 | }; 140 | 141 | struct MTPOT : TransparentWidget { 142 | EACH *module; 143 | 144 | 145 | MTPOT() { 146 | 147 | } 148 | 149 | void draw(const DrawArgs &args) override { 150 | 151 | float gainX = module ? module->or_gain : 1.0f; 152 | 153 | float d=18; 154 | 155 | float xx = d*sin(-(gainX*0.17+0.15)*M_PI) ; 156 | float yy = d*cos((gainX*0.17+0.15)*M_PI) ; 157 | 158 | nvgStrokeWidth(args.vg,2); 159 | nvgStrokeColor(args.vg, nvgRGBA(0xff, 0xff, 0xff, 0x88)); 160 | { 161 | nvgBeginPath(args.vg); 162 | nvgMoveTo(args.vg, 0,0); 163 | nvgLineTo(args.vg, xx,yy); 164 | nvgClosePath(args.vg); 165 | } 166 | nvgStroke(args.vg); 167 | } 168 | }; 169 | 170 | 171 | struct EACHWidget : ModuleWidget { 172 | EACHWidget(EACH *module) { 173 | setModule(module); 174 | setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/EACH.svg"))); 175 | 176 | addChild(createWidget(Vec(15, 0))); 177 | addChild(createWidget(Vec(box.size.x-30, 0))); 178 | addChild(createWidget(Vec(15, 365))); 179 | addChild(createWidget(Vec(box.size.x-30, 365))); 180 | 181 | addInput(createInput(Vec(11, 26), module, EACH::START_INPUT)); 182 | addOutput(createOutput(Vec(35, 275), module, EACH::RESET_OUTPUT)); 183 | addOutput(createOutput(Vec(11, 321), module, EACH::START_OUTPUT)); 184 | 185 | addInput(createInput(Vec(54, 26), module, EACH::DOUZE_INPUT)); 186 | addOutput(createOutput(Vec(54, 321), module, EACH::DOUZE_OUTPUT)); 187 | addOutput(createOutput(Vec(35, 235), module, EACH::BEAT_OUTPUT)); 188 | 189 | addParam(createParam(Vec(27, 107), module, EACH::DIV_PARAM)); 190 | addInput(createInput(Vec(11, 141), module, EACH::DIV_INPUT)); 191 | { 192 | MTPOT *display1 = new MTPOT(); 193 | display1->box.pos = Vec(45, 125); 194 | display1->module = module; 195 | addChild(display1); 196 | } 197 | 198 | addParam(createParam(Vec(38, 197), module, EACH::BEAT_PARAM)); 199 | addChild(createLight>(Vec(42.4, 201.4), module, EACH::BEAT_LIGHT)); 200 | 201 | 202 | NuDisp *display2 = new NuDisp(); 203 | display2->box.pos = Vec(20,56); 204 | display2->box.size = Vec(50, 20); 205 | display2->module = module; 206 | addChild(display2); 207 | 208 | 209 | } 210 | }; 211 | 212 | Model *modelEACH = createModel("EACH"); 213 | -------------------------------------------------------------------------------- /src/FOUR.cpp: -------------------------------------------------------------------------------- 1 | #include "plugin.hpp" 2 | 3 | 4 | struct FOUR : Module { 5 | enum ParamIds { 6 | ENUMS(S_PARAM,4), 7 | ENUMS(M_PARAM,4), 8 | NUM_PARAMS 9 | }; 10 | enum InputIds { 11 | ENUMS(TRM_INPUT,4), 12 | ENUMS(TRS_INPUT,4), 13 | ENUMS(IN_INPUT,4), 14 | NUM_INPUTS 15 | }; 16 | enum OutputIds { 17 | ENUMS(OUT_OUTPUT,4), 18 | NUM_OUTPUTS 19 | }; 20 | enum LightIds { 21 | ENUMS(M_LIGHT,4), 22 | ENUMS(S_LIGHT,4), 23 | NUM_LIGHTS 24 | }; 25 | 26 | 27 | bool muteState[8] = {}; 28 | int solo = 0; 29 | int cligno = 0; 30 | 31 | dsp::SchmittTrigger muteTrigger[8]; 32 | dsp::SchmittTrigger soloTrigger[8]; 33 | 34 | 35 | FOUR() { 36 | config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); 37 | for (int i = 0; i < 4; i++) { 38 | configButton(M_PARAM + i,"Mute "+std::to_string(i+1)); 39 | configButton(S_PARAM + i,"Solo "+std::to_string(i+1)); 40 | configInput(IN_INPUT+i,"Number "+std::to_string(i+1)); 41 | configInput(TRM_INPUT+i,"Mute trigger "+std::to_string(i+1)); 42 | configInput(TRS_INPUT+i,"Solo trigger "+std::to_string(i+1)); 43 | configOutput(OUT_OUTPUT+i,"Number "+std::to_string(i+1)); 44 | } 45 | onReset(); 46 | } 47 | 48 | void onReset() override { 49 | for (int i = 0; i < 4; i++) { 50 | muteState[i] = true; 51 | muteState[i+4] = false; 52 | } 53 | solo = 0; 54 | 55 | 56 | } 57 | 58 | void onRandomize() override { 59 | for (int i = 0; i < 8; i++) { 60 | muteState[i] = (random::uniform() < 0.5); 61 | } 62 | } 63 | 64 | json_t *dataToJson() override { 65 | json_t *rootJ = json_object(); 66 | 67 | // states 68 | json_t *mutestatesJ = json_array(); 69 | for (int i = 0; i < 8; i++) { 70 | json_t *mutestateJ = json_boolean(muteState[i]); 71 | json_array_append_new(mutestatesJ, mutestateJ); 72 | } 73 | json_object_set_new(rootJ, "mutestates", mutestatesJ); 74 | 75 | // solo 76 | json_object_set_new(rootJ, "solo", json_integer(solo)); 77 | return rootJ; 78 | } 79 | 80 | void dataFromJson(json_t *rootJ) override { 81 | 82 | // states 83 | json_t *mutestatesJ = json_object_get(rootJ, "mutestates"); 84 | if (mutestatesJ) { 85 | for (int i = 0; i < 8; i++) { 86 | json_t *mutestateJ = json_array_get(mutestatesJ, i); 87 | if (mutestateJ) 88 | muteState[i] = json_boolean_value(mutestateJ); 89 | } 90 | } 91 | // solo 92 | json_t *soloJ = json_object_get(rootJ, "solo"); 93 | if (soloJ) 94 | solo = json_integer_value(soloJ); 95 | 96 | } 97 | 98 | 99 | 100 | 101 | 102 | void process(const ProcessArgs &args) override { 103 | 104 | for (int i = 0; i < 4; i++) { 105 | 106 | if (soloTrigger[i].process(params[S_PARAM + i].getValue())+soloTrigger[i+4].process(inputs[TRS_INPUT + i].getVoltage())) 107 | { 108 | muteState[i+4] ^= true; 109 | solo = (i+1)*muteState[i+4]; 110 | }; 111 | if (solo==i+1) 112 | { 113 | float in = inputs[IN_INPUT + i].getVoltage(); 114 | outputs[OUT_OUTPUT + i].setVoltage(in); 115 | 116 | } else {muteState[i+4] = false;lights[S_LIGHT + i].setBrightness(0);outputs[OUT_OUTPUT + i].setVoltage(0.0);} 117 | if (muteState[i+4]==true) 118 | { 119 | cligno = cligno + 1; 120 | if (cligno ==10000) {lights[S_LIGHT + i].setBrightness(!lights[S_LIGHT + i].getBrightness());cligno =0;} 121 | } 122 | } 123 | 124 | for (int i = 0; i < 4; i++) { 125 | if (muteTrigger[i].process(params[M_PARAM + i].getValue())+muteTrigger[i+4].process(inputs[TRM_INPUT + i].getVoltage())) 126 | muteState[i] ^= true; 127 | float in = inputs[IN_INPUT + i].getVoltage(); 128 | if (solo == 0) outputs[OUT_OUTPUT + i].setVoltage(muteState[i] ? in : 0.0); 129 | lights[M_LIGHT + i].setBrightness(muteState[i]); 130 | } 131 | 132 | 133 | } 134 | }; 135 | 136 | struct FOURWidget : ModuleWidget { 137 | FOURWidget(FOUR *module) { 138 | setModule(module); 139 | setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/FOUR.svg"))); 140 | 141 | int y = 56; 142 | 143 | 144 | addChild(createWidget(Vec(15, 0))); 145 | addChild(createWidget(Vec(box.size.x-30, 0))); 146 | addChild(createWidget(Vec(15, 365))); 147 | addChild(createWidget(Vec(box.size.x-30, 365))); 148 | 149 | for (int i = 0; i < 4; i++) { 150 | 151 | addInput(createInput(Vec(15, y), module, FOUR::IN_INPUT + i)); 152 | 153 | addInput(createInput(Vec(21, y+25), module, FOUR::TRS_INPUT + i)); 154 | addParam(createParam(Vec(45, y+4), module, FOUR::S_PARAM + i)); 155 | addChild(createLight>(Vec(45+4.4, y+8.4), module, FOUR::S_LIGHT + i)); 156 | 157 | addInput(createInput(Vec(46, y+31), module, FOUR::TRM_INPUT + i)); 158 | addParam(createParam(Vec(70, y+4), module, FOUR::M_PARAM + i)); 159 | addChild(createLight>(Vec(70+4.4, y+8.4), module, FOUR::M_LIGHT + i)); 160 | 161 | addOutput(createOutput(Vec(95, y), module, FOUR::OUT_OUTPUT + i)); 162 | 163 | y = y + 75 ; 164 | } 165 | 166 | } 167 | }; 168 | 169 | Model *modelFOUR = createModel("FOUR"); -------------------------------------------------------------------------------- /src/FUNKTION.cpp: -------------------------------------------------------------------------------- 1 | #include "plugin.hpp" 2 | 3 | 4 | 5 | using namespace std; 6 | 7 | 8 | struct FUNKTION : Module { 9 | enum ParamIds { 10 | PREV_PARAM, 11 | NEXT_PARAM, 12 | NUM_PARAMS 13 | }; 14 | enum InputIds { 15 | IN1_INPUT, 16 | NUM_INPUTS 17 | }; 18 | enum OutputIds { 19 | OUT_OUTPUT, 20 | NUM_OUTPUTS 21 | }; 22 | enum LightIds { 23 | ERROR_LIGHT, 24 | PERROR_LIGHT, 25 | OERROR_LIGHT, 26 | NUM_LIGHTS 27 | }; 28 | 29 | std::string fctDesc; 30 | int OP_STATE = 0 ; 31 | int perror = 0 ; 32 | int oerror = 0 ; 33 | dsp::SchmittTrigger nextTrigger; 34 | dsp::SchmittTrigger prevTrigger; 35 | 36 | 37 | FUNKTION() { 38 | config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); 39 | configButton(NEXT_PARAM, "Next function"); 40 | configButton(PREV_PARAM, "Previous function"); 41 | configInput(IN1_INPUT,"Signal"); 42 | configOutput(OUT_OUTPUT,"Result"); 43 | configLight(ERROR_LIGHT, "Function input error"); 44 | configLight(PERROR_LIGHT, "Function input error"); 45 | configLight(OERROR_LIGHT, "Function input error"); 46 | 47 | } 48 | 49 | 50 | json_t *dataToJson() override { 51 | json_t *rootJ = json_object(); 52 | 53 | 54 | json_object_set_new(rootJ, "opstate", json_integer(OP_STATE)); 55 | return rootJ; 56 | } 57 | 58 | void dataFromJson(json_t *rootJ) override { 59 | 60 | 61 | json_t *opstateJ = json_object_get(rootJ, "opstate"); 62 | if (opstateJ) 63 | OP_STATE = json_integer_value(opstateJ); 64 | 65 | } 66 | 67 | 68 | 69 | 70 | 71 | void process(const ProcessArgs &args) override { 72 | 73 | if (nextTrigger.process(params[NEXT_PARAM].getValue()) & (OP_STATE<20)) OP_STATE+= 1; 74 | if (prevTrigger.process(params[PREV_PARAM].getValue()) & (OP_STATE>0)) OP_STATE-= 1; 75 | 76 | float val ; 77 | 78 | if (OP_STATE==0) {val = abs(inputs[IN1_INPUT].getVoltage());fctDesc="abs";} 79 | 80 | if (OP_STATE==1) {val = round(inputs[IN1_INPUT].getVoltage());fctDesc="round";} 81 | if (OP_STATE==2) {val = ceil(inputs[IN1_INPUT].getVoltage());fctDesc="ceil";} 82 | if (OP_STATE==3) {val = int(inputs[IN1_INPUT].getVoltage());fctDesc="floor";} 83 | 84 | if (OP_STATE==4) {val = pow(inputs[IN1_INPUT].getVoltage(), 2.0);fctDesc="pow2";} 85 | if (OP_STATE==5) {val = sqrt(inputs[IN1_INPUT].getVoltage());fctDesc="sqrt";} 86 | 87 | if (OP_STATE==6) {val = exp(inputs[IN1_INPUT].getVoltage());fctDesc="exp";} 88 | if (OP_STATE==7) {val = log(inputs[IN1_INPUT].getVoltage());fctDesc="log";} 89 | if (OP_STATE==8) {val = log10(inputs[IN1_INPUT].getVoltage());fctDesc="log10";} 90 | 91 | if (OP_STATE==9) {val = cos(inputs[IN1_INPUT].getVoltage());fctDesc="cos";} 92 | if (OP_STATE==10) {val = sin(inputs[IN1_INPUT].getVoltage());fctDesc="sin";} 93 | if (OP_STATE==11) {val = tan(inputs[IN1_INPUT].getVoltage());fctDesc="tan";} 94 | if (OP_STATE==12) {val = acos(inputs[IN1_INPUT].getVoltage());fctDesc="acos";} 95 | if (OP_STATE==13) {val = asin(inputs[IN1_INPUT].getVoltage());fctDesc="asin";} 96 | if (OP_STATE==14) {val = atan(inputs[IN1_INPUT].getVoltage());fctDesc="atan";} 97 | 98 | if (OP_STATE==15) {val = cosh(inputs[IN1_INPUT].getVoltage());fctDesc="cosh";} 99 | if (OP_STATE==16) {val = sinh(inputs[IN1_INPUT].getVoltage());fctDesc="sinh";} 100 | if (OP_STATE==17) {val = tanh(inputs[IN1_INPUT].getVoltage());fctDesc="tanh";} 101 | if (OP_STATE==18) {val = acosh(inputs[IN1_INPUT].getVoltage());fctDesc="acosh";} 102 | if (OP_STATE==19) {val = asinh(inputs[IN1_INPUT].getVoltage());fctDesc="asinh";} 103 | if (OP_STATE==20) {val = atanh(inputs[IN1_INPUT].getVoltage());fctDesc="atanh";} 104 | 105 | if (isfinite(val)) lights[ERROR_LIGHT].setBrightness(0); else {lights[ERROR_LIGHT].setBrightness(1);perror=10000;oerror=50000;} 106 | if (perror>0) perror-=1;if (oerror>0) oerror-=1; 107 | lights[PERROR_LIGHT].setBrightness(float(perror)/10000.0);lights[OERROR_LIGHT].setBrightness(float(oerror)/50000.0); 108 | 109 | outputs[OUT_OUTPUT].setVoltage(val); 110 | } 111 | }; 112 | struct FUNKTIONDisplay : TransparentWidget { 113 | FUNKTION *module; 114 | 115 | int frame = 0; 116 | 117 | 118 | FUNKTIONDisplay() { 119 | 120 | } 121 | 122 | void drawLayer(const DrawArgs &args, int layer) override { 123 | if (layer ==1) { 124 | shared_ptr font = APP->window->loadFont(asset::plugin(pluginInstance, "res/LEDCalculator.ttf")); 125 | std::string fD= module ? module->fctDesc : "sin"; 126 | std::string to_display = ""; 127 | for (int i=0; i<14; i++) to_display = to_display + fD[i]; 128 | nvgFontSize(args.vg, 24); 129 | nvgFontFaceId(args.vg, font->handle); 130 | nvgTextLetterSpacing(args.vg, 0); 131 | nvgFillColor(args.vg, nvgRGBA(0x4c, 0xc7, 0xf3, 0xff)); 132 | nvgRotate(args.vg, -M_PI / 2.0f); 133 | nvgTextBox(args.vg, 5, 5,350, to_display.c_str(), NULL); 134 | } 135 | Widget::drawLayer(args, layer); 136 | } 137 | }; 138 | struct upButton : app::SvgSwitch { 139 | upButton() { 140 | momentary = true; 141 | addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/upButton.svg"))); 142 | addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/upButtonDown.svg"))); 143 | } 144 | }; 145 | struct downButton : app::SvgSwitch { 146 | downButton() { 147 | momentary = true; 148 | addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/downButton.svg"))); 149 | addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/downButtonDown.svg"))); 150 | } 151 | }; 152 | 153 | 154 | struct FUNKTIONWidget : ModuleWidget { 155 | FUNKTIONWidget(FUNKTION *module){ 156 | setModule(module); 157 | setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/FUNKTION.svg"))); 158 | 159 | addChild(createWidget(Vec(15, 0))); 160 | addChild(createWidget(Vec(box.size.x-30, 365))); 161 | 162 | 163 | addInput(createInput(Vec(3, 31), module, FUNKTION::IN1_INPUT)); 164 | //addInput(Port::create(Vec(3, 95), Port::INPUT, module, FUNKTION::IN2_INPUT)); 165 | 166 | { 167 | FUNKTIONDisplay *fdisplay = new FUNKTIONDisplay(); 168 | fdisplay->box.pos = Vec(18, 253); 169 | fdisplay->box.size = Vec(130, 250); 170 | fdisplay->module = module; 171 | addChild(fdisplay); 172 | } 173 | addChild(createLight>(Vec(11, 81.4), module, FUNKTION::ERROR_LIGHT)); 174 | addChild(createLight>(Vec(11, 96.4), module, FUNKTION::PERROR_LIGHT)); 175 | addChild(createLight>(Vec(11, 111.4), module, FUNKTION::OERROR_LIGHT)); 176 | 177 | addParam(createParam(Vec(6, 296+2), module, FUNKTION::PREV_PARAM)); 178 | addParam(createParam(Vec(6, 276+2), module, FUNKTION::NEXT_PARAM)); 179 | 180 | addOutput(createOutput(Vec(3, 321), module, FUNKTION::OUT_OUTPUT)); 181 | 182 | } 183 | }; 184 | 185 | 186 | Model *modelFUNKTION =createModel("FUNKTION"); 187 | -------------------------------------------------------------------------------- /src/L3DS3Q.cpp: -------------------------------------------------------------------------------- 1 | #include "plugin.hpp" 2 | 3 | 4 | struct L3DS3Q : Module { 5 | enum ParamIds { 6 | EDIT_PARAM, 7 | ENUMS(ON_PARAM,80), 8 | NUM_PARAMS 9 | }; 10 | enum InputIds { 11 | RST_INPUT, 12 | UP_INPUT, 13 | NUM_INPUTS 14 | }; 15 | enum OutputIds { 16 | ENUMS(TR_OUTPUT,5), 17 | NUM_OUTPUTS 18 | }; 19 | enum LightIds { 20 | EDIT_LIGHT, 21 | ENUMS(LED_LIGHT,80), 22 | NUM_LIGHTS 23 | }; 24 | 25 | 26 | int pas = 0; 27 | bool ledState[80] = {}; 28 | int tempState[5] = {}; 29 | bool editState = false ; 30 | dsp::SchmittTrigger rstTrigger; 31 | dsp::SchmittTrigger upTrigger; 32 | dsp::SchmittTrigger editTrigger; 33 | dsp::SchmittTrigger ledTrigger[80] ={}; 34 | 35 | L3DS3Q() { 36 | config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); 37 | configButton(EDIT_PARAM, "Edit mode"); 38 | for (int i = 0; i < 80; i++) { 39 | configButton(ON_PARAM + i, std::to_string(int(i%5)+1) + ":" + std::to_string(int(i/5)+1)); 40 | } 41 | for (int i = 0; i < 5; i++) { 42 | configOutput(TR_OUTPUT+i,"No " +std::to_string(i+1)+ " trigger"); 43 | } 44 | configInput(RST_INPUT,"Reset trigger"); 45 | configInput(UP_INPUT,"Step trigger"); 46 | } 47 | 48 | 49 | json_t *dataToJson() override { 50 | json_t *rootJ = json_object(); 51 | 52 | // leds 53 | json_t *ledsJ = json_array(); 54 | for (int i = 0; i < 80; i++) { 55 | json_t *ledJ = json_integer((int) ledState[i]); 56 | json_array_append_new(ledsJ, ledJ); 57 | } 58 | json_object_set_new(rootJ, "leds", ledsJ); 59 | 60 | return rootJ; 61 | } 62 | 63 | void dataFromJson(json_t *rootJ) override { 64 | 65 | // leds 66 | json_t *ledsJ = json_object_get(rootJ, "leds"); 67 | if (ledsJ) { 68 | for (int i = 0; i < 80; i++) { 69 | json_t *ledJ = json_array_get(ledsJ, i); 70 | if (ledJ) 71 | ledState[i] = !!json_integer_value(ledJ); 72 | } 73 | } 74 | 75 | } 76 | 77 | void onReset() override { 78 | for (int i = 0; i < 80; i++) { 79 | ledState[i] = false; 80 | } 81 | } 82 | 83 | void onRandomize() override { 84 | for (int i = 0; i < 80; i++) { 85 | ledState[i] = (random::uniform() > 0.5); 86 | } 87 | } 88 | 89 | 90 | 91 | 92 | void process(const ProcessArgs &args) override { 93 | 94 | if (rstTrigger.process(inputs[RST_INPUT].getVoltage())) 95 | { 96 | pas = 0; 97 | } 98 | 99 | if (upTrigger.process(inputs[UP_INPUT].getVoltage())) 100 | { 101 | for (int i = 0; i < 5; i++) { 102 | if (ledState[(i+pas*5)%80]) tempState [i] = 50; 103 | } 104 | if (pas <15) pas = pas+1; else pas =0; 105 | } 106 | 107 | if (editTrigger.process(params[EDIT_PARAM].getValue())) 108 | { 109 | editState = !editState ; 110 | lights[EDIT_LIGHT].setBrightness(editState) ; 111 | } 112 | if (!editState) 113 | { 114 | for (int i = 0; i < 80; i++) {lights[LED_LIGHT +i].setBrightness(ledState[(i+pas*5)%80]);} 115 | 116 | for (int i = 0; i < 80; i++) { 117 | if (ledTrigger[i].process(params[ON_PARAM +i].getValue())) {ledState[(i+pas*5)%80]=!ledState[(i+pas*5)%80];} 118 | }; 119 | 120 | } else { 121 | for (int i = 0; i < 80; i++) {lights[LED_LIGHT +i].setBrightness(ledState[i]);} 122 | 123 | for (int i = 0; i < 80; i++) { 124 | if (ledTrigger[i].process(params[ON_PARAM +i].getValue())) {ledState[i]=!ledState[i];} 125 | }; 126 | } 127 | 128 | for (int i = 0; i < 5; i++) { 129 | if (tempState [i]>0) {tempState [i] = tempState [i]-1;outputs[TR_OUTPUT+i].setVoltage(10.0f);} else outputs[TR_OUTPUT+i].setVoltage(0.0f); 130 | } 131 | 132 | 133 | }; 134 | }; 135 | 136 | 137 | struct LButton : app::SvgSwitch { 138 | LButton() { 139 | momentary = true; 140 | addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/L.svg"))); 141 | addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/Ldown.svg"))); 142 | } 143 | }; 144 | 145 | struct L3DS3QWidget : ModuleWidget { 146 | L3DS3QWidget(L3DS3Q *module){ 147 | setModule(module); 148 | setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/L3DS3Q.svg"))); 149 | 150 | 151 | addChild(createWidget(Vec(15, 0))); 152 | addChild(createWidget(Vec(box.size.x-30, 0))); 153 | addChild(createWidget(Vec(15, 365))); 154 | addChild(createWidget(Vec(box.size.x-30, 365))); 155 | 156 | for (int i = 0; i < 16; i++) { 157 | for (int j = 0; j < 5; j++) { 158 | addParam(createParam(Vec(j*15+10-0.8, (15-i)*15+15-0.8+51), module, L3DS3Q::ON_PARAM + (i*5+j))); 159 | addChild(createLight>(Vec(j*15+10, (15-i)*15+15+51), module, L3DS3Q::LED_LIGHT + (i*5+j))); 160 | }} 161 | 162 | addInput(createInput(Vec(32, 27), module, L3DS3Q::RST_INPUT)); 163 | addInput(createInput(Vec(4, 27), module, L3DS3Q::UP_INPUT)); 164 | 165 | addParam(createParam(Vec(65, 31), module, L3DS3Q::EDIT_PARAM)); 166 | addChild(createLight>(Vec(69.4, 35.4), module, L3DS3Q::EDIT_LIGHT)); 167 | 168 | for (int i = 0; i < 5; i++) { 169 | addOutput(createOutput(Vec(4+i*14, 332- 22*(i%2)), module, L3DS3Q::TR_OUTPUT +i)); 170 | }; 171 | 172 | 173 | 174 | 175 | }; 176 | }; 177 | 178 | Model *modelL3DS3Q = createModel("L3DS3Q"); 179 | 180 | 181 | -------------------------------------------------------------------------------- /src/LABEL.cpp: -------------------------------------------------------------------------------- 1 | #include "plugin.hpp" 2 | #include "osdialog.h" 3 | #include 4 | 5 | 6 | using namespace std; 7 | 8 | 9 | struct LABEL : Module { 10 | enum ParamIds { 11 | NUM_PARAMS 12 | }; 13 | enum InputIds { 14 | NUM_INPUTS 15 | }; 16 | enum OutputIds { 17 | NUM_OUTPUTS 18 | }; 19 | enum LightIds { 20 | NUM_LIGHTS 21 | }; 22 | 23 | 24 | std::string fileDesc = "Right clic to write"; 25 | 26 | 27 | 28 | LABEL() { 29 | config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); 30 | } 31 | 32 | json_t *dataToJson() override { 33 | json_t *rootJ = json_object(); 34 | // lastPath 35 | json_object_set_new(rootJ, "lastPath", json_string(fileDesc.c_str())); 36 | return rootJ; 37 | } 38 | 39 | void dataFromJson(json_t *rootJ) override { 40 | // lastPath 41 | json_t *lastPathJ = json_object_get(rootJ, "lastPath"); 42 | if (lastPathJ) { 43 | fileDesc = json_string_value(lastPathJ); 44 | //fileDesc = lastPath; 45 | 46 | } 47 | } 48 | 49 | 50 | 51 | void process(const ProcessArgs &args) override { 52 | 53 | } 54 | 55 | }; 56 | 57 | 58 | 59 | 60 | 61 | struct LABELDisplay : TransparentWidget { 62 | LABEL *module; 63 | 64 | int frame = 0; 65 | 66 | 67 | LABELDisplay() { 68 | 69 | } 70 | 71 | void drawLayer(const DrawArgs &args, int layer) override { 72 | if (layer ==1) { 73 | shared_ptr font = APP->window->loadFont(asset::plugin(pluginInstance, "res/LEDCalculator.ttf")); 74 | std::string fD= module ? module->fileDesc : "Right clic to write"; 75 | std::string to_display = ""; 76 | for (int i=0; i<20; i++) to_display = to_display + fD[i]; 77 | nvgFontSize(args.vg, 24); 78 | nvgFontFaceId(args.vg, font->handle); 79 | nvgTextLetterSpacing(args.vg, 0); 80 | nvgFillColor(args.vg, nvgRGBA(0x4c, 0xc7, 0xf3, 0xff)); 81 | nvgRotate(args.vg, -M_PI / 2.0f); 82 | nvgTextBox(args.vg, 5, 5,350, to_display.c_str(), NULL); 83 | } 84 | Widget::drawLayer(args, layer); 85 | } 86 | }; 87 | 88 | struct LABELItem : MenuItem { 89 | LABEL *rm ; 90 | void onAction(const event::Action &e) override { 91 | 92 | char *path = osdialog_prompt(OSDIALOG_INFO, "Label :", ""); 93 | if (path) { 94 | rm->fileDesc = std::string(path); 95 | free(path); 96 | } 97 | 98 | 99 | } 100 | 101 | }; 102 | 103 | struct LABELWidget : ModuleWidget { 104 | LABELWidget(LABEL *module){ 105 | setModule(module); 106 | setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/LABEL.svg"))); 107 | 108 | 109 | { 110 | LABELDisplay *ldisplay = new LABELDisplay(); 111 | ldisplay->box.pos = Vec(18, 333); 112 | ldisplay->box.size = Vec(130, 250); 113 | ldisplay->module = module; 114 | addChild(ldisplay); 115 | } 116 | 117 | addChild(createWidget(Vec(15, 0))); 118 | addChild(createWidget(Vec(box.size.x-30, 365))); 119 | 120 | 121 | } 122 | 123 | void appendContextMenu(Menu *menu) override { 124 | LABEL *module = dynamic_cast(this->module); 125 | assert(module); 126 | 127 | menu->addChild(new MenuEntry); 128 | 129 | LABELItem *rootDirItem = new LABELItem; 130 | rootDirItem->text = "Enter label"; 131 | rootDirItem->rm = module; 132 | menu->addChild(rootDirItem); 133 | 134 | } 135 | 136 | }; 137 | 138 | 139 | Model *modelLABEL = createModel("LABEL"); 140 | 141 | -------------------------------------------------------------------------------- /src/LEDSEQ.cpp: -------------------------------------------------------------------------------- 1 | #include "plugin.hpp" 2 | 3 | 4 | 5 | struct LEDSEQ : Module { 6 | enum ParamIds { 7 | EDIT_PARAM, 8 | ENUMS(ON_PARAM,80), 9 | NUM_PARAMS 10 | }; 11 | enum InputIds { 12 | RST_INPUT, 13 | UP_INPUT, 14 | NUM_INPUTS 15 | }; 16 | enum OutputIds { 17 | ENUMS(TR_OUTPUT,5), 18 | NUM_OUTPUTS 19 | }; 20 | enum LightIds { 21 | EDIT_LIGHT, 22 | ENUMS(LED_LIGHT,80), 23 | NUM_LIGHTS 24 | }; 25 | 26 | 27 | 28 | int pas = 0; 29 | bool ledState[80] = {}; 30 | int tempState[5] = {}; 31 | bool editState = false ; 32 | dsp::SchmittTrigger rstTrigger; 33 | dsp::SchmittTrigger upTrigger; 34 | dsp::SchmittTrigger editTrigger; 35 | dsp::SchmittTrigger ledTrigger[80] ={}; 36 | 37 | 38 | LEDSEQ() { 39 | config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); 40 | configButton(EDIT_PARAM, "Edit mode"); 41 | for (int i = 0; i < 80; i++) { 42 | configButton(ON_PARAM + i, std::to_string(int(i%5)+1) + ":" + std::to_string(int(i/5)+1)); 43 | } 44 | for (int i = 0; i < 5; i++) { 45 | configOutput(TR_OUTPUT+i,"No " +std::to_string(i+1)+ " trigger"); 46 | } 47 | configInput(RST_INPUT,"Reset trigger"); 48 | configInput(UP_INPUT,"Step trigger"); 49 | } 50 | 51 | 52 | json_t *dataToJson() override { 53 | json_t *rootJ = json_object(); 54 | 55 | // leds 56 | json_t *ledsJ = json_array(); 57 | for (int i = 0; i < 80; i++) { 58 | json_t *ledJ = json_integer((int) ledState[i]); 59 | json_array_append_new(ledsJ, ledJ); 60 | } 61 | json_object_set_new(rootJ, "leds", ledsJ); 62 | 63 | return rootJ; 64 | } 65 | 66 | void dataFromJson(json_t *rootJ) override { 67 | 68 | // leds 69 | json_t *ledsJ = json_object_get(rootJ, "leds"); 70 | if (ledsJ) { 71 | for (int i = 0; i < 80; i++) { 72 | json_t *ledJ = json_array_get(ledsJ, i); 73 | if (ledJ) 74 | ledState[i] = !!json_integer_value(ledJ); 75 | } 76 | } 77 | 78 | } 79 | 80 | void onReset() override { 81 | for (int i = 0; i < 80; i++) { 82 | ledState[i] = false; 83 | } 84 | } 85 | 86 | void onRandomize() override { 87 | for (int i = 0; i < 80; i++) { 88 | ledState[i] = (random::uniform() > 0.5); 89 | } 90 | } 91 | 92 | 93 | 94 | 95 | void process(const ProcessArgs &args) override { 96 | 97 | if (rstTrigger.process(inputs[RST_INPUT].getVoltage())) 98 | { 99 | pas = 0; 100 | } 101 | 102 | if (upTrigger.process(inputs[UP_INPUT].getVoltage())) 103 | { 104 | for (int i = 0; i < 5; i++) { 105 | if (ledState[(i+pas*5)%80]) tempState [i] = 50; 106 | } 107 | if (pas <15) pas = pas+1; else pas =0; 108 | } 109 | 110 | if (editTrigger.process(params[EDIT_PARAM].getValue())) 111 | { 112 | editState = !editState ; 113 | lights[EDIT_LIGHT].setBrightness(editState) ; 114 | } 115 | if (!editState) 116 | { 117 | for (int i = 0; i < 80; i++) {lights[LED_LIGHT +i].setBrightness(ledState[(i+pas*5)%80]);} 118 | 119 | 120 | for (int i = 0; i < 80; i++) { 121 | if (ledTrigger[i].process(params[ON_PARAM +i].getValue())) {ledState[(i+pas*5)%80]=!ledState[(i+pas*5)%80];} 122 | }; 123 | 124 | } else { 125 | for (int i = 0; i < 80; i++) {lights[LED_LIGHT +i].setBrightness(ledState[i]);} 126 | 127 | for (int i = 0; i < 80; i++) { 128 | if (ledTrigger[i].process(params[ON_PARAM +i].getValue())) {ledState[i]=!ledState[i];} 129 | }; 130 | } 131 | 132 | for (int i = 0; i < 5; i++) { 133 | if (tempState [i]>0) {tempState [i] = tempState [i]-1;outputs[TR_OUTPUT+i].setVoltage(10.0f);} else outputs[TR_OUTPUT+i].setVoltage(0.0f); 134 | } 135 | 136 | 137 | 138 | }; 139 | }; 140 | 141 | struct LButton : app::SvgSwitch { 142 | LButton() { 143 | momentary = true; 144 | addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/L.svg"))); 145 | addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/Ldown.svg"))); 146 | } 147 | }; 148 | 149 | struct LEDSEQWidget : ModuleWidget { 150 | LEDSEQWidget(LEDSEQ *module) { 151 | setModule(module); 152 | setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/LEDSEQ.svg"))); 153 | 154 | addChild(createWidget(Vec(15, 0))); 155 | addChild(createWidget(Vec(box.size.x-30, 0))); 156 | addChild(createWidget(Vec(15, 365))); 157 | addChild(createWidget(Vec(box.size.x-30, 365))); 158 | 159 | 160 | 161 | 162 | for (int i = 0; i < 16; i++) { 163 | for (int j = 0; j < 5; j++) { 164 | addParam(createParam(Vec(j*15+10-0.8, i*15+35-0.8+51), module, LEDSEQ::ON_PARAM + (i*5+j))); 165 | addChild(createLight>(Vec(j*15+10, i*15+35+51), module, LEDSEQ::LED_LIGHT + (i*5+j))); 166 | }} 167 | addInput(createInput(Vec(4, 340), module, LEDSEQ::RST_INPUT)); 168 | addInput(createInput(Vec(60, 340), module, LEDSEQ::UP_INPUT)); 169 | 170 | addParam(createParam(Vec(35, 340), module, LEDSEQ::EDIT_PARAM)); 171 | addChild(createLight>(Vec(39.4, 344.4), module, LEDSEQ::EDIT_LIGHT)); 172 | 173 | for (int i = 0; i < 5; i++) { 174 | addOutput(createOutput(Vec(4+i*14, 30+ 22*(i%2)), module, LEDSEQ::TR_OUTPUT +i)); 175 | }; 176 | 177 | 178 | 179 | 180 | }; 181 | }; 182 | 183 | Model *modelLEDSEQ =createModel("LEDSEQ"); 184 | 185 | -------------------------------------------------------------------------------- /src/MASTER.cpp: -------------------------------------------------------------------------------- 1 | #include "plugin.hpp" 2 | 3 | 4 | 5 | struct MASTER : Module { 6 | enum ParamIds { 7 | GAIN_PARAM, 8 | ON_PARAM, 9 | NUM_PARAMS 10 | }; 11 | enum InputIds { 12 | ONT_INPUT, 13 | GAIN_INPUT, 14 | LEFT_INPUT, 15 | RIGHT_INPUT, 16 | NUM_INPUTS 17 | }; 18 | enum OutputIds { 19 | LEFT_OUTPUT, 20 | RIGHT_OUTPUT, 21 | LEFT_MAIN_OUTPUT, 22 | RIGHT_MAIN_OUTPUT, 23 | NUM_OUTPUTS 24 | }; 25 | enum LightIds { 26 | ON_LIGHT, 27 | ENUMS(L_LEVEL_LIGHTS, 11), 28 | ENUMS(R_LEVEL_LIGHTS, 11), 29 | NUM_LIGHTS 30 | }; 31 | 32 | 33 | float SIGNAL_LEFT = 0.0 ; 34 | float SIGNAL_RIGHT = 0.0 ; 35 | bool ON_STATE = false ; 36 | int l_lightState[11] = {}; 37 | int r_lightState[11] = {}; 38 | dsp::SchmittTrigger onTrigger; 39 | dsp::SchmittTrigger oninTrigger; 40 | 41 | 42 | MASTER() { 43 | config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); 44 | configButton(ON_PARAM, "On/off"); 45 | configParam(GAIN_PARAM, 0.0f, 10.0f, 5.0f, "Gain"); 46 | configInput(LEFT_INPUT, "Left"); 47 | configInput(RIGHT_INPUT, "Right"); 48 | configOutput(LEFT_OUTPUT, "Left"); 49 | configOutput(RIGHT_OUTPUT, "Right"); 50 | configOutput(LEFT_MAIN_OUTPUT, "Left main"); 51 | configOutput(RIGHT_MAIN_OUTPUT, "Right main"); 52 | configBypass(LEFT_INPUT, LEFT_OUTPUT); 53 | configBypass(RIGHT_INPUT, RIGHT_OUTPUT); 54 | onReset(); 55 | } 56 | 57 | void onReset() override { 58 | ON_STATE = true; 59 | } 60 | 61 | json_t *dataToJson() override { 62 | json_t *rootJ = json_object(); 63 | 64 | 65 | // solo 66 | json_object_set_new(rootJ, "onstate", json_integer(ON_STATE)); 67 | return rootJ; 68 | } 69 | 70 | void dataFromJson(json_t *rootJ) override { 71 | 72 | 73 | // solo 74 | json_t *onstateJ = json_object_get(rootJ, "onstate"); 75 | if (onstateJ) 76 | ON_STATE = json_integer_value(onstateJ); 77 | 78 | } 79 | 80 | 81 | 82 | 83 | 84 | void process(const ProcessArgs &args) override { 85 | 86 | SIGNAL_LEFT = inputs[LEFT_INPUT].getVoltage() ; 87 | SIGNAL_RIGHT = inputs[RIGHT_INPUT].getVoltage() ; 88 | 89 | outputs[LEFT_OUTPUT].setVoltage(SIGNAL_LEFT); 90 | outputs[RIGHT_OUTPUT].setVoltage(SIGNAL_RIGHT); 91 | 92 | 93 | if (onTrigger.process(params[ON_PARAM].getValue())+oninTrigger.process(inputs[ONT_INPUT].getVoltage())) 94 | {if (ON_STATE == 0) ON_STATE = 1; else ON_STATE = 0;} 95 | 96 | SIGNAL_LEFT = SIGNAL_LEFT * ON_STATE * params[GAIN_PARAM].getValue()/5.0; 97 | SIGNAL_RIGHT = SIGNAL_RIGHT * ON_STATE * params[GAIN_PARAM].getValue()/5.0; 98 | 99 | outputs[LEFT_MAIN_OUTPUT].setVoltage(SIGNAL_LEFT); 100 | outputs[RIGHT_MAIN_OUTPUT].setVoltage(SIGNAL_RIGHT); 101 | 102 | 103 | if (ON_STATE==1) lights[ON_LIGHT].setBrightness(1); else lights[ON_LIGHT].setBrightness(0); 104 | 105 | 106 | for (int i = 0; i < 11; i++) { 107 | if (SIGNAL_LEFT> i) {if (i<10) l_lightState[i]=5000;else l_lightState[i]=20000;} 108 | } 109 | for (int i = 0; i < 11; i++) { 110 | if (l_lightState[i]> 0) {l_lightState[i]=l_lightState[i]-1;lights[L_LEVEL_LIGHTS + i].setBrightness(1);} else lights[L_LEVEL_LIGHTS + i].setBrightness(0); 111 | } 112 | for (int i = 0; i < 11; i++) { 113 | if (SIGNAL_RIGHT> i) {if (i<10) r_lightState[i]=5000;else r_lightState[i]=20000;} 114 | } 115 | for (int i = 0; i < 11; i++) { 116 | if (r_lightState[i]> 0) {r_lightState[i]=r_lightState[i]-1;lights[R_LEVEL_LIGHTS + i].setBrightness(1);} else lights[R_LEVEL_LIGHTS + i].setBrightness(0); 117 | } 118 | } 119 | }; 120 | 121 | struct MASTERWidget : ModuleWidget { 122 | MASTERWidget(MASTER *module) { 123 | setModule(module); 124 | setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/MASTER.svg"))); 125 | 126 | 127 | 128 | addChild(createWidget(Vec(15, 0))); 129 | addChild(createWidget(Vec(box.size.x-30, 0))); 130 | addChild(createWidget(Vec(15, 365))); 131 | addChild(createWidget(Vec(box.size.x-30, 365))); 132 | 133 | 134 | addParam(createParam(Vec(27, 247), module, MASTER::GAIN_PARAM)); 135 | 136 | 137 | addParam(createParam(Vec(38, 208), module, MASTER::ON_PARAM)); 138 | addChild(createLight>(Vec(42.4, 212.4), module, MASTER::ON_LIGHT)); 139 | 140 | 141 | addOutput(createOutput(Vec(54, 61), module, MASTER::LEFT_OUTPUT)); 142 | addOutput(createOutput(Vec(54, 91), module, MASTER::RIGHT_OUTPUT)); 143 | 144 | addOutput(createOutput(Vec(54, 308), module, MASTER::LEFT_MAIN_OUTPUT)); 145 | addOutput(createOutput(Vec(54, 334), module, MASTER::RIGHT_MAIN_OUTPUT)); 146 | 147 | addInput(createInput(Vec(11, 61), module, MASTER::LEFT_INPUT)); 148 | addInput(createInput(Vec(11, 91), module, MASTER::RIGHT_INPUT)); 149 | 150 | 151 | for (int i = 0; i < 11; i++) { 152 | if (i<10) addChild(createLight>(Vec(15, 242-i*12), module, MASTER::L_LEVEL_LIGHTS + i)); 153 | else addChild(createLight>(Vec(15, 242-i*12), module, MASTER::L_LEVEL_LIGHTS + i)); 154 | if (i<10) addChild(createLight>(Vec(68, 242-i*12), module, MASTER::R_LEVEL_LIGHTS + i)); 155 | else addChild(createLight>(Vec(68, 242-i*12), module, MASTER::R_LEVEL_LIGHTS + i)); 156 | } 157 | 158 | }; 159 | }; 160 | 161 | Model *modelMASTER = createModel("MASTER"); 162 | -------------------------------------------------------------------------------- /src/METRO.cpp: -------------------------------------------------------------------------------- 1 | #include "plugin.hpp" 2 | 3 | 4 | struct METRO : Module { 5 | enum ParamIds { 6 | BPM_PARAM, 7 | RST_PARAM, 8 | BEAT_PARAM, 9 | ON_PARAM, 10 | NUM_PARAMS 11 | }; 12 | enum InputIds { 13 | ON_INPUT, 14 | BPM_INPUT, 15 | NUM_INPUTS 16 | }; 17 | enum OutputIds { 18 | OUT_OUTPUT, 19 | MES_OUTPUT, 20 | BEAT_OUTPUT, 21 | START_OUTPUT, 22 | NUM_OUTPUTS 23 | }; 24 | enum LightIds { 25 | ON_LIGHT, 26 | MES_LIGHT, 27 | BEAT_LIGHT, 28 | NUM_LIGHTS 29 | }; 30 | 31 | int max_METRO = 120 ; 32 | int beatl = 0 ; 33 | int mesl = 0 ; 34 | int beats = 0 ; 35 | int mess = 0 ; 36 | int strt = 0 ; 37 | int note ; 38 | float toc_phase = 0.f; 39 | uint32_t toc = 0u; 40 | dsp::SchmittTrigger onTrigger; 41 | dsp::SchmittTrigger oninTrigger; 42 | dsp::SchmittTrigger rstTrigger; 43 | bool ON_STATE = false; 44 | float or_gain ; 45 | int or_affi ; 46 | 47 | METRO() { 48 | config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); 49 | configButton(BEAT_PARAM, "Beat"); 50 | configButton(RST_PARAM, "Reset"); 51 | configButton(ON_PARAM, "Start/stop"); 52 | configParam(BPM_PARAM, 0.0f, 301.0f, 120.1f, "BPM"); 53 | configInput(ON_INPUT,"Start/stop trigger"); 54 | configInput(BPM_INPUT,"BPM control"); 55 | configOutput(START_OUTPUT,"Start/reset"); 56 | configOutput(OUT_OUTPUT,"12 ppn"); 57 | configOutput(BEAT_OUTPUT,"Audio ticks per note"); 58 | onReset(); 59 | } 60 | 61 | 62 | 63 | void onReset() override { 64 | ON_STATE = true; 65 | 66 | } 67 | 68 | json_t *dataToJson() override { 69 | json_t *rootJ = json_object(); 70 | 71 | // on 72 | json_object_set_new(rootJ, "onstate", json_integer(ON_STATE)); 73 | return rootJ; 74 | } 75 | 76 | void dataFromJson(json_t *rootJ) override { 77 | 78 | // on 79 | json_t *onstateJ = json_object_get(rootJ, "onstate"); 80 | if (onstateJ) 81 | ON_STATE = json_integer_value(onstateJ); 82 | 83 | } 84 | 85 | 86 | 87 | void process(const ProcessArgs &args) override { 88 | 89 | if (!inputs[BPM_INPUT].isConnected()) { 90 | max_METRO = floor(params[BPM_PARAM].getValue()); 91 | or_affi = 0; 92 | or_gain = max_METRO/30.0; 93 | } else { 94 | max_METRO = round(clamp(inputs[BPM_INPUT].getVoltage() *30,0.0f,300.0f)); 95 | or_affi = 1; 96 | or_gain = max_METRO/30.0; 97 | } 98 | 99 | float bpm = max_METRO ; 100 | bool toced = false; 101 | 102 | if (onTrigger.process(params[ON_PARAM].getValue())+oninTrigger.process(inputs[ON_INPUT].getVoltage())) 103 | {if (ON_STATE == 0) {ON_STATE = 1; strt = 5;} else ON_STATE = 0;} 104 | 105 | lights[ON_LIGHT].setBrightness(ON_STATE) ; 106 | 107 | 108 | if (rstTrigger.process(params[RST_PARAM].getValue())) 109 | {toc = 47u;toc_phase = 1.f; strt = 5;} 110 | 111 | 112 | if (ON_STATE) { 113 | toc_phase += ((bpm / 60.f) * args.sampleTime) * 12.f; 114 | 115 | if(toc_phase >= 1.f) { 116 | toced = true; 117 | toc = (toc+1u) % 48u ; 118 | toc_phase -= 1.f; 119 | } 120 | 121 | if(toced) { 122 | if (toc % 12u ? 0 : 1) beatl = 4000; 123 | if (toc % 48u ? 0 : 1) mesl = 5000; 124 | if (toc % 12u ? 0 : 1) beats = 200; 125 | if (toc % 48u ? 0 : 1) mess = 200; 126 | note =5; 127 | } 128 | 129 | if (beatl>0) { 130 | lights[BEAT_LIGHT].setBrightness(1); 131 | beatl = beatl -1; 132 | } else { 133 | lights[BEAT_LIGHT].setBrightness(0); 134 | } 135 | 136 | if (mesl>0) { 137 | lights[MES_LIGHT].setBrightness(1); 138 | mesl = mesl -1; 139 | } else { 140 | lights[MES_LIGHT].setBrightness(0); 141 | } 142 | 143 | 144 | if (beats>0) { 145 | beats = beats -1; 146 | outputs[BEAT_OUTPUT].setVoltage(2.5 * (beats- 150*round(beats/150))/150); 147 | } else { 148 | outputs[BEAT_OUTPUT].setVoltage(0.0); 149 | } 150 | 151 | if (mess>0) { 152 | mess = mess -1; 153 | outputs[BEAT_OUTPUT].setVoltage(5.0 * (mess- 150*round(mess/150))/150); 154 | } 155 | 156 | } else {toc = 47u;toc_phase = 1.f;outputs[OUT_OUTPUT].setVoltage(0.f);} 157 | 158 | 159 | if (strt > 0) {outputs[START_OUTPUT].setVoltage(10.f);strt=strt-1;} else outputs[START_OUTPUT].setVoltage(0.f); 160 | if (note > 0) {outputs[OUT_OUTPUT].setVoltage(10.f);note=note-1;} else outputs[OUT_OUTPUT].setVoltage(0.f); 161 | } 162 | }; 163 | 164 | struct NumDisplayWidget : TransparentWidget { 165 | METRO *module; 166 | 167 | 168 | 169 | NumDisplayWidget() { 170 | 171 | }; 172 | 173 | void drawLayer(const DrawArgs &args, int layer) override { 174 | if (layer ==1) { 175 | std::shared_ptr font = APP->window->loadFont(asset::plugin(pluginInstance, "res/Segment7Standard.ttf")); 176 | int val = module ? module->max_METRO : 120; 177 | // Background 178 | NVGcolor backgroundColor = nvgRGB(0x44, 0x44, 0x44); 179 | NVGcolor borderColor = nvgRGB(0x10, 0x10, 0x10); 180 | nvgBeginPath(args.vg); 181 | nvgRoundedRect(args.vg, 0.0, 0.0, box.size.x, box.size.y, 4.0); 182 | nvgFillColor(args.vg, backgroundColor); 183 | nvgFill(args.vg); 184 | nvgStrokeWidth(args.vg, 1.0); 185 | nvgStrokeColor(args.vg, borderColor); 186 | nvgStroke(args.vg); 187 | 188 | nvgFontSize(args.vg, 18); 189 | nvgFontFaceId(args.vg, font->handle); 190 | nvgTextLetterSpacing(args.vg, 2.5); 191 | 192 | std::string to_display = std::to_string(val); 193 | 194 | 195 | while(to_display.length()<3) to_display = ' ' + to_display; 196 | 197 | Vec textPos = Vec(6.0f, 17.0f); 198 | 199 | NVGcolor textColor = nvgRGB(0xdf, 0xd2, 0x2c); 200 | nvgFillColor(args.vg, nvgTransRGBA(textColor, 16)); 201 | nvgText(args.vg, textPos.x, textPos.y, "~~~", NULL); 202 | 203 | textColor = nvgRGB(0xda, 0xe9, 0x29); 204 | 205 | nvgFillColor(args.vg, nvgTransRGBA(textColor, 16)); 206 | nvgText(args.vg, textPos.x, textPos.y, "\\\\\\", NULL); 207 | 208 | 209 | textColor = nvgRGB(0x28, 0xb0, 0xf3); 210 | nvgFillColor(args.vg, textColor); 211 | nvgText(args.vg, textPos.x, textPos.y, to_display.c_str(), NULL); 212 | } 213 | Widget::drawLayer(args, layer); 214 | } 215 | }; 216 | 217 | struct METROPOTDisplay : TransparentWidget { 218 | METRO *module; 219 | 220 | METROPOTDisplay() { 221 | 222 | } 223 | 224 | void draw(const DrawArgs &args) override { 225 | 226 | float gainX = module ? module->or_gain : 1.0f; 227 | //int affich = module ? module->or_affi : 0; 228 | float d=18; 229 | //if (affich==1) { 230 | float xx = d*sin(-(gainX*0.17+0.15)*M_PI) ; 231 | float yy = d*cos((gainX*0.17+0.15)*M_PI) ; 232 | 233 | 234 | //nvgBeginPath(args.vg); 235 | //nvgCircle(args.vg, 0,0, d); 236 | //nvgFillColor(args.vg, nvgRGBA(0x00, 0x00, 0x00, 0xff)); 237 | //nvgFill(args.vg); 238 | 239 | nvgStrokeWidth(args.vg,2); 240 | nvgStrokeColor(args.vg, nvgRGBA(0xff, 0xff, 0xff, 0x88)); 241 | { 242 | nvgBeginPath(args.vg); 243 | nvgMoveTo(args.vg, 0,0); 244 | nvgLineTo(args.vg, xx,yy); 245 | nvgClosePath(args.vg); 246 | } 247 | nvgStroke(args.vg); 248 | //} 249 | 250 | } 251 | }; 252 | 253 | 254 | struct METROWidget : ModuleWidget { 255 | METROWidget(METRO *module) { 256 | setModule(module); 257 | setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/METRO.svg"))); 258 | 259 | addChild(createWidget(Vec(15, 0))); 260 | addChild(createWidget(Vec(box.size.x-30, 0))); 261 | addChild(createWidget(Vec(15, 365))); 262 | addChild(createWidget(Vec(box.size.x-30, 365))); 263 | 264 | addParam(createParam(Vec(27, 107), module, METRO::BPM_PARAM)); 265 | addInput(createInput(Vec(11, 141), module, METRO::BPM_INPUT)); 266 | { 267 | METROPOTDisplay *display = new METROPOTDisplay(); 268 | display->box.pos = Vec(45, 125); 269 | display->module = module; 270 | addChild(display); 271 | } 272 | 273 | addParam(createParam(Vec(38, 167), module, METRO::ON_PARAM)); 274 | addChild(createLight>(Vec(42.4, 171.4), module, METRO::ON_LIGHT)); 275 | addInput(createInput(Vec(11, 171), module, METRO::ON_INPUT)); 276 | 277 | addParam(createParam(Vec(38, 197), module, METRO::RST_PARAM)); 278 | addChild(createLight>(Vec(42.4, 201.4), module, METRO::MES_LIGHT)); 279 | 280 | addParam(createParam(Vec(38, 227), module, METRO::BEAT_PARAM)); 281 | addChild(createLight>(Vec(42.4, 231.4), module, METRO::BEAT_LIGHT)); 282 | addOutput(createOutput(Vec(54, 265), module, METRO::BEAT_OUTPUT)); 283 | 284 | addOutput(createOutput(Vec(11, 321), module, METRO::START_OUTPUT)); 285 | addOutput(createOutput(Vec(54, 321), module, METRO::OUT_OUTPUT)); 286 | 287 | NumDisplayWidget *display = new NumDisplayWidget(); 288 | display->box.pos = Vec(20,56); 289 | display->box.size = Vec(50, 20); 290 | display->module = module; 291 | addChild(display); 292 | 293 | 294 | } 295 | }; 296 | 297 | Model *modelMETRO = createModel ("METRO"); -------------------------------------------------------------------------------- /src/PATCH.cpp: -------------------------------------------------------------------------------- 1 | #include "plugin.hpp" 2 | 3 | 4 | struct PATCH : Module { 5 | 6 | enum ParamIds { 7 | NUM_PARAMS 8 | }; 9 | enum InputIds { 10 | L_INPUT, 11 | R_INPUT, 12 | M1_INPUT, 13 | M2_INPUT, 14 | M3_INPUT, 15 | ENUMS(IN_INPUT,8), 16 | NUM_INPUTS 17 | }; 18 | enum OutputIds { 19 | L_OUTPUT, 20 | R_OUTPUT, 21 | M1_OUTPUT, 22 | M2_OUTPUT, 23 | M3_OUTPUT, 24 | ENUMS(OUT_OUTPUT,8), 25 | NUM_OUTPUTS 26 | }; 27 | enum LightIds { 28 | NUM_LIGHTS 29 | }; 30 | 31 | 32 | 33 | 34 | 35 | 36 | PATCH() { 37 | config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS,NUM_LIGHTS); 38 | }; 39 | 40 | 41 | void process(const ProcessArgs &args) override { 42 | 43 | outputs[L_OUTPUT].setVoltage(inputs[L_INPUT].getVoltage()); 44 | outputs[R_OUTPUT].setVoltage(inputs[R_INPUT].getVoltage()); 45 | 46 | outputs[M1_OUTPUT].setVoltage(inputs[M1_INPUT].getVoltage()+inputs[M2_INPUT].getVoltage()+inputs[M3_INPUT].getVoltage()); 47 | outputs[M2_OUTPUT].setVoltage(inputs[M1_INPUT].getVoltage()+inputs[M2_INPUT].getVoltage()+inputs[M3_INPUT].getVoltage()); 48 | outputs[M3_OUTPUT].setVoltage(inputs[M1_INPUT].getVoltage()+inputs[M2_INPUT].getVoltage()+inputs[M3_INPUT].getVoltage()); 49 | 50 | for (int i = 0; i < 8; i++) { 51 | if (inputs[IN_INPUT + i].isConnected()) outputs[OUT_OUTPUT + i].setVoltage(inputs[IN_INPUT + i].getVoltage()); 52 | else outputs[OUT_OUTPUT + i].setVoltage(0); 53 | } 54 | 55 | }; 56 | }; 57 | 58 | 59 | 60 | struct PATCHWidget : ModuleWidget { 61 | PATCHWidget(PATCH *module) { 62 | setModule(module); 63 | setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/PATCH.svg"))); 64 | 65 | 66 | addChild(createWidget(Vec(15, 0))); 67 | addChild(createWidget(Vec(box.size.x-30, 0))); 68 | addChild(createWidget(Vec(15, 365))); 69 | addChild(createWidget(Vec(box.size.x-30, 365))); 70 | 71 | addInput(createInput(Vec(10, 171), module, PATCH::L_INPUT)); 72 | addInput(createInput(Vec(40, 171), module, PATCH::R_INPUT)); 73 | addOutput(createOutput(Vec(70, 171), module, PATCH::L_OUTPUT)); 74 | addOutput(createOutput(Vec(100, 171), module, PATCH::R_OUTPUT)); 75 | 76 | addInput(createInput(Vec(15, 61), module, PATCH::M1_INPUT)); 77 | addInput(createInput(Vec(55, 41), module, PATCH::M2_INPUT)); 78 | addInput(createInput(Vec(95, 71), module, PATCH::M3_INPUT)); 79 | 80 | addOutput(createOutput(Vec(40, 121), module, PATCH::M1_OUTPUT)); 81 | addOutput(createOutput(Vec(55, 81), module, PATCH::M2_OUTPUT)); 82 | addOutput(createOutput(Vec(80, 111), module, PATCH::M3_OUTPUT)); 83 | 84 | for (int i = 0; i < 8; i++) { 85 | 86 | addInput(createInput(Vec(10+(i-4*floor(i/4))*30, 231+60*floor(i/4)), module, PATCH::IN_INPUT + i)); 87 | addOutput(createOutput(Vec(10+(i-4*floor(i/4))*30, 261+60*floor(i/4)), module, PATCH::OUT_OUTPUT + i)); 88 | 89 | 90 | } 91 | } 92 | 93 | }; 94 | 95 | Model *modelPATCH = createModel("PATCH"); 96 | -------------------------------------------------------------------------------- /src/PEAK.cpp: -------------------------------------------------------------------------------- 1 | #include "plugin.hpp" 2 | 3 | 4 | struct PEAK : Module { 5 | enum ParamIds { 6 | TRESHOLD_PARAM, 7 | GAIN_PARAM, 8 | NUM_PARAMS 9 | }; 10 | enum InputIds { 11 | LIN1_INPUT, 12 | IN1_INPUT, 13 | IN2_INPUT, 14 | NUM_INPUTS 15 | }; 16 | enum OutputIds { 17 | OUT1_OUTPUT, 18 | OUT2_OUTPUT, 19 | NUM_OUTPUTS 20 | }; 21 | enum LightIds { 22 | TRESHOLD_LIGHT, 23 | OVER_LIGHT, 24 | NUM_LIGHTS 25 | }; 26 | float max_GAIN = 1.0 ; 27 | int affich = 1 ; 28 | int reman_t = 0; 29 | int reman_o = 0; 30 | int sensiv = 10000; 31 | 32 | 33 | PEAK() { 34 | config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); 35 | configParam(GAIN_PARAM, 0.0f, 10.0f, 1.0f, "Gain"); 36 | configParam(TRESHOLD_PARAM, 0.0f, 10.0f, 10.0f, "Treshold"); 37 | configInput(IN1_INPUT,"Left"); 38 | configInput(IN2_INPUT,"Right"); 39 | configOutput(OUT1_OUTPUT,"Left"); 40 | configOutput(OUT2_OUTPUT,"Right"); 41 | } 42 | 43 | 44 | void process(const ProcessArgs &args) override { 45 | 46 | max_GAIN = roundf(params[GAIN_PARAM].getValue()*10); 47 | 48 | affich = round(max_GAIN); 49 | 50 | if (inputs[IN1_INPUT].isConnected()) 51 | { 52 | 53 | if (inputs[IN1_INPUT].getVoltage() > params[TRESHOLD_PARAM].getValue()) 54 | { 55 | outputs[OUT1_OUTPUT].setVoltage((max_GAIN/10.0*(params[TRESHOLD_PARAM].getValue() + ((inputs[IN1_INPUT].getVoltage()-params[TRESHOLD_PARAM].getValue())/(1+(inputs[IN1_INPUT].getVoltage()-params[TRESHOLD_PARAM].getValue())))))); 56 | reman_t = sensiv; 57 | } 58 | else if (inputs[IN1_INPUT].getVoltage() < 0-params[TRESHOLD_PARAM].getValue()) 59 | { 60 | outputs[OUT1_OUTPUT].setVoltage((max_GAIN/10.0*(0-(params[TRESHOLD_PARAM].getValue() - ((inputs[IN1_INPUT].getVoltage()+params[TRESHOLD_PARAM].getValue())/(1+(-inputs[IN1_INPUT].getVoltage()-params[TRESHOLD_PARAM].getValue()))))))); 61 | reman_t = sensiv; 62 | } 63 | else 64 | { 65 | outputs[OUT1_OUTPUT].setVoltage((max_GAIN*inputs[IN1_INPUT].getVoltage())/10.0); 66 | } 67 | 68 | if (outputs[OUT1_OUTPUT].getVoltage() >10) reman_o=sensiv; 69 | 70 | } 71 | else 72 | { 73 | outputs[OUT1_OUTPUT].setVoltage(max_GAIN/10); 74 | lights[TRESHOLD_LIGHT].setBrightness(0.0); 75 | lights[OVER_LIGHT].setBrightness(0.0); 76 | } 77 | 78 | 79 | 80 | if (inputs[IN2_INPUT].isConnected()) 81 | { 82 | 83 | if (inputs[IN2_INPUT].getVoltage() > params[TRESHOLD_PARAM].getValue()) 84 | { 85 | outputs[OUT2_OUTPUT].setVoltage((max_GAIN/10.0*(params[TRESHOLD_PARAM].getValue() + ((inputs[IN2_INPUT].getVoltage()-params[TRESHOLD_PARAM].getValue())/(1+(inputs[IN2_INPUT].getVoltage()-params[TRESHOLD_PARAM].getValue())))))); 86 | reman_t = sensiv; 87 | } 88 | else if (inputs[IN2_INPUT].getVoltage() < 0-params[TRESHOLD_PARAM].getValue()) 89 | { 90 | outputs[OUT2_OUTPUT].setVoltage((max_GAIN/10.0*(0-(params[TRESHOLD_PARAM].getValue() - ((inputs[IN2_INPUT].getVoltage()+params[TRESHOLD_PARAM].getValue())/(1+(-inputs[IN2_INPUT].getVoltage()-params[TRESHOLD_PARAM].getValue()))))))); 91 | reman_t = sensiv; 92 | } 93 | else 94 | { 95 | outputs[OUT2_OUTPUT].setVoltage((max_GAIN*inputs[IN2_INPUT].getVoltage())/10.0); 96 | } 97 | 98 | if (outputs[OUT2_OUTPUT].getVoltage() >10) reman_o=sensiv; 99 | 100 | } 101 | else 102 | { 103 | outputs[OUT2_OUTPUT].setVoltage(max_GAIN/10); 104 | lights[TRESHOLD_LIGHT].setBrightness(0.0); 105 | lights[OVER_LIGHT].setBrightness(0.0); 106 | } 107 | 108 | 109 | if (reman_t >0) 110 | { 111 | reman_t--; 112 | lights[TRESHOLD_LIGHT].setBrightness(1); 113 | } 114 | else lights[TRESHOLD_LIGHT].setBrightness(0.0); 115 | 116 | if (reman_o >0) 117 | { 118 | reman_o--; 119 | lights[OVER_LIGHT].setBrightness(1); 120 | } 121 | else lights[OVER_LIGHT].setBrightness(0.0); 122 | }; 123 | }; 124 | 125 | struct NumbDisplayWidget : TransparentWidget { 126 | PEAK *module; 127 | // float *value=0; 128 | 129 | 130 | NumbDisplayWidget() { 131 | 132 | }; 133 | 134 | void drawLayer(const DrawArgs &args, int layer) override { 135 | if (layer ==1) { 136 | std::shared_ptr font = APP->window->loadFont(asset::plugin(pluginInstance, "res/Segment7Standard.ttf")); 137 | int st = module ? module->affich : 0; 138 | // Background 139 | NVGcolor backgroundColor = nvgRGB(0x44, 0x44, 0x44); 140 | NVGcolor borderColor = nvgRGB(0x10, 0x10, 0x10); 141 | nvgBeginPath(args.vg); 142 | nvgRoundedRect(args.vg, 0.0, 0.0, box.size.x, box.size.y, 4.0); 143 | nvgFillColor(args.vg, backgroundColor); 144 | nvgFill(args.vg); 145 | nvgStrokeWidth(args.vg, 1.0); 146 | nvgStrokeColor(args.vg, borderColor); 147 | nvgStroke(args.vg); 148 | 149 | nvgFontSize(args.vg, 18); 150 | nvgFontFaceId(args.vg, font->handle); 151 | nvgTextLetterSpacing(args.vg, 2.5); 152 | 153 | std::string to_display = std::to_string(st); 154 | if (st<10) to_display = '0' + to_display; 155 | if (st<100) to_display = ' ' + to_display; 156 | 157 | 158 | Vec textPos = Vec(6.0f, 17.0f); 159 | 160 | NVGcolor textColor = nvgRGB(0xdf, 0xd2, 0x2c); 161 | nvgFillColor(args.vg, nvgTransRGBA(textColor, 16)); 162 | nvgText(args.vg, textPos.x, textPos.y, "~~~", NULL); 163 | 164 | textColor = nvgRGB(0xda, 0xe9, 0x29); 165 | 166 | nvgFillColor(args.vg, nvgTransRGBA(textColor, 16)); 167 | nvgText(args.vg, textPos.x, textPos.y, "\\\\\\", NULL); 168 | 169 | 170 | textColor = nvgRGB(0x28, 0xb0, 0xf3); 171 | nvgFillColor(args.vg, textColor); 172 | nvgText(args.vg, textPos.x, textPos.y, to_display.c_str(), NULL); 173 | nvgFillColor(args.vg, textColor); 174 | nvgText(args.vg, textPos.x+1, textPos.y, " . ", NULL); 175 | nvgText(args.vg, textPos.x+1, textPos.y-1, " . ", NULL); 176 | 177 | } 178 | Widget::drawLayer(args, layer); 179 | } 180 | }; 181 | 182 | 183 | struct PEAKWidget : ModuleWidget { 184 | PEAKWidget(PEAK *module) { 185 | setModule(module); 186 | setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/PEAK.svg"))); 187 | 188 | addChild(createWidget(Vec(15, 0))); 189 | addChild(createWidget(Vec(box.size.x-30, 0))); 190 | addChild(createWidget(Vec(15, 365))); 191 | addChild(createWidget(Vec(box.size.x-30, 365))); 192 | 193 | addParam(createParam(Vec(27, 97), module, PEAK::GAIN_PARAM)); 194 | addChild(createLight>(Vec(42.4, 141.4), module, PEAK::OVER_LIGHT)); 195 | 196 | addParam(createParam(Vec(27, 227), module, PEAK::TRESHOLD_PARAM)); 197 | addChild(createLight>(Vec(42.4, 211.4), module, PEAK::TRESHOLD_LIGHT)); 198 | 199 | addInput(createInput(Vec(11, 308), module, PEAK::IN1_INPUT)); 200 | 201 | addOutput(createOutput(Vec(54, 308), module, PEAK::OUT1_OUTPUT)); 202 | 203 | addInput(createInput(Vec(11, 334), module, PEAK::IN2_INPUT)); 204 | 205 | addOutput(createOutput(Vec(54, 334), module, PEAK::OUT2_OUTPUT)); 206 | 207 | NumbDisplayWidget *display = new NumbDisplayWidget(); 208 | display->box.pos = Vec(20,56); 209 | display->box.size = Vec(50, 20); 210 | //display->value = &module->affich; 211 | display->module = module; 212 | addChild(display); 213 | 214 | 215 | } 216 | }; 217 | Model *modelPEAK = createModel("PEAK"); 218 | -------------------------------------------------------------------------------- /src/SLIDERSEQ.cpp: -------------------------------------------------------------------------------- 1 | #include "plugin.hpp" 2 | 3 | 4 | 5 | struct SLIDERSEQ : Module { 6 | enum ParamIds { 7 | OFFSET_PARAM, 8 | ENUMS(LVL_PARAM, 16), 9 | ON_PARAM, 10 | NUM_PARAMS 11 | }; 12 | enum InputIds { 13 | RST_INPUT, 14 | UP_INPUT, 15 | POS_INPUT, 16 | NUM_INPUTS 17 | }; 18 | enum OutputIds { 19 | TR_OUTPUT, 20 | NUM_OUTPUTS 21 | }; 22 | enum LightIds { 23 | OFFSET_LIGHT, 24 | ENUMS(LVL_LIGHT, 16), 25 | NUM_LIGHTS 26 | }; 27 | 28 | 29 | int pas = 0; 30 | bool OFFSET_STATE = false ; 31 | 32 | dsp::SchmittTrigger rstTrigger; 33 | dsp::SchmittTrigger upTrigger; 34 | dsp::SchmittTrigger offsetTrigger; 35 | dsp::SchmittTrigger posTrigger; 36 | float sl_pas ; 37 | float sl_value ; 38 | 39 | SLIDERSEQ() { 40 | config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); 41 | configParam(ON_PARAM, 0.f, 1.f, 0.f); 42 | configButton(OFFSET_PARAM, "-5V offset"); 43 | for (int i = 0; i < 16; i++) { 44 | configParam(LVL_PARAM + i, 0.f, 1.f, 0.f,"Step " +std::to_string(i+1)); 45 | } 46 | configInput(RST_INPUT,"Reset trigger"); 47 | configInput(UP_INPUT,"Step trigger"); 48 | configInput(POS_INPUT,"Position control"); 49 | configOutput(TR_OUTPUT,"CV"); 50 | } 51 | 52 | 53 | 54 | 55 | json_t *dataToJson() override { 56 | json_t *rootJ = json_object(); 57 | 58 | 59 | json_object_set_new(rootJ, "offsetstate", json_integer(OFFSET_STATE)); 60 | return rootJ; 61 | } 62 | 63 | void dataFromJson(json_t *rootJ) override { 64 | 65 | 66 | json_t *offsetstateJ = json_object_get(rootJ, "offsetstate"); 67 | if (offsetstateJ) 68 | OFFSET_STATE = json_integer_value(offsetstateJ); 69 | 70 | } 71 | 72 | 73 | 74 | 75 | 76 | void process(const ProcessArgs &args) override { 77 | 78 | 79 | if (!inputs[POS_INPUT].isConnected()) { 80 | if (rstTrigger.process(inputs[RST_INPUT].getVoltage())) 81 | { 82 | pas = -1; 83 | } 84 | if (upTrigger.process(inputs[UP_INPUT].getVoltage())) 85 | { 86 | if (pas <15) pas = pas+1; else pas =0; 87 | } 88 | 89 | 90 | } else { pas = int(inputs[POS_INPUT].getVoltage()*1.6); 91 | if (pas<0) pas =0; 92 | if (pas>15) pas =15; 93 | }; 94 | 95 | if (offsetTrigger.process(params[OFFSET_PARAM].getValue())) 96 | {if (OFFSET_STATE == 0) OFFSET_STATE = 1; else OFFSET_STATE = 0;} 97 | 98 | if (OFFSET_STATE==1) lights[OFFSET_LIGHT].setBrightness(1); else lights[OFFSET_LIGHT].setBrightness(0); 99 | 100 | 101 | if (pas>-1) { 102 | sl_pas=pas; sl_value = params[LVL_PARAM +pas].getValue() ; 103 | outputs[TR_OUTPUT].setVoltage(params[LVL_PARAM +pas].getValue()*10-OFFSET_STATE*5.0);} 104 | else { 105 | sl_pas=0; sl_value = params[LVL_PARAM +0].getValue() ; 106 | outputs[TR_OUTPUT].setVoltage(params[LVL_PARAM +0].getValue()*10-OFFSET_STATE*5.0);} 107 | 108 | for (int i = 0; i < 16; i++) { 109 | if (i!=pas) { 110 | lights[LVL_LIGHT+i].setBrightness(0.2f); 111 | //lights[LVL_LIGHT+i].setSmoothBrightness(0.f, 0.2); 112 | } 113 | else { 114 | lights[LVL_LIGHT+i].setBrightness(5.f); 115 | //lights[LVL_LIGHT+i].setSmoothBrightness(0.f, 1); 116 | } 117 | 118 | }; 119 | 120 | }; 121 | 122 | }; 123 | 124 | struct SLIDERSEQWidget : ModuleWidget { 125 | SLIDERSEQWidget(SLIDERSEQ *module) { 126 | setModule(module); 127 | setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/SLIDERSEQ.svg"))); 128 | 129 | addChild(createWidget(Vec(15, 0))); 130 | addChild(createWidget(Vec(box.size.x-30, 0))); 131 | addChild(createWidget(Vec(15, 365))); 132 | addChild(createWidget(Vec(box.size.x-30, 365))); 133 | 134 | addInput(createInput(Vec(10, 320), module, SLIDERSEQ::RST_INPUT)); 135 | addInput(createInput(Vec(39, 320), module, SLIDERSEQ::UP_INPUT)); 136 | addOutput(createOutput(Vec(100, 320), module, SLIDERSEQ::TR_OUTPUT)); 137 | 138 | 139 | addParam(createParam(Vec(84, 288), module, SLIDERSEQ::OFFSET_PARAM)); 140 | addChild(createLight>(Vec(88.4, 292.4), module, SLIDERSEQ::OFFSET_LIGHT)); 141 | 142 | 143 | for (int i = 0; i < 8; i++) { 144 | addParam(createLightParamCentered>(Vec(4+i*15+10, 30+ 30+30), module, SLIDERSEQ::LVL_PARAM+i, SLIDERSEQ::LVL_LIGHT+i)); 145 | //addParam(createParam(Vec(4+i*15, 30+ 30), module, SLIDERSEQ::LVL_PARAM+i)); 146 | 147 | } 148 | for (int i = 8; i < 16; i++) { 149 | addParam(createLightParamCentered>(Vec(4+(i-8)*15+10, 30+ 155+30), module, SLIDERSEQ::LVL_PARAM+i, SLIDERSEQ::LVL_LIGHT+i)); 150 | //addParam(createParam(Vec(4+(i-8)*15, 30+ 155), module, SLIDERSEQ::LVL_PARAM+i)); 151 | 152 | } 153 | 154 | 155 | addInput(createInput(Vec(68, 320), module, SLIDERSEQ::POS_INPUT)); 156 | }; 157 | }; 158 | 159 | Model *modelSLIDERSEQ = createModel("SLIDERSEQ"); 160 | 161 | -------------------------------------------------------------------------------- /src/STEPS.cpp: -------------------------------------------------------------------------------- 1 | #include "plugin.hpp" 2 | 3 | struct STEPS : Module { 4 | enum ParamIds { 5 | LEVEL1_PARAM, 6 | TRIM1_PARAM, 7 | NUM_PARAMS 8 | }; 9 | enum InputIds { 10 | LIN1_INPUT, 11 | IN1_INPUT, 12 | NUM_INPUTS 13 | }; 14 | enum OutputIds { 15 | OUT1_OUTPUT, 16 | NUM_OUTPUTS 17 | }; 18 | 19 | float max_steps = 8 ; 20 | 21 | STEPS() { 22 | config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS); 23 | configParam(LEVEL1_PARAM, 1.0f, 32.0f, 8.1f, "Steps"); 24 | configParam(TRIM1_PARAM, -10.0f, 10.0f, 0.0f, "Trim"); 25 | configInput(LIN1_INPUT,"Steps control"); 26 | configInput(IN1_INPUT,"CV"); 27 | configOutput(OUT1_OUTPUT,"Stepped CV"); 28 | } 29 | 30 | void process(const ProcessArgs &args) override { 31 | 32 | 33 | if (inputs[LIN1_INPUT].isConnected()) 34 | { 35 | max_steps = round(clamp(params[LEVEL1_PARAM].getValue() + inputs[LIN1_INPUT].getVoltage()*0.32*params[TRIM1_PARAM].getValue(),1.0f,32.0f)); 36 | outputs[OUT1_OUTPUT].setVoltage(floor((inputs[IN1_INPUT].getVoltage() * round(clamp(params[LEVEL1_PARAM].getValue() + inputs[LIN1_INPUT].getVoltage()*0.32*params[TRIM1_PARAM].getValue(),1.0f,32.0f))) / 10.01) * (10 / round(clamp(params[LEVEL1_PARAM].getValue() + inputs[LIN1_INPUT].getVoltage()*0.32*params[TRIM1_PARAM].getValue(),1.0f,32.0f)))) ; 37 | } 38 | else 39 | { 40 | max_steps = round(params[LEVEL1_PARAM].getValue()); 41 | outputs[OUT1_OUTPUT].setVoltage(floor((inputs[IN1_INPUT].getVoltage() * round(params[LEVEL1_PARAM].getValue())) / 10.01) * (10 / round(params[LEVEL1_PARAM].getValue()))); 42 | } 43 | }; 44 | 45 | 46 | }; 47 | 48 | struct NumbeDisplayWidget : TransparentWidget { 49 | STEPS *module; 50 | 51 | 52 | 53 | NumbeDisplayWidget() { 54 | 55 | }; 56 | 57 | void drawLayer(const DrawArgs &args, int layer) override { 58 | if (layer ==1) { 59 | std::shared_ptr font = APP->window->loadFont(asset::plugin(pluginInstance, "res/Segment7Standard.ttf")); 60 | int st = module ? module->max_steps : 0; 61 | // Background 62 | NVGcolor backgroundColor = nvgRGB(0x44, 0x44, 0x44); 63 | NVGcolor borderColor = nvgRGB(0x10, 0x10, 0x10); 64 | nvgBeginPath(args.vg); 65 | nvgRoundedRect(args.vg, 0.0, 0.0, box.size.x, box.size.y, 4.0); 66 | nvgFillColor(args.vg, backgroundColor); 67 | nvgFill(args.vg); 68 | nvgStrokeWidth(args.vg, 1.0); 69 | nvgStrokeColor(args.vg, borderColor); 70 | nvgStroke(args.vg); 71 | 72 | nvgFontSize(args.vg, 18); 73 | nvgFontFaceId(args.vg, font->handle); 74 | nvgTextLetterSpacing(args.vg, 2.5); 75 | 76 | std::string to_display = std::to_string(st); 77 | 78 | //char d_string[10]; 79 | // if(st) sprintf(d_string,"%6i",st); 80 | 81 | while(to_display.length()<3) to_display = ' ' + to_display; 82 | 83 | Vec textPos = Vec(6.0f, 17.0f); 84 | 85 | NVGcolor textColor = nvgRGB(0xdf, 0xd2, 0x2c); 86 | nvgFillColor(args.vg, nvgTransRGBA(textColor, 16)); 87 | nvgText(args.vg, textPos.x, textPos.y, "~~~", NULL); 88 | 89 | textColor = nvgRGB(0xda, 0xe9, 0x29); 90 | 91 | nvgFillColor(args.vg, nvgTransRGBA(textColor, 16)); 92 | nvgText(args.vg, textPos.x, textPos.y, "\\\\\\", NULL); 93 | 94 | 95 | textColor = nvgRGB(0x28, 0xb0, 0xf3); 96 | nvgFillColor(args.vg, textColor); 97 | nvgText(args.vg, textPos.x, textPos.y, to_display.c_str(), NULL); 98 | //nvgText(args.vg, textPos.x, textPos.y, d_string, NULL); 99 | } 100 | Widget::drawLayer(args, layer); 101 | } 102 | }; 103 | 104 | struct STEPSWidget : ModuleWidget { 105 | STEPSWidget(STEPS *module) { 106 | setModule(module); 107 | setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/STEPS.svg"))); 108 | 109 | 110 | addChild(createWidget(Vec(15, 0))); 111 | addChild(createWidget(Vec(box.size.x-30, 0))); 112 | addChild(createWidget(Vec(15, 365))); 113 | addChild(createWidget(Vec(box.size.x-30, 365))); 114 | 115 | addParam(createParam(Vec(27, 157), module, STEPS::LEVEL1_PARAM)); 116 | 117 | addParam(createParam(Vec(37, 207), module, STEPS::TRIM1_PARAM)); 118 | 119 | addInput(createInput(Vec(34, 250), module, STEPS::LIN1_INPUT)); 120 | 121 | addInput(createInput(Vec(11, 321), module, STEPS::IN1_INPUT)); 122 | 123 | addOutput(createOutput(Vec(54, 321), module, STEPS::OUT1_OUTPUT)); 124 | 125 | 126 | NumbeDisplayWidget *display = new NumbeDisplayWidget(); 127 | display->box.pos = Vec(20,56); 128 | display->box.size = Vec(50, 20); 129 | display->module = module; 130 | addChild(display); 131 | 132 | } 133 | }; 134 | 135 | Model *modelSTEPS = createModel("STEPS"); 136 | -------------------------------------------------------------------------------- /src/SUB.cpp: -------------------------------------------------------------------------------- 1 | #include "plugin.hpp" 2 | 3 | 4 | 5 | struct SUB : Module { 6 | enum ParamIds { 7 | GAIN_PARAM, 8 | GAIN2_PARAM, 9 | LINK_PARAM, 10 | NUM_PARAMS 11 | }; 12 | enum InputIds { 13 | GAIN_INPUT, 14 | GAIN2_INPUT, 15 | M1_INPUT, 16 | M2_INPUT, 17 | IN1_INPUT, 18 | IN2_INPUT, 19 | NUM_INPUTS 20 | }; 21 | enum OutputIds { 22 | M1_OUTPUT, 23 | OUT1_OUTPUT, 24 | M2_OUTPUT, 25 | OUT2_OUTPUT, 26 | NUM_OUTPUTS 27 | }; 28 | enum LightIds { 29 | LINK_LIGHT, 30 | NUM_LIGHTS 31 | }; 32 | 33 | 34 | float SIGNAL = 0.0 ; 35 | float SIGNAL2 = 0.0 ; 36 | float or_gain ; 37 | float or2_gain ; 38 | int or_affi ; 39 | int or2_affi ; 40 | bool LINK_STATE = false ; 41 | dsp::SchmittTrigger linkTrigger; 42 | 43 | 44 | SUB() { 45 | config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); 46 | configButton(LINK_PARAM, "Link"); 47 | configParam(GAIN_PARAM, 0.0f, 1.0f, 0.0f, "Send 1"); 48 | configParam(GAIN2_PARAM, 0.0f, 1.0f, 0.0f, "Send 2"); 49 | 50 | configInput(GAIN_INPUT,"Send 1 control"); 51 | configInput(GAIN2_INPUT,"Send 2 control"); 52 | configInput(M1_INPUT,"A1"); 53 | configInput(M2_INPUT,"A2"); 54 | configInput(IN1_INPUT,"B1"); 55 | configInput(IN2_INPUT,"B2"); 56 | 57 | configOutput(M1_OUTPUT,"A1+B1xSend1"); 58 | configOutput(OUT1_OUTPUT,"B1 thru"); 59 | configOutput(M2_OUTPUT,"A2+B2xSend2"); 60 | configOutput(OUT2_OUTPUT,"B2 thru"); 61 | onReset(); 62 | } 63 | 64 | 65 | void onReset() override { 66 | LINK_STATE = false; 67 | } 68 | 69 | json_t *dataToJson() override { 70 | json_t *rootJ = json_object(); 71 | // solo 72 | json_object_set_new(rootJ, "linkstate", json_integer(LINK_STATE)); 73 | 74 | return rootJ; 75 | } 76 | 77 | void dataFromJson(json_t *rootJ) override { 78 | // solo 79 | json_t *linkstateJ = json_object_get(rootJ, "linkstate"); 80 | if (linkstateJ) 81 | LINK_STATE = json_integer_value(linkstateJ); 82 | 83 | 84 | } 85 | 86 | 87 | 88 | 89 | void process(const ProcessArgs &args) override { 90 | 91 | if (linkTrigger.process(params[LINK_PARAM].getValue())) 92 | {LINK_STATE=!LINK_STATE;} 93 | lights[LINK_LIGHT].setBrightness(LINK_STATE); 94 | 95 | 96 | SIGNAL = inputs[IN1_INPUT].getVoltage() ; 97 | 98 | outputs[OUT1_OUTPUT].setVoltage(SIGNAL); 99 | 100 | if (!inputs[GAIN_INPUT].isConnected()) 101 | {SIGNAL = SIGNAL * params[GAIN_PARAM].getValue();or_affi=0; or_gain=params[GAIN_PARAM].getValue()*10.0;} 102 | else {SIGNAL = SIGNAL * clamp(inputs[GAIN_INPUT].getVoltage()/10.0f,0.0f,1.0f) ; or_affi=1;or_gain=clamp(inputs[GAIN_INPUT].getVoltage(),0.0f,10.0f);} 103 | 104 | outputs[M1_OUTPUT].setVoltage(inputs[M1_INPUT].getVoltage() + SIGNAL); 105 | 106 | 107 | SIGNAL2 = inputs[IN2_INPUT].getVoltage() ; 108 | 109 | outputs[OUT2_OUTPUT].setVoltage(SIGNAL2); 110 | 111 | if (!LINK_STATE) { 112 | if (!inputs[GAIN2_INPUT].isConnected()) 113 | {SIGNAL2 = SIGNAL2 * params[GAIN2_PARAM].getValue();or2_affi=0;or2_gain=params[GAIN2_PARAM].getValue()*10.0;} 114 | else {SIGNAL2 = SIGNAL2 * clamp(inputs[GAIN2_INPUT].getVoltage()/10.0f,0.0f,1.0f) ; or2_affi=1;or2_gain=clamp(inputs[GAIN2_INPUT].getVoltage(),0.0f,10.0f);} 115 | } else { 116 | if (!inputs[GAIN_INPUT].isConnected()) 117 | {SIGNAL2 = SIGNAL2 * params[GAIN_PARAM].getValue() ;or2_affi=1;or2_gain=clamp(params[GAIN_PARAM].getValue()*10.0,0.0f,10.0f);} 118 | else {SIGNAL2 = SIGNAL2 * clamp(inputs[GAIN_INPUT].getVoltage()/10.0f,0.0f,1.0f) ; or2_affi=1;or2_gain=clamp(inputs[GAIN_INPUT].getVoltage(),0.0f,10.0f);} 119 | } 120 | 121 | outputs[M2_OUTPUT].setVoltage(inputs[M2_INPUT].getVoltage() + SIGNAL2); 122 | 123 | 124 | } 125 | }; 126 | 127 | struct MDisplay : TransparentWidget { 128 | SUB *module; 129 | 130 | MDisplay() { 131 | 132 | } 133 | 134 | void draw(const DrawArgs &args) override { 135 | //nvgGlobalTint(args.vg, color::WHITE); 136 | float gainX = module ? module->or_gain : 1.0f; 137 | //int affich = module ? module->or_affi : 0; 138 | float d=18; 139 | 140 | //if (affich==1) { 141 | float xx = d*sin(-(gainX*0.17+0.15)*M_PI) ; 142 | float yy = d*cos((gainX*0.17+0.15)*M_PI) ; 143 | 144 | 145 | //nvgBeginPath(args.vg); 146 | //nvgCircle(args.vg, 0,0, d); 147 | //nvgFillColor(args.vg, nvgRGBA(0x00, 0x00, 0x00, 0xff)); 148 | //nvgFill(args.vg); 149 | 150 | nvgStrokeWidth(args.vg,2); 151 | nvgStrokeColor(args.vg, nvgRGBA(0xff, 0xff, 0xff, 0x88)); 152 | { 153 | nvgBeginPath(args.vg); 154 | nvgMoveTo(args.vg, 0,0); 155 | nvgLineTo(args.vg, xx,yy); 156 | nvgClosePath(args.vg); 157 | } 158 | nvgStroke(args.vg); 159 | //} 160 | 161 | } 162 | }; 163 | 164 | struct MSDisplay : TransparentWidget { 165 | SUB *module; 166 | 167 | MSDisplay() { 168 | 169 | } 170 | 171 | void draw(const DrawArgs &args) override { 172 | //nvgGlobalTint(args.vg, color::WHITE); 173 | float gainX = module ? module->or2_gain : 1.0f; 174 | //int affich = module ? module->or2_affi : 0; 175 | float d=18; 176 | 177 | //if (affich==1) { 178 | float xx = d*sin(-(gainX*0.17+0.15)*M_PI) ; 179 | float yy = d*cos((gainX*0.17+0.15)*M_PI) ; 180 | 181 | 182 | //nvgBeginPath(args.vg); 183 | //nvgCircle(args.vg, 0,0, d); 184 | //nvgFillColor(args.vg, nvgRGBA(0x00, 0x00, 0x00, 0xff)); 185 | //nvgFill(args.vg); 186 | 187 | nvgStrokeWidth(args.vg,2); 188 | nvgStrokeColor(args.vg, nvgRGBA(0xff, 0xff, 0xff, 0x88)); 189 | { 190 | nvgBeginPath(args.vg); 191 | nvgMoveTo(args.vg, 0,0); 192 | nvgLineTo(args.vg, xx,yy); 193 | nvgClosePath(args.vg); 194 | } 195 | nvgStroke(args.vg); 196 | //} 197 | 198 | } 199 | }; 200 | 201 | 202 | struct SUBWidget : ModuleWidget { 203 | SUBWidget(SUB *module){ 204 | setModule(module); 205 | setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/SUB.svg"))); 206 | 207 | addChild(createWidget(Vec(15, 0))); 208 | addChild(createWidget(Vec(box.size.x-30, 0))); 209 | addChild(createWidget(Vec(15, 365))); 210 | addChild(createWidget(Vec(box.size.x-30, 365))); 211 | 212 | addParam(createParam(Vec(22, 179), module, SUB::LINK_PARAM)); 213 | addChild(createLight>(Vec(26.5, 182.5), module, SUB::LINK_LIGHT)); 214 | 215 | 216 | addParam(createParam(Vec(27, 247), module, SUB::GAIN2_PARAM)); 217 | addInput(createInput(Vec(11, 281), module, SUB::GAIN2_INPUT)); 218 | { 219 | MSDisplay *display2 = new MSDisplay(); 220 | display2->box.pos = Vec(45, 265); 221 | display2->module = module; 222 | addChild(display2); 223 | } 224 | 225 | 226 | 227 | addInput(createInput(Vec(11, 321), module, SUB::IN2_INPUT)); 228 | 229 | addOutput(createOutput(Vec(54, 321), module, SUB::OUT2_OUTPUT)); 230 | 231 | 232 | addOutput(createOutput(Vec(54, 61+152), module, SUB::M2_OUTPUT)); 233 | 234 | 235 | addInput(createInput(Vec(11, 61+152), module, SUB::M2_INPUT)); 236 | 237 | 238 | 239 | addParam(createParam(Vec(27, 247-182), module, SUB::GAIN_PARAM)); 240 | addInput(createInput(Vec(11, 281-182), module, SUB::GAIN_INPUT)); 241 | { 242 | MDisplay *display = new MDisplay(); 243 | display->box.pos = Vec(45, 265-182); 244 | display->module = module; 245 | addChild(display); 246 | } 247 | 248 | 249 | 250 | addInput(createInput(Vec(11, 321-182), module, SUB::IN1_INPUT)); 251 | 252 | addOutput(createOutput(Vec(54, 321-182), module, SUB::OUT1_OUTPUT)); 253 | 254 | 255 | addOutput(createOutput(Vec(54, 31), module, SUB::M1_OUTPUT)); 256 | 257 | 258 | addInput(createInput(Vec(11, 31), module, SUB::M1_INPUT)); 259 | 260 | 261 | } 262 | }; 263 | 264 | Model *modelSUB = createModel("SUB"); 265 | -------------------------------------------------------------------------------- /src/VARIABLE.cpp: -------------------------------------------------------------------------------- 1 | #include "plugin.hpp" 2 | 3 | 4 | 5 | 6 | 7 | using namespace std; 8 | 9 | 10 | struct VARIABLE : Module { 11 | enum ParamIds { 12 | PREV_PARAM, 13 | NEXT_PARAM, 14 | HOLD_PARAM, 15 | NUM_PARAMS 16 | }; 17 | enum InputIds { 18 | IN_INPUT, 19 | TRIG_INPUT, 20 | NUM_INPUTS 21 | }; 22 | enum OutputIds { 23 | OUT_OUTPUT, 24 | NUM_OUTPUTS 25 | }; 26 | enum LightIds { 27 | HOLD_LIGHT, 28 | NUM_LIGHTS 29 | }; 30 | 31 | 32 | bool lock = false ; 33 | bool plugged = false ; 34 | float value = 0; 35 | dsp::SchmittTrigger trigTrigger; 36 | dsp::SchmittTrigger holdTrigger; 37 | dsp::SchmittTrigger nextTrigger; 38 | dsp::SchmittTrigger prevTrigger; 39 | 40 | VARIABLE(){ 41 | config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); 42 | configButton(PREV_PARAM, "-1"); 43 | configButton(NEXT_PARAM, "+1"); 44 | configButton(HOLD_PARAM, "Hold value"); 45 | configInput(IN_INPUT,"Value"); 46 | configInput(TRIG_INPUT,"Value hold trigger"); 47 | configOutput(OUT_OUTPUT,"Value"); 48 | } 49 | 50 | 51 | 52 | json_t *dataToJson() override { 53 | json_t *rootJ = json_object(); 54 | 55 | json_object_set_new(rootJ, "loc", json_integer(lock)); 56 | json_object_set_new(rootJ, "plu", json_integer(plugged)); 57 | json_object_set_new(rootJ, "val", json_real(value)); 58 | return rootJ; 59 | } 60 | 61 | void dataFromJson(json_t *rootJ) override { 62 | 63 | json_t *locJ = json_object_get(rootJ, "loc"); 64 | if (locJ) 65 | lock = json_integer_value(locJ); 66 | 67 | json_t *pluJ = json_object_get(rootJ, "plu"); 68 | if (pluJ) 69 | plugged = json_integer_value(pluJ); 70 | 71 | json_t *valJ = json_object_get(rootJ, "val"); 72 | if (valJ) 73 | value = json_real_value(valJ); 74 | 75 | } 76 | 77 | 78 | 79 | 80 | void process(const ProcessArgs &args) override { 81 | 82 | if (inputs[IN_INPUT].isConnected() & !plugged) {plugged = true; lock = false;} 83 | if (!inputs[IN_INPUT].isConnected()) {plugged = false;} 84 | 85 | if (inputs[IN_INPUT].isConnected() & !lock) value = inputs[IN_INPUT].getVoltage(); 86 | 87 | 88 | if ( ( holdTrigger.process(params[HOLD_PARAM].getValue()) or trigTrigger.process(inputs[TRIG_INPUT].getVoltage()) ) & inputs[IN_INPUT].isConnected()) 89 | { 90 | value = inputs[IN_INPUT].getVoltage(); 91 | lock = true; 92 | } 93 | 94 | 95 | if (nextTrigger.process(params[NEXT_PARAM].getValue())) 96 | { 97 | if ((value<0)&(value!=int(value))) value = int(value) ; else value = int(value+1); 98 | } 99 | 100 | 101 | if (prevTrigger.process(params[PREV_PARAM].getValue())) 102 | { 103 | if ((value>=0)&(value!=int(value))) value = int(value) ; else value = int(value-1); 104 | } 105 | 106 | 107 | lights[HOLD_LIGHT].setBrightness(lock) ; 108 | outputs[OUT_OUTPUT].setVoltage(value) ; 109 | 110 | } 111 | }; 112 | struct upButton : app::SvgSwitch { 113 | upButton() { 114 | momentary = true; 115 | addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/upButton.svg"))); 116 | addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/upButtonDown.svg"))); 117 | } 118 | }; 119 | struct downButton : app::SvgSwitch { 120 | downButton() { 121 | momentary = true; 122 | addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/downButton.svg"))); 123 | addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/downButtonDown.svg"))); 124 | }; 125 | }; 126 | 127 | struct VARIABLEDisplay : TransparentWidget { 128 | VARIABLE *module; 129 | 130 | int frame = 0; 131 | 132 | 133 | VARIABLEDisplay() { 134 | 135 | }; 136 | 137 | void drawLayer(const DrawArgs &args, int layer) override { 138 | if (layer ==1) { 139 | std::shared_ptr font = APP->window->loadFont(asset::plugin(pluginInstance, "res/LEDCalculator.ttf")); 140 | float val = module ? module->value : 0; 141 | std::string to_display = ""; 142 | std::string fileDesc = ""; 143 | if (val>=0) 144 | fileDesc = "+" + std::to_string(val); else fileDesc = std::to_string(val); 145 | for (int i=0; i<9; i++) to_display = to_display + fileDesc[i]; 146 | nvgFontSize(args.vg, 24); 147 | nvgFontFaceId(args.vg, font->handle); 148 | nvgTextLetterSpacing(args.vg, 0); 149 | nvgFillColor(args.vg, nvgRGBA(0x4c, 0xc7, 0xf3, 0xff)); 150 | nvgRotate(args.vg, -M_PI / 2.0f); 151 | nvgTextBox(args.vg, 5, 5,350, to_display.c_str(), NULL); 152 | } 153 | Widget::drawLayer(args, layer); 154 | } 155 | }; 156 | 157 | 158 | struct VARIABLEWidget : ModuleWidget { 159 | VARIABLEWidget(VARIABLE *module){ 160 | setModule(module); 161 | setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/VARIABLE.svg"))); 162 | 163 | 164 | 165 | { 166 | VARIABLEDisplay *gdisplay = new VARIABLEDisplay(); 167 | gdisplay->box.pos = Vec(18, 268); 168 | gdisplay->box.size = Vec(130, 250); 169 | gdisplay->module = module; 170 | addChild(gdisplay); 171 | } 172 | 173 | 174 | addChild(createWidget(Vec(15, 0))); 175 | addChild(createWidget(Vec(box.size.x-30, 365))); 176 | 177 | addInput(createInput(Vec(3, 31), module, VARIABLE::IN_INPUT)); 178 | addInput(createInput(Vec(3, 96), module, VARIABLE::TRIG_INPUT)); 179 | addParam(createParam(Vec(6, 66+3), module, VARIABLE::HOLD_PARAM)); 180 | addChild(createLight>(Vec(6+4.4, 69+4.4), module, VARIABLE::HOLD_LIGHT)); 181 | 182 | addOutput(createOutput(Vec(3, 321), module, VARIABLE::OUT_OUTPUT)); 183 | 184 | addParam(createParam(Vec(6, 296+2), module, VARIABLE::PREV_PARAM)); 185 | addParam(createParam(Vec(6, 276+2), module, VARIABLE::NEXT_PARAM)); 186 | } 187 | }; 188 | 189 | Model *modelVARIABLE = createModel("VARIABLE"); 190 | -------------------------------------------------------------------------------- /src/plugin.cpp: -------------------------------------------------------------------------------- 1 | #include "plugin.hpp" 2 | 3 | 4 | Plugin *pluginInstance; 5 | 6 | void init(rack::Plugin *p) { 7 | pluginInstance = p; 8 | 9 | p->addModel(modelMETRO); 10 | p->addModel(modelEACH); 11 | p->addModel(modeltrSEQ); 12 | p->addModel(modelLEDSEQ); 13 | p->addModel(modelL3DS3Q); 14 | p->addModel(modelSLIDERSEQ); 15 | p->addModel(modelPLAYER); 16 | p->addModel(modelPLAY); 17 | p->addModel(modelMONO); 18 | p->addModel(modelSTEREO); 19 | p->addModel(modelSUB); 20 | p->addModel(modelMASTER); 21 | p->addModel(modelVARIABLE); 22 | p->addModel(modelALGEBRA); 23 | p->addModel(modelFUNKTION); 24 | p->addModel(modelCHOKE); 25 | p->addModel(modelFOUR); 26 | p->addModel(modelSTEPS); 27 | p->addModel(modelPEAK); 28 | p->addModel(modelCUTS); 29 | p->addModel(modelBUFFER); 30 | p->addModel(modelDISTO); 31 | p->addModel(modelCUBE); 32 | p->addModel(modelPATCH); 33 | p->addModel(modelLABEL); 34 | p->addModel(modelDAVE); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/plugin.hpp: -------------------------------------------------------------------------------- 1 | #include "rack.hpp" 2 | 3 | using namespace rack; 4 | 5 | 6 | extern Plugin *pluginInstance; 7 | 8 | struct cfBigKnob : RoundKnob { 9 | cfBigKnob() { 10 | setSvg(Svg::load(asset::plugin(pluginInstance,"res/cfBigKnob.svg"))); 11 | bg->setSvg(Svg::load(asset::plugin(pluginInstance,"res/cfBigKnob-bg.svg"))); 12 | } 13 | 14 | }; 15 | 16 | struct cfTrimpot : RoundKnob { 17 | cfTrimpot() { 18 | setSvg(Svg::load(asset::plugin(pluginInstance,"res/cfTrimpot.svg"))); 19 | bg->setSvg(Svg::load(asset::plugin(pluginInstance,"res/cfTrimpot-bg.svg"))); 20 | } 21 | 22 | }; 23 | 24 | //////////////////// 25 | // module widgets 26 | //////////////////// 27 | 28 | extern Model *modelMETRO; 29 | extern Model *modelEACH; 30 | extern Model *modeltrSEQ; 31 | extern Model *modelLEDSEQ; 32 | extern Model *modelL3DS3Q; 33 | extern Model *modelSLIDERSEQ; 34 | extern Model *modelPLAYER; 35 | extern Model *modelPLAY; 36 | extern Model *modelMONO; 37 | extern Model *modelSTEREO; 38 | extern Model *modelSUB; 39 | extern Model *modelMASTER; 40 | extern Model *modelVARIABLE; 41 | extern Model *modelALGEBRA; 42 | extern Model *modelFUNKTION; 43 | extern Model *modelCHOKE; 44 | extern Model *modelFOUR; 45 | extern Model *modelSTEPS; 46 | extern Model *modelPEAK; 47 | extern Model *modelCUTS; 48 | extern Model *modelBUFFER; 49 | extern Model *modelDISTO; 50 | extern Model *modelCUBE; 51 | extern Model *modelPATCH; 52 | extern Model *modelLABEL; 53 | extern Model *modelDAVE; 54 | --------------------------------------------------------------------------------