Signed-off-by: falkTX <falktx@falktx.com>tags/22.05
@@ -67,7 +67,7 @@ DGL_EXTRA_ARGS = \ | |||||
WINDOWS_ICON_ID=401 | WINDOWS_ICON_ID=401 | ||||
# -------------------------------------------------------------- | # -------------------------------------------------------------- | ||||
# Check for system-wide dependencies | |||||
# Check for required system-wide dependencies | |||||
ifeq ($(SYSDEPS),true) | ifeq ($(SYSDEPS),true) | ||||
@@ -125,6 +125,15 @@ endif | |||||
endif | 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 | # MOD builds | ||||
@@ -202,6 +211,9 @@ ifeq ($(SYSDEPS),true) | |||||
else | else | ||||
$(MAKE) all -C deps | $(MAKE) all -C deps | ||||
endif | endif | ||||
ifeq ($(HAVE_FFTW3F),true) | |||||
$(MAKE) all -C deps/aubio | |||||
endif | |||||
dgl: | dgl: | ||||
ifneq ($(HEADLESS),true) | ifneq ($(HEADLESS),true) | ||||
@@ -250,6 +262,7 @@ deps/unzipfx/unzipfx2cat.exe: | |||||
clean: | clean: | ||||
$(MAKE) distclean -C carla $(CARLA_EXTRA_ARGS) CAN_GENERATE_LV2_TTL=false STATIC_PLUGIN_TARGET=true | $(MAKE) distclean -C carla $(CARLA_EXTRA_ARGS) CAN_GENERATE_LV2_TTL=false STATIC_PLUGIN_TARGET=true | ||||
$(MAKE) clean -C deps | $(MAKE) clean -C deps | ||||
$(MAKE) clean -C deps/aubio | |||||
$(MAKE) clean -C dpf/dgl | $(MAKE) clean -C dpf/dgl | ||||
$(MAKE) clean -C dpf/utils/lv2-ttl-generator | $(MAKE) clean -C dpf/utils/lv2-ttl-generator | ||||
$(MAKE) clean -C plugins | $(MAKE) clean -C plugins | ||||
@@ -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> |
@@ -146,6 +146,15 @@ | |||||
"Utility" | "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", | "slug": "Carla", | ||||
"name": "Carla Plugin Host", | "name": "Carla Plugin Host", | ||||
@@ -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,3 +1,4 @@ | |||||
../../../deps/aubio/src | |||||
../../../include | ../../../include | ||||
../../../carla/source/backend | ../../../carla/source/backend | ||||
../../../carla/source/includes | ../../../carla/source/includes | ||||
@@ -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"); | |||||
// -------------------------------------------------------------------------------------------------------------------- |
@@ -329,12 +329,14 @@ struct HostAudioNanoMeter : NanoMeter { | |||||
// -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
struct HostAudioWidget2 : HostAudioWidget<2> { | struct HostAudioWidget2 : HostAudioWidget<2> { | ||||
typedef NanoKnob<> Knob; | |||||
HostAudioWidget2(HostAudio2* const m) | HostAudioWidget2(HostAudio2* const m) | ||||
: HostAudioWidget<2>(m) | : HostAudioWidget<2>(m) | ||||
{ | { | ||||
// FIXME | // FIXME | ||||
const float middleX = box.size.x * 0.5f; | 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); | HostAudioNanoMeter* const meter = new HostAudioNanoMeter(m); | ||||
meter->box.pos = Vec(middleX - padding + 2.75f, startY + padding * 2); | meter->box.pos = Vec(middleX - padding + 2.75f, startY + padding * 2); | ||||
@@ -214,7 +214,7 @@ struct HostTimeWidget : ModuleWidget { | |||||
{ | { | ||||
const float y = startY_cv + offset * padding; | const float y = startY_cv + offset * padding; | ||||
nvgBeginPath(vg); | 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)); | nvgFillColor(vg, nvgRGB(0xd0, 0xd0, 0xd0)); | ||||
nvgFill(vg); | nvgFill(vg); | ||||
nvgBeginPath(vg); | nvgBeginPath(vg); | ||||
@@ -61,9 +61,8 @@ struct CardinalLedDisplayChoice : LedDisplayChoice { | |||||
} | } | ||||
}; | }; | ||||
template<int ringSize = 4, int heightPadding = 2> | |||||
struct NanoKnob : Knob { | struct NanoKnob : Knob { | ||||
static const int ringSize = 4; | |||||
std::string displayLabel = "Level"; | std::string displayLabel = "Level"; | ||||
std::string displayString = "0 dB"; | std::string displayString = "0 dB"; | ||||
float normalizedValue = 0.5f; | float normalizedValue = 0.5f; | ||||
@@ -81,14 +80,14 @@ struct NanoKnob : Knob { | |||||
const float w = box.size.x; | const float w = box.size.x; | ||||
const float h = box.size.y; | 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 knobStartX = w / 2 - knobSize / 2; | ||||
const int knobStartY = ringSize; | const int knobStartY = ringSize; | ||||
const int knobCenterX = knobStartX + knobSize / 2; | const int knobCenterX = knobStartX + knobSize / 2; | ||||
const int knobCenterY = knobStartY + 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); | nvgLineCap(args.vg, NVG_ROUND); | ||||
@@ -102,7 +101,7 @@ struct NanoKnob : Knob { | |||||
nvgDegToRad(135.0f) + nvgDegToRad(270.0f * normalizedValue), | nvgDegToRad(135.0f) + nvgDegToRad(270.0f * normalizedValue), | ||||
NVG_CW); | NVG_CW); | ||||
nvgStrokeWidth(args.vg, ringSize); | nvgStrokeWidth(args.vg, ringSize); | ||||
nvgStrokeColor(args.vg, testing); | |||||
nvgStrokeColor(args.vg, cardinalColor); | |||||
nvgStroke(args.vg); | nvgStroke(args.vg); | ||||
// simulate color bleeding | // simulate color bleeding | ||||
@@ -115,7 +114,7 @@ struct NanoKnob : Knob { | |||||
nvgDegToRad(135.0f) + nvgDegToRad(270.0f * normalizedValue), | nvgDegToRad(135.0f) + nvgDegToRad(270.0f * normalizedValue), | ||||
NVG_CW); | NVG_CW); | ||||
nvgStrokeWidth(args.vg, 5); | 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); | nvgStroke(args.vg); | ||||
// line indicator | // line indicator | ||||
@@ -136,7 +135,7 @@ struct NanoKnob : Knob { | |||||
float radius = knobSize * 0.5f; | float radius = knobSize * 0.5f; | ||||
float oradius = radius + std::min(radius * 4.f, 15.f); | 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); | NVGcolor ocol = nvgRGBA(0, 0, 0, 0); | ||||
NVGpaint paint = nvgRadialGradient(args.vg, knobCenterX, knobCenterY, radius, oradius, icol, ocol); | NVGpaint paint = nvgRadialGradient(args.vg, knobCenterX, knobCenterY, radius, oradius, icol, ocol); | ||||
@@ -146,10 +145,13 @@ struct NanoKnob : Knob { | |||||
nvgFill(args.vg); | 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); | Knob::drawLayer(args, layer); | ||||
} | } | ||||
@@ -162,7 +164,7 @@ struct NanoKnob : Knob { | |||||
const float w = box.size.x; | const float w = box.size.x; | ||||
const float h = box.size.y; | 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 knobStartX = w / 2 - knobSize / 2; | ||||
const int knobStartY = ringSize; | const int knobStartY = ringSize; | ||||
@@ -224,10 +226,14 @@ struct NanoKnob : Knob { | |||||
nvgStrokeColor(args.vg, nvgRGBf(0.5f, 0.5f, 0.5f)); | nvgStrokeColor(args.vg, nvgRGBf(0.5f, 0.5f, 0.5f)); | ||||
nvgStroke(args.vg); | 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); | Knob::draw(args); | ||||
} | } | ||||
@@ -29,6 +29,7 @@ using namespace rack; | |||||
extern Plugin* pluginInstance; | extern Plugin* pluginInstance; | ||||
extern Model* modelAudioFile; | extern Model* modelAudioFile; | ||||
extern Model* modelAudioToCVPitch; | |||||
extern Model* modelCarla; | extern Model* modelCarla; | ||||
extern Model* modelCardinalBlank; | extern Model* modelCardinalBlank; | ||||
extern Model* modelExpanderInputMIDI; | extern Model* modelExpanderInputMIDI; | ||||
@@ -1 +1 @@ | |||||
Subproject commit 71f4c72ded3560639b4ff1df3bb827e31c7d61a0 | |||||
Subproject commit ec6d477cedc9a00b7dde0f2713d263c4778162d2 |
@@ -222,6 +222,11 @@ PLUGIN_FILES += $(wildcard Cardinal/src/DearImGui/*.cpp) | |||||
PLUGIN_FILES += $(wildcard Cardinal/src/DearImGuiColorTextEditor/*.cpp) | PLUGIN_FILES += $(wildcard Cardinal/src/DearImGuiColorTextEditor/*.cpp) | ||||
endif | endif | ||||
ifeq ($(shell pkg-config --exists fftw3f && echo true),true) | |||||
PLUGIN_FILES += Cardinal/src/AudioToCVPitch.cpp | |||||
BASE_FLAGS += -DHAVE_FFTW3F | |||||
endif | |||||
# -------------------------------------------------------------- | # -------------------------------------------------------------- | ||||
# Fundamental (always enabled) | # Fundamental (always enabled) | ||||
@@ -1215,6 +1220,7 @@ $(BUILD_DIR)/Cardinal/%.cpp.o: Cardinal/%.cpp | |||||
-DCARLA_BACKEND_NAMESPACE=Cardinal \ | -DCARLA_BACKEND_NAMESPACE=Cardinal \ | ||||
-DREAL_BUILD \ | -DREAL_BUILD \ | ||||
-DSTATIC_PLUGIN_TARGET \ | -DSTATIC_PLUGIN_TARGET \ | ||||
-I../deps/aubio/src \ | |||||
-I../carla/source/backend \ | -I../carla/source/backend \ | ||||
-I../carla/source/includes \ | -I../carla/source/includes \ | ||||
-I../carla/source/modules \ | -I../carla/source/modules \ | ||||
@@ -882,6 +882,11 @@ static void initStatic__Cardinal() | |||||
#else | #else | ||||
spl.removeModule("MPV"); | spl.removeModule("MPV"); | ||||
#endif | #endif | ||||
#ifdef HAVE_FFTW3F | |||||
p->addModel(modelAudioToCVPitch); | |||||
#else | |||||
spl.removeModule("AudioToCVPitch"); | |||||
#endif | |||||
hostTerminalModels = { | hostTerminalModels = { | ||||
modelHostAudio2, | modelHostAudio2, | ||||
@@ -113,6 +113,12 @@ endif | |||||
EXTRA_DEPENDENCIES = $(RACK_EXTRA_LIBS) $(CARLA_EXTRA_LIBS) | EXTRA_DEPENDENCIES = $(RACK_EXTRA_LIBS) $(CARLA_EXTRA_LIBS) | ||||
EXTRA_LIBS = $(RACK_EXTRA_LIBS) $(CARLA_EXTRA_LIBS) $(STATIC_CARLA_PLUGIN_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 | # Do some magic | ||||