Binary files /tmp/tmp6t9mjqw1/TswSJiaqV_/yoshimi-2.1.1.1~dfsg0/banks/Drums/0100-Tom Toms.xiy and /tmp/tmp6t9mjqw1/As9a5djH7i/yoshimi-2.1.2.2~dfsg0/banks/Drums/0100-Tom Toms.xiy differ Binary files /tmp/tmp6t9mjqw1/TswSJiaqV_/yoshimi-2.1.1.1~dfsg0/banks/Drums/0100-Tom Toms.xiz and /tmp/tmp6t9mjqw1/As9a5djH7i/yoshimi-2.1.2.2~dfsg0/banks/Drums/0100-Tom Toms.xiz differ Binary files /tmp/tmp6t9mjqw1/TswSJiaqV_/yoshimi-2.1.1.1~dfsg0/banks/Drums/0123-Hugh's Kit.xiy and /tmp/tmp6t9mjqw1/As9a5djH7i/yoshimi-2.1.2.2~dfsg0/banks/Drums/0123-Hugh's Kit.xiy differ Binary files /tmp/tmp6t9mjqw1/TswSJiaqV_/yoshimi-2.1.1.1~dfsg0/banks/Drums/0123-Hugh's Kit.xiz and /tmp/tmp6t9mjqw1/As9a5djH7i/yoshimi-2.1.2.2~dfsg0/banks/Drums/0123-Hugh's Kit.xiz differ diff -Nru yoshimi-2.1.1.1~dfsg0/banks/Drums/.bankdir yoshimi-2.1.2.2~dfsg0/banks/Drums/.bankdir --- yoshimi-2.1.1.1~dfsg0/banks/Drums/.bankdir 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/banks/Drums/.bankdir 2021-12-03 20:12:12.000000000 +0000 @@ -1 +1 @@ -2.0 M \ No newline at end of file +2.1.1 M \ No newline at end of file Binary files /tmp/tmp6t9mjqw1/TswSJiaqV_/yoshimi-2.1.1.1~dfsg0/banks/Guitar/0007-Dist Guitar 6.xiy and /tmp/tmp6t9mjqw1/As9a5djH7i/yoshimi-2.1.2.2~dfsg0/banks/Guitar/0007-Dist Guitar 6.xiy differ Binary files /tmp/tmp6t9mjqw1/TswSJiaqV_/yoshimi-2.1.1.1~dfsg0/banks/Guitar/0007-Dist Guitar 6.xiz and /tmp/tmp6t9mjqw1/As9a5djH7i/yoshimi-2.1.2.2~dfsg0/banks/Guitar/0007-Dist Guitar 6.xiz differ Binary files /tmp/tmp6t9mjqw1/TswSJiaqV_/yoshimi-2.1.1.1~dfsg0/banks/Guitar/0103-Twang.xiy and /tmp/tmp6t9mjqw1/As9a5djH7i/yoshimi-2.1.2.2~dfsg0/banks/Guitar/0103-Twang.xiy differ Binary files /tmp/tmp6t9mjqw1/TswSJiaqV_/yoshimi-2.1.1.1~dfsg0/banks/Guitar/0103-Twang.xiz and /tmp/tmp6t9mjqw1/As9a5djH7i/yoshimi-2.1.2.2~dfsg0/banks/Guitar/0103-Twang.xiz differ Binary files /tmp/tmp6t9mjqw1/TswSJiaqV_/yoshimi-2.1.1.1~dfsg0/banks/Guitar/0104-Twang 2.xiy and /tmp/tmp6t9mjqw1/As9a5djH7i/yoshimi-2.1.2.2~dfsg0/banks/Guitar/0104-Twang 2.xiy differ Binary files /tmp/tmp6t9mjqw1/TswSJiaqV_/yoshimi-2.1.1.1~dfsg0/banks/Guitar/0104-Twang 2.xiz and /tmp/tmp6t9mjqw1/As9a5djH7i/yoshimi-2.1.2.2~dfsg0/banks/Guitar/0104-Twang 2.xiz differ diff -Nru yoshimi-2.1.1.1~dfsg0/banks/Guitar/.bankdir yoshimi-2.1.2.2~dfsg0/banks/Guitar/.bankdir --- yoshimi-2.1.1.1~dfsg0/banks/Guitar/.bankdir 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/banks/Guitar/.bankdir 2021-12-03 20:12:12.000000000 +0000 @@ -1 +1 @@ -0.0.0 +2.1.1 M \ No newline at end of file Binary files /tmp/tmp6t9mjqw1/TswSJiaqV_/yoshimi-2.1.1.1~dfsg0/banks/Misc/0097-Tubular Bells.xiy and /tmp/tmp6t9mjqw1/As9a5djH7i/yoshimi-2.1.2.2~dfsg0/banks/Misc/0097-Tubular Bells.xiy differ Binary files /tmp/tmp6t9mjqw1/TswSJiaqV_/yoshimi-2.1.1.1~dfsg0/banks/Misc/0097-Tubular Bells.xiz and /tmp/tmp6t9mjqw1/As9a5djH7i/yoshimi-2.1.2.2~dfsg0/banks/Misc/0097-Tubular Bells.xiz differ diff -Nru yoshimi-2.1.1.1~dfsg0/banks/Misc/.bankdir yoshimi-2.1.2.2~dfsg0/banks/Misc/.bankdir --- yoshimi-2.1.1.1~dfsg0/banks/Misc/.bankdir 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/banks/Misc/.bankdir 2021-12-03 20:12:12.000000000 +0000 @@ -1 +1 @@ -0.0.0 +2.1.1 M \ No newline at end of file diff -Nru yoshimi-2.1.1.1~dfsg0/banks/Plucked/.bankdir yoshimi-2.1.2.2~dfsg0/banks/Plucked/.bankdir --- yoshimi-2.1.1.1~dfsg0/banks/Plucked/.bankdir 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/banks/Plucked/.bankdir 2021-12-03 20:12:12.000000000 +0000 @@ -1 +1 @@ -0.0.0 +2.1.1 M \ No newline at end of file Binary files /tmp/tmp6t9mjqw1/TswSJiaqV_/yoshimi-2.1.1.1~dfsg0/banks/Strings/0097-Smooth Strings.xiy and /tmp/tmp6t9mjqw1/As9a5djH7i/yoshimi-2.1.2.2~dfsg0/banks/Strings/0097-Smooth Strings.xiy differ Binary files /tmp/tmp6t9mjqw1/TswSJiaqV_/yoshimi-2.1.1.1~dfsg0/banks/Strings/0097-Smooth Strings.xiz and /tmp/tmp6t9mjqw1/As9a5djH7i/yoshimi-2.1.2.2~dfsg0/banks/Strings/0097-Smooth Strings.xiz differ Binary files /tmp/tmp6t9mjqw1/TswSJiaqV_/yoshimi-2.1.1.1~dfsg0/banks/Strings/0098-Antique Strings.xiy and /tmp/tmp6t9mjqw1/As9a5djH7i/yoshimi-2.1.2.2~dfsg0/banks/Strings/0098-Antique Strings.xiy differ Binary files /tmp/tmp6t9mjqw1/TswSJiaqV_/yoshimi-2.1.1.1~dfsg0/banks/Strings/0098-Antique Strings.xiz and /tmp/tmp6t9mjqw1/As9a5djH7i/yoshimi-2.1.2.2~dfsg0/banks/Strings/0098-Antique Strings.xiz differ diff -Nru yoshimi-2.1.1.1~dfsg0/banks/Strings/.bankdir yoshimi-2.1.2.2~dfsg0/banks/Strings/.bankdir --- yoshimi-2.1.1.1~dfsg0/banks/Strings/.bankdir 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/banks/Strings/.bankdir 2021-12-03 20:12:12.000000000 +0000 @@ -1 +1 @@ -0.0.0 +2.1.1 M \ No newline at end of file Binary files /tmp/tmp6t9mjqw1/TswSJiaqV_/yoshimi-2.1.1.1~dfsg0/banks/Synth/0100-Dungeon Lead.xiy and /tmp/tmp6t9mjqw1/As9a5djH7i/yoshimi-2.1.2.2~dfsg0/banks/Synth/0100-Dungeon Lead.xiy differ Binary files /tmp/tmp6t9mjqw1/TswSJiaqV_/yoshimi-2.1.1.1~dfsg0/banks/Synth/0100-Dungeon Lead.xiz and /tmp/tmp6t9mjqw1/As9a5djH7i/yoshimi-2.1.2.2~dfsg0/banks/Synth/0100-Dungeon Lead.xiz differ Binary files /tmp/tmp6t9mjqw1/TswSJiaqV_/yoshimi-2.1.1.1~dfsg0/banks/Synth/0103-Shepard Synth.xiy and /tmp/tmp6t9mjqw1/As9a5djH7i/yoshimi-2.1.2.2~dfsg0/banks/Synth/0103-Shepard Synth.xiy differ Binary files /tmp/tmp6t9mjqw1/TswSJiaqV_/yoshimi-2.1.1.1~dfsg0/banks/Synth/0103-Shepard Synth.xiz and /tmp/tmp6t9mjqw1/As9a5djH7i/yoshimi-2.1.2.2~dfsg0/banks/Synth/0103-Shepard Synth.xiz differ diff -Nru yoshimi-2.1.1.1~dfsg0/banks/Synth/.bankdir yoshimi-2.1.2.2~dfsg0/banks/Synth/.bankdir --- yoshimi-2.1.1.1~dfsg0/banks/Synth/.bankdir 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/banks/Synth/.bankdir 2021-12-03 20:12:12.000000000 +0000 @@ -1 +1 @@ -0.0.0 +2.1.1 M \ No newline at end of file diff -Nru yoshimi-2.1.1.1~dfsg0/Changelog yoshimi-2.1.2.2~dfsg0/Changelog --- yoshimi-2.1.1.1~dfsg0/Changelog 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/Changelog 2021-12-03 20:12:12.000000000 +0000 @@ -1,4 +1,93 @@ -yoshimi 2.1.1.1 +yoshimi 2.1.2.2 + +2021-12-3 Will +* Includes compatibility fix for Clang compiler. +* Set minimum C++ version to 14 +* set bugfix version 2.1.2.2 + +2021-11-30 Will +* BugFix: failed to link using recent cmake versions. + Thanks to David Runge for a timely fix. +* set bugfix version 2.1.2.1 + +2021-11-29 Will +* Filer window path deactivated if in favourites. +* Disabled difference reporting in midi learn. +* Final doc and user guide updates. +* Set release version 2.1.2 + +2021-11-24 Will +* Improved recognition of Apply Parameters from MIDI +* doc updates +* Rationalised more Data2Text and Text2Data names. +* CLI can now read midi source and audio destination. +* Set version as 2.1.2 rc2 + +2021-11-23 Will +* Completed unification of padsynth apply status +* CLI can now read CLI and GUI current status. + +* Doc Updates. +* Set version as 2.1.2 rc1 + +2021-11-22 Will +* Bugfix CLI sub and pad stereo set but not read. +* padsynth applied status now correctly set. + GUI still not fully in sync. +* CLI can now read padsynth applied status. + +2021-11-21 Will +* More small GUI tweaks. + +2021-11-20 Will +* Added instruments from Hugh across various banks. +* Updated User Guide +* Adjustments to names in Data2Text and Text2Data +* GUI text position adjustments. + +* Filter tracking check box label now reflects its status. +* Filter label changed to 'Parameters' and position properly scaled. + +2021-11-16 Will +* BugFix: CLI padsynth waveform and resonance not setting 'apply' +* New MIDI-learn style enabled. + +2021-11-12 Will +* BugFix: Crash loading scala keymap file + +* Dat2Text Ocsillator controls now independent of list position. + +2021-11-12 Will +* All Dat2Text engines now independent of numeric positions. +* Unified control names for MIDI learn. + +2021-11-11 Will +* BugFix: Data2Text making assumptions about control numbers. + +2021-11-5 Will +* Updated user guide. + +2021-11-4 Will +* Loading a state file now always clears the MIDI learn list. + +2021-10-27 Will +* BugFix: crash with corrupted history file. +* added Default_Maths.txt to dev_notes. + +2021-10-26 Will +* Rationalised some PI calculation variations. +* Added old (commented out) jack MIDI check. + +2021-10-17 Will +* Reverted VU changes + +2021-10-16 Will +* Minor adjustments to VU metering +* Extra check when loading history lists +* Doc updates + +2021-10-15 Will +* BugFix: Missing jack midi entry in CmdOptions.cpp 2021-10-12 Will * BugFix: Not recognising no FLTK on first time start diff -Nru yoshimi-2.1.1.1~dfsg0/debian/changelog yoshimi-2.1.2.2~dfsg0/debian/changelog --- yoshimi-2.1.1.1~dfsg0/debian/changelog 2021-10-14 21:43:13.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/debian/changelog 2021-12-04 23:24:13.000000000 +0000 @@ -1,3 +1,12 @@ +yoshimi (2.1.2.2~dfsg0-1) unstable; urgency=medium + + * New upstream version 2.1.2.2~dfsg0 + * Update lintian-overrides + * Fix spelling error + * Fix d/watch + + -- Dennis Braun Sun, 05 Dec 2021 00:24:13 +0100 + yoshimi (2.1.1.1~dfsg0-1) unstable; urgency=medium * New upstream version 2.1.1.1~dfsg0 diff -Nru yoshimi-2.1.1.1~dfsg0/debian/patches/fix_spelling_error.patch yoshimi-2.1.2.2~dfsg0/debian/patches/fix_spelling_error.patch --- yoshimi-2.1.1.1~dfsg0/debian/patches/fix_spelling_error.patch 1970-01-01 00:00:00.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/debian/patches/fix_spelling_error.patch 2021-12-04 23:04:21.000000000 +0000 @@ -0,0 +1,43 @@ +Description: Fix spelling error +Author: Dennis Braun +Forwarded: yes + +Index: yoshimi/desktop/metainfo/yoshimi.appdata.xml +=================================================================== +--- yoshimi.orig/desktop/metainfo/yoshimi.appdata.xml ++++ yoshimi/desktop/metainfo/yoshimi.appdata.xml +@@ -17,7 +17,7 @@ + In the V1.7.x series ALSA MIDI can search for and connect to all viable sources, almost all controls have been made realtime, both key and channel aftertouch have been implemented and there is now the ability to change the panning law. Refinement continues, both visually and within the code. +

+

+- Version 2.0 brings fully resizeable windows, both key and channel aftertouch, MIDI sync for LFOs, and extensions to panning control. ++ Version 2.0 brings fully resizable windows, both key and channel aftertouch, MIDI sync for LFOs, and extensions to panning control. +

+

+ Version 2.1.0 extends MIDI sync for Effects where relevant, and extensions to NRPNs. There is also an new HTML User Guide. +Index: yoshimi/desktop/yoshimi.1 +=================================================================== +--- yoshimi.orig/desktop/yoshimi.1 ++++ yoshimi/desktop/yoshimi.1 +@@ -18,7 +18,7 @@ Other recent extensions are the ability + .PP + One of the latest additions is the ability to load a list of MIDI-learned settings from the command line at startup. + .PP +-Recent improvements are key and channel aftertouch, fully resizeable windows, MIDI sync for LFOs and Panning extensions. ++Recent improvements are key and channel aftertouch, fully resizable windows, MIDI sync for LFOs and Panning extensions. + .PP + The latest development is the inclusion of MIDI-sync for all LFOs, and all relevant Effects. + .SH COMMANDS +Index: yoshimi/doc/yoshimi_user_guide/introduction/introduction.html +=================================================================== +--- yoshimi.orig/doc/yoshimi_user_guide/introduction/introduction.html ++++ yoshimi/doc/yoshimi_user_guide/introduction/introduction.html +@@ -28,7 +28,7 @@ + Parts, can have further Insertion effects applied to them before being directed to either the main audio output, an individual output (if such is available), or both! The main output can have System effects combined from all active parts. +

+

+- Yoshimi is a highly complex synth with very extensive control options. Therefore, it is split up into a number of context sensitive windows to make this manageable. All of these windows are resizeable, and the size and position are stored. With the exception of the Console window, they also maintain their geometry and the contents are scaled accordingly. ++ Yoshimi is a highly complex synth with very extensive control options. Therefore, it is split up into a number of context sensitive windows to make this manageable. All of these windows are resizable, and the size and position are stored. With the exception of the Console window, they also maintain their geometry and the contents are scaled accordingly. +

+ You will probably only use a fraction of the options available, but the more obscure ones are there for the occasions when you do need them. +

diff -Nru yoshimi-2.1.1.1~dfsg0/debian/patches/series yoshimi-2.1.2.2~dfsg0/debian/patches/series --- yoshimi-2.1.1.1~dfsg0/debian/patches/series 2021-08-24 21:10:46.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/debian/patches/series 2021-12-04 22:43:13.000000000 +0000 @@ -1 +1,2 @@ +fix_spelling_error.patch fix_privacy_breach_in_index_html.patch diff -Nru yoshimi-2.1.1.1~dfsg0/debian/watch yoshimi-2.1.2.2~dfsg0/debian/watch --- yoshimi-2.1.1.1~dfsg0/debian/watch 2021-04-29 19:00:29.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/debian/watch 2021-12-03 22:28:11.000000000 +0000 @@ -1,3 +1,3 @@ version=4 opts="uversionmangle=s/-/./,dversionmangle=s/~dfsg0.*//,repacksuffix=~dfsg0" \ -https://github.com/Yoshimi/yoshimi/releases .*/v?(\d[\d\.]+)\.tar\.gz +https://github.com/Yoshimi/yoshimi/tags .*/v?(\d[\d\.]+)\.tar\.gz diff -Nru yoshimi-2.1.1.1~dfsg0/debian/yoshimi.lintian-overrides yoshimi-2.1.2.2~dfsg0/debian/yoshimi.lintian-overrides --- yoshimi-2.1.1.1~dfsg0/debian/yoshimi.lintian-overrides 2021-08-10 19:28:52.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/debian/yoshimi.lintian-overrides 2021-12-04 23:20:32.000000000 +0000 @@ -1,11 +1,11 @@ # I can't find these spelling errors in source code using grep tool. # So overriding them. -spelling-error-in-binary usr/bin/yoshimi AfE Safe -spelling-error-in-binary usr/bin/yoshimi CONTROLL CONTROL +spelling-error-in-binary usr/bin/yoshimi controlL control spelling-error-in-binary usr/bin/yoshimi defaulH default spelling-error-in-binary usr/bin/yoshimi ment meant spelling-error-in-binary usr/bin/yoshimi pres press -spelling-error-in-binary usr/lib/lv2/yoshimi.lv2/yoshimi_lv2.so AfE Safe +spelling-error-in-binary usr/bin/yoshimi TeH The spelling-error-in-binary usr/lib/lv2/yoshimi.lv2/yoshimi_lv2.so CONTROLL CONTROL spelling-error-in-binary usr/lib/lv2/yoshimi.lv2/yoshimi_lv2.so defaulH default spelling-error-in-binary usr/lib/lv2/yoshimi.lv2/yoshimi_lv2.so ment meant +spelling-error-in-binary usr/lib/lv2/yoshimi.lv2/yoshimi_lv2.so TeH The diff -Nru yoshimi-2.1.1.1~dfsg0/desktop/metainfo/yoshimi.appdata.xml yoshimi-2.1.2.2~dfsg0/desktop/metainfo/yoshimi.appdata.xml --- yoshimi-2.1.1.1~dfsg0/desktop/metainfo/yoshimi.appdata.xml 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/desktop/metainfo/yoshimi.appdata.xml 2021-12-03 20:12:12.000000000 +0000 @@ -8,7 +8,7 @@

A Software Synthesizer for Linux

- Yoshimi is a MIDI software synthesizer for Linux. It synthesizes in real time, can run polyphonic and/or monophonic in multiple simultaneous patches in one or more MIDI channels and has broad microtonal capability. It includes extensive addititive, subtractive, and PAD synth capabilities which can be run simultaneously within the same patch. It also has comprehensive effects capabilities. + Yoshimi is a MIDI software synthesizer for Linux. It synthesizes in real time, can run polyphonic and/or monophonic in multiple simultaneous patches in one or more MIDI channels and has broad microtonal capability. It includes extensive additive, subtractive, and PAD synth capabilities which can be run simultaneously within the same patch. It also has comprehensive effects capabilities.

Originally based on the 2.4.0 version of ZynAddSubFX (Copyright 2002-2009 Nasca Octavian Paul), development of Yoshimi has continued for quite a while now in its own direction. Originally these included major optimizations for audio and MIDI performance. More recently there has been progressive development of user-level access to all controls, including command line access. Since V1.5.0 there is full Midi Learn capability. @@ -24,7 +24,7 @@

-​ +​ yoshimi diff -Nru yoshimi-2.1.1.1~dfsg0/desktop/yoshimi.1 yoshimi-2.1.2.2~dfsg0/desktop/yoshimi.1 --- yoshimi-2.1.1.1~dfsg0/desktop/yoshimi.1 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/desktop/yoshimi.1 2021-12-03 20:12:12.000000000 +0000 @@ -1,4 +1,4 @@ -.TH yoshimi 1 " 2021" "yoshimi 2.1.1" +.TH yoshimi 1 " 2021" "yoshimi 2.1.2.2" .SH NAME yoshimi \- a software music synthesiser .SH SYNOPSIS diff -Nru yoshimi-2.1.1.1~dfsg0/dev_notes/Default_Maths.txt yoshimi-2.1.2.2~dfsg0/dev_notes/Default_Maths.txt --- yoshimi-2.1.1.1~dfsg0/dev_notes/Default_Maths.txt 1970-01-01 00:00:00.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/dev_notes/Default_Maths.txt 2021-12-03 20:12:12.000000000 +0000 @@ -0,0 +1,24 @@ +There are four significant constants set in globals.h +At the time of writing there still is no standard consistent across platforms so please use these in all new calculations. + +#define PI 3.1415926536f +#define LOG_2 0.693147181f + +The above were always defined right back to Zyn 2.2.1 +We've kept the values the same to ensure consistency. + +#define TWOPI 6.28318530718f +#define HALFPI 1.57079632679f + +These were introduced in Yoshimi 1.2.2 +Throughout Yoshimi these had been computed in different ways, and it was thought this, along with unknown compiler optimisations could give varying results. +Typically: +2 * {some calculation} * PI +{some calculation} * 2 * PI +PI * 2.0f + +{some calculation} * PI / 2 +PI * {some calculation} / 2.0f + +Currently there are three remaining in Analogfitler.cpp +We were leaving these until we can properly test the effect of unifying them with the rest. diff -Nru yoshimi-2.1.1.1~dfsg0/dev_notes/MIDI_Learn.txt yoshimi-2.1.2.2~dfsg0/dev_notes/MIDI_Learn.txt --- yoshimi-2.1.1.1~dfsg0/dev_notes/MIDI_Learn.txt 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/dev_notes/MIDI_Learn.txt 2021-12-03 20:12:12.000000000 +0000 @@ -87,6 +87,6 @@ Max MIDI-learn lines has been increased to 400. -This has been achieved by inserting a 10mS sleep every 32 lines while updating the GUI. This ensures the message buffer doesn't get overloaded. There was no other reason for the earlier limit. This still comes in at less that 1mS for a full list load. +This has been achieved by inserting a 10mS sleep every 32 lines while updating the GUI. This ensures the message buffer doesn't get overloaded. There was no other reason for the earlier limit. This still comes in at less that 1S for a full list load. Time to scan is very difficult to measure. Finding a bunch of 5 controls at the end of a list of 20 usually returned less than 3uS, and very occasionally one at around 8uS. The search is fairly straightforward so presumably ones right at the end of a full list would be worst case around 160uS diff -Nru yoshimi-2.1.1.1~dfsg0/dev_notes/Part_On_Off.txt yoshimi-2.1.2.2~dfsg0/dev_notes/Part_On_Off.txt --- yoshimi-2.1.1.1~dfsg0/dev_notes/Part_On_Off.txt 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/dev_notes/Part_On_Off.txt 2021-12-03 20:12:12.000000000 +0000 @@ -1,6 +1,6 @@ This control has a degree of intelligence built in. -If a part on, then sending 0 will switch it off and sending 1 will switch it back on. These are absolute actions used mostly when doing resets, state and patch set loads etc. +If a part is on, then sending 0 will switch it off and sending 1 will switch it back on. These are absolute actions used mostly when doing resets, state and patch set loads etc. If you send -1 when it was on, it will again switch it off. However if it was already off, sending -1 will set the internal counter to -1. Yet another -1 will set -2 etc. Anything less than 1 is regarded as off. If you later send 2 the counter will be stepped up again. In this way, if several routines switch a part off it will only be switched back on again when all of them switch in on. diff -Nru yoshimi-2.1.1.1~dfsg0/dev_notes/ToDo.txt yoshimi-2.1.2.2~dfsg0/dev_notes/ToDo.txt --- yoshimi-2.1.1.1~dfsg0/dev_notes/ToDo.txt 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/dev_notes/ToDo.txt 2021-12-03 20:12:12.000000000 +0000 @@ -12,6 +12,7 @@ From then on repeats the last action. Add which engines are enabled in CLI list part. +In fact significantly re-write this! Revise GUI voice list related to voice editor. Binary files /tmp/tmp6t9mjqw1/TswSJiaqV_/yoshimi-2.1.1.1~dfsg0/dev_notes/Yoshimi Control Numbers.ods and /tmp/tmp6t9mjqw1/As9a5djH7i/yoshimi-2.1.2.2~dfsg0/dev_notes/Yoshimi Control Numbers.ods differ diff -Nru yoshimi-2.1.1.1~dfsg0/dev_notes/Yoshimi_Policies.txt yoshimi-2.1.2.2~dfsg0/dev_notes/Yoshimi_Policies.txt --- yoshimi-2.1.1.1~dfsg0/dev_notes/Yoshimi_Policies.txt 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/dev_notes/Yoshimi_Policies.txt 2021-12-03 20:12:12.000000000 +0000 @@ -54,7 +54,7 @@ Alternatively, please send me a brief description to include when I next update. ACKNOWLEDGEMENTS -The ones that appear in the GUI 'About->More' lists are those who have either made very significant improvements, or have consistently helpled in various ways. Some them go back to the start of the Yoshimi fork. +The ones that appear in the GUI 'About->More' lists are those who have either made very significant improvements, or have consistently helped in various ways. Some them go back to the start of the Yoshimi fork. The list in the 'Yoshimi_Helpers' file in 'docs' is of everyone I know about, some of which may only have made a few small suggestions or bug reports. diff -Nru yoshimi-2.1.1.1~dfsg0/doc/Banks_Presets_Update.txt yoshimi-2.1.2.2~dfsg0/doc/Banks_Presets_Update.txt --- yoshimi-2.1.1.1~dfsg0/doc/Banks_Presets_Update.txt 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/doc/Banks_Presets_Update.txt 2021-12-03 20:12:12.000000000 +0000 @@ -2,11 +2,11 @@ Initially, existing users should see no difference, apart from a slightly quicker startup if they have a very large number of banks and roots. New users will see all the bank roots that Yoshimi can find, and this will include "$HOME/.local/share/yoshimi/found/" with "yoshimi/banks" and/or "zynaddsubfx/banks" if these are found in the default locations. -Unlike the actual defaults, these will be editable. They are also kept up to date if any default ones are added to. +Unlike the actual defaults, these will be editable. After first being copied they are NOT kept up to date if any default ones are added to. This is to protect any that you may have changed. -This still happens for existing users, but these roots will not be shown in the roots list. Instead there will be a message informing you of this, and inviting you to add them to the Path, not add them, or ask again later. +This is also the case for existing users the first time they see the new format, but these roots will not be shown in the roots list. Instead there will be a message informing you of this, and inviting you to A: add them to the Path, B: not add them, C: ask again later. -For all users if banks get added or removed by external means this will be reported, and the associated bank roots updated in the master file accordingly *without* disrupting any other banks and roots. Previously if new banks were seen as added externally the bank structure was regenerated, resulting in bank IDs changing - this could break old MIDI files that performed bank changes. +For all users if any banks get added or removed by external means this will be reported, and the associated bank roots updated in the master file accordingly *without* disrupting any other banks and roots. Previously if new banks were seen as added externally the bank structure was regenerated, resulting in bank IDs changing - this could have broken old MIDI files that performed bank changes. There is a really strange anomaly where phantom empty banks sometimes get added to the first and/or the last bank root in the list. These are always at bank ID 0 - which should be impossible! diff -Nru yoshimi-2.1.1.1~dfsg0/doc/examples/1st_README.txt yoshimi-2.1.2.2~dfsg0/doc/examples/1st_README.txt --- yoshimi-2.1.1.1~dfsg0/doc/examples/1st_README.txt 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/doc/examples/1st_README.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,13 +0,0 @@ -This 'Examples' directory is most likely to be in either: -/usr/local/share/yoshimi/ -or: -/usr/share/yoshimi/ - -The same applies to 'Banks' and 'Presets'. - -These locations are not normally writable, meaning you can't make changes. Therefore it is a good idea to create a working directory in your 'home' one and copy all of these across. - -These is also some additional information either in: -/usr/local/share/doc/yoshimi -or: -/usr/share/doc/yoshimi Binary files /tmp/tmp6t9mjqw1/TswSJiaqV_/yoshimi-2.1.1.1~dfsg0/doc/Histories.tar.bz2 and /tmp/tmp6t9mjqw1/As9a5djH7i/yoshimi-2.1.2.2~dfsg0/doc/Histories.tar.bz2 differ diff -Nru yoshimi-2.1.1.1~dfsg0/doc/Yoshimi_2.1.1_features.txt yoshimi-2.1.2.2~dfsg0/doc/Yoshimi_2.1.1_features.txt --- yoshimi-2.1.1.1~dfsg0/doc/Yoshimi_2.1.1_features.txt 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/doc/Yoshimi_2.1.1_features.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,32 +0,0 @@ -Version 2.1.1 - -This is a relatively minor update. - -The most noticeable feature is a new button in the main window for access to the MIDI CCs window. This was always possible, but required a *right* click on the Controllers button. Lots of people never knew it was available! Not only can these controls be used when you don't have a MIDI source connected, but they can also be learned and combined with others for greater expression. - -We've also improved instrument bank management. This gives a faster startup (particularly with very large banks and roots) and greater protection against outside influences. A setup with approximately 7500 instrument in 200 banks that used to take nearly 5 seconds to get to the main window, now takes much less than a second. - -There is a mechanism that properly separates out instruments in banks that have the same numeric prefix, but different names. Also two that have different filenames but the same prefix (and are in fact the same) are treated as just the one. This situation typically occured when banks were merged in the past with a mixture of spaces and underscores in the filenames. - -We've removed the switch for disabling 'Enable part on program change'. It was only relevant to MIDI and nobody could think of a circumstance where they'd want to select a program via MIDI but not have it active. If you *did* want to silence a channel, CC7 (volume) would do so, and if it was just a specific part, there is an NRPN that can do it. - -A double-click on a path in the filer favourites view will now select it and return you to the main filer window. - -Finding the user guide is now virtually instant. The only delay is opening your web browser to view it. -There are also improvements to the User Guide, adding extra information and clarifying some of what was already there. - -Various entries in the doc directory have been updated. - -A few more obscure bugs have been fixed. - -Yoshimi source code is available from either: -https://sourceforge.net/projects/yoshimi -Or: -https://github.com/Yoshimi/yoshimi - -Full build instructions are in 'INSTALL'. - -Our list archive is at: -https://www.freelists.org/archive/yoshimi -To post, email to: -yoshimi@freelists.org diff -Nru yoshimi-2.1.1.1~dfsg0/doc/Yoshimi_2.1.2_features.txt yoshimi-2.1.2.2~dfsg0/doc/Yoshimi_2.1.2_features.txt --- yoshimi-2.1.1.1~dfsg0/doc/Yoshimi_2.1.2_features.txt 1970-01-01 00:00:00.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/doc/Yoshimi_2.1.2_features.txt 2021-12-03 20:12:12.000000000 +0000 @@ -0,0 +1,31 @@ +Version 2.1.2 + +More small improvements and extensions. + +MIDI-learn had remained substantially unchanged since it was implemented in 2016. It's now been overhauled, as due to some internal changes the very oldest saved files could have been misread. This has now been resolved, and a degree of 'future proofing' has been achieved. There are also more controls that can be learned, with some learnable buttons given a pale blue surround (like the check boxes). + +PadSynth status can now be read by the CLI so as well as seeing the " Need to Apply" warning when changing controls, you can check if you get distracted and forget. Just enter "Read apply" while in the PadSynth context to make this clear. "Apply" is also a learnable control now so it is now possible to change the harmonic content in a running project. + +In the CLI as well as setting GUI/CLI saved status you can now read these without changing them. + +The CLI can now also read the currently selected MIDI source and audio destination. + +We continue to refine the development testing system and at the same time have made changes in the code to ensure the minimum difference in sound output across various distros, compliers and versions. However, there will always be some differences due to the complexities of floating point code and differences within the processors themselves. + +Some parts of the GUI have been made a bit clearer and more readable. + +There has been more work on the HTML user guide, with extra details and new information. + +Finally, there have been a few more fixes to deeply buried bugs. + +Yoshimi source code is available from either: +https://sourceforge.net/projects/yoshimi +Or: +https://github.com/Yoshimi/yoshimi + +Full build instructions are in 'INSTALL'. + +Our list archive is at: +https://www.freelists.org/archive/yoshimi +To post, email to: +yoshimi@freelists.org diff -Nru yoshimi-2.1.1.1~dfsg0/doc/Yoshimi_Quote.txt yoshimi-2.1.2.2~dfsg0/doc/Yoshimi_Quote.txt --- yoshimi-2.1.1.1~dfsg0/doc/Yoshimi_Quote.txt 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/doc/Yoshimi_Quote.txt 2021-12-03 20:12:12.000000000 +0000 @@ -6,6 +6,8 @@ In recent times we've been able to dispose of the donkeys, and the bandits are on the run :) - Updated: The trucks are gone, there have been considerable road repairs, and the few remaining bandits are in hiding. There are headlights so you can see where you are going. + +Later: +The blizard has blown itself out. We're still doing 90 + and sometimes reach 110 :) Binary files /tmp/tmp6t9mjqw1/TswSJiaqV_/yoshimi-2.1.1.1~dfsg0/doc/yoshimi_user_guide/add/images/global.png and /tmp/tmp6t9mjqw1/As9a5djH7i/yoshimi-2.1.2.2~dfsg0/doc/yoshimi_user_guide/add/images/global.png differ Binary files /tmp/tmp6t9mjqw1/TswSJiaqV_/yoshimi-2.1.1.1~dfsg0/doc/yoshimi_user_guide/add/images/voice.png and /tmp/tmp6t9mjqw1/As9a5djH7i/yoshimi-2.1.2.2~dfsg0/doc/yoshimi_user_guide/add/images/voice.png differ diff -Nru yoshimi-2.1.1.1~dfsg0/doc/yoshimi_user_guide/add/voice.html yoshimi-2.1.2.2~dfsg0/doc/yoshimi_user_guide/add/voice.html --- yoshimi-2.1.1.1~dfsg0/doc/yoshimi_user_guide/add/voice.html 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/doc/yoshimi_user_guide/add/voice.html 2021-12-03 20:12:12.000000000 +0000 @@ -36,9 +36,9 @@

Minus This inverts the phase of the entire voice so it will tend to subtract from the others.

- Bend Modifies the range of an income pitch bend for just this voice. + Bend Modifies the range of an income pitch bend for just this voice relative to the rest, and can also make it go in the reverse direction.

- Offset Shifts the overall position of pitch bend for this voice. + Offset Shifts the overall pitch (up or down) for this voice.

440Hz This fixes the frequency to 'A' regardless of the key pressed. However, see below.

diff -Nru yoshimi-2.1.1.1~dfsg0/doc/yoshimi_user_guide/appendix.html yoshimi-2.1.2.2~dfsg0/doc/yoshimi_user_guide/appendix.html --- yoshimi-2.1.1.1~dfsg0/doc/yoshimi_user_guide/appendix.html 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/doc/yoshimi_user_guide/appendix.html 2021-12-03 20:12:12.000000000 +0000 @@ -283,7 +283,7 @@ 8757h - - - 8858h - - + 8858h High Resolution Velocity Prefix 8959h - - diff -Nru yoshimi-2.1.1.1~dfsg0/doc/yoshimi_user_guide/bank/bank.html yoshimi-2.1.2.2~dfsg0/doc/yoshimi_user_guide/bank/bank.html --- yoshimi-2.1.1.1~dfsg0/doc/yoshimi_user_guide/bank/bank.html 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/doc/yoshimi_user_guide/bank/bank.html 2021-12-03 20:12:12.000000000 +0000 @@ -78,6 +78,12 @@ Finally there is a spin box enabling you to change the MIDI number of the selected one. This can be any number between 0 and 127. It is only a number change. No files are moved. When changing this, a button will appear marked 'Pending'. The change is only made and the list position moved once this is clicked. If you set it to the number of an existing one the two will swap places. It also makes this the current root path.

We suggest you avoid Root 0, as this is the one that many sequencers automatically send from time to time. Yoshimi reports attempts to access non-existent roots, but otherwise does nothing. +

+ Note +
+
+ .local/share/yoshimi/found/yoshimi/banks is a root path automatically created on first time startup, and is a copy of the installed default one. It is proved so that you have the contents in a form that you can add to, move around and edit. You can't do this with the default ones. +

divider diff -Nru yoshimi-2.1.1.1~dfsg0/doc/yoshimi_user_guide/files/yoshimi_user_guide_version yoshimi-2.1.2.2~dfsg0/doc/yoshimi_user_guide/files/yoshimi_user_guide_version --- yoshimi-2.1.1.1~dfsg0/doc/yoshimi_user_guide/files/yoshimi_user_guide_version 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/doc/yoshimi_user_guide/files/yoshimi_user_guide_version 2021-12-03 20:12:12.000000000 +0000 @@ -1 +1 @@ -2.1.1.1 \ No newline at end of file +2.1.2.2 \ No newline at end of file diff -Nru yoshimi-2.1.1.1~dfsg0/doc/yoshimi_user_guide/filter/filter.html yoshimi-2.1.2.2~dfsg0/doc/yoshimi_user_guide/filter/filter.html --- yoshimi-2.1.1.1~dfsg0/doc/yoshimi_user_guide/filter/filter.html 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/doc/yoshimi_user_guide/filter/filter.html 2021-12-03 20:12:12.000000000 +0000 @@ -31,16 +31,16 @@ Q Q factor for the filter

  • - V.SensA. Velocity sensing. How much the filter is influenced by (MIDI) velocity of the note + V.Sns. Velocity sensing. How much the filter is influenced by (MIDI) velocity of the note
  • - V.Sns. Velocity sensing function + VF.Sns. Velocity sensing function i.e the curve it follows.
  • Gain Filter output gain
  • - Freq.tr. Amount of frequency tracking for the filter. If this is positive (rightmost) higher note frequencies will shift the filter cutoff frequency higher. Default range is -100% to 98% unless the checkbox above ('0 / +') is selected: in this case the range is 0% to 198% + Freq.tr. Amount of frequency tracking for the filter. If this is positive (rightmost) higher note frequencies will shift the filter cutoff frequency higher. Default range is -100% to 98% unless the checkbox above ('- / +') is selected: in this case the range is 0% to 198%
  • @@ -48,7 +48,7 @@

    The Formant Filter

    Formant Window

    - When the formant window is selected, the FilterType list is covered with an Edit button, and clicking on this opens the window shown. These controls are additional to the others and adjust individual formants and the vowels they are contained in. Also, remember that the formant filter interacts with the filter envelope. + When the formant window is selected, the FilterType list is replaced by an Edit button, and clicking on this opens the window shown. These controls are additional to the others and adjust individual formants and the vowels they are contained in. Also, remember that the formant filter interacts with the filter envelope.

    For a deep understanding of formant filtering there is a highly detailed Wikipedia article Here.

    @@ -61,7 +61,7 @@ Fr.Sl (formant slowness) The rate at which one formant morphs to the next.
  • - Vw.Cl (vowel clearness) The rate at which vowels transition. + Vw.Cl (vowel clearness) The amount of overlap when vowels transition.
  • Vowel no. The vowel being edited. @@ -70,7 +70,7 @@ Formant The formant being edited.
  • - Freq The frequency of the current formant. Uniquely this has no default value, and will be set randomly at the time the filter is first set. + Freq The frequency of the current formant. Uniquely this has no default value, and will be set randomly at the time the filter is created.
  • Q The current formant's Q factor. Binary files /tmp/tmp6t9mjqw1/TswSJiaqV_/yoshimi-2.1.1.1~dfsg0/doc/yoshimi_user_guide/filter/images/filter.png and /tmp/tmp6t9mjqw1/As9a5djH7i/yoshimi-2.1.2.2~dfsg0/doc/yoshimi_user_guide/filter/images/filter.png differ diff -Nru yoshimi-2.1.1.1~dfsg0/doc/yoshimi_user_guide/index.html yoshimi-2.1.2.2~dfsg0/doc/yoshimi_user_guide/index.html --- yoshimi-2.1.1.1~dfsg0/doc/yoshimi_user_guide/index.html 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/doc/yoshimi_user_guide/index.html 2021-12-03 20:12:12.000000000 +0000 @@ -13,7 +13,7 @@ -

    The Yoshimi User Guide V2.1.1

    +

    The Yoshimi User Guide V2.1.2

    Contents Window

    This image is the first, and main Yoshimi window. You may want to keep this view visible while reading the guide. @@ -86,6 +86,8 @@
    MIDI CCs and NRPNs

    + Miscellany +

    Appendix

    Writing this user guide was a collaborative effort by the following: Binary files /tmp/tmp6t9mjqw1/TswSJiaqV_/yoshimi-2.1.1.1~dfsg0/doc/yoshimi_user_guide/lfo/images/lfo.png and /tmp/tmp6t9mjqw1/As9a5djH7i/yoshimi-2.1.2.2~dfsg0/doc/yoshimi_user_guide/lfo/images/lfo.png differ diff -Nru yoshimi-2.1.1.1~dfsg0/doc/yoshimi_user_guide/main.html yoshimi-2.1.2.2~dfsg0/doc/yoshimi_user_guide/main.html --- yoshimi-2.1.1.1~dfsg0/doc/yoshimi_user_guide/main.html 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/doc/yoshimi_user_guide/main.html 2021-12-03 20:12:12.000000000 +0000 @@ -35,7 +35,7 @@

    Instrument Menu

    Instrument

    - Show Stored This will open a window on the currently selected Bank of instruments. A selection from this will be loaded to the current part. + Show Stored This will open a window with the currently selected Bank of instruments. A selection from this will be loaded to the current part.

    Load External You can use this to load an instrument from outside Yoshimi, using the filer (which will be opened for loading). Again this will go to the current part.

    @@ -51,7 +51,7 @@

    Patch Set Menu

    PatchSet

    - Show Patch Banks This opens a window on the currently selected Bank Root. Clicking on one of the entries will open that instrument bank. + Show Patch Banks This opens a window with the currently selected Bank Root. Clicking on one of the entries will open that instrument bank.

    Load External This will open a filer window for loading a complete set of instrument patches.

    @@ -147,14 +147,15 @@

    Here, you can have up to eight effects, and they can be sent to any individual part or the main outputs. Again, you have a menu to select the wanted effect.

    - There is no need of an On checkbox for insertion effects because you can disable an effect simply by setting its destination to 'off'. + There is no need of an On checkbox for insertion effects because you can temporarily disable an effect simply by setting its destination to 'off'.

    Most of the lower half of this window is associated with the Part context, and is described in detail there.

    At the very bottom is the Left/Right VU display for the main audio output. VU meter overloading - The VU display will indicate if there is overload (aka clipping) by highlighting the number in red. In case of overload you might need to reduce the master volume or the volume of a Part which is too loud. You can reset the overload indicator by simply clicking on it. + The VU display will indicate if there is overload (aka clipping) by highlighting the number in red. In case of overload you might need to reduce the master volume or the volume of a Part which is too loud. You can reset the overload indicator by simply clicking on it.
    + The fine division are 1dB steps, and the thickest ones 10dB.

    Next (Instrument Banks) diff -Nru yoshimi-2.1.1.1~dfsg0/doc/yoshimi_user_guide/miscellany.html yoshimi-2.1.2.2~dfsg0/doc/yoshimi_user_guide/miscellany.html --- yoshimi-2.1.1.1~dfsg0/doc/yoshimi_user_guide/miscellany.html 1970-01-01 00:00:00.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/doc/yoshimi_user_guide/miscellany.html 2021-12-03 20:12:12.000000000 +0000 @@ -0,0 +1,67 @@ + + + + Yoshimi User Manual ~ Miscellany + + + +

    + +

    Default Banks Updates

    +

    Instruments added/changed since Yoshimi V1.7.1

    +

    +

    + +
    + For existing users, these are not automatically transferred to .local/share/found to avoid overwriting changes you may have made yourself. However, you may wish to copy them manually. If so, check you don't inadvertently create duplicates. +

    + New users will have all the default ones that were available at the time they first run Yoshimi. These will all be copied to .local/share/found. +

    + V 1.7.4
    + Will Godfrey Companion
    +
    + Cracked Chimes +
    +
    + V 2.0
    + At this time a major revision was done to ensure all default instruments had internal names that matched the filenames. This had been causing a lot of confusion. Also, where possible the instrument 'type' field was corrected on many of these, or added if it was missing. There are still some undefined as it was impossible to guess the intention of the designer. +

    + V 2.1.0
    + Will Godfrey Companion +
    + Scaffold Pole
    + Sharp Sweep Synth
    + Sharp Sweep Multi
    + Surf +
    + V 2.1.2
    + Drums +
    + Hugh's Kit
    + Tom Toms +
    + Guitar +
    + Dist Guitar 6
    + Twang
    + Twang 2 +
    + Misc +
    + Tubular Bells +
    + Strings +
    + Antique Strings
    + Smooth Strings +
    + Synth +
    + Dungeon Lead
    + Shepard Synth +
    +

    + + diff -Nru yoshimi-2.1.1.1~dfsg0/doc/yoshimi_user_guide/navigation/navigation.html yoshimi-2.1.2.2~dfsg0/doc/yoshimi_user_guide/navigation/navigation.html --- yoshimi-2.1.1.1~dfsg0/doc/yoshimi_user_guide/navigation/navigation.html 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/doc/yoshimi_user_guide/navigation/navigation.html 2021-12-03 20:12:12.000000000 +0000 @@ -33,7 +33,7 @@

    Sliders behave in a similar way, although there is no difference between the left hand button and the middle one. Again, most of these can be learned.

    - Almost all of these controls have dynamic tooltips showing you what the current setting is. Also the default settings have been very carefully thought out - especially the ones deep in the synth engines so just enabling features can produce dramatic results. + Almost all of the above controls have dynamic tooltips showing you what the current setting is. Also the default settings have been very carefully thought out - especially the ones deep in the synth engines so just enabling features can produce dramatic results.

    Any check/tick box with a pale blue surround can be learned. These will be On if the incoming value is greater than 63, otherwise Off. The counters and spinboxes with pale blue surrounds to the arrows can also be learned and will give a scaled response to the incoming value. @@ -42,6 +42,9 @@ Blue arrowed menus are a bit strange, as you have to first click on them to open up the menu, then click the right hand button while holding Ctrl. The incoming value will again be scaled to the numeric menu range.

    + The final learnable type is any button with a blue surround - not the button itself (the exception being the Mono/Stereo button). Some of these will take immediate effect while others are only next note. +

    +

    In many places you will see a pair of small dark blue buttons marked 'C' and 'P'. These enable you to copy the entire contents of just that section and later paste it to either a Presets file or to another identical section. For example you can copy AddSynth Global in part 1 and then paste it to any other AddSynth Global engine, such as part 4 kit item number 7 AddSynth.

    Binary files /tmp/tmp6t9mjqw1/TswSJiaqV_/yoshimi-2.1.1.1~dfsg0/doc/yoshimi_user_guide/pad/images/padenvelope.png and /tmp/tmp6t9mjqw1/As9a5djH7i/yoshimi-2.1.2.2~dfsg0/doc/yoshimi_user_guide/pad/images/padenvelope.png differ Binary files /tmp/tmp6t9mjqw1/TswSJiaqV_/yoshimi-2.1.1.1~dfsg0/doc/yoshimi_user_guide/pad/images/padharmonic.png and /tmp/tmp6t9mjqw1/As9a5djH7i/yoshimi-2.1.2.2~dfsg0/doc/yoshimi_user_guide/pad/images/padharmonic.png differ diff -Nru yoshimi-2.1.1.1~dfsg0/doc/yoshimi_user_guide/pad/pad.html yoshimi-2.1.2.2~dfsg0/doc/yoshimi_user_guide/pad/pad.html --- yoshimi-2.1.1.1~dfsg0/doc/yoshimi_user_guide/pad/pad.html 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/doc/yoshimi_user_guide/pad/pad.html 2021-12-03 20:12:12.000000000 +0000 @@ -13,7 +13,7 @@ PadSynth Harmonics Window PadSynth Envelopes Window

    - The PadSynth engine was designed by Paul Nasca and to the best of our knowledge there is no comparable type generally available. It uses a waveform oscillator that is virtually identical to the one used by AddSynth. Some complex mathematics is then applied to manipulate the overall spectrum. Finally this is converted to a set of fixed perfectly looping wavetables. As a result none of the previous controls are real-time. However, it is the wavetables that are called for actual sound generation after passing through the usual envelope controls (which are real-time). + The PadSynth engine was designed by Paul Nasca and to the best of our knowledge there is no comparable type generally available. It uses a waveform oscillator that is virtually identical to the one used by AddSynth. Some complex mathematics is then applied to manipulate the overall spectrum. Finally this is converted to a set of fixed perfectly looping wavetables. As a result none of these harmonics controls are real-time. Also, it is the wavetables that are called for actual sound generation after passing through the usual envelope controls (which are real-time).

    There are two tabbed views in a single window. You will normally be shown the harmonic structure, the envelopes one (as it's name suggests) consisting mostly of envelope and LFO inserts.

    @@ -42,9 +42,9 @@

    AmpMode Amplitude mode: Sum, Multiply, Div1, Div2.

    - Par1 Parameter 1 for AmpMode (depends on mode selected). + Par1 The spectral width of the multiplier (depends on mode selected).

    - Par2 Parameter 2 for AmpMode (depends on mode selected). + Par2 The amplitude of the multiplier (depends on mode selected).

    AutoScale We don't currently have information about this control. @@ -55,7 +55,7 @@

    smp/oct The number of samples used in each octave.

    - no.oct The number of octaves covered. + no.oct The number of octaves of samples independently generated.

    Sample Size Size of the sample.

    @@ -83,13 +83,15 @@
    Note -
    -  If any of the above controls are altered it will be necessary to click on the Apply button as the wavetable has to be rebuilt. +
    + If any of the above controls are altered it will be necessary to click on the Apply button (which will have turned red) as the wavetable has to be rebuilt.
    + Also, be aware that with a very big sample size and/or octave range and samples/octave this could take many seconds to complete. +

    Envelopes and LFOs

    - Once again we have all the standard inserts. There are also the local controls found in AddSynth and SubSynth. None of these affect the wavetable itself, so there is no need for the apply button here. + Once again we have all the standard inserts. There are also the same local controls found in AddSynth and SubSynth. None of these affect the wavetable itself, so there is no need for the apply button here.

    Binary files /tmp/tmp6t9mjqw1/TswSJiaqV_/yoshimi-2.1.1.1~dfsg0/doc/yoshimi_user_guide/part/images/edit.png and /tmp/tmp6t9mjqw1/As9a5djH7i/yoshimi-2.1.2.2~dfsg0/doc/yoshimi_user_guide/part/images/edit.png differ diff -Nru yoshimi-2.1.1.1~dfsg0/doc/yoshimi_user_guide/part/part.html yoshimi-2.1.2.2~dfsg0/doc/yoshimi_user_guide/part/part.html --- yoshimi-2.1.1.1~dfsg0/doc/yoshimi_user_guide/part/part.html 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/doc/yoshimi_user_guide/part/part.html 2021-12-03 20:12:12.000000000 +0000 @@ -13,7 +13,7 @@ Main - Bottom

    The first control is the part number you are currently looking at, and - alongside this selection is an entry to decide the number of parts. These are rows of 16, and can be 16 (the default), 32 and 64. Initially the higher numbered ones take the same channel as the matching default ones. The is especially useful for Vector control where a 'column' of up to four parts can be linked and controlled by a MIDI joystick, or similar. + alongside this selection is an entry to decide the number of parts. These are rows of 16, and can be 16 (the default), 32 and 64. Initially the higher numbered ones take the same channel as the matching default ones. This is especially useful for Vector control where a 'column' of up to four parts can be linked and controlled by a MIDI joystick, or similar.

    On the same line you then have what is both a shortcut button to open the window for the current selected bank and (with a right-click) an editable field for the part's current instrument name. Finally, there is an Edit button for detailed part editing. Binary files /tmp/tmp6t9mjqw1/TswSJiaqV_/yoshimi-2.1.1.1~dfsg0/doc/yoshimi_user_guide/resonance/images/resonance.png and /tmp/tmp6t9mjqw1/As9a5djH7i/yoshimi-2.1.2.2~dfsg0/doc/yoshimi_user_guide/resonance/images/resonance.png differ diff -Nru yoshimi-2.1.1.1~dfsg0/doc/yoshimi_user_guide/resonance/resonance.html yoshimi-2.1.2.2~dfsg0/doc/yoshimi_user_guide/resonance/resonance.html --- yoshimi-2.1.1.1~dfsg0/doc/yoshimi_user_guide/resonance/resonance.html 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/doc/yoshimi_user_guide/resonance/resonance.html 2021-12-03 20:12:12.000000000 +0000 @@ -40,9 +40,6 @@

  • InterpPk L Interpolate peak levels for a linear slope beween peaks.
  • -
  • - Clear Set the graph to a flat line, so no resonance. -

  • kHz Indicates the frequency component of the mouse position in the graph. The scale of this control is set by the octave setting. @@ -52,6 +49,9 @@

  • + Clear Set the graph to a flat line, so no resonance. +
  • +
  • Smooth This is not like smooth interpolation but can be used to progressively even out and reduce the amplitude of the graph.
  • @@ -69,7 +69,7 @@ Next (Effects) To AddSynth
    - To PaddSynth + To PadSynth

    Binary files /tmp/tmp6t9mjqw1/TswSJiaqV_/yoshimi-2.1.1.1~dfsg0/doc/yoshimi_user_guide/sub/images/sub.png and /tmp/tmp6t9mjqw1/As9a5djH7i/yoshimi-2.1.2.2~dfsg0/doc/yoshimi_user_guide/sub/images/sub.png differ diff -Nru yoshimi-2.1.1.1~dfsg0/doc/yoshimi_user_guide/wave/wave.html yoshimi-2.1.2.2~dfsg0/doc/yoshimi_user_guide/wave/wave.html --- yoshimi-2.1.1.1~dfsg0/doc/yoshimi_user_guide/wave/wave.html 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/doc/yoshimi_user_guide/wave/wave.html 2021-12-03 20:12:12.000000000 +0000 @@ -64,7 +64,7 @@ Next (Resonance) To AddSynth
    - To PaddSynth + To PadSynth

    diff -Nru yoshimi-2.1.1.1~dfsg0/indexref.html yoshimi-2.1.2.2~dfsg0/indexref.html --- yoshimi-2.1.1.1~dfsg0/indexref.html 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/indexref.html 2021-12-03 20:12:12.000000000 +0000 @@ -86,6 +86,8 @@
    MIDI CCs and NRPNs

    + Miscellany +

    Appendix

    Writing this user guide was a collaborative effort by the following: diff -Nru yoshimi-2.1.1.1~dfsg0/INSTALL yoshimi-2.1.2.2~dfsg0/INSTALL --- yoshimi-2.1.1.1~dfsg0/INSTALL 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/INSTALL 2021-12-03 20:12:12.000000000 +0000 @@ -6,7 +6,7 @@ ---- Sample instructions to compile/build using ccmake on Linux, outside-source-tree ----- -This uses "yoshimi-1.5.1" as an example, and should work fine with other versions. It is an easy way to build/compile using ccmake, in a separate build directory. This way, changes to source code can be readily compared without combing through the build-related files. +This uses "yoshimi-1.5.1" as an example, and should work fine with all other versions. It is an easy way to build/compile using ccmake, in a separate build directory. This way, changes to source code can be readily compared without combing through the build-related files. We will assume you have a home directory called 'user' and want Yoshimi to reside in a directory called 'software', but downloaded the archive to /home/user/download. diff -Nru yoshimi-2.1.1.1~dfsg0/README.txt yoshimi-2.1.2.2~dfsg0/README.txt --- yoshimi-2.1.1.1~dfsg0/README.txt 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/README.txt 2021-12-03 20:12:12.000000000 +0000 @@ -1,14 +1,23 @@ -Version 2.1.1 +Version 2.1.2 -This is a relatively minor update. +More small improvements and extensions. -Controllers and MIDI CCs windows now have separate buttons in the main window. +Improvements to MIDI-learn, and better compatibility with the earliest versions. -Instrument bank improvements give faster startup. +CLI extensions: +PadSynth status can be read. +GUI status can be read. +MIDI source and audio destination can be read. -The switch for disabling 'Enable part on program change' has been removed. +GUI clarity improvements. -Further details in /doc/Yoshimi_2.1.1_features.txt +Further revision and extension of the HTML user guide. + +Better actual sound conformity across distros/compliers. + +Bugfixes. + +Further details in /doc/Yoshimi_2.1.2_features.txt Yoshimi source code is available from either: https://sourceforge.net/projects/yoshimi diff -Nru yoshimi-2.1.1.1~dfsg0/src/CLI/CmdInterpreter.cpp yoshimi-2.1.2.2~dfsg0/src/CLI/CmdInterpreter.cpp --- yoshimi-2.1.1.1~dfsg0/src/CLI/CmdInterpreter.cpp 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/CLI/CmdInterpreter.cpp 2021-12-03 20:12:12.000000000 +0000 @@ -1384,6 +1384,7 @@ value = (input.toggle() == 1); } } + break; } if (selected > -1) { @@ -3147,16 +3148,26 @@ else if (input.matchnMove(1, "gui")) { command = CONFIG::control::enableGUI; - value = input.toggle(); - if (value == -1) - return REPLY::value_msg; + if (controlType == type_read) + value = 0; + else + { + value = input.toggle(); + if (value == -1) + return REPLY::value_msg; + } } else if (input.matchnMove(1, "cli")) { command = CONFIG::control::enableCLI; - value = input.toggle(); - if (value == -1) - return REPLY::value_msg; + if (controlType == type_read) + value = 0; + else + { + value = input.toggle(); + if (value == -1) + return REPLY::value_msg; + } } else if (input.matchnMove(2, "identify")) @@ -3266,24 +3277,38 @@ else if (input.matchnMove(2, "midi")) { - value = 1; - if (input.matchnMove(1, "alsa")) - command = CONFIG::control::alsaPreferredMidi; - else if (controlType != TOPLEVEL::type::Write || input.matchnMove(1, "jack")) - command = CONFIG::control::jackPreferredMidi; + if (controlType != TOPLEVEL::type::Write) + { + return sendDirect(synth, TOPLEVEL::action::fromCLI, 0, controlType, CONFIG::control::readMIDI, TOPLEVEL::section::config); + } else - return REPLY::value_msg; + { + value = 1; + if (input.matchnMove(1, "alsa")) + command = CONFIG::control::alsaPreferredMidi; + else if (input.matchnMove(1, "jack")) + command = CONFIG::control::jackPreferredMidi; + else + return REPLY::value_msg; + } } else if (input.matchnMove(2, "audio")) { - value = 1; - if (input.matchnMove(1, "alsa")) - command = CONFIG::control::alsaPreferredAudio; - else if (controlType != TOPLEVEL::type::Write || input.matchnMove(1, "jack")) - command = CONFIG::control::jackPreferredAudio; + if (controlType != TOPLEVEL::type::Write) + { + return sendDirect(synth, TOPLEVEL::action::fromCLI, 0, controlType, CONFIG::control::readAudio, TOPLEVEL::section::config); + } else - return REPLY::value_msg; + { + value = 1; + if (input.matchnMove(1, "alsa")) + command = CONFIG::control::alsaPreferredAudio; + else if (input.matchnMove(1, "jack")) + command = CONFIG::control::jackPreferredAudio; + else + return REPLY::value_msg; + } } else if (input.matchnMove(2, "root")) @@ -4762,7 +4787,7 @@ if (input.matchnMove(2, "apply")) { - value = 0; // dummy + value = 1; cmd = PADSYNTH::control::applyChanges; } @@ -4837,7 +4862,14 @@ cmd = RESONANCE::control::smoothGraph; else if (input.matchnMove(1, "clear")) cmd = RESONANCE::control::clearGraph; - + else if (input.matchnMove(2, "apply")) + { // this is a padsynth level control but must be callable here + if (engine != PART::engine::padSynth) + return REPLY::available_msg; + value = 1; + insert = UNUSED; + cmd = PADSYNTH::control::applyChanges; + } if (cmd > -1) return sendNormal(synth, 0, value, controlType, cmd, npart, kitNumber, engine, insert); @@ -5086,10 +5118,10 @@ } else if (input.matchnMove(2, "apply")) - { + { // this is a padsynth level control but must be callable here if (engine != PART::engine::padSynth) return REPLY::available_msg; - value = 0; // dummy + value = 1; insert = UNUSED; cmd = PADSYNTH::control::applyChanges; } diff -Nru yoshimi-2.1.1.1~dfsg0/src/CMakeLists.txt yoshimi-2.1.2.2~dfsg0/src/CMakeLists.txt --- yoshimi-2.1.1.1~dfsg0/src/CMakeLists.txt 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/CMakeLists.txt 2021-12-03 20:12:12.000000000 +0000 @@ -27,8 +27,8 @@ if (POLICY CMP0072) cmake_policy (SET CMP0072 OLD) endif () -set (CMAKE_CXX_STANDARD 11) # we seem to need both for -add_definitions(-std=gnu++11) # various versions of cmake +set (CMAKE_CXX_STANDARD 14) # we seem to need both for +add_definitions(-std=gnu++14) # various versions of cmake add_definitions(-Wall) @@ -41,7 +41,7 @@ #add_definitions(-Wno-vla) # Nothing wrong with variable length arrays # ^^^ comment these out on release pushes -set (YOSHIMI_VERSION "2.1.1.1") +set (YOSHIMI_VERSION "2.1.2.2") add_definitions (-DMIN_CONFIG_MAJOR=2) add_definitions (-DMIN_CONFIG_MINOR=0) @@ -139,13 +139,7 @@ find_package (PkgConfig REQUIRED) -include (CheckFunctionExists) - -check_function_exists(exp10f EXP10F) - -if (EXP10F) - add_definitions(-DHAVE_EXP10F) -endif () +find_package(Threads REQUIRED) check_c_source_compiles ( "#include @@ -293,6 +287,7 @@ set (Interface_Sources Interface/InterChange.cpp Interface/Data2Text.cpp + Interface/Text2Data.cpp Interface/MidiLearn.cpp Interface/MidiDecode.cpp Interface/RingBuffer.h @@ -441,6 +436,7 @@ ${Readline_LIBRARY} ${ZLIB_LIBRARIES} ${LIBDL_LINUX} + ${CMAKE_THREAD_LIBS_INIT} ) if ("${CMAKE_SYSTEM_NAME}" STREQUAL "FreeBSD") diff -Nru yoshimi-2.1.1.1~dfsg0/src/DSP/AnalogFilter.cpp yoshimi-2.1.2.2~dfsg0/src/DSP/AnalogFilter.cpp --- yoshimi-2.1.1.1~dfsg0/src/DSP/AnalogFilter.cpp 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/DSP/AnalogFilter.cpp 2021-12-03 20:12:12.000000000 +0000 @@ -30,7 +30,7 @@ #include "Misc/SynthEngine.h" #include "Misc/NumericFuncs.h" -using func::dB2rap; +using func::decibel; AnalogFilter::AnalogFilter(unsigned char Ftype, float Ffreq, float Fq, unsigned char Fstages, SynthEngine *_synth) : @@ -111,24 +111,24 @@ void AnalogFilter::computefiltercoefs(void) { - float tmp; - float omega, sn, cs, alpha, beta; - int zerocoefs = 0; // this is used if the freq is too high + double tmp; + double omega, sn, cs, alpha, beta; + bool zerocoefs = false; // this is used if the freq is too high // do not allow frequencies bigger than samplerate/2 float freq = this->freq; if (freq > (synth->halfsamplerate_f - 500.0f)) { freq = synth->halfsamplerate_f - 500.0f; - zerocoefs = 1; + zerocoefs = true; } if (freq < 0.1f) freq = 0.1; // do not allow bogus Q if (q < 0.0f) q = 0.0f; - float tmpq; - float tmpgain; + double tmpq; + double tmpgain; if (stages == 0) { tmpq = q; @@ -136,22 +136,28 @@ } else { - tmpq = (q > 1.0f) ? powf(q, 1.0f / (stages + 1)) : q; - tmpgain = powf(gain, 1.0f / (stages + 1)); + tmpq = (q > 1.0f) ? pow(q, 1.0 / (stages + 1)) : q; + tmpgain = pow(gain, 1.0 / (stages + 1)); } - // most of theese are implementations of + // most of these are implementations of // the "Cookbook formulae for audio EQ" by Robert Bristow-Johnson // The original location of the Cookbook is: // http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt + + // (Remark 2021: URL went offline in 2005; content can still be found on archive.org): + // https://web.archive.org/web/20050404051659/http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt + + // Note: filter coefficients are computed using doubles, + // to get reproducible numbers under optimisation on different compilers/platforms switch (type) { case 0: // LPF 1 pole - if (zerocoefs == 0) - tmp = expf(-2.0f * PI * freq / synth->samplerate_f); + if (not zerocoefs) + tmp = exp(-TWOPI * freq / synth->samplerate_f); else - tmp = 0.0f; - c[0] = 1.0f - tmp; + tmp = 0.0; + c[0] = 1.0 - tmp; c[1] = 0.0f; c[2] = 0.0f; d[1] = tmp; @@ -160,12 +166,12 @@ break; case 1: // HPF 1 pole - if (zerocoefs == 0) - tmp = expf(-2.0f * PI * freq / synth->samplerate_f); + if (not zerocoefs) + tmp = exp(-TWOPI * freq / synth->samplerate_f); else tmp = 0.0f; - c[0] = (1.0f + tmp) / 2.0f; - c[1] = -(1.0f + tmp) / 2.0f; + c[0] = (1.0 + tmp) / 2.0; + c[1] = -(1.0 + tmp) / 2.0; c[2] = 0.0f; d[1] = tmp; d[2] = 0.0f; @@ -173,23 +179,17 @@ break; case 2:// LPF 2 poles - if (zerocoefs == 0) + if (not zerocoefs) { omega = TWOPI * freq / synth->samplerate_f; - sn = sinf(omega); - cs = cosf(omega); - alpha = sn / (2.0f * tmpq); + sn = sin(omega); + cs = cos(omega); + alpha = sn / (2.0 * tmpq); tmp = 1 + alpha; - c[1] = (1.0f - cs) / tmp; - c[0] = c[2] = c[1] / 2.0f; - d[1] = -2.0f * cs / tmp * -1.0f; - d[2] = (1.0f - alpha) / tmp * -1.0f; - - //c[0] = (1.0f - cs) / 2.0f / tmp; - //c[1] = (1.0f - cs) / tmp; - //c[2] = (1.0f - cs) / 2.0f / tmp; - //d[1] = -2.0f * cs / tmp * -1.0f; - //d[2] = (1.0f - alpha) / tmp * -1.0f; + c[1] = (1.0 - cs) / tmp; + c[0] = c[2] = c[1] / 2.0; + d[1] = -2.0 * cs / tmp * -1.0; + d[2] = (1.0 - alpha) / tmp * -1.0; } else { @@ -200,18 +200,18 @@ break; case 3: // HPF 2 poles - if (zerocoefs == 0) + if (not zerocoefs) { omega = TWOPI * freq / synth->samplerate_f; - sn = sinf(omega); - cs = cosf(omega); - alpha = sn / (2.0f * tmpq); + sn = sin(omega); + cs = cos(omega); + alpha = sn / (2.0 * tmpq); tmp = 1 + alpha; - c[0] = (1.0f + cs) / 2.0f / tmp; - c[1] = -(1.0f + cs) / tmp; - c[2] = (1.0f + cs) / 2.0f / tmp; - d[1] = -2.0f * cs / tmp * -1.0f; - d[2] = (1.0f - alpha) / tmp * -1.0f; + c[0] = (1.0 + cs) / 2.0 / tmp; + c[1] = -(1.0 + cs) / tmp; + c[2] = (1.0 + cs) / 2.0 / tmp; + d[1] = -2.0 * cs / tmp * -1.0; + d[2] = (1.0 - alpha) / tmp * -1.0; } else c[0] = c[1] = c[2] = d[1] = d[2] = 0.0f; @@ -219,18 +219,18 @@ break; case 4: // BPF 2 poles - if (zerocoefs == 0) + if (not zerocoefs) { omega = TWOPI * freq / synth->samplerate_f; - sn = sinf(omega); - cs = cosf(omega); - alpha = sn / (2.0f * tmpq); - tmp = 1.0f + alpha; - c[0] = alpha / tmp * sqrtf(tmpq + 1.0f); + sn = sin(omega); + cs = cos(omega); + alpha = sn / (2.0 * tmpq); + tmp = 1.0 + alpha; + c[0] = alpha / tmp * sqrt(tmpq + 1.0); c[1] = 0.0f; - c[2] = -alpha / tmp * sqrtf(tmpq + 1.0f); - d[1] = -2.0f * cs / tmp * -1.0f; - d[2] = (1.0f - alpha) / tmp * -1.0f; + c[2] = -alpha / tmp * sqrt(tmpq + 1.0); + d[1] = -2.0 * cs / tmp * -1.0; + d[2] = (1.0 - alpha) / tmp * -1.0; } else c[0] = c[1] = c[2] = d[1] = d[2] = 0.0f; @@ -238,18 +238,18 @@ break; case 5: // NOTCH 2 poles - if (zerocoefs == 0) + if (not zerocoefs) { omega = TWOPI * freq / synth->samplerate_f; - sn = sinf(omega); - cs = cosf(omega); - alpha = sn / (2.0f * sqrtf(tmpq)); - tmp = 1.0f + alpha; - c[0] = 1.0f / tmp; - c[1] = -2.0f * cs / tmp; - c[2] = 1.0f / tmp; - d[1] = -2.0f * cs / tmp * -1.0f; - d[2] = (1.0f - alpha) / tmp * -1.0f; + sn = sin(omega); + cs = cos(omega); + alpha = sn / (2.0 * sqrt(tmpq)); + tmp = 1.0 + alpha; + c[0] = 1.0 / tmp; + c[1] = -2.0 * cs / tmp; + c[2] = 1.0 / tmp; + d[1] = -2.0 * cs / tmp * -1.0; + d[2] = (1.0 - alpha) / tmp * -1.0; } else { @@ -260,19 +260,19 @@ break; case 6: // PEAK (2 poles) - if (zerocoefs == 0) + if (not zerocoefs) { omega = TWOPI * freq / synth->samplerate_f; - sn = sinf(omega); - cs = cosf(omega); - tmpq *= 3.0f; - alpha = sn / (2.0f * tmpq); - tmp = 1.0f + alpha / tmpgain; - c[0] = (1.0f + alpha * tmpgain) / tmp; - c[1] = (-2.0f * cs) / tmp; - c[2] = (1.0f - alpha * tmpgain) / tmp; - d[1] = -2.0f * cs / tmp * -1.0f; - d[2] = (1.0f - alpha / tmpgain) / tmp * -1.0f; + sn = sin(omega); + cs = cos(omega); + tmpq *= 3.0; + alpha = sn / (2.0 * tmpq); + tmp = 1.0 + alpha / tmpgain; + c[0] = (1.0 + alpha * tmpgain) / tmp; + c[1] = (-2.0 * cs) / tmp; + c[2] = (1.0 - alpha * tmpgain) / tmp; + d[1] = -2.0 * cs / tmp * -1.0; + d[2] = (1.0 - alpha / tmpgain) / tmp * -1.0; } else { @@ -283,21 +283,21 @@ break; case 7: // Low Shelf - 2 poles - if (zerocoefs == 0) + if (not zerocoefs) { omega = TWOPI * freq / synth->samplerate_f; - sn = sinf(omega); - cs = cosf(omega); - tmpq = sqrtf(tmpq); - alpha = sn / (2.0f * tmpq); - beta = sqrtf(tmpgain) / tmpq; - tmp = (tmpgain + 1.0f) + (tmpgain - 1.0f) * cs + beta * sn; - - c[0] = tmpgain * ((tmpgain + 1.0f) - (tmpgain - 1.0f) * cs + beta * sn) / tmp; - c[1] = 2.0f * tmpgain * ((tmpgain - 1.0f) - (tmpgain + 1.0f) * cs) / tmp; - c[2] = tmpgain * ((tmpgain + 1.0f) - (tmpgain - 1.0f) * cs - beta * sn) / tmp; - d[1] = -2.0f * ((tmpgain - 1.0f) + (tmpgain + 1.0f) * cs) / tmp * -1; - d[2] = ((tmpgain + 1.0f) + (tmpgain - 1.0f) * cs - beta * sn) / tmp * -1.0f; + sn = sin(omega); + cs = cos(omega); + tmpq = sqrt(tmpq); + alpha = sn / (2.0 * tmpq); + beta = sqrt(tmpgain) / tmpq; + tmp = (tmpgain + 1.0) + (tmpgain - 1.0) * cs + beta * sn; + + c[0] = tmpgain * ((tmpgain + 1.0) - (tmpgain - 1.0) * cs + beta * sn) / tmp; + c[1] = 2.0 * tmpgain * ((tmpgain - 1.0) - (tmpgain + 1.0) * cs) / tmp; + c[2] = tmpgain * ((tmpgain + 1.0) - (tmpgain - 1.0) * cs - beta * sn) / tmp; + d[1] = -2.0 * ((tmpgain - 1.0) + (tmpgain + 1.0) * cs) / tmp * -1.0; + d[2] = ((tmpgain + 1.0) + (tmpgain - 1.0) * cs - beta * sn) / tmp * -1.0; } else { @@ -308,21 +308,21 @@ break; case 8: // High Shelf - 2 poles - if (zerocoefs == 0) + if (not zerocoefs) { omega = TWOPI * freq / synth->samplerate_f; - sn = sinf(omega); - cs = cosf(omega); - tmpq = sqrtf(tmpq); - alpha = sn / (2.0f * tmpq); - beta = sqrtf(tmpgain) / tmpq; - tmp = (tmpgain + 1.0f) - (tmpgain - 1.0f) * cs + beta * sn; - - c[0] = tmpgain * ((tmpgain + 1.0f) + (tmpgain - 1.0f) * cs + beta * sn) / tmp; - c[1] = -2.0f * tmpgain * ((tmpgain - 1.0f) + (tmpgain + 1.0f) * cs) / tmp; - c[2] = tmpgain * ((tmpgain + 1.0f) + (tmpgain - 1.0f) * cs - beta * sn) / tmp; - d[1] = 2.0f * ((tmpgain - 1.0f) - (tmpgain + 1.0f) * cs) / tmp * -1.0f; - d[2] = ((tmpgain + 1.0f) - (tmpgain - 1.0f) * cs - beta * sn) / tmp * -1.0f; + sn = sin(omega); + cs = cos(omega); + tmpq = sqrt(tmpq); + alpha = sn / (2.0 * tmpq); + beta = sqrt(tmpgain) / tmpq; + tmp = (tmpgain + 1.0) - (tmpgain - 1.0) * cs + beta * sn; + + c[0] = tmpgain * ((tmpgain + 1.0) + (tmpgain - 1.0) * cs + beta * sn) / tmp; + c[1] = -2.0 * tmpgain * ((tmpgain - 1.0) + (tmpgain + 1.0) * cs) / tmp; + c[2] = tmpgain * ((tmpgain + 1.0) + (tmpgain - 1.0) * cs - beta * sn) / tmp; + d[1] = 2.0 * ((tmpgain - 1.0) - (tmpgain + 1.0) * cs) / tmp * -1.0; + d[2] = ((tmpgain + 1.0) - (tmpgain - 1.0) * cs - beta * sn) / tmp * -1.0; } else { @@ -387,7 +387,7 @@ void AnalogFilter::setgain(float dBgain) { - gain = dB2rap(dBgain); + gain = decibel(dBgain); computefiltercoefs(); } diff -Nru yoshimi-2.1.1.1~dfsg0/src/DSP/Filter.cpp yoshimi-2.1.2.2~dfsg0/src/DSP/Filter.cpp --- yoshimi-2.1.1.1~dfsg0/src/DSP/Filter.cpp 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/DSP/Filter.cpp 2021-12-03 20:12:12.000000000 +0000 @@ -26,7 +26,8 @@ #include "DSP/Filter.h" #include "Misc/NumericFuncs.h" -using func::dB2rap; +using func::decibel; +using func::power; Filter::Filter(FilterParams *pars_, SynthEngine *_synth): @@ -72,7 +73,7 @@ break; case 2: - filter->outgain = dB2rap(pars->getgain()); + filter->outgain = decibel(pars->getgain()); if (filter->outgain > 1.0f) filter->outgain = sqrtf(filter->outgain); break; @@ -82,7 +83,7 @@ if (Ftype >= 6 && Ftype <= 8) filter->setgain(pars->getgain()); else - filter->outgain = dB2rap(pars->getgain()); + filter->outgain = decibel(pars->getgain()); break; } } @@ -117,7 +118,7 @@ float Filter::getrealfreq(float freqpitch) { if (category == 0 || category == 2) - return powf(2.0f, freqpitch + 9.96578428f); // log2(1000)=9.95748 + return power<2>(freqpitch + 9.96578428f); // log2(1000)=9.95748 else return freqpitch; } diff -Nru yoshimi-2.1.1.1~dfsg0/src/DSP/FormantFilter.cpp yoshimi-2.1.2.2~dfsg0/src/DSP/FormantFilter.cpp --- yoshimi-2.1.1.1~dfsg0/src/DSP/FormantFilter.cpp 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/DSP/FormantFilter.cpp 2021-12-03 20:12:12.000000000 +0000 @@ -32,7 +32,9 @@ using synth::aboveAmplitudeThreshold; using synth::interpolateAmplitude; -using func::dB2rap; +using func::decibel; +using func::powFrac; +using func::power; FormantFilter::FormantFilter(FilterParams *pars_, SynthEngine *_synth): @@ -211,13 +213,13 @@ formantslowness = powf(1.0f - (pars->Pformantslowness / 128.0f), 3.0f); - vowelclearness = powf(10.0f, (pars->Pvowelclearness - 32.0f) / 48.0f); + vowelclearness = power<10>((pars->Pvowelclearness - 32.0f) / 48.0f); - sequencestretch = powf(0.1f, (pars->Psequencestretch - 32.0f) / 48.0f); + sequencestretch = powFrac<10>((pars->Psequencestretch - 32.0f) / 48.0f); if (pars->Psequencereversed) sequencestretch *= -1.0f; - outgain = dB2rap(pars->getgain()); + outgain = decibel(pars->getgain()); Qfactor = pars->getq(); } diff -Nru yoshimi-2.1.1.1~dfsg0/src/DSP/SVFilter.cpp yoshimi-2.1.2.2~dfsg0/src/DSP/SVFilter.cpp --- yoshimi-2.1.1.1~dfsg0/src/DSP/SVFilter.cpp 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/DSP/SVFilter.cpp 2021-12-03 20:12:12.000000000 +0000 @@ -30,8 +30,6 @@ #include "DSP/SVFilter.h" #include "Misc/NumericFuncs.h" -using func::dB2rap; - SVFilter::SVFilter(unsigned char Ftype, float Ffreq, float Fq, unsigned char Fstages, SynthEngine *_synth) : @@ -91,12 +89,13 @@ void SVFilter::computefiltercoefs(void) { - par.f = freq / synth->samplerate_f * 4.0f; + // calculations done in doubles for better portability of results + par.f = double(freq) / synth->samplerate * 4.0; if (par.f > 0.99999f) par.f = 0.99999f; - par.q = 1.0f - atanf(sqrtf(q)) * 2.0f / PI; - par.q = powf(par.q, 1.0f / (stages + 1)); - par.q_sqrt = sqrtf(par.q); + double qq = 1.0 - atan(sqrt(q)) * 2.0 / PI; + par.q = pow(qq, 1.0 / (stages + 1)); + par.q_sqrt = sqrt(qq); } diff -Nru yoshimi-2.1.1.1~dfsg0/src/DSP/Unison.cpp yoshimi-2.1.2.2~dfsg0/src/DSP/Unison.cpp --- yoshimi-2.1.1.1~dfsg0/src/DSP/Unison.cpp 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/DSP/Unison.cpp 2021-12-03 20:12:12.000000000 +0000 @@ -29,11 +29,13 @@ #include #include -using namespace std; - #include "Misc/Config.h" +#include "Misc/NumericFuncs.h" #include "DSP/Unison.h" +using func::power; + + Unison::Unison(int update_period_samples_, float max_delay_sec_, SynthEngine *_synth) : unison_size(0), base_freq(1.0f), @@ -121,7 +123,7 @@ // printf("%g %g\n",uv[i].relative_amplitude,period); } - float max_speed = powf(2.0f, unison_bandwidth_cents / 1200.0f); + float max_speed = power<2>(unison_bandwidth_cents / 1200.0f); // printf("speed %f\n", max_speed); unison_amplitude_samples = 0.125f * (max_speed - 1.0f) * synth->samplerate_f / base_freq; diff -Nru yoshimi-2.1.1.1~dfsg0/src/Effects/Chorus.cpp yoshimi-2.1.2.2~dfsg0/src/Effects/Chorus.cpp --- yoshimi-2.1.1.1~dfsg0/src/Effects/Chorus.cpp 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/Effects/Chorus.cpp 2021-12-03 20:12:12.000000000 +0000 @@ -25,8 +25,12 @@ */ #include "Misc/SynthEngine.h" +#include "Misc/NumericFuncs.h" #include "Effects/Chorus.h" +using func::power; + + #define MAX_CHORUS_DELAY 250.0f // ms static const int PRESET_SIZE = 12; @@ -173,14 +177,14 @@ void Chorus::setdepth(unsigned char Pdepth_) { Pdepth = Pdepth_; - depth = (powf(8.0f, (Pdepth / 127.0f) * 2.0f) - 1.0f) / 1000.0f; // seconds + depth = (power<8>((Pdepth / 127.0f) * 2.0f) - 1.0f) / 1000.0f; // seconds } void Chorus::setdelay(unsigned char Pdelay_) { Pdelay = Pdelay_; - delay = (powf(10.0f, (Pdelay / 127.0f) * 2.0f) - 1.0f) / 1000.0f; // seconds + delay = (power<10>((Pdelay / 127.0f) * 2.0f) - 1.0f) / 1000.0f; // seconds } @@ -283,6 +287,7 @@ break; default: Pchanged = false; + break; } } diff -Nru yoshimi-2.1.1.1~dfsg0/src/Effects/Distorsion.cpp yoshimi-2.1.2.2~dfsg0/src/Effects/Distorsion.cpp --- yoshimi-2.1.1.1~dfsg0/src/Effects/Distorsion.cpp 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/Effects/Distorsion.cpp 2021-12-03 20:12:12.000000000 +0000 @@ -25,10 +25,13 @@ */ #include "Misc/SynthEngine.h" +#include "Misc/SynthHelper.h" #include "Effects/Distorsion.h" #include "Misc/NumericFuncs.h" -using func::dB2rap; +using func::power; +using func::powFrac; +using func::decibel; namespace { // Implementation details... @@ -131,7 +134,7 @@ { outvolume.advanceValue(synth->sent_buffersize); - float inputdrive = powf(5.0f, (Pdrive - 32.0f) / 127.0f); + float inputdrive = power<5>((Pdrive - 32.0f) / 127.0f); if (Pnegate) inputdrive *= -1.0f; @@ -163,7 +166,7 @@ for (int i = 0; i < synth->sent_buffersize; ++i) { - float lvl = dB2rap(60.0f * level.getAndAdvanceValue() - 40.0f); + float lvl = decibel<-40>(1.0f - 1.5f * level.getAndAdvanceValue()); float lout = efxoutl[i]; float rout = efxoutr[i]; float l = lout * (1.0f - lrcross.getValue()) + rout * lrcross.getValue(); @@ -184,7 +187,7 @@ float tmp = Pvolume / 127.0f; if (insertion == 0) { - outvolume.setTargetValue(powf(0.01f, (1.0f - tmp)) * 4.0f); + outvolume.setTargetValue(4.0f * powFrac<100>(1.0f - tmp)); volume.setTargetValue(1.0f); } else diff -Nru yoshimi-2.1.1.1~dfsg0/src/Effects/Echo.cpp yoshimi-2.1.2.2~dfsg0/src/Effects/Echo.cpp --- yoshimi-2.1.1.1~dfsg0/src/Effects/Echo.cpp 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/Effects/Echo.cpp 2021-12-03 20:12:12.000000000 +0000 @@ -25,10 +25,14 @@ */ #include "Misc/NumericFuncs.h" +#include "Misc/SynthHelper.h" #include "Misc/SynthEngine.h" #include "Effects/Echo.h" #include +using func::power; +using func::powFrac; + static const int PRESET_SIZE = 7; static const int NUM_PRESETS = 9; static unsigned char presets[NUM_PRESETS][PRESET_SIZE] = { @@ -214,7 +218,7 @@ Pvolume = Pvolume_; if (insertion == 0) { - outvolume.setTargetValue(powf(0.01f, (1.0f - Pvolume / 127.0f)) * 4.0f); + outvolume.setTargetValue(4.0f * powFrac<100>(1.0f - Pvolume / 127.0f)); volume.setTargetValue(1.0f); } else @@ -238,7 +242,7 @@ { float tmp; Plrdelay = Plrdelay_; - tmp = (powf(2.0f, fabsf(Plrdelay - 64.0f) / 64.0f * 9.0f) -1.0f) / 1000.0f * synth->samplerate_f; + tmp = (power<2>(fabsf(Plrdelay - 64.0f) / 64.0f * 9.0f) -1.0f) / 1000.0f * synth->samplerate_f; if (Plrdelay < 64.0f) tmp = -tmp; lrdelay = (int)tmp; @@ -331,6 +335,7 @@ default: Pchanged = false; + break; } } diff -Nru yoshimi-2.1.1.1~dfsg0/src/Effects/EffectLFO.cpp yoshimi-2.1.2.2~dfsg0/src/Effects/EffectLFO.cpp --- yoshimi-2.1.1.1~dfsg0/src/Effects/EffectLFO.cpp 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/Effects/EffectLFO.cpp 2021-12-03 20:12:12.000000000 +0000 @@ -28,6 +28,9 @@ #include "Misc/SynthEngine.h" #include "Effects/EffectLFO.h" +using func::power; + + EffectLFO::EffectLFO(SynthEngine *_synth) : Pfreq(40), Prandomness(0), @@ -68,7 +71,7 @@ // Update the changed parameters void EffectLFO::updateparams() { - float lfofreq = (powf(2.0f, Pfreq / 127.0f * 10.0f) - 1.0f) * 0.03f; + float lfofreq = (power<2>(Pfreq / 127.0f * 10.0f) - 1.0f) * 0.03f; incx = fabsf(lfofreq) * synth->fixed_sample_step_f; if (incx > 0.49999999f) incx = 0.499999999f; // Limit the Frequency @@ -104,6 +107,7 @@ // updated (to allow more lfotypes) default: out = cosf(x * TWOPI); // EffectLFO_SINE + break; } return out; } diff -Nru yoshimi-2.1.1.1~dfsg0/src/Effects/EffectMgr.cpp yoshimi-2.1.2.2~dfsg0/src/Effects/EffectMgr.cpp --- yoshimi-2.1.1.1~dfsg0/src/Effects/EffectMgr.cpp 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/Effects/EffectMgr.cpp 2021-12-03 20:12:12.000000000 +0000 @@ -377,6 +377,7 @@ break; default: value = EFFECT::type::count - EFFECT::type::none; + break; } return value; } diff -Nru yoshimi-2.1.1.1~dfsg0/src/Effects/EQ.cpp yoshimi-2.1.2.2~dfsg0/src/Effects/EQ.cpp --- yoshimi-2.1.1.1~dfsg0/src/Effects/EQ.cpp 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/Effects/EQ.cpp 2021-12-03 20:12:12.000000000 +0000 @@ -24,11 +24,13 @@ */ +#include "Misc/NumericFuncs.h" #include "Misc/SynthEngine.h" #include "Effects/EQ.h" -#include "Misc/NumericFuncs.h" -using func::rap2dB; +using func::power; +using func::powFrac; +using func::asDecibel; EQ::EQ(bool insertion_, float *efxoutl_, float *efxoutr_, SynthEngine *_synth) : @@ -126,7 +128,7 @@ void EQ::setvolume(unsigned char Pvolume_) { Pvolume = Pvolume_; - float tmp = powf(0.005f, (1.0f - Pvolume / 127.0f)) * 10.0f; + float tmp = 10.0f * powFrac<200>(1.0f - Pvolume / 127.0f); outvolume.setTargetValue(tmp); volume.setTargetValue((!insertion) ? 1.0f : tmp); } @@ -164,6 +166,7 @@ break; case 1: Pband = value; + break; } if (npar < 10) return; @@ -189,7 +192,7 @@ case 1: filter[nb].Pfreq = value; - tmp = 600.0f * powf(30.0f, (value - 64.0f) / 64.0f); + tmp = 600.0f * power<30>((value - 64.0f) / 64.0f); filter[nb].freq.setTargetValue(tmp); break; @@ -201,7 +204,7 @@ case 3: filter[nb].Pq = value; - tmp = powf(30.0f, (value - 64.0f) / 64.0f); + tmp = power<30>((value - 64.0f) / 64.0f); filter[nb].q.setTargetValue(tmp); break; @@ -271,7 +274,7 @@ resp *= filter[i].l->H(freq); } // Only for UI purposes, use target value. - return rap2dB(resp * outvolume.getTargetValue()); + return asDecibel(resp * outvolume.getTargetValue()); } diff -Nru yoshimi-2.1.1.1~dfsg0/src/Effects/Reverb.cpp yoshimi-2.1.2.2~dfsg0/src/Effects/Reverb.cpp --- yoshimi-2.1.1.1~dfsg0/src/Effects/Reverb.cpp 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/Effects/Reverb.cpp 2021-12-03 20:12:12.000000000 +0000 @@ -32,8 +32,12 @@ #include "DSP/Unison.h" #include "DSP/AnalogFilter.h" #include "Misc/SynthEngine.h" +#include "Misc/SynthHelper.h" #include "Effects/Reverb.h" +using func::power; +using func::powFrac; + static const int PRESET_SIZE = 13; static const int NUM_PRESETS = 13; static unsigned char presets[NUM_PRESETS][PRESET_SIZE] = { @@ -279,7 +283,7 @@ Pvolume = Pvolume_; if (!insertion) { - outvolume.setTargetValue(powf(0.01f, (1.0f - Pvolume / 127.0f)) * 4.0f); + outvolume.setTargetValue(4.0f * powFrac<100>(1.0f - Pvolume / 127.0f)); volume.setTargetValue(1.0f); } else @@ -296,7 +300,7 @@ void Reverb::settime(unsigned char Ptime_) { Ptime = Ptime_; - float t = powf(60.0f, Ptime / 127.0f) - 0.97f; + float t = power<60>(Ptime / 127.0f) - 0.97f; for (int i = 0; i < REV_COMBS * 2; ++i) combfb[i] = -expf((float)comblen[i] / synth->samplerate_f * logf(0.001f) / t); // the feedback is negative because it removes the DC @@ -477,7 +481,7 @@ roomsize = (this->Proomsize - 64.0f) / 64.0f; if (roomsize > 0.0f) roomsize *= 2.0f; - roomsize = powf(10.0f, roomsize); + roomsize = power<10>(roomsize); rs = sqrtf(roomsize); settype(Ptype); } diff -Nru yoshimi-2.1.1.1~dfsg0/src/globals.h yoshimi-2.1.2.2~dfsg0/src/globals.h --- yoshimi-2.1.1.1~dfsg0/src/globals.h 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/globals.h 2021-12-03 20:12:12.000000000 +0000 @@ -160,8 +160,9 @@ namespace TOPLEVEL // usage TOPLEVEL::section::vector { enum section : unsigned char { - part1 = 0, - part64 = 63, + part1 = 0, // nothing must come + part64 = 63, // between these two + copyPaste = 72, // 48 (not yet!) vector = 192, // CO midiLearn = 216, // D8 @@ -215,7 +216,8 @@ /* * the following values must never appear in any other sections */ - textMessage = 254, // FE + unrecognised = 253, // FD + textMessage, forceExit // this is effective from *any* section! }; @@ -312,6 +314,8 @@ alsaAudioDevice, alsaPreferredAudio, alsaSampleRate, + readAudio, + readMIDI, // end of engine controls addPresetRootDir = 60, @@ -498,21 +502,22 @@ invertScale, invertedScaleCenter, scaleShift, - enableKeyboardMap = 16, lowKey, middleKey, highKey, tuning = 32, + clearAll, + retune, // GUI only + // all the above directly alter the tuning. retune must be the last + keyboardMap, importScl = 48, importKbm, exportScl, // not yet exportKbm, // not yet name = 64, - comment, - retune = 80, // GUI only - clearAll = 96 + comment }; } @@ -854,10 +859,6 @@ enableRandomPan, randomWidth, - bandwidth = 16, - bandwidthScale, - spectrumMode = 19, // Bandwidth, Discrete, Continuous - detuneFrequency = 32, equalTemperVariation, baseFrequencyAs440Hz, @@ -867,6 +868,10 @@ pitchBendAdjustment, pitchBendOffset, + bandwidth,// = 16, moved these three + bandwidthScale, + spectrumMode,// = 19, // Bandwidth, Discrete, Continuous + overtoneParameter1 = 48, overtoneParameter2, overtoneForceHarmonics, diff -Nru yoshimi-2.1.1.1~dfsg0/src/Interface/Data2Text.cpp yoshimi-2.1.2.2~dfsg0/src/Interface/Data2Text.cpp --- yoshimi-2.1.1.1~dfsg0/src/Interface/Data2Text.cpp 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/Interface/Data2Text.cpp 2021-12-03 20:12:12.000000000 +0000 @@ -91,7 +91,7 @@ string commandName; // this is unique and placed here to avoid Xruns - if (npart == TOPLEVEL::section::scales && (control <= SCALES::control::tuning || control >= SCALES::control::retune)) + if (npart == TOPLEVEL::section::scales && control <= SCALES::control::retune) synth->setAllPartMaps(); if (npart == TOPLEVEL::section::vector) @@ -138,24 +138,11 @@ if (kititem >= NUM_KIT_ITEMS && kititem < UNUSED) return "Invalid kit " + to_string(int(kititem) + 1); - Part *part; - part = synth->part[npart]; - - if (kititem > 0 && engine != UNUSED && control != PART::control::enable && part->kit[kititem].Penabled == false) - return "Part " + to_string(int(npart) + 1) + " Kit item " + to_string(int(kititem) + 1) + " not enabled"; - if (kititem == UNUSED || insert == TOPLEVEL::insert::kitGroup) { - if (control != PART::control::kitMode && kititem != UNUSED && part->Pkitmode == 0) - return "Part " + to_string(int(npart) + 1) + " Kitmode not enabled"; - else - { - commandName = resolvePart(getData, addValue); - return withValue(commandName, type, showValue, addValue, value); - } + commandName = resolvePart(getData, addValue); + return withValue(commandName, type, showValue, addValue, value); } - if (kititem > 0 && part->Pkitmode == 0) - return "Part " + to_string(int(npart) + 1) + " Kitmode not enabled"; if (engine == PART::engine::padSynth) { @@ -306,12 +293,6 @@ string contstr = ""; switch (control) { - //case 0: - //contstr = "Base Channel"; // local to source - //break; - //case 1: - //contstr = "Options"; - //break; case VECTOR::control::name: showValue = false; contstr = "Name " + textMsgBuffer.fetch(value_int); @@ -512,7 +493,13 @@ } - if (value < 1 && control >= SCALES::control::tuning && control <= SCALES::control::importKbm) + if (value < 1 && + ( + control == SCALES::control::tuning + || control == SCALES::control::keyboardMap + || control == SCALES::control::importScl + || control == SCALES::control::importKbm + )) { // errors :@( switch (value) { @@ -714,6 +701,43 @@ } break; + case CONFIG::control::readAudio: + contstr += "Audio Destination "; + if (addValue) + { + switch (value_int) + { + case 1: + contstr += "JACK"; + break; + case 2: + contstr += "ALSA"; + break; + default: + contstr += "None"; + } + showValue = false; + } + break; + + case CONFIG::control::readMIDI: + contstr += "MIDI Source "; + if (addValue) + { + switch (value_int) + { + case 1: + contstr += "JACK"; + break; + case 2: + contstr += "ALSA"; + break; + default: + contstr += "None"; + } + showValue = false; + } + break; case CONFIG::control::jackMidiSource: contstr += "JACK MIDI source: "; if (addValue) @@ -1377,27 +1401,20 @@ else kitnum = " "; - string name = ""; - if (control >= PART::control::volumeRange && control <= PART::control::receivePortamento) - { - name = "Controller "; - if (control >= PART::control::portamentoTime) - name += "Portamento "; - } - else if (control >= PART::control::midiModWheel && control <= PART::control::midiBandwidth) - name = "MIDI "; - else if (kititem != UNUSED) + string group = ""; + + if (kititem != UNUSED) { switch (engine) { case PART::engine::addSynth: - name = "AddSynth "; + group = "AddSynth "; break; case PART::engine::subSynth: - name = "SubSynth "; + group = "SubSynth "; break; case PART::engine::padSynth: - name = "PadSynth "; + group = "PadSynth "; break; } } @@ -1430,13 +1447,13 @@ contstr = "Volume"; break; case PART::control::velocitySense: - contstr = "Vel Sens"; + contstr = "Velocity Sense"; break; case PART::control::panning: contstr = "Panning"; break; case PART::control::velocityOffset: - contstr = "Vel Offset"; + contstr = "Velocity Offset"; break; case PART::control::midiChannel: showValue = false; @@ -1605,7 +1622,51 @@ } break; - case PART::control::volumeRange: + case PART::control::instrumentCopyright: + showValue = false; + contstr = "Copyright: " + textMsgBuffer.fetch(value_int); + break; + case PART::control::instrumentComments: + showValue = false; + contstr = "Comment: " + textMsgBuffer.fetch(value_int); + break; + case PART::control::instrumentName: + showValue = false; + contstr = "Name is: " + textMsgBuffer.fetch(value_int); + break; + case PART::control::instrumentType: + showValue = false; + contstr = "Type is: " + type_list[value_int]; + break; + case PART::control::defaultInstrumentCopyright: + showValue = false; + contstr = "Copyright "; + if (parameter == 0) + contstr += "load:\n"; + else + contstr += "save:\n"; + contstr += textMsgBuffer.fetch(value_int); + break; + case PART::control::resetAllControllers: + showValue = false; + contstr = "Cleared controllers"; + break; + + case PART::control::partBusy: + showValue = false; + if (value_bool) + contstr = "is busy"; + else + contstr = "is free"; + break; + + } + if (!contstr.empty()) + return ("Part " + to_string(npart + 1) + kitnum + group + contstr); + + switch (control) + { + case PART::control::volumeRange: contstr = "Vol Range"; // not the *actual* volume break; case PART::control::volumeEnable: @@ -1694,8 +1755,14 @@ contstr = "Receive"; yesno = true; break; + } + if (!contstr.empty()) + return ("Part " + to_string(npart + 1) + kitnum + "Controller " + contstr); - case PART::control::midiModWheel: + string name = "MIDI "; + switch (control) + { + case PART::control::midiModWheel: contstr = "Modulation"; break; case PART::control::midiBreath: @@ -1719,51 +1786,21 @@ case PART::control::midiBandwidth: contstr = "Bandwidth"; break; - - case PART::control::instrumentCopyright: - showValue = false; - contstr = "Copyright: " + textMsgBuffer.fetch(value_int); - break; - case PART::control::instrumentComments: - showValue = false; - contstr = "Comment: " + textMsgBuffer.fetch(value_int); + case PART::control::midiFMamp: + contstr = "FM Amp"; break; - case PART::control::instrumentName: - showValue = false; - contstr = "Name is: " + textMsgBuffer.fetch(value_int); + case PART::control::midiResonanceCenter: + contstr = "Resonance Cent"; break; - case PART::control::instrumentType: - showValue = false; - contstr = "Type is: " + type_list[value_int]; - break; - case PART::control::defaultInstrumentCopyright: - showValue = false; - contstr = "Copyright "; - if (parameter == 0) - contstr += "load:\n"; - else - contstr += "save:\n"; - contstr += textMsgBuffer.fetch(value_int); - break; - case PART::control::resetAllControllers: - showValue = false; - contstr = "Cleared controllers"; - break; - - case PART::control::partBusy: - showValue = false; - if (value_bool) - contstr = "is busy"; - else - contstr = "is free"; + case PART::control::midiResonanceBandwidth: + contstr = "Resonance Band"; break; default: showValue = false; + name = ""; contstr = "Unrecognised"; - } - return ("Part " + to_string(npart + 1) + kitnum + name + contstr); } @@ -1774,11 +1811,6 @@ unsigned char control = getData->data.control; unsigned char npart = getData->data.part; unsigned char kititem = getData->data.kit; - string name = ""; - if (control <= ADDSYNTH::control::panning) - name = " Amplitude "; - else if (control >= ADDSYNTH::control::detuneFrequency && control <= ADDSYNTH::control::relativeBandwidth) - name = "Frequency "; string contstr = ""; @@ -1788,7 +1820,7 @@ contstr = "Volume"; break; case ADDSYNTH::control::velocitySense: - contstr = "Vel Sens"; + contstr = "Velocity Sense"; break; case ADDSYNTH::control::panning: @@ -1810,7 +1842,7 @@ contstr = "Octave"; break; case ADDSYNTH::control::detuneType: - contstr = "Det type "; + contstr = "Detune Type "; showValue = false; if (addValue) contstr += detuneType [int(value)]; @@ -1819,7 +1851,7 @@ contstr = "Coarse Det"; break; case ADDSYNTH::control::relativeBandwidth: - contstr = "Rel B Wdth"; + contstr = "Relative Bandwidth"; break; case ADDSYNTH::control::stereo: @@ -1835,16 +1867,16 @@ contstr = "De Pop"; break; case ADDSYNTH::control::punchStrength: - contstr = "Punch Strngth"; + contstr = "Punch Strength"; break; case ADDSYNTH::control::punchDuration: contstr = "Punch Time"; break; case ADDSYNTH::control::punchStretch: - contstr = "Punch Strtch"; + contstr = "Punch Stretch"; break; case ADDSYNTH::control::punchVelocity: - contstr = "Punch Vel"; + contstr = "Punch Velocity"; break; default: @@ -1852,7 +1884,7 @@ contstr = "Unrecognised"; } - return ("Part " + to_string(npart + 1) + " Kit " + to_string(kititem + 1) + " AddSynth " + name + contstr); + return ("Part " + to_string(npart + 1) + " Kit " + to_string(kititem + 1) + " AddSynth " + contstr); } @@ -1871,69 +1903,42 @@ else nvoice = engine - PART::engine::addVoice1; - string name = ""; - switch (control & 0xf0) - { - case ADDVOICE::control::modulatorType: - name = " Modulator "; - break; - case ADDVOICE::control::detuneFrequency: - name = " Frequency "; - break; - case ADDVOICE::control::unisonFrequencySpread: - name = " Unison "; - break; - case ADDVOICE::control::bypassGlobalFilter: - name = " Filter "; - yesno = true; - break; - case ADDVOICE::control::modulatorAmplitude: - name = " Modulator Amp "; - break; - case ADDVOICE::control::modulatorDetuneFrequency: - name = " Modulator Freq "; - break; - case ADDVOICE::control::modulatorOscillatorPhase: - name = " Modulator Osc"; - break; - } - string contstr = ""; switch (control) { case ADDVOICE::control::volume: - contstr = " Volume"; + contstr = "Volume"; break; case ADDVOICE::control::velocitySense: - contstr = " Vel Sens"; + contstr = "Velocity Sense"; break; case ADDVOICE::control::panning: - contstr = " Panning"; + contstr = "Panning"; break; case ADDVOICE::control::enableRandomPan: - contstr = " Random Pan"; + contstr = "Random Pan"; yesno = true; break; case ADDVOICE::control::randomWidth: - contstr = " Random Width"; + contstr = "Random Width"; break; case ADDVOICE::control::invertPhase: - contstr = " Minus"; + contstr = "Minus"; yesno = true; break; case ADDVOICE::control::enableAmplitudeEnvelope: - contstr = " Amplitude Enable Env"; + contstr = "Amp Enable Env"; yesno = true; break; case ADDVOICE::control::enableAmplitudeLFO: - contstr = " Amplitude Enable LFO"; + contstr = "Amp Enable LFO"; yesno = true; break; case ADDVOICE::control::modulatorType: - contstr = "Type "; + contstr = "Modulator Type "; if (addValue) { showValue = false; @@ -1947,7 +1952,7 @@ if (value_int < 0) contstr = "Local"; else - contstr = "Source Voice " + to_string(value_int + 1); + contstr = "Modulator Source Voice " + to_string(value_int + 1); } break; @@ -1958,7 +1963,7 @@ if (value_int < 0) contstr = "Local"; else - contstr = " Source " + to_string(value_int + 1); + contstr = "Source " + to_string(value_int + 1); } break; @@ -1966,7 +1971,7 @@ contstr = "Detune"; break; case ADDVOICE::control::equalTemperVariation: - contstr = "Eq T"; + contstr = "Equal Temper"; break; case ADDVOICE::control::baseFrequencyAs440Hz: contstr = "440Hz"; @@ -1976,13 +1981,13 @@ contstr = "Octave"; break; case ADDVOICE::control::detuneType: - contstr = "Det type "; + contstr = "Detune Type "; showValue = false; if (addValue) contstr += stringCaps(detuneType [int(value)], 1); break; case ADDVOICE::control::coarseDetune: - contstr = "Coarse Det"; + contstr = "Coarse Detune"; break; case ADDVOICE::control::pitchBendAdjustment: contstr = "Bend Adj"; @@ -1991,147 +1996,149 @@ contstr = "Offset Hz"; break; case ADDVOICE::control::enableFrequencyEnvelope: - contstr = "Enable Env"; + contstr = "Freq Enable Env"; yesno = true; break; case ADDVOICE::control::enableFrequencyLFO: - contstr = "Enable LFO"; + contstr = "Freq Enable LFO"; yesno = true; break; case ADDVOICE::control::unisonFrequencySpread: - contstr = "Freq Spread"; + contstr = "Unison Freq Spread"; break; case ADDVOICE::control::unisonPhaseRandomise: - contstr = "Phase Rnd"; + contstr = "Unison Phase Rnd"; break; case ADDVOICE::control::unisonStereoSpread: - contstr = "Stereo"; + contstr = "Unison Stereo"; break; case ADDVOICE::control::unisonVibratoDepth: - contstr = "Vibrato"; + contstr = "Unison Vibrato"; break; case ADDVOICE::control::unisonVibratoSpeed: - contstr = "Vib Speed"; + contstr = "Unison Vib Speed"; break; case ADDVOICE::control::unisonSize: - contstr = "Size"; + contstr = "Unison Size"; break; case ADDVOICE::control::unisonPhaseInvert: showValue = false; - contstr = "Invert " + unisonPhase[value_int]; + contstr = "Unison Invert " + unisonPhase[value_int]; break; case ADDVOICE::control::enableUnison: - contstr = "Enable"; + contstr = "Unison Enable"; yesno = true; break; case ADDVOICE::control::bypassGlobalFilter: - contstr = "Bypass Global"; + contstr = "Filter Bypass Global"; yesno = true; break; case ADDVOICE::control::enableFilter: - contstr = "Enable"; + contstr = "Filter Enable"; yesno = true; break; case ADDVOICE::control::enableFilterEnvelope: - contstr = "Enable Env"; + contstr = "Filter Enable Env"; yesno = true; break; case ADDVOICE::control::enableFilterLFO: - contstr = "Enable LFO"; + contstr = "Filter Enable LFO"; yesno = true; break; case ADDVOICE::control::modulatorAmplitude: - contstr = "Volume"; + contstr = "Modulator Volume"; break; case ADDVOICE::control::modulatorVelocitySense: - contstr = "V Sense"; + contstr = "Modulator Vel Sense"; break; case ADDVOICE::control::modulatorHFdamping: - contstr = "F Damp"; + contstr = "Modulator HF Damping"; break; + case ADDVOICE::control::enableModulatorAmplitudeEnvelope: - contstr = "Enable Env"; + contstr = "Modulator Amp Enable Env"; yesno = true; break; case ADDVOICE::control::modulatorDetuneFrequency: + contstr = "Modulator Detune"; break; case ADDVOICE::control::modulatorFrequencyAs440Hz: - contstr = "440Hz"; + contstr = "Modulator 440Hz"; yesno = true; break; case ADDVOICE::control::modulatorDetuneFromBaseOsc: - contstr = "Follow voice"; + contstr = "Modulator Follow voice"; yesno = true; break; case ADDVOICE::control::modulatorOctave: - contstr = "Octave"; + contstr = "Modulator Octave"; break; case ADDVOICE::control::modulatorDetuneType: - contstr = "Det type "; + contstr = "Modulator Detune Type "; showValue = false; if (addValue) contstr += detuneType [int(value)]; break; case ADDVOICE::control::modulatorCoarseDetune: - contstr = "Coarse Det"; + contstr = "Modulator Coarse Detune"; break; case ADDVOICE::control::enableModulatorFrequencyEnvelope: // local, external - contstr = "Enable Env"; + contstr = "Modulator Freq Enable Env"; yesno = true; break; case ADDVOICE::control::modulatorOscillatorPhase: - contstr = " Phase"; + contstr = "Modulator Osc Phase"; break; case ADDVOICE::control::modulatorOscillatorSource: if (addValue) { showValue = false; if (value_int < 0) - contstr = " Internal"; + contstr = "Modulator Internal"; else - contstr = " from " + to_string(value_int + 1); + contstr = "Modulator Osc from " + to_string(value_int + 1); } break; case ADDVOICE::control::delay: - contstr = " Delay"; + contstr = "Delay"; break; case ADDVOICE::control::enableVoice: - contstr = " Enable"; + contstr = "Enable"; yesno = true; break; case ADDVOICE::control::enableResonance: - contstr = " Resonance Enable"; + contstr = "Resonance Enable"; yesno = true; break; case ADDVOICE::control::voiceOscillatorPhase: - contstr = " Osc Phase"; + contstr = "Osc Phase"; break; case ADDVOICE::control::voiceOscillatorSource: if (addValue) { showValue = false; if (value_int < 0) - contstr = " Internal"; + contstr = "Internal"; else - contstr = " from " + to_string(value_int + 1); + contstr = "from " + to_string(value_int + 1); } break; case ADDVOICE::control::soundType: - contstr = " Sound type"; + contstr = "Sound type"; break; default: showValue = false; - contstr = " Unrecognised"; + contstr = "Unrecognised"; } - return ("Part " + to_string(npart + 1) + " Kit " + to_string(kititem + 1) + " Add Voice " + to_string(nvoice + 1) + name + contstr); + return ("Part " + to_string(npart + 1) + " Kit " + to_string(kititem + 1) + " Add Voice " + to_string(nvoice + 1) + " " + contstr); } @@ -2157,24 +2164,6 @@ } string name = ""; - switch (control & 0x70) - { - case SUBSYNTH::control::volume: - name = " Amplitude "; - break; - case SUBSYNTH::control::bandwidth: - name = " Bandwidth "; - break; - case SUBSYNTH::control::detuneFrequency: - name = " Frequency "; - break; - case SUBSYNTH::control::overtoneParameter1: - name = " Overtones "; - break; - case SUBSYNTH::control::enableFilter: - name = " Filter "; - break; - } string contstr = ""; switch (control) @@ -2183,7 +2172,7 @@ contstr = "Volume"; break; case SUBSYNTH::control::velocitySense: - contstr = "Vel Sens"; + contstr = "Velocity Sense"; break; case SUBSYNTH::control::panning: contstr = "Panning"; @@ -2197,13 +2186,13 @@ break; case SUBSYNTH::control::bandwidth: - contstr = ""; + contstr = "Bandwidth"; // it's the actual bandwidth control break; case SUBSYNTH::control::bandwidthScale: - contstr = "Band Scale"; + contstr = "Bandwidth Band Scale"; break; case SUBSYNTH::control::enableBandwidthEnvelope: - contstr = "Env Enab"; + contstr = "Bandwidth Env Enab"; yesno = true; break; @@ -2211,7 +2200,7 @@ contstr = "Detune"; break; case SUBSYNTH::control::equalTemperVariation: - contstr = "Eq T"; + contstr = "Equal Temper"; break; case SUBSYNTH::control::baseFrequencyAs440Hz: contstr = "440Hz"; @@ -2221,13 +2210,13 @@ contstr = "Octave"; break; case SUBSYNTH::control::detuneType: - contstr = "Det type "; + contstr = "Detune Type "; showValue = false; if (addValue) contstr += detuneType [value_int]; break; case SUBSYNTH::control::coarseDetune: - contstr = "Coarse Det"; + contstr = "Coarse Detune"; break; case SUBSYNTH::control::pitchBendAdjustment: contstr = "Bend Adj"; @@ -2236,26 +2225,26 @@ contstr = "Offset Hz"; break; case SUBSYNTH::control::enableFrequencyEnvelope: - contstr = "Env Enab"; + contstr = "Frequency Env Enab"; yesno = true; break; case SUBSYNTH::control::overtoneParameter1: - contstr = "Par 1"; + contstr = "Overtones Par 1"; break; case SUBSYNTH::control::overtoneParameter2: - contstr = "Par 2"; + contstr = "Overtones Par 2"; break; case SUBSYNTH::control::overtoneForceHarmonics: - contstr = "Force H"; + contstr = "Overtones Force H"; break; case SUBSYNTH::control::overtonePosition: - contstr = "Position " + subPadPosition[value_int]; + contstr = "Overtones Position " + subPadPosition[value_int]; showValue = false; break; case SUBSYNTH::control::enableFilter: - contstr = "Enable"; + contstr = "Filter Enable"; yesno = true; break; @@ -2298,7 +2287,7 @@ contstr = "Unrecognised"; } - return ("Part " + to_string(npart + 1) + " Kit " + to_string(kititem + 1) + " SubSynth " + name + contstr); + return ("Part " + to_string(npart + 1) + " Kit " + to_string(kititem + 1) + " SubSynth " + contstr); } @@ -2312,28 +2301,6 @@ bool write = (type & TOPLEVEL::type::Write) > 0; int value_int = int(value); - string name = ""; - switch (control & 0x70) - { - case PADSYNTH::control::volume: - name = " Amplitude "; - break; - case PADSYNTH::control::bandwidth: - name = " Bandwidth "; - break; - case PADSYNTH::control::detuneFrequency: - name = " Frequency "; - break; - case PADSYNTH::control::overtoneParameter1: - name = " Overtones "; - break; - case PADSYNTH::control::baseWidth: - name = " Harmonic Base "; - break; - case PADSYNTH::control::harmonicBase: - name = " Harmonic Samples "; - break; - } string contstr = ""; switch (control) @@ -2342,7 +2309,7 @@ contstr = "Volume"; break; case PADSYNTH::control::velocitySense: - contstr = "Vel Sens"; + contstr = "Velocity Sense"; break; case PADSYNTH::control::panning: contstr = "Panning"; @@ -2355,21 +2322,11 @@ contstr = "Random Width"; break; - case PADSYNTH::control::bandwidth: - contstr = "Bandwidth"; - break; - case PADSYNTH::control::bandwidthScale: - contstr = "Band Scale"; - break; - case PADSYNTH::control::spectrumMode: - contstr = "Spect Mode"; - break; - case PADSYNTH::control::detuneFrequency: contstr = "Detune"; break; case PADSYNTH::control::equalTemperVariation: - contstr = "Eq T"; + contstr = "Equal Temper"; break; case PADSYNTH::control::baseFrequencyAs440Hz: contstr = "440Hz"; @@ -2379,36 +2336,91 @@ contstr = "Octave"; break; case PADSYNTH::control::detuneType: - contstr = "Det type "; + contstr = "Detune Type "; showValue = false; if (addValue) contstr += detuneType [int(value)]; break; case PADSYNTH::control::coarseDetune: - contstr = "Coarse Det"; + contstr = "Coarse Detune"; break; case PADSYNTH::control::pitchBendAdjustment: - contstr = "Bend Adj"; + contstr = "Bend Adjust"; break; case PADSYNTH::control::pitchBendOffset: contstr = "Offset Hz"; break; + case PADSYNTH::control::stereo: + contstr = "Stereo"; + yesno = true; + break; + case PADSYNTH::control::dePop: + contstr = "De Pop"; + break; + case PADSYNTH::control::punchStrength: + contstr = "Punch Strength"; + break; + case PADSYNTH::control::punchDuration: + contstr = "Punch Time"; + break; + case PADSYNTH::control::punchStretch: + contstr = "Punch Stretch"; + break; + case PADSYNTH::control::punchVelocity: + contstr = "Punch Velocity"; + break; + case PADSYNTH::control::applyChanges: + showValue = false; + contstr = "Changes Applied "; + if (addValue) + { + if (value_int != 0) + contstr += "Yes"; + else + contstr += "No"; + } + break; + } + if (!contstr.empty()) + return ("Part " + to_string(npart + 1) + " Kit " + to_string(kititem + 1) + " PadSynth " + contstr); + + switch (control) + { case PADSYNTH::control::overtoneParameter1: - contstr = "Overt Par 1"; + contstr = "Overtones Par 1"; break; case PADSYNTH::control::overtoneParameter2: - contstr = "Overt Par 2"; + contstr = "Overtones Par 2"; break; case PADSYNTH::control::overtoneForceHarmonics: - contstr = "Force H"; + contstr = "Overtones Force H"; break; case PADSYNTH::control::overtonePosition: contstr = "Position " + subPadPosition[value_int]; showValue = false; break; + case PADSYNTH::control::bandwidth: + contstr = "Bandwidth"; + break; + case PADSYNTH::control::bandwidthScale: + contstr = "Bandwidth Scale"; + break; + case PADSYNTH::control::spectrumMode: + contstr = "Spectrum Mode"; + break; + } + if (!contstr.empty()) + { + if (write) + contstr += " - Need to Apply"; + return ("Part " + to_string(npart + 1) + " Kit " + to_string(kititem + 1) + " PadSynth " + contstr); + } + + switch (control) + { case PADSYNTH::control::baseWidth: contstr = "Width"; break; @@ -2442,11 +2454,21 @@ case PADSYNTH::control::amplitudeMode: contstr = "Amp Mode"; break; - case PADSYNTH::control::autoscale: + case PADSYNTH::control::autoscale: // contstr = "Autoscale"; yesno = true; break; + } + if (!contstr.empty()) + { + contstr = "Harmonic Base " + contstr; + if (write) + contstr += " - Need to Apply"; + return ("Part " + to_string(npart + 1) + " Kit " + to_string(kititem + 1) + " PadSynth " + contstr); + } + switch (control) + { case PADSYNTH::control::harmonicBase: contstr = "Base"; break; @@ -2459,42 +2481,15 @@ case PADSYNTH::control::sampleSize: break; - case PADSYNTH::control::applyChanges: - showValue = false; - contstr = "Changes Applied"; - break; - - case PADSYNTH::control::stereo: - contstr = "Stereo"; - yesno = true; - break; - - case PADSYNTH::control::dePop: - contstr = "De Pop"; - break; - case PADSYNTH::control::punchStrength: - contstr = "Punch Strngth"; - break; - case PADSYNTH::control::punchDuration: - contstr = "Punch Time"; - break; - case PADSYNTH::control::punchStretch: - contstr = "Punch Strtch"; - break; - case PADSYNTH::control::punchVelocity: - contstr = "Punch Vel"; - break; - default: showValue = false; contstr = "Unrecognised"; } - - string isPad = ""; - - if (write && ((control >= PADSYNTH::control::bandwidth && control <= PADSYNTH::control::spectrumMode) || (control >= PADSYNTH::control::overtoneParameter1 && control <= PADSYNTH::control::sampleSize))) - isPad += " - Need to Apply"; - return ("Part " + to_string(npart + 1) + " Kit " + to_string(kititem + 1) + " PadSynth " + name + contstr + isPad); + if (contstr != "Unrecognised") + contstr = "Harmonic Samples " + contstr; + if (write && contstr != "Unrecognised") + contstr += " - Need to Apply"; + return ("Part " + to_string(npart + 1) + " Kit " + to_string(kititem + 1) + " PadSynth " + contstr); } @@ -2514,7 +2509,7 @@ string eng_name; if (engine == PART::engine::padSynth) { - eng_name = " Padsysnth"; + eng_name = " PadSynth"; if (write) isPad = " - Need to Apply"; } @@ -2539,76 +2534,88 @@ return ("Part " + to_string(npart + 1) + " Kit " + to_string(kititem + 1) + eng_name + " Harmonic " + to_string((int)control + 1) + " Phase" + isPad); } - string name; - if (control >= OSCILLATOR::control::clearHarmonics || control <= OSCILLATOR::control::harmonicRandomnessType) - name = " Oscillator"; - else if (control >= OSCILLATOR::control::harmonicShift) - name = " Harm Mods"; - else if (control >= OSCILLATOR::control::autoClear) - name = " Base Mods"; - else - name = " Base Funct"; - string contstr; switch (control) { case OSCILLATOR::control::phaseRandomness: - contstr = " Random"; + contstr = "Random"; break; case OSCILLATOR::control::magType: - contstr = " Mag Type"; + contstr = "Mag Type"; break; case OSCILLATOR::control::harmonicAmplitudeRandomness: - contstr = " Harm Rnd"; + contstr = "Harm Rnd"; break; case OSCILLATOR::control::harmonicRandomnessType: - contstr = " Harm Rnd Type"; + contstr = "Harm Rnd Type"; + break; + + case OSCILLATOR::control::clearHarmonics: + contstr = "Clear Harmonics"; break; + case OSCILLATOR::control::convertToSine: + contstr = "Conv To Sine"; + break; + } + if (!contstr.empty()) + { + return ("Part " + to_string(npart + 1) + " Kit " + to_string(kititem + 1) + eng_name + " Oscillator " + contstr + isPad); + } + switch(control) + { case OSCILLATOR::control::baseFunctionParameter: - contstr = " Par"; + contstr = "Par"; break; case OSCILLATOR::control::baseFunctionType: - contstr = " Type "; + contstr = "Type "; showValue = false; if (addValue) contstr += stringCaps(waveformlist[int(value) * 2], 1); break; case OSCILLATOR::control::baseModulationParameter1: - contstr = " Mod Par 1"; + contstr = "Mod Par 1"; break; case OSCILLATOR::control::baseModulationParameter2: - contstr = " Mod Par 2"; + contstr = "Mod Par 2"; break; case OSCILLATOR::control::baseModulationParameter3: - contstr = " Mod Par 3"; + contstr = "Mod Par 3"; break; case OSCILLATOR::control::baseModulationType: - contstr = " Mod Type"; + contstr = "Mod Type"; break; case OSCILLATOR::control::autoClear: // this is local to the GUI break; + } + if (!contstr.empty()) + { + return ("Part " + to_string(npart + 1) + " Kit " + to_string(kititem + 1) + eng_name + " Base Func " + contstr + isPad); + } + + switch(control) + { case OSCILLATOR::control::useAsBaseFunction: - contstr = " Osc As Base"; + contstr = "Osc As Base"; break; case OSCILLATOR::control::waveshapeParameter: - contstr = " Waveshape Par"; + contstr = "Waveshape Par"; break; case OSCILLATOR::control::waveshapeType: - contstr = " Waveshape Type"; + contstr = "Waveshape Type"; break; case OSCILLATOR::control::filterParameter1: - contstr = " Osc Filt Par 1"; + contstr = "Osc Filt Par 1"; break; case OSCILLATOR::control::filterParameter2: - contstr = " Osc Filt Par 2"; + contstr = "Osc Filt Par 2"; break; case OSCILLATOR::control::filterBeforeWaveshape: - contstr = " Osc Filt B4 Waveshape"; + contstr = "Osc Filt B4 Waveshape"; break; case OSCILLATOR::control::filterType: - contstr = " Osc Filt Type "; + contstr = "Osc Filt Type "; if (addValue) { showValue = false; @@ -2616,51 +2623,51 @@ } break; case OSCILLATOR::control::modulationParameter1: - contstr = " Osc Mod Par 1"; + contstr = "Osc Mod Par 1"; break; case OSCILLATOR::control::modulationParameter2: - contstr = " Osc Mod Par 2"; + contstr = "Osc Mod Par 2"; break; case OSCILLATOR::control::modulationParameter3: - contstr = " Osc Mod Par 3"; + contstr = "Osc Mod Par 3"; break; case OSCILLATOR::control::modulationType: - contstr = " Osc Mod Type"; + contstr = "Osc Mod Type"; break; case OSCILLATOR::control::spectrumAdjustParameter: - contstr = " Osc Spect Par"; + contstr = "Osc Spect Par"; break; case OSCILLATOR::control::spectrumAdjustType: - contstr = " Osc Spect Type"; + contstr = "Osc Spect Type"; break; + } + if (!contstr.empty()) + { + return ("Part " + to_string(npart + 1) + " Kit " + to_string(kititem + 1) + eng_name + " Base Mods " + contstr + isPad); + } + switch(control) + { case OSCILLATOR::control::harmonicShift: - contstr = " Shift"; + contstr = "Shift"; break; case OSCILLATOR::control::clearHarmonicShift: - contstr = " Reset"; + contstr = "Reset"; break; case OSCILLATOR::control::shiftBeforeWaveshapeAndFilter: - contstr = " B4 Waveshape & Filt"; + contstr = "B4 Waveshape & Filt"; break; case OSCILLATOR::control::adaptiveHarmonicsParameter: - contstr = " Adapt Param"; + contstr = "Adapt Param"; break; case OSCILLATOR::control::adaptiveHarmonicsBase: - contstr = " Adapt Base Freq"; + contstr = "Adapt Base Freq"; break; case OSCILLATOR::control::adaptiveHarmonicsPower: - contstr = " Adapt Power"; + contstr = "Adapt Power"; break; case OSCILLATOR::control::adaptiveHarmonicsType: - contstr = " Adapt Type"; - break; - - case OSCILLATOR::control::clearHarmonics: - contstr = " Clear Harmonics"; - break; - case OSCILLATOR::control::convertToSine: - contstr = " Conv To Sine"; + contstr = "Adapt Type"; break; default: @@ -2668,7 +2675,7 @@ contstr = "Unrecognised"; } - return ("Part " + to_string(npart + 1) + " Kit " + to_string(kititem + 1) + eng_name + name + contstr + isPad); + return ("Part " + to_string(npart + 1) + " Kit " + to_string(kititem + 1) + eng_name + " Harm Mods " + contstr + isPad); } @@ -2702,7 +2709,7 @@ return ("Part " + to_string(npart + 1) + " Kit " + to_string(kititem + 1) + name + " Resonance Point " + to_string(parameter + 1) + isPad); } - if (write == true && engine == PART::engine::padSynth && control != 104) + if (write == true && engine == PART::engine::padSynth && control != PADSYNTH::control::applyChanges) isPad = " - Need to Apply"; string contstr; switch (control) @@ -2825,7 +2832,7 @@ contstr = "Start"; break; case LFOINSERT::control::amplitudeRandomness: - contstr = "AmpRand"; + contstr = "Amp Rand"; break; case LFOINSERT::control::type: { @@ -2844,7 +2851,7 @@ yesno = true; break; case LFOINSERT::control::frequencyRandomness: - contstr = "FreqRand"; + contstr = "Freq Rand"; break; case LFOINSERT::control::stretch: contstr = "Stretch"; @@ -2869,7 +2876,7 @@ int nseqpos = getData->data.parameter; int nformant = getData->data.parameter; - int nvowel = getData->data.miscmsg; + int nvowel = getData->data.offset; string name; @@ -2885,22 +2892,22 @@ switch (control) { case FILTERINSERT::control::centerFrequency: - contstr = "C_Freq"; + contstr = "Cent Freq"; break; case FILTERINSERT::control::Q: contstr = "Q"; break; case FILTERINSERT::control::frequencyTracking: - contstr = "FreqTrk"; + contstr = "Freq Track"; break; case FILTERINSERT::control::velocitySensitivity: - contstr = "VsensA"; + contstr = "Velocity Sense"; break; case FILTERINSERT::control::velocityCurve: - contstr = "Vsens"; + contstr = "Velocity Sense Curve"; break; case FILTERINSERT::control::gain: - contstr = "gain"; + contstr = "Gain"; break; case FILTERINSERT::control::stages: showValue = false; @@ -2951,14 +2958,14 @@ break; } case FILTERINSERT::control::frequencyTrackingRange: - contstr = "Fre Trk Offs"; + contstr = "Freq Track Offs"; yesno = true; break; case FILTERINSERT::control::formantSlowness: - contstr = "Form Fr Sl"; + contstr = "Form Morph"; break; case FILTERINSERT::control::formantClearness: - contstr = "Form Vw Cl"; + contstr = "Form Lucidity"; break; case FILTERINSERT::control::formantFrequency: contstr = "Form Freq"; @@ -3062,7 +3069,7 @@ env = " Filt"; break; case TOPLEVEL::insertType::bandwidth: - env = " B.Width"; + env = " Band"; break; } @@ -3090,25 +3097,25 @@ switch (control) { case ENVELOPEINSERT::control::attackLevel: - contstr = "A val"; + contstr = "Attack Level"; break; case ENVELOPEINSERT::control::attackTime: - contstr = "A dt"; + contstr = "Attack Time"; break; case ENVELOPEINSERT::control::decayLevel: - contstr = "D val"; + contstr = "Decay Level"; break; case ENVELOPEINSERT::control::decayTime: - contstr = "D dt"; + contstr = "Decay Time"; break; case ENVELOPEINSERT::control::sustainLevel: - contstr = "S val"; - break; - case ENVELOPEINSERT::control::releaseTime: - contstr = "R dt"; + contstr = "Sustain Level"; break; case ENVELOPEINSERT::control::releaseLevel: - contstr = "R val"; + contstr = "Release Level"; + break; + case ENVELOPEINSERT::control::releaseTime: + contstr = "Release Time"; break; case ENVELOPEINSERT::control::stretch: contstr = "Stretch"; @@ -3176,7 +3183,26 @@ else name = "Part " + to_string(npart + 1); name += " Effect " + to_string(effnum + 1); - return (name + " DynFilter ~ Filter Internal Control " + to_string(control)); + name += " DynFilter ~ Filter "; + switch (control) + { + case 0: + name += "C Freq"; + break; + case 1: + name += "Q"; + break; + case 5: + name += "Gain"; + break; + case 2: + name += "FreqTrk"; + break; + default: + name += "unrecognised"; + break; + } + return name; } name += " Effect " + to_string(effnum + 1); @@ -3226,6 +3252,7 @@ } if (control == EFFECT::sysIns::effectEnable) { + contstr += " Enable"; if (addValue) { showValue = false; diff -Nru yoshimi-2.1.1.1~dfsg0/src/Interface/InterChange.cpp yoshimi-2.1.2.2~dfsg0/src/Interface/InterChange.cpp --- yoshimi-2.1.1.1~dfsg0/src/Interface/InterChange.cpp 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/Interface/InterChange.cpp 2021-12-03 20:12:12.000000000 +0000 @@ -92,9 +92,13 @@ syncWrite(false), lowPrioWrite(false), tick(0), + sortResultsThreadHandle(0), swapRoot1(UNUSED), swapBank1(UNUSED), - swapInstrument1(UNUSED) + swapInstrument1(UNUSED), + searchInst(0), + searchBank(0), + searchRoot(0) { ; } @@ -419,21 +423,24 @@ #endif bool ok = returnsBuffer.write(getData->bytes); #ifdef GUI_FLTK - if (synth->getRuntime().showGui && switchNum == TOPLEVEL::section::scales && control == SCALES::control::importScl) - { // loading a tuning includes a name and comment! - getData->data.control = SCALES::control::name; - getData->data.miscmsg = textMsgBuffer.push(synth->microtonal.Pname); - returnsBuffer.write(getData->bytes); - getData->data.control = SCALES::control::comment; - getData->data.miscmsg = textMsgBuffer.push(synth->microtonal.Pcomment); - ok &= returnsBuffer.write(getData->bytes); + if (synth->getRuntime().showGui) + { + if (switchNum == TOPLEVEL::section::scales && control == SCALES::control::importScl) + { // loading a tuning includes a name and comment! + getData->data.control = SCALES::control::name; + getData->data.miscmsg = textMsgBuffer.push(synth->microtonal.Pname); + returnsBuffer.write(getData->bytes); + getData->data.control = SCALES::control::comment; + getData->data.miscmsg = textMsgBuffer.push(synth->microtonal.Pcomment); + ok &= returnsBuffer.write(getData->bytes); + } + if (switchNum == TOPLEVEL::section::main && control == MAIN::control::loadNamedState) + synth->midilearn.updateGui(); + /* + * This needs improving. We should only set it + * when the state file contains a learn list. + */ } - if (synth->getRuntime().showGui && switchNum == TOPLEVEL::section::main && control == MAIN::control::loadNamedState) - synth->midilearn.updateGui(); - /* - * This needs improving. We should only set it - * when the state file contains a learn list. - */ #endif if (!ok) synth->getRuntime().Log("Unable to write to returnsBuffer buffer"); @@ -443,7 +450,8 @@ { synth->fileCompatible = true; #ifdef GUI_FLTK - if ((getData->data.source & TOPLEVEL::action::noAction) == TOPLEVEL::action::fromGUI) + if (synth->getRuntime().showGui && + (getData->data.source & TOPLEVEL::action::noAction) == TOPLEVEL::action::fromGUI) { getData->data.control = TOPLEVEL::control::textMessage; getData->data.miscmsg = textMsgBuffer.push("File from ZynAddSubFX 3.0 or later has parameter types changed incompatibly with earlier versions, and with Yoshimi. It may not perform correctly."); @@ -511,7 +519,7 @@ text += textMsgBuffer.fetch(msgID & NO_MSG); newMsg = true; getData->data.source = TOPLEVEL::action::toAll; - // everyone will want to knopw about these! + // everyone will want to know about these! guiTo = true; return value; } @@ -1757,8 +1765,8 @@ } #endif #ifdef GUI_FLTK - - if (fromGUI.read(getData.bytes)) + if (synth->getRuntime().showGui + && fromGUI.read(getData.bytes)) { more = true; if (getData.data.part != TOPLEVEL::section::midiLearn) // Not special midi-learn message @@ -1777,7 +1785,8 @@ returns(&getData); } #ifdef GUI_FLTK - else if (getData.data.control == MIDILEARN::control::reportActivity) + else if (synth->getRuntime().showGui + && getData.data.control == MIDILEARN::control::reportActivity) toGUI.write(getData.bytes); #endif } @@ -1799,30 +1808,33 @@ if (effpar > 0xffff) { #ifdef GUI_FLTK - CommandBlock effData; - memset(&effData.bytes, 255, sizeof(effData)); - unsigned char npart = effpar & 0xff; - unsigned char effnum = (effpar >> 8) & 0xff; - unsigned char efftype; - if (npart < NUM_MIDI_PARTS) - { - efftype = synth->part[npart]->partefx[effnum]->geteffect(); - effData.data.control = PART::control::effectType; - } - else + if (synth->getRuntime().showGui) { - effData.data.control = EFFECT::sysIns::effectType; - if (npart == TOPLEVEL::section::systemEffects) - efftype = synth->sysefx[effnum]->geteffect(); + CommandBlock effData; + memset(&effData.bytes, 255, sizeof(effData)); + unsigned char npart = effpar & 0xff; + unsigned char effnum = (effpar >> 8) & 0xff; + unsigned char efftype; + if (npart < NUM_MIDI_PARTS) + { + efftype = synth->part[npart]->partefx[effnum]->geteffect(); + effData.data.control = PART::control::effectType; + } else - efftype = synth->insefx[effnum]->geteffect(); + { + effData.data.control = EFFECT::sysIns::effectType; + if (npart == TOPLEVEL::section::systemEffects) + efftype = synth->sysefx[effnum]->geteffect(); + else + efftype = synth->insefx[effnum]->geteffect(); + } + effData.data.source = TOPLEVEL::action::fromGUI | TOPLEVEL::action::forceUpdate; + effData.data.type = TOPLEVEL::type::Write; + effData.data.value = efftype; + effData.data.part = npart; + effData.data.engine = effnum; + toGUI.write(effData.bytes); } - effData.data.source = TOPLEVEL::action::fromGUI | TOPLEVEL::action::forceUpdate; - effData.data.type = TOPLEVEL::type::Write; - effData.data.value = efftype; - effData.data.part = npart; - effData.data.engine = effnum; - toGUI.write(effData.bytes); #endif synth->getRuntime().effectChange = UNUSED; } // end of temporary fix @@ -1873,13 +1885,16 @@ if (getData->data.source < TOPLEVEL::action::lowPrio) { // currently only used by gui. this may change! #ifdef GUI_FLTK - unsigned char type = getData->data.type; // back from synth - int tmp = (getData->data.source & TOPLEVEL::action::noAction); - if (getData->data.source & TOPLEVEL::action::forceUpdate) - tmp = TOPLEVEL::action::toAll; + if (synth->getRuntime().showGui) + { + unsigned char type = getData->data.type; // back from synth + int tmp = (getData->data.source & TOPLEVEL::action::noAction); + if (getData->data.source & TOPLEVEL::action::forceUpdate) + tmp = TOPLEVEL::action::toAll; - if ((type & TOPLEVEL::type::Write) && tmp != TOPLEVEL::action::fromGUI) - toGUI.write(getData->bytes); + if ((type & TOPLEVEL::type::Write) && tmp != TOPLEVEL::action::fromGUI) + toGUI.write(getData->bytes); + } #endif } if (!decodeLoopback.write(getData->bytes)) @@ -2024,21 +2039,18 @@ getData->data.value = part->busy; return false; } - if (kititem != UNUSED && kititem != 0 && engine != UNUSED && control != 8 && part->kit[kititem].Penabled == false) - return false; // attempt to access not enabled kititem - if (kititem == UNUSED || insert == TOPLEVEL::insert::kitGroup) { - if (control != PART::control::kitMode && kititem != UNUSED && part->Pkitmode == 0) - return false; - commandPart(getData); return true; } - if (kititem > 0 && kititem != UNUSED && part->Pkitmode == 0) + if (kititem > 0 && kititem != UNUSED) { - return false; + if (part->Pkitmode == 0) + return false; + else if (!part->kit[kititem].Penabled) + return false; } if (engine == PART::engine::addSynth) @@ -2201,6 +2213,7 @@ { Part *part = synth->part[getData->data.part]; int kititem = getData->data.kit; + bool needApply = false; switch(getData->data.insert) { case UNUSED: @@ -2225,24 +2238,34 @@ case TOPLEVEL::insert::oscillatorGroup: commandOscillator(getData, part->kit[kititem].padpars->POscil); part->kit[kititem].padpars->presetsUpdated(); + needApply = true; break; case TOPLEVEL::insert::harmonicAmplitude: commandOscillator(getData, part->kit[kititem].padpars->POscil); part->kit[kititem].padpars->presetsUpdated(); + needApply = true; break; case TOPLEVEL::insert::harmonicPhaseBandwidth: commandOscillator(getData, part->kit[kititem].padpars->POscil); part->kit[kititem].padpars->presetsUpdated(); + needApply = true; break; case TOPLEVEL::insert::resonanceGroup: commandResonance(getData, part->kit[kititem].padpars->resonance); part->kit[kititem].padpars->presetsUpdated(); + needApply = true; break; case TOPLEVEL::insert::resonanceGraphInsert: commandResonance(getData, part->kit[kititem].padpars->resonance); part->kit[kititem].padpars->presetsUpdated(); + needApply = true; break; } + if (needApply) + { + part->kit[kititem].padpars->Papplied = 0; + getData->data.offset = 0; + } return true; } @@ -2812,6 +2835,13 @@ else value = firstSynth->getRuntime().showCLIcontext; break; + + case CONFIG::control::readAudio: + value = int(synth->getRuntime().audioEngine); + break; + case CONFIG::control::readMIDI: + value = int(synth->getRuntime().midiEngine); + break; // jack case CONFIG::control::jackMidiSource: // done elsewhere break; @@ -3357,6 +3387,22 @@ Part *part; part = synth->part[npart]; + if (part->Pkitmode == 0) + { + kitType = false; + if (control != PART::control::kitMode && kititem != UNUSED) + { + getData->data.source = TOPLEVEL::action::noAction; + synth->getRuntime().Log("Not in kit mode"); + } + } + else if (control != PART::control::enableKitLine && !part->kit[kititem].Penabled && kititem < UNUSED) + { + getData->data.source = TOPLEVEL::action::noAction; + synth->getRuntime().Log("Kit item " + to_string(kititem + 1) + " not enabled"); + return; + } + unsigned char effNum = part->Peffnum; if (!kitType) kititem = 0; @@ -4874,6 +4920,8 @@ case SUBSYNTH::control::stereo: if (write) pars->Pstereo = value_bool; + else + value = pars->Pstereo; break; } @@ -5153,20 +5201,26 @@ break; case PADSYNTH::control::applyChanges: - if (write) - { - synth->partonoffWrite(npart, -1); - getData->data.source = TOPLEVEL::action::lowPrio; + if (write && value >= 0.5f) + { // this control is 'expensive' only used if necessary + if (!pars->Papplied) + { + synth->partonoffWrite(npart, -1); + getData->data.source = TOPLEVEL::action::lowPrio; + getData->data.value = 1; + } + else + getData->data.source = TOPLEVEL::action::noAction; } + else + value = pars->Papplied; break; case PADSYNTH::control::stereo: if (write) pars->PStereo = value_bool; else - { - ; - } + value = pars->PStereo; break; case PADSYNTH::control::dePop: @@ -5201,6 +5255,11 @@ break; } + if (control >= PADSYNTH::control::bandwidth && control < PADSYNTH::control::applyChanges) + { + pars->Papplied = 0; + getData->data.offset = 0; + } if (!write) getData->data.value = value; } diff -Nru yoshimi-2.1.1.1~dfsg0/src/Interface/MidiLearn.cpp yoshimi-2.1.2.2~dfsg0/src/Interface/MidiLearn.cpp --- yoshimi-2.1.1.1~dfsg0/src/Interface/MidiLearn.cpp 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/Interface/MidiLearn.cpp 2021-12-03 20:12:12.000000000 +0000 @@ -20,6 +20,9 @@ */ +#define NEWML YES +//#define NEWML_REPORT YES + #include "Interface/MidiLearn.h" #include "Interface/InterChange.h" #include "Interface/RingBuffer.h" @@ -43,6 +46,8 @@ using func::asString; using func::asHexString; +using std::cout; +using std::endl; using std::to_string; using std::string; using std::vector; @@ -154,19 +159,14 @@ value = minOut +((maxOut - minOut) * value / 127.0f); else if (minOut != 0) // it's just a shift value += minOut; - CommandBlock putData; + + memcpy(putData.bytes, foundEntry.frame.bytes, sizeof(CommandBlock)); putData.data.value = value; - putData.data.type = TOPLEVEL::type::Write | (foundEntry.data.type & TOPLEVEL::type::Integer); + putData.data.type = TOPLEVEL::type::Write | (foundEntry.frame.data.type & TOPLEVEL::type::Integer); // write command from midi with original integer / float type putData.data.source = TOPLEVEL::action::toAll; - putData.data.control = foundEntry.data.control; - putData.data.part = foundEntry.data.part; - putData.data.kit = foundEntry.data.kit; - putData.data.engine = foundEntry.data.engine; - putData.data.insert = foundEntry.data.insert; - putData.data.parameter = foundEntry.data.parameter; - putData.data.miscmsg = foundEntry.data.miscmsg; + if (writeMidi(&putData, in_place)) { if (firstLine && !in_place) // not in_place @@ -259,7 +259,7 @@ block->status = it->status; block->min_out = it->min_out; block->max_out = it->max_out; - block->data = it->data; + block->frame.data = it->frame.data; if ((it->status & 5) == 1) // blocked, not muted return scan::listBlocked; // don't allow any more of this CC and channel; return newpos; @@ -397,6 +397,7 @@ unsigned char engine = getData->data.engine; unsigned char insert = getData->data.insert; unsigned char parameter = getData->data.parameter; + unsigned char offset = getData->data.offset; unsigned char par2 = getData->data.miscmsg; if (control == MIDILEARN::control::sendRefreshRequest) @@ -610,6 +611,7 @@ putData.data.engine = engine; putData.data.insert = insert; putData.data.parameter = parameter; + putData.data.offset = offset; it->CC = kit; it->chan = engine; it->min_in = insert; @@ -628,7 +630,7 @@ entry.status = type; entry.min_out = it->min_out; entry.max_out = it->max_out; - entry.data = it->data; + entry.frame.data = it->frame.data; unsigned int CC = entry.CC; int chan = entry.chan; @@ -666,18 +668,10 @@ string MidiLearn::findName(list::iterator it) { CommandBlock putData; + memcpy(putData.bytes, it->frame.bytes, sizeof(CommandBlock)); putData.data.value = 0; putData.data.source = 0; - - putData.data.type = it->data.type; - putData.data.control = it->data.control; - putData.data.part = it->data.part; - putData.data.kit = it->data.kit; - putData.data.engine = it->data.engine; - putData.data.insert = it->data.insert; - putData.data.parameter = it->data.parameter; - putData.data.offset = UNUSED; - string name = resolveAll(synth, &putData, false);; + string name = resolveAll(synth, &putData, false); return name; } @@ -718,23 +712,14 @@ //std::cout << "SEND Control " << (int) learnTransferBlock.data.control << " Part " << (int) learnTransferBlock.data.part << " Kit " << (int) learnTransferBlock.data.kit << " Engine " << (int) learnTransferBlock.data.engine << " Insert " << (int) learnTransferBlock.data.insert << std::std::endl; - unsigned char type = learnTransferBlock.data.type & 0x80; - learnTransferBlock.data.type = (type &0xf8) | 5; // min + unsigned char type = learnTransferBlock.data.type & TOPLEVEL::type::Integer; + learnTransferBlock.data.type = (type | TOPLEVEL::type::Limits | TOPLEVEL::type::Minimum); entry.min_out = synth->interchange.readAllData(&learnTransferBlock); - learnTransferBlock.data.type = (type &0xf8) | 6; // max + learnTransferBlock.data.type = (type | TOPLEVEL::type::Limits | TOPLEVEL::type::Maximum); entry.max_out = synth->interchange.readAllData(&learnTransferBlock); - // Should be a better way to do this! - - entry.data.type = type; - entry.data.control = learnTransferBlock.data.control; - entry.data.part = learnTransferBlock.data.part; - entry.data.kit = learnTransferBlock.data.kit; - entry.data.engine = learnTransferBlock.data.engine; - entry.data.insert = learnTransferBlock.data.insert; - entry.data.parameter = learnTransferBlock.data.parameter; - entry.data.miscmsg = learnTransferBlock.data.miscmsg; - + memcpy(entry.frame.bytes, learnTransferBlock.bytes, sizeof(CommandBlock)); + entry.frame.data.type = type; list::iterator it; it = midi_list.begin(); int lineNo = 0; @@ -782,14 +767,14 @@ ok = synth->interchange.toGUI.write(putData->bytes); ++tries; if (!ok) - usleep(1); + usleep(100); // we can afford a short delay for buffer to clear } while (!ok && tries < 3); if (!ok) synth->getRuntime().Log("toGui buffer full!", _SYS_::LogNotSerious | _SYS_::LogError); -#endif +#endif // GUI_FLTK } @@ -890,7 +875,6 @@ } string file = setExtension(name, EXTEN::mlearn); -// make_legit_filename(file); synth->getRuntime().xmlType = TOPLEVEL::XML::MLearn; XMLwrapper *xml = new XMLwrapper(synth, true); if (!xml) @@ -942,14 +926,14 @@ xml->addpar("Convert_Min", it->min_out); xml->addpar("Convert_Max", it->max_out); xml->beginbranch("COMMAND"); - xml->addpar("Type", it->data.type); - xml->addpar("Control", it->data.control); - xml->addpar("Part", it->data.part); - xml->addpar("Kit_Item", it->data.kit); - xml->addpar("Engine", it->data.engine); - xml->addpar("Insert", it->data.insert); - xml->addpar("Parameter", it->data.parameter); - xml->addpar("Secondary_Parameter", it->data.miscmsg); + xml->addpar("Type", it->frame.data.type); + xml->addpar("Control", it->frame.data.control); + xml->addpar("Part", it->frame.data.part); + xml->addpar("Kit_Item", it->frame.data.kit); + xml->addpar("Engine", it->frame.data.engine); + xml->addpar("Insert", it->frame.data.insert); + xml->addpar("Parameter", it->frame.data.parameter); + xml->addpar("Secondary_Parameter", it->frame.data.offset); xml->addparstr("Command_Name",findName(it).c_str()); xml->endbranch(); xml->endbranch(); @@ -992,6 +976,7 @@ bool MidiLearn::extractMidiListData(bool full, XMLwrapper *xml) { + midi_list.clear(); if (!xml->enterbranch("MIDILEARN")) { if (full) @@ -1038,14 +1023,46 @@ entry.min_out = xml->getpar("Convert_Min", 0, -16384, 16383); entry.max_out = xml->getpar("Convert_Max", 0, -16384, 16383); xml->enterbranch("COMMAND"); - entry.data.type = xml->getpar255("Type", 0); // ?? - entry.data.control = xml->getpar255("Control", 0); - entry.data.part = xml->getpar255("Part", 0); - entry.data.kit = xml->getpar255("Kit_Item", 0); - entry.data.engine = xml->getpar255("Engine", 0); - entry.data.insert = xml->getpar255("Insert", 0); - entry.data.parameter = xml->getpar255("Parameter", 0); - entry.data.miscmsg = xml->getpar255("Secondary_Parameter", 0); + entry.frame.data.type = xml->getpar255("Type", 0); // ?? + entry.frame.data.control = xml->getpar255("Control", 0); + entry.frame.data.part = xml->getpar255("Part", 0); + entry.frame.data.kit = xml->getpar255("Kit_Item", 0); + entry.frame.data.engine = xml->getpar255("Engine", 0); + entry.frame.data.insert = xml->getpar255("Insert", 0); + entry.frame.data.parameter = xml->getpar255("Parameter", 0); + entry.frame.data.offset = xml->getpar255("Secondary_Parameter", 0); +#ifdef NEWML + CommandBlock allData; + string test = xml->getparstr("Command_Name"); + TextData::encodeAll(synth, test, allData); +#ifdef NEWML_REPORT + if (ID == 0) + cout << endl; + cout << "line " << (ID + 1); + if (allData.data.control != entry.frame.data.control) + cout << " changed control Old " << int(entry.frame.data.control) << " > New " << int(allData.data.control); + if (allData.data.part != entry.frame.data.part) + cout << " changed part Old " << int(entry.frame.data.part) << " > New " << int(allData.data.part); + if (allData.data.kit != entry.frame.data.kit) + cout << " changed kit Old " << int(entry.frame.data.kit) << " > New " << int(allData.data.kit); + if (allData.data.engine != entry.frame.data.engine) + cout << " changed engine Old " << int(entry.frame.data.engine) << " > New " << int(allData.data.engine); + if (allData.data.insert != entry.frame.data.insert) + cout << " changed insert Old " << int(entry.frame.data.insert) << " > New " << int(allData.data.insert); + if (allData.data.parameter != entry.frame.data.parameter) + cout << " changed parameter Old " << int(entry.frame.data.parameter) << " > New " << int(allData.data.parameter); + if (allData.data.offset != entry.frame.data.offset) + cout << " changed offset Old " << int(entry.frame.data.offset) << " > " << int(allData.data.offset); + cout << endl; +#endif // NEWML_REPORT + entry.frame.data.control = allData.data.control; + entry.frame.data.part = allData.data.part; + entry.frame.data.kit = allData.data.kit; + entry.frame.data.engine = allData.data.engine; + entry.frame.data.insert = allData.data.insert; + entry.frame.data.parameter = allData.data.parameter; + entry.frame.data.offset = allData.data.offset; +#endif // NEWML xml->exitbranch(); xml->exitbranch(); entry.status = status; diff -Nru yoshimi-2.1.1.1~dfsg0/src/Interface/MidiLearn.h yoshimi-2.1.2.2~dfsg0/src/Interface/MidiLearn.h --- yoshimi-2.1.1.1~dfsg0/src/Interface/MidiLearn.h 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/Interface/MidiLearn.h 2021-12-03 20:12:12.000000000 +0000 @@ -22,29 +22,33 @@ #ifndef MIDILEARN_H #define MIDILEARN_H +#include "globals.h" + #include #include #include "Interface/InterChange.h" #include "Interface/Data2Text.h" +#include "Interface/Text2Data.h" class XMLwrapper; class SynthEngine; class DataText; +class TextData; using std::string; using std::list; -class MidiLearn : private DataText +class MidiLearn : private DataText, TextData { public: MidiLearn(SynthEngine *_synth); ~MidiLearn(); void add2XML(XMLwrapper *xml); void getfromXML(XMLwrapper *xml); - CommandBlock commandData; + CommandBlock data;//commandData; - struct Control{ +/* struct Control{ unsigned char type = 0; unsigned char control = 0; unsigned char part = 0; @@ -52,10 +56,11 @@ unsigned char engine = 0; unsigned char insert = 0; unsigned char parameter = 0; + unsigned char offset = 0; unsigned char miscmsg = 0; - }; + };*/ - Control data; + //Control data; struct LearnBlock{ unsigned short int CC = 0; @@ -65,7 +70,7 @@ unsigned char status = 0; // up to here must be specified on input int min_out = 0; // defined programmatically int max_out = 0; // defined programmatically - Control data; // controller to learn + CommandBlock frame; // controller to learn }; bool learning; diff -Nru yoshimi-2.1.1.1~dfsg0/src/Interface/Text2Data.cpp yoshimi-2.1.2.2~dfsg0/src/Interface/Text2Data.cpp --- yoshimi-2.1.1.1~dfsg0/src/Interface/Text2Data.cpp 1970-01-01 00:00:00.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/Interface/Text2Data.cpp 2021-12-03 20:12:12.000000000 +0000 @@ -0,0 +1,1509 @@ +/* + Text2Data.cpp - conversion of text to commandBlock entries + + Copyright 2021, Will Godfrey + + This file is part of yoshimi, which is free software: you can redistribute + it and/or modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + yoshimi is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License (version 2 or + later) for more details. + + You should have received a copy of the GNU General Public License along with + yoshimi; if not, write to the Free Software Foundation, Inc., 51 Franklin + Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ +#include +#include + +#include "Interface/Text2Data.h" +#include "Interface/TextLists.h" +#include "Interface/InterChange.h" +#include "Misc/SynthEngine.h" +#include "Misc/TextMsgBuffer.h" +#include "Misc/FormatFuncs.h" +#include "Misc/NumericFuncs.h" + +using std::string; +using std::to_string; +using std::cout; +using std::endl; + +void TextData::encodeAll(SynthEngine *_synth, string &sentCommand, CommandBlock &allData) +{ + memset(&allData.bytes, 255, sizeof(allData)); + + oursynth = _synth; + string source = sentCommand; + strip (source); + if (source.empty()) + { + allData.data.control = TOPLEVEL::control::unrecognised; + allData.data.source = TOPLEVEL::action::noAction; + log(source, "empty Command String"); + return; + } + encodeLoop(source, allData); + + //cout << "Control " << int(allData.data.control) << " Part " << int(allData.data.part) << " Kit " << int(allData.data.kit) << " Engine " << int(allData.data.engine) << " Insert " << int(allData.data.insert) << " Parameter " << int(allData.data.parameter) << " Offset " << int(allData.data.offset) << endl; + + /* + * If we later decide to be able to set and read values + * this is where the code should go in order to catch + * all of the subroutines. + * + * MIDI-learn will not use this + */ + + /*size_t pos = source.find("Value"); + if (pos != string::npos) + { // done directly - we don't know 'source' is tidy + source = source.substr(pos); + nextWord(source); + if (isdigit(source[0])) + { + allData.data.value = strtof(source.c_str(), NULL); + // need a ring buffer to write allData CommandBlock + } + else + log (source, "no value to write given"); + } + else + { + // return the supplied allData CommandBlock + // and/or the supplied string + allData.data.type = 0; + allData.data.value = oursynth->interchange.readAllData(&allData); + sentCommand += (" Value >" + to_string(allData.data.value)); + }*/ +} + + +void TextData::log(std::string &line, std::string text) +{ + oursynth->getRuntime().Log("Error: " + text); + // we may later decide to print the string before emptying it + + line = ""; +} + + +void TextData::strip(std::string &line) +{ + size_t pos = line.find_first_not_of(" "); + if (pos == string::npos) + line = ""; + else + line = line.substr(pos); +} + + +void TextData::nextWord(std::string &line) +{ + size_t pos = line.find_first_of(" "); + if (pos == string::npos) + { + line = ""; + return; + } + line = line.substr(pos); + strip(line); +} + + +bool TextData::findCharNum(string &line, unsigned char &value) +{ + if (!isdigit(line[0])) + return false; + value = stoi(line) - 1; + nextWord(line); + return true; +} + +bool TextData::findAndStep(std::string &line, std::string text, bool step) +{ + size_t pos = line.find(text); + if (pos != string::npos && pos < 3) // allow leading spaces + { + if (step) + { + pos += text.length(); + line = line.substr(pos); + nextWord(line); + } + return true; + } + return false; +} + +int TextData::findListEntry(std::string &line, int step, std::string list []) +{ + int count = 0; + bool found = false; + std::string test; + do { + test = func::stringCaps(list [count], 1); + size_t split = test.find(" "); + if (split != string::npos) + test = test.substr(0, split); + found = findAndStep(line, test); + if (!found) + count += step; + + } while (!found && test != "@end"); + if (count > 0) + count = count / step; // gives actual list position + return count; +} + +void TextData::encodeLoop(std::string source, CommandBlock &allData) +{ + /* NOTE + * subsections must *always* come before local controls! + */ + if (findAndStep(source, "Main")) + { + encodeMain(source, allData); + return; + } + + if (findAndStep(source, "System")) + { + allData.data.part = (TOPLEVEL::section::systemEffects); + if (findAndStep(source, "Effect")) + encodeEffects(source, allData); + return; + } + + if (findAndStep(source, "Insert")) + { + allData.data.part = (TOPLEVEL::section::insertEffects); + if (findAndStep(source, "Effect")) + encodeEffects(source, allData); + return; + } + + if (findAndStep(source, "Scales")) + { + encodeScale(source, allData); + return; + } + + if (findAndStep(source, "Part")) + { + encodePart(source, allData); + return; + } + + allData.data.control = TOPLEVEL::control::unrecognised; + allData.data.source = TOPLEVEL::action::noAction; + log(source, "bad Command String"); +} + + +void TextData::encodeMain(std::string &source, CommandBlock &allData) +{ + strip (source); + //cout << ">" << source << endl; + allData.data.part = TOPLEVEL::section::main; + if (findAndStep(source, "Master")) + { + if (findAndStep(source, "Mono/Stereo")) + { + allData.data.control = MAIN::control::mono; + return; + } + } + if (findAndStep(source, "Volume")) + { + allData.data.control = MAIN::control::volume; + return; + } + + allData.data.control = TOPLEVEL::control::unrecognised; + allData.data.source = TOPLEVEL::action::noAction; + cout << "main overflow >" << source << endl; +} + + +void TextData::encodeScale(std::string &source, CommandBlock &allData) +{ + strip (source); + allData.data.part = TOPLEVEL::section::scales; + + unsigned char ctl = UNUSED; + if (findAndStep(source, "Enable")) + { + if (findAndStep(source, "Microtonal")) + ctl = SCALES::control::enableMicrotonal; + else if (findAndStep(source, "Keyboard Mapping")) + ctl = SCALES::control::enableKeyboardMap; + } + else if (findAndStep(source, "Ref note")) + ctl = SCALES::control::refNote; + else if (findAndStep(source, "Invert Keys")) + ctl = SCALES::control::invertScale; + else if (findAndStep(source, "Key Center")) + ctl = SCALES::control::invertedScaleCenter; + else if (findAndStep(source, "Scale Shift")) + ctl = SCALES::control::scaleShift; + else if (findAndStep(source, "Keyboard")) + { + if (findAndStep(source, "First Note")) + ctl = SCALES::control::lowKey; + else if (findAndStep(source, "Middle Note")) + ctl = SCALES::control::middleKey; + else if (findAndStep(source, "Last Note")) + ctl = SCALES::control::highKey; + } + + if (ctl < UNUSED) + { + allData.data.control = ctl; + return; + } + + allData.data.control = TOPLEVEL::control::unrecognised; + allData.data.source = TOPLEVEL::action::noAction; + cout << "scale overflow >" << source << endl; +} + +void TextData::encodePart(std::string &source, CommandBlock &allData) +{ + strip (source); + unsigned char npart = UNUSED; + if (findCharNum(source, npart)) + { + //cout << "part " << int(npart) << endl; + if (npart >= NUM_MIDI_PARTS) + { + log(source, "part number out of range"); + return; + } + allData.data.part = (TOPLEVEL::section::part1 + npart); + if (findAndStep(source, "Effect")) + { + encodeEffects(source, allData); + return; + } + } + else + return; // must have a part number! + + unsigned char kitnum = UNUSED; + if (findAndStep(source, "Kit")) + { + if (findCharNum(source, kitnum)) + { + if (kitnum >= NUM_KIT_ITEMS) + { + log(source, "kit number out of range"); + return; + } + + allData.data.kit = kitnum; + //cout << "kitnum " << int(kitnum) << endl; + } + + //allData.data.insert = TOPLEVEL::insert::kitGroup; + unsigned char kitctl = UNUSED; + if (findAndStep(source, "Mute")) + kitctl = PART::control::kitItemMute; + // we may add other controls later + if (kitctl < UNUSED) + { + allData.data.insert = TOPLEVEL::insert::kitGroup; + allData.data.control = kitctl; + return; + } + } + if (findAndStep(source, "Controller")) + { + encodeController(source, allData); + return; + } + if (findAndStep(source, "MIDI")) + { + encodeMidi(source, allData); + return; + } + + if (findAndStep(source, "AddSynth")) + { + encodeAddSynth(source, allData); + return; + } + + if (findAndStep(source, "Add Voice") || findAndStep(source, "Adsynth Voice") || findAndStep(source, "addvoice")) + { + unsigned char voiceNum = UNUSED; + if (findCharNum(source, voiceNum)) + { + if (voiceNum >= NUM_VOICES) + { + log(source, "voice number out of range"); + return; + } + allData.data.engine = PART::engine::addVoice1+voiceNum; + encodeAddVoice(source, allData); + return; + } + } + if (findAndStep(source, "SubSynth")) + { + encodeSubSynth(source, allData); + return; + } + if (findAndStep(source, "PadSynth")) + { + encodePadSynth(source, allData); + return; + } + + unsigned char ctl = UNUSED; + if (findAndStep(source, "Vel")) + { + if (findAndStep(source, "Sens")) + ctl = PART::control::velocitySense; + else if (findAndStep(source, "Offset")) + ctl = PART::control::velocityOffset; + } + else if (findAndStep(source, "Panning")) + ctl = PART::control::panning; + else if (findAndStep(source, "Volume")) + ctl = PART::control::volume; + else if (findAndStep(source, "Humanise")) + { + if (findAndStep(source, "Pitch")) + ctl = PART::control::humanise; + else if (findAndStep(source, "Velocity")) + ctl = PART::control::humanvelocity; + else + ctl = PART::control::humanise; // old single control version + } + else if (findAndStep(source, "Portamento Enable") || findAndStep(source, "Portamento")) + ctl = PART::control::portamento; + if (ctl < UNUSED) + { + allData.data.control = ctl; + return; + } + allData.data.control = TOPLEVEL::control::unrecognised; + allData.data.source = TOPLEVEL::action::noAction; + cout << "part overflow >" << source << endl; +} + +// ---------------------------- + +void TextData::encodeController(std::string &source, CommandBlock &allData) +{ + unsigned char ctl = UNUSED; + if (findAndStep(source,"Vol")) + { + if (findAndStep(source,"Range")) + ctl = PART::control::volumeRange; + else if (findAndStep(source,"Enable")) + ctl = PART::control::volumeEnable; + } + else if (findAndStep(source,"Pan Width")) + { + ctl = PART::control::panningWidth; + } + else if (findAndStep(source,"Mod Wheel Range") || findAndStep(source,"Mod Wheel Depth")) + { + ctl = PART::control::modWheelDepth; + } + else if (findAndStep(source,"Exponent")) + { + if (findAndStep(source,"Mod Wheel")) + { + ctl = PART::control::exponentialModWheel; + } + else if (findAndStep(source,"Bandwidth")) + ctl = PART::control::exponentialBandwidth; + } + else if (findAndStep(source,"Bandwidth Range") || findAndStep(source,"Bandwidth depth")) + { + ctl = PART::control::bandwidthDepth; + } + else if (findAndStep(source,"Expression Enable")) + { + ctl = PART::control::expressionEnable; + } + else if (findAndStep(source,"FM Amp Enable")) + { + ctl = PART::control::FMamplitudeEnable; + } + else if (findAndStep(source,"Sustain Ped Enable")) + { + ctl = PART::control::sustainPedalEnable; + } + else if (findAndStep(source,"Pitch Wheel Range")) + { + ctl = PART::control::pitchWheelRange; + } + else if (findAndStep(source,"Filter")) + { + if (findAndStep(source,"Q Range") || findAndStep(source,"Q Depth")) + { + ctl = PART::control::filterQdepth; + } + else if (findAndStep(source,"Cutoff Range") || findAndStep(source,"Cutoff Depth")) + { + ctl = PART::control::filterCutoffDepth; + } + } + else if (findAndStep(source,"Breath Control")) + { + ctl = PART::control::breathControlEnable; + } + else if (findAndStep(source,"Res")) + { + if (findAndStep(source,"Cent Freq Range")) + { + ctl = PART::control::resonanceCenterFrequencyDepth; + } + else if (findAndStep(source,"Band Range") || findAndStep(source,"Band Depth")) + { + ctl = PART::control::resonanceBandwidthDepth; + } + } + else if (findAndStep(source,"Portamento")) + { + if (findAndStep(source,"Receive")) + ctl = PART::control::receivePortamento; + else if (findAndStep(source,"Time")) + { + if (findAndStep(source,"Stretch")) + ctl = PART::control::portamentoTimeStretch; + else + ctl = PART::control::portamentoTime; + } + else if (findAndStep(source,"Threshold Gate")) + { + if (findAndStep(source,"Type")) + ctl = PART::control::portamentoThresholdType; + else + ctl = PART::control::portamentoThreshold; + } + else if (findAndStep(source,"Prop")) + { + if (findAndStep(source,"Enable")) + ctl = PART::control::enableProportionalPortamento; + else if (findAndStep(source,"Rate")) + ctl = PART::control::proportionalPortamentoRate; + else if (findAndStep(source,"depth")) + ctl = PART::control::proportionalPortamentoDepth; + } + } + if (ctl < UNUSED) + { + allData.data.control = ctl; + return; + } + + allData.data.control = TOPLEVEL::control::unrecognised; + allData.data.source = TOPLEVEL::action::noAction; + cout << "controller overflow >" << source << endl; +} + + +void TextData::encodeMidi(std::string &source, CommandBlock &allData) +{ + unsigned char ctl = UNUSED; + if (findAndStep(source,"Modulation")) + ctl = PART::control::midiModWheel; + else if (findAndStep(source,"Expression")) + ctl = PART::control::midiExpression; + else if (findAndStep(source,"Filter")) + { + if (findAndStep(source,"Q")) + ctl = PART::control::midiFilterQ; + else if (findAndStep(source,"Cutoff")) + ctl = PART::control::midiFilterCutoff; + } + else if (findAndStep(source,"Bandwidth")) + ctl = PART::control::midiBandwidth; + + if (ctl < UNUSED) + { + allData.data.control = ctl; + return; + } + + allData.data.control = TOPLEVEL::control::unrecognised; + allData.data.source = TOPLEVEL::action::noAction; + cout << "midi overflow >" << source << endl; +} + + +void TextData::encodeEffects(std::string &source, CommandBlock &allData) +{ + if (findAndStep(source, "Send")) + { + unsigned char sendto = UNUSED; + if (findCharNum(source, sendto)) + { + allData.data.control = PART::control::partToSystemEffect1 + sendto; + return; + } + } + unsigned char effnum = UNUSED; + if (findCharNum(source, effnum)) // need to find number ranges + { + allData.data.engine = effnum; + //cout << "effnum " << int(effnum) << endl; + if (findAndStep(source, "DynFilter ~ Filter")) + { + allData.data.kit = EFFECT::type::dynFilter; + encodeFilter(source, allData); + return; + } + if (allData.data.part < NUM_MIDI_PARTS) + { + if (findAndStep(source, "Bypass") || findAndStep(source, "bypassed")) + { + allData.data.control = PART::control::effectBypass; + allData.data.insert = TOPLEVEL::insert::partEffectSelect; + return; + } + } + if (allData.data.part == TOPLEVEL::section::systemEffects) + { + bool test = (source == ""); + if (!test) + { + test = (source.find("Enable") != string::npos); + if (!test) + test = isdigit(source[0]); + + } + if (test) + { + if (!isdigit(source[0])) + nextWord(source); // a number might be a value for later + allData.data.control = EFFECT::sysIns::effectEnable; + return; + } + } + + unsigned char efftype = findListEntry(source, 1, fx_list); + if (efftype >= EFFECT::type::count - EFFECT::type::none) + { + log(source, "effect type out of range"); + return; + } + int effpos = efftype + EFFECT::type::none; + allData.data.kit = efftype + EFFECT::type::none; + + // now need to do actual control + unsigned char result = UNUSED; + switch (effpos) + { + case EFFECT::type::reverb: + result = findListEntry(source, 2, reverblist); + if (result > 4) // no 5 or 6 + result += 2; + break; + case EFFECT::type::echo: + result = findListEntry(source, 2, echolist); + if (result == 7) // skip unused numbers + result = EFFECT::control::bpm; + break; + case EFFECT::type::chorus: + result = findListEntry(source, 2, choruslist); + if (result >= 11) // skip unused numbers + result = result - 11 + EFFECT::control::bpm; + break; + case EFFECT::type::phaser: + result = findListEntry(source, 2, phaserlist); + if (result >= 15) // skip unused numbers + result = result - 15 + EFFECT::control::bpm; + break; + case EFFECT::type::alienWah: + result = findListEntry(source, 2, alienwahlist); + if (result >= 11) // skip unused numbers + result = result - 11 + EFFECT::control::bpm; + break; + case EFFECT::type::distortion: + result = findListEntry(source, 2, distortionlist); + if (result > 5) // extra line + result -= 1; + break; + case EFFECT::type::eq: + result = findListEntry(source, 2, eqlist); + if (result > 2) // extra line + result -= 1; + break; + case EFFECT::type::dynFilter: + result = findListEntry(source, 2, dynfilterlist); + if (result >= 11) // skip unused numbers + result = result - 11 + EFFECT::control::bpm; + break; + default: + log(source, "effect control out of range"); + return; + } + //cout << "effnum " << int(effnum) << " efftype " << int(efftype + EFFECT::type::none) << " control " << int(result) << endl; + allData.data.control = result; + return; + } + + allData.data.control = TOPLEVEL::control::unrecognised; + allData.data.source = TOPLEVEL::action::noAction; + cout << "effects overflow >" << source << endl; +} + +// ---------------------------- + +void TextData::encodeAddSynth(std::string &source, CommandBlock &allData) +{ + if (findAndStep(source, "Enable")) + { + if (allData.data.kit != UNUSED) + allData.data.insert = TOPLEVEL::insert::kitGroup; + allData.data.control = PART::control::enableAdd; + return; + } + allData.data.engine = PART::engine::addSynth; + unsigned char ctl = UNUSED; + + if (findAndStep(source, "Resonance")) + { + encodeResonance(source, allData); + return; + } + else if (findAndStep(source, "Amp Env")) + { + allData.data.parameter = TOPLEVEL::insertType::amplitude; + encodeEnvelope(source, allData); + return; + } + else if (findAndStep(source, "Amp LFO")) + { + allData.data.parameter = TOPLEVEL::insertType::amplitude; + encodeLFO(source, allData); + return; + } + else if (findAndStep(source, "Filt Env")) + { + allData.data.parameter = TOPLEVEL::insertType::filter; + encodeEnvelope(source, allData); + return; + } + else if (findAndStep(source, "Filt LFO")) + { + allData.data.parameter = TOPLEVEL::insertType::filter; + encodeLFO(source, allData); + return; + } + else if (findAndStep(source, "Filter")) + { + encodeFilter(source, allData); + return; + } + else if (findAndStep(source, "Freq Env")) + { + allData.data.parameter = TOPLEVEL::insertType::frequency; + encodeEnvelope(source, allData); + return; + } + else if (findAndStep(source, "Freq LFO")) + { + allData.data.parameter = TOPLEVEL::insertType::frequency; + encodeLFO(source, allData); + return; + } + findAndStep(source, "Amplitude") // we just throw this away + ; + if (findAndStep(source, "Volume")) + ctl = ADDSYNTH::control::volume; + else if (findAndStep(source, "Velocity Sense") || findAndStep(source, "Vel Sens")) + ctl = ADDSYNTH::control::velocitySense; + else if (findAndStep(source, "Panning")) + ctl = ADDSYNTH::control::panning; + else if (findAndStep(source, "Random Width")) + ctl = ADDSYNTH::control::randomWidth; + else if (findAndStep(source, "Stereo")) + ctl = ADDSYNTH::control::stereo; + else if (findAndStep(source, "De Pop")) + ctl = ADDSYNTH::control::dePop; + + else if (findAndStep(source, "Punch")) + { + if (findAndStep(source, "Strength") || findAndStep(source, "Strngth")) + ctl = ADDSYNTH::control::punchStrength; + else if (findAndStep(source, "Time")) + ctl = ADDSYNTH::control::punchDuration; + else if (findAndStep(source, "Stretch") || findAndStep(source, "Strtch")) + ctl = ADDSYNTH::control::punchStretch; + else if (findAndStep(source, "Vel")) + ctl = ADDSYNTH::control::punchVelocity; + } + + findAndStep(source, "Frequency"); // throw this away too + if (findAndStep(source, "Detune")) + ctl = ADDSYNTH::control::detuneFrequency; + else if (findAndStep(source, "Octave")) + ctl = ADDSYNTH::control::octave; + else if (findAndStep(source, "Relative Bandwidth") ||findAndStep(source, "Rel B Wdth")) + ctl = ADDSYNTH::control::relativeBandwidth; + + if (ctl < UNUSED) + { + allData.data.control = ctl; + return; + } + + allData.data.control = TOPLEVEL::control::unrecognised; + allData.data.source = TOPLEVEL::action::noAction; + cout << "addsynth overflow >" << source << endl; +} + + +void TextData::encodeAddVoice(std::string &source, CommandBlock &allData) +{ + unsigned char ctl = UNUSED; + + if (findAndStep(source, "Enable")) + ctl = ADDVOICE::control::enableVoice; + + else if (findAndStep(source, "Resonance")) + { + encodeResonance(source, allData); + return; + } + else if (findAndStep(source, "Oscillator", false) || findAndStep(source, "Base", false) || findAndStep(source, "Harm Mods", false) || findAndStep(source, "Harmonic", false)) + { + encodeWaveform(source, allData); + return; + } + + else if (findAndStep(source, "Amp Env")) + { + allData.data.parameter = TOPLEVEL::insertType::amplitude; + encodeEnvelope(source, allData); + return; + } + else if (findAndStep(source, "Amp LFO")) + { + allData.data.parameter = TOPLEVEL::insertType::amplitude; + encodeLFO(source, allData); + return; + } + if (findAndStep(source, "Amp")) + { + if (findAndStep(source, "Enable Env")) + ctl = ADDVOICE::control::enableAmplitudeEnvelope; + else if (findAndStep(source, "Enable LFO")) + ctl = ADDVOICE::control::enableAmplitudeLFO; + } + else if (findAndStep(source, "Filt Env")) + { + allData.data.parameter = TOPLEVEL::insertType::filter; + encodeEnvelope(source, allData); + return; + } + else if (findAndStep(source, "Filt LFO")) + { + allData.data.parameter = TOPLEVEL::insertType::filter; + encodeLFO(source, allData); + return; + } + else if (findAndStep(source, "Filter")) + { + if (findAndStep(source, "Enable Env")) + ctl = ADDVOICE::control::enableFilterEnvelope; + else if (findAndStep(source, "Enable LFO")) + ctl = ADDVOICE::control::enableFilterLFO; + else if (findAndStep(source, "Enable")) + ctl = ADDVOICE::control::enableFilter; + else + { + encodeFilter(source, allData); + return; + } + } + + else if (findAndStep(source, "Modulator")) + { + if (findAndStep(source, "Amp Env")) + { + allData.data.engine += (PART::engine::addMod1 - PART::engine::addVoice1); + allData.data.parameter = TOPLEVEL::insertType::amplitude; + encodeEnvelope(source, allData); + return; + } + if (findAndStep(source, "Freq Env")) + { + allData.data.engine += (PART::engine::addMod1 - PART::engine::addVoice1); + allData.data.parameter = TOPLEVEL::insertType::frequency; + encodeEnvelope(source, allData); + return; + } + else if (findAndStep(source, "Amp")) + { + if (findAndStep(source, "Enable Env")) + ctl = ADDVOICE::control::enableModulatorAmplitudeEnvelope; + } // throw it away for the next three controls + if (findAndStep(source, "Volume")) + ctl = ADDVOICE::control::modulatorAmplitude; + else if (findAndStep(source, "Vel Sense") || findAndStep(source, "V Sense")) + ctl = ADDVOICE::control::modulatorVelocitySense; + else if (findAndStep(source, "HF Damping") || findAndStep(source, "F Damp")) + ctl = ADDVOICE::control::modulatorHFdamping; + + if (findAndStep(source, "Freq")) + { + if (findAndStep(source, "Enable Env")) + ctl = ADDVOICE::control::enableModulatorFrequencyEnvelope; + else + ctl = ADDVOICE::control::modulatorDetuneFrequency; // old form + } // throw away for next + if (findAndStep(source, "Octave")) + ctl = ADDVOICE::control::modulatorOctave; + + else if (findAndStep(source, "Detune")) + ctl = ADDVOICE::control::modulatorDetuneFrequency; + + else if (findAndStep(source, "Osc Phase")) + ctl = ADDVOICE::control::modulatorOscillatorPhase; + } + + else if (findAndStep(source, "Freq Env")) + { + allData.data.parameter = TOPLEVEL::insertType::frequency; + encodeEnvelope(source, allData); + return; + } + else if (findAndStep(source, "Freq LFO")) + { + allData.data.parameter = TOPLEVEL::insertType::frequency; + encodeLFO(source, allData); + return; + } + else if (findAndStep(source, "Freq")) + { + if (findAndStep(source, "Enable Env")) + { + ctl = ADDVOICE::control::enableFrequencyEnvelope; + allData.data.control = ctl; + return; + } + else if (findAndStep(source, "Enable LFO")) + { + ctl = ADDVOICE::control::enableFrequencyLFO; + allData.data.control = ctl; + return; + } + // throw away for next few + } + if (findAndStep(source, "Bend Adj")) + ctl = ADDVOICE::control::pitchBendAdjustment; + else if (findAndStep(source, "Offset Hz")) + ctl = ADDVOICE::control::pitchBendOffset; + else if (findAndStep(source, "Equal Temper") || findAndStep(source, "Eq T")) + ctl = ADDVOICE::control::equalTemperVariation; + else if (findAndStep(source, "Detune")) + ctl = ADDVOICE::control::detuneFrequency; + else if (findAndStep(source, "Octave")) + ctl = ADDVOICE::control::octave; + + else if (findAndStep(source, "Unison")) + { + if (findAndStep(source, "Enable")) + ctl = ADDVOICE::control::enableUnison; + else if (findAndStep(source, "Freq Spread")) + ctl = ADDVOICE::control::unisonFrequencySpread; + else if (findAndStep(source, "Phase Rnd")) + ctl = ADDVOICE::control::unisonPhaseRandomise; + else if (findAndStep(source, "Stereo")) + ctl = ADDVOICE::control::unisonStereoSpread; + else if (findAndStep(source, "Vibrato")) + ctl = ADDVOICE::control::unisonVibratoDepth; + else if (findAndStep(source, "Vib Speed")) + ctl = ADDVOICE::control::unisonVibratoSpeed; + } + + else if (findAndStep(source, "Volume")) + ctl = ADDVOICE::control::volume; + else if (findAndStep(source, "Velocity Sense") || findAndStep(source, "Vel Sens")) + ctl = ADDVOICE::control::velocitySense; + else if (findAndStep(source, "Panning")) + ctl = ADDVOICE::control::panning; + else if (findAndStep(source, "Random Width")) + ctl = ADDVOICE::control::randomWidth; + + if (ctl < UNUSED) + { + allData.data.control = ctl; + return; + } + + allData.data.control = TOPLEVEL::control::unrecognised; + allData.data.source = TOPLEVEL::action::noAction; + cout << "addvoice overflow >" << source << endl; +} + + +void TextData::encodeSubSynth(std::string &source, CommandBlock &allData) +{ + if (findAndStep(source, "Enable")) + { + if (allData.data.kit != UNUSED) + allData.data.insert = TOPLEVEL::insert::kitGroup; + allData.data.control = PART::control::enableSub; + return; + } + + allData.data.engine = PART::engine::subSynth; + unsigned char ctl = UNUSED; + + if (findAndStep(source, "Amp Env")) + { + allData.data.parameter = TOPLEVEL::insertType::amplitude; + encodeEnvelope(source, allData); + return; + } + else if (findAndStep(source, "Filt Env")) + { + allData.data.parameter = TOPLEVEL::insertType::filter; + encodeEnvelope(source, allData); + return; + } + else if (findAndStep(source, "Freq Env")) + { + allData.data.parameter = TOPLEVEL::insertType::frequency; + encodeEnvelope(source, allData); + return; + } + else if (findAndStep(source, "Band Env")) + { + allData.data.parameter = TOPLEVEL::insertType::bandwidth; + encodeEnvelope(source, allData); + return; + } + + if (findAndStep(source, "Filter")) + { + if (findAndStep(source, "Enable")) + { + ctl = SUBSYNTH::control::enableFilter; + } + else + { + encodeFilter(source, allData); + return; + } + } + else if (findAndStep(source, "Stereo")) + ctl = SUBSYNTH::control::stereo; + + else if (findAndStep(source, "Overtones")) + { + if (findAndStep(source, "Par 1")) + ctl = SUBSYNTH::control::overtoneParameter1; + else if (findAndStep(source, "Par 2")) + ctl = SUBSYNTH::control::overtoneParameter2; + else if (findAndStep(source, "Force H")) + ctl = SUBSYNTH::control::overtoneForceHarmonics; + } + else if (findAndStep(source, "Harmonic")) + { // has to be before anything starting with Amplitude or Bandwidth + unsigned char harmonicNum = UNUSED; + if (!findCharNum(source, harmonicNum)) + { + log (source, "no harmonic number"); + return; + } + if (findAndStep(source, "Amplitude")) + { + allData.data.insert = TOPLEVEL::insert::harmonicAmplitude; + ctl = harmonicNum; + } + else if (findAndStep(source, "Bandwidth")) + { + allData.data.insert = TOPLEVEL::insert::harmonicPhaseBandwidth; + ctl = harmonicNum; + } + if (ctl < UNUSED) + { + allData.data.control = ctl; + return; + } + } + else if (findAndStep(source, "Bandwidth")) + { + if (findAndStep(source, "Env Enab")) + ctl = SUBSYNTH::control::enableBandwidthEnvelope; + else if (findAndStep(source, "Band Scale")) + ctl = SUBSYNTH::control::bandwidthScale; + else + ctl = SUBSYNTH::control::bandwidth; + } + else if (findAndStep(source, "Frequency")) + { + if (findAndStep(source, "Env Enab")) + { + ctl = SUBSYNTH::control::enableFrequencyEnvelope; + allData.data.control = ctl; + return; + } + // throw away for the next few + } + else if (findAndStep(source, "Octave")) + ctl = SUBSYNTH::control::octave; + else if (findAndStep(source, "Bend Adj")) + ctl = SUBSYNTH::control::pitchBendAdjustment; + else if (findAndStep(source, "Offset Hz")) + ctl = SUBSYNTH::control::pitchBendOffset; + else if (findAndStep(source, "Equal Temper") || findAndStep(source, "Eq T")) + ctl = SUBSYNTH::control::equalTemperVariation; + else if (findAndStep(source, "Detune")) + ctl = SUBSYNTH::control::detuneFrequency; + + findAndStep(source, "Amplitude"); // throw away for next few + if (findAndStep(source, "Volume")) + ctl = SUBSYNTH::control::volume; + else if (findAndStep(source, "Velocity Sense") || findAndStep(source, "Vel Sens")) + ctl = SUBSYNTH::control::velocitySense; + else if (findAndStep(source, "Panning")) + ctl = SUBSYNTH::control::panning; + else if (findAndStep(source, "Random Width")) + ctl = SUBSYNTH::control::randomWidth; + if (ctl < UNUSED) + { + allData.data.control = ctl; + return; + } + + allData.data.control = TOPLEVEL::control::unrecognised; + allData.data.source = TOPLEVEL::action::noAction; + cout << "subsynth overflow >" << source << endl; +} + + +void TextData::encodePadSynth(std::string &source, CommandBlock &allData) +{ + if (findAndStep(source, "Enable")) + { + if (allData.data.kit != UNUSED) + allData.data.insert = TOPLEVEL::insert::kitGroup; + allData.data.control = PART::control::enablePad; + return; + } + + + allData.data.engine = PART::engine::padSynth; + unsigned char ctl = UNUSED; + + if (findAndStep(source, "Resonance")) + { + encodeResonance(source, allData); + return; + } + else if (findAndStep(source, "Oscillator", false) || findAndStep(source, "Base", false) || findAndStep(source, "Harm Mods", false)) + { + encodeWaveform(source, allData); + return; + } + else if (findAndStep(source, "Amp Env")) + { + allData.data.parameter = TOPLEVEL::insertType::amplitude; + encodeEnvelope(source, allData); + return; + } + else if (findAndStep(source, "Amp LFO")) + { + allData.data.parameter = TOPLEVEL::insertType::amplitude; + encodeLFO(source, allData); + return; + } + else if (findAndStep(source, "Filt Env")) + { + allData.data.parameter = TOPLEVEL::insertType::filter; + encodeEnvelope(source, allData); + return; + } + else if (findAndStep(source, "Filt LFO")) + { + allData.data.parameter = TOPLEVEL::insertType::filter; + encodeLFO(source, allData); + return; + } + else if (findAndStep(source, "Filter")) + { + encodeFilter(source, allData); + return; + } + else if (findAndStep(source, "Freq Env")) + { + allData.data.parameter = TOPLEVEL::insertType::frequency; + encodeEnvelope(source, allData); + return; + } + else if (findAndStep(source, "Freq LFO")) + { + allData.data.parameter = TOPLEVEL::insertType::frequency; + encodeLFO(source, allData); + return; + } + else if (findAndStep(source, "Harmonic Base")) + { + if (findAndStep(source, "Width")) + ctl =PADSYNTH::control::baseWidth; + else if (findAndStep(source, "Freq Mult")) + ctl =PADSYNTH::control::frequencyMultiplier; + else if (findAndStep(source, "Str")) + ctl =PADSYNTH::control::modulatorStretch; + else if (findAndStep(source, "Freq")) + ctl =PADSYNTH::control::modulatorFrequency; + else if (findAndStep(source, "Size")) + ctl =PADSYNTH::control::size; + else if (findAndStep(source, "Amp Par 1")) + ctl =PADSYNTH::control::spectralWidth; + else if (findAndStep(source, "Amp Par 2")) + ctl =PADSYNTH::control::spectralAmplitude; + } + else if (findAndStep(source, "Oscillator", false) || findAndStep(source, "Base", false) || findAndStep(source, "Harm Mods", false) || findAndStep(source, "Harmonic", false)) + { // must come after harmonic base + encodeWaveform(source, allData); + return; + } + else if (findAndStep(source, "Overtones")) + { + findAndStep(source, "Overt"); // throw it away + if (findAndStep(source, "Par 1")) + ctl =PADSYNTH::control::overtoneParameter1; + else if (findAndStep(source, "Par 2")) + ctl =PADSYNTH::control::overtoneParameter2; + else if (findAndStep(source, "Force H")) + ctl =PADSYNTH::control::overtoneForceHarmonics; + } + + else if (findAndStep(source, "Bandwidth")) + { + if (findAndStep(source, "Scale")) + ; // not yet + else if(findAndStep(source, "Spectrum Mode")) // old form + ; // not yet + else + { + findAndStep(source, "Bandwidth"); //throw it away (old form) + ctl =PADSYNTH::control::bandwidth; + } + } + else if(findAndStep(source, "Spectrum Mode")) // new form + ; // not yet + + else if (findAndStep(source, "Changes Applied")) + ctl =PADSYNTH::control::applyChanges; + + findAndStep(source, "Amplitude"); // throw it away for the next few + if (findAndStep(source, "Volume")) + ctl =PADSYNTH::control::volume; + else if (findAndStep(source, "Velocity Sense") || findAndStep(source, "Vel Sens")) + ctl =PADSYNTH::control::velocitySense; + else if (findAndStep(source, "Panning")) + ctl =PADSYNTH::control::panning; + else if (findAndStep(source, "Random Pan")) + ctl =PADSYNTH::control::enableRandomPan; + else if (findAndStep(source, "Random Width")) + ctl =PADSYNTH::control::randomWidth; + + else if (findAndStep(source, "Punch")) + { + if (findAndStep(source, "Strength") || findAndStep(source, "Strngth")) + ctl =PADSYNTH::control::punchStrength; + else if (findAndStep(source, "Time")) + ctl =PADSYNTH::control::punchDuration; + else if (findAndStep(source, "Stretch") || findAndStep(source, "Strtch")) + ctl =PADSYNTH::control::punchStretch; + else if (findAndStep(source, "Vel")) + ctl =PADSYNTH::control::punchVelocity; + } + else if (findAndStep(source, "Stereo")) + ctl =PADSYNTH::control::stereo; + else if (findAndStep(source, "De Pop")) + ctl =PADSYNTH::control::dePop; + + findAndStep(source, "Frequency"); // throw it away for the next few + if (findAndStep(source, "Bend Adj")) + ctl =PADSYNTH::control::pitchBendAdjustment; + else if (findAndStep(source, "Offset Hz")) + ctl =PADSYNTH::control::pitchBendOffset; + else if (findAndStep(source, "440Hz")) + ctl =PADSYNTH::control::baseFrequencyAs440Hz; + else if (findAndStep(source, "Detune")) + ctl =PADSYNTH::control::detuneFrequency; + else if (findAndStep(source, "Equal Temper") || findAndStep(source, "Eq T")) + ctl =PADSYNTH::control::equalTemperVariation; + else if (findAndStep(source, "Octave")) + ctl =PADSYNTH::control::octave; + + if (ctl < UNUSED) + { + allData.data.control = ctl; + return; + } + + allData.data.control = TOPLEVEL::control::unrecognised; + allData.data.source = TOPLEVEL::action::noAction; + cout << "padsynth overflow >" << source << endl; +} + +// ---------------------------- + +void TextData::encodeWaveform(string &source, CommandBlock &allData) +{ + unsigned char ctl = UNUSED; + allData.data.insert = TOPLEVEL::insert::oscillatorGroup; + + if (findAndStep(source, "Harmonic")) + { + if (findCharNum(source, ctl)) + allData.data.control = ctl; + else + { + log(source, " no harmonic number"); + return; + } + + if (findAndStep(source, "Amplitude")) + allData.data.insert = TOPLEVEL::insert::harmonicAmplitude; + else if (findAndStep(source, "Phase")) + allData.data.insert = TOPLEVEL::insert::harmonicPhaseBandwidth; + else + log(source, " no harmonic type"); + } + else if (findAndStep(source, "Oscillator")) + { + if (findAndStep(source, "Random")) + ctl = OSCILLATOR::control::phaseRandomness; + else if (findAndStep(source, "Harm Rnd")) + ctl = OSCILLATOR::control::harmonicAmplitudeRandomness; + } + else if (findAndStep(source, "Harm Mods")) + { + if (findAndStep(source, "Adapt Param")) + ctl = OSCILLATOR::control::adaptiveHarmonicsParameter; + else if (findAndStep(source, "Adapt Base Freq")) + ctl = OSCILLATOR::control::adaptiveHarmonicsBase; + else if (findAndStep(source, "Adapt Power")) + ctl = OSCILLATOR::control::adaptiveHarmonicsPower; + } + else if (findAndStep(source, "Base Mods")) + { + if (findAndStep(source, "Osc")) + { + if (findAndStep(source, "Filt Par 1")) + ctl = OSCILLATOR::control::filterParameter1; + else if (findAndStep(source, "Filt Par 2")) + ctl = OSCILLATOR::control::filterParameter2; + else if (findAndStep(source, "Mod Par 1")) + ctl = OSCILLATOR::control::modulationParameter1; + else if (findAndStep(source, "Mod Par 2")) + ctl = OSCILLATOR::control::modulationParameter2; + else if (findAndStep(source, "Mod Par 3")) + ctl = OSCILLATOR::control::modulationParameter3; + else if (findAndStep(source, "Spect Par")) + ctl = OSCILLATOR::control::spectrumAdjustParameter; + } + else if (findAndStep(source, "Waveshape Par")) + ctl = OSCILLATOR::control::waveshapeParameter; + } + else if (findAndStep(source, "Base Funct")) + { + if (findAndStep(source, "Par")) + ctl = OSCILLATOR::control::baseFunctionParameter; + else if (findAndStep(source, "Mod Par 1")) + ctl = OSCILLATOR::control::baseModulationParameter1; + else if (findAndStep(source, "Mod Par 2")) + ctl = OSCILLATOR::control::baseModulationParameter2; + else if (findAndStep(source, "Mod Par 3")) + ctl = OSCILLATOR::control::baseModulationParameter3; + } + + if (ctl < UNUSED) + { + allData.data.control = ctl; + return; + } + + allData.data.control = TOPLEVEL::control::unrecognised; + allData.data.source = TOPLEVEL::action::noAction; + cout << "waveform overflow >" << source << endl; +} + + +void TextData::encodeResonance(string &source, CommandBlock &allData) +{ + unsigned char ctl = UNUSED; + allData.data.insert = TOPLEVEL::insert::resonanceGroup; + // this might be changed for graph inserts + + if (findAndStep(source, "Max dB")) + ctl = RESONANCE::control::maxDb; + if (findAndStep(source, "Center Freq")) + ctl = RESONANCE::control::centerFrequency; + if (findAndStep(source, "Octaves")) + ctl = RESONANCE::control::octaves; + if (findAndStep(source, "Random")) + ctl = RESONANCE::control::randomType; + + if (ctl < UNUSED) + { + allData.data.control = ctl; + return; + } + + allData.data.control = TOPLEVEL::control::unrecognised; + allData.data.source = TOPLEVEL::action::noAction; + cout << "resonance overflow >" << source << endl; +} + +// ---------------------------- + +void TextData::encodeLFO(string &source, CommandBlock &allData) +{ + unsigned char ctl = UNUSED; + allData.data.insert = TOPLEVEL::insert::LFOgroup; + + if (findAndStep(source, "Freq Random") ||findAndStep(source, "FreqRand")) // must be before Freq + ctl = LFOINSERT::control::frequencyRandomness; + else if (findAndStep(source, "Freq")) + ctl = LFOINSERT::control::speed; + else if (findAndStep(source, "Depth")) + ctl = LFOINSERT::control::depth; + else if (findAndStep(source, "Start")) + ctl = LFOINSERT::control::start; + else if (findAndStep(source, "Delay")) + ctl = LFOINSERT::control::delay; + else if (findAndStep(source, "Amp Random")||findAndStep(source, "AmpRand")) + ctl = LFOINSERT::control::amplitudeRandomness; + else if (findAndStep(source, "Stretch")) + ctl = LFOINSERT::control::stretch; + + if (ctl < UNUSED) + { + allData.data.control = ctl; + return; + } + + allData.data.control = TOPLEVEL::control::unrecognised; + allData.data.source = TOPLEVEL::action::noAction; + cout << "lfo overflow >" << source << endl; +} + + +void TextData::encodeEnvelope(string &source, CommandBlock &allData) +{ + unsigned char ctl = UNUSED; + allData.data.insert = TOPLEVEL::insert::envelopeGroup; + // this might be changed for freemode points + + if (findAndStep(source, "Attack Level") || findAndStep(source, "A val")) + ctl = ENVELOPEINSERT::control::attackLevel; + else if (findAndStep(source, "Attack Time") || findAndStep(source, "A dt")) + ctl = ENVELOPEINSERT::control::attackTime; + else if (findAndStep(source, "Decay Level") || findAndStep(source, "D val")) + ctl = ENVELOPEINSERT::control::decayLevel; + else if (findAndStep(source, "Decay Time") || findAndStep(source, "D dt")) + ctl = ENVELOPEINSERT::control::decayTime; + else if (findAndStep(source, "Sustain Level") || findAndStep(source, "S val")) + ctl = ENVELOPEINSERT::control::sustainLevel; + else if (findAndStep(source, "Release Level") || findAndStep(source, "R val")) + ctl = ENVELOPEINSERT::control::releaseLevel; + else if (findAndStep(source, "Release Time") || findAndStep(source, "R dt")) + ctl =ENVELOPEINSERT::control::releaseTime; + else if (findAndStep(source, "Stretch")) + ctl = ENVELOPEINSERT::control::stretch; + + if (ctl < UNUSED) + { + allData.data.control = ctl; + return; + } + + allData.data.control = TOPLEVEL::control::unrecognised; + allData.data.source = TOPLEVEL::action::noAction; + cout << "envelope overflow >" << source << endl; +} + + +void TextData::encodeFilter(string &source, CommandBlock &allData) +{ + unsigned char ctl = UNUSED; + allData.data.insert = TOPLEVEL::insert::filterGroup; + + if (findAndStep(source, "C_Freq") || findAndStep(source, "C Freq") || findAndStep(source, "Cent Freq")) + ctl = FILTERINSERT::control::centerFrequency; + else if (findAndStep(source, "Q")) + ctl = FILTERINSERT::control::Q; + else if (findAndStep(source, "VsensA") || findAndStep(source, "Velocity Sense")) + ctl = FILTERINSERT::control::velocitySensitivity; + else if (findAndStep(source, "Vsens") || findAndStep(source, "Velocity Sense Curve")) + ctl = FILTERINSERT::control::velocityCurve; + else if (findAndStep(source, "ain")) // missing G/g deliberate + ctl = FILTERINSERT::control::gain; + else if (findAndStep(source, "Freq Track") || findAndStep(source, "FreqTrk")) + ctl = FILTERINSERT::control::frequencyTracking; + + else if (findAndStep(source, "Form")) + { + if (findAndStep(source, "Morph") || findAndStep(source, "Fr Sl")) + ctl = FILTERINSERT::control::formantSlowness; + else if (findAndStep(source, "Lucidity") || findAndStep(source, "Vw Cl")) + ctl = FILTERINSERT::control::formantClearness; + else if (findAndStep(source, "Stretch")) + ctl = FILTERINSERT::control::formantStretch; + else if (findAndStep(source, "Cent Freq")) + ctl = FILTERINSERT::control::formantCenter; + else if (findAndStep(source, "Octave")) + ctl = FILTERINSERT::control::formantOctave; + } + + else if (findAndStep(source, "Vowel")) + { + unsigned char Vnum = UNUSED - 1; // special cases + unsigned char Fnum = UNUSED - 1; // actually have printed zeros + if (findCharNum(source, Vnum)) + allData.data.offset = Vnum + 1; + else + { + log(source, "no vowel number"); + return; + } + if (findAndStep(source, "Formant")) + { + if (findCharNum(source, Fnum)) + allData.data.parameter = Fnum + 1; + else + { + log(source, "no formant number"); + return; + } + if (findAndStep(source, "Form Freq")) + ctl = FILTERINSERT::control::formantFrequency; + else if (findAndStep(source, "Form Q")) + ctl = FILTERINSERT::control::formantQ; + else if (findAndStep(source, "Form Amp")) + ctl = FILTERINSERT::control::formantAmplitude; + } + } + + if (ctl < UNUSED) + { + allData.data.control = ctl; + return; + } + + allData.data.control = TOPLEVEL::control::unrecognised; + allData.data.source = TOPLEVEL::action::noAction; + cout << "filter overflow >" << source << endl; +} diff -Nru yoshimi-2.1.1.1~dfsg0/src/Interface/Text2Data.h yoshimi-2.1.2.2~dfsg0/src/Interface/Text2Data.h --- yoshimi-2.1.1.1~dfsg0/src/Interface/Text2Data.h 1970-01-01 00:00:00.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/Interface/Text2Data.h 2021-12-03 20:12:12.000000000 +0000 @@ -0,0 +1,70 @@ +/* + Text2Data.h - conversion of text to commandBlock entries + + Copyright 2021, Will Godfrey + + This file is part of yoshimi, which is free software: you can redistribute + it and/or modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + yoshimi is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License (version 2 or + later) for more details. + + You should have received a copy of the GNU General Public License along with + yoshimi; if not, write to the Free Software Foundation, Inc., 51 Franklin + Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#ifndef TEXTDATA_H +#define TEXTDATA_H + +#include + +#include "globals.h" + +using std::string; + +class SynthEngine; +class TextMsgBuffer; + +class TextData +{ + public: + void encodeAll(SynthEngine *_synth, string &sendCommand, CommandBlock &allData); + + private: + SynthEngine *oursynth; + void log(string &line, string text); + void strip(string &line); + void nextWord(string &line); + bool findCharNum(string &line, unsigned char &value); + bool findAndStep(string &line, string text, bool step = true); + int findListEntry(string &line, int step, string list []); + void encodeLoop(string source, CommandBlock &allData); + + void encodeMain(string &source, CommandBlock &allData); + void encodeScale(string &source, CommandBlock &allData); + void encodePart(string &source, CommandBlock &allData); + + void encodeController(string &source, CommandBlock &allData); + void encodeMidi(string &source, CommandBlock &allData); + void encodeEffects(string &source, CommandBlock &allData); + + void encodeAddSynth(string &source, CommandBlock &allData); + void encodeAddVoice(string &source, CommandBlock &allData); + void encodeSubSynth(string &source, CommandBlock &allData); + void encodePadSynth(string &source, CommandBlock &allData); + + void encodeWaveform(string &source, CommandBlock &allData); + void encodeResonance(string &source, CommandBlock &allData); + + void encodeLFO(string &source, CommandBlock &allData); + void encodeEnvelope(string &source, CommandBlock &allData); + void encodeFilter(string &source, CommandBlock &allData); + +}; +#endif // TEXTDATA_H diff -Nru yoshimi-2.1.1.1~dfsg0/src/Interface/TextLists.h yoshimi-2.1.2.2~dfsg0/src/Interface/TextLists.h --- yoshimi-2.1.1.1~dfsg0/src/Interface/TextLists.h 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/Interface/TextLists.h 2021-12-03 20:12:12.000000000 +0000 @@ -133,7 +133,7 @@ " WAIT ", "1mS to 30,000mS delay, within script only", "..", "step back one level", "/", "step back to top level", - "@end" + "@end","@end" }; static std::string toplist [] = { @@ -179,7 +179,7 @@ " SOlo [s]", "channel 'solo' switch type (ROw, COlumn, LOop, TWoway, CHannel {other} off)", " SOlo CC ", "incoming 'solo' CC number (type must be set first)", " CLear ", "restore instrument on part n to default settings", - "@end" + "@end","@end" }; static std::string configlist [] = { @@ -224,7 +224,7 @@ "Nrpn [s]", "incoming NRPN (ON, {other})", "Log [s]", "incoming MIDI CCs (ON, {other})", "SHow [s]", "GUI MIDI learn editor (ON, {other})", - "@end" + "@end","@end" }; static std::string banklist [] = { @@ -238,7 +238,7 @@ // "Swap [n2]", "Swap current bank with bank n1, (opt. in root n2)", "INstrument Rename ", "change the name of slot n in the current bank", "INstrument SAve ", "save current part's instrument to bank slot n", - "@end" + "@end","@end" }; static std::string partlist [] = { @@ -293,7 +293,7 @@ "SUBsynth ...", "enter SubSynth context", "PADsynth ...", "enter PadSynth context", "MCOntrol ...", "enter MIDI controllers context", - "@end" + "@end","@end" }; static std::string mcontrollist [] = { @@ -329,7 +329,7 @@ "E Cutoff ", "emulate filter cutoff controller", "E Q ", "emulate filter Q controller", "E BAndwidth ", "emulate bandwidth controller", - "@end" + "@end","@end" }; static std::string commonlist [] = { @@ -371,7 +371,7 @@ "*-voice", "not AddVoice", "&", "AddSynth & PadSynth only", "#", "SubSynth & PadSynth only", - "@end" + "@end","@end" }; static std::string addsynthlist [] = { @@ -400,7 +400,7 @@ "FILter ...", "enter Filter insert context", "ENVelope ...", "enter Envelope insert context", "REsonance ...", "enter Resonance context", - "@end" + "@end","@end" }; static std::string addvoicelist [] = { @@ -441,7 +441,7 @@ "LFO ...", "enter LFO insert context", "FILter ...", "enter Filter insert context", "ENVelope ...", "enter Envelope insert context", - "@end" + "@end","@end" }; static std::string addmodlist [] = { @@ -468,7 +468,7 @@ "FIXed ", "set modulator frequency to 440Hz (ON, {other})", "SHift ", "oscillator relative phase", "WAveform ...", "enter the oscillator waveform context", - "@end" + "@end","@end" }; // need to find a way to avoid this kind of duplication @@ -506,7 +506,7 @@ "BAnd Scale ", "bandwidth slope v frequency", "FILter ...", "enter Filter insert context", "ENVelope ...", "enter Envelope insert context", - "@end" + "@end","@end" }; static std::string padsynthlist [] = { @@ -568,7 +568,7 @@ "LFO ...", "enter LFO insert context", "FILter ...", "enter Filter insert context", "ENVelope ...", "enter Envelope insert context", - "@end" + "@end","@end" }; static std::string resonancelist [] = { @@ -582,7 +582,8 @@ "Smooth", "reduce range and sharpness of peaks", "CLear", "set all points to mid level", "POints [ [n2]]", "show all or set/read n1 to n2", - "@end" + "APply", "puts latest changes into the wavetable", + "@end","@end" }; static std::string waveformlist [] = { @@ -629,7 +630,7 @@ "ADdaptive Level ", "adaptive power", "ADdaptive Par ", "adaptive parameter", "APply", "fix settings (only for PadSynth)", - "@end" + "@end","@end" }; static std::string LFOlist [] = { @@ -651,7 +652,7 @@ "","SIne, TRiangle, SQuare, RUp (ramp up), RDown (ramp down), E1down (exp. 1), E2down (exp. 1)", "","SH (sample/hold), RSU (rand square up), RSD (rand square down)", "e.g. S FI T RU", "set filter type ramp up", - "@end" + "@end","@end" }; // TODO need to find a way to safely (and efficiently) combine these static std::string LFOtype [] = { @@ -708,7 +709,7 @@ " FFrequency ", "center frequency of formant", " FQ ", "bandwidth of formant", " FGain ", "amplitude of formant", - "@end" + "@end","@end" }; static std::string envelopelist [] = { @@ -742,7 +743,7 @@ "Insert ", "insert point at n1 with X increment n2, Y value n3", "Delete ", "remove point n", "Change ", "change point n1 to X increment n2, Y value n3", - "@end" + "@end","@end" }; static std::string reverblist [] = { @@ -757,7 +758,7 @@ "TYPe ", "reverb type (Random, Freeverb, Bandwidth)", "ROOm ", "room size", "BANdwidth ", "actual bandwidth (only for bandwidth type)", - "@end" + "@end","@end" }; static std::string echolist [] = { @@ -769,7 +770,7 @@ "FEEdback ", "echo feedback", "DAMp ", "feedback damping", "BPM ", "delay BPM sync (ON {other})", - "@end" + "@end","@end" }; static std::string choruslist [] = { @@ -786,7 +787,7 @@ "SUBtract ", "invert output (ON {other})", "BPM ", "LFO BPM sync (ON {other})", "STArt ", "LFO BPM phase start", - "@end" + "@end","@end" }; static std::string phaserlist [] = { @@ -807,7 +808,7 @@ "ANAlog ", "analog emulation (ON {other})", "BPM ", "LFO BPM sync (ON {other})", "STArt ", "LFO BPM phase start", - "@end" + "@end","@end" }; static std::string alienwahlist [] = { @@ -824,7 +825,7 @@ "RELative ", "relative phase", "BPM ", "LFO BPM sync (ON {other})", "STArt ", "LFO BPM phase start", - "@end" + "@end","@end" }; static std::string distortionlist [] = { @@ -834,25 +835,25 @@ "DRIve ", "input level", "OUTput ", "output balance", "WAVe ", "function waveshape", - "","(ATAn, ASYm1, POWer, SINe, QNTs, ZIGzag, LMT, ULMt, LLMt, ILMt, CLIp, AS2, PO2, SGM)", + "-","(ATAn, ASYm1, POWer, SINe, QNTs, ZIGzag, LMT, ULMt, LLMt, ILMt, CLIp, AS2, PO2, SGM)", "INVert ", "invert ? (ON {other})", "LOW ", "low pass filter", "HIGh ", "high pass filter", "STEreo ", "stereo (ON {other})", "FILter ", "filter before distortion", - "@end" + "@end","@end" }; static std::string eqlist [] = { "LEVel ", "intensity", "BANd ", "EQ band number for following controls", "FILter ", "filter type", - "","(LP1, HP1, LP2, HP2, NOT, PEA, LOW, HIG)", + "-","(LP1, HP1, LP2, HP2, NOT, PEA, LOW, HIG)", "FREquency ", "cutoff/band frequency", "GAIn ", "makeup gain", "Q ", "filter Q", "STAges ", "filter stages", - "@end" + "@end","@end" }; static std::string dynfilterlist [] = { @@ -869,7 +870,7 @@ "FILter ...", "enter dynamic filter context", "BPM ", "LFO BPM sync (ON {other})", "STArt ", "LFO BPM phase start", - "@end" + "@end","@end" }; static std::string filtershapes [] = {"OFF" ,"ATA", "ASY", "POW", "SIN", "QNT", "ZIG", "LMT", "ULM", "LLM", "ILM", "CLI", "CLI", "AS2", "PO2", "SGM", "@end"}; @@ -884,7 +885,7 @@ "MAx ", "set maximum percentage", "LImit ", "limit instead of compress (ON, {other})", "BLock ", "inhibit others on this CC/Chan pair (ON, {other})", - "@end" + "@end","@end" }; static std::string vectlist [] = { @@ -896,7 +897,7 @@ "[X/Y] Control ", "sets n2 CC to use for X or Y feature n1 (2-4)", "OFF", "disable vector for this channel", "Name ", "text name for this complete vector", - "@end" + "@end","@end" }; static std::string scalelist [] = { @@ -917,7 +918,7 @@ "NAme ", "internal name for this scale", "DEscription ", "description of this scale", "CLEar", "clear all settings and revert to standard scale", - "@end" + "@end","@end" }; static std::string noteslist [] = { // from 21 @@ -938,7 +939,7 @@ "Patchset ", "complete set of instruments from named file", "MLearn ", "midi learned list from named file", "STate ", "all system settings and patch sets from named file", - "@end" + "@end","@end" }; static std::string savelist [] = { @@ -950,7 +951,7 @@ "MLearn ", "midi learned list to named file", "STate ", "all system settings and patch sets to named file", "Config", "current configuration", - "@end", + "@end","@end" }; static std::string listlist [] = { @@ -967,7 +968,7 @@ "History [s]", "recent files (Patchsets, SCales, STates, Vectors, MLearn)", "Effects [s]", "effect types ('all' include preset numbers and names)", "PREsets", "all the presets for the currently selected effect", - "@end" + "@end","@end" }; static std::string testlist [] = { @@ -981,7 +982,7 @@ "BUffersize [n]", "number of samples per Synth-call < global buffsize (=default)", "TArget [s]", "target file path to write sound data (empty: /dev/null)", "EXEcute", "actually trigger the test. Stops all other sound output.", - "@end" + "@end","@end" }; static std::string replies [] = { @@ -1045,11 +1046,13 @@ }; const int type_offset [] = {0, 1, -3, 2, 3, 4, 5, 6, 7, -6, -2, 8, 9, 10, -5, 11, 12, -4, 13, 14, 15, 16, 255}; /* - * the number of the above entries must match + * The number of the above 2 entries must match * @end and 255 are the recognised terminators - * only add negative numbers for backward compatibility - * they will resolve as 'undefined' - * note: can't use -1 as ID here + * The list order is the display order + * Only add negative numbers (for backward compatibility) + * On old synth versions they will resolve as 'undefined' + * + * Note: can't use -1 as ID */ static std::string fx_presets [] = { diff -Nru yoshimi-2.1.1.1~dfsg0/src/LV2_Plugin/CMakeLists.txt yoshimi-2.1.2.2~dfsg0/src/LV2_Plugin/CMakeLists.txt --- yoshimi-2.1.1.1~dfsg0/src/LV2_Plugin/CMakeLists.txt 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/LV2_Plugin/CMakeLists.txt 2021-12-03 20:12:12.000000000 +0000 @@ -46,6 +46,7 @@ ../Interface/MidiDecode.cpp ../Interface/MidiDecode.h ../Interface/InterChange.cpp ../Interface/InterChange.h ../Interface/Data2Text.cpp ../Interface/Data2text.h + ../Interface/Text2Data.cpp ../Interface/Text2Data.h ../Interface/RingBuffer.h ../Interface/MidiLearn.cpp ../Interface/MidiLearn.h ../UI/MiscGui.cpp ../UI/MiscGui.h) diff -Nru yoshimi-2.1.1.1~dfsg0/src/LV2_Plugin/YoshimiLV2Plugin.cpp yoshimi-2.1.2.2~dfsg0/src/LV2_Plugin/YoshimiLV2Plugin.cpp --- yoshimi-2.1.1.1~dfsg0/src/LV2_Plugin/YoshimiLV2Plugin.cpp 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/LV2_Plugin/YoshimiLV2Plugin.cpp 2021-12-03 20:12:12.000000000 +0000 @@ -25,6 +25,7 @@ #include "Misc/SynthEngine.h" #include "Interface/InterChange.h" #include "Interface/Data2Text.h" +#include "Interface/Text2Data.h" #include "Interface/MidiDecode.h" #include "MusicIO/MusicClient.h" #ifdef GUI_FLTK diff -Nru yoshimi-2.1.1.1~dfsg0/src/main.cpp yoshimi-2.1.2.2~dfsg0/src/main.cpp --- yoshimi-2.1.1.1~dfsg0/src/main.cpp 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/main.cpp 2021-12-03 20:12:12.000000000 +0000 @@ -128,76 +128,87 @@ map::iterator it; #ifdef GUI_FLTK - - Fl::lock(); const int textHeight = 15; const int textY = 10; const unsigned char lred = 0xd7; const unsigned char lgreen = 0xf7; const unsigned char lblue = 0xff; - int winH, winW; - int LbX, LbY, LbW, LbH; - int timeout; - + int winH=10, winW=50; + int LbX=2, LbY=2, LbW=2, LbH=2; + int timeout =3; std::string startup = YOSHIMI_VERSION; - if (showSplash) - { - startup = "V " + startup; - winH = splashHeight; - winW = splashWidth; - LbX = 0; - LbY = winH - textY - textHeight; - LbW = winW; - LbH = textHeight; - timeout = 5; - } - else + + if (bShowGui) { - startup = "Yoshimi V " + startup + " is starting"; - winH = 36; - winW = 300; - LbX = 2; - LbY = 2; - LbW = winW - 4; - LbH = winH -4; - timeout = 3; - } + Fl::lock(); + + if (showSplash) + { + startup = "V " + startup; + winH = splashHeight; + winW = splashWidth; + LbX = 0; + LbY = winH - textY - textHeight; + LbW = winW; + LbH = textHeight; + timeout = 5; + } + else + { + startup = "Yoshimi V " + startup + " is starting"; + winH = 36; + winW = 300; + LbX = 2; + LbY = 2; + LbW = winW - 4; + LbH = winH -4; + timeout = 3; + } + }//bShowGui + Fl_PNG_Image pix("splash_screen_png", splashPngData, splashPngLength); Fl_Window winSplash(winW, winH, "yoshimi splash screen"); Fl_Box box(0, 0, winW,winH); Fl_Box boxLb(LbX, LbY, LbW, LbH, startup.c_str()); - if (showSplash) + if (bShowGui) { - box.image(pix); - boxLb.box(FL_NO_BOX); - boxLb.align(FL_ALIGN_CENTER); - boxLb.labelsize(textHeight); - boxLb.labeltype(FL_NORMAL_LABEL); - boxLb.labelcolor(fl_rgb_color(lred, lgreen, lblue)); - boxLb.labelfont(FL_HELVETICA | FL_BOLD); - } - else - { - boxLb.box(FL_EMBOSSED_FRAME); - boxLb.labelsize(16); - boxLb.labelfont(FL_BOLD); - boxLb.labelcolor(YOSHI_COLOUR); - } - winSplash.border(false); - if (splashSet && bShowGui) - { - winSplash.position((Fl::w() - winSplash.w()) / 2, (Fl::h() - winSplash.h()) / 2); + if (showSplash) + { + box.image(pix); + boxLb.box(FL_NO_BOX); + boxLb.align(FL_ALIGN_CENTER); + boxLb.labelsize(textHeight); + boxLb.labeltype(FL_NORMAL_LABEL); + boxLb.labelcolor(fl_rgb_color(lred, lgreen, lblue)); + boxLb.labelfont(FL_HELVETICA | FL_BOLD); + } + else + { + boxLb.box(FL_EMBOSSED_FRAME); + boxLb.labelsize(16); + boxLb.labelfont(FL_BOLD); + boxLb.labelcolor(YOSHI_COLOUR); + } + winSplash.border(false); + if (splashSet && bShowGui) + { + winSplash.position((Fl::w() - winSplash.w()) / 2, (Fl::h() - winSplash.h()) / 2); + } + else + splashSet = false; + do + { + winSplash.show(); + usleep(33333); + } + while (firstSynth == NULL); // just wait } - else - splashSet = false; - do + else /* not bShowGui */ +#endif /*GUI_FLTK*/ { - winSplash.show(); - usleep(33333); + while (firstSynth == NULL); // just wait } -#endif - while (firstSynth == NULL); // just wait if (firstRuntime->autoInstance) newBlock(); @@ -527,7 +538,8 @@ firstSynth->loadHistory(); firstSynth->installBanks(); #ifdef GUI_FLTK - GuiThreadMsg::sendMessage(firstSynth, GuiThreadMsg::NewSynthEngine, 0); + if (bShowGui) + GuiThreadMsg::sendMessage(firstSynth, GuiThreadMsg::NewSynthEngine, 0); #endif //create command line processing thread diff -Nru yoshimi-2.1.1.1~dfsg0/src/Misc/CmdOptions.cpp yoshimi-2.1.2.2~dfsg0/src/Misc/CmdOptions.cpp --- yoshimi-2.1.1.1~dfsg0/src/Misc/CmdOptions.cpp 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/Misc/CmdOptions.cpp 2021-12-03 20:12:12.000000000 +0000 @@ -132,6 +132,13 @@ base->gui = 1; break; + case 'j': + if (arg) + base->settings.push_back("j:" + string(arg)); + else + base->settings.push_back("j:"); + break; + case 'J': if (arg) base->settings.push_back("J:" + string(arg)); diff -Nru yoshimi-2.1.1.1~dfsg0/src/Misc/ConfBuild.h yoshimi-2.1.2.2~dfsg0/src/Misc/ConfBuild.h --- yoshimi-2.1.1.1~dfsg0/src/Misc/ConfBuild.h 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/Misc/ConfBuild.h 2021-12-03 20:12:12.000000000 +0000 @@ -2,4 +2,4 @@ ConfBuild.h */ -#define BUILD_NUMBER 2050 +#define BUILD_NUMBER 2074 diff -Nru yoshimi-2.1.1.1~dfsg0/src/Misc/Microtonal.cpp yoshimi-2.1.2.2~dfsg0/src/Misc/Microtonal.cpp --- yoshimi-2.1.1.1~dfsg0/src/Misc/Microtonal.cpp 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/Misc/Microtonal.cpp 2021-12-03 20:12:12.000000000 +0000 @@ -32,9 +32,11 @@ #include "Misc/XMLwrapper.h" #include "Misc/Microtonal.h" #include "Misc/SynthEngine.h" +#include "Misc/NumericFuncs.h" #include "Misc/FormatFuncs.h" #include "Misc/FileMgrFuncs.h" +using func::power; using file::loadText; using file::findLeafName; using std::cout; @@ -133,7 +135,7 @@ // compute global fine detune, -64.0 .. 63.0 cents float globalfinedetunerap = (Pglobalfinedetune > 64.0f || Pglobalfinedetune < 64.0f) - ? powf(2.0f, (Pglobalfinedetune - 64.0f) / 1200.0f) + ? power<2>((Pglobalfinedetune - 64.0f) / 1200.0f) : 1.0f; // was float globalfinedetunerap = powf(2.0f, (Pglobalfinedetune - 64.0f) / 1200.0f); diff -Nru yoshimi-2.1.1.1~dfsg0/src/Misc/Microtonal.h yoshimi-2.1.2.2~dfsg0/src/Misc/Microtonal.h --- yoshimi-2.1.1.1~dfsg0/src/Misc/Microtonal.h 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/Misc/Microtonal.h 2021-12-03 20:12:12.000000000 +0000 @@ -31,11 +31,13 @@ #include #include #include "globals.h" +#include "Misc/NumericFuncs.h" class SynthEngine; class XMLwrapper; using std::string; +using func::power; const size_t MAX_OCTAVE_SIZE = 128; @@ -120,7 +122,7 @@ inline float Microtonal::getFixedNoteFreq(int note) { - return powf(2.0f, (float)(note - PrefNote) / 12.0f) * PrefFreq; + return power<2>(float(note - PrefNote) / 12.0f) * PrefFreq; } diff -Nru yoshimi-2.1.1.1~dfsg0/src/Misc/NumericFuncs.h yoshimi-2.1.2.2~dfsg0/src/Misc/NumericFuncs.h --- yoshimi-2.1.1.1~dfsg0/src/Misc/NumericFuncs.h 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/Misc/NumericFuncs.h 2021-12-03 20:12:12.000000000 +0000 @@ -3,6 +3,7 @@ Copyright 2010, Alan Calvert Copyright 2014-2021, Will Godfrey and others + Copyright 2021, Hermann Vosseler This file is part of yoshimi, which is free software: you can redistribute it and/or modify it under the terms of the GNU General @@ -47,21 +48,6 @@ } -inline float dB2rap(float dB) { -#if defined(HAVE_EXP10F) - return exp10f((dB) / 20.0f); -#else - return powf(10.0, (dB) / 20.0f); -#endif -} - - -inline float rap2dB(float rap) -{ - return 20.0f * log10f(rap); -} - - inline int version2value(void) { /* @@ -93,6 +79,68 @@ } +/* === Helper for exponential with constant base == */ +/* + * Yoshimi code used the generic power function powf() at various places just to compute the exponential + * for a fixed (and even integral) base. This can be optimised, since b^x = exp(ln(b)*x); and in fact, + * modern optimisers apply this rewriting with --fast-math. But unfortunately these rewritings differ + * slightly (esp. regarding to SSE), which leads to slightly different sample (float numbers) being + * computed on different Compilers/Platforms. + * For sake of reproducibility / acceptance testing we thus apply this optimisation explicitly, + * using inline front-end functions, and storing the precomputed logarithm of the base in a static var. + */ +namespace { + template + struct PowerFunction + { + static_assert(base > 0, "0^x is always zero"); + + static float invoke(float exponent) + { + return expf(LN_BASE * exponent); + } + static const float LN_BASE; + }; + + template + const float PowerFunction::LN_BASE = log(fraction? 1.0/base : double(base)); +} + +/* compute base^exponent for a fixed integral base */ +template +inline float power(float exponent) +{ + return PowerFunction::invoke(exponent); +} + +/* compute 1/base^exponent for a fixed integral base */ +template +inline float powFrac(float exponent) +{ + return PowerFunction::invoke(exponent); +} + + +/* Amplitude factor for volume attenuation in deciBel. + * Power ~ Amplitude^2 = 10^(dB/10). sqrt(10^x) = 10^(x/2) + * The template parameter "scale" defines how the function argument is mapped. + * If e.g. scale = -60, then param=1 => -60dB, param=0 => 0dB, param=-0.5 => +30dB + * If scale = 1, then the param is directly in decibel. + */ +template +inline float decibel(float param) +{ + return power<10>(float(scale)/20.0f * param); +} + +/* convert an amplitude factor into dB (volume) */ +inline float asDecibel(float amplitude) +{ + return 20.0f * log10f(amplitude); +} + + + // no more than 32 bit please! inline unsigned int nearestPowerOf2(unsigned int x, unsigned int min, unsigned int max) { @@ -191,6 +239,7 @@ default: // no panning left = 0.7; right = 0.7; + break; } } @@ -222,6 +271,7 @@ default: // no panning left = 0.7; right = 0.7; + break; } } diff -Nru yoshimi-2.1.1.1~dfsg0/src/Misc/Part.cpp yoshimi-2.1.2.2~dfsg0/src/Misc/Part.cpp --- yoshimi-2.1.1.1~dfsg0/src/Misc/Part.cpp 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/Misc/Part.cpp 2021-12-03 20:12:12.000000000 +0000 @@ -50,9 +50,9 @@ using file::isRegularFile; using file::setExtension; using file::findLeafName; -using func::dB2rap; using func::findSplitPoint; using func::setAllPan; +using func::decibel; Part::Part(Microtonal *microtonal_, FFTwrapper *fft_, SynthEngine *_synth) : microtonal(microtonal_), @@ -1272,7 +1272,7 @@ void Part::checkVolume(float step) { TransVolume += step; - volume = dB2rap((TransVolume - 96.0f) / 96.0f * 40.0f); + volume = decibel<-40>(1.0f - TransVolume/96.0f); if (volume < 0.01015f) // done to get a smooth cutoff at what was - 40dB volume = 0.0f; } diff -Nru yoshimi-2.1.1.1~dfsg0/src/Misc/SynthEngine.cpp yoshimi-2.1.2.2~dfsg0/src/Misc/SynthEngine.cpp --- yoshimi-2.1.1.1~dfsg0/src/Misc/SynthEngine.cpp 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/Misc/SynthEngine.cpp 2021-12-03 20:12:12.000000000 +0000 @@ -59,7 +59,7 @@ using file::deleteFile; using file::make_legit_filename; -using func::dB2rap; +using func::decibel; using func::bitTest; using func::asString; using func::string2int; @@ -84,7 +84,7 @@ static vector TuningHistory; static vector KeymapHistory; - static vector historyLastSeen(TOPLEVEL::XML::ScalaMap, ""); + static vector historyLastSeen(TOPLEVEL::XML::ScalaMap + 1, ""); // don't really understand this :( } @@ -163,7 +163,6 @@ uint8_t arr[4]; } x; Runtime.isLittleEndian = (x.arr[0] == 0x44); - meterDelay = 20; ctl = new Controller(this); for (int i = 0; i < NUM_MIDI_CHANNELS; ++ i) Runtime.vectordata.Name[i] = "No Name " + to_string(i + 1); @@ -359,7 +358,7 @@ if (midilearn.loadList(feml)) { #ifdef GUI_FLTK - midilearn.updateGui(); + midilearn.updateGui(); // does nothing if --no-gui #endif Runtime.Log("midiLearn file " + feml + " loaded"); } @@ -2153,9 +2152,9 @@ // Mix the channels according to the part settings about System Effect for (int npart = 0; npart < Runtime.NumAvailableParts; ++npart) { - if (partLocal[npart] // it's enabled - && Psysefxvol[nefx][npart] // it's sending an output - && part[npart]->Paudiodest & 1) // it's connected to the main outs + if (partLocal[npart] // it's enabled + && Psysefxvol[nefx][npart] // it's sending an output + && (part[npart]->Paudiodest & 1)) // it's connected to the main outs { // the output volume of each part to system effect float vol = sysefxvol[nefx][npart]; @@ -2227,12 +2226,12 @@ if (Pvolume - TransVolume > cStep) { TransVolume += cStep; - volume = dB2rap((TransVolume - 96.0f) / 96.0f * 40.0f); + volume = decibel<-40>(1.0f - TransVolume/96.0f); } else if (TransVolume - Pvolume > cStep) { TransVolume -= cStep; - volume = dB2rap((TransVolume - 96.0f) / 96.0f * 40.0f); + volume = decibel<-40>(1.0f - TransVolume/96.0f); } mainL[idx] *= volume; // apply Master Volume mainR[idx] *= volume; @@ -2326,16 +2325,6 @@ { // overload protection below shouldn't be needed :( if (!VUready) return; - if (meterDelay > 0) - { - --meterDelay; - VUdata.values.vuOutPeakL = 0.0f; - VUdata.values.vuOutPeakR = 0.0f; - VUdata.values.vuRmsPeakL = 0.0f; - VUdata.values.vuRmsPeakR = 0.0f; - VUready = true; - return; - } float fade; float root; int buffsize; @@ -2367,7 +2356,7 @@ fade = VUdata.values.vuOutPeakR * 0.92f;// mult; if (fade >= 1.0f) // overload protection - fade = 00.f; + fade = 0.0f; if (VUcopy.values.vuOutPeakR > 1.8f) // overload protection VUcopy.values.vuOutPeakR = fade; else @@ -2422,14 +2411,14 @@ void SynthEngine::setPsysefxvol(int Ppart, int Pefx, char Pvol) { Psysefxvol[Pefx][Ppart] = Pvol; - sysefxvol[Pefx][Ppart] = powf(0.1f, (1.0f - Pvol / 96.0f) * 2.0f); + sysefxvol[Pefx][Ppart] = decibel<-40>(1.0f - Pvol / 96.0f); // Pvol=0..127 => -40dB .. +12.9166dB } void SynthEngine::setPsysefxsend(int Pefxfrom, int Pefxto, char Pvol) { Psysefxsend[Pefxfrom][Pefxto] = Pvol; - sysefxsend[Pefxfrom][Pefxto] = powf(0.1f, (1.0f - Pvol / 96.0f) * 2.0f); + sysefxsend[Pefxfrom][Pefxto] = decibel<-40>(1.0f - Pvol / 96.0f); } void SynthEngine::setPaudiodest(int value) @@ -2689,7 +2678,7 @@ string filetype; string type; string extension; - for (count = TOPLEVEL::XML::Instrument; count < TOPLEVEL::XML::ScalaMap; ++count) + for (count = TOPLEVEL::XML::Instrument; count <= TOPLEVEL::XML::ScalaMap; ++count) { switch (count) { @@ -2739,28 +2728,30 @@ { // should never exceed max history Runtime.historyLock[count] = xml->getparbool("lock_status", false); hist_size = xml->getpar("history_size", 0, 0, MAX_HISTORY); - for (int i = 0; i < hist_size; ++i) + if (hist_size > 0) { - if (xml->enterbranch("XMZ_FILE", i)) + for (int i = 0; i < hist_size; ++i) { - filetype = xml->getparstr(extension); - if (extension == "xiz_file" && !isRegularFile(filetype)) + if (xml->enterbranch("XMZ_FILE", i)) { - if (filetype.rfind(EXTEN::zynInst) != string::npos) - filetype = setExtension(filetype, EXTEN::yoshInst); + filetype = xml->getparstr(extension); + if (extension == "xiz_file" && !isRegularFile(filetype)) + { + if (filetype.rfind(EXTEN::zynInst) != string::npos) + filetype = setExtension(filetype, EXTEN::yoshInst); + } + if (filetype.size() && isRegularFile(filetype)) + newHistory(filetype, count); + xml->exitbranch(); } - if (filetype.size() && isRegularFile(filetype)) - newHistory(filetype, count); - xml->exitbranch(); + } + string tryRecent = xml->getparstr("most_recent"); + //std::cout << "new >" << tryRecent << "<" << std::endl; + if (!tryRecent.empty()) + historyLastSeen.at(count) = tryRecent; } - string tryRecent = xml->getparstr("most_recent"); - //std::cout << "new >" << tryRecent << "<" << std::endl; - if (tryRecent.empty()) - historyLastSeen.at(count) = getHistory(count)->at(0); - else - historyLastSeen.at(count) = tryRecent; xml->exitbranch(); } } @@ -3443,6 +3434,7 @@ case MAIN::control::mono: def = 0; // off max = 1; + type |= learnable; break; case MAIN::control::soloType: @@ -3727,6 +3719,7 @@ break; case CONFIG::control::enableNRPNs: def = 1; + break; case CONFIG::control::saveCurrentConfig: break; diff -Nru yoshimi-2.1.1.1~dfsg0/src/Misc/SynthEngine.h yoshimi-2.1.2.2~dfsg0/src/Misc/SynthEngine.h --- yoshimi-2.1.1.1~dfsg0/src/Misc/SynthEngine.h 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/Misc/SynthEngine.h 2021-12-03 20:12:12.000000000 +0000 @@ -245,7 +245,6 @@ VUtransfer VUpeak, VUcopy, VUdata; unsigned int VUcount; bool VUready; - int meterDelay; void fetchMeterData(void); inline LV2PluginType getLV2PluginType() {return lv2PluginType;} diff -Nru yoshimi-2.1.1.1~dfsg0/src/Misc/WaveShapeSamples.h yoshimi-2.1.2.2~dfsg0/src/Misc/WaveShapeSamples.h --- yoshimi-2.1.1.1~dfsg0/src/Misc/WaveShapeSamples.h 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/Misc/WaveShapeSamples.h 2021-12-03 20:12:12.000000000 +0000 @@ -27,6 +27,11 @@ #include +#include "Misc/NumericFuncs.h" + +using func::power; + + class WaveShapeSamples { public: @@ -87,7 +92,7 @@ smps[i] = asinf(sinf(smps[i] * ws)) / tmpv; break; case 7: - ws = powf(2.0f, -ws * ws * 8.0f); // Limiter + ws = power<2>(-ws * ws * 8.0f); // Limiter for (i = 0; i < n; ++i) { float tmp = smps[i]; @@ -100,7 +105,7 @@ } break; case 8: - ws = powf(2.0f, -ws * ws * 8.0f); // Upper Limiter + ws = power<2>(-ws * ws * 8.0f); // Upper Limiter for (i = 0; i < n; ++i) { float tmp = smps[i]; @@ -110,7 +115,7 @@ } break; case 9: - ws = powf(2.0f, -ws * ws * 8.0f); // Lower Limiter + ws = power<2>(-ws * ws * 8.0f); // Lower Limiter for (i = 0; i < n; ++i) { float tmp = smps[i]; @@ -120,7 +125,7 @@ } break; case 10: - ws = (powf(2.0f, ws * 6.0f) - 1.0f) / powf(2.0f, 6.0f); // Inverse Limiter + ws = (power<2>(ws * 6.0f) - 1.0f) / power<2>(6.0f); // Inverse Limiter for (i = 0; i < n; ++i) { float tmp = smps[i]; @@ -133,7 +138,7 @@ } break; case 11: - ws = powf(5.0f, ws * ws * 1.0f) - 1.0f; // Clip + ws = power<5>(ws * ws * 1.0f) - 1.0f; // Clip for (i = 0; i < n; ++i) smps[i] = smps[i] * (ws + 0.5f) * 0.9999f - floorf(0.5f + smps[i] * (ws + 0.5f) * 0.9999f); break; diff -Nru yoshimi-2.1.1.1~dfsg0/src/MusicIO/JackEngine.cpp yoshimi-2.1.2.2~dfsg0/src/MusicIO/JackEngine.cpp --- yoshimi-2.1.1.1~dfsg0/src/MusicIO/JackEngine.cpp 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/MusicIO/JackEngine.cpp 2021-12-03 20:12:12.000000000 +0000 @@ -175,6 +175,10 @@ * Shows identical results but doesn't connect. * Original 1.4.1 version also fails - it used to work. */ + /* pre V 1.3.0 was this: + if (Runtime.midiEngine == jack_midi and jack_connect(jackClient,Runtime.midiDevice.c_str(),jack_port_name(midi.port))) + Runtime.Log("Didn't find jack MIDI source '" + Runtime.midiDevice + "'"); + */ // style-wise I think the next bit is the wrong place /*if (synth->getRuntime().midiEngine == jack_midi diff -Nru yoshimi-2.1.1.1~dfsg0/src/Params/ADnoteParameters.cpp yoshimi-2.1.2.2~dfsg0/src/Params/ADnoteParameters.cpp --- yoshimi-2.1.1.1~dfsg0/src/Params/ADnoteParameters.cpp 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/Params/ADnoteParameters.cpp 2021-12-03 20:12:12.000000000 +0000 @@ -29,12 +29,12 @@ #include #include #include "Misc/NumericFuncs.h" +#include "Misc/SynthEngine.h" +#include "Params/ADnoteParameters.h" -using namespace std; using func::setAllPan; +using func::power; -#include "Misc/SynthEngine.h" -#include "Params/ADnoteParameters.h" int ADnoteParameters::ADnote_unison_sizes[] = {2, 3, 4, 5, 6, 8, 10, 12, 15, 20, 25, 30, 40, 50, 0}; @@ -217,7 +217,7 @@ float ADnoteParameters::getBandwidthDetuneMultiplier(void) { float bw = (GlobalPar.PBandwidth - 64.0f) / 64.0f; - bw = powf(2.0f, bw * pow(fabs(bw), 0.2f) * 5.0f); + bw = power<2>(bw * pow(fabs(bw), 0.2f) * 5.0f); return bw; } @@ -956,6 +956,7 @@ break; case ADDSYNTH::control::randomWidth: + type |= learnable; def = 63; max = 63; break; @@ -998,20 +999,26 @@ break; case ADDSYNTH::control::dePop: + type |= learnable; def = FADEIN_ADJUSTMENT_SCALE; + break; - case ADDSYNTH::control::punchStrength: // just ensures it doesn't get caught by default + case ADDSYNTH::control::punchStrength: + type |= learnable; break; case ADDSYNTH::control::punchDuration: + type |= learnable; def = 60; break; case ADDSYNTH::control::punchStretch: + type |= learnable; def = 64; break; case ADDSYNTH::control::punchVelocity: + type |= learnable; def = 72; break; @@ -1183,6 +1190,7 @@ break; case ADDVOICE::control::enableUnison: + type |= learnable; max = 1; break; diff -Nru yoshimi-2.1.1.1~dfsg0/src/Params/Controller.cpp yoshimi-2.1.2.2~dfsg0/src/Params/Controller.cpp --- yoshimi-2.1.1.1~dfsg0/src/Params/Controller.cpp 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/Params/Controller.cpp 2021-12-03 20:12:12.000000000 +0000 @@ -32,8 +32,13 @@ #include "Misc/XMLwrapper.h" #include "Misc/SynthEngine.h" +#include "Misc/SynthHelper.h" #include "Params/Controller.h" +using func::power; +using func::powFrac; + + Controller::Controller(SynthEngine *_synth): synth(_synth) { @@ -123,7 +128,7 @@ pitchwheel.data = value; float cents = value / 8192.0f; cents *= pitchwheel.bendrange; - pitchwheel.relfreq = powf(2.0f, cents / 1200.0f); + pitchwheel.relfreq = power<2>(cents / 1200.0f); // original comment //fprintf(stderr,"%ld %ld -> %.3f\n",pitchwheel.bendrange,pitchwheel.data,pitchwheel.relfreq);fflush(stderr); } @@ -156,7 +161,7 @@ void Controller::setfilterq(int value) { filterq.data = value; - filterq.relq = powf(30.0f, (value - 64.0f) / 64.0f * (filterq.depth / 64.0f)); + filterq.relq = power<30>((value - 64.0f) / 64.0f * (filterq.depth / 64.0f)); } @@ -165,7 +170,7 @@ bandwidth.data = value; if (!bandwidth.exponential) { - float tmp = powf(25.0f, powf(bandwidth.depth / 127.0f, 1.5f)) - 1.0f; + float tmp = power<25>(powf(bandwidth.depth / 127.0f, 1.5f)) - 1.0f; if (value < 64 && bandwidth.depth >= 64) tmp = 1.0f; bandwidth.relbw = (value / 64.0f - 1.0f) * tmp + 1.0f; @@ -174,7 +179,7 @@ } else { - bandwidth.relbw = powf(25.0f, (value - 64.0f) / 64.0f * (bandwidth.depth / 64.0f)); + bandwidth.relbw = power<25>((value - 64.0f) / 64.0f * (bandwidth.depth / 64.0f)); } } @@ -184,7 +189,7 @@ modwheel.data = value; if (!modwheel.exponential) { - float tmp = powf(25.0f, powf(modwheel.depth / 127.0f, 1.5f) * 2.0f) / 25.0f; + float tmp = power<25>(powf(modwheel.depth / 127.0f, 1.5f) * 2.0f) / 25.0f; if (value < 64 && modwheel.depth >= 64) tmp = 1.0f; modwheel.relmod = (value / 64.0f - 1.0f) * tmp + 1.0f; @@ -192,7 +197,7 @@ modwheel.relmod = 0.0f; } else - modwheel.relmod = powf(25.0f, (value - 64.0f) / 64.0f * (modwheel.depth / 80.0f)); + modwheel.relmod = power<25>((value - 64.0f) / 64.0f * (modwheel.depth / 80.0f)); } @@ -249,7 +254,7 @@ return 0; } - float portamentotime = powf(100.0f, portamento.time / 127.0f) / 50.0f; // portamento time in seconds + float portamentotime = power<100>(portamento.time / 127.0f) / 50.0f; // portamento time in seconds if (portamento.proportional) { @@ -272,13 +277,13 @@ { if (portamento.updowntimestretch == 127) return 0; - portamentotime *= powf(0.1f, (portamento.updowntimestretch - 64) / 63.0f); + portamentotime *= powFrac<10>((portamento.updowntimestretch - 64) / 63.0f); } if (portamento.updowntimestretch < 64 && newfreq > oldfreq) { if (portamento.updowntimestretch == 0) return 0; - portamentotime *= powf(0.1f, (64.0f - portamento.updowntimestretch) / 64.0f); + portamentotime *= powFrac<10>((64.0f - portamento.updowntimestretch) / 64.0f); } portamento.dx = synth->fixed_sample_step_f / portamentotime; @@ -288,7 +293,7 @@ ? portamento.origfreqrap : 1.0 / portamento.origfreqrap ; - float thresholdrap = powf(2.0f, portamento.pitchthresh / 12.0f); + float thresholdrap = power<2>(portamento.pitchthresh / 12.0f); if (portamento.pitchthreshtype == 0 && (tmprap - 0.00001f) > thresholdrap) return 0; if (portamento.pitchthreshtype == 1 && (tmprap + 0.00001f) < thresholdrap) @@ -318,14 +323,19 @@ void Controller::setresonancecenter(int value) { resonancecenter.data = value; - resonancecenter.relcenter = powf(3.0f, (value - 64.0f) / 64.0f * (resonancecenter.depth / 64.0f)); + resonancecenter.relcenter = power<3>((value - 64.0f) / 64.0f * (resonancecenter.depth / 64.0f)); } +namespace { + static const float LN_BASE1_5 = log(1.5); + inline float power1_5(float exponent) { return expf(LN_BASE1_5 * exponent); } // 1.5^exponent +} + void Controller::setresonancebw(int value) { resonancebandwidth.data = value; - resonancebandwidth.relbw = powf(1.5f, (value - 64.0f) / 64.0f * (resonancebandwidth.depth / 127.0f)); + resonancebandwidth.relbw = power1_5((value - 64.0f) / 64.0f * (resonancebandwidth.depth / 127.0f)); } diff -Nru yoshimi-2.1.1.1~dfsg0/src/Params/EnvelopeParams.cpp yoshimi-2.1.2.2~dfsg0/src/Params/EnvelopeParams.cpp --- yoshimi-2.1.1.1~dfsg0/src/Params/EnvelopeParams.cpp 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/Params/EnvelopeParams.cpp 2021-12-03 20:12:12.000000000 +0000 @@ -30,8 +30,12 @@ #include #include "Misc/XMLwrapper.h" +#include "Misc/NumericFuncs.h" #include "Params/EnvelopeParams.h" +using func::power; + + EnvelopeParams::EnvelopeParams(unsigned char Penvstretch_, unsigned char Pforcedrelease_, SynthEngine *_synth) : Presets(_synth), @@ -65,7 +69,7 @@ float EnvelopeParams::getdt(char i) { - float result = (powf(2.0f, Penvdt[(int)i] / 127.0f * 12.0f) - 1.0f) * 10.0f; // milliseconds + float result = (power<2>(Penvdt[(int)i] / 127.0f * 12.0f) - 1.0f) * 10.0f; // milliseconds return result; } diff -Nru yoshimi-2.1.1.1~dfsg0/src/Params/FilterParams.cpp yoshimi-2.1.2.2~dfsg0/src/Params/FilterParams.cpp --- yoshimi-2.1.1.1~dfsg0/src/Params/FilterParams.cpp 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/Params/FilterParams.cpp 2021-12-03 20:12:12.000000000 +0000 @@ -30,7 +30,8 @@ #include "Misc/NumericFuncs.h" #include "Params/FilterParams.h" -using func::rap2dB; +using func::asDecibel; +using func::power; FilterParams::FilterParams(unsigned char Ptype_, unsigned char Pfreq_, unsigned char Pq_, unsigned char Pfreqtrackoffset_, SynthEngine *_synth) : @@ -167,7 +168,7 @@ // Get the center frequency of the formant's graph float FilterParams::getcenterfreq(void) { - return 10000.0f * powf(10.0f, -(1.0f - Pcenterfreq / 127.0f) * 2.0f); + return 10000.0f * power<10>(-(1.0f - Pcenterfreq / 127.0f) * 2.0f); } @@ -183,7 +184,7 @@ { if (x > 1.0f) x = 1.0f; - float octf = powf(2.0f, getoctavesfreq()); + float octf = power<2>(getoctavesfreq()); return getcenterfreq() / sqrtf(octf) * powf(octf, x); } @@ -265,7 +266,7 @@ for (int i = 0; i < nfreqs; ++i) { if (freqs[i] > 0.000000001f) - freqs[i] = rap2dB(freqs[i]) + getgain(); + freqs[i] = asDecibel(freqs[i]) + getgain(); else freqs[i] = -90.0f; } diff -Nru yoshimi-2.1.1.1~dfsg0/src/Params/FilterParams.h yoshimi-2.1.2.2~dfsg0/src/Params/FilterParams.h --- yoshimi-2.1.1.1~dfsg0/src/Params/FilterParams.h 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/Params/FilterParams.h 2021-12-03 20:12:12.000000000 +0000 @@ -29,10 +29,14 @@ #define FILTER_PARAMS_H #include "Params/Presets.h" +#include "Misc/NumericFuncs.h" #include "globals.h" #include +using func::power; +using func::decibel; + class XMLwrapper; class SynthEngine; @@ -66,9 +70,9 @@ float getformantfreq(unsigned char freq) // Transforms a parameter to { return getfreqx(freq / 127.0f); } // the real value float getformantamp(unsigned char amp) - { return powf(0.1f, (1.0f - amp / 127.0f) * 4.0f); } + { return decibel<-80>(1.0f - amp / 127.0f); } float getformantq(unsigned char q) - { return powf(25.0f, (q - 32.0f) / 64.0f); } + { return power<25>((q - 32.0f) / 64.0f); } unsigned char Pcategory; // Filter category (Analog/Formant/StVar) unsigned char Ptype; // Filter type (for analog lpf,hpf,bpf..) diff -Nru yoshimi-2.1.1.1~dfsg0/src/Params/LFOParams.cpp yoshimi-2.1.2.2~dfsg0/src/Params/LFOParams.cpp --- yoshimi-2.1.1.1~dfsg0/src/Params/LFOParams.cpp 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/Params/LFOParams.cpp 2021-12-03 20:12:12.000000000 +0000 @@ -31,8 +31,8 @@ #include "Params/LFOParams.h" #include "Misc/NumericFuncs.h" -//#include -//int LFOParams::time = 0; +using func::power; + LFOParams::LFOParams(float Pfreq_, unsigned char Pintensity_, unsigned char Pstartphase_, unsigned char PLFOtype_, @@ -84,7 +84,7 @@ { PfreqI = n; - Pfreq = (powf(2.0f, (float(n) / float(Fmul2I)) * 10.0f) - 1.0f) / 12.0f; + Pfreq = (power<2>((float(n) / float(Fmul2I)) * 10.0f) - 1.0f) / 12.0f; presetsUpdated(); } diff -Nru yoshimi-2.1.1.1~dfsg0/src/Params/PADnoteParameters.cpp yoshimi-2.1.2.2~dfsg0/src/Params/PADnoteParameters.cpp --- yoshimi-2.1.1.1~dfsg0/src/Params/PADnoteParameters.cpp 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/Params/PADnoteParameters.cpp 2021-12-03 20:12:12.000000000 +0000 @@ -42,6 +42,8 @@ using file::saveData; using func::setAllPan; +using func::power; + PADnoteParameters::PADnoteParameters(FFTwrapper *fft_, SynthEngine *_synth) : Presets(_synth) { @@ -154,7 +156,7 @@ FilterEnvelope->defaults(); FilterLfo->defaults(); deletesamples(); - Papplied = false; + Papplied = 0; } @@ -186,12 +188,12 @@ smp[i] = 0.0f; const int supersample = 16; - float basepar = powf(2.0f, ((1.0f - Php.base.par1 / 127.0f) * 12.0f)); - float freqmult = floorf(powf(2.0f, (Php.freqmult / 127.0f * 5.0f)) + 0.000001f); + float basepar = power<2>(((1.0f - Php.base.par1 / 127.0f) * 12.0f)); + float freqmult = floorf(power<2>((Php.freqmult / 127.0f * 5.0f)) + 0.000001f); - float modfreq = floorf(powf(2.0f, (Php.modulator.freq / 127.0f * 5.0f)) + 0.000001f); + float modfreq = floorf(power<2>((Php.modulator.freq / 127.0f * 5.0f)) + 0.000001f); float modpar1 = powf((Php.modulator.par1 / 127.0f), 4.0f) * 5.0 / sqrtf(modfreq); - float amppar1 = powf(2.0f, powf((Php.amp.par1 / 127.0f), 2.0f) * 10.0f) - 0.999f; + float amppar1 = power<2>(powf((Php.amp.par1 / 127.0f), 2.0f) * 10.0f) - 0.999f; float amppar2 = (1.0f - Php.amp.par2 / 127.0f) * 0.998f + 0.001f; float width = powf((150.0f / (Php.width + 22.0f)), 2.0f); @@ -332,7 +334,7 @@ { this->Pbandwidth = Pbandwidth; float result = powf(Pbandwidth / 1000.0f, 1.1f); - result = powf(10.0f, result * 4.0f) * 0.25f; + result = power<10>(result * 4.0f) * 0.25f; return result; } @@ -341,7 +343,7 @@ float PADnoteParameters::getNhr(int n) { float result = 1.0; - float par1 = powf(10.0f, -(1.0f - Phrpos.par1 / 255.0f) * 3.0f); + float par1 = power<10>(-(1.0f - Phrpos.par1 / 255.0f) * 3.0f); float par2 = Phrpos.par2 / 255.0f; float n0 = n - 1.0f; @@ -437,7 +439,7 @@ continue; //compute the bandwidth of each harmonic float bandwidthcents = setPbandwidth(Pbandwidth); - float bw = (powf(2.0f, bandwidthcents / 1200.0f) - 1.0f) * basefreq / bwadjust; + float bw = (power<2>(bandwidthcents / 1200.0f) - 1.0f) * basefreq / bwadjust; float power = 1.0f; switch (Pbwscale) { @@ -595,7 +597,7 @@ float bwadjust = getprofile(profile, profilesize); // for (int i=0;i(Pquality.basenote / 2); if (Pquality.basenote %2 == 1) basefreq *= 1.5; @@ -623,7 +625,7 @@ for (int nsample = 0; nsample < samplemax; ++nsample) { float tmp = adj[nsample] - adj[samplemax - 1] * 0.5f; - float basefreqadjust = powf(2.0f, tmp); + float basefreqadjust = power<2>(tmp); if (Pmode == 0) generatespectrum_bandwidthMode(&spectrum[0], spectrumsize, @@ -674,7 +676,7 @@ // delete the additional samples that might exists and are not useful for (int i = samplemax; i < PAD_MAX_SAMPLES; ++i) deletesample(i); - Papplied = true; + Papplied = 1; } @@ -1043,11 +1045,13 @@ break; case PADSYNTH::control::randomWidth: + type |= learnable; def = 63; max = 63; break; case PADSYNTH::control::bandwidth: + type |= learnable; def = 500; max = 1000; break; @@ -1208,9 +1212,9 @@ break; case PADSYNTH::control::applyChanges: - min = 0; - def = 0; - max = 0; + type |= learnable; + def = 1; + max = 1; break; case PADSYNTH::control::stereo: diff -Nru yoshimi-2.1.1.1~dfsg0/src/Params/PADnoteParameters.h yoshimi-2.1.2.2~dfsg0/src/Params/PADnoteParameters.h --- yoshimi-2.1.1.1~dfsg0/src/Params/PADnoteParameters.h 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/Params/PADnoteParameters.h 2021-12-03 20:12:12.000000000 +0000 @@ -152,7 +152,7 @@ float setPbandwidth(int Pbandwidth); // returns the BandWidth in cents float getNhr(int n); // gets the n-th overtone position relatively to N harmonic - bool Papplied; + unsigned char Papplied; void applyparameters(void); bool export2wav(std::string basefilename); diff -Nru yoshimi-2.1.1.1~dfsg0/src/Params/SUBnoteParameters.cpp yoshimi-2.1.2.2~dfsg0/src/Params/SUBnoteParameters.cpp --- yoshimi-2.1.1.1~dfsg0/src/Params/SUBnoteParameters.cpp 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/Params/SUBnoteParameters.cpp 2021-12-03 20:12:12.000000000 +0000 @@ -30,6 +30,8 @@ #include "Misc/NumericFuncs.h" using func::setAllPan; +using func::power; + SUBnoteParameters::SUBnoteParameters(SynthEngine *_synth) : Presets(_synth) { @@ -215,8 +217,7 @@ void SUBnoteParameters::updateFrequencyMultipliers(void) { float par1 = POvertoneSpread.par1 / 255.0f; - float par1pow = powf(10.0f, - -(1.0f - POvertoneSpread.par1 / 255.0f) * 3.0f); + float par1pow = power<10>(-(1.0f - POvertoneSpread.par1 / 255.0f) * 3.0f); float par2 = POvertoneSpread.par2 / 255.0f; float par3 = 1.0f - POvertoneSpread.par3 / 255.0f; float result; diff -Nru yoshimi-2.1.1.1~dfsg0/src/Synth/ADnote.cpp yoshimi-2.1.2.2~dfsg0/src/Synth/ADnote.cpp --- yoshimi-2.1.1.1~dfsg0/src/Synth/ADnote.cpp 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/Synth/ADnote.cpp 2021-12-03 20:12:12.000000000 +0000 @@ -42,6 +42,8 @@ #include "globals.h" +using func::power; +using func::decibel; using synth::velF; using synth::getDetune; using synth::interpolateAmplitude; @@ -115,6 +117,7 @@ ctl(orig.ctl), NoteGlobalPar(orig.NoteGlobalPar), time(orig.time), // This is incremented, but never actually used for some reason + Tspot(orig.Tspot), paramRNG(orig.paramRNG), paramSeed(orig.paramSeed), detuneFromParent(orig.detuneFromParent), @@ -414,9 +417,9 @@ NoteGlobalPar.Punch.Enabled = 1; NoteGlobalPar.Punch.t = 1.0f; //start from 1.0 and to 0.0 NoteGlobalPar.Punch.initialvalue = - ((powf(10.0f, 1.5f * adpars->GlobalPar.PPunchStrength / 127.0f) - 1.0f) + ((power<10>(1.5f * adpars->GlobalPar.PPunchStrength / 127.0f) - 1.0f) * velF(velocity, adpars->GlobalPar.PPunchVelocitySensing)); - float time = powf(10.0f, 3.0f * adpars->GlobalPar.PPunchTime / 127.0f) / 10000.0f; // 0.1 .. 100 ms + float time = power<10>(3.0f * adpars->GlobalPar.PPunchTime / 127.0f) / 10000.0f; // 0.1 .. 100 ms float stretch = powf(440.0f / basefreq, adpars->GlobalPar.PPunchStretch / 64.0f); NoteGlobalPar.Punch.dt = 1.0f / (time * synth->samplerate_f * stretch); } @@ -609,6 +612,7 @@ default: NoteVoicePar[nvoice].FMEnabled = NONE; freqbasedmod[nvoice] = false; + break; } NoteVoicePar[nvoice].FMringToSide = adpars->VoicePar[nvoice].PFMringToSide; NoteVoicePar[nvoice].FMVoice = adpars->VoicePar[nvoice].PFMVoice; @@ -1165,7 +1169,8 @@ bandwidthDetuneMultiplier = adpars->getBandwidthDetuneMultiplier(); NoteGlobalPar.Volume = - 4.0f * powf(0.1f, 3.0f * (1.0f - adpars->GlobalPar.PVolume / 96.0f)) //-60 dB .. 0 dB + 4.0f // +12dB boost (similar on PADnote, while SUBnote only boosts +6dB) + * decibel<-60>(1.0f - adpars->GlobalPar.PVolume / 96.0f) // -60 dB .. +19.375 dB * velF(velocity, adpars->GlobalPar.PAmpVelocityScaleFunction); // velocity sensing for (int nvoice = 0; nvoice < NUM_VOICES; ++nvoice) @@ -1268,6 +1273,7 @@ fmvoldamp = 1.0f; NoteVoicePar[nvoice].FMVolume = adpars->VoicePar[nvoice].PFMVolume / 127.0f * fmvoldamp; + break; } // Voice's modulator velocity sensing @@ -1279,7 +1285,7 @@ NoteVoicePar[nvoice].Volume = 0.0f; else NoteVoicePar[nvoice].Volume = - powf(0.1f, 3.0f * (1.0f - adpars->VoicePar[nvoice].PVolume / 127.0f)) // -60 dB .. 0 dB + decibel<-60>(1.0f - adpars->VoicePar[nvoice].PVolume / 127.0f) // -60 dB .. 0 dB * velF(velocity, adpars->VoicePar[nvoice].PAmpVelocityScaleFunction); // velocity if (adpars->VoicePar[nvoice].PVolumeminus) @@ -1356,7 +1362,7 @@ unison_stereo_spread[nvoice] = adpars->VoicePar[nvoice].Unison_stereo_spread / 127.0f; float unison_spread = adpars->getUnisonFrequencySpreadCents(nvoice); - float unison_real_spread = powf(2.0f, (unison_spread * 0.5f) / 1200.0f); + float unison_real_spread = power<2>((unison_spread * 0.5f) / 1200.0f); float unison_vibratto_a = adpars->VoicePar[nvoice].Unison_vibratto / 127.0f; //0.0 .. 1.0 int true_unison = unison >> is_pwm; @@ -1394,9 +1400,10 @@ (unison_values[k] - (max + min) * 0.5f) / diff; // the lowest value will be -1 and the highest will be 1 unison_base_freq_rap[nvoice][k] = - powf(2.0f, (unison_spread * unison_values[k]) / 1200.0f); + power<2>((unison_spread * unison_values[k]) / 1200.0f); } } + break; } if (is_pwm) for (int i = true_unison - 1; i >= 0; i--) @@ -1420,11 +1427,11 @@ float increments_per_second = 1 / synth->fixed_sample_step_f; const float vib_speed = adpars->VoicePar[nvoice].Unison_vibratto_speed / 127.0f; - float vibratto_base_period = 0.25f * powf(2.0f, (1.0f - vib_speed) * 4.0f); + float vibratto_base_period = 0.25f * power<2>((1.0f - vib_speed) * 4.0f); for (int k = 0; k < unison; ++k) { // make period to vary randomly from 50% to 200% vibratto base period - float vibratto_period = vibratto_base_period * powf(2.0f, paramRNG.numRandom() * 2.0f - 1.0f); + float vibratto_period = vibratto_base_period * power<2>(paramRNG.numRandom() * 2.0f - 1.0f); float m = 4.0f / (vibratto_period * increments_per_second); if (unison_vibratto[nvoice].step[k] < 0.0f) m = -m; @@ -1483,7 +1490,7 @@ float freq; if (NoteVoicePar[nvoice].FMFreqFixed) - return 440.0f * powf(2.0f, detune / 12.0f); + return 440.0f * power<2>(detune / 12.0f); if (NoteVoicePar[nvoice].FMDetuneFromBaseOsc) freq = getVoiceBaseFreq(nvoice); @@ -1494,7 +1501,7 @@ detune += NoteGlobalPar.Detune / 100.0f; } - return freq * powf(2.0f, detune / 12.0f); + return freq * power<2>(detune / 12.0f); } @@ -1591,7 +1598,7 @@ detune += NoteGlobalPar.Detune / 100.0f; if (!NoteVoicePar[nvoice].fixedfreq) - return basefreq * powf(2.0f, detune / 12.0f); + return basefreq * power<2>(detune / 12.0f); else // fixed freq is enabled { float fixedfreq; @@ -1604,13 +1611,13 @@ int fixedfreqET = NoteVoicePar[nvoice].fixedfreqET; if (fixedfreqET) { // if the frequency varies according the keyboard note - float tmp = (midinote - 69.0f) / 12.0f * (powf(2.0f, (fixedfreqET - 1) / 63.0f) - 1.0f); + float tmp = (midinote - 69.0f) / 12.0f * (power<2>((fixedfreqET - 1) / 63.0f) - 1.0f); if (fixedfreqET <= 64) - fixedfreq *= powf(2.0f, tmp); + fixedfreq *= power<2>(tmp); else - fixedfreq *= powf(3.0f, tmp); + fixedfreq *= power<3>(tmp); } - return fixedfreq * powf(2.0f, detune / 12.0f); + return fixedfreq * power<2>(detune / 12.0f); } } @@ -1721,7 +1728,7 @@ } float nonoffsetfreq = getVoiceBaseFreq(nvoice) - * powf(2.0f, (voicepitch + globalpitch) / 12.0f); + * power<2>((voicepitch + globalpitch) / 12.0f); nonoffsetfreq *= portamentofreqrap; float voicefreq = nonoffsetfreq + NoteVoicePar[nvoice].OffsetHz; voicepitch += log2f(voicefreq / nonoffsetfreq) * 12.0f; @@ -1753,16 +1760,16 @@ if (NoteVoicePar[nvoice].FMFreqFixed) { // Apply FM detuning since base frequency is 440Hz. FMrelativepitch += NoteVoicePar[nvoice].FMDetune / 100.0f; - FMfreq = powf(2.0f, FMrelativepitch / 12.0f) * 440.0f; + FMfreq = power<2>(FMrelativepitch / 12.0f) * 440.0f; } else if (NoteVoicePar[nvoice].FMDetuneFromBaseOsc) { // Apply FM detuning since base frequency is from main voice. FMrelativepitch += NoteVoicePar[nvoice].FMDetune / 100.0f; - FMfreq = powf(2.0f, FMrelativepitch / 12.0f) * voicefreq; + FMfreq = power<2>(FMrelativepitch / 12.0f) * voicefreq; } else { // No need to apply FM detuning, since getFMVoiceBaseFreq() // takes it into account. FMfreq = getFMVoiceBaseFreq(nvoice) * - powf(2.0f, (basevoicepitch + globalpitch + FMrelativepitch) / 12.0f); + power<2>((basevoicepitch + globalpitch + FMrelativepitch) / 12.0f); FMfreq *= portamentofreqrap; } setfreqFM(nvoice, FMfreq, FMpitch); @@ -2246,8 +2253,7 @@ void ADnote::computeVoiceOscillatorForFMFrequencyModulation(int nvoice) { - // See computeVoiceModulatorForFMFrequencyModulation for details on how this - // works. + // See computeVoiceModulatorForFMFrequencyModulation for details on how this works. for (int k = 0; k < unison_size[nvoice]; ++k) { float *tw = tmpwave_unison[k]; @@ -2401,6 +2407,7 @@ break; default: ComputeVoiceSpotNoise(nvoice); // spot noise + break; } } @@ -2811,5 +2818,3 @@ if (NoteStatus == NOTE_KEEPALIVE) NoteStatus = NOTE_ENABLED; } - -// for future reference ... re replacing pow(x, y) by exp(y * log(x)) diff -Nru yoshimi-2.1.1.1~dfsg0/src/Synth/ADnote.h yoshimi-2.1.2.2~dfsg0/src/Synth/ADnote.h --- yoshimi-2.1.1.1~dfsg0/src/Synth/ADnote.h 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/Synth/ADnote.h 2021-12-03 20:12:12.000000000 +0000 @@ -214,7 +214,8 @@ float FMDetune; // in cents Envelope *FMFreqEnvelope; Envelope *FMAmpEnvelope; - } NoteVoicePar[NUM_VOICES]; + }; + ADnoteVoice NoteVoicePar[NUM_VOICES]; // Internal values of the note and of the voices float time; // time from the start of the note diff -Nru yoshimi-2.1.1.1~dfsg0/src/Synth/Envelope.cpp yoshimi-2.1.2.2~dfsg0/src/Synth/Envelope.cpp --- yoshimi-2.1.1.1~dfsg0/src/Synth/Envelope.cpp 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/Synth/Envelope.cpp 2021-12-03 20:12:12.000000000 +0000 @@ -28,8 +28,9 @@ #include "Misc/NumericFuncs.h" #include "Params/EnvelopeParams.h" -using func::dB2rap; -using func::rap2dB; +using func::power; +using func::decibel; +using func::asDecibel; Envelope::Envelope(EnvelopeParams *envpars, float basefreq_, SynthEngine *_synth): @@ -90,7 +91,7 @@ case 3: envval[i] = - (powf(2.0f, 6.0f * fabsf(_envpars->Penvval[i] - 64.0f) / 64.0f) - 1.0f) * 100.0f; + (power<2>(6.0f * fabsf(_envpars->Penvval[i] - 64.0f) / 64.0f) - 1.0f) * 100.0f; if (_envpars->Penvval[i] < 64) envval[i] = -envval[i]; break; @@ -105,6 +106,7 @@ default: envval[i] = _envpars->Penvval[i] / 127.0f; + break; } } } @@ -191,9 +193,9 @@ return envout(); if (currentpoint == 1 && (keyreleased == 0 || forcedrelase == 0)) - { // first point is always lineary interpolated - float v1 = dB2rap(envval[0]); - float v2 = dB2rap(envval[1]); + { // first point is always linearly interpolated + float v1 = decibel(envval[0]); + float v2 = decibel(envval[1]); out = v1 + (v2 - v1) * t; float bufferdt = synth->sent_buffersize_f / synth->samplerate_f; @@ -210,11 +212,11 @@ } if (out > 0.001f) - envoutval = rap2dB(out); + envoutval = asDecibel(out); else envoutval = MIN_ENVELOPE_DB; } else - out = dB2rap(envout()); + out = decibel(envout()); return out; } diff -Nru yoshimi-2.1.1.1~dfsg0/src/Synth/LFO.cpp yoshimi-2.1.2.2~dfsg0/src/Synth/LFO.cpp --- yoshimi-2.1.1.1~dfsg0/src/Synth/LFO.cpp 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/Synth/LFO.cpp 2021-12-03 20:12:12.000000000 +0000 @@ -28,8 +28,12 @@ #include #include "Misc/SynthEngine.h" +#include "Misc/SynthHelper.h" #include "Synth/LFO.h" +using func::power; +using func::powFrac; + LFO::LFO(LFOParams *_lfopars, float _basefreq, SynthEngine *_synth): lfopars(_lfopars), @@ -107,7 +111,7 @@ break; // in octave default: - lfointensity = powf(2.0f, lfopars->Pintensity / 127.0f * 11.0f) - 1.0f; // in centi + lfointensity = power<2>(lfopars->Pintensity / 127.0f * 11.0f) - 1.0f; // in centi break; } @@ -165,11 +169,11 @@ break; case 5: // LFO_EXP_DOWN 1 - out = powf(0.05f, x) * 2.0f - 1.0f; + out = powFrac<20>(x) * 2.0f - 1.0f; break; case 6: // LFO_EXP_DOWN 2 - out = powf(0.001f, x) * 2.0f - 1.0f; + out = powFrac<1000>(x) * 2.0f - 1.0f; break; case 7: // LFO_SAMPLE_&_HOLD @@ -233,6 +237,7 @@ default: out = cosf(x * TWOPI); // LFO_SINE + break; } if (lfotype == 0 || lfotype == 1) @@ -316,5 +321,5 @@ if (!freqrndenabled) return; incrnd = nextincrnd; - nextincrnd = powf(0.5f, lfofreqrnd) + synth->numRandom() * (powf(2.0f, lfofreqrnd) - 1.0f); + nextincrnd = powFrac<2>(lfofreqrnd) + synth->numRandom() * (power<2>(lfofreqrnd) - 1.0f); } diff -Nru yoshimi-2.1.1.1~dfsg0/src/Synth/OscilGen.cpp yoshimi-2.1.2.2~dfsg0/src/Synth/OscilGen.cpp --- yoshimi-2.1.1.1~dfsg0/src/Synth/OscilGen.cpp 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/Synth/OscilGen.cpp 2021-12-03 20:12:12.000000000 +0000 @@ -34,8 +34,12 @@ #include "Effects/Distorsion.h" #include "Misc/Config.h" #include "Misc/SynthEngine.h" +#include "Misc/NumericFuncs.h" #include "Synth/OscilGen.h" +using func::power; + + //char OscilGen::random_state[256]; //struct random_data OscilGen::random_buf; //char OscilGen::harmonic_random_state[256]; @@ -263,7 +267,7 @@ a =(a - 0.5f) * 4.0f; if (a > 0.0f) a *= 2.0f; - a = powf(3.0f, a); + a = power<3>(a); float b = powf(fabsf(x), a); if (x < 0.0f) b = -b; @@ -277,7 +281,7 @@ a = (a - 0.5f) * 4.0f; if (a < 0.0f) a *= 2.0f; - a = powf(3.0f, a); + a = power<3>(a); return sinf(x / 2.0f) * sinf(a * x * x); } @@ -286,7 +290,7 @@ { x = fmodf(x + 0.5f, 1.0f) * 2.0f - 1.0f; a = (a - 0.5f) * 9.0f; - a = powf(3.0f, a); + a = power<3>(a); float b = powf(fabsf(x), a); if (x < 0.0f) b = -b; @@ -386,25 +390,25 @@ { case 1: basefuncmodulationpar1 = - (powf(2.0f, basefuncmodulationpar1 * 5.0f) - 1.0f) / 10.0f; + (power<2>(basefuncmodulationpar1 * 5.0f) - 1.0f) / 10.0f; basefuncmodulationpar3 = - floorf((powf(2.0f, basefuncmodulationpar3 * 5.0f) - 1.0f)); + floorf((power<2>(basefuncmodulationpar3 * 5.0f) - 1.0f)); if (basefuncmodulationpar3 < 0.9999f) basefuncmodulationpar3 = -1.0f; break; case 2: basefuncmodulationpar1 = - (powf(2.0f, basefuncmodulationpar1 * 5.0f) - 1.0f) / 10.0f; + (power<2>(basefuncmodulationpar1 * 5.0f) - 1.0f) / 10.0f; basefuncmodulationpar3 = - 1.0f + floorf((powf(2.0f, basefuncmodulationpar3 * 5.0f) - 1.0f)); + 1.0f + floorf((power<2>(basefuncmodulationpar3 * 5.0f) - 1.0f)); break; case 3: basefuncmodulationpar1 = - (powf(2.0f, basefuncmodulationpar1 * 7.0f) - 1.0f) / 10.0f; + (power<2>(basefuncmodulationpar1 * 7.0f) - 1.0f) / 10.0f; basefuncmodulationpar3 = - 0.01f + (powf(2.0f, basefuncmodulationpar3 * 16.0f) - 1.0f) / 10.0f; + 0.01f + (power<2>(basefuncmodulationpar3 * 16.0f) - 1.0f) / 10.0f; break; default: @@ -504,6 +508,7 @@ default: // sine smps[i] = -sinf(TWOPI * (float)i / synth->oscilsize_f); + break; } } } @@ -546,15 +551,15 @@ par = par * 0.25f + 0.15f; gain = 1.0f - powf(1.0f - par * par * 0.999f + 0.001f, i * 0.05f * i + 1.0f); // hp1b - float tmp = powf(5.0f, (par2 * 2.0f)); + float tmp = power<5>((par2 * 2.0f)); gain = powf(gain, tmp); break; } case 4: { - gain = (i + 1) - powf(2.0f, ((1.0f - par) * 7.5f)); // bp1 + gain = (i + 1) - power<2>(((1.0f - par) * 7.5f)); // bp1 gain = 1.0f / (1.0f + gain * gain / (i + 1.0f)); - float tmp = powf(5.0f, (par2 * 2.0f)); + float tmp = power<5>((par2 * 2.0f)); gain = powf(gain, tmp); if (gain < 1e-5f) gain = 1e-5f; @@ -562,7 +567,7 @@ } case 5: { - gain = i + 1 - powf(2.0f, (1.0f - par) * 7.5f); // bs1 + gain = i + 1 - power<2>((1.0f - par) * 7.5f); // bs1 gain = powf(atanf(gain / (i / 10.0f + 1.0f)) / 1.57f, 6.0f); gain = powf(gain, (par2 * par2 * 3.9f + 0.1f)); break; @@ -570,7 +575,7 @@ case 6: { //float tmp = powf(par2, 0.33f); - gain = (i + 1 > powf(2.0f, (1.0f - par) * 10.0f) ? 0.0f : 1.0f) + gain = (i + 1 > power<2>((1.0f - par) * 10.0f) ? 0.0f : 1.0f) * par2 + (1.0f - par2); // lp2 break; } @@ -578,7 +583,7 @@ { //float tmp = powf(par2, 0.33f); // tmp=1.0-(1.0-par2)*(1.0-par2); - gain = (i + 1 > powf(2.0f, (1.0f - par) * 7.0f) ? 1.0f : 0.0f) + gain = (i + 1 > power<2>((1.0f - par) * 7.0f) ? 1.0f : 0.0f) * par2 + (1.0f - par2); // hp2 if (params->Pfilterpar1 == 0) gain = 1.0f; @@ -588,20 +593,20 @@ { //float tmp = powf(par2, 0.33f); // tmp=1.0-(1.0-par2)*(1.0-par2); - gain = (fabsf(powf(2.0f, (1.0f - par) * 7.0f) - i) > i / 2 + 1 ? 0.0f : 1.0f) + gain = (fabsf(power<2>((1.0f - par) * 7.0f) - i) > i / 2 + 1 ? 0.0f : 1.0f) * par2 + (1.0f - par2); // bp2 break; } case 9: { //float tmp = powf(par2, 0.33f); - gain = (fabsf(powf(2.0f, (1.0f - par) * 7.0f) - i) < i / 2 + 1 ? 0.0f : 1.0f) + gain = (fabsf(power<2>((1.0f - par) * 7.0f) - i) < i / 2 + 1 ? 0.0f : 1.0f) * par2 + (1.0f - par2); // bs2 break; } case 10: { - float tmp = powf(5.0f, par2 * 2.0f - 1.0f); + float tmp = power<5>(par2 * 2.0f - 1.0f); tmp = powf((i / 32.0f), tmp) * 32.0f; if (params->Pfilterpar2 == 64) tmp = i; @@ -611,7 +616,7 @@ } case 11: { - float tmp = powf(5.0f, par2 * 2.0f - 1.0f); + float tmp = power<5>(par2 * 2.0f - 1.0f); tmp = powf((i / 32.0f), tmp) * 32.0f; if (params->Pfilterpar2 == 64) tmp = i; @@ -630,10 +635,10 @@ } case 13: { - int tmp = (int)powf(2.0f, ((1.0f - par) * 7.2f)); + int tmp = (int)power<2>(((1.0f - par) * 7.2f)); gain = 1.0f; if (i == tmp) - gain = powf(2.0f, par2 * par2 * 8.0f); + gain = power<2>(par2 * par2 * 8.0f); break; } } @@ -747,20 +752,20 @@ switch (params->Pmodulation) { case 1: - modulationpar1 = (powf(2.0f, modulationpar1 * 7.0f) - 1.0f) / 100.0f; - modulationpar3 = floorf((powf(2.0f, modulationpar3 * 5.0f) - 1.0f)); + modulationpar1 = (power<2>(modulationpar1 * 7.0f) - 1.0f) / 100.0f; + modulationpar3 = floorf((power<2>(modulationpar3 * 5.0f) - 1.0f)); if (modulationpar3 < 0.9999f) modulationpar3 = -1.0f; break; case 2: - modulationpar1 = (powf(2.0f, modulationpar1 * 7.0f) - 1.0f) / 100.0f; - modulationpar3 = 1.0f + floorf((powf(2.0f, modulationpar3 * 5.0f) - 1.0f)); + modulationpar1 = (power<2>(modulationpar1 * 7.0f) - 1.0f) / 100.0f; + modulationpar3 = 1.0f + floorf((power<2>(modulationpar3 * 5.0f) - 1.0f)); break; case 3: - modulationpar1 = (powf(2.0f, modulationpar1 * 9.0f) - 1.0f) / 100.0f; - modulationpar3 = 0.01f + (powf(2.0f, modulationpar3 * 16.0f) - 1.0f) / 10.0f; + modulationpar1 = (power<2>(modulationpar1 * 9.0f) - 1.0f) / 100.0f; + modulationpar3 = 0.01f + (power<2>(modulationpar3 * 16.0f) - 1.0f) / 10.0f; break; } @@ -841,17 +846,17 @@ case 1: par = 1.0f - par * 2.0f; if (par >= 0.0f) - par = powf(5.0f, par); + par = power<5>(par); else - par = powf(8.0f, par); + par = power<8>(par); break; case 2: - par = powf(10.0f, (1.0f - par) * 3.0f) * 0.25f; + par = power<10>((1.0f - par) * 3.0f) * 0.25f; break; case 3: - par = powf(10.0f, (1.0f - par) * 3.0f) * 0.25f; + par = power<10>((1.0f - par) * 3.0f) * 0.25f; break; } @@ -1081,7 +1086,7 @@ float hc = 0.0f; float hs = 0.0f; - float basefreq = 30.0f * powf(10.0f, params->Padaptiveharmonicsbasefreq / 128.0f); + float basefreq = 30.0f * power<10>(params->Padaptiveharmonicsbasefreq / 128.0f); float power = (params->Padaptiveharmonicspower + 1.0f) / 101.0f; float rap = freq / basefreq; @@ -1296,7 +1301,7 @@ { case 1: power = power * 2.0f - 0.5f; - power = powf(15.0f, power); + power = func::power<15>(power); for (int i = 1; i < nyquist - 1; ++i) { float amp = powf(harmonicPrng.numRandom(), power) * normalize; @@ -1307,7 +1312,7 @@ case 2: power = power * 2.0f - 0.5f; - power = powf(15.0f, power) * 2.0f; + power = func::power<15>(power) * 2.0f; float rndfreq = TWOPI * harmonicPrng.numRandom(); for (int i = 1 ; i < nyquist - 1; ++i) { diff -Nru yoshimi-2.1.1.1~dfsg0/src/Synth/PADnote.cpp yoshimi-2.1.2.2~dfsg0/src/Synth/PADnote.cpp --- yoshimi-2.1.1.1~dfsg0/src/Synth/PADnote.cpp 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/Synth/PADnote.cpp 2021-12-03 20:12:12.000000000 +0000 @@ -29,15 +29,17 @@ #include "Misc/Config.h" #include "Params/PADnoteParameters.h" #include "Params/Controller.h" +#include "Synth/PADnote.h" #include "Synth/Envelope.h" #include "Synth/LFO.h" #include "DSP/Filter.h" #include "Params/Controller.h" #include "Misc/SynthEngine.h" #include "Misc/SynthHelper.h" -#include "Synth/PADnote.h" #include "Misc/NumericFuncs.h" +using func::decibel; +using func::power; using synth::velF; using synth::getDetune; using synth::interpolateAmplitude; @@ -72,14 +74,15 @@ NoteGlobalPar.Fadein_adjustment = pars->Fadein_adjustment / (float)FADEIN_ADJUSTMENT_SCALE; NoteGlobalPar.Fadein_adjustment *= NoteGlobalPar.Fadein_adjustment; + if (pars->PPunchStrength != 0) { NoteGlobalPar.Punch.Enabled = 1; NoteGlobalPar.Punch.t = 1.0f; // start from 1.0 and to 0.0 NoteGlobalPar.Punch.initialvalue = - (powf(10.0f, 1.5f * pars->PPunchStrength / 127.0f) - 1.0f) + (power<10>(1.5f * pars->PPunchStrength / 127.0f) - 1.0f) * velF(velocity, pars->PPunchVelocitySensing); - float time = powf(10.0f, 3.0f * pars->PPunchTime / 127.0f) / 10000.0f; // 0.1 .. 100 ms + float time = power<10>(3.0f * pars->PPunchTime / 127.0f) / 10000.0f; // 0.1 .. 100 ms float stretch = powf(440.0f / freq, pars->PPunchStretch / 64.0f); NoteGlobalPar.Punch.dt = 1.0f / (time * synth->samplerate_f * stretch); } @@ -123,7 +126,6 @@ if (parameters->sample[nsample].smp == NULL) { NoteStatus = NOTE_DISABLED; - return; } } @@ -144,6 +146,7 @@ released(orig.released), nsample(orig.nsample), portamento(orig.portamento), + midinote(orig.midinote), ctl(orig.ctl), globaloldamplitude(orig.globaloldamplitude), globalnewamplitude(orig.globalnewamplitude), @@ -285,11 +288,11 @@ if (fixedfreqET != 0) { // if the frequency varies according the keyboard note float tmp = (midinote - 69.0f) / 12.0f - * (powf(2.0f, (fixedfreqET - 1) / 63.0f) - 1.0f); + * (power<2>((fixedfreqET - 1) / 63.0f) - 1.0f); if (fixedfreqET <= 64) - basefreq *= powf(2.0f, tmp); + basefreq *= power<2>(tmp); else - basefreq *= powf(3.0f, tmp); + basefreq *= power<3>(tmp); } } } @@ -332,7 +335,7 @@ NoteGlobalPar.Detune = getDetune(pars->PDetuneType, pars->PCoarseDetune, pars->PDetune); // find out the closest note - float logfreq = logf(basefreq * powf(2.0f, NoteGlobalPar.Detune / 1200.0f)); + float logfreq = logf(basefreq * power<2>(NoteGlobalPar.Detune / 1200.0f)); float mindist = fabsf(logfreq - logf(pars->sample[0].basefreq + 0.0001f)); nsample = 0; for (int i = 1; i < PAD_MAX_SAMPLES; ++i) @@ -350,7 +353,8 @@ } NoteGlobalPar.Volume = - 4.0f * powf(0.1f, 3.0f * (1.0f - pars->PVolume / 96.0f)) //-60 dB .. 0 dB + 4.0f // +12dB boost (similar on ADDnote, while SUBnote only boosts +6dB) + * decibel<-60>(1.0f - pars->PVolume / 96.0f) // -60 dB .. +19.375 dB * velF(velocity, pars->PAmpVelocityScaleFunction); // velocity sensing } @@ -399,7 +403,7 @@ } } - realfreq = basefreq * portamentofreqrap * powf(2.0f, globalpitch / 12.0) + realfreq = basefreq * portamentofreqrap * power<2>(globalpitch / 12.0) * powf(ctl->pitchwheel.relfreq, BendAdjust) + OffsetHz; } diff -Nru yoshimi-2.1.1.1~dfsg0/src/Synth/Resonance.cpp yoshimi-2.1.2.2~dfsg0/src/Synth/Resonance.cpp --- yoshimi-2.1.1.1~dfsg0/src/Synth/Resonance.cpp 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/Synth/Resonance.cpp 2021-12-03 20:12:12.000000000 +0000 @@ -28,10 +28,12 @@ #include #include -using namespace std; - -#include "Misc/SynthEngine.h" #include "Synth/Resonance.h" +#include "Misc/SynthEngine.h" +#include "Misc/NumericFuncs.h" + +using func::power; + Resonance::Resonance(SynthEngine *_synth) : Presets(_synth) { @@ -95,7 +97,7 @@ if (kx2 >= MAX_RESONANCE_POINTS) kx2 = MAX_RESONANCE_POINTS - 1; float y = (Prespoints[kx1] * (1.0 - dx) + Prespoints[kx2] * dx) / 127.0 - sum / 127.0; - y = powf(10.0f, y * PmaxdB / 20.0); + y = power<10>(y * PmaxdB / 20.0); if (Pprotectthefundamental != 0 && i == 1) y = 1.0; fftdata.c[i] *= y; @@ -131,7 +133,7 @@ kx2 = MAX_RESONANCE_POINTS - 1; float result = (Prespoints[kx1] * (1.0 - dx) + Prespoints[kx2] * dx) / 127.0 - sum / 127.0; - result = powf(10.0f, result * PmaxdB / 20.0); + result = power<10>(result * PmaxdB / 20.0); return result; } @@ -202,7 +204,7 @@ { if (x > 1.0) x = 1.0; - float octf = powf(2.0f, getoctavesfreq()); + float octf = power<2>(getoctavesfreq()); return (getcenterfreq() / sqrtf(octf) * powf(octf, x)); } @@ -217,7 +219,7 @@ // Get the center frequency of the resonance graph float Resonance::getcenterfreq(void) { - return 10000.0 * powf(10.0f, -(1.0f - Pcenterfreq / 127.0f) * 2.0f); + return 10000.0 * power<10>(-(1.0f - Pcenterfreq / 127.0f) * 2.0f); } @@ -288,6 +290,7 @@ int max = 1; int def = 0; type |= TOPLEVEL::type::Integer; + unsigned char learnable = TOPLEVEL::type::Learnable; if (insert == TOPLEVEL::insert::resonanceGraphInsert) { @@ -321,26 +324,32 @@ switch (control) { case RESONANCE::control::maxDb: + type |= learnable; min = 1; max = 90; def = 20; break; case RESONANCE::control::centerFrequency: + type |= learnable; max = 127; def = 64; break; case RESONANCE::control::octaves: + type |= learnable; max = 127; def = 64; break; case RESONANCE::control::enableResonance: + type |= learnable; break; case RESONANCE::control::randomType: + type |= learnable; max = 2; break; case RESONANCE::control::interpolatePeaks: break; case RESONANCE::control::protectFundamental: + type |= learnable; break; case RESONANCE::control::clearGraph: max = 0; diff -Nru yoshimi-2.1.1.1~dfsg0/src/Synth/SUBnote.cpp yoshimi-2.1.2.2~dfsg0/src/Synth/SUBnote.cpp --- yoshimi-2.1.1.1~dfsg0/src/Synth/SUBnote.cpp 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/Synth/SUBnote.cpp 2021-12-03 20:12:12.000000000 +0000 @@ -32,13 +32,16 @@ #include "DSP/FFTwrapper.h" #include "Params/SUBnoteParameters.h" #include "Params/Controller.h" +#include "Synth/SUBnote.h" #include "Synth/Envelope.h" #include "DSP/Filter.h" #include "Misc/SynthEngine.h" #include "Misc/SynthHelper.h" -#include "Synth/SUBnote.h" #include "Misc/NumericFuncs.h" +using func::power; +using func::powFrac; +using func::decibel; using synth::velF; using synth::getDetune; using synth::interpolateAmplitude; @@ -46,16 +49,6 @@ using func::setRandomPan; -// These have little reason to exist, as GCC actually performs constant folding -// on logf even on -O0 and Clang (currently, as of 9.0.1) constant-folds these -// on -O1 and above. These used to be members of SUBnote initialized on note -// construction. Thankfully constant folding would still occur, but it wasn't -// ideal. Older compilers might generate library calls, so there might still be -// some justification for this. -const float LOG_0_01 = logf(0.01f); -const float LOG_0_001 = logf(0.001f); -const float LOG_0_0001 = logf(0.0001f); -const float LOG_0_00001 = logf(0.00001f); SUBnote::SUBnote(SUBnoteParameters *parameters, Controller *ctl_, float basefreq_, @@ -137,6 +130,8 @@ newamplitude(orig.newamplitude), lfilter(NULL), rfilter(NULL), + tmpsmp(NULL), + tmprnd(NULL), ctl(orig.ctl), oldpitchwheel(orig.oldpitchwheel), oldbandwidth(orig.oldbandwidth), @@ -344,23 +339,23 @@ if (fixedfreqET) { // if the frequency varies according the keyboard note float tmp = - (midinote - 69.0f) / 12.0f * powf(2.0f, (((fixedfreqET - 1) / 63.0f) - 1.0f)); + (midinote - 69.0f) / 12.0f * power<2>((((fixedfreqET - 1) / 63.0f) - 1.0f)); if (fixedfreqET <= 64) - notefreq *= powf(2.0f, tmp); + notefreq *= power<2>(tmp); else - notefreq *= powf(3.0f, tmp); + notefreq *= power<3>(tmp); } } float detune = getDetune(pars->PDetuneType, pars->PCoarseDetune, pars->PDetune); - notefreq *= powf(2.0f, detune / 1200.0f); // detune -// notefreq*=ctl->pitchwheel.relfreq;//pitch wheel + notefreq *= power<2>(detune / 1200.0f); // detune } void SUBnote::computeNoteParameters() { - volume = powf(0.1f, 3.0f * (1.0f - pars->PVolume / 96.0f)); // -60 dB .. 0 dB - volume *= velF(velocity, pars->PAmpVelocityScaleFunction); + volume = 2.0f // +6dB boost (note ADDnote and PADnote apply a +12dB boost) + * decibel<-60>(1.0f - pars->PVolume / 96.0f) // -60 dB .. +19.375 dB + * velF(velocity, pars->PAmpVelocityScaleFunction); int BendAdj = pars->PBendAdjust - 64; if (BendAdj % 24 == 0) @@ -580,8 +575,8 @@ if (freq <= lower_limit || freq >= upper_limit) return 0.0f; if (freq <= lower_limit + lower_width) - return (1.0f - cosf(M_PI * (freq - lower_limit) / lower_width)) / 2.0f; - return (1.0f - cosf(M_PI * (freq - upper_limit) / upper_width)) / 2.0f; + return (1.0f - cosf(PI * (freq - lower_limit) / lower_width)) / 2.0f; + return (1.0f - cosf(PI * (freq - upper_limit) / upper_width)) / 2.0f; } void SUBnote::computeallfiltercoefs() @@ -593,7 +588,7 @@ if (FreqEnvelope != NULL) { envfreq = FreqEnvelope->envout() / 1200; - envfreq = powf(2.0f, envfreq); + envfreq = power<2>(envfreq); } envfreq *= powf(ctl->pitchwheel.relfreq, BendAdjust); // pitch wheel @@ -610,7 +605,7 @@ if (BandWidthEnvelope != NULL) { envbw = BandWidthEnvelope->envout(); - envbw = powf(2.0f, envbw); + envbw = power<2>(envbw); } envbw *= ctl->bandwidth.relbw; // bandwidth controller @@ -650,27 +645,15 @@ // Compute Parameters of SUBnote for each tick void SUBnote::computecurrentparameters(void) { - // disabled till we know what we are doing! - /*for (int n = 0; n < MAX_SUB_HARMONICS; ++n) - { - int changed = pars->PfilterChanged[n]; - if (changed) - { - if (changed == 6) // magnitude - ; - else if (changed == 7) // bandwidth - ; - cout << "Filter changed " << changed << endl; - pars->PfilterChanged[n] = 0; - } - }*/ if (FreqEnvelope != NULL || BandWidthEnvelope != NULL || oldpitchwheel != ctl->pitchwheel.data || oldbandwidth != ctl->bandwidth.data || portamento != 0) computeallfiltercoefs(); - newamplitude = volume * AmpEnvelope->envout_dB() * 2.0f; + + // Envelope + newamplitude = volume * AmpEnvelope->envout_dB(); // Filter if (GlobalFilterL != NULL) @@ -856,23 +839,24 @@ switch (pars->Phmagtype) { case 1: - hgain = expf(hmagnew * LOG_0_01); + hgain = powFrac<100>(hmagnew); break; case 2: - hgain = expf(hmagnew * LOG_0_001); + hgain = powFrac<1000>(hmagnew); break; case 3: - hgain = expf(hmagnew * LOG_0_0001); + hgain = powFrac<10000>(hmagnew); break; case 4: - hgain = expf(hmagnew * LOG_0_00001); + hgain = powFrac<100000>(hmagnew); break; default: hgain = 1.0f - hmagnew; + break; } return hgain; @@ -893,13 +877,13 @@ overtone_rolloff[n] = computerolloff(freq); // the bandwidth is not absolute(Hz); it is relative to frequency - float bw = powf(10.0f, (pars->Pbandwidth - 127.0f) / 127.0f * 4.0f) * numstages; + float bw = power<10>((pars->Pbandwidth - 127.0f) / 127.0f * 4.0f) * numstages; // Bandwidth Scale bw *= powf(1000.0f / freq, (pars->Pbwscale - 64.0f) / 64.0f * 3.0f); // Relative BandWidth - bw *= powf(100.0f, (pars->Phrelbw[pos[n]] - 64.0f) / 64.0f); + bw *= power<100>((pars->Phrelbw[pos[n]] - 64.0f) / 64.0f); if (bw > 25.0f) bw = 25.0f; @@ -937,6 +921,4 @@ if (reduceamp < 0.001f) reduceamp = 1.0f; volume /= reduceamp; - } - diff -Nru yoshimi-2.1.1.1~dfsg0/src/UI/ADnoteUI.fl yoshimi-2.1.2.2~dfsg0/src/UI/ADnoteUI.fl --- yoshimi-2.1.1.1~dfsg0/src/UI/ADnoteUI.fl 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/UI/ADnoteUI.fl 2021-12-03 20:12:12.000000000 +0000 @@ -1,5 +1,5 @@ # data file for the Fltk User Interface Designer (fluid) -version 1.0304 +version 1.0305 header_name {.h} code_name {.cc} comment {ADNoteUI.h} {not_in_source in_header @@ -409,7 +409,7 @@ class Fl_Group } { Fl_Box {} { - xywh {8 71 277 64} box PLASTIC_THIN_UP_BOX color 223 + xywh {8 69 277 66} box PLASTIC_UP_BOX color 223 } Fl_Group voiceparametersgroup { xywh {0 0 805 615} box THIN_UP_FRAME color 48 @@ -428,7 +428,7 @@ } { Fl_Group voiceFMfreqenvgroup { label {ADSynth Modulator - Frequency Envelope} - xywh {585 290 205 70} box FLAT_BOX color 51 align 144 + xywh {585 290 210 70} box FLAT_BOX color 51 align 144 code0 {o->init(pars->VoicePar[nvoice].FMFreqEnvelope, npart, kititem, nvoice + PART::engine::addMod1, 1);} code1 {if (pars->VoicePar[nvoice].PFMFreqEnvelopeEnabled==0) o->deactivate();} class EnvelopeUI @@ -526,7 +526,7 @@ } Fl_Group voiceFMampenvgroup { label {ADSynth Modulator - Amplitude Envelope} - xywh {587 129 205 70} box FLAT_BOX color 51 align 144 + xywh {585 129 210 70} box FLAT_BOX color 51 align 144 code0 {o->init(pars->VoicePar[nvoice].FMAmpEnvelope, npart, kititem, nvoice + PART::engine::addMod1, 0);} code1 {if (pars->VoicePar[nvoice].PFMAmpEnvelopeEnabled==0) o->deactivate();} class EnvelopeUI @@ -553,7 +553,7 @@ class mwheel_val_slider_rev } } - Fl_Group modOscDisplay {open + Fl_Group modOscDisplay { xywh {580 365 220 200} } { Fl_Group modoscil { @@ -771,10 +771,10 @@ class WidgetPDial } } - Fl_Group oscDisplay {open + Fl_Group oscDisplay { xywh {5 462 570 145} } { - Fl_Group oscGroup {open + Fl_Group oscGroup { xywh {5 462 570 145} labelfont 1 labelsize 13 align 17 code0 {if (pars->VoicePar[nvoice].PVoice >= 0) o->deactivate();} } { @@ -830,7 +830,7 @@ } } Fl_Box {} { - xywh {205 35 85 35} box THIN_UP_FRAME + xywh {205 35 85 33} box THIN_UP_FRAME } Fl_Check_Button ResonanceEn { label Resonance @@ -839,7 +839,7 @@ pars->VoicePar[nvoice].Presonance = enab; synth->getGuiMaster()->partui->adnoteui->voicelistitem[nvoice]->voiceresonanceenabled->value(enab); send_data(0, ADDVOICE::control::enableResonance, enab, TOPLEVEL::type::Integer);} - tooltip {Resonance On/Off} xywh {238 50 17 19} down_box DOWN_BOX labelsize 12 align 1 + tooltip {Resonance On/Off} xywh {238 49 17 19} down_box DOWN_BOX labelsize 12 align 1 code0 {o->value(pars->VoicePar[nvoice].Presonance);} class Fl_Check_Button2 } @@ -932,7 +932,7 @@ } Fl_Group amplitudegroup { label AMPLITUDE - xywh {5 70 285 210} box UP_FRAME labelfont 1 labelsize 12 align 17 + xywh {5 68 285 212} box UP_FRAME labelfont 1 labelsize 12 align 17 } { Fl_Dial voicevolume { label Volume @@ -940,7 +940,7 @@ int vol = lrint(o->value()); synth->getGuiMaster()->partui->adnoteui->voicelistitem[nvoice]->voicevolume->value(vol); send_data(0, ADDVOICE::control::volume, vol, TOPLEVEL::type::Integer);} - tooltip Volume xywh {30 87 33 33} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + tooltip Volume xywh {30 86 33 33} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 code0 {o->setValueType(VC_ADDVoiceVolume);} code1 {o->value(pars->VoicePar[nvoice].PVolume);} class WidgetPDial @@ -949,7 +949,7 @@ label {Vel Sens} callback {// send_data(0, ADDVOICE::control::velocitySense, o->value(), TOPLEVEL::type::Integer);} - tooltip {Velocity Sensing Function - rightmost/max disables)} xywh {85 87 33 33} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + tooltip {Velocity Sensing Function - rightmost/max disables)} xywh {86 87 33 33} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 code0 {o->value(pars->VoicePar[nvoice].PAmpVelocityScaleFunction);} code1 {o->setValueType(VC_AmpVelocitySense);} class WidgetPDial @@ -959,7 +959,7 @@ callback {// int pan = lrint(o->value()); send_data(TOPLEVEL::action::forceUpdate, ADDVOICE::control::panning, pan, TOPLEVEL::type::Integer);} - tooltip {Voice panning} xywh {160 87 33 33} box ROUND_UP_BOX labelsize 10 align 6 maximum 127 step 1 + tooltip {Voice panning} xywh {160 86 33 33} box ROUND_UP_BOX labelsize 10 align 6 maximum 127 step 1 code0 {o->setValueType(VC_PanningStd);} code1 {o->value(pars->VoicePar[nvoice].PPanning);} class WidgetPDial @@ -968,7 +968,7 @@ label Width callback {// send_data(0, ADDVOICE::control::randomWidth, o->value(), TOPLEVEL::type::Integer);} - tooltip {Voice random width} xywh {235 87 33 33} box ROUND_UP_BOX labelsize 10 maximum 63 step 1 value 63 + tooltip {Voice random width} xywh {235 86 33 33} box ROUND_UP_BOX labelsize 10 maximum 63 step 1 value 63 code0 {o->setValueType(VC_PanningRandom);} code1 {o->value(pars->VoicePar[nvoice].PWidth);} class WidgetPDial @@ -1036,7 +1036,7 @@ class Fl_Check_Button2 } Fl_Box {} { - xywh {140 86 4 44} box THIN_DOWN_FRAME + xywh {140 85 4 44} box THIN_DOWN_FRAME } } Fl_Group voicefiltergroup { @@ -1082,16 +1082,16 @@ } } Fl_Box {} { - xywh {5 35 64 35} box THIN_UP_FRAME + xywh {5 35 64 33} box THIN_UP_FRAME } Fl_Group {} { - xywh {69 35 136 35} box THIN_UP_FRAME + xywh {69 35 136 33} box THIN_UP_FRAME } { Fl_Value_Slider Delay { label Delay callback {// send_data(0, ADDVOICE::control::delay, o->value(), TOPLEVEL::type::Integer);} - tooltip {Time before the voice activates} xywh {76 51 124 12} type {Horz Knob} box THIN_DOWN_BOX labelsize 11 align 1 maximum 127 step 1 + tooltip {Time before the voice activates} xywh {76 50 124 12} type {Horz Knob} box THIN_DOWN_BOX labelsize 11 align 1 maximum 127 step 1 code0 {o->value(pars->VoicePar[nvoice].PDelay);} code1 {o->setValueType(VC_ADDVoiceDelay);o->useCustomTip(true);} class mwheel_slider_rev @@ -1161,7 +1161,7 @@ label On callback {// send_data(TOPLEVEL::action::forceUpdate, ADDVOICE::control::enableVoice, o->value(), TOPLEVEL::type::Integer);} - xywh {12 43 50 20} box THIN_UP_BOX down_box DOWN_BOX color 237 labelfont 1 + xywh {12 41 50 20} box THIN_UP_BOX down_box DOWN_BOX color 237 labelfont 1 code0 {o->value(pars->VoicePar[nvoice].Enabled);} class Fl_Check_Button2 } @@ -1232,7 +1232,7 @@ case ADDVOICE::control::enableAmplitudeEnvelope: AmpEnvEn->value(val_bool); - if (value == 0) + if (val_bool == 0) voiceampenvgroup->deactivate(); else voiceampenvgroup->activate(); @@ -1240,7 +1240,7 @@ case ADDVOICE::control::enableAmplitudeLFO: AmpLfoEn->value(val_bool); - if (value == 0) + if (val_bool == 0) voiceamplfogroup->deactivate(); else voiceamplfogroup->activate(); @@ -1316,7 +1316,7 @@ case ADDVOICE::control::enableFrequencyEnvelope: FreqEn->value(val_bool); - if (value == 0) + if (val_bool == 0) voicefreqenvgroup->deactivate(); else voicefreqenvgroup->activate(); @@ -1324,7 +1324,7 @@ case ADDVOICE::control::enableFrequencyLFO: FreqLfoEn->value(val_bool); - if (value == 0) + if (val_bool == 0) voicefreqlfogroup->deactivate(); else voicefreqlfogroup->activate(); @@ -1353,7 +1353,7 @@ case ADDVOICE::control::unisonSize: { - tmp = (int) value; + tmp = int(value); unisonsize->value(tmp); int colr = FL_BLACK; int i = 0; @@ -1377,16 +1377,14 @@ break; case ADDVOICE::control::enableUnison: - tmp = (int) value; - UnisonEn->value(tmp); - if (tmp == 0) + UnisonEn->value(val_bool); + if (val_bool == 0) { unisonsize->value(2); unisongroup->deactivate(); } else { - tmp = lrint(unisonsize->value()); unisongroup->activate(); int colr = FL_BLACK; int i = -1; @@ -1395,7 +1393,7 @@ ++i; if (pars->ADnote_unison_sizes[i] == 0) break; - if (pars->ADnote_unison_sizes[i] == tmp) + if (pars->ADnote_unison_sizes[i] == int(unisonsize->value())) { colr = FL_RED; break; @@ -1494,7 +1492,7 @@ case ADDVOICE::control::enableModulatorFrequencyEnvelope: ModFreqEn->value(val_bool); - if (value == 0) + if (val_bool == 0) voiceFMfreqenvgroup->deactivate(); else voiceFMfreqenvgroup->activate(); @@ -1991,17 +1989,17 @@ } } Fl_Box {} { - xywh {10 7 275 68} box PLASTIC_THIN_UP_BOX color 223 + xywh {10 7 275 68} box PLASTIC_UP_BOX color 223 } Fl_Group amplitudegrp { label AMPLITUDE - xywh {5 5 285 250} box THIN_UP_FRAME labelfont 1 labelsize 12 align 17 + xywh {5 7 285 250} box THIN_UP_FRAME labelfont 1 labelsize 12 align 17 } { Fl_Dial globalvolume { label Volume callback {// send_data(0, ADDSYNTH::control::volume, o->value(), TOPLEVEL::type::Integer);} - tooltip Volume xywh {30 22 35 35} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + tooltip Volume xywh {30 23 35 35} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 code0 {o->setValueType(VC_InstrumentVolume);} code1 {o->value(pars->GlobalPar.PVolume);} class WidgetPDial @@ -2009,7 +2007,7 @@ Fl_Dial vsns { label {Vel Sens} callback {send_data(0, ADDSYNTH::control::velocitySense, o->value(), TOPLEVEL::type::Integer);} - tooltip {Velocity Sensing Function - rightmost/max to disable} xywh {85 22 35 35} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + tooltip {Velocity Sensing Function - rightmost/max to disable} xywh {85 23 35 35} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 code0 {o->value(pars->GlobalPar.PAmpVelocityScaleFunction);} code2 {o->setValueType(VC_AmpVelocitySense);} class WidgetPDial @@ -2018,7 +2016,7 @@ label Pan callback {// send_data(0, ADDSYNTH::control::panning, o->value(), TOPLEVEL::type::Integer);} - tooltip {Global panning} xywh {155 22 35 35} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + tooltip {Global panning} xywh {155 23 35 35} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 code0 {o->setValueType(VC_PanningStd);} code1 {o->value(pars->GlobalPar.PPanning);} class WidgetPDial @@ -2027,7 +2025,7 @@ label Width callback {// send_data(0, ADDSYNTH::control::randomWidth, o->value(), TOPLEVEL::type::Integer);} - tooltip {Global random width} xywh {235 22 35 35} box ROUND_UP_BOX labelsize 10 maximum 63 step 1 value 63 + tooltip {Global random width} xywh {235 23 35 35} box ROUND_UP_BOX labelsize 10 maximum 63 step 1 value 63 code0 {o->setValueType(VC_PanningRandom);} code1 {o->value(pars->GlobalPar.PWidth);} class WidgetPDial @@ -2041,7 +2039,7 @@ else globalwidth->activate(); send_data(0, ADDSYNTH::control::enableRandomPan, tmp, TOPLEVEL::type::Integer);} - tooltip {Enable random panning} xywh {205 31 15 15} down_box DOWN_BOX color 48 labelsize 11 align 1 + tooltip {Enable random panning} xywh {205 32 15 15} down_box DOWN_BOX color 48 labelsize 11 align 1 code0 {o->value(pars->GlobalPar.PRandom);} code1 {if (o->value() == 0) globalwidth->deactivate(); else globalwidth->activate();} class Fl_Check_Button2 diff -Nru yoshimi-2.1.1.1~dfsg0/src/UI/EffUI.fl yoshimi-2.1.2.2~dfsg0/src/UI/EffUI.fl --- yoshimi-2.1.1.1~dfsg0/src/UI/EffUI.fl 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/UI/EffUI.fl 2021-12-03 20:12:12.000000000 +0000 @@ -53,6 +53,10 @@ decl {\#include "Misc/SynthEngine.h"} {public local } +decl {\#include "Misc/NumericFuncs.h" + using func::power;} {private local +} + decl {\#include "Effects/EffectMgr.h"} {public local } @@ -175,7 +179,7 @@ } { code {if (x > 1.0) x = 1.0; - return 20.0 * powf(1000.0, x);} {} + return 20.0 * power<1000>(x);} {} } Function {getfreqpos(float freq)} {return_type float } { diff -Nru yoshimi-2.1.1.1~dfsg0/src/UI/EnvelopeUI.fl yoshimi-2.1.2.2~dfsg0/src/UI/EnvelopeUI.fl --- yoshimi-2.1.1.1~dfsg0/src/UI/EnvelopeUI.fl 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/UI/EnvelopeUI.fl 2021-12-03 20:12:12.000000000 +0000 @@ -1,5 +1,5 @@ # data file for the Fltk User Interface Designer (fluid) -version 1.0304 +version 1.0305 header_name {.h} code_name {.cc} comment {Envelope.h} {not_in_source in_header @@ -424,22 +424,22 @@ class WidgetPDial } Fl_Check_Button linearenvelopecheck { - class Fl_Check_Button2 label L callback {// send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::linearEnvelope, o->value(), TOPLEVEL::type::Write);} tooltip {Linear Envelope} xywh {415 151 30 15} down_box DOWN_BOX labelsize 10 code0 {o->value(env->Plinearenvelope);} code1 {if ((env->Pfreemode==0)||(env->Envmode>2)) o->hide();} + class Fl_Check_Button2 } Fl_Check_Button forcedreleasecheck { - class Fl_Check_Button2 label frcR callback {// send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::forcedRelease, o->value(), TOPLEVEL::type::Write);} tooltip {Forced Release} xywh {415 165 40 15} down_box DOWN_BOX labelsize 10 code0 {o->value(env->Pforcedrelease);} code1 {if (env->Pfreemode==0) o->hide();} + class Fl_Check_Button2 } Fl_Button freecopy { label C @@ -487,7 +487,7 @@ class WidgetPDial } Fl_Dial e1rdt { - label {R.dt} + label {R.dt } callback {// send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::releaseTime, o->value(), TOPLEVEL::type::Write);} tooltip {Release time} xywh {110 20 30 30} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 @@ -505,12 +505,12 @@ class WidgetPDial } Fl_Check_Button e1forcedrelease { - class Fl_Check_Button2 label frcR callback {// send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::forcedRelease, o->value(), TOPLEVEL::type::Write);} tooltip {Forced Release} xywh {180 35 20 15} down_box DOWN_BOX labelsize 10 align 6 code0 {o->value(env->Pforcedrelease);} + class Fl_Check_Button2 } Fl_Dial e1envstretch { label Stretch @@ -529,12 +529,12 @@ tooltip {Envelope window} xywh {185 5 15 15} box PLASTIC_UP_BOX labelfont 1 labelsize 10 } Fl_Check_Button e1linearenvelope { - class Fl_Check_Button2 label L callback {// send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::linearEnvelope, o->value(), TOPLEVEL::type::Write);} tooltip {The envelope is linear} xywh {180 20 15 15} down_box DOWN_BOX labelsize 10 align 4 code0 {o->value(env->Plinearenvelope);} + class Fl_Check_Button2 } Fl_Button e1C { label C @@ -578,7 +578,7 @@ class WidgetPDial } Fl_Dial e2rval { - label {R.val} + label {R.val } callback {// send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::releaseLevel, o->value(), TOPLEVEL::type::Write);} tooltip {Release value} xywh {110 20 30 30} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 @@ -596,7 +596,7 @@ class WidgetPDial } Fl_Dial e2envstretch { - label Stretch + label { Stretch} callback {// send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::stretch, o->value(), TOPLEVEL::type::Write);} tooltip {Envelope stretch (on lower notes makes the envelope longer)} xywh {145 25 25 25} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 @@ -605,12 +605,12 @@ class WidgetPDial } Fl_Check_Button e2forcedrelease { - class Fl_Check_Button2 label frcR callback {// send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::forcedRelease, o->value(), TOPLEVEL::type::Write);} - tooltip {Forced release} xywh {180 25 15 25} down_box DOWN_BOX labelsize 10 align 6 + tooltip {Forced release} xywh {185 25 15 25} down_box DOWN_BOX labelsize 10 align 6 code0 {o->value(env->Pforcedrelease);} + class Fl_Check_Button2 } Fl_Button e2C { label C @@ -687,7 +687,7 @@ class WidgetPDial } Fl_Dial e3rval { - label {R.val} + label {R.val } callback {// send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::releaseLevel, o->value(), TOPLEVEL::type::Write);} tooltip {Release value} xywh {180 20 30 30} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 @@ -696,7 +696,7 @@ class WidgetPDial } Fl_Dial e3envstretch { - label Stretch + label { Stretch} callback {// send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::stretch, o->value(), TOPLEVEL::type::Write);} tooltip {Envelope stretch (on lower notes makes the envelope longer)} xywh {215 25 25 25} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 @@ -705,12 +705,12 @@ class WidgetPDial } Fl_Check_Button e3forcedrelease { - class Fl_Check_Button2 label frcR callback {// send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::forcedRelease, o->value(), TOPLEVEL::type::Write);} tooltip {Forced Release} xywh {250 30 15 20} down_box DOWN_BOX labelsize 10 align 6 code0 {o->value(env->Pforcedrelease);} + class Fl_Check_Button2 } Fl_Button e3E { label E @@ -787,12 +787,12 @@ class WidgetPDial } Fl_Check_Button e4forcedrelease { - class Fl_Check_Button2 label frcR callback {// send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::forcedRelease, o->value(), TOPLEVEL::type::Write);} tooltip {Forced release} xywh {185 25 15 25} down_box DOWN_BOX labelsize 10 align 6 code0 {o->value(env->Pforcedrelease);} + class Fl_Check_Button2 } Fl_Button e4C { label C diff -Nru yoshimi-2.1.1.1~dfsg0/src/UI/FilterUI.fl yoshimi-2.1.2.2~dfsg0/src/UI/FilterUI.fl --- yoshimi-2.1.1.1~dfsg0/src/UI/FilterUI.fl 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/UI/FilterUI.fl 2021-12-03 20:12:12.000000000 +0000 @@ -1,5 +1,5 @@ # data file for the Fltk User Interface Designer (fluid) -version 1.0304 +version 1.0305 header_name {.h} code_name {.cc} comment {FilterUI.h} {not_in_source in_header @@ -85,7 +85,7 @@ } decl {\#include "Misc/NumericFuncs.h" - using func::rap2dB; + using func::asDecibel; using func::limit;} {private local } @@ -170,8 +170,8 @@ + " kHz"; fl_draw(tmpstr.c_str(), ox + 2 * scale, oy + 2 * scale, 40 * scale, 12 * scale, FL_ALIGN_LEFT, NULL, 0); tmpstr = asString((int) - (rap2dB(1e-9 + pars->getformantamp(pars->Pvowels[*nvowel].formants[*nformant].amp)) + pars->getgain())) - + " dB"; + (asDecibel(1e-9 + pars->getformantamp(pars->Pvowels[*nvowel].formants[*nformant].amp)) + pars->getgain())) + + " dB"; fl_draw(tmpstr.c_str(), ox + 2 * scale, oy + 15 * scale, 40 * scale, 12 * scale, FL_ALIGN_LEFT, NULL, 0); } @@ -404,7 +404,6 @@ class Fl_Group } { Fl_Group filterparamswindow { - label { Filter Params} xywh {0 0 275 75} box PLASTIC_UP_BOX color 231 labelfont 1 labelsize 10 align 17 } { Fl_Choice analogfiltertypechoice { @@ -432,7 +431,7 @@ code1 {o->add("analog");o->add("formant");o->add("StVarF");} } {} Fl_Dial cfreqdial { - label {C.Freq} + label { C.Freq} callback {// send_data(0, FILTERINSERT::control::centerFrequency, o->value(), TOPLEVEL::type::Write);} tooltip {Center Frequency of the Filter or the base position in the vowel's sequence} xywh {65 28 30 30} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 @@ -458,7 +457,7 @@ class WidgetPDial } Fl_Dial vsnsadial { - label {V.SnsA.} + label {V.Sns.} callback {// send_data(TOPLEVEL::action::forceUpdate, FILTERINSERT::control::velocitySensitivity, o->value(), TOPLEVEL::type::Write);} tooltip {Velocity sensing amount of the Filter} xywh {135 28 30 30} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 @@ -466,7 +465,7 @@ class WidgetPDial } Fl_Dial vsnsdial { - label {V.Sns.} + label { VF.Sns.} callback {// send_data(TOPLEVEL::action::forceUpdate, FILTERINSERT::control::velocityCurve, o->value(), TOPLEVEL::type::Write);} tooltip {Velocity Sensing Function of the Filter} xywh {170 28 30 30} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 @@ -486,13 +485,14 @@ Fl_Counter stcounter { label {St.} callback {// - send_data(TOPLEVEL::action::forceUpdate, FILTERINSERT::control::stages, o->value() - 1, TOPLEVEL::type::Write); - -// stages has been fixed at 5 (current max stages) until a programatic -// way can be found to set max to this value} + send_data(TOPLEVEL::action::forceUpdate, FILTERINSERT::control::stages, o->value() - 1, TOPLEVEL::type::Write);} tooltip {Filter stages (in order to increase dB/oct. value and the order of the filter)} xywh {78 10 31 15} type Simple labelsize 10 align 8 minimum 1 maximum 5 step 1 value 1 textfont 1 textsize 10 } } + Fl_Text_Display filterparamslabel { + label Parameters + xywh {135 14 50 4} box NO_BOX labelfont 1 labelsize 10 + } Fl_Button editbutton { label Edit callback {// @@ -528,12 +528,20 @@ xywh {220 8 15 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 10 labelcolor 7 } Fl_Check_Button freqtrackoffset { - label { 0 /+} callback {// - send_data(TOPLEVEL::action::forceUpdate, FILTERINSERT::control::frequencyTrackingRange, o->value(), TOPLEVEL::type::Write);} - tooltip {Set frequency tracking range to 0%-200%} xywh {238 10 33 16} down_box DOWN_BOX labelsize 10 align 24 + int tmp = (o->value() != 0); + send_data(TOPLEVEL::action::forceUpdate, FILTERINSERT::control::frequencyTrackingRange, tmp, TOPLEVEL::type::Write);} + tooltip {Set frequency tracking range to 0%-200%} xywh {236 10 16 16} down_box DOWN_BOX align 24 class Fl_Check_Button2 } + Fl_Text_Display freqtracknormal { + label {- /+} + xywh {242 24 44 4} box NO_BOX labelsize 10 textsize 10 + } + Fl_Text_Display freqtrackchecked { + label {0/+} + xywh {242 24 44 4} box NO_BOX labelsize 10 textsize 10 hide + } } } Function {make_formant_window()} {} { @@ -806,7 +814,7 @@ code {// int size = int(dScale * 10); - filterparamswindow->labelsize(size); + filterparamslabel->labelsize(size); cfreqdial->labelsize(size); qdial->labelsize(size); @@ -830,8 +838,9 @@ editbutton->labelsize(size); filtC->labelsize(size); filtP->labelsize(size); - - freqtrackoffset->labelsize(size);} {} + freqtrackoffset->labelsize(size); + freqtracknormal->labelsize(size); + freqtrackchecked->labelsize(size);} {} } Function {formantRtext()} {} { code {// @@ -902,6 +911,11 @@ unsigned char part = getData->data.part; unsigned char kititem = getData->data.kit; unsigned char eng = getData->data.engine; + unsigned char param = getData->data.parameter; + unsigned char offset = getData->data.offset; + + bool isCurrent = (param == nformant && offset == nvowel); + int value_int = lrint(value); bool fromUs = ((getData->data.source & TOPLEVEL::action::noAction) == TOPLEVEL::action::fromGUI); @@ -932,7 +946,7 @@ break; case FILTERINSERT::control::frequencyTracking: - freqtrdial->value(value); + freqtrdial->value(value_int); break; case FILTERINSERT::control::velocitySensitivity: @@ -977,8 +991,18 @@ break; case FILTERINSERT::control::frequencyTrackingRange: - freqtrackoffset->value(value != 0); - freqtrdial->setValueType(getFilterFreqTrackType(value != 0)); + freqtrackoffset->value(value_int); + freqtrdial->setValueType(getFilterFreqTrackType(value_int)); + if (value_int) + { + freqtracknormal->hide(); + freqtrackchecked->show(); + } + else + { + freqtracknormal->show(); + freqtrackchecked->hide(); + } break; case FILTERINSERT::control::formantSlowness: @@ -990,18 +1014,27 @@ break; case FILTERINSERT::control::formantFrequency: - formant_freq_dial->value(value); - formantfiltergraph->redraw(); + if (isCurrent) + { + formant_freq_dial->value(value); + formantfiltergraph->redraw(); + } break; case FILTERINSERT::control::formantQ: - formant_q_dial->value(value); - formantfiltergraph->redraw(); + if (isCurrent) + { + formant_q_dial->value(value); + formantfiltergraph->redraw(); + } break; case FILTERINSERT::control::formantAmplitude: - formant_amp_dial->value(value); - formantfiltergraph->redraw(); + if (isCurrent) + { + formant_amp_dial->value(value); + formantfiltergraph->redraw(); + } break; case FILTERINSERT::control::formantStretch: diff -Nru yoshimi-2.1.1.1~dfsg0/src/UI/LFOUI.fl yoshimi-2.1.2.2~dfsg0/src/UI/LFOUI.fl --- yoshimi-2.1.1.1~dfsg0/src/UI/LFOUI.fl 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/UI/LFOUI.fl 2021-12-03 20:12:12.000000000 +0000 @@ -1,5 +1,5 @@ # data file for the Fltk User Interface Designer (fluid) -version 1.0304 +version 1.0305 header_name {.h} code_name {.cc} comment {LFOUI.h} {not_in_source in_header @@ -143,7 +143,7 @@ code0 {o->add("Sine");o->add("Tri");o->add("Squr");o->add("R.up");o->add("R.dn");o->add("E1dn");o->add("E2dn");o->add("S&&H");o->add("RSqU");o->add("RSqD");} } {} Fl_Dial randomness { - label {Amp.} + label {Amp. } callback {// send_data(0, group, LFOINSERT::control::amplitudeRandomness, o->value(), TOPLEVEL::type::Integer);} tooltip {LFO Amplitude Randomness} xywh {145 30 20 20} box ROUND_UP_BOX labelsize 10 align 1 maximum 127 step 1 @@ -151,7 +151,7 @@ class WidgetPDial } Fl_Dial freqrand { - label {Freq.} + label { Freq.} callback {// send_data(0, group, LFOINSERT::control::frequencyRandomness, o->value(), TOPLEVEL::type::Integer);} tooltip {LFO Frequency Randomness} xywh {170 30 20 20} box ROUND_UP_BOX labelsize 10 align 1 maximum 127 step 1 diff -Nru yoshimi-2.1.1.1~dfsg0/src/UI/MasterMiscUI.fl yoshimi-2.1.2.2~dfsg0/src/UI/MasterMiscUI.fl --- yoshimi-2.1.1.1~dfsg0/src/UI/MasterMiscUI.fl 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/UI/MasterMiscUI.fl 2021-12-03 20:12:12.000000000 +0000 @@ -1,5 +1,5 @@ # data file for the Fltk User Interface Designer (fluid) -version 1.0304 +version 1.0305 header_name {.h} code_name {.cc} comment {MasterUI.h} {not_in_source in_header @@ -102,8 +102,7 @@ } decl {\#include "Misc/NumericFuncs.h" - using func::dB2rap; - using func::rap2dB;} {private local + using func::asDecibel;} {private local } decl {\#include "Misc/FormatFuncs.h" @@ -147,12 +146,16 @@ int oy = y(); int lx = w(); int ly = h(); - float dbl = rap2dB(fetchData(0, MAIN::control::readMainLRpeak, TOPLEVEL::section::main, 0)); - float dbr = rap2dB(fetchData(0, MAIN::control::readMainLRpeak, TOPLEVEL::section::main, 1)); - float rmsdbl = rap2dB(fetchData(0, MAIN::control::readMainLRrms, TOPLEVEL::section::main, 0)); - float rmsdbr = rap2dB(fetchData(0, MAIN::control::readMainLRrms, TOPLEVEL::section::main, 1)); + float dbl = asDecibel(fetchData(0, MAIN::control::readMainLRpeak, TOPLEVEL::section::main, 0)); + float dbr = asDecibel(fetchData(0, MAIN::control::readMainLRpeak, TOPLEVEL::section::main, 1)); + float rmsdbl = asDecibel(fetchData(0, MAIN::control::readMainLRrms, TOPLEVEL::section::main, 0)); + float rmsdbr = asDecibel(fetchData(0, MAIN::control::readMainLRrms, TOPLEVEL::section::main, 1)); clipped = clipped | (dbl > 0) | ((dbr > 0) << 1); + if (dbl > 0.5f) + dbl = 0.5f; + if (dbr > 0.5f) + dbr = 0.5f; if (dbl > maxdbl) maxdbl = dbl; @@ -231,6 +234,7 @@ // show maxdB static char tmpstr[8]; const char *dbtag = "dB"; + if ((maxdbl > NO_DB)) { fl_font(FL_HELVETICA | FL_BOLD, 9); @@ -239,6 +243,7 @@ fl_draw(tmpstr, ox + VULENX + 1, oy + 1, lx - VULENX - 4, VULENY - 2, FL_ALIGN_RIGHT, NULL, 0); } + if ((maxdbr > NO_DB)) { fl_font(FL_HELVETICA | FL_BOLD, 9); @@ -255,7 +260,7 @@ int lx = w()-4; int ly = h()-4; int mid = (w() / 2) - 2; - float Vpeak = fetchData(0, MAIN::control::readPartPeak, TOPLEVEL::section::main, npart + *plgroup); + float Vpeak = fetchData(0, MAIN::control::readPartPeak, TOPLEVEL::section::main, npart); if (Vpeak < 0) // its inactive { fl_rectf(ox, oy, lx, ly, 140, 140, 140); @@ -263,38 +268,42 @@ else { - if (Vpeak > 1.0) - panelpart.clip[npart + *plgroup] = true; + if (Vpeak > 1.0f) + { + panelpart.clip[npart] = true; + if (Vpeak > 1.5f) + Vpeak = 1.0f; + } // draw the vu lines - float db = rap2dB(Vpeak); + float db = asDecibel(Vpeak); db = (MIN_DB - db) / MIN_DB; db = (db > 1.0) ? 1.0 : db; db = db * ly - 2; - panelpart.oldpeak[npart + *plgroup] = (int) db; + panelpart.oldpeak[npart] = int(db); fl_rectf(ox, oy,mid, ly, 0, 0, 0); - fl_rectf(ox, oy + ly - panelpart.oldpeak[npart + *plgroup], mid, panelpart.oldpeak[npart + *plgroup], 0, 200, 255); - if (panelpart.clip[npart + *plgroup]) + fl_rectf(ox, oy + ly - panelpart.oldpeak[npart], mid, panelpart.oldpeak[npart], 0, 200, 255); + if (panelpart.clip[npart]) fl_rectf(ox, oy, mid, 4, 255, 0, 0); - Vpeak = fetchData(0, MAIN::control::readPartPeak, TOPLEVEL::section::main, npart + *plgroup, 1); + Vpeak = fetchData(0, MAIN::control::readPartPeak, TOPLEVEL::section::main, npart, 1); if (Vpeak > 1.0) - panelpart.clipR[npart + *plgroup] = true; - db = rap2dB(Vpeak); + panelpart.clipR[npart] = true; + db = asDecibel(Vpeak); db = (MIN_DB - db) / MIN_DB; db = (db > 1.0) ? 1.0 : db; db = db * ly - 2; - panelpart.oldpeakR[npart + *plgroup] = (int) db; + panelpart.oldpeakR[npart] = int(db); fl_rectf(ox + mid, oy,lx - mid, ly, 0, 0, 0); - fl_rectf(ox + mid, oy + ly - panelpart.oldpeakR[npart + *plgroup], lx - mid, panelpart.oldpeakR[npart + *plgroup], 0, 200, 255); - if (panelpart.clipR[npart + *plgroup]) + fl_rectf(ox + mid, oy + ly - panelpart.oldpeakR[npart], lx - mid, panelpart.oldpeakR[npart], 0, 200, 255); + if (panelpart.clipR[npart]) fl_rectf(ox + mid, oy, lx - mid, 4, 255, 0, 0); // draw the scales float tmp = ly * 1.0 / MIN_DB; for (int i = 1; i < 1 - MIN_DB; ++i) { - int ty = ly + (int)(tmp * i); + int ty = ly + int(tmp * i); if (i % 5 == 0) fl_rectf(ox, oy + ly - ty, lx, 1, 0, 160, 200); if (i % 10 == 0) @@ -305,11 +314,10 @@ } Function {draw()} {} { code {// - if (npart>=0) + if (npart >= 0) draw_part(); else - draw_master(); - ;} {} + draw_master();} {} } Function {tickdraw(VUMeter *o)} {return_type {static void} } { diff -Nru yoshimi-2.1.1.1~dfsg0/src/UI/MasterUI.fl yoshimi-2.1.2.2~dfsg0/src/UI/MasterUI.fl --- yoshimi-2.1.1.1~dfsg0/src/UI/MasterUI.fl 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/UI/MasterUI.fl 2021-12-03 20:12:12.000000000 +0000 @@ -1,5 +1,5 @@ # data file for the Fltk User Interface Designer (fluid) -version 1.0304 +version 1.0305 header_name {.h} code_name {.cc} comment {MasterUI.h} {not_in_source in_header @@ -236,7 +236,7 @@ } } -class MasterUI {: {private GuiUpdates} +class MasterUI {open : {private GuiUpdates} } { Function {MasterUI(SynthEngine *_synth)} {} { code {// @@ -1565,6 +1565,7 @@ Fl_Button favecancel { label Back callback {// + fileroldpath->activate(); filernewname->activate(); fileruse->activate(); filerback->activate(); @@ -1925,6 +1926,7 @@ } Function {setfavourites()} {} { code {// + fileroldpath->deactivate(); filernewname->deactivate(); fileruse->deactivate(); filerback->deactivate(); @@ -3528,10 +3530,13 @@ if (yoshiLog->logConsole->visible()) yoshiLog->consoleRtext(); - if (panelwindow->visible() && panelwindow->w() != lastpanelW) + if (panelwindow->visible()) { - panelRtext(); - lastpanelW = panelwindow->w(); + if (panelwindow->w() != lastpanelW) + { + panelRtext(); + lastpanelW = panelwindow->w(); + } } if (message->visible() && message->w() != lastmsgW) diff -Nru yoshimi-2.1.1.1~dfsg0/src/UI/MiscGui.cpp yoshimi-2.1.2.2~dfsg0/src/UI/MiscGui.cpp --- yoshimi-2.1.1.1~dfsg0/src/UI/MiscGui.cpp 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/UI/MiscGui.cpp 2021-12-03 20:12:12.000000000 +0000 @@ -32,6 +32,7 @@ #include using func::bpm2text; +using func::power; namespace { // Implementation details... @@ -425,6 +426,8 @@ synth->getGuiMaster()->partui->padnoteui->resui->returns_update(getData); break; } + if (getData->data.offset == 0) + synth->getGuiMaster()->partui->padnoteui->applycolour(FL_RED); } else if (miscmsg != NO_MSG) { @@ -631,14 +634,14 @@ return(custom_value_units((val-96.0f)/96.0f*40.0f,"dB",1)); case VC_LFOfreq: - f = (powf(2.0f, val * 10.0f) - 1.0f) / 12.0f; + f = (power<2>(val * 10.0f) - 1.0f) / 12.0f; return variable_prec_units(f, "Hz", 3); case VC_LFOfreqBPM: return bpm2text(val); case VC_LFOdepthFreq: // frequency LFO - f=powf(2.0f,(int)val/127.0f*11.0f)-1.0f; + f=power<2>((int)val/127.0f*11.0f)-1.0f; return variable_prec_units(f, "cents", 2); case VC_LFOdepthAmp: // amplitude LFO @@ -664,14 +667,14 @@ case VC_EnvelopeDT: // unfortunately converttofree() is not called in time for us to // be able to use env->getdt(), so we have to compute ourselves - f = (powf(2.0f, ((int)val) / 127.0f * 12.0f) - 1.0f) * 10.0f; + f = (power<2>(((int)val) / 127.0f * 12.0f) - 1.0f) * 10.0f; if (f >= 1000) return variable_prec_units(f/1000.0f, "s", 2); else return variable_prec_units(f, "ms", 2); case VC_EnvelopeFreqVal: - f=(powf(2.0f, 6.0f * fabsf((int)val - 64.0f) / 64.0f) -1.0f) * 100.0f; + f=(power<2>(6.0f * fabsf((int)val - 64.0f) / 64.0f) -1.0f) * 100.0f; if ((int)val<64) f = -f; return variable_prec_units(f, "cents", 2); @@ -690,18 +693,18 @@ return variable_prec_units(f, "dB", 2); case VC_EnvelopeBandwidthVal: - f = powf(2.0f, 10.0f * ((int)val - 64) / 64.0f); + f = power<2>(10.0f * ((int)val - 64) / 64.0f); return variable_prec_units(f, "x", 4); case VC_FilterFreq0: // AnalogFilter - f=powf(2.0f, (val / 64.0f - 1.0f) * 5.0f + 9.96578428f); + f=power<2>((val / 64.0f - 1.0f) * 5.0f + 9.96578428f); if (f >= 1000.0f) return variable_prec_units(f/1000.0f, "kHz", 2); else return variable_prec_units(f, "Hz", 2); case VC_FilterFreq2: // SVFilter - f=powf(2.0f, (val / 64.0f - 1.0f) * 5.0f + 9.96578428f); + f=power<2>((val / 64.0f - 1.0f) * 5.0f + 9.96578428f); // We have to adjust the freq because of this line // in method SVFilter::computefiltercoefs() (file SVFilter.cpp) // @@ -709,7 +712,7 @@ // // Using factor 4.0 instead of the usual 2.0*PI leads to a // different effective cut-off freq, which we will be showing - f *= 4.0 / (2.0 * PI); + f *= 4.0 / TWOPI; if (f >= 1000.0f) return variable_prec_units(f/1000.0f, "kHz", 2); else @@ -730,8 +733,8 @@ case VC_FilterVelocityAmp: val = (int)val / 127.0 * -6.0; // formant offset value - f = powf(2.0f,val + log(1000.0f)/log(2.0f)); // getrealfreq - f = log(f/1000.0f)/log(powf(2.0f,1.0f/12.0f))*100.0f; // in cents + f = power<2>(val + log(1000.0f)/log(2.0f)); // getrealfreq + f = log(f/1000.0f)/log(power<2>(1.0f/12.0f))*100.0f; // in cents return custom_value_units(f-0.5, "cents") + "\n(Formant offset: " + custom_value_units(val, "x stretch)",2); @@ -750,7 +753,7 @@ return(s); case VC_FormFilterClearness: - f = powf(10.0f, (val - 32.0f) / 48.0f); + f = power<10>((val - 32.0f) / 48.0f); return custom_value_units(f, " switch rate",2); case VC_FormFilterSlowness: @@ -824,7 +827,7 @@ case VC_EnvStretch: s.clear(); - f = powf(2.0f,(int)val/64.0f); + f = power<2>((int)val/64.0f); s += custom_value_units((int)val/127.0f*100.0f+0.05f,"%",1); if ((int)val!=0) { @@ -837,7 +840,7 @@ s.clear(); i = val; i = (i == 0) ? 1 : (i); // val == 0 is not allowed - f = powf(2.0f,(i-64.0)/63.0f); + f = power<2>((i-64.0)/63.0f); s += custom_value_units((i-64.0f)/63.0f*100.0f,"%"); if (i != 64) { @@ -853,13 +856,13 @@ return(custom_value_units(f+((f<0) ? (-0.005f) : (0.005f)),"Hz",2)); case VC_FixedFreqET: - f = powf(2.0f, (lrint(val) - 1) / 63.0f) - 1.0f; + f = power<2>((lrint(val) - 1) / 63.0f) - 1.0f; if (lrint(val) <= 1) /* 0 and 1 are both fixed */ return "Fixed"; else if (lrint(val) <= 64) - return custom_value_units(powf(2.0f,f),"x /octave up",2); + return custom_value_units(power<2>(f),"x /octave up",2); else - return custom_value_units(powf(3.0f,f),"x /octave up",2); + return custom_value_units(power<3>(f),"x /octave up",2); case VC_FilterGain: f = ((int)val / 64.0f -1.0f) * 30.0f; // -30..30dB @@ -874,7 +877,7 @@ s += "Velocity sensing disabled."; return(s); } - f = powf(8.0f, (64.0f - (float)i) / 64.0f); + f = power<8>((64.0f - (float)i) / 64.0f); // Max dB range for vel=1 compared to vel=127 s += "Velocity Dynamic Range "; f = -20.0f * logf(powf((1.0f / 127.0f), f)) / log(10.0f); @@ -885,7 +888,7 @@ case VC_BandWidth: f = powf((int)val / 1000.0f, 1.1f); - f = powf(10.0f, f * 4.0f) * 0.25f; + f = power<10>(f * 4.0f) * 0.25f; return variable_prec_units(f, "cents", 2); case VC_SubBandwidth: @@ -893,11 +896,11 @@ Considering the variability of the synthesis depending on number of filter stages, it seems accurate enough. */ - f = powf(10.0f, (val - 127.0f) / 127.0f * 4.0f) * 4800; + f = power<10>((val - 127.0f) / 127.0f * 4.0f) * 4800; return variable_prec_units(f, "cents", 3); case VC_SubBandwidthRel: - f = powf(100.0f, val / 64.0f); + f = power<100>(val / 64.0f); return variable_prec_units(f, "x", 3); case VC_SubHarmonicMagnitude: @@ -908,7 +911,7 @@ return "Constant"; f = val / 64.0f * 3.0f; return "Factor (100,10k): " + - variable_prec_units(powf(10,f), "", 4) + ", " + + variable_prec_units(power<10>(f), "", 4) + ", " + variable_prec_units(powf(0.1,f), "x", 4); case VC_FilterVelocitySense: // this is also shown graphically @@ -945,7 +948,7 @@ s.clear(); // ToDo: It would be nice to calculate the ratio between left // and right. We would need to know the delay time however... - f = (powf(2.0f, fabsf((int)val-64.0f)/64.0f*9.0f)-1.0); // ms + f = (power<2>(fabsf((int)val-64.0f)/64.0f*9.0f)-1.0); // ms if ((int)val < 64) { s+="left +"+custom_value_units(f+0.05,"ms",1)+" / "; @@ -985,7 +988,7 @@ return(custom_value_units(f,"dB",1)); case VC_FXReverbTime: - f = powf(60.0f, (int)val / 127.0f) - 0.97f; // s + f = power<60>((int)val / 127.0f) - 0.97f; // s return variable_prec_units(f, "s", 2, true); case VC_FXReverbIDelay: @@ -1048,18 +1051,18 @@ return(custom_value_units(f,"dB",1)); case VC_FXlfofreq: - f = (powf(2.0f, (int)val / 127.0f * 10.0f) - 1.0f) * 0.03f; + f = (power<2>((int)val / 127.0f * 10.0f) - 1.0f) * 0.03f; return variable_prec_units(f, "Hz", 3); case VC_FXlfofreqBPM: return bpm2text(val / 127.0f); case VC_FXChorusDepth: - f = powf(8.0f, ((int)val / 127.0f) * 2.0f) -1.0f; //ms + f = power<8>(((int)val / 127.0f) * 2.0f) -1.0f; //ms return variable_prec_units(f, "ms", 2, true); case VC_FXChorusDelay: - f = powf(10.0f, ((int)val / 127.0f) * 2.0f) -1.0f; //ms + f = power<10>(((int)val / 127.0f) * 2.0f) -1.0f; //ms return variable_prec_units(f, "ms", 2, true); case VC_FXdefaultFb: @@ -1095,14 +1098,14 @@ return(s); case VC_FXEQfreq: - f = 600.0f * powf(30.0f, ((int)val - 64.0f) / 64.0f); + f = 600.0f * power<30>(((int)val - 64.0f) / 64.0f); if (f >= 1000) return variable_prec_units(f/1000.f, "kHz", 2); else return variable_prec_units(f, "Hz", 2, true); case VC_FXEQq: - f = powf(30.0f, ((int)val - 64.0f) / 64.0f); + f = power<30>(((int)val - 64.0f) / 64.0f); return variable_prec_units(f, "", 3, true); case VC_FXEQgain: @@ -1171,6 +1174,7 @@ default: w = 0; h = 0; + break; } } @@ -1205,7 +1209,7 @@ { case VC_FilterVelocitySense: { - p = powf(8.0f,(64.0f-(int)val)/64.0f); + p = power<8>((64.0f-(int)val)/64.0f); /* Grid */ grid(x0,y0,_w,_h, 4); @@ -1231,7 +1235,7 @@ } case VC_FormFilterClearness: { - p = powf(10.0f, (val - 32.0f) / 48.0f); //clearness param + p = power<10>((val - 32.0f) / 48.0f); //clearness param grid(x0,y0,_w,_h,10); fl_color(FL_BLUE); fl_begin_line(); @@ -1337,7 +1341,7 @@ cairo_set_source_rgb(cr, 1, 0, 0); cairo_set_line_width(cr, 1.5); - cairo_move_to(cr, x0, cy - ry * log10(powf(50, p))); + cairo_move_to(cr, x0, cy - ry * log10(power<50>(p))); cairo_line_to(cr, x0 + _w, cy - ry * log10(powf(0.05, p))); cairo_stroke(cr); @@ -1363,7 +1367,7 @@ } if (roundup) { - v += 5 * powf(10,-(digits + 1)); + v += 5 * power<10>(-(digits + 1)); } return custom_value_units(v, u, digits); } diff -Nru yoshimi-2.1.1.1~dfsg0/src/UI/OscilGenUI.fl yoshimi-2.1.2.2~dfsg0/src/UI/OscilGenUI.fl --- yoshimi-2.1.1.1~dfsg0/src/UI/OscilGenUI.fl 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/UI/OscilGenUI.fl 2021-12-03 20:12:12.000000000 +0000 @@ -1,5 +1,5 @@ # data file for the Fltk User Interface Designer (fluid) -version 1.0304 +version 1.0305 header_name {.h} code_name {.cc} comment {OscilgenUI.h} {not_in_source in_header @@ -29,7 +29,7 @@ This file is a derivative of the ZynAddSubFX original. -} {selected in_source in_header +} {in_source in_header } decl {\#include "ResonanceUI.h"} {public local @@ -84,8 +84,8 @@ } decl {\#include "Misc/NumericFuncs.h" - using func::dB2rap; - using func::rap2dB;} {private local + using func::decibel; + using func::asDecibel;} {private local } class OscilSpectrum {: {public Fl_Box} @@ -162,8 +162,8 @@ int tmp = i * GX + 2; x = spc[i] / max; - if (x > dB2rap(-maxdb)) - x = rap2dB(x) / maxdb + 1; + if (x > decibel(-maxdb)) + x = asDecibel(x) / maxdb + 1; else x = 0; @@ -458,25 +458,30 @@ } } -class OscilEditor {: {public PresetsUI_} +class OscilEditor {open : {public PresetsUI_} } { - Function {make_window()} {} { + Function {make_window()} {open + } { Fl_Window osceditUI { label {ADsynth Oscillator Editor} callback {saveWin(synth, osceditUI->w(), osceditUI->h(), osceditUI->x(), osceditUI->y(), false, "Waveform " + to_string(waveType)); OSCseen = false; -o->hide();} - xywh {11 26 735 595} type Double hide resizable +o->hide();} open + xywh {11 26 735 595} type Double labelsize 12 hide resizable code0 {string tname;} code1 {setWindowTitle();} code2 {waveDW = o->w() * 9 / 10; waveDH = o->h() * 9 / 10;} code3 {o->size_range(waveDW, waveDH, 0, 0, 0, 0, 1);} } { + Fl_Box applybox { + xywh {298 278 64 24} box THIN_UP_BOX color 237 + code0 {if (!oscil->ADvsPAD) o->hide();} + } Fl_Button applybutton { label Apply callback {// - send_data(TOPLEVEL::action::forceUpdate, PART::control::padsynthParameters, 0, TOPLEVEL::type::Integer);} - xywh {300 280 60 20} box THIN_UP_BOX labelfont 1 + send_data(TOPLEVEL::action::forceUpdate, PART::control::padsynthParameters, 1, TOPLEVEL::type::Integer);} selected + xywh {301 281 58 18} box THIN_UP_BOX labelfont 1 labelsize 12 code0 {if (!oscil->ADvsPAD) o->hide();} } Fl_Group oscildisplaygroup { @@ -832,7 +837,7 @@ code {// float value = getData->data.value; unsigned char control = getData->data.control; - unsigned char eng = getData->data.engine; + //unsigned char eng = getData->data.engine; unsigned char insert = getData->data.insert; //if (eng != engine) @@ -1075,11 +1080,6 @@ waveformgroup->redraw(); harmonicgroup->redraw(); oldosc->redraw(); - if (eng == 2) - { - applybutton->color(FL_RED); - applybutton->redraw(); - } }} {} } Function {fetchData(float value, int control, int part, int kititem = UNUSED, int engine = UNUSED, int insert = UNUSED, int parameter = UNUSED, int offset = UNUSED, int miscmsg = UNUSED, int request = UNUSED)} {return_type float @@ -1263,8 +1263,8 @@ oldosc->redraw(); if (cbwidget!=NULL) { cbwidget->do_callback(); - applybutton->color(FL_RED); - applybutton->redraw(); + //applybutton->color(FL_RED); + //applybutton->redraw(); };} {} } Function {waveRtext()} {} { @@ -1278,7 +1278,7 @@ int size12 = int(12 * dScale); int size14 = int(14 * dScale); - applybutton->labelsize(size14); + applybutton->labelsize(size12); hrndtype->labelsize(size); hrndtype->textsize(size); oscilname->labelsize(size12); diff -Nru yoshimi-2.1.1.1~dfsg0/src/UI/PADnoteUI.fl yoshimi-2.1.2.2~dfsg0/src/UI/PADnoteUI.fl --- yoshimi-2.1.1.1~dfsg0/src/UI/PADnoteUI.fl 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/UI/PADnoteUI.fl 2021-12-03 20:12:12.000000000 +0000 @@ -1,5 +1,5 @@ # data file for the Fltk User Interface Designer (fluid) -version 1.0304 +version 1.0305 header_name {.h} code_name {.cc} comment {PADNoteUI.h} {not_in_source in_header @@ -57,8 +57,9 @@ } decl {\#include "Misc/NumericFuncs.h" - using func::dB2rap; - using func::rap2dB;} {private local + using func::decibel; + using func::asDecibel; + using func::power;} {private local } decl {\#include "Misc/TextMsgBuffer.h" @@ -243,8 +244,8 @@ for (int i = 0; i < lx; i++) { float x = spectrum[i]; - if (x > dB2rap(-maxdb)) - x = rap2dB(x) / maxdb + 1; + if (x > decibel(-maxdb)) + x = asDecibel(x) / maxdb + 1; else continue; int yy = (int)(x * ly); @@ -274,9 +275,14 @@ Fl_Tabs {} { callback {// if (o->value() != harmonicstructuregroup) + { + applybox->hide(); applybutton->hide(); + } else - applybutton->show();} + { + applybox->show(); + applybutton->show();}} xywh {0 0 580 405} } { Fl_Group harmonicstructuregroup { @@ -397,9 +403,7 @@ Fl_Box cbwidget { label {Harmonic Content} callback {// - overtonepos->redraw(); - applybutton->color(FL_RED); - applybutton->redraw();} + overtonepos->redraw();} xywh {125 135 205 20} labelsize 12 align 16 } Fl_Button resonance { @@ -548,11 +552,11 @@ xywh {0 20 580 385} box ENGRAVED_BOX labelsize 12 hide } { Fl_Box {} { - xywh {9 27 275 68} box PLASTIC_THIN_UP_BOX color 223 + xywh {10 27 275 68} box PLASTIC_UP_BOX color 223 } Fl_Group ampgrp { label AMPLITUDE - xywh {5 25 285 250} box THIN_UP_FRAME labelfont 1 labelsize 11 align 17 + xywh {5 27 285 250} box THIN_UP_FRAME labelfont 1 labelsize 11 align 17 } { Fl_Dial volume { label Volume @@ -801,12 +805,14 @@ send_data(TOPLEVEL::action::forceUpdate, MAIN::control::exportPadSynthSamples, 0, TOPLEVEL::type::Integer, npart, textMsgBuffer.push(filename));} tooltip {Export samples as wav file} xywh {15 410 123 24} box THIN_UP_BOX labelfont 1 labelsize 12 align 128 } + Fl_Box applybox { + xywh {236 407 139 31} box THIN_UP_BOX color 237 selection_color 29 + } Fl_Button applybutton { label {Apply Changes} callback {// - send_data(TOPLEVEL::action::forceUpdate, PADSYNTH::control::applyChanges, o->value(), TOPLEVEL::type::Integer);} - xywh {240 410 131 24} box THIN_UP_BOX labelfont 1 labelsize 12 - code0 {o->color(FL_RED);} + send_data(TOPLEVEL::action::forceUpdate, PADSYNTH::control::applyChanges, 1, TOPLEVEL::type::Integer);} + xywh {242 412 128 22} box THIN_UP_BOX labelfont 1 labelsize 12 } Fl_Button padCopy { label C @@ -1033,7 +1039,7 @@ case PADSYNTH::control::bandwidth: bwdial->value(value); result = powf(value / 1000.0f, 1.1f); - result = powf(10.0f, result * 4.0f) * 0.25f; + result = power<10>(result * 4.0f) * 0.25f; bwcents->value(result); cbwidget->do_callback(); break; @@ -1240,33 +1246,12 @@ if (wasFromHere) alert(synth, "Some samples have failed."); } - applybutton->color(FL_GRAY); - applybutton->redraw(); - if (oscui) - { - oscui->applybutton->color(FL_GRAY); - oscui->applybutton->redraw(); - } - if (resui) - { - resui->applybutton->color(FL_GRAY); - resui->applybutton->redraw(); - } - break; // TODO drop-through intended? + applycolour(FL_GRAY); + break; case PADSYNTH::control::applyChanges: - applybutton->color(FL_GRAY); - applybutton->redraw(); - if (oscui) - { - oscui->applybutton->color(FL_GRAY); - oscui->applybutton->redraw(); - } - if (resui) - { - resui->applybutton->color(FL_GRAY); - resui->applybutton->redraw(); - } + if (lrint(value) == 1) + applycolour(FL_GRAY); break; case PADSYNTH::control::stereo: @@ -1295,6 +1280,21 @@ }} {} } + Function {applycolour(int set)} {} { + code {// + applybutton->color(set); + applybutton->redraw(); + if (oscui) + { + oscui->applybutton->color(set); + oscui->applybutton->redraw(); + } + if (resui) + { + resui->applybutton->color(set); + resui->applybutton->redraw(); + }} {} + } Function {PADnoteUI(PADnoteParameters *parameters, int npart_, int kititem_)} {} { code {// synth = parameters->getSynthEngine(); diff -Nru yoshimi-2.1.1.1~dfsg0/src/UI/ResonanceUI.fl yoshimi-2.1.2.2~dfsg0/src/UI/ResonanceUI.fl --- yoshimi-2.1.1.1~dfsg0/src/UI/ResonanceUI.fl 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/UI/ResonanceUI.fl 2021-12-03 20:12:12.000000000 +0000 @@ -1,5 +1,5 @@ # data file for the Fltk User Interface Designer (fluid) -version 1.0304 +version 1.0305 header_name {.h} code_name {.cc} comment {ResonanceUI.h} {not_in_source in_header @@ -11,7 +11,7 @@ comment {Original ZynAddSubFX author Nasca Octavian Paul Copyright (C) 2002-2005 Nasca Octavian Paul Copyright 2009-2010, Alan Calvert -Copyright 2015-2020, Will Godfrey +Copyright 2015-2021, Will Godfrey This file is part of yoshimi, which is free software: you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -71,6 +71,10 @@ decl {\#include "Misc/SynthEngine.h"} {public global } +decl {\#include "Misc/NumericFuncs.h" + using func::power;} {private local +} + class ResonanceGraph {: {public Fl_Box} } { Function {ResonanceGraph(int x,int y, int w, int h, const char *label=0):Fl_Box(x,y,w,h,label)} {} { @@ -258,11 +262,6 @@ if (cbwidget != NULL) { cbwidget->do_callback(); - if (applybutton != NULL) - { - applybutton->color(FL_RED); - applybutton->redraw(); - } } } @@ -316,7 +315,7 @@ } Fl_Value_Output dbvalue { label dB - xywh {435 282 40 18} labelsize 12 align 8 minimum -150 maximum 150 textfont 1 textsize 12 + xywh {435 283 40 18} labelsize 12 align 8 minimum -150 maximum 150 textfont 1 textsize 12 code0 {o->step(0.1, 1);} code1 {//this widget must be before the calling widgets} } @@ -336,7 +335,7 @@ label Smooth callback {// send_data(TOPLEVEL::action::forceUpdate, RESONANCE::control::smoothGraph, o->value(), TOPLEVEL::type::Integer);} - tooltip {Smooth the resonance function} xywh {507 282 66 18} box THIN_UP_BOX labelfont 1 labelsize 12 + tooltip {Smooth the resonance function} xywh {507 283 66 18} box THIN_UP_BOX labelfont 1 labelsize 12 } Fl_Value_Output maxdbvo { label {Max dB} @@ -351,7 +350,7 @@ o->value(20); send_data(TOPLEVEL::action::forceUpdate, RESONANCE::control::maxDb, o->value(), TOPLEVEL::type::Integer);} - xywh {77 282 98 18} type {Horz Knob} box THIN_DOWN_BOX labelsize 11 align 8 minimum 1 maximum 90 step 1 value 30 + xywh {77 283 98 18} type {Horz Knob} box THIN_DOWN_BOX labelsize 11 align 8 minimum 1 maximum 90 step 1 value 30 code0 {o->value(respar->PmaxdB);} class mwheel_slider_rev } @@ -384,42 +383,48 @@ o->value(64); send_data(TOPLEVEL::action::forceUpdate, RESONANCE::control::octaves, o->value(), TOPLEVEL::type::Integer);} - xywh {243 282 110 18} type {Horz Knob} box THIN_DOWN_BOX labelsize 11 align 8 maximum 127 step 1 + xywh {243 283 110 18} type {Horz Knob} box THIN_DOWN_BOX labelsize 11 align 8 maximum 127 step 1 code0 {o->value(respar->Poctavesfreq);} class mwheel_slider_rev } + Fl_Box {} { + xywh {580 262 48 41} box THIN_UP_BOX color 237 + } Fl_Button rnd1 { label Rnd1 callback {// send_data(TOPLEVEL::action::forceUpdate, RESONANCE::control::randomType, 0, TOPLEVEL::type::Integer);} - tooltip {Randomize the resonance function} xywh {583 264 42 12} box THIN_UP_BOX labelfont 1 labelsize 10 + tooltip {Randomize the resonance function} xywh {583 264 42 11} box THIN_UP_BOX color 29 labelfont 1 labelsize 10 } Fl_Button rnd2 { label Rnd2 callback {// send_data(TOPLEVEL::action::forceUpdate, RESONANCE::control::randomType, 1, TOPLEVEL::type::Integer);} - tooltip {Randomize the resonance function} xywh {583 276 42 12} box THIN_UP_BOX labelfont 1 labelsize 10 + tooltip {Randomize the resonance function} xywh {583 277 42 11} box THIN_UP_BOX color 29 labelfont 1 labelsize 10 } Fl_Button rnd3 { label Rnd3 callback {// send_data(TOPLEVEL::action::forceUpdate, RESONANCE::control::randomType, 2, TOPLEVEL::type::Integer);} - tooltip {Randomize the resonance function} xywh {583 288 42 12} box THIN_UP_BOX labelfont 1 labelsize 10 + tooltip {Randomize the resonance function} xywh {583 290 42 11} box THIN_UP_BOX color 29 labelfont 1 labelsize 10 + } + Fl_Box {} { + xywh {104 263 18 18} box THIN_UP_BOX color 237 } Fl_Check_Button p1st { - class Fl_Check_Button2 - label {Prot.1st} + label { Prot.1st} callback {// send_data(TOPLEVEL::action::forceUpdate, RESONANCE::control::protectFundamental, o->value(), TOPLEVEL::type::Integer);} tooltip {Protect the fundamental frequency (do not damp the first harmonic)} xywh {106 265 45 15} down_box DOWN_BOX labelsize 12 code0 {o->value(respar->Pprotectthefundamental);} + class Fl_Check_Button2 } Fl_Text_Display interpk { label InterpPk xywh {364 280 62 0} box NO_BOX labelsize 12 align 33 textsize 12 } Fl_Box {} { - tooltip {Interpolate the peaks (left button smooth, right button linear)} xywh {359 264 72 36} box THIN_DOWN_FRAME + tooltip {Interpolate the peaks (left button smooth, right button linear)} xywh {359 264 72 37} box THIN_DOWN_FRAME } Fl_Button sbutton { label S @@ -444,18 +449,24 @@ xywh {665 275 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 11 labelcolor 7 } } + Fl_Box {} { + xywh {4 263 18 18} box THIN_UP_BOX color 237 + } Fl_Check_Button enabled { - class Fl_Check_Button2 - label Enable + label { Enable} callback {// send_data(TOPLEVEL::action::forceUpdate, RESONANCE::control::enableResonance, o->value(), TOPLEVEL::type::Integer);} xywh {6 265 78 15} down_box DOWN_BOX labelfont 1 labelsize 12 code0 {o->value(respar->Penabled);} + class Fl_Check_Button2 + } + Fl_Box applybox { + xywh {696 261 80 24} box THIN_UP_BOX color 237 } Fl_Button applybutton { label Apply callback {// - send_data(TOPLEVEL::action::forceUpdate, PART::control::padsynthParameters, 0, TOPLEVEL::type::Integer);} + send_data(TOPLEVEL::action::forceUpdate, PART::control::padsynthParameters, 1, TOPLEVEL::type::Integer);} xywh {700 265 74 17} box THIN_UP_BOX down_box THIN_DOWN_BOX labelfont 1 labelsize 12 } Fl_Button resClose { @@ -472,7 +483,7 @@ else synth->getGuiMaster()->partui->padnoteui->padnotewindow->show(); }} - tooltip {Right click: also reopen previous} xywh {700 285 74 16} box THIN_UP_BOX labelsize 12 + tooltip {Right click: also reopen previous} xywh {700 286 74 16} box THIN_UP_BOX labelsize 12 } } } @@ -513,7 +524,7 @@ case RESONANCE::control::centerFrequency: centerfreq->value(value); - value = 10000.0 * powf(10.0f, - (1.0f - value / 127.0f) * 2.0f); + value = 10000.0 * power<10>(- (1.0f - value / 127.0f) * 2.0f); centerfreqvo->value(value/1000.0); rg->redraw(); break; @@ -579,6 +590,7 @@ cbapplywidget = NULL; make_window(); resSeen = false; + applybox->hide(); applybutton->hide(); refresh();} {} } @@ -593,8 +605,6 @@ Function {redrawPADnoteApply()} {} { code {if (cbwidget!=NULL) { cbwidget->do_callback(); - applybutton->color(FL_RED); - applybutton->redraw(); };} {} } Function {setcbwidget(Fl_Widget *cbwidget,Fl_Widget *cbapplywidget)} {} { @@ -602,6 +612,7 @@ this->cbwidget = cbwidget; this->cbapplywidget = cbapplywidget; rg->setcbwidget(cbwidget, applybutton); + applybox->show(); applybutton->show();} {} } Function {refresh()} {} { diff -Nru yoshimi-2.1.1.1~dfsg0/src/UI/SUBnoteUI.fl yoshimi-2.1.2.2~dfsg0/src/UI/SUBnoteUI.fl --- yoshimi-2.1.1.1~dfsg0/src/UI/SUBnoteUI.fl 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/UI/SUBnoteUI.fl 2021-12-03 20:12:12.000000000 +0000 @@ -1,5 +1,5 @@ # data file for the Fltk User Interface Designer (fluid) -version 1.0304 +version 1.0305 header_name {.h} code_name {.cc} comment {SubNoteUI.h} {not_in_source in_header @@ -189,11 +189,11 @@ } {} } Fl_Box {} { - xywh {10 6 205 60} box PLASTIC_THIN_UP_BOX color 223 + xywh {10 6 205 60} box PLASTIC_UP_BOX color 223 } Fl_Group ampgrp { label AMPLITUDE - xywh {5 5 215 135} box THIN_UP_FRAME labelfont 1 labelsize 11 align 17 + xywh {5 6 215 135} box THIN_UP_FRAME labelfont 1 labelsize 11 align 17 } { Fl_Dial vol { label Volume @@ -238,7 +238,6 @@ class WidgetPDial } Fl_Check_Button randompan { - class Fl_Check_Button2 label Rand callback {// int tmp = o->value(); @@ -250,6 +249,7 @@ tooltip {Enable random panning} xywh {155 31 15 15} down_box DOWN_BOX color 48 labelsize 11 align 1 code0 {o->value(pars->PRandom);} code1 {if (o->value() == 0) panwidth->deactivate(); else panwidth->activate();} + class Fl_Check_Button2 } Fl_Box {} { xywh {108 22 4 37} box THIN_DOWN_FRAME @@ -267,7 +267,6 @@ class EnvelopeUI } {} Fl_Check_Button freqee { - class Fl_Check_Button2 label On callback {// if (o->value() == 0) @@ -279,6 +278,7 @@ send_data (0, SUBSYNTH::control::enableFrequencyEnvelope, o->value(), TOPLEVEL::type::Integer);} xywh {445 67 34 12} box THIN_UP_BOX down_box DOWN_BOX color 237 labelfont 1 labelsize 10 code0 {o->value(pars->PFreqEnvelopeEnabled);} + class Fl_Check_Button2 } Fl_Counter octave { label Octave @@ -307,7 +307,6 @@ class WidgetPDial } Fl_Check_Button hz440 { - class Fl_Check_Button2 label 440Hz callback {// int x = (int) o->value(); @@ -319,6 +318,7 @@ send_data (0, SUBSYNTH::control::baseFrequencyAs440Hz, x, TOPLEVEL::type::Integer);} tooltip {set the base frequency to 440Hz} xywh {620 24 48 15} down_box DOWN_BOX labelfont 1 labelsize 10 align 24 code0 {o->value(pars->Pfixedfreq);} + class Fl_Check_Button2 } Fl_Dial fixedfreqetdial { label {Eq.T.} @@ -382,7 +382,6 @@ class EnvelopeUI } {} Fl_Check_Button bwee { - class Fl_Check_Button2 label On callback {// if (o->value() == 0) @@ -394,6 +393,7 @@ send_data (0, SUBSYNTH::control::enableBandwidthEnvelope, o->value(), TOPLEVEL::type::Integer);} xywh {225 67 34 12} box THIN_UP_BOX down_box DOWN_BOX color 237 labelfont 1 labelsize 10 code0 {o->value(pars->PBandWidthEnvelopeEnabled);} + class Fl_Check_Button2 } Fl_Value_Slider bandwidth { label Bandwidth @@ -474,7 +474,6 @@ } {} } Fl_Check_Button filtere { - class Fl_Check_Button2 label On callback {// if (o->value() == 0) @@ -486,6 +485,7 @@ send_data (0, SUBSYNTH::control::enableFilter, o->value(), TOPLEVEL::type::Integer);} xywh {446 227 36 13} box THIN_UP_BOX down_box DOWN_BOX color 237 labelfont 1 labelsize 10 code0 {o->value(pars->PGlobalFilterEnabled);} + class Fl_Check_Button2 } Fl_Group {} { xywh {504 406 226 35} box THIN_UP_FRAME @@ -518,12 +518,12 @@ xywh {441 414 16 17} box THIN_UP_BOX color 237 } Fl_Check_Button stereo { - class Fl_Check_Button2 label { Stereo} callback {// send_data (0, SUBSYNTH::control::stereo, o->value(), TOPLEVEL::type::Integer);} xywh {442 415 59 15} down_box DOWN_BOX color 237 labelfont 1 labelsize 10 code0 {o->value(pars->Pstereo);} + class Fl_Check_Button2 } Fl_Button subClear { label Clear diff -Nru yoshimi-2.1.1.1~dfsg0/src/UI/WidgetPDial.cpp yoshimi-2.1.2.2~dfsg0/src/UI/WidgetPDial.cpp --- yoshimi-2.1.1.1~dfsg0/src/UI/WidgetPDial.cpp 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/src/UI/WidgetPDial.cpp 2021-12-03 20:12:12.000000000 +0000 @@ -6,7 +6,7 @@ Copyright 2009-2010, Alan Calvert Copyright 2016 Will Godfrey Copyright 2017 Jesper Lloyd - Coyright 2020, Will Godfrey & others + Coyright 2020 - 2021, Will Godfrey & others This file is part of yoshimi, which is free software: you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -194,7 +194,7 @@ } else { cairo_set_source_rgb(cr,0.4,0.4,0.4); } - cairo_arc(cr,0,0,dh,0,2*M_PI); + cairo_arc(cr,0,0,dh,0,2*PI); cairo_fill(cr); cairo_pattern_t* pat; //drawing the inner circle: @@ -202,14 +202,14 @@ cairo_pattern_add_color_stop_rgba (pat, 0, 0.8*186.0/255, 0.8*198.0/255, 0.8*211.0/255, 1); cairo_pattern_add_color_stop_rgba (pat, 1, 231.0/255, 235.0/255, 239.0/255, 1); cairo_set_source (cr, pat); - cairo_arc(cr,0,0,d*rCout,0,2*M_PI); + cairo_arc(cr,0,0,d*rCout,0,2*PI); cairo_fill(cr); //drawing the outer circle: pat = cairo_pattern_create_radial(2.0/35*d,6.0/35*d,2.0/35*d,0,0,d*rCint); cairo_pattern_add_color_stop_rgba (pat, 0, 231.0/255, 235.0/255, 239.0/255, 1); cairo_pattern_add_color_stop_rgba (pat, 1, 186.0/255, 198.0/255, 211.0/255, 1); cairo_set_source (cr, pat); - cairo_arc(cr,0,0,d*rCint,0,2*M_PI); + cairo_arc(cr,0,0,d*rCint,0,2*PI); cairo_fill(cr); //drawing the "light" circle: int linewidth = int(2.0f * sx / 30); @@ -223,7 +223,7 @@ } cairo_set_line_width (cr, linewidth); cairo_new_sub_path(cr); - cairo_arc(cr,0,0,d*rGear,0.75*M_PI,+val*1.5*M_PI+0.75*M_PI); + cairo_arc(cr,0,0,d*rGear,0.75*PI,+val*1.5*PI+0.75*PI); cairo_stroke(cr); //drawing the hand: if (active_r()) @@ -232,7 +232,7 @@ } else { cairo_set_source_rgb(cr,111.0/255,111.0/255,111.0/255); } - cairo_rotate(cr,val*3/2*M_PI+0.25*M_PI); + cairo_rotate(cr,val*3/2*PI+0.25*PI); cairo_set_line_width (cr, linewidth); cairo_move_to(cr,0,0); cairo_line_to(cr,0,d*rHand); diff -Nru yoshimi-2.1.1.1~dfsg0/Yoshimi_Helpers yoshimi-2.1.2.2~dfsg0/Yoshimi_Helpers --- yoshimi-2.1.1.1~dfsg0/Yoshimi_Helpers 2021-10-12 15:24:34.000000000 +0000 +++ yoshimi-2.1.2.2~dfsg0/Yoshimi_Helpers 2021-12-03 20:12:12.000000000 +0000 @@ -33,7 +33,9 @@ Iurie Nistor Stephen Parry Sebastian Ramacher +David Runge Adam Samson +Hugh Spiller Lorenzo Sutton Hermann Voßeler Nikita Zlobin