├── .gitignore
├── CMakeLists.txt
├── ChangeLog
├── LICENSE
├── README
├── debian
├── changelog
├── compat
├── control
├── copyright
├── docs
├── rules
├── synthv1-jack.docs
├── synthv1-jack.install
└── synthv1-lv2.install
├── rpm
└── synthv1.spec
└── src
├── CMakeLists.txt
├── appdata
├── org.rncbc.synthv1.desktop
└── org.rncbc.synthv1.metainfo.xml
├── config.h.cmake
├── images
├── fileOpen.png
├── itemReset.png
├── ledOff.png
├── ledOn.png
├── presetBank.png
├── presetBankOpen.png
├── presetDelete.png
├── presetEdit.png
├── presetNew.png
├── presetOpen.png
├── presetSave.png
├── synthv1.png
├── synthv1.svg
├── synthv1_control.png
└── synthv1_preset.png
├── lv2
├── lv2_external_ui.h
├── lv2_port_change_request.h
└── lv2_programs.h
├── man1
├── synthv1.1
└── synthv1.fr.1
├── mimetypes
├── org.rncbc.synthv1.application-x-synthv1-preset.png
├── org.rncbc.synthv1.application-x-synthv1-preset.svg
└── org.rncbc.synthv1.xml
├── palette
├── KXStudio.conf
└── Wonton Soup.conf
├── synthv1.cpp
├── synthv1.h
├── synthv1.lv2
├── manifest-win32.ttl
├── manifest.ttl
├── synthv1.ttl
├── synthv1_ui-win32.ttl
└── synthv1_ui.ttl
├── synthv1.qrc
├── synthv1_config.cpp
├── synthv1_config.h
├── synthv1_controls.cpp
├── synthv1_controls.h
├── synthv1_filter.h
├── synthv1_formant.cpp
├── synthv1_formant.h
├── synthv1_fx.h
├── synthv1_jack.cpp
├── synthv1_jack.h
├── synthv1_list.h
├── synthv1_lv2.cpp
├── synthv1_lv2.h
├── synthv1_lv2ui.cpp
├── synthv1_lv2ui.h
├── synthv1_nsm.cpp
├── synthv1_nsm.h
├── synthv1_param.cpp
├── synthv1_param.h
├── synthv1_programs.cpp
├── synthv1_programs.h
├── synthv1_ramp.h
├── synthv1_reverb.h
├── synthv1_sched.cpp
├── synthv1_sched.h
├── synthv1_tuning.cpp
├── synthv1_tuning.h
├── synthv1_ui.cpp
├── synthv1_ui.h
├── synthv1_wave.cpp
├── synthv1_wave.h
├── synthv1widget.cpp
├── synthv1widget.h
├── synthv1widget.ui
├── synthv1widget_config.cpp
├── synthv1widget_config.h
├── synthv1widget_config.ui
├── synthv1widget_control.cpp
├── synthv1widget_control.h
├── synthv1widget_control.ui
├── synthv1widget_controls.cpp
├── synthv1widget_controls.h
├── synthv1widget_env.cpp
├── synthv1widget_env.h
├── synthv1widget_filt.cpp
├── synthv1widget_filt.h
├── synthv1widget_jack.cpp
├── synthv1widget_jack.h
├── synthv1widget_keybd.cpp
├── synthv1widget_keybd.h
├── synthv1widget_lv2.cpp
├── synthv1widget_lv2.h
├── synthv1widget_palette.cpp
├── synthv1widget_palette.h
├── synthv1widget_palette.ui
├── synthv1widget_param.cpp
├── synthv1widget_param.h
├── synthv1widget_preset.cpp
├── synthv1widget_preset.h
├── synthv1widget_programs.cpp
├── synthv1widget_programs.h
├── synthv1widget_status.cpp
├── synthv1widget_status.h
├── synthv1widget_wave.cpp
└── synthv1widget_wave.h
/.gitignore:
--------------------------------------------------------------------------------
1 | build*
2 | *.txt.user
3 |
--------------------------------------------------------------------------------
/README:
--------------------------------------------------------------------------------
1 | synthv1 - an old-school polyphonic synthesizer
2 | ----------------------------------------------
3 |
4 | an old-school 4-oscillator subtractive polyphonic synthesizer
5 | with stereo fx.
6 |
7 | Features:
8 |
9 | - pure stand-alone JACK [1] client with JACK-session, NSM [3] and both
10 | JACK MIDI and ALSA MIDI [2] input support;
11 |
12 | - LV2 [4] instrument plugin.
13 | URI: http://synthv1.sourceforge.net/lv2
14 |
15 | License:
16 |
17 | synthv1 is free, Linux Audio [5] open-source software, distributed under
18 | the terms of the GNU General Public License (GPL) [6] version 2 or later.
19 |
20 | Website:
21 |
22 | https://synthv1.sourceforge.io
23 | http://synthv1.sourceforge.net
24 |
25 | Project page:
26 |
27 | https://sourceforge.net/projects/synthv1
28 |
29 | Git repos:
30 |
31 | https://git.code.sf.net/p/synthv1/code
32 | https://github.com/rncbc/synthv1.git
33 | https://gitlab.com/rncbc/synthv1.git
34 | https://codeberg.org/rncbc/synthv1.git
35 |
36 | Weblog:
37 |
38 | https://www.rncbc.org
39 |
40 | Requirements:
41 |
42 | mandatory,
43 |
44 | - Qt framework [7], C++ class library and tools for
45 | cross-platform application and UI development
46 | https://qt.io/
47 |
48 | optional (opted-in at build time),
49 |
50 | - JACK [1] Audio Connection Kit
51 | https://jackaudio.org/
52 |
53 | - ALSA [2], Advanced Linux Sound Architecture
54 | https://www.alsa-project.org/
55 |
56 | - LV2 [4], Audio Plugin Standard, the extensible successor of LADSPA
57 | https://lv2plug.in/
58 |
59 | - liblo [8], Lightweight OSC implementation
60 | (needed for NSM support [3])
61 | http://liblo.sourceforge.net/
62 |
63 | Installation:
64 |
65 | - unpack tarball as usual; in the extracted source directory:
66 |
67 | cmake [-DCMAKE_INSTALL_PREFIX=] -B build
68 | cmake --build build [--parallel ]
69 |
70 | - optionally, as root:
71 |
72 | [sudo] cmake --install build
73 |
74 | - note that the default installation path () is /usr/local .
75 |
76 | Acknowledgements:
77 |
78 | synthv1 logo/icon is an original fine work of Jarle Richard Akselsen.
79 |
80 | References:
81 |
82 | [1] JACK Audio Connection Kit
83 | https://jackaudio.org/
84 |
85 | [2] ALSA, Advanced Linux Sound Architecture
86 | https://www.alsa-project.org/
87 |
88 | [3] Non Session Management (NSM) (legacy)
89 | http://non.tuxfamily.org/nsm/
90 | New Session Manager (NSM)
91 | https://new-session-manager.jackaudio.org/
92 |
93 | [4] LV2, Audio Plugin Standard, the extensible successor of LADSPA
94 | http://lv2plug.in/
95 |
96 | [5] Linux Audio consortium of libre software for audio-related work
97 | https://linuxaudio.org
98 |
99 | [6] GNU General Public License
100 | https://www.gnu.org/copyleft/gpl.html
101 |
102 | [7] Qt framework, C++ class library and tools for
103 | cross-platform application and UI development
104 | https://qt.io/
105 |
106 | [8] liblo [8], Lightweight OSC implementation
107 | (needed for NSM support)
108 | http://liblo.sourceforge.net/
109 |
110 |
111 | Cheers && Enjoy.
112 | --
113 | rncbc aka. Rui Nuno Capela
114 | rncbc@rncbc.org
115 | https://www.rncbc.org
116 |
--------------------------------------------------------------------------------
/debian/changelog:
--------------------------------------------------------------------------------
1 | synthv1 (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 | synthv1 (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 | synthv1 (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 | synthv1 (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 | synthv1 (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 | synthv1 (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 | synthv1 (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 | synthv1 (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 | synthv1 (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 |
--------------------------------------------------------------------------------
/debian/compat:
--------------------------------------------------------------------------------
1 | 11
2 |
--------------------------------------------------------------------------------
/debian/control:
--------------------------------------------------------------------------------
1 | Source: synthv1
2 | Section: sound
3 | Priority: optional
4 | Maintainer: Rui Nuno Capela
5 | Build-Depends: debhelper (>= 11), cmake, pkg-config,
6 | qtbase6.9-static (>= 6.9), qttools6.9-static (>= 6.9),
7 | qtsvg6.9-static (>= 6.9), qttranslations6.9-static (>= 6.9),
8 | libjack-dev | libjack-jackd2-dev, libasound2-dev,
9 | lv2-dev, liblo-dev
10 | Standards-Version: 4.6.2
11 | Rules-Requires-Root: no
12 |
13 | Package: synthv1-jack
14 | Architecture: any
15 | Depends: ${shlibs:Depends}, ${misc:Depends}, libjack0 | libjack-jackd2-0
16 | Replaces: synthv1-common (<= ${source:Version}), synthv1 (<= ${source:Version})
17 | Description: An old-school polyphonic subtractive synthesizer - JACK standalone
18 | An old-school all-digital 4-oscillator subtractive polyphonic synthesizer
19 | with stereo fx.
20 | .
21 | This package provides the standalone JACK client application (synthv1_jack)
22 |
23 | Package: synthv1-lv2
24 | Architecture: any
25 | Depends: ${shlibs:Depends}, ${misc:Depends}
26 | Replaces: synthv1-common (<= ${source:Version})
27 | Description: An old-school polyphonic subtractive synthesizer - LV2 plugin
28 | An old-school all-digital 4-oscillator subtractive polyphonic synthesizer
29 | with stereo fx.
30 | .
31 | This package provides the LV2 plugin (http://synthv1.sourceforge.net/lv2)
32 |
--------------------------------------------------------------------------------
/debian/copyright:
--------------------------------------------------------------------------------
1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
2 | Upstream-Name: synthv1
3 | Upstream-Contact: Rui Nuno Capela
4 | Source: https://synthv1.sourceforge.io
5 |
6 | Files: *
7 | Copyright: 2012-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: 2012-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/docs:
--------------------------------------------------------------------------------
1 | README
2 | ChangeLog
3 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/debian/synthv1-jack.docs:
--------------------------------------------------------------------------------
1 | README
2 | LICENSE
3 | ChangeLog
4 |
--------------------------------------------------------------------------------
/debian/synthv1-jack.install:
--------------------------------------------------------------------------------
1 | debian/tmp/usr/bin/synthv1_jack
2 | debian/tmp/usr/share/metainfo/org.rncbc.synthv1.metainfo.xml
3 | debian/tmp/usr/share/applications/org.rncbc.synthv1.desktop
4 | debian/tmp/usr/share/mime/packages/org.rncbc.synthv1.xml
5 | debian/tmp/usr/share/icons/hicolor/32x32/apps/org.rncbc.synthv1.png
6 | debian/tmp/usr/share/icons/hicolor/32x32/mimetypes/org.rncbc.synthv1.application-x-synthv1*.png
7 | debian/tmp/usr/share/icons/hicolor/scalable/apps/org.rncbc.synthv1.svg
8 | debian/tmp/usr/share/icons/hicolor/scalable/mimetypes/org.rncbc.synthv1.application-x-synthv1*.svg
9 | debian/tmp/usr/share/man/man1/synthv1*.*
10 | debian/tmp/usr/share/synthv1/palette/*.conf
11 |
--------------------------------------------------------------------------------
/debian/synthv1-lv2.install:
--------------------------------------------------------------------------------
1 | debian/tmp/usr/lib*/lv2/synthv1.lv2/manifest.ttl
2 | debian/tmp/usr/lib*/lv2/synthv1.lv2/synthv1.ttl
3 | debian/tmp/usr/lib*/lv2/synthv1.lv2/synthv1.so
4 | debian/tmp/usr/lib*/lv2/synthv1.lv2/synthv1_ui.ttl
5 |
--------------------------------------------------------------------------------
/rpm/synthv1.spec:
--------------------------------------------------------------------------------
1 | #
2 | # spec file for package synthv1
3 | #
4 | # Copyright (C) 2012-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 subtractive synthesizer
19 | Name: synthv1
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://synthv1.sourceforge.net
26 | #Packager: rncbc.org
27 |
28 | %if 0%{?fedora_version} >= 34 || 0%{?suse_version} > 1500 || ( 0%{?sle_version} >= 150200 && 0%{?is_opensuse} )
29 | %define qt_major_version 6
30 | %else
31 | %define qt_major_version 5
32 | %endif
33 |
34 | %if %{defined fedora}
35 | %global debug_package %{nil}
36 | %endif
37 |
38 | BuildRequires: coreutils
39 | BuildRequires: pkgconfig
40 | BuildRequires: glibc-devel
41 | BuildRequires: cmake >= 3.15
42 | %if 0%{?sle_version} >= 150200 && 0%{?is_opensuse}
43 | BuildRequires: gcc10 >= 10
44 | BuildRequires: gcc10-c++ >= 10
45 | %define _GCC /usr/bin/gcc-10
46 | %define _GXX /usr/bin/g++-10
47 | %else
48 | BuildRequires: gcc >= 10
49 | BuildRequires: gcc-c++ >= 10
50 | %define _GCC /usr/bin/gcc
51 | %define _GXX /usr/bin/g++
52 | %endif
53 | %if 0%{qt_major_version} == 6
54 | BuildRequires: qtbase6.9-static >= 6.9
55 | BuildRequires: qttools6.9-static
56 | BuildRequires: qttranslations6.9-static
57 | BuildRequires: qtsvg6.9-static
58 | %else
59 | BuildRequires: pkgconfig(Qt5Core)
60 | BuildRequires: pkgconfig(Qt5Gui)
61 | BuildRequires: pkgconfig(Qt5Widgets)
62 | BuildRequires: pkgconfig(Qt5Svg)
63 | BuildRequires: pkgconfig(Qt5Xml)
64 | %endif
65 | %if %{defined fedora}
66 | BuildRequires: jack-audio-connection-kit-devel
67 | %else
68 | BuildRequires: pkgconfig(jack)
69 | %endif
70 | BuildRequires: pkgconfig(alsa)
71 |
72 | BuildRequires: pkgconfig(liblo)
73 | BuildRequires: pkgconfig(lv2)
74 |
75 | BuildRequires: pkgconfig(egl)
76 |
77 | %description
78 | An old-school all-digital 4-oscillator subtractive polyphonic synthesizer
79 | with stereo fx.
80 |
81 |
82 | %package -n %{name}-jack
83 | Summary: An old-school polyphonic subtractive synthesizer - JACK standalone
84 | Provides: %{name}_jack
85 | Obsoletes: %{name}-common <= %{version}, %{name} <= %{version}
86 |
87 | %description -n %{name}-jack
88 | An old-school all-digital 4-oscillator subtractive polyphonic synthesizer
89 | with stereo fx.
90 |
91 | This package provides the standalone JACK client application (synthv1_jack)
92 |
93 |
94 | %package -n %{name}-lv2
95 | Summary: An old-school polyphonic subtractive synthesizer - LV2 plugin
96 | Provides: %{name}_lv2, %{name}_lv2ui
97 | Obsoletes: %{name}-common <= %{version}
98 |
99 | %description -n %{name}-lv2
100 | An old-school all-digital 4-oscillator subtractive polyphonic synthesizer
101 | with stereo fx.
102 |
103 | This package provides the LV2 plugin (http://synthv1.sourceforge.net/lv2)
104 |
105 |
106 | %prep
107 | %setup -q
108 |
109 | %build
110 | %if 0%{qt_major_version} == 6
111 | source /opt/qt6.9-static/bin/qt6.9-static-env.sh
112 | %endif
113 | CXX=%{_GXX} CC=%{_GCC} \
114 | cmake -DCMAKE_INSTALL_PREFIX=%{_prefix} -Wno-dev -B build
115 | cmake --build build %{?_smp_mflags}
116 |
117 | %install
118 | DESTDIR="%{buildroot}" \
119 | cmake --install build
120 |
121 |
122 | %files -n %{name}-jack
123 | %license LICENSE
124 | %doc README ChangeLog
125 | #dir %{_datadir}/applications
126 | %dir %{_datadir}/metainfo
127 | #dir %{_datadir}/mime
128 | #dir %{_datadir}/mime/packages
129 | %dir %{_datadir}/icons/hicolor
130 | %dir %{_datadir}/icons/hicolor/32x32
131 | %dir %{_datadir}/icons/hicolor/32x32/apps
132 | %dir %{_datadir}/icons/hicolor/32x32/mimetypes
133 | %dir %{_datadir}/icons/hicolor/scalable
134 | %dir %{_datadir}/icons/hicolor/scalable/apps
135 | %dir %{_datadir}/icons/hicolor/scalable/mimetypes
136 | #dir %{_datadir}/man
137 | #dir %{_datadir}/man/man1
138 | #dir %{_datadir}/man/fr
139 | #dir %{_datadir}/man/fr/man1
140 | %dir %{_datadir}/%{name}
141 | %dir %{_datadir}/%{name}/palette
142 | %{_bindir}/%{name}_jack
143 | %{_datadir}/metainfo/org.rncbc.%{name}.metainfo.xml
144 | %{_datadir}/applications/org.rncbc.%{name}.desktop
145 | %{_datadir}/mime/packages/org.rncbc.%{name}.xml
146 | %{_datadir}/icons/hicolor/32x32/apps/org.rncbc.%{name}.png
147 | %{_datadir}/icons/hicolor/scalable/apps/org.rncbc.%{name}.svg
148 | %{_datadir}/icons/hicolor/32x32/mimetypes/org.rncbc.%{name}.application-x-%{name}*.png
149 | %{_datadir}/icons/hicolor/scalable/mimetypes/org.rncbc.%{name}.application-x-%{name}*.svg
150 | %{_datadir}/man/man1/%{name}.1.gz
151 | %{_datadir}/man/fr/man1/%{name}.1.gz
152 | %{_datadir}/%{name}/palette/*.conf
153 |
154 | %files -n %{name}-lv2
155 | %dir %{_libdir}/lv2
156 | %dir %{_libdir}/lv2/%{name}.lv2
157 | %{_libdir}/lv2/%{name}.lv2/manifest.ttl
158 | %{_libdir}/lv2/%{name}.lv2/%{name}.ttl
159 | %{_libdir}/lv2/%{name}.lv2/%{name}.so
160 | %{_libdir}/lv2/%{name}.lv2/%{name}_ui.ttl
161 |
162 |
163 | %changelog
164 | * Tue May 20 2025 Rui Nuno Capela 1.3.2
165 | - A Mid-Spring'25 Release.
166 | * Thu Apr 3 2025 Rui Nuno Capela 1.3.1
167 | - An Early Spring'25 Release.
168 | * Thu Jan 16 2025 Rui Nuno Capela 1.3.0
169 | - A New-Year'25 Release.
170 | * Sun Dec 15 2024 Rui Nuno Capela 1.2.0
171 | - An End-of-Year'24 Release.
172 | * Thu Oct 31 2024 Rui Nuno Capela 1.1.3
173 | - A Halloween'24 Release.
174 | * Wed Oct 2 2024 Rui Nuno Capela 1.1.2
175 | - An Early-Fall'24 Release.
176 | * Fri Sep 20 2024 Rui Nuno Capela 1.1.1
177 | - An End-of-Summer'24 Release.
178 | * Wed Aug 28 2024 Rui Nuno Capela 1.1.0
179 | - A Mid-Summer'24 Release.
180 | * Thu Jun 20 2024 Rui Nuno Capela 1.0.0
181 | - An Unthinkable Release.
182 |
--------------------------------------------------------------------------------
/src/appdata/org.rncbc.synthv1.desktop:
--------------------------------------------------------------------------------
1 | [Desktop Entry]
2 | Name=synthv1
3 | Version=1.0
4 | GenericName=MIDI
5 | Comment=synthv1 is an old school polyphonic synthesizer
6 | Comment[fr]=synthv1 est un synthétiseur polyphonique à l'ancienne
7 | Exec=synthv1_jack %f
8 | Icon=org.rncbc.synthv1
9 | Categories=Audio;AudioVideo;Midi;X-Alsa;X-Jack;Qt;
10 | MimeType=application/x-synthv1-preset;
11 | Keywords=Audio;MIDI;ALSA;JACK;Synthesizer;LV2;Qt;
12 | Terminal=false
13 | Type=Application
14 | StartupWMClass=synthv1_jack
15 | X-Window-Icon=synthv1
16 | X-SuSE-translate=true
17 | X-NSM-Capable=true
18 | X-NSM-Exec=synthv1_jack
19 |
--------------------------------------------------------------------------------
/src/appdata/org.rncbc.synthv1.metainfo.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | org.rncbc.synthv1
5 | FSFAP
6 | GPL-2.0+
7 | synthv1
8 | an old-school polyphonic synthesizer
9 |
10 | synthv1 is an old-school 4-oscillator subtractive polyphonic 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\://synthv1.sourceforge.net/lv2
17 |
18 |
19 | org.rncbc.synthv1.desktop
20 |
21 | synthv1_jack
22 |
23 |
24 |
25 | https://synthv1.sourceforge.io/image/synthv1-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://synthv1.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/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 JACK library is available. */
39 | #cmakedefine CONFIG_JACK @CONFIG_JACK@
40 |
41 | /* Define if ALSA MIDI support is enabled. */
42 | #cmakedefine CONFIG_ALSA_MIDI @CONFIG_ALSA_MIDI@
43 |
44 | /* Define if LIBLO library is available. */
45 | #cmakedefine CONFIG_LIBLO @CONFIG_LIBLO@
46 |
47 | /* Define if JACK session support is available. */
48 | #cmakedefine CONFIG_JACK_SESSION @CONFIG_JACK_SESSION@
49 |
50 | /* Define if JACK MIDI support is enabled. */
51 | #cmakedefine CONFIG_JACK_MIDI @CONFIG_JACK_MIDI@
52 |
53 | /* Define if LV2 plug-in build is enabled. */
54 | #cmakedefine CONFIG_LV2 @CONFIG_LV2@
55 |
56 | /* Define if LV2 old headers are enabled. */
57 | #cmakedefine CONFIG_LV2_OLD_HEADERS @CONFIG_LV2_OLD_HEADERS@
58 |
59 | /* Define if lv2_atom_forge_object is available. */
60 | #cmakedefine CONFIG_LV2_ATOM_FORGE_OBJECT @CONFIG_LV2_ATOM_FORGE_OBJECT@
61 |
62 | /* Define if lv2_atom_forge_key is available. */
63 | #cmakedefine CONFIG_LV2_ATOM_FORGE_KEY @CONFIG_LV2_ATOM_FORGE_KEY@
64 |
65 | /* Define if LV2 X11 UI support is available. */
66 | #cmakedefine CONFIG_LV2_UI_X11 @CONFIG_LV2_UI_X11@
67 |
68 | /* Define if LV2 Windows UI support is available. */
69 | #cmakedefine CONFIG_LV2_UI_WINDOWS @CONFIG_LV2_UI_WINDOWS@
70 |
71 | /* Define if LV2 External UI extension is available. */
72 | #cmakedefine CONFIG_LV2_UI_EXTERNAL @CONFIG_LV2_UI_EXTERNAL@
73 |
74 | /* Define if LV2 UI Idle interface support is available. */
75 | #cmakedefine CONFIG_LV2_UI_IDLE @CONFIG_LV2_UI_IDLE@
76 |
77 | /* Define if LV2 UI Show interface support is available. */
78 | #cmakedefine CONFIG_LV2_UI_SHOW @CONFIG_LV2_UI_SHOW@
79 |
80 | /* Define if LV2 UI Resize interface support is available. */
81 | #cmakedefine CONFIG_LV2_UI_RESIZE @CONFIG_LV2_UI_RESIZE@
82 |
83 | /* Define if LV2 Programs extension is available. */
84 | #cmakedefine CONFIG_LV2_PROGRAMS @CONFIG_LV2_PROGRAMS@
85 |
86 | /* Define if LV2 Patch is supported. */
87 | #cmakedefine CONFIG_LV2_PATCH @CONFIG_LV2_PATCH@
88 |
89 | /* Define if LV2 Port-event is supported. */
90 | #cmakedefine CONFIG_LV2_PORT_EVENT @CONFIG_LV2_PORT_EVENT@
91 |
92 | /* Define if LV2 Port-change request is supported. */
93 | #cmakedefine CONFIG_LV2_PORT_CHANGE_REQUEST @CONFIG_LV2_PORT_CHANGE_REQUEST@
94 |
95 | /* Define if NSM support is available. */
96 | #cmakedefine CONFIG_NSM @CONFIG_NSM@
97 |
98 | /* Define if Wayland is supported */
99 | #cmakedefine CONFIG_WAYLAND @CONFIG_WAYLAND@
100 |
101 |
102 | #endif /* CONFIG_H */
103 |
--------------------------------------------------------------------------------
/src/images/fileOpen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rncbc/synthv1/0545b01a1945bc24d50bc5c325567353ee6fed67/src/images/fileOpen.png
--------------------------------------------------------------------------------
/src/images/itemReset.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rncbc/synthv1/0545b01a1945bc24d50bc5c325567353ee6fed67/src/images/itemReset.png
--------------------------------------------------------------------------------
/src/images/ledOff.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rncbc/synthv1/0545b01a1945bc24d50bc5c325567353ee6fed67/src/images/ledOff.png
--------------------------------------------------------------------------------
/src/images/ledOn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rncbc/synthv1/0545b01a1945bc24d50bc5c325567353ee6fed67/src/images/ledOn.png
--------------------------------------------------------------------------------
/src/images/presetBank.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rncbc/synthv1/0545b01a1945bc24d50bc5c325567353ee6fed67/src/images/presetBank.png
--------------------------------------------------------------------------------
/src/images/presetBankOpen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rncbc/synthv1/0545b01a1945bc24d50bc5c325567353ee6fed67/src/images/presetBankOpen.png
--------------------------------------------------------------------------------
/src/images/presetDelete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rncbc/synthv1/0545b01a1945bc24d50bc5c325567353ee6fed67/src/images/presetDelete.png
--------------------------------------------------------------------------------
/src/images/presetEdit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rncbc/synthv1/0545b01a1945bc24d50bc5c325567353ee6fed67/src/images/presetEdit.png
--------------------------------------------------------------------------------
/src/images/presetNew.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rncbc/synthv1/0545b01a1945bc24d50bc5c325567353ee6fed67/src/images/presetNew.png
--------------------------------------------------------------------------------
/src/images/presetOpen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rncbc/synthv1/0545b01a1945bc24d50bc5c325567353ee6fed67/src/images/presetOpen.png
--------------------------------------------------------------------------------
/src/images/presetSave.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rncbc/synthv1/0545b01a1945bc24d50bc5c325567353ee6fed67/src/images/presetSave.png
--------------------------------------------------------------------------------
/src/images/synthv1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rncbc/synthv1/0545b01a1945bc24d50bc5c325567353ee6fed67/src/images/synthv1.png
--------------------------------------------------------------------------------
/src/images/synthv1_control.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rncbc/synthv1/0545b01a1945bc24d50bc5c325567353ee6fed67/src/images/synthv1_control.png
--------------------------------------------------------------------------------
/src/images/synthv1_preset.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rncbc/synthv1/0545b01a1945bc24d50bc5c325567353ee6fed67/src/images/synthv1_preset.png
--------------------------------------------------------------------------------
/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/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/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/man1/synthv1.1:
--------------------------------------------------------------------------------
1 | .TH SYNTHV1 "1" "August 31, 2020"
2 | .SH NAME
3 | synthv1 \- an old-school polyphonic synthesizer
4 | .SH SYNOPSIS
5 | .B synthv1_jack
6 | [\fIoptions\fR] [\fIpreset-file\fR]
7 | .SH DESCRIPTION
8 | This manual page documents briefly the
9 | .B synthv1_jack
10 | command.
11 | .PP
12 | \fBsynthv1\fP is an old-school 4-oscillator subtractive
13 | polyphonic synthesizer with stereo fx.
14 | .PP
15 | features:
16 | .IP
17 | a pure stand-alone JACK client with JACK-session,
18 | NSM and both JACK MIDI and ALSA MIDI input support;
19 | .IP
20 | a LV2 instrument plugin.
21 | URI: http://synthv1.sourceforge.net/lv2
22 | .SH OPTIONS
23 | .HP
24 | \fB\-g\fR, \fB\-\-no\-gui\fR
25 | .IP
26 | Disable the graphical user interface (GUI)
27 | .HP
28 | \fB\-n\fR, \fB\-\-client\-name\fR=[\fIlabel\fR]
29 | .IP
30 | Set the JACK client name (default: synthv1)
31 | .HP
32 | \fB\-h\fR, \fB\-\-help\fR
33 | .IP
34 | Show help about command line options
35 | .HP
36 | \fB\-v\fR, \fB\-\-version\fR
37 | .IP
38 | Show version information
39 | .SH FILES
40 | Configuration settings are stored in ~/.config/rncbc.org/synthv1.conf
41 | .SH AUTHOR
42 | synthv1 was written by Rui Nuno Capela.
43 |
--------------------------------------------------------------------------------
/src/man1/synthv1.fr.1:
--------------------------------------------------------------------------------
1 | .TH SYNTHV1 "1" "Juin 17, 2014"
2 | .SH NOM
3 | synthv1 \- un synthétiseur polyphonique à l'ancienne
4 | .SH SYNOPSIS
5 | .B synthv1_jack
6 | [\fIoptions\fR] [\fIfichier-de-pré-réglage\fR]
7 | .SH DESCRIPTION
8 | Cette page de manuel documente rapidement la commande
9 | .B synthv1_jack
10 | .
11 | .PP
12 | \fBsynthv1\fP est un synthétiseur polyphonique soustractif 4-oscillateurs à
13 | l'ancienne, 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://synthv1.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/synthv1.conf
37 | .SH AUTEUR
38 | synthv1 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 |
--------------------------------------------------------------------------------
/src/mimetypes/org.rncbc.synthv1.application-x-synthv1-preset.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rncbc/synthv1/0545b01a1945bc24d50bc5c325567353ee6fed67/src/mimetypes/org.rncbc.synthv1.application-x-synthv1-preset.png
--------------------------------------------------------------------------------
/src/mimetypes/org.rncbc.synthv1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | synthv1 preset
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/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/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/synthv1.h:
--------------------------------------------------------------------------------
1 | // synthv1.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 __synthv1_h
23 | #define __synthv1_h
24 |
25 | #include "config.h"
26 |
27 | #include
28 |
29 |
30 | // forward declarations
31 | class synthv1_impl;
32 | class synthv1_port;
33 | class synthv1_controls;
34 | class synthv1_programs;
35 |
36 |
37 | //-------------------------------------------------------------------------
38 | // synthv1 - decl.
39 | //
40 |
41 | class synthv1
42 | {
43 | public:
44 |
45 | synthv1(uint16_t nchannels = 2, float srate = 44100.0f, uint32_t nsize = 1024);
46 |
47 | virtual ~synthv1();
48 |
49 | void setChannels(uint16_t nchannels);
50 | uint16_t channels() const;
51 |
52 | void setSampleRate(float srate);
53 | float sampleRate() const;
54 |
55 | void setBufferSize(uint32_t nsize);
56 | uint32_t bufferSize() const;
57 |
58 | void setTempo(float bpm);
59 | float tempo() const;
60 |
61 | enum ParamIndex {
62 |
63 | DCO1_SHAPE1 = 0,
64 | DCO1_WIDTH1,
65 | DCO1_BANDL1,
66 | DCO1_SYNC1,
67 | DCO1_SHAPE2,
68 | DCO1_WIDTH2,
69 | DCO1_BANDL2,
70 | DCO1_SYNC2,
71 | DCO1_BALANCE,
72 | DCO1_DETUNE,
73 | DCO1_PHASE,
74 | DCO1_RINGMOD,
75 | DCO1_OCTAVE,
76 | DCO1_TUNING,
77 | DCO1_GLIDE,
78 | DCO1_ENVTIME,
79 | DCF1_ENABLED,
80 | DCF1_CUTOFF,
81 | DCF1_RESO,
82 | DCF1_TYPE,
83 | DCF1_SLOPE,
84 | DCF1_ENVELOPE,
85 | DCF1_ATTACK,
86 | DCF1_DECAY,
87 | DCF1_SUSTAIN,
88 | DCF1_RELEASE,
89 | LFO1_ENABLED,
90 | LFO1_SHAPE,
91 | LFO1_WIDTH,
92 | LFO1_BPM,
93 | LFO1_RATE,
94 | LFO1_SYNC,
95 | LFO1_SWEEP,
96 | LFO1_PITCH,
97 | LFO1_BALANCE,
98 | LFO1_RINGMOD,
99 | LFO1_CUTOFF,
100 | LFO1_RESO,
101 | LFO1_PANNING,
102 | LFO1_VOLUME,
103 | LFO1_ATTACK,
104 | LFO1_DECAY,
105 | LFO1_SUSTAIN,
106 | LFO1_RELEASE,
107 | DCA1_VOLUME,
108 | DCA1_ATTACK,
109 | DCA1_DECAY,
110 | DCA1_SUSTAIN,
111 | DCA1_RELEASE,
112 | OUT1_WIDTH,
113 | OUT1_PANNING,
114 | OUT1_FXSEND,
115 | OUT1_VOLUME,
116 |
117 | DEF1_PITCHBEND,
118 | DEF1_MODWHEEL,
119 | DEF1_PRESSURE,
120 | DEF1_VELOCITY,
121 | DEF1_CHANNEL,
122 | DEF1_MONO,
123 |
124 | DCO2_SHAPE1,
125 | DCO2_WIDTH1,
126 | DCO2_BANDL1,
127 | DCO2_SYNC1,
128 | DCO2_SHAPE2,
129 | DCO2_WIDTH2,
130 | DCO2_BANDL2,
131 | DCO2_SYNC2,
132 | DCO2_BALANCE,
133 | DCO2_DETUNE,
134 | DCO2_PHASE,
135 | DCO2_RINGMOD,
136 | DCO2_OCTAVE,
137 | DCO2_TUNING,
138 | DCO2_GLIDE,
139 | DCO2_ENVTIME,
140 | DCF2_ENABLED,
141 | DCF2_CUTOFF,
142 | DCF2_RESO,
143 | DCF2_TYPE,
144 | DCF2_SLOPE,
145 | DCF2_ENVELOPE,
146 | DCF2_ATTACK,
147 | DCF2_DECAY,
148 | DCF2_SUSTAIN,
149 | DCF2_RELEASE,
150 | LFO2_ENABLED,
151 | LFO2_SHAPE,
152 | LFO2_WIDTH,
153 | LFO2_BPM,
154 | LFO2_RATE,
155 | LFO2_SYNC,
156 | LFO2_SWEEP,
157 | LFO2_PITCH,
158 | LFO2_BALANCE,
159 | LFO2_RINGMOD,
160 | LFO2_CUTOFF,
161 | LFO2_RESO,
162 | LFO2_PANNING,
163 | LFO2_VOLUME,
164 | LFO2_ATTACK,
165 | LFO2_DECAY,
166 | LFO2_SUSTAIN,
167 | LFO2_RELEASE,
168 | DCA2_VOLUME,
169 | DCA2_ATTACK,
170 | DCA2_DECAY,
171 | DCA2_SUSTAIN,
172 | DCA2_RELEASE,
173 | OUT2_WIDTH,
174 | OUT2_PANNING,
175 | OUT2_FXSEND,
176 | OUT2_VOLUME,
177 |
178 | DEF2_PITCHBEND,
179 | DEF2_MODWHEEL,
180 | DEF2_PRESSURE,
181 | DEF2_VELOCITY,
182 | DEF2_CHANNEL,
183 | DEF2_MONO,
184 |
185 | CHO1_WET,
186 | CHO1_DELAY,
187 | CHO1_FEEDB,
188 | CHO1_RATE,
189 | CHO1_MOD,
190 | FLA1_WET,
191 | FLA1_DELAY,
192 | FLA1_FEEDB,
193 | FLA1_DAFT,
194 | PHA1_WET,
195 | PHA1_RATE,
196 | PHA1_FEEDB,
197 | PHA1_DEPTH,
198 | PHA1_DAFT,
199 | DEL1_WET,
200 | DEL1_DELAY,
201 | DEL1_FEEDB,
202 | DEL1_BPM,
203 | REV1_WET,
204 | REV1_ROOM,
205 | REV1_DAMP,
206 | REV1_FEEDB,
207 | REV1_WIDTH,
208 | DYN1_COMPRESS,
209 | DYN1_LIMITER,
210 |
211 | KEY1_LOW,
212 | KEY1_HIGH,
213 |
214 | NUM_PARAMS
215 | };
216 |
217 | void setParamPort(ParamIndex index, float *pfParam);
218 | synthv1_port *paramPort(ParamIndex index) const;
219 |
220 | synthv1_controls *controls() const;
221 | synthv1_programs *programs() const;
222 |
223 | void setParamValue(ParamIndex index, float fValue);
224 | float paramValue(ParamIndex index) const;
225 |
226 | bool running(bool on);
227 |
228 | void stabilize();
229 | void reset();
230 |
231 | void process_midi(uint8_t *data, uint32_t size);
232 | void process(float **ins, float **outs, uint32_t nframes);
233 |
234 | virtual void updatePreset(bool bDirty) = 0;
235 | virtual void updateParam(ParamIndex index) = 0;
236 | virtual void updateParams() = 0;
237 |
238 | void midiInEnabled(bool on);
239 | uint32_t midiInCount();
240 |
241 | void directNoteOn(int note, int vel);
242 |
243 | void setTuningEnabled(bool enabled);
244 | bool isTuningEnabled() const;
245 |
246 | void setTuningRefPitch(float refPitch);
247 | float tuningRefPitch() const;
248 |
249 | void setTuningRefNote(int refNote);
250 | int tuningRefNote() const;
251 |
252 | void setTuningScaleFile(const char *pszScaleFile);
253 | const char *tuningScaleFile() const;
254 |
255 | void setTuningKeyMapFile(const char *pszKeyMapFile);
256 | const char *tuningKeyMapFile() const;
257 |
258 | void resetTuning();
259 |
260 | virtual void updateTuning() = 0;
261 |
262 | private:
263 |
264 | synthv1_impl *m_pImpl;
265 | };
266 |
267 |
268 | #endif// __synthv1_h
269 |
270 | // end of synthv1.h
271 |
--------------------------------------------------------------------------------
/src/synthv1.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 |
--------------------------------------------------------------------------------
/src/synthv1.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/synthv1.lv2/synthv1_ui-win32.ttl:
--------------------------------------------------------------------------------
1 | @prefix lv2: .
2 | @prefix lv2ui: .
3 |
4 | @prefix synthv1_lv2: .
5 |
6 |
7 | lv2ui:ui synthv1_lv2:ui_windows, synthv1_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/synthv1.lv2/synthv1_ui.ttl:
--------------------------------------------------------------------------------
1 | @prefix lv2: .
2 | @prefix lv2ui: .
3 |
4 | @prefix synthv1_lv2: .
5 |
6 |
7 | lv2ui:ui synthv1_lv2:ui_x11, synthv1_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/synthv1.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | images/synthv1.png
4 | images/synthv1.svg
5 | images/ledOn.png
6 | images/ledOff.png
7 | images/presetNew.png
8 | images/presetOpen.png
9 | images/presetSave.png
10 | images/presetDelete.png
11 | images/presetBank.png
12 | images/presetBankOpen.png
13 | images/presetEdit.png
14 | images/itemReset.png
15 | images/fileOpen.png
16 | images/synthv1_preset.png
17 | images/synthv1_control.png
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/synthv1_config.h:
--------------------------------------------------------------------------------
1 | // synthv1_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 __synthv1_config_h
23 | #define __synthv1_config_h
24 |
25 | #include "config.h"
26 |
27 |
28 | //-------------------------------------------------------------------------
29 | // synthv1_config - Prototype settings class (singleton).
30 | //
31 |
32 | #include
33 | #include
34 |
35 | // forward decls.
36 | class synthv1_programs;
37 | class synthv1_controls;
38 |
39 |
40 | class synthv1_config : public QSettings
41 | {
42 | public:
43 |
44 | // Constructor.
45 | synthv1_config();
46 |
47 | // Default destructor.
48 | ~synthv1_config();
49 |
50 | // Default options...
51 | QString sPreset;
52 | QString sPresetDir;
53 |
54 | // Knob behavior modes.
55 | int iKnobDialMode;
56 | int iKnobEditMode;
57 |
58 | // Default randomize factor (percent).
59 | float fRandomizePercent;
60 |
61 | // Special persistent options.
62 | bool bControlsEnabled;
63 | bool bProgramsEnabled;
64 | bool bProgramsPreview;
65 | bool bUseNativeDialogs;
66 | // Run-time special non-persistent options.
67 | bool bDontUseNativeDialogs;
68 |
69 | // Custom color palette/widget style themes.
70 | QString sCustomColorTheme;
71 | QString sCustomStyleTheme;
72 |
73 | // Micro-tuning options.
74 | bool bTuningEnabled;
75 | float fTuningRefPitch;
76 | int iTuningRefNote;
77 | QString sTuningScaleDir;
78 | QString sTuningScaleFile;
79 | QString sTuningKeyMapDir;
80 | QString sTuningKeyMapFile;
81 |
82 | // Singleton instance accessor.
83 | static synthv1_config *getInstance();
84 |
85 | // Preset utility methods.
86 | QString presetFile(const QString& sPreset);
87 | void setPresetFile(const QString& sPreset, const QString& sPresetFile);
88 | void removePreset(const QString& sPreset);
89 | const QStringList& presetList();
90 |
91 | // Programs utility methods.
92 | void loadPrograms(synthv1_programs *pPrograms);
93 | void savePrograms(synthv1_programs *pPrograms);
94 |
95 | // Controllers utility methods.
96 | void loadControls(synthv1_controls *pControls);
97 | void saveControls(synthv1_controls *pControls);
98 |
99 | protected:
100 |
101 | // Preset group path.
102 | QString presetGroup() const;
103 |
104 | // Banks programs group path.
105 | QString programsGroup() const;
106 | QString bankPrefix() const;
107 |
108 | void clearPrograms();
109 |
110 | // Controllers group path.
111 | QString controlsGroup() const;
112 | QString controlPrefix() const;
113 |
114 | void clearControls();
115 |
116 | // Explicit I/O methods.
117 | void load();
118 | void save();
119 |
120 | private:
121 |
122 | // The presets list cache.
123 | QStringList m_presetList;
124 |
125 | // The singleton instance.
126 | static synthv1_config *g_pSettings;
127 | };
128 |
129 |
130 | #endif // __synthv1_config_h
131 |
132 | // end of synthv1_config.h
133 |
134 |
--------------------------------------------------------------------------------
/src/synthv1_controls.h:
--------------------------------------------------------------------------------
1 | // synthv1_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 __synthv1_controls_h
23 | #define __synthv1_controls_h
24 |
25 | #include "synthv1_param.h"
26 | #include "synthv1_sched.h"
27 |
28 | #include
29 |
30 |
31 | //-------------------------------------------------------------------------
32 | // synthv1_controls - Controller processs class.
33 | //
34 |
35 | class synthv1_controls
36 | {
37 | public:
38 |
39 | // ctor.
40 | synthv1_controls(synthv1 *pSynth);
41 |
42 | // dtor.
43 | ~synthv1_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 synthv1_sched
152 | {
153 | public:
154 |
155 | // ctor.
156 | SchedIn (synthv1 *pSynth)
157 | : synthv1_sched(pSynth, 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 synthv1_sched
177 | {
178 | public:
179 |
180 | // ctor.
181 | SchedOut (synthv1 *pSynth)
182 | : synthv1_sched(pSynth, Controls), m_value(0.0f) {}
183 |
184 | void schedule_event(synthv1::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 | synthv1 *pSynth = instance();
196 | synthv1::ParamIndex index = synthv1::ParamIndex(sid);
197 | pSynth->setParamValue(index, m_value);
198 | pSynth->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 // __synthv1_controls_h
231 |
232 | // end of synthv1_controls.h
233 |
--------------------------------------------------------------------------------
/src/synthv1_filter.h:
--------------------------------------------------------------------------------
1 | // synthv1_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 __synthv1_filter_h
23 | #define __synthv1_filter_h
24 |
25 | #include
26 | #include
27 | #include
28 |
29 |
30 | //-------------------------------------------------------------------------
31 | // synthv1_filter1 - Hal Chamberlin's State Variable (12dB/oct) filter
32 | //
33 |
34 | class synthv1_filter1
35 | {
36 | public:
37 |
38 | enum Type { Low = 0, Band, High, Notch };
39 |
40 | synthv1_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 | // synthv1_filter2 - Stilson/Smith Moog (24dB/oct) filter
104 | //
105 |
106 | class synthv1_filter2
107 | {
108 | public:
109 |
110 | enum Type { Low = 0, Band, High, Notch };
111 |
112 | synthv1_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 | // synthv1_filter3 - RBJ biquad filter implementation.
168 | //
169 | // http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt
170 |
171 | class synthv1_filter3
172 | {
173 | public:
174 |
175 | enum Type { Low = 0, Band, High, Notch };
176 |
177 | synthv1_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 // __synthv1_filter_h
286 |
287 |
288 | // end of synthv1_filter.h
289 |
--------------------------------------------------------------------------------
/src/synthv1_formant.h:
--------------------------------------------------------------------------------
1 | // synthv1_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 __synthv1_formant_h
23 | #define __synthv1_formant_h
24 |
25 | #include
26 | #include
27 |
28 |
29 | //---------------------------------------------------------------------
30 | // synthv1_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 synthv1_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 | synthv1_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 // __synthv1_formant_h
256 |
257 | // end of synthv1_formant.h
258 |
--------------------------------------------------------------------------------
/src/synthv1_jack.h:
--------------------------------------------------------------------------------
1 | // synthv1_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 __synthv1_jack_h
23 | #define __synthv1_jack_h
24 |
25 | #include "synthv1.h"
26 |
27 | #include
28 |
29 |
30 | #ifdef CONFIG_ALSA_MIDI
31 | #include
32 | #include
33 | // forward decls.
34 | class synthv1_alsa_thread;
35 | #endif
36 |
37 |
38 | //-------------------------------------------------------------------------
39 | // synthv1_jack - decl.
40 | //
41 |
42 | class synthv1_jack : public synthv1
43 | {
44 | public:
45 |
46 | synthv1_jack(const char *client_name);
47 |
48 | ~synthv1_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(synthv1::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[synthv1::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 | synthv1_alsa_thread *m_alsa_thread;
104 | #endif
105 | };
106 |
107 |
108 | //-------------------------------------------------------------------------
109 | // synthv1_jack_application -- Singleton application instance.
110 | //
111 |
112 | #include
113 | #include
114 |
115 |
116 | // forward decls.
117 | class QCoreApplication;
118 | class synthv1widget_jack;
119 |
120 | #ifdef CONFIG_NSM
121 | class synthv1_nsm;
122 | #endif
123 |
124 | #ifdef HAVE_SIGNAL_H
125 | class QSocketNotifier;
126 | #endif
127 |
128 | class synthv1_jack_application : public QObject
129 | {
130 | Q_OBJECT
131 |
132 | public:
133 |
134 | // Constructor.
135 | synthv1_jack_application(int& argc, char **argv);
136 |
137 | // Destructor.
138 | ~synthv1_jack_application();
139 |
140 | // Facade method.
141 | int exec();
142 |
143 | // JACK shutdown handler.
144 | void shutdown();
145 |
146 | // Pseudo-singleton accessor.
147 | static synthv1_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 | synthv1_jack *m_pSynth;
194 | synthv1widget_jack *m_pWidget;
195 |
196 | #ifdef CONFIG_NSM
197 | synthv1_nsm *m_pNsmClient;
198 | #endif
199 |
200 | #ifdef HAVE_SIGNAL_H
201 | QSocketNotifier *m_pSigtermNotifier;
202 | #endif
203 |
204 | static synthv1_jack_application *g_pInstance;
205 | };
206 |
207 |
208 | #endif// __synthv1_jack_h
209 |
210 | // end of synthv1_jack.h
211 |
212 |
--------------------------------------------------------------------------------
/src/synthv1_list.h:
--------------------------------------------------------------------------------
1 | // synthv1_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 __synthv1_list_h
23 | #define __synthv1_list_h
24 |
25 |
26 | //-------------------------------------------------------------------------
27 | // synthv1_list - generic double-linked list node.
28 |
29 | template
30 | class synthv1_list
31 | {
32 | public:
33 |
34 | synthv1_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 // __synthv1_list_h
73 |
74 | // end of synthv1_list.h
75 |
--------------------------------------------------------------------------------
/src/synthv1_lv2.h:
--------------------------------------------------------------------------------
1 | // synthv1_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 __synthv1_lv2_h
23 | #define __synthv1_lv2_h
24 |
25 | #include "synthv1.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 SYNTHV1_LV2_URI "http://synthv1.sourceforge.net/lv2"
41 | #define SYNTHV1_LV2_PREFIX SYNTHV1_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 | // synthv1_lv2 - decl.
59 | //
60 |
61 | class synthv1_lv2 : public synthv1
62 | {
63 | public:
64 |
65 | synthv1_lv2(double sample_rate, const LV2_Feature *const *host_features);
66 |
67 | ~synthv1_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(synthv1::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(synthv1::ParamIndex index);
118 | bool port_events();
119 | #endif
120 |
121 | #ifdef CONFIG_LV2_PORT_CHANGE_REQUEST
122 | bool port_change_request(synthv1::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// __synthv1_lv2_h
191 |
192 | // end of synthv1_lv2.h
193 |
194 |
--------------------------------------------------------------------------------
/src/synthv1_lv2ui.h:
--------------------------------------------------------------------------------
1 | // synthv1_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 __synthv1_lv2ui_h
23 | #define __synthv1_lv2ui_h
24 |
25 | #include "synthv1_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 SYNTHV1_LV2UI_URI SYNTHV1_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 SYNTHV1_LV2UI_X11_URI SYNTHV1_LV2_PREFIX "ui_x11"
41 | #endif
42 |
43 | #ifdef CONFIG_LV2_UI_WINDOWS
44 | #include
45 | #define SYNTHV1_LV2UI_WINDOWS_URI SYNTHV1_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 SYNTHV1_LV2UI_EXTERNAL_URI SYNTHV1_LV2_PREFIX "ui_external"
56 | #endif
57 |
58 |
59 | // Forward decls.
60 | class synthv1_lv2;
61 |
62 |
63 | //-------------------------------------------------------------------------
64 | // synthv1_lv2ui - decl.
65 | //
66 |
67 | class synthv1_lv2ui : public synthv1_ui
68 | {
69 | public:
70 |
71 | // Constructor.
72 | synthv1_lv2ui(synthv1_lv2 *pSynth,
73 | LV2UI_Controller controller, LV2UI_Write_Function write_function);
74 |
75 | // Accessors.
76 | const LV2UI_Controller& controller() const;
77 | void write_function(synthv1::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 // __synthv1_lv2ui_h
88 |
89 | // end of synthv1_lv2ui.h
90 |
--------------------------------------------------------------------------------
/src/synthv1_nsm.h:
--------------------------------------------------------------------------------
1 | // synthv1_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 __synthv1_nsm_h
23 | #define __synthv1_nsm_h
24 |
25 | #include "synthv1_config.h"
26 |
27 | #include
28 |
29 | #ifdef CONFIG_LIBLO
30 | #include
31 | #endif
32 |
33 |
34 | //---------------------------------------------------------------------------
35 | // synthv1_nsm - NSM OSC client agent.
36 |
37 | class synthv1_nsm : public QObject
38 | {
39 | Q_OBJECT
40 |
41 | public:
42 |
43 | // Constructor.
44 | synthv1_nsm(const QString& nsm_url, QObject *pParent = 0);
45 |
46 | // Destructor.
47 | ~synthv1_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 // __synthv1_nsm_h
140 |
141 | // end of synthv1_nsm.h
142 |
--------------------------------------------------------------------------------
/src/synthv1_param.h:
--------------------------------------------------------------------------------
1 | // synthv1_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 __synthv1_param_h
23 | #define __synthv1_param_h
24 |
25 | #include "synthv1.h"
26 |
27 | #include
28 |
29 | // forward decl.
30 | class QDomElement;
31 | class QDomDocument;
32 |
33 |
34 | //-------------------------------------------------------------------------
35 | // synthv1_param - decl.
36 | //
37 |
38 | namespace synthv1_param
39 | {
40 | // Preset initialization method.
41 | bool newPreset(synthv1 *pSynth);
42 |
43 | // Preset serialization methods.
44 | bool loadPreset(synthv1 *pSynth,
45 | const QString& sFilename);
46 | bool savePreset(synthv1 *pSynth,
47 | const QString& sFilename,
48 | bool bSymLink = false);
49 |
50 | // Tuning serialization methods.
51 | void loadTuning(synthv1 *pSynth,
52 | const QDomElement& eTuning);
53 | void saveTuning(synthv1 *pSynth,
54 | QDomDocument& doc, QDomElement& eTuning,
55 | bool bSymLink = false);
56 |
57 | // Default parameter name/value helpers.
58 | const char *paramName(synthv1::ParamIndex index);
59 | float paramDefaultValue(synthv1::ParamIndex index);
60 | float paramSafeValue(synthv1::ParamIndex index, float fValue);
61 | float paramValue(synthv1::ParamIndex index, float fScale);
62 | float paramScale(synthv1::ParamIndex index, float fValue);
63 | bool paramFloat(synthv1::ParamIndex index);
64 |
65 | // Load/save and convert canonical/absolute filename helpers.
66 | QString loadFilename(const QString& sFilename);
67 | QString saveFilename(const QString& sFilename, bool bSymLink);
68 | };
69 |
70 |
71 | #endif // __synthv1_param_h
72 |
73 | // end of synthv1_param.h
74 |
--------------------------------------------------------------------------------
/src/synthv1_programs.cpp:
--------------------------------------------------------------------------------
1 | // synthv1_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 "synthv1_programs.h"
23 |
24 |
25 | //-------------------------------------------------------------------------
26 | // synthv1_programs - Bank/programs database class (singleton).
27 | //
28 |
29 | // ctor.
30 | synthv1_programs::synthv1_programs ( synthv1 *pSynth )
31 | : m_enabled(false), m_sched(pSynth),
32 | m_bank_msb(0), m_bank_lsb(0),
33 | m_bank(nullptr), m_prog(nullptr)
34 | {
35 | }
36 |
37 |
38 | // dtor.
39 | synthv1_programs::~synthv1_programs (void)
40 | {
41 | clear_banks();
42 | }
43 |
44 |
45 | // prog. managers
46 | synthv1_programs::Prog *synthv1_programs::Bank::find_prog ( uint16_t prog_id ) const
47 | {
48 | return m_progs.value(prog_id, nullptr);
49 | }
50 |
51 |
52 | synthv1_programs::Prog *synthv1_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 synthv1_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 synthv1_programs::Bank::clear_progs (void)
75 | {
76 | qDeleteAll(m_progs);
77 | m_progs.clear();
78 | }
79 |
80 |
81 | // bank managers
82 | synthv1_programs::Bank *synthv1_programs::find_bank ( uint16_t bank_id ) const
83 | {
84 | return m_banks.value(bank_id, nullptr);
85 | }
86 |
87 |
88 | synthv1_programs::Bank *synthv1_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 synthv1_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 synthv1_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 synthv1_programs::bank_select_msb ( uint8_t bank_msb )
125 | {
126 | m_bank_msb = 0x80 | (bank_msb & 0x7f);
127 | }
128 |
129 |
130 | void synthv1_programs::bank_select_lsb ( uint8_t bank_lsb )
131 | {
132 | m_bank_lsb = 0x80 | (bank_lsb & 0x7f);
133 | }
134 |
135 |
136 | void synthv1_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 synthv1_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 synthv1_programs::prog_change ( uint16_t prog_id )
159 | {
160 | select_program(current_bank_id(), prog_id);
161 | }
162 |
163 |
164 | void synthv1_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 synthv1_programs::process_program (
178 | synthv1 *pSynth, 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 | synthv1_param::loadPreset(pSynth, m_prog->name());
185 | pSynth->updateParams();
186 | }
187 | }
188 |
189 |
190 | // end of synthv1_programs.cpp
191 |
--------------------------------------------------------------------------------
/src/synthv1_programs.h:
--------------------------------------------------------------------------------
1 | // synthv1_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 __synthv1_programs_h
23 | #define __synthv1_programs_h
24 |
25 | #include "synthv1_sched.h"
26 | #include "synthv1_param.h"
27 |
28 | #include
29 |
30 |
31 | //-------------------------------------------------------------------------
32 | // synthv1_programs - Bank/programs database class.
33 | //
34 |
35 | class synthv1_programs
36 | {
37 | public:
38 |
39 | // ctor.
40 | synthv1_programs(synthv1 *pSynth);
41 |
42 | // dtor.
43 | ~synthv1_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(synthv1 *pSynth, 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 synthv1_sched
125 | {
126 | public:
127 |
128 | // ctor.
129 | Sched (synthv1 *pSynth)
130 | : synthv1_sched(pSynth, 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 | synthv1 *pSynth = instance();
147 | synthv1_programs *pPrograms = pSynth->programs();
148 | pPrograms->process_program(pSynth, 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 // __synthv1_programs_h
176 |
177 | // end of synthv1_programs.h
178 |
--------------------------------------------------------------------------------
/src/synthv1_ramp.h:
--------------------------------------------------------------------------------
1 | // synthv1_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 __synthv1_ramp_h
23 | #define __synthv1_ramp_h
24 |
25 | #include
26 | #include
27 |
28 |
29 | //-------------------------------------------------------------------------
30 | // synthv1_ramp - ramp/smooth parameter changes
31 |
32 | class synthv1_ramp
33 | {
34 | public:
35 |
36 | synthv1_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 ~synthv1_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 | // synthv1_ramp1 (1 port tracking)
111 |
112 | class synthv1_ramp1 : public synthv1_ramp
113 | {
114 | public:
115 |
116 | synthv1_ramp1(uint16_t nvalues = 1)
117 | : synthv1_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 | synthv1_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 | // synthv1_ramp2 (2 port tracking)
154 |
155 | class synthv1_ramp2 : public synthv1_ramp1
156 | {
157 | public:
158 |
159 | synthv1_ramp2(uint16_t nvalues = 1)
160 | : synthv1_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 | synthv1_ramp1::reset(param1);
168 | }
169 |
170 | protected:
171 |
172 | virtual bool probe() const
173 | {
174 | return synthv1_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 synthv1_ramp1::evaluate(i) * m_param2_v;
183 | }
184 |
185 | void update()
186 | {
187 | synthv1_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 | // synthv1_ramp3 (3 port tracking)
200 |
201 | class synthv1_ramp3 : public synthv1_ramp2
202 | {
203 | public:
204 |
205 | synthv1_ramp3(uint16_t nvalues = 1)
206 | : synthv1_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 | synthv1_ramp2::reset(param1, param2);
214 | }
215 |
216 | protected:
217 |
218 | virtual bool probe() const
219 | {
220 | return synthv1_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 synthv1_ramp2::evaluate(i) * m_param3_v;
229 | }
230 |
231 | void update()
232 | {
233 | synthv1_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 | // synthv1_ramp4 (4 port tracking)
248 |
249 | class synthv1_ramp4 : public synthv1_ramp3
250 | {
251 | public:
252 |
253 | synthv1_ramp4(uint16_t nvalues = 1)
254 | : synthv1_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 | synthv1_ramp3::reset(param1, param2, param3);
262 | }
263 |
264 | protected:
265 |
266 | virtual bool probe() const
267 | {
268 | return synthv1_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 synthv1_ramp3::evaluate(i) * m_param4_v;
277 | }
278 |
279 | void update()
280 | {
281 | synthv1_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 // __synthv1_ramp_h
293 |
294 | // end of synthv1_ramp.h
295 |
--------------------------------------------------------------------------------
/src/synthv1_reverb.h:
--------------------------------------------------------------------------------
1 | // synthv1_reverb.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 __synthv1_reverb_h
23 | #define __synthv1_reverb_h
24 |
25 | #include
26 | #include
27 |
28 |
29 | //-------------------------------------------------------------------------
30 | // synthv1_reverb
31 | //
32 | // -- borrowed, stirred and refactored from original FreeVerb --
33 | // by Jezar at Dreampoint, June 2000 (public domain)
34 | //
35 |
36 | class synthv1_reverb
37 | {
38 | public:
39 |
40 | synthv1_reverb (float srate = 44100.0f)
41 | : m_srate(srate), m_room(0.5f), m_damp(0.5f), m_feedb(0.5f)
42 | { reset(); }
43 |
44 | void setSampleRate(float srate)
45 | { m_srate = srate; }
46 | float sampleRate() const
47 | { return m_srate; }
48 |
49 | void reset()
50 | {
51 | static const uint32_t s_comb[NUM_COMBS]
52 | = { 1116, 1188, 1277, 1356, 1422, 1491, 1557, 1617, 1685, 1748 };
53 | static const uint32_t s_allpass[NUM_ALLPASSES]
54 | = { 556, 441, 341, 225, 180, 153 };
55 |
56 | const float sr = m_srate / 44100.0f;
57 |
58 | uint32_t j;
59 |
60 | for (j = 0; j < NUM_ALLPASSES; ++j) {
61 | m_allpass0[j].resize(uint32_t(s_allpass[j] * sr));
62 | m_allpass0[j].reset();
63 | m_allpass1[j].resize(uint32_t((s_allpass[j] + STEREO_SPREAD) * sr));
64 | m_allpass1[j].reset();
65 | }
66 |
67 | for (j = 0; j < NUM_COMBS; ++j) {
68 | m_comb0[j].resize(uint32_t(s_comb[j] * sr));
69 | m_comb0[j].reset();
70 | m_comb1[j].resize(uint32_t((s_comb[j] + STEREO_SPREAD) * sr));
71 | m_comb1[j].reset();
72 | }
73 |
74 | reset_feedb();
75 | reset_room();
76 | reset_damp();
77 | }
78 |
79 | void process(float *in0, float *in1, uint32_t nframes,
80 | float wet, float feedb, float room, float damp, float width)
81 | {
82 | if (wet < 1E-9f)
83 | return;
84 |
85 | if (m_feedb != feedb) {
86 | m_feedb = feedb;
87 | reset_feedb();
88 | }
89 |
90 | if (m_room != room) {
91 | m_room = room;
92 | reset_room();
93 | }
94 |
95 | if (m_damp != damp) {
96 | m_damp = damp;
97 | reset_damp();
98 | }
99 |
100 | uint32_t i, j;
101 |
102 | for (i = 0; i < nframes; ++i) {
103 |
104 | float out0 = *in0 * 0.05f; // 0.015f;
105 | float out1 = *in1 * 0.05f; // 0.015f;
106 |
107 | float tmp0 = 0.0f;
108 | float tmp1 = 0.0f;
109 |
110 | for (j = 0; j < NUM_COMBS; ++j) {
111 | tmp0 += m_comb0[j].output(out0);
112 | tmp1 += m_comb1[j].output(out1);
113 | }
114 |
115 | for (j = 0; j < NUM_ALLPASSES; ++j) {
116 | tmp0 = m_allpass0[j].output(tmp0);
117 | tmp1 = m_allpass1[j].output(tmp1);
118 | }
119 |
120 | if (width < 0.0f) {
121 | out0 = tmp0 * (1.0f + width) - tmp1 * width;
122 | out1 = tmp1 * (1.0f + width) - tmp0 * width;
123 | } else {
124 | out0 = tmp0 * width + tmp1 * (1.0f - width);
125 | out1 = tmp1 * width + tmp0 * (1.0f - width);
126 | }
127 |
128 | *in0++ += wet * out0;
129 | *in1++ += wet * out1;
130 | }
131 | }
132 |
133 | protected:
134 |
135 | static const uint32_t NUM_COMBS = 10;
136 | static const uint32_t NUM_ALLPASSES = 6;
137 | static const uint32_t STEREO_SPREAD = 23;
138 |
139 | void reset_room()
140 | {
141 | for (uint32_t j = 0; j < NUM_COMBS; ++j) {
142 | m_comb0[j].set_feedb(m_room);
143 | m_comb1[j].set_feedb(m_room);
144 | }
145 | }
146 |
147 | void reset_damp()
148 | {
149 | const float damp2 = m_damp * m_damp;
150 | for (uint32_t j = 0; j < NUM_COMBS; ++j) {
151 | m_comb0[j].set_damp(damp2);
152 | m_comb1[j].set_damp(damp2);
153 | }
154 | }
155 |
156 | void reset_feedb()
157 | {
158 | const float feedb2 = 2.0f * m_feedb * (2.0f - m_feedb) / 3.0f;
159 | for (uint32_t j = 0; j < NUM_ALLPASSES; ++j) {
160 | m_allpass0[j].set_feedb(feedb2);
161 | m_allpass1[j].set_feedb(feedb2);
162 | }
163 | }
164 |
165 | class sample_buffer
166 | {
167 | public:
168 |
169 | sample_buffer (uint32_t size = 0)
170 | : m_buffer(0), m_size(0), m_index(0)
171 | { resize(size); }
172 |
173 | virtual ~sample_buffer()
174 | { delete [] m_buffer; }
175 |
176 | void reset()
177 | { ::memset(m_buffer, 0, m_size * sizeof(float)); m_index = 0; }
178 |
179 | void resize(uint32_t size)
180 | {
181 | if (size < 1)
182 | size = 1;
183 | if (m_size != size) {
184 | const uint32_t old_size = m_size;
185 | if (size > old_size) {
186 | float *old_buffer = m_buffer;
187 | m_buffer = new float [size];
188 | m_size = size;
189 | if (old_buffer) {
190 | ::memcpy(m_buffer, old_buffer,
191 | old_size * sizeof(float));
192 | delete [] old_buffer;
193 | }
194 | }
195 | }
196 | }
197 |
198 | float *tick()
199 | {
200 | float *buf = m_buffer + m_index;
201 | if (++m_index >= m_size)
202 | m_index = 0;
203 | return buf;
204 | }
205 |
206 | private:
207 |
208 | float *m_buffer;
209 | uint32_t m_size;
210 | uint32_t m_index;
211 | };
212 |
213 | class comb_filter : public sample_buffer
214 | {
215 | public:
216 |
217 | comb_filter (uint32_t size = 0)
218 | : sample_buffer(size), m_feedb(0.5f), m_damp(0.5f), m_out(0.0f) {}
219 |
220 | void set_feedb(float feedb)
221 | { m_feedb = feedb; }
222 | float feedb() const
223 | { return m_feedb; }
224 |
225 | void set_damp(float damp)
226 | { m_damp = damp; }
227 | float damp() const
228 | { return m_damp; }
229 |
230 | void reset()
231 | { sample_buffer::reset(); m_out = 0.0f; }
232 |
233 | float output(float in)
234 | {
235 | float *buf = tick();
236 | float out = *buf;
237 | m_out = denormal(out * (1.0f - m_damp) + m_out * m_damp);
238 | *buf = in + (m_out * m_feedb);
239 | return out;
240 | }
241 |
242 | private:
243 |
244 | float m_feedb;
245 | float m_damp;
246 | float m_out;
247 | };
248 |
249 | class allpass_filter : public sample_buffer
250 | {
251 | public:
252 |
253 | allpass_filter(uint32_t size = 0)
254 | : sample_buffer(size), m_feedb(0.5f) {}
255 |
256 | void set_feedb(float feedb)
257 | { m_feedb = feedb; }
258 | float feedb () const
259 | { return m_feedb; }
260 |
261 | float output(float in)
262 | {
263 | float *buf = tick();
264 | float out = *buf;
265 | *buf = denormal(in + out * m_feedb);
266 | return out - in;
267 | }
268 |
269 | private:
270 |
271 | float m_feedb;
272 | };
273 |
274 | static float denormal(float v)
275 | {
276 | union { float f; uint32_t w; } u;
277 | u.f = v;
278 | return (u.w & 0x7f800000) ? v : 0.0f;
279 | }
280 |
281 | private:
282 |
283 | float m_srate;
284 |
285 | float m_room;
286 | float m_damp;
287 | float m_feedb;
288 |
289 | comb_filter m_comb0[NUM_COMBS];
290 | comb_filter m_comb1[NUM_COMBS];
291 |
292 | allpass_filter m_allpass0[NUM_ALLPASSES];
293 | allpass_filter m_allpass1[NUM_ALLPASSES];
294 | };
295 |
296 |
297 | #endif // __synthv1_reverb_h
298 |
--------------------------------------------------------------------------------
/src/synthv1_sched.cpp:
--------------------------------------------------------------------------------
1 | // synthv1_sched.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 "synthv1_sched.h"
23 |
24 | #include
25 | #include
26 | #include
27 |
28 | #include
29 |
30 |
31 | //-------------------------------------------------------------------------
32 | // synthv1_sched_thread - worker/schedule thread decl.
33 | //
34 |
35 | class synthv1_sched_thread : public QThread
36 | {
37 | public:
38 |
39 | // ctor.
40 | synthv1_sched_thread(uint32_t nsize = 32);
41 |
42 | // dtor.
43 | ~synthv1_sched_thread();
44 |
45 | // schedule processing and wake from wait condition.
46 | void schedule(synthv1_sched *sched);
47 |
48 | // process all pending runs immediately.
49 | void sync_pending();
50 |
51 | // clear all pending runs immediately.
52 | void sync_reset();
53 |
54 | protected:
55 |
56 | // main thread executive.
57 | void run();
58 | void run_process();
59 |
60 | // clear all.
61 | void clear();
62 |
63 | private:
64 |
65 | // sync queue instance reference.
66 | uint32_t m_nsize;
67 | uint32_t m_nmask;
68 |
69 | synthv1_sched **m_items;
70 |
71 | volatile uint32_t m_iread;
72 | volatile uint32_t m_iwrite;
73 |
74 | // whether the thread is logically running.
75 | volatile bool m_running;
76 |
77 | // thread synchronization objects.
78 | QMutex m_mutex;
79 | QWaitCondition m_cond;
80 | };
81 |
82 |
83 | static synthv1_sched_thread *g_sched_thread = nullptr;
84 | static uint32_t g_sched_refcount = 0;
85 |
86 | static QHash > g_sched_notifiers;
87 |
88 |
89 | //-------------------------------------------------------------------------
90 | // synthv1_sched_thread - worker/schedule thread impl.
91 | //
92 |
93 | // ctor.
94 | synthv1_sched_thread::synthv1_sched_thread ( uint32_t nsize ) : QThread()
95 | {
96 | m_nsize = (4 << 1);
97 | while (m_nsize < nsize)
98 | m_nsize <<= 1;
99 | m_nmask = (m_nsize - 1);
100 | m_items = new synthv1_sched * [m_nsize];
101 |
102 | m_iread = 0;
103 | m_iwrite = 0;
104 |
105 | ::memset(m_items, 0, m_nsize * sizeof(synthv1_sched *));
106 |
107 | m_running = false;
108 | }
109 |
110 |
111 | // dtor.
112 | synthv1_sched_thread::~synthv1_sched_thread (void)
113 | {
114 | // fake sync and wait
115 | if (m_running && isRunning()) do {
116 | if (m_mutex.tryLock()) {
117 | m_running = false;
118 | m_cond.wakeAll();
119 | m_mutex.unlock();
120 | }
121 | } while (!wait(100));
122 |
123 | delete [] m_items;
124 | }
125 |
126 |
127 | // schedule processing and wake from wait condition.
128 | void synthv1_sched_thread::schedule ( synthv1_sched *sched )
129 | {
130 | if (!sched->sync_wait()) {
131 | const uint32_t w = (m_iwrite + 1) & m_nmask;
132 | if (w != m_iread) {
133 | m_items[m_iwrite] = sched;
134 | m_iwrite = w;
135 | }
136 | }
137 |
138 | if (m_mutex.tryLock()) {
139 | m_cond.wakeAll();
140 | m_mutex.unlock();
141 | }
142 | }
143 |
144 |
145 | // process all pending runs, immediately.
146 | void synthv1_sched_thread::sync_pending (void)
147 | {
148 | QMutexLocker locker(&m_mutex);
149 |
150 | run_process();
151 | }
152 |
153 |
154 | // clear all pending runs, immediately.
155 | void synthv1_sched_thread::sync_reset (void)
156 | {
157 | QMutexLocker locker(&m_mutex);
158 |
159 | clear();
160 | }
161 |
162 |
163 | void synthv1_sched_thread::clear (void)
164 | {
165 | m_iread = 0;
166 | m_iwrite = 0;
167 |
168 | ::memset(m_items, 0, m_nsize * sizeof(synthv1_sched *));
169 | }
170 |
171 |
172 | // main thread executive.
173 | void synthv1_sched_thread::run (void)
174 | {
175 | m_mutex.lock();
176 |
177 | m_running = true;
178 |
179 | while (m_running) {
180 | // do whatever we must...
181 | run_process();
182 | // wait for sync...
183 | m_cond.wait(&m_mutex);
184 | }
185 |
186 | m_mutex.unlock();
187 | }
188 |
189 |
190 | void synthv1_sched_thread::run_process (void)
191 | {
192 | uint32_t r = m_iread;
193 | while (r != m_iwrite) {
194 | synthv1_sched *sched = m_items[r];
195 | if (sched) {
196 | sched->sync_process();
197 | m_items[r] = nullptr;
198 | }
199 | ++r &= m_nmask;
200 | }
201 | m_iread = r;
202 | }
203 |
204 |
205 | //-------------------------------------------------------------------------
206 | // synthv1_sched - worker/scheduled stuff (pure virtual).
207 | //
208 |
209 | // ctor.
210 | synthv1_sched::synthv1_sched ( synthv1 *pSynth, Type stype, uint32_t nsize )
211 | : m_pSynth(pSynth), m_stype(stype), m_sync_wait(false)
212 | {
213 | m_nsize = (4 << 1);
214 | while (m_nsize < nsize)
215 | m_nsize <<= 1;
216 | m_nmask = (m_nsize - 1);
217 | m_items = new int [m_nsize];
218 |
219 | m_iread = 0;
220 | m_iwrite = 0;
221 |
222 | ::memset(m_items, 0, m_nsize * sizeof(int));
223 |
224 | if (++g_sched_refcount == 1 && g_sched_thread == nullptr) {
225 | g_sched_thread = new synthv1_sched_thread();
226 | g_sched_thread->start();
227 | }
228 | }
229 |
230 |
231 | // dtor (virtual).
232 | synthv1_sched::~synthv1_sched (void)
233 | {
234 | delete [] m_items;
235 |
236 | if (--g_sched_refcount == 0) {
237 | if (g_sched_thread) {
238 | delete g_sched_thread;
239 | g_sched_thread = nullptr;
240 | }
241 | }
242 | }
243 |
244 |
245 | // instance access.
246 | synthv1 *synthv1_sched::instance (void) const
247 | {
248 | return m_pSynth;
249 | }
250 |
251 |
252 | // schedule process.
253 | void synthv1_sched::schedule ( int sid )
254 | {
255 | const uint32_t w = (m_iwrite + 1) & m_nmask;
256 | if (w != m_iread) {
257 | m_items[m_iwrite] = sid;
258 | m_iwrite = w;
259 | }
260 |
261 | if (g_sched_thread)
262 | g_sched_thread->schedule(this);
263 | }
264 |
265 |
266 | // test-and-set.
267 | bool synthv1_sched::sync_wait (void)
268 | {
269 | const bool sync_wait = m_sync_wait;
270 |
271 | if (!sync_wait)
272 | m_sync_wait = true;
273 |
274 | return sync_wait;
275 | }
276 |
277 |
278 | // scheduled processor.
279 | void synthv1_sched::sync_process (void)
280 | {
281 | // do whatever we must...
282 | uint32_t r = m_iread;
283 | while (r != m_iwrite) {
284 | const int sid = m_items[r];
285 | process(sid);
286 | sync_notify(m_pSynth, m_stype, sid);
287 | m_items[r] = 0;
288 | ++r &= m_nmask;
289 | }
290 | m_iread = r;
291 |
292 | m_sync_wait = false;
293 | }
294 |
295 |
296 | // signal broadcast (static).
297 | void synthv1_sched::sync_notify ( synthv1 *pSynth, Type stype, int sid )
298 | {
299 | if (g_sched_notifiers.contains(pSynth)) {
300 | const QList& list
301 | = g_sched_notifiers.value(pSynth);
302 | QListIterator iter(list);
303 | while (iter.hasNext())
304 | iter.next()->notify(stype, sid);
305 | }
306 | }
307 |
308 |
309 | // process/clear pending schedules, immediately. (static)
310 | void synthv1_sched::sync_pending (void)
311 | {
312 | if (g_sched_thread)
313 | g_sched_thread->sync_pending();
314 | }
315 |
316 |
317 | void synthv1_sched::sync_reset (void)
318 | {
319 | if (g_sched_thread)
320 | g_sched_thread->sync_reset();
321 | }
322 |
323 |
324 | //-------------------------------------------------------------------------
325 | // synthv1_sched::Notifier - worker/schedule proxy decl.
326 | //
327 |
328 | // ctor.
329 | synthv1_sched::Notifier::Notifier ( synthv1 *pSynth )
330 | : m_pSynth(pSynth)
331 | {
332 | g_sched_notifiers[pSynth].append(this);
333 | }
334 |
335 |
336 | // dtor.
337 | synthv1_sched::Notifier::~Notifier (void)
338 | {
339 | if (g_sched_notifiers.contains(m_pSynth)) {
340 | QList& list = g_sched_notifiers[m_pSynth];
341 | list.removeAll(this);
342 | if (list.isEmpty())
343 | g_sched_notifiers.remove(m_pSynth);
344 | }
345 | }
346 |
347 |
348 | // end of synthv1_sched.cpp
349 |
--------------------------------------------------------------------------------
/src/synthv1_sched.h:
--------------------------------------------------------------------------------
1 | // synthv1_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 __synthv1_sched_h
23 | #define __synthv1_sched_h
24 |
25 | #include
26 |
27 | // forward decls.
28 | class synthv1;
29 |
30 |
31 | //-------------------------------------------------------------------------
32 | // synthv1_sched - worker/scheduled stuff (pure virtual).
33 | //
34 |
35 | class synthv1_sched
36 | {
37 | public:
38 |
39 | // plausible sched types.
40 | enum Type { Wave, Programs, Controls, Controller, MidiIn };
41 |
42 | // ctor.
43 | synthv1_sched(synthv1 *pSynth, Type stype, uint32_t nsize = 8);
44 |
45 | // virtual dtor.
46 | virtual ~synthv1_sched();
47 |
48 | // instance access.
49 | synthv1 *instance() const;
50 |
51 | // schedule process.
52 | void schedule(int sid = 0);
53 |
54 | // test-and-set wait.
55 | bool sync_wait();
56 |
57 | // scheduled processor.
58 | void sync_process();
59 |
60 | // (pure) virtual processor.
61 | virtual void process(int sid) = 0;
62 |
63 | // signal broadcast (static).
64 | static void sync_notify(synthv1 *pSynth, Type stype, int sid);
65 |
66 | // Notifier - Worker/schedule proxy decl.
67 | //
68 | class Notifier
69 | {
70 | public:
71 |
72 | // ctor.
73 | Notifier(synthv1 *pSynth);
74 |
75 | // dtor.
76 | virtual ~Notifier();
77 |
78 | // signal notifier.
79 | virtual void notify(synthv1_sched::Type stype, int sid) const = 0;
80 |
81 | private:
82 |
83 | // instance variables.
84 | synthv1 *m_pSynth;
85 | };
86 |
87 | // process/clear pending schedules, immediately. (static)
88 | static void sync_pending();
89 | static void sync_reset();
90 |
91 | private:
92 |
93 | // instance variables.
94 | synthv1 *m_pSynth;
95 |
96 | Type m_stype;
97 |
98 | // sched queue instance reference.
99 | uint32_t m_nsize;
100 | uint32_t m_nmask;
101 |
102 | int *m_items;
103 |
104 | volatile uint32_t m_iread;
105 | volatile uint32_t m_iwrite;
106 |
107 | volatile bool m_sync_wait;
108 | };
109 |
110 |
111 | #endif // __synthv1_sched_h
112 |
113 | // end of synthv1_sched.h
114 |
--------------------------------------------------------------------------------
/src/synthv1_tuning.h:
--------------------------------------------------------------------------------
1 | // synthv1_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 __synthv1_tuning_h
23 | #define __synthv1_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 synthv1_tuning
53 | {
54 | public:
55 |
56 | // Default reference note and pitch (A4 @440hz)
57 | synthv1_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 // __synthv1_tuning_h
107 |
108 | // end of synthv1_tuning.h
109 |
--------------------------------------------------------------------------------
/src/synthv1_ui.cpp:
--------------------------------------------------------------------------------
1 | // synthv1_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 "synthv1_ui.h"
23 |
24 | #include "synthv1_param.h"
25 |
26 |
27 | //-------------------------------------------------------------------------
28 | // synthv1_ui - decl.
29 | //
30 |
31 | synthv1_ui::synthv1_ui ( synthv1 *pSynth, bool bPlugin )
32 | : m_pSynth(pSynth), m_bPlugin(bPlugin)
33 | {
34 | }
35 |
36 |
37 | synthv1 *synthv1_ui::instance (void) const
38 | {
39 | return m_pSynth;
40 | }
41 |
42 |
43 | bool synthv1_ui::isPlugin (void) const
44 | {
45 | return m_bPlugin;
46 | }
47 |
48 |
49 | bool synthv1_ui::newPreset (void)
50 | {
51 | return synthv1_param::newPreset(m_pSynth);
52 | }
53 |
54 |
55 | bool synthv1_ui::loadPreset ( const QString& sFilename )
56 | {
57 | return synthv1_param::loadPreset(m_pSynth, sFilename);
58 | }
59 |
60 | bool synthv1_ui::savePreset ( const QString& sFilename )
61 | {
62 | return synthv1_param::savePreset(m_pSynth, sFilename);
63 | }
64 |
65 |
66 | void synthv1_ui::setParamValue ( synthv1::ParamIndex index, float fValue )
67 | {
68 | m_pSynth->setParamValue(index, fValue);
69 | }
70 |
71 | float synthv1_ui::paramValue ( synthv1::ParamIndex index ) const
72 | {
73 | return m_pSynth->paramValue(index);
74 | }
75 |
76 |
77 | synthv1_controls *synthv1_ui::controls (void) const
78 | {
79 | return m_pSynth->controls();
80 | }
81 |
82 |
83 | synthv1_programs *synthv1_ui::programs (void) const
84 | {
85 | return m_pSynth->programs();
86 | }
87 |
88 |
89 | void synthv1_ui::reset (void)
90 | {
91 | return m_pSynth->reset();
92 | }
93 |
94 |
95 | void synthv1_ui::updatePreset ( bool bDirty )
96 | {
97 | m_pSynth->updatePreset(bDirty);
98 | }
99 |
100 |
101 | void synthv1_ui::updateParam ( synthv1::ParamIndex index )
102 | {
103 | m_pSynth->updateParam(index);
104 | }
105 |
106 |
107 | void synthv1_ui::midiInEnabled ( bool bEnabled )
108 | {
109 | m_pSynth->midiInEnabled(bEnabled);
110 | }
111 |
112 |
113 | uint32_t synthv1_ui::midiInCount (void)
114 | {
115 | return m_pSynth->midiInCount();
116 | }
117 |
118 |
119 | void synthv1_ui::directNoteOn ( int note, int vel )
120 | {
121 | m_pSynth->directNoteOn(note, vel);
122 | }
123 |
124 |
125 | void synthv1_ui::setTuningEnabled ( bool enabled )
126 | {
127 | m_pSynth->setTuningEnabled(enabled);
128 | }
129 |
130 | bool synthv1_ui::isTuningEnabled (void) const
131 | {
132 | return m_pSynth->isTuningEnabled();
133 | }
134 |
135 |
136 | void synthv1_ui::setTuningRefPitch ( float refPitch )
137 | {
138 | m_pSynth->setTuningRefPitch(refPitch);
139 | }
140 |
141 | float synthv1_ui::tuningRefPitch (void) const
142 | {
143 | return m_pSynth->tuningRefPitch();
144 | }
145 |
146 |
147 | void synthv1_ui::setTuningRefNote ( int refNote )
148 | {
149 | m_pSynth->setTuningRefNote(refNote);
150 | }
151 |
152 | int synthv1_ui::tuningRefNote (void) const
153 | {
154 | return m_pSynth->tuningRefNote();
155 | }
156 |
157 |
158 | void synthv1_ui::setTuningScaleFile ( const char *pszScaleFile )
159 | {
160 | m_pSynth->setTuningScaleFile(pszScaleFile);
161 | }
162 |
163 | const char *synthv1_ui::tuningScaleFile (void) const
164 | {
165 | return m_pSynth->tuningScaleFile();
166 | }
167 |
168 |
169 | void synthv1_ui::setTuningKeyMapFile ( const char *pszKeyMapFile )
170 | {
171 | m_pSynth->setTuningKeyMapFile(pszKeyMapFile);
172 | }
173 |
174 | const char *synthv1_ui::tuningKeyMapFile (void) const
175 | {
176 | return m_pSynth->tuningKeyMapFile();
177 | }
178 |
179 |
180 | void synthv1_ui::resetTuning (void)
181 | {
182 | m_pSynth->resetTuning();
183 | }
184 |
185 |
186 | // MIDI note/octave name helper (static).
187 | QString synthv1_ui::noteName ( int note )
188 | {
189 | static const char *s_notes[] =
190 | {
191 | QT_TR_NOOP("C"),
192 | QT_TR_NOOP("C#/Db"),
193 | QT_TR_NOOP("D"),
194 | QT_TR_NOOP("D#/Eb"),
195 | QT_TR_NOOP("E"),
196 | QT_TR_NOOP("F"),
197 | QT_TR_NOOP("F#/Gb"),
198 | QT_TR_NOOP("G"),
199 | QT_TR_NOOP("G#/Ab"),
200 | QT_TR_NOOP("A"),
201 | QT_TR_NOOP("A#/Bb"),
202 | QT_TR_NOOP("B")
203 | };
204 |
205 | return QString("%1 %2").arg(s_notes[note % 12]).arg((note / 12) - 1);
206 | }
207 |
208 |
209 | // end of synthv1_ui.cpp
210 |
--------------------------------------------------------------------------------
/src/synthv1_ui.h:
--------------------------------------------------------------------------------
1 | // synthv1_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 __synthv1_ui_h
23 | #define __synthv1_ui_h
24 |
25 | #include "synthv1.h"
26 |
27 | #include
28 |
29 |
30 | //-------------------------------------------------------------------------
31 | // synthv1_ui - decl.
32 | //
33 |
34 | class synthv1_ui
35 | {
36 | public:
37 |
38 | synthv1_ui(synthv1 *pSynth, bool bPlugin);
39 |
40 | synthv1 *instance() const;
41 |
42 | bool isPlugin() const;
43 |
44 | bool newPreset();
45 |
46 | bool loadPreset(const QString& sFilename);
47 | bool savePreset(const QString& sFilename);
48 |
49 | void setParamValue(synthv1::ParamIndex index, float fValue);
50 | float paramValue(synthv1::ParamIndex index) const;
51 |
52 | synthv1_controls *controls() const;
53 | synthv1_programs *programs() const;
54 |
55 | void reset();
56 |
57 | void updatePreset(bool bDirty);
58 |
59 | void updateParam(synthv1::ParamIndex index);
60 |
61 | void midiInEnabled(bool bEnabled);
62 | uint32_t midiInCount();
63 |
64 | void directNoteOn(int note, int vel);
65 |
66 | void setTuningEnabled(bool enabled);
67 | bool isTuningEnabled() const;
68 |
69 | void setTuningRefPitch(float refPitch);
70 | float tuningRefPitch() const;
71 |
72 | void setTuningRefNote(int refNote);
73 | int tuningRefNote() const;
74 |
75 | void setTuningScaleFile(const char *pszScaleFile);
76 | const char *tuningScaleFile() const;
77 |
78 | void setTuningKeyMapFile(const char *pszKeyMapFile);
79 | const char *tuningKeyMapFile() const;
80 |
81 | void resetTuning();
82 |
83 | // MIDI note/octave name helper.
84 | static QString noteName(int note);
85 |
86 | private:
87 |
88 | synthv1 *m_pSynth;
89 |
90 | bool m_bPlugin;
91 | };
92 |
93 |
94 | #endif// __synthv1_ui_h
95 |
96 | // end of synthv1_ui.h
97 |
--------------------------------------------------------------------------------
/src/synthv1widget.h:
--------------------------------------------------------------------------------
1 | // synthv1widget.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 __synthv1widget_h
23 | #define __synthv1widget_h
24 |
25 | #include "synthv1_config.h"
26 | #include "synthv1_sched.h"
27 |
28 | #include "synthv1_ui.h"
29 |
30 | #include
31 |
32 |
33 | // forward decls.
34 | namespace Ui { class synthv1widget; }
35 |
36 | class synthv1widget_param;
37 | class synthv1widget_sched;
38 |
39 |
40 | //-------------------------------------------------------------------------
41 | // synthv1widget - decl.
42 | //
43 |
44 | class synthv1widget : public QWidget
45 | {
46 | Q_OBJECT
47 |
48 | public:
49 |
50 | // Constructor
51 | synthv1widget(QWidget *pParent = nullptr);
52 |
53 | // Destructor.
54 | virtual ~synthv1widget();
55 |
56 | // Open/close the scheduler/work notifier.
57 | void openSchedNotifier();
58 | void closeSchedNotifier();
59 |
60 | // Param port accessors.
61 | void setParamValue(synthv1::ParamIndex index, float fValue);
62 | float paramValue(synthv1::ParamIndex index) const;
63 |
64 | // Param kbob (widget) mapper.
65 | void setParamKnob(synthv1::ParamIndex index, synthv1widget_param *pKnob);
66 | synthv1widget_param *paramKnob(synthv1::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 | // Schedule 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 | // Menu actions.
121 | void helpConfigure();
122 |
123 | void helpAbout();
124 | void helpAboutQt();
125 |
126 | protected:
127 |
128 | // Synth engine accessor.
129 | virtual synthv1_ui *ui_instance() const = 0;
130 |
131 | // Reset swap params A/B group.
132 | void resetSwapParams();
133 |
134 | // Initialize all param/knob values.
135 | void updateParamValues();
136 |
137 | // Reset all param/knob default values.
138 | void resetParamValues();
139 | void resetParamKnobs();
140 |
141 | // Param port methods.
142 | virtual void updateParam(synthv1::ParamIndex index, float fValue) const = 0;
143 |
144 | // Update local tied widgets.
145 | void updateParamEx(synthv1::ParamIndex index, float fValue);
146 |
147 | // Update scheduled controllers param/knob widgets.
148 | void updateSchedParam(synthv1::ParamIndex index, float fValue);
149 |
150 | // Preset status updater.
151 | void updateLoadPreset(const QString& sPreset);
152 |
153 | // Dirty flag (overridable virtual) methods.
154 | virtual void updateDirtyPreset(bool bDirtyPreset);
155 |
156 | // Show/hide dget handlers.
157 | void showEvent(QShowEvent *pShowEvent);
158 | void hideEvent(QHideEvent *pHideEvent);
159 |
160 | private:
161 |
162 | // Instance variables.
163 | Ui::synthv1widget *p_ui;
164 | Ui::synthv1widget& m_ui;
165 |
166 | synthv1widget_sched *m_sched_notifier;
167 |
168 | QHash m_paramKnobs;
169 | QHash m_knobParams;
170 |
171 | float m_params_ab[synthv1::NUM_PARAMS];
172 |
173 | int m_iUpdate;
174 | };
175 |
176 |
177 | //-------------------------------------------------------------------------
178 | // synthv1widget_sched - worker/schedule proxy decl.
179 | //
180 |
181 | class synthv1widget_sched : public QObject
182 | {
183 | Q_OBJECT
184 |
185 | public:
186 |
187 | // ctor.
188 | synthv1widget_sched(synthv1 *pSynth, QObject *pParent = nullptr)
189 | : QObject(pParent), m_notifier(pSynth, this) {}
190 |
191 | signals:
192 |
193 | // Notification signal.
194 | void notify(int stype, int sid);
195 |
196 | protected:
197 |
198 | // Notififier visitor.
199 | class Notifier : public synthv1_sched::Notifier
200 | {
201 | public:
202 |
203 | Notifier(synthv1 *pSynth, synthv1widget_sched *pSched)
204 | : synthv1_sched::Notifier(pSynth), m_pSched(pSched) {}
205 |
206 | void notify(synthv1_sched::Type stype, int sid) const
207 | { m_pSched->emit_notify(stype, sid); }
208 |
209 | private:
210 |
211 | synthv1widget_sched *m_pSched;
212 | };
213 |
214 | // Notification method.
215 | void emit_notify(synthv1_sched::Type stype, int sid)
216 | { emit notify(int(stype), sid); }
217 |
218 | private:
219 |
220 | // Instance variables.
221 | Notifier m_notifier;
222 | };
223 |
224 |
225 | #endif // __synthv1widget_h
226 |
227 | // end of synthv1widget.h
228 |
--------------------------------------------------------------------------------
/src/synthv1widget_config.h:
--------------------------------------------------------------------------------
1 | // synthv1widget_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 __synthv1widget_config_h
23 | #define __synthv1widget_config_h
24 |
25 | #include "synthv1_config.h"
26 |
27 | #include
28 |
29 |
30 | // forward decls.
31 | namespace Ui { class synthv1widget_config; }
32 |
33 | class synthv1widget;
34 | class synthv1_ui;
35 |
36 | class QComboBox;
37 | class QFileInfo;
38 |
39 |
40 | //----------------------------------------------------------------------------
41 | // synthv1widget_config -- UI wrapper form.
42 |
43 | class synthv1widget_config : public QDialog
44 | {
45 | Q_OBJECT
46 |
47 | public:
48 |
49 | // ctor.
50 | synthv1widget_config(synthv1widget *pParent, synthv1_ui *pSynthUi);
51 |
52 | // dtor.
53 | ~synthv1widget_config();
54 |
55 | // UI instance accessors.
56 | synthv1_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::synthv1widget_config *p_ui;
121 | Ui::synthv1widget_config& m_ui;
122 |
123 | // Instance reference.
124 | synthv1_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 // __synthv1widget_config_h
141 |
142 | // end of synthv1widget_config.h
143 |
--------------------------------------------------------------------------------
/src/synthv1widget_control.h:
--------------------------------------------------------------------------------
1 | // synthv1widget_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 __synthv1widget_control_h
23 | #define __synthv1widget_control_h
24 |
25 | #include "synthv1_controls.h"
26 | #include "synthv1_param.h"
27 |
28 | #include
29 |
30 |
31 | // forward decls.
32 | namespace Ui { class synthv1widget_control; }
33 |
34 | class QAbstractButton;
35 | class QCloseEvent;
36 |
37 |
38 | //----------------------------------------------------------------------------
39 | // synthv1widget_control -- UI wrapper form.
40 |
41 | class synthv1widget_control : public QDialog
42 | {
43 | Q_OBJECT
44 |
45 | public:
46 |
47 | // Pseudo-singleton instance.
48 | static synthv1widget_control *getInstance();
49 |
50 | // Pseudo-constructor.
51 | static void showInstance(
52 | synthv1_controls *pControls, synthv1::ParamIndex index,
53 | const QString& sTitle, QWidget *pParent = nullptr);
54 |
55 | // Control accessors.
56 | void setControls(synthv1_controls *pControls, synthv1::ParamIndex index);
57 | synthv1_controls *controls() const;
58 | synthv1::ParamIndex controlIndex() const;
59 |
60 | // Process incoming controller key event.
61 | void setControlKey(const synthv1_controls::Key& key);
62 | synthv1_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 | synthv1widget_control(QWidget *pParent = nullptr);
83 |
84 | // Destructor.
85 | ~synthv1widget_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(synthv1_controls::Type ctype);
96 | synthv1_controls::Type controlType() const;
97 |
98 | void setControlParam(unsigned short param);
99 | unsigned short controlParam() const;
100 |
101 | unsigned short controlChannel() const;
102 |
103 | synthv1_controls::Type controlTypeFromIndex (int iIndex) const;
104 | int indexFromControlType(synthv1_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::synthv1widget_control *p_ui;
113 | Ui::synthv1widget_control& m_ui;
114 |
115 | // Instance variables.
116 | synthv1_controls *m_pControls;
117 |
118 | // Target subject.
119 | synthv1_controls::Key m_key;
120 | synthv1::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 synthv1widget_control *g_pInstance;
130 | };
131 |
132 |
133 | #endif // __synthv1widget_control_h
134 |
135 |
136 | // end of synthv1widget_control.h
137 |
--------------------------------------------------------------------------------
/src/synthv1widget_control.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | rncbc aka Rui Nuno Capela
4 | synthv1 - an old-school 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 | synthv1widget_control
24 |
25 |
26 |
27 | 0
28 | 0
29 | 320
30 | 120
31 |
32 |
33 |
34 | MIDI Controller
35 |
36 |
37 | :/images/synthv1_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/synthv1widget_controls.h:
--------------------------------------------------------------------------------
1 | // synthv1widget_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 __synthv1widget_controls_h
23 | #define __synthv1widget_controls_h
24 |
25 | #include
26 |
27 | #include
28 |
29 |
30 | // forward decls.
31 | class synthv1_controls;
32 |
33 |
34 | //----------------------------------------------------------------------------
35 | // synthv1widget_controls -- Custom (tree) widget.
36 |
37 | class synthv1widget_controls : public QTreeWidget
38 | {
39 | Q_OBJECT
40 |
41 | public:
42 |
43 | // ctor.
44 | synthv1widget_controls(QWidget *pParent = nullptr);
45 | // dtor.
46 | ~synthv1widget_controls();
47 |
48 | // utilities.
49 | void loadControls(synthv1_controls *pControls);
50 | void saveControls(synthv1_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 // __synthv1widget_controls_h
81 |
82 | // end of synthv1widget_controls.h
83 |
--------------------------------------------------------------------------------
/src/synthv1widget_env.h:
--------------------------------------------------------------------------------
1 | // synthv1widget_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 __synthv1widget_env_h
23 | #define __synthv1widget_env_h
24 |
25 | #include
26 | #include
27 |
28 |
29 | //----------------------------------------------------------------------------
30 | // synthv1widget_env -- Custom widget
31 |
32 | class synthv1widget_env : public QFrame
33 | {
34 | Q_OBJECT
35 |
36 | public:
37 |
38 | // Constructor.
39 | synthv1widget_env(QWidget *pParent = nullptr);
40 | // Destructor.
41 | ~synthv1widget_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 // __synthv1widget_env_h
114 |
115 |
116 | // end of synthv1widget_env.h
117 |
--------------------------------------------------------------------------------
/src/synthv1widget_filt.h:
--------------------------------------------------------------------------------
1 | // synthv1widget_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 __synthv1widget_filt_h
23 | #define __synthv1widget_filt_h
24 |
25 | #include
26 | #include
27 |
28 |
29 | //----------------------------------------------------------------------------
30 | // synthv1widget_filt -- Custom widget
31 |
32 | class synthv1widget_filt : public QFrame
33 | {
34 | Q_OBJECT
35 |
36 | public:
37 |
38 | // Constructor.
39 | synthv1widget_filt(QWidget *pParent = nullptr);
40 | // Destructor.
41 | ~synthv1widget_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 // __synthv1widget_filt_h
116 |
117 |
118 | // end of synthv1widget_filt.h
119 |
--------------------------------------------------------------------------------
/src/synthv1widget_jack.cpp:
--------------------------------------------------------------------------------
1 | // synthv1widget_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 "synthv1widget_jack.h"
23 |
24 | #include "synthv1widget_palette.h"
25 |
26 | #include "synthv1_jack.h"
27 |
28 | #ifdef CONFIG_NSM
29 | #include "synthv1_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 | // synthv1widget_jack - impl.
63 | //
64 |
65 | // Constructor.
66 | synthv1widget_jack::synthv1widget_jack ( synthv1_jack *pSynth )
67 | : synthv1widget(), m_pSynth(pSynth)
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 | synthv1_config *pConfig = synthv1_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 | synthv1widget_palette::addNamedPaletteConf(
100 | pConfig, name, fi.absoluteFilePath());
101 | }
102 | }
103 | }
104 | if (!pConfig->sCustomColorTheme.isEmpty()) {
105 | QPalette pal;
106 | if (synthv1widget_palette::namedPalette(
107 | pConfig, pConfig->sCustomColorTheme, pal))
108 | synthv1widget::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_pSynthUi = new synthv1_ui(m_pSynth, false);
118 |
119 | // Initialise preset stuff...
120 | clearPreset();
121 |
122 | // Initial update, always...
123 | resetParamValues();
124 | resetParamKnobs();
125 |
126 | // May initialize the scheduler/work notifier.
127 | openSchedNotifier();
128 | }
129 |
130 |
131 | // Destructor.
132 | synthv1widget_jack::~synthv1widget_jack (void)
133 | {
134 | delete m_pSynthUi;
135 | }
136 |
137 |
138 | // Synth engine accessor.
139 | synthv1_ui *synthv1widget_jack::ui_instance (void) const
140 | {
141 | return m_pSynthUi;
142 | }
143 |
144 | #ifdef CONFIG_NSM
145 |
146 | // NSM client accessors.
147 | void synthv1widget_jack::setNsmClient ( synthv1_nsm *pNsmClient )
148 | {
149 | m_pNsmClient = pNsmClient;
150 | }
151 |
152 | synthv1_nsm *synthv1widget_jack::nsmClient (void) const
153 | {
154 | return m_pNsmClient;
155 | }
156 |
157 | #endif // CONFIG_NSM
158 |
159 |
160 | // Param port method.
161 | void synthv1widget_jack::updateParam (
162 | synthv1::ParamIndex index, float fValue ) const
163 | {
164 | m_pSynthUi->setParamValue(index, fValue);
165 | }
166 |
167 |
168 | // Dirty flag method.
169 | void synthv1widget_jack::updateDirtyPreset ( bool bDirtyPreset )
170 | {
171 | synthv1widget::updateDirtyPreset(bDirtyPreset);
172 |
173 | #ifdef CONFIG_NSM
174 | if (m_pNsmClient && m_pNsmClient->is_active() && bDirtyPreset)
175 | m_pNsmClient->dirty(true);
176 | #endif
177 | }
178 |
179 |
180 | // Application close.
181 | void synthv1widget_jack::closeEvent ( QCloseEvent *pCloseEvent )
182 | {
183 | #ifdef CONFIG_NSM
184 | if (m_pNsmClient && m_pNsmClient->is_active()) {
185 | pCloseEvent->ignore();
186 | synthv1widget::hide();
187 | }
188 | else
189 | #endif
190 | // Let's be sure about that...
191 | if (queryClose()) {
192 | pCloseEvent->accept();
193 | #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
194 | QApplication::exit(0);
195 | #else
196 | QApplication::quit();
197 | #endif
198 | } else {
199 | pCloseEvent->ignore();
200 | }
201 | }
202 |
203 |
204 | #ifdef CONFIG_NSM
205 |
206 | // Optional GUI handlers.
207 | void synthv1widget_jack::showEvent ( QShowEvent *pShowEvent )
208 | {
209 | synthv1widget::showEvent(pShowEvent);
210 |
211 | if (m_pNsmClient)
212 | m_pNsmClient->visible(true);
213 | }
214 |
215 | void synthv1widget_jack::hideEvent ( QHideEvent *pHideEvent )
216 | {
217 | if (m_pNsmClient)
218 | m_pNsmClient->visible(false);
219 |
220 | synthv1widget::hideEvent(pHideEvent);
221 | }
222 |
223 | #endif // CONFIG_NSM
224 |
225 |
226 | // end of synthv1widget_jack.cpp
227 |
--------------------------------------------------------------------------------
/src/synthv1widget_jack.h:
--------------------------------------------------------------------------------
1 | // synthv1widget_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 __synthv1widget_jack_h
23 | #define __synthv1widget_jack_h
24 |
25 | #include "synthv1widget.h"
26 |
27 |
28 | // Forward decls.
29 | class synthv1_jack;
30 |
31 | #ifdef CONFIG_NSM
32 | class synthv1_nsm;
33 | #endif
34 |
35 |
36 | //-------------------------------------------------------------------------
37 | // synthv1widget_jack - decl.
38 | //
39 |
40 | class synthv1widget_jack : public synthv1widget
41 | {
42 | public:
43 |
44 | // Constructor.
45 | synthv1widget_jack(synthv1_jack *pSynth);
46 |
47 | // Destructor.
48 | ~synthv1widget_jack();
49 |
50 | #ifdef CONFIG_NSM
51 | // NSM client accessors.
52 | void setNsmClient(synthv1_nsm *pNsmClient);
53 | synthv1_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 | synthv1_ui *ui_instance() const;
63 |
64 | // Param port method.
65 | void updateParam(synthv1::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 | synthv1 *m_pSynth;
80 | synthv1_ui *m_pSynthUi;
81 |
82 | #ifdef CONFIG_NSM
83 | synthv1_nsm *m_pNsmClient;
84 | #endif
85 | };
86 |
87 |
88 | #endif // __synthv1widget_jack_h
89 |
90 | // end of synthv1widget_jack.h
91 |
--------------------------------------------------------------------------------
/src/synthv1widget_keybd.h:
--------------------------------------------------------------------------------
1 | // synthv1widget_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 __synthv1widget_keybd_h
23 | #define __synthv1widget_keybd_h
24 |
25 | #include
26 | #include
27 | #include
28 |
29 |
30 | //-------------------------------------------------------------------------
31 | // synthv1widget_keybd - A horizontal piano keyboard widget.
32 |
33 | class synthv1widget_keybd : public QWidget
34 | {
35 | Q_OBJECT
36 |
37 | public:
38 |
39 | // Constructor.
40 | synthv1widget_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 // __synthv1widget_keybd_h
192 |
193 | // end of synthv1widget_keybd.h
194 |
--------------------------------------------------------------------------------
/src/synthv1widget_lv2.cpp:
--------------------------------------------------------------------------------
1 | // synthv1widget_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 "synthv1widget_lv2.h"
23 |
24 | #include "synthv1_lv2.h"
25 |
26 | #include
27 | #include
28 | #include
29 |
30 | #include "synthv1widget_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 | // synthv1widget_lv2 - impl.
57 | //
58 |
59 | synthv1widget_lv2::synthv1widget_lv2 ( synthv1_lv2 *pSynth,
60 | LV2UI_Controller controller, LV2UI_Write_Function write_function )
61 | : synthv1widget()
62 | {
63 | // Check whether under a dedicated application instance...
64 | QApplication *pApp = synthv1_lv2::qapp_instance();
65 | if (pApp) {
66 | // Special style paths...
67 | QString sPluginsPath = pApp->applicationDirPath();
68 | sPluginsPath.remove(CONFIG_BINDIR);
69 | sPluginsPath.append(CONFIG_PLUGINSDIR);
70 | if (QDir(sPluginsPath).exists())
71 | pApp->addLibraryPath(CONFIG_PLUGINSDIR);
72 | }
73 |
74 | // Custom color/style themes...
75 | synthv1_config *pConfig = synthv1_config::getInstance();
76 | if (pConfig) {
77 | const QChar sep = QDir::separator();
78 | QString sPalettePath = QApplication::applicationDirPath();
79 | sPalettePath.remove(CONFIG_BINDIR);
80 | sPalettePath.append(CONFIG_DATADIR);
81 | sPalettePath.append(sep);
82 | sPalettePath.append(PROJECT_NAME);
83 | sPalettePath.append(sep);
84 | sPalettePath.append("palette");
85 | if (QDir(sPalettePath).exists()) {
86 | QStringList names;
87 | names.append("KXStudio");
88 | names.append("Wonton Soup");
89 | QStringListIterator name_iter(names);
90 | while (name_iter.hasNext()) {
91 | const QString& name = name_iter.next();
92 | const QFileInfo fi(sPalettePath, name + ".conf");
93 | if (fi.isReadable()) {
94 | synthv1widget_palette::addNamedPaletteConf(
95 | pConfig, name, fi.absoluteFilePath());
96 | }
97 | }
98 | }
99 | if (!pConfig->sCustomColorTheme.isEmpty()) {
100 | QPalette pal;
101 | if (synthv1widget_palette::namedPalette(
102 | pConfig, pConfig->sCustomColorTheme, pal))
103 | synthv1widget::setPalette(pal);
104 | }
105 | #if 0//--Not applicable to plugin forms...
106 | if (!pConfig->sCustomStyleTheme.isEmpty()) {
107 | QApplication::setStyle(
108 | QStyleFactory::create(pConfig->sCustomStyleTheme));
109 | }
110 | #endif
111 | }
112 |
113 | // Initialize (user) interface stuff...
114 | m_pSynthUi = new synthv1_lv2ui(pSynth, controller, write_function);
115 |
116 | #ifdef CONFIG_LV2_UI_EXTERNAL
117 | m_external_host = nullptr;
118 | #endif
119 | #ifdef CONFIG_LV2_UI_IDLE
120 | m_bIdleClosed = false;
121 | #endif
122 |
123 | // Initialise preset stuff...
124 | clearPreset();
125 |
126 | // Initial update, always...
127 | //resetParamValues();
128 | resetParamKnobs();
129 |
130 | // May initialize the scheduler/work notifier.
131 | openSchedNotifier();
132 | }
133 |
134 |
135 | // Destructor.
136 | synthv1widget_lv2::~synthv1widget_lv2 (void)
137 | {
138 | delete m_pSynthUi;
139 | }
140 |
141 |
142 | // Synth engine accessor.
143 | synthv1_ui *synthv1widget_lv2::ui_instance (void) const
144 | {
145 | return m_pSynthUi;
146 | }
147 |
148 |
149 | #ifdef CONFIG_LV2_UI_EXTERNAL
150 |
151 | void synthv1widget_lv2::setExternalHost ( LV2_External_UI_Host *external_host )
152 | {
153 | m_external_host = external_host;
154 | }
155 |
156 | const LV2_External_UI_Host *synthv1widget_lv2::externalHost (void) const
157 | {
158 | return m_external_host;
159 | }
160 |
161 | #endif // CONFIG_LV2_UI_EXTERNAL
162 |
163 |
164 | #ifdef CONFIG_LV2_UI_IDLE
165 |
166 | bool synthv1widget_lv2::isIdleClosed (void) const
167 | {
168 | return m_bIdleClosed;
169 | }
170 |
171 | #endif // CONFIG_LV2_UI_IDLE
172 |
173 |
174 | // Close event handler.
175 | void synthv1widget_lv2::closeEvent ( QCloseEvent *pCloseEvent )
176 | {
177 | synthv1widget::closeEvent(pCloseEvent);
178 |
179 | #ifdef CONFIG_LV2_UI_IDLE
180 | if (pCloseEvent->isAccepted())
181 | m_bIdleClosed = true;
182 | #endif
183 | #ifdef CONFIG_LV2_UI_EXTERNAL
184 | if (m_external_host && m_external_host->ui_closed) {
185 | if (pCloseEvent->isAccepted())
186 | m_external_host->ui_closed(m_pSynthUi->controller());
187 | }
188 | #endif
189 | }
190 |
191 |
192 | // LV2 port event dispatcher.
193 | void synthv1widget_lv2::port_event ( uint32_t port_index,
194 | uint32_t buffer_size, uint32_t format, const void *buffer )
195 | {
196 | if (format == 0 && buffer_size == sizeof(float)) {
197 | const synthv1::ParamIndex index
198 | = synthv1::ParamIndex(port_index - synthv1_lv2::ParamBase);
199 | const float fValue = *(float *) buffer;
200 | setParamValue(index, fValue);
201 | }
202 | }
203 |
204 |
205 | // Param method.
206 | void synthv1widget_lv2::updateParam (
207 | synthv1::ParamIndex index, float fValue ) const
208 | {
209 | m_pSynthUi->write_function(index, fValue);
210 | }
211 |
212 |
213 | // end of synthv1widget_lv2.cpp
214 |
--------------------------------------------------------------------------------
/src/synthv1widget_lv2.h:
--------------------------------------------------------------------------------
1 | // synthv1widget_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 __synthv1widget_lv2_h
23 | #define __synthv1widget_lv2_h
24 |
25 | #include "synthv1widget.h"
26 | #include "synthv1_lv2ui.h"
27 |
28 |
29 | //-------------------------------------------------------------------------
30 | // synthv1widget_lv2 - decl.
31 | //
32 |
33 | class synthv1widget_lv2 : public synthv1widget
34 | {
35 | public:
36 |
37 | // Constructor.
38 | synthv1widget_lv2(synthv1_lv2 *pSynth,
39 | LV2UI_Controller controller, LV2UI_Write_Function write_function);
40 |
41 | // Destructor.
42 | ~synthv1widget_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 | synthv1_ui *ui_instance() const;
61 |
62 | // Param methods.
63 | void updateParam(synthv1::ParamIndex index, float fValue) const;
64 |
65 | // Close event handler.
66 | void closeEvent(QCloseEvent *pCloseEvent);
67 |
68 | private:
69 |
70 | // Instance variables.
71 | synthv1_lv2ui *m_pSynthUi;
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 // __synthv1widget_lv2_h
83 |
84 | // end of synthv1widget_lv2.h
85 |
--------------------------------------------------------------------------------
/src/synthv1widget_preset.h:
--------------------------------------------------------------------------------
1 | // synthv1widget_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 __synthv1widget_preset_h
23 | #define __synthv1widget_preset_h
24 |
25 | #include
26 |
27 | // Forward declarations.
28 | class QToolButton;
29 | class QComboBox;
30 |
31 |
32 | //-------------------------------------------------------------------------
33 | // synthv1widget_preset - Custom combo/edit-box widget.
34 |
35 | class synthv1widget_preset : public QWidget
36 | {
37 | Q_OBJECT
38 |
39 | public:
40 |
41 | // Constructor.
42 | synthv1widget_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 // __synthv1widget_preset_h
99 |
100 | // end of synthv1widget_preset.h
101 |
--------------------------------------------------------------------------------
/src/synthv1widget_programs.h:
--------------------------------------------------------------------------------
1 | // synthv1widget_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 __synthv1widget_programs_h
23 | #define __synthv1widget_programs_h
24 |
25 | #include
26 |
27 |
28 | // forward decls.
29 | class synthv1_programs;
30 |
31 |
32 | //----------------------------------------------------------------------------
33 | // synthv1widget_programs -- Custom (tree) widget.
34 |
35 | class synthv1widget_programs : public QTreeWidget
36 | {
37 | Q_OBJECT
38 |
39 | public:
40 |
41 | // ctor.
42 | synthv1widget_programs(QWidget *pParent = nullptr);
43 | // dtor.
44 | ~synthv1widget_programs();
45 |
46 | // utilities.
47 | void loadPrograms(synthv1_programs *pPrograms);
48 | void savePrograms(synthv1_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 // __synthv1widget_programs_h
78 |
79 | // end of synthv1widget_programs.h
80 |
--------------------------------------------------------------------------------
/src/synthv1widget_status.cpp:
--------------------------------------------------------------------------------
1 | // synthv1widget_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 "synthv1widget_status.h"
23 |
24 | #include "synthv1widget_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 | // synthv1widget_status - Custom status-bar widget.
38 | //
39 |
40 | // Constructor.
41 | synthv1widget_status::synthv1widget_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 synthv1widget_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 | synthv1widget_status::~synthv1widget_status (void)
98 | {
99 | delete m_midiInLed[1];
100 | delete m_midiInLed[0];
101 | }
102 |
103 |
104 | // Permanent widgets accessors.
105 | synthv1widget_keybd *synthv1widget_status::keybd (void) const
106 | {
107 | return m_pKeybd;
108 | }
109 |
110 |
111 | void synthv1widget_status::midiInLed ( bool bMidiInLed )
112 | {
113 | m_pMidiInLedLabel->setPixmap(*m_midiInLed[bMidiInLed ? 1 : 0]);
114 | }
115 |
116 |
117 | void synthv1widget_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 synthv1widget_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 synthv1widget_status.cpp
136 |
--------------------------------------------------------------------------------
/src/synthv1widget_status.h:
--------------------------------------------------------------------------------
1 | // synthv1widget_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 __synthv1widget_status_h
23 | #define __synthv1widget_status_h
24 |
25 | #include
26 |
27 |
28 | // Forward declarations.
29 | class synthv1widget_keybd;
30 |
31 | class QLabel;
32 | class QPixmap;
33 |
34 |
35 | //-------------------------------------------------------------------------
36 | // synthv1widget_status - Custom status-bar widget.
37 |
38 | class synthv1widget_status : public QStatusBar
39 | {
40 | Q_OBJECT
41 |
42 | public:
43 |
44 | // Constructor.
45 | synthv1widget_status(QWidget *pParent = 0);
46 |
47 | // Destructor.
48 | ~synthv1widget_status();
49 |
50 | // Permanent widgets accessors.
51 | synthv1widget_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 | synthv1widget_keybd *m_pKeybd;
66 | };
67 |
68 |
69 | #endif // __synthv1widget_status_h
70 |
71 | // end of synthv1widget_status.h
72 |
--------------------------------------------------------------------------------
/src/synthv1widget_wave.cpp:
--------------------------------------------------------------------------------
1 | // synthv1widget_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 "synthv1widget_wave.h"
23 |
24 | #include "synthv1_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 | // synthv1widget_wave -- Custom widget
44 |
45 | // Constructor.
46 | synthv1widget_wave::synthv1widget_wave ( QWidget *pParent )
47 | : QFrame(pParent),
48 | m_bDragging(false), m_iDragShape(0)
49 | {
50 | m_pWave = new synthv1_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 | synthv1widget_wave::~synthv1widget_wave (void)
61 | {
62 | delete m_pWave;
63 | }
64 |
65 |
66 | // Parameter accessors.
67 | void synthv1widget_wave::setWaveShape ( float fWaveShape )
68 | {
69 | int iWaveShape = int(fWaveShape);
70 | if (iWaveShape != int(m_pWave->shape())) {
71 | if (iWaveShape < int(synthv1_wave::Pulse))
72 | iWaveShape = int(synthv1_wave::Noise);
73 | else
74 | if (iWaveShape > int(synthv1_wave::Noise))
75 | iWaveShape = int(synthv1_wave::Pulse);
76 | m_pWave->reset(synthv1_wave::Shape(iWaveShape), m_pWave->width());
77 | update();
78 | emit waveShapeChanged(waveShape());
79 | }
80 | }
81 |
82 | float synthv1widget_wave::waveShape (void) const
83 | {
84 | return float(m_pWave->shape());
85 | }
86 |
87 |
88 | void synthv1widget_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 synthv1widget_wave::waveWidth (void) const
98 | {
99 | return m_pWave->width();
100 | }
101 |
102 |
103 | // Draw curve.
104 | void synthv1widget_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 synthv1widget_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 synthv1widget_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 synthv1widget_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 synthv1widget_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 synthv1widget_wave::mouseDoubleClickEvent ( QMouseEvent *pMouseEvent )
228 | {
229 | QFrame::mouseDoubleClickEvent(pMouseEvent);
230 |
231 | if (!m_bDragging)
232 | setWaveShape(waveShape() + 1);
233 | }
234 |
235 |
236 | void synthv1widget_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 synthv1widget_wave.cpp
251 |
--------------------------------------------------------------------------------
/src/synthv1widget_wave.h:
--------------------------------------------------------------------------------
1 | // synthv1widget_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 __synthv1widget_wave_h
23 | #define __synthv1widget_wave_h
24 |
25 | #include
26 |
27 |
28 | // Forward decl.
29 | class synthv1_wave_lf;
30 |
31 |
32 | //----------------------------------------------------------------------------
33 | // synthv1widget_wave -- Custom widget
34 |
35 | class synthv1widget_wave : public QFrame
36 | {
37 | Q_OBJECT
38 |
39 | public:
40 |
41 | // Constructor.
42 | synthv1widget_wave(QWidget *pParent = nullptr);
43 | // Destructor.
44 | ~synthv1widget_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 | synthv1_wave_lf *m_pWave;
81 |
82 | // Drag state.
83 | bool m_bDragging;
84 | int m_iDragShape;
85 | QPoint m_posDrag;
86 | };
87 |
88 | #endif // __synthv1widget_wave_h
89 |
90 |
91 | // end of synthv1widget_wave.h
92 |
--------------------------------------------------------------------------------