├── debian ├── compat ├── docs ├── padthv1-jack.docs ├── padthv1-lv2.install ├── rules ├── padthv1-jack.install ├── copyright ├── control └── changelog ├── .gitignore ├── src ├── images │ ├── ledOff.png │ ├── ledOn.png │ ├── padthv1.png │ ├── fileOpen.png │ ├── itemReset.png │ ├── presetNew.png │ ├── editSample.png │ ├── playSample.png │ ├── presetBank.png │ ├── presetDelete.png │ ├── presetEdit.png │ ├── presetOpen.png │ ├── presetSave.png │ ├── padthv1_preset.png │ ├── presetBankOpen.png │ └── padthv1_control.png ├── mimetypes │ ├── org.rncbc.padthv1.application-x-padthv1-preset.png │ └── org.rncbc.padthv1.xml ├── padthv1.lv2 │ ├── manifest.ttl │ ├── manifest-win32.ttl │ ├── padthv1_ui.ttl │ └── padthv1_ui-win32.ttl ├── appdata │ ├── org.rncbc.padthv1.desktop │ └── org.rncbc.padthv1.metainfo.xml ├── padthv1.qrc ├── palette │ ├── KXStudio.conf │ └── Wonton Soup.conf ├── man1 │ ├── padthv1.1 │ └── padthv1.fr.1 ├── padthv1_list.h ├── padthv1widget_status.h ├── padthv1widget_programs.h ├── padthv1widget_controls.h ├── padthv1widget_jack.h ├── padthv1widget_lv2.h ├── padthv1widget_wave.h ├── padthv1_ui.h ├── padthv1_lv2ui.h ├── padthv1_param.h ├── padthv1widget_preset.h ├── padthv1_sched.h ├── padthv1widget_filt.h ├── padthv1widget_env.h ├── lv2 │ ├── lv2_port_change_request.h │ ├── lv2_external_ui.h │ └── lv2_programs.h ├── padthv1_tuning.h ├── padthv1widget_sample.h ├── config.h.cmake ├── padthv1_config.h ├── padthv1_nsm.h ├── padthv1widget_control.h ├── padthv1widget_config.h ├── padthv1widget_status.cpp ├── padthv1_programs.h ├── padthv1_programs.cpp ├── padthv1_jack.h ├── padthv1_ui.cpp ├── padthv1_lv2.h ├── padthv1.h ├── padthv1widget_keybd.h ├── padthv1_wave.h ├── padthv1widget_control.ui ├── padthv1_controls.h ├── padthv1_wave.cpp ├── padthv1widget_lv2.cpp ├── padthv1widget.h ├── padthv1_formant.h ├── padthv1widget_jack.cpp ├── padthv1_filter.h ├── padthv1_ramp.h └── padthv1widget_wave.cpp ├── README └── rpm └── padthv1.spec /debian/compat: -------------------------------------------------------------------------------- 1 | 11 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build* 2 | *.txt.user 3 | -------------------------------------------------------------------------------- /debian/docs: -------------------------------------------------------------------------------- 1 | README 2 | ChangeLog 3 | -------------------------------------------------------------------------------- /debian/padthv1-jack.docs: -------------------------------------------------------------------------------- 1 | README 2 | LICENSE 3 | ChangeLog 4 | -------------------------------------------------------------------------------- /src/images/ledOff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/padthv1/HEAD/src/images/ledOff.png -------------------------------------------------------------------------------- /src/images/ledOn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/padthv1/HEAD/src/images/ledOn.png -------------------------------------------------------------------------------- /src/images/padthv1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/padthv1/HEAD/src/images/padthv1.png -------------------------------------------------------------------------------- /src/images/fileOpen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/padthv1/HEAD/src/images/fileOpen.png -------------------------------------------------------------------------------- /src/images/itemReset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/padthv1/HEAD/src/images/itemReset.png -------------------------------------------------------------------------------- /src/images/presetNew.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/padthv1/HEAD/src/images/presetNew.png -------------------------------------------------------------------------------- /src/images/editSample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/padthv1/HEAD/src/images/editSample.png -------------------------------------------------------------------------------- /src/images/playSample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/padthv1/HEAD/src/images/playSample.png -------------------------------------------------------------------------------- /src/images/presetBank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/padthv1/HEAD/src/images/presetBank.png -------------------------------------------------------------------------------- /src/images/presetDelete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/padthv1/HEAD/src/images/presetDelete.png -------------------------------------------------------------------------------- /src/images/presetEdit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/padthv1/HEAD/src/images/presetEdit.png -------------------------------------------------------------------------------- /src/images/presetOpen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/padthv1/HEAD/src/images/presetOpen.png -------------------------------------------------------------------------------- /src/images/presetSave.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/padthv1/HEAD/src/images/presetSave.png -------------------------------------------------------------------------------- /src/images/padthv1_preset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/padthv1/HEAD/src/images/padthv1_preset.png -------------------------------------------------------------------------------- /src/images/presetBankOpen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/padthv1/HEAD/src/images/presetBankOpen.png -------------------------------------------------------------------------------- /src/images/padthv1_control.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/padthv1/HEAD/src/images/padthv1_control.png -------------------------------------------------------------------------------- /src/mimetypes/org.rncbc.padthv1.application-x-padthv1-preset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/padthv1/HEAD/src/mimetypes/org.rncbc.padthv1.application-x-padthv1-preset.png -------------------------------------------------------------------------------- /debian/padthv1-lv2.install: -------------------------------------------------------------------------------- 1 | debian/tmp/usr/lib*/lv2/padthv1.lv2/manifest.ttl 2 | debian/tmp/usr/lib*/lv2/padthv1.lv2/padthv1.ttl 3 | debian/tmp/usr/lib*/lv2/padthv1.lv2/padthv1.so 4 | debian/tmp/usr/lib*/lv2/padthv1.lv2/padthv1_ui.ttl 5 | -------------------------------------------------------------------------------- /src/padthv1.lv2/manifest.ttl: -------------------------------------------------------------------------------- 1 | @prefix lv2: . 2 | @prefix rdfs: . 3 | 4 | 5 | a lv2:Plugin, lv2:InstrumentPlugin ; 6 | lv2:binary ; 7 | rdfs:seeAlso , . 8 | -------------------------------------------------------------------------------- /src/padthv1.lv2/manifest-win32.ttl: -------------------------------------------------------------------------------- 1 | @prefix lv2: . 2 | @prefix rdfs: . 3 | 4 | 5 | a lv2:Plugin, lv2:InstrumentPlugin ; 6 | lv2:binary ; 7 | rdfs:seeAlso , . 8 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # 3 | QTDIR ?= /opt/qt6.9-static 4 | 5 | %: 6 | dh $@ 7 | 8 | override_dh_auto_configure: 9 | # Add here commands to configure the package. 10 | cmake -DCMAKE_INSTALL_PREFIX=/usr \ 11 | -DCMAKE_INSTALL_LIBDIR=lib \ 12 | -DCMAKE_PREFIX_PATH=$(QTDIR) . 13 | # --- end custom part for configure 14 | -------------------------------------------------------------------------------- /src/mimetypes/org.rncbc.padthv1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | padthv1 preset 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/appdata/org.rncbc.padthv1.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=padthv1 3 | Version=1.0 4 | GenericName=MIDI 5 | Comment=padthv1 is an old school polyphonic additive synthesizer 6 | Comment[fr]=padthv1 est un synthétiseur polyphonique additif à l'ancienne 7 | Exec=padthv1_jack %f 8 | Icon=org.rncbc.padthv1 9 | Categories=Audio;AudioVideo;Midi;X-Alsa;X-Jack;Qt; 10 | MimeType=application/x-padthv1-preset; 11 | Keywords=Audio;MIDI;ALSA;JACK;Synthesizer;LV2;Qt; 12 | Terminal=false 13 | Type=Application 14 | StartupWMClass=padthv1_jack 15 | X-Window-Icon=padthv1 16 | X-SuSE-translate=true 17 | X-NSM-Capable=true 18 | X-NSM-Exec=padthv1_jack 19 | -------------------------------------------------------------------------------- /debian/padthv1-jack.install: -------------------------------------------------------------------------------- 1 | debian/tmp/usr/bin/padthv1_jack 2 | debian/tmp/usr/share/metainfo/org.rncbc.padthv1.metainfo.xml 3 | debian/tmp/usr/share/applications/org.rncbc.padthv1.desktop 4 | debian/tmp/usr/share/mime/packages/org.rncbc.padthv1.xml 5 | debian/tmp/usr/share/icons/hicolor/32x32/apps/org.rncbc.padthv1.png 6 | debian/tmp/usr/share/icons/hicolor/32x32/mimetypes/org.rncbc.padthv1.application-x-padthv1*.png 7 | debian/tmp/usr/share/icons/hicolor/scalable/apps/org.rncbc.padthv1.svg 8 | debian/tmp/usr/share/icons/hicolor/scalable/mimetypes/org.rncbc.padthv1.application-x-padthv1*.svg 9 | debian/tmp/usr/share/man/man1/padthv1*.* 10 | debian/tmp/usr/share/padthv1/palette/*.conf 11 | -------------------------------------------------------------------------------- /src/padthv1.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | images/padthv1.png 4 | images/padthv1.svg 5 | images/ledOn.png 6 | images/ledOff.png 7 | images/editSample.png 8 | images/playSample.png 9 | images/presetNew.png 10 | images/presetOpen.png 11 | images/presetSave.png 12 | images/presetDelete.png 13 | images/presetBank.png 14 | images/presetBankOpen.png 15 | images/presetEdit.png 16 | images/itemReset.png 17 | images/fileOpen.png 18 | images/padthv1_preset.png 19 | images/padthv1_control.png 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/palette/KXStudio.conf: -------------------------------------------------------------------------------- 1 | [ColorThemes] 2 | KXStudio\AlternateBase=#0e0e0e, #0e0e0e, #0c0c0c 3 | KXStudio\Base=#070707, #070707, #060606 4 | KXStudio\BrightText=#ffffff, #ffffff, #ffffff 5 | KXStudio\Button=#1c1c1c, #1c1c1c, #181818 6 | KXStudio\ButtonText=#f0f0f0, #f0f0f0, #5a5a5a 7 | KXStudio\Dark=#818181, #818181, #818181 8 | KXStudio\Highlight=#3c3c3c, #222222, #0e0e0e 9 | KXStudio\HighlightedText=#ffffff, #f0f0f0, #535353 10 | KXStudio\Light=#bfbfbf, #bfbfbf, #bfbfbf 11 | KXStudio\Link=#6464e6, #6464e6, #22224a 12 | KXStudio\LinkVisited=#e664e6, #e664e6, #4a224a 13 | KXStudio\Mid=#5e5e5e, #5e5e5e, #5e5e5e 14 | KXStudio\Midlight=#9b9b9b, #9b9b9b, #9b9b9b 15 | KXStudio\NoRole=#000000, #000000, #000000 16 | KXStudio\PlaceholderText=#000000, #000000, #000000 17 | KXStudio\Shadow=#9b9b9b, #9b9b9b, #9b9b9b 18 | KXStudio\Text=#e6e6e6, #e6e6e6, #4a4a4a 19 | KXStudio\ToolTipBase=#040404, #040404, #040404 20 | KXStudio\ToolTipText=#e6e6e6, #e6e6e6, #e6e6e6 21 | KXStudio\Window=#111111, #111111, #0e0e0e 22 | KXStudio\WindowText=#f0f0f0, #f0f0f0, #535353 23 | -------------------------------------------------------------------------------- /src/padthv1.lv2/padthv1_ui.ttl: -------------------------------------------------------------------------------- 1 | @prefix lv2: . 2 | @prefix lv2ui: . 3 | 4 | @prefix padthv1_lv2: . 5 | 6 | 7 | lv2ui:ui padthv1_lv2:ui_x11, padthv1_lv2:ui_external . 8 | 9 | 10 | a lv2ui:Qt6UI ; 11 | lv2:requiredFeature ; 12 | lv2ui:binary . 13 | 14 | 15 | a lv2ui:X11UI ; 16 | lv2:requiredFeature ; 17 | lv2:optionalFeature lv2ui:resize, lv2ui:idleInterface, lv2ui:showInterface ; 18 | lv2:extensionData lv2ui:resize, lv2ui:idleInterface, lv2ui:showInterface ; 19 | lv2ui:binary . 20 | 21 | 22 | a ; 23 | lv2:requiredFeature ; 24 | lv2ui:binary . 25 | -------------------------------------------------------------------------------- /src/padthv1.lv2/padthv1_ui-win32.ttl: -------------------------------------------------------------------------------- 1 | @prefix lv2: . 2 | @prefix lv2ui: . 3 | 4 | @prefix padthv1_lv2: . 5 | 6 | 7 | lv2ui:ui padthv1_lv2:ui_windows, padthv1_lv2:ui_external . 8 | 9 | 10 | a lv2ui:Qt6UI ; 11 | lv2:requiredFeature ; 12 | lv2ui:binary . 13 | 14 | 15 | a lv2ui:WindowsUI ; 16 | lv2:requiredFeature ; 17 | lv2:optionalFeature lv2ui:resize, lv2ui:idleInterface, lv2ui:showInterface ; 18 | lv2:extensionData lv2ui:resize, lv2ui:idleInterface, lv2ui:showInterface ; 19 | lv2ui:binary . 20 | 21 | 22 | a ; 23 | lv2:requiredFeature ; 24 | lv2ui:binary . 25 | -------------------------------------------------------------------------------- /src/palette/Wonton Soup.conf: -------------------------------------------------------------------------------- 1 | [ColorThemes] 2 | Wonton%20Soup\AlternateBase=#434750, #434750, #3b3e46 3 | Wonton%20Soup\Base=#3c4048, #3c4048, #34383f 4 | Wonton%20Soup\BrightText=#ffffff, #ffffff, #ffffff 5 | Wonton%20Soup\Button=#525863, #525863, #484d57 6 | Wonton%20Soup\ButtonText=#d2def0, #d2def0, #6f7682 7 | Wonton%20Soup\Dark=#282b31, #282b31, #23262b 8 | Wonton%20Soup\Highlight=#78889c, #515a67, #40444d 9 | Wonton%20Soup\HighlightedText=#d1e1f4, #b6c1d0, #616872 10 | Wonton%20Soup\Light=#5f6572, #5f6572, #565c68 11 | Wonton%20Soup\Link=#9cd4ff, #9cd4ff, #526677 12 | Wonton%20Soup\LinkVisited=#4080ff, #4080ff, #364c77 13 | Wonton%20Soup\Mid=#3f444c, #3f444c, #383b43 14 | Wonton%20Soup\Midlight=#545a65, #545a65, #4b515b 15 | Wonton%20Soup\NoRole=#000000, #000000, #000000 16 | Wonton%20Soup\PlaceholderText=#000000, #000000, #000000 17 | Wonton%20Soup\Shadow=#1d1f23, #1d1f23, #191b1e 18 | Wonton%20Soup\Text=#d2def0, #d2def0, #636973 19 | Wonton%20Soup\ToolTipBase=#b6c1d0, #b6c1d0, #b6c1d0 20 | Wonton%20Soup\ToolTipText=#2a2c30, #2a2c30, #2a2c30 21 | Wonton%20Soup\Window=#494e58, #494e58, #40444d 22 | Wonton%20Soup\WindowText=#b6c1d0, #b6c1d0, #616872 23 | -------------------------------------------------------------------------------- /src/man1/padthv1.1: -------------------------------------------------------------------------------- 1 | .TH PADTHV1 "1" "August 31, 2020" 2 | .SH NAME 3 | padthv1 \- an old-school polyphonic additive synthesizer 4 | .SH SYNOPSIS 5 | .B padthv1_jack 6 | [\fIoptions\fR] [\fIpreset-file\fR] 7 | .SH DESCRIPTION 8 | This manual page documents briefly the 9 | .B padthv1_jack 10 | command. 11 | .PP 12 | \fBpadthv1\fP is an old-school polyphonic additive synthesizer with stereo fx. 13 | .PP 14 | features: 15 | .IP 16 | a pure stand-alone JACK client with JACK-session, 17 | NSM and both JACK MIDI and ALSA MIDI input support; 18 | .IP 19 | a LV2 instrument plugin. 20 | URI: http://padthv1.sourceforge.net/lv2 21 | .SH OPTIONS 22 | .HP 23 | \fB\-g\fR, \fB\-\-no\-gui\fR 24 | .IP 25 | Disable the graphical user interface (GUI) 26 | .HP 27 | \fB\-n\fR, \fB\-\-client\-name\fR=[\fIlabel\fR] 28 | .IP 29 | Set the JACK client name (default: padthv1) 30 | .HP 31 | \fB\-h\fR, \fB\-\-help\fR 32 | .IP 33 | Show help about command line options 34 | .HP 35 | \fB\-v\fR, \fB\-\-version\fR 36 | .IP 37 | Show version information 38 | .SH FILES 39 | Configuration settings are stored in ~/.config/rncbc.org/padthv1.conf 40 | .SH AUTHOR 41 | padthv1 was written by Rui Nuno Capela. 42 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: padthv1 3 | Upstream-Contact: Rui Nuno Capela 4 | Source: https://padthv1.sourceforge.io 5 | 6 | Files: * 7 | Copyright: 2017-2025 Rui Nuno Capela 8 | License: GPL-2+ 9 | This package is free software; you can redistribute it and/or modify 10 | it under the terms of the GNU General Public License as published by 11 | the Free Software Foundation; either version 2 of the License, or (at 12 | your option) any later version. 13 | . 14 | This package is distributed in the hope that it will be useful, but 15 | WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | General Public License for more details. 18 | . 19 | On Debian systems, the complete text of the GNU General Public 20 | License can be found in /usr/share/common-licenses/GPL-2. 21 | 22 | Files: src/appdata/* 23 | Copyright: 2017-2025 Rui Nuno Capela 24 | License: FSFAP 25 | Copying and distribution of this file, with or without modification, 26 | are permitted in any medium without royalty provided the copyright 27 | notice and this notice are preserved. This file is offered as-is, 28 | without any warranty. 29 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: padthv1 2 | Section: sound 3 | Priority: optional 4 | Maintainer: Rui Nuno Capela 5 | Build-Depends: debhelper (>= 11), cmake, pkg-config, 6 | qtbase6.10-static (>= 6.10), qttools6.10-static (>= 6.10), 7 | qtsvg6.10-static (>= 6.10), qttranslations6.10-static (>= 6.10), 8 | libjack-dev | libjack-jackd2-dev, libasound2-dev, 9 | lv2-dev, liblo-dev, libfftw3-dev 10 | Standards-Version: 4.6.2 11 | Rules-Requires-Root: no 12 | 13 | Package: padthv1-jack 14 | Architecture: any 15 | Depends: ${shlibs:Depends}, ${misc:Depends}, libjack0 | libjack-jackd2-0 16 | Replaces: padthv1-common (<= ${source:Version}), padthv1 (<= ${source:Version}) 17 | Description: An old-school polyphonic additive synthesizer - JACK standalone 18 | An old-school all-digital polyphonic additive synthesizer with stereo fx. 19 | . 20 | This package provides the standalone JACK client application (padthv1_jack) 21 | 22 | Package: padthv1-lv2 23 | Architecture: any 24 | Depends: ${misc:Depends}, ${shlibs:Depends} 25 | Replaces: padthv1-common (<= ${source:Version}) 26 | Description: An old-school polyphonic additive synthesizer - LV2 plugin 27 | An old-school all-digital polyphonic additive synthesizer with stereo fx. 28 | . 29 | This package provides the LV2 plugin (http://padthv1.sourceforge.net/lv2) 30 | -------------------------------------------------------------------------------- /src/man1/padthv1.fr.1: -------------------------------------------------------------------------------- 1 | .TH PATHV1 "1" "Septembre 02, 2017" 2 | .SH NOM 3 | padthv1 \- un synthétiseur polyphonique additif à l'ancienne 4 | .SH SYNOPSIS 5 | .B padthv1_jack 6 | [\fIoptions\fR] [\fIfichier-de-pré-réglage\fR] 7 | .SH DESCRIPTION 8 | Cette page de manuel documente rapidement la commande 9 | .B padthv1_jack 10 | . 11 | .PP 12 | \fBpadthv1\fP est un synthétiseur polyphonique additif à l'ancienne, 13 | avec des effets stéréo. 14 | .PP 15 | fonctionnalités : 16 | .IP 17 | un client JACK autonome pur avec JACK-session, NSM, et un support d'entrée 18 | JACK MIDI ainsi que ALSA MIDI; 19 | .IP 20 | un greffon d'instrument LV2. 21 | URI : http://padthv1.sourceforge.net/lv2 22 | .SH OPTIONS 23 | .HP 24 | \fB\-g\fR, \fB\-\-no\-gui\fR 25 | .IP 26 | Désactive l'interface graphique utilisateur 27 | .HP 28 | \fB\-h\fR, \fB\-\-help\fR 29 | .IP 30 | Affiche de l'aide à propos des options de ligne de commande 31 | .HP 32 | \fB\-v\fR, \fB\-\-version\fR 33 | .IP 34 | Affiche des informations de version 35 | .SH FICHIERS 36 | Les paramètres de configuration sont stockés dans ~/.config/rncbc.org/padthv1.conf 37 | .SH AUTEUR 38 | padthv1 a été écrit par Rui Nuno Capela. 39 | .PP 40 | La version française de cette page de manuel a été traduite par Olivier Humbert 41 | , pour le projet LibraZiK (mais peut être utilisée par 42 | d'autres). 43 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | padthv1 (1.3.2-9.1) unstable; urgency=low 2 | 3 | * A Mid-Spring'25 Release. 4 | 5 | -- Rui Nuno Capela Tue, 20 May 2025 18:00:00 +0100 6 | 7 | padthv1 (1.3.1-8.1) unstable; urgency=low 8 | 9 | * An Early Spring'25 Release. 10 | 11 | -- Rui Nuno Capela Thu, 3 Apr 2025 18:00:00 +0100 12 | 13 | padthv1 (1.3.0-7.1) unstable; urgency=low 14 | 15 | * A New-Year'25 Release. 16 | 17 | -- Rui Nuno Capela Thu, 16 Jan 2025 18:00:00 +0000 18 | 19 | padthv1 (1.2.0-6.1) unstable; urgency=low 20 | 21 | * An End-of-Year'24 release. 22 | 23 | -- Rui Nuno Capela Sun, 15 Dec 2024 12:00:00 +0000 24 | 25 | padthv1 (1.1.3-5.1) unstable; urgency=low 26 | 27 | * A Halloween'24 release. 28 | 29 | -- Rui Nuno Capela Thu, 31 Oct 2024 20:00:00 +0000 30 | 31 | padthv1 (1.1.2-4.1) unstable; urgency=low 32 | 33 | * An Early-Fall'24 release. 34 | 35 | -- Rui Nuno Capela Wed, 2 oct 2024 18:00:00 +0100 36 | 37 | padthv1 (1.1.1-3.1) unstable; urgency=low 38 | 39 | * An End-of-Summer'24 release. 40 | 41 | -- Rui Nuno Capela Fri, 20 Sep 2024 18:00:00 +0100 42 | 43 | padthv1 (1.1.0-2.1) unstable; urgency=low 44 | 45 | * A Mid-Summer'24 release. 46 | 47 | -- Rui Nuno Capela Wed, 28 Aug 2024 18:00:00 +0100 48 | 49 | padthv1 (1.0.0-1.1) unstable; urgency=low 50 | 51 | * An Unthinkable release. 52 | 53 | -- Rui Nuno Capela Thu, 20 Jun 2024 18:00:00 +0100 54 | -------------------------------------------------------------------------------- /src/padthv1_list.h: -------------------------------------------------------------------------------- 1 | // padthv1_list.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2012, rncbc aka Rui Nuno Capela. All rights reserved. 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | 20 | *****************************************************************************/ 21 | 22 | #ifndef __padthv1_list_h 23 | #define __padthv1_list_h 24 | 25 | 26 | //------------------------------------------------------------------------- 27 | // padthv1_list - generic double-linked list node. 28 | 29 | template 30 | class padthv1_list 31 | { 32 | public: 33 | 34 | padthv1_list() : m_prev(0), m_next(0) {} 35 | 36 | void append(T *p) 37 | { 38 | p->m_prev = m_prev; 39 | p->m_next = 0; 40 | 41 | if (m_prev) 42 | m_prev->m_next = p; 43 | else 44 | m_next = p; 45 | 46 | m_prev = p; 47 | } 48 | 49 | void remove(T *p) 50 | { 51 | if (p->m_prev) 52 | p->m_prev->m_next = p->m_next; 53 | else 54 | m_next = p->m_next; 55 | 56 | if (p->m_next) 57 | p->m_next->m_prev = p->m_prev; 58 | else 59 | m_prev = p->m_prev; 60 | } 61 | 62 | T *prev() const { return m_prev; } 63 | T *next() const { return m_next; } 64 | 65 | private: 66 | 67 | T *m_prev; 68 | T *m_next; 69 | }; 70 | 71 | 72 | #endif // __padthv1_list_h 73 | 74 | // end of padthv1_list.h 75 | -------------------------------------------------------------------------------- /src/appdata/org.rncbc.padthv1.metainfo.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | org.rncbc.padthv1 5 | FSFAP 6 | GPL-2.0+ 7 | padthv1 8 | an old-school polyphonic additive synthesizer 9 | 10 |

padthv1 is an old-school polyphonic additive synthesizer 11 | with stereo fx.

12 |

features:

    13 |
  • pure stand-alone JACK client with JACK-session, NSM and both JACK MIDI 14 | and ALSA MIDI input support;
  • 15 |
  • LV2 instrument plugin. 16 | URI: http\://padthv1.sourceforge.net/lv2
  • 17 |

18 |
19 | org.rncbc.padthv1.desktop 20 | 21 | padthv1_jack 22 | 23 | 24 | 25 | https://padthv1.sourceforge.io/image/padthv1-screenshot9.png 26 | The main window showing the application in action 27 | 28 | 29 | 30 | Audio 31 | MIDI 32 | ALSA 33 | JACK 34 | Synthesizer 35 | LV2 36 | Qt 37 | 38 | https://padthv1.sourceforge.io 39 | rncbc.org 40 | rncbc aka. Rui Nuno Capela 41 | rncbc@rncbc.org 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 |
52 | -------------------------------------------------------------------------------- /src/padthv1widget_status.h: -------------------------------------------------------------------------------- 1 | // padthv1widget_status.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2012-2020, rncbc aka Rui Nuno Capela. All rights reserved. 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | 20 | *****************************************************************************/ 21 | 22 | #ifndef __padthv1widget_status_h 23 | #define __padthv1widget_status_h 24 | 25 | #include 26 | 27 | 28 | // Forward declarations. 29 | class padthv1widget_keybd; 30 | 31 | class QLabel; 32 | class QPixmap; 33 | 34 | 35 | //------------------------------------------------------------------------- 36 | // padthv1widget_status - Custom status-bar widget. 37 | 38 | class padthv1widget_status : public QStatusBar 39 | { 40 | Q_OBJECT 41 | 42 | public: 43 | 44 | // Constructor. 45 | padthv1widget_status(QWidget *pParent = 0); 46 | 47 | // Destructor. 48 | ~padthv1widget_status(); 49 | 50 | // Permanent widgets accessors. 51 | padthv1widget_keybd *keybd() const; 52 | 53 | void midiInLed(bool bMidiInLed); 54 | void midiInNote(int iNote, int iVelocity); 55 | void modified(bool bModified); 56 | 57 | private: 58 | 59 | // Permanent widgets. 60 | QPixmap *m_midiInLed[2]; 61 | 62 | QLabel *m_pMidiInLedLabel; 63 | QLabel *m_pModifiedLabel; 64 | 65 | padthv1widget_keybd *m_pKeybd; 66 | }; 67 | 68 | 69 | #endif // __padthv1widget_status_h 70 | 71 | // end of padthv1widget_status.h 72 | -------------------------------------------------------------------------------- /src/padthv1widget_programs.h: -------------------------------------------------------------------------------- 1 | // padthv1widget_programs.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2012-2023, rncbc aka Rui Nuno Capela. All rights reserved. 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | 20 | *****************************************************************************/ 21 | 22 | #ifndef __padthv1widget_programs_h 23 | #define __padthv1widget_programs_h 24 | 25 | #include 26 | 27 | 28 | // forward decls. 29 | class padthv1_programs; 30 | 31 | 32 | //---------------------------------------------------------------------------- 33 | // padthv1widget_programs -- Custom (tree) widget. 34 | 35 | class padthv1widget_programs : public QTreeWidget 36 | { 37 | Q_OBJECT 38 | 39 | public: 40 | 41 | // ctor. 42 | padthv1widget_programs(QWidget *pParent = nullptr); 43 | // dtor. 44 | ~padthv1widget_programs(); 45 | 46 | // utilities. 47 | void loadPrograms(padthv1_programs *pPrograms); 48 | void savePrograms(padthv1_programs *pPrograms); 49 | 50 | QString currentProgramName() const; 51 | 52 | public slots: 53 | 54 | // slots. 55 | void addBankItem(); 56 | void addProgramItem(); 57 | 58 | protected slots: 59 | 60 | // private slots. 61 | void itemChangedSlot(QTreeWidgetItem *, int); 62 | 63 | void itemExpandedSlot(QTreeWidgetItem *); 64 | void itemCollapsedSlot(QTreeWidgetItem *); 65 | 66 | protected: 67 | 68 | // item delegate decl.. 69 | class ItemDelegate; 70 | 71 | // factory methods. 72 | QTreeWidgetItem *newBankItem(); 73 | QTreeWidgetItem *newProgramItem(); 74 | }; 75 | 76 | 77 | #endif // __padthv1widget_programs_h 78 | 79 | // end of padthv1widget_programs.h 80 | -------------------------------------------------------------------------------- /src/padthv1widget_controls.h: -------------------------------------------------------------------------------- 1 | // padthv1widget_controls.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2012-2023, rncbc aka Rui Nuno Capela. All rights reserved. 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | 20 | *****************************************************************************/ 21 | 22 | #ifndef __padthv1widget_controls_h 23 | #define __padthv1widget_controls_h 24 | 25 | #include 26 | 27 | #include 28 | 29 | 30 | // forward decls. 31 | class padthv1_controls; 32 | 33 | 34 | //---------------------------------------------------------------------------- 35 | // padthv1widget_controls -- Custom (tree) widget. 36 | 37 | class padthv1widget_controls : public QTreeWidget 38 | { 39 | Q_OBJECT 40 | 41 | public: 42 | 43 | // ctor. 44 | padthv1widget_controls(QWidget *pParent = nullptr); 45 | // dtor. 46 | ~padthv1widget_controls(); 47 | 48 | // utilities. 49 | void loadControls(padthv1_controls *pControls); 50 | void saveControls(padthv1_controls *pControls); 51 | 52 | // controller name utilities. 53 | typedef QMap Names; 54 | 55 | static const Names& controllerNames(); 56 | static const Names& rpnNames(); 57 | static const Names& nrpnNames(); 58 | static const Names& control14Names(); 59 | 60 | public slots: 61 | 62 | // slots. 63 | void addControlItem(); 64 | 65 | protected slots: 66 | 67 | // private slots. 68 | void itemChangedSlot(QTreeWidgetItem *, int); 69 | 70 | protected: 71 | 72 | // item delegate decl.. 73 | class ItemDelegate; 74 | 75 | // factory methods. 76 | QTreeWidgetItem *newControlItem(); 77 | }; 78 | 79 | 80 | #endif // __padthv1widget_controls_h 81 | 82 | // end of padthv1widget_controls.h 83 | -------------------------------------------------------------------------------- /src/padthv1widget_jack.h: -------------------------------------------------------------------------------- 1 | // padthv1widget_jack.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2012-2025, rncbc aka Rui Nuno Capela. All rights reserved. 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | 20 | *****************************************************************************/ 21 | 22 | #ifndef __padthv1widget_jack_h 23 | #define __padthv1widget_jack_h 24 | 25 | #include "padthv1widget.h" 26 | 27 | 28 | // Forward decls. 29 | class padthv1_jack; 30 | 31 | #ifdef CONFIG_NSM 32 | class padthv1_nsm; 33 | #endif 34 | 35 | 36 | //------------------------------------------------------------------------- 37 | // padthv1widget_jack - decl. 38 | // 39 | 40 | class padthv1widget_jack : public padthv1widget 41 | { 42 | public: 43 | 44 | // Constructor. 45 | padthv1widget_jack(padthv1_jack *pPadth); 46 | 47 | // Destructor. 48 | ~padthv1widget_jack(); 49 | 50 | #ifdef CONFIG_NSM 51 | // NSM client accessors. 52 | void setNsmClient(padthv1_nsm *pNsmClient); 53 | padthv1_nsm *nsmClient() const; 54 | #endif // CONFIG_NSM 55 | 56 | // Dirty flag method. 57 | void updateDirtyPreset(bool bDirtyPreset); 58 | 59 | protected: 60 | 61 | // Synth engine accessor. 62 | padthv1_ui *ui_instance() const; 63 | 64 | // Param port method. 65 | void updateParam(padthv1::ParamIndex index, float fValue) const; 66 | 67 | // Application close. 68 | void closeEvent(QCloseEvent *pCloseEvent); 69 | 70 | #ifdef CONFIG_NSM 71 | // Optional GUI handlers. 72 | void showEvent(QShowEvent *pShowEvent); 73 | void hideEvent(QHideEvent *pHideEvent); 74 | #endif // CONFIG_NSM 75 | 76 | private: 77 | 78 | // Instance variables. 79 | padthv1 *m_pPadth; 80 | padthv1_ui *m_pPadthUi; 81 | 82 | #ifdef CONFIG_NSM 83 | padthv1_nsm *m_pNsmClient; 84 | #endif 85 | }; 86 | 87 | 88 | #endif // __padthv1widget_jack_h 89 | 90 | // end of padthv1widget_jack.h 91 | -------------------------------------------------------------------------------- /src/padthv1widget_lv2.h: -------------------------------------------------------------------------------- 1 | // padthv1widget_lv2.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2012-2025, rncbc aka Rui Nuno Capela. All rights reserved. 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | 20 | *****************************************************************************/ 21 | 22 | #ifndef __padthv1widget_lv2_h 23 | #define __padthv1widget_lv2_h 24 | 25 | #include "padthv1widget.h" 26 | #include "padthv1_lv2ui.h" 27 | 28 | 29 | //------------------------------------------------------------------------- 30 | // padthv1widget_lv2 - decl. 31 | // 32 | 33 | class padthv1widget_lv2 : public padthv1widget 34 | { 35 | public: 36 | 37 | // Constructor. 38 | padthv1widget_lv2(padthv1_lv2 *pPadth, 39 | LV2UI_Controller controller, LV2UI_Write_Function write_function); 40 | 41 | // Destructor. 42 | ~padthv1widget_lv2(); 43 | 44 | // LV2 port event dispatcher. 45 | void port_event(uint32_t port_index, 46 | uint32_t buffer_size, uint32_t format, const void *buffer); 47 | 48 | #ifdef CONFIG_LV2_UI_EXTERNAL 49 | void setExternalHost(LV2_External_UI_Host *external_host); 50 | const LV2_External_UI_Host *externalHost() const; 51 | #endif 52 | 53 | #ifdef CONFIG_LV2_UI_IDLE 54 | bool isIdleClosed() const; 55 | #endif 56 | 57 | protected: 58 | 59 | // Synth engine accessor. 60 | padthv1_ui *ui_instance() const; 61 | 62 | // Param methods. 63 | void updateParam(padthv1::ParamIndex index, float fValue) const; 64 | 65 | // Close event handler. 66 | void closeEvent(QCloseEvent *pCloseEvent); 67 | 68 | private: 69 | 70 | // Instance variables. 71 | padthv1_lv2ui *m_pPadthUi; 72 | 73 | #ifdef CONFIG_LV2_UI_EXTERNAL 74 | LV2_External_UI_Host *m_external_host; 75 | #endif 76 | #ifdef CONFIG_LV2_UI_IDLE 77 | bool m_bIdleClosed; 78 | #endif 79 | }; 80 | 81 | 82 | #endif // __padthv1widget_lv2_h 83 | 84 | // end of padthv1widget_lv2.h 85 | -------------------------------------------------------------------------------- /src/padthv1widget_wave.h: -------------------------------------------------------------------------------- 1 | // padthv1widget_wave.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2012-2021, rncbc aka Rui Nuno Capela. All rights reserved. 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | 20 | *****************************************************************************/ 21 | 22 | #ifndef __padthv1widget_wave_h 23 | #define __padthv1widget_wave_h 24 | 25 | #include 26 | 27 | 28 | // Forward decl. 29 | class padthv1_wave_lf; 30 | 31 | 32 | //---------------------------------------------------------------------------- 33 | // padthv1widget_wave -- Custom widget 34 | 35 | class padthv1widget_wave : public QFrame 36 | { 37 | Q_OBJECT 38 | 39 | public: 40 | 41 | // Constructor. 42 | padthv1widget_wave(QWidget *pParent = nullptr); 43 | // Destructor. 44 | ~padthv1widget_wave(); 45 | 46 | // Parameter getters. 47 | float waveShape() const; 48 | float waveWidth() const; 49 | 50 | public slots: 51 | 52 | // Parameter setters. 53 | void setWaveShape(float fWaveShape); 54 | void setWaveWidth(float fWaveWidth); 55 | 56 | signals: 57 | 58 | // Parameter change signals. 59 | void waveShapeChanged(float fWaveShape); 60 | void waveWidthChanged(float fWaveWidth); 61 | 62 | protected: 63 | 64 | // Draw canvas. 65 | void paintEvent(QPaintEvent *); 66 | 67 | // Drag/move curve. 68 | void dragCurve(const QPoint& pos); 69 | 70 | // Mouse interaction. 71 | void mousePressEvent(QMouseEvent *pMouseEvent); 72 | void mouseMoveEvent(QMouseEvent *pMouseEvent); 73 | void mouseReleaseEvent(QMouseEvent *pMouseEvent); 74 | void mouseDoubleClickEvent(QMouseEvent *pMouseEvent); 75 | void wheelEvent(QWheelEvent *pWheelEvent); 76 | 77 | private: 78 | 79 | // Instance state. 80 | padthv1_wave_lf *m_pWave; 81 | 82 | // Drag state. 83 | bool m_bDragging; 84 | int m_iDragShape; 85 | QPoint m_posDrag; 86 | }; 87 | 88 | #endif // __padthv1widget_wave_h 89 | 90 | 91 | // end of padthv1widget_wave.h 92 | -------------------------------------------------------------------------------- /src/padthv1_ui.h: -------------------------------------------------------------------------------- 1 | // padthv1_ui.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2012-2025, rncbc aka Rui Nuno Capela. All rights reserved. 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | 20 | *****************************************************************************/ 21 | 22 | #ifndef __padthv1_ui_h 23 | #define __padthv1_ui_h 24 | 25 | #include "padthv1.h" 26 | 27 | #include 28 | 29 | 30 | //------------------------------------------------------------------------- 31 | // padthv1_ui - decl. 32 | // 33 | 34 | class padthv1_ui 35 | { 36 | public: 37 | 38 | padthv1_ui(padthv1 *pPadth, bool bPlugin); 39 | 40 | padthv1 *instance() const; 41 | 42 | bool isPlugin() const; 43 | 44 | padthv1_sample *sample(int sid) const; 45 | 46 | bool newPreset(); 47 | 48 | bool loadPreset(const QString& sFilename); 49 | bool savePreset(const QString& sFilename); 50 | 51 | void setParamValue(padthv1::ParamIndex index, float fValue); 52 | float paramValue(padthv1::ParamIndex index) const; 53 | 54 | padthv1_controls *controls() const; 55 | padthv1_programs *programs() const; 56 | 57 | void reset(); 58 | 59 | void updatePreset(bool bDirty); 60 | 61 | void updateParam(padthv1::ParamIndex index); 62 | 63 | void midiInEnabled(bool bEnabled); 64 | uint32_t midiInCount(); 65 | 66 | void directNoteOn(int note, int vel); 67 | 68 | void setTuningEnabled(bool enabled); 69 | bool isTuningEnabled() const; 70 | 71 | void setTuningRefPitch(float refPitch); 72 | float tuningRefPitch() const; 73 | 74 | void setTuningRefNote(int refNote); 75 | int tuningRefNote() const; 76 | 77 | void setTuningScaleFile(const char *pszScaleFile); 78 | const char *tuningScaleFile() const; 79 | 80 | void setTuningKeyMapFile(const char *pszKeyMapFile); 81 | const char *tuningKeyMapFile() const; 82 | 83 | void resetTuning(); 84 | 85 | // MIDI note/octave name helper. 86 | static QString noteName(int note); 87 | 88 | private: 89 | 90 | padthv1 *m_pPadth; 91 | 92 | bool m_bPlugin; 93 | }; 94 | 95 | 96 | #endif// __padthv1_ui_h 97 | 98 | // end of padthv1_ui.h 99 | -------------------------------------------------------------------------------- /src/padthv1_lv2ui.h: -------------------------------------------------------------------------------- 1 | // padthv1_lv2ui.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2012-2024, rncbc aka Rui Nuno Capela. All rights reserved. 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | 20 | *****************************************************************************/ 21 | 22 | #ifndef __padthv1_lv2ui_h 23 | #define __padthv1_lv2ui_h 24 | 25 | #include "padthv1_ui.h" 26 | 27 | #ifdef CONFIG_LV2_OLD_HEADERS 28 | #include "lv2/lv2plug.in/ns/extensions/ui/ui.h" 29 | #else 30 | #include "lv2/ui/ui.h" 31 | #endif 32 | 33 | #define PADTHV1_LV2UI_URI PADTHV1_LV2_PREFIX "ui" 34 | 35 | #if defined(CONFIG_LV2_UI_X11) || defined(CONFIG_LV2_UI_WINDOWS) 36 | #include 37 | #endif 38 | 39 | #ifdef CONFIG_LV2_UI_X11 40 | #define PADTHV1_LV2UI_X11_URI PADTHV1_LV2_PREFIX "ui_x11" 41 | #endif 42 | 43 | #ifdef CONFIG_LV2_UI_WINDOWS 44 | #include 45 | #define PADTHV1_LV2UI_WINDOWS_URI PADTHV1_LV2_PREFIX "ui_windows" 46 | 47 | // Polyfill for windows size (minimal suitable size) 48 | // Qt cannot determine the right window size on Windows. 49 | #define UI_WINDOWS_RECOMMENDED_WIDTH 1380 50 | #define UI_WINDOWS_RECOMMENDED_HEIGHT 650 51 | #endif 52 | 53 | #ifdef CONFIG_LV2_UI_EXTERNAL 54 | #include "lv2_external_ui.h" 55 | #define PADTHV1_LV2UI_EXTERNAL_URI PADTHV1_LV2_PREFIX "ui_external" 56 | #endif 57 | 58 | 59 | // Forward decls. 60 | class padthv1_lv2; 61 | 62 | 63 | //------------------------------------------------------------------------- 64 | // padthv1_lv2ui - decl. 65 | // 66 | 67 | class padthv1_lv2ui : public padthv1_ui 68 | { 69 | public: 70 | 71 | // Constructor. 72 | padthv1_lv2ui(padthv1_lv2 *pPadth, 73 | LV2UI_Controller controller, LV2UI_Write_Function write_function); 74 | 75 | // Accessors. 76 | const LV2UI_Controller& controller() const; 77 | void write_function(padthv1::ParamIndex index, float fValue) const; 78 | 79 | private: 80 | 81 | // Instance variables. 82 | LV2UI_Controller m_controller; 83 | LV2UI_Write_Function m_write_function; 84 | }; 85 | 86 | 87 | #endif // __padthv1_lv2ui_h 88 | 89 | // end of padthv1_lv2ui.h 90 | -------------------------------------------------------------------------------- /src/padthv1_param.h: -------------------------------------------------------------------------------- 1 | // padthv1_param.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2012-2024, rncbc aka Rui Nuno Capela. All rights reserved. 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | 20 | *****************************************************************************/ 21 | 22 | #ifndef __padthv1_param_h 23 | #define __padthv1_param_h 24 | 25 | #include "padthv1.h" 26 | 27 | #include 28 | 29 | // forward decl. 30 | class QDomElement; 31 | class QDomDocument; 32 | 33 | 34 | //------------------------------------------------------------------------- 35 | // padthv1_param - decl. 36 | // 37 | 38 | namespace padthv1_param 39 | { 40 | // Preset initialization method. 41 | bool newPreset(padthv1 *pPadth); 42 | 43 | // Preset serialization methods. 44 | bool loadPreset(padthv1 *pPadth, 45 | const QString& sFilename); 46 | bool savePreset(padthv1 *pPadth, 47 | const QString& sFilename, 48 | bool bSymLink = false); 49 | 50 | // Sample serialization methods. 51 | void loadSamples(padthv1 *pPadth, 52 | const QDomElement& eSamples); 53 | void saveSamples(padthv1 *pPadth, 54 | QDomDocument& doc, QDomElement& eSamples, 55 | bool bSymLink = false); 56 | 57 | // Tuning serialization methods. 58 | void loadTuning(padthv1 *pPadth, 59 | const QDomElement& eTuning); 60 | void saveTuning(padthv1 *pPadth, 61 | QDomDocument& doc, QDomElement& eTuning, 62 | bool bSymLink = false); 63 | 64 | // Default parameter name/value helpers. 65 | const char *paramName(padthv1::ParamIndex index); 66 | float paramDefaultValue(padthv1::ParamIndex index); 67 | float paramSafeValue(padthv1::ParamIndex index, float fValue); 68 | float paramValue(padthv1::ParamIndex index, float fScale); 69 | float paramScale(padthv1::ParamIndex index, float fValue); 70 | bool paramFloat(padthv1::ParamIndex index); 71 | 72 | // Load/save and convert canonical/absolute filename helpers. 73 | QString loadFilename(const QString& sFilename); 74 | QString saveFilename(const QString& sFilename, bool bSymLink); 75 | }; 76 | 77 | 78 | #endif // __padthv1_param_h 79 | 80 | // end of padthv1_param.h 81 | -------------------------------------------------------------------------------- /src/padthv1widget_preset.h: -------------------------------------------------------------------------------- 1 | // padthv1widget_preset.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2012-2024, rncbc aka Rui Nuno Capela. All rights reserved. 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | 20 | *****************************************************************************/ 21 | 22 | #ifndef __padthv1widget_preset_h 23 | #define __padthv1widget_preset_h 24 | 25 | #include 26 | 27 | // Forward declarations. 28 | class QToolButton; 29 | class QComboBox; 30 | 31 | 32 | //------------------------------------------------------------------------- 33 | // padthv1widget_preset - Custom combo/edit-box widget. 34 | 35 | class padthv1widget_preset : public QWidget 36 | { 37 | Q_OBJECT 38 | 39 | public: 40 | 41 | // Constructor. 42 | padthv1widget_preset(QWidget *pParent = 0); 43 | 44 | void setPreset(const QString& sPreset); 45 | QString preset() const; 46 | 47 | void setDirtyPreset(bool bDirtyPreset); 48 | bool isDirtyPreset() const; 49 | 50 | void clearPreset(); 51 | bool queryPreset(); 52 | 53 | signals: 54 | 55 | void newPresetFile(); 56 | 57 | void loadPresetFile(const QString&); 58 | void savePresetFile(const QString&); 59 | 60 | void resetPresetFile(); 61 | 62 | public slots: 63 | 64 | void initPreset(); 65 | void stabilizePreset(); 66 | 67 | protected slots: 68 | 69 | void newPreset(); 70 | void openPreset(); 71 | void activatePreset(const QString&); 72 | void savePreset(); 73 | void deletePreset(); 74 | void resetPreset(); 75 | 76 | protected: 77 | 78 | void loadPreset(const QString&); 79 | void savePreset(const QString&); 80 | 81 | void refreshPreset(); 82 | 83 | private: 84 | 85 | // Widget members. 86 | QToolButton *m_pNewButton; 87 | QToolButton *m_pOpenButton; 88 | QComboBox *m_pComboBox; 89 | QToolButton *m_pSaveButton; 90 | QToolButton *m_pDeleteButton; 91 | QToolButton *m_pResetButton; 92 | 93 | int m_iInitPreset; 94 | int m_iDirtyPreset; 95 | }; 96 | 97 | 98 | #endif // __padthv1widget_preset_h 99 | 100 | // end of padthv1widget_preset.h 101 | -------------------------------------------------------------------------------- /src/padthv1_sched.h: -------------------------------------------------------------------------------- 1 | // padthv1_sched.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2012-2024, rncbc aka Rui Nuno Capela. All rights reserved. 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | 20 | *****************************************************************************/ 21 | 22 | #ifndef __padthv1_sched_h 23 | #define __padthv1_sched_h 24 | 25 | #include 26 | 27 | 28 | // forward decls. 29 | class padthv1; 30 | 31 | 32 | //------------------------------------------------------------------------- 33 | // padthv1_sched - worker/scheduled stuff (pure virtual). 34 | // 35 | 36 | class padthv1_sched 37 | { 38 | public: 39 | 40 | // plausible sched types. 41 | enum Type { Sample, Programs, Controls, Controller, MidiIn }; 42 | 43 | // ctor. 44 | padthv1_sched(padthv1 *pPadth, Type stype, uint32_t nsize = 8); 45 | 46 | // virtual dtor. 47 | virtual ~padthv1_sched(); 48 | 49 | // instance access. 50 | padthv1 *instance() const; 51 | 52 | // schedule process. 53 | void schedule(int sid = 0); 54 | 55 | // test-and-set wait. 56 | bool sync_wait(); 57 | 58 | // scheduled processor. 59 | void sync_process(); 60 | 61 | // (pure) virtual processor. 62 | virtual void process(int sid) = 0; 63 | 64 | // signal broadcast (static). 65 | static void sync_notify(padthv1 *pPadth, Type stype, int sid); 66 | 67 | // Notifier - Worker/schedule proxy decl. 68 | // 69 | class Notifier 70 | { 71 | public: 72 | 73 | // ctor. 74 | Notifier(padthv1 *pPadth); 75 | 76 | // dtor. 77 | virtual ~Notifier(); 78 | 79 | // signal notifier. 80 | virtual void notify(padthv1_sched::Type stype, int sid) const = 0; 81 | 82 | private: 83 | 84 | // instance variables. 85 | padthv1 *m_pPadth; 86 | }; 87 | 88 | // process/clear pending schedules, immediately. (static) 89 | static void sync_pending(); 90 | static void sync_reset(); 91 | 92 | private: 93 | 94 | // instance variables. 95 | padthv1 *m_pPadth; 96 | 97 | Type m_stype; 98 | 99 | // sched queue instance reference. 100 | uint32_t m_nsize; 101 | uint32_t m_nmask; 102 | 103 | int *m_items; 104 | 105 | volatile uint32_t m_iread; 106 | volatile uint32_t m_iwrite; 107 | 108 | volatile bool m_sync_wait; 109 | }; 110 | 111 | 112 | #endif // __padthv1_sched_h 113 | 114 | // end of padthv1_sched.h 115 | -------------------------------------------------------------------------------- /src/padthv1widget_filt.h: -------------------------------------------------------------------------------- 1 | // padthv1widget_filt.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2012-2021, rncbc aka Rui Nuno Capela. All rights reserved. 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | 20 | *****************************************************************************/ 21 | 22 | #ifndef __padthv1widget_filt_h 23 | #define __padthv1widget_filt_h 24 | 25 | #include 26 | #include 27 | 28 | 29 | //---------------------------------------------------------------------------- 30 | // padthv1widget_filt -- Custom widget 31 | 32 | class padthv1widget_filt : public QFrame 33 | { 34 | Q_OBJECT 35 | 36 | public: 37 | 38 | // Constructor. 39 | padthv1widget_filt(QWidget *pParent = nullptr); 40 | // Destructor. 41 | ~padthv1widget_filt(); 42 | 43 | // Parameter getters. 44 | float cutoff() const; 45 | float reso() const; 46 | float type() const; 47 | float slope() const; 48 | 49 | public slots: 50 | 51 | // Parameter setters. 52 | void setCutoff(float fCutoff); 53 | void setReso(float fReso); 54 | void setType(float fType); 55 | void setSlope(float fSlope); 56 | 57 | signals: 58 | 59 | // Parameter change signals. 60 | void cutoffChanged(float fCutoff); 61 | void resoChanged(float fReso); 62 | 63 | protected: 64 | 65 | // Draw canvas. 66 | void paintEvent(QPaintEvent *); 67 | 68 | // Filter types/slopes. 69 | enum Types { 70 | LPF = 0, 71 | BPF = 1, 72 | HPF = 2, 73 | BRF = 3, 74 | L2F = 4 75 | }; 76 | 77 | enum Slopes { 78 | S12DB = 0, 79 | S24DB = 1, 80 | SBIQUAD = 2, 81 | SFORMANT = 3 82 | }; 83 | 84 | // Drag/move curve. 85 | void dragCurve(const QPoint& pos); 86 | 87 | // Mouse interaction. 88 | void mousePressEvent(QMouseEvent *pMouseEvent); 89 | void mouseMoveEvent(QMouseEvent *pMouseEvent); 90 | void mouseReleaseEvent(QMouseEvent *pMouseEvent); 91 | void wheelEvent(QWheelEvent *pWheelEvent); 92 | 93 | // Resize canvas. 94 | void resizeEvent(QResizeEvent *); 95 | 96 | // Update the drawing path. 97 | void updatePath(); 98 | 99 | private: 100 | 101 | // Instance state. 102 | float m_fCutoff; 103 | float m_fReso; 104 | int m_iType; 105 | int m_iSlope; 106 | 107 | // Drag state. 108 | bool m_bDragging; 109 | QPoint m_posDrag; 110 | 111 | // Drawable path. 112 | QPainterPath m_path; 113 | }; 114 | 115 | #endif // __padthv1widget_filt_h 116 | 117 | 118 | // end of padthv1widget_filt.h 119 | -------------------------------------------------------------------------------- /src/padthv1widget_env.h: -------------------------------------------------------------------------------- 1 | // padthv1widget_env.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2012-2021, rncbc aka Rui Nuno Capela. All rights reserved. 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | 20 | *****************************************************************************/ 21 | 22 | #ifndef __padthv1widget_env_h 23 | #define __padthv1widget_env_h 24 | 25 | #include 26 | #include 27 | 28 | 29 | //---------------------------------------------------------------------------- 30 | // padthv1widget_env -- Custom widget 31 | 32 | class padthv1widget_env : public QFrame 33 | { 34 | Q_OBJECT 35 | 36 | public: 37 | 38 | // Constructor. 39 | padthv1widget_env(QWidget *pParent = nullptr); 40 | // Destructor. 41 | ~padthv1widget_env(); 42 | 43 | // Parameter getters. 44 | float attack() const; 45 | float decay() const; 46 | float sustain() const; 47 | float release() const; 48 | 49 | public slots: 50 | 51 | // Parameter setters. 52 | void setAttack(float fAttack); 53 | void setDecay(float fDecay); 54 | void setSustain(float fSustain); 55 | void setRelease(float fRelease); 56 | 57 | signals: 58 | 59 | // Parameter change signals. 60 | void attackChanged(float fAttack); 61 | void decayChanged(float fDecay); 62 | void sustainChanged(float fSustain); 63 | void releaseChanged(float fRelease); 64 | 65 | protected: 66 | 67 | // Draw canvas. 68 | void paintEvent(QPaintEvent *); 69 | 70 | // Parameter node indexes. 71 | enum NodeIndex { 72 | Idle = 1, 73 | Attack = 2, 74 | Decay = 3, 75 | Sustain = 4, 76 | Release = 5, 77 | End = 6 78 | }; 79 | 80 | // Draw rectangular point. 81 | QRect nodeRect(int iNode) const; 82 | int nodeIndex(const QPoint& pos) const; 83 | 84 | void dragNode(const QPoint& pos); 85 | 86 | // Mouse interaction. 87 | void mousePressEvent(QMouseEvent *pMouseEvent); 88 | void mouseMoveEvent(QMouseEvent *pMouseEvent); 89 | void mouseReleaseEvent(QMouseEvent *pMouseEvent); 90 | 91 | // Resize canvas. 92 | void resizeEvent(QResizeEvent *); 93 | 94 | // Update the drawing polygon. 95 | void updatePolygon(); 96 | 97 | private: 98 | 99 | // Instance state. 100 | float m_fAttack; 101 | float m_fDecay; 102 | float m_fSustain; 103 | float m_fRelease; 104 | 105 | // Draw state. 106 | QPolygon m_poly; 107 | 108 | // Drag state. 109 | int m_iDragNode; 110 | QPoint m_posDrag; 111 | }; 112 | 113 | #endif // __padthv1widget_env_h 114 | 115 | 116 | // end of padthv1widget_env.h 117 | -------------------------------------------------------------------------------- /src/lv2/lv2_port_change_request.h: -------------------------------------------------------------------------------- 1 | /* 2 | LV2 ControlInputPort change request extension 3 | Copyright 2020 Filipe Coelho 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted, provided that the above 7 | copyright notice and this permission notice appear in all copies. 8 | 9 | THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | */ 17 | 18 | /** 19 | @file control-input-port-change-request.h 20 | C header for the LV2 ControlInputPort change request extension . 21 | */ 22 | 23 | #ifndef LV2_CONTROL_INPUT_PORT_CHANGE_REQUEST_H 24 | #define LV2_CONTROL_INPUT_PORT_CHANGE_REQUEST_H 25 | 26 | #if CONFIG_LV2_OLD_HEADERS 27 | #include "lv2.h" 28 | #else 29 | #include "lv2/core/lv2.h" 30 | #endif 31 | 32 | #define LV2_CONTROL_INPUT_PORT_CHANGE_REQUEST_URI "http://kx.studio/ns/lv2ext/control-input-port-change-request" 33 | #define LV2_CONTROL_INPUT_PORT_CHANGE_REQUEST_PREFIX LV2_CONTROL_INPUT_PORT_CHANGE_REQUEST_URI "#" 34 | 35 | #include 36 | 37 | #ifdef __cplusplus 38 | extern "C" { 39 | #else 40 | #include 41 | #endif 42 | 43 | /** A status code for LV2_CONTROL_INPUT_PORT_CHANGE_REQUEST_URI functions. */ 44 | typedef enum { 45 | LV2_CONTROL_INPUT_PORT_CHANGE_SUCCESS = 0, /**< Completed successfully. */ 46 | LV2_CONTROL_INPUT_PORT_CHANGE_ERR_UNKNOWN = 1, /**< Unknown error. */ 47 | LV2_CONTROL_INPUT_PORT_CHANGE_ERR_INVALID_INDEX = 2 /**< Failed due to invalid port index. */ 48 | } LV2_ControlInputPort_Change_Status; 49 | 50 | /** 51 | * Opaque handle for LV2_CONTROL_INPUT_PORT_CHANGE_REQUEST_URI feature. 52 | */ 53 | typedef void* LV2_ControlInputPort_Change_Request_Handle; 54 | 55 | /** 56 | * On instantiation, host must supply LV2_CONTROL_INPUT_PORT_CHANGE_REQUEST_URI feature. 57 | * LV2_Feature::data must be pointer to LV2_ControlInputPort_Change_Request. 58 | */ 59 | typedef struct _LV2_ControlInputPort_Change_Request { 60 | /** 61 | * Opaque host data. 62 | */ 63 | LV2_ControlInputPort_Change_Request_Handle handle; 64 | 65 | /** 66 | * request_change() 67 | * 68 | * Ask the host to change a plugin's control input port value. 69 | * Parameter handle MUST be the 'handle' member of this struct. 70 | * Parameter index is port index to change. 71 | * Parameter value is the requested value to change the control port input to. 72 | * 73 | * Returns status of the request. 74 | * The host may decline this request, if e.g. it is currently automating this port. 75 | * 76 | * The plugin MUST call this function during run(). 77 | */ 78 | LV2_ControlInputPort_Change_Status (*request_change)(LV2_ControlInputPort_Change_Request_Handle handle, 79 | uint32_t index, 80 | float value); 81 | 82 | } LV2_ControlInputPort_Change_Request; 83 | 84 | #ifdef __cplusplus 85 | } /* extern "C" */ 86 | #endif 87 | 88 | #endif /* LV2_CONTROL_INPUT_PORT_CHANGE_REQUEST_H */ 89 | -------------------------------------------------------------------------------- /src/padthv1_tuning.h: -------------------------------------------------------------------------------- 1 | // padthv1_tuning.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2012-2021, rncbc aka Rui Nuno Capela. All rights reserved. 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | 20 | *****************************************************************************/ 21 | 22 | #ifndef __padthv1_tuning_h 23 | #define __padthv1_tuning_h 24 | 25 | #include 26 | #include 27 | 28 | //------------------------------------------------------------------------- 29 | // TuningMap 30 | // 31 | // -- borrowed, stirred and refactored from amsynth -- 32 | // https://github.com/amsynth/amsynth 33 | // Copyright (C) 2001-2012 Nick Dowell 34 | // 35 | 36 | /* 37 | * A TuningMap consists of two parts. 38 | * 39 | * The "key map" maps from MIDI note numbers to logical note numbers 40 | * for the scale. This is often the identity mapping, but if your 41 | * scale has, for example, 11 notes in it, you'll want to skip one 42 | * per octave so the scale lines up with the pattern of keys on a 43 | * standard keyboard. 44 | * 45 | * The "scale" maps from those logical note numbers to actual pitches. 46 | * In terms of member variables, "scale" and "scaleDesc" belong to the 47 | * scale, and everything else belongs to the mapping. 48 | * 49 | * For more information, refer to http://www.huygens-fokker.org/scala/ 50 | */ 51 | 52 | class padthv1_tuning 53 | { 54 | public: 55 | 56 | // Default reference note and pitch (A4 @440hz) 57 | padthv1_tuning(float refPitch = 440.0f, int refNote = 69); 58 | 59 | // Default 12-tone equal temperament, wstern standard mapping 60 | void reset(float refPitch, int refNote); 61 | 62 | // Reference note and pitch accessors. 63 | float refPitch() const { return m_refPitch; } 64 | int refNote() const { return m_refNote; } 65 | 66 | // Load custom Scala key map file (.kbm) 67 | bool loadKeyMapFile (const QString& filename); 68 | 69 | // Load custom Scala scale file (.scl) 70 | bool loadScaleFile (const QString& filename); 71 | 72 | const QString& keyMapFile() const { return m_keyMapFile; } 73 | 74 | const QString& scaleFile() const { return m_scaleFile; } 75 | const QString& scaleDesc() const { return m_scaleDesc; } 76 | 77 | // The main pitch/frequency (Hz) getter 78 | float noteToPitch(int note) const; 79 | 80 | protected: 81 | 82 | float parseScaleLine(const QString& line) const; 83 | 84 | void updateBasePitch(); 85 | 86 | private: 87 | 88 | // Instance member variables. 89 | QString m_keyMapFile; 90 | 91 | QString m_scaleFile; 92 | QString m_scaleDesc; 93 | 94 | QVector m_scale; 95 | 96 | float m_refPitch; 97 | int m_refNote; 98 | int m_zeroNote; 99 | int m_mapRepeatInc; 100 | float m_basePitch; 101 | 102 | QVector m_mapping; 103 | }; 104 | 105 | 106 | #endif // __padthv1_tuning_h 107 | 108 | // end of padthv1_tuning.h 109 | -------------------------------------------------------------------------------- /src/padthv1widget_sample.h: -------------------------------------------------------------------------------- 1 | // padthv1widget_sample.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2012-2021, rncbc aka Rui Nuno Capela. All rights reserved. 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | 20 | *****************************************************************************/ 21 | 22 | #ifndef __padthv1widget_sample_h 23 | #define __padthv1widget_sample_h 24 | 25 | #include 26 | 27 | #include 28 | 29 | 30 | // Forward decl. 31 | class padthv1_sample; 32 | 33 | 34 | //---------------------------------------------------------------------------- 35 | // padthv1widget_sample -- Custom widget 36 | 37 | class padthv1widget_sample : public QFrame 38 | { 39 | Q_OBJECT 40 | 41 | public: 42 | 43 | // Constructor. 44 | padthv1widget_sample(QWidget *pParent = nullptr); 45 | 46 | // Destructor. 47 | ~padthv1widget_sample(); 48 | 49 | // Parameter accessors. 50 | void setSample(padthv1_sample *pSample); 51 | padthv1_sample *sample() const; 52 | 53 | signals: 54 | 55 | // Parameter change signals. 56 | void sampleChanged(); 57 | 58 | protected slots: 59 | 60 | // Wavetable reset options. 61 | void resetDefault(); 62 | 63 | void resetNormal(); 64 | void resetNormalOdd(); 65 | void resetNormalEven(); 66 | 67 | void resetSquare(); 68 | void resetSquareOdd(); 69 | void resetSquareEven(); 70 | 71 | void resetSinc(); 72 | 73 | // Randomize all current partials. 74 | void randomize(); 75 | 76 | protected: 77 | 78 | // Widget resize handler. 79 | void resizeEvent(QResizeEvent *); 80 | 81 | // Draw canvas. 82 | void paintEvent(QPaintEvent *); 83 | 84 | // Draggable rectangular point. 85 | int nodeIndex(const QPoint& pos) const; 86 | 87 | void dragSelect(const QPoint& pos); 88 | void dragNode(const QPoint& pos); 89 | 90 | // Mouse interaction. 91 | void mousePressEvent(QMouseEvent *pMouseEvent); 92 | void mouseMoveEvent(QMouseEvent *pMouseEvent); 93 | void mouseReleaseEvent(QMouseEvent *pMouseEvent); 94 | 95 | // Special context-menu. 96 | void contextMenuEvent(QContextMenuEvent *pContextMenuEvent); 97 | 98 | // Harmonic value tool-tip. 99 | void showToolTip(const QPoint& pos, int n); 100 | 101 | // Reset drag/select state. 102 | void resetDragState(); 103 | 104 | // Trap for help/tool-tip events. 105 | bool eventFilter(QObject *pObject, QEvent *pEvent); 106 | 107 | // Default size hint. 108 | QSize sizeHint() const; 109 | 110 | private: 111 | 112 | // Instance state. 113 | padthv1_sample *m_pSample; 114 | 115 | QPolygon *m_pPolyg; 116 | int m_nrects; 117 | QRect *m_pRects; 118 | 119 | // Drag state. 120 | enum DragState { 121 | DragNone = 0, DragStart, DragSelect, DragNode 122 | } m_dragState, m_dragCursor; 123 | 124 | int m_iDragged; 125 | int m_iDragNode; 126 | QPoint m_posDrag; 127 | }; 128 | 129 | #endif // __padthv1widget_sample_h 130 | 131 | 132 | // end of padthv1widget_sample.h 133 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | padthv1 - an old-school polyphonic additive synthesizer 2 | ------------------------------------------------------- 3 | 4 | an old-school polyphonic additive synthesizer with stereo fx. 5 | 6 | based on the PADsynth algorithm, by Paul Nasca, as a special 7 | variant of additive synthesis. 8 | 9 | cf. https://zynaddsubfx.sourceforge.net/doc/PADsynth/PADsynth.htm 10 | 11 | Features: 12 | 13 | - pure stand-alone JACK [1] client with JACK-session, NSM [3] and both 14 | JACK MIDI and ALSA MIDI [2] input support; 15 | 16 | - LV2 [4] instrument plugin. 17 | URI: http://padthv1.sourceforge.net/lv2 18 | 19 | License: 20 | 21 | padthv1 is free, Linux Audio [5] open-source software, distributed under 22 | the terms of the GNU General Public License (GPL) [6] version 2 or later. 23 | 24 | Website: 25 | 26 | https://padthv1.sourceforge.io 27 | http://padthv1.sourceforge.net 28 | 29 | Project page: 30 | 31 | https://sourceforge.net/projects/padthv1 32 | 33 | Git repos: 34 | 35 | https://git.code.sf.net/p/padthv1/code 36 | https://github.com/rncbc/padthv1.git 37 | https://gitlab.com/rncbc/padthv1.git 38 | https://codeberg.org/rncbc/padthv1.git 39 | 40 | Weblog: 41 | 42 | https://www.rncbc.org 43 | 44 | Requirements: 45 | 46 | mandatory, 47 | 48 | - Qt framework [7], C++ class library and tools for 49 | cross-platform application and UI development 50 | https://qt.io/ 51 | 52 | - FFTW3 [9], a C library for computing the discrete 53 | Fourier transform (DFT) in one or more dimensions 54 | http://www.fftw.org 55 | 56 | optional (opted-in at build time), 57 | 58 | - JACK [1] Audio Connection Kit 59 | https://jackaudio.org/ 60 | 61 | - ALSA [2], Advanced Linux Sound Architecture 62 | https://www.alsa-project.org/ 63 | 64 | - LV2 [4], Audio Plugin Standard, the extensible successor of LADSPA 65 | https://lv2plug.in/ 66 | 67 | - liblo [8], Lightweight OSC implementation 68 | (needed for NSM support [3]) 69 | http://liblo.sourceforge.net/ 70 | 71 | Installation: 72 | 73 | - unpack tarball as usual; in the extracted source directory: 74 | 75 | cmake [-DCMAKE_INSTALL_PREFIX=] -B build 76 | cmake --build build [--parallel ] 77 | 78 | - optionally, as root: 79 | 80 | [sudo] cmake --install build 81 | 82 | - note that the default installation path () is /usr/local . 83 | 84 | Acknowledgements: 85 | 86 | drumkv1 logo/icon is an original fine work of Jarle Richard Akselsen. 87 | 88 | References: 89 | 90 | [1] JACK Audio Connection Kit 91 | https://jackaudio.org/ 92 | 93 | [2] ALSA, Advanced Linux Sound Architecture 94 | https://www.alsa-project.org/ 95 | 96 | [3] Non Session Management (NSM) (legacy) 97 | http://non.tuxfamily.org/nsm/ 98 | New Session Manager (NSM) 99 | https://new-session-manager.jackaudio.org/ 100 | 101 | [4] LV2, Audio Plugin Standard, the extensible successor of LADSPA 102 | http://lv2plug.in/ 103 | 104 | [5] Linux Audio consortium of libre software for audio-related work 105 | https://linuxaudio.org 106 | 107 | [6] GNU General Public License 108 | https://www.gnu.org/copyleft/gpl.html 109 | 110 | [7] Qt framework, C++ class library and tools for 111 | cross-platform application and UI development 112 | https://qt.io/ 113 | 114 | [8] liblo [8], Lightweight OSC implementation 115 | (needed for NSM support) 116 | http://liblo.sourceforge.net/ 117 | 118 | [9] FFTW3, a C library for computing the discrete 119 | Fourier transform (DFT) in one or more dimensions 120 | http://www.fftw.org 121 | 122 | 123 | Cheers && Enjoy. 124 | -- 125 | rncbc aka. Rui Nuno Capela 126 | rncbc at rncbc dot org 127 | https://www.rncbc.org 128 | -------------------------------------------------------------------------------- /src/config.h.cmake: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H 2 | #define CONFIG_H 3 | 4 | /* Define to the name of this package. */ 5 | #cmakedefine PROJECT_NAME "@PROJECT_NAME@" 6 | 7 | /* Define to the version of this package. */ 8 | #cmakedefine PROJECT_VERSION "@PROJECT_VERSION@" 9 | 10 | /* Define to the description of this package. */ 11 | #cmakedefine PROJECT_DESCRIPTION "@PROJECT_DESCRIPTION@" 12 | 13 | /* Define to the homepage of this package. */ 14 | #cmakedefine PROJECT_HOMEPAGE_URL "@PROJECT_HOMEPAGE_URL@" 15 | 16 | /* Define to the copyright of this package. */ 17 | #cmakedefine PROJECT_COPYRIGHT "@PROJECT_COPYRIGHT@" 18 | 19 | /* Define to the domain of this package. */ 20 | #cmakedefine PROJECT_DOMAIN "@PROJECT_DOMAIN@" 21 | 22 | 23 | /* Default installation prefix. */ 24 | #cmakedefine CONFIG_PREFIX "@CONFIG_PREFIX@" 25 | 26 | /* Define to target installation dirs. */ 27 | #cmakedefine CONFIG_BINDIR "@CONFIG_BINDIR@" 28 | #cmakedefine CONFIG_LIBDIR "@CONFIG_LIBDIR@" 29 | #cmakedefine CONFIG_DATADIR "@CONFIG_DATADIR@" 30 | #cmakedefine CONFIG_MANDIR "@CONFIG_MANDIR@" 31 | 32 | /* Define if debugging is enabled. */ 33 | #cmakedefine CONFIG_DEBUG @CONFIG_DEBUG@ 34 | 35 | /* Define to 1 if you have the header file. */ 36 | #cmakedefine HAVE_SIGNAL_H @HAVE_SIGNAL_H@ 37 | 38 | /* Define if FFTW3 library is available. */ 39 | #cmakedefine CONFIG_FFTW3 @CONFIG_FFTW3@ 40 | 41 | /* Define if JACK library is available. */ 42 | #cmakedefine CONFIG_JACK @CONFIG_JACK@ 43 | 44 | /* Define if ALSA MIDI support is enabled. */ 45 | #cmakedefine CONFIG_ALSA_MIDI @CONFIG_ALSA_MIDI@ 46 | 47 | /* Define if LIBLO library is available. */ 48 | #cmakedefine CONFIG_LIBLO @CONFIG_LIBLO@ 49 | 50 | /* Define if JACK session support is available. */ 51 | #cmakedefine CONFIG_JACK_SESSION @CONFIG_JACK_SESSION@ 52 | 53 | /* Define if JACK MIDI support is enabled. */ 54 | #cmakedefine CONFIG_JACK_MIDI @CONFIG_JACK_MIDI@ 55 | 56 | /* Define if LV2 plug-in build is enabled. */ 57 | #cmakedefine CONFIG_LV2 @CONFIG_LV2@ 58 | 59 | /* Define if LV2 old headers are enabled. */ 60 | #cmakedefine CONFIG_LV2_OLD_HEADERS @CONFIG_LV2_OLD_HEADERS@ 61 | 62 | /* Define if lv2_atom_forge_object is available. */ 63 | #cmakedefine CONFIG_LV2_ATOM_FORGE_OBJECT @CONFIG_LV2_ATOM_FORGE_OBJECT@ 64 | 65 | /* Define if lv2_atom_forge_key is available. */ 66 | #cmakedefine CONFIG_LV2_ATOM_FORGE_KEY @CONFIG_LV2_ATOM_FORGE_KEY@ 67 | 68 | /* Define if LV2 X11 UI support is available. */ 69 | #cmakedefine CONFIG_LV2_UI_X11 @CONFIG_LV2_UI_X11@ 70 | 71 | /* Define if LV2 Windows UI support is available. */ 72 | #cmakedefine CONFIG_LV2_UI_WINDOWS @CONFIG_LV2_UI_WINDOWS@ 73 | 74 | /* Define if LV2 External UI extension is available. */ 75 | #cmakedefine CONFIG_LV2_UI_EXTERNAL @CONFIG_LV2_UI_EXTERNAL@ 76 | 77 | /* Define if LV2 UI Idle interface support is available. */ 78 | #cmakedefine CONFIG_LV2_UI_IDLE @CONFIG_LV2_UI_IDLE@ 79 | 80 | /* Define if LV2 UI Show interface support is available. */ 81 | #cmakedefine CONFIG_LV2_UI_SHOW @CONFIG_LV2_UI_SHOW@ 82 | 83 | /* Define if LV2 UI Resize interface support is available. */ 84 | #cmakedefine CONFIG_LV2_UI_RESIZE @CONFIG_LV2_UI_RESIZE@ 85 | 86 | /* Define if LV2 Programs extension is available. */ 87 | #cmakedefine CONFIG_LV2_PROGRAMS @CONFIG_LV2_PROGRAMS@ 88 | 89 | /* Define if LV2 Patch is supported. */ 90 | #cmakedefine CONFIG_LV2_PATCH @CONFIG_LV2_PATCH@ 91 | 92 | /* Define if LV2 Port-event is supported. */ 93 | #cmakedefine CONFIG_LV2_PORT_EVENT @CONFIG_LV2_PORT_EVENT@ 94 | 95 | /* Define if LV2 Port-change request is supported. */ 96 | #cmakedefine CONFIG_LV2_PORT_CHANGE_REQUEST @CONFIG_LV2_PORT_CHANGE_REQUEST@ 97 | 98 | /* Define if NSM support is available. */ 99 | #cmakedefine CONFIG_NSM @CONFIG_NSM@ 100 | 101 | 102 | #endif /* CONFIG_H */ 103 | -------------------------------------------------------------------------------- /src/padthv1_config.h: -------------------------------------------------------------------------------- 1 | // padthv1_config.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2012-2024, rncbc aka Rui Nuno Capela. All rights reserved. 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | 20 | *****************************************************************************/ 21 | 22 | #ifndef __padthv1_config_h 23 | #define __padthv1_config_h 24 | 25 | #include "config.h" 26 | 27 | 28 | //------------------------------------------------------------------------- 29 | // padthv1_config - Prototype settings class (singleton). 30 | // 31 | 32 | #include 33 | #include 34 | 35 | // forward decls. 36 | class padthv1_programs; 37 | class padthv1_controls; 38 | 39 | 40 | class padthv1_config : public QSettings 41 | { 42 | public: 43 | 44 | // Constructor. 45 | padthv1_config(); 46 | 47 | // Default destructor. 48 | ~padthv1_config(); 49 | 50 | // Default options... 51 | QString sPreset; 52 | QString sPresetDir; 53 | QString sSampleDir; 54 | 55 | // Knob behavior modes. 56 | int iKnobDialMode; 57 | int iKnobEditMode; 58 | 59 | // Default randomize factor (percent). 60 | float fRandomizePercent; 61 | 62 | // Special persistent options. 63 | bool bControlsEnabled; 64 | bool bProgramsEnabled; 65 | bool bProgramsPreview; 66 | bool bUseNativeDialogs; 67 | // Run-time special non-persistent options. 68 | bool bDontUseNativeDialogs; 69 | 70 | // Custom color palette/widget style themes. 71 | QString sCustomColorTheme; 72 | QString sCustomStyleTheme; 73 | 74 | // Micro-tuning options. 75 | bool bTuningEnabled; 76 | float fTuningRefPitch; 77 | int iTuningRefNote; 78 | QString sTuningScaleDir; 79 | QString sTuningScaleFile; 80 | QString sTuningKeyMapDir; 81 | QString sTuningKeyMapFile; 82 | 83 | // Singleton instance accessor. 84 | static padthv1_config *getInstance(); 85 | 86 | // Preset utility methods. 87 | QString presetFile(const QString& sPreset); 88 | void setPresetFile(const QString& sPreset, const QString& sPresetFile); 89 | void removePreset(const QString& sPreset); 90 | const QStringList& presetList(); 91 | 92 | // Programs utility methods. 93 | void loadPrograms(padthv1_programs *pPrograms); 94 | void savePrograms(padthv1_programs *pPrograms); 95 | 96 | // Controllers utility methods. 97 | void loadControls(padthv1_controls *pControls); 98 | void saveControls(padthv1_controls *pControls); 99 | 100 | protected: 101 | 102 | // Preset group path. 103 | QString presetGroup() const; 104 | 105 | // Banks programs group path. 106 | QString programsGroup() const; 107 | QString bankPrefix() const; 108 | 109 | void clearPrograms(); 110 | 111 | // Controllers group path. 112 | QString controlsGroup() const; 113 | QString controlPrefix() const; 114 | 115 | void clearControls(); 116 | 117 | // Explicit I/O methods. 118 | void load(); 119 | void save(); 120 | 121 | private: 122 | 123 | // The presets list cache. 124 | QStringList m_presetList; 125 | 126 | // The singleton instance. 127 | static padthv1_config *g_pSettings; 128 | }; 129 | 130 | 131 | #endif // __padthv1_config_h 132 | 133 | // end of padthv1_config.h 134 | 135 | -------------------------------------------------------------------------------- /src/padthv1_nsm.h: -------------------------------------------------------------------------------- 1 | // padthv1_nsm.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2012-2023, rncbc aka Rui Nuno Capela. All rights reserved. 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | 20 | *****************************************************************************/ 21 | 22 | #ifndef __padthv1_nsm_h 23 | #define __padthv1_nsm_h 24 | 25 | #include "padthv1_config.h" 26 | 27 | #include 28 | 29 | #ifdef CONFIG_LIBLO 30 | #include 31 | #endif 32 | 33 | 34 | //--------------------------------------------------------------------------- 35 | // padthv1_nsm - NSM OSC client agent. 36 | 37 | class padthv1_nsm : public QObject 38 | { 39 | Q_OBJECT 40 | 41 | public: 42 | 43 | // Constructor. 44 | padthv1_nsm(const QString& nsm_url, QObject *pParent = 0); 45 | 46 | // Destructor. 47 | ~padthv1_nsm(); 48 | 49 | // Session activation accessor. 50 | bool is_active() const; 51 | 52 | // Session manager accessors. 53 | const QString& manager() const; 54 | const QString& capabilities() const; 55 | 56 | // Session client accessors. 57 | const QString& path_name() const; 58 | const QString& display_name() const; 59 | const QString& client_name() const; 60 | 61 | // Session client methods. 62 | void announce(const QString& app_name, const QString& capabilities); 63 | void dirty(bool is_dirty); 64 | void visible(bool is_visible); 65 | void progress(float percent); 66 | void message(int priority, const QString& mesg); 67 | 68 | // Status/error codes 69 | enum ReplyCode 70 | { 71 | ERR_OK = 0, 72 | ERR_GENERAL = -1, 73 | ERR_INCOMPATIBLE_API = -2, 74 | ERR_BLACKLISTED = -3, 75 | ERR_LAUNCH_FAILED = -4, 76 | ERR_NO_SUCH_FILE = -5, 77 | ERR_NO_SESSION_OPEN = -6, 78 | ERR_UNSAVED_CHANGES = -7, 79 | ERR_NOT_NOW = -8, 80 | ERR_BAD_PROJECT = -9, 81 | ERR_CREATE_FAILED = -10 82 | }; 83 | 84 | // Session client reply methods. 85 | void open_reply(ReplyCode reply_code = ERR_OK); 86 | void save_reply(ReplyCode reply_code = ERR_OK); 87 | 88 | // Server methods response methods. 89 | void nsm_announce_error( 90 | const char *mesg); 91 | 92 | void nsm_announce_reply( 93 | const char *mesg, 94 | const char *manager, 95 | const char *capabilities); 96 | 97 | void nsm_open( 98 | const char *path_name, 99 | const char *display_name, 100 | const char *client_name); 101 | 102 | void nsm_save(); 103 | void nsm_loaded(); 104 | void nsm_show(); 105 | void nsm_hide(); 106 | 107 | protected: 108 | 109 | void reply(const QString& path, ReplyCode reply_code); 110 | 111 | signals: 112 | 113 | // Session client callbacks. 114 | void active(bool is_active); 115 | void open(); 116 | void save(); 117 | void loaded(); 118 | void show(); 119 | void hide(); 120 | 121 | private: 122 | 123 | // Instance variables. 124 | #ifdef CONFIG_LIBLO 125 | lo_address m_address; 126 | lo_server_thread m_thread; 127 | lo_server m_server; 128 | #endif 129 | bool m_active; 130 | bool m_dirty; 131 | QString m_manager; 132 | QString m_capabilities; 133 | QString m_path_name; 134 | QString m_display_name; 135 | QString m_client_name; 136 | }; 137 | 138 | 139 | #endif // __padthv1_nsm_h 140 | 141 | // end of padthv1_nsm.h 142 | -------------------------------------------------------------------------------- /src/padthv1widget_control.h: -------------------------------------------------------------------------------- 1 | // padthv1widget_control.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2012-2022, rncbc aka Rui Nuno Capela. All rights reserved. 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | 20 | *****************************************************************************/ 21 | 22 | #ifndef __padthv1widget_control_h 23 | #define __padthv1widget_control_h 24 | 25 | #include "padthv1_controls.h" 26 | #include "padthv1_param.h" 27 | 28 | #include 29 | 30 | 31 | // forward decls. 32 | namespace Ui { class padthv1widget_control; } 33 | 34 | class QAbstractButton; 35 | class QCloseEvent; 36 | 37 | 38 | //---------------------------------------------------------------------------- 39 | // padthv1widget_control -- UI wrapper form. 40 | 41 | class padthv1widget_control : public QDialog 42 | { 43 | Q_OBJECT 44 | 45 | public: 46 | 47 | // Pseudo-singleton instance. 48 | static padthv1widget_control *getInstance(); 49 | 50 | // Pseudo-constructor. 51 | static void showInstance( 52 | padthv1_controls *pControls, padthv1::ParamIndex index, 53 | const QString& sTitle, QWidget *pParent = nullptr); 54 | 55 | // Control accessors. 56 | void setControls(padthv1_controls *pControls, padthv1::ParamIndex index); 57 | padthv1_controls *controls() const; 58 | padthv1::ParamIndex controlIndex() const; 59 | 60 | // Process incoming controller key event. 61 | void setControlKey(const padthv1_controls::Key& key); 62 | padthv1_controls::Key controlKey() const; 63 | 64 | protected slots: 65 | 66 | void changed(); 67 | 68 | void clicked(QAbstractButton *); 69 | void reset(); 70 | 71 | void accept(); 72 | void reject(); 73 | 74 | void activateControlType(int); 75 | void editControlParamFinished(); 76 | 77 | void stabilize(); 78 | 79 | protected: 80 | 81 | // Constructor. 82 | padthv1widget_control(QWidget *pParent = nullptr); 83 | 84 | // Destructor. 85 | ~padthv1widget_control(); 86 | 87 | // Pseudo-destructor. 88 | void cleanup(); 89 | 90 | void closeEvent(QCloseEvent *pCloseEvent); 91 | 92 | // Control type dependency refresh. 93 | void updateControlType(int iControlType); 94 | 95 | void setControlType(padthv1_controls::Type ctype); 96 | padthv1_controls::Type controlType() const; 97 | 98 | void setControlParam(unsigned short param); 99 | unsigned short controlParam() const; 100 | 101 | unsigned short controlChannel() const; 102 | 103 | padthv1_controls::Type controlTypeFromIndex (int iIndex) const; 104 | int indexFromControlType(padthv1_controls::Type ctype) const; 105 | 106 | unsigned short controlParamFromIndex(int iIndex) const; 107 | int indexFromControlParam(unsigned short param) const; 108 | 109 | private: 110 | 111 | // The Qt-designer UI struct... 112 | Ui::padthv1widget_control *p_ui; 113 | Ui::padthv1widget_control& m_ui; 114 | 115 | // Instance variables. 116 | padthv1_controls *m_pControls; 117 | 118 | // Target subject. 119 | padthv1_controls::Key m_key; 120 | padthv1::ParamIndex m_index; 121 | 122 | // Instance variables. 123 | int m_iControlParamUpdate; 124 | 125 | int m_iDirtyCount; 126 | int m_iDirtySetup; 127 | 128 | // Pseudo-singleton instance. 129 | static padthv1widget_control *g_pInstance; 130 | }; 131 | 132 | 133 | #endif // __padthv1widget_control_h 134 | 135 | 136 | // end of padthv1widget_control.h 137 | -------------------------------------------------------------------------------- /src/lv2/lv2_external_ui.h: -------------------------------------------------------------------------------- 1 | /* 2 | LV2 External UI extension 3 | This work is in public domain. 4 | 5 | This file is distributed in the hope that it will be useful, 6 | but WITHOUT ANY WARRANTY; without even the implied warranty of 7 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 8 | 9 | If you have questions, contact Filipe Coelho (aka falkTX) 10 | or ask in #lad channel, FreeNode IRC network. 11 | */ 12 | 13 | /** 14 | @file lv2_external_ui.h 15 | C header for the LV2 External UI extension . 16 | */ 17 | 18 | #ifndef LV2_EXTERNAL_UI_H 19 | #define LV2_EXTERNAL_UI_H 20 | 21 | #ifdef CONFIG_LV2_OLD_HEADERS 22 | #include "lv2/lv2plug.in/ns/extensions/ui/ui.h" 23 | #else 24 | #include "lv2/ui/ui.h" 25 | #endif 26 | 27 | #define LV2_EXTERNAL_UI_URI "http://kxstudio.sf.net/ns/lv2ext/external-ui" 28 | #define LV2_EXTERNAL_UI_PREFIX LV2_EXTERNAL_UI_URI "#" 29 | 30 | #define LV2_EXTERNAL_UI__Host LV2_EXTERNAL_UI_PREFIX "Host" 31 | #define LV2_EXTERNAL_UI__Widget LV2_EXTERNAL_UI_PREFIX "Widget" 32 | 33 | /** This extension used to be defined by a lv2plug.in URI */ 34 | #define LV2_EXTERNAL_UI_DEPRECATED_URI "http://lv2plug.in/ns/extensions/ui#external" 35 | 36 | #ifdef __cplusplus 37 | extern "C" { 38 | #endif 39 | 40 | /** 41 | * When LV2_EXTERNAL_UI__Widget UI is instantiated, the returned 42 | * LV2UI_Widget handle must be cast to pointer to LV2_External_UI_Widget. 43 | * UI is created in invisible state. 44 | */ 45 | typedef struct _LV2_External_UI_Widget { 46 | /** 47 | * Host calls this function regulary. UI library implementing the 48 | * callback may do IPC or redraw the UI. 49 | * 50 | * @param _this_ the UI context 51 | */ 52 | void (*run)(struct _LV2_External_UI_Widget * _this_); 53 | 54 | /** 55 | * Host calls this function to make the plugin UI visible. 56 | * 57 | * @param _this_ the UI context 58 | */ 59 | void (*show)(struct _LV2_External_UI_Widget * _this_); 60 | 61 | /** 62 | * Host calls this function to make the plugin UI invisible again. 63 | * 64 | * @param _this_ the UI context 65 | */ 66 | void (*hide)(struct _LV2_External_UI_Widget * _this_); 67 | 68 | } LV2_External_UI_Widget; 69 | 70 | #define LV2_EXTERNAL_UI_RUN(ptr) (ptr)->run(ptr) 71 | #define LV2_EXTERNAL_UI_SHOW(ptr) (ptr)->show(ptr) 72 | #define LV2_EXTERNAL_UI_HIDE(ptr) (ptr)->hide(ptr) 73 | 74 | /** 75 | * On UI instantiation, host must supply LV2_EXTERNAL_UI__Host feature. 76 | * LV2_Feature::data must be pointer to LV2_External_UI_Host. 77 | */ 78 | typedef struct _LV2_External_UI_Host { 79 | /** 80 | * Callback that plugin UI will call when UI (GUI window) is closed by user. 81 | * This callback will be called during execution of LV2_External_UI_Widget::run() 82 | * (i.e. not from background thread). 83 | * 84 | * After this callback is called, UI is defunct. Host must call LV2UI_Descriptor::cleanup(). 85 | * If host wants to make the UI visible again, the UI must be reinstantiated. 86 | * 87 | * @note When using the depreated URI LV2_EXTERNAL_UI_DEPRECATED_URI, 88 | * some hosts will not call LV2UI_Descriptor::cleanup() as they should, 89 | * and may call show() again without re-initialization. 90 | * 91 | * @param controller Host context associated with plugin UI, as 92 | * supplied to LV2UI_Descriptor::instantiate(). 93 | */ 94 | void (*ui_closed)(LV2UI_Controller controller); 95 | 96 | /** 97 | * Optional (may be NULL) "user friendly" identifier which the UI 98 | * may display to allow a user to easily associate this particular 99 | * UI instance with the correct plugin instance as it is represented 100 | * by the host (e.g. "track 1" or "channel 4"). 101 | * 102 | * If supplied by host, the string will be referenced only during 103 | * LV2UI_Descriptor::instantiate() 104 | */ 105 | const char * plugin_human_id; 106 | 107 | } LV2_External_UI_Host; 108 | 109 | #ifdef __cplusplus 110 | } /* extern "C" */ 111 | #endif 112 | 113 | #endif /* LV2_EXTERNAL_UI_H */ 114 | -------------------------------------------------------------------------------- /src/padthv1widget_config.h: -------------------------------------------------------------------------------- 1 | // padthv1widget_config.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2012-2024, rncbc aka Rui Nuno Capela. All rights reserved. 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | 20 | *****************************************************************************/ 21 | 22 | #ifndef __padthv1widget_config_h 23 | #define __padthv1widget_config_h 24 | 25 | #include "padthv1_config.h" 26 | 27 | #include 28 | 29 | 30 | // forward decls. 31 | namespace Ui { class padthv1widget_config; } 32 | 33 | class padthv1widget; 34 | class padthv1_ui; 35 | 36 | class QComboBox; 37 | class QFileInfo; 38 | 39 | 40 | //---------------------------------------------------------------------------- 41 | // padthv1widget_config -- UI wrapper form. 42 | 43 | class padthv1widget_config : public QDialog 44 | { 45 | Q_OBJECT 46 | 47 | public: 48 | 49 | // ctor. 50 | padthv1widget_config(padthv1widget *pParent, padthv1_ui *pSynthUi); 51 | 52 | // dtor. 53 | ~padthv1widget_config(); 54 | 55 | // UI instance accessors. 56 | padthv1_ui *ui_instance() const; 57 | 58 | protected slots: 59 | 60 | // command slots. 61 | void editCustomColorThemes(); 62 | 63 | void controlsAddItem(); 64 | void controlsEditItem(); 65 | void controlsDeleteItem(); 66 | 67 | void programsAddBankItem(); 68 | void programsAddItem(); 69 | void programsEditItem(); 70 | void programsDeleteItem(); 71 | 72 | // janitorial slots. 73 | void controlsCurrentChanged(); 74 | void controlsContextMenuRequested(const QPoint&); 75 | 76 | void programsCurrentChanged(); 77 | void programsActivated(); 78 | void programsContextMenuRequested(const QPoint&); 79 | 80 | void controlsEnabled(bool); 81 | void programsEnabled(bool); 82 | 83 | void tuningTabChanged(int); 84 | void tuningRefNoteClicked(); 85 | void tuningScaleFileClicked(); 86 | void tuningKeyMapFileClicked(); 87 | 88 | void tuningChanged(); 89 | void controlsChanged(); 90 | void programsChanged(); 91 | void optionsChanged(); 92 | 93 | // dialog slots. 94 | void accept(); 95 | void reject(); 96 | 97 | protected: 98 | 99 | // Custom color/style themes settlers. 100 | void resetCustomColorThemes(const QString& sCustomColorTheme); 101 | void resetCustomStyleThemes(const QString& sCustomColorTheme); 102 | 103 | // Combo box history persistence helper prototypes. 104 | void loadComboBoxHistory(QComboBox *pComboBox); 105 | void saveComboBoxHistory(QComboBox *pComboBox); 106 | 107 | // Combo box settter/gettter helper prototypes. 108 | bool setComboBoxCurrentItem(QComboBox *pComboBox, const QFileInfo& info); 109 | QString comboBoxCurrentItem(QComboBox *pComboBox); 110 | 111 | // Programs/preset preview stuff... 112 | void loadPreset(const QString& sPreset); 113 | 114 | // stabilizer. 115 | void stabilize(); 116 | 117 | private: 118 | 119 | // UI struct. 120 | Ui::padthv1widget_config *p_ui; 121 | Ui::padthv1widget_config& m_ui; 122 | 123 | // Instance reference. 124 | padthv1_ui *m_pSynthUi; 125 | 126 | // Dialog dirty flag. 127 | int m_iDirtyTuning; 128 | int m_iDirtyControls; 129 | int m_iDirtyPrograms; 130 | int m_iDirtyOptions; 131 | 132 | // Programs/preset related stuff... 133 | bool m_bPresets; 134 | 135 | int m_iLoadPreset; 136 | QString m_sSavePreset; 137 | }; 138 | 139 | 140 | #endif // __padthv1widget_config_h 141 | 142 | // end of padthv1widget_config.h 143 | -------------------------------------------------------------------------------- /src/padthv1widget_status.cpp: -------------------------------------------------------------------------------- 1 | // padthv1widget_status.cpp 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2012-2020, rncbc aka Rui Nuno Capela. All rights reserved. 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | 20 | *****************************************************************************/ 21 | 22 | #include "padthv1widget_status.h" 23 | 24 | #include "padthv1widget_keybd.h" 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #if QT_VERSION < QT_VERSION_CHECK(5, 11, 0) 32 | #define horizontalAdvance width 33 | #endif 34 | 35 | 36 | //------------------------------------------------------------------------- 37 | // padthv1widget_status - Custom status-bar widget. 38 | // 39 | 40 | // Constructor. 41 | padthv1widget_status::padthv1widget_status ( QWidget *pParent ) 42 | : QStatusBar (pParent) 43 | { 44 | QIcon icon; 45 | 46 | icon.addPixmap( 47 | QPixmap(":/images/ledOff.png"), QIcon::Normal, QIcon::Off); 48 | icon.addPixmap( 49 | QPixmap(":/images/ledOn.png"), QIcon::Normal, QIcon::On); 50 | 51 | m_midiInLed[0] = new QPixmap( 52 | icon.pixmap(16, 16, QIcon::Normal, QIcon::Off)); 53 | m_midiInLed[1] = new QPixmap( 54 | icon.pixmap(16, 16, QIcon::Normal, QIcon::On)); 55 | 56 | const QString sMidiIn(tr("MIDI In")); 57 | 58 | QWidget *pMidiInWidget = new QWidget(); 59 | pMidiInWidget->setToolTip(tr("%1 status").arg(sMidiIn)); 60 | 61 | QHBoxLayout *pMidiInLayout = new QHBoxLayout(); 62 | pMidiInLayout->setContentsMargins(0, 0, 0, 0); 63 | pMidiInLayout->setSpacing(0); 64 | 65 | m_pMidiInLedLabel = new QLabel(); 66 | m_pMidiInLedLabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); 67 | m_pMidiInLedLabel->setPixmap(*m_midiInLed[0]); 68 | m_pMidiInLedLabel->setFrameStyle(QFrame::NoFrame | QFrame::Plain); 69 | m_pMidiInLedLabel->setAutoFillBackground(true); 70 | pMidiInLayout->addWidget(m_pMidiInLedLabel); 71 | 72 | QLabel *pMidiInTextLabel = new QLabel(sMidiIn); 73 | pMidiInTextLabel->setMargin(2); 74 | pMidiInTextLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); 75 | pMidiInTextLabel->setFrameStyle(QFrame::NoFrame | QFrame::Plain); 76 | pMidiInTextLabel->setAutoFillBackground(true); 77 | pMidiInLayout->addWidget(pMidiInTextLabel); 78 | 79 | pMidiInWidget->setLayout(pMidiInLayout); 80 | QStatusBar::addWidget(pMidiInWidget); 81 | 82 | m_pKeybd = new padthv1widget_keybd(); 83 | m_pKeybd->setMinimumWidth(760); 84 | QStatusBar::addPermanentWidget(m_pKeybd); 85 | 86 | const QFontMetrics fm(QStatusBar::font()); 87 | m_pModifiedLabel = new QLabel(); 88 | m_pModifiedLabel->setAlignment(Qt::AlignHCenter); 89 | m_pModifiedLabel->setMinimumSize(QSize(fm.horizontalAdvance("MOD") + 4, fm.height())); 90 | m_pModifiedLabel->setToolTip(tr("Modification status")); 91 | m_pModifiedLabel->setAutoFillBackground(true); 92 | QStatusBar::addPermanentWidget(m_pModifiedLabel); 93 | } 94 | 95 | 96 | // Destructor. 97 | padthv1widget_status::~padthv1widget_status (void) 98 | { 99 | delete m_midiInLed[1]; 100 | delete m_midiInLed[0]; 101 | } 102 | 103 | 104 | // Permanent widgets accessors. 105 | padthv1widget_keybd *padthv1widget_status::keybd (void) const 106 | { 107 | return m_pKeybd; 108 | } 109 | 110 | 111 | void padthv1widget_status::midiInLed ( bool bMidiInLed ) 112 | { 113 | m_pMidiInLedLabel->setPixmap(*m_midiInLed[bMidiInLed ? 1 : 0]); 114 | } 115 | 116 | 117 | void padthv1widget_status::midiInNote ( int iNote, int iVelocity ) 118 | { 119 | if (iVelocity > 0) 120 | m_pKeybd->noteOn(iNote); 121 | else 122 | m_pKeybd->noteOff(iNote); 123 | } 124 | 125 | 126 | void padthv1widget_status::modified ( bool bModified ) 127 | { 128 | if (bModified) 129 | m_pModifiedLabel->setText(tr("MOD")); 130 | else 131 | m_pModifiedLabel->clear(); 132 | } 133 | 134 | 135 | // end of padthv1widget_status.cpp 136 | -------------------------------------------------------------------------------- /src/padthv1_programs.h: -------------------------------------------------------------------------------- 1 | // padthv1_programs.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2012-2024, rncbc aka Rui Nuno Capela. All rights reserved. 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | 20 | *****************************************************************************/ 21 | 22 | #ifndef __padthv1_programs_h 23 | #define __padthv1_programs_h 24 | 25 | #include "padthv1_sched.h" 26 | #include "padthv1_param.h" 27 | 28 | #include 29 | 30 | 31 | //------------------------------------------------------------------------- 32 | // padthv1_programs - Bank/programs database class. 33 | // 34 | 35 | class padthv1_programs 36 | { 37 | public: 38 | 39 | // ctor. 40 | padthv1_programs(padthv1 *pPadth); 41 | 42 | // dtor. 43 | ~padthv1_programs(); 44 | 45 | // operational mode flags. 46 | void enabled(bool on) 47 | { m_enabled = on; } 48 | bool enabled() const 49 | { return m_enabled; } 50 | 51 | // prog. base node 52 | class Prog 53 | { 54 | public: 55 | 56 | Prog(uint16_t id, const QString& name) 57 | : m_id(id), m_name(name) {} 58 | 59 | uint16_t id() const { return m_id; } 60 | const QString& name() const { return m_name; } 61 | void set_name(const QString& name) { m_name = name; } 62 | 63 | private: 64 | 65 | uint16_t m_id; 66 | QString m_name; 67 | }; 68 | 69 | typedef QMap Progs; 70 | 71 | // bank node 72 | class Bank : public Prog 73 | { 74 | public: 75 | 76 | Bank(uint16_t id, const QString& name) 77 | : Prog(id, name) {} 78 | 79 | ~Bank() { clear_progs(); } 80 | 81 | const Progs& progs() const { return m_progs; } 82 | 83 | // prog. managers 84 | Prog *find_prog(uint16_t prog_id) const; 85 | Prog *add_prog(uint16_t prog_id, const QString& prog_name); 86 | void remove_prog(uint16_t prog_id); 87 | void clear_progs(); 88 | 89 | private: 90 | 91 | Progs m_progs; 92 | }; 93 | 94 | typedef QMap Banks; 95 | 96 | const Banks& banks() const { return m_banks; } 97 | 98 | // bank managers 99 | Bank *find_bank(uint16_t bank_id) const; 100 | Bank *add_bank(uint16_t bank_id, const QString& bank_name); 101 | void remove_bank(uint16_t bank_id); 102 | 103 | void clear_banks(); 104 | 105 | // current bank/prog. managers 106 | void bank_select_msb(uint8_t bank_msb); 107 | void bank_select_lsb(uint8_t bank_lsb); 108 | 109 | void bank_select(uint16_t bank_id); 110 | void prog_change(uint16_t prog_id); 111 | 112 | void select_program(uint16_t bank_id, uint16_t prog_id); 113 | 114 | void process_program(padthv1 *pPadth, uint16_t bank_id, uint16_t prog_id); 115 | 116 | Bank *current_bank() const { return m_bank; } 117 | Prog *current_prog() const { return m_prog; } 118 | 119 | protected: 120 | 121 | uint16_t current_bank_id() const; 122 | 123 | // current bank/prog. scheduled thread 124 | class Sched : public padthv1_sched 125 | { 126 | public: 127 | 128 | // ctor. 129 | Sched (padthv1 *pPadth) 130 | : padthv1_sched(pPadth, Programs), m_bank_id(0), m_prog_id(0) {} 131 | 132 | // schedule (override) 133 | void select_program(uint16_t bank_id, uint16_t prog_id) 134 | { 135 | if (m_bank_id != bank_id || 136 | m_prog_id != prog_id) { 137 | m_bank_id = bank_id; 138 | m_prog_id = prog_id; 139 | schedule(); 140 | } 141 | } 142 | 143 | // process (virtual). 144 | void process(int) 145 | { 146 | padthv1 *pPadth = instance(); 147 | padthv1_programs *pPrograms = pPadth->programs(); 148 | pPrograms->process_program(pPadth, m_bank_id, m_prog_id); 149 | } 150 | 151 | private: 152 | 153 | // instance variables. 154 | uint16_t m_bank_id; 155 | uint16_t m_prog_id; 156 | }; 157 | 158 | private: 159 | 160 | // instance variables. 161 | bool m_enabled; 162 | 163 | Sched m_sched; 164 | 165 | uint8_t m_bank_msb; 166 | uint8_t m_bank_lsb; 167 | 168 | Bank *m_bank; 169 | Prog *m_prog; 170 | 171 | Banks m_banks; 172 | }; 173 | 174 | 175 | #endif // __padthv1_programs_h 176 | 177 | // end of padthv1_programs.h 178 | -------------------------------------------------------------------------------- /src/padthv1_programs.cpp: -------------------------------------------------------------------------------- 1 | // padthv1_programs.cpp 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2012-2024, rncbc aka Rui Nuno Capela. All rights reserved. 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | 20 | *****************************************************************************/ 21 | 22 | #include "padthv1_programs.h" 23 | 24 | 25 | //------------------------------------------------------------------------- 26 | // padthv1_programs - Bank/programs database class (singleton). 27 | // 28 | 29 | // ctor. 30 | padthv1_programs::padthv1_programs ( padthv1 *pPadth ) 31 | : m_enabled(false), m_sched(pPadth), 32 | m_bank_msb(0), m_bank_lsb(0), 33 | m_bank(nullptr), m_prog(nullptr) 34 | { 35 | } 36 | 37 | 38 | // dtor. 39 | padthv1_programs::~padthv1_programs (void) 40 | { 41 | clear_banks(); 42 | } 43 | 44 | 45 | // prog. managers 46 | padthv1_programs::Prog *padthv1_programs::Bank::find_prog ( uint16_t prog_id ) const 47 | { 48 | return m_progs.value(prog_id, nullptr); 49 | } 50 | 51 | 52 | padthv1_programs::Prog *padthv1_programs::Bank::add_prog ( 53 | uint16_t prog_id, const QString& prog_name ) 54 | { 55 | Prog *prog = find_prog(prog_id); 56 | if (prog) { 57 | prog->set_name(prog_name); 58 | } else { 59 | prog = new Prog(prog_id, prog_name); 60 | m_progs.insert(prog_id, prog); 61 | } 62 | return prog; 63 | } 64 | 65 | 66 | void padthv1_programs::Bank::remove_prog ( uint16_t prog_id ) 67 | { 68 | Prog *prog = find_prog(prog_id); 69 | if (prog && m_progs.remove(prog_id)) 70 | delete prog; 71 | } 72 | 73 | 74 | void padthv1_programs::Bank::clear_progs (void) 75 | { 76 | qDeleteAll(m_progs); 77 | m_progs.clear(); 78 | } 79 | 80 | 81 | // bank managers 82 | padthv1_programs::Bank *padthv1_programs::find_bank ( uint16_t bank_id ) const 83 | { 84 | return m_banks.value(bank_id, nullptr); 85 | } 86 | 87 | 88 | padthv1_programs::Bank *padthv1_programs::add_bank ( 89 | uint16_t bank_id, const QString& bank_name ) 90 | { 91 | Bank *bank = find_bank(bank_id); 92 | if (bank) { 93 | bank->set_name(bank_name); 94 | } else { 95 | bank = new Bank(bank_id, bank_name); 96 | m_banks.insert(bank_id, bank); 97 | } 98 | return bank; 99 | } 100 | 101 | 102 | void padthv1_programs::remove_bank ( uint16_t bank_id ) 103 | { 104 | Bank *bank = find_bank(bank_id); 105 | if (bank && m_banks.remove(bank_id)) 106 | delete bank; 107 | } 108 | 109 | 110 | void padthv1_programs::clear_banks (void) 111 | { 112 | m_bank_msb = 0; 113 | m_bank_lsb = 0; 114 | 115 | m_bank = nullptr; 116 | m_prog = nullptr; 117 | 118 | qDeleteAll(m_banks); 119 | m_banks.clear(); 120 | } 121 | 122 | 123 | // current bank/prog. managers 124 | void padthv1_programs::bank_select_msb ( uint8_t bank_msb ) 125 | { 126 | m_bank_msb = 0x80 | (bank_msb & 0x7f); 127 | } 128 | 129 | 130 | void padthv1_programs::bank_select_lsb ( uint8_t bank_lsb ) 131 | { 132 | m_bank_lsb = 0x80 | (bank_lsb & 0x7f); 133 | } 134 | 135 | 136 | void padthv1_programs::bank_select ( uint16_t bank_id ) 137 | { 138 | bank_select_msb(bank_id >> 7); 139 | bank_select_lsb(bank_id); 140 | } 141 | 142 | 143 | uint16_t padthv1_programs::current_bank_id (void) const 144 | { 145 | uint16_t bank_id = 0; 146 | 147 | if (m_bank_msb & 0x80) 148 | bank_id = (m_bank_msb & 0x7f); 149 | if (m_bank_lsb & 0x80) { 150 | bank_id <<= 7; 151 | bank_id |= (m_bank_lsb & 0x7f); 152 | } 153 | 154 | return bank_id; 155 | } 156 | 157 | 158 | void padthv1_programs::prog_change ( uint16_t prog_id ) 159 | { 160 | select_program(current_bank_id(), prog_id); 161 | } 162 | 163 | 164 | void padthv1_programs::select_program ( uint16_t bank_id, uint16_t prog_id ) 165 | { 166 | if (!enabled()) 167 | return; 168 | 169 | if (m_bank && m_bank->id() == bank_id && 170 | m_prog && m_prog->id() == prog_id) 171 | return; 172 | 173 | m_sched.select_program(bank_id, prog_id); 174 | } 175 | 176 | 177 | void padthv1_programs::process_program ( 178 | padthv1 *pPadth, uint16_t bank_id, uint16_t prog_id ) 179 | { 180 | m_bank = find_bank(bank_id); 181 | m_prog = (m_bank ? m_bank->find_prog(prog_id) : nullptr); 182 | 183 | if (m_prog) { 184 | padthv1_param::loadPreset(pPadth, m_prog->name()); 185 | pPadth->updateParams(); 186 | } 187 | } 188 | 189 | 190 | // end of padthv1_programs.cpp 191 | -------------------------------------------------------------------------------- /src/padthv1_jack.h: -------------------------------------------------------------------------------- 1 | // padthv1_jack.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2012-2025, rncbc aka Rui Nuno Capela. All rights reserved. 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | 20 | *****************************************************************************/ 21 | 22 | #ifndef __padthv1_jack_h 23 | #define __padthv1_jack_h 24 | 25 | #include "padthv1.h" 26 | 27 | #include 28 | 29 | 30 | #ifdef CONFIG_ALSA_MIDI 31 | #include 32 | #include 33 | // forward decls. 34 | class padthv1_alsa_thread; 35 | #endif 36 | 37 | 38 | //------------------------------------------------------------------------- 39 | // padthv1_jack - decl. 40 | // 41 | 42 | class padthv1_jack : public padthv1 43 | { 44 | public: 45 | 46 | padthv1_jack(const char *client_name); 47 | 48 | ~padthv1_jack(); 49 | 50 | jack_client_t *client() const; 51 | 52 | void open(const char *client_name); 53 | void close(); 54 | 55 | void activate(); 56 | void deactivate(); 57 | 58 | int process(jack_nframes_t nframes); 59 | 60 | #ifdef CONFIG_ALSA_MIDI 61 | snd_seq_t *alsa_seq() const; 62 | void alsa_capture(snd_seq_event_t *ev); 63 | #endif 64 | 65 | #ifdef CONFIG_JACK_SESSION 66 | // JACK session event handler. 67 | void sessionEvent(void *pvSessionArg); 68 | #endif 69 | 70 | void shutdown(); 71 | void shutdown_close(); 72 | 73 | protected: 74 | 75 | void updatePreset(bool bDirty); 76 | void updateParam(padthv1::ParamIndex index); 77 | void updateParams(); 78 | void updateTuning(); 79 | 80 | private: 81 | 82 | jack_client_t *m_client; 83 | 84 | volatile bool m_activated; 85 | 86 | jack_port_t **m_audio_ins; 87 | jack_port_t **m_audio_outs; 88 | 89 | float **m_ins; 90 | float **m_outs; 91 | 92 | float m_params[padthv1::NUM_PARAMS]; 93 | 94 | #ifdef CONFIG_JACK_MIDI 95 | jack_port_t *m_midi_in; 96 | #endif 97 | #ifdef CONFIG_ALSA_MIDI 98 | snd_seq_t *m_alsa_seq; 99 | // int m_alsa_client; 100 | int m_alsa_port; 101 | snd_midi_event_t *m_alsa_decoder; 102 | jack_ringbuffer_t *m_alsa_buffer; 103 | padthv1_alsa_thread *m_alsa_thread; 104 | #endif 105 | }; 106 | 107 | 108 | //------------------------------------------------------------------------- 109 | // padthv1_jack_application -- Singleton application instance. 110 | // 111 | 112 | #include 113 | #include 114 | 115 | 116 | // forward decls. 117 | class QCoreApplication; 118 | class padthv1widget_jack; 119 | 120 | #ifdef CONFIG_NSM 121 | class padthv1_nsm; 122 | #endif 123 | 124 | #ifdef HAVE_SIGNAL_H 125 | class QSocketNotifier; 126 | #endif 127 | 128 | class padthv1_jack_application : public QObject 129 | { 130 | Q_OBJECT 131 | 132 | public: 133 | 134 | // Constructor. 135 | padthv1_jack_application(int& argc, char **argv); 136 | 137 | // Destructor. 138 | ~padthv1_jack_application(); 139 | 140 | // Facade method. 141 | int exec(); 142 | 143 | // JACK shutdown handler. 144 | void shutdown(); 145 | 146 | // Pseudo-singleton accessor. 147 | static padthv1_jack_application *getInstance(); 148 | 149 | signals: 150 | 151 | void shutdown_signal(); 152 | 153 | protected slots: 154 | 155 | #ifdef CONFIG_NSM 156 | // NSM callback slots. 157 | void openSession(); 158 | void saveSession(); 159 | void hideSession(); 160 | void showSession(); 161 | #endif // CONFIG_NSM 162 | 163 | #ifdef HAVE_SIGNAL_H 164 | // SIGTERM signal handler. 165 | void handle_sigterm(); 166 | #endif 167 | 168 | void watchdog_slot(); 169 | void shutdown_slot(); 170 | 171 | protected: 172 | 173 | // Argument parser method. 174 | bool parse_args(); 175 | #if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0) 176 | void show_error(const QString& msg); 177 | #endif 178 | 179 | // Startup method. 180 | bool setup(); 181 | 182 | void watchdog_start(); 183 | 184 | private: 185 | 186 | // Instance variables. 187 | QCoreApplication *m_pApp; 188 | bool m_bGui; 189 | 190 | QString m_sClientName; 191 | QStringList m_presets; 192 | 193 | padthv1_jack *m_pPadth; 194 | padthv1widget_jack *m_pWidget; 195 | 196 | #ifdef CONFIG_NSM 197 | padthv1_nsm *m_pNsmClient; 198 | #endif 199 | 200 | #ifdef HAVE_SIGNAL_H 201 | QSocketNotifier *m_pSigtermNotifier; 202 | #endif 203 | 204 | static padthv1_jack_application *g_pInstance; 205 | }; 206 | 207 | 208 | #endif// __padthv1_jack_h 209 | 210 | // end of padthv1_jack.h 211 | 212 | -------------------------------------------------------------------------------- /src/padthv1_ui.cpp: -------------------------------------------------------------------------------- 1 | // padthv1_ui.cpp 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2012-2025, rncbc aka Rui Nuno Capela. All rights reserved. 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | 20 | *****************************************************************************/ 21 | 22 | #include "padthv1_ui.h" 23 | 24 | #include "padthv1_param.h" 25 | 26 | 27 | //------------------------------------------------------------------------- 28 | // padthv1_ui - decl. 29 | // 30 | 31 | padthv1_ui::padthv1_ui ( padthv1 *pPadth, bool bPlugin ) 32 | : m_pPadth(pPadth), m_bPlugin(bPlugin) 33 | { 34 | } 35 | 36 | 37 | padthv1 *padthv1_ui::instance (void) const 38 | { 39 | return m_pPadth; 40 | } 41 | 42 | 43 | bool padthv1_ui::isPlugin (void) const 44 | { 45 | return m_bPlugin; 46 | } 47 | 48 | 49 | padthv1_sample *padthv1_ui::sample ( int sid ) const 50 | { 51 | return m_pPadth->sample(sid); 52 | } 53 | 54 | 55 | bool padthv1_ui::newPreset (void) 56 | { 57 | return padthv1_param::newPreset(m_pPadth); 58 | } 59 | 60 | 61 | bool padthv1_ui::loadPreset ( const QString& sFilename ) 62 | { 63 | return padthv1_param::loadPreset(m_pPadth, sFilename); 64 | } 65 | 66 | bool padthv1_ui::savePreset ( const QString& sFilename ) 67 | { 68 | return padthv1_param::savePreset(m_pPadth, sFilename); 69 | } 70 | 71 | 72 | void padthv1_ui::setParamValue ( padthv1::ParamIndex index, float fValue ) 73 | { 74 | m_pPadth->setParamValue(index, fValue); 75 | } 76 | 77 | 78 | float padthv1_ui::paramValue ( padthv1::ParamIndex index ) const 79 | { 80 | return m_pPadth->paramValue(index); 81 | } 82 | 83 | 84 | padthv1_controls *padthv1_ui::controls (void) const 85 | { 86 | return m_pPadth->controls(); 87 | } 88 | 89 | 90 | padthv1_programs *padthv1_ui::programs (void) const 91 | { 92 | return m_pPadth->programs(); 93 | } 94 | 95 | 96 | void padthv1_ui::reset (void) 97 | { 98 | return m_pPadth->reset(); 99 | } 100 | 101 | 102 | void padthv1_ui::updatePreset ( bool bDirty ) 103 | { 104 | m_pPadth->updatePreset(bDirty); 105 | } 106 | 107 | 108 | void padthv1_ui::updateParam ( padthv1::ParamIndex index ) 109 | { 110 | m_pPadth->updateParam(index); 111 | } 112 | 113 | 114 | void padthv1_ui::midiInEnabled ( bool bEnabled ) 115 | { 116 | m_pPadth->midiInEnabled(bEnabled); 117 | } 118 | 119 | 120 | uint32_t padthv1_ui::midiInCount (void) 121 | { 122 | return m_pPadth->midiInCount(); 123 | } 124 | 125 | 126 | void padthv1_ui::directNoteOn ( int note, int vel ) 127 | { 128 | m_pPadth->directNoteOn(note, vel); 129 | } 130 | 131 | 132 | void padthv1_ui::setTuningEnabled ( bool enabled ) 133 | { 134 | m_pPadth->setTuningEnabled(enabled); 135 | } 136 | 137 | bool padthv1_ui::isTuningEnabled (void) const 138 | { 139 | return m_pPadth->isTuningEnabled(); 140 | } 141 | 142 | 143 | void padthv1_ui::setTuningRefPitch ( float refPitch ) 144 | { 145 | m_pPadth->setTuningRefPitch(refPitch); 146 | } 147 | 148 | float padthv1_ui::tuningRefPitch (void) const 149 | { 150 | return m_pPadth->tuningRefPitch(); 151 | } 152 | 153 | 154 | void padthv1_ui::setTuningRefNote ( int refNote ) 155 | { 156 | m_pPadth->setTuningRefNote(refNote); 157 | } 158 | 159 | int padthv1_ui::tuningRefNote (void) const 160 | { 161 | return m_pPadth->tuningRefNote(); 162 | } 163 | 164 | 165 | void padthv1_ui::setTuningScaleFile ( const char *pszScaleFile ) 166 | { 167 | m_pPadth->setTuningScaleFile(pszScaleFile); 168 | } 169 | 170 | const char *padthv1_ui::tuningScaleFile (void) const 171 | { 172 | return m_pPadth->tuningScaleFile(); 173 | } 174 | 175 | 176 | void padthv1_ui::setTuningKeyMapFile ( const char *pszKeyMapFile ) 177 | { 178 | m_pPadth->setTuningKeyMapFile(pszKeyMapFile); 179 | } 180 | 181 | const char *padthv1_ui::tuningKeyMapFile (void) const 182 | { 183 | return m_pPadth->tuningKeyMapFile(); 184 | } 185 | 186 | 187 | void padthv1_ui::resetTuning (void) 188 | { 189 | m_pPadth->resetTuning(); 190 | } 191 | 192 | 193 | // MIDI note/octave name helper (static). 194 | QString padthv1_ui::noteName ( int note ) 195 | { 196 | static const char *s_notes[] = 197 | { 198 | QT_TR_NOOP("C"), 199 | QT_TR_NOOP("C#/Db"), 200 | QT_TR_NOOP("D"), 201 | QT_TR_NOOP("D#/Eb"), 202 | QT_TR_NOOP("E"), 203 | QT_TR_NOOP("F"), 204 | QT_TR_NOOP("F#/Gb"), 205 | QT_TR_NOOP("G"), 206 | QT_TR_NOOP("G#/Ab"), 207 | QT_TR_NOOP("A"), 208 | QT_TR_NOOP("A#/Bb"), 209 | QT_TR_NOOP("B") 210 | }; 211 | 212 | return QString("%1 %2").arg(s_notes[note % 12]).arg((note / 12) - 1); 213 | } 214 | 215 | 216 | // end of padthv1_ui.cpp 217 | -------------------------------------------------------------------------------- /src/padthv1_lv2.h: -------------------------------------------------------------------------------- 1 | // padthv1_lv2.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2012-2025, rncbc aka Rui Nuno Capela. All rights reserved. 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | 20 | *****************************************************************************/ 21 | 22 | #ifndef __padthv1_lv2_h 23 | #define __padthv1_lv2_h 24 | 25 | #include "padthv1.h" 26 | 27 | #ifdef CONFIG_LV2_OLD_HEADERS 28 | #include "lv2/lv2plug.in/ns/ext/urid/urid.h" 29 | #include "lv2/lv2plug.in/ns/ext/atom/atom.h" 30 | #include "lv2/lv2plug.in/ns/ext/atom/forge.h" 31 | #include "lv2/lv2plug.in/ns/ext/worker/worker.h" 32 | #else 33 | #include "lv2/urid/urid.h" 34 | #include "lv2/atom/atom.h" 35 | #include "lv2/atom/forge.h" 36 | #include "lv2/worker/worker.h" 37 | #endif 38 | 39 | 40 | #define PADTHV1_LV2_URI "http://padthv1.sourceforge.net/lv2" 41 | #define PADTHV1_LV2_PREFIX PADTHV1_LV2_URI "#" 42 | 43 | 44 | #ifdef CONFIG_LV2_PROGRAMS 45 | #include "lv2_programs.h" 46 | #include 47 | #endif 48 | 49 | #ifdef CONFIG_LV2_PORT_CHANGE_REQUEST 50 | #include "lv2_port_change_request.h" 51 | #endif 52 | 53 | // Forward decls. 54 | class QApplication; 55 | 56 | 57 | //------------------------------------------------------------------------- 58 | // padthv1_lv2 - decl. 59 | // 60 | 61 | class padthv1_lv2 : public padthv1 62 | { 63 | public: 64 | 65 | padthv1_lv2(double sample_rate, const LV2_Feature *const *host_features); 66 | 67 | ~padthv1_lv2(); 68 | 69 | enum PortIndex { 70 | 71 | MidiIn = 0, 72 | Notify, 73 | AudioInL, 74 | AudioInR, 75 | AudioOutL, 76 | AudioOutR, 77 | ParamBase 78 | }; 79 | 80 | void connect_port(uint32_t port, void *data); 81 | 82 | void run(uint32_t nframes); 83 | 84 | void activate(); 85 | void deactivate(); 86 | 87 | uint32_t urid_map(const char *uri) const; 88 | 89 | #ifdef CONFIG_LV2_PROGRAMS 90 | const LV2_Program_Descriptor *get_program(uint32_t index); 91 | void select_program(uint32_t bank, uint32_t program); 92 | #endif 93 | 94 | bool worker_work(const void *data, uint32_t size); 95 | bool worker_response(const void *data, uint32_t size); 96 | 97 | static void qapp_instantiate(); 98 | static void qapp_cleanup(); 99 | 100 | static QApplication *qapp_instance(); 101 | 102 | protected: 103 | 104 | void updatePreset(bool bDirty); 105 | void updateParam(padthv1::ParamIndex index); 106 | void updateParams(); 107 | void updateTuning(); 108 | 109 | bool state_changed(); 110 | 111 | #ifdef CONFIG_LV2_PATCH 112 | bool patch_set(LV2_URID key); 113 | bool patch_get(LV2_URID key); 114 | #endif 115 | 116 | #ifdef CONFIG_LV2_PORT_EVENT 117 | bool port_event(padthv1::ParamIndex index); 118 | bool port_events(); 119 | #endif 120 | 121 | #ifdef CONFIG_LV2_PORT_CHANGE_REQUEST 122 | bool port_change_request(padthv1::ParamIndex index); 123 | bool port_change_requests(); 124 | #endif 125 | 126 | private: 127 | 128 | LV2_URID_Map *m_urid_map; 129 | 130 | struct lv2_urids 131 | { 132 | LV2_URID p201_tuning_enabled; 133 | LV2_URID p202_tuning_refPitch; 134 | LV2_URID p203_tuning_refNote; 135 | LV2_URID p204_tuning_scaleFile; 136 | LV2_URID p205_tuning_keyMapFile; 137 | LV2_URID tun1_update; 138 | LV2_URID atom_Blank; 139 | LV2_URID atom_Object; 140 | LV2_URID atom_Float; 141 | LV2_URID atom_Int; 142 | LV2_URID atom_Bool; 143 | LV2_URID atom_Path; 144 | #ifdef CONFIG_LV2_PORT_EVENT 145 | LV2_URID atom_PortEvent; 146 | LV2_URID atom_portTuple; 147 | #endif 148 | LV2_URID time_Position; 149 | LV2_URID time_beatsPerMinute; 150 | LV2_URID midi_MidiEvent; 151 | LV2_URID bufsz_minBlockLength; 152 | LV2_URID bufsz_maxBlockLength; 153 | LV2_URID bufsz_nominalBlockLength; 154 | LV2_URID state_StateChanged; 155 | #ifdef CONFIG_LV2_PATCH 156 | LV2_URID patch_Get; 157 | LV2_URID patch_Set; 158 | LV2_URID patch_property; 159 | LV2_URID patch_value; 160 | #endif 161 | } m_urids; 162 | 163 | LV2_Atom_Forge m_forge; 164 | LV2_Atom_Forge_Frame m_notify_frame; 165 | 166 | LV2_Worker_Schedule *m_schedule; 167 | 168 | uint32_t m_ndelta; 169 | 170 | LV2_Atom_Sequence *m_atom_in; 171 | LV2_Atom_Sequence *m_atom_out; 172 | 173 | float **m_ins; 174 | float **m_outs; 175 | 176 | #ifdef CONFIG_LV2_PROGRAMS 177 | LV2_Program_Descriptor m_program; 178 | QByteArray m_aProgramName; 179 | #endif 180 | 181 | #ifdef CONFIG_LV2_PORT_CHANGE_REQUEST 182 | LV2_ControlInputPort_Change_Request *m_port_change_request; 183 | #endif 184 | 185 | static QApplication *g_qapp_instance; 186 | static unsigned int g_qapp_refcount; 187 | }; 188 | 189 | 190 | #endif// __padthv1_lv2_h 191 | 192 | // end of padthv1_lv2.h 193 | 194 | -------------------------------------------------------------------------------- /src/padthv1.h: -------------------------------------------------------------------------------- 1 | // padthv1.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2012-2024, rncbc aka Rui Nuno Capela. All rights reserved. 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | 20 | *****************************************************************************/ 21 | 22 | #ifndef __padthv1_h 23 | #define __padthv1_h 24 | 25 | #include "config.h" 26 | 27 | #include 28 | 29 | 30 | // forward declarations 31 | class padthv1_impl; 32 | class padthv1_port; 33 | class padthv1_sample; 34 | class padthv1_controls; 35 | class padthv1_programs; 36 | 37 | 38 | //------------------------------------------------------------------------- 39 | // padthv1 - decl. 40 | // 41 | 42 | class padthv1 43 | { 44 | public: 45 | 46 | padthv1(uint16_t nchannels = 2, float srate = 44100.0f, uint32_t nsize = 1024); 47 | 48 | virtual ~padthv1(); 49 | 50 | void setChannels(uint16_t nchannels); 51 | uint16_t channels() const; 52 | 53 | void setSampleRate(float srate); 54 | float sampleRate() const; 55 | 56 | padthv1_sample *sample(int sid) const; 57 | 58 | void setBufferSize(uint32_t nsize); 59 | uint32_t bufferSize() const; 60 | 61 | void setTempo(float bpm); 62 | float tempo() const; 63 | 64 | enum ParamIndex { 65 | 66 | GEN1_SAMPLE1 = 0, 67 | GEN1_WIDTH1, 68 | GEN1_SCALE1, 69 | GEN1_NH1, 70 | GEN1_APOD1, 71 | GEN1_DETUNE1, 72 | GEN1_GLIDE1, 73 | GEN1_SAMPLE2, 74 | GEN1_WIDTH2, 75 | GEN1_SCALE2, 76 | GEN1_NH2, 77 | GEN1_APOD2, 78 | GEN1_DETUNE2, 79 | GEN1_GLIDE2, 80 | GEN1_BALANCE, 81 | GEN1_PHASE, 82 | GEN1_RINGMOD, 83 | GEN1_OCTAVE, 84 | GEN1_TUNING, 85 | GEN1_ENVTIME, 86 | DCF1_ENABLED, 87 | DCF1_CUTOFF, 88 | DCF1_RESO, 89 | DCF1_TYPE, 90 | DCF1_SLOPE, 91 | DCF1_ENVELOPE, 92 | DCF1_ATTACK, 93 | DCF1_DECAY, 94 | DCF1_SUSTAIN, 95 | DCF1_RELEASE, 96 | LFO1_ENABLED, 97 | LFO1_SHAPE, 98 | LFO1_WIDTH, 99 | LFO1_BPM, 100 | LFO1_RATE, 101 | LFO1_SYNC, 102 | LFO1_SWEEP, 103 | LFO1_PITCH, 104 | LFO1_BALANCE, 105 | LFO1_RINGMOD, 106 | LFO1_CUTOFF, 107 | LFO1_RESO, 108 | LFO1_PANNING, 109 | LFO1_VOLUME, 110 | LFO1_ATTACK, 111 | LFO1_DECAY, 112 | LFO1_SUSTAIN, 113 | LFO1_RELEASE, 114 | DCA1_VOLUME, 115 | DCA1_ATTACK, 116 | DCA1_DECAY, 117 | DCA1_SUSTAIN, 118 | DCA1_RELEASE, 119 | OUT1_WIDTH, 120 | OUT1_PANNING, 121 | OUT1_FXSEND, 122 | OUT1_VOLUME, 123 | 124 | DEF1_PITCHBEND, 125 | DEF1_MODWHEEL, 126 | DEF1_PRESSURE, 127 | DEF1_VELOCITY, 128 | DEF1_CHANNEL, 129 | DEF1_MONO, 130 | 131 | CHO1_WET, 132 | CHO1_DELAY, 133 | CHO1_FEEDB, 134 | CHO1_RATE, 135 | CHO1_MOD, 136 | FLA1_WET, 137 | FLA1_DELAY, 138 | FLA1_FEEDB, 139 | FLA1_DAFT, 140 | PHA1_WET, 141 | PHA1_RATE, 142 | PHA1_FEEDB, 143 | PHA1_DEPTH, 144 | PHA1_DAFT, 145 | DEL1_WET, 146 | DEL1_DELAY, 147 | DEL1_FEEDB, 148 | DEL1_BPM, 149 | REV1_WET, 150 | REV1_ROOM, 151 | REV1_DAMP, 152 | REV1_FEEDB, 153 | REV1_WIDTH, 154 | DYN1_COMPRESS, 155 | DYN1_LIMITER, 156 | 157 | KEY1_LOW, 158 | KEY1_HIGH, 159 | 160 | NUM_PARAMS 161 | }; 162 | 163 | void setParamPort(ParamIndex index, float *pfParam); 164 | padthv1_port *paramPort(ParamIndex index) const; 165 | 166 | void setParamValue(ParamIndex index, float fValue); 167 | float paramValue(ParamIndex index) const; 168 | 169 | bool running(bool on); 170 | 171 | void stabilize(); 172 | void reset_test(); 173 | void reset_sync( 174 | float freq0, float width, float scale, 175 | uint16_t nh, int apod, int sid); 176 | void reset(); 177 | 178 | padthv1_controls *controls() const; 179 | padthv1_programs *programs() const; 180 | 181 | void process_midi(uint8_t *data, uint32_t size); 182 | void process(float **ins, float **outs, uint32_t nframes); 183 | 184 | virtual void updatePreset(bool bDirty) = 0; 185 | virtual void updateParam(ParamIndex index) = 0; 186 | virtual void updateParams() = 0; 187 | 188 | void midiInEnabled(bool on); 189 | uint32_t midiInCount(); 190 | 191 | void directNoteOn(int note, int vel); 192 | 193 | void setTuningEnabled(bool enabled); 194 | bool isTuningEnabled() const; 195 | 196 | void setTuningRefPitch(float refPitch); 197 | float tuningRefPitch() const; 198 | 199 | void setTuningRefNote(int refNote); 200 | int tuningRefNote() const; 201 | 202 | void setTuningScaleFile(const char *pszScaleFile); 203 | const char *tuningScaleFile() const; 204 | 205 | void setTuningKeyMapFile(const char *pszKeyMapFile); 206 | const char *tuningKeyMapFile() const; 207 | 208 | void resetTuning(); 209 | 210 | virtual void updateTuning() = 0; 211 | 212 | private: 213 | 214 | padthv1_impl *m_pImpl; 215 | }; 216 | 217 | 218 | #endif// __padthv1_h 219 | 220 | // end of padthv1.h 221 | -------------------------------------------------------------------------------- /src/padthv1widget_keybd.h: -------------------------------------------------------------------------------- 1 | // padthv1widget_keybd.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2012-2025, rncbc aka Rui Nuno Capela. All rights reserved. 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | 20 | *****************************************************************************/ 21 | 22 | #ifndef __padthv1widget_keybd_h 23 | #define __padthv1widget_keybd_h 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | 30 | //------------------------------------------------------------------------- 31 | // padthv1widget_keybd - A horizontal piano keyboard widget. 32 | 33 | class padthv1widget_keybd : public QWidget 34 | { 35 | Q_OBJECT 36 | 37 | public: 38 | 39 | // Constructor. 40 | padthv1widget_keybd(QWidget *pParent = 0); 41 | 42 | // Note range predicate. 43 | void setNoteRange(bool bNoteRange); 44 | bool isNoteRange() const; 45 | 46 | // Note enabled predicates. 47 | void setNoteEnabled(int iNote, bool bEnabled); 48 | bool isNoteEnabled(int iNote) const; 49 | 50 | void setAllNotesEnabled(bool bEnabled); 51 | 52 | // Default note-on velocity. 53 | void setVelocity(int iVelocity); 54 | int velocity() const; 55 | 56 | // Keyboard note range getters. 57 | int noteLow() const; 58 | int noteHigh() const; 59 | 60 | // Highlighted note getter. 61 | int noteKey() const; 62 | 63 | public slots: 64 | 65 | // Keyboard note range setters. 66 | void setNoteLow(int iNoteLow); 67 | void setNoteHigh(int iNoteHigh); 68 | 69 | // Keyboard note/key actions. 70 | void noteOn(int iNote); 71 | void noteOff(int iNote); 72 | 73 | void allNotesOff(); 74 | 75 | // Highlighted note setter. 76 | void setNoteKey(int iNoteKey); 77 | 78 | signals: 79 | 80 | // Piano keyboard note-on/off signal. 81 | void noteOnClicked(int iNote, int iVelocity); 82 | 83 | // Keyboard note range changed signal. 84 | void noteRangeChanged(); 85 | 86 | protected slots: 87 | 88 | // Kill dangling notes, if any... 89 | void allNotesTimeout(); 90 | 91 | protected: 92 | 93 | // Keyboard note range sanitizers. 94 | int safeNoteLow(int iNoteLow) const; 95 | int safeNoteHigh(int iNoteHigh) const; 96 | 97 | // Piano key rectangle finder. 98 | QRect noteRect(int iNote, bool bOn = false) const; 99 | QPainterPath notePath(int iNote, bool bOn = false) const; 100 | 101 | // Piano keyboard note-on/off handlers. 102 | void dragNoteOn(const QPoint& pos); 103 | void dragNoteOff(); 104 | 105 | // Piano keyboard note descriminator. 106 | int noteAt(const QPoint& pos) const; 107 | 108 | // (Re)create the complete view pixmap. 109 | void updatePixmap(); 110 | 111 | // Paint event handler. 112 | void paintEvent(QPaintEvent *pPaintEvent); 113 | 114 | // Resize event handler. 115 | void resizeEvent(QResizeEvent *pResizeEvent); 116 | 117 | // Alternate mouse behavior event handlers. 118 | void mousePressEvent(QMouseEvent *pMouseEvent); 119 | void mouseMoveEvent(QMouseEvent *pMouseEvent); 120 | void mouseReleaseEvent(QMouseEvent *pMouseEvent); 121 | 122 | // Keyboard event handler. 123 | void keyPressEvent(QKeyEvent *pKeyEvent); 124 | 125 | // Trap for help/tool-tip events. 126 | bool eventFilter(QObject *pObject, QEvent *pEvent); 127 | 128 | // Present a tooltip for a note. 129 | void noteToolTip(const QPoint& pos) const; 130 | 131 | // Default note name map accessor. 132 | QString noteName(int iNote) const; 133 | 134 | // Reset drag/select state. 135 | void resetDragState(); 136 | 137 | protected: 138 | 139 | // Constants 140 | static const int NUM_NOTES = 128; 141 | 142 | static const int MIN_NOTE = 0; 143 | static const int MAX_NOTE = 127; 144 | 145 | static const int MIN_VELOCITY = 1; 146 | static const int MAX_VELOCITY = 127; 147 | 148 | // Local double-buffering pixmap. 149 | QPixmap m_pixmap; 150 | 151 | // Current notes being keyed on. 152 | struct Note 153 | { 154 | bool enabled; 155 | bool on; 156 | QPainterPath path; 157 | 158 | } m_notes[NUM_NOTES]; 159 | 160 | // Keyboard note range state. 161 | enum DragState { 162 | DragNone = 0, DragStart, 163 | DragNoteRange, DragNoteLow, DragNoteHigh 164 | } m_dragState, m_dragCursor; 165 | 166 | QPoint m_posDrag; 167 | 168 | // Piano keyboard note range. 169 | bool m_bNoteRange; 170 | 171 | int m_iNoteLow; 172 | int m_iNoteLowX; 173 | 174 | int m_iNoteHigh; 175 | int m_iNoteHighX; 176 | 177 | // Current note being keyed on. 178 | int m_iNoteOn; 179 | 180 | // Current note-on timeout. 181 | int m_iTimeout; 182 | 183 | // Default note-on velocity. 184 | int m_iVelocity; 185 | 186 | // Current highlighted note. 187 | int m_iNoteKey; 188 | }; 189 | 190 | 191 | #endif // __padthv1widget_keybd_h 192 | 193 | // end of padthv1widget_keybd.h 194 | -------------------------------------------------------------------------------- /src/padthv1_wave.h: -------------------------------------------------------------------------------- 1 | // padthv1_wave.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2012-2023, rncbc aka Rui Nuno Capela. All rights reserved. 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | 20 | *****************************************************************************/ 21 | 22 | #ifndef __padthv1_wave_h 23 | #define __padthv1_wave_h 24 | 25 | #include 26 | 27 | 28 | 29 | //------------------------------------------------------------------------- 30 | // padthv1_wave - smoothed (integrating oversampled) wave table. 31 | // 32 | 33 | class padthv1_wave 34 | { 35 | public: 36 | 37 | // shape. 38 | enum Shape { Pulse = 0, Saw, Sine, Rand, Noise }; 39 | 40 | // ctor. 41 | padthv1_wave(uint32_t nsize = 4096, uint16_t nover = 24); 42 | 43 | // dtor. 44 | ~padthv1_wave(); 45 | 46 | // properties. 47 | Shape shape() const 48 | { return m_shape; } 49 | float width() const 50 | { return m_width; } 51 | 52 | // sample rate. 53 | void setSampleRate(float srate) 54 | { m_srate = srate; } 55 | float sampleRate() const 56 | { return m_srate; } 57 | 58 | // table size (in frames) 59 | uint32_t size() const 60 | { return m_nsize; } 61 | 62 | // phase-zero (for slave reset) 63 | float phase0() const 64 | { return m_phase0; } 65 | 66 | // init. 67 | void reset(Shape shape, float width); 68 | 69 | // init.test 70 | void reset_test(Shape shape, float width) 71 | { 72 | if (shape != m_shape || width != m_width) 73 | reset(shape, width); 74 | } 75 | 76 | // begin. 77 | float start(float& phase, float pshift = 0.0f, float freq = 0.0f) const 78 | { 79 | phase = m_phase0 + pshift; 80 | if (phase >= 1.0f) 81 | phase -= 1.0f; 82 | 83 | return sample(phase, freq); 84 | } 85 | 86 | // iterate. 87 | float sample(float& phase, float freq) const 88 | { 89 | const float index = phase * float(m_nsize); 90 | const uint32_t i = uint32_t(index); 91 | const float alpha = index - float(i); 92 | 93 | phase += freq / m_srate; 94 | if (phase >= 1.0f) 95 | phase -= 1.0f; 96 | 97 | // cubic interpolation... 98 | const float x0 = m_table[i]; 99 | const float x1 = m_table[i + 1]; 100 | #if 0 // cubic interp. 101 | const float x2 = m_table[i + 2]; 102 | const float x3 = m_table[i + 3]; 103 | 104 | const float c1 = (x2 - x0) * 0.5f; 105 | const float b1 = (x1 - x2); 106 | const float b2 = (c1 + b1); 107 | const float c3 = (x3 - x1) * 0.5f + b2 + b1; 108 | const float c2 = (c3 + b2); 109 | 110 | return (((c3 * alpha) - c2) * alpha + c1) * alpha + x1; 111 | #else // linear interp. 112 | return x0 + alpha * (x1 - x0); 113 | #endif 114 | } 115 | 116 | // absolute value. 117 | float value(float phase) const 118 | { 119 | phase += m_phase0; 120 | if (phase >= 1.0f) 121 | phase -= 1.0f; 122 | 123 | return m_table[uint32_t(phase * float(m_nsize))]; 124 | } 125 | 126 | protected: 127 | 128 | // init pulse table. 129 | void reset_pulse(); 130 | 131 | // init saw table. 132 | void reset_saw(); 133 | 134 | // init sine table. 135 | void reset_sine(); 136 | 137 | // init random table. 138 | void reset_rand(); 139 | 140 | // init noise table. 141 | void reset_noise(); 142 | 143 | // post-processors 144 | void reset_filter(); 145 | void reset_normalize(); 146 | void reset_interp(); 147 | 148 | // Hal Chamberlain's pseudo-random linear congruential method. 149 | float pseudo_randf () 150 | { 151 | m_srand = (m_srand * 196314165) + 907633515; 152 | return m_srand / float(INT32_MAX) - 1.0f; 153 | } 154 | 155 | private: 156 | 157 | uint32_t m_nsize; 158 | uint16_t m_nover; 159 | 160 | Shape m_shape; 161 | float m_width; 162 | 163 | float m_srate; 164 | float *m_table; 165 | float m_phase0; 166 | 167 | uint32_t m_srand; 168 | }; 169 | 170 | 171 | //------------------------------------------------------------------------- 172 | // padthv1_wave_lf - hard/non-smoothed wave table (eg. LFO). 173 | // 174 | 175 | class padthv1_wave_lf : public padthv1_wave 176 | { 177 | public: 178 | 179 | // ctor. 180 | padthv1_wave_lf(uint32_t nsize = 1024) 181 | : padthv1_wave(nsize, 0) {} 182 | }; 183 | 184 | 185 | //------------------------------------------------------------------------- 186 | // padthv1_oscillator - wave table oscillator 187 | // 188 | 189 | class padthv1_oscillator 190 | { 191 | public: 192 | 193 | // ctor. 194 | padthv1_oscillator(padthv1_wave *wave = 0) { reset(wave); } 195 | 196 | // wave and phase accessors. 197 | void reset(padthv1_wave *wave) 198 | { m_wave = wave; m_phase = 0.0f; } 199 | 200 | padthv1_wave *wave() const 201 | { return m_wave; } 202 | 203 | // begin. 204 | float start(float pshift = 0.0f, float freq = 0.0f) 205 | { return m_wave->start(m_phase, pshift, freq); } 206 | 207 | // iterate. 208 | float sample(float freq) 209 | { return m_wave->sample(m_phase, freq); } 210 | 211 | // phase-shift accessor. 212 | float pshift() const 213 | { 214 | const float pshift = m_wave->phase0() + m_phase; 215 | return (pshift >= 1.0f ? pshift - 1.0f : pshift); 216 | } 217 | 218 | private: 219 | 220 | padthv1_wave *m_wave; 221 | 222 | float m_phase; 223 | }; 224 | 225 | 226 | #endif // __padthv1_wave_h 227 | 228 | // end of padthv1_wave.h 229 | -------------------------------------------------------------------------------- /src/padthv1widget_control.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | rncbc aka Rui Nuno Capela 4 | padthv1 - an old-school additive polyphonic synthesizer 5 | 6 | Copyright (C) 2012-2020, rncbc aka Rui Nuno Capela. All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License 10 | as published by the Free Software Foundation; either version 2 11 | of the License, or (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | 22 | 23 | padthv1widget_control 24 | 25 | 26 | 27 | 0 28 | 0 29 | 320 30 | 120 31 | 32 | 33 | 34 | MIDI Controller 35 | 36 | 37 | :/images/padthv1_control.png 38 | 39 | 40 | 41 | 42 | 43 | &Type: 44 | 45 | 46 | ControlTypeComboBox 47 | 48 | 49 | 50 | 51 | 52 | 53 | MIDI event type 54 | 55 | 56 | 57 | 58 | 59 | 60 | &Channel: 61 | 62 | 63 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 64 | 65 | 66 | ControlChannelSpinBox 67 | 68 | 69 | 70 | 71 | 72 | 73 | MIDI channel 74 | 75 | 76 | Auto 77 | 78 | 79 | false 80 | 81 | 82 | 0 83 | 84 | 85 | 16 86 | 87 | 88 | 89 | 90 | 91 | 92 | &Parameter: 93 | 94 | 95 | ControlParamComboBox 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 220 104 | 0 105 | 106 | 107 | 108 | MIDI parameter 109 | 110 | 111 | 112 | 113 | 114 | 115 | &Logarithmic 116 | 117 | 118 | 119 | 120 | 121 | 122 | &Invert 123 | 124 | 125 | 126 | 127 | 128 | 129 | &Hook 130 | 131 | 132 | 133 | 134 | 135 | 136 | Qt::Vertical 137 | 138 | 139 | 140 | 20 141 | 8 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | Qt::Horizontal 150 | 151 | 152 | QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::Reset 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | ControlTypeComboBox 161 | ControlChannelSpinBox 162 | ControlParamComboBox 163 | ControlLogarithmicCheckBox 164 | ControlInvertCheckBox 165 | ControlHookCheckBox 166 | DialogButtonBox 167 | 168 | 169 | 170 | 171 | 172 | 173 | -------------------------------------------------------------------------------- /src/padthv1_controls.h: -------------------------------------------------------------------------------- 1 | // padthv1_controls.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2012-2024, rncbc aka Rui Nuno Capela. All rights reserved. 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | 20 | *****************************************************************************/ 21 | 22 | #ifndef __padthv1_controls_h 23 | #define __padthv1_controls_h 24 | 25 | #include "padthv1_param.h" 26 | #include "padthv1_sched.h" 27 | 28 | #include 29 | 30 | 31 | //------------------------------------------------------------------------- 32 | // padthv1_controls - Controller processs class. 33 | // 34 | 35 | class padthv1_controls 36 | { 37 | public: 38 | 39 | // ctor. 40 | padthv1_controls(padthv1 *pPadth); 41 | 42 | // dtor. 43 | ~padthv1_controls(); 44 | 45 | // operational mode flags. 46 | void enabled(bool on) 47 | { m_enabled = on; } 48 | bool enabled() const 49 | { return m_enabled; } 50 | 51 | // controller types, 52 | enum Type { None = 0, CC = 0x100, RPN = 0x200, NRPN = 0x300, CC14 = 0x400 }; 53 | 54 | // controller hash key. 55 | struct Key 56 | { 57 | Key () : status(0), param(0) {} 58 | Key (const Key& key) 59 | : status(key.status), param(key.param) {} 60 | 61 | Type type() const 62 | { return Type(status & 0xf00); } 63 | unsigned short channel() const 64 | { return (status & 0x1f); } 65 | 66 | // hash key comparator. 67 | bool operator< (const Key& key) const 68 | { 69 | if (status != key.status) 70 | return (status < key.status); 71 | else 72 | return (param < key.param); 73 | } 74 | 75 | // copy assignment operator. 76 | Key& operator= (const Key& key) 77 | { 78 | if (this != &key) { 79 | status = key.status; 80 | param = key.param; 81 | } 82 | return *this; 83 | } 84 | 85 | unsigned short status; 86 | unsigned short param; 87 | }; 88 | 89 | // controller flags, 90 | enum Flag { Logarithmic = 1, Invert = 2, Hook = 4 }; 91 | 92 | // controller data. 93 | struct Data 94 | { 95 | Data () : index(-1), flags(0), val(0.0f), sync(false) {} 96 | 97 | int index; 98 | int flags; 99 | float val; 100 | bool sync; 101 | }; 102 | 103 | typedef QMap Map; 104 | 105 | // controller events. 106 | struct Event 107 | { 108 | Key key; 109 | unsigned short value; 110 | }; 111 | 112 | // controller map methods. 113 | const Map& map() const { return m_map; } 114 | 115 | int find_control(const Key& key) const 116 | { return m_map.value(key).index; } 117 | void add_control(const Key& key, const Data& data) 118 | { m_map.insert(key, data); } 119 | void remove_control(const Key& key) 120 | { m_map.remove(key); } 121 | 122 | void clear() { m_map.clear(); } 123 | 124 | // reset all controllers. 125 | void reset(); 126 | 127 | // controller queue methods. 128 | void process_enqueue( 129 | unsigned short channel, 130 | unsigned short param, 131 | unsigned short value); 132 | 133 | void process_dequeue(); 134 | 135 | // process timer counter. 136 | void process(unsigned int nframes); 137 | 138 | // text utilities. 139 | static Type typeFromText(const QString& sText); 140 | static QString textFromType(Type ctype); 141 | 142 | // current/last controller accessor. 143 | const Key& current_key() const; 144 | 145 | protected: 146 | 147 | // controller action. 148 | void process_event(const Event& event); 149 | 150 | // input controller scheduled events (learn) 151 | class SchedIn : public padthv1_sched 152 | { 153 | public: 154 | 155 | // ctor. 156 | SchedIn (padthv1 *pPadth) 157 | : padthv1_sched(pPadth, Controller) {} 158 | 159 | void schedule_key(const Key& key) 160 | { m_key = key; schedule(); } 161 | 162 | // process (virtual stub). 163 | void process(int) {} 164 | 165 | // current controller accessor. 166 | const Key& current_key() const 167 | { return m_key; } 168 | 169 | private: 170 | 171 | // instance variables,. 172 | Key m_key; 173 | }; 174 | 175 | // output controller scheduled events (assignments) 176 | class SchedOut : public padthv1_sched 177 | { 178 | public: 179 | 180 | // ctor. 181 | SchedOut (padthv1 *pPadth) 182 | : padthv1_sched(pPadth, Controls), m_value(0.0f) {} 183 | 184 | void schedule_event(padthv1::ParamIndex index, float value) 185 | { 186 | if (qAbs(value - m_value) > 0.001f) { 187 | m_value = value; 188 | schedule(int(index)); 189 | } 190 | } 191 | 192 | // process (virtual stub). 193 | void process(int sid) 194 | { 195 | padthv1 *pPadth = instance(); 196 | padthv1::ParamIndex index = padthv1::ParamIndex(sid); 197 | pPadth->setParamValue(index, m_value); 198 | pPadth->updateParam(index); 199 | } 200 | 201 | private: 202 | 203 | // instance variables 204 | float m_value; 205 | }; 206 | 207 | private: 208 | 209 | // instance variables. 210 | class Impl; 211 | 212 | Impl *m_pImpl; 213 | 214 | // operational mode flags. 215 | bool m_enabled; 216 | 217 | // controller schedulers. 218 | SchedIn m_sched_in; 219 | SchedOut m_sched_out; 220 | 221 | // controllers map. 222 | Map m_map; 223 | 224 | // frame timers. 225 | unsigned int m_timeout; 226 | unsigned int m_timein; 227 | }; 228 | 229 | 230 | #endif // __padthv1_controls_h 231 | 232 | // end of padthv1_controls.h 233 | -------------------------------------------------------------------------------- /rpm/padthv1.spec: -------------------------------------------------------------------------------- 1 | # 2 | # spec file for package padthv1 3 | # 4 | # Copyright (C) 2017-2025, rncbc aka Rui Nuno Capela. All rights reserved. 5 | # 6 | # All modifications and additions to the file contributed by third parties 7 | # remain the property of their copyright owners, unless otherwise agreed 8 | # upon. The license for this file, and modifications and additions to the 9 | # file, is the same license as for the pristine package itself (unless the 10 | # license for the pristine package is not an Open Source License, in which 11 | # case the license is the MIT License). An "Open Source License" is a 12 | # license that conforms to the Open Source Definition (Version 1.9) 13 | # published by the Open Source Initiative. 14 | 15 | # Please submit bugfixes or comments via http://bugs.opensuse.org/ 16 | # 17 | 18 | Summary: An old-school polyphonic additive synthesizer 19 | Name: padthv1 20 | Version: 1.3.2 21 | Release: 9.1 22 | License: GPL-2.0-or-later 23 | Group: Productivity/Multimedia/Sound/Midi 24 | Source: %{name}-%{version}.tar.gz 25 | URL: http://padthv1.sourceforge.net 26 | #Packager: rncbc.org 27 | 28 | %if %{defined fedora} 29 | %global debug_package %{nil} 30 | %endif 31 | 32 | BuildRequires: coreutils 33 | BuildRequires: pkgconfig 34 | BuildRequires: glibc-devel 35 | BuildRequires: cmake >= 3.15 36 | %if 0%{?sle_version} >= 150200 && 0%{?is_opensuse} 37 | BuildRequires: gcc10 >= 10 38 | BuildRequires: gcc10-c++ >= 10 39 | %define _GCC /usr/bin/gcc-10 40 | %define _GXX /usr/bin/g++-10 41 | %else 42 | BuildRequires: gcc >= 10 43 | BuildRequires: gcc-c++ >= 10 44 | %define _GCC /usr/bin/gcc 45 | %define _GXX /usr/bin/g++ 46 | %endif 47 | 48 | %if 0%{?sle_version} == 150200 && 0%{?is_opensuse} 49 | BuildRequires: qtbase6.9-static >= 6.9 50 | BuildRequires: qttools6.9-static 51 | BuildRequires: qttranslations6.9-static 52 | BuildRequires: qtsvg6.9-static 53 | %else 54 | BuildRequires: qtbase6.10-static >= 6.10 55 | BuildRequires: qttools6.10-static 56 | BuildRequires: qttranslations6.10-static 57 | BuildRequires: qtsvg6.10-static 58 | %endif 59 | %if %{defined fedora} 60 | BuildRequires: jack-audio-connection-kit-devel 61 | %else 62 | BuildRequires: pkgconfig(jack) 63 | %endif 64 | BuildRequires: pkgconfig(alsa) 65 | 66 | BuildRequires: pkgconfig(fftw3) 67 | BuildRequires: pkgconfig(liblo) 68 | BuildRequires: pkgconfig(lv2) 69 | 70 | BuildRequires: pkgconfig(egl) 71 | 72 | %description 73 | An old-school all-digital polyphonic additive synthesizer with stereo fx. 74 | 75 | 76 | %package -n %{name}-jack 77 | Summary: An old-school polyphonic additive synthesizer - JACK standalone 78 | Provides: %{name}_jack 79 | Obsoletes: %{name}-common <= %{version}, %{name} <= %{version} 80 | 81 | %description -n %{name}-jack 82 | An old-school all-digital polyphonic additive synthesizer with stereo fx. 83 | 84 | This package provides the standalone JACK client application (padthv1_jack) 85 | 86 | 87 | %package -n %{name}-lv2 88 | Summary: An old-school polyphonic additive synthesizer - LV2 plugin 89 | Provides: %{name}_lv2, %{name}_lv2ui 90 | Obsoletes: %{name}-common <= %{version} 91 | 92 | %description -n %{name}-lv2 93 | An old-school all-digital polyphonic additive synthesizer with stereo fx. 94 | 95 | This package provides the LV2 plugin (http://padthv1.sourceforge.net/lv2) 96 | 97 | 98 | %prep 99 | %setup -q 100 | 101 | %build 102 | %if 0%{?sle_version} == 150200 && 0%{?is_opensuse} 103 | source /opt/qt6.9-static/bin/qt6.9-static-env.sh 104 | %else 105 | source /opt/qt6.10-static/bin/qt6.10-static-env.sh 106 | %endif 107 | CXX=%{_GXX} CC=%{_GCC} \ 108 | cmake -DCMAKE_INSTALL_PREFIX=%{_prefix} -Wno-dev -B build 109 | cmake --build build %{?_smp_mflags} 110 | 111 | %install 112 | DESTDIR="%{buildroot}" \ 113 | cmake --install build 114 | 115 | 116 | %files -n %{name}-jack 117 | %license LICENSE 118 | %doc README ChangeLog 119 | #dir %{_datadir}/applications 120 | %dir %{_datadir}/metainfo 121 | #dir %{_datadir}/mime 122 | #dir %{_datadir}/mime/packages 123 | %dir %{_datadir}/icons/hicolor 124 | %dir %{_datadir}/icons/hicolor/32x32 125 | %dir %{_datadir}/icons/hicolor/32x32/apps 126 | %dir %{_datadir}/icons/hicolor/32x32/mimetypes 127 | %dir %{_datadir}/icons/hicolor/scalable 128 | %dir %{_datadir}/icons/hicolor/scalable/apps 129 | %dir %{_datadir}/icons/hicolor/scalable/mimetypes 130 | #dir %{_datadir}/man 131 | #dir %{_datadir}/man/man1 132 | #dir %{_datadir}/man/fr 133 | #dir %{_datadir}/man/fr/man1 134 | %dir %{_datadir}/%{name} 135 | %dir %{_datadir}/%{name}/palette 136 | %{_bindir}/%{name}_jack 137 | %{_datadir}/metainfo/org.rncbc.%{name}.metainfo.xml 138 | %{_datadir}/applications/org.rncbc.%{name}.desktop 139 | %{_datadir}/mime/packages/org.rncbc.%{name}.xml 140 | %{_datadir}/icons/hicolor/32x32/apps/org.rncbc.%{name}.png 141 | %{_datadir}/icons/hicolor/scalable/apps/org.rncbc.%{name}.svg 142 | %{_datadir}/icons/hicolor/32x32/mimetypes/org.rncbc.%{name}.application-x-%{name}*.png 143 | %{_datadir}/icons/hicolor/scalable/mimetypes/org.rncbc.%{name}.application-x-%{name}*.svg 144 | %{_datadir}/man/man1/%{name}.1.gz 145 | %{_datadir}/man/fr/man1/%{name}.1.gz 146 | %{_datadir}/%{name}/palette/*.conf 147 | 148 | %files -n %{name}-lv2 149 | %dir %{_libdir}/lv2 150 | %dir %{_libdir}/lv2/%{name}.lv2 151 | %{_libdir}/lv2/%{name}.lv2/manifest.ttl 152 | %{_libdir}/lv2/%{name}.lv2/%{name}.ttl 153 | %{_libdir}/lv2/%{name}.lv2/%{name}.so 154 | %{_libdir}/lv2/%{name}.lv2/%{name}_ui.ttl 155 | 156 | 157 | %changelog 158 | * Tue May 20 2025 Rui Nuno Capela 1.3.2 159 | - A Mid-Spring'25 Release. 160 | * Thu Apr 3 2025 Rui Nuno Capela 1.3.1 161 | - An Early Spring'25 Release. 162 | * Thu Jan 16 2025 Rui Nuno Capela 1.3.0 163 | - A New-Year'25 Release. 164 | * Sun Dec 15 2024 Rui Nuno Capela 1.2.0 165 | - An End-of-Year'24 Release. 166 | * Thu Oct 31 2024 Rui Nuno Capela 1.1.3 167 | - A Halloween'24 Release. 168 | * Wed Oct 2 2024 Rui Nuno Capela 1.1.2 169 | - An Early-Fall'24 Release. 170 | * Fri Sep 20 2024 Rui Nuno Capela 1.1.1 171 | - An End-of-Summer'24 Release. 172 | * Wed Aug 28 2024 Rui Nuno Capela 1.1.0 173 | - A Mid-Summer'24 Release. 174 | * Thu Jun 20 2024 Rui Nuno Capela 1.0.0 175 | - An Unthinkable Release. 176 | -------------------------------------------------------------------------------- /src/padthv1_wave.cpp: -------------------------------------------------------------------------------- 1 | // padthv1_wave.cpp 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2012-2023, rncbc aka Rui Nuno Capela. All rights reserved. 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | 20 | *****************************************************************************/ 21 | 22 | #include "padthv1_wave.h" 23 | 24 | #include 25 | #include 26 | 27 | 28 | //------------------------------------------------------------------------- 29 | // padthv1_wave - smoothed (integrating oversampled) wave table. 30 | // 31 | 32 | // ctor. 33 | padthv1_wave::padthv1_wave ( uint32_t nsize, uint16_t nover ) 34 | : m_nsize(nsize), m_nover(nover), 35 | m_shape(Pulse), m_width(1.0f), 36 | m_srate(44100.0f), m_phase0(0.0f), m_srand(0) 37 | { 38 | m_table = new float [m_nsize + 4]; 39 | 40 | reset(m_shape, m_width); 41 | } 42 | 43 | 44 | // dtor. 45 | padthv1_wave::~padthv1_wave (void) 46 | { 47 | delete [] m_table; 48 | } 49 | 50 | 51 | // init. 52 | void padthv1_wave::reset ( Shape shape, float width ) 53 | { 54 | m_shape = shape; 55 | m_width = width;; 56 | 57 | switch (m_shape) { 58 | case Pulse: 59 | reset_pulse(); 60 | break; 61 | case Saw: 62 | reset_saw(); 63 | break; 64 | case Sine: 65 | reset_sine(); 66 | break; 67 | case Rand: 68 | reset_rand(); 69 | break; 70 | case Noise: 71 | reset_noise(); 72 | // Fall thru... 73 | default: 74 | break; 75 | } 76 | } 77 | 78 | 79 | // init pulse table. 80 | void padthv1_wave::reset_pulse (void) 81 | { 82 | const float p0 = float(m_nsize); 83 | const float w2 = p0 * m_width * 0.5f; 84 | 85 | for (uint32_t i = 0; i < m_nsize; ++i) { 86 | const float p = float(i); 87 | m_table[i] = (p < w2 ? 1.0f : -1.0f); 88 | } 89 | 90 | reset_filter(); 91 | reset_normalize(); 92 | reset_interp(); 93 | } 94 | 95 | 96 | // init saw table. 97 | void padthv1_wave::reset_saw (void) 98 | { 99 | const float p0 = float(m_nsize); 100 | const float w0 = p0 * m_width; 101 | 102 | for (uint32_t i = 0; i < m_nsize; ++i) { 103 | const float p = float(i); 104 | if (p < w0) { 105 | m_table[i] = 2.0f * p / w0 - 1.0f; 106 | } else { 107 | m_table[i] = 1.0f - 2.0f * (1.0f + (p - w0)) / (p0 - w0); 108 | } 109 | } 110 | 111 | reset_filter(); 112 | reset_normalize(); 113 | reset_interp(); 114 | } 115 | 116 | 117 | // init sine table. 118 | void padthv1_wave::reset_sine (void) 119 | { 120 | const float p0 = float(m_nsize); 121 | const float w0 = p0 * m_width; 122 | const float w2 = w0 * 0.5f; 123 | 124 | for (uint32_t i = 0; i < m_nsize; ++i) { 125 | float p = float(i); 126 | if (p < w2) 127 | m_table[i] = ::sinf(2.0f * M_PI * p / w0); 128 | else 129 | m_table[i] = ::sinf(M_PI * (p + (p0 - w0)) / (p0 - w2)); 130 | } 131 | 132 | if (m_width < 1.0f) { 133 | reset_filter(); 134 | reset_normalize(); 135 | } 136 | 137 | reset_interp(); 138 | } 139 | 140 | 141 | // init random table. 142 | void padthv1_wave::reset_rand (void) 143 | { 144 | const float p0 = float(m_nsize); 145 | const float w0 = p0 * m_width; 146 | const uint32_t ihold = (uint32_t(p0 - w0) >> 3) + 1; 147 | 148 | m_srand = uint32_t(w0); 149 | 150 | float p = 0.0f; 151 | 152 | for (uint32_t i = 0; i < m_nsize; ++i) { 153 | if ((i % ihold) == 0) 154 | p = pseudo_randf(); 155 | m_table[i] = p; 156 | } 157 | 158 | reset_filter(); 159 | reset_normalize(); 160 | reset_interp(); 161 | } 162 | 163 | 164 | // init noise table. 165 | void padthv1_wave::reset_noise (void) 166 | { 167 | const float p0 = float(m_nsize); 168 | const float w0 = p0 * m_width; 169 | 170 | m_srand = uint32_t(w0) ^ 0x9631; // magic! 171 | 172 | for (uint32_t i = 0; i < m_nsize; ++i) 173 | m_table[i] = pseudo_randf(); 174 | 175 | // reset_filter(); 176 | // reset_normalize(); 177 | reset_interp(); 178 | } 179 | 180 | 181 | // post-processors 182 | void padthv1_wave::reset_filter (void) 183 | { 184 | uint32_t i, k = 0; 185 | 186 | for (i = 1; i < m_nsize; ++i) { 187 | const float p1 = m_table[i - 1]; 188 | const float p2 = m_table[i]; 189 | if (p1 < 0.0f && p2 >= 0.0f) { 190 | k = i; 191 | break; 192 | } 193 | } 194 | 195 | for (uint16_t n = 0; n < m_nover; ++n) { 196 | float p = m_table[k]; 197 | for (i = 0; i < m_nsize; ++i) { 198 | if (++k >= m_nsize) k = 0; 199 | p = 0.5f * (m_table[k] + p); 200 | m_table[k] = p; 201 | } 202 | } 203 | } 204 | 205 | 206 | void padthv1_wave::reset_normalize (void) 207 | { 208 | uint32_t i; 209 | 210 | float pmax = 0.0f; 211 | float pmin = 0.0f; 212 | 213 | for (i = 0; i < m_nsize; ++i) { 214 | const float p = m_table[i]; 215 | if (pmax < p) 216 | pmax = p; 217 | else 218 | if (pmin > p) 219 | pmin = p; 220 | } 221 | 222 | const float pmid = 0.5f * (pmax + pmin); 223 | 224 | pmax = 0.0f; 225 | for (i = 0; i < m_nsize; ++i) { 226 | m_table[i] -= pmid; 227 | const float p = ::fabsf(m_table[i]); 228 | if (pmax < p) 229 | pmax = p; 230 | } 231 | 232 | if (pmax > 0.0f) { 233 | const float gain = 1.0f / pmax; 234 | for (i = 0; i < m_nsize; ++i) 235 | m_table[i] *= gain; 236 | } 237 | } 238 | 239 | 240 | void padthv1_wave::reset_interp (void) 241 | { 242 | uint32_t i, k = 0; 243 | 244 | for (i = m_nsize; i < m_nsize + 4; ++i) 245 | m_table[i] = m_table[i - m_nsize]; 246 | 247 | for (i = 1; i < m_nsize; ++i) { 248 | const float p1 = m_table[i - 1]; 249 | const float p2 = m_table[i]; 250 | if (p1 < 0.0f && p2 >= 0.0f) 251 | k = i; 252 | } 253 | 254 | m_phase0 = float(k) / float(m_nsize); 255 | } 256 | 257 | 258 | // end of padthv1_wave.cpp 259 | -------------------------------------------------------------------------------- /src/padthv1widget_lv2.cpp: -------------------------------------------------------------------------------- 1 | // padthv1widget_lv2.cpp 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2012-2025, rncbc aka Rui Nuno Capela. All rights reserved. 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | 20 | *****************************************************************************/ 21 | 22 | #include "padthv1widget_lv2.h" 23 | 24 | #include "padthv1_lv2.h" 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | #include "padthv1widget_palette.h" 31 | 32 | #include 33 | 34 | #include 35 | 36 | #ifndef CONFIG_BINDIR 37 | #define CONFIG_BINDIR CONFIG_PREFIX "/bin" 38 | #endif 39 | 40 | #ifndef CONFIG_LIBDIR 41 | #if defined(__x86_64__) 42 | #define CONFIG_LIBDIR CONFIG_PREFIX "/lib64" 43 | #else 44 | #define CONFIG_LIBDIR CONFIG_PREFIX "/lib" 45 | #endif 46 | #endif 47 | 48 | #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 49 | #define CONFIG_PLUGINSDIR CONFIG_LIBDIR "/qt5/plugins" 50 | #else 51 | #define CONFIG_PLUGINSDIR CONFIG_LIBDIR "/qt6/plugins" 52 | #endif 53 | 54 | 55 | //------------------------------------------------------------------------- 56 | // padthv1widget_lv2 - impl. 57 | // 58 | 59 | // Constructor. 60 | padthv1widget_lv2::padthv1widget_lv2 ( padthv1_lv2 *pPadth, 61 | LV2UI_Controller controller, LV2UI_Write_Function write_function ) 62 | : padthv1widget() 63 | { 64 | // Check whether under a dedicated application instance... 65 | QApplication *pApp = padthv1_lv2::qapp_instance(); 66 | if (pApp) { 67 | // Special style paths... 68 | QString sPluginsPath = pApp->applicationDirPath(); 69 | sPluginsPath.remove(CONFIG_BINDIR); 70 | sPluginsPath.append(CONFIG_PLUGINSDIR); 71 | if (QDir(sPluginsPath).exists()) 72 | pApp->addLibraryPath(CONFIG_PLUGINSDIR); 73 | } 74 | 75 | // Custom color/style themes... 76 | padthv1_config *pConfig = padthv1_config::getInstance(); 77 | if (pConfig) { 78 | const QChar sep = QDir::separator(); 79 | QString sPalettePath = QApplication::applicationDirPath(); 80 | sPalettePath.remove(CONFIG_BINDIR); 81 | sPalettePath.append(CONFIG_DATADIR); 82 | sPalettePath.append(sep); 83 | sPalettePath.append(PROJECT_NAME); 84 | sPalettePath.append(sep); 85 | sPalettePath.append("palette"); 86 | if (QDir(sPalettePath).exists()) { 87 | QStringList names; 88 | names.append("KXStudio"); 89 | names.append("Wonton Soup"); 90 | QStringListIterator name_iter(names); 91 | while (name_iter.hasNext()) { 92 | const QString& name = name_iter.next(); 93 | const QFileInfo fi(sPalettePath, name + ".conf"); 94 | if (fi.isReadable()) { 95 | padthv1widget_palette::addNamedPaletteConf( 96 | pConfig, name, fi.absoluteFilePath()); 97 | } 98 | } 99 | } 100 | if (!pConfig->sCustomColorTheme.isEmpty()) { 101 | QPalette pal; 102 | if (padthv1widget_palette::namedPalette( 103 | pConfig, pConfig->sCustomColorTheme, pal)) 104 | padthv1widget::setPalette(pal); 105 | } 106 | #if 0//--Not applicable to plugin forms... 107 | if (!pConfig->sCustomStyleTheme.isEmpty()) { 108 | QApplication::setStyle( 109 | QStyleFactory::create(pConfig->sCustomStyleTheme)); 110 | } 111 | #endif 112 | } 113 | 114 | // Initialize (user) interface stuff... 115 | m_pPadthUi = new padthv1_lv2ui(pPadth, controller, write_function); 116 | 117 | #ifdef CONFIG_LV2_UI_EXTERNAL 118 | m_external_host = nullptr; 119 | #endif 120 | #ifdef CONFIG_LV2_UI_IDLE 121 | m_bIdleClosed = false; 122 | #endif 123 | 124 | // Initialise preset stuff... 125 | clearPreset(); 126 | 127 | // Initial update, always... 128 | updateSample(); 129 | 130 | //resetParamValues(); 131 | resetParamKnobs(); 132 | 133 | // May initialize the scheduler/work notifier. 134 | openSchedNotifier(); 135 | } 136 | 137 | 138 | // Destructor. 139 | padthv1widget_lv2::~padthv1widget_lv2 (void) 140 | { 141 | delete m_pPadthUi; 142 | } 143 | 144 | 145 | // Synth engine accessor. 146 | padthv1_ui *padthv1widget_lv2::ui_instance (void) const 147 | { 148 | return m_pPadthUi; 149 | } 150 | 151 | 152 | #ifdef CONFIG_LV2_UI_EXTERNAL 153 | 154 | void padthv1widget_lv2::setExternalHost ( LV2_External_UI_Host *external_host ) 155 | { 156 | m_external_host = external_host; 157 | } 158 | 159 | const LV2_External_UI_Host *padthv1widget_lv2::externalHost (void) const 160 | { 161 | return m_external_host; 162 | } 163 | 164 | #endif // CONFIG_LV2_UI_EXTERNAL 165 | 166 | 167 | #ifdef CONFIG_LV2_UI_IDLE 168 | 169 | bool padthv1widget_lv2::isIdleClosed (void) const 170 | { 171 | return m_bIdleClosed; 172 | } 173 | 174 | #endif // CONFIG_LV2_UI_IDLE 175 | 176 | 177 | // Close event handler. 178 | void padthv1widget_lv2::closeEvent ( QCloseEvent *pCloseEvent ) 179 | { 180 | padthv1widget::closeEvent(pCloseEvent); 181 | 182 | #ifdef CONFIG_LV2_UI_IDLE 183 | if (pCloseEvent->isAccepted()) 184 | m_bIdleClosed = true; 185 | #endif 186 | #ifdef CONFIG_LV2_UI_EXTERNAL 187 | if (m_external_host && m_external_host->ui_closed) { 188 | if (pCloseEvent->isAccepted()) 189 | m_external_host->ui_closed(m_pPadthUi->controller()); 190 | } 191 | #endif 192 | } 193 | 194 | 195 | // LV2 port event dispatcher. 196 | void padthv1widget_lv2::port_event ( uint32_t port_index, 197 | uint32_t buffer_size, uint32_t format, const void *buffer ) 198 | { 199 | if (format == 0 && buffer_size == sizeof(float)) { 200 | const padthv1::ParamIndex index 201 | = padthv1::ParamIndex(port_index - padthv1_lv2::ParamBase); 202 | const float fValue = *(float *) buffer; 203 | setParamValue(index, fValue); 204 | } 205 | } 206 | 207 | 208 | // Param method. 209 | void padthv1widget_lv2::updateParam ( 210 | padthv1::ParamIndex index, float fValue ) const 211 | { 212 | m_pPadthUi->write_function(index, fValue); 213 | } 214 | 215 | 216 | // end of padthv1widget_lv2.cpp 217 | -------------------------------------------------------------------------------- /src/padthv1widget.h: -------------------------------------------------------------------------------- 1 | // padthv1widget.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2012-2025, rncbc aka Rui Nuno Capela. All rights reserved. 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | 20 | *****************************************************************************/ 21 | 22 | #ifndef __padthv1widget_h 23 | #define __padthv1widget_h 24 | 25 | #include "padthv1_config.h" 26 | #include "padthv1_sched.h" 27 | 28 | #include "padthv1_ui.h" 29 | 30 | #include 31 | 32 | 33 | // forward decls. 34 | namespace Ui { class padthv1widget; } 35 | 36 | class padthv1widget_param; 37 | class padthv1widget_sched; 38 | 39 | 40 | //------------------------------------------------------------------------- 41 | // padthv1widget - decl. 42 | // 43 | 44 | class padthv1widget : public QWidget 45 | { 46 | Q_OBJECT 47 | 48 | public: 49 | 50 | // Constructor 51 | padthv1widget(QWidget *pParent = nullptr); 52 | 53 | // Destructor. 54 | virtual ~padthv1widget(); 55 | 56 | // Open/close the scheduler/work notifier. 57 | void openSchedNotifier(); 58 | void closeSchedNotifier(); 59 | 60 | // Param port accessors. 61 | void setParamValue(padthv1::ParamIndex index, float fValue); 62 | float paramValue(padthv1::ParamIndex index) const; 63 | 64 | // Param kbob (widget) mapper. 65 | void setParamKnob(padthv1::ParamIndex index, padthv1widget_param *pKnob); 66 | padthv1widget_param *paramKnob(padthv1::ParamIndex index) const; 67 | 68 | // Preset init. 69 | void initPreset(); 70 | // Preset clear. 71 | void clearPreset(); 72 | 73 | // Dirty close prompt, 74 | bool queryClose(); 75 | 76 | // Update visual configuration. 77 | void updateConfig(); 78 | 79 | public slots: 80 | 81 | // Preset file I/O. 82 | bool loadPreset(const QString& sFilename); 83 | bool savePreset(const QString& sFilename); 84 | 85 | // Direct note-on/off slot. 86 | void directNoteOn(int iNote, int iVelocity); 87 | 88 | protected slots: 89 | 90 | // Preset renewal. 91 | void newPreset(); 92 | 93 | // Param knob (widget) slots. 94 | void paramChanged(float fValue); 95 | 96 | // Reset param knobs to default value. 97 | void resetParams(); 98 | 99 | // Randomize params (partial). 100 | void randomParams(); 101 | 102 | // Swap params A/B. 103 | void swapParams(bool bOn); 104 | 105 | // Panic: all-notes/sound-off (reset). 106 | void panic(); 107 | 108 | // Notification updater. 109 | void updateSchedNotify(int stype, int sid); 110 | 111 | // MIDI In LED timeout. 112 | void midiInLedTimeout(); 113 | 114 | // Keyboard note range change. 115 | void noteRangeChanged(); 116 | 117 | // Param knob context menu. 118 | void paramContextMenu(const QPoint& pos); 119 | 120 | // Sample harmonics edits. 121 | void resetSample1(); 122 | void resetSample2(); 123 | 124 | // Menu actions. 125 | void helpConfigure(); 126 | 127 | void helpAbout(); 128 | void helpAboutQt(); 129 | 130 | protected: 131 | 132 | // Synth engine accessor. 133 | virtual padthv1_ui *ui_instance() const = 0; 134 | 135 | // Reset swap params A/B group. 136 | void resetSwapParams(); 137 | 138 | // Initialize all param/knob values. 139 | void updateParamValues(); 140 | 141 | // Reset all param/knob default values. 142 | void resetParamValues(); 143 | void resetParamKnobs(); 144 | 145 | // Sample reset (3=both). 146 | void clearSample(int sid = 3); 147 | 148 | // Sample updater (3=both). 149 | void updateSample(int sid = 3); 150 | 151 | // Param port methods. 152 | virtual void updateParam(padthv1::ParamIndex index, float fValue) const = 0; 153 | 154 | // Update local tied widgets. 155 | void updateParamEx(padthv1::ParamIndex index, float fValue); 156 | 157 | // Update scheduled controllers param/knob widgets. 158 | void updateSchedParam(padthv1::ParamIndex index, float fValue); 159 | 160 | // Preset status updater. 161 | void updateLoadPreset(const QString& sPreset); 162 | 163 | // Dirty flag (overridable virtual) methods. 164 | virtual void updateDirtyPreset(bool bDirtyPreset); 165 | 166 | // Show/hide dget handlers. 167 | void showEvent(QShowEvent *pShowEvent); 168 | void hideEvent(QHideEvent *pHideEvent); 169 | 170 | private: 171 | 172 | // Instance variables. 173 | Ui::padthv1widget *p_ui; 174 | Ui::padthv1widget& m_ui; 175 | 176 | padthv1widget_sched *m_sched_notifier; 177 | 178 | QHash m_paramKnobs; 179 | QHash m_knobParams; 180 | 181 | float m_params_ab[padthv1::NUM_PARAMS]; 182 | 183 | int m_iUpdate; 184 | }; 185 | 186 | 187 | //------------------------------------------------------------------------- 188 | // padthv1widget_sched - worker/schedule proxy decl. 189 | // 190 | 191 | class padthv1widget_sched : public QObject 192 | { 193 | Q_OBJECT 194 | 195 | public: 196 | 197 | // ctor. 198 | padthv1widget_sched(padthv1 *pPadth, QObject *pParent = nullptr) 199 | : QObject(pParent), m_notifier(pPadth, this) {} 200 | 201 | signals: 202 | 203 | // Notification signal. 204 | void notify(int stype, int sid); 205 | 206 | protected: 207 | 208 | // Notififier visitor. 209 | class Notifier : public padthv1_sched::Notifier 210 | { 211 | public: 212 | 213 | Notifier(padthv1 *pPadth, padthv1widget_sched *pSched) 214 | : padthv1_sched::Notifier(pPadth), m_pSched(pSched) {} 215 | 216 | void notify(padthv1_sched::Type stype, int sid) const 217 | { m_pSched->emit_notify(stype, sid); } 218 | 219 | private: 220 | 221 | padthv1widget_sched *m_pSched; 222 | }; 223 | 224 | // Notification method. 225 | void emit_notify(padthv1_sched::Type stype, int sid) 226 | { emit notify(int(stype), sid); } 227 | 228 | private: 229 | 230 | // Instance variables. 231 | Notifier m_notifier; 232 | }; 233 | 234 | 235 | #endif // __padthv1widget_h 236 | 237 | // end of padthv1widget.h 238 | -------------------------------------------------------------------------------- /src/padthv1_formant.h: -------------------------------------------------------------------------------- 1 | // padthv1_formant.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2012-2021, rncbc aka Rui Nuno Capela. All rights reserved. 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | 20 | *****************************************************************************/ 21 | 22 | #ifndef __padthv1_formant_h 23 | #define __padthv1_formant_h 24 | 25 | #include 26 | #include 27 | 28 | 29 | //--------------------------------------------------------------------- 30 | // padthv1_formant - formant parallel filter after Dennis H. Klatt's 31 | // Software for a cascade/parallel formant synthesizer 32 | // 1979 MIT; 1980 Acoustical Society of America. 33 | // 34 | 35 | class padthv1_formant 36 | { 37 | public: 38 | 39 | // constants 40 | static const uint32_t NUM_VTABS = 5; 41 | static const uint32_t NUM_VOWELS = 5; 42 | static const uint32_t NUM_FORMANTS = 5; 43 | static const uint32_t NUM_STEPS = 320; 44 | 45 | // 2-pole filter coeffs. 46 | struct Coeffs { float a0, b1, b2; }; 47 | 48 | // vocal/vowel table 49 | struct Vtab 50 | { 51 | float freq[NUM_FORMANTS]; // frequency [Hz] 52 | float gain[NUM_FORMANTS]; // peak gain [dB] 53 | float band[NUM_FORMANTS]; // bandwidth [Hz] 54 | }; 55 | 56 | // main impl. 57 | class Impl 58 | { 59 | public: 60 | 61 | // ctor. 62 | Impl(float srate = 44100.0f) 63 | : m_srate(srate) { reset_coeffs(); } 64 | 65 | // sample-rate accessors 66 | void setSampleRate(float srate) 67 | { m_srate = srate; reset_coeffs(); } 68 | float sampleRate() const 69 | { return m_srate; } 70 | 71 | // formant coeffs. accessor 72 | const Coeffs& coeffs(uint32_t i) const 73 | { return m_ctabs[i]; } 74 | 75 | // reset coeffs. method 76 | void reset_coeffs(float cutoff = 0.5f, float reso = 0.0f); 77 | 78 | protected: 79 | 80 | // compute coeffs. for given vocal formant table 81 | void vtab_coeffs(Coeffs& coeffs, const Vtab *vtab, uint32_t i, float p); 82 | 83 | private: 84 | 85 | // instance members 86 | float m_srate; 87 | 88 | // filter coeffs. 89 | Coeffs m_ctabs[NUM_FORMANTS]; 90 | }; 91 | 92 | // ctor. 93 | padthv1_formant(Impl *pImpl = 0) 94 | : m_pImpl(pImpl), m_cutoff(0.5f), m_reso(0.0f), m_nstep(0) 95 | { reset_coeffs(); } 96 | 97 | // reset impl. 98 | void reset(Impl *pImpl) 99 | { m_pImpl = pImpl; reset_coeffs(); } 100 | 101 | void reset_filters(float cutoff, float reso) 102 | { 103 | for (uint32_t i = 0; i < NUM_FORMANTS; ++i) 104 | m_filters[i].reset(); 105 | 106 | update(cutoff, reso); 107 | } 108 | 109 | // output tick 110 | float output(float in, float cutoff, float reso) 111 | { 112 | update(cutoff, reso); 113 | 114 | float out = 0.0f; 115 | for (uint32_t i = 0; i < NUM_FORMANTS; ++i) 116 | out += m_filters[i].output(in); 117 | return out; 118 | } 119 | 120 | // process block 121 | void process(float *in, uint32_t nframes, float wet, float cutoff, float reso) 122 | { 123 | for (uint32_t i = 0; i < nframes; ++i) { 124 | const float out = output(in[i], cutoff, reso); 125 | in[i] *= (1.0f - wet); 126 | in[i] += (wet * out); 127 | } 128 | } 129 | 130 | protected: 131 | 132 | // step-wise smoothed coeff. 133 | class Coeff 134 | { 135 | public: 136 | 137 | Coeff() { reset(); } 138 | 139 | void reset() 140 | { 141 | m_value = m_vstep = 0.0f; 142 | m_nstep = 0; 143 | } 144 | 145 | void set_value(float value) 146 | { 147 | m_nstep = NUM_STEPS; 148 | m_vstep = (value - m_value) / float(m_nstep); 149 | } 150 | 151 | float value() const 152 | { return m_value + m_vstep * float(m_nstep); } 153 | 154 | float tick() 155 | { 156 | if (m_nstep > 0) { 157 | m_value += m_vstep; 158 | --m_nstep; 159 | } 160 | return m_value; 161 | } 162 | 163 | private: 164 | 165 | float m_value; 166 | float m_vstep; 167 | uint32_t m_nstep; 168 | }; 169 | 170 | // 2-pole resonator filter 171 | class Filter 172 | { 173 | public: 174 | 175 | Filter() { reset(); } 176 | 177 | void reset() 178 | { 179 | m_a0.reset(); 180 | m_b1.reset(); 181 | m_b2.reset(); 182 | 183 | m_out1 = m_out2 = 0.0f; 184 | } 185 | 186 | void reset_coeffs(const Coeffs& coeffs) 187 | { 188 | m_a0.set_value(coeffs.a0); 189 | m_b1.set_value(coeffs.b1); 190 | m_b2.set_value(coeffs.b2); 191 | } 192 | 193 | float output(float in) 194 | { 195 | const float out 196 | = m_a0.tick() * in 197 | + m_b1.tick() * m_out1 198 | - m_b2.tick() * m_out2; 199 | 200 | m_out2 = m_out1; 201 | m_out1 = out; 202 | return out; 203 | } 204 | 205 | private: 206 | 207 | Coeff m_a0, m_b1, m_b2; 208 | float m_out1, m_out2; 209 | }; 210 | 211 | // update method 212 | void update(float cutoff, float reso) 213 | { 214 | if (m_nstep > 0) 215 | --m_nstep; 216 | else 217 | if (::fabsf(m_cutoff - cutoff) > 0.001f || 218 | ::fabsf(m_reso - reso) > 0.001f) { 219 | m_nstep = NUM_STEPS; 220 | m_cutoff = cutoff; 221 | m_reso = reso; 222 | reset_coeffs(); 223 | } 224 | } 225 | 226 | // reset coeffs. method 227 | void reset_coeffs(); 228 | 229 | private: 230 | 231 | // instance members 232 | Impl *m_pImpl; 233 | 234 | // parameters. 235 | float m_cutoff; 236 | float m_reso; 237 | 238 | // slew-rate control. 239 | uint32_t m_nstep; 240 | 241 | // formant filters 242 | Filter m_filters[NUM_FORMANTS]; 243 | 244 | // base vocal tables 245 | static Vtab g_bass_vtab[NUM_VOWELS]; 246 | static Vtab g_tenor_vtab[NUM_VOWELS]; 247 | static Vtab g_countertenor_vtab[NUM_VOWELS]; 248 | static Vtab g_soprano_vtab[NUM_VOWELS]; 249 | static Vtab g_alto_vtab[NUM_VOWELS]; 250 | 251 | static Vtab *g_vtabs[NUM_VTABS]; 252 | }; 253 | 254 | 255 | #endif // __padthv1_formant_h 256 | 257 | // end of padthv1_formant.h 258 | -------------------------------------------------------------------------------- /src/padthv1widget_jack.cpp: -------------------------------------------------------------------------------- 1 | // padthv1widget_jack.cpp 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2012-2025, rncbc aka Rui Nuno Capela. All rights reserved. 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | 20 | *****************************************************************************/ 21 | 22 | #include "padthv1widget_jack.h" 23 | 24 | #include "padthv1widget_palette.h" 25 | 26 | #include "padthv1_jack.h" 27 | 28 | #ifdef CONFIG_NSM 29 | #include "padthv1_nsm.h" 30 | #endif 31 | 32 | #include 33 | #include 34 | #include 35 | 36 | #include 37 | 38 | #include 39 | 40 | #ifndef CONFIG_BINDIR 41 | #define CONFIG_BINDIR CONFIG_PREFIX "/bin" 42 | #endif 43 | 44 | #ifndef CONFIG_LIBDIR 45 | #if defined(__x86_64__) 46 | #define CONFIG_LIBDIR CONFIG_PREFIX "/lib64" 47 | #else 48 | #define CONFIG_LIBDIR CONFIG_PREFIX "/lib" 49 | #endif 50 | #endif 51 | 52 | #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) 53 | #define CONFIG_PLUGINSDIR CONFIG_LIBDIR "/qt4/plugins" 54 | #elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 55 | #define CONFIG_PLUGINSDIR CONFIG_LIBDIR "/qt5/plugins" 56 | #else 57 | #define CONFIG_PLUGINSDIR CONFIG_LIBDIR "/qt6/plugins" 58 | #endif 59 | 60 | 61 | //------------------------------------------------------------------------- 62 | // padthv1widget_jack - impl. 63 | // 64 | 65 | // Constructor. 66 | padthv1widget_jack::padthv1widget_jack ( padthv1_jack *pPadth ) 67 | : padthv1widget(), m_pPadth(pPadth) 68 | #ifdef CONFIG_NSM 69 | , m_pNsmClient(nullptr) 70 | #endif 71 | { 72 | // Special style paths... 73 | QString sPluginsPath = QApplication::applicationDirPath(); 74 | sPluginsPath.remove(CONFIG_BINDIR); 75 | sPluginsPath.append(CONFIG_PLUGINSDIR); 76 | if (QDir(sPluginsPath).exists()) 77 | QApplication::addLibraryPath(sPluginsPath); 78 | 79 | // Custom color/style themes... 80 | padthv1_config *pConfig = padthv1_config::getInstance(); 81 | if (pConfig) { 82 | const QChar sep = QDir::separator(); 83 | QString sPalettePath = QApplication::applicationDirPath(); 84 | sPalettePath.remove(CONFIG_BINDIR); 85 | sPalettePath.append(CONFIG_DATADIR); 86 | sPalettePath.append(sep); 87 | sPalettePath.append(PROJECT_NAME); 88 | sPalettePath.append(sep); 89 | sPalettePath.append("palette"); 90 | if (QDir(sPalettePath).exists()) { 91 | QStringList names; 92 | names.append("KXStudio"); 93 | names.append("Wonton Soup"); 94 | QStringListIterator name_iter(names); 95 | while (name_iter.hasNext()) { 96 | const QString& name = name_iter.next(); 97 | const QFileInfo fi(sPalettePath, name + ".conf"); 98 | if (fi.isReadable()) { 99 | padthv1widget_palette::addNamedPaletteConf( 100 | pConfig, name, fi.absoluteFilePath()); 101 | } 102 | } 103 | } 104 | if (!pConfig->sCustomColorTheme.isEmpty()) { 105 | QPalette pal; 106 | if (padthv1widget_palette::namedPalette( 107 | pConfig, pConfig->sCustomColorTheme, pal)) 108 | padthv1widget::setPalette(pal); 109 | } 110 | if (!pConfig->sCustomStyleTheme.isEmpty()) { 111 | QApplication::setStyle( 112 | QStyleFactory::create(pConfig->sCustomStyleTheme)); 113 | } 114 | } 115 | 116 | // Initialize (user) interface stuff... 117 | m_pPadthUi = new padthv1_ui(m_pPadth, false); 118 | 119 | // Initialise preset stuff... 120 | clearPreset(); 121 | 122 | // Initial update, always... 123 | updateSample(); 124 | 125 | resetParamValues(); 126 | resetParamKnobs(); 127 | 128 | // May initialize the scheduler/work notifier. 129 | openSchedNotifier(); 130 | } 131 | 132 | 133 | // Destructor. 134 | padthv1widget_jack::~padthv1widget_jack (void) 135 | { 136 | delete m_pPadthUi; 137 | } 138 | 139 | 140 | // Synth engine accessor. 141 | padthv1_ui *padthv1widget_jack::ui_instance (void) const 142 | { 143 | return m_pPadthUi; 144 | } 145 | 146 | #ifdef CONFIG_NSM 147 | 148 | // NSM client accessors. 149 | void padthv1widget_jack::setNsmClient ( padthv1_nsm *pNsmClient ) 150 | { 151 | m_pNsmClient = pNsmClient; 152 | } 153 | 154 | padthv1_nsm *padthv1widget_jack::nsmClient (void) const 155 | { 156 | return m_pNsmClient; 157 | } 158 | 159 | #endif // CONFIG_NSM 160 | 161 | 162 | // Param port method. 163 | void padthv1widget_jack::updateParam ( 164 | padthv1::ParamIndex index, float fValue ) const 165 | { 166 | m_pPadthUi->setParamValue(index, fValue); 167 | } 168 | 169 | 170 | // Dirty flag method. 171 | void padthv1widget_jack::updateDirtyPreset ( bool bDirtyPreset ) 172 | { 173 | padthv1widget::updateDirtyPreset(bDirtyPreset); 174 | 175 | #ifdef CONFIG_NSM 176 | if (m_pNsmClient && m_pNsmClient->is_active() && bDirtyPreset) 177 | m_pNsmClient->dirty(true); 178 | #endif 179 | } 180 | 181 | 182 | // Application close. 183 | void padthv1widget_jack::closeEvent ( QCloseEvent *pCloseEvent ) 184 | { 185 | #ifdef CONFIG_NSM 186 | if (m_pNsmClient && m_pNsmClient->is_active()) { 187 | pCloseEvent->ignore(); 188 | padthv1widget::hide(); 189 | } 190 | else 191 | #endif 192 | // Let's be sure about that... 193 | if (queryClose()) { 194 | pCloseEvent->accept(); 195 | #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) 196 | QApplication::exit(0); 197 | #else 198 | QApplication::quit(); 199 | #endif 200 | } else { 201 | pCloseEvent->ignore(); 202 | } 203 | } 204 | 205 | 206 | #ifdef CONFIG_NSM 207 | 208 | // Optional GUI handlers. 209 | void padthv1widget_jack::showEvent ( QShowEvent *pShowEvent ) 210 | { 211 | padthv1widget::showEvent(pShowEvent); 212 | 213 | if (m_pNsmClient) 214 | m_pNsmClient->visible(true); 215 | } 216 | 217 | void padthv1widget_jack::hideEvent ( QHideEvent *pHideEvent ) 218 | { 219 | if (m_pNsmClient) 220 | m_pNsmClient->visible(false); 221 | 222 | padthv1widget::hideEvent(pHideEvent); 223 | } 224 | 225 | #endif // CONFIG_NSM 226 | 227 | 228 | // end of padthv1widget_jack.cpp 229 | -------------------------------------------------------------------------------- /src/padthv1_filter.h: -------------------------------------------------------------------------------- 1 | // padthv1_filter.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2012-2021, rncbc aka Rui Nuno Capela. All rights reserved. 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | 20 | *****************************************************************************/ 21 | 22 | #ifndef __padthv1_filter_h 23 | #define __padthv1_filter_h 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | 30 | //------------------------------------------------------------------------- 31 | // padthv1_filter1 - Hal Chamberlin's State Variable (12dB/oct) filter 32 | // 33 | 34 | class padthv1_filter1 35 | { 36 | public: 37 | 38 | enum Type { Low = 0, Band, High, Notch }; 39 | 40 | padthv1_filter1(Type type = Low, uint16_t nover = 2) 41 | { reset(type, nover); } 42 | 43 | Type type() const 44 | { return m_type; } 45 | 46 | void reset(Type type = Low, uint16_t nover = 2) 47 | { 48 | m_type = type; 49 | m_nover = nover; 50 | 51 | m_low = 0.0f; 52 | m_band = 0.0f; 53 | m_high = 0.0f; 54 | m_notch = 0.0f; 55 | 56 | switch (m_type) { 57 | case Notch: 58 | m_out = &m_notch; 59 | break; 60 | case High: 61 | m_out = &m_high; 62 | break; 63 | case Band: 64 | m_out = &m_band; 65 | break; 66 | case Low: 67 | default: 68 | m_out = &m_low; 69 | break; 70 | } 71 | } 72 | 73 | float output(float in, float cutoff, float reso) 74 | { 75 | const float q = (1.0f - reso); 76 | 77 | for (uint16_t i = 0; i < m_nover; ++i) { 78 | m_low += cutoff * m_band; 79 | m_high = in - m_low - q * m_band; 80 | m_band += cutoff * m_high; 81 | m_notch = m_high + m_low; 82 | } 83 | 84 | return *m_out; 85 | } 86 | 87 | private: 88 | 89 | Type m_type; 90 | 91 | uint16_t m_nover; 92 | 93 | float m_low; 94 | float m_band; 95 | float m_high; 96 | float m_notch; 97 | 98 | float *m_out; 99 | }; 100 | 101 | 102 | //------------------------------------------------------------------------- 103 | // padthv1_filter2 - Stilson/Smith Moog (24dB/oct) filter 104 | // 105 | 106 | class padthv1_filter2 107 | { 108 | public: 109 | 110 | enum Type { Low = 0, Band, High, Notch }; 111 | 112 | padthv1_filter2(Type type = Low) { reset(type); } 113 | 114 | Type type() const 115 | { return m_type; } 116 | 117 | void reset(Type type = Low) 118 | { 119 | m_type = type; 120 | 121 | m_b0 = m_b1 = m_b2 = m_b3 = m_b4 = 0.0f; 122 | m_t1 = m_t2 = 0.0f; 123 | } 124 | 125 | float output(float in, float cutoff, float reso) 126 | { 127 | const float c = 1.0f - cutoff; 128 | const float p = cutoff + 0.8f * cutoff * c; 129 | const float f = p + p - 1.0f; 130 | const float q = reso * (1.0f + 0.5f * c * (1.0f - c + 5.6f * c * c)); 131 | 132 | in -= q * m_b4; // feedback 133 | 134 | m_t1 = m_b1; m_b1 = (in + m_b0) * p - m_b1 * f; 135 | m_t2 = m_b2; m_b2 = (m_b1 + m_t1) * p - m_b2 * f; 136 | m_t1 = m_b3; m_b3 = (m_b2 + m_t2) * p - m_b3 * f; 137 | 138 | m_b4 = (m_b3 + m_t1) * p - m_b4 * f; 139 | m_b4 = m_b4 - m_b4 * m_b4 * m_b4 * 0.166667f; // clipping 140 | 141 | m_b0 = in; 142 | 143 | switch (m_type) { 144 | case Notch: 145 | return 3.0f * (m_b3 - m_b4) - in; 146 | case High: 147 | return in - m_b4; 148 | case Band: 149 | return 3.0f * (m_b3 - m_b4); 150 | case Low: 151 | default: 152 | return m_b4; 153 | } 154 | } 155 | 156 | private: 157 | 158 | // filter type 159 | Type m_type; 160 | 161 | float m_b0, m_b1, m_b2, m_b3, m_b4; 162 | float m_t1, m_t2; 163 | }; 164 | 165 | 166 | //------------------------------------------------------------------------- 167 | // padthv1_filter3 - RBJ biquad filter implementation. 168 | // 169 | // http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt 170 | 171 | class padthv1_filter3 172 | { 173 | public: 174 | 175 | enum Type { Low = 0, Band, High, Notch }; 176 | 177 | padthv1_filter3(Type type = Low) 178 | : m_type(type), m_cutoff(0.5f), m_reso(0.0f) { reset(type); } 179 | 180 | Type type() const 181 | { return m_type; } 182 | 183 | void reset(Type type) 184 | { 185 | m_type = type; 186 | 187 | m_out1 = m_out2 = 0.0f; 188 | m_in1 = m_in2 = 0.0f; 189 | 190 | reset(); 191 | } 192 | 193 | float output(float in, float cutoff, float reso) 194 | { 195 | // parameter changes 196 | if (::fabsf(m_cutoff - cutoff) > 0.001f || 197 | ::fabsf(m_reso - reso) > 0.001f) { 198 | m_cutoff = cutoff; 199 | m_reso = reso; 200 | reset(); 201 | } 202 | 203 | // filter 204 | const float out = m_b0a0 * in 205 | + m_b1a0 * m_in1 + m_b2a0 * m_in2 206 | - m_a1a0 * m_out1 - m_a2a0 * m_out2; 207 | 208 | // push in/out buffers 209 | m_in2 = m_in1; 210 | m_in1 = in; 211 | m_out2 = m_out1; 212 | m_out1 = out; 213 | 214 | // return output 215 | return out; 216 | } 217 | 218 | protected: 219 | 220 | void reset() 221 | { 222 | const float q = 2.0f * m_reso * m_reso + 1.0f; 223 | 224 | const float omega = M_PI * m_cutoff; 225 | const float tsin = ::sinf(omega); 226 | const float tcos = ::cosf(omega); 227 | const float alpha = tsin / (2.0f * q); 228 | 229 | // temp vars 230 | const float a0 = 1.0f + alpha; 231 | const float a1 = -2.0f * tcos; 232 | const float a2 = 1.0f - alpha; 233 | 234 | float b0, b1, b2; 235 | 236 | switch (m_type) { 237 | case Notch: 238 | b0 = 1.0f; 239 | b1 = -2.0f * tcos; 240 | b2 = 1.0f; 241 | break; 242 | case High: 243 | b0 = (1.0f + tcos) / 2.0f; 244 | b1 = -1.0f - tcos; 245 | b2 = b0; 246 | break; 247 | case Band: 248 | b0 = tsin / 2.0f; 249 | b1 = 0.0f; 250 | b2 = -b0; 251 | break; 252 | case Low: 253 | default: 254 | b0 = (1.0f - tcos) / 2.0f; 255 | b1 = 1.0f - tcos; 256 | b2 = b0; 257 | break; 258 | } 259 | 260 | // set filter coeffs 261 | m_b0a0 = b0 / a0; 262 | m_b1a0 = b1 / a0; 263 | m_b2a0 = b2 / a0; 264 | m_a1a0 = a1 / a0; 265 | m_a2a0 = a2 / a0; 266 | } 267 | 268 | private: 269 | 270 | // filter type 271 | Type m_type; 272 | 273 | // filter params 274 | float m_cutoff; 275 | float m_reso; 276 | 277 | // filter coeffs 278 | float m_b0a0, m_b1a0, m_b2a0, m_a1a0, m_a2a0; 279 | 280 | // in/out history 281 | float m_out1, m_out2, m_in1, m_in2; 282 | }; 283 | 284 | 285 | #endif // __padthv1_filter_h 286 | 287 | 288 | // end of padthv1_filter.h 289 | -------------------------------------------------------------------------------- /src/padthv1_ramp.h: -------------------------------------------------------------------------------- 1 | // padthv1_ramp.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2012-2021, rncbc aka Rui Nuno Capela. All rights reserved. 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | 20 | *****************************************************************************/ 21 | 22 | #ifndef __padthv1_ramp_h 23 | #define __padthv1_ramp_h 24 | 25 | #include 26 | #include 27 | 28 | 29 | //------------------------------------------------------------------------- 30 | // padthv1_ramp - ramp/smooth parameter changes 31 | 32 | class padthv1_ramp 33 | { 34 | public: 35 | 36 | padthv1_ramp(uint16_t nvalues = 1) 37 | { 38 | m_nvalues = nvalues; 39 | m_value0 = new float [m_nvalues]; 40 | m_value1 = new float [m_nvalues]; 41 | m_delta = new float [m_nvalues]; 42 | 43 | for (uint16_t i = 0; i < m_nvalues; ++i) 44 | m_value0[i] = m_value1[i] = m_delta[i] = 0.0f; 45 | 46 | m_frames = 0; 47 | } 48 | 49 | virtual ~padthv1_ramp() 50 | { 51 | delete [] m_delta; 52 | delete [] m_value1; 53 | delete [] m_value0; 54 | } 55 | 56 | void reset() 57 | { 58 | for (uint16_t i = 0; i < m_nvalues; ++i) { 59 | m_value0[i] = m_value1[i]; 60 | m_value1[i] = evaluate(i); 61 | } 62 | 63 | m_frames = 0; 64 | } 65 | 66 | void process(uint32_t nframes) 67 | { 68 | if (m_frames > 0) { 69 | if (nframes > m_frames) 70 | nframes = m_frames; 71 | for (uint16_t i = 0; i < m_nvalues; ++i) 72 | m_value0[i] += float(nframes) * m_delta[i]; 73 | m_frames -= nframes; 74 | } 75 | else 76 | if (probe()) { 77 | reset(); 78 | m_frames = nframes; 79 | const uint32_t MIN_FRAMES = 32; 80 | if (m_frames < MIN_FRAMES) 81 | m_frames = MIN_FRAMES; 82 | for (uint16_t i = 0; i < m_nvalues; ++i) 83 | m_delta[i] = (m_value1[i] - m_value0[i]) / float(m_frames); 84 | } 85 | } 86 | 87 | float value(uint32_t n, uint16_t i = 0) const 88 | { 89 | return (n < m_frames ? (m_value0[i] + float(n) * m_delta[i]) : m_value1[i]); 90 | } 91 | 92 | protected: 93 | 94 | virtual bool probe() const = 0; 95 | virtual float evaluate(uint16_t i) = 0; 96 | 97 | private: 98 | 99 | uint16_t m_nvalues; 100 | 101 | float *m_value1; 102 | float *m_value0; 103 | float *m_delta; 104 | 105 | uint32_t m_frames; 106 | }; 107 | 108 | 109 | //------------------------------------------------------------------------- 110 | // padthv1_ramp1 (1 port tracking) 111 | 112 | class padthv1_ramp1 : public padthv1_ramp 113 | { 114 | public: 115 | 116 | padthv1_ramp1(uint16_t nvalues = 1) 117 | : padthv1_ramp(nvalues), m_param1(nullptr), m_param1_v(0.0f) {} 118 | 119 | void reset(float *param1) 120 | { 121 | m_param1 = param1; 122 | m_param1_v = 0.0f; 123 | 124 | padthv1_ramp::reset(); 125 | } 126 | 127 | protected: 128 | 129 | virtual bool probe() const 130 | { 131 | return m_param1 && ::fabsf(*m_param1 - m_param1_v) > 0.001f; 132 | } 133 | 134 | virtual float evaluate(uint16_t) 135 | { 136 | update(); 137 | 138 | return m_param1_v; 139 | } 140 | 141 | void update() 142 | { 143 | if (m_param1) 144 | m_param1_v = *m_param1; 145 | } 146 | 147 | float *m_param1; 148 | float m_param1_v; 149 | }; 150 | 151 | 152 | //------------------------------------------------------------------------- 153 | // padthv1_ramp2 (2 port tracking) 154 | 155 | class padthv1_ramp2 : public padthv1_ramp1 156 | { 157 | public: 158 | 159 | padthv1_ramp2(uint16_t nvalues = 1) 160 | : padthv1_ramp1(nvalues), m_param2(nullptr), m_param2_v(0.0f) {} 161 | 162 | void reset(float *param1, float *param2) 163 | { 164 | m_param2 = param2; 165 | m_param2_v = 0.0f; 166 | 167 | padthv1_ramp1::reset(param1); 168 | } 169 | 170 | protected: 171 | 172 | virtual bool probe() const 173 | { 174 | return padthv1_ramp1::probe() 175 | || (m_param2 && ::fabsf(*m_param2 - m_param2_v) > 0.001f); 176 | } 177 | 178 | virtual float evaluate(uint16_t i) 179 | { 180 | update(); 181 | 182 | return padthv1_ramp1::evaluate(i) * m_param2_v; 183 | } 184 | 185 | void update() 186 | { 187 | padthv1_ramp1::update(); 188 | 189 | if (m_param2) 190 | m_param2_v = *m_param2; 191 | } 192 | 193 | float *m_param2; 194 | float m_param2_v; 195 | }; 196 | 197 | 198 | //------------------------------------------------------------------------- 199 | // padthv1_ramp3 (3 port tracking) 200 | 201 | class padthv1_ramp3 : public padthv1_ramp2 202 | { 203 | public: 204 | 205 | padthv1_ramp3(uint16_t nvalues = 1) 206 | : padthv1_ramp2(nvalues), m_param3(nullptr), m_param3_v(0.0f) {} 207 | 208 | void reset(float *param1, float *param2, float *param3) 209 | { 210 | m_param3 = param3; 211 | m_param3_v = 0.0f; 212 | 213 | padthv1_ramp2::reset(param1, param2); 214 | } 215 | 216 | protected: 217 | 218 | virtual bool probe() const 219 | { 220 | return padthv1_ramp2::probe() 221 | || (m_param3 && ::fabsf(*m_param3 - m_param3_v) > 0.001f); 222 | } 223 | 224 | virtual float evaluate(uint16_t i) 225 | { 226 | update(); 227 | 228 | return padthv1_ramp2::evaluate(i) * m_param3_v; 229 | } 230 | 231 | void update() 232 | { 233 | padthv1_ramp2::update(); 234 | 235 | if (m_param3) 236 | m_param3_v = *m_param3; 237 | } 238 | 239 | float *m_param3; 240 | float m_param3_v; 241 | }; 242 | 243 | 244 | 245 | 246 | //------------------------------------------------------------------------- 247 | // padthv1_ramp4 (4 port tracking) 248 | 249 | class padthv1_ramp4 : public padthv1_ramp3 250 | { 251 | public: 252 | 253 | padthv1_ramp4(uint16_t nvalues = 1) 254 | : padthv1_ramp3(nvalues), m_param4(nullptr), m_param4_v(0.0f) {} 255 | 256 | void reset(float *param1, float *param2, float *param3, float *param4) 257 | { 258 | m_param4 = param4; 259 | m_param4_v = 0.0f; 260 | 261 | padthv1_ramp3::reset(param1, param2, param3); 262 | } 263 | 264 | protected: 265 | 266 | virtual bool probe() const 267 | { 268 | return padthv1_ramp3::probe() 269 | || (m_param4 && ::fabsf(*m_param4 - m_param4_v) > 0.001f); 270 | } 271 | 272 | virtual float evaluate(uint16_t i) 273 | { 274 | update(); 275 | 276 | return padthv1_ramp3::evaluate(i) * m_param4_v; 277 | } 278 | 279 | void update() 280 | { 281 | padthv1_ramp3::update(); 282 | 283 | if (m_param4) 284 | m_param4_v = *m_param4; 285 | } 286 | 287 | float *m_param4; 288 | float m_param4_v; 289 | }; 290 | 291 | 292 | #endif // __padthv1_ramp_h 293 | 294 | // end of padthv1_ramp.h 295 | -------------------------------------------------------------------------------- /src/lv2/lv2_programs.h: -------------------------------------------------------------------------------- 1 | /* 2 | LV2 Programs Extension 3 | Copyright 2012 Filipe Coelho 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted, provided that the above 7 | copyright notice and this permission notice appear in all copies. 8 | 9 | THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | */ 17 | 18 | /** 19 | @file lv2_programs.h 20 | C header for the LV2 programs extension . 21 | */ 22 | 23 | #ifndef LV2_PROGRAMS_H 24 | #define LV2_PROGRAMS_H 25 | 26 | #ifdef CONFIG_LV2_OLD_HEADERS 27 | #include "lv2.h" 28 | #include "lv2/lv2plug.in/ns/extensions/ui/ui.h" 29 | #else 30 | #include "lv2/core/lv2.h" 31 | #include "lv2//ui/ui.h" 32 | #endif 33 | 34 | #define LV2_PROGRAMS_URI "http://kxstudio.sf.net/ns/lv2ext/programs" 35 | #define LV2_PROGRAMS_PREFIX LV2_PROGRAMS_URI "#" 36 | 37 | #define LV2_PROGRAMS__Host LV2_PROGRAMS_PREFIX "Host" 38 | #define LV2_PROGRAMS__Interface LV2_PROGRAMS_PREFIX "Interface" 39 | #define LV2_PROGRAMS__UIInterface LV2_PROGRAMS_PREFIX "UIInterface" 40 | 41 | #ifdef __cplusplus 42 | extern "C" { 43 | #endif 44 | 45 | typedef void* LV2_Programs_Handle; 46 | 47 | typedef struct _LV2_Program_Descriptor { 48 | 49 | /** Bank number for this program. Note that this extension does not 50 | support MIDI-style separation of bank LSB and MSB values. There is 51 | no restriction on the set of available banks: the numbers do not 52 | need to be contiguous, there does not need to be a bank 0, etc. */ 53 | uint32_t bank; 54 | 55 | /** Program number (unique within its bank) for this program. There is 56 | no restriction on the set of available programs: the numbers do not 57 | need to be contiguous, there does not need to be a program 0, etc. */ 58 | uint32_t program; 59 | 60 | /** Name of the program. */ 61 | const char * name; 62 | 63 | } LV2_Program_Descriptor; 64 | 65 | /** 66 | Programs extension, plugin data. 67 | 68 | When the plugin's extension_data is called with argument LV2_PROGRAMS__Interface, 69 | the plugin MUST return an LV2_Programs_Instance structure, which remains valid 70 | for the lifetime of the plugin. 71 | */ 72 | typedef struct _LV2_Programs_Interface { 73 | /** 74 | * get_program() 75 | * 76 | * This member is a function pointer that provides a description 77 | * of a program (named preset sound) available on this plugin. 78 | * 79 | * The index argument is an index into the plugin's list of 80 | * programs, not a program number as represented by the Program 81 | * field of the LV2_Program_Descriptor. (This distinction is 82 | * needed to support plugins that use non-contiguous program or 83 | * bank numbers.) 84 | * 85 | * This function returns a LV2_Program_Descriptor pointer that is 86 | * guaranteed to be valid only until the next call to get_program 87 | * or deactivate, on the same plugin instance. This function must 88 | * return NULL if passed an index argument out of range, so that 89 | * the host can use it to query the number of programs as well as 90 | * their properties. 91 | */ 92 | const LV2_Program_Descriptor *(*get_program)(LV2_Handle handle, 93 | uint32_t index); 94 | 95 | /** 96 | * select_program() 97 | * 98 | * This member is a function pointer that selects a new program 99 | * for this plugin. The program change should take effect 100 | * immediately at the start of the next run() call. (This 101 | * means that a host providing the capability of changing programs 102 | * between any two notes on a track must vary the block size so as 103 | * to place the program change at the right place. A host that 104 | * wanted to avoid this would probably just instantiate a plugin 105 | * for each program.) 106 | * 107 | * Plugins should ignore a select_program() call with an invalid 108 | * bank or program. 109 | * 110 | * A plugin is not required to select any particular default 111 | * program on activate(): it's the host's duty to set a program 112 | * explicitly. 113 | * 114 | * A plugin is permitted to re-write the values of its input 115 | * control ports when select_program is called. The host should 116 | * re-read the input control port values and update its own 117 | * records appropriately. (This is the only circumstance in which 118 | * a LV2 plugin is allowed to modify its own control-input ports.) 119 | */ 120 | void (*select_program)(LV2_Handle handle, 121 | uint32_t bank, 122 | uint32_t program); 123 | 124 | } LV2_Programs_Interface; 125 | 126 | /** 127 | Programs extension, UI data. 128 | 129 | When the UI's extension_data is called with argument LV2_PROGRAMS__UIInterface, 130 | the UI MUST return an LV2_Programs_UI_Interface structure, which remains valid 131 | for the lifetime of the UI. 132 | */ 133 | typedef struct _LV2_Programs_UI_Interface { 134 | /** 135 | * select_program() 136 | * 137 | * This is exactly the same as select_program in LV2_Programs_Instance, 138 | * but this struct relates to the UI instead of the plugin. 139 | * 140 | * When called, UIs should update their state to match the selected program. 141 | */ 142 | void (*select_program)(LV2UI_Handle handle, 143 | uint32_t bank, 144 | uint32_t program); 145 | 146 | } LV2_Programs_UI_Interface; 147 | 148 | /** 149 | Feature data for LV2_PROGRAMS__Host. 150 | */ 151 | typedef struct _LV2_Programs_Host { 152 | /** 153 | * Opaque host data. 154 | */ 155 | LV2_Programs_Handle handle; 156 | 157 | /** 158 | * program_changed() 159 | * 160 | * Tell the host to reload a plugin's program. 161 | * Parameter handle MUST be the 'handle' member of this struct. 162 | * Parameter index is program index to change. 163 | * When index is -1, host should reload all the programs. 164 | * 165 | * The plugin MUST NEVER call this function on a RT context or during run(). 166 | * 167 | * NOTE: This call is to inform the host about a program's bank, program or name change. 168 | * It DOES NOT change the current selected program. 169 | */ 170 | void (*program_changed)(LV2_Programs_Handle handle, 171 | int32_t index); 172 | 173 | } LV2_Programs_Host; 174 | 175 | #ifdef __cplusplus 176 | } /* extern "C" */ 177 | #endif 178 | 179 | #endif /* LV2_PROGRAMS_H */ 180 | -------------------------------------------------------------------------------- /src/padthv1widget_wave.cpp: -------------------------------------------------------------------------------- 1 | // padthv1widget_wave.cpp 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2012-2021, rncbc aka Rui Nuno Capela. All rights reserved. 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | 20 | *****************************************************************************/ 21 | 22 | #include "padthv1widget_wave.h" 23 | 24 | #include "padthv1_wave.h" 25 | 26 | #include 27 | #include 28 | 29 | #include 30 | 31 | #include 32 | #include 33 | 34 | 35 | // Safe value capping. 36 | inline float safe_value ( float x ) 37 | { 38 | return (x < 0.0f ? 0.0f : (x > 1.0f ? 1.0f : x)); 39 | } 40 | 41 | 42 | //---------------------------------------------------------------------------- 43 | // padthv1widget_wave -- Custom widget 44 | 45 | // Constructor. 46 | padthv1widget_wave::padthv1widget_wave ( QWidget *pParent ) 47 | : QFrame(pParent), 48 | m_bDragging(false), m_iDragShape(0) 49 | { 50 | m_pWave = new padthv1_wave_lf(128); 51 | 52 | setFixedSize(QSize(60, 60)); 53 | 54 | QFrame::setFrameShape(QFrame::Panel); 55 | QFrame::setFrameShadow(QFrame::Sunken); 56 | } 57 | 58 | 59 | // Destructor. 60 | padthv1widget_wave::~padthv1widget_wave (void) 61 | { 62 | delete m_pWave; 63 | } 64 | 65 | 66 | // Parameter accessors. 67 | void padthv1widget_wave::setWaveShape ( float fWaveShape ) 68 | { 69 | int iWaveShape = int(fWaveShape); 70 | if (iWaveShape != int(m_pWave->shape())) { 71 | if (iWaveShape < int(padthv1_wave::Pulse)) 72 | iWaveShape = int(padthv1_wave::Noise); 73 | else 74 | if (iWaveShape > int(padthv1_wave::Noise)) 75 | iWaveShape = int(padthv1_wave::Pulse); 76 | m_pWave->reset(padthv1_wave::Shape(iWaveShape), m_pWave->width()); 77 | update(); 78 | emit waveShapeChanged(waveShape()); 79 | } 80 | } 81 | 82 | float padthv1widget_wave::waveShape (void) const 83 | { 84 | return float(m_pWave->shape()); 85 | } 86 | 87 | 88 | void padthv1widget_wave::setWaveWidth ( float fWaveWidth ) 89 | { 90 | if (qAbs(fWaveWidth - m_pWave->width()) > 0.001f) { 91 | m_pWave->reset(m_pWave->shape(), safe_value(fWaveWidth)); 92 | update(); 93 | emit waveWidthChanged(waveWidth()); 94 | } 95 | } 96 | 97 | float padthv1widget_wave::waveWidth (void) const 98 | { 99 | return m_pWave->width(); 100 | } 101 | 102 | 103 | // Draw curve. 104 | void padthv1widget_wave::paintEvent ( QPaintEvent *pPaintEvent ) 105 | { 106 | QPainter painter(this); 107 | 108 | const QRect& rect = QWidget::rect(); 109 | const int h = rect.height(); 110 | const int w = rect.width(); 111 | 112 | const int h2 = (h >> 1); 113 | const int w2 = (w >> 1); 114 | 115 | QPainterPath path; 116 | path.moveTo(0, h2); 117 | for (int x = 1; x < w; ++x) 118 | path.lineTo(x, h2 - int(m_pWave->value(float(x) / float(w)) * float(h2 - 2))); 119 | path.lineTo(w, h2); 120 | 121 | const QPalette& pal = palette(); 122 | const bool bDark = (pal.window().color().value() < 0x7f); 123 | const QColor& rgbLite = (isEnabled() ? Qt::yellow : pal.mid().color()); 124 | const QColor& rgbDark = pal.window().color().darker(); 125 | 126 | painter.fillRect(rect, rgbDark); 127 | 128 | painter.setPen(pal.mid().color()); 129 | painter.drawLine(w2, 0, w2, h); 130 | painter.drawLine(0, h2, w, h2); 131 | 132 | QColor rgbLite1(rgbLite); 133 | QColor rgbDrop1(Qt::black); 134 | rgbLite1.setAlpha(bDark ? 120 : 180); 135 | rgbDrop1.setAlpha(80); 136 | 137 | QLinearGradient grad(0, 0, w << 1, h << 1); 138 | grad.setColorAt(0.0f, rgbLite1.darker(bDark ? 200 : 160)); 139 | grad.setColorAt(1.0f, rgbDrop1); 140 | 141 | painter.setRenderHint(QPainter::Antialiasing, true); 142 | 143 | path.translate(+1, +1); 144 | painter.setPen(QPen(rgbDrop1, 2)); 145 | painter.setBrush(Qt::transparent); 146 | painter.drawPath(path); 147 | path.translate(-1, -1); 148 | painter.setPen(QPen(rgbLite1, 2)); 149 | painter.drawPath(path); 150 | 151 | path.lineTo(1, h2); 152 | painter.setPen(Qt::transparent); 153 | painter.setBrush(grad); 154 | painter.drawPath(path); 155 | 156 | painter.setRenderHint(QPainter::Antialiasing, false); 157 | 158 | painter.end(); 159 | 160 | QFrame::paintEvent(pPaintEvent); 161 | } 162 | 163 | 164 | // Drag/move curve. 165 | void padthv1widget_wave::dragCurve ( const QPoint& pos ) 166 | { 167 | const int h = height(); 168 | const int w = width(); 169 | 170 | const int dx = (pos.x() - m_posDrag.x()); 171 | const int dy = (pos.y() - m_posDrag.y()); 172 | 173 | if (dx || dy) { 174 | const int x = int(waveWidth() * float(w)); 175 | setWaveWidth(float(x + dx) / float(w)); 176 | const int h2 = (h >> 1); 177 | m_iDragShape += dy; 178 | if (m_iDragShape > +h2) { 179 | setWaveShape(waveShape() - 1); 180 | m_iDragShape = 0; 181 | } 182 | else 183 | if (m_iDragShape < -h2) { 184 | setWaveShape(waveShape() + 1); 185 | m_iDragShape = 0; 186 | } 187 | m_posDrag = pos; 188 | } 189 | } 190 | 191 | 192 | // Mouse interaction. 193 | void padthv1widget_wave::mousePressEvent ( QMouseEvent *pMouseEvent ) 194 | { 195 | if (pMouseEvent->button() == Qt::LeftButton) 196 | m_posDrag = pMouseEvent->pos(); 197 | 198 | QFrame::mousePressEvent(pMouseEvent); 199 | } 200 | 201 | 202 | void padthv1widget_wave::mouseMoveEvent ( QMouseEvent *pMouseEvent ) 203 | { 204 | const QPoint& pos = pMouseEvent->pos(); 205 | if (m_bDragging) { 206 | dragCurve(pos); 207 | } else if ((pos - m_posDrag).manhattanLength() > 4) { 208 | setCursor(Qt::SizeAllCursor); 209 | m_bDragging = true; 210 | m_iDragShape = 0; 211 | } 212 | } 213 | 214 | 215 | void padthv1widget_wave::mouseReleaseEvent ( QMouseEvent *pMouseEvent ) 216 | { 217 | QFrame::mouseReleaseEvent(pMouseEvent); 218 | 219 | if (m_bDragging) { 220 | dragCurve(pMouseEvent->pos()); 221 | m_bDragging = false; 222 | unsetCursor(); 223 | } 224 | } 225 | 226 | 227 | void padthv1widget_wave::mouseDoubleClickEvent ( QMouseEvent *pMouseEvent ) 228 | { 229 | QFrame::mouseDoubleClickEvent(pMouseEvent); 230 | 231 | if (!m_bDragging) 232 | setWaveShape(waveShape() + 1); 233 | } 234 | 235 | 236 | void padthv1widget_wave::wheelEvent ( QWheelEvent *pWheelEvent ) 237 | { 238 | const int delta = (pWheelEvent->angleDelta().y() / 60); 239 | 240 | if (pWheelEvent->modifiers() & (Qt::ShiftModifier | Qt::ControlModifier)) { 241 | setWaveShape(waveShape() + (delta < 0 ? -1 : +1)); 242 | } else { 243 | const float w2 = float(width() >> 1); 244 | const int x = int(waveWidth() * w2); 245 | setWaveWidth(float(x + delta) / w2); 246 | } 247 | } 248 | 249 | 250 | // end of padthv1widget_wave.cpp 251 | --------------------------------------------------------------------------------