Browse Source

Add Audio to CV Pitch Cardinal module

Signed-off-by: falkTX <falktx@falktx.com>
tags/22.05
falkTX 2 months ago
parent
commit
0d952f80af
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
14 changed files with 750 additions and 20 deletions
  1. +14
    -1
      Makefile
  2. +140
    -0
      plugins/Cardinal/orig/AudioToCVPitch.svg
  3. +9
    -0
      plugins/Cardinal/plugin.json
  4. +179
    -0
      plugins/Cardinal/res/AudioToCVPitch.svg
  5. +1
    -0
      plugins/Cardinal/src/.kdev_include_paths
  6. +362
    -0
      plugins/Cardinal/src/AudioToCVPitch.cpp
  7. +3
    -1
      plugins/Cardinal/src/HostAudio.cpp
  8. +1
    -1
      plugins/Cardinal/src/HostTime.cpp
  9. +22
    -16
      plugins/Cardinal/src/Widgets.hpp
  10. +1
    -0
      plugins/Cardinal/src/plugin.hpp
  11. +1
    -1
      plugins/Fundamental
  12. +6
    -0
      plugins/Makefile
  13. +5
    -0
      plugins/plugins.cpp
  14. +6
    -0
      src/Makefile.cardinal.mk

+ 14
- 1
Makefile View File

@@ -67,7 +67,7 @@ DGL_EXTRA_ARGS = \
WINDOWS_ICON_ID=401

# --------------------------------------------------------------
# Check for system-wide dependencies
# Check for required system-wide dependencies

ifeq ($(SYSDEPS),true)

@@ -125,6 +125,15 @@ endif
endif
endif

# --------------------------------------------------------------
# Check for optional system-wide dependencies

ifeq ($(shell pkg-config --exists fftw3f && echo true),true)
HAVE_FFTW3F = true
else
$(warning fftw3f dependency not installed/available)
endif

# --------------------------------------------------------------
# MOD builds

@@ -202,6 +211,9 @@ ifeq ($(SYSDEPS),true)
else
$(MAKE) all -C deps
endif
ifeq ($(HAVE_FFTW3F),true)
$(MAKE) all -C deps/aubio
endif

dgl:
ifneq ($(HEADLESS),true)
@@ -250,6 +262,7 @@ deps/unzipfx/unzipfx2cat.exe:
clean:
$(MAKE) distclean -C carla $(CARLA_EXTRA_ARGS) CAN_GENERATE_LV2_TTL=false STATIC_PLUGIN_TARGET=true
$(MAKE) clean -C deps
$(MAKE) clean -C deps/aubio
$(MAKE) clean -C dpf/dgl
$(MAKE) clean -C dpf/utils/lv2-ttl-generator
$(MAKE) clean -C plugins


+ 140
- 0
plugins/Cardinal/orig/AudioToCVPitch.svg View File

@@ -0,0 +1,140 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->

<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="30.48mm"
height="128.5mm"
viewBox="0 0 30.479999 128.5"
version="1.1"
id="svg4620"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
sodipodi:docname="AudioToCVPitch.svg">
<defs
id="defs4614">
<style
id="style6"
type="text/css">
.str0 {stroke:#565656;stroke-width:0.0966867}
.str1 {stroke:#4F4F4F;stroke-width:0.193345}
.fil0 {fill:none}
.fil2 {fill:#2B2A29}
.fil1 {fill:#6B6B6B}
</style>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="5.6"
inkscape:cx="62.166118"
inkscape:cy="427.68633"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1026"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1" />
<metadata
id="metadata4617">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-168.5)">
<g
id="g843"
transform="translate(-2.2361371)">
<g
transform="matrix(6.342689,0,0,6.342689,5.4472535,175.6457)"
id="g5299"
style="fill-rule:evenodd">
<g
id="Layer_x0020_1"
transform="translate(-1.6191379e-5,-0.08553947)">
<metadata
id="CorelCorpID_0Corel-Layer" />
<circle
class="fil0 str0"
cx="0.525226"
cy="0.61075097"
r="0.15916"
id="circle10"
style="fill:none;stroke:#ffffff;stroke-width:0.0966867;stroke-opacity:1" />
<circle
class="fil0 str1"
cx="0.525226"
cy="0.61075097"
r="0.42853901"
id="circle12"
style="fill:none;stroke:#ffffff;stroke-width:0.193345;stroke-opacity:1" />
</g>
</g>
<g
transform="translate(-0.09449404,0.14174107)"
id="text5303"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.58333302px;line-height:1.25;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
aria-label="Cardinal">
<path
inkscape:connector-curvature="0"
id="path5305"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.3499999px;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke-width:0.26458332"
d="m 17.923601,176.99103 v 0.66043 q -0.31626,-0.29456 -0.675928,-0.44028 -0.356567,-0.14573 -0.759643,-0.14573 -0.79375,0 -1.21543,0.48679 -0.42168,0.48369 -0.42168,1.40146 0,0.91468 0.42168,1.40147 0.42168,0.48369 1.21543,0.48369 0.403076,0 0.759643,-0.14573 0.359668,-0.14572 0.675928,-0.44028 v 0.65422 q -0.328662,0.22325 -0.697632,0.33487 -0.365869,0.11162 -0.775146,0.11162 -1.051099,0 -1.655713,-0.64182 -0.604615,-0.64492 -0.604615,-1.75804 0,-1.11621 0.604615,-1.75803 0.604614,-0.64492 1.655713,-0.64492 0.415478,0 0.781347,0.11162 0.36897,0.10852 0.691431,0.32866 z" />
<path
inkscape:connector-curvature="0"
id="path5309"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.3499999px;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke-width:0.26458332"
d="m 20.682747,178.32429 q -0.09612,-0.0558 -0.21084,-0.0806 -0.111621,-0.0279 -0.248047,-0.0279 -0.483691,0 -0.744141,0.31626 -0.257348,0.31315 -0.257348,0.90227 v 1.82934 h -0.573609 v -3.47265 h 0.573609 v 0.5395 q 0.179834,-0.31626 0.468188,-0.46819 0.288355,-0.15503 0.700733,-0.15503 0.05891,0 0.130224,0.009 0.07131,0.006 0.15813,0.0217 z" />
<path
inkscape:connector-curvature="0"
id="path5311"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.3499999px;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke-width:0.26458332"
d="m 23.45467,178.31808 v -1.87895 h 0.570508 v 4.82451 H 23.45467 v -0.5209 q -0.179834,0.31006 -0.455786,0.46199 -0.272851,0.14883 -0.657324,0.14883 -0.629419,0 -1.026294,-0.5023 -0.393774,-0.50229 -0.393774,-1.32085 0,-0.81855 0.393774,-1.32085 0.396875,-0.50229 1.026294,-0.50229 0.384473,0 0.657324,0.15193 0.275952,0.14883 0.455786,0.45888 z m -1.944067,1.21233 q 0,0.62942 0.257349,0.98909 0.260449,0.35657 0.713134,0.35657 0.452686,0 0.713135,-0.35657 0.260449,-0.35967 0.260449,-0.98909 0,-0.62942 -0.260449,-0.98598 -0.260449,-0.35967 -0.713135,-0.35967 -0.452685,0 -0.713134,0.35967 -0.257349,0.35656 -0.257349,0.98598 z" />
<path
inkscape:connector-curvature="0"
id="path5315"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.3499999px;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke-width:0.26458332"
d="m 28.108637,179.16765 v 2.09599 h -0.570508 v -2.07739 q 0,-0.49299 -0.192236,-0.73794 -0.192236,-0.24495 -0.576709,-0.24495 -0.461987,0 -0.728638,0.29456 -0.26665,0.29455 -0.26665,0.80305 v 1.96267 h -0.573608 v -3.47265 h 0.573608 v 0.5395 q 0.204639,-0.31316 0.480591,-0.46819 0.279053,-0.15503 0.641821,-0.15503 0.598413,0 0.905371,0.37207 0.306958,0.36897 0.306958,1.08831 z" />
<path
inkscape:connector-curvature="0"
id="path5319"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.3499999px;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke-width:0.26458332"
d="m 29.029017,176.43913 h 0.570508 v 4.82451 h -0.570508 z" />
</g>
</g>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.58333302px;line-height:1.25;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#808a8a;fill-opacity:1;stroke:none;stroke-width:0.26458332"
x="2.6467977"
y="189.18228"
id="text845"><tspan
sodipodi:role="line"
id="tspan843"
x="2.6467977"
y="189.18228"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.93888903px;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#808a8a;fill-opacity:1;stroke-width:0.26458332">ToCV Pitch</tspan></text>
</g>
</svg>

+ 9
- 0
plugins/Cardinal/plugin.json View File

@@ -146,6 +146,15 @@
"Utility"
]
},
{
"slug": "AudioToCVPitch",
"name": "Audio To CV Pitch",
"description": "Converts a monophonic audio signal to CV pitch",
"manualUrl": "https://github.com/DISTRHO/Cardinal/blob/main/docs/CARDINAL-MODULES.md#audio-to-cv-pitch",
"tags": [
"Utility"
]
},
{
"slug": "Carla",
"name": "Carla Plugin Host",


+ 179
- 0
plugins/Cardinal/res/AudioToCVPitch.svg View File

@@ -0,0 +1,179 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->

<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="30.48mm"
height="128.5mm"
viewBox="0 0 30.479999 128.5"
version="1.1"
id="svg4620"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
sodipodi:docname="AudioToCVPitch.svg">
<defs
id="defs4614">
<style
id="style6"
type="text/css">
.str0 {stroke:#565656;stroke-width:0.0966867}
.str1 {stroke:#4F4F4F;stroke-width:0.193345}
.fil0 {fill:none}
.fil2 {fill:#2B2A29}
.fil1 {fill:#6B6B6B}
</style>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="5.6"
inkscape:cx="62.166118"
inkscape:cy="427.68633"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1026"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1" />
<metadata
id="metadata4617">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-168.5)">
<g
id="g843"
transform="translate(-2.2361371)">
<g
transform="matrix(6.342689,0,0,6.342689,5.4472535,175.6457)"
id="g5299"
style="fill-rule:evenodd">
<g
id="Layer_x0020_1"
transform="translate(-1.6191379e-5,-0.08553947)">
<metadata
id="CorelCorpID_0Corel-Layer" />
<circle
class="fil0 str0"
cx="0.525226"
cy="0.61075097"
r="0.15916"
id="circle10"
style="fill:none;stroke:#ffffff;stroke-width:0.0966867;stroke-opacity:1" />
<circle
class="fil0 str1"
cx="0.525226"
cy="0.61075097"
r="0.42853901"
id="circle12"
style="fill:none;stroke:#ffffff;stroke-width:0.193345;stroke-opacity:1" />
</g>
</g>
<g
transform="translate(-0.09449404,0.14174107)"
id="text5303"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.58333302px;line-height:1.25;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
aria-label="Cardinal">
<path
inkscape:connector-curvature="0"
id="path5305"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.3499999px;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke-width:0.26458332"
d="m 17.923601,176.99103 v 0.66043 q -0.31626,-0.29456 -0.675928,-0.44028 -0.356567,-0.14573 -0.759643,-0.14573 -0.79375,0 -1.21543,0.48679 -0.42168,0.48369 -0.42168,1.40146 0,0.91468 0.42168,1.40147 0.42168,0.48369 1.21543,0.48369 0.403076,0 0.759643,-0.14573 0.359668,-0.14572 0.675928,-0.44028 v 0.65422 q -0.328662,0.22325 -0.697632,0.33487 -0.365869,0.11162 -0.775146,0.11162 -1.051099,0 -1.655713,-0.64182 -0.604615,-0.64492 -0.604615,-1.75804 0,-1.11621 0.604615,-1.75803 0.604614,-0.64492 1.655713,-0.64492 0.415478,0 0.781347,0.11162 0.36897,0.10852 0.691431,0.32866 z" />
<path
inkscape:connector-curvature="0"
id="path5309"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.3499999px;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke-width:0.26458332"
d="m 20.682747,178.32429 q -0.09612,-0.0558 -0.21084,-0.0806 -0.111621,-0.0279 -0.248047,-0.0279 -0.483691,0 -0.744141,0.31626 -0.257348,0.31315 -0.257348,0.90227 v 1.82934 h -0.573609 v -3.47265 h 0.573609 v 0.5395 q 0.179834,-0.31626 0.468188,-0.46819 0.288355,-0.15503 0.700733,-0.15503 0.05891,0 0.130224,0.009 0.07131,0.006 0.15813,0.0217 z" />
<path
inkscape:connector-curvature="0"
id="path5311"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.3499999px;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke-width:0.26458332"
d="m 23.45467,178.31808 v -1.87895 h 0.570508 v 4.82451 H 23.45467 v -0.5209 q -0.179834,0.31006 -0.455786,0.46199 -0.272851,0.14883 -0.657324,0.14883 -0.629419,0 -1.026294,-0.5023 -0.393774,-0.50229 -0.393774,-1.32085 0,-0.81855 0.393774,-1.32085 0.396875,-0.50229 1.026294,-0.50229 0.384473,0 0.657324,0.15193 0.275952,0.14883 0.455786,0.45888 z m -1.944067,1.21233 q 0,0.62942 0.257349,0.98909 0.260449,0.35657 0.713134,0.35657 0.452686,0 0.713135,-0.35657 0.260449,-0.35967 0.260449,-0.98909 0,-0.62942 -0.260449,-0.98598 -0.260449,-0.35967 -0.713135,-0.35967 -0.452685,0 -0.713134,0.35967 -0.257349,0.35656 -0.257349,0.98598 z" />
<path
inkscape:connector-curvature="0"
id="path5315"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.3499999px;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke-width:0.26458332"
d="m 28.108637,179.16765 v 2.09599 h -0.570508 v -2.07739 q 0,-0.49299 -0.192236,-0.73794 -0.192236,-0.24495 -0.576709,-0.24495 -0.461987,0 -0.728638,0.29456 -0.26665,0.29455 -0.26665,0.80305 v 1.96267 h -0.573608 v -3.47265 h 0.573608 v 0.5395 q 0.204639,-0.31316 0.480591,-0.46819 0.279053,-0.15503 0.641821,-0.15503 0.598413,0 0.905371,0.37207 0.306958,0.36897 0.306958,1.08831 z" />
<path
inkscape:connector-curvature="0"
id="path5319"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.3499999px;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke-width:0.26458332"
d="m 29.029017,176.43913 h 0.570508 v 4.82451 h -0.570508 z" />
</g>
</g>
<g
aria-label="ToCV Pitch"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.58333302px;line-height:1.25;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#808a8a;fill-opacity:1;stroke:none;stroke-width:0.26458332"
id="text845">
<path
d="m 2.6323283,185.58181 h 3.045809 v 0.40997 H 4.4000068 v 3.1905 H 3.9104587 v -3.1905 H 2.6323283 Z"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.93888903px;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#808a8a;fill-opacity:1;stroke-width:0.26458332"
id="path904"
inkscape:connector-curvature="0" />
<path
d="m 6.3364951,186.79242 q -0.3569119,0 -0.5643067,0.27974 -0.2073947,0.27733 -0.2073947,0.76206 0,0.48472 0.2049832,0.76446 0.2073947,0.27733 0.5667182,0.27733 0.3545003,0 0.5618951,-0.27974 0.2073947,-0.27974 0.2073947,-0.76205 0,-0.47991 -0.2073947,-0.75965 -0.2073948,-0.28215 -0.5618951,-0.28215 z m 0,-0.37621 q 0.578776,0 0.9091607,0.37621 0.3303847,0.3762 0.3303847,1.0418 0,0.66318 -0.3303847,1.04179 -0.3303847,0.37621 -0.9091607,0.37621 -0.5811876,0 -0.9115723,-0.37621 -0.3279731,-0.37861 -0.3279731,-1.04179 0,-0.6656 0.3279731,-1.0418 0.3303847,-0.37621 0.9115723,-0.37621 z"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.93888903px;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#808a8a;fill-opacity:1;stroke-width:0.26458332"
id="path906"
inkscape:connector-curvature="0" />
<path
d="m 11.026992,185.85914 v 0.51367 q -0.245979,-0.2291 -0.525721,-0.34245 -0.27733,-0.11334 -0.5908341,-0.11334 -0.6173611,0 -0.9453342,0.37862 -0.3279731,0.3762 -0.3279731,1.09002 0,0.71142 0.3279731,1.09003 0.3279731,0.37621 0.9453342,0.37621 0.3135041,0 0.5908341,-0.11335 0.279742,-0.11334 0.525721,-0.34244 v 0.50884 q -0.255626,0.17363 -0.542602,0.26045 -0.284565,0.0868 -0.6028919,0.0868 -0.8175212,0 -1.2877767,-0.4992 -0.4702556,-0.5016 -0.4702556,-1.36736 0,-0.86816 0.4702556,-1.36735 0.4702555,-0.50161 1.2877767,-0.50161 0.3231499,0 0.6077149,0.0868 0.286976,0.0844 0.537779,0.25562 z"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.93888903px;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#808a8a;fill-opacity:1;stroke-width:0.26458332"
id="path908"
inkscape:connector-curvature="0" />
<path
d="m 12.707855,189.18228 -1.374594,-3.60047 h 0.508841 l 1.140671,3.03134 1.143083,-3.03134 h 0.506429 l -1.372182,3.60047 z"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.93888903px;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#808a8a;fill-opacity:1;stroke-width:0.26458332"
id="path910"
inkscape:connector-curvature="0" />
<path
d="m 17.215074,185.98213 v 1.35289 h 0.612538 q 0.340031,0 0.525721,-0.17604 0.185691,-0.17605 0.185691,-0.50161 0,-0.32315 -0.185691,-0.49919 -0.18569,-0.17605 -0.525721,-0.17605 z m -0.487137,-0.40032 h 1.099675 q 0.605303,0 0.913984,0.27492 0.311092,0.27251 0.311092,0.80064 0,0.53296 -0.311092,0.80546 -0.308681,0.27251 -0.913984,0.27251 h -0.612538 v 1.44694 h -0.487137 z"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.93888903px;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#808a8a;fill-opacity:1;stroke-width:0.26458332"
id="path912"
inkscape:connector-curvature="0" />
<path
d="m 19.578409,186.48133 h 0.443728 v 2.70095 h -0.443728 z m 0,-1.05145 h 0.443728 v 0.5619 h -0.443728 z"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.93888903px;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#808a8a;fill-opacity:1;stroke-width:0.26458332"
id="path914"
inkscape:connector-curvature="0" />
<path
d="m 21.389495,185.71445 v 0.76688 h 0.913984 v 0.34485 h -0.913984 v 1.46623 q 0,0.33039 0.08923,0.42444 0.09164,0.0941 0.36897,0.0941 h 0.455786 v 0.37138 h -0.455786 q -0.513664,0 -0.709001,-0.19051 -0.195337,-0.19293 -0.195337,-0.69936 v -1.46623 h -0.325561 v -0.34485 h 0.325561 v -0.76688 z"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.93888903px;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#808a8a;fill-opacity:1;stroke-width:0.26458332"
id="path916"
inkscape:connector-curvature="0" />
<path
d="m 24.830802,186.58502 v 0.41479 q -0.188102,-0.10369 -0.378616,-0.15434 -0.188102,-0.0531 -0.381028,-0.0531 -0.43167,0 -0.670415,0.27492 -0.238745,0.2725 -0.238745,0.76688 0,0.49437 0.238745,0.76929 0.238745,0.2725 0.670415,0.2725 0.192926,0 0.381028,-0.0506 0.190514,-0.053 0.378616,-0.15675 v 0.40996 q -0.185691,0.0868 -0.385851,0.13023 -0.197748,0.0434 -0.422024,0.0434 -0.610126,0 -0.96945,-0.38344 -0.359323,-0.38344 -0.359323,-1.03456 0,-0.66077 0.361735,-1.03939 0.364146,-0.37862 0.995977,-0.37862 0.204983,0 0.40032,0.0434 0.195337,0.041 0.378616,0.1254 z"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.93888903px;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#808a8a;fill-opacity:1;stroke-width:0.26458332"
id="path918"
inkscape:connector-curvature="0" />
<path
d="m 27.847671,187.55206 v 1.63022 h -0.443728 v -1.61575 q 0,-0.38344 -0.149517,-0.57395 -0.149517,-0.19052 -0.448552,-0.19052 -0.359323,0 -0.566718,0.2291 -0.207394,0.2291 -0.207394,0.6246 v 1.52652 h -0.44614 v -3.7524 h 0.44614 v 1.47106 q 0.159163,-0.24357 0.373792,-0.36415 0.217041,-0.12058 0.499195,-0.12058 0.465432,0 0.704177,0.28939 0.238745,0.28698 0.238745,0.84646 z"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.93888903px;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#808a8a;fill-opacity:1;stroke-width:0.26458332"
id="path920"
inkscape:connector-curvature="0" />
</g>
</g>
</svg>

+ 1
- 0
plugins/Cardinal/src/.kdev_include_paths View File

@@ -1,3 +1,4 @@
../../../deps/aubio/src
../../../include
../../../carla/source/backend
../../../carla/source/includes


+ 362
- 0
plugins/Cardinal/src/AudioToCVPitch.cpp View File

@@ -0,0 +1,362 @@
/*
* DISTRHO Cardinal Plugin
* Copyright (C) 2021-2022 Bram Giesen
* Copyright (C) 2022 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 3 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the LICENSE file.
*/

#include "plugincontext.hpp"
#include "ModuleWidgets.hpp"
#include "Widgets.hpp"

extern "C" {
#include "aubio.h"
}

USE_NAMESPACE_DISTRHO;

// --------------------------------------------------------------------------------------------------------------------

// aubio setup values (tested under 48 kHz sample rate)
static constexpr const uint32_t kAubioHopSize = 1;
static constexpr const uint32_t kAubioBufferSize = (1024 + 256 + 128) / kAubioHopSize;

// default values
static constexpr const float kDefaultSensitivity = 50.f;
static constexpr const float kDefaultTolerance = 6.25f;
static constexpr const float kDefaultThreshold = 12.5f;

// static checks
static_assert(sizeof(smpl_t) == sizeof(float), "smpl_t is float");
static_assert(kAubioBufferSize % kAubioHopSize == 0, "kAubioBufferSize / kAubioHopSize has no remainder");

// --------------------------------------------------------------------------------------------------------------------

struct AudioToCVPitch : Module {
enum ParamIds {
PARAM_SENSITIVITY,
PARAM_CONFIDENCETHRESHOLD,
PARAM_TOLERANCE,
PARAM_OCTAVE,
NUM_PARAMS
};
enum InputIds {
AUDIO_INPUT,
NUM_INPUTS
};
enum OutputIds {
CV_PITCH,
CV_GATE,
NUM_OUTPUTS
};
enum LightIds {
NUM_LIGHTS
};

bool holdOutputPitch = true;
bool smooth = true;
int octave = 0;

float lastKnownPitchInHz = 0.f;
float lastKnownPitchConfidence = 0.f;

float lastUsedTolerance = kDefaultTolerance;
float lastUsedOutputPitch = 0.f;
float lastUsedOutputSignal = 0.f;

fvec_t* const detectedPitch = new_fvec(1);
fvec_t* const inputBuffer = new_fvec(kAubioBufferSize);
uint32_t inputBufferPos = 0;

aubio_pitch_t* pitchDetector = nullptr;

dsp::SlewLimiter smoothOutputSignal;

AudioToCVPitch()
{
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);

configInput(AUDIO_INPUT, "Audio");
configOutput(CV_PITCH, "Pitch");
configOutput(CV_GATE, "Gate");
configParam(PARAM_SENSITIVITY, 0.1f, 99.f, kDefaultSensitivity, "Sensitivity", " %");
configParam(PARAM_CONFIDENCETHRESHOLD, 0.f, 99.f, kDefaultThreshold, "Confidence Threshold", " %");
configParam(PARAM_TOLERANCE, 0.f, 99.f, kDefaultTolerance, "Tolerance", " %");
}

void process(const ProcessArgs& args) override
{
float cvPitch = lastUsedOutputPitch;
float cvSignal = lastUsedOutputSignal;

inputBuffer->data[inputBufferPos] = inputs[AUDIO_INPUT].getVoltage() * 0.1f
* params[PARAM_SENSITIVITY].getValue();

if (++inputBufferPos == kAubioBufferSize)
{
inputBufferPos = 0;

const float tolerance = params[PARAM_TOLERANCE].getValue();
if (d_isNotEqual(lastUsedTolerance, tolerance))
{
lastUsedTolerance = tolerance;
aubio_pitch_set_tolerance(pitchDetector, tolerance * 0.01f);
}

aubio_pitch_do(pitchDetector, inputBuffer, detectedPitch);
const float detectedPitchInHz = fvec_get_sample(detectedPitch, 0);
const float pitchConfidence = aubio_pitch_get_confidence(pitchDetector);

if (detectedPitchInHz > 0.f && pitchConfidence >= params[PARAM_CONFIDENCETHRESHOLD].getValue() * 0.01f)
{
const float linearPitch = 12.f * (log2f(detectedPitchInHz / 440.f) + octave - 1) + 69.f;
cvPitch = std::max(-10.f, std::min(10.f, linearPitch * (1.f/12.f)));
lastKnownPitchInHz = detectedPitchInHz;
cvSignal = 10.f;
}
else
{
if (! holdOutputPitch)
lastKnownPitchInHz = cvPitch = 0.0f;

cvSignal = 0.f;
}

lastKnownPitchConfidence = pitchConfidence;
lastUsedOutputPitch = cvPitch;
lastUsedOutputSignal = cvSignal;
}

outputs[CV_PITCH].setVoltage(smooth ? smoothOutputSignal.process(args.sampleTime, cvPitch) : cvPitch);
outputs[CV_GATE].setVoltage(cvSignal);
}

void onReset() override
{
inputBufferPos = 0;
smooth = true;
holdOutputPitch = true;
octave = 0;
}

void onSampleRateChange(const SampleRateChangeEvent& e) override
{
float tolerance;

if (pitchDetector != nullptr)
{
tolerance = aubio_pitch_get_tolerance(pitchDetector);
del_aubio_pitch(pitchDetector);
}
else
{
tolerance = kDefaultTolerance * 0.01f;
}

pitchDetector = new_aubio_pitch("yinfast", kAubioBufferSize, kAubioHopSize, e.sampleRate);
DISTRHO_SAFE_ASSERT_RETURN(pitchDetector != nullptr,);

aubio_pitch_set_silence(pitchDetector, -30.0f);
aubio_pitch_set_tolerance(pitchDetector, tolerance);
aubio_pitch_set_unit(pitchDetector, "Hz");

const double fall = 1.0 / (double(kAubioBufferSize) / e.sampleRate);
smoothOutputSignal.reset();
smoothOutputSignal.setRiseFall(fall, fall);
}

json_t* dataToJson() override
{
json_t* const rootJ = json_object();
DISTRHO_SAFE_ASSERT_RETURN(rootJ != nullptr, nullptr);

json_object_set_new(rootJ, "holdOutputPitch", json_boolean(holdOutputPitch));
json_object_set_new(rootJ, "smooth", json_boolean(smooth));
json_object_set_new(rootJ, "octave", json_integer(octave));

return rootJ;
}

void dataFromJson(json_t* const rootJ) override
{
if (json_t* const holdOutputPitchJ = json_object_get(rootJ, "holdOutputPitch"))
holdOutputPitch = json_boolean_value(holdOutputPitchJ);

if (json_t* const smoothJ = json_object_get(rootJ, "smooth"))
smooth = json_boolean_value(smoothJ);

if (json_t* const octaveJ = json_object_get(rootJ, "octave"))
octave = json_integer_value(octaveJ);
}
};

struct SmallPercentageNanoKnob : NanoKnob<2, 0> {
SmallPercentageNanoKnob() {
box.size = Vec(32, 32);
displayLabel = "";
}

void onChange(const ChangeEvent&) override
{
engine::ParamQuantity* const pq = getParamQuantity();
DISTRHO_SAFE_ASSERT_RETURN(pq != nullptr,);

displayString = string::f("%.1f %%", pq->getDisplayValue());
}
};

struct AudioToCVPitchWidget : ModuleWidgetWith9HP {
static constexpr const float startX = 10.0f;
static constexpr const float startY_top = 71.0f;
static constexpr const float startY_cv1 = 115.0f;
static constexpr const float startY_cv2 = 145.0f;
static constexpr const float padding = 32.0f;

AudioToCVPitch* const module;
std::string monoFontPath;

AudioToCVPitchWidget(AudioToCVPitch* const m)
: module(m)
{
setModule(m);
setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/AudioToCVPitch.svg")));
monoFontPath = asset::system("res/fonts/ShareTechMono-Regular.ttf");

createAndAddScrews();

addInput(createInput<PJ301MPort>(Vec(startX, startY_cv1 + 0 * padding), m, AudioToCVPitch::AUDIO_INPUT));
addOutput(createOutput<PJ301MPort>(Vec(startX, startY_cv2 + 0 * padding), m, AudioToCVPitch::CV_PITCH));
addOutput(createOutput<PJ301MPort>(Vec(startX, startY_cv2 + 1 * padding), m, AudioToCVPitch::CV_GATE));

SmallPercentageNanoKnob* knobSens = createParamCentered<SmallPercentageNanoKnob>(Vec(box.size.x * 0.5f, startY_cv2 + 85.f),
module, AudioToCVPitch::PARAM_SENSITIVITY);
knobSens->displayString = "50 %";
addChild(knobSens);

SmallPercentageNanoKnob* knobTolerance = createParamCentered<SmallPercentageNanoKnob>(Vec(box.size.x * 0.5f, startY_cv2 + 135.f),
module, AudioToCVPitch::PARAM_TOLERANCE);
knobTolerance->displayString = "6.25 %";
addChild(knobTolerance);

SmallPercentageNanoKnob* knobThres = createParamCentered<SmallPercentageNanoKnob>(Vec(box.size.x * 0.5f, startY_cv2 + 185.f),
module, AudioToCVPitch::PARAM_CONFIDENCETHRESHOLD);
knobThres->displayString = "12.5 %";
addChild(knobThres);
}

void drawInputLine(NVGcontext* const vg, const uint offset, const char* const text)
{
const float y = startY_cv1 + offset * padding;
nvgBeginPath(vg);
nvgFillColor(vg, nvgRGB(0xd0, 0xd0, 0xd0));
nvgText(vg, startX + 28, y + 16, text, nullptr);
}

void drawOutputLine(NVGcontext* const vg, const uint offset, const char* const text)
{
const float y = startY_cv2 + offset * padding;
nvgBeginPath(vg);
nvgRoundedRect(vg, startX - 1.f, y - 2.f, box.size.x - startX * 2 + 2.f, 28.f, 4);
nvgFillColor(vg, nvgRGB(0xd0, 0xd0, 0xd0));
nvgFill(vg);
nvgBeginPath(vg);
nvgFillColor(vg, color::BLACK);
nvgText(vg, startX + 28, y + 16, text, nullptr);
}

void draw(const DrawArgs& args) override
{
drawBackground(args.vg);

nvgFontFaceId(args.vg, 0);
nvgFontSize(args.vg, 14);

drawInputLine(args.vg, 0, "Input");
drawOutputLine(args.vg, 0, "Pitch");
drawOutputLine(args.vg, 1, "Gate");

nvgFontSize(args.vg, 11);
nvgBeginPath(args.vg);
nvgFillColor(args.vg, nvgRGB(0xd0, 0xd0, 0xd0));
nvgTextLineHeight(args.vg, 0.8f);
nvgTextAlign(args.vg, NVG_ALIGN_CENTER);
nvgTextBox(args.vg, startX + 6.f, startY_cv2 + 75.f, 11.f, "S\ne\nn\ns", nullptr);
nvgTextBox(args.vg, box.size.x - startX - 16.f, startY_cv2 + 130.f, 11.f, "T\no\nl", nullptr);
nvgTextBox(args.vg, startX + 6.f, startY_cv2 + 175.f, 11.f, "T\nh\nr\ne\ns", nullptr);

nvgBeginPath(args.vg);
nvgRoundedRect(args.vg, 10.0f, startY_top, box.size.x - 20.f, 38.0f, 4);
nvgFillColor(args.vg, color::BLACK);
nvgFill(args.vg);

ModuleWidgetWith9HP::draw(args);
}

void drawLayer(const DrawArgs& args, int layer) override
{
if (layer == 1)
{
nvgFontSize(args.vg, 17);
nvgFillColor(args.vg, nvgRGBf(0.76f, 0.11f, 0.22f));

char pitchConfString[24];
char pitchFreqString[24];

std::shared_ptr<Font> monoFont = APP->window->loadFont(monoFontPath);

if (module != nullptr && monoFont != nullptr)
{
nvgFontFaceId(args.vg, monoFont->handle);

std::snprintf(pitchConfString, sizeof(pitchConfString), "%5.1f %%", module->lastKnownPitchConfidence * 100.f);
std::snprintf(pitchFreqString, sizeof(pitchFreqString), "%5.0f Hz", module->lastKnownPitchInHz);
}
else
{
std::strcpy(pitchConfString, "0.0 %");
std::strcpy(pitchFreqString, "0 Hz");
}

nvgTextAlign(args.vg, NVG_ALIGN_CENTER);
nvgText(args.vg, box.size.x * 0.5f, startY_top + 15.0f, pitchConfString, nullptr);
nvgText(args.vg, box.size.x * 0.5f, startY_top + 33.0f, pitchFreqString, nullptr);
}

ModuleWidgetWith9HP::drawLayer(args, layer);
}

void appendContextMenu(Menu* const menu) override
{
menu->addChild(new MenuSeparator);

menu->addChild(createBoolPtrMenuItem("Hold Output Pitch", "", &module->holdOutputPitch));
menu->addChild(createBoolPtrMenuItem("Smooth Output Pitch", "", &module->smooth));

static const std::vector<int> octaves = {-4, -3, -2, -1, 0, 1, 2, 3, 4};
menu->addChild(createSubmenuItem("Octave", string::f("%d", module->octave), [=](Menu* menu) {
for (size_t i = 0; i < octaves.size(); i++) {
menu->addChild(createCheckMenuItem(string::f("%d", octaves[i]), "",
[=]() {return module->octave == octaves[i];},
[=]() {module->octave = octaves[i];}
));
}
}));
}
};

// --------------------------------------------------------------------------------------------------------------------

Model* modelAudioToCVPitch = createModel<AudioToCVPitch, AudioToCVPitchWidget>("AudioToCVPitch");

// --------------------------------------------------------------------------------------------------------------------

+ 3
- 1
plugins/Cardinal/src/HostAudio.cpp View File

@@ -329,12 +329,14 @@ struct HostAudioNanoMeter : NanoMeter {
// --------------------------------------------------------------------------------------------------------------------

struct HostAudioWidget2 : HostAudioWidget<2> {
typedef NanoKnob<> Knob;

HostAudioWidget2(HostAudio2* const m)
: HostAudioWidget<2>(m)
{
// FIXME
const float middleX = box.size.x * 0.5f;
addParam(createParamCentered<NanoKnob>(Vec(middleX, 310.0f), m, 0));
addParam(createParamCentered<Knob>(Vec(middleX, 310.0f), m, 0));

HostAudioNanoMeter* const meter = new HostAudioNanoMeter(m);
meter->box.pos = Vec(middleX - padding + 2.75f, startY + padding * 2);


+ 1
- 1
plugins/Cardinal/src/HostTime.cpp View File

@@ -214,7 +214,7 @@ struct HostTimeWidget : ModuleWidget {
{
const float y = startY_cv + offset * padding;
nvgBeginPath(vg);
nvgRoundedRect(vg, startX - 1.0f, y - 2.0f, box.size.x - (startX + 1) * 2, 28.0f, 4);
nvgRoundedRect(vg, startX - 1.0f, y - 2.f, box.size.x - startX * 2 + 2.f, 28.f, 4);
nvgFillColor(vg, nvgRGB(0xd0, 0xd0, 0xd0));
nvgFill(vg);
nvgBeginPath(vg);


+ 22
- 16
plugins/Cardinal/src/Widgets.hpp View File

@@ -61,9 +61,8 @@ struct CardinalLedDisplayChoice : LedDisplayChoice {
}
};

template<int ringSize = 4, int heightPadding = 2>
struct NanoKnob : Knob {
static const int ringSize = 4;

std::string displayLabel = "Level";
std::string displayString = "0 dB";
float normalizedValue = 0.5f;
@@ -81,14 +80,14 @@ struct NanoKnob : Knob {
const float w = box.size.x;
const float h = box.size.y;

const int knobSize = std::min(w, h - BND_WIDGET_HEIGHT * 2) - ringSize;
const int knobSize = std::min(w, h - BND_WIDGET_HEIGHT * heightPadding) - ringSize;

const int knobStartX = w / 2 - knobSize / 2;
const int knobStartY = ringSize;
const int knobCenterX = knobStartX + knobSize / 2;
const int knobCenterY = knobStartY + knobSize / 2;

const NVGcolor testing = nvgRGBf(0.76f, 0.11f, 0.22f);
const NVGcolor cardinalColor = nvgRGBf(0.76f, 0.11f, 0.22f);

nvgLineCap(args.vg, NVG_ROUND);

@@ -102,7 +101,7 @@ struct NanoKnob : Knob {
nvgDegToRad(135.0f) + nvgDegToRad(270.0f * normalizedValue),
NVG_CW);
nvgStrokeWidth(args.vg, ringSize);
nvgStrokeColor(args.vg, testing);
nvgStrokeColor(args.vg, cardinalColor);
nvgStroke(args.vg);

// simulate color bleeding
@@ -115,7 +114,7 @@ struct NanoKnob : Knob {
nvgDegToRad(135.0f) + nvgDegToRad(270.0f * normalizedValue),
NVG_CW);
nvgStrokeWidth(args.vg, 5);
nvgStrokeColor(args.vg, nvgRGBAf(testing.r, testing.g, testing.b, 0.1f));
nvgStrokeColor(args.vg, nvgRGBAf(cardinalColor.r, cardinalColor.g, cardinalColor.b, 0.1f));
nvgStroke(args.vg);

// line indicator
@@ -136,7 +135,7 @@ struct NanoKnob : Knob {
float radius = knobSize * 0.5f;
float oradius = radius + std::min(radius * 4.f, 15.f);

NVGcolor icol = color::mult(nvgRGBAf(testing.r, testing.g, testing.b, 0.2f), halo);
NVGcolor icol = color::mult(nvgRGBAf(cardinalColor.r, cardinalColor.g, cardinalColor.b, 0.2f), halo);
NVGcolor ocol = nvgRGBA(0, 0, 0, 0);
NVGpaint paint = nvgRadialGradient(args.vg, knobCenterX, knobCenterY, radius, oradius, icol, ocol);

@@ -146,10 +145,13 @@ struct NanoKnob : Knob {
nvgFill(args.vg);
}

// bottom label (value)
bndIconLabelValue(args.vg, 0, knobSize + ringSize, w, BND_WIDGET_HEIGHT, -1,
testing, BND_CENTER,
BND_LABEL_FONT_SIZE, displayString.c_str(), nullptr);
if (! displayString.empty())
{
// bottom label (value)
bndIconLabelValue(args.vg, -w, knobSize + ringSize, w*3, BND_WIDGET_HEIGHT, -1,
cardinalColor, BND_CENTER,
BND_LABEL_FONT_SIZE, displayString.c_str(), nullptr);
}

Knob::drawLayer(args, layer);
}
@@ -162,7 +164,7 @@ struct NanoKnob : Knob {
const float w = box.size.x;
const float h = box.size.y;

const int knobSize = std::min(w, h - BND_WIDGET_HEIGHT * 2) - ringSize;
const int knobSize = std::min(w, h - BND_WIDGET_HEIGHT * heightPadding) - ringSize;

const int knobStartX = w / 2 - knobSize / 2;
const int knobStartY = ringSize;
@@ -224,10 +226,14 @@ struct NanoKnob : Knob {
nvgStrokeColor(args.vg, nvgRGBf(0.5f, 0.5f, 0.5f));
nvgStroke(args.vg);

// bottom label (name)
bndIconLabelValue(args.vg, 0, knobStartY + knobSize + BND_WIDGET_HEIGHT * 0.75f, w, BND_WIDGET_HEIGHT, -1,
SCHEME_WHITE, BND_CENTER,
BND_LABEL_FONT_SIZE, displayLabel.c_str(), nullptr);
if (! displayLabel.empty())
{
// bottom label (name)
bndIconLabelValue(args.vg, -w, knobStartY + knobSize + BND_WIDGET_HEIGHT * 0.75f,
w*3, BND_WIDGET_HEIGHT, -1,
SCHEME_WHITE, BND_CENTER,
BND_LABEL_FONT_SIZE, displayLabel.c_str(), nullptr);
}

Knob::draw(args);
}


+ 1
- 0
plugins/Cardinal/src/plugin.hpp View File

@@ -29,6 +29,7 @@ using namespace rack;
extern Plugin* pluginInstance;

extern Model* modelAudioFile;
extern Model* modelAudioToCVPitch;
extern Model* modelCarla;
extern Model* modelCardinalBlank;
extern Model* modelExpanderInputMIDI;


+ 1
- 1
plugins/Fundamental

@@ -1 +1 @@
Subproject commit 71f4c72ded3560639b4ff1df3bb827e31c7d61a0
Subproject commit ec6d477cedc9a00b7dde0f2713d263c4778162d2

+ 6
- 0
plugins/Makefile View File

@@ -222,6 +222,11 @@ PLUGIN_FILES += $(wildcard Cardinal/src/DearImGui/*.cpp)
PLUGIN_FILES += $(wildcard Cardinal/src/DearImGuiColorTextEditor/*.cpp)
endif

ifeq ($(shell pkg-config --exists fftw3f && echo true),true)
PLUGIN_FILES += Cardinal/src/AudioToCVPitch.cpp
BASE_FLAGS += -DHAVE_FFTW3F
endif

# --------------------------------------------------------------
# Fundamental (always enabled)

@@ -1215,6 +1220,7 @@ $(BUILD_DIR)/Cardinal/%.cpp.o: Cardinal/%.cpp
-DCARLA_BACKEND_NAMESPACE=Cardinal \
-DREAL_BUILD \
-DSTATIC_PLUGIN_TARGET \
-I../deps/aubio/src \
-I../carla/source/backend \
-I../carla/source/includes \
-I../carla/source/modules \


+ 5
- 0
plugins/plugins.cpp View File

@@ -882,6 +882,11 @@ static void initStatic__Cardinal()
#else
spl.removeModule("MPV");
#endif
#ifdef HAVE_FFTW3F
p->addModel(modelAudioToCVPitch);
#else
spl.removeModule("AudioToCVPitch");
#endif

hostTerminalModels = {
modelHostAudio2,


+ 6
- 0
src/Makefile.cardinal.mk View File

@@ -113,6 +113,12 @@ endif
EXTRA_DEPENDENCIES = $(RACK_EXTRA_LIBS) $(CARLA_EXTRA_LIBS)
EXTRA_LIBS = $(RACK_EXTRA_LIBS) $(CARLA_EXTRA_LIBS) $(STATIC_CARLA_PLUGIN_LIBS)

ifeq ($(shell pkg-config --exists fftw3f && echo true),true)
EXTRA_DEPENDENCIES += ../../deps/aubio/libaubio.a
EXTRA_LIBS += ../../deps/aubio/libaubio.a
EXTRA_LIBS += $(shell $(PKG_CONFIG) --libs fftw3f)
endif

# --------------------------------------------------------------
# Do some magic



Loading…
Cancel
Save