diff --git a/plugins/community/repos/SubmarineFree/Makefile b/plugins/community/repos/SubmarineFree/Makefile index aafe02db..27f0c4f5 100644 --- a/plugins/community/repos/SubmarineFree/Makefile +++ b/plugins/community/repos/SubmarineFree/Makefile @@ -2,7 +2,7 @@ SLUG = SubmarineFree # Must follow the format in the Versioning section of https://vcvrack.com/manual/PluginDevelopmentTutorial.html -VERSION = 0.6.4 +VERSION = 0.6.8 # FLAGS will be passed to both the C and C++ compiler FLAGS += diff --git a/plugins/community/repos/SubmarineFree/README.md b/plugins/community/repos/SubmarineFree/README.md index cd836c76..40798426 100644 --- a/plugins/community/repos/SubmarineFree/README.md +++ b/plugins/community/repos/SubmarineFree/README.md @@ -1,9 +1,16 @@ # SubmarineFree Free plugins for VCV Rack +[.plan (what I'm working on)](https://github.com/david-c14/SubmarineFree/issues/23) + # [Manual](https://github.com/david-c14/SubmarineFree/blob/master/manual/index.md) -# [Builds](https://github.com/david-c14/SubmarineFree/issues/9) +# [Builds](https://github.com/david-c14/SubmarineFree/releases/tag/v0.6.8) +###### [0.6.8](https://github.com/david-c14/SubmarineFree/releases/tag/v0.6.8) +###### [0.6.7](https://github.com/david-c14/SubmarineFree/releases/tag/v0.6.7) +###### [0.6.6](https://github.com/david-c14/SubmarineFree/issues/20) +###### [0.6.5](https://github.com/david-c14/SubmarineFree/issues/19) +###### [0.6.4](https://github.com/david-c14/SubmarineFree/issues/14) ###### [0.6.3](https://github.com/david-c14/SubmarineFree/issues/9) ###### [0.6.2](https://github.com/david-c14/SubmarineFree/issues/4) @@ -11,3 +18,5 @@ Free plugins for VCV Rack Source code licensed under BSD-3-Clause by carbon14 (David O'Rourke) All graphics in res/ and src/res are © 2018 by carbon14 (David O'Rourke) + +Some portions of this source code are based on code © 2016 by Andrew Belt diff --git a/plugins/community/repos/SubmarineFree/make.objects b/plugins/community/repos/SubmarineFree/make.objects index 8c00e537..d0008398 100644 --- a/plugins/community/repos/SubmarineFree/make.objects +++ b/plugins/community/repos/SubmarineFree/make.objects @@ -1,25 +1,32 @@ ALL_OBJ= \ - src/AG-106.o \ - src/BB-120.o \ - src/BP.o \ + src/AG1.o \ + src/AO1.o \ + src/BB1.o \ + src/BP1.o \ src/DS.o \ - src/FF-110.o \ - src/FF-120.o \ - src/FF-212.o \ - src/LA-108.o \ - src/LD-106.o \ - src/NG-112.o \ - src/OG-106.o \ - src/PG-112.o \ - src/PO.o \ + src/EO1.o \ + src/FF1.o \ + src/FF2.o \ + src/LA1.o \ + src/LD1.o \ + src/NG1.o \ + src/OG1.o \ + src/PG1.o \ + src/PO12.o \ + src/SS1.o \ src/SubmarineFree.o \ - src/WK-101.o \ + src/TD1.o \ + src/TD2.o \ + src/TF1.o \ + src/TM1.o \ + src/WK12.o \ src/XF-101.o \ src/XF-102.o \ src/XF-104.o \ src/XF-201.o \ src/XF-202.o \ src/XF.o \ - src/XG-106.o \ + src/XG1.o \ src/torpedo.o \ - src/ComponentLibrary/LightKnob.o + src/ComponentLibrary/LightKnob.o \ + src/ComponentLibrary/Port.o diff --git a/plugins/community/repos/SubmarineFree/manual/AG.md b/plugins/community/repos/SubmarineFree/manual/AG.md index 8034311a..59c85eeb 100644 --- a/plugins/community/repos/SubmarineFree/manual/AG.md +++ b/plugins/community/repos/SubmarineFree/manual/AG.md @@ -1,5 +1,6 @@ # Logical AND Gates ### [Part of the Digital Suite](DS.md) +#### AG-104 AND Gates #### AG-106 AND Gates @@ -18,3 +19,7 @@ The voltage range of the digital gates can be configured from the context menu. Any output not connected will be normalled into a third input on the gate below. In this way multi-input gates can be created up to a maximum of 12 inputs. An input not connected will be ignored. + +## AG-104 + +The AG-104 provides four two-input AND gates in a small form factor. Otherwise functionality is as for the AG-106 above. diff --git a/plugins/community/repos/SubmarineFree/manual/AO-118.png b/plugins/community/repos/SubmarineFree/manual/AO-118.png new file mode 100644 index 00000000..4c72e0be Binary files /dev/null and b/plugins/community/repos/SubmarineFree/manual/AO-118.png differ diff --git a/plugins/community/repos/SubmarineFree/manual/AO-example-osc.md b/plugins/community/repos/SubmarineFree/manual/AO-example-osc.md new file mode 100644 index 00000000..811dbd37 --- /dev/null +++ b/plugins/community/repos/SubmarineFree/manual/AO-example-osc.md @@ -0,0 +1,64 @@ +# A sine wave oscillator using AO-106 + +![Example Patch](./AO-example-osc.png "AO-example-osc.png") + +In the example above we have an AO-106 6-algorithm device functioning as a voltage controlled sine wave oscillator. +An SS-221 on the left is providing a reference 1v/oct CV to both the AO-106 and a Frank Buss Formula for comparison. + +The first block in the AO-106 is providing a small delta value. + +The second block takes that delta value and adds it to the X-input which is fed from... + +...the third block which takes the accumulated value and reduces it modulo 1. + +The result is that we have a signal in a feedback loop from the third block back to the second block, which gradually grows over time, +and cycles around every time it reaches 1. Effectively a sawtooth wave with a frequency that depends on the input voltage, and a range from +0V to 1V. + +The fourth block multiplies this sawtooth amplitude by tau (2 pi) to give an amplitude that ranges from 0V to tauV. + +The fifth block takes the sine of this sawtooth. Since a range of 0 to tau in radians represents one complete cycle, the resulting signal +is a sine wave with a range of -1V to +1V + +The sixth block multiplies the signal by 5 to give the final -5V to +5V sine wave. + +The complicated part of this patch is in the first block where the algorithm is 2x+c. Where does this value of C = -7.52 come from? + +To acheive our basic requirement of 1v/oct, we need to raise 2 to the power of the CV input. For each increase 1V increase in the CV, +the resulting value doubles, just like the frequency doubling as we move up an octave. But we have some further requirements. + +We want our signal frequency to be middle C (261.6Hz) when the CV is at 0V, so we should multiply our power of 2 by 261.6. +That gives us a value in cycles per second. But then we need to divide this value by our sample rate, in this case I'm running at 48,000Hz +sample rate. We divide by this number so that our delta accumulates to the right number of cycles every second. + +Our algorithm for the delta value then is + +2x × 261.6 ÷ 48000 + +or + +2x × 0.00545 + +But we could represent 0.00545 as a 2 raised to some power... 2n + +n would be the base-2 logarithm of 0.00545 which is -7.51953 + +Now we can say that our delta value is + +2x × 2-7.51953 + +or + +2x - 7.51953 + +This is where the figures in the first block come from. + +The AO-1xx series of devices offer only two decimal places of precision in the constant setting, as a result this example oscillator is ever so slightly flat. +However this discrepancy is less that the drift in the Fundamental VCO1. + +Note also that changing the engine sample rate would change the frequency of the oscillator. Doubling the engine sample rate to 96,000 Hz +would require adjusting the constant from -7.52 to -8.52. + +The Frank Buss Formula has a built in sawtooth oscillator which automatically compensates for changes in the engine sample rate. + + diff --git a/plugins/community/repos/SubmarineFree/manual/AO-example-osc.png b/plugins/community/repos/SubmarineFree/manual/AO-example-osc.png new file mode 100644 index 00000000..f3a2b179 Binary files /dev/null and b/plugins/community/repos/SubmarineFree/manual/AO-example-osc.png differ diff --git a/plugins/community/repos/SubmarineFree/manual/AO-example-square.png b/plugins/community/repos/SubmarineFree/manual/AO-example-square.png new file mode 100644 index 00000000..21dfc9a7 Binary files /dev/null and b/plugins/community/repos/SubmarineFree/manual/AO-example-square.png differ diff --git a/plugins/community/repos/SubmarineFree/manual/AO-list.md b/plugins/community/repos/SubmarineFree/manual/AO-list.md new file mode 100644 index 00000000..729daae7 --- /dev/null +++ b/plugins/community/repos/SubmarineFree/manual/AO-list.md @@ -0,0 +1,230 @@ +# AO-1xx Algorithms + +## Arithmetical +| Display | Code | Description | +| ------------------------ | ------------------ | -------------------- | +| | | Pass-through. X passes across unchanged, Y passes down unchanged | +| C | c | The value of the selected constant C | +| X+C | x + c | X added to C | +| Y+C | y + c | Y added to C| +| X+Y+C | x + y + c | X and Y added to C | +| C-X | c - x | X subtracted from C | +| C-Y | c - y | Y subtracted from C | +| X-(Y+C) | x - ( y + c ) | Y added to C then all subtracted from X | +| (X+C)-Y | ( x + c ) - y | Y subtracted from X and C | +| Y-(X+C) | y - ( x + c ) | X added to C then all subtracted from Y | +| (Y+C)-X | ( y + c ) - x | X subtracted from Y and C | +| (X⨯Y)+C | ( x * y ) + c | X times Y added to C | +| (X+C)⨯Y | ( x + c ) * y | X and C multiplied by Y | +| X⨯(Y+C) | x * ( y + c ) | Y and C multiplied by X | +| X⨯C | x * c | X times C | +| Y⨯C | y * c | Y times C | +| X⨯Y⨯C | x * y * c | X times Y times C| +| π⨯(X+C) | M_PI * ( x + c ) | X and C multiplied by pi | +| π⨯(Y+C) | M_PI * ( y + c ) | Y and C multiplied by pi | +| τ⨯(X+C) | 2 * M_PI * ( x + c ) | X and C multiplied by tau | +| τ⨯(Y+C) | 2 * M_PI * ( y + c ) | Y and C multiplied by tau | +| X÷C | x / c | X divided by C | +| C÷X | c / x | C divided by X | +| Y÷C | y / c | Y divided by C | +| C÷Y | c / y | C divided by Y | +| C+(X÷Y) | c + ( x / y ) | C added to X divided by Y | +| C+(Y÷X) | c + ( y / x ) | C added to Y divided by X | +| X+(Y÷C) | x + ( y / c ) | X added to Y divided by C | +| X+(C÷Y) | x + ( c / y ) | X added to C divided by Y | +| Y+(X÷C) | y + ( x / c ) | Y added to X divided by C | +| Y+(C÷X) | y + ( c / x ) | Y added to C divided by X | +| (X+C)÷Y | ( x + c ) / y | X and C divided by Y | +| X÷(Y+C) | x / ( y + c ) | X divided by Y and C | +| (Y+C)÷X | ( y + c ) / x | Y and C divided by X | +| Y÷(X+C) | y / ( x + c ) | Y divided by X and C | +## Modular +| Display | Code | Description | +| ------------------------ | ------------------ | -------------------- | +| (X+C)%Y | fmodf( x + c , y ) | The remainder of X and C divided by Y | +| (Y+C)%X | fmodf( y + c , x ) | The remainder of Y and C divided by X | +| X%(Y+C) | fmodf( x , y + c ) | The remainder of X divided by Y and C | +| Y%(X+C) | fmodf( y , x + c) | The remainder of Y divided by X and C | +| X%C | fmodf( x , c ) | The remainder of X divided by C | +| Y%C | fmodf( y , c ) | The remainder of Y divided by C | +## Quadratic +| Display | Code | Description | +| ------------------------ | ------------------ | -------------------- | +| X²+C | x * x + c | X squared added to C | +| Y²+C | y * y + c | Y squared added to C | +| (X+C)² | ( x + c ) * ( x + c ) | X and C squared | +| (Y+C)² | ( y + c ) * ( y + c ) | Y and C squared | +| X²+Y+C | x * x + y + c | X squared added to Y and C | +| Y²+X+C | y * y + x + c | Y squared added to X and C | +| X²+CY | x * x + c * y | X squared added to Y multiplied by C | +| Y²+CX | y * y + c * x | Y squared added to X multiplied by C | +## Powers +| Display | Code | Description | +| ------------------------ | ------------------ | -------------------- | +| √(X+C) | sqrt( x + c ) | The square root of X and C | +| √(Y+C) | sqrt( y + c ) | The square root of Y and C | +| Cˣ | powf( c , x ) | C raised to the power of X | +| Cʸ | powf( c , y ) | C raised to the power of Y | +| Cˣ⁺ʸ | powf( c , x + y ) | C raised to the power of X and Y | +| Cˣʸ | powf( c , x * y ) | C raised to the power of X multiplied by Y | +| Xᶜ | powf( x , c ) | X raised to the power of C | +| Yᶜ | powf( y , c ) | Y raised to the power of C | +| Xʸ⁺ᶜ | powf( x , y + c ) | X raised to the power of Y and C | +| Yˣ⁺ᶜ | powf( y , x + c ) | Y raised to the power of X and C | +| Xᶜʸ | powf( x , c * y ) | X raised to the power of Y multiplied by C | +| Yᶜˣ | powf( y , c * x ) | Y raised to the power of X multiplied by C | +## Positive values only +| Display | Code | Description | +| ------------------------ | ------------------ | -------------------- | +| |X+C| | abs( x + c ) | X Added to C with any minus sign removed | +| |Y+C| | abs( y + c ) | Y added to C with any minus sign removed | +## Maximum and Minimum +| Display | Code | Description | +| ------------------------ | ------------------ | -------------------- | +| min(X+C,Y) | min( x + c, y ) | The smaller of X Added to C, or Y | +| min(X,C) | min( x, c ) | The smaller of X or C | +| min(Y,C) | min( y, c ) | The smaller of Y or C | +| max(X+C,Y) | max( x + c, y ) | The larger of X added to C, or Y | +| max(X,C) | max( x, c ) | The larger of X or C | +| max(Y,C) | max( y, c ) | The larger of Y or C | +## Trigonometric +| Display | Code | Description | +| ------------------------ | ------------------ | -------------------- | +| sin(X+C) | sin( x + c ) | The sine of X and C | +| sin(Y+C) | sin( y + c ) | The sine of Y and C | +| sin(X+Y) | sin( x + y ) | The sine of X and Y | +| sin(CX) | sin( c * x ) | The sine of X mulitplied by C | +| sin(CY) | sin( c * y ) | The sine of Y multiplied by C | +| sin(XY) | sin( x * y ) | The sine of X multiplied by Y | +| cos(X+C) | cos( x + c ) | The cosine of X and C | +| cos(Y+C) | cos( y + c ) || +| cos(X+Y) | cos( x + y ) || +| cos(CX) | cos( c * x ) || +| cos(CY) | cos( c * y ) || +| cos(XY) | cos( x * y ) || +| tan(X+C) | tan( x + c ) | The tangent of X and C | +| tan(Y+C) | tan( y + c ) || +| tan(X+Y) | tan( x + y ) || +| tan(CX) | tan( c * x ) || +| tan(CY) | tan( c * y ) || +| tan(XY) | tan( x * y ) || +| asin(X+C) | asin( x + c ) | The arcsine of X and C | +| asin(Y+C) | asin( y + c ) || +| asin(X+Y) | asin( x + y ) || +| asin(CX) | asin( c * x ) || +| asin(CY) | asin( c * y ) || +| asin(XY) | asin( x * y ) || +| acos(X+C) | acos( x + c ) | The arcosine of X and C | +| acos(Y+C) | acos( y + c ) || +| acos(X+Y) | acos( x + y ) || +| acos(CX) | acos( c * x ) || +| acos(CY) | acos( c * y ) || +| acos(XY) | acos( x * y ) || +| atan(X+C) | atan( x + c ) | The arctangent of X and C | +| atan(Y+C) | atan( y + c ) || +| atan(X+Y) | atan( x + y ) || +| atan(CX) | atan( c * x ) || +| atan(CY) | atan( c * y ) || +| atan(XY) | atan( x * y ) || +## Logarithmic +| Display | Code | Description | +| ------------------------ | ------------------ | -------------------- | +| log(X+C) | log( x + c ) | The natural logarithm of X and C | +| log(Y+C) | log( y + c ) | The natural logarithm of Y and C | +| log₂(X+C) | log2( x + c ) | The base-2 logarithm of X and C | +| log₂(Y+C) | log2( y + c ) | The base-2 logarithm of Y and C | +| log₁₀(X+C) | log10( x + c ) | The base-10 logarithm of X and C | +| log₁₀(Y+C) | log10( y + c ) | The base-10 logarithm of Y and C | +## Exponential +| Display | Code | Description | +| ------------------------ | ------------------ | -------------------- | +| ℯˣ⁺ᶜ | exp( x + c ) | e raised to the power of X and C | +| ℯʸ⁺ᶜ | exp( y + c ) | e raised to the power of Y and C | +| ℯᶜˣ | exp( c * x ) | e raised to the power of X multiplied by C | +| ℯᶜʸ | exp( c * y ) | e raised to the power of Y multiplied by C | +| 2ˣ⁺ᶜ | powf( 2, x + c ) | 2 raised to the power of X and C | +| 2ʸ⁺ᶜ | powf( 2, y + c ) | 2 raised to the power of Y and C | +| 2ᶜˣ | powf( 2, c * x ) | 2 raised to the power of X multiplied by C | +| 2ᶜʸ | powf( 2, c * y ) | 2 raised to the power of Y multiplied by C | +| 10ˣ⁺ᶜ | powf( 10, x + c ) | 10 raised to the power of X and C | +| 10ʸ⁺ᶜ | powf( 10, y + c ) | 10 raised to the power of Y and C | +| 10ᶜˣ | powf( 10, c * x ) | 10 raised to the power of X multiplied by C | +| 10ᶜʸ | powf( 10, c * y ) | 10 raised to the power of Y multiplied by C | +## Conditional +| Display | Code | Description | +| ------------------------ | ------------------ | -------------------- | +| if X>0↣Y/C | (x > 0) ? y : c | Y if X is greater than 0 otherwise C | +| if X<0↣Y/C | (x < 0) ? y : c | Y if X is less than 0 otherwise C | +| if X=0↣Y/C | (x == 0) ? y : c | Y if X is 0 otherwise C | +| if X>0↣C/Y | (x > 0) ? c : y | C if X is greater than 0 otherwise Y | +| if X<0↣C/Y | (x < 0) ? c : y | C if X is less that 0 otherwise Y | +| if X=0↣C/Y | (x == 0) ? c : y | C if X is 0 otherwise Y | +| if X>0↣1/0 | (x > 0) ? 1 : 0 | 1 if X is greater than 0 otherwise 0 | +| if X<0↣1/0 | (x < 0) ? 1 : 0 || +| if X=0↣1/0 | (x == 0) ? 1 : 0 || +| if X>0↣X/C | (x > 0) ? x : c | X if X is greater than 0 otherwise C | +| if X<0↣X/C | (x < 0) ? x : c || +| if X=0↣X/C | (x == 0) ? x : c || +| if X>0↣C/X | (x > 0) ? c : x | C if X is greater than 0 otherwise X | +| if X<0↣C/X | (x < 0) ? c : x || +| if X=0↣C/X | (x == 0) ? c : x || +| if Y>0↣X/C | (y > 0) ? x : c | X if Y is greater than 0 otherwise C | +| if Y<0↣X/C | (y < 0) ? x : c || +| if Y=0↣X/C | (y == 0) ? x : c || +| if Y>0↣C/X | (y > 0) ? c : x | C if Y is greater than 0 otherwise X | +| if Y<0↣C/X | (y < 0) ? c : x || +| if Y=0↣C/X | (y == 0) ? c : x || +| if Y>0↣1/0 | (y > 0) ? 1 : 0 || +| if Y<0↣1/0 | (y < 0) ? 1 : 0 || +| if Y=0↣1/0 | (y == 0) ? 1 : 0 || +| if Y>0↣Y/C | (y > 0) ? y : c || +| if Y<0↣Y/C | (y < 0) ? y : c || +| if Y=0↣Y/C | (y == 0) ? y : c || +| if Y>0↣C/Y | (y > 0) ? c : y || +| if Y<0↣C/Y | (y < 0) ? c : y || +| if Y=0↣C/Y | (y == 0) ? c : y || +| if X>Y↣C/0 | (x > y) ? c : 0 | C if X is greater than Y otherwise 0 | +| if XX↣C/0 | (y > x) ? c : 0 || +| if YY↣X/0 | (x > y) ? x : 0 | X if X is greater than Y otherwise 0 | +| if XX↣X/0 | (y > x) ? x : 0 || +| if YY↣Y/0 | (x > y) ? y : 0 || +| if XX↣Y/0 | (y > x) ? y : 0 || +| if YC↣Y/0 | (x > c) ? y : 0 || +| if XX↣Y/0 | (c > x) ? y : 0 || +| if CC↣X/0 | (x > c) ? x : 0 || +| if XX↣X/0 | (c > x) ? x : 0 || +| if CC↣X/Y | (x > c) ? x : y || +| if XX↣X/Y | (c > x) ? x : y || +| if CC↣X/0 | (y > c) ? x : 0 || +| if YY↣X/0 | (c > y) ? x : 0 || +| if CC↣Y/0 | (y > c) ? y : 0 || +| if YY↣Y/0 | (c > y) ? y : 0 || +| if CC↣Y/X | (y > c) ? y : x | Y if Y is greater than C otherwise X | +| if YY↣Y/X | (c > y) ? y : x | Y if C is greater than Y otherwise X | +| if C + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/plugins/community/repos/SubmarineFree/res/AO-106.svg b/plugins/community/repos/SubmarineFree/res/AO-106.svg new file mode 100644 index 00000000..2c712ebc --- /dev/null +++ b/plugins/community/repos/SubmarineFree/res/AO-106.svg @@ -0,0 +1,424 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/community/repos/SubmarineFree/res/AO-112.svg b/plugins/community/repos/SubmarineFree/res/AO-112.svg new file mode 100644 index 00000000..acbf6198 --- /dev/null +++ b/plugins/community/repos/SubmarineFree/res/AO-112.svg @@ -0,0 +1,475 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/community/repos/SubmarineFree/res/AO-118.svg b/plugins/community/repos/SubmarineFree/res/AO-118.svg new file mode 100644 index 00000000..162c8c4b --- /dev/null +++ b/plugins/community/repos/SubmarineFree/res/AO-118.svg @@ -0,0 +1,562 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/community/repos/SubmarineFree/res/AO-124.svg b/plugins/community/repos/SubmarineFree/res/AO-124.svg new file mode 100644 index 00000000..1f1385fe --- /dev/null +++ b/plugins/community/repos/SubmarineFree/res/AO-124.svg @@ -0,0 +1,649 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/community/repos/SubmarineFree/res/AO-136.svg b/plugins/community/repos/SubmarineFree/res/AO-136.svg new file mode 100644 index 00000000..0ac2c0a9 --- /dev/null +++ b/plugins/community/repos/SubmarineFree/res/AO-136.svg @@ -0,0 +1,823 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/community/repos/SubmarineFree/res/Components/sub_knob_large.svg b/plugins/community/repos/SubmarineFree/res/Components/sub_knob_large.svg deleted file mode 100644 index 36fe70c8..00000000 --- a/plugins/community/repos/SubmarineFree/res/Components/sub_knob_large.svg +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - diff --git a/plugins/community/repos/SubmarineFree/res/Components/sub_knob_large_a.svg b/plugins/community/repos/SubmarineFree/res/Components/sub_knob_large_a.svg deleted file mode 100644 index dc3aaf68..00000000 --- a/plugins/community/repos/SubmarineFree/res/Components/sub_knob_large_a.svg +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - diff --git a/plugins/community/repos/SubmarineFree/res/Components/sub_knob_med.svg b/plugins/community/repos/SubmarineFree/res/Components/sub_knob_med.svg deleted file mode 100644 index 5e0a882e..00000000 --- a/plugins/community/repos/SubmarineFree/res/Components/sub_knob_med.svg +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - diff --git a/plugins/community/repos/SubmarineFree/res/Components/sub_knob_med_a.svg b/plugins/community/repos/SubmarineFree/res/Components/sub_knob_med_a.svg deleted file mode 100644 index 85058fa8..00000000 --- a/plugins/community/repos/SubmarineFree/res/Components/sub_knob_med_a.svg +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - diff --git a/plugins/community/repos/SubmarineFree/res/Components/sub_knob_small.svg b/plugins/community/repos/SubmarineFree/res/Components/sub_knob_small.svg deleted file mode 100644 index 8374f96e..00000000 --- a/plugins/community/repos/SubmarineFree/res/Components/sub_knob_small.svg +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - diff --git a/plugins/community/repos/SubmarineFree/res/Components/sub_knob_small_a.svg b/plugins/community/repos/SubmarineFree/res/Components/sub_knob_small_a.svg deleted file mode 100644 index e0dedda0..00000000 --- a/plugins/community/repos/SubmarineFree/res/Components/sub_knob_small_a.svg +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - diff --git a/plugins/community/repos/SubmarineFree/res/EO-102.svg b/plugins/community/repos/SubmarineFree/res/EO-102.svg new file mode 100644 index 00000000..c5a47552 --- /dev/null +++ b/plugins/community/repos/SubmarineFree/res/EO-102.svg @@ -0,0 +1,649 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/community/repos/SubmarineFree/res/FF-206.svg b/plugins/community/repos/SubmarineFree/res/FF-206.svg new file mode 100644 index 00000000..6c243796 --- /dev/null +++ b/plugins/community/repos/SubmarineFree/res/FF-206.svg @@ -0,0 +1,108 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/community/repos/SubmarineFree/res/LD-103.svg b/plugins/community/repos/SubmarineFree/res/LD-103.svg new file mode 100644 index 00000000..944d9fa4 --- /dev/null +++ b/plugins/community/repos/SubmarineFree/res/LD-103.svg @@ -0,0 +1,145 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/plugins/community/repos/SubmarineFree/res/NG-106.svg b/plugins/community/repos/SubmarineFree/res/NG-106.svg new file mode 100644 index 00000000..9dabce81 --- /dev/null +++ b/plugins/community/repos/SubmarineFree/res/NG-106.svg @@ -0,0 +1,104 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/community/repos/SubmarineFree/res/OG-104.svg b/plugins/community/repos/SubmarineFree/res/OG-104.svg new file mode 100644 index 00000000..131190dd --- /dev/null +++ b/plugins/community/repos/SubmarineFree/res/OG-104.svg @@ -0,0 +1,100 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/plugins/community/repos/SubmarineFree/res/PG-104.svg b/plugins/community/repos/SubmarineFree/res/PG-104.svg new file mode 100644 index 00000000..b7fb29d5 --- /dev/null +++ b/plugins/community/repos/SubmarineFree/res/PG-104.svg @@ -0,0 +1,96 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/plugins/community/repos/SubmarineFree/res/SS-112.svg b/plugins/community/repos/SubmarineFree/res/SS-112.svg new file mode 100644 index 00000000..053e9e53 --- /dev/null +++ b/plugins/community/repos/SubmarineFree/res/SS-112.svg @@ -0,0 +1,76 @@ + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/plugins/community/repos/SubmarineFree/res/SS-208.svg b/plugins/community/repos/SubmarineFree/res/SS-208.svg new file mode 100644 index 00000000..f5a326ba --- /dev/null +++ b/plugins/community/repos/SubmarineFree/res/SS-208.svg @@ -0,0 +1,165 @@ + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/plugins/community/repos/SubmarineFree/res/SS-212.svg b/plugins/community/repos/SubmarineFree/res/SS-212.svg new file mode 100644 index 00000000..4147c199 --- /dev/null +++ b/plugins/community/repos/SubmarineFree/res/SS-212.svg @@ -0,0 +1,104 @@ + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/plugins/community/repos/SubmarineFree/res/SS-220.svg b/plugins/community/repos/SubmarineFree/res/SS-220.svg new file mode 100644 index 00000000..f67f4a99 --- /dev/null +++ b/plugins/community/repos/SubmarineFree/res/SS-220.svg @@ -0,0 +1,153 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/plugins/community/repos/SubmarineFree/res/SS-221.svg b/plugins/community/repos/SubmarineFree/res/SS-221.svg new file mode 100644 index 00000000..9ba5787c --- /dev/null +++ b/plugins/community/repos/SubmarineFree/res/SS-221.svg @@ -0,0 +1,414 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/community/repos/SubmarineFree/res/TD-116.svg b/plugins/community/repos/SubmarineFree/res/TD-116.svg new file mode 100644 index 00000000..4337fa87 --- /dev/null +++ b/plugins/community/repos/SubmarineFree/res/TD-116.svg @@ -0,0 +1,181 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/community/repos/SubmarineFree/res/TD-202.svg b/plugins/community/repos/SubmarineFree/res/TD-202.svg new file mode 100644 index 00000000..0911b5ae --- /dev/null +++ b/plugins/community/repos/SubmarineFree/res/TD-202.svg @@ -0,0 +1,81 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/plugins/community/repos/SubmarineFree/res/TF-101.svg b/plugins/community/repos/SubmarineFree/res/TF-101.svg new file mode 100644 index 00000000..bbbcfc0a --- /dev/null +++ b/plugins/community/repos/SubmarineFree/res/TF-101.svg @@ -0,0 +1,329 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/community/repos/SubmarineFree/res/TM-105.svg b/plugins/community/repos/SubmarineFree/res/TM-105.svg new file mode 100644 index 00000000..2867cabd --- /dev/null +++ b/plugins/community/repos/SubmarineFree/res/TM-105.svg @@ -0,0 +1,109 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/community/repos/SubmarineFree/res/XG-104.svg b/plugins/community/repos/SubmarineFree/res/XG-104.svg new file mode 100644 index 00000000..90e488ad --- /dev/null +++ b/plugins/community/repos/SubmarineFree/res/XG-104.svg @@ -0,0 +1,100 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/plugins/community/repos/SubmarineFree/src/AG-106.cpp b/plugins/community/repos/SubmarineFree/src/AG-106.cpp deleted file mode 100644 index 5a2040aa..00000000 --- a/plugins/community/repos/SubmarineFree/src/AG-106.cpp +++ /dev/null @@ -1,91 +0,0 @@ -#include "DS.hpp" - -namespace rack_plugin_SubmarineFree { - -struct AG_106 : DS_Module { - static const int deviceCount = 6; - enum ParamIds { - NUM_PARAMS - }; - enum InputIds { - INPUT_A_1, - INPUT_A_2, - INPUT_A_3, - INPUT_A_4, - INPUT_A_5, - INPUT_A_6, - INPUT_B_1, - INPUT_B_2, - INPUT_B_3, - INPUT_B_4, - INPUT_B_5, - INPUT_B_6, - NUM_INPUTS - }; - enum OutputIds { - OUTPUT_1, - OUTPUT_2, - OUTPUT_3, - OUTPUT_4, - OUTPUT_5, - OUTPUT_6, - NUM_OUTPUTS - }; - enum LightIds { - NUM_LIGHTS - }; - - AG_106() : DS_Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} - void step() override; -}; - -void AG_106::step() { - int connCount = 0; - int setCount = 0; - for (int i = 0; i < deviceCount; i++) { - if (inputs[INPUT_A_1 + i].active) { - connCount++; - if (inputs[INPUT_A_1 + i].value > midpoint()) - setCount++; - } - if (inputs[INPUT_B_1 + i].active) { - connCount++; - if (inputs[INPUT_B_1 + i].value > midpoint()) - setCount++; - } - if (outputs[OUTPUT_1 + i].active) { - if (connCount) - outputs[OUTPUT_1 + i].value = (connCount == setCount)?voltage1:voltage0; - else - outputs[OUTPUT_1 + i].value = voltage0; - connCount = 0; - setCount = 0; - } - } -} - -struct AG106 : ModuleWidget { - AG106(AG_106 *module) : ModuleWidget(module) { - setPanel(SVG::load(assetPlugin(plugin, "res/AG-106.svg"))); - - for (int i = 0; i < AG_106::deviceCount; i++) { - int offset = 58 * i; - addInput(Port::create(Vec(4,19 + offset), Port::INPUT, module, AG_106::INPUT_A_1 + i)); - addInput(Port::create(Vec(4,47 + offset), Port::INPUT, module, AG_106::INPUT_B_1 + i)); - - addOutput(Port::create(Vec(62,33 + offset), Port::OUTPUT, module, AG_106::OUTPUT_1 + i)); - } - } - void appendContextMenu(Menu *menu) override { - ((DS_Module *)module)->appendContextMenu(menu); - } -}; - -} // namespace rack_plugin_SubmarineFree - -using namespace rack_plugin_SubmarineFree; - -RACK_PLUGIN_MODEL_INIT(SubmarineFree, AG106) { - Model *modelAG106 = Model::create("SubmarineFree", "AG-106", "AG-106 AND Gates", LOGIC_TAG, MULTIPLE_TAG); - return modelAG106; -} diff --git a/plugins/community/repos/SubmarineFree/src/AG1.cpp b/plugins/community/repos/SubmarineFree/src/AG1.cpp new file mode 100644 index 00000000..12e3d410 --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/AG1.cpp @@ -0,0 +1,97 @@ +#include "DS.hpp" + +namespace rack_plugin_SubmarineFree { + +template +struct AG_1 : DS_Module { + enum ParamIds { + NUM_PARAMS + }; + enum InputIds { + INPUT_A_1, + INPUT_B_1 = x, + NUM_INPUTS = x + x + }; + enum OutputIds { + OUTPUT_1, + NUM_OUTPUTS = x + }; + enum LightIds { + NUM_LIGHTS + }; + + AG_1() : DS_Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} + + void step() override { + int connCount = 0; + int setCount = 0; + for (int i = 0; i < x; i++) { + if (inputs[INPUT_A_1 + i].active) { + connCount++; + if (inputs[INPUT_A_1 + i].value > midpoint()) + setCount++; + } + if (inputs[INPUT_B_1 + i].active) { + connCount++; + if (inputs[INPUT_B_1 + i].value > midpoint()) + setCount++; + } + if (outputs[OUTPUT_1 + i].active) { + if (connCount) + outputs[OUTPUT_1 + i].value = (connCount == setCount)?voltage1:voltage0; + else + outputs[OUTPUT_1 + i].value = voltage0; + connCount = 0; + setCount = 0; + } + } + } +}; + +struct AG104 : ModuleWidget { + AG104(AG_1<4> *module) : ModuleWidget(module) { + setPanel(SVG::load(assetPlugin(plugin, "res/AG-104.svg"))); + + for (int i = 0; i < 4; i++) { + int offset = 87 * i; + addInput(Port::create(Vec(2.5,19 + offset), Port::INPUT, module, AG_1<4>::INPUT_A_1 + i)); + addInput(Port::create(Vec(2.5,47 + offset), Port::INPUT, module, AG_1<4>::INPUT_B_1 + i)); + + addOutput(Port::create(Vec(2.5,75 + offset), Port::OUTPUT, module, AG_1<4>::OUTPUT_1 + i)); + } + } + void appendContextMenu(Menu *menu) override { + ((DS_Module *)module)->appendContextMenu(menu); + } +}; + +struct AG106 : ModuleWidget { + AG106(AG_1<6> *module) : ModuleWidget(module) { + setPanel(SVG::load(assetPlugin(plugin, "res/AG-106.svg"))); + + for (int i = 0; i < 6; i++) { + int offset = 58 * i; + addInput(Port::create(Vec(4,19 + offset), Port::INPUT, module, AG_1<6>::INPUT_A_1 + i)); + addInput(Port::create(Vec(4,47 + offset), Port::INPUT, module, AG_1<6>::INPUT_B_1 + i)); + + addOutput(Port::create(Vec(62,33 + offset), Port::OUTPUT, module, AG_1<6>::OUTPUT_1 + i)); + } + } + void appendContextMenu(Menu *menu) override { + ((DS_Module *)module)->appendContextMenu(menu); + } +}; + +} // namespace rack_plugin_SubmarineFree + +using namespace rack_plugin_SubmarineFree; + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, AG104) { + Model *modelAG104 = Model::create, AG104>("Submarine (Free)", "AG-104", "AG-104 AND Gates", LOGIC_TAG, MULTIPLE_TAG); + return modelAG104; +} + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, AG106) { + Model *modelAG106 = Model::create, AG106>("Submarine (Free)", "AG-106", "AG-106 AND Gates", LOGIC_TAG, MULTIPLE_TAG); + return modelAG106; +} diff --git a/plugins/community/repos/SubmarineFree/src/AO1.cpp b/plugins/community/repos/SubmarineFree/src/AO1.cpp new file mode 100644 index 00000000..89e4b69d --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/AO1.cpp @@ -0,0 +1,449 @@ +#include "SubmarineFree.hpp" + +namespace rack_plugin_SubmarineFree { + +namespace SubmarineAO { + + typedef float (*func_t)(float, float, float); + + struct Functor { + std::string name; + func_t func; + }; + +#define sMIN(a,b) (((a)>(b))?(b):(a)) +#define sMAX(a,b) (((a)>(b))?(a):(b)) + +#define LAMBDA(e) [](float x, float y, float c)->float { return e ; } +#define X "X" // X +#define Y "Y" // Y +#define C "C" // C +#define A "+" // Addition symbol +#define S "-" // Subtraction symbol +#define O "%" // Modulo symbol +#define OP "(" // Open Parenthesis +#define CP ")" // Close Parenthesis +#define P "|" // Pipe symbol +#define M "\xe2\xa8\xaf" +#define D "\xc3\xb7" // Division symbol +#define R "\xe2\x88\x9a" // Root symbol +#define S2 "\xc2\xb2" // Superscript 2 +#define S3 "\xc2\xb3" // Superscript 3 +#define s0 "\xe2\x82\x80" // Subscript 0 +#define s1 "\xe2\x82\x81" // Subscript 1 +#define s2 "\xe2\x82\x82" // Subscript 2 +#define E "\xe2\x84\xaf" // e +#define SA "\xe2\x81\xba" // Superscript + +#define SX "\xcb\xa3" // Superscript x +#define SY "\xca\xb8" // Superscript y +#define SC "\xe1\xb6\x9c" // Superscript c +#define MIN "min" // Minimum function +#define MAX "max" // Maximum function +#define COMMA "," // Comma symbol +#define SIN "sin" // sine function +#define COS "cos" // cosine function +#define TAN "tan" // tangent function +#define ASIN "asin" // arcsine function +#define ACOS "acos" // arcosine function +#define ATAN "atan" // arctangent function +#define LOG "log" // log function +#define LOG2 LOG s2 // base-2 log function +#define LOG10 LOG s1 s0 // base-10 log function +#define IF "if " // if conditional +#define G ">" // Greater Than symbol +#define L "<" // Less Than symbol +#define Q "=" // Equality symbol +#define Z "0" // Zero +#define W "1" // One +#define T "\xe2\x86\xa3" // Right arrow +#define H "/" // Slash +#define Pi "\xcf\x80" // PI +#define TAU "\xcf\x84" // TAU + + std::vector functions { + { "", LAMBDA( 0 ) }, // Passthrough + { C, LAMBDA( c ) }, // Addition + { X A C, LAMBDA( x + c ) }, + { Y A C, LAMBDA( y + c ) }, + { X A Y A C, LAMBDA( x + y + c ) }, + { C S X, LAMBDA( c - x ) }, // Subtraction + { C S Y, LAMBDA( c - y ) }, + { X S OP Y A C CP, LAMBDA( x - ( y + c ) ) }, + { OP X A C CP S Y, LAMBDA( ( x + c ) - y ) }, + { Y S OP X A C CP, LAMBDA( y - ( x + c ) ) }, + { OP Y A C CP S X, LAMBDA( ( y + c ) - x ) }, + { OP X M Y CP A C, LAMBDA( ( x * y ) + c ) }, // Multiplication + { OP X A C CP M Y, LAMBDA( ( x + c ) * y ) }, + { X M OP Y A C CP, LAMBDA( x * ( y + c ) ) }, + { X M C, LAMBDA( x * c ) }, + { Y M C, LAMBDA( y * c ) }, + { X M Y M C, LAMBDA( x * y * c ) }, + { Pi M OP X A C CP, LAMBDA( M_PI * ( x + c ) ) }, + { Pi M OP Y A C CP, LAMBDA( M_PI * ( y + c ) ) }, + { TAU M OP X A C CP, LAMBDA( 2 * M_PI * ( x + c ) ) }, + { TAU M OP Y A C CP, LAMBDA( 2 * M_PI * ( y + c ) ) }, + { X D C, LAMBDA( x / c ) }, // Division + { C D X, LAMBDA( c / x ) }, + { Y D C, LAMBDA( y / c ) }, + { C D Y, LAMBDA( c / y ) }, + { C A OP X D Y CP, LAMBDA( c + ( x / y ) ) }, + { C A OP Y D X CP, LAMBDA( c + ( y / x ) ) }, + { X A OP Y D C CP, LAMBDA( x + ( y / c ) ) }, + { X A OP C D Y CP, LAMBDA( x + ( c / y ) ) }, + { Y A OP X D C CP, LAMBDA( y + ( x / c ) ) }, + { Y A OP C D X CP, LAMBDA( y + ( c / x ) ) }, + { OP X A C CP D Y, LAMBDA( ( x + c ) / y ) }, + { X D OP Y A C CP, LAMBDA( x / ( y + c ) ) }, + { OP Y A C CP D X, LAMBDA( ( y + c ) / x ) }, + { Y D OP X A C CP, LAMBDA( y / ( x + c ) ) }, + { OP X A C CP O Y, LAMBDA( fmodf( x + c , y ) ) }, // Modulo + { OP Y A C CP O X, LAMBDA( fmodf( y + c , x ) ) }, + { X O OP Y A C CP, LAMBDA( fmodf( x , y + c ) ) }, + { Y O OP X A C CP, LAMBDA( fmodf( y , x + c) ) }, + { X O C, LAMBDA( fmodf( x , c ) ) }, + { Y O C, LAMBDA( fmodf( y , c ) ) }, + { X S2 A C, LAMBDA( x * x + c ) }, // Quadratic + { Y S2 A C, LAMBDA( y * y + c ) }, + { OP X A C CP S2, LAMBDA( ( x + c ) * ( x + c ) ) }, + { OP Y A C CP S2, LAMBDA( ( y + c ) * ( y + c ) ) }, + { X S2 A Y A C, LAMBDA( x * x + y + c ) }, + { Y S2 A X A C, LAMBDA( y * y + x + c ) }, + { X S2 A C Y, LAMBDA( x * x + c * y ) }, + { Y S2 A C X, LAMBDA( y * y + c * x ) }, + { R OP X A C CP, LAMBDA( sqrt( x + c ) ) }, // Square Root + { R OP Y A C CP, LAMBDA( sqrt( y + c ) ) }, + { C SX, LAMBDA( powf( c , x ) ) }, // Powers + { C SY, LAMBDA( powf( c , y ) ) }, + { C SX SA SY, LAMBDA( powf( c , x + y ) ) }, + { C SX SY, LAMBDA( powf( c , x * y ) ) }, + { X SC, LAMBDA( powf( x , c ) ) }, + { Y SC, LAMBDA( powf( y , c ) ) }, + { X SY SA SC, LAMBDA( powf( x , y + c ) ) }, + { Y SX SA SC, LAMBDA( powf( y , x + c ) ) }, + { X SC SY, LAMBDA( powf( x , c * y ) ) }, + { Y SC SX, LAMBDA( powf( y , c * x ) ) }, + { P X A C P, LAMBDA( abs( x + c ) ) }, // Modulus + { P Y A C P, LAMBDA( abs( y + c ) ) }, + { MIN OP X A C COMMA Y CP, LAMBDA( sMIN( x + c, y ) ) }, // Minmax + { MIN OP X COMMA C CP, LAMBDA( sMIN( x, c ) ) }, + { MIN OP Y COMMA C CP, LAMBDA( sMIN( y, c ) ) }, + { MAX OP X A C COMMA Y CP, LAMBDA( sMAX( x + c, y ) ) }, + { MAX OP X COMMA C CP, LAMBDA( sMAX( x, c ) ) }, + { MAX OP Y COMMA C CP, LAMBDA( sMAX( y, c ) ) }, + { SIN OP X A C CP, LAMBDA( sin( x + c ) ) }, // Trigonometric + { SIN OP Y A C CP, LAMBDA( sin( y + c ) ) }, + { SIN OP X A Y CP, LAMBDA( sin( x + y ) ) }, + { SIN OP C X CP, LAMBDA( sin( c * x ) ) }, + { SIN OP C Y CP, LAMBDA( sin( c * y ) ) }, + { SIN OP X Y CP, LAMBDA( sin( x * y ) ) }, + { COS OP X A C CP, LAMBDA( cos( x + c ) ) }, + { COS OP Y A C CP, LAMBDA( cos( y + c ) ) }, + { COS OP X A Y CP, LAMBDA( cos( x + y ) ) }, + { COS OP C X CP, LAMBDA( cos( c * x ) ) }, + { COS OP C Y CP, LAMBDA( cos( c * y ) ) }, + { COS OP X Y CP, LAMBDA( cos( x * y ) ) }, + { TAN OP X A C CP, LAMBDA( tan( x + c ) ) }, + { TAN OP Y A C CP, LAMBDA( tan( y + c ) ) }, + { TAN OP X A Y CP, LAMBDA( tan( x + y ) ) }, + { TAN OP C X CP, LAMBDA( tan( c * x ) ) }, + { TAN OP C Y CP, LAMBDA( tan( c * y ) ) }, + { TAN OP X Y CP, LAMBDA( tan( x * y ) ) }, + { ASIN OP X A C CP, LAMBDA( asin( x + c ) ) }, + { ASIN OP Y A C CP, LAMBDA( asin( y + c ) ) }, + { ASIN OP X A Y CP, LAMBDA( asin( x + y ) ) }, + { ASIN OP C X CP, LAMBDA( asin( c * x ) ) }, + { ASIN OP C Y CP, LAMBDA( asin( c * y ) ) }, + { ASIN OP X Y CP, LAMBDA( asin( x * y ) ) }, + { ACOS OP X A C CP, LAMBDA( acos( x + c ) ) }, + { ACOS OP Y A C CP, LAMBDA( acos( y + c ) ) }, + { ACOS OP X A Y CP, LAMBDA( acos( x + y ) ) }, + { ACOS OP C X CP, LAMBDA( acos( c * x ) ) }, + { ACOS OP C Y CP, LAMBDA( acos( c * y ) ) }, + { ACOS OP X Y CP, LAMBDA( acos( x * y ) ) }, + { ATAN OP X A C CP, LAMBDA( atan( x + c ) ) }, + { ATAN OP Y A C CP, LAMBDA( atan( y + c ) ) }, + { ATAN OP X A Y CP, LAMBDA( atan( x + y ) ) }, + { ATAN OP C X CP, LAMBDA( atan( c * x ) ) }, + { ATAN OP C Y CP, LAMBDA( atan( c * y ) ) }, + { ATAN OP X Y CP, LAMBDA( atan( x * y ) ) }, + { LOG OP X A C CP, LAMBDA( log( x + c ) ) }, // Logarithmic + { LOG OP Y A C CP, LAMBDA( log( y + c ) ) }, + { LOG2 OP X A C CP, LAMBDA( log2( x + c ) ) }, + { LOG2 OP Y A C CP, LAMBDA( log2( y + c ) ) }, + { LOG10 OP X A C CP, LAMBDA( log10( x + c ) ) }, + { LOG10 OP Y A C CP, LAMBDA( log10( y + c ) ) }, + { E SX SA SC, LAMBDA( exp( x + c ) ) }, // Exponential + { E SY SA SC, LAMBDA( exp( y + c ) ) }, + { E SC SX, LAMBDA( exp( c * x ) ) }, + { E SC SY, LAMBDA( exp( c * y ) ) }, + { "2" SX SA SC, LAMBDA( powf( 2, x + c ) ) }, + { "2" SY SA SC, LAMBDA( powf( 2, y + c ) ) }, + { "2" SC SX, LAMBDA( powf( 2, c * x ) ) }, + { "2" SC SY, LAMBDA( powf( 2, c * y ) ) }, + { "10" SX SA SC, LAMBDA( powf( 10, x + c ) ) }, + { "10" SY SA SC, LAMBDA( powf( 10, y + c ) ) }, + { "10" SC SX, LAMBDA( powf( 10, c * x ) ) }, + { "10" SC SY, LAMBDA( powf( 10, c * y ) ) }, + + { IF X G Z T Y H C, LAMBDA( (x > 0) ? y : c ) }, // Conditional + { IF X L Z T Y H C, LAMBDA( (x < 0) ? y : c ) }, + { IF X Q Z T Y H C, LAMBDA( (x == 0) ? y : c ) }, + { IF X G Z T C H Y, LAMBDA( (x > 0) ? c : y ) }, + { IF X L Z T C H Y, LAMBDA( (x < 0) ? c : y ) }, + { IF X Q Z T C H Y, LAMBDA( (x == 0) ? c : y ) }, + { IF X G Z T W H Z, LAMBDA( (x > 0) ? 1 : 0 ) }, + { IF X L Z T W H Z, LAMBDA( (x < 0) ? 1 : 0 ) }, + { IF X Q Z T W H Z, LAMBDA( (x == 0) ? 1 : 0 ) }, + { IF X G Z T X H C, LAMBDA( (x > 0) ? x : c ) }, + { IF X L Z T X H C, LAMBDA( (x < 0) ? x : c ) }, + { IF X Q Z T X H C, LAMBDA( (x == 0) ? x : c ) }, + { IF X G Z T C H X, LAMBDA( (x > 0) ? c : x ) }, + { IF X L Z T C H X, LAMBDA( (x < 0) ? c : x ) }, + { IF X Q Z T C H X, LAMBDA( (x == 0) ? c : x ) }, + + { IF Y G Z T X H C, LAMBDA( (y > 0) ? x : c ) }, + { IF Y L Z T X H C, LAMBDA( (y < 0) ? x : c ) }, + { IF Y Q Z T X H C, LAMBDA( (y == 0) ? x : c ) }, + { IF Y G Z T C H X, LAMBDA( (y > 0) ? c : x ) }, + { IF Y L Z T C H X, LAMBDA( (y < 0) ? c : x ) }, + { IF Y Q Z T C H X, LAMBDA( (y == 0) ? c : x ) }, + { IF Y G Z T W H Z, LAMBDA( (y > 0) ? 1 : 0 ) }, + { IF Y L Z T W H Z, LAMBDA( (y < 0) ? 1 : 0 ) }, + { IF Y Q Z T W H Z, LAMBDA( (y == 0) ? 1 : 0 ) }, + { IF Y G Z T Y H C, LAMBDA( (y > 0) ? y : c ) }, + { IF Y L Z T Y H C, LAMBDA( (y < 0) ? y : c ) }, + { IF Y Q Z T Y H C, LAMBDA( (y == 0) ? y : c ) }, + { IF Y G Z T C H Y, LAMBDA( (y > 0) ? c : y ) }, + { IF Y L Z T C H Y, LAMBDA( (y < 0) ? c : y ) }, + { IF Y Q Z T C H Y, LAMBDA( (y == 0) ? c : y ) }, + + { IF X G Y T C H Z, LAMBDA( (x > y) ? c : 0 ) }, + { IF X L Y T C H Z, LAMBDA( (x < y) ? c : 0 ) }, + { IF X Q Y T C H Z, LAMBDA( (x == y) ? c : 0 ) }, + { IF Y G X T C H Z, LAMBDA( (y > x) ? c : 0 ) }, + { IF Y L X T C H Z, LAMBDA( (y < x) ? c : 0 ) }, + { IF X G Y T X H Z, LAMBDA( (x > y) ? x : 0 ) }, + { IF X L Y T X H Z, LAMBDA( (x < y) ? x : 0 ) }, + { IF X Q Y T X H Z, LAMBDA( (x == y) ? x : 0 ) }, + { IF Y G X T X H Z, LAMBDA( (y > x) ? x : 0 ) }, + { IF Y L X T X H Z, LAMBDA( (y < x) ? x : 0 ) }, + { IF X G Y T Y H Z, LAMBDA( (x > y) ? y : 0 ) }, + { IF X L Y T Y H Z, LAMBDA( (x < y) ? y : 0 ) }, + { IF X Q Y T Y H Z, LAMBDA( (x == y) ? y : 0 ) }, + { IF Y G X T Y H Z, LAMBDA( (y > x) ? y : 0 ) }, + { IF Y L X T Y H Z, LAMBDA( (y < x) ? y : 0 ) }, + + { IF X G C T Y H Z, LAMBDA( (x > c) ? y : 0 ) }, + { IF X L C T Y H Z, LAMBDA( (x < c) ? y : 0 ) }, + { IF X Q C T Y H Z, LAMBDA( (x == c) ? y : 0 ) }, + { IF C G X T Y H Z, LAMBDA( (c > x) ? y : 0 ) }, + { IF C L X T Y H Z, LAMBDA( (c < x) ? y : 0 ) }, + { IF X G C T X H Z, LAMBDA( (x > c) ? x : 0 ) }, + { IF X L C T X H Z, LAMBDA( (x < c) ? x : 0 ) }, + { IF X Q C T X H Z, LAMBDA( (x == c) ? x : 0 ) }, + { IF C G X T X H Z, LAMBDA( (c > x) ? x : 0 ) }, + { IF C L X T X H Z, LAMBDA( (c < x) ? x : 0 ) }, + { IF X G C T X H Y, LAMBDA( (x > c) ? x : y ) }, + { IF X L C T X H Y, LAMBDA( (x < c) ? x : y ) }, + { IF X Q C T X H Y, LAMBDA( (x == c) ? x : y ) }, + { IF C G X T X H Y, LAMBDA( (c > x) ? x : y ) }, + { IF C L X T X H Y, LAMBDA( (c < x) ? x : y ) }, + + { IF Y G C T X H Z, LAMBDA( (y > c) ? x : 0 ) }, + { IF Y L C T X H Z, LAMBDA( (y < c) ? x : 0 ) }, + { IF Y Q C T X H Z, LAMBDA( (y == c) ? x : 0 ) }, + { IF C G Y T X H Z, LAMBDA( (c > y) ? x : 0 ) }, + { IF C L Y T X H Z, LAMBDA( (c < y) ? x : 0 ) }, + { IF Y G C T Y H Z, LAMBDA( (y > c) ? y : 0 ) }, + { IF Y L C T Y H Z, LAMBDA( (y < c) ? y : 0 ) }, + { IF Y Q C T Y H Z, LAMBDA( (y == c) ? y : 0 ) }, + { IF C G Y T Y H Z, LAMBDA( (c > y) ? y : 0 ) }, + { IF C L Y T Y H Z, LAMBDA( (c < y) ? y : 0 ) }, + { IF Y G C T Y H X, LAMBDA( (y > c) ? y : x ) }, + { IF Y L C T Y H X, LAMBDA( (y < c) ? y : x ) }, + { IF Y Q C T Y H X, LAMBDA( (y == c) ? y : x ) }, + { IF C G Y T Y H X, LAMBDA( (c > y) ? y : x ) }, + { IF C L Y T Y H X, LAMBDA( (c < y) ? y : x ) }, + + }; + +#undef X +#undef Y +#undef C +#undef A +#undef S +#undef O +#undef OP +#undef CP +#undef P +#undef M +#undef D +#undef R +#undef S2 +#undef S3 +#undef s0 +#undef s1 +#undef s2 +#undef E +#undef SA +#undef SX +#undef SY +#undef SC +#undef COMMA +#undef MIN +#undef MAX +#undef SIN +#undef COS +#undef TAN +#undef ASIN +#undef ACOS +#undef ATAN +#undef LOG +#undef LOG2 +#undef LOG10 +#undef IF +#undef G +#undef L +#undef Q +#undef Z +#undef W +#undef T +#undef H +#undef Pi +#undef TAU + +} // end namespace SubmarineA0 + +struct AOFuncDisplay : Knob { + std::shared_ptr font; + AOFuncDisplay() { + box.size.x = 80; + box.size.y = 15; + snap = true; + smooth = false; + speed = 0.5f; + font = Font::load(assetGlobal("res/fonts/DejaVuSans.ttf")); + } + void draw(NVGcontext *vg) override { + nvgFontSize(vg, 16); + nvgFontFaceId(vg, font->handle); + nvgFillColor(vg, nvgRGBA(0x28, 0xb0, 0xf3, 0xff)); + nvgTextAlign(vg, NVG_ALIGN_CENTER); + nvgText(vg, 41.5, 13, SubmarineAO::functions[value].name.c_str(), NULL); + } +}; + +struct AOConstDisplay : Knob { + std::shared_ptr font; + AOConstDisplay() { + box.size.x = 80; + box.size.y = 15; + snap = true; + speed = 0.005; + font = Font::load(assetGlobal("res/fonts/DejaVuSans.ttf")); + } + void draw(NVGcontext *vg) override { + char mtext[41]; + sprintf(mtext, "C=%4.2f", ((int)value)/100.0f); + nvgFontSize(vg, 16); + nvgFontFaceId(vg, font->handle); + nvgFillColor(vg, nvgRGBA(0x28, 0xb0, 0xf3, 0xff)); + nvgTextAlign(vg, NVG_ALIGN_CENTER); + nvgText(vg, 41.5, 13, mtext, NULL); + } +}; + +template +struct AO1 : Module { + enum ParamIds { + PARAM_FUNC_1, + PARAM_CONST_1 = x * y, + NUM_PARAMS = 2 * x * y + }; + enum InputIds { + INPUT_X_1, + INPUT_Y_1 = x, + NUM_INPUTS = x + y + }; + enum OutputIds { + OUTPUT_X_1, + OUTPUT_Y_1 = x, + NUM_OUTPUTS = x + y + }; + enum LightIds { + NUM_LIGHTS + }; + + AO1() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} + void step() override { + float vx[x]; + for (unsigned int ix = 0; ix < x; ix++) { + vx[ix] = inputs[INPUT_X_1 + ix].value; + } + for (unsigned int iy = 0; iy < y; iy++) { + float vy = inputs[INPUT_Y_1 + iy].value; + for (unsigned int ix = 0; ix < x; ix++) { + unsigned int f = params[PARAM_FUNC_1 + ix + iy * x].value; + if (f >= SubmarineAO::functions.size()) + f = SubmarineAO::functions.size() - 1; + if (f > 0) + vy = vx[ix] = SubmarineAO::functions[f].func(vx[ix], vy, ((int)params[PARAM_CONST_1 + ix + iy * x].value)/100.0f); + // if f is equal to 0, then both x and y pass (crossing) through the module unchanged. + } + outputs[OUTPUT_Y_1 + iy].value = std::isfinite(vy)?vy:0.0f; + } + for (unsigned int ix = 0; ix < x; ix++) { + outputs[OUTPUT_X_1 + ix].value = std::isfinite(vx[ix])?vx[ix]:0.0f; + } + } +}; + +template +struct AOWidget : ModuleWidget { + AOWidget(AO1 *module) : ModuleWidget(module) { + setPanel(SubHelper::LoadPanel(plugin, "AO-1", x*y)); + for (unsigned int ix = 0; ix < x; ix++) { + addInput(Port::create(Vec(4, 61 + ix * 46), Port::INPUT, module, AO1::INPUT_X_1 + ix)); + addOutput(Port::create(Vec(46 + y * 90, 61 + ix * 46), Port::OUTPUT, module, AO1::OUTPUT_X_1 + ix)); + } + for (unsigned int iy = 0; iy < y; iy++) { + addInput(Port::create(Vec(70 + 90 * iy, 19), Port::INPUT, module, AO1::INPUT_Y_1 + iy)); + addOutput(Port::create(Vec(70 + 90 * iy, 335), Port::OUTPUT, module, AO1::OUTPUT_Y_1 + iy)); + } + for (unsigned int iy = 0; iy < y; iy++) { + for (unsigned int ix = 0; ix < x; ix++) { + addParam(ParamWidget::create(Vec(42.5 + 90 * iy, 59 + 46 * ix), module, AO1::PARAM_FUNC_1 + ix + iy * x, 0.0f, SubmarineAO::functions.size() - 1.0f, 0.0f )); + addParam(ParamWidget::create(Vec(42.5 + 90 * iy, 78 + 46 * ix), module, AO1::PARAM_CONST_1 + ix + iy * x, -10000.0f, 10000.0f, 0.0f)); + } + } + } +}; + +} // namespace rack_plugin_SubmarineFree + +using namespace rack_plugin_SubmarineFree; + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, AO106) { + Model *modelAO106 = Model::create, AOWidget<6,1>>("Submarine (Free)", "A0-106", "A0-106 Arithmetic Operators", UTILITY_TAG, MULTIPLE_TAG); + return modelAO106; +} + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, AO112) { + Model *modelAO112 = Model::create, AOWidget<6,2>>("Submarine (Free)", "A0-112", "A0-112 Arithmetic Operators", UTILITY_TAG, MULTIPLE_TAG); + return modelAO112; +} + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, AO118) { + Model *modelAO118 = Model::create, AOWidget<6,3>>("Submarine (Free)", "A0-118", "A0-118 Arithmetic Operators", UTILITY_TAG, MULTIPLE_TAG); + return modelAO118; +} + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, AO124) { + Model *modelAO124 = Model::create, AOWidget<6,4>>("Submarine (Free)", "A0-124", "A0-124 Arithmetic Operators", UTILITY_TAG, MULTIPLE_TAG); + return modelAO124; +} + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, AO136) { + Model *modelAO136 = Model::create, AOWidget<6,6>>("Submarine (Free)", "A0-136", "A0-136 Arithmetic Operators", UTILITY_TAG, MULTIPLE_TAG); + return modelAO136; +} diff --git a/plugins/community/repos/SubmarineFree/src/BB-120.cpp b/plugins/community/repos/SubmarineFree/src/BB-120.cpp deleted file mode 100644 index 9b4cfc93..00000000 --- a/plugins/community/repos/SubmarineFree/src/BB-120.cpp +++ /dev/null @@ -1,89 +0,0 @@ -#include "DS.hpp" - -namespace rack_plugin_SubmarineFree { - -struct BB_120 : DS_Module { - static const int deviceCount = 20; - enum ParamIds { - NUM_PARAMS - }; - enum InputIds { - INPUT_CLK, - INPUT_CV, - NUM_INPUTS - }; - enum OutputIds { - OUTPUT_1, - OUTPUT_2, - OUTPUT_3, - OUTPUT_4, - OUTPUT_5, - OUTPUT_6, - OUTPUT_7, - OUTPUT_8, - OUTPUT_9, - OUTPUT_10, - OUTPUT_11, - OUTPUT_12, - OUTPUT_13, - OUTPUT_14, - OUTPUT_15, - OUTPUT_16, - OUTPUT_17, - OUTPUT_18, - OUTPUT_19, - OUTPUT_20, - NUM_OUTPUTS - }; - enum LightIds { - NUM_LIGHTS - }; - - float sample[deviceCount] = {}; - DS_Schmitt schmittTrigger; - - BB_120() : DS_Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} - void step() override; -}; - -void BB_120::step() { - int triggered = true; - if (inputs[INPUT_CLK].active) { - triggered = schmittTrigger.redge(this, inputs[INPUT_CLK].value); - } - if (triggered) { - for (int i = deviceCount - 1; i; i--) - sample[i] = sample[i - 1]; - sample[0] = inputs[INPUT_CV].value; - } - for (int i = 0; i < deviceCount; i++) - outputs[OUTPUT_1 + i].value = sample[i]; -} - -struct BB120 : ModuleWidget { - BB120(BB_120 *module) : ModuleWidget(module) { - setPanel(SVG::load(assetPlugin(plugin, "res/BB-120.svg"))); - - addInput(Port::create(Vec(4.5,19), Port::INPUT, module, BB_120::INPUT_CLK)); - addInput(Port::create(Vec(31.5,34), Port::INPUT, module, BB_120::INPUT_CV)); - - for (int i = 0; i < BB_120::deviceCount; i+=2) { - int offset = 15 * i; - - addOutput(Port::create(Vec(4,53 + offset), Port::OUTPUT, module, BB_120::OUTPUT_1 + i)); - addOutput(Port::create(Vec(31,68 + offset), Port::OUTPUT, module, BB_120::OUTPUT_1 + i + 1)); - } - } - void appendContextMenu(Menu *menu) override { - ((DS_Module *)module)->appendContextMenu(menu); - } -}; - -} // namespace rack_plugin_SubmarineFree - -using namespace rack_plugin_SubmarineFree; - -RACK_PLUGIN_MODEL_INIT(SubmarineFree, BB120) { - Model *modelBB120 = Model::create("SubmarineFree", "BB-120", "BB-120 20-Stage Bucket Brigade Sample and Hold", LOGIC_TAG, DELAY_TAG, SAMPLE_AND_HOLD_TAG, MULTIPLE_TAG); - return modelBB120; -} diff --git a/plugins/community/repos/SubmarineFree/src/BB1.cpp b/plugins/community/repos/SubmarineFree/src/BB1.cpp new file mode 100644 index 00000000..f59bc0ef --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/BB1.cpp @@ -0,0 +1,107 @@ +#include +#include +#include "DS.hpp" +#include +#include + +namespace rack_plugin_SubmarineFree { + +template +struct BB_1 : DS_Module { + int doResetFlag = 0; + int doRandomFlag = 0; + enum ParamIds { + NUM_PARAMS + }; + enum InputIds { + INPUT_CLK, + INPUT_CV, + NUM_INPUTS + }; + enum OutputIds { + OUTPUT_1, + NUM_OUTPUTS = x + }; + enum LightIds { + NUM_LIGHTS + }; + + float sample[x] = {}; + DS_Schmitt schmittTrigger; + + BB_1() : DS_Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} + void step() override { + if (doResetFlag) doReset(); + if (doRandomFlag) doRandomize(); + int triggered = true; + if (inputs[INPUT_CLK].active) { + triggered = schmittTrigger.redge(this, inputs[INPUT_CLK].value); + } + if (triggered) { + for (int i = x - 1; i; i--) + sample[i] = sample[i - 1]; + sample[0] = inputs[INPUT_CV].value; + } + for (int i = 0; i < x; i++) + outputs[OUTPUT_1 + i].value = sample[i]; + } + void doRandomize() { + doRandomFlag = 0; + std::default_random_engine generator(std::chrono::system_clock::now().time_since_epoch().count()); + std::uniform_real_distribution distribution(voltage0, voltage1); + for (int i = 0; i < x; i++) { + outputs[OUTPUT_1 + i].value = sample[i] = distribution(generator); + } + } + void doReset() { + doResetFlag = 0; + for (int i = 0; i < x; i++) + outputs[OUTPUT_1 + i].value = sample[i] = 0.0f; + } + void onRandomize() override { + if (rack::global->gPaused) { + doRandomize(); + } + else { + doResetFlag = 0; + doRandomFlag = 1; + } + } + void onReset() override { + if (rack::global->gPaused) { + doReset(); + } + else { + doRandomFlag = 0; + doResetFlag = 1; + } + } +}; + +struct BB120 : ModuleWidget { + BB120(BB_1<20> *module) : ModuleWidget(module) { + setPanel(SVG::load(assetPlugin(plugin, "res/BB-120.svg"))); + + addInput(Port::create(Vec(4.5,19), Port::INPUT, module, BB_1<20>::INPUT_CLK)); + addInput(Port::create(Vec(31.5,34), Port::INPUT, module, BB_1<20>::INPUT_CV)); + + for (int i = 0; i < 20; i+=2) { + int offset = 15 * i; + + addOutput(Port::create(Vec(4,53 + offset), Port::OUTPUT, module, BB_1<20>::OUTPUT_1 + i)); + addOutput(Port::create(Vec(31,68 + offset), Port::OUTPUT, module, BB_1<20>::OUTPUT_1 + i + 1)); + } + } + void appendContextMenu(Menu *menu) override { + ((DS_Module *)module)->appendContextMenu(menu); + } +}; + +} // namespace rack_plugin_SubmarineFree + +using namespace rack_plugin_SubmarineFree; + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, BB120) { + Model *modelBB120 = Model::create, BB120>("Submarine (Free)", "BB-120", "BB-120 20-Stage Bucket Brigade Sample and Hold", LOGIC_TAG, DELAY_TAG, SAMPLE_AND_HOLD_TAG, MULTIPLE_TAG); + return modelBB120; +} diff --git a/plugins/community/repos/SubmarineFree/src/BP.cpp b/plugins/community/repos/SubmarineFree/src/BP.cpp deleted file mode 100644 index 0a05e4c5..00000000 --- a/plugins/community/repos/SubmarineFree/src/BP.cpp +++ /dev/null @@ -1,147 +0,0 @@ -#include "SubmarineFree.hpp" - -namespace rack_plugin_SubmarineFree { - -struct BP : Module { - enum ParamIds { - NUM_PARAMS - }; - enum InputIds { - NUM_INPUTS - }; - enum OutputIds { - NUM_OUTPUTS - }; - enum LightIds { - NUM_LIGHTS - }; - - BP() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} - void step() override; - - // For more advanced Module features, read Rack's engine.hpp header file - // - toJson, fromJson: serialization of internal data - // - onSampleRateChange: event triggered by a change of sample rate - // - onReset, onRandomize, onCreate, onDelete: implements special behavior when user clicks these from the context menu -}; - -void BP::step() { -} - -struct BP101 : ModuleWidget { - BP101(BP *module) : ModuleWidget(module) { - setPanel(SVG::load(assetPlugin(plugin, "res/BP-101.svg"))); - } -}; - -struct BP102 : ModuleWidget { - BP102(BP *module) : ModuleWidget(module) { - setPanel(SVG::load(assetPlugin(plugin, "res/BP-102.svg"))); - } -}; - -struct BP104 : ModuleWidget { - BP104(BP *module) : ModuleWidget(module) { - setPanel(SVG::load(assetPlugin(plugin, "res/BP-104.svg"))); - } -}; - -struct BP108 : ModuleWidget { - BP108(BP *module) : ModuleWidget(module) { - setPanel(SVG::load(assetPlugin(plugin, "res/BP-108.svg"))); - } -}; - -struct BP110 : ModuleWidget { - BP110(BP *module) : ModuleWidget(module) { - setPanel(SVG::load(assetPlugin(plugin, "res/BP-110.svg"))); - } -}; - -struct BP112 : ModuleWidget { - BP112(BP *module) : ModuleWidget(module) { - setPanel(SVG::load(assetPlugin(plugin, "res/BP-112.svg"))); - } -}; - -struct BP116 : ModuleWidget { - BP116(BP *module) : ModuleWidget(module) { - setPanel(SVG::load(assetPlugin(plugin, "res/BP-116.svg"))); - } -}; - -struct BP120 : ModuleWidget { - BP120(BP *module) : ModuleWidget(module) { - setPanel(SVG::load(assetPlugin(plugin, "res/BP-120.svg"))); - } -}; - -struct BP124 : ModuleWidget { - BP124(BP *module) : ModuleWidget(module) { - setPanel(SVG::load(assetPlugin(plugin, "res/BP-124.svg"))); - } -}; - -struct BP132 : ModuleWidget { - BP132(BP *module) : ModuleWidget(module) { - setPanel(SVG::load(assetPlugin(plugin, "res/BP-132.svg"))); - } -}; - -} // namespace rack_plugin_SubmarineFree - -using namespace rack_plugin_SubmarineFree; - -// Specify the Module and ModuleWidget subclass, human-readable -// author name for categorization per plugin, module slug (should never -// change), human-readable module name, and any number of tags -// (found in `include/tags.hpp`) separated by commas. -RACK_PLUGIN_MODEL_INIT(SubmarineFree, BP101) { - Model *modelBP101 = Model::create("SubmarineFree", "BP-101", "BP-101 Blanking Plate", BLANK_TAG); - return modelBP101; -} - -RACK_PLUGIN_MODEL_INIT(SubmarineFree, BP102) { - Model *modelBP102 = Model::create("SubmarineFree", "BP-102", "BP-102 Blanking Plate", BLANK_TAG); - return modelBP102; -} - -RACK_PLUGIN_MODEL_INIT(SubmarineFree, BP104) { - Model *modelBP104 = Model::create("SubmarineFree", "BP-104", "BP-104 Blanking Plate", BLANK_TAG); - return modelBP104; -} - -RACK_PLUGIN_MODEL_INIT(SubmarineFree, BP108) { - Model *modelBP108 = Model::create("SubmarineFree", "BP-108", "BP-108 Blanking Plate", BLANK_TAG); - return modelBP108; -} - -RACK_PLUGIN_MODEL_INIT(SubmarineFree, BP110) { - Model *modelBP110 = Model::create("SubmarineFree", "BP-110", "BP-110 Blanking Plate", BLANK_TAG); - return modelBP110; -} - -RACK_PLUGIN_MODEL_INIT(SubmarineFree, BP112) { - Model *modelBP112 = Model::create("SubmarineFree", "BP-112", "BP-112 Blanking Plate", BLANK_TAG); - return modelBP112; -} - -RACK_PLUGIN_MODEL_INIT(SubmarineFree, BP116) { - Model *modelBP116 = Model::create("SubmarineFree", "BP-116", "BP-116 Blanking Plate", BLANK_TAG); - return modelBP116; -} - -RACK_PLUGIN_MODEL_INIT(SubmarineFree, BP120) { - Model *modelBP120 = Model::create("SubmarineFree", "BP-120", "BP-120 Blanking Plate", BLANK_TAG); - return modelBP120; -} - -RACK_PLUGIN_MODEL_INIT(SubmarineFree, BP124) { - Model *modelBP124 = Model::create("SubmarineFree", "BP-124", "BP-124 Blanking Plate", BLANK_TAG); - return modelBP124; -} - -RACK_PLUGIN_MODEL_INIT(SubmarineFree, BP132) { - Model *modelBP132 = Model::create("SubmarineFree", "BP-132", "BP-132 Blanking Plate", BLANK_TAG); - return modelBP132; -} diff --git a/plugins/community/repos/SubmarineFree/src/BP1.cpp b/plugins/community/repos/SubmarineFree/src/BP1.cpp new file mode 100644 index 00000000..307af4f1 --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/BP1.cpp @@ -0,0 +1,64 @@ +#include "SubmarineFree.hpp" + +namespace rack_plugin_SubmarineFree { + +template +struct BP1 : ModuleWidget { + BP1(Module *module) : ModuleWidget(module) { + setPanel(SubHelper::LoadPanel(plugin, "BP-1", x)); + } +}; + +} // namespace rack_plugin_SubmarineFree + +using namespace rack_plugin_SubmarineFree; + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, BP101) { + Model *modelBP101 = Model::create>("Submarine (Free)", "BP-101", "BP-101 Blanking Plate", BLANK_TAG); + return modelBP101; +} + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, BP102) { + Model *modelBP102 = Model::create>("Submarine (Free)", "BP-102", "BP-102 Blanking Plate", BLANK_TAG); + return modelBP102; +} + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, BP104) { + Model *modelBP104 = Model::create>("Submarine (Free)", "BP-104", "BP-104 Blanking Plate", BLANK_TAG); + return modelBP104; +} + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, BP108) { + Model *modelBP108 = Model::create>("Submarine (Free)", "BP-108", "BP-108 Blanking Plate", BLANK_TAG); + return modelBP108; +} + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, BP110) { + Model *modelBP110 = Model::create>("Submarine (Free)", "BP-110", "BP-110 Blanking Plate", BLANK_TAG); + return modelBP110; +} + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, BP112) { + Model *modelBP112 = Model::create>("Submarine (Free)", "BP-112", "BP-112 Blanking Plate", BLANK_TAG); + return modelBP112; +} + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, BP116) { + Model *modelBP116 = Model::create>("Submarine (Free)", "BP-116", "BP-116 Blanking Plate", BLANK_TAG); + return modelBP116; +} + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, BP120) { + Model *modelBP120 = Model::create>("Submarine (Free)", "BP-120", "BP-120 Blanking Plate", BLANK_TAG); + return modelBP120; +} + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, BP124) { + Model *modelBP124 = Model::create>("Submarine (Free)", "BP-124", "BP-124 Blanking Plate", BLANK_TAG); + return modelBP124; +} + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, BP132) { + Model *modelBP132 = Model::create>("Submarine (Free)", "BP-132", "BP-132 Blanking Plate", BLANK_TAG); + return modelBP132; +} diff --git a/plugins/community/repos/SubmarineFree/src/ComponentLibrary/Port.cpp b/plugins/community/repos/SubmarineFree/src/ComponentLibrary/Port.cpp new file mode 100644 index 00000000..f2806af0 --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/ComponentLibrary/Port.cpp @@ -0,0 +1,62 @@ +#include "../SubmarineFree.hpp" +#include "util/color.hpp" + +void SilverPort::draw(NVGcontext *vg) { + float radius = box.size.x / 2.0f; + + // Shadow + { + nvgBeginPath(vg); + nvgCircle(vg, radius, radius * 1.2, radius); + nvgFillColor(vg, nvgRGBAf(0, 0, 0, 0.15)); + nvgFill(vg); + } + + // Switch + { + nvgBeginPath(vg); + nvgRect(vg, 6, 6, 13, 13); + nvgFillColor(vg, nvgRGB(0,0,0)); + nvgFill(vg); + nvgBeginPath(vg); + nvgRect(vg, 10, 6, 5, 13); + nvgFillPaint(vg, nvgLinearGradient(vg, radius, 19, radius, radius, nvgRGB(0x60, 0x60, 0x60), nvgRGB(0,0,0))); + nvgFill(vg); + } + + // Port body + { + nvgBeginPath(vg); + nvgCircle(vg, radius, radius, 7); + nvgStrokeWidth(vg, 4); + nvgStrokePaint(vg, nvgRadialGradient(vg, radius + 0.3, radius + 1, 0, 9, nvgRGB(0x20, 0x20, 0x20), col)); + nvgStroke(vg); + } + + // Outer rim + { + nvgBeginPath(vg); + nvgMoveTo(vg, 0.66556777, 9.9934984); + nvgArc(vg, radius, radius, radius - 1, M_PI + 0.2076, -0.2076, NVG_CW); + nvgArc(vg, 24.5, 12.5, 2.5, 1.467 - M_PI, M_PI - 1.467, NVG_CCW); + nvgArc(vg, radius, radius, radius - 1, 0.2076, M_PI - 0.2076, NVG_CW); + nvgArc(vg, 0.5, 12.5, 2.5, 1.467, -1.467, NVG_CCW); + nvgClosePath(vg); + //nvgCircle(vg, radius, radius, 8.5709); + nvgCircle(vg, radius, radius, 8.0); + nvgPathWinding(vg, NVG_HOLE); + nvgStrokeColor(vg, nvgRGB(0x66,0x66,0x66)); + nvgStrokeWidth(vg, 0.80645); + if (type == Port::OUTPUT) { + nvgFillPaint(vg, nvgRadialGradient(vg, radius + 0.3, radius + 1, 1, 12, col, nvgRGB(0x3f, 0x3f, 0x3f))); + nvgStrokeColor(vg, nvgRGB(0x36,0x36,0x36)); + } + else { + nvgFillPaint(vg, nvgRadialGradient(vg, radius + 0.3, radius + 1, 1, 12, col, nvgRGB(0xff, 0xff, 0xff))); + nvgStrokeColor(vg, nvgRGB(0x66,0x66,0x66)); + } + nvgFill(vg); + nvgStroke(vg); + } + +} diff --git a/plugins/community/repos/SubmarineFree/src/ComponentLibrary/components.hpp b/plugins/community/repos/SubmarineFree/src/ComponentLibrary/components.hpp index c3fe5a43..08120cc8 100644 --- a/plugins/community/repos/SubmarineFree/src/ComponentLibrary/components.hpp +++ b/plugins/community/repos/SubmarineFree/src/ComponentLibrary/components.hpp @@ -2,6 +2,27 @@ // Ports ////////////////// +struct SilverPort : Port { + NVGcolor col = nvgRGB(0xf0, 0xf0, 0xf0); + SilverPort() { + box.size.x = 25; + box.size.y = 25; + } + void draw(NVGcontext *vg) override; +}; + +struct RedPort : SilverPort { + RedPort() { col = nvgRGB(0xff, 0x20, 0x20); } +}; + +struct BluePort : SilverPort { + BluePort() { col = nvgRGB(0x29, 0xb2, 0xef); } +}; + +struct BlackPort : SilverPort { + BlackPort() { col = nvgRGB(0x40, 0x40, 0x40); } +}; +/* struct sub_port : SVGPort { sub_port() { setSVG(SVG::load(assetPlugin(plugin, "res/Components/sub_port.svg"))); @@ -26,6 +47,7 @@ struct sub_port_black : SVGPort { } }; +*/ ////////////////// // Switches ////////////////// @@ -83,6 +105,9 @@ struct sub_btn : SVGSwitch, ToggleSwitch { addFrame(SVG::load(assetPlugin(plugin, "res/Components/sub_btn.svg"))); addFrame(SVG::load(assetPlugin(plugin, "res/Components/sub_btn_a.svg"))); } + void step() override { + setValue(module->params[paramId].value); + } }; ////////////////// @@ -96,76 +121,52 @@ struct LightKnob : Knob { /** Radii in standard units */ float radius = 19.0; int enabled = 1; - LightKnob() {} + LightKnob() {smooth = false;} void draw(NVGcontext *vg) override; void setEnabled(int val); void setRadius(int r); }; -struct sub_knob_small : LightKnob { - sub_knob_small() { - setRadius(12.0); - } -}; - -struct sub_knob_med : LightKnob { - sub_knob_med() { - setRadius(19.0); - } -}; - -struct sub_knob_large : LightKnob { - sub_knob_large() { - setRadius(27.0); - } -}; - -struct sub_knob_small_narrow : sub_knob_small { - sub_knob_small_narrow() { - minAngle = -0.75*M_PI; - maxAngle = 0.75*M_PI; - } -}; - -struct sub_knob_med_narrow : sub_knob_med { - sub_knob_med_narrow() { - minAngle = -0.75*M_PI; - maxAngle = 0.75*M_PI; +template +struct TinyKnob : K { + TinyKnob() { + K::setRadius(9.0f); } }; -struct sub_knob_large_narrow : sub_knob_large { - sub_knob_large_narrow() { - minAngle = -0.75*M_PI; - maxAngle = 0.75*M_PI; +template +struct SmallKnob : K { + SmallKnob() { + K::setRadius(12.0f); } }; -struct sub_knob_small_snap : sub_knob_small { - sub_knob_small_snap() { - snap = true; - smooth = false; +template +struct MedKnob : K { + MedKnob() { + K::setRadius(19.0f); } }; -struct sub_knob_med_snap : sub_knob_med { - sub_knob_med_snap() { - snap = true; - smooth = false; +template +struct LargeKnob : K { + LargeKnob() { + K::setRadius(27.0f); } }; -struct sub_knob_large_snap : sub_knob_large { - sub_knob_large_snap() { - snap = true; - smooth = false; +template +struct SnapKnob : K { + SnapKnob() { + K::snap = true; } }; -struct sub_knob_med_snap_narrow : sub_knob_med_snap { - sub_knob_med_snap_narrow() { - minAngle = -0.75*M_PI; - maxAngle = 0.75*M_PI; +template +struct NarrowKnob : K { + NarrowKnob() { + K::minAngle = -0.75*M_PI; + K::maxAngle = 0.75*M_PI; } }; diff --git a/plugins/community/repos/SubmarineFree/src/DS.cpp b/plugins/community/repos/SubmarineFree/src/DS.cpp index 8acbd6fa..99bfc34d 100644 --- a/plugins/community/repos/SubmarineFree/src/DS.cpp +++ b/plugins/community/repos/SubmarineFree/src/DS.cpp @@ -22,7 +22,7 @@ void DS_Module::fromJson(json_t *rootJ) { void DS_Module::onReset() { voltage0 = 0.0f; - voltage1 = 5.0f; + voltage1 = 10.0f; } float DS_Module::output(int state) { diff --git a/plugins/community/repos/SubmarineFree/src/EO1.cpp b/plugins/community/repos/SubmarineFree/src/EO1.cpp new file mode 100644 index 00000000..7c96c645 --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/EO1.cpp @@ -0,0 +1,457 @@ +/* Portions of this code derive from Fundamental/src/Scope.cpp - Copyright 2017 by Andrew Belt */ +#include +#include "SubmarineFree.hpp" +#include "dsp/digital.hpp" + +namespace rack_plugin_SubmarineFree { + +#define BUFFER_SIZE 800 +#define PRE_SIZE 100 + +#define sMAX(a,b) (((a)>(b))?(a):(b)) + +struct EO_102 : Module { + enum ParamIds { + PARAM_SCALE_1, + PARAM_SCALE_2, + PARAM_OFFSET_1, + PARAM_OFFSET_2, + PARAM_TRIGGER, + PARAM_TIME, + PARAM_INDEX_1, + PARAM_INDEX_2, + PARAM_INDEX_3, + PARAM_RUNMODE, + PARAM_RUN, + PARAM_PRE, + PARAM_MODE_1, + PARAM_MODE_2, + NUM_PARAMS + }; + enum InputIds { + INPUT_1, + INPUT_2, + INPUT_EXT, + NUM_INPUTS + }; + enum OutputIds { + NUM_OUTPUTS + }; + enum LightIds { + LIGHT_TRIGGER, + NUM_LIGHTS + }; + + float buffer[2][BUFFER_SIZE] = {}; + int bufferIndex = 0; + float frameIndex = 0; + + float preBuffer[2][PRE_SIZE] = {}; + int preBufferIndex = 0; + float preFrameIndex = 0; + int preCount = 0; + + SchmittTrigger trigger; + PulseGenerator triggerLight; + float runMode; + int traceMode[2]; + int traceStep; + + EO_102() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} + void step() override; + void startFrame(void); +}; + +void EO_102::startFrame() { + triggerLight.trigger(0.1f); + frameIndex = 0; + preCount = (int)(params[PARAM_PRE].value + 0.5f); + for (int i = 0; i < 2; i++) { + for (int s = 0; s < preCount; s++) { + buffer[i][s] = preBuffer[i][(preBufferIndex + (PRE_SIZE * 2) - preCount + s) % PRE_SIZE]; + } + traceMode[i] = (int)(params[PARAM_MODE_1 + i].value + 0.5f); + } + bufferIndex = preCount; + traceStep = 1; +} + +void EO_102::step() { + if (runMode > 0.5f) { + if (params[PARAM_RUNMODE].value < 0.5f) + // runningButtonWidget->setValue(1.0f); + engineSetParam(this, PARAM_RUN, 1.0f); + } + runMode = params[PARAM_RUNMODE].value; + // Compute time + float deltaTime = powf(2.0f, params[PARAM_TIME].value); + int frameCount = (int)ceilf(deltaTime * engineGetSampleRate()); + lights[LIGHT_TRIGGER].value = triggerLight.process(engineGetSampleTime()); + + // Add frame to preBuffer + for (int i = 0; i < 2; i++) { + if (params[PARAM_MODE_1 + i].value > 0.5f) { + if (traceStep) { + preBuffer[i][preBufferIndex] = fabs(inputs[INPUT_1 + i].value); + } + preBuffer[i][preBufferIndex] = sMAX(preBuffer[i][preBufferIndex], (float)fabs(inputs[INPUT_1 + i].value)); + } + } + if (++preFrameIndex >= frameCount) { + preFrameIndex = 0; + for (int i = 0; i < 2; i++) { + if (params[PARAM_MODE_1 + i].value < 0.5f) { + preBuffer[i][preBufferIndex] = inputs[INPUT_1 + i].value; + } + } + preBufferIndex++; + if (preBufferIndex >= PRE_SIZE) { + preBufferIndex = 0; + } + } + + // Add frame to buffer + if (bufferIndex < BUFFER_SIZE) { + for (int i = 0; i < 2; i++) { + if (traceMode[i]) { + if (traceStep) { + buffer[i][bufferIndex] = fabs(inputs[INPUT_1 + i].value); + } + buffer[i][bufferIndex] = sMAX(buffer[i][bufferIndex], (float)fabs(inputs[INPUT_1 + i].value)); + } + } + traceStep = 0; + if (++frameIndex >= frameCount) { + frameIndex = 0; + for (int i = 0; i < 2; i++) { + if (!traceMode[i]) { + buffer[i][bufferIndex] = inputs[INPUT_1 + i].value; + } + } + bufferIndex++; + traceStep = 1; + } + } + + int triggerInput = INPUT_1; + if (inputs[INPUT_EXT].active) + triggerInput = INPUT_EXT; + + // Are we waiting on the next trigger? + if (bufferIndex >= BUFFER_SIZE) { + // Trigger immediately if nothing connected to trigger input + if (!inputs[triggerInput].active) { + startFrame(); + return; + } + + // Reset the Schmitt trigger so we don't trigger immediately if the input is high + if (frameIndex == 0) { + trigger.reset(); + } + frameIndex++; + + float gate = inputs[triggerInput].value; + int triggered = trigger.process(rescale(gate, params[PARAM_TRIGGER].value - 0.1f, params[PARAM_TRIGGER].value, 0.0f, 1.0f)); + + if (params[PARAM_RUN].value > 0.5f) { + if (triggered) { + startFrame(); + if (runMode > 0.5f) // Continuous run mode + engineSetParam(this, PARAM_RUN, 0.0f); + return; + } + } + } +} + +struct EO_Display : TransparentWidget { + EO_102 *module; + + void drawTrace(NVGcontext *vg, float *values, float offset, float scale, NVGcolor col, int mode) { + if (!values) + return; + float scaling = powf(2.0, scale); + nvgSave(vg); + Rect b = Rect(Vec(0, 0), box.size); + nvgScissor(vg, b.pos.x, b.pos.y, b.size.x, b.size.y); + nvgBeginPath(vg); + for (int i = 0; i < BUFFER_SIZE; i++) { + float x, y; + x = (float)i / (BUFFER_SIZE - 1) * b.size.x; + y = ((values[i] * scaling + offset ) / 20.0f - 0.8f) * -b.size.y; + if (i == 0) + nvgMoveTo(vg, x, y); + else + nvgLineTo(vg, x, y); + } + if (mode) { + nvgLineTo(vg, b.size.x, (offset / 20.0f - 0.8f) * -b.size.y); + nvgLineTo(vg, 0, (offset / 20.0f - 0.8f) * -b.size.y); + nvgClosePath(vg); + nvgFillColor(vg, col); + nvgGlobalCompositeOperation(vg, NVG_LIGHTER); + nvgFill(vg); + } + else { + nvgStrokeColor(vg, col); + nvgLineCap(vg, NVG_ROUND); + nvgMiterLimit(vg, 2.0f); + nvgStrokeWidth(vg, 1.5f); + nvgGlobalCompositeOperation(vg, NVG_LIGHTER); + nvgStroke(vg); + } + nvgResetScissor(vg); + nvgRestore(vg); + } + + void drawIndex(NVGcontext *vg, float value) { + Rect b = Rect(Vec(0, 0), box.size); + nvgScissor(vg, b.pos.x, b.pos.y, b.size.x, b.size.y); + value = value * b.size.x; + + nvgStrokeColor(vg, nvgRGBA(0xff, 0xff, 0xff, 0x40)); + { + nvgBeginPath(vg); + nvgMoveTo(vg, value, 0); + nvgLineTo(vg, value, b.size.y); + nvgClosePath(vg); + } + nvgStroke(vg); + nvgResetScissor(vg); + } + void drawIndexV(NVGcontext *vg, float value) { + Rect b = Rect(Vec(0, 0), box.size); + nvgScissor(vg, b.pos.x, b.pos.y, b.size.x, b.size.y); + value = (1-value) * b.size.y; + + nvgStrokeColor(vg, nvgRGBA(0xff, 0xff, 0xff, 0x40)); + { + nvgBeginPath(vg); + nvgMoveTo(vg, 0, value); + nvgLineTo(vg, b.size.x, value); + nvgClosePath(vg); + } + nvgStroke(vg); + nvgResetScissor(vg); + } + + void drawTrigger(NVGcontext *vg, float value, float offset, float scale) { + Rect b = Rect(Vec(0, 0), box.size); + float scaling = powf(2.0f, scale); + float y = ((value * scaling + offset ) / 20.0f - 0.8f) * -b.size.y; + if (y < 0) return; + if (y > b.size.y) return; + nvgScissor(vg, b.pos.x, b.pos.y, b.size.x, b.size.y); + + nvgStrokeColor(vg, nvgRGBA(0xff, 0xff, 0xff, 0x40)); + { + nvgBeginPath(vg); + nvgMoveTo(vg, 0, y); + nvgLineTo(vg, b.size.x, y); + nvgClosePath(vg); + } + nvgStroke(vg); + nvgResetScissor(vg); + } + + void drawPre(NVGcontext *vg, float value) { + if (value == 0.0f) + return; + Rect b = Rect(Vec(0, 0), box.size); + nvgScissor(vg, b.pos.x, b.pos.y, b.size.x, b.size.y); + value = value * b.size.x; + + nvgStrokeColor(vg, nvgRGBA(0xff, 0x40, 0x40, 0x80)); + { + nvgBeginPath(vg); + nvgMoveTo(vg, value, 0); + nvgLineTo(vg, value, b.size.y); + nvgClosePath(vg); + } + nvgStroke(vg); + nvgResetScissor(vg); + } + + void drawMask(NVGcontext *vg, float value) { + if (value == 0.0f) + return; + Rect b = Rect(Vec(0, 0), box.size); + nvgScissor(vg, b.pos.x, b.pos.y, b.size.x, b.size.y); + value = value * b.size.x; + + nvgFillColor(vg, nvgRGBA(0xff, 0x40, 0x40, 0x40)); + { + nvgBeginPath(vg); + nvgRect(vg, 0, 0, value, b.size.y); + nvgClosePath(vg); + } + nvgFill(vg); + nvgResetScissor(vg); + } + + void draw(NVGcontext *vg) override { + NVGcolor col = nvgRGBA(0x28, 0xb0, 0xf3, 0xc0); + for (int i = 0; i < 2; i++) { + if (module->inputs[EO_102::INPUT_1 + i].active) { + drawTrace(vg, module->buffer[i], module->params[EO_102::PARAM_OFFSET_1 + i].value, module->params[EO_102::PARAM_SCALE_1 + i].value, col, module->traceMode[i]); + } + col = nvgRGBA(0xed, 0x2c, 0x24, 0xc0); + } + drawIndex(vg, clamp(module->params[EO_102::PARAM_INDEX_1].value, 0.0f, 1.0f)); + drawIndex(vg, clamp(module->params[EO_102::PARAM_INDEX_2].value, 0.0f, 1.0f)); + drawIndexV(vg, clamp(module->params[EO_102::PARAM_INDEX_3].value, 0.0f, 1.0f)); + if (module->inputs[EO_102::INPUT_EXT].active) + drawTrigger(vg, module->params[EO_102::PARAM_TRIGGER].value, 0.0f, 1.0f); + else + drawTrigger(vg, module->params[EO_102::PARAM_TRIGGER].value, module->params[EO_102::PARAM_OFFSET_1].value, module->params[EO_102::PARAM_SCALE_1].value); + drawMask(vg, clamp(module->params[EO_102::PARAM_PRE].value, 0.0f, 1.0f * PRE_SIZE) / BUFFER_SIZE); + drawPre(vg, 1.0f * module->preCount / BUFFER_SIZE); + } +}; + +struct EO_Measure : TransparentWidget { + std::shared_ptr font; + EO_102 *module; + char measureText[41]; + NVGcolor col; + + EO_Measure() { + font = Font::load(assetGlobal( "res/fonts/DejaVuSans.ttf")); + } + + virtual void updateText() { + } + + void draw(NVGcontext *vg) override { + updateText(); + nvgFontSize(vg, 14); + nvgFontFaceId(vg, font->handle); + nvgFillColor(vg, col); + nvgTextAlign(vg, NVG_ALIGN_CENTER); + nvgText(vg, box.size.x / 2, 12, measureText, NULL); + } +}; + +struct EO_Measure_Horz : EO_Measure { + void updateText() override { + float deltaTime = powf(2.0f, module->params[EO_102::PARAM_TIME].value); + int frameCount = (int)ceilf(deltaTime * engineGetSampleRate()); + frameCount *= BUFFER_SIZE; + float width = (float)frameCount * fabs(module->params[EO_102::PARAM_INDEX_1].value - module->params[EO_102::PARAM_INDEX_2].value) / engineGetSampleRate(); + + if (width < 0.00000995f) + sprintf(measureText, "%4.3f\xc2\xb5s", width * 1000000.0f); + else if (width < 0.0000995f) + sprintf(measureText, "%4.2f\xc2\xb5s", width * 1000000.0f); + else if (width < 0.000995f) + sprintf(measureText, "%4.1f\xc2\xb5s", width * 1000000.0f); + else if (width < 0.00995f) + sprintf(measureText, "%4.3fms", width * 1000.0f); + else if (width < 0.0995f) + sprintf(measureText, "%4.2fms", width * 1000.0f); + else if (width < 0.995f) + sprintf(measureText, "%4.1fms", width * 1000.0f); + else if (width < 9.95f) + sprintf(measureText, "%4.3fs", width); + else if (width < 99.5f) + sprintf(measureText, "%4.2fs", width); + else + sprintf(measureText, "%4.1fs", width); + } +}; + +struct EO_Measure_Vert : EO_Measure { + int index = 0; + void updateText() override { + float height = ((module->params[EO_102::PARAM_INDEX_3].value - 0.2f) * 20.0f - module->params[EO_102::PARAM_OFFSET_1 + index].value) / powf(2, module->params[EO_102::PARAM_SCALE_1 + index].value); + + float ah = fabs(height); + if (ah < 0.00000995f) + sprintf(measureText, "%4.3f\xc2\xb5V", height * 1000000.0f); + else if (ah < 0.0000995f) + sprintf(measureText, "%4.2f\xc2\xb5V", height * 1000000.0f); + else if (ah < 0.000995f) + sprintf(measureText, "%4.1f\xc2\xb5V", height * 1000000.0f); + else if (ah < 0.00995f) + sprintf(measureText, "%4.3fmV", height * 1000.0f); + else if (ah < 0.0995f) + sprintf(measureText, "%4.2fmV", height * 1000.0f); + else if (ah < 0.995f) + sprintf(measureText, "%4.1fmV", height * 1000.0f); + else if (ah < 9.95f) + sprintf(measureText, "%4.3fV", height); + else if (ah < 99.5f) + sprintf(measureText, "%4.2fV", height); + else + sprintf(measureText, "%4.1fV", height); + } +}; + +struct EO102 : ModuleWidget { + EO102(EO_102 *module) : ModuleWidget(module) { + setPanel(SVG::load(assetPlugin(plugin, "res/EO-102.svg"))); + + { + EO_Display * display = new EO_Display(); + display->module = module; + display->box.pos = Vec(2.5, 14); + display->box.size = Vec(box.size.x - 5, 236); + addChild(display); + } + { + EO_Measure_Horz * display = new EO_Measure_Horz(); + display->module = module; + display->box.pos = Vec(284, 272); + display->box.size = Vec(54, 16); + display->col = nvgRGBA(0xff, 0xff, 0xff, 0xff); + addChild(display); + } + { + EO_Measure_Vert * display = new EO_Measure_Vert(); + display->module = module; + display->box.pos = Vec(341, 254); + display->box.size = Vec(62, 16); + display->index = 0; + display->col = nvgRGBA(0x28, 0xb0, 0xf3, 0xff); + addChild(display); + } + { + EO_Measure_Vert * display = new EO_Measure_Vert(); + display->module = module; + display->box.pos = Vec(341, 272); + display->box.size = Vec(62, 16); + display->index = 1; + display->col = nvgRGBA(0xed, 0x2c, 0x24, 0xff); + addChild(display); + } + + for (int i = 0; i < 2; i++) { + addInput(createInputCentered(Vec(16.5 + 75 * i, 326.5), module, EO_102::INPUT_1 + i)); + addParam(createParamCentered(Vec(16.5 + 75 * i, 280), module, EO_102::PARAM_MODE_1 + i, 0.0f, 1.0f, 0.0f)); + addParam(createParamCentered>(Vec(50 + 75 * i, 320), module, EO_102::PARAM_OFFSET_1 + i, -10.0f, 10.0f, 0.0f)); + addParam(createParamCentered>>(Vec(50 + 75 * i, 270), module, EO_102::PARAM_SCALE_1 + i, -5.0f, 5.0f, 0.0f)); + } + addParam(createParamCentered>(Vec(172.5, 320), module, EO_102::PARAM_TIME, -6.0f, -16.0f, -14.0f)); + addParam(createParamCentered>>(Vec(172.5, 270), module, EO_102::PARAM_PRE, 0.0f, 1.0f * PRE_SIZE, 0.0f)); + + addInput(createInputCentered(Vec(211.5, 326.5), module, EO_102::INPUT_EXT)); + addParam(createParamCentered>(Vec(245, 320), module, EO_102::PARAM_TRIGGER, -10.0f, 10.0f, 0.0f)); + addChild(createLightCentered>(Vec(226, 333), module, EO_102::LIGHT_TRIGGER)); + addParam(createParamCentered(Vec(211.5, 280), module, EO_102::PARAM_RUNMODE, 0.0f, 1.0f, 0.0f)); + addParam(createParamCentered(Vec(245, 280), module, EO_102::PARAM_RUN, 0.0f, 1.0f, 1.0f)); + + addParam(createParamCentered>(Vec(290, 320), module, EO_102::PARAM_INDEX_1, 0.0f, 1.0f, 0.0f)); + addParam(createParamCentered>(Vec(332, 320), module, EO_102::PARAM_INDEX_2, 0.0f, 1.0f, 1.0f)); + addParam(createParamCentered>(Vec(376, 320), module, EO_102::PARAM_INDEX_3, 0.0f, 1.0f, 0.2f)); + } +}; + +} // namespace rack_plugin_SubmarineFree + +using namespace rack_plugin_SubmarineFree; + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, EO102) { + Model *modelEO102 = Model::create("Submarine (Free)", "EO-102", "EO-102 Envelope Oscilloscope", VISUAL_TAG); + return modelEO102; +} diff --git a/plugins/community/repos/SubmarineFree/src/FF-110.cpp b/plugins/community/repos/SubmarineFree/src/FF-110.cpp deleted file mode 100644 index 82e47134..00000000 --- a/plugins/community/repos/SubmarineFree/src/FF-110.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#include "DS.hpp" - -namespace rack_plugin_SubmarineFree { - -struct FF_110 : DS_Module { - static const int deviceCount = 10; - enum ParamIds { - NUM_PARAMS - }; - enum InputIds { - INPUT, - NUM_INPUTS - }; - enum OutputIds { - OUTPUT_1, - OUTPUT_2, - OUTPUT_3, - OUTPUT_4, - OUTPUT_5, - OUTPUT_6, - OUTPUT_7, - OUTPUT_8, - OUTPUT_9, - OUTPUT_10, - NUM_OUTPUTS - }; - enum LightIds { - NUM_LIGHTS - }; - - int state[deviceCount] = {0,0,0,0,0,0,0,0,0,0}; - DS_Schmitt schmittTrigger[deviceCount]; - - FF_110() : DS_Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} - void step() override; -}; - -void FF_110::step() { - if (inputs[INPUT].active) { - if (schmittTrigger[0].redge(this, inputs[INPUT].value)) - state[0] = !state[0]; - } - outputs[OUTPUT_1].value = state[0]?voltage1:voltage0; - for (int i = 1; i < deviceCount; i++) { - if (schmittTrigger[i].redge(this, state[i-1]?voltage0:voltage1)) - state[i] = !state[i]; - outputs[OUTPUT_1 + i].value = state[i]?voltage1:voltage0; - } -} - -struct FF110 : ModuleWidget { - FF110(FF_110 *module) : ModuleWidget(module) { - setPanel(SVG::load(assetPlugin(plugin, "res/FF-110.svg"))); - - addInput(Port::create(Vec(2.5,19), Port::INPUT, module, FF_110::INPUT)); - - for (int i = 0; i < FF_110::deviceCount; i++) { - int offset = 29 * i; - - addOutput(Port::create(Vec(2.5,77 + offset), Port::OUTPUT, module, FF_110::OUTPUT_1 + i)); - } - } - void appendContextMenu(Menu *menu) override { - ((DS_Module *)module)->appendContextMenu(menu); - } -}; - -} // namespace rack_plugin_SubmarineFree - -using namespace rack_plugin_SubmarineFree; - -RACK_PLUGIN_MODEL_INIT(SubmarineFree, FF110) { - Model *modelFF110 = Model::create("SubmarineFree", "FF-110", "FF-110 10-Stage Flip-Flop Counter", LOGIC_TAG, MULTIPLE_TAG); - return modelFF110; -} diff --git a/plugins/community/repos/SubmarineFree/src/FF-120.cpp b/plugins/community/repos/SubmarineFree/src/FF-120.cpp deleted file mode 100644 index 82b3d7a9..00000000 --- a/plugins/community/repos/SubmarineFree/src/FF-120.cpp +++ /dev/null @@ -1,87 +0,0 @@ -#include "DS.hpp" - -namespace rack_plugin_SubmarineFree { - -struct FF_120 : DS_Module { - static const int deviceCount = 20; - enum ParamIds { - NUM_PARAMS - }; - enum InputIds { - INPUT, - NUM_INPUTS - }; - enum OutputIds { - OUTPUT_1, - OUTPUT_2, - OUTPUT_3, - OUTPUT_4, - OUTPUT_5, - OUTPUT_6, - OUTPUT_7, - OUTPUT_8, - OUTPUT_9, - OUTPUT_10, - OUTPUT_11, - OUTPUT_12, - OUTPUT_13, - OUTPUT_14, - OUTPUT_15, - OUTPUT_16, - OUTPUT_17, - OUTPUT_18, - OUTPUT_19, - OUTPUT_20, - NUM_OUTPUTS - }; - enum LightIds { - NUM_LIGHTS - }; - - int state[deviceCount] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - DS_Schmitt schmittTrigger[deviceCount]; - - FF_120() : DS_Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} - void step() override; -}; - -void FF_120::step() { - if (inputs[INPUT].active) { - if (schmittTrigger[0].redge(this, inputs[INPUT].value)) - state[0] = !state[0]; - } - outputs[OUTPUT_1].value = state[0]?voltage1:voltage0; - for (int i = 1; i < deviceCount; i++) { - if (schmittTrigger[i].redge(this, state[i-1]?voltage0:voltage1)) - state[i] = !state[i]; - outputs[OUTPUT_1 + i].value = state[i]?voltage1:voltage0; - } -} - -struct FF120 : ModuleWidget { - FF120(FF_120 *module) : ModuleWidget(module) { - setPanel(SVG::load(assetPlugin(plugin, "res/FF-120.svg"))); - - addInput(Port::create(Vec(17.5,19), Port::INPUT, module, FF_120::INPUT)); - - for (int i = 0; i < FF_120::deviceCount; i+=2) { - int offset = 15 * i; - - addOutput(Port::create(Vec(4,53 + offset), Port::OUTPUT, module, FF_120::OUTPUT_1 + i)); - addOutput(Port::create(Vec(31,68 + offset), Port::OUTPUT, module, FF_120::OUTPUT_1 + i + 1)); - } - } - void appendContextMenu(Menu *menu) override { - ((DS_Module *)module)->appendContextMenu(menu); - } -}; - -} // namespace rack_plugin_SubmarineFree - -using namespace rack_plugin_SubmarineFree; - -RACK_PLUGIN_MODEL_INIT(SubmarineFree, FF120) { - Model *modelFF120 = Model::create("SubmarineFree", "FF-120", "FF-120 20-Stage Flip-Flop Counter", LOGIC_TAG, MULTIPLE_TAG); - return modelFF120; -} - diff --git a/plugins/community/repos/SubmarineFree/src/FF-212.cpp b/plugins/community/repos/SubmarineFree/src/FF-212.cpp deleted file mode 100644 index 4dd0a210..00000000 --- a/plugins/community/repos/SubmarineFree/src/FF-212.cpp +++ /dev/null @@ -1,90 +0,0 @@ -#include "DS.hpp" - -namespace rack_plugin_SubmarineFree { - -struct FF_212 : DS_Module { - static const int deviceCount = 12; - enum ParamIds { - NUM_PARAMS - }; - enum InputIds { - INPUT_1, - INPUT_2, - INPUT_3, - INPUT_4, - INPUT_5, - INPUT_6, - INPUT_7, - INPUT_8, - INPUT_9, - INPUT_10, - INPUT_11, - INPUT_12, - NUM_INPUTS - }; - enum OutputIds { - OUTPUT_1, - OUTPUT_2, - OUTPUT_3, - OUTPUT_4, - OUTPUT_5, - OUTPUT_6, - OUTPUT_7, - OUTPUT_8, - OUTPUT_9, - OUTPUT_10, - OUTPUT_11, - OUTPUT_12, - NUM_OUTPUTS - }; - enum LightIds { - NUM_LIGHTS - }; - - int state[deviceCount] = {0,0,0,0,0,0,0,0,0,0,0,0}; - DS_Schmitt schmittTrigger[deviceCount]; - - FF_212() : DS_Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} - void step() override; -}; - -void FF_212::step() { - for (int i = 0; i < deviceCount; i++) { - if (inputs[INPUT_1 + i].active) { - if (schmittTrigger[i].redge(this, inputs[INPUT_1 + i].value)) - state[i] = !state[i]; - } - else { - if (i) { - if (schmittTrigger[i].redge(this, state[i-1]?voltage0:voltage1)) - state[i] = !state[i]; - } - } - outputs[OUTPUT_1 + i].value = state[i]?voltage1:voltage0; - } -} - -struct FF212 : ModuleWidget { - FF212(FF_212 *module) : ModuleWidget(module) { - setPanel(SVG::load(assetPlugin(plugin, "res/FF-212.svg"))); - - for (int i = 0; i < FF_212::deviceCount; i++) { - int offset = 29 * i; - addInput(Port::create(Vec(4,19 + offset), Port::INPUT, module, FF_212::INPUT_1 + i)); - - addOutput(Port::create(Vec(62,19 + offset), Port::OUTPUT, module, FF_212::OUTPUT_1 + i)); - } - } - void appendContextMenu(Menu *menu) override { - ((DS_Module *)module)->appendContextMenu(menu); - } -}; - -} // namespace rack_plugin_SubmarineFree - -using namespace rack_plugin_SubmarineFree; - -RACK_PLUGIN_MODEL_INIT(SubmarineFree, FF212) { - Model *modelFF212 = Model::create("SubmarineFree", "FF-212", "FF-212 Edge Triggered Flip-Flops", LOGIC_TAG, MULTIPLE_TAG); - return modelFF212; -} diff --git a/plugins/community/repos/SubmarineFree/src/FF1.cpp b/plugins/community/repos/SubmarineFree/src/FF1.cpp new file mode 100644 index 00000000..3aa92bce --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/FF1.cpp @@ -0,0 +1,134 @@ +#include +#include +#include "DS.hpp" +#include +#include + +namespace rack_plugin_SubmarineFree { + +template +struct FF_1 : DS_Module { + int doResetFlag = 0; + int doRandomFlag = 0; + enum ParamIds { + NUM_PARAMS + }; + enum InputIds { + INPUT, + NUM_INPUTS + }; + enum OutputIds { + OUTPUT_1, + NUM_OUTPUTS = deviceCount + }; + enum LightIds { + NUM_LIGHTS + }; + + int state[deviceCount] = {}; + DS_Schmitt schmittTrigger[deviceCount]; + + FF_1() : DS_Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} + + void step() override { + if (doResetFlag) doReset(); + if (doRandomFlag) doRandomize(); + if (inputs[INPUT].active) { + if (schmittTrigger[0].redge(this, inputs[INPUT].value)) + state[0] = !state[0]; + } + outputs[OUTPUT_1].value = state[0]?voltage1:voltage0; + for (int i = 1; i < deviceCount; i++) { + if (schmittTrigger[i].fedge(this, state[i-1]?voltage1:voltage0)) + state[i] = !state[i]; + outputs[OUTPUT_1 + i].value = state[i]?voltage1:voltage0; + } + } + void doRandomize() { + doRandomFlag = 0; + std::default_random_engine generator(std::chrono::system_clock::now().time_since_epoch().count()); + std::uniform_int_distribution distribution(0,1); + state[0] = distribution(generator); + outputs[OUTPUT_1].value = state[0]?voltage1:voltage0; + for (int i = 1; i < deviceCount; i++) { + state[i] = distribution(generator); + schmittTrigger[i].set(state[i-1]); + outputs[OUTPUT_1 + i].value = state[i]?voltage1:voltage0; + } + } + void doReset() { + doResetFlag = 0; + for (int i = 0; i < deviceCount; i++) { + state[i] = 0; + if (i) schmittTrigger[i].reset(); + outputs[OUTPUT_1 + i].value = voltage0; + } + } + void onRandomize() override { + if (rack::global->gPaused) { + doRandomize(); + } + else { + doResetFlag = 0; + doRandomFlag = 1; + } + } + void onReset() override { + if (rack::global->gPaused) { + doReset(); + } + else { + doRandomFlag = 0; + doResetFlag = 1; + } + } +}; + +struct FF110 : ModuleWidget { + FF110(FF_1<10> *module) : ModuleWidget(module) { + setPanel(SVG::load(assetPlugin(plugin, "res/FF-110.svg"))); + + addInput(Port::create(Vec(2.5,19), Port::INPUT, module, FF_1<10>::INPUT)); + + for (int i = 0; i < 10; i++) { + int offset = 29 * i; + + addOutput(Port::create(Vec(2.5,77 + offset), Port::OUTPUT, module, FF_1<10>::OUTPUT_1 + i)); + } + } + void appendContextMenu(Menu *menu) override { + ((DS_Module *)module)->appendContextMenu(menu); + } +}; + +struct FF120 : ModuleWidget { + FF120(FF_1<20> *module) : ModuleWidget(module) { + setPanel(SVG::load(assetPlugin(plugin, "res/FF-120.svg"))); + + addInput(Port::create(Vec(17.5,19), Port::INPUT, module, FF_1<20>::INPUT)); + + for (int i = 0; i < 20; i+=2) { + int offset = 15 * i; + + addOutput(Port::create(Vec(4,53 + offset), Port::OUTPUT, module, FF_1<20>::OUTPUT_1 + i)); + addOutput(Port::create(Vec(31,68 + offset), Port::OUTPUT, module, FF_1<20>::OUTPUT_1 + i + 1)); + } + } + void appendContextMenu(Menu *menu) override { + ((DS_Module *)module)->appendContextMenu(menu); + } +}; + +} // namespace rack_plugin_SubmarineFree + +using namespace rack_plugin_SubmarineFree; + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, FF110) { + Model *modelFF110 = Model::create, FF110>("Submarine (Free)", "FF-110", "FF-110 10-Stage Flip-Flop Counter", LOGIC_TAG, MULTIPLE_TAG); + return modelFF110; +} + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, FF120) { + Model *modelFF120 = Model::create, FF120>("Submarine (Free)", "FF-120", "FF-120 20-Stage Flip-Flop Counter", LOGIC_TAG, MULTIPLE_TAG); + return modelFF120; +} diff --git a/plugins/community/repos/SubmarineFree/src/FF2.cpp b/plugins/community/repos/SubmarineFree/src/FF2.cpp new file mode 100644 index 00000000..6975868e --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/FF2.cpp @@ -0,0 +1,131 @@ +#include +#include +#include "DS.hpp" +#include +#include + +namespace rack_plugin_SubmarineFree { + +template +struct FF_2 : DS_Module { + int doResetFlag = 0; + int doRandomFlag = 0; + enum ParamIds { + NUM_PARAMS + }; + enum InputIds { + INPUT_1, + NUM_INPUTS = x + }; + enum OutputIds { + OUTPUT_1, + NUM_OUTPUTS = x + }; + enum LightIds { + NUM_LIGHTS + }; + + int state[x] = {}; + DS_Schmitt schmittTrigger[x]; + + FF_2() : DS_Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} + void step() override { + if (doResetFlag) doReset(); + if (doRandomFlag) doRandomize(); + for (int i = 0; i < x; i++) { + if (inputs[INPUT_1 + i].active) { + if (schmittTrigger[i].redge(this, inputs[INPUT_1 + i].value)) + state[i] = !state[i]; + } + else { + if (i) { + if (schmittTrigger[i].fedge(this, state[i-1]?voltage1:voltage0)) + state[i] = !state[i]; + } + } + outputs[OUTPUT_1 + i].value = state[i]?voltage1:voltage0; + } + } + void doRandomize() { + doRandomFlag = 0; + std::default_random_engine generator(std::chrono::system_clock::now().time_since_epoch().count()); + std::uniform_int_distribution distribution(0,1); + for (int i = 0; i < x; i++) { + state[i] = distribution(generator); + if (i) if (!inputs[INPUT_1 + i].active) schmittTrigger[i].set(state[i-1]); + outputs[OUTPUT_1 + i].value = state[i]?voltage1:voltage0; + } + } + void doReset() { + doResetFlag = 0; + for (int i = 0; i < x; i++) { + state[i] = 0; + if (!inputs[INPUT_1 + i].active) schmittTrigger[i].reset(); + outputs[OUTPUT_1 + i].value = voltage0; + } + } + void onRandomize() override { + if (rack::global->gPaused) { + doRandomize(); + } + else { + doResetFlag = 0; + doRandomFlag = 1; + } + } + void onReset() override { + if (rack::global->gPaused) { + doReset(); + } + else { + doRandomFlag = 0; + doResetFlag = 1; + } + } +}; + +struct FF206 : ModuleWidget { + FF206(FF_2<6> *module) : ModuleWidget(module) { + setPanel(SVG::load(assetPlugin(plugin, "res/FF-206.svg"))); + + for (int i = 0; i < 6; i++) { + int offset = 58 * i; + addInput(Port::create(Vec(2.5,19 + offset), Port::INPUT, module, FF_2<6>::INPUT_1 + i)); + + addOutput(Port::create(Vec(2.5,47 + offset), Port::OUTPUT, module, FF_2<6>::OUTPUT_1 + i)); + } + } + void appendContextMenu(Menu *menu) override { + ((DS_Module *)module)->appendContextMenu(menu); + } +}; + +struct FF212 : ModuleWidget { + FF212(FF_2<12> *module) : ModuleWidget(module) { + setPanel(SVG::load(assetPlugin(plugin, "res/FF-212.svg"))); + + for (int i = 0; i < 12; i++) { + int offset = 29 * i; + addInput(Port::create(Vec(4,19 + offset), Port::INPUT, module, FF_2<12>::INPUT_1 + i)); + + addOutput(Port::create(Vec(62,19 + offset), Port::OUTPUT, module, FF_2<12>::OUTPUT_1 + i)); + } + } + void appendContextMenu(Menu *menu) override { + ((DS_Module *)module)->appendContextMenu(menu); + } +}; + +} // namespace rack_plugin_SubmarineFree + +using namespace rack_plugin_SubmarineFree; + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, FF206) { + Model *modelFF206 = Model::create, FF206>("Submarine (Free)", "FF-206", "FF-206 Edge Triggered Flip-Flops", LOGIC_TAG, MULTIPLE_TAG); + return modelFF206; +} + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, FF212) { + Model *modelFF212 = Model::create, FF212>("Submarine (Free)", "FF-212", "FF-212 Edge Triggered Flip-Flops", LOGIC_TAG, MULTIPLE_TAG); + return modelFF212; +} diff --git a/plugins/community/repos/SubmarineFree/src/LA-108.cpp b/plugins/community/repos/SubmarineFree/src/LA1.cpp similarity index 87% rename from plugins/community/repos/SubmarineFree/src/LA-108.cpp rename to plugins/community/repos/SubmarineFree/src/LA1.cpp index d500cd12..66c1cc76 100644 --- a/plugins/community/repos/SubmarineFree/src/LA-108.cpp +++ b/plugins/community/repos/SubmarineFree/src/LA1.cpp @@ -1,10 +1,11 @@ +/* Portions of this code derive from Fundamental/src/Scope.cpp - Copyright © 2016 by Andrew Belt */ #include #include "DS.hpp" -#define BUFFER_SIZE 512 - namespace rack_plugin_SubmarineFree { +#define BUFFER_SIZE 512 + struct LA_108 : DS_Module { enum ParamIds { PARAM_TRIGGER, @@ -55,7 +56,6 @@ struct LA_108 : DS_Module { int preCount = 0; DS_Schmitt trigger; - sub_btn *resetButtonWidget; LA_108() : DS_Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} void step() override; @@ -126,7 +126,7 @@ void LA_108::step() { int triggered = trigger.edge(this, gate, edge); if (params[PARAM_RUN].value < 0.5f) { // Continuous run mode - resetButtonWidget->setValue(0.0f); + engineSetParam(this, PARAM_RESET, 0.0f); // Reset if triggered float holdTime = 0.1f; if (triggered) { @@ -144,7 +144,7 @@ void LA_108::step() { if (params[PARAM_RESET].value > 0.5f) { if (triggered) { startFrame(); - resetButtonWidget->setValue(0.0f); + engineSetParam(this, PARAM_RESET, 0.0f); return; } } @@ -309,22 +309,21 @@ struct LA108 : ModuleWidget { } for (int i = 0; i < 8; i++) { - addInput(Port::create(Vec(4, 20 + 35 * i), Port::INPUT, module, LA_108::INPUT_1 + i)); + addInput(Port::create(Vec(4, 20 + 35 * i), Port::INPUT, module, LA_108::INPUT_1 + i)); addChild(ModuleLightWidget::create>(Vec(30, 22 + 35 * i), module, LA_108::LIGHT_1 + i)); } - addInput(Port::create(Vec(4, 310), Port::INPUT, module, LA_108::INPUT_EXT)); + addInput(Port::create(Vec(4, 310), Port::INPUT, module, LA_108::INPUT_EXT)); addChild(ModuleLightWidget::create>(Vec(30, 312), module, LA_108::LIGHT_EXT)); - addParam(ParamWidget::create(Vec(39, 301), module, LA_108::PARAM_TRIGGER, 0.0f, 8.0f, 0.0f)); + addParam(ParamWidget::create>>(Vec(39, 301), module, LA_108::PARAM_TRIGGER, 0.0f, 8.0f, 0.0f)); addParam(ParamWidget::create(Vec(82, 308), module, LA_108::PARAM_EDGE, 0.0f, 1.0f, 0.0f)); addParam(ParamWidget::create(Vec(108, 308), module, LA_108::PARAM_RUN, 0.0f, 1.0f, 0.0f)); - module->resetButtonWidget = ParamWidget::create(Vec(151, 312), module, LA_108::PARAM_RESET, 0.0f, 1.0f, 0.0f); - addParam(module->resetButtonWidget); - addParam(ParamWidget::create(Vec(171, 301), module, LA_108::PARAM_TIME, -6.0f, -16.0f, -14.0f)); - addParam(ParamWidget::create(Vec(214, 315), module, LA_108::PARAM_INDEX_1, 0.0f, 1.0f, 0.0f)); - addParam(ParamWidget::create(Vec(242, 315), module, LA_108::PARAM_INDEX_2, 0.0f, 1.0f, 1.0f)); - addParam(ParamWidget::create(Vec(271, 315), module, LA_108::PARAM_PRE, 0.0f, 32.0f, 0.0f)); + addParam(ParamWidget::create(Vec(151, 312), module, LA_108::PARAM_RESET, 0.0f, 1.0f, 0.0f)); + addParam(ParamWidget::create>(Vec(171, 301), module, LA_108::PARAM_TIME, -6.0f, -16.0f, -14.0f)); + addParam(ParamWidget::create>(Vec(214, 315), module, LA_108::PARAM_INDEX_1, 0.0f, 1.0f, 0.0f)); + addParam(ParamWidget::create>(Vec(242, 315), module, LA_108::PARAM_INDEX_2, 0.0f, 1.0f, 1.0f)); + addParam(ParamWidget::create>>(Vec(271, 315), module, LA_108::PARAM_PRE, 0.0f, 32.0f, 0.0f)); } void appendContextMenu(Menu *menu) override { ((DS_Module *)module)->appendContextMenu(menu); @@ -336,6 +335,6 @@ struct LA108 : ModuleWidget { using namespace rack_plugin_SubmarineFree; RACK_PLUGIN_MODEL_INIT(SubmarineFree, LA108) { - Model *modelLA108 = Model::create("SubmarineFree", "LA-108", "LA-108 Logic Analyser", LOGIC_TAG, VISUAL_TAG); + Model *modelLA108 = Model::create("Submarine (Free)", "LA-108", "LA-108 Logic Analyser", LOGIC_TAG, VISUAL_TAG); return modelLA108; } diff --git a/plugins/community/repos/SubmarineFree/src/LD-106.cpp b/plugins/community/repos/SubmarineFree/src/LD-106.cpp deleted file mode 100644 index 48f228ce..00000000 --- a/plugins/community/repos/SubmarineFree/src/LD-106.cpp +++ /dev/null @@ -1,123 +0,0 @@ -#include "DS.hpp" - -namespace rack_plugin_SubmarineFree { - -struct LD_106 : DS_Module { - static const int deviceCount = 6; - enum ParamIds { - PARAM_CUTOFF_1, - PARAM_CUTOFF_2, - PARAM_CUTOFF_3, - PARAM_CUTOFF_4, - PARAM_CUTOFF_5, - PARAM_CUTOFF_6, - PARAM_WIDTH_1, - PARAM_WIDTH_2, - PARAM_WIDTH_3, - PARAM_WIDTH_4, - PARAM_WIDTH_5, - PARAM_WIDTH_6, - NUM_PARAMS - }; - enum InputIds { - INPUT_1, - INPUT_2, - INPUT_3, - INPUT_4, - INPUT_5, - INPUT_6, - NUM_INPUTS - }; - enum OutputIds { - OUTPUT_1, - OUTPUT_2, - OUTPUT_3, - OUTPUT_4, - OUTPUT_5, - OUTPUT_6, - NUM_OUTPUTS - }; - enum LightIds { - NUM_LIGHTS - }; - - DS_Schmitt schmittState[deviceCount]; - - LD_106() : DS_Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} - void step() override; -}; - -void LD_106::step() { - for (int i = 0; i < deviceCount; i++) { - outputs[OUTPUT_1 + i].value = output(schmittState[i].state(params[PARAM_CUTOFF_1 + i].value - params[PARAM_WIDTH_1 + i].value, params[PARAM_CUTOFF_1 + i].value + params[PARAM_WIDTH_1 + i].value, inputs[INPUT_1 + i].value)); - } -} - -struct LD106 : ModuleWidget { - ParamWidget *cutoffWidgets[LD_106::deviceCount]; - ParamWidget *widthWidgets[LD_106::deviceCount]; - LD106(LD_106 *module) : ModuleWidget(module) { - setPanel(SVG::load(assetPlugin(plugin, "res/LD-106.svg"))); - - for (int i = 0; i < LD_106::deviceCount; i++) { - int offset = 58 * i; - addInput(Port::create(Vec(4,19 + offset), Port::INPUT, module, LD_106::INPUT_1 + i)); - - addOutput(Port::create(Vec(62,19 + offset), Port::OUTPUT, module, LD_106::OUTPUT_1 + i)); - - cutoffWidgets[i] = ParamWidget::create(Vec(4, 47 + offset), module, LD_106::PARAM_CUTOFF_1 + i, -10.0f, 10.0f, 5.0f); - addParam(cutoffWidgets[i]); - widthWidgets[i] = ParamWidget::create(Vec(62, 47 + offset), module, LD_106::PARAM_WIDTH_1 + i, 0.0f, 5.0f, 1.0f); - addParam(widthWidgets[i]); - } - } - void appendContextMenu(Menu *menu) override; -}; - -struct LDMenuItem: MenuItem { - LD106 *ld106; - float cutoff; - float width; - void onAction(EventAction &e) override { - for (int i = 0; i < LD_106::deviceCount; i++) { - ld106->cutoffWidgets[i]->setValue(cutoff); - ld106->widthWidgets[i]->setValue(width); - } - } -}; - -void LD106::appendContextMenu(Menu *menu) { - menu->addChild(MenuEntry::create()); - LD106 *ld106 = dynamic_cast(this); - assert(ld106); - LDMenuItem *menuItem = MenuItem::create("Cutoff 5V"); - menuItem->ld106 = ld106; - menuItem->cutoff = 5.0f; - menuItem->width = 1.0f; - menu->addChild(menuItem); - menuItem = MenuItem::create("Cutoff 0V"); - menuItem->ld106 = ld106; - menuItem->cutoff = 0.0f; - menuItem->width = 0.0f; - menu->addChild(menuItem); - menuItem = MenuItem::create("Cutoff 2.5V"); - menuItem->ld106 = ld106; - menuItem->cutoff = 2.5f; - menuItem->width = 0.5f; - menu->addChild(menuItem); - menuItem = MenuItem::create("TTL Levels"); - menuItem->ld106 = ld106; - menuItem->cutoff = 1.4f; - menuItem->width = 0.6f; - menu->addChild(menuItem); - ((LD_106 *)module)->appendContextMenu(menu); -} - -} // namespace rack_plugin_SubmarineFree - -using namespace rack_plugin_SubmarineFree; - -RACK_PLUGIN_MODEL_INIT(SubmarineFree, LD106) { - Model *modelLD106 = Model::create("SubmarineFree", "LD-106", "LD-106 Schmitt Trigger Line Drivers", LOGIC_TAG, MULTIPLE_TAG); - return modelLD106; -} diff --git a/plugins/community/repos/SubmarineFree/src/LD1.cpp b/plugins/community/repos/SubmarineFree/src/LD1.cpp new file mode 100644 index 00000000..86fe46e5 --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/LD1.cpp @@ -0,0 +1,168 @@ +#include "DS.hpp" + +namespace rack_plugin_SubmarineFree { + +template +struct LD_1 : DS_Module { + enum ParamIds { + PARAM_CUTOFF_1, + PARAM_WIDTH_1 = x, + NUM_PARAMS = x + x + }; + enum InputIds { + INPUT_1, + NUM_INPUTS = x + }; + enum OutputIds { + OUTPUT_1, + NUM_OUTPUTS = x + }; + enum LightIds { + NUM_LIGHTS + }; + + DS_Schmitt schmittState[x]; + + LD_1() : DS_Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} + void step() override { + for (int i = 0; i < x; i++) { + outputs[OUTPUT_1 + i].value = output(schmittState[i].state(params[PARAM_CUTOFF_1 + i].value - params[PARAM_WIDTH_1 + i].value, params[PARAM_CUTOFF_1 + i].value + params[PARAM_WIDTH_1 + i].value, inputs[INPUT_1 + i].value)); + } + } +}; + +struct LD103 : ModuleWidget { + static const int deviceCount = 3; + ParamWidget *cutoffWidgets[deviceCount]; + ParamWidget *widthWidgets[deviceCount]; + LD103(LD_1 *module) : ModuleWidget(module) { + setPanel(SVG::load(assetPlugin(plugin, "res/LD-103.svg"))); + + for (int i = 0; i < deviceCount; i++) { + int offset = 116 * i; + addInput(Port::create(Vec(2.5,19 + offset), Port::INPUT, module, LD_1<3>::INPUT_1 + i)); + + addOutput(Port::create(Vec(2.5,103 + offset), Port::OUTPUT, module, LD_1<3>::OUTPUT_1 + i)); + + cutoffWidgets[i] = ParamWidget::create>(Vec(6, 48.5 + offset), module, LD_1<3>::PARAM_CUTOFF_1 + i, -10.0f, 10.0f, 5.0f); + addParam(cutoffWidgets[i]); + widthWidgets[i] = ParamWidget::create>(Vec(6, 80.5 + offset), module, LD_1<3>::PARAM_WIDTH_1 + i, 0.0f, 5.0f, 1.0f); + addParam(widthWidgets[i]); + } + } + void appendContextMenu(Menu *menu) override; +}; + +struct LDMenuItem3: MenuItem { + LD103 *ld103; + float cutoff; + float width; + void onAction(EventAction &e) override { + for (int i = 0; i < LD103::deviceCount; i++) { + ld103->cutoffWidgets[i]->setValue(cutoff); + ld103->widthWidgets[i]->setValue(width); + } + } +}; + +void LD103::appendContextMenu(Menu *menu) { + menu->addChild(MenuEntry::create()); + LD103 *ld103 = dynamic_cast(this); + assert(ld103); + LDMenuItem3 *menuItem = MenuItem::create("Cutoff 5V"); + menuItem->ld103 = ld103; + menuItem->cutoff = 5.0f; + menuItem->width = 1.0f; + menu->addChild(menuItem); + menuItem = MenuItem::create("Cutoff 0V"); + menuItem->ld103 = ld103; + menuItem->cutoff = 0.0f; + menuItem->width = 0.0f; + menu->addChild(menuItem); + menuItem = MenuItem::create("Cutoff 2.5V"); + menuItem->ld103 = ld103; + menuItem->cutoff = 2.5f; + menuItem->width = 0.5f; + menu->addChild(menuItem); + menuItem = MenuItem::create("TTL Levels"); + menuItem->ld103 = ld103; + menuItem->cutoff = 1.4f; + menuItem->width = 0.6f; + menu->addChild(menuItem); + ((DS_Module *)module)->appendContextMenu(menu); +} + +struct LD106 : ModuleWidget { + static const int deviceCount = 6; + ParamWidget *cutoffWidgets[deviceCount]; + ParamWidget *widthWidgets[deviceCount]; + LD106(LD_1 *module) : ModuleWidget(module) { + setPanel(SVG::load(assetPlugin(plugin, "res/LD-106.svg"))); + + for (int i = 0; i < deviceCount; i++) { + int offset = 58 * i; + addInput(Port::create(Vec(4,19 + offset), Port::INPUT, module, LD_1<6>::INPUT_1 + i)); + + addOutput(Port::create(Vec(62,19 + offset), Port::OUTPUT, module, LD_1<6>::OUTPUT_1 + i)); + + cutoffWidgets[i] = ParamWidget::create>(Vec(4, 47 + offset), module, LD_1<6>::PARAM_CUTOFF_1 + i, -10.0f, 10.0f, 5.0f); + addParam(cutoffWidgets[i]); + widthWidgets[i] = ParamWidget::create>(Vec(62, 47 + offset), module, LD_1<6>::PARAM_WIDTH_1 + i, 0.0f, 5.0f, 1.0f); + addParam(widthWidgets[i]); + } + } + void appendContextMenu(Menu *menu) override; +}; + +struct LDMenuItem: MenuItem { + LD106 *ld106; + float cutoff; + float width; + void onAction(EventAction &e) override { + for (int i = 0; i < LD106::deviceCount; i++) { + ld106->cutoffWidgets[i]->setValue(cutoff); + ld106->widthWidgets[i]->setValue(width); + } + } +}; + +void LD106::appendContextMenu(Menu *menu) { + menu->addChild(MenuEntry::create()); + LD106 *ld106 = dynamic_cast(this); + assert(ld106); + LDMenuItem *menuItem = MenuItem::create("Cutoff 5V"); + menuItem->ld106 = ld106; + menuItem->cutoff = 5.0f; + menuItem->width = 1.0f; + menu->addChild(menuItem); + menuItem = MenuItem::create("Cutoff 0V"); + menuItem->ld106 = ld106; + menuItem->cutoff = 0.0f; + menuItem->width = 0.0f; + menu->addChild(menuItem); + menuItem = MenuItem::create("Cutoff 2.5V"); + menuItem->ld106 = ld106; + menuItem->cutoff = 2.5f; + menuItem->width = 0.5f; + menu->addChild(menuItem); + menuItem = MenuItem::create("TTL Levels"); + menuItem->ld106 = ld106; + menuItem->cutoff = 1.4f; + menuItem->width = 0.6f; + menu->addChild(menuItem); + ((DS_Module *)module)->appendContextMenu(menu); +} + +} // namespace rack_plugin_SubmarineFree + +using namespace rack_plugin_SubmarineFree; + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, LD103) { + Model *modelLD103 = Model::create, LD103>("Submarine (Free)", "LD-103", "LD-103 Schmitt Trigger Line Drivers", LOGIC_TAG, MULTIPLE_TAG); + return modelLD103; +} + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, LD106) { + Model *modelLD106 = Model::create, LD106>("Submarine (Free)", "LD-106", "LD-106 Schmitt Trigger Line Drivers", LOGIC_TAG, MULTIPLE_TAG); + return modelLD106; +} diff --git a/plugins/community/repos/SubmarineFree/src/NG-112.cpp b/plugins/community/repos/SubmarineFree/src/NG-112.cpp deleted file mode 100644 index 9e094236..00000000 --- a/plugins/community/repos/SubmarineFree/src/NG-112.cpp +++ /dev/null @@ -1,77 +0,0 @@ -#include "DS.hpp" - -namespace rack_plugin_SubmarineFree { - -struct NG_112 : DS_Module { - static const int deviceCount = 12; - enum ParamIds { - NUM_PARAMS - }; - enum InputIds { - INPUT_1, - INPUT_2, - INPUT_3, - INPUT_4, - INPUT_5, - INPUT_6, - INPUT_7, - INPUT_8, - INPUT_9, - INPUT_10, - INPUT_11, - INPUT_12, - NUM_INPUTS - }; - enum OutputIds { - OUTPUT_1, - OUTPUT_2, - OUTPUT_3, - OUTPUT_4, - OUTPUT_5, - OUTPUT_6, - OUTPUT_7, - OUTPUT_8, - OUTPUT_9, - OUTPUT_10, - OUTPUT_11, - OUTPUT_12, - NUM_OUTPUTS - }; - enum LightIds { - NUM_LIGHTS - }; - - NG_112() : DS_Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} - void step() override; -}; - -void NG_112::step() { - for (int i = 0; i < deviceCount; i++) { - outputs[OUTPUT_1 + i].value = (inputs[INPUT_1 + i].value < midpoint())?voltage1:voltage0; - } -} - -struct NG112 : ModuleWidget { - NG112(NG_112 *module) : ModuleWidget(module) { - setPanel(SVG::load(assetPlugin(plugin, "res/NG-112.svg"))); - - for (int i = 0; i < NG_112::deviceCount; i++) { - int offset = 29 * i; - addInput(Port::create(Vec(4,19 + offset), Port::INPUT, module, NG_112::INPUT_1 + i)); - - addOutput(Port::create(Vec(62,19 + offset), Port::OUTPUT, module, NG_112::OUTPUT_1 + i)); - } - } - void appendContextMenu(Menu *menu) override { - ((DS_Module *)module)->appendContextMenu(menu); - } -}; - -} // namespace rack_plugin_SubmarineFree - -using namespace rack_plugin_SubmarineFree; - -RACK_PLUGIN_MODEL_INIT(SubmarineFree, NG112) { - Model *modelNG112 = Model::create("SubmarineFree", "NG-112", "NG-112 NOT Gates", LOGIC_TAG, MULTIPLE_TAG); - return modelNG112; -} diff --git a/plugins/community/repos/SubmarineFree/src/NG1.cpp b/plugins/community/repos/SubmarineFree/src/NG1.cpp new file mode 100644 index 00000000..eb3b25d9 --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/NG1.cpp @@ -0,0 +1,74 @@ +#include "DS.hpp" + +namespace rack_plugin_SubmarineFree { + +template +struct NG_1 : DS_Module { + enum ParamIds { + NUM_PARAMS + }; + enum InputIds { + INPUT_1, + NUM_INPUTS = x + }; + enum OutputIds { + OUTPUT_1, + NUM_OUTPUTS = x + }; + enum LightIds { + NUM_LIGHTS + }; + + NG_1() : DS_Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} + void step() override { + for (int i = 0; i < x; i++) { + outputs[OUTPUT_1 + i].value = (inputs[INPUT_1 + i].value < midpoint())?voltage1:voltage0; + } + } +}; + +struct NG106 : ModuleWidget { + NG106(NG_1<6> *module) : ModuleWidget(module) { + setPanel(SVG::load(assetPlugin(plugin, "res/NG-106.svg"))); + + for (int i = 0; i < 6; i++) { + int offset = 58 * i; + addInput(Port::create(Vec(2.5,19 + offset), Port::INPUT, module, NG_1<6>::INPUT_1 + i)); + + addOutput(Port::create(Vec(2.5,47 + offset), Port::OUTPUT, module, NG_1<6>::OUTPUT_1 + i)); + } + } + void appendContextMenu(Menu *menu) override { + ((DS_Module *)module)->appendContextMenu(menu); + } +}; + +struct NG112 : ModuleWidget { + NG112(NG_1<12> *module) : ModuleWidget(module) { + setPanel(SVG::load(assetPlugin(plugin, "res/NG-112.svg"))); + + for (int i = 0; i < 12; i++) { + int offset = 29 * i; + addInput(Port::create(Vec(4,19 + offset), Port::INPUT, module, NG_1<12>::INPUT_1 + i)); + + addOutput(Port::create(Vec(62,19 + offset), Port::OUTPUT, module, NG_1<12>::OUTPUT_1 + i)); + } + } + void appendContextMenu(Menu *menu) override { + ((DS_Module *)module)->appendContextMenu(menu); + } +}; + +} // namespace rack_plugin_SubmarineFree + +using namespace rack_plugin_SubmarineFree; + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, NG106) { + Model *modelNG106 = Model::create, NG106>("Submarine (Free)", "NG-106", "NG-106 NOT Gates", LOGIC_TAG, MULTIPLE_TAG); + return modelNG106; +} + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, NG112) { + Model *modelNG112 = Model::create, NG112>("Submarine (Free)", "NG-112", "NG-112 NOT Gates", LOGIC_TAG, MULTIPLE_TAG); + return modelNG112; +} diff --git a/plugins/community/repos/SubmarineFree/src/OG-106.cpp b/plugins/community/repos/SubmarineFree/src/OG-106.cpp deleted file mode 100644 index 22327537..00000000 --- a/plugins/community/repos/SubmarineFree/src/OG-106.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#include "DS.hpp" - -namespace rack_plugin_SubmarineFree { - -struct OG_106 : DS_Module { - static const int deviceCount = 6; - enum ParamIds { - NUM_PARAMS - }; - enum InputIds { - INPUT_A_1, - INPUT_A_2, - INPUT_A_3, - INPUT_A_4, - INPUT_A_5, - INPUT_A_6, - INPUT_B_1, - INPUT_B_2, - INPUT_B_3, - INPUT_B_4, - INPUT_B_5, - INPUT_B_6, - NUM_INPUTS - }; - enum OutputIds { - OUTPUT_1, - OUTPUT_2, - OUTPUT_3, - OUTPUT_4, - OUTPUT_5, - OUTPUT_6, - NUM_OUTPUTS - }; - enum LightIds { - NUM_LIGHTS - }; - - OG_106() : DS_Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} - void step() override; -}; - -void OG_106::step() { - int setCount = 0; - for (int i = 0; i < deviceCount; i++) { - if (inputs[INPUT_A_1 + i].active) - if (inputs[INPUT_A_1 + i].value > midpoint()) - setCount++; - if (inputs[INPUT_B_1 + i].active) - if (inputs[INPUT_B_1 + i].value > midpoint()) - setCount++; - if (outputs[OUTPUT_1 + i].active) { - outputs[OUTPUT_1 + i].value = (setCount > 0)?voltage1:voltage0; - setCount = 0; - } - } -} - -struct OG106 : ModuleWidget { - OG106(OG_106 *module) : ModuleWidget(module) { - setPanel(SVG::load(assetPlugin(plugin, "res/OG-106.svg"))); - - for (int i = 0; i < OG_106::deviceCount; i++) { - int offset = 58 * i; - addInput(Port::create(Vec(4,19 + offset), Port::INPUT, module, OG_106::INPUT_A_1 + i)); - addInput(Port::create(Vec(4,47 + offset), Port::INPUT, module, OG_106::INPUT_B_1 + i)); - - addOutput(Port::create(Vec(62,33 + offset), Port::OUTPUT, module, OG_106::OUTPUT_1 + i)); - } - } - void appendContextMenu(Menu *menu) override { - ((DS_Module *)module)->appendContextMenu(menu); - } -}; - -} // namespace rack_plugin_SubmarineFree - -using namespace rack_plugin_SubmarineFree; - -RACK_PLUGIN_MODEL_INIT(SubmarineFree, OG106) { - Model *modelOG106 = Model::create("SubmarineFree", "OG-106", "OG-106 OR Gates", LOGIC_TAG, MULTIPLE_TAG); - return modelOG106; -} diff --git a/plugins/community/repos/SubmarineFree/src/OG1.cpp b/plugins/community/repos/SubmarineFree/src/OG1.cpp new file mode 100644 index 00000000..8a53b359 --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/OG1.cpp @@ -0,0 +1,87 @@ +#include "DS.hpp" + +namespace rack_plugin_SubmarineFree { + +template +struct OG_1 : DS_Module { + enum ParamIds { + NUM_PARAMS + }; + enum InputIds { + INPUT_A_1, + INPUT_B_1 = x, + NUM_INPUTS = x + x + }; + enum OutputIds { + OUTPUT_1, + NUM_OUTPUTS = x + }; + enum LightIds { + NUM_LIGHTS + }; + + OG_1() : DS_Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} + void step() override { + int setCount = 0; + for (int i = 0; i < x; i++) { + if (inputs[INPUT_A_1 + i].active) + if (inputs[INPUT_A_1 + i].value > midpoint()) + setCount++; + if (inputs[INPUT_B_1 + i].active) + if (inputs[INPUT_B_1 + i].value > midpoint()) + setCount++; + if (outputs[OUTPUT_1 + i].active) { + outputs[OUTPUT_1 + i].value = (setCount > 0)?voltage1:voltage0; + setCount = 0; + } + } + } +}; + +struct OG104 : ModuleWidget { + OG104(OG_1<4> *module) : ModuleWidget(module) { + setPanel(SVG::load(assetPlugin(plugin, "res/OG-104.svg"))); + + for (int i = 0; i < 4; i++) { + int offset = 87 * i; + addInput(Port::create(Vec(2.5,19 + offset), Port::INPUT, module, OG_1<4>::INPUT_A_1 + i)); + addInput(Port::create(Vec(2.5,47 + offset), Port::INPUT, module, OG_1<4>::INPUT_B_1 + i)); + + addOutput(Port::create(Vec(2.5,75 + offset), Port::OUTPUT, module, OG_1<4>::OUTPUT_1 + i)); + } + } + void appendContextMenu(Menu *menu) override { + ((DS_Module *)module)->appendContextMenu(menu); + } +}; + +struct OG106 : ModuleWidget { + OG106(OG_1<6> *module) : ModuleWidget(module) { + setPanel(SVG::load(assetPlugin(plugin, "res/OG-106.svg"))); + + for (int i = 0; i < 6; i++) { + int offset = 58 * i; + addInput(Port::create(Vec(4,19 + offset), Port::INPUT, module, OG_1<6>::INPUT_A_1 + i)); + addInput(Port::create(Vec(4,47 + offset), Port::INPUT, module, OG_1<6>::INPUT_B_1 + i)); + + addOutput(Port::create(Vec(62,33 + offset), Port::OUTPUT, module, OG_1<6>::OUTPUT_1 + i)); + } + } + void appendContextMenu(Menu *menu) override { + ((DS_Module *)module)->appendContextMenu(menu); + } +}; + +} // namespace rack_plugin_SubmarineFree + +using namespace rack_plugin_SubmarineFree; + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, OG104) { + Model *modelOG104 = Model::create, OG104>("Submarine (Free)", "OG-104", "OG-104 OR Gates", LOGIC_TAG, MULTIPLE_TAG); + return modelOG104; +} + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, OG106) { + Model *modelOG106 = Model::create, OG106>("Submarine (Free)", "OG-106", "OG-106 OR Gates", LOGIC_TAG, MULTIPLE_TAG); + return modelOG106; +} diff --git a/plugins/community/repos/SubmarineFree/src/PG-112.cpp b/plugins/community/repos/SubmarineFree/src/PG-112.cpp deleted file mode 100644 index 7a33c7ac..00000000 --- a/plugins/community/repos/SubmarineFree/src/PG-112.cpp +++ /dev/null @@ -1,102 +0,0 @@ -#include "DS.hpp" -#include "dsp/digital.hpp" - -namespace rack_plugin_SubmarineFree { - -struct PG_112 : DS_Module { - static const int deviceCount = 12; - enum ParamIds { - PARAM_1, - PARAM_2, - PARAM_3, - PARAM_4, - PARAM_5, - PARAM_6, - PARAM_7, - PARAM_8, - PARAM_9, - PARAM_10, - PARAM_11, - PARAM_12, - NUM_PARAMS - }; - enum InputIds { - INPUT_1, - INPUT_2, - INPUT_3, - INPUT_4, - INPUT_5, - INPUT_6, - INPUT_7, - INPUT_8, - INPUT_9, - INPUT_10, - INPUT_11, - INPUT_12, - NUM_INPUTS - }; - enum OutputIds { - OUTPUT_1, - OUTPUT_2, - OUTPUT_3, - OUTPUT_4, - OUTPUT_5, - OUTPUT_6, - OUTPUT_7, - OUTPUT_8, - OUTPUT_9, - OUTPUT_10, - OUTPUT_11, - OUTPUT_12, - NUM_OUTPUTS - }; - enum LightIds { - NUM_LIGHTS - }; - DS_Schmitt schmitt[deviceCount]; - PulseGenerator pulse[deviceCount]; - - PG_112() : DS_Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} - void step() override; -}; - -void PG_112::step() { - float deltaTime = 1.0f / engineGetSampleRate(); - for (int i = 0; i < deviceCount; i++) { - if (schmitt[i].redge(this, inputs[INPUT_1 + i].value)) { - pulse[i].process(deltaTime); - pulse[i].trigger(powf(10.0f, params[PARAM_1 + i].value)); - outputs[OUTPUT_1 + i].value = voltage1; - } - else { - outputs[OUTPUT_1 + i].value = pulse[i].process(deltaTime)?voltage1:voltage0; - } - } -} - -struct PG112 : ModuleWidget { - PG112(PG_112 *module) : ModuleWidget(module) { - setPanel(SVG::load(assetPlugin(plugin, "res/PG-112.svg"))); - - for (int i = 0; i < PG_112::deviceCount; i++) { - int offset = 29 * i; - addInput(Port::create(Vec(4,19 + offset), Port::INPUT, module, PG_112::INPUT_1 + i)); - - addOutput(Port::create(Vec(92,19 + offset), Port::OUTPUT, module, PG_112::OUTPUT_1 + i)); - - addParam(ParamWidget::create(Vec(33,19.5 + offset), module, PG_112::PARAM_1 + i, -5.0f, 2.0f, -2.0f)); - } - } - void appendContextMenu(Menu *menu) override { - ((DS_Module *)module)->appendContextMenu(menu); - } -}; - -} // namespace rack_plugin_SubmarineFree - -using namespace rack_plugin_SubmarineFree; - -RACK_PLUGIN_MODEL_INIT(SubmarineFree, PG112) { - Model *modelPG112 = Model::create("SubmarineFree", "PG-112", "PG-112 Pulse Generators", LOGIC_TAG, MULTIPLE_TAG); - return modelPG112; -} diff --git a/plugins/community/repos/SubmarineFree/src/PG1.cpp b/plugins/community/repos/SubmarineFree/src/PG1.cpp new file mode 100644 index 00000000..17f52af1 --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/PG1.cpp @@ -0,0 +1,90 @@ +#include "DS.hpp" +#include "dsp/digital.hpp" + +namespace rack_plugin_SubmarineFree { + +template +struct PG_1 : DS_Module { + enum ParamIds { + PARAM_1, + NUM_PARAMS = x + }; + enum InputIds { + INPUT_1, + NUM_INPUTS = x + }; + enum OutputIds { + OUTPUT_1, + NUM_OUTPUTS = x + }; + enum LightIds { + NUM_LIGHTS + }; + DS_Schmitt schmitt[x]; + PulseGenerator pulse[x]; + + PG_1() : DS_Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} + void step() override { + float deltaTime = 1.0f / engineGetSampleRate(); + for (int i = 0; i < x; i++) { + if (schmitt[i].redge(this, inputs[INPUT_1 + i].value)) { + pulse[i].process(deltaTime); + pulse[i].trigger(powf(10.0f, params[PARAM_1 + i].value)); + outputs[OUTPUT_1 + i].value = voltage1; + } + else { + outputs[OUTPUT_1 + i].value = pulse[i].process(deltaTime)?voltage1:voltage0; + } + } + } +}; + +struct PG104 : ModuleWidget { + PG104(PG_1<4> *module) : ModuleWidget(module) { + setPanel(SVG::load(assetPlugin(plugin, "res/PG-104.svg"))); + + for (int i = 0; i < 4; i++) { + int offset = 87 * i; + addInput(Port::create(Vec(2.5,19 + offset), Port::INPUT, module, PG_1<4>::INPUT_1 + i)); + + addOutput(Port::create(Vec(2.5,75 + offset), Port::OUTPUT, module, PG_1<4>::OUTPUT_1 + i)); + + addParam(ParamWidget::create>(Vec(3,47.5 + offset), module, PG_1<4>::PARAM_1 + i, -5.0f, 2.0f, -2.0f)); + } + } + void appendContextMenu(Menu *menu) override { + ((DS_Module *)module)->appendContextMenu(menu); + } +}; + +struct PG112 : ModuleWidget { + PG112(PG_1<12> *module) : ModuleWidget(module) { + setPanel(SVG::load(assetPlugin(plugin, "res/PG-112.svg"))); + + for (int i = 0; i < 12; i++) { + int offset = 29 * i; + addInput(Port::create(Vec(4,19 + offset), Port::INPUT, module, PG_1<12>::INPUT_1 + i)); + + addOutput(Port::create(Vec(92,19 + offset), Port::OUTPUT, module, PG_1<12>::OUTPUT_1 + i)); + + addParam(ParamWidget::create>(Vec(33,19.5 + offset), module, PG_1<12>::PARAM_1 + i, -5.0f, 2.0f, -2.0f)); + } + } + void appendContextMenu(Menu *menu) override { + ((DS_Module *)module)->appendContextMenu(menu); + } +}; + +} // namespace rack_plugin_SubmarineFree + +using namespace rack_plugin_SubmarineFree; + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, PG104) { + Model *modelPG104 = Model::create, PG104>("Submarine (Free)", "PG-104", "PG-104 Pulse Generators", LOGIC_TAG, MULTIPLE_TAG); + return modelPG104; +} + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, PG112) { + Model *modelPG112 = Model::create, PG112>("Submarine (Free)", "PG-112", "PG-112 Pulse Generators", LOGIC_TAG, MULTIPLE_TAG); + return modelPG112; +} diff --git a/plugins/community/repos/SubmarineFree/src/PO12.cpp b/plugins/community/repos/SubmarineFree/src/PO12.cpp new file mode 100644 index 00000000..7a58244b --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/PO12.cpp @@ -0,0 +1,509 @@ +#include "SubmarineFree.hpp" +#include "dsp/functions.hpp" + +namespace rack_plugin_SubmarineFree { + +struct PO_Util { + static constexpr float deg0 = 0.0f; + static constexpr float deg30 = M_PI / 6.0f; + static constexpr float deg45 = M_PI / 4.0f; + static constexpr float deg60 = M_PI / 3.0f; + static constexpr float deg90 = M_PI / 2.0f; + static constexpr float deg120 = 2.0f * M_PI / 3.0f; + static constexpr float deg135 = 3.0f * M_PI / 4.0f; + static constexpr float deg150 = 5.0f * M_PI / 6.0f; + static constexpr float ph0 = 0.0f; + static constexpr float ph30 = 1.0f / 12.0f; + static constexpr float ph45 = 0.125f; + static constexpr float ph60 = 1.0f / 6.0f; + static constexpr float ph90 = 0.25f; + static constexpr float ph120 = 1.0f / 3.0f; + static constexpr float ph135 = 0.375f; + static constexpr float ph150 = 5.0f / 12.0f; + static constexpr float ph180 = 0.5f; + static constexpr float ph210 = 7.0f / 12.0f; + static constexpr float ph225 = 0.625; + static constexpr float ph240 = 2.0f / 3.0f; + static constexpr float ph270 = 0.75f; + static constexpr float ph300 = 5.0f / 6.0f; + static constexpr float ph315 = 0.875f; + static constexpr float ph330 = 11.0f / 12.0f; + + float sin(float phase); + float tri(float phase); + float saw(float phase); + float sqr(float phase); + float rsn(float phase); +}; + +float PO_Util::sin(float phase) { + return 5.0f * sinf(phase); +} + +float PO_Util::tri(float phase) { + phase -= floor(phase); + if (phase < 0.25f) + return 20.0f * phase; + if (phase < 0.75f) + return 20.0f * (0.5f - phase); + return 20.0f * (phase - 1.0f); +} + +float PO_Util::saw(float phase) { + phase -= floor(phase); + if (phase < 0.5f) + return 10.0f * phase; + return 10.0f * (phase - 1.0f); +} + +float PO_Util::sqr(float phase) { + phase -= floor(phase); + return (phase < 0.5f)?5.0f:-5.0f; +} + +float PO_Util::rsn(float phase) { + return 10.0f * fabs(sinf(phase)) - 5.0f; +} + +struct PO_101 : Module, PO_Util { + + enum ParamIds { + PARAM_TUNE, + PARAM_FINE, + PARAM_WAVE, + PARAM_PHASE_1, + PARAM_PHASE_2, + PARAM_PHASE_3, + PARAM_PHASE_4, + NUM_PARAMS + }; + enum InputIds { + INPUT_NOTE_CV, + INPUT_PHASE_1, + INPUT_PHASE_2, + INPUT_PHASE_3, + INPUT_PHASE_4, + NUM_INPUTS + }; + enum OutputIds { + OUTPUT_1, + OUTPUT_2, + OUTPUT_3, + OUTPUT_4, + OUTPUT_5, + OUTPUT_6, + OUTPUT_7, + OUTPUT_8, + OUTPUT_9, + OUTPUT_10, + OUTPUT_11, + OUTPUT_12, + OUTPUT_13, + OUTPUT_14, + OUTPUT_15, + OUTPUT_16, + OUTPUT_17, + OUTPUT_18, + OUTPUT_19, + OUTPUT_20, + NUM_OUTPUTS + }; + enum LightIds { + NUM_LIGHTS + }; + + PO_101() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} + void step() override; + void sin(float phase); + void tri(float phase); + void saw(float phase); + void sqr(float phase); + void rsn(float phase); + float phase = 0.0f; + float baseFreq = 261.626f; +}; + +void PO_101::sin(float phase) { + phase *= (2 * M_PI); + if (outputs[OUTPUT_1].active || outputs[OUTPUT_9].active) + outputs[OUTPUT_9].value = -(outputs[OUTPUT_1].value = PO_Util::sin(phase + deg0)); + if (outputs[OUTPUT_2].active || outputs[OUTPUT_10].active) + outputs[OUTPUT_10].value = -(outputs[OUTPUT_2].value = PO_Util::sin(phase + deg30)); + if (outputs[OUTPUT_3].active || outputs[OUTPUT_11].active) + outputs[OUTPUT_11].value = -(outputs[OUTPUT_3].value = PO_Util::sin(phase + deg45)); + if (outputs[OUTPUT_4].active || outputs[OUTPUT_12].active) + outputs[OUTPUT_12].value = -(outputs[OUTPUT_4].value = PO_Util::sin(phase + deg60)); + if (outputs[OUTPUT_5].active || outputs[OUTPUT_13].active) + outputs[OUTPUT_13].value = -(outputs[OUTPUT_5].value = PO_Util::sin(phase + deg90)); + if (outputs[OUTPUT_6].active || outputs[OUTPUT_14].active) + outputs[OUTPUT_14].value = -(outputs[OUTPUT_6].value = PO_Util::sin(phase + deg120)); + if (outputs[OUTPUT_7].active || outputs[OUTPUT_15].active) + outputs[OUTPUT_15].value = -(outputs[OUTPUT_7].value = PO_Util::sin(phase + deg135)); + if (outputs[OUTPUT_8].active || outputs[OUTPUT_16].active) + outputs[OUTPUT_16].value = -(outputs[OUTPUT_8].value = PO_Util::sin(phase + deg150)); + for (int i = 0; i < 4; i++) { + if (outputs[OUTPUT_17 + i].active) { + float offset = params[PARAM_PHASE_1 + i].value; + if (inputs[INPUT_PHASE_1 + i].active) + offset += inputs[INPUT_PHASE_1 + i].value * 0.4f; + offset *= 2 * M_PI; + outputs[OUTPUT_17 + i].value = PO_Util::sin(phase + offset); + } + } +} + +void PO_101::tri(float phase) { + if (outputs[OUTPUT_1].active || outputs[OUTPUT_9].active) + outputs[OUTPUT_9].value = -(outputs[OUTPUT_1].value = PO_Util::tri(phase + ph0)); + if (outputs[OUTPUT_2].active || outputs[OUTPUT_10].active) + outputs[OUTPUT_10].value = -(outputs[OUTPUT_2].value = PO_Util::tri(phase + ph30)); + if (outputs[OUTPUT_3].active || outputs[OUTPUT_11].active) + outputs[OUTPUT_11].value = -(outputs[OUTPUT_3].value = PO_Util::tri(phase + ph45)); + if (outputs[OUTPUT_4].active || outputs[OUTPUT_12].active) + outputs[OUTPUT_12].value = -(outputs[OUTPUT_4].value = PO_Util::tri(phase + ph60)); + if (outputs[OUTPUT_5].active || outputs[OUTPUT_13].active) + outputs[OUTPUT_13].value = -(outputs[OUTPUT_5].value = PO_Util::tri(phase + ph90)); + if (outputs[OUTPUT_6].active || outputs[OUTPUT_14].active) + outputs[OUTPUT_14].value = -(outputs[OUTPUT_6].value = PO_Util::tri(phase + ph120)); + if (outputs[OUTPUT_7].active || outputs[OUTPUT_15].active) + outputs[OUTPUT_15].value = -(outputs[OUTPUT_7].value = PO_Util::tri(phase + ph135)); + if (outputs[OUTPUT_8].active || outputs[OUTPUT_16].active) + outputs[OUTPUT_16].value = -(outputs[OUTPUT_8].value = PO_Util::tri(phase + ph150)); + for (int i = 0; i < 4; i++) { + if (outputs[OUTPUT_17 + i].active) { + float offset = params[PARAM_PHASE_1 + i].value; + if (inputs[INPUT_PHASE_1 + i].active) + offset += inputs[INPUT_PHASE_1 + i].value * 0.4f; + outputs[OUTPUT_17 + i].value = PO_Util::tri(phase + offset); + } + } +} + +void PO_101::saw(float phase) { + if (outputs[OUTPUT_1].active) + outputs[OUTPUT_1].value = PO_Util::saw(phase + ph0); + if (outputs[OUTPUT_2].active) + outputs[OUTPUT_2].value = PO_Util::saw(phase + ph30); + if (outputs[OUTPUT_3].active) + outputs[OUTPUT_3].value = PO_Util::saw(phase + ph45); + if (outputs[OUTPUT_4].active) + outputs[OUTPUT_4].value = PO_Util::saw(phase + ph60); + if (outputs[OUTPUT_5].active) + outputs[OUTPUT_5].value = PO_Util::saw(phase + ph90); + if (outputs[OUTPUT_6].active) + outputs[OUTPUT_6].value = PO_Util::saw(phase + ph120); + if (outputs[OUTPUT_7].active) + outputs[OUTPUT_7].value = PO_Util::saw(phase + ph135); + if (outputs[OUTPUT_8].active) + outputs[OUTPUT_8].value = PO_Util::saw(phase + ph150); + if (outputs[OUTPUT_9].active) + outputs[OUTPUT_9].value = PO_Util::saw(phase + ph180); + if (outputs[OUTPUT_10].active) + outputs[OUTPUT_10].value = PO_Util::saw(phase + ph210); + if (outputs[OUTPUT_11].active) + outputs[OUTPUT_11].value = PO_Util::saw(phase + ph225); + if (outputs[OUTPUT_12].active) + outputs[OUTPUT_12].value = PO_Util::saw(phase + ph240); + if (outputs[OUTPUT_13].active) + outputs[OUTPUT_13].value = PO_Util::saw(phase + ph270); + if (outputs[OUTPUT_14].active) + outputs[OUTPUT_14].value = PO_Util::saw(phase + ph300); + if (outputs[OUTPUT_15].active) + outputs[OUTPUT_15].value = PO_Util::saw(phase + ph315); + if (outputs[OUTPUT_16].active) + outputs[OUTPUT_16].value = PO_Util::saw(phase + ph330); + for (int i = 0; i < 4; i++) { + if (outputs[OUTPUT_17 + i].active) { + float offset = params[PARAM_PHASE_1 + i].value; + if (inputs[INPUT_PHASE_1 + i].active) + offset += inputs[INPUT_PHASE_1 + i].value * 0.4f; + outputs[OUTPUT_17 + i].value = PO_Util::saw(phase + offset); + } + } +} + +void PO_101::sqr(float phase) { + if (outputs[OUTPUT_1].active || outputs[OUTPUT_9].active) + outputs[OUTPUT_9].value = -(outputs[OUTPUT_1].value = PO_Util::sqr(phase + ph0)); + if (outputs[OUTPUT_2].active || outputs[OUTPUT_10].active) + outputs[OUTPUT_10].value = -(outputs[OUTPUT_2].value = PO_Util::sqr(phase + ph30)); + if (outputs[OUTPUT_3].active || outputs[OUTPUT_11].active) + outputs[OUTPUT_11].value = -(outputs[OUTPUT_3].value = PO_Util::sqr(phase + ph45)); + if (outputs[OUTPUT_4].active || outputs[OUTPUT_12].active) + outputs[OUTPUT_12].value = -(outputs[OUTPUT_4].value = PO_Util::sqr(phase + ph60)); + if (outputs[OUTPUT_5].active || outputs[OUTPUT_13].active) + outputs[OUTPUT_13].value = -(outputs[OUTPUT_5].value = PO_Util::sqr(phase + ph90)); + if (outputs[OUTPUT_6].active || outputs[OUTPUT_14].active) + outputs[OUTPUT_14].value = -(outputs[OUTPUT_6].value = PO_Util::sqr(phase + ph120)); + if (outputs[OUTPUT_7].active || outputs[OUTPUT_15].active) + outputs[OUTPUT_15].value = -(outputs[OUTPUT_7].value = PO_Util::sqr(phase + ph135)); + if (outputs[OUTPUT_8].active || outputs[OUTPUT_16].active) + outputs[OUTPUT_16].value = -(outputs[OUTPUT_8].value = PO_Util::sqr(phase + ph150)); + for (int i = 0; i < 4; i++) { + if (outputs[OUTPUT_17 + i].active) { + float offset = params[PARAM_PHASE_1 + i].value; + if (inputs[INPUT_PHASE_1 + i].active) + offset += inputs[INPUT_PHASE_1 + i].value * 0.4f; + outputs[OUTPUT_17 + i].value = PO_Util::sqr(phase + offset); + } + } +} + +void PO_101::rsn(float phase) { + phase *= (2 * M_PI); + if (outputs[OUTPUT_1].active || outputs[OUTPUT_9].active) + outputs[OUTPUT_9].value = (outputs[OUTPUT_1].value = PO_Util::rsn(phase + deg0)); + if (outputs[OUTPUT_2].active || outputs[OUTPUT_10].active) + outputs[OUTPUT_10].value = (outputs[OUTPUT_2].value = PO_Util::rsn(phase + deg30)); + if (outputs[OUTPUT_3].active || outputs[OUTPUT_11].active) + outputs[OUTPUT_11].value = (outputs[OUTPUT_3].value = PO_Util::rsn(phase + deg45)); + if (outputs[OUTPUT_4].active || outputs[OUTPUT_12].active) + outputs[OUTPUT_12].value = (outputs[OUTPUT_4].value = PO_Util::rsn(phase + deg60)); + if (outputs[OUTPUT_5].active || outputs[OUTPUT_13].active) + outputs[OUTPUT_13].value = (outputs[OUTPUT_5].value = PO_Util::rsn(phase + deg90)); + if (outputs[OUTPUT_6].active || outputs[OUTPUT_14].active) + outputs[OUTPUT_14].value = (outputs[OUTPUT_6].value = PO_Util::rsn(phase + deg120)); + if (outputs[OUTPUT_7].active || outputs[OUTPUT_15].active) + outputs[OUTPUT_15].value = (outputs[OUTPUT_7].value = PO_Util::rsn(phase + deg135)); + if (outputs[OUTPUT_8].active || outputs[OUTPUT_16].active) + outputs[OUTPUT_16].value = (outputs[OUTPUT_8].value = PO_Util::rsn(phase + deg150)); + for (int i = 0; i < 4; i++) { + if (outputs[OUTPUT_17 + i].active) { + float offset = params[PARAM_PHASE_1 + i].value; + if (inputs[INPUT_PHASE_1 + i].active) + offset += inputs[INPUT_PHASE_1 + i].value * 0.4f; + offset *= 2 * M_PI; + outputs[OUTPUT_17 + i].value = PO_Util::rsn(phase + offset); + } + } +} + +void PO_101::step() { + float freq = baseFreq * powf(2.0f, (params[PARAM_TUNE].value + 3.0f * quadraticBipolar(params[PARAM_FINE].value)) / 12.0f + (inputs[INPUT_NOTE_CV].active?inputs[INPUT_NOTE_CV].value:0.0f)); + float deltaTime = freq / engineGetSampleRate(); + phase += deltaTime; + double intPart; + phase = modf(phase, &intPart); + + { + float waveShape = clamp(params[PARAM_WAVE].value, 0.0f, 4.0f); + if (waveShape < 0.5f) + sin(phase); + else if (waveShape < 1.5f) + tri(phase); + else if (waveShape < 2.5f) + saw(phase); + else if (waveShape < 3.5f) + sqr(phase); + else + rsn(phase); + } + +} + +struct PO_204 : Module, PO_Util { + + enum ParamIds { + PARAM_TUNE, + PARAM_FINE, + PARAM_WAVE_1, + PARAM_WAVE_2, + PARAM_WAVE_3, + PARAM_WAVE_4, + PARAM_PHASE_1, + PARAM_PHASE_2, + PARAM_PHASE_3, + PARAM_PHASE_4, + PARAM_MULT_1, + PARAM_MULT_2, + PARAM_MULT_3, + PARAM_MULT_4, + NUM_PARAMS + }; + enum InputIds { + INPUT_TUNE, + INPUT_WAVE_1, + INPUT_WAVE_2, + INPUT_WAVE_3, + INPUT_WAVE_4, + INPUT_PHASE_1, + INPUT_PHASE_2, + INPUT_PHASE_3, + INPUT_PHASE_4, + INPUT_MULT_1, + INPUT_MULT_2, + INPUT_MULT_3, + INPUT_MULT_4, + NUM_INPUTS + }; + enum OutputIds { + OUTPUT_1, + OUTPUT_2, + OUTPUT_3, + OUTPUT_4, + NUM_OUTPUTS + }; + enum LightIds { + NUM_LIGHTS + }; + + PO_204() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} + void step() override; + float phase = 0.0f; + float baseFreq = 261.626f; +}; + +void PO_204::step() { + float freq = baseFreq * powf(2.0f, (params[PARAM_TUNE].value + 3.0f * quadraticBipolar(params[PARAM_FINE].value)) / 12.0f + (inputs[INPUT_TUNE].active?inputs[INPUT_TUNE].value:0.0f)); + float deltaTime = freq / engineGetSampleRate(); + phase += deltaTime; + double intPart; + phase = modf(phase, &intPart); + for (int i = 0; i < 4; i++) { + if (outputs[OUTPUT_1 + i].active) { + float offset = phase + params[PARAM_PHASE_1 + i].value; + if (inputs[INPUT_PHASE_1 + i].active) + offset += inputs[INPUT_PHASE_1 + i].value * 0.4f; + offset *= floor(clamp(params[PARAM_MULT_1 + i].value + (inputs[INPUT_MULT_1 + i].active?inputs[INPUT_MULT_1 + i].value:0.0f) * 16.0f / 10.0f, 1.0f, 16.5f)); + float wave = params[PARAM_WAVE_1 + i].value + (inputs[INPUT_WAVE_1 + i].active?inputs[INPUT_WAVE_1 + i].value:0.0f); + double waveSection; + wave = modf(clamp(wave, 0.0f, 10.0f), &waveSection); + float w1 = 0.0f; + float w2 = 0.0f; + switch ((int)waveSection) { + case 0: + w1 = PO_Util::sin(offset * 2 * M_PI); + w2 = PO_Util::saw(offset); + break; + case 1: + w1 = PO_Util::saw(offset); + w2 = PO_Util::rsn(offset * 2 * M_PI); + break; + case 2: + w1 = PO_Util::rsn(offset * 2 * M_PI); + w2 = PO_Util::tri(offset); + break; + case 3: + w1 = PO_Util::tri(offset); + w2 = PO_Util::sqr(offset); + break; + case 4: + w1 = PO_Util::sqr(offset); + w2 = PO_Util::sin(offset * 2 * M_PI); + break; + case 5: + w1 = PO_Util::sin(offset * 2 * M_PI); + w2 = PO_Util::tri(offset); + break; + case 6: + w1 = PO_Util::tri(offset); + w2 = PO_Util::saw(offset); + break; + case 7: + w1 = PO_Util::saw(offset); + w2 = PO_Util::sqr(offset); + break; + case 8: + w1 = PO_Util::sqr(offset); + w2 = PO_Util::rsn(offset * 2 * M_PI); + break; + case 9: + w1 = PO_Util::rsn(offset * 2 * M_PI); + w2 = PO_Util::sin(offset * 2 * M_PI); + break; + default: + w2 = w1 = PO_Util::sin(offset * 2 * M_PI); + break; + } + outputs[OUTPUT_1 + i].value = w1 * (1.0f - wave) + w2 * wave; + } + } +} + +struct PO_Layout : ModuleWidget { + PO_Layout(PO_101 *module) : ModuleWidget(module) {} + void Layout() { + addParam(ParamWidget::create>(Vec(66, 39), module, PO_101::PARAM_FINE, -1.0f, +1.0f, 0.0f)); + addParam(ParamWidget::create>>>(Vec(121, 39), module, PO_101::PARAM_WAVE, 0.0f, +4.0f, 0.0f)); + + addInput(Port::create(Vec(45,19), Port::INPUT, module, PO_101::INPUT_NOTE_CV)); + + addOutput(Port::create(Vec(77.5,100), Port::OUTPUT, module, PO_101::OUTPUT_1)); + addOutput(Port::create(Vec(110,109), Port::OUTPUT, module, PO_101::OUTPUT_2)); + addOutput(Port::create(Vec(142.5,100), Port::OUTPUT, module, PO_101::OUTPUT_3)); + addOutput(Port::create(Vec(133.5,132.5), Port::OUTPUT, module, PO_101::OUTPUT_4)); + addOutput(Port::create(Vec(142.5,165), Port::OUTPUT, module, PO_101::OUTPUT_5)); + addOutput(Port::create(Vec(133.5,197.5), Port::OUTPUT, module, PO_101::OUTPUT_6)); + addOutput(Port::create(Vec(142.5,230), Port::OUTPUT, module, PO_101::OUTPUT_7)); + addOutput(Port::create(Vec(110,221), Port::OUTPUT, module, PO_101::OUTPUT_8)); + addOutput(Port::create(Vec(77.5,230), Port::OUTPUT, module, PO_101::OUTPUT_9)); + addOutput(Port::create(Vec(45,221), Port::OUTPUT, module, PO_101::OUTPUT_10)); + addOutput(Port::create(Vec(12.5,230), Port::OUTPUT, module, PO_101::OUTPUT_11)); + addOutput(Port::create(Vec(21.5,197.5), Port::OUTPUT, module, PO_101::OUTPUT_12)); + addOutput(Port::create(Vec(12.5,165), Port::OUTPUT, module, PO_101::OUTPUT_13)); + addOutput(Port::create(Vec(21.5,132.5), Port::OUTPUT, module, PO_101::OUTPUT_14)); + addOutput(Port::create(Vec(12.5,100), Port::OUTPUT, module, PO_101::OUTPUT_15)); + addOutput(Port::create(Vec(45,109), Port::OUTPUT, module, PO_101::OUTPUT_16)); + + for (int i = 0; i < 4; i++) { + addInput(Port::create(Vec(10 + 45 * i,260), Port::INPUT, module, PO_101::INPUT_PHASE_1 + i)); + addParam(ParamWidget::create>(Vec(3.5 + 45 * i, 290), module, PO_101::PARAM_PHASE_1 + i, -1.0f, +1.0f, 0.0f)); + addOutput(Port::create(Vec(10 + 45 * i,333), Port::OUTPUT, module, PO_101::OUTPUT_17 + i)); + } + } +}; + +struct PO101 : PO_Layout { + PO101(PO_101 *module) : PO_Layout(module) { + setPanel(SVG::load(assetPlugin(plugin, "res/PO-101.svg"))); + addParam(ParamWidget::create>(Vec(11, 39), module, PO_101::PARAM_TUNE, -54.0f, +54.0f, 0.0f)); + Layout(); + } +}; + +struct PO102 : PO_Layout { + PO102(PO_101 *module) : PO_Layout(module) { + setPanel(SVG::load(assetPlugin(plugin, "res/PO-102.svg"))); + addParam(ParamWidget::create>(Vec(11, 39), module, PO_101::PARAM_TUNE, -96.0f, 72.0f, -12.0f)); + module->baseFreq = 1.0f; + Layout(); + } +}; + +struct PO204 : ModuleWidget { + PO204(PO_204 *module) : ModuleWidget(module) { + setPanel(SVG::load(assetPlugin(plugin, "res/PO-204.svg"))); + addParam(ParamWidget::create>(Vec(60, 19), module, PO_204::PARAM_TUNE, -90.0f, +54.0f, 0.0f)); + addParam(ParamWidget::create>(Vec(105, 19), module, PO_204::PARAM_FINE, -1.0f, +1.0f, 0.0f)); + addInput(Port::create(Vec(17.5, 25.5), Port::INPUT, module, PO_204::INPUT_TUNE)); + + for (int i = 0; i < 4; i++) { + addParam(ParamWidget::create>(Vec(5, 89 + 70 * i), module, PO_204::PARAM_WAVE_1 + i, 0.0f, 10.0f, 5.0f)); + addParam(ParamWidget::create>(Vec(45, 89 + 70 * i), module, PO_204::PARAM_PHASE_1 + i, -1.0f, +1.0f, 0.0f)); + addParam(ParamWidget::create>>(Vec(85, 89 + 70 * i), module, PO_204::PARAM_MULT_1 + i, 1.0f, 16.0f, 1.0f)); + addInput(Port::create(Vec(4.5, 125 + 70 * i), Port::INPUT, module, PO_204::INPUT_WAVE_1 + i)); + addInput(Port::create(Vec(44.5, 125 + 70 * i), Port::INPUT, module, PO_204::INPUT_PHASE_1 + i)); + addInput(Port::create(Vec(84.5, 125 + 70 * i), Port::INPUT, module, PO_204::INPUT_MULT_1 + i)); + addOutput(Port::create(Vec(120.5, 125 + 70 * i), Port::OUTPUT, module, PO_204::OUTPUT_1 + i)); + } + } +}; + +} // namespace rack_plugin_SubmarineFree + +using namespace rack_plugin_SubmarineFree; + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, PO101) { + Model *modelPO101 = Model::create("Submarine (Free)", "PO-101", "PO-101 Phased VCO", OSCILLATOR_TAG, MULTIPLE_TAG, DIGITAL_TAG); + return modelPO101; +} + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, PO102) { + Model *modelPO102 = Model::create("Submarine (Free)", "PO-102", "PO-102 Phased LFO", OSCILLATOR_TAG, MULTIPLE_TAG, DIGITAL_TAG); + return modelPO102; +} + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, PO204) { + Model *modelPO204 = Model::create("Submarine (Free)", "PO-204", "PO-204 Phase Modulation Engine", OSCILLATOR_TAG, QUAD_TAG, DIGITAL_TAG); + return modelPO204; +} diff --git a/plugins/community/repos/SubmarineFree/src/SS1.cpp b/plugins/community/repos/SubmarineFree/src/SS1.cpp new file mode 100644 index 00000000..be82175f --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/SS1.cpp @@ -0,0 +1,174 @@ +#include "SubmarineFree.hpp" + +namespace rack_plugin_SubmarineFree { + +struct SS_112 : Module { + static constexpr int deviceCount = 12; + SS_112() : Module(0, deviceCount, 0, 0) {} +}; + +struct SS112 : ModuleWidget { + SS112(SS_112 *module) : ModuleWidget(module) { + setPanel(SVG::load(assetPlugin(plugin, "res/SS-112.svg"))); + for (int i = 0; i < SS_112::deviceCount; i++) { + addInput(Port::create(Vec(2.5,19 + i * 29), Port::INPUT, module, i)); + } + } +}; + +struct SS_208 : Module { + static constexpr int deviceCount = 8; + SS_208() : Module(0, 0, deviceCount, 0) { + outputs[0].value = M_PI; + outputs[1].value = 2 * M_PI; + outputs[2].value = M_E; + outputs[3].value = M_SQRT1_2; + outputs[4].value = M_SQRT2; + outputs[5].value = powf(3.0f, 0.5f); + outputs[6].value = powf(5.0f, 0.5f); + outputs[7].value = powf(7.0f, 0.5f); + } +}; + +struct SS208 : ModuleWidget { + SS208(SS_208 *module) : ModuleWidget(module) { + setPanel(SVG::load(assetPlugin(plugin, "res/SS-208.svg"))); + for (int i = 0; i < SS_208::deviceCount; i++) { + addOutput(Port::create(Vec(2.5,19 + 43 * i), Port::OUTPUT, module, i)); + } + } +}; + +struct SS_212 : Module { + static constexpr int deviceCount = 12; + int v = 0; + void setValues() { + for (int i = 0; i < deviceCount; i++) { + outputs[i].value = v + 1.0f * i / 12.0f; + } + } + + SS_212() : Module(0, 0, deviceCount, 0) { + setValues(); + } + + json_t *toJson() override { + json_t *rootJ = json_object(); + json_object_set_new(rootJ, "octave", json_integer(v)); + return rootJ; + } + + void fromJson(json_t *rootJ) override { + json_t *intJ = json_object_get(rootJ, "octave"); + if (intJ) + v = json_integer_value(intJ); + setValues(); + } +}; + +struct SS212 : ModuleWidget { + SS212(SS_212 *module) : ModuleWidget(module) { + setPanel(SVG::load(assetPlugin(plugin, "res/SS-212.svg"))); + for (int i = 0; i < SS_212::deviceCount; i++) { + addOutput(Port::create(Vec(2.5,19 + i * 29), Port::OUTPUT, module, i)); + } + } + + void appendContextMenu(Menu *menu) override; +}; + +struct SSMenuItem : MenuItem { + SS_212 *ss_212; + int v; + void onAction(EventAction &e) override { + ss_212->v = v; + ss_212->setValues(); + } + void step() override { + rightText = CHECKMARK(ss_212->v == v); + } +}; + +void SS212::appendContextMenu(Menu *menu) { + char label[20]; + menu->addChild(MenuEntry::create()); + SS_212 *ss_212 = dynamic_cast(this->module); + assert(ss_212); + for (int i = -5; i < 5; i++) { + sprintf(label, "Octave %d", i); + SSMenuItem *menuItem = MenuItem::create(label); + menuItem->ss_212 = ss_212; + menuItem->v = i; + menu->addChild(menuItem); + } +} + +struct SS_221 : Module { + static constexpr int deviceCount = 21; + SS_221() : Module(0, 0, deviceCount, 0) { + for (int i = 0; i < deviceCount; i++) { + outputs[i].value = 10.0f - i; + } + } +}; + +struct SS221 : ModuleWidget { + SS221(SS_221 *module) : ModuleWidget(module) { + setPanel(SVG::load(assetPlugin(plugin, "res/SS-221.svg"))); + for (int i = 0; i < SS_221::deviceCount; i++) { + addOutput(Port::create(Vec(2.5 + 45 * (i % 2),19 + i * 16), Port::OUTPUT, module, i)); + } + } +}; + +struct SS_220 : Module { + static constexpr int deviceCount = 12; + static constexpr int deviceSetCount = 10; + SS_220() : Module(0, 0, deviceCount * deviceSetCount, 0) { + for (int j = 0; j < deviceSetCount; j++) { + for (int i = 0; i < deviceCount; i++) { + outputs[j * deviceCount + i].value = (j - 5.0f) + 1.0f * i / 12.0f; + } + } + } +}; + +struct SS220 : ModuleWidget { + SS220(SS_220 *module) : ModuleWidget(module) { + setPanel(SVG::load(assetPlugin(plugin, "res/SS-220.svg"))); + for (int j = 0; j < SS_220::deviceSetCount; j++) { + for (int i = 0; i < SS_220::deviceCount; i++) { + addOutput(Port::create(Vec(2.5 + 30 * j, 19 + i * 29), Port::OUTPUT, module, j * SS_220::deviceCount + i)); + } + } + } +}; + +} // namespace rack_plugin_SubmarineFree + +using namespace rack_plugin_SubmarineFree; + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, SS112) { + Model *modelSS112 = Model::create("Submarine (Free)", "SS-112", "SS-112 12 Input Sinks", UTILITY_TAG); + return modelSS112; +} + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, SS208) { + Model *modelSS208 = Model::create("Submarine (Free)", "SS-208", "SS-208 8 Irrational Output Voltage Sources", UTILITY_TAG); + return modelSS208; +} + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, SS212) { + Model *modelSS212 = Model::create("Submarine (Free)", "SS-212", "SS-212 12 Chromatic Output Voltage Sources", UTILITY_TAG); + return modelSS212; +} + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, SS220) { + Model *modelSS220 = Model::create("Submarine (Free)", "SS-220", "SS-220 120 Chromatic Output Voltage Sources", UTILITY_TAG); + return modelSS220; +} + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, SS221) { + Model *modelSS221 = Model::create("Submarine (Free)", "SS-221", "SS-221 21 Output Voltage Sources", UTILITY_TAG); + return modelSS221; +} diff --git a/plugins/community/repos/SubmarineFree/src/SubmarineFree.cpp b/plugins/community/repos/SubmarineFree/src/SubmarineFree.cpp index bf33efba..8668b1c4 100644 --- a/plugins/community/repos/SubmarineFree/src/SubmarineFree.cpp +++ b/plugins/community/repos/SubmarineFree/src/SubmarineFree.cpp @@ -1,18 +1,55 @@ #include "SubmarineFree.hpp" +RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, AG104); RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, AG106); + +RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, AO106); +RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, AO112); +RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, AO118); +RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, AO124); +RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, AO136); + RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, BB120); + +RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, EO102); + RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, FF110); RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, FF120); RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, FF212); + RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, LA108); + +RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, LD103); RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, LD106); + +RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, NG106); RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, NG112); + +RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, OG104); RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, OG106); + +RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, PG104); RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, PG112); + RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, PO101); RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, PO102); RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, PO204); + +RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, SS112); + +RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, SS208); +RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, SS212); +RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, SS220); +RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, SS221); + +RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, TD116); + +RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, TD202); + +RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, TF101); + +RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, TM105); + RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, WK101); RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, WK205); @@ -22,6 +59,7 @@ RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, XF104); RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, XF201); RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, XF202); +RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, XG104); RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, XG106); RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, BP101); @@ -37,21 +75,58 @@ RACK_PLUGIN_MODEL_DECLARE(SubmarineFree, BP132); RACK_PLUGIN_INIT(SubmarineFree) { RACK_PLUGIN_INIT_ID(); + RACK_PLUGIN_INIT_VERSION("0.6.8"); // Add all Models defined throughout the plugin + RACK_PLUGIN_MODEL_ADD(SubmarineFree, AG104); RACK_PLUGIN_MODEL_ADD(SubmarineFree, AG106); + + RACK_PLUGIN_MODEL_ADD(SubmarineFree, AO106); + RACK_PLUGIN_MODEL_ADD(SubmarineFree, AO112); + RACK_PLUGIN_MODEL_ADD(SubmarineFree, AO118); + RACK_PLUGIN_MODEL_ADD(SubmarineFree, AO124); + RACK_PLUGIN_MODEL_ADD(SubmarineFree, AO136); + RACK_PLUGIN_MODEL_ADD(SubmarineFree, BB120); + + RACK_PLUGIN_MODEL_ADD(SubmarineFree, EO102); + RACK_PLUGIN_MODEL_ADD(SubmarineFree, FF110); RACK_PLUGIN_MODEL_ADD(SubmarineFree, FF120); RACK_PLUGIN_MODEL_ADD(SubmarineFree, FF212); + RACK_PLUGIN_MODEL_ADD(SubmarineFree, LA108); + + RACK_PLUGIN_MODEL_ADD(SubmarineFree, LD103); RACK_PLUGIN_MODEL_ADD(SubmarineFree, LD106); + + RACK_PLUGIN_MODEL_ADD(SubmarineFree, NG106); RACK_PLUGIN_MODEL_ADD(SubmarineFree, NG112); + + RACK_PLUGIN_MODEL_ADD(SubmarineFree, OG104); RACK_PLUGIN_MODEL_ADD(SubmarineFree, OG106); + + RACK_PLUGIN_MODEL_ADD(SubmarineFree, PG104); RACK_PLUGIN_MODEL_ADD(SubmarineFree, PG112); + RACK_PLUGIN_MODEL_ADD(SubmarineFree, PO101); RACK_PLUGIN_MODEL_ADD(SubmarineFree, PO102); RACK_PLUGIN_MODEL_ADD(SubmarineFree, PO204); + + RACK_PLUGIN_MODEL_ADD(SubmarineFree, SS112); + RACK_PLUGIN_MODEL_ADD(SubmarineFree, SS208); + RACK_PLUGIN_MODEL_ADD(SubmarineFree, SS212); + RACK_PLUGIN_MODEL_ADD(SubmarineFree, SS220); + RACK_PLUGIN_MODEL_ADD(SubmarineFree, SS221); + + RACK_PLUGIN_MODEL_ADD(SubmarineFree, TD116); + + RACK_PLUGIN_MODEL_ADD(SubmarineFree, TD202); + + RACK_PLUGIN_MODEL_ADD(SubmarineFree, TF101); + + RACK_PLUGIN_MODEL_ADD(SubmarineFree, TM105); + RACK_PLUGIN_MODEL_ADD(SubmarineFree, WK101); RACK_PLUGIN_MODEL_ADD(SubmarineFree, WK205); @@ -61,6 +136,7 @@ RACK_PLUGIN_INIT(SubmarineFree) { RACK_PLUGIN_MODEL_ADD(SubmarineFree, XF201); RACK_PLUGIN_MODEL_ADD(SubmarineFree, XF202); + RACK_PLUGIN_MODEL_ADD(SubmarineFree, XG104); RACK_PLUGIN_MODEL_ADD(SubmarineFree, XG106); RACK_PLUGIN_MODEL_ADD(SubmarineFree, BP101); diff --git a/plugins/community/repos/SubmarineFree/src/SubmarineFree.hpp b/plugins/community/repos/SubmarineFree/src/SubmarineFree.hpp index 19974142..4ca3d44e 100644 --- a/plugins/community/repos/SubmarineFree/src/SubmarineFree.hpp +++ b/plugins/community/repos/SubmarineFree/src/SubmarineFree.hpp @@ -9,3 +9,11 @@ RACK_PLUGIN_DECLARE(SubmarineFree); #endif // USE_VST2 #include "ComponentLibrary/components.hpp" + +struct SubHelper { + static std::shared_ptr LoadPanel(const char/*Plugin*/ *_plugin, const char *str, int num) { + char workingSpace[100]; + snprintf(workingSpace, 100, "res/%s%02d.svg", str, num); + return SVG::load(assetPlugin(_plugin, workingSpace)); + } +}; diff --git a/plugins/community/repos/SubmarineFree/src/TD1.cpp b/plugins/community/repos/SubmarineFree/src/TD1.cpp new file mode 100644 index 00000000..1cd3b358 --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/TD1.cpp @@ -0,0 +1,254 @@ +#include +#include +#include "SubmarineFree.hpp" +#include "window.hpp" +#include "torpedo.hpp" + +namespace rack_plugin_SubmarineFree { + +struct TD_116; + +struct TDInput : Torpedo::PatchInputPort { + TD_116 *tdModule; + TDInput(TD_116 *module, unsigned int portNum) : Torpedo::PatchInputPort((Module *)module, portNum) { tdModule = module; } + void received(std::string pluginName, std::string moduleName, json_t *rootJ) override; + NVGcolor decodeColor(std::string colorStr); +}; + +struct TD_116 : Module { + TDInput inPort = TDInput(this, 0); + Torpedo::PatchOutputPort outPort = Torpedo::PatchOutputPort(this, 0); + TD_116() : Module (0, 1, 1, 0) {outPort.size(1);} + void step() override { + inPort.process(); + outPort.process(); + } + void sendText(std::string text) { + json_t *rootJ = json_object();; + + // text + json_object_set_new(rootJ, "text", json_string(text.c_str())); + + outPort.send("SubmarineFree", "TDNotesText", rootJ); + } + std::string text; + int fontSize = 12; + NVGcolor fg = nvgRGB(0x28, 0xb0, 0xf3); + NVGcolor bg = nvgRGB(0,0,0); + int isDirty = false; + int isDirtyC = false; +}; + +struct TDText : LedDisplayTextField { + TD_116 *tdModule; + NVGcolor bgColor = nvgRGB(0x00, 0x00, 0x00); + int fontSize = 12; + TDText() { + color = nvgRGB(0x28, 0xb0, 0xf3); + } + void onTextChange() override { + LedDisplayTextField::onTextChange(); + tdModule->sendText(text); + } + int getTextPosition(Vec mousePos) override { + bndSetFont(font->handle); + int textPos = bndIconLabelTextPosition(rack::global_ui->window.gVg, textOffset.x, textOffset.y, + box.size.x - 2*textOffset.x, box.size.y - 2*textOffset.y, + -1, fontSize, text.c_str(), mousePos.x, mousePos.y); + bndSetFont(rack::global_ui->window.gGuiFont->handle); + return textPos; + } + void draw(NVGcontext *vg) override { + nvgScissor(vg, 0, 0, box.size.x, box.size.y); + //Background + nvgBeginPath(vg); + nvgRoundedRect(vg, 0, 0, box.size.x, box.size.y, 5.0); + nvgFillColor(vg, bgColor); + nvgFill(vg); + + //Text + if (font->handle >= 0) { + bndSetFont(font->handle); + + NVGcolor highlightColor = color; + highlightColor.a = 0.5; + int begin = min(cursor, selection); + int end = (this == rack::global_ui->widgets.gFocusedWidget) ? max(cursor, selection) : -1; + bndIconLabelCaret(vg, textOffset.x, textOffset.y, + box.size.x - 2*textOffset.x, box.size.y - 2*textOffset.y, + -1, color, fontSize, text.c_str(), highlightColor, begin, end); + } + nvgResetScissor(vg); + bndSetFont(rack::global_ui->window.gGuiFont->handle); + } +}; + +NVGcolor TDInput::decodeColor(std::string colorStr) { + int r = (colorStr[0] - 'A') * 16 + (colorStr[1] - 'A'); + int g = (colorStr[2] - 'A') * 16 + (colorStr[3] - 'A'); + int b = (colorStr[4] - 'A') * 16 + (colorStr[5] - 'A'); + return nvgRGB(r, g, b); +} + +void TDInput::received(std::string pluginName, std::string moduleName, json_t *rootJ) { + if (pluginName.compare("SubmarineFree")) return; + if (!moduleName.compare("TDNotesText")) { + json_t *text = json_object_get(rootJ, "text"); + if (text) { + tdModule->text.assign(json_string_value(text)); + tdModule->isDirty = true; + } + } + else if (!moduleName.compare("TDNotesColor")) { + json_t *size = json_object_get(rootJ, "size"); + if (size) { + tdModule->fontSize = json_number_value(size); + tdModule->isDirtyC = true; + } + json_t *fg = json_object_get(rootJ, "fg"); + if (fg) { + tdModule->fg = decodeColor(std::string(json_string_value(fg))); + tdModule->isDirtyC = true; + } + json_t *bg = json_object_get(rootJ, "bg"); + if (bg) { + tdModule->bg = decodeColor(std::string(json_string_value(bg))); + tdModule->isDirtyC = true; + } + } +} + +struct TD116 : ModuleWidget { + TDText *textField; + + TD116(TD_116 *module) : ModuleWidget(module) { + setPanel(SVG::load(assetPlugin(plugin, "res/TD-116.svg"))); + + addInput(Port::create(Vec(4,19), Port::INPUT, module, 0)); + addOutput(Port::create(Vec(211,19), Port::OUTPUT, module, 0)); + + textField = Widget::create(mm2px(Vec(3.39962, 15.8373))); + textField->box.size = mm2px(Vec(74.480, 102.753)); + textField->multiline = true; + textField->tdModule = module; + addChild(textField); + } + + json_t *toJson() override { + json_t *rootJ = ModuleWidget::toJson(); + + json_object_set_new(rootJ, "text", json_string(textField->text.c_str())); + json_object_set_new(rootJ, "size", json_real(textField->fontSize)); + json_object_set_new(rootJ, "fg", json_string(colorToHexString(textField->color).c_str())); + json_object_set_new(rootJ, "bg", json_string(colorToHexString(textField->bgColor).c_str())); + + return rootJ; + } + + void fromJson(json_t *rootJ) override { + ModuleWidget::fromJson(rootJ); + + json_t *textJ = json_object_get(rootJ, "text"); + if (textJ) + textField->text = json_string_value(textJ); + json_t *sizeJ = json_object_get(rootJ, "size"); + if (sizeJ) + textField->fontSize = json_number_value(sizeJ); + json_t *fgJ = json_object_get(rootJ, "fg"); + if (fgJ) { + if (json_is_object(fgJ)) + textField->color = jsonToColor(fgJ); + else + textField->color = colorFromHexString(json_string_value(fgJ)); + } + json_t *bgJ = json_object_get(rootJ, "bg"); + if (bgJ) { + if (json_is_object(bgJ)) + textField->bgColor = jsonToColor(bgJ); + else + textField->bgColor = colorFromHexString(json_string_value(bgJ)); + } + } + + void step() override { + TD_116 *tdModule = dynamic_cast(module); + if (tdModule->isDirty) { + textField->text = tdModule->text; + tdModule->isDirty = false; + } + if (tdModule->isDirtyC) { + textField->fontSize = tdModule->fontSize; + textField->color = tdModule->fg; + textField->bgColor = tdModule->bg; + tdModule->isDirtyC = false; + } + ModuleWidget::step(); + } + + void reset() override { + textField->fontSize = 12; + textField->text = ""; + textField->color = nvgRGB(0x28, 0xb0, 0xf3); + textField->bgColor = nvgRGB(0,0,0); + ModuleWidget::reset(); + } + + void appendContextMenu(Menu *menu) override; +}; + +struct TD116_MenuItem : MenuItem { + TD116 *widget; + NVGcolor color; + void onAction(EventAction &e) override { + widget->textField->tdModule->fg = color; + widget->textField->color = color; + } +}; + +void TD116::appendContextMenu(Menu *menu) { + menu->addChild(MenuEntry::create()); + TD116_MenuItem *m = MenuItem::create("Blue"); + m->widget = this; + m->color = nvgRGB(0x28, 0xb0, 0xf3); + menu->addChild(m); + + m = MenuItem::create("Yellow"); + m->widget = this; + m->color = nvgRGB(0xc9, 0xb7, 0x0e); + menu->addChild(m); + + m = MenuItem::create("Red"); + m->widget = this; + m->color = nvgRGB(0xff, 0x13, 0x13); + menu->addChild(m); + + m = MenuItem::create("Green"); + m->widget = this; + m->color = nvgRGB(0x0a, 0xff, 0x13); + menu->addChild(m); + + m = MenuItem::create("Orange"); + m->widget = this; + m->color = nvgRGB(0xff, 0xa5, 0x2d); + menu->addChild(m); + + m = MenuItem::create("Pink"); + m->widget = this; + m->color = nvgRGB(0xff, 0x7d, 0xec); + menu->addChild(m); + + m = MenuItem::create("White"); + m->widget = this; + m->color = nvgRGB(0xff, 0xff, 0xff); + menu->addChild(m); + +} + +} // namespace rack_plugin_SubmarineFree + +using namespace rack_plugin_SubmarineFree; + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, TD116) { + Model *modelTD116 = Model::create("Submarine (Free)", "TD-116", "TD-116 Text Display", VISUAL_TAG); + return modelTD116; +} diff --git a/plugins/community/repos/SubmarineFree/src/TD2.cpp b/plugins/community/repos/SubmarineFree/src/TD2.cpp new file mode 100644 index 00000000..554a9a41 --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/TD2.cpp @@ -0,0 +1,179 @@ +#include +#include +#include "SubmarineFree.hpp" +#include "window.hpp" +#include "torpedo.hpp" + +namespace rack_plugin_SubmarineFree { + +struct TDVText : LedDisplayTextField { + NVGcolor bgColor; + TDVText() { + multiline = false; + color = nvgRGB(0x28, 0xb0, 0xf3); + bgColor = nvgRGBA(0, 0, 0, 0); + } + void draw(NVGcontext *vg) override { + nvgScissor(vg, 0, 0, box.size.x, box.size.y); + + nvgBeginPath(vg); + nvgRoundedRect(vg, 0, 0, box.size.x, box.size.y, 2); + nvgFillColor(vg, bgColor); + nvgFill(vg); + + nvgTranslate(vg, 24, 0); + nvgRotate(vg, M_PI / 2.0f); + //Text + if (font->handle >= 0) { + bndSetFont(font->handle); + + NVGcolor highlightColor = color; + highlightColor.a = 0.5; + int begin = min(cursor, selection); + int end = (this == rack::global_ui->widgets.gFocusedWidget) ? max(cursor, selection) : -1; + bndIconLabelCaret(vg, textOffset.y, textOffset.x, + box.size.y - 2*textOffset.y, box.size.x - 2*textOffset.x, + -1, color, 28, text.c_str(), highlightColor, begin, end); + } + nvgResetScissor(vg); + bndSetFont(rack::global_ui->window.gGuiFont->handle); + } +}; + +struct TD202 : ModuleWidget { + TDVText *textField; + + TD202(Module *module) : ModuleWidget(module) { + setPanel(SVG::load(assetPlugin(plugin, "res/TD-202.svg"))); + + textField = Widget::create(Vec(2, 15)); + textField->box.size = Vec(26, 350); + addChild(textField); + } + + json_t *toJson() override { + json_t *rootJ = ModuleWidget::toJson(); + + json_object_set_new(rootJ, "text", json_string(textField->text.c_str())); + json_object_set_new(rootJ, "fg", json_string(colorToHexString(textField->color).c_str())); + json_object_set_new(rootJ, "bg", json_string(colorToHexString(textField->bgColor).c_str())); + + return rootJ; + } + + void fromJson(json_t *rootJ) override { + ModuleWidget::fromJson(rootJ); + + json_t *textJ = json_object_get(rootJ, "text"); + if (textJ) + textField->text = json_string_value(textJ); + json_t *fgJ = json_object_get(rootJ, "fg"); + if (fgJ) { + if (json_is_object(fgJ)) + textField->color = jsonToColor(fgJ); + else + textField->color = colorFromHexString(json_string_value(fgJ)); + } + json_t *bgJ = json_object_get(rootJ, "bg"); + if (bgJ) { + if (json_is_object(bgJ)) + textField->bgColor = jsonToColor(bgJ); + else + textField->bgColor = colorFromHexString(json_string_value(bgJ)); + } + } + + void reset() override { + textField->text = ""; + textField->multiline = false; + textField->color = nvgRGB(0x28, 0xb0, 0xf3); + textField->bgColor = nvgRGBA(0, 0, 0, 0); + ModuleWidget::reset(); + } + + void appendContextMenu(Menu *menu) override; +}; + +struct TD202_MenuItem : MenuItem { + TD202 *widget; + NVGcolor color; + void onAction(EventAction &e) override { + widget->textField->color = color; + } +}; + +struct TD202_MenuItemB : MenuItem { + TD202 *widget; + NVGcolor color; + void onAction(EventAction &e) override { + widget->textField->bgColor = color; + } +}; + +void TD202::appendContextMenu(Menu *menu) { + menu->addChild(MenuEntry::create()); + TD202_MenuItem *m = MenuItem::create("Blue"); + m->widget = this; + m->color = nvgRGB(0x28, 0xb0, 0xf3); + menu->addChild(m); + + m = MenuItem::create("Yellow"); + m->widget = this; + m->color = nvgRGB(0xc9, 0xb7, 0x0e); + menu->addChild(m); + + m = MenuItem::create("Red"); + m->widget = this; + m->color = nvgRGB(0xff, 0x13, 0x13); + menu->addChild(m); + + m = MenuItem::create("Green"); + m->widget = this; + m->color = nvgRGB(0x0a, 0xff, 0x13); + menu->addChild(m); + + m = MenuItem::create("Orange"); + m->widget = this; + m->color = nvgRGB(0xff, 0xa5, 0x2d); + menu->addChild(m); + + m = MenuItem::create("Pink"); + m->widget = this; + m->color = nvgRGB(0xff, 0x7d, 0xec); + menu->addChild(m); + + m = MenuItem::create("White"); + m->widget = this; + m->color = nvgRGB(0xff, 0xff, 0xff); + menu->addChild(m); + + m = MenuItem::create("Black"); + m->widget = this; + m->color = nvgRGB(0x00, 0x00, 0x00); + menu->addChild(m); + + menu->addChild(MenuEntry::create()); + TD202_MenuItemB *b = MenuItem::create("Background - None"); + b->widget = this; + b->color = nvgRGBA(0, 0, 0, 0); + menu->addChild(b); + + b = MenuItem::create("Background - Black"); + b->widget = this; + b->color = nvgRGB(0, 0, 0); + menu->addChild(b); + + b = MenuItem::create("Background - White"); + b->widget = this; + b->color = nvgRGB(0xff, 0xff, 0xff); + menu->addChild(b); +} + +} // namespace rack_plugin_SubmarineFree + +using namespace rack_plugin_SubmarineFree; + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, TD202) { + Model *modelTD202 = Model::create("Submarine (Free)", "TD-202", "TD-202 Vertical Text Display", VISUAL_TAG); + return modelTD202; +} diff --git a/plugins/community/repos/SubmarineFree/src/TF1.cpp b/plugins/community/repos/SubmarineFree/src/TF1.cpp new file mode 100644 index 00000000..d702daae --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/TF1.cpp @@ -0,0 +1,133 @@ +#include "SubmarineFree.hpp" +#include "torpedo.hpp" + +namespace rack_plugin_SubmarineFree { + +struct TF_101 : Module { + enum ParamIds { + PARAM_FG_RED, + PARAM_FG_GREEN, + PARAM_FG_BLUE, + PARAM_BG_RED, + PARAM_BG_GREEN, + PARAM_BG_BLUE, + PARAM_FONT_SIZE, + NUM_PARAMS + }; + enum InputIds { + INPUT_FG_RED, + INPUT_FG_GREEN, + INPUT_FG_BLUE, + INPUT_BG_RED, + INPUT_BG_GREEN, + INPUT_BG_BLUE, + INPUT_FONT_SIZE, + NUM_INPUTS + }; + enum OutputIds { + OUTPUT_TOR, + NUM_OUTPUTS + }; + enum LightIds { + LIGHT_FG_RED, + LIGHT_FG_GREEN, + LIGHT_FG_BLUE, + LIGHT_BG_RED, + LIGHT_BG_GREEN, + LIGHT_BG_BLUE, + NUM_LIGHTS + }; + + float prevValues[7]; + int isDirty = false; + Torpedo::PatchOutputPort outPort = Torpedo::PatchOutputPort(this, OUTPUT_TOR); + TF_101() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) { + prevValues[0] = 0.1569f; + prevValues[1] = 0.6902f; + prevValues[2] = 0.9529f; + prevValues[6] = 12.0f; + outPort.size(1); + } + void step() override; + std::string encodeColor(float r, float g, float b) { + std::string out; + out.push_back('A'+(int)(r * 255) / 16); + out.push_back('A'+(int)(r * 255) % 16); + out.push_back('A'+(int)(g * 255) / 16); + out.push_back('A'+(int)(g * 255) % 16); + out.push_back('A'+(int)(b * 255) / 16); + out.push_back('A'+(int)(b * 255) % 16); + + return out; + } +}; + +void TF_101::step() { + for (int i = 0; i < 6; i++) { + float newValue = clamp(params[PARAM_FG_RED + i].value + inputs[INPUT_FG_RED + i].value / 10.0f, 0.0f, 1.0f); + lights[LIGHT_FG_RED + i].value = newValue; + if (prevValues[i] != newValue) { + isDirty = true; + prevValues[i] = newValue; + } + } + float newValue = clamp(params[PARAM_FONT_SIZE].value + inputs[INPUT_FONT_SIZE].value * 2.0f, 6.0f, 26.0f); + if (prevValues[6] != newValue) { + isDirty = true; + prevValues[6] = newValue; + } + if (isDirty) { + isDirty = false; + json_t *rootJ = json_object(); + json_object_set_new(rootJ, "fg", json_string(encodeColor(prevValues[0], prevValues[1], prevValues[2]).c_str())); + json_object_set_new(rootJ, "bg", json_string(encodeColor(prevValues[3], prevValues[4], prevValues[5]).c_str())); + json_object_set_new(rootJ, "size", json_real(prevValues[6])); + outPort.send("SubmarineFree", "TDNotesColor", rootJ); + } + outPort.process(); +} + +struct WhiteLight : GrayModuleLightWidget { + WhiteLight() { + addBaseColor(nvgRGB(0xff, 0x00, 0x00)); + addBaseColor(nvgRGB(0x00, 0xff, 0x00)); + addBaseColor(nvgRGB(0x00, 0x00, 0xff)); + } +}; + + +struct TF101 : ModuleWidget { + TF101(TF_101 *module) : ModuleWidget(module) { + setPanel(SVG::load(assetPlugin(plugin, "res/TF-101.svg"))); + + addInput(Port::create(Vec(4,66.5), Port::INPUT, module, TF_101::INPUT_FG_RED)); + addInput(Port::create(Vec(4,106.5), Port::INPUT, module, TF_101::INPUT_FG_GREEN)); + addInput(Port::create(Vec(4,146.5), Port::INPUT, module, TF_101::INPUT_FG_BLUE)); + addInput(Port::create(Vec(4,200.5), Port::INPUT, module, TF_101::INPUT_BG_RED)); + addInput(Port::create(Vec(4,240.5), Port::INPUT, module, TF_101::INPUT_BG_GREEN)); + addInput(Port::create(Vec(4,280.5), Port::INPUT, module, TF_101::INPUT_BG_BLUE)); + addInput(Port::create(Vec(4,334.5), Port::INPUT, module, TF_101::INPUT_FONT_SIZE)); + + addParam(ParamWidget::create>(Vec(46, 60), module, TF_101::PARAM_FG_RED, 0.0f, 1.0f, 0.1569f)); + addParam(ParamWidget::create>(Vec(46, 100), module, TF_101::PARAM_FG_GREEN, 0.0f, 1.0f, 0.6902f)); + addParam(ParamWidget::create>(Vec(46, 140), module, TF_101::PARAM_FG_BLUE, 0.0f, 1.0f, 0.9529f)); + addParam(ParamWidget::create>(Vec(46, 194), module, TF_101::PARAM_BG_RED, 0.0f, 1.0f, 0.0f)); + addParam(ParamWidget::create>(Vec(46, 234), module, TF_101::PARAM_BG_GREEN, 0.0f, 1.0f, 0.0f)); + addParam(ParamWidget::create>(Vec(46, 274), module, TF_101::PARAM_BG_BLUE, 0.0f, 1.0f, 0.0f)); + addParam(ParamWidget::create>(Vec(46, 328), module, TF_101::PARAM_FONT_SIZE, 6.0f, 26.0f, 12.0f)); + + addChild(ModuleLightWidget::create>(Vec(10, 51), module, TF_101::LIGHT_FG_RED)); + addChild(ModuleLightWidget::create>(Vec(10, 185), module, TF_101::LIGHT_BG_RED)); + + addOutput(Port::create(Vec(61,19), Port::OUTPUT, module, TF_101::OUTPUT_TOR)); + } +}; + +} // namespace rack_plugin_SubmarineFree + +using namespace rack_plugin_SubmarineFree; + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, TF101) { + Model *modelTF101 = Model::create("Submarine (Free)", "TF-101", "TF-101 Text Display Format Control", VISUAL_TAG); + return modelTF101; +} diff --git a/plugins/community/repos/SubmarineFree/src/TM1.cpp b/plugins/community/repos/SubmarineFree/src/TM1.cpp new file mode 100644 index 00000000..b66b45bd --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/TM1.cpp @@ -0,0 +1,137 @@ +#include "SubmarineFree.hpp" +#include "torpedo.hpp" +#include "dsp/digital.hpp" + +namespace rack_plugin_SubmarineFree { + +struct TM_105; + +struct TM_105InPort : Torpedo::RawInputPort { + TM_105 *tmModule; + TM_105InPort(TM_105 *module, unsigned int portNum) : RawInputPort((Module *)module, portNum) {tmModule = module;} + void received(std::string appId, std::string message) override; + void error(unsigned int errorType) override; +}; + +struct TM_Msg { + std::string appId; + std::string msg; +}; + +struct TM_105 : Module { + enum ParamIds { + NUM_PARAMS + }; + enum InputIds { + INPUT_1, + INPUT_2, + INPUT_3, + INPUT_4, + INPUT_5, + NUM_INPUTS + }; + enum OutputIds { + OUTPUT_TOR, + NUM_OUTPUTS + }; + enum LightIds { + LIGHT_Q_1, + LIGHT_Q_2, + LIGHT_Q_3, + LIGHT_Q_4, + LIGHT_Q_5, + LIGHT_M_1, + LIGHT_M_2, + LIGHT_M_3, + LIGHT_M_4, + LIGHT_M_5, + LIGHT_E_1, + LIGHT_E_2, + LIGHT_E_3, + LIGHT_E_4, + LIGHT_E_5, + NUM_LIGHTS + }; + + std::vector queue; + unsigned int count = 0; + unsigned int index = 0; + TM_105InPort inPort1 = TM_105InPort(this, INPUT_1); + TM_105InPort inPort2 = TM_105InPort(this, INPUT_2); + TM_105InPort inPort3 = TM_105InPort(this, INPUT_3); + TM_105InPort inPort4 = TM_105InPort(this, INPUT_4); + TM_105InPort inPort5 = TM_105InPort(this, INPUT_5); + PulseGenerator msgPulses[5]; + PulseGenerator errPulses[5]; + Torpedo::RawOutputPort outPort = Torpedo::RawOutputPort(this, OUTPUT_TOR); + TM_105() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) { + for (unsigned int i = 0; i < 5; i++) { + queue.push_back(TM_Msg()); + } + } + void step() override; +}; + +void TM_105InPort::received(std::string appId, std::string msg) { + if (tmModule->count >= 5) { + return; + } + unsigned int newPos = (tmModule->index + tmModule->count) % 5; + tmModule->queue[newPos].appId.assign(appId); + tmModule->queue[newPos].msg.assign(msg); + tmModule->count++; + tmModule->msgPulses[_portNum - TM_105::INPUT_1].trigger(0.1f); +} + +void TM_105InPort::error(unsigned int errorType) { + tmModule->errPulses[_portNum - TM_105::INPUT_1].trigger(0.1f); +} + +void TM_105::step() { + inPort1.process(); + inPort2.process(); + inPort3.process(); + inPort4.process(); + inPort5.process(); + if (!outPort.isBusy()) { + if (count) { + unsigned int sendPos = (count + index) % 5; + outPort.send(queue[sendPos].appId, queue[sendPos].msg); + index++; + index %= 5; + count--; + } + } + for(unsigned int i = 0; i < 5; i++) { + lights[LIGHT_Q_1 + i].value = count > i; + lights[LIGHT_M_1 + i].value = msgPulses[i].process(engineGetSampleTime()); + lights[LIGHT_E_1 + i].value = errPulses[i].process(engineGetSampleTime()); + } + outPort.process(); +} + +struct TM105 : ModuleWidget { + TM105(TM_105 *module) : ModuleWidget(module) { + setPanel(SVG::load(assetPlugin(plugin, "res/TM-105.svg"))); + for (unsigned int i = 0; i < 5; i++) { + addInput(Port::create(Vec(2.5,29 + 32 * i), Port::INPUT, module, TM_105::INPUT_1 + i)); + addChild(ModuleLightWidget::create>(Vec(2.5, 53 + 32 * i), module, TM_105::LIGHT_M_1 + i)); + addChild(ModuleLightWidget::create>(Vec(24.5, 53 + 32 * i), module, TM_105::LIGHT_E_1 + i)); + } + addChild(ModuleLightWidget::create>(Vec(13.5, 260), module, TM_105::LIGHT_Q_1)); + addChild(ModuleLightWidget::create>(Vec(13.5, 265), module, TM_105::LIGHT_Q_2)); + addChild(ModuleLightWidget::create>(Vec(13.5, 270), module, TM_105::LIGHT_Q_3)); + addChild(ModuleLightWidget::create>(Vec(13.5, 275), module, TM_105::LIGHT_Q_4)); + addChild(ModuleLightWidget::create>(Vec(13.5, 280), module, TM_105::LIGHT_Q_5)); + addOutput(Port::create(Vec(2.5,232), Port::OUTPUT, module, TM_105::OUTPUT_TOR)); + } +}; + +} // namespace rack_plugin_SubmarineFree + +using namespace rack_plugin_SubmarineFree; + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, TM105) { + Model *modelTM105 = Model::create("Submarine (Free)", "TM-105", "TM-105 Torpedo Message Merge", UTILITY_TAG); + return modelTM105; +} diff --git a/plugins/community/repos/SubmarineFree/src/UpdateRing.hpp b/plugins/community/repos/SubmarineFree/src/UpdateRing.hpp new file mode 100644 index 00000000..546f6945 --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/UpdateRing.hpp @@ -0,0 +1,29 @@ +// +// UpdateRing is similar in approach to double buffering +// +// UpdateRing provides a number (2) of objects so that the +// module can communicate with the moduleWidget. Previously I +// have used mutexes to do this, but I would rather not use +// a blocking lock_guard in the audio thread. +// +// Double buffering does not offer the same guarantees, but if +// the code is kept tight, it should be good enough for practical purposes. +// +// When the module has something to communicate, it asks for a pointer to the +// background object, It writes into this, and the swaps the buffers +// +// When the moduleWidget is checking for something to read, it asks for +// a pointer to the foreground object, which it then can read. +// +// This process should minimize the risk of tearing artifacts in the process +// + +template +struct UpdateRing { + T items[2]; + unsigned int bufCount = 0; + T* fg() { return items + (bufCount % 2); } + T* bg() { return items + ((bufCount + 1) % 2); } + void swap() { bufCount++; }; +}; + diff --git a/plugins/community/repos/SubmarineFree/src/WK-101.cpp b/plugins/community/repos/SubmarineFree/src/WK12.cpp similarity index 81% rename from plugins/community/repos/SubmarineFree/src/WK-101.cpp rename to plugins/community/repos/SubmarineFree/src/WK12.cpp index 09a51724..5bfbbd2a 100644 --- a/plugins/community/repos/SubmarineFree/src/WK-101.cpp +++ b/plugins/community/repos/SubmarineFree/src/WK12.cpp @@ -3,6 +3,14 @@ #include "torpedo.hpp" #include #include +#include "UpdateRing.hpp" + +namespace rack_plugin_SubmarineFree { + +struct WK_Update { + float offsets[12]; + int isDirty = false; +}; struct WK_Tuning { std::string name; @@ -11,20 +19,13 @@ struct WK_Tuning { std::vector tunings; -// (todo) mutex int tuningsLoaded = false; -namespace rack_plugin_SubmarineFree { - -#ifdef USE_VST2 -#define Plugin const char -#endif // USE_VST2 - struct WK_Tunings { static void loadTuningsFromWK(const char *path); - static void loadTuningsFromScala(Plugin *_plugin); + static void loadTuningsFromScala(const char /*Plugin*/ *_plugin); static void loadScalaFile(std::string path); - static void loadTunings(Plugin *_plugin) { + static void loadTunings(const char /*Plugin*/ *_plugin) { if (tuningsLoaded) return; tuningsLoaded = true; @@ -73,7 +74,7 @@ void WK_Tunings::loadTuningsFromWK(const char *path) { } else { std::string message = stringf("SubmarineFree WK: JSON parsing error at %s %d:%d %s", error.source, error.line, error.column, error.text); - //warn(message.c_str()); + warn(message.c_str()); } fclose(file); } @@ -116,7 +117,7 @@ void WK_Tunings::loadScalaFile(std::string path) { line.append(1,c); strings[i].erase(0,1); if (!std::isdigit(c) && (c != '/') && (c != '.')) { - //warn("SubmarineFree WK: Scala file format error in %s", stringFilename(path).c_str()); + warn("SubmarineFree WK: Scala file format error in %s", stringFilename(path).c_str()); return; } if (c == '.') @@ -124,7 +125,7 @@ void WK_Tunings::loadScalaFile(std::string path) { if (c == '/' && !ratio) ratio = line.size(); if (decimal && ratio) { - //warn("SubmarineFree WK: Scala file format error in %s", stringFilename(path).c_str()); + warn("SubmarineFree WK: Scala file format error in %s", stringFilename(path).c_str()); return; } } @@ -133,13 +134,13 @@ void WK_Tunings::loadScalaFile(std::string path) { float d = std::stof(line, nullptr); d -= (i-1) * 100.0; if ((d < -50.0) || (d > 50.0)) { - //warn("SubmarineFree WK: Scala file format error in %s", stringFilename(path).c_str()); + warn("SubmarineFree WK: Scala file format error in %s", stringFilename(path).c_str()); return; } tuning.offsets[(i-1)%12] = d; } catch (std::exception &err) { - //warn("SubmarineFree WK: Scala file format error in %s", stringFilename(path).c_str()); + warn("SubmarineFree WK: Scala file format error in %s", stringFilename(path).c_str()); return; } } @@ -151,20 +152,20 @@ void WK_Tunings::loadScalaFile(std::string path) { int inum = std::stoi(num,nullptr); int idenom = std::stoi(denom, nullptr); if (!idenom) { - //warn("SubmarineFree WK: Scala file format error in %s", stringFilename(path).c_str()); + warn("SubmarineFree WK: Scala file format error in %s", stringFilename(path).c_str()); return; } float r = (1.0f * inum / idenom); float d = 1200.0 * log2(r); d -= (i-1) * 100.0; if ((d < -50.0) || (d > 50.0)) { - //warn("SubmarineFree WK: Scala file format error in %s", stringFilename(path).c_str()); + warn("SubmarineFree WK: Scala file format error in %s", stringFilename(path).c_str()); return; } tuning.offsets[(i-1)%12] = d; } catch (std::exception &err) { - //warn("SubmarineFree WK: Scala file format error in %s", stringFilename(path).c_str()); + warn("SubmarineFree WK: Scala file format error in %s", stringFilename(path).c_str()); return; } } @@ -174,13 +175,13 @@ void WK_Tunings::loadScalaFile(std::string path) { float d = 1200.0 * log2(inum); d -= (i-1) * 100.0; if ((d < -50.0) || (d > 50.0)) { - //warn("SubmarineFree WK: Scala file format error in %s", stringFilename(path).c_str()); + warn("SubmarineFree WK: Scala file format error in %s", stringFilename(path).c_str()); return; } tuning.offsets[(i-1)%12] = d; } catch (std::exception &err) { - //warn("SubmarineFree WK: Scala file format error in %s", stringFilename(path).c_str()); + warn("SubmarineFree WK: Scala file format error in %s", stringFilename(path).c_str()); return; } } @@ -191,12 +192,12 @@ void WK_Tunings::loadScalaFile(std::string path) { tunings[index].name = tuning.name; for (int i = 0; i < 12; i++) tunings[index].offsets[i] = tuning.offsets[i]; - //info("SubmarineFree WK: Loaded Scala file %s", tuning.name.c_str()); + info("SubmarineFree WK: Loaded Scala file %s", tuning.name.c_str()); } } -void WK_Tunings::loadTuningsFromScala(Plugin *_plugin) { +void WK_Tunings::loadTuningsFromScala(const char /*Plugin*/ *_plugin) { std::vector dirList = systemListEntries(assetPlugin(_plugin, "Scala")); for (auto entry : dirList) { if (systemIsDirectory(entry)) continue; @@ -255,14 +256,20 @@ struct WK_101 : Module { NUM_LIGHTS }; float tunings[12]; - int isDirty = 0; int toSend = 0; - std::mutex mtx; + UpdateRing updateRing; Torpedo::PatchOutputPort outPort = Torpedo::PatchOutputPort(this, OUTPUT_TOR); WK101_InputPort inPort = WK101_InputPort(this, INPUT_TOR); - WK_101() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} + WK_101() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {outPort.size(5);} void step() override; + void PrepareUpdate() { + WK_Update *upd = updateRing.bg(); + for (int i = 0; i < 12; i++) + upd->offsets[i] = tunings[i]; + upd->isDirty = true; + updateRing.swap(); + } }; void WK_101::step() { @@ -297,10 +304,13 @@ void WK101_InputPort::received(std::string pluginName, std::string moduleName, j tunings[i] = json_number_value(j1); } { - std::lock_guard guard(wkModule->mtx); + //std::lock_guard guard(wkModule->mtx); + //wkModule->isDirty = true; + WK_Update *upd = wkModule->updateRing.bg(); for (int i = 0; i < 12; i++) - wkModule->tunings[i] = tunings[i]; - wkModule->isDirty = true; + upd->offsets[i] = tunings[i]; + upd->isDirty = true; + wkModule->updateRing.swap(); } } @@ -331,15 +341,15 @@ struct WK101_MenuItem : MenuItem { void onAction(EventAction &e) override { for (int i = 0; i < 12; i++) module->tunings[i] = tunings[index].offsets[i]; - module->isDirty = true; + module->PrepareUpdate(); module->toSend = true; } }; -struct WK_Param : sub_knob_med { +struct WK_Param : MedKnob { void onChange(EventChange &e) override { - sub_knob_med::onChange(e); + MedKnob::onChange(e); WK_101 *module = dynamic_cast(this->module); module->tunings[paramId - WK_101::PARAM_1] = value; module->toSend = true; @@ -351,10 +361,10 @@ struct WK101 : ModuleWidget { WK101(WK_101 *module) : ModuleWidget(module) { setPanel(SVG::load(assetPlugin(plugin, "res/WK-101.svg"))); - addInput(Port::create(Vec(4,29), Port::INPUT, module, WK_101::INPUT_CV)); - addOutput(Port::create(Vec(43,29), Port::OUTPUT, module, WK_101::OUTPUT_CV)); - addInput(Port::create(Vec(82,29), Port::INPUT, module, WK_101::INPUT_TOR)); - addOutput(Port::create(Vec(121,29), Port::OUTPUT, module, WK_101::OUTPUT_TOR)); + addInput(Port::create(Vec(4,29), Port::INPUT, module, WK_101::INPUT_CV)); + addOutput(Port::create(Vec(43,29), Port::OUTPUT, module, WK_101::OUTPUT_CV)); + addInput(Port::create(Vec(82,29), Port::INPUT, module, WK_101::INPUT_TOR)); + addOutput(Port::create(Vec(121,29), Port::OUTPUT, module, WK_101::OUTPUT_TOR)); for (int i = 0; i < 5; i++) { @@ -402,11 +412,13 @@ void WK101::step() { int isDirty = 0; WK_101 *module = dynamic_cast(this->module); { - std::lock_guard guard(module->mtx); - if (module->isDirty) { + //std::lock_guard guard(module->mtx); + WK_Update *upd = module->updateRing.fg(); + if (upd->isDirty) { for (int i = 0; i < 12; i++) - tunings[i] = module->tunings[i]; - isDirty = 1; + tunings[i] = upd->offsets[i]; + upd->isDirty = false; + isDirty = true; } } if (isDirty) { @@ -512,10 +524,10 @@ struct WK205 : ModuleWidget { WK205(WK_205 *module) : ModuleWidget(module) { setPanel(SVG::load(assetPlugin(plugin, "res/WK-205.svg"))); - addInput(Port::create(Vec(2.5,19), Port::INPUT, module, WK_205::INPUT_TOR)); + addInput(Port::create(Vec(2.5,19), Port::INPUT, module, WK_205::INPUT_TOR)); for (int i = 0; i < WK_205::deviceCount; i++) { - addInput(Port::create(Vec(2.5,63 + i * 60), Port::INPUT, module, WK_205::INPUT_CV_1 + i)); - addOutput(Port::create(Vec(2.5,92 + i * 60), Port::OUTPUT, module, WK_205::OUTPUT_CV_1 + i)); + addInput(Port::create(Vec(2.5,63 + i * 60), Port::INPUT, module, WK_205::INPUT_CV_1 + i)); + addOutput(Port::create(Vec(2.5,92 + i * 60), Port::OUTPUT, module, WK_205::OUTPUT_CV_1 + i)); } WK_Tunings::loadTunings(plugin); @@ -539,11 +551,10 @@ void WK205::appendContextMenu(Menu *menu) { using namespace rack_plugin_SubmarineFree; RACK_PLUGIN_MODEL_INIT(SubmarineFree, WK101) { - Model *modelWK101 = Model::create("SubmarineFree", "WK-101", "WK-101 Das Wohltemperierte Klavier", QUANTIZER_TAG, TUNER_TAG); - return modelWK101; + Model *modelWK101 = Model::create("Submarine (Free)", "WK-101", "WK-101 Das Wohltemperierte Klavier", QUANTIZER_TAG, TUNER_TAG); } RACK_PLUGIN_MODEL_INIT(SubmarineFree, WK205) { - Model *modelWK205 = Model::create("SubmarineFree", "WK-205", "WK-205 Das Wohltemperierte Klavier Nano", QUANTIZER_TAG, TUNER_TAG, MULTIPLE_TAG); + Model *modelWK205 = Model::create("Submarine (Free)", "WK-205", "WK-205 Das Wohltemperierte Klavier Nano", QUANTIZER_TAG, TUNER_TAG, MULTIPLE_TAG); return modelWK205; } diff --git a/plugins/community/repos/SubmarineFree/src/XF-101.cpp b/plugins/community/repos/SubmarineFree/src/XF-101.cpp index 14268fa1..76d9490b 100644 --- a/plugins/community/repos/SubmarineFree/src/XF-101.cpp +++ b/plugins/community/repos/SubmarineFree/src/XF-101.cpp @@ -59,11 +59,11 @@ struct XF101 : ModuleWidget { XF_LightKnob *fader; setPanel(SVG::load(assetPlugin(plugin, "res/XF-101.svg"))); - addInput(Port::create(Vec(27.5,18), Port::INPUT, module, XF_101::INPUT_A_1)); - addInput(Port::create(Vec(127.5,18), Port::INPUT, module, XF_101::INPUT_B_1)); - addInput(Port::create(Vec(27.5,74), Port::INPUT, module, XF_101::INPUT_CV_1)); + addInput(Port::create(Vec(27.5,18), Port::INPUT, module, XF_101::INPUT_A_1)); + addInput(Port::create(Vec(127.5,18), Port::INPUT, module, XF_101::INPUT_B_1)); + addInput(Port::create(Vec(27.5,74), Port::INPUT, module, XF_101::INPUT_CV_1)); - addOutput(Port::create(Vec(127.5,74), Port::OUTPUT, module, XF_101::OUTPUT_1)); + addOutput(Port::create(Vec(127.5,74), Port::OUTPUT, module, XF_101::OUTPUT_1)); addParam(ParamWidget::create(Vec(41, 46), module, XF_101::PARAM_CV_1, 0.0f, 1.0f, 0.0f)); addParam(ParamWidget::create(Vec(125, 43.5), module, XF_101::PARAM_MODE_1, 0.0f, 2.0f, 0.0f)); @@ -83,6 +83,6 @@ struct XF101 : ModuleWidget { using namespace rack_plugin_SubmarineFree; RACK_PLUGIN_MODEL_INIT(SubmarineFree, XF101) { - Model *modelXF101 = Model::create("SubmarineFree", "XF-101", "XF-101 Single Mono Cross Fader", MIXER_TAG); + Model *modelXF101 = Model::create("Submarine (Free)", "XF-101", "XF-101 Single Mono Cross Fader", MIXER_TAG); return modelXF101; } diff --git a/plugins/community/repos/SubmarineFree/src/XF-102.cpp b/plugins/community/repos/SubmarineFree/src/XF-102.cpp index a75eae1c..2098a616 100644 --- a/plugins/community/repos/SubmarineFree/src/XF-102.cpp +++ b/plugins/community/repos/SubmarineFree/src/XF-102.cpp @@ -84,11 +84,11 @@ struct XF102 : ModuleWidget { setPanel(SVG::load(assetPlugin(plugin, "res/XF-102.svg"))); for (int i = 0; i < XF_102::deviceCount; i++) { int offset = 88 * i; - addInput(Port::create(Vec(27.5,18 + offset), Port::INPUT, module, XF_102::INPUT_A_1 + i)); - addInput(Port::create(Vec(127.5,18 + offset), Port::INPUT, module, XF_102::INPUT_B_1 + i)); - addInput(Port::create(Vec(27.5,74 + offset), Port::INPUT, module, XF_102::INPUT_CV_1 + i)); + addInput(Port::create(Vec(27.5,18 + offset), Port::INPUT, module, XF_102::INPUT_A_1 + i)); + addInput(Port::create(Vec(127.5,18 + offset), Port::INPUT, module, XF_102::INPUT_B_1 + i)); + addInput(Port::create(Vec(27.5,74 + offset), Port::INPUT, module, XF_102::INPUT_CV_1 + i)); - addOutput(Port::create(Vec(127.5,74 + offset), Port::OUTPUT, module, XF_102::OUTPUT_1 + i)); + addOutput(Port::create(Vec(127.5,74 + offset), Port::OUTPUT, module, XF_102::OUTPUT_1 + i)); addParam(ParamWidget::create(Vec(41, 46 + offset), module, XF_102::PARAM_CV_1 + i, 0.0f, 1.0f, 0.0f)); addParam(ParamWidget::create(Vec(125, 43.5 + offset), module, XF_102::PARAM_MODE_1 + i, 0.0f, 2.0f, 0.0f)); @@ -111,6 +111,6 @@ struct XF102 : ModuleWidget { using namespace rack_plugin_SubmarineFree; RACK_PLUGIN_MODEL_INIT(SubmarineFree, XF102) { - Model *modelXF102 = Model::create("SubmarineFree", "XF-102", "XF-102 Dual Mono Cross Fader", MIXER_TAG, DUAL_TAG); + Model *modelXF102 = Model::create("Submarine (Free)", "XF-102", "XF-102 Dual Mono Cross Fader", MIXER_TAG, DUAL_TAG); return modelXF102; } diff --git a/plugins/community/repos/SubmarineFree/src/XF-104.cpp b/plugins/community/repos/SubmarineFree/src/XF-104.cpp index 92687331..82daba87 100644 --- a/plugins/community/repos/SubmarineFree/src/XF-104.cpp +++ b/plugins/community/repos/SubmarineFree/src/XF-104.cpp @@ -91,11 +91,11 @@ struct XF104 : ModuleWidget { setPanel(SVG::load(assetPlugin(plugin, "res/XF-104.svg"))); for (int i = 0; i < XF_104::deviceCount; i++) { int offset = 88 * i; - addInput(Port::create(Vec(27.5,18 + offset), Port::INPUT, module, XF_104::INPUT_A_1 + i)); - addInput(Port::create(Vec(127.5,18 + offset), Port::INPUT, module, XF_104::INPUT_B_1 + i)); - addInput(Port::create(Vec(27.5,74 + offset), Port::INPUT, module, XF_104::INPUT_CV_1 + i)); + addInput(Port::create(Vec(27.5,18 + offset), Port::INPUT, module, XF_104::INPUT_A_1 + i)); + addInput(Port::create(Vec(127.5,18 + offset), Port::INPUT, module, XF_104::INPUT_B_1 + i)); + addInput(Port::create(Vec(27.5,74 + offset), Port::INPUT, module, XF_104::INPUT_CV_1 + i)); - addOutput(Port::create(Vec(127.5,74 + offset), Port::OUTPUT, module, XF_104::OUTPUT_1 + i)); + addOutput(Port::create(Vec(127.5,74 + offset), Port::OUTPUT, module, XF_104::OUTPUT_1 + i)); addParam(ParamWidget::create(Vec(41, 46 + offset), module, XF_104::PARAM_CV_1 + i, 0.0f, 1.0f, 0.0f)); addParam(ParamWidget::create(Vec(125, 43.5 + offset), module, XF_104::PARAM_MODE_1 + i, 0.0f, 2.0f, 0.0f)); @@ -130,6 +130,6 @@ struct XF104 : ModuleWidget { using namespace rack_plugin_SubmarineFree; RACK_PLUGIN_MODEL_INIT(SubmarineFree, XF104) { - Model *modelXF104 = Model::create("SubmarineFree", "XF-104", "XF-104 Quad Mono Cross Fader", MIXER_TAG, QUAD_TAG); + Model *modelXF104 = Model::create("Submarine (Free)", "XF-104", "XF-104 Quad Mono Cross Fader", MIXER_TAG, QUAD_TAG); return modelXF104; } diff --git a/plugins/community/repos/SubmarineFree/src/XF-201.cpp b/plugins/community/repos/SubmarineFree/src/XF-201.cpp index d3d898f5..df288067 100644 --- a/plugins/community/repos/SubmarineFree/src/XF-201.cpp +++ b/plugins/community/repos/SubmarineFree/src/XF-201.cpp @@ -63,14 +63,14 @@ struct XF201 : ModuleWidget { setPanel(SVG::load(assetPlugin(plugin, "res/XF-201.svg"))); for (int i = 0; i < XF_201::deviceCount; i++) { int offset = 176 * i; - addInput(Port::create(Vec(3,18 + offset), Port::INPUT, module, XF_201::INPUT_A_1 + i)); - addInput(Port::create(Vec(3,45 + offset), Port::INPUT, module, XF_201::INPUT_AR_1 + i)); - addInput(Port::create(Vec(92,18 + offset), Port::INPUT, module, XF_201::INPUT_B_1 + i)); - addInput(Port::create(Vec(92,45 + offset), Port::INPUT, module, XF_201::INPUT_BR_1 + i)); - addInput(Port::create(Vec(3,120 + offset), Port::INPUT, module, XF_201::INPUT_CV_1 + i)); + addInput(Port::create(Vec(3,18 + offset), Port::INPUT, module, XF_201::INPUT_A_1 + i)); + addInput(Port::create(Vec(3,45 + offset), Port::INPUT, module, XF_201::INPUT_AR_1 + i)); + addInput(Port::create(Vec(92,18 + offset), Port::INPUT, module, XF_201::INPUT_B_1 + i)); + addInput(Port::create(Vec(92,45 + offset), Port::INPUT, module, XF_201::INPUT_BR_1 + i)); + addInput(Port::create(Vec(3,120 + offset), Port::INPUT, module, XF_201::INPUT_CV_1 + i)); - addOutput(Port::create(Vec(92,93 + offset), Port::OUTPUT, module, XF_201::OUTPUT_1 + i)); - addOutput(Port::create(Vec(92,120 + offset), Port::OUTPUT, module, XF_201::OUTPUTR_1 + i)); + addOutput(Port::create(Vec(92,93 + offset), Port::OUTPUT, module, XF_201::OUTPUT_1 + i)); + addOutput(Port::create(Vec(92,120 + offset), Port::OUTPUT, module, XF_201::OUTPUTR_1 + i)); addParam(ParamWidget::create(Vec(28, 154.5 + offset), module, XF_201::PARAM_CV_1 + i, 0.0f, 1.0f, 0.0f)); addParam(ParamWidget::create(Vec(65, 152 + offset), module, XF_201::PARAM_MODE_1 + i, 0.0f, 2.0f, 0.0f)); @@ -92,6 +92,6 @@ struct XF201 : ModuleWidget { using namespace rack_plugin_SubmarineFree; RACK_PLUGIN_MODEL_INIT(SubmarineFree, XF201) { - Model *modelXF201 = Model::create("SubmarineFree", "XF-201", "XF-201 Single Stereo Cross Fader", MIXER_TAG); + Model *modelXF201 = Model::create("Submarine (Free)", "XF-201", "XF-201 Single Stereo Cross Fader", MIXER_TAG); return modelXF201; } diff --git a/plugins/community/repos/SubmarineFree/src/XF-202.cpp b/plugins/community/repos/SubmarineFree/src/XF-202.cpp index caffc108..3b719b91 100644 --- a/plugins/community/repos/SubmarineFree/src/XF-202.cpp +++ b/plugins/community/repos/SubmarineFree/src/XF-202.cpp @@ -64,14 +64,14 @@ struct XF202 : ModuleWidget { setPanel(SVG::load(assetPlugin(plugin, "res/XF-202.svg"))); for (int i = 0; i < XF_202::deviceCount; i++) { int offset = 176 * i; - addInput(Port::create(Vec(3,18 + offset), Port::INPUT, module, XF_202::INPUT_A_1 + i)); - addInput(Port::create(Vec(3,45 + offset), Port::INPUT, module, XF_202::INPUT_AR_1 + i)); - addInput(Port::create(Vec(92,18 + offset), Port::INPUT, module, XF_202::INPUT_B_1 + i)); - addInput(Port::create(Vec(92,45 + offset), Port::INPUT, module, XF_202::INPUT_BR_1 + i)); - addInput(Port::create(Vec(3,120 + offset), Port::INPUT, module, XF_202::INPUT_CV_1 + i)); + addInput(Port::create(Vec(3,18 + offset), Port::INPUT, module, XF_202::INPUT_A_1 + i)); + addInput(Port::create(Vec(3,45 + offset), Port::INPUT, module, XF_202::INPUT_AR_1 + i)); + addInput(Port::create(Vec(92,18 + offset), Port::INPUT, module, XF_202::INPUT_B_1 + i)); + addInput(Port::create(Vec(92,45 + offset), Port::INPUT, module, XF_202::INPUT_BR_1 + i)); + addInput(Port::create(Vec(3,120 + offset), Port::INPUT, module, XF_202::INPUT_CV_1 + i)); - addOutput(Port::create(Vec(92,93 + offset), Port::OUTPUT, module, XF_202::OUTPUT_1 + i)); - addOutput(Port::create(Vec(92,120 + offset), Port::OUTPUT, module, XF_202::OUTPUTR_1 + i)); + addOutput(Port::create(Vec(92,93 + offset), Port::OUTPUT, module, XF_202::OUTPUT_1 + i)); + addOutput(Port::create(Vec(92,120 + offset), Port::OUTPUT, module, XF_202::OUTPUTR_1 + i)); addParam(ParamWidget::create(Vec(28, 154.5 + offset), module, XF_202::PARAM_CV_1 + i, 0.0f, 1.0f, 0.0f)); addParam(ParamWidget::create(Vec(65, 152 + offset), module, XF_202::PARAM_MODE_1 + i, 0.0f, 2.0f, 0.0f)); @@ -93,6 +93,6 @@ struct XF202 : ModuleWidget { using namespace rack_plugin_SubmarineFree; RACK_PLUGIN_MODEL_INIT(SubmarineFree, XF202) { - Model *modelXF202 = Model::create("SubmarineFree", "XF-202", "XF-202 Dual Stereo Cross Fader", MIXER_TAG, DUAL_TAG); + Model *modelXF202 = Model::create("Submarine (Free)", "XF-202", "XF-202 Dual Stereo Cross Fader", MIXER_TAG, DUAL_TAG); return modelXF202; } diff --git a/plugins/community/repos/SubmarineFree/src/XF.hpp b/plugins/community/repos/SubmarineFree/src/XF.hpp index 9ef34260..93ba0faf 100644 --- a/plugins/community/repos/SubmarineFree/src/XF.hpp +++ b/plugins/community/repos/SubmarineFree/src/XF.hpp @@ -35,7 +35,7 @@ struct XF_Controls { XF_Correlator *correlator; }; -struct XF_LightKnob : sub_knob_large_narrow { +struct XF_LightKnob : LargeKnob> { int cv; int link; void step() override; diff --git a/plugins/community/repos/SubmarineFree/src/XG-106.cpp b/plugins/community/repos/SubmarineFree/src/XG-106.cpp deleted file mode 100644 index dec89b40..00000000 --- a/plugins/community/repos/SubmarineFree/src/XG-106.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#include "DS.hpp" - -namespace rack_plugin_SubmarineFree { - -struct XG_106 : DS_Module { - static const int deviceCount = 6; - enum ParamIds { - NUM_PARAMS - }; - enum InputIds { - INPUT_A_1, - INPUT_A_2, - INPUT_A_3, - INPUT_A_4, - INPUT_A_5, - INPUT_A_6, - INPUT_B_1, - INPUT_B_2, - INPUT_B_3, - INPUT_B_4, - INPUT_B_5, - INPUT_B_6, - NUM_INPUTS - }; - enum OutputIds { - OUTPUT_1, - OUTPUT_2, - OUTPUT_3, - OUTPUT_4, - OUTPUT_5, - OUTPUT_6, - NUM_OUTPUTS - }; - enum LightIds { - NUM_LIGHTS - }; - - XG_106() : DS_Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} - void step() override; -}; - -void XG_106::step() { - int setCount = 0; - for (int i = 0; i < deviceCount; i++) { - if (inputs[INPUT_A_1 + i].active) - if (inputs[INPUT_A_1 + i].value > midpoint()) - setCount++; - if (inputs[INPUT_B_1 + i].active) - if (inputs[INPUT_B_1 + i].value > midpoint()) - setCount++; - if (outputs[OUTPUT_1 + i].active) { - outputs[OUTPUT_1 + i].value = (setCount % 2)?voltage1:voltage0; - setCount = 0; - } - } -} - -struct XG106 : ModuleWidget { - XG106(XG_106 *module) : ModuleWidget(module) { - setPanel(SVG::load(assetPlugin(plugin, "res/XG-106.svg"))); - - for (int i = 0; i < XG_106::deviceCount; i++) { - int offset = 58 * i; - addInput(Port::create(Vec(4,19 + offset), Port::INPUT, module, XG_106::INPUT_A_1 + i)); - addInput(Port::create(Vec(4,47 + offset), Port::INPUT, module, XG_106::INPUT_B_1 + i)); - - addOutput(Port::create(Vec(62,33 + offset), Port::OUTPUT, module, XG_106::OUTPUT_1 + i)); - } - } - void appendContextMenu(Menu *menu) override { - ((DS_Module *)module)->appendContextMenu(menu); - } -}; - -} // namespace rack_plugin_SubmarineFree - -using namespace rack_plugin_SubmarineFree; - -RACK_PLUGIN_MODEL_INIT(SubmarineFree, XG106) { - Model *modelXG106 = Model::create("SubmarineFree", "XG-106", "XG-106 XOR Gates", LOGIC_TAG, MULTIPLE_TAG); - return modelXG106; -} diff --git a/plugins/community/repos/SubmarineFree/src/XG1.cpp b/plugins/community/repos/SubmarineFree/src/XG1.cpp new file mode 100644 index 00000000..b2fdec69 --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/XG1.cpp @@ -0,0 +1,87 @@ +#include "DS.hpp" + +namespace rack_plugin_SubmarineFree { + +template +struct XG_1 : DS_Module { + enum ParamIds { + NUM_PARAMS + }; + enum InputIds { + INPUT_A_1, + INPUT_B_1 = x, + NUM_INPUTS = x + x + }; + enum OutputIds { + OUTPUT_1, + NUM_OUTPUTS = x + }; + enum LightIds { + NUM_LIGHTS + }; + + XG_1() : DS_Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} + void step() override { + int setCount = 0; + for (int i = 0; i < x; i++) { + if (inputs[INPUT_A_1 + i].active) + if (inputs[INPUT_A_1 + i].value > midpoint()) + setCount++; + if (inputs[INPUT_B_1 + i].active) + if (inputs[INPUT_B_1 + i].value > midpoint()) + setCount++; + if (outputs[OUTPUT_1 + i].active) { + outputs[OUTPUT_1 + i].value = (setCount % 2)?voltage1:voltage0; + setCount = 0; + } + } + } +}; + +struct XG104 : ModuleWidget { + XG104(XG_1<4> *module) : ModuleWidget(module) { + setPanel(SVG::load(assetPlugin(plugin, "res/XG-104.svg"))); + + for (int i = 0; i < 4; i++) { + int offset = 87 * i; + addInput(Port::create(Vec(2.5,19 + offset), Port::INPUT, module, XG_1<4>::INPUT_A_1 + i)); + addInput(Port::create(Vec(2.5,47 + offset), Port::INPUT, module, XG_1<4>::INPUT_B_1 + i)); + + addOutput(Port::create(Vec(2.5,75 + offset), Port::OUTPUT, module, XG_1<4>::OUTPUT_1 + i)); + } + } + void appendContextMenu(Menu *menu) override { + ((DS_Module *)module)->appendContextMenu(menu); + } +}; + +struct XG106 : ModuleWidget { + XG106(XG_1<6> *module) : ModuleWidget(module) { + setPanel(SVG::load(assetPlugin(plugin, "res/XG-106.svg"))); + + for (int i = 0; i < 6; i++) { + int offset = 58 * i; + addInput(Port::create(Vec(4,19 + offset), Port::INPUT, module, XG_1<6>::INPUT_A_1 + i)); + addInput(Port::create(Vec(4,47 + offset), Port::INPUT, module, XG_1<6>::INPUT_B_1 + i)); + + addOutput(Port::create(Vec(62,33 + offset), Port::OUTPUT, module, XG_1<6>::OUTPUT_1 + i)); + } + } + void appendContextMenu(Menu *menu) override { + ((DS_Module *)module)->appendContextMenu(menu); + } +}; + +} // namespace rack_plugin_SubmarineFree + +using namespace rack_plugin_SubmarineFree; + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, XG104) { + Model *modelXG104 = Model::create, XG104>("Submarine (Free)", "XG-104", "XG-104 XOR Gates", LOGIC_TAG, MULTIPLE_TAG); + return modelXG104; +} + +RACK_PLUGIN_MODEL_INIT(SubmarineFree, XG106) { + Model *modelXG106 = Model::create, XG106>("Submarine (Free)", "XG-106", "XG-106 XOR Gates", LOGIC_TAG, MULTIPLE_TAG); + return modelXG106; +} diff --git a/plugins/community/repos/SubmarineFree/src/res/AG-104.svg b/plugins/community/repos/SubmarineFree/src/res/AG-104.svg new file mode 100644 index 00000000..d3774d15 --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/res/AG-104.svg @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + diff --git a/plugins/community/repos/SubmarineFree/src/res/AO-106.svg b/plugins/community/repos/SubmarineFree/src/res/AO-106.svg new file mode 100644 index 00000000..baf59f73 --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/res/AO-106.svg @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + X IN + X IN + X IN + X IN + X IN + X OUT + X OUT + X OUT + X OUT + X OUT + Y IN + Y OUT + + + diff --git a/plugins/community/repos/SubmarineFree/src/res/AO-112.svg b/plugins/community/repos/SubmarineFree/src/res/AO-112.svg new file mode 100644 index 00000000..3bb1a82c --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/res/AO-112.svg @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + X IN + X IN + X IN + X IN + X IN + X OUT + X OUT + X OUT + X OUT + X OUT + Y IN + Y OUT + + + diff --git a/plugins/community/repos/SubmarineFree/src/res/AO-118.svg b/plugins/community/repos/SubmarineFree/src/res/AO-118.svg new file mode 100644 index 00000000..0a1edc0d --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/res/AO-118.svg @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + X IN + X IN + X IN + X IN + X IN + X OUT + X OUT + X OUT + X OUT + X OUT + Y IN + Y OUT + Y IN + Y OUT + + + diff --git a/plugins/community/repos/SubmarineFree/src/res/AO-124.svg b/plugins/community/repos/SubmarineFree/src/res/AO-124.svg new file mode 100644 index 00000000..b41a5ad7 --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/res/AO-124.svg @@ -0,0 +1,146 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + X IN + X IN + X IN + X IN + X IN + X OUT + X OUT + X OUT + X OUT + X OUT + Y IN + Y OUT + Y IN + Y OUT + Y IN + Y OUT + + + diff --git a/plugins/community/repos/SubmarineFree/src/res/AO-136.svg b/plugins/community/repos/SubmarineFree/src/res/AO-136.svg new file mode 100644 index 00000000..ba15ada4 --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/res/AO-136.svg @@ -0,0 +1,176 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + X IN + X IN + X IN + X IN + X IN + X OUT + X OUT + X OUT + X OUT + X OUT + Y IN + Y OUT + Y IN + Y OUT + Y IN + Y OUT + Y IN + Y OUT + Y IN + Y OUT + + + diff --git a/plugins/community/repos/SubmarineFree/src/res/EO-102.svg b/plugins/community/repos/SubmarineFree/src/res/EO-102.svg new file mode 100644 index 00000000..f5bb9243 --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/res/EO-102.svg @@ -0,0 +1,119 @@ + + + + + + + + + + + + + + + + + + + + + + + CHANNEL A + CHANNEL B + TIME + TRIGGER + INDICES + CV + + SCALE + OFFSET + CV + + SCALE + OFFSET + PRE + TIME + CONT. + ONCE + RUN + LEVEL + LEFT + RIGHT + HORZ + + diff --git a/plugins/community/repos/SubmarineFree/src/res/FF-206.svg b/plugins/community/repos/SubmarineFree/src/res/FF-206.svg new file mode 100644 index 00000000..8fa96561 --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/res/FF-206.svg @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + diff --git a/plugins/community/repos/SubmarineFree/src/res/LD-103.svg b/plugins/community/repos/SubmarineFree/src/res/LD-103.svg new file mode 100644 index 00000000..e01b3fba --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/res/LD-103.svg @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + diff --git a/plugins/community/repos/SubmarineFree/src/res/NG-106.svg b/plugins/community/repos/SubmarineFree/src/res/NG-106.svg new file mode 100644 index 00000000..13bc75b1 --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/res/NG-106.svg @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + diff --git a/plugins/community/repos/SubmarineFree/src/res/OG-104.svg b/plugins/community/repos/SubmarineFree/src/res/OG-104.svg new file mode 100644 index 00000000..46e86594 --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/res/OG-104.svg @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + diff --git a/plugins/community/repos/SubmarineFree/src/res/PG-104.svg b/plugins/community/repos/SubmarineFree/src/res/PG-104.svg new file mode 100644 index 00000000..9dea499f --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/res/PG-104.svg @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + diff --git a/plugins/community/repos/SubmarineFree/src/res/SS-112.svg b/plugins/community/repos/SubmarineFree/src/res/SS-112.svg new file mode 100644 index 00000000..286be6ba --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/res/SS-112.svg @@ -0,0 +1,43 @@ + + + + + + + + + diff --git a/plugins/community/repos/SubmarineFree/src/res/SS-208.svg b/plugins/community/repos/SubmarineFree/src/res/SS-208.svg new file mode 100644 index 00000000..129c88a9 --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/res/SS-208.svg @@ -0,0 +1,59 @@ + + + + + + + + + + diff --git a/plugins/community/repos/SubmarineFree/src/res/SS-212.svg b/plugins/community/repos/SubmarineFree/src/res/SS-212.svg new file mode 100644 index 00000000..de5ba322 --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/res/SS-212.svg @@ -0,0 +1,51 @@ + + + + + + + + + + diff --git a/plugins/community/repos/SubmarineFree/src/res/SS-220.svg b/plugins/community/repos/SubmarineFree/src/res/SS-220.svg new file mode 100644 index 00000000..56718aaf --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/res/SS-220.svg @@ -0,0 +1,67 @@ + + + + + + + + + + + + diff --git a/plugins/community/repos/SubmarineFree/src/res/SS-221.svg b/plugins/community/repos/SubmarineFree/src/res/SS-221.svg new file mode 100644 index 00000000..0e08e00d --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/res/SS-221.svg @@ -0,0 +1,155 @@ + + + + + + + + + + 10V + 9V + 8V + 7V + 6V + 5V + 4V + 3V + 2V + 1V + 0V + -1V + -2V + -3V + -4V + -5V + -6V + -7V + -8V + -9V + -10 + + diff --git a/plugins/community/repos/SubmarineFree/src/res/TD-116.svg b/plugins/community/repos/SubmarineFree/src/res/TD-116.svg new file mode 100644 index 00000000..31d97010 --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/res/TD-116.svg @@ -0,0 +1,61 @@ + + + + + + + + + + SYNC IN + SYNC OUT + + diff --git a/plugins/community/repos/SubmarineFree/src/res/TD-202.svg b/plugins/community/repos/SubmarineFree/src/res/TD-202.svg new file mode 100644 index 00000000..1d5b22e5 --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/res/TD-202.svg @@ -0,0 +1,51 @@ + + + + + + + + + + + + diff --git a/plugins/community/repos/SubmarineFree/src/res/TF-101.svg b/plugins/community/repos/SubmarineFree/src/res/TF-101.svg new file mode 100644 index 00000000..84f8ee4d --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/res/TF-101.svg @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + OUT + FOREGROUND + BACKGROUND + TEXT-SIZE + R + G + B + R + G + B + + + diff --git a/plugins/community/repos/SubmarineFree/src/res/TM-105.svg b/plugins/community/repos/SubmarineFree/src/res/TM-105.svg new file mode 100644 index 00000000..e40747f2 --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/res/TM-105.svg @@ -0,0 +1,54 @@ + + + + + + + + + + IN + OUT + + diff --git a/plugins/community/repos/SubmarineFree/src/res/XG-104.svg b/plugins/community/repos/SubmarineFree/src/res/XG-104.svg new file mode 100644 index 00000000..1afb02b0 --- /dev/null +++ b/plugins/community/repos/SubmarineFree/src/res/XG-104.svg @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + diff --git a/plugins/community/repos/SubmarineFree/src/torpedo.cpp b/plugins/community/repos/SubmarineFree/src/torpedo.cpp index 18771ee3..bd8a6cc9 100644 --- a/plugins/community/repos/SubmarineFree/src/torpedo.cpp +++ b/plugins/community/repos/SubmarineFree/src/torpedo.cpp @@ -11,16 +11,16 @@ void BasePort::raiseError(unsigned int errorType) { _checksum = 0; switch (errorType) { case ERROR_STATE: - //if (dbg) debug("Torpedo Error: STATE"); + if (dbg) debug("Torpedo Error: STATE"); break; case ERROR_COUNTER: - //if (dbg) debug("Torpedo Error: COUNTER"); + if (dbg) debug("Torpedo Error: COUNTER"); break; case ERROR_LENGTH: - //if (dbg) debug("Torpedo Error: LENGTH"); + if (dbg) debug("Torpedo Error: LENGTH"); break; case ERROR_CHECKSUM: - //if (dbg) debug("Torpedo Error: CHECKSUM"); + if (dbg) debug("Torpedo Error: CHECKSUM"); break; } error(errorType); @@ -33,7 +33,7 @@ void RawOutputPort::abort(void) { } void RawOutputPort::completed(void) { - //if (dbg) debug("Torpedo Completed:"); + if (dbg) debug("Torpedo Completed:"); } void RawOutputPort::process(void) { @@ -130,7 +130,7 @@ void RawOutputPort::send(std::string message) { raiseError(ERROR_LENGTH); return; } - //if (dbg) debug("Torpedo Send:%s %s", _appId.c_str(), message.c_str()); + if (dbg) debug("Torpedo Send:%s %s", _appId.c_str(), message.c_str()); switch (_state) { case STATE_HEADER: case STATE_BODY: @@ -269,7 +269,7 @@ void RawInputPort::process(void) { } void RawInputPort::received(std::string appId, std::string message) { - //if (dbg) debug("Torpedo Received:%s %s", appId.c_str(), message.c_str()); + if (dbg) debug("Torpedo Received:%s %s", appId.c_str(), message.c_str()); } void TextInputPort::received(std::string appId, std::string message) { @@ -303,12 +303,12 @@ void QueuedOutputPort::send(std::string message) { std::string *s = _queue.back(); _queue.pop_back(); delete s; - //if (dbg) debug("Torpedo Replaced:"); + if (dbg) debug("Torpedo Replaced:"); } { std::string *s = new std::string(message); _queue.push_back(s); - //if (dbg) debug("Torpedo Queued:"); + if (dbg) debug("Torpedo Queued:"); } return; } @@ -334,7 +334,7 @@ void MessageOutputPort::send(std::string pluginName, std::string moduleName, std } void MessageInputPort::received(std::string appId, std::string message) { - //if (dbg) debug("Torpedo Received: %s", message.c_str()); + if (dbg) debug("Torpedo Received: %s", message.c_str()); std::string pluginName; std::string moduleName; std::string messageText; @@ -344,7 +344,7 @@ void MessageInputPort::received(std::string appId, std::string message) { json_error_t error; json_t *rootJ = json_loads(message.c_str(), 0, &error); if (!rootJ) { - //debug("Torpedo MESG Error: %s", error.text); + debug("Torpedo MESG Error: %s", error.text); return; } json_t *jp = json_object_get(rootJ, "plugin"); @@ -372,7 +372,7 @@ void PatchOutputPort::send(std::string pluginName, std::string moduleName, json_ } void PatchInputPort::received(std::string appId, std::string message) { - //if (dbg) debug("Torpedo Received: %s", message.c_str()); + if (dbg) debug("Torpedo Received: %s", message.c_str()); std::string pluginName; std::string moduleName; @@ -381,7 +381,7 @@ void PatchInputPort::received(std::string appId, std::string message) { json_error_t error; json_t *rootJ = json_loads(message.c_str(), 0, &error); if (!rootJ) { - //debug("Torpedo MESG Error: %s", error.text); + debug("Torpedo MESG Error: %s", error.text); return; } json_t *jp = json_object_get(rootJ, "plugin"); diff --git a/vst2_bin/CHANGELOG_VST.txt b/vst2_bin/CHANGELOG_VST.txt index a54bcaa8..a2cce515 100644 --- a/vst2_bin/CHANGELOG_VST.txt +++ b/vst2_bin/CHANGELOG_VST.txt @@ -1,6 +1,8 @@ ** October ??th, 2018 - add Linux port +- support FBO rendering in dynamically loaded modules + - add "fbo" and "fbo_shared" settings (must be set to false in VirtualBox VM) - update dBiz modules (fixes UI issues) - add module dBiz.FourSeq - add module dBiz.Divider @@ -23,6 +25,27 @@ - add module SquinkyLabs.LFN - add module SquinkyLabs.Shaper (crash) - add module SquinkyLabs.Super +- add module SubmarineFree.AG-104 +- add module SubmarineFree.AO106 +- add module SubmarineFree.AO112 +- add module SubmarineFree.AO118 +- add module SubmarineFree.AO124 +- add module SubmarineFree.AO136 +- add module SubmarineFree.EO102 +- add module SubmarineFree.LD103 +- add module SubmarineFree.NG106 +- add module SubmarineFree.OG104 +- add module SubmarineFree.PG104 +- add module SubmarineFree.SS112 +- add module SubmarineFree.SS208 +- add module SubmarineFree.SS212 +- add module SubmarineFree.SS220 +- add module SubmarineFree.SS221 +- add module SubmarineFree.TD116 +- add module SubmarineFree.TD202 +- add module SubmarineFree.TF101 +- add module SubmarineFree.TM105 +- add module SubmarineFree.XG104 ** October 12th, 2018 diff --git a/vst2_bin/log.txt b/vst2_bin/log.txt index 2392f86d..87614c33 100644 --- a/vst2_bin/log.txt +++ b/vst2_bin/log.txt @@ -15,9 +15,9 @@ [0.002 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin CastleRocktronics 0.6.1 [0.002 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin cf 0.6.1 [0.002 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin com-soundchasing-stochasm 0.6.1 -[0.002 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin computerscare 0.6.1 -[0.002 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin DHE-Modules 0.6.1 -[0.002 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin DrumKit 0.6.1 +[0.003 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin computerscare 0.6.1 +[0.003 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin DHE-Modules 0.6.1 +[0.003 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin DrumKit 0.6.1 [0.003 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin ErraticInstruments 0.6.1 [0.003 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin ESeries 0.6.1 [0.003 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin FrankBussFormula 0.6.1 @@ -27,31 +27,31 @@ [0.003 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin Gratrix 0.6.1 [0.003 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin HetrickCV 0.6.1 [0.003 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin huaba 0.6.1 -[0.003 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin ImpromptuModular 0.6.11 -[0.003 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin JE 0.6.1 -[0.003 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin JW-Modules 0.6.1 -[0.003 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin Koralfx-Modules 0.6.1 +[0.004 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin ImpromptuModular 0.6.11 +[0.004 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin JE 0.6.1 +[0.004 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin JW-Modules 0.6.1 +[0.004 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin Koralfx-Modules 0.6.1 [0.004 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin LindenbergResearch 0.6.2b [0.004 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin LOGinstruments 0.6.1 [0.004 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin mental 0.6.1 [0.004 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin ML_modules 0.6.1 [0.004 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin moDllz 0.6.1 [0.004 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin modular80 0.6.1 -[0.004 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin mscHack 0.6.1 -[0.004 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin mtsch-plugins 0.6.1 -[0.004 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin NauModular 0.6.1 -[0.004 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin Nohmad 0.6.1 -[0.004 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin Ohmer 0.6.1 +[0.005 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin mscHack 0.6.1 +[0.005 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin mtsch-plugins 0.6.1 +[0.005 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin NauModular 0.6.1 +[0.005 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin Nohmad 0.6.1 +[0.005 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin Ohmer 0.6.1 [0.005 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin PG-Instruments 0.6.1 [0.005 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin PvC 0.6.1 [0.005 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin Qwelk 0.6.1 [0.005 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin RJModules 0.6.1 [0.005 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin SerialRacker 0.6.1 [0.005 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin SonusModular 0.6.1 -[0.005 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin Southpole 0.6.1 -[0.005 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin Southpole-parasites 0.6.1 -[0.005 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin squinkylabs-plug1 0.6.9 -[0.006 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin SubmarineFree 0.6.1 +[0.006 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin Southpole 0.6.1 +[0.006 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin Southpole-parasites 0.6.1 +[0.006 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin squinkylabs-plug1 0.6.9 +[0.006 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin SubmarineFree 0.6.8 [0.006 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin SynthKit 0.6.1 [0.006 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin Template 0.6.1 [0.006 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin TheXOR 0.6.1 @@ -59,87 +59,58 @@ [0.006 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin unless_modules 0.6.1 [0.006 info src/plugin_static.cpp:140] vcvrack: Loaded static plugin Valley 0.6.1 [0.007 info src/plugin.cpp:90] trying to load shared plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/bsp/plugin.dll.instr -[0.007 info src/plugin.cpp:160] Loaded plugin bsp 0.6.1 from f:\git\VeeSeeVSTRack\vst2_bin\/plugins/bsp/plugin.dll.instr -[0.007 info src/plugin.cpp:90] trying to load shared plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/dBiz/plugin.dll.instr +[0.008 info src/plugin.cpp:160] Loaded plugin bsp 0.6.1 from f:\git\VeeSeeVSTRack\vst2_bin\/plugins/bsp/plugin.dll.instr +[0.008 info src/plugin.cpp:90] trying to load shared plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/dBiz/plugin.dll.instr [0.008 info src/plugin.cpp:160] Loaded plugin dBiz 0.6.1 from f:\git\VeeSeeVSTRack\vst2_bin\/plugins/dBiz/plugin.dll.instr -[0.008 info src/plugin.cpp:90] trying to load shared plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/Template_shared/plugin.dll.instr +[0.009 info src/plugin.cpp:90] trying to load shared plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/Template_shared/plugin.dll.instr [0.009 info src/plugin.cpp:160] Loaded plugin Template_shared 0.6.1 from f:\git\VeeSeeVSTRack\vst2_bin\/plugins/Template_shared/plugin.dll.instr -[0.009 info src/settings.cpp:451] Loading settings f:\git\VeeSeeVSTRack\vst2_bin\/settings.json -[0.018 info src/window.cpp:725] Loaded font f:\git\VeeSeeVSTRack\vst2_bin\/res/fonts/DejaVuSans.ttf -[0.019 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/icons/noun_146097_cc.svg -[0.019 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/icons/noun_31859_cc.svg -[0.019 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/icons/noun_1343816_cc.svg -[0.020 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/icons/noun_1343811_cc.svg -[0.020 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/icons/noun_1084369_cc.svg -[0.020 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/icons/noun_1745061_cc.svg -[0.020 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/icons/noun_1240789_cc.svg -[0.020 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/icons/noun_305536_cc.svg -[0.020 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/icons/noun_468341_cc.svg -[0.021 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/icons/idle_mode_icon_cc.svg -[0.021 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/icons/settings_icon_cc.svg -[0.021 info src/settings.cpp:451] Loading settings f:\git\VeeSeeVSTRack\vst2_bin\/settings.json -[0.024 info src/app/RackWidget.cpp:216] Loading patch from string -[0.026 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/Core/AudioInterface.svg -[0.026 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/ComponentLibrary/ScrewSilver.svg -[0.026 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/ComponentLibrary/PJ301M.svg -[0.026 info src/window.cpp:725] Loaded font f:\git\VeeSeeVSTRack\vst2_bin\/res/fonts/ShareTechMono-Regular.ttf -[0.027 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/Core/MIDIToCVInterface.svg -[0.030 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Bogaudio/res/XCO.svg -[0.030 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Bogaudio/res/knob_68px.svg -[0.030 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Bogaudio/res/knob_16px.svg -[0.030 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Bogaudio/res/button_9px_0.svg -[0.030 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Bogaudio/res/button_9px_1.svg -[0.031 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Bogaudio/res/knob_38px.svg -[0.031 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Bogaudio/res/slider_switch_2_14px_0.svg -[0.031 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Bogaudio/res/slider_switch_2_14px_1.svg -[0.031 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Bogaudio/res/port.svg -[0.032 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Fundamental/res/VCA.svg -[0.032 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/ComponentLibrary/RoundLargeBlackKnob.svg -[0.034 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/AS/res/ADSR.svg -[0.034 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/AS/res/as-hexscrew.svg -[0.034 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/AS/res/as-SlidePot.svg -[0.034 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/AS/res/as-SlidePotHandle.svg -[0.035 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/AS/res/as-PJ301M.svg -[0.038 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/21kHz/res/Panels/D_Inf.svg -[0.038 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/21kHz/res/Components/kHzScrew.svg -[0.039 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/21kHz/res/Components/kHzKnobSmall.svg -[0.039 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/21kHz/res/Components/kHzButton_0.svg -[0.039 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/21kHz/res/Components/kHzButton_1.svg -[0.039 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/21kHz/res/Components/kHzPort.svg -[0.040 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Autodafe/res/Multiple18.svg -[0.041 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/ComponentLibrary/PJ3410.svg -[2.986 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/squinkylabs-plug1/res/booty_panel.svg -[2.986 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/ComponentLibrary/Rogan3PSBlue.svg -[4.414 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/squinkylabs-plug1/res/chb_panel.svg -[4.414 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/ComponentLibrary/Trimpot.svg -[4.414 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/squinkylabs-plug1/res/Blue30.svg -[4.415 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/squinkylabs-plug1/res/BluePush_1.svg -[4.415 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/squinkylabs-plug1/res/BluePush_0.svg -[6.315 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/squinkylabs-plug1/res/ev3_panel.svg -[6.315 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/squinkylabs-plug1/res/waveforms-6-08.svg -[6.315 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/squinkylabs-plug1/res/waveforms-6-07.svg -[6.316 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/squinkylabs-plug1/res/waveforms-6-06.svg -[6.316 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/squinkylabs-plug1/res/waveforms-6-05.svg -[6.316 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/squinkylabs-plug1/res/waveforms-6-02.svg -[6.316 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/squinkylabs-plug1/res/waveforms-6-01.svg -[6.316 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/squinkylabs-plug1/res/waveforms-6-04.svg -[6.317 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/squinkylabs-plug1/res/waveforms-6-03.svg -[6.317 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/squinkylabs-plug1/res/waveforms-6-12.svg -[6.317 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/squinkylabs-plug1/res/waveforms-6-11.svg -[6.317 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/squinkylabs-plug1/res/waveforms-6-10.svg -[6.317 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/squinkylabs-plug1/res/waveforms-6-09.svg -[10.517 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/squinkylabs-plug1/res/gray.svg -[13.194 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/squinkylabs-plug1/res/lfn_panel.svg -[13.194 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/ComponentLibrary/Rogan1PSBlue.svg -[15.288 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/squinkylabs-plug1/res/blank_panel.svg -[16.920 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/squinkylabs-plug1/res/vocal_animator_panel.svg -[16.920 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/ComponentLibrary/NKK_0.svg -[16.920 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/ComponentLibrary/NKK_1.svg -[16.920 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/ComponentLibrary/NKK_2.svg -[18.568 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/squinkylabs-plug1/res/formants_panel.svg -[18.568 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/ComponentLibrary/RoundBlackKnob.svg -[20.741 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/squinkylabs-plug1/res/colors_panel.svg -[20.741 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/ComponentLibrary/Rogan2PSWhite.svg -[27.641 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/squinkylabs-plug1/res/trem_panel.svg -[29.941 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/squinkylabs-plug1/res/thread_booster_panel.svg -[33.512 info src/app/RackWidget.cpp:178] Saving patch to string +[0.010 info src/settings.cpp:462] Loading settings f:\git\VeeSeeVSTRack\vst2_bin\/settings.json +[0.019 info src/window.cpp:725] Loaded font f:\git\VeeSeeVSTRack\vst2_bin\/res/fonts/DejaVuSans.ttf +[0.020 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/icons/noun_146097_cc.svg +[0.020 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/icons/noun_31859_cc.svg +[0.021 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/icons/noun_1343816_cc.svg +[0.021 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/icons/noun_1343811_cc.svg +[0.021 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/icons/noun_1084369_cc.svg +[0.021 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/icons/noun_1745061_cc.svg +[0.021 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/icons/noun_1240789_cc.svg +[0.021 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/icons/noun_305536_cc.svg +[0.022 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/icons/noun_468341_cc.svg +[0.022 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/icons/idle_mode_icon_cc.svg +[0.022 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/icons/settings_icon_cc.svg +[0.022 info src/settings.cpp:462] Loading settings f:\git\VeeSeeVSTRack\vst2_bin\/settings.json +[0.025 info src/app/RackWidget.cpp:216] Loading patch from string +[0.027 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/Core/AudioInterface.svg +[0.027 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/ComponentLibrary/ScrewSilver.svg +[0.027 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/ComponentLibrary/PJ301M.svg +[0.028 info src/window.cpp:725] Loaded font f:\git\VeeSeeVSTRack\vst2_bin\/res/fonts/ShareTechMono-Regular.ttf +[0.029 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/Core/MIDIToCVInterface.svg +[0.031 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Bogaudio/res/XCO.svg +[0.031 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Bogaudio/res/knob_68px.svg +[0.032 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Bogaudio/res/knob_16px.svg +[0.032 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Bogaudio/res/button_9px_0.svg +[0.032 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Bogaudio/res/button_9px_1.svg +[0.032 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Bogaudio/res/knob_38px.svg +[0.032 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Bogaudio/res/slider_switch_2_14px_0.svg +[0.033 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Bogaudio/res/slider_switch_2_14px_1.svg +[0.033 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Bogaudio/res/port.svg +[0.034 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Fundamental/res/VCA.svg +[0.034 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/ComponentLibrary/RoundLargeBlackKnob.svg +[0.035 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/AS/res/ADSR.svg +[0.035 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/AS/res/as-hexscrew.svg +[0.036 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/AS/res/as-SlidePot.svg +[0.036 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/AS/res/as-SlidePotHandle.svg +[0.036 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/AS/res/as-PJ301M.svg +[0.040 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/21kHz/res/Panels/D_Inf.svg +[0.040 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/21kHz/res/Components/kHzScrew.svg +[0.040 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/21kHz/res/Components/kHzKnobSmall.svg +[0.040 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/21kHz/res/Components/kHzButton_0.svg +[0.040 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/21kHz/res/Components/kHzButton_1.svg +[0.041 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/21kHz/res/Components/kHzPort.svg +[0.042 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Autodafe/res/Multiple18.svg +[0.042 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/ComponentLibrary/PJ3410.svg +[6.416 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/AudibleInstruments/res/Stages.svg +[6.416 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/ComponentLibrary/Trimpot.svg +[6.416 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/ComponentLibrary/TL1105_0.svg +[6.417 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/ComponentLibrary/TL1105_1.svg +[6.417 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/ComponentLibrary/LEDSlider.svg +[6.417 info src/window.cpp:780] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/ComponentLibrary/LEDSliderGreenHandle.svg diff --git a/vst2_bin/plugins/Fundamental/res/test.svg b/vst2_bin/plugins/Fundamental/res/test.svg new file mode 100644 index 00000000..53ba302d --- /dev/null +++ b/vst2_bin/plugins/Fundamental/res/test.svg @@ -0,0 +1,82 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/vst2_bin/plugins/SubmarineFree/README.md b/vst2_bin/plugins/SubmarineFree/README.md index cd836c76..40798426 100644 --- a/vst2_bin/plugins/SubmarineFree/README.md +++ b/vst2_bin/plugins/SubmarineFree/README.md @@ -1,9 +1,16 @@ # SubmarineFree Free plugins for VCV Rack +[.plan (what I'm working on)](https://github.com/david-c14/SubmarineFree/issues/23) + # [Manual](https://github.com/david-c14/SubmarineFree/blob/master/manual/index.md) -# [Builds](https://github.com/david-c14/SubmarineFree/issues/9) +# [Builds](https://github.com/david-c14/SubmarineFree/releases/tag/v0.6.8) +###### [0.6.8](https://github.com/david-c14/SubmarineFree/releases/tag/v0.6.8) +###### [0.6.7](https://github.com/david-c14/SubmarineFree/releases/tag/v0.6.7) +###### [0.6.6](https://github.com/david-c14/SubmarineFree/issues/20) +###### [0.6.5](https://github.com/david-c14/SubmarineFree/issues/19) +###### [0.6.4](https://github.com/david-c14/SubmarineFree/issues/14) ###### [0.6.3](https://github.com/david-c14/SubmarineFree/issues/9) ###### [0.6.2](https://github.com/david-c14/SubmarineFree/issues/4) @@ -11,3 +18,5 @@ Free plugins for VCV Rack Source code licensed under BSD-3-Clause by carbon14 (David O'Rourke) All graphics in res/ and src/res are © 2018 by carbon14 (David O'Rourke) + +Some portions of this source code are based on code © 2016 by Andrew Belt diff --git a/vst2_bin/plugins/SubmarineFree/Scala/equal.scl b/vst2_bin/plugins/SubmarineFree/Scala/equal.scl new file mode 100644 index 00000000..37243c20 --- /dev/null +++ b/vst2_bin/plugins/SubmarineFree/Scala/equal.scl @@ -0,0 +1,17 @@ +! equal +! +Equal Temperament 12-ET +12 +! +100.0 +200.0 +300.0 +400.0 +500.0 +600.0 +700.0 +800.0 +900.0 +1000.0 +1100.0 +1200.0 diff --git a/vst2_bin/plugins/SubmarineFree/Scala/just.scl b/vst2_bin/plugins/SubmarineFree/Scala/just.scl new file mode 100644 index 00000000..5e657487 --- /dev/null +++ b/vst2_bin/plugins/SubmarineFree/Scala/just.scl @@ -0,0 +1,17 @@ +! werck1.scl +! +Just intonation + 12 +! + 16/15 + 9/8 + 6/5 + 5/4 + 4/3 + 45/32 + 3/2 + 8/5 + 5/3 + 9/5 + 15/8 + 2/1 diff --git a/vst2_bin/plugins/SubmarineFree/Scala/lehman3.scl b/vst2_bin/plugins/SubmarineFree/Scala/lehman3.scl new file mode 100644 index 00000000..800ba4b1 --- /dev/null +++ b/vst2_bin/plugins/SubmarineFree/Scala/lehman3.scl @@ -0,0 +1,17 @@ +! lehman3.scl +! +Bradley Lehman Bach temperament III (2006) + 12 +! + 94.13500 + 196.09000 + 298.04500 + 392.18000 + 4/3 + 596.09000 + 698.04500 + 800.00000 + 894.13500 + 1000.00000 + 1094.13500 + 2/1 diff --git a/vst2_bin/plugins/SubmarineFree/Scala/werck3.scl b/vst2_bin/plugins/SubmarineFree/Scala/werck3.scl new file mode 100644 index 00000000..846eaf86 --- /dev/null +++ b/vst2_bin/plugins/SubmarineFree/Scala/werck3.scl @@ -0,0 +1,17 @@ +! werck3.scl +! +Andreas Werckmeister's temperament III (the most famous one, 1681) + 12 +! + 256/243 + 192.18000 + 32/27 + 390.22500 + 4/3 + 1024/729 + 696.09000 + 128/81 + 888.26999 + 16/9 + 1092.18000 + 2/1 diff --git a/vst2_bin/plugins/SubmarineFree/Scala/young.scl b/vst2_bin/plugins/SubmarineFree/Scala/young.scl new file mode 100644 index 00000000..620b4cad --- /dev/null +++ b/vst2_bin/plugins/SubmarineFree/Scala/young.scl @@ -0,0 +1,17 @@ +! young.scl +! +Thomas Young well temperament (1807), also Luigi Malerbi nr.2 (1794) + 12 +! + 256/243 + 196.09000 + 32/27 + 392.18000 + 4/3 + 1024/729 + 698.04500 + 128/81 + 894.13500 + 16/9 + 1090.22500 + 2/1 diff --git a/vst2_bin/plugins/SubmarineFree/WK_Custom.tunings.template b/vst2_bin/plugins/SubmarineFree/WK_Custom.tunings.template new file mode 100644 index 00000000..1e0ecc21 --- /dev/null +++ b/vst2_bin/plugins/SubmarineFree/WK_Custom.tunings.template @@ -0,0 +1,14 @@ +[ + { + "comment1": "To use custom tunings with the SubmarineFree WK modules", + "comment2": "Copy this template file and name it WK_Custom.tunings", + "comment3": "Each entry has a name and an array of 12 values", + "comment4": "Each value is the offset in cents." + "name": "Custom", + "tunings": [0,1.5,2.5,3.5,4.5,5.5,-6.5,-7.5,8.5,9.5,10.5,11.872] + }, + { + "name": "Custom2", + "tunings": [11,10,9,8,7,6,5,4,3,2,1,0] + } +] diff --git a/vst2_bin/plugins/SubmarineFree/manual/AG.md b/vst2_bin/plugins/SubmarineFree/manual/AG.md new file mode 100644 index 00000000..59c85eeb --- /dev/null +++ b/vst2_bin/plugins/SubmarineFree/manual/AG.md @@ -0,0 +1,25 @@ +# Logical AND Gates +### [Part of the Digital Suite](DS.md) +#### AG-104 AND Gates +#### AG-106 AND Gates + + +![View of the AND Gates](AG.png "AND Gates") + +## Basic Operation + +The AG-106 provides 6 two-input AND gates. It is designed to take digital signals, but it will happily accept analog signals. + +## Signal Range + +The voltage range of the digital gates can be configured from the context menu. The device will output at the full range of the configured settings. The inputs will measure a logical high signal anywhere above the midpoint of the configured range. + +## Normalling + +Any output not connected will be normalled into a third input on the gate below. In this way multi-input gates can be created up to a maximum of 12 inputs. + +An input not connected will be ignored. + +## AG-104 + +The AG-104 provides four two-input AND gates in a small form factor. Otherwise functionality is as for the AG-106 above. diff --git a/vst2_bin/plugins/SubmarineFree/manual/AG.png b/vst2_bin/plugins/SubmarineFree/manual/AG.png new file mode 100644 index 00000000..fea9ed18 Binary files /dev/null and b/vst2_bin/plugins/SubmarineFree/manual/AG.png differ diff --git a/vst2_bin/plugins/SubmarineFree/manual/AO-118.png b/vst2_bin/plugins/SubmarineFree/manual/AO-118.png new file mode 100644 index 00000000..4c72e0be Binary files /dev/null and b/vst2_bin/plugins/SubmarineFree/manual/AO-118.png differ diff --git a/vst2_bin/plugins/SubmarineFree/manual/AO-example-osc.md b/vst2_bin/plugins/SubmarineFree/manual/AO-example-osc.md new file mode 100644 index 00000000..811dbd37 --- /dev/null +++ b/vst2_bin/plugins/SubmarineFree/manual/AO-example-osc.md @@ -0,0 +1,64 @@ +# A sine wave oscillator using AO-106 + +![Example Patch](./AO-example-osc.png "AO-example-osc.png") + +In the example above we have an AO-106 6-algorithm device functioning as a voltage controlled sine wave oscillator. +An SS-221 on the left is providing a reference 1v/oct CV to both the AO-106 and a Frank Buss Formula for comparison. + +The first block in the AO-106 is providing a small delta value. + +The second block takes that delta value and adds it to the X-input which is fed from... + +...the third block which takes the accumulated value and reduces it modulo 1. + +The result is that we have a signal in a feedback loop from the third block back to the second block, which gradually grows over time, +and cycles around every time it reaches 1. Effectively a sawtooth wave with a frequency that depends on the input voltage, and a range from +0V to 1V. + +The fourth block multiplies this sawtooth amplitude by tau (2 pi) to give an amplitude that ranges from 0V to tauV. + +The fifth block takes the sine of this sawtooth. Since a range of 0 to tau in radians represents one complete cycle, the resulting signal +is a sine wave with a range of -1V to +1V + +The sixth block multiplies the signal by 5 to give the final -5V to +5V sine wave. + +The complicated part of this patch is in the first block where the algorithm is 2x+c. Where does this value of C = -7.52 come from? + +To acheive our basic requirement of 1v/oct, we need to raise 2 to the power of the CV input. For each increase 1V increase in the CV, +the resulting value doubles, just like the frequency doubling as we move up an octave. But we have some further requirements. + +We want our signal frequency to be middle C (261.6Hz) when the CV is at 0V, so we should multiply our power of 2 by 261.6. +That gives us a value in cycles per second. But then we need to divide this value by our sample rate, in this case I'm running at 48,000Hz +sample rate. We divide by this number so that our delta accumulates to the right number of cycles every second. + +Our algorithm for the delta value then is + +2x × 261.6 ÷ 48000 + +or + +2x × 0.00545 + +But we could represent 0.00545 as a 2 raised to some power... 2n + +n would be the base-2 logarithm of 0.00545 which is -7.51953 + +Now we can say that our delta value is + +2x × 2-7.51953 + +or + +2x - 7.51953 + +This is where the figures in the first block come from. + +The AO-1xx series of devices offer only two decimal places of precision in the constant setting, as a result this example oscillator is ever so slightly flat. +However this discrepancy is less that the drift in the Fundamental VCO1. + +Note also that changing the engine sample rate would change the frequency of the oscillator. Doubling the engine sample rate to 96,000 Hz +would require adjusting the constant from -7.52 to -8.52. + +The Frank Buss Formula has a built in sawtooth oscillator which automatically compensates for changes in the engine sample rate. + + diff --git a/vst2_bin/plugins/SubmarineFree/manual/AO-example-osc.png b/vst2_bin/plugins/SubmarineFree/manual/AO-example-osc.png new file mode 100644 index 00000000..f3a2b179 Binary files /dev/null and b/vst2_bin/plugins/SubmarineFree/manual/AO-example-osc.png differ diff --git a/vst2_bin/plugins/SubmarineFree/manual/AO-example-square.png b/vst2_bin/plugins/SubmarineFree/manual/AO-example-square.png new file mode 100644 index 00000000..21dfc9a7 Binary files /dev/null and b/vst2_bin/plugins/SubmarineFree/manual/AO-example-square.png differ diff --git a/vst2_bin/plugins/SubmarineFree/manual/AO-list.md b/vst2_bin/plugins/SubmarineFree/manual/AO-list.md new file mode 100644 index 00000000..729daae7 --- /dev/null +++ b/vst2_bin/plugins/SubmarineFree/manual/AO-list.md @@ -0,0 +1,230 @@ +# AO-1xx Algorithms + +## Arithmetical +| Display | Code | Description | +| ------------------------ | ------------------ | -------------------- | +| | | Pass-through. X passes across unchanged, Y passes down unchanged | +| C | c | The value of the selected constant C | +| X+C | x + c | X added to C | +| Y+C | y + c | Y added to C| +| X+Y+C | x + y + c | X and Y added to C | +| C-X | c - x | X subtracted from C | +| C-Y | c - y | Y subtracted from C | +| X-(Y+C) | x - ( y + c ) | Y added to C then all subtracted from X | +| (X+C)-Y | ( x + c ) - y | Y subtracted from X and C | +| Y-(X+C) | y - ( x + c ) | X added to C then all subtracted from Y | +| (Y+C)-X | ( y + c ) - x | X subtracted from Y and C | +| (X⨯Y)+C | ( x * y ) + c | X times Y added to C | +| (X+C)⨯Y | ( x + c ) * y | X and C multiplied by Y | +| X⨯(Y+C) | x * ( y + c ) | Y and C multiplied by X | +| X⨯C | x * c | X times C | +| Y⨯C | y * c | Y times C | +| X⨯Y⨯C | x * y * c | X times Y times C| +| π⨯(X+C) | M_PI * ( x + c ) | X and C multiplied by pi | +| π⨯(Y+C) | M_PI * ( y + c ) | Y and C multiplied by pi | +| τ⨯(X+C) | 2 * M_PI * ( x + c ) | X and C multiplied by tau | +| τ⨯(Y+C) | 2 * M_PI * ( y + c ) | Y and C multiplied by tau | +| X÷C | x / c | X divided by C | +| C÷X | c / x | C divided by X | +| Y÷C | y / c | Y divided by C | +| C÷Y | c / y | C divided by Y | +| C+(X÷Y) | c + ( x / y ) | C added to X divided by Y | +| C+(Y÷X) | c + ( y / x ) | C added to Y divided by X | +| X+(Y÷C) | x + ( y / c ) | X added to Y divided by C | +| X+(C÷Y) | x + ( c / y ) | X added to C divided by Y | +| Y+(X÷C) | y + ( x / c ) | Y added to X divided by C | +| Y+(C÷X) | y + ( c / x ) | Y added to C divided by X | +| (X+C)÷Y | ( x + c ) / y | X and C divided by Y | +| X÷(Y+C) | x / ( y + c ) | X divided by Y and C | +| (Y+C)÷X | ( y + c ) / x | Y and C divided by X | +| Y÷(X+C) | y / ( x + c ) | Y divided by X and C | +## Modular +| Display | Code | Description | +| ------------------------ | ------------------ | -------------------- | +| (X+C)%Y | fmodf( x + c , y ) | The remainder of X and C divided by Y | +| (Y+C)%X | fmodf( y + c , x ) | The remainder of Y and C divided by X | +| X%(Y+C) | fmodf( x , y + c ) | The remainder of X divided by Y and C | +| Y%(X+C) | fmodf( y , x + c) | The remainder of Y divided by X and C | +| X%C | fmodf( x , c ) | The remainder of X divided by C | +| Y%C | fmodf( y , c ) | The remainder of Y divided by C | +## Quadratic +| Display | Code | Description | +| ------------------------ | ------------------ | -------------------- | +| X²+C | x * x + c | X squared added to C | +| Y²+C | y * y + c | Y squared added to C | +| (X+C)² | ( x + c ) * ( x + c ) | X and C squared | +| (Y+C)² | ( y + c ) * ( y + c ) | Y and C squared | +| X²+Y+C | x * x + y + c | X squared added to Y and C | +| Y²+X+C | y * y + x + c | Y squared added to X and C | +| X²+CY | x * x + c * y | X squared added to Y multiplied by C | +| Y²+CX | y * y + c * x | Y squared added to X multiplied by C | +## Powers +| Display | Code | Description | +| ------------------------ | ------------------ | -------------------- | +| √(X+C) | sqrt( x + c ) | The square root of X and C | +| √(Y+C) | sqrt( y + c ) | The square root of Y and C | +| Cˣ | powf( c , x ) | C raised to the power of X | +| Cʸ | powf( c , y ) | C raised to the power of Y | +| Cˣ⁺ʸ | powf( c , x + y ) | C raised to the power of X and Y | +| Cˣʸ | powf( c , x * y ) | C raised to the power of X multiplied by Y | +| Xᶜ | powf( x , c ) | X raised to the power of C | +| Yᶜ | powf( y , c ) | Y raised to the power of C | +| Xʸ⁺ᶜ | powf( x , y + c ) | X raised to the power of Y and C | +| Yˣ⁺ᶜ | powf( y , x + c ) | Y raised to the power of X and C | +| Xᶜʸ | powf( x , c * y ) | X raised to the power of Y multiplied by C | +| Yᶜˣ | powf( y , c * x ) | Y raised to the power of X multiplied by C | +## Positive values only +| Display | Code | Description | +| ------------------------ | ------------------ | -------------------- | +| |X+C| | abs( x + c ) | X Added to C with any minus sign removed | +| |Y+C| | abs( y + c ) | Y added to C with any minus sign removed | +## Maximum and Minimum +| Display | Code | Description | +| ------------------------ | ------------------ | -------------------- | +| min(X+C,Y) | min( x + c, y ) | The smaller of X Added to C, or Y | +| min(X,C) | min( x, c ) | The smaller of X or C | +| min(Y,C) | min( y, c ) | The smaller of Y or C | +| max(X+C,Y) | max( x + c, y ) | The larger of X added to C, or Y | +| max(X,C) | max( x, c ) | The larger of X or C | +| max(Y,C) | max( y, c ) | The larger of Y or C | +## Trigonometric +| Display | Code | Description | +| ------------------------ | ------------------ | -------------------- | +| sin(X+C) | sin( x + c ) | The sine of X and C | +| sin(Y+C) | sin( y + c ) | The sine of Y and C | +| sin(X+Y) | sin( x + y ) | The sine of X and Y | +| sin(CX) | sin( c * x ) | The sine of X mulitplied by C | +| sin(CY) | sin( c * y ) | The sine of Y multiplied by C | +| sin(XY) | sin( x * y ) | The sine of X multiplied by Y | +| cos(X+C) | cos( x + c ) | The cosine of X and C | +| cos(Y+C) | cos( y + c ) || +| cos(X+Y) | cos( x + y ) || +| cos(CX) | cos( c * x ) || +| cos(CY) | cos( c * y ) || +| cos(XY) | cos( x * y ) || +| tan(X+C) | tan( x + c ) | The tangent of X and C | +| tan(Y+C) | tan( y + c ) || +| tan(X+Y) | tan( x + y ) || +| tan(CX) | tan( c * x ) || +| tan(CY) | tan( c * y ) || +| tan(XY) | tan( x * y ) || +| asin(X+C) | asin( x + c ) | The arcsine of X and C | +| asin(Y+C) | asin( y + c ) || +| asin(X+Y) | asin( x + y ) || +| asin(CX) | asin( c * x ) || +| asin(CY) | asin( c * y ) || +| asin(XY) | asin( x * y ) || +| acos(X+C) | acos( x + c ) | The arcosine of X and C | +| acos(Y+C) | acos( y + c ) || +| acos(X+Y) | acos( x + y ) || +| acos(CX) | acos( c * x ) || +| acos(CY) | acos( c * y ) || +| acos(XY) | acos( x * y ) || +| atan(X+C) | atan( x + c ) | The arctangent of X and C | +| atan(Y+C) | atan( y + c ) || +| atan(X+Y) | atan( x + y ) || +| atan(CX) | atan( c * x ) || +| atan(CY) | atan( c * y ) || +| atan(XY) | atan( x * y ) || +## Logarithmic +| Display | Code | Description | +| ------------------------ | ------------------ | -------------------- | +| log(X+C) | log( x + c ) | The natural logarithm of X and C | +| log(Y+C) | log( y + c ) | The natural logarithm of Y and C | +| log₂(X+C) | log2( x + c ) | The base-2 logarithm of X and C | +| log₂(Y+C) | log2( y + c ) | The base-2 logarithm of Y and C | +| log₁₀(X+C) | log10( x + c ) | The base-10 logarithm of X and C | +| log₁₀(Y+C) | log10( y + c ) | The base-10 logarithm of Y and C | +## Exponential +| Display | Code | Description | +| ------------------------ | ------------------ | -------------------- | +| ℯˣ⁺ᶜ | exp( x + c ) | e raised to the power of X and C | +| ℯʸ⁺ᶜ | exp( y + c ) | e raised to the power of Y and C | +| ℯᶜˣ | exp( c * x ) | e raised to the power of X multiplied by C | +| ℯᶜʸ | exp( c * y ) | e raised to the power of Y multiplied by C | +| 2ˣ⁺ᶜ | powf( 2, x + c ) | 2 raised to the power of X and C | +| 2ʸ⁺ᶜ | powf( 2, y + c ) | 2 raised to the power of Y and C | +| 2ᶜˣ | powf( 2, c * x ) | 2 raised to the power of X multiplied by C | +| 2ᶜʸ | powf( 2, c * y ) | 2 raised to the power of Y multiplied by C | +| 10ˣ⁺ᶜ | powf( 10, x + c ) | 10 raised to the power of X and C | +| 10ʸ⁺ᶜ | powf( 10, y + c ) | 10 raised to the power of Y and C | +| 10ᶜˣ | powf( 10, c * x ) | 10 raised to the power of X multiplied by C | +| 10ᶜʸ | powf( 10, c * y ) | 10 raised to the power of Y multiplied by C | +## Conditional +| Display | Code | Description | +| ------------------------ | ------------------ | -------------------- | +| if X>0↣Y/C | (x > 0) ? y : c | Y if X is greater than 0 otherwise C | +| if X<0↣Y/C | (x < 0) ? y : c | Y if X is less than 0 otherwise C | +| if X=0↣Y/C | (x == 0) ? y : c | Y if X is 0 otherwise C | +| if X>0↣C/Y | (x > 0) ? c : y | C if X is greater than 0 otherwise Y | +| if X<0↣C/Y | (x < 0) ? c : y | C if X is less that 0 otherwise Y | +| if X=0↣C/Y | (x == 0) ? c : y | C if X is 0 otherwise Y | +| if X>0↣1/0 | (x > 0) ? 1 : 0 | 1 if X is greater than 0 otherwise 0 | +| if X<0↣1/0 | (x < 0) ? 1 : 0 || +| if X=0↣1/0 | (x == 0) ? 1 : 0 || +| if X>0↣X/C | (x > 0) ? x : c | X if X is greater than 0 otherwise C | +| if X<0↣X/C | (x < 0) ? x : c || +| if X=0↣X/C | (x == 0) ? x : c || +| if X>0↣C/X | (x > 0) ? c : x | C if X is greater than 0 otherwise X | +| if X<0↣C/X | (x < 0) ? c : x || +| if X=0↣C/X | (x == 0) ? c : x || +| if Y>0↣X/C | (y > 0) ? x : c | X if Y is greater than 0 otherwise C | +| if Y<0↣X/C | (y < 0) ? x : c || +| if Y=0↣X/C | (y == 0) ? x : c || +| if Y>0↣C/X | (y > 0) ? c : x | C if Y is greater than 0 otherwise X | +| if Y<0↣C/X | (y < 0) ? c : x || +| if Y=0↣C/X | (y == 0) ? c : x || +| if Y>0↣1/0 | (y > 0) ? 1 : 0 || +| if Y<0↣1/0 | (y < 0) ? 1 : 0 || +| if Y=0↣1/0 | (y == 0) ? 1 : 0 || +| if Y>0↣Y/C | (y > 0) ? y : c || +| if Y<0↣Y/C | (y < 0) ? y : c || +| if Y=0↣Y/C | (y == 0) ? y : c || +| if Y>0↣C/Y | (y > 0) ? c : y || +| if Y<0↣C/Y | (y < 0) ? c : y || +| if Y=0↣C/Y | (y == 0) ? c : y || +| if X>Y↣C/0 | (x > y) ? c : 0 | C if X is greater than Y otherwise 0 | +| if XX↣C/0 | (y > x) ? c : 0 || +| if YY↣X/0 | (x > y) ? x : 0 | X if X is greater than Y otherwise 0 | +| if XX↣X/0 | (y > x) ? x : 0 || +| if YY↣Y/0 | (x > y) ? y : 0 || +| if XX↣Y/0 | (y > x) ? y : 0 || +| if YC↣Y/0 | (x > c) ? y : 0 || +| if XX↣Y/0 | (c > x) ? y : 0 || +| if CC↣X/0 | (x > c) ? x : 0 || +| if XX↣X/0 | (c > x) ? x : 0 || +| if CC↣X/Y | (x > c) ? x : y || +| if XX↣X/Y | (c > x) ? x : y || +| if CC↣X/0 | (y > c) ? x : 0 || +| if YY↣X/0 | (c > y) ? x : 0 || +| if CC↣Y/0 | (y > c) ? y : 0 || +| if YY↣Y/0 | (c > y) ? y : 0 || +| if CC↣Y/X | (y > c) ? y : x | Y if Y is greater than C otherwise X | +| if YY↣Y/X | (c > y) ? y : x | Y if C is greater than Y otherwise X | +| if C + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/vst2_bin/plugins/SubmarineFree/res/AO-106.svg b/vst2_bin/plugins/SubmarineFree/res/AO-106.svg new file mode 100644 index 00000000..2c712ebc --- /dev/null +++ b/vst2_bin/plugins/SubmarineFree/res/AO-106.svg @@ -0,0 +1,424 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vst2_bin/plugins/SubmarineFree/res/AO-112.svg b/vst2_bin/plugins/SubmarineFree/res/AO-112.svg new file mode 100644 index 00000000..acbf6198 --- /dev/null +++ b/vst2_bin/plugins/SubmarineFree/res/AO-112.svg @@ -0,0 +1,475 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vst2_bin/plugins/SubmarineFree/res/AO-118.svg b/vst2_bin/plugins/SubmarineFree/res/AO-118.svg new file mode 100644 index 00000000..162c8c4b --- /dev/null +++ b/vst2_bin/plugins/SubmarineFree/res/AO-118.svg @@ -0,0 +1,562 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vst2_bin/plugins/SubmarineFree/res/AO-124.svg b/vst2_bin/plugins/SubmarineFree/res/AO-124.svg new file mode 100644 index 00000000..1f1385fe --- /dev/null +++ b/vst2_bin/plugins/SubmarineFree/res/AO-124.svg @@ -0,0 +1,649 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vst2_bin/plugins/SubmarineFree/res/AO-136.svg b/vst2_bin/plugins/SubmarineFree/res/AO-136.svg new file mode 100644 index 00000000..0ac2c0a9 --- /dev/null +++ b/vst2_bin/plugins/SubmarineFree/res/AO-136.svg @@ -0,0 +1,823 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vst2_bin/plugins/SubmarineFree/res/EO-102.svg b/vst2_bin/plugins/SubmarineFree/res/EO-102.svg new file mode 100644 index 00000000..c5a47552 --- /dev/null +++ b/vst2_bin/plugins/SubmarineFree/res/EO-102.svg @@ -0,0 +1,649 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vst2_bin/plugins/SubmarineFree/res/FF-206.svg b/vst2_bin/plugins/SubmarineFree/res/FF-206.svg new file mode 100644 index 00000000..6c243796 --- /dev/null +++ b/vst2_bin/plugins/SubmarineFree/res/FF-206.svg @@ -0,0 +1,108 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/vst2_bin/plugins/SubmarineFree/res/LD-103.svg b/vst2_bin/plugins/SubmarineFree/res/LD-103.svg new file mode 100644 index 00000000..944d9fa4 --- /dev/null +++ b/vst2_bin/plugins/SubmarineFree/res/LD-103.svg @@ -0,0 +1,145 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/vst2_bin/plugins/SubmarineFree/res/NG-106.svg b/vst2_bin/plugins/SubmarineFree/res/NG-106.svg new file mode 100644 index 00000000..9dabce81 --- /dev/null +++ b/vst2_bin/plugins/SubmarineFree/res/NG-106.svg @@ -0,0 +1,104 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/vst2_bin/plugins/SubmarineFree/res/OG-104.svg b/vst2_bin/plugins/SubmarineFree/res/OG-104.svg new file mode 100644 index 00000000..131190dd --- /dev/null +++ b/vst2_bin/plugins/SubmarineFree/res/OG-104.svg @@ -0,0 +1,100 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/vst2_bin/plugins/SubmarineFree/res/PG-104.svg b/vst2_bin/plugins/SubmarineFree/res/PG-104.svg new file mode 100644 index 00000000..b7fb29d5 --- /dev/null +++ b/vst2_bin/plugins/SubmarineFree/res/PG-104.svg @@ -0,0 +1,96 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/vst2_bin/plugins/SubmarineFree/res/SS-112.svg b/vst2_bin/plugins/SubmarineFree/res/SS-112.svg new file mode 100644 index 00000000..053e9e53 --- /dev/null +++ b/vst2_bin/plugins/SubmarineFree/res/SS-112.svg @@ -0,0 +1,76 @@ + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/vst2_bin/plugins/SubmarineFree/res/SS-208.svg b/vst2_bin/plugins/SubmarineFree/res/SS-208.svg new file mode 100644 index 00000000..f5a326ba --- /dev/null +++ b/vst2_bin/plugins/SubmarineFree/res/SS-208.svg @@ -0,0 +1,165 @@ + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/vst2_bin/plugins/SubmarineFree/res/SS-212.svg b/vst2_bin/plugins/SubmarineFree/res/SS-212.svg new file mode 100644 index 00000000..4147c199 --- /dev/null +++ b/vst2_bin/plugins/SubmarineFree/res/SS-212.svg @@ -0,0 +1,104 @@ + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/vst2_bin/plugins/SubmarineFree/res/SS-220.svg b/vst2_bin/plugins/SubmarineFree/res/SS-220.svg new file mode 100644 index 00000000..f67f4a99 --- /dev/null +++ b/vst2_bin/plugins/SubmarineFree/res/SS-220.svg @@ -0,0 +1,153 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/vst2_bin/plugins/SubmarineFree/res/SS-221.svg b/vst2_bin/plugins/SubmarineFree/res/SS-221.svg new file mode 100644 index 00000000..9ba5787c --- /dev/null +++ b/vst2_bin/plugins/SubmarineFree/res/SS-221.svg @@ -0,0 +1,414 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vst2_bin/plugins/SubmarineFree/res/TD-116.svg b/vst2_bin/plugins/SubmarineFree/res/TD-116.svg new file mode 100644 index 00000000..4337fa87 --- /dev/null +++ b/vst2_bin/plugins/SubmarineFree/res/TD-116.svg @@ -0,0 +1,181 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vst2_bin/plugins/SubmarineFree/res/TD-202.svg b/vst2_bin/plugins/SubmarineFree/res/TD-202.svg new file mode 100644 index 00000000..0911b5ae --- /dev/null +++ b/vst2_bin/plugins/SubmarineFree/res/TD-202.svg @@ -0,0 +1,81 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/vst2_bin/plugins/SubmarineFree/res/TF-101.svg b/vst2_bin/plugins/SubmarineFree/res/TF-101.svg new file mode 100644 index 00000000..bbbcfc0a --- /dev/null +++ b/vst2_bin/plugins/SubmarineFree/res/TF-101.svg @@ -0,0 +1,329 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vst2_bin/plugins/SubmarineFree/res/TM-105.svg b/vst2_bin/plugins/SubmarineFree/res/TM-105.svg new file mode 100644 index 00000000..2867cabd --- /dev/null +++ b/vst2_bin/plugins/SubmarineFree/res/TM-105.svg @@ -0,0 +1,109 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vst2_bin/plugins/SubmarineFree/res/XG-104.svg b/vst2_bin/plugins/SubmarineFree/res/XG-104.svg new file mode 100644 index 00000000..90e488ad --- /dev/null +++ b/vst2_bin/plugins/SubmarineFree/res/XG-104.svg @@ -0,0 +1,100 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/vst2_bin/settings.json b/vst2_bin/settings.json index b1be097b..8688a3e2 100644 --- a/vst2_bin/settings.json +++ b/vst2_bin/settings.json @@ -31,6 +31,10 @@ "lastPath": "", "moduleBrowser": { "favorites": [ + { + "plugin": "Alikins", + "model": "SpecificValue" + }, { "plugin": "Core", "model": "Notes" @@ -40,8 +44,24 @@ "model": "kHzD_Inf" }, { - "plugin": "Alikins", - "model": "SpecificValue" + "plugin": "AudibleInstruments", + "model": "Braids" + }, + { + "plugin": "AudibleInstruments", + "model": "Clouds" + }, + { + "plugin": "AudibleInstruments", + "model": "Rings" + }, + { + "plugin": "AudibleInstruments", + "model": "Plaits" + }, + { + "plugin": "AudibleInstruments", + "model": "Stages" }, { "plugin": "AS", @@ -55,21 +75,13 @@ "plugin": "AS", "model": "AtNuVrTr" }, - { - "plugin": "AudibleInstruments", - "model": "Braids" - }, { "plugin": "AudibleInstruments", "model": "Elements" }, { "plugin": "AudibleInstruments", - "model": "Clouds" - }, - { - "plugin": "Autodafe", - "model": "Multiple 1x8" + "model": "Tides" }, { "plugin": "Befaco", @@ -80,8 +92,8 @@ "model": "SlewLimiter" }, { - "plugin": "Bidoo", - "model": "lIMbO" + "plugin": "Autodafe", + "model": "Multiple 1x8" }, { "plugin": "Bidoo", @@ -93,23 +105,23 @@ }, { "plugin": "Bogaudio", - "model": "Bogaudio-XCO" + "model": "Bogaudio-Additator" }, { - "plugin": "Bogaudio", - "model": "Bogaudio-Additator" + "plugin": "Bidoo", + "model": "lIMbO" }, { "plugin": "Bogaudio", - "model": "Bogaudio-XFade" + "model": "Bogaudio-XCO" }, { "plugin": "Bogaudio", - "model": "Bogaudio-VCAmp" + "model": "Bogaudio-SampleHold" }, { "plugin": "Bogaudio", - "model": "Bogaudio-Mult" + "model": "Bogaudio-XFade" }, { "plugin": "Bogaudio", @@ -117,27 +129,31 @@ }, { "plugin": "Bogaudio", - "model": "Bogaudio-SampleHold" + "model": "Bogaudio-Switch" }, { "plugin": "Bogaudio", - "model": "Bogaudio-Switch" + "model": "Bogaudio-VCAmp" }, { - "plugin": "DHE-Modules", - "model": "Cubic" + "plugin": "Bogaudio", + "model": "Bogaudio-Mult" }, { - "plugin": "ErraticInstruments", - "model": "MPEToCV" + "plugin": "huaba", + "model": "EQ3" }, { - "plugin": "FrankBussFormula", - "model": "FrankBussFormula" + "plugin": "Fundamental", + "model": "Scope" + }, + { + "plugin": "HetrickCV", + "model": "Exponent" }, { "plugin": "Fundamental", - "model": "VCO" + "model": "VCA-1" }, { "plugin": "Fundamental", @@ -145,67 +161,67 @@ }, { "plugin": "Fundamental", - "model": "VCF" + "model": "VCMixer" }, { "plugin": "Fundamental", - "model": "VCA-1" + "model": "VCO" }, { - "plugin": "Fundamental", - "model": "VCA" + "plugin": "FrankBussFormula", + "model": "FrankBussFormula" }, { "plugin": "Fundamental", - "model": "LFO" + "model": "VCF" }, { "plugin": "Fundamental", - "model": "LFO2" + "model": "VCA" }, { "plugin": "Fundamental", - "model": "VCMixer" + "model": "LFO" }, { "plugin": "Fundamental", - "model": "Scope" + "model": "LFO2" }, { - "plugin": "HetrickCV", - "model": "Exponent" + "plugin": "ErraticInstruments", + "model": "MPEToCV" }, { - "plugin": "huaba", - "model": "EQ3" + "plugin": "DHE-Modules", + "model": "Cubic" }, { - "plugin": "JE", - "model": "RingModulator" + "plugin": "ML_modules", + "model": "VoltMeter" }, { - "plugin": "LindenbergResearch", - "model": "VCF" + "plugin": "mscHack", + "model": "Maude221" }, { "plugin": "LindenbergResearch", - "model": "MS20 VCF" + "model": "Westcoast VCS" }, { "plugin": "LindenbergResearch", - "model": "VCO" + "model": "MS20 VCF" }, { "plugin": "LindenbergResearch", - "model": "Westcoast VCS" + "model": "VCF" }, { - "plugin": "ML_modules", - "model": "VoltMeter" + "plugin": "JE", + "model": "RingModulator" }, { - "plugin": "mscHack", - "model": "Maude221" + "plugin": "LindenbergResearch", + "model": "VCO" }, { "plugin": "PG-Instruments", @@ -220,20 +236,20 @@ "model": "Abr" }, { - "plugin": "Valley", - "model": "Dexter" + "plugin": "bsp", + "model": "TunedDelayLine" }, { "plugin": "Valley", - "model": "Plateau" + "model": "Dexter" }, { "plugin": "bsp", - "model": "AttenuMixer" + "model": "RMS" }, { - "plugin": "bsp", - "model": "DownSampler" + "plugin": "Valley", + "model": "Plateau" }, { "plugin": "bsp", @@ -241,23 +257,23 @@ }, { "plugin": "bsp", - "model": "Obxd_VCF" + "model": "Scanner" }, { "plugin": "bsp", - "model": "RMS" + "model": "AttenuMixer" }, { "plugin": "bsp", - "model": "Scanner" + "model": "DownSampler" }, { "plugin": "bsp", - "model": "Sway" + "model": "Obxd_VCF" }, { "plugin": "bsp", - "model": "TunedDelayLine" + "model": "Sway" }, { "plugin": "Template_shared", @@ -267,4 +283,4 @@ }, "powerMeter": false, "checkVersion": true -} +} \ No newline at end of file