From 8dce0e480f94bc24a2cbb6fd39a4a289b9f7cb44 Mon Sep 17 00:00:00 2001 From: tresf Date: Sat, 4 Nov 2017 23:43:56 -0400 Subject: [PATCH 01/25] Move calf to submodule Currently broken --- plugins/LadspaEffect/calf/CMakeLists.txt | 45 --- plugins/LadspaEffect/calf/calf | 1 + plugins/LadspaEffect/cmt/doc/COPYING | 340 ----------------------- 3 files changed, 1 insertion(+), 385 deletions(-) delete mode 100644 plugins/LadspaEffect/calf/CMakeLists.txt create mode 160000 plugins/LadspaEffect/calf/calf delete mode 100644 plugins/LadspaEffect/cmt/doc/COPYING diff --git a/plugins/LadspaEffect/calf/CMakeLists.txt b/plugins/LadspaEffect/calf/CMakeLists.txt deleted file mode 100644 index eaccd87aee8..00000000000 --- a/plugins/LadspaEffect/calf/CMakeLists.txt +++ /dev/null @@ -1,45 +0,0 @@ -# Note: -# The last version of Calf that was LADSPA-capable is version 0.0.18.2 - -# Parse version info from autoconf -FILE(READ veal/configure.ac VERSION_FILE) -STRING(REPLACE "[" ";" VERSION_FILE ${VERSION_FILE} ) -STRING(REPLACE "]" ";" VERSION_FILE ${VERSION_FILE} ) -LIST(GET VERSION_FILE 2 VERSION) -CONFIGURE_FILE(config.h.in config.h) - -FILE(GLOB SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/veal/src/*.cpp") -LIST(SORT SOURCES) - -# Skip files matching pattern -SET(FILE_PATTERNS "ctl;gui;gtk;session;connector;jack;rdf;draw;fluid;preset;lv2;benchmark;win") -FOREACH(_item ${SOURCES}) - FOREACH(_pattern ${FILE_PATTERNS}) - IF(${_item} MATCHES ${_pattern}) - LIST(REMOVE_ITEM SOURCES ${_item}) - ENDIF() - ENDFOREACH() -ENDFOREACH() - -ADD_LIBRARY(veal MODULE ${SOURCES}) -INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/include" - "${CMAKE_BINARY_DIR}" - "${CMAKE_CURRENT_BINARY_DIR}" - "${CMAKE_CURRENT_SOURCE_DIR}/veal/src") - -INSTALL(TARGETS veal LIBRARY DESTINATION "${PLUGIN_DIR}/ladspa") -SET_TARGET_PROPERTIES(veal PROPERTIES PREFIX "") -SET(INLINE_FLAGS "") -IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") - SET(INLINE_FLAGS "-finline-functions-called-once -finline-limit=80") -ENDIF() -SET_TARGET_PROPERTIES(veal PROPERTIES COMPILE_FLAGS "-fexceptions -O2 -finline-functions ${INLINE_FLAGS}") - -# Don't strip if "Debug" or "RelWithDebInfo" -IF(LMMS_BUILD_WIN32 AND NOT CMAKE_BUILD_TYPE MATCHES "Deb") - ADD_CUSTOM_COMMAND(TARGET veal POST_BUILD COMMAND "${STRIP}" "$") -ENDIF() -IF(NOT LMMS_BUILD_APPLE AND NOT LMMS_BUILD_OPENBSD) - SET_TARGET_PROPERTIES(veal PROPERTIES LINK_FLAGS "${LINK_FLAGS} -shared -Wl,-no-undefined") -ENDIF() - diff --git a/plugins/LadspaEffect/calf/calf b/plugins/LadspaEffect/calf/calf new file mode 160000 index 00000000000..f71e2742e14 --- /dev/null +++ b/plugins/LadspaEffect/calf/calf @@ -0,0 +1 @@ +Subproject commit f71e2742e1463906c3d44a4b33c1d90e3ad61acb diff --git a/plugins/LadspaEffect/cmt/doc/COPYING b/plugins/LadspaEffect/cmt/doc/COPYING deleted file mode 100644 index eeb586b392a..00000000000 --- a/plugins/LadspaEffect/cmt/doc/COPYING +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) 19yy - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) 19yy name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. From 8d428bc6ab3a947012f1db127f2967d7aa66019b Mon Sep 17 00:00:00 2001 From: tresf Date: Sat, 4 Nov 2017 23:46:12 -0400 Subject: [PATCH 02/25] Add CMakeLists.txt, use old Calf version --- plugins/LadspaEffect/calf/CMakeLists.txt | 46 ++++++++++++++++++++++++ plugins/LadspaEffect/calf/calf | 2 +- 2 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 plugins/LadspaEffect/calf/CMakeLists.txt diff --git a/plugins/LadspaEffect/calf/CMakeLists.txt b/plugins/LadspaEffect/calf/CMakeLists.txt new file mode 100644 index 00000000000..1ca29deb0c7 --- /dev/null +++ b/plugins/LadspaEffect/calf/CMakeLists.txt @@ -0,0 +1,46 @@ +# INCLUDE(CheckSubmodule) +# CHECK_SUBMODULE(swh/configure.ac) + +# Note: The last version of Calf that was LADSPA-capable is version 0.0.18.2 + +# Parse version info from autoconf +FILE(READ calf/configure.ac VERSION_FILE) +STRING(REPLACE "[" ";" VERSION_FILE ${VERSION_FILE} ) +STRING(REPLACE "]" ";" VERSION_FILE ${VERSION_FILE} ) +LIST(GET VERSION_FILE 2 VERSION) +CONFIGURE_FILE(config.h.in config.h) + +FILE(GLOB SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/calf/src/*.cpp") +LIST(SORT SOURCES) + +# Skip files matching pattern +SET(FILE_PATTERNS "ctl;gui;gtk;session;connector;jack;rdf;draw;fluid;dist;preset;lv2;benchmark;win") +FOREACH(_item ${SOURCES}) + FOREACH(_pattern ${FILE_PATTERNS}) + IF(${_item} MATCHES ${_pattern}) + LIST(REMOVE_ITEM SOURCES ${_item}) + ENDIF() + ENDFOREACH() +ENDFOREACH() + +ADD_LIBRARY(calf MODULE ${SOURCES}) +INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/include" + "${CMAKE_BINARY_DIR}" + "${CMAKE_CURRENT_BINARY_DIR}" + "${CMAKE_CURRENT_SOURCE_DIR}/calf/src") +INSTALL(TARGETS calf LIBRARY DESTINATION "${PLUGIN_DIR}/ladspa") +SET_TARGET_PROPERTIES(calf PROPERTIES PREFIX "") +SET(INLINE_FLAGS "") +IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") + SET(INLINE_FLAGS "-finline-functions-called-once -finline-limit=80") +ENDIF() +SET_TARGET_PROPERTIES(calf PROPERTIES COMPILE_FLAGS "-fexceptions -O2 -finline-functions ${INLINE_FLAGS}") + +# Don't strip if "Debug" or "RelWithDebInfo" +IF(LMMS_BUILD_WIN32 AND NOT CMAKE_BUILD_TYPE MATCHES "Deb") + ADD_CUSTOM_COMMAND(TARGET calf POST_BUILD COMMAND "${STRIP}" "$") +ENDIF() +IF(NOT LMMS_BUILD_APPLE AND NOT LMMS_BUILD_OPENBSD) + SET_TARGET_PROPERTIES(calf PROPERTIES LINK_FLAGS "${LINK_FLAGS} -shared -Wl,-no-undefined") +ENDIF() + diff --git a/plugins/LadspaEffect/calf/calf b/plugins/LadspaEffect/calf/calf index f71e2742e14..d2f3811fe6c 160000 --- a/plugins/LadspaEffect/calf/calf +++ b/plugins/LadspaEffect/calf/calf @@ -1 +1 @@ -Subproject commit f71e2742e1463906c3d44a4b33c1d90e3ad61acb +Subproject commit d2f3811fe6c0fdbce5ad102ec6e374d967feb932 From aa542c513fbac09fc0b9c3f75d527f6e1e6cb796 Mon Sep 17 00:00:00 2001 From: tresf Date: Sun, 5 Nov 2017 02:41:12 -0500 Subject: [PATCH 03/25] Revert submodule to 0.0.60.0 --- plugins/LadspaEffect/calf/CMakeLists.txt | 11 +- plugins/LadspaEffect/calf/calf | 2 +- plugins/LadspaEffect/calf/ladspa_wrap.h.diff | 133 +++++ plugins/LadspaEffect/calf/plugin.cpp.diff | 492 +++++++++++++++++++ 4 files changed, 636 insertions(+), 2 deletions(-) create mode 100644 plugins/LadspaEffect/calf/ladspa_wrap.h.diff create mode 100644 plugins/LadspaEffect/calf/plugin.cpp.diff diff --git a/plugins/LadspaEffect/calf/CMakeLists.txt b/plugins/LadspaEffect/calf/CMakeLists.txt index 1ca29deb0c7..27560414f57 100644 --- a/plugins/LadspaEffect/calf/CMakeLists.txt +++ b/plugins/LadspaEffect/calf/CMakeLists.txt @@ -1,7 +1,8 @@ # INCLUDE(CheckSubmodule) # CHECK_SUBMODULE(swh/configure.ac) -# Note: The last version of Calf that was LADSPA-capable is version 0.0.18.2 +# Note: +# The last version of Calf that was LADSPA-capable is version 0.0.18.2 # Parse version info from autoconf FILE(READ calf/configure.ac VERSION_FILE) @@ -10,6 +11,14 @@ STRING(REPLACE "]" ";" VERSION_FILE ${VERSION_FILE} ) LIST(GET VERSION_FILE 2 VERSION) CONFIGURE_FILE(config.h.in config.h) +# Revert LADSPA removal patch +EXECUTE_PROCESS( + COMMAND patch calf/src/calf/ladspa_wrap.h ladspa_wrap.h.diff + COMMAND patch calf/src/plugin.cpp plugin.cpp.diff + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + OUTPUT_QUIET +) + FILE(GLOB SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/calf/src/*.cpp") LIST(SORT SOURCES) diff --git a/plugins/LadspaEffect/calf/calf b/plugins/LadspaEffect/calf/calf index d2f3811fe6c..664bdc91df0 160000 --- a/plugins/LadspaEffect/calf/calf +++ b/plugins/LadspaEffect/calf/calf @@ -1 +1 @@ -Subproject commit d2f3811fe6c0fdbce5ad102ec6e374d967feb932 +Subproject commit 664bdc91df082f84593afe46693a4316b9665867 diff --git a/plugins/LadspaEffect/calf/ladspa_wrap.h.diff b/plugins/LadspaEffect/calf/ladspa_wrap.h.diff new file mode 100644 index 00000000000..e7915f5401a --- /dev/null +++ b/plugins/LadspaEffect/calf/ladspa_wrap.h.diff @@ -0,0 +1,133 @@ +--- a/plugins/LadspaEffect/calf/src/calf/calf/ladspa_wrap.h ++++ b/plugins/LadspaEffect/calf/src/calf/calf/ladspa_wrap.h +@@ -0,0 +1,130 @@ ++/* Calf DSP Library ++ * API wrappers for LADSPA/DSSI ++ * ++ * Copyright (C) 2007-2008 Krzysztof Foltman ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General ++ * Public License along with this program; if not, write to the ++ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, ++ * Boston, MA 02111-1307, USA. ++ */ ++#ifndef __CALF_LADSPA_WRAP_H ++#define __CALF_LADSPA_WRAP_H ++ ++#if USE_LADSPA ++ ++#include ++#include ++#if USE_DSSI ++#include ++#endif ++#include "giface.h" ++#include "preset.h" ++ ++namespace calf_plugins { ++ ++struct ladspa_plugin_metadata_set; ++/// A template implementing plugin_ctl_iface for a given plugin ++struct ladspa_instance: public plugin_ctl_iface ++{ ++ audio_module_iface *module; ++ const plugin_metadata_iface *metadata; ++ ladspa_plugin_metadata_set *ladspa; ++ bool activate_flag; ++ float **ins, **outs, **params; ++#if USE_DSSI ++ dssi_feedback_sender *feedback_sender; ++#endif ++ ++ ladspa_instance(audio_module_iface *_module, ladspa_plugin_metadata_set *_ladspa, int sample_rate); ++ virtual const line_graph_iface *get_line_graph_iface() const { return module->get_line_graph_iface(); } ++ virtual float get_param_value(int param_no); ++ virtual void set_param_value(int param_no, float value); ++ virtual bool activate_preset(int bank, int program); ++ virtual char *configure(const char *key, const char *value); ++ virtual float get_level(unsigned int port) { return 0.f; } ++ virtual void execute(int cmd_no) { ++ module->execute(cmd_no); ++ } ++ virtual void send_configures(send_configure_iface *sci) { ++ module->send_configures(sci); ++ } ++ virtual int send_status_updates(send_updates_iface *sui, int last_serial) { return module->send_status_updates(sui, last_serial); } ++ void run(unsigned long SampleCount); ++#if USE_DSSI ++ /// Utility function: handle MIDI event (only handles a subset in this version) ++ void process_dssi_event(snd_seq_event_t &event); ++ void run_synth(unsigned long SampleCount, snd_seq_event_t *Events, unsigned long EventCount); ++#endif ++ virtual const plugin_metadata_iface *get_metadata_iface() const ++ { ++ return metadata; ++ } ++}; ++ ++/// Set of metadata produced by LADSPA wrapper for LADSPA-related purposes ++struct ladspa_plugin_metadata_set ++{ ++ /// LADSPA descriptor ++ LADSPA_Descriptor descriptor; ++ /// LADSPA descriptor for DSSI (uses a different name for the plugin, otherwise same as descriptor) ++ LADSPA_Descriptor descriptor_for_dssi; ++#if USE_DSSI ++ /// Extended DSSI descriptor (points to descriptor_for_dssi for things like name/label/port info etc.) ++ DSSI_Descriptor dssi_descriptor; ++ DSSI_Program_Descriptor dssi_default_program; ++ ++ std::vector *presets; ++ std::vector *preset_descs; ++#endif ++ ++ int input_count, output_count, param_count; ++ const plugin_metadata_iface *metadata; ++ ++ ladspa_plugin_metadata_set(); ++ void prepare(const plugin_metadata_iface *md, LADSPA_Handle (*cb_instantiate)(const struct _LADSPA_Descriptor * Descriptor, unsigned long sample_rate)); ++ void prepare_dssi(); ++ ~ladspa_plugin_metadata_set(); ++}; ++ ++/// A wrapper class for plugin class object (there is only one ladspa_wrapper singleton for many instances of the same plugin) ++template ++struct ladspa_wrapper ++{ ++ static ladspa_plugin_metadata_set output; ++ ++private: ++ ladspa_wrapper(const plugin_metadata_iface *md) ++ { ++ output.prepare(md, cb_instantiate); ++ } ++ ++public: ++ /// LADSPA instantiation function (create a plugin instance) ++ static LADSPA_Handle cb_instantiate(const struct _LADSPA_Descriptor * Descriptor, unsigned long sample_rate) ++ { ++ return new ladspa_instance(new Module, &output, sample_rate); ++ } ++ ++ /// Get a wrapper singleton - used to prevent initialization order problems which were present in older versions ++ static ladspa_plugin_metadata_set &get() { ++ static ladspa_wrapper instance(new typename Module::metadata_class); ++ return instance.output; ++ } ++}; ++ ++}; ++ ++#endif ++ ++#endif diff --git a/plugins/LadspaEffect/calf/plugin.cpp.diff b/plugins/LadspaEffect/calf/plugin.cpp.diff new file mode 100644 index 00000000000..29a9cc07a2d --- /dev/null +++ b/plugins/LadspaEffect/calf/plugin.cpp.diff @@ -0,0 +1,492 @@ +--- a/plugins/LadspaEffect/calf/calf/src/plugin.cpp ++++ b/plugins/LadspaEffect/calf/calf/src/plugin.cpp +@@ -19,6 +19,7 @@ + * Boston, MA 02110-1301 USA + */ + #include ++#include + #include + #include + #include +@@ -32,6 +33,447 @@ + + using namespace calf_plugins; + ++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ++ ++#if USE_LADSPA ++ ++ladspa_instance::ladspa_instance(audio_module_iface *_module, ladspa_plugin_metadata_set *_ladspa, int sample_rate) ++{ ++ module = _module; ++ metadata = module->get_metadata_iface(); ++ ladspa = _ladspa; ++ ++ module->get_port_arrays(ins, outs, params); ++ ++ activate_flag = true; ++#if USE_DSSI ++ feedback_sender = NULL; ++#endif ++ ++ module->set_sample_rate(sample_rate); ++ module->post_instantiate(); ++} ++ ++float ladspa_instance::get_param_value(int param_no) ++{ ++ // XXXKF hack ++ if (param_no >= ladspa->param_count) ++ return 0; ++ return *params[param_no]; ++} ++ ++void ladspa_instance::set_param_value(int param_no, float value) ++{ ++ // XXXKF hack ++ if (param_no >= ladspa->param_count) ++ return; ++ *params[param_no] = value; ++} ++ ++bool ladspa_instance::activate_preset(int bank, int program) ++{ ++ return false; ++} ++ ++/// LADSPA run function - does set sample rate / activate logic when it's run first time after activation ++void ladspa_instance::run(unsigned long SampleCount) ++{ ++ if (activate_flag) ++ { ++ module->activate(); ++ activate_flag = false; ++ } ++ module->params_changed(); ++ module->process_slice(0, SampleCount); ++} ++ ++#if USE_DSSI ++ ++void ladspa_instance::run_synth(unsigned long SampleCount, snd_seq_event_t *Events, unsigned long EventCount) ++{ ++ if (activate_flag) ++ { ++ module->activate(); ++ activate_flag = false; ++ } ++ module->params_changed(); ++ ++ uint32_t offset = 0; ++ for (uint32_t e = 0; e < EventCount; e++) ++ { ++ uint32_t timestamp = Events[e].time.tick; ++ if (timestamp != offset) ++ module->process_slice(offset, timestamp); ++ process_dssi_event(Events[e]); ++ offset = timestamp; ++ } ++ if (offset != SampleCount) ++ module->process_slice(offset, SampleCount); ++} ++ ++#endif ++ ++char *ladspa_instance::configure(const char *key, const char *value) ++{ ++#if USE_DSSI_GUI ++ if (!strcmp(key, "OSC:FEEDBACK_URI")) ++ { ++ const line_graph_iface *lgi = dynamic_cast(metadata); ++ //if (!lgi) ++ // return NULL; ++ if (*value) ++ { ++ if (feedback_sender) { ++ delete feedback_sender; ++ feedback_sender = NULL; ++ } ++ feedback_sender = new dssi_feedback_sender(value, lgi); ++ feedback_sender->add_graphs(metadata->get_param_props(0), metadata->get_param_count()); ++ } ++ else ++ { ++ if (feedback_sender) { ++ delete feedback_sender; ++ feedback_sender = NULL; ++ } ++ } ++ return NULL; ++ } ++ else ++ if (!strcmp(key, "OSC:UPDATE")) ++ { ++ if (feedback_sender) ++ feedback_sender->update(); ++ return NULL; ++ } ++ else ++ if (!strcmp(key, "OSC:SEND_STATUS")) ++ { ++ if (!feedback_sender) ++ return NULL; ++ struct status_gatherer: public send_updates_iface ++ { ++ osc_inline_typed_strstream str; ++ void send_status(const char *key, const char *value) ++ { ++ str << key << value; ++ } ++ } sg; ++ int serial = atoi(value); ++ serial = module->send_status_updates(&sg, serial); ++ sg.str << (uint32_t)serial; ++ feedback_sender->client->send("/status_data", sg.str); ++ return NULL; ++ } ++ else ++#endif ++ if (!strcmp(key, "ExecCommand")) ++ { ++ if (*value) ++ { ++ execute(atoi(value)); ++ } ++ return NULL; ++ } ++ return module->configure(key, value); ++} ++ ++template ++ladspa_plugin_metadata_set ladspa_wrapper::output; ++ ++#if USE_DSSI ++ ++/// Utility function: handle MIDI event (only handles a subset in this version) ++void ladspa_instance::process_dssi_event(snd_seq_event_t &event) ++{ ++ switch(event.type) { ++ case SND_SEQ_EVENT_NOTEON: ++ module->note_on(event.data.note.channel, event.data.note.note, event.data.note.velocity); ++ break; ++ case SND_SEQ_EVENT_NOTEOFF: ++ module->note_off(event.data.note.channel, event.data.note.note, event.data.note.velocity); ++ break; ++ case SND_SEQ_EVENT_PGMCHANGE: ++ module->program_change(event.data.control.channel, event.data.control.value); ++ break; ++ case SND_SEQ_EVENT_CONTROLLER: ++ module->control_change(event.data.control.channel, event.data.control.param, event.data.control.value); ++ break; ++ case SND_SEQ_EVENT_PITCHBEND: ++ module->pitch_bend(event.data.control.channel, event.data.control.value); ++ break; ++ case SND_SEQ_EVENT_CHANPRESS: ++ module->channel_pressure(event.data.control.channel, event.data.control.value); ++ break; ++ } ++} ++#endif ++ ++/////////////////////////////////////////////////////////////////////////////////////////////////////////////// ++// LADSPA callbacks ++ ++/// LADSPA activate function (note that at this moment the ports are not set) ++static void cb_activate(LADSPA_Handle Instance) ++{ ++ ((ladspa_instance *)(Instance))->activate_flag = true; ++} ++ ++/// LADSPA run function - does set sample rate / activate logic when it's run first time after activation ++static void cb_run(LADSPA_Handle Instance, unsigned long SampleCount) { ++ ((ladspa_instance *)(Instance))->run(SampleCount); ++} ++ ++/// LADSPA port connection function ++static void cb_connect(LADSPA_Handle Instance, unsigned long port, LADSPA_Data *DataLocation) ++{ ++ ladspa_instance *const mod = (ladspa_instance *)Instance; ++ ++ int first_out = mod->ladspa->input_count; ++ int first_param = first_out + mod->ladspa->output_count; ++ int ladspa_port_count = first_param + mod->ladspa->param_count; ++ ++ if ((int)port < first_out) ++ mod->ins[port] = DataLocation; ++ else if ((int)port < first_param) ++ mod->outs[port - first_out] = DataLocation; ++ else if ((int)port < ladspa_port_count) { ++ int i = port - first_param; ++ mod->params[i] = DataLocation; ++ *mod->params[i] = mod->metadata->get_param_props(i)->def_value; ++ } ++} ++ ++ ++/// LADSPA deactivate function ++static void cb_deactivate(LADSPA_Handle Instance) { ++ ((ladspa_instance *)(Instance))->module->deactivate(); ++} ++ ++/// LADSPA cleanup (delete instance) function ++static void cb_cleanup(LADSPA_Handle Instance) { ++ delete ((ladspa_instance *)(Instance)); ++} ++ ++/////////////////////////////////////////////////////////////////////////////////////////////////////////////// ++// DSSI callbacks ++ ++#if USE_DSSI ++/// DSSI "run synth" function, same as run() except it allows for event delivery ++static void cb_run_synth(LADSPA_Handle Instance, unsigned long SampleCount, ++ snd_seq_event_t *Events, unsigned long EventCount) { ++ ((ladspa_instance *)(Instance))->run_synth(SampleCount, Events, EventCount); ++} ++ ++/// DSSI configure function (named properties) ++static char *cb_configure(LADSPA_Handle Instance, ++ const char *Key, ++ const char *Value) ++{ ++ return ((ladspa_instance *)(Instance))->configure(Key, Value); ++} ++ ++/// DSSI get program descriptor function; for 0, it returns the default program (from parameter properties table), for others, it uses global or user preset ++static const DSSI_Program_Descriptor *cb_get_program(LADSPA_Handle Instance, unsigned long index) ++{ ++ ladspa_plugin_metadata_set *ladspa = ((ladspa_instance *)(Instance))->ladspa; ++ if (index > ladspa->presets->size()) ++ return NULL; ++ if (index) ++ return &(*ladspa->preset_descs)[index - 1]; ++ return &ladspa->dssi_default_program; ++} ++ ++/// DSSI select program function; for 0, it sets the defaults, for others, it sets global or user preset ++static void cb_select_program(LADSPA_Handle Instance, unsigned long Bank, unsigned long Program) ++{ ++ ladspa_instance *mod = (ladspa_instance *)Instance; ++ ladspa_plugin_metadata_set *ladspa = mod->ladspa; ++ unsigned int no = (Bank << 7) + Program - 1; ++ // printf("no = %d presets = %p:%d\n", no, presets, presets->size()); ++ if (no == -1U) { ++ int rpc = ladspa->param_count; ++ for (int i =0 ; i < rpc; i++) ++ *mod->params[i] = mod->metadata->get_param_props(i)->def_value; ++ return; ++ } ++ if (no >= ladspa->presets->size()) ++ return; ++ plugin_preset &p = (*ladspa->presets)[no]; ++ // printf("activating preset %s\n", p.name.c_str()); ++ p.activate(mod); ++} ++ ++#endif ++ ++/////////////////////////////////////////////////////////////////////////////////////////////////////////////// ++ ++ladspa_plugin_metadata_set::ladspa_plugin_metadata_set() ++{ ++ metadata = NULL; ++ memset(&descriptor, 0, sizeof(descriptor)); ++ ++#if USE_DSSI ++ presets = NULL; ++ preset_descs = NULL; ++ memset(&descriptor_for_dssi, 0, sizeof(descriptor_for_dssi)); ++ memset(&dssi_descriptor, 0, sizeof(dssi_descriptor)); ++#endif ++} ++ ++void ladspa_plugin_metadata_set::prepare(const plugin_metadata_iface *md, LADSPA_Handle (*cb_instantiate)(const struct _LADSPA_Descriptor * Descriptor, unsigned long sample_rate)) ++{ ++ metadata = md; ++ ++ input_count = md->get_input_count(); ++ output_count = md->get_output_count(); ++ param_count = md->get_param_count(); // XXXKF ladspa_instance::real_param_count(); ++ ++ const ladspa_plugin_info &plugin_info = md->get_plugin_info(); ++ descriptor.UniqueID = plugin_info.unique_id; ++ descriptor.Label = plugin_info.label; ++ descriptor.Name = strdup((std::string(plugin_info.name) + " LADSPA").c_str()); ++ descriptor.Maker = plugin_info.maker; ++ descriptor.Copyright = plugin_info.copyright; ++ descriptor.Properties = md->is_rt_capable() ? LADSPA_PROPERTY_HARD_RT_CAPABLE : 0; ++ descriptor.PortCount = input_count + output_count + param_count; ++ descriptor.PortNames = new char *[descriptor.PortCount]; ++ descriptor.PortDescriptors = new LADSPA_PortDescriptor[descriptor.PortCount]; ++ descriptor.PortRangeHints = new LADSPA_PortRangeHint[descriptor.PortCount]; ++ int i; ++ for (i = 0; i < input_count + output_count; i++) ++ { ++ LADSPA_PortRangeHint &prh = ((LADSPA_PortRangeHint *)descriptor.PortRangeHints)[i]; ++ ((int *)descriptor.PortDescriptors)[i] = i < input_count ? LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO ++ : LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO; ++ prh.HintDescriptor = 0; ++ ((const char **)descriptor.PortNames)[i] = md->get_port_names()[i]; ++ } ++ for (; i < input_count + output_count + param_count; i++) ++ { ++ LADSPA_PortRangeHint &prh = ((LADSPA_PortRangeHint *)descriptor.PortRangeHints)[i]; ++ const parameter_properties &pp = *md->get_param_props(i - input_count - output_count); ++ ((int *)descriptor.PortDescriptors)[i] = ++ LADSPA_PORT_CONTROL | (pp.flags & PF_PROP_OUTPUT ? LADSPA_PORT_OUTPUT : LADSPA_PORT_INPUT); ++ prh.HintDescriptor = LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW; ++ ((const char **)descriptor.PortNames)[i] = pp.name; ++ prh.LowerBound = pp.min; ++ prh.UpperBound = pp.max; ++ switch(pp.flags & PF_TYPEMASK) { ++ case PF_BOOL: ++ prh.HintDescriptor |= LADSPA_HINT_TOGGLED; ++ prh.HintDescriptor &= ~(LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW); ++ break; ++ case PF_INT: ++ case PF_ENUM: ++ prh.HintDescriptor |= LADSPA_HINT_INTEGER; ++ break; ++ default: { ++ int defpt = (int)(100 * (pp.def_value - pp.min) / (pp.max - pp.min)); ++ if ((pp.flags & PF_SCALEMASK) == PF_SCALE_LOG) ++ defpt = (int)(100 * log(pp.def_value / pp.min) / log(pp.max / pp.min)); ++ if (defpt < 12) ++ prh.HintDescriptor |= LADSPA_HINT_DEFAULT_MINIMUM; ++ else if (defpt < 37) ++ prh.HintDescriptor |= LADSPA_HINT_DEFAULT_LOW; ++ else if (defpt < 63) ++ prh.HintDescriptor |= LADSPA_HINT_DEFAULT_MIDDLE; ++ else if (defpt < 88) ++ prh.HintDescriptor |= LADSPA_HINT_DEFAULT_HIGH; ++ else ++ prh.HintDescriptor |= LADSPA_HINT_DEFAULT_MAXIMUM; ++ } ++ } ++ if (pp.def_value == 0 || pp.def_value == 1 || pp.def_value == 100 || pp.def_value == 440 ) { ++ prh.HintDescriptor &= ~LADSPA_HINT_DEFAULT_MASK; ++ if (pp.def_value == 1) ++ prh.HintDescriptor |= LADSPA_HINT_DEFAULT_1; ++ else if (pp.def_value == 100) ++ prh.HintDescriptor |= LADSPA_HINT_DEFAULT_100; ++ else if (pp.def_value == 440) ++ prh.HintDescriptor |= LADSPA_HINT_DEFAULT_440; ++ else ++ prh.HintDescriptor |= LADSPA_HINT_DEFAULT_0; ++ } ++ switch(pp.flags & PF_SCALEMASK) { ++ case PF_SCALE_LOG: ++ prh.HintDescriptor |= LADSPA_HINT_LOGARITHMIC; ++ break; ++ } ++ } ++ descriptor.ImplementationData = this; ++ descriptor.instantiate = cb_instantiate; ++ descriptor.connect_port = cb_connect; ++ descriptor.activate = cb_activate; ++ descriptor.run = cb_run; ++ descriptor.run_adding = NULL; ++ descriptor.set_run_adding_gain = NULL; ++ descriptor.deactivate = cb_deactivate; ++ descriptor.cleanup = cb_cleanup; ++ prepare_dssi(); ++} ++ ++void ladspa_plugin_metadata_set::prepare_dssi() ++{ ++#if USE_DSSI ++ const ladspa_plugin_info &plugin_info = metadata->get_plugin_info(); ++ memcpy(&descriptor_for_dssi, &descriptor, sizeof(descriptor)); ++ descriptor_for_dssi.Name = strdup((std::string(plugin_info.name) + " DSSI").c_str()); ++ memset(&dssi_descriptor, 0, sizeof(dssi_descriptor)); ++ dssi_descriptor.DSSI_API_Version = 1; ++ dssi_descriptor.LADSPA_Plugin = &descriptor_for_dssi; ++ dssi_descriptor.configure = cb_configure; ++ dssi_descriptor.get_program = cb_get_program; ++ dssi_descriptor.select_program = cb_select_program; ++ if (metadata->get_midi()) ++ dssi_descriptor.run_synth = cb_run_synth; ++ ++ presets = new std::vector; ++ preset_descs = new std::vector; ++ ++ preset_list plist_tmp, plist; ++ plist.load_defaults(true); ++ plist_tmp.load_defaults(false); ++ plist.presets.insert(plist.presets.end(), plist_tmp.presets.begin(), plist_tmp.presets.end()); ++ ++ // XXXKF this assumes that plugin name in preset is case-insensitive equal to plugin label ++ // if I forget about this, I'll be in a deep trouble ++ dssi_default_program.Bank = 0; ++ dssi_default_program.Program = 0; ++ dssi_default_program.Name = "default"; ++ ++ int pos = 1; ++ for (unsigned int i = 0; i < plist.presets.size(); i++) ++ { ++ plugin_preset &pp = plist.presets[i]; ++ if (strcasecmp(pp.plugin.c_str(), descriptor.Label)) ++ continue; ++ DSSI_Program_Descriptor pd; ++ pd.Bank = pos >> 7; ++ pd.Program = pos++; ++ pd.Name = pp.name.c_str(); ++ preset_descs->push_back(pd); ++ presets->push_back(pp); ++ } ++#endif ++} ++ ++ladspa_plugin_metadata_set::~ladspa_plugin_metadata_set() ++{ ++ delete []descriptor.PortNames; ++ delete []descriptor.PortDescriptors; ++ delete []descriptor.PortRangeHints; ++#if USE_DSSI ++ if (presets) ++ presets->clear(); ++ if (preset_descs) ++ preset_descs->clear(); ++ delete presets; ++ delete preset_descs; ++#endif ++} ++ ++#endif ++ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + #if USE_LV2 +@@ -53,6 +495,33 @@ const LV2_Descriptor *lv2_descriptor(uint32_t index) + + #endif + ++#if USE_LADSPA ++extern "C" { ++ ++const LADSPA_Descriptor *ladspa_descriptor(unsigned long Index) ++{ ++ #define PER_MODULE_ITEM(name, isSynth, jackname) if (!isSynth && !(Index--)) return &ladspa_wrapper::get().descriptor; ++ #include ++ return NULL; ++} ++ ++}; ++ ++#if USE_DSSI ++extern "C" { ++ ++const DSSI_Descriptor *dssi_descriptor(unsigned long Index) ++{ ++ #define PER_MODULE_ITEM(name, isSynth, jackname) if (!(Index--)) return &calf_plugins::ladspa_wrapper::get().dssi_descriptor; ++ #include ++ return NULL; ++} ++ ++}; ++#endif ++ ++#endif ++ + #if USE_JACK + + extern "C" { From 2631d22243f66e6bd5173a37f73284a893b71b33 Mon Sep 17 00:00:00 2001 From: tresf Date: Sun, 5 Nov 2017 03:45:09 -0500 Subject: [PATCH 04/25] Revert Calf to 0.0.18.2 --- plugins/LadspaEffect/calf/CMakeLists.txt | 9 +- plugins/LadspaEffect/calf/calf | 2 +- plugins/LadspaEffect/calf/ladspa_wrap.h.diff | 133 ----- plugins/LadspaEffect/calf/plugin.cpp.diff | 492 ------------------- 4 files changed, 2 insertions(+), 634 deletions(-) delete mode 100644 plugins/LadspaEffect/calf/ladspa_wrap.h.diff delete mode 100644 plugins/LadspaEffect/calf/plugin.cpp.diff diff --git a/plugins/LadspaEffect/calf/CMakeLists.txt b/plugins/LadspaEffect/calf/CMakeLists.txt index 27560414f57..889f8dde4c2 100644 --- a/plugins/LadspaEffect/calf/CMakeLists.txt +++ b/plugins/LadspaEffect/calf/CMakeLists.txt @@ -11,14 +11,6 @@ STRING(REPLACE "]" ";" VERSION_FILE ${VERSION_FILE} ) LIST(GET VERSION_FILE 2 VERSION) CONFIGURE_FILE(config.h.in config.h) -# Revert LADSPA removal patch -EXECUTE_PROCESS( - COMMAND patch calf/src/calf/ladspa_wrap.h ladspa_wrap.h.diff - COMMAND patch calf/src/plugin.cpp plugin.cpp.diff - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - OUTPUT_QUIET -) - FILE(GLOB SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/calf/src/*.cpp") LIST(SORT SOURCES) @@ -37,6 +29,7 @@ INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/include" "${CMAKE_BINARY_DIR}" "${CMAKE_CURRENT_BINARY_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/calf/src") + INSTALL(TARGETS calf LIBRARY DESTINATION "${PLUGIN_DIR}/ladspa") SET_TARGET_PROPERTIES(calf PROPERTIES PREFIX "") SET(INLINE_FLAGS "") diff --git a/plugins/LadspaEffect/calf/calf b/plugins/LadspaEffect/calf/calf index 664bdc91df0..d2f3811fe6c 160000 --- a/plugins/LadspaEffect/calf/calf +++ b/plugins/LadspaEffect/calf/calf @@ -1 +1 @@ -Subproject commit 664bdc91df082f84593afe46693a4316b9665867 +Subproject commit d2f3811fe6c0fdbce5ad102ec6e374d967feb932 diff --git a/plugins/LadspaEffect/calf/ladspa_wrap.h.diff b/plugins/LadspaEffect/calf/ladspa_wrap.h.diff deleted file mode 100644 index e7915f5401a..00000000000 --- a/plugins/LadspaEffect/calf/ladspa_wrap.h.diff +++ /dev/null @@ -1,133 +0,0 @@ ---- a/plugins/LadspaEffect/calf/src/calf/calf/ladspa_wrap.h -+++ b/plugins/LadspaEffect/calf/src/calf/calf/ladspa_wrap.h -@@ -0,0 +1,130 @@ -+/* Calf DSP Library -+ * API wrappers for LADSPA/DSSI -+ * -+ * Copyright (C) 2007-2008 Krzysztof Foltman -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General -+ * Public License along with this program; if not, write to the -+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ * Boston, MA 02111-1307, USA. -+ */ -+#ifndef __CALF_LADSPA_WRAP_H -+#define __CALF_LADSPA_WRAP_H -+ -+#if USE_LADSPA -+ -+#include -+#include -+#if USE_DSSI -+#include -+#endif -+#include "giface.h" -+#include "preset.h" -+ -+namespace calf_plugins { -+ -+struct ladspa_plugin_metadata_set; -+/// A template implementing plugin_ctl_iface for a given plugin -+struct ladspa_instance: public plugin_ctl_iface -+{ -+ audio_module_iface *module; -+ const plugin_metadata_iface *metadata; -+ ladspa_plugin_metadata_set *ladspa; -+ bool activate_flag; -+ float **ins, **outs, **params; -+#if USE_DSSI -+ dssi_feedback_sender *feedback_sender; -+#endif -+ -+ ladspa_instance(audio_module_iface *_module, ladspa_plugin_metadata_set *_ladspa, int sample_rate); -+ virtual const line_graph_iface *get_line_graph_iface() const { return module->get_line_graph_iface(); } -+ virtual float get_param_value(int param_no); -+ virtual void set_param_value(int param_no, float value); -+ virtual bool activate_preset(int bank, int program); -+ virtual char *configure(const char *key, const char *value); -+ virtual float get_level(unsigned int port) { return 0.f; } -+ virtual void execute(int cmd_no) { -+ module->execute(cmd_no); -+ } -+ virtual void send_configures(send_configure_iface *sci) { -+ module->send_configures(sci); -+ } -+ virtual int send_status_updates(send_updates_iface *sui, int last_serial) { return module->send_status_updates(sui, last_serial); } -+ void run(unsigned long SampleCount); -+#if USE_DSSI -+ /// Utility function: handle MIDI event (only handles a subset in this version) -+ void process_dssi_event(snd_seq_event_t &event); -+ void run_synth(unsigned long SampleCount, snd_seq_event_t *Events, unsigned long EventCount); -+#endif -+ virtual const plugin_metadata_iface *get_metadata_iface() const -+ { -+ return metadata; -+ } -+}; -+ -+/// Set of metadata produced by LADSPA wrapper for LADSPA-related purposes -+struct ladspa_plugin_metadata_set -+{ -+ /// LADSPA descriptor -+ LADSPA_Descriptor descriptor; -+ /// LADSPA descriptor for DSSI (uses a different name for the plugin, otherwise same as descriptor) -+ LADSPA_Descriptor descriptor_for_dssi; -+#if USE_DSSI -+ /// Extended DSSI descriptor (points to descriptor_for_dssi for things like name/label/port info etc.) -+ DSSI_Descriptor dssi_descriptor; -+ DSSI_Program_Descriptor dssi_default_program; -+ -+ std::vector *presets; -+ std::vector *preset_descs; -+#endif -+ -+ int input_count, output_count, param_count; -+ const plugin_metadata_iface *metadata; -+ -+ ladspa_plugin_metadata_set(); -+ void prepare(const plugin_metadata_iface *md, LADSPA_Handle (*cb_instantiate)(const struct _LADSPA_Descriptor * Descriptor, unsigned long sample_rate)); -+ void prepare_dssi(); -+ ~ladspa_plugin_metadata_set(); -+}; -+ -+/// A wrapper class for plugin class object (there is only one ladspa_wrapper singleton for many instances of the same plugin) -+template -+struct ladspa_wrapper -+{ -+ static ladspa_plugin_metadata_set output; -+ -+private: -+ ladspa_wrapper(const plugin_metadata_iface *md) -+ { -+ output.prepare(md, cb_instantiate); -+ } -+ -+public: -+ /// LADSPA instantiation function (create a plugin instance) -+ static LADSPA_Handle cb_instantiate(const struct _LADSPA_Descriptor * Descriptor, unsigned long sample_rate) -+ { -+ return new ladspa_instance(new Module, &output, sample_rate); -+ } -+ -+ /// Get a wrapper singleton - used to prevent initialization order problems which were present in older versions -+ static ladspa_plugin_metadata_set &get() { -+ static ladspa_wrapper instance(new typename Module::metadata_class); -+ return instance.output; -+ } -+}; -+ -+}; -+ -+#endif -+ -+#endif diff --git a/plugins/LadspaEffect/calf/plugin.cpp.diff b/plugins/LadspaEffect/calf/plugin.cpp.diff deleted file mode 100644 index 29a9cc07a2d..00000000000 --- a/plugins/LadspaEffect/calf/plugin.cpp.diff +++ /dev/null @@ -1,492 +0,0 @@ ---- a/plugins/LadspaEffect/calf/calf/src/plugin.cpp -+++ b/plugins/LadspaEffect/calf/calf/src/plugin.cpp -@@ -19,6 +19,7 @@ - * Boston, MA 02110-1301 USA - */ - #include -+#include - #include - #include - #include -@@ -32,6 +33,447 @@ - - using namespace calf_plugins; - -+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+ -+#if USE_LADSPA -+ -+ladspa_instance::ladspa_instance(audio_module_iface *_module, ladspa_plugin_metadata_set *_ladspa, int sample_rate) -+{ -+ module = _module; -+ metadata = module->get_metadata_iface(); -+ ladspa = _ladspa; -+ -+ module->get_port_arrays(ins, outs, params); -+ -+ activate_flag = true; -+#if USE_DSSI -+ feedback_sender = NULL; -+#endif -+ -+ module->set_sample_rate(sample_rate); -+ module->post_instantiate(); -+} -+ -+float ladspa_instance::get_param_value(int param_no) -+{ -+ // XXXKF hack -+ if (param_no >= ladspa->param_count) -+ return 0; -+ return *params[param_no]; -+} -+ -+void ladspa_instance::set_param_value(int param_no, float value) -+{ -+ // XXXKF hack -+ if (param_no >= ladspa->param_count) -+ return; -+ *params[param_no] = value; -+} -+ -+bool ladspa_instance::activate_preset(int bank, int program) -+{ -+ return false; -+} -+ -+/// LADSPA run function - does set sample rate / activate logic when it's run first time after activation -+void ladspa_instance::run(unsigned long SampleCount) -+{ -+ if (activate_flag) -+ { -+ module->activate(); -+ activate_flag = false; -+ } -+ module->params_changed(); -+ module->process_slice(0, SampleCount); -+} -+ -+#if USE_DSSI -+ -+void ladspa_instance::run_synth(unsigned long SampleCount, snd_seq_event_t *Events, unsigned long EventCount) -+{ -+ if (activate_flag) -+ { -+ module->activate(); -+ activate_flag = false; -+ } -+ module->params_changed(); -+ -+ uint32_t offset = 0; -+ for (uint32_t e = 0; e < EventCount; e++) -+ { -+ uint32_t timestamp = Events[e].time.tick; -+ if (timestamp != offset) -+ module->process_slice(offset, timestamp); -+ process_dssi_event(Events[e]); -+ offset = timestamp; -+ } -+ if (offset != SampleCount) -+ module->process_slice(offset, SampleCount); -+} -+ -+#endif -+ -+char *ladspa_instance::configure(const char *key, const char *value) -+{ -+#if USE_DSSI_GUI -+ if (!strcmp(key, "OSC:FEEDBACK_URI")) -+ { -+ const line_graph_iface *lgi = dynamic_cast(metadata); -+ //if (!lgi) -+ // return NULL; -+ if (*value) -+ { -+ if (feedback_sender) { -+ delete feedback_sender; -+ feedback_sender = NULL; -+ } -+ feedback_sender = new dssi_feedback_sender(value, lgi); -+ feedback_sender->add_graphs(metadata->get_param_props(0), metadata->get_param_count()); -+ } -+ else -+ { -+ if (feedback_sender) { -+ delete feedback_sender; -+ feedback_sender = NULL; -+ } -+ } -+ return NULL; -+ } -+ else -+ if (!strcmp(key, "OSC:UPDATE")) -+ { -+ if (feedback_sender) -+ feedback_sender->update(); -+ return NULL; -+ } -+ else -+ if (!strcmp(key, "OSC:SEND_STATUS")) -+ { -+ if (!feedback_sender) -+ return NULL; -+ struct status_gatherer: public send_updates_iface -+ { -+ osc_inline_typed_strstream str; -+ void send_status(const char *key, const char *value) -+ { -+ str << key << value; -+ } -+ } sg; -+ int serial = atoi(value); -+ serial = module->send_status_updates(&sg, serial); -+ sg.str << (uint32_t)serial; -+ feedback_sender->client->send("/status_data", sg.str); -+ return NULL; -+ } -+ else -+#endif -+ if (!strcmp(key, "ExecCommand")) -+ { -+ if (*value) -+ { -+ execute(atoi(value)); -+ } -+ return NULL; -+ } -+ return module->configure(key, value); -+} -+ -+template -+ladspa_plugin_metadata_set ladspa_wrapper::output; -+ -+#if USE_DSSI -+ -+/// Utility function: handle MIDI event (only handles a subset in this version) -+void ladspa_instance::process_dssi_event(snd_seq_event_t &event) -+{ -+ switch(event.type) { -+ case SND_SEQ_EVENT_NOTEON: -+ module->note_on(event.data.note.channel, event.data.note.note, event.data.note.velocity); -+ break; -+ case SND_SEQ_EVENT_NOTEOFF: -+ module->note_off(event.data.note.channel, event.data.note.note, event.data.note.velocity); -+ break; -+ case SND_SEQ_EVENT_PGMCHANGE: -+ module->program_change(event.data.control.channel, event.data.control.value); -+ break; -+ case SND_SEQ_EVENT_CONTROLLER: -+ module->control_change(event.data.control.channel, event.data.control.param, event.data.control.value); -+ break; -+ case SND_SEQ_EVENT_PITCHBEND: -+ module->pitch_bend(event.data.control.channel, event.data.control.value); -+ break; -+ case SND_SEQ_EVENT_CHANPRESS: -+ module->channel_pressure(event.data.control.channel, event.data.control.value); -+ break; -+ } -+} -+#endif -+ -+/////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+// LADSPA callbacks -+ -+/// LADSPA activate function (note that at this moment the ports are not set) -+static void cb_activate(LADSPA_Handle Instance) -+{ -+ ((ladspa_instance *)(Instance))->activate_flag = true; -+} -+ -+/// LADSPA run function - does set sample rate / activate logic when it's run first time after activation -+static void cb_run(LADSPA_Handle Instance, unsigned long SampleCount) { -+ ((ladspa_instance *)(Instance))->run(SampleCount); -+} -+ -+/// LADSPA port connection function -+static void cb_connect(LADSPA_Handle Instance, unsigned long port, LADSPA_Data *DataLocation) -+{ -+ ladspa_instance *const mod = (ladspa_instance *)Instance; -+ -+ int first_out = mod->ladspa->input_count; -+ int first_param = first_out + mod->ladspa->output_count; -+ int ladspa_port_count = first_param + mod->ladspa->param_count; -+ -+ if ((int)port < first_out) -+ mod->ins[port] = DataLocation; -+ else if ((int)port < first_param) -+ mod->outs[port - first_out] = DataLocation; -+ else if ((int)port < ladspa_port_count) { -+ int i = port - first_param; -+ mod->params[i] = DataLocation; -+ *mod->params[i] = mod->metadata->get_param_props(i)->def_value; -+ } -+} -+ -+ -+/// LADSPA deactivate function -+static void cb_deactivate(LADSPA_Handle Instance) { -+ ((ladspa_instance *)(Instance))->module->deactivate(); -+} -+ -+/// LADSPA cleanup (delete instance) function -+static void cb_cleanup(LADSPA_Handle Instance) { -+ delete ((ladspa_instance *)(Instance)); -+} -+ -+/////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+// DSSI callbacks -+ -+#if USE_DSSI -+/// DSSI "run synth" function, same as run() except it allows for event delivery -+static void cb_run_synth(LADSPA_Handle Instance, unsigned long SampleCount, -+ snd_seq_event_t *Events, unsigned long EventCount) { -+ ((ladspa_instance *)(Instance))->run_synth(SampleCount, Events, EventCount); -+} -+ -+/// DSSI configure function (named properties) -+static char *cb_configure(LADSPA_Handle Instance, -+ const char *Key, -+ const char *Value) -+{ -+ return ((ladspa_instance *)(Instance))->configure(Key, Value); -+} -+ -+/// DSSI get program descriptor function; for 0, it returns the default program (from parameter properties table), for others, it uses global or user preset -+static const DSSI_Program_Descriptor *cb_get_program(LADSPA_Handle Instance, unsigned long index) -+{ -+ ladspa_plugin_metadata_set *ladspa = ((ladspa_instance *)(Instance))->ladspa; -+ if (index > ladspa->presets->size()) -+ return NULL; -+ if (index) -+ return &(*ladspa->preset_descs)[index - 1]; -+ return &ladspa->dssi_default_program; -+} -+ -+/// DSSI select program function; for 0, it sets the defaults, for others, it sets global or user preset -+static void cb_select_program(LADSPA_Handle Instance, unsigned long Bank, unsigned long Program) -+{ -+ ladspa_instance *mod = (ladspa_instance *)Instance; -+ ladspa_plugin_metadata_set *ladspa = mod->ladspa; -+ unsigned int no = (Bank << 7) + Program - 1; -+ // printf("no = %d presets = %p:%d\n", no, presets, presets->size()); -+ if (no == -1U) { -+ int rpc = ladspa->param_count; -+ for (int i =0 ; i < rpc; i++) -+ *mod->params[i] = mod->metadata->get_param_props(i)->def_value; -+ return; -+ } -+ if (no >= ladspa->presets->size()) -+ return; -+ plugin_preset &p = (*ladspa->presets)[no]; -+ // printf("activating preset %s\n", p.name.c_str()); -+ p.activate(mod); -+} -+ -+#endif -+ -+/////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+ -+ladspa_plugin_metadata_set::ladspa_plugin_metadata_set() -+{ -+ metadata = NULL; -+ memset(&descriptor, 0, sizeof(descriptor)); -+ -+#if USE_DSSI -+ presets = NULL; -+ preset_descs = NULL; -+ memset(&descriptor_for_dssi, 0, sizeof(descriptor_for_dssi)); -+ memset(&dssi_descriptor, 0, sizeof(dssi_descriptor)); -+#endif -+} -+ -+void ladspa_plugin_metadata_set::prepare(const plugin_metadata_iface *md, LADSPA_Handle (*cb_instantiate)(const struct _LADSPA_Descriptor * Descriptor, unsigned long sample_rate)) -+{ -+ metadata = md; -+ -+ input_count = md->get_input_count(); -+ output_count = md->get_output_count(); -+ param_count = md->get_param_count(); // XXXKF ladspa_instance::real_param_count(); -+ -+ const ladspa_plugin_info &plugin_info = md->get_plugin_info(); -+ descriptor.UniqueID = plugin_info.unique_id; -+ descriptor.Label = plugin_info.label; -+ descriptor.Name = strdup((std::string(plugin_info.name) + " LADSPA").c_str()); -+ descriptor.Maker = plugin_info.maker; -+ descriptor.Copyright = plugin_info.copyright; -+ descriptor.Properties = md->is_rt_capable() ? LADSPA_PROPERTY_HARD_RT_CAPABLE : 0; -+ descriptor.PortCount = input_count + output_count + param_count; -+ descriptor.PortNames = new char *[descriptor.PortCount]; -+ descriptor.PortDescriptors = new LADSPA_PortDescriptor[descriptor.PortCount]; -+ descriptor.PortRangeHints = new LADSPA_PortRangeHint[descriptor.PortCount]; -+ int i; -+ for (i = 0; i < input_count + output_count; i++) -+ { -+ LADSPA_PortRangeHint &prh = ((LADSPA_PortRangeHint *)descriptor.PortRangeHints)[i]; -+ ((int *)descriptor.PortDescriptors)[i] = i < input_count ? LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO -+ : LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO; -+ prh.HintDescriptor = 0; -+ ((const char **)descriptor.PortNames)[i] = md->get_port_names()[i]; -+ } -+ for (; i < input_count + output_count + param_count; i++) -+ { -+ LADSPA_PortRangeHint &prh = ((LADSPA_PortRangeHint *)descriptor.PortRangeHints)[i]; -+ const parameter_properties &pp = *md->get_param_props(i - input_count - output_count); -+ ((int *)descriptor.PortDescriptors)[i] = -+ LADSPA_PORT_CONTROL | (pp.flags & PF_PROP_OUTPUT ? LADSPA_PORT_OUTPUT : LADSPA_PORT_INPUT); -+ prh.HintDescriptor = LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW; -+ ((const char **)descriptor.PortNames)[i] = pp.name; -+ prh.LowerBound = pp.min; -+ prh.UpperBound = pp.max; -+ switch(pp.flags & PF_TYPEMASK) { -+ case PF_BOOL: -+ prh.HintDescriptor |= LADSPA_HINT_TOGGLED; -+ prh.HintDescriptor &= ~(LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW); -+ break; -+ case PF_INT: -+ case PF_ENUM: -+ prh.HintDescriptor |= LADSPA_HINT_INTEGER; -+ break; -+ default: { -+ int defpt = (int)(100 * (pp.def_value - pp.min) / (pp.max - pp.min)); -+ if ((pp.flags & PF_SCALEMASK) == PF_SCALE_LOG) -+ defpt = (int)(100 * log(pp.def_value / pp.min) / log(pp.max / pp.min)); -+ if (defpt < 12) -+ prh.HintDescriptor |= LADSPA_HINT_DEFAULT_MINIMUM; -+ else if (defpt < 37) -+ prh.HintDescriptor |= LADSPA_HINT_DEFAULT_LOW; -+ else if (defpt < 63) -+ prh.HintDescriptor |= LADSPA_HINT_DEFAULT_MIDDLE; -+ else if (defpt < 88) -+ prh.HintDescriptor |= LADSPA_HINT_DEFAULT_HIGH; -+ else -+ prh.HintDescriptor |= LADSPA_HINT_DEFAULT_MAXIMUM; -+ } -+ } -+ if (pp.def_value == 0 || pp.def_value == 1 || pp.def_value == 100 || pp.def_value == 440 ) { -+ prh.HintDescriptor &= ~LADSPA_HINT_DEFAULT_MASK; -+ if (pp.def_value == 1) -+ prh.HintDescriptor |= LADSPA_HINT_DEFAULT_1; -+ else if (pp.def_value == 100) -+ prh.HintDescriptor |= LADSPA_HINT_DEFAULT_100; -+ else if (pp.def_value == 440) -+ prh.HintDescriptor |= LADSPA_HINT_DEFAULT_440; -+ else -+ prh.HintDescriptor |= LADSPA_HINT_DEFAULT_0; -+ } -+ switch(pp.flags & PF_SCALEMASK) { -+ case PF_SCALE_LOG: -+ prh.HintDescriptor |= LADSPA_HINT_LOGARITHMIC; -+ break; -+ } -+ } -+ descriptor.ImplementationData = this; -+ descriptor.instantiate = cb_instantiate; -+ descriptor.connect_port = cb_connect; -+ descriptor.activate = cb_activate; -+ descriptor.run = cb_run; -+ descriptor.run_adding = NULL; -+ descriptor.set_run_adding_gain = NULL; -+ descriptor.deactivate = cb_deactivate; -+ descriptor.cleanup = cb_cleanup; -+ prepare_dssi(); -+} -+ -+void ladspa_plugin_metadata_set::prepare_dssi() -+{ -+#if USE_DSSI -+ const ladspa_plugin_info &plugin_info = metadata->get_plugin_info(); -+ memcpy(&descriptor_for_dssi, &descriptor, sizeof(descriptor)); -+ descriptor_for_dssi.Name = strdup((std::string(plugin_info.name) + " DSSI").c_str()); -+ memset(&dssi_descriptor, 0, sizeof(dssi_descriptor)); -+ dssi_descriptor.DSSI_API_Version = 1; -+ dssi_descriptor.LADSPA_Plugin = &descriptor_for_dssi; -+ dssi_descriptor.configure = cb_configure; -+ dssi_descriptor.get_program = cb_get_program; -+ dssi_descriptor.select_program = cb_select_program; -+ if (metadata->get_midi()) -+ dssi_descriptor.run_synth = cb_run_synth; -+ -+ presets = new std::vector; -+ preset_descs = new std::vector; -+ -+ preset_list plist_tmp, plist; -+ plist.load_defaults(true); -+ plist_tmp.load_defaults(false); -+ plist.presets.insert(plist.presets.end(), plist_tmp.presets.begin(), plist_tmp.presets.end()); -+ -+ // XXXKF this assumes that plugin name in preset is case-insensitive equal to plugin label -+ // if I forget about this, I'll be in a deep trouble -+ dssi_default_program.Bank = 0; -+ dssi_default_program.Program = 0; -+ dssi_default_program.Name = "default"; -+ -+ int pos = 1; -+ for (unsigned int i = 0; i < plist.presets.size(); i++) -+ { -+ plugin_preset &pp = plist.presets[i]; -+ if (strcasecmp(pp.plugin.c_str(), descriptor.Label)) -+ continue; -+ DSSI_Program_Descriptor pd; -+ pd.Bank = pos >> 7; -+ pd.Program = pos++; -+ pd.Name = pp.name.c_str(); -+ preset_descs->push_back(pd); -+ presets->push_back(pp); -+ } -+#endif -+} -+ -+ladspa_plugin_metadata_set::~ladspa_plugin_metadata_set() -+{ -+ delete []descriptor.PortNames; -+ delete []descriptor.PortDescriptors; -+ delete []descriptor.PortRangeHints; -+#if USE_DSSI -+ if (presets) -+ presets->clear(); -+ if (preset_descs) -+ preset_descs->clear(); -+ delete presets; -+ delete preset_descs; -+#endif -+} -+ -+#endif -+ - /////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - #if USE_LV2 -@@ -53,6 +495,33 @@ const LV2_Descriptor *lv2_descriptor(uint32_t index) - - #endif - -+#if USE_LADSPA -+extern "C" { -+ -+const LADSPA_Descriptor *ladspa_descriptor(unsigned long Index) -+{ -+ #define PER_MODULE_ITEM(name, isSynth, jackname) if (!isSynth && !(Index--)) return &ladspa_wrapper::get().descriptor; -+ #include -+ return NULL; -+} -+ -+}; -+ -+#if USE_DSSI -+extern "C" { -+ -+const DSSI_Descriptor *dssi_descriptor(unsigned long Index) -+{ -+ #define PER_MODULE_ITEM(name, isSynth, jackname) if (!(Index--)) return &calf_plugins::ladspa_wrapper::get().dssi_descriptor; -+ #include -+ return NULL; -+} -+ -+}; -+#endif -+ -+#endif -+ - #if USE_JACK - - extern "C" { From c540efc6e2062e96e769fce6af0cd81b8aeea93c Mon Sep 17 00:00:00 2001 From: tresf Date: Sun, 5 Nov 2017 23:47:21 -0500 Subject: [PATCH 05/25] Point calf submodule at fork --- .gitmodules | 2 +- plugins/LadspaEffect/calf/CMakeLists.txt | 18 +++++++++--------- plugins/LadspaEffect/calf/calf | 1 - plugins/LadspaEffect/calf/veal | 2 +- src/3rdparty/rpmalloc/rpmalloc | 2 +- 5 files changed, 12 insertions(+), 13 deletions(-) delete mode 160000 plugins/LadspaEffect/calf/calf diff --git a/.gitmodules b/.gitmodules index 4a8c9adc1ee..dd8cbf2834e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -12,7 +12,7 @@ url = https://github.com/adplug/adplug.git [submodule "plugins/LadspaEffect/calf/veal"] path = plugins/LadspaEffect/calf/veal - url = https://github.com/lmms/veal + url = https://github.com/tresf/veal [submodule "plugins/Xpressive/exprtk"] path = plugins/Xpressive/exprtk url = https://github.com/ArashPartow/exprtk diff --git a/plugins/LadspaEffect/calf/CMakeLists.txt b/plugins/LadspaEffect/calf/CMakeLists.txt index 889f8dde4c2..6d197ed7b46 100644 --- a/plugins/LadspaEffect/calf/CMakeLists.txt +++ b/plugins/LadspaEffect/calf/CMakeLists.txt @@ -5,13 +5,13 @@ # The last version of Calf that was LADSPA-capable is version 0.0.18.2 # Parse version info from autoconf -FILE(READ calf/configure.ac VERSION_FILE) +FILE(READ veal/configure.ac VERSION_FILE) STRING(REPLACE "[" ";" VERSION_FILE ${VERSION_FILE} ) STRING(REPLACE "]" ";" VERSION_FILE ${VERSION_FILE} ) LIST(GET VERSION_FILE 2 VERSION) CONFIGURE_FILE(config.h.in config.h) -FILE(GLOB SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/calf/src/*.cpp") +FILE(GLOB SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/veal/src/*.cpp") LIST(SORT SOURCES) # Skip files matching pattern @@ -24,25 +24,25 @@ FOREACH(_item ${SOURCES}) ENDFOREACH() ENDFOREACH() -ADD_LIBRARY(calf MODULE ${SOURCES}) +ADD_LIBRARY(veal MODULE ${SOURCES}) INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/include" "${CMAKE_BINARY_DIR}" "${CMAKE_CURRENT_BINARY_DIR}" - "${CMAKE_CURRENT_SOURCE_DIR}/calf/src") + "${CMAKE_CURRENT_SOURCE_DIR}/veal/src") -INSTALL(TARGETS calf LIBRARY DESTINATION "${PLUGIN_DIR}/ladspa") -SET_TARGET_PROPERTIES(calf PROPERTIES PREFIX "") +INSTALL(TARGETS veal LIBRARY DESTINATION "${PLUGIN_DIR}/ladspa") +SET_TARGET_PROPERTIES(veal PROPERTIES PREFIX "") SET(INLINE_FLAGS "") IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") SET(INLINE_FLAGS "-finline-functions-called-once -finline-limit=80") ENDIF() -SET_TARGET_PROPERTIES(calf PROPERTIES COMPILE_FLAGS "-fexceptions -O2 -finline-functions ${INLINE_FLAGS}") +SET_TARGET_PROPERTIES(veal PROPERTIES COMPILE_FLAGS "-fexceptions -O2 -finline-functions ${INLINE_FLAGS}") # Don't strip if "Debug" or "RelWithDebInfo" IF(LMMS_BUILD_WIN32 AND NOT CMAKE_BUILD_TYPE MATCHES "Deb") - ADD_CUSTOM_COMMAND(TARGET calf POST_BUILD COMMAND "${STRIP}" "$") + ADD_CUSTOM_COMMAND(TARGET veal POST_BUILD COMMAND "${STRIP}" "$") ENDIF() IF(NOT LMMS_BUILD_APPLE AND NOT LMMS_BUILD_OPENBSD) - SET_TARGET_PROPERTIES(calf PROPERTIES LINK_FLAGS "${LINK_FLAGS} -shared -Wl,-no-undefined") + SET_TARGET_PROPERTIES(veal PROPERTIES LINK_FLAGS "${LINK_FLAGS} -shared -Wl,-no-undefined") ENDIF() diff --git a/plugins/LadspaEffect/calf/calf b/plugins/LadspaEffect/calf/calf deleted file mode 160000 index d2f3811fe6c..00000000000 --- a/plugins/LadspaEffect/calf/calf +++ /dev/null @@ -1 +0,0 @@ -Subproject commit d2f3811fe6c0fdbce5ad102ec6e374d967feb932 diff --git a/plugins/LadspaEffect/calf/veal b/plugins/LadspaEffect/calf/veal index 816b4d2b7cc..faa75eaea15 160000 --- a/plugins/LadspaEffect/calf/veal +++ b/plugins/LadspaEffect/calf/veal @@ -1 +1 @@ -Subproject commit 816b4d2b7cc20429faf96863d7e8ba1cda48ace8 +Subproject commit faa75eaea15d3f9930fe19bdc88abbd169e02e8e diff --git a/src/3rdparty/rpmalloc/rpmalloc b/src/3rdparty/rpmalloc/rpmalloc index 2e0479192b8..f3b2e630871 160000 --- a/src/3rdparty/rpmalloc/rpmalloc +++ b/src/3rdparty/rpmalloc/rpmalloc @@ -1 +1 @@ -Subproject commit 2e0479192b8dfb15e0084969fdf06208cffbfd09 +Subproject commit f3b2e630871c32288e7b501877c6d99d20171c20 From ebd1fbdd3c3a4de986efc4047e3ad601f777800b Mon Sep 17 00:00:00 2001 From: tresf Date: Mon, 6 Nov 2017 01:03:00 -0500 Subject: [PATCH 06/25] Make it work --- plugins/LadspaEffect/calf/CMakeLists.txt | 2 +- src/3rdparty/rpmalloc/rpmalloc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/LadspaEffect/calf/CMakeLists.txt b/plugins/LadspaEffect/calf/CMakeLists.txt index 6d197ed7b46..899407ecc5e 100644 --- a/plugins/LadspaEffect/calf/CMakeLists.txt +++ b/plugins/LadspaEffect/calf/CMakeLists.txt @@ -15,7 +15,7 @@ FILE(GLOB SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/veal/src/*.cpp") LIST(SORT SOURCES) # Skip files matching pattern -SET(FILE_PATTERNS "ctl;gui;gtk;session;connector;jack;rdf;draw;fluid;dist;preset;lv2;benchmark;win") +SET(FILE_PATTERNS "ctl;gui;gtk;session;connector;jack;rdf;draw;fluid;preset;lv2;benchmark;win") FOREACH(_item ${SOURCES}) FOREACH(_pattern ${FILE_PATTERNS}) IF(${_item} MATCHES ${_pattern}) diff --git a/src/3rdparty/rpmalloc/rpmalloc b/src/3rdparty/rpmalloc/rpmalloc index f3b2e630871..2e0479192b8 160000 --- a/src/3rdparty/rpmalloc/rpmalloc +++ b/src/3rdparty/rpmalloc/rpmalloc @@ -1 +1 @@ -Subproject commit f3b2e630871c32288e7b501877c6d99d20171c20 +Subproject commit 2e0479192b8dfb15e0084969fdf06208cffbfd09 From c817ad3396f9e4888a70095168045e8cb2b9bbd5 Mon Sep 17 00:00:00 2001 From: tresf Date: Mon, 6 Nov 2017 14:39:43 -0500 Subject: [PATCH 07/25] Bump to Calf 0.90 --- plugins/LadspaEffect/calf/CMakeLists.txt | 2 +- plugins/LadspaEffect/calf/config.h.in | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/LadspaEffect/calf/CMakeLists.txt b/plugins/LadspaEffect/calf/CMakeLists.txt index 899407ecc5e..f90415887a6 100644 --- a/plugins/LadspaEffect/calf/CMakeLists.txt +++ b/plugins/LadspaEffect/calf/CMakeLists.txt @@ -15,7 +15,7 @@ FILE(GLOB SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/veal/src/*.cpp") LIST(SORT SOURCES) # Skip files matching pattern -SET(FILE_PATTERNS "ctl;gui;gtk;session;connector;jack;rdf;draw;fluid;preset;lv2;benchmark;win") +SET(FILE_PATTERNS "ctl;gui;gtk;session;connector;jack;rdf;draw;fluid;preset;lv2;benchmark;win;plugin.cpp") FOREACH(_item ${SOURCES}) FOREACH(_pattern ${FILE_PATTERNS}) IF(${_item} MATCHES ${_pattern}) diff --git a/plugins/LadspaEffect/calf/config.h.in b/plugins/LadspaEffect/calf/config.h.in index a636660e583..2dd0cd0183d 100644 --- a/plugins/LadspaEffect/calf/config.h.in +++ b/plugins/LadspaEffect/calf/config.h.in @@ -1,3 +1,4 @@ #define VERSION "${VERSION}" #define PACKAGE_NAME "veal" #define USE_LADSPA 1 +#define PKGLIBDIR "" From cd80f8eebdf75c6ba5e63d3023cfe4a33c9512cd Mon Sep 17 00:00:00 2001 From: tresf Date: Fri, 17 Nov 2017 00:26:18 -0500 Subject: [PATCH 08/25] Cleanup comments --- plugins/LadspaEffect/calf/CMakeLists.txt | 3 - plugins/LadspaEffect/cmt/doc/COPYING | 340 +++++++++++++++++++++++ 2 files changed, 340 insertions(+), 3 deletions(-) create mode 100644 plugins/LadspaEffect/cmt/doc/COPYING diff --git a/plugins/LadspaEffect/calf/CMakeLists.txt b/plugins/LadspaEffect/calf/CMakeLists.txt index f90415887a6..8e90b8da277 100644 --- a/plugins/LadspaEffect/calf/CMakeLists.txt +++ b/plugins/LadspaEffect/calf/CMakeLists.txt @@ -1,6 +1,3 @@ -# INCLUDE(CheckSubmodule) -# CHECK_SUBMODULE(swh/configure.ac) - # Note: # The last version of Calf that was LADSPA-capable is version 0.0.18.2 diff --git a/plugins/LadspaEffect/cmt/doc/COPYING b/plugins/LadspaEffect/cmt/doc/COPYING new file mode 100644 index 00000000000..eeb586b392a --- /dev/null +++ b/plugins/LadspaEffect/cmt/doc/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. From 67adaf32b87ad712a7aee81fef27bbe8321124df Mon Sep 17 00:00:00 2001 From: tresf Date: Sat, 18 Nov 2017 23:16:24 -0500 Subject: [PATCH 09/25] Namespace calf_plugins to veal_plugins --- plugins/LadspaEffect/calf/config.h.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/LadspaEffect/calf/config.h.in b/plugins/LadspaEffect/calf/config.h.in index 2dd0cd0183d..8719ecc4c03 100644 --- a/plugins/LadspaEffect/calf/config.h.in +++ b/plugins/LadspaEffect/calf/config.h.in @@ -2,3 +2,6 @@ #define PACKAGE_NAME "veal" #define USE_LADSPA 1 #define PKGLIBDIR "" + +// Namespace change to avoid conflict with LV2 +#define calf_plugins veal_plugins From a02730ac53688abf9a9c176b1025e0c53c3b6a5d Mon Sep 17 00:00:00 2001 From: tresf Date: Sat, 18 Nov 2017 23:55:47 -0500 Subject: [PATCH 10/25] Nudge to latest commits --- plugins/LadspaEffect/calf/veal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/LadspaEffect/calf/veal b/plugins/LadspaEffect/calf/veal index faa75eaea15..b772ae260a4 160000 --- a/plugins/LadspaEffect/calf/veal +++ b/plugins/LadspaEffect/calf/veal @@ -1 +1 @@ -Subproject commit faa75eaea15d3f9930fe19bdc88abbd169e02e8e +Subproject commit b772ae260a4b89eb833feafb2a56aaa192ae46de From 0a0fd0ac1922cce0e4d3e87136cd17754dee5536 Mon Sep 17 00:00:00 2001 From: tresf Date: Tue, 21 Nov 2017 13:15:44 -0500 Subject: [PATCH 11/25] Fix windows, bump to latest commits --- .gitmodules | 6 +++--- plugins/LadspaEffect/calf/CMakeLists.txt | 5 ++++- plugins/LadspaEffect/calf/veal | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.gitmodules b/.gitmodules index dd8cbf2834e..13b98c6529a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,9 +10,6 @@ [submodule "plugins/OpulenZ/adplug"] path = plugins/OpulenZ/adplug url = https://github.com/adplug/adplug.git -[submodule "plugins/LadspaEffect/calf/veal"] - path = plugins/LadspaEffect/calf/veal - url = https://github.com/tresf/veal [submodule "plugins/Xpressive/exprtk"] path = plugins/Xpressive/exprtk url = https://github.com/ArashPartow/exprtk @@ -25,3 +22,6 @@ [submodule "src/3rdparty/weakjack/weakjack"] path = src/3rdparty/weakjack/weakjack url = https://github.com/x42/weakjack.git +[submodule "plugins/LadspaEffect/calf/veal"] + path = plugins/LadspaEffect/calf/veal + url = https://github.com/tresf/veal diff --git a/plugins/LadspaEffect/calf/CMakeLists.txt b/plugins/LadspaEffect/calf/CMakeLists.txt index 8e90b8da277..88361f735b1 100644 --- a/plugins/LadspaEffect/calf/CMakeLists.txt +++ b/plugins/LadspaEffect/calf/CMakeLists.txt @@ -29,6 +29,10 @@ INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/include" INSTALL(TARGETS veal LIBRARY DESTINATION "${PLUGIN_DIR}/ladspa") SET_TARGET_PROPERTIES(veal PROPERTIES PREFIX "") + +# Disable OSC messaging, it's not mingw compatible +TARGET_COMPILE_DEFINITIONS(veal PRIVATE DISABLE_OSC=1) + SET(INLINE_FLAGS "") IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") SET(INLINE_FLAGS "-finline-functions-called-once -finline-limit=80") @@ -42,4 +46,3 @@ ENDIF() IF(NOT LMMS_BUILD_APPLE AND NOT LMMS_BUILD_OPENBSD) SET_TARGET_PROPERTIES(veal PROPERTIES LINK_FLAGS "${LINK_FLAGS} -shared -Wl,-no-undefined") ENDIF() - diff --git a/plugins/LadspaEffect/calf/veal b/plugins/LadspaEffect/calf/veal index b772ae260a4..c6e74543ee1 160000 --- a/plugins/LadspaEffect/calf/veal +++ b/plugins/LadspaEffect/calf/veal @@ -1 +1 @@ -Subproject commit b772ae260a4b89eb833feafb2a56aaa192ae46de +Subproject commit c6e74543ee1ae2d99132446d873066347d4ade5d From 2e9f98d63e0eefefc2b76329282cb70a5f3bf079 Mon Sep 17 00:00:00 2001 From: tresf Date: Sat, 2 Dec 2017 14:33:34 -0500 Subject: [PATCH 12/25] Bump to latest changes at tresf/veal --- plugins/LadspaEffect/calf/veal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/LadspaEffect/calf/veal b/plugins/LadspaEffect/calf/veal index c6e74543ee1..d2943d34862 160000 --- a/plugins/LadspaEffect/calf/veal +++ b/plugins/LadspaEffect/calf/veal @@ -1 +1 @@ -Subproject commit c6e74543ee1ae2d99132446d873066347d4ade5d +Subproject commit d2943d348624261202681d22c308f8ac106041ed From 14d00cd775f4ab0a36b1171b9fded70eb388ecfe Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Tue, 2 Jan 2018 19:58:14 +0100 Subject: [PATCH 13/25] Tmp --- include/LadspaBase.h | 1 + include/LadspaManager.h | 6 +++++ plugins/LadspaEffect/LadspaControlDialog.cpp | 6 ++--- plugins/LadspaEffect/LadspaEffect.cpp | 4 ++++ plugins/LadspaEffect/calf/veal | 2 +- src/core/LadspaControl.cpp | 8 +++++++ src/core/LadspaManager.cpp | 25 ++++++++++++++++++++ src/gui/widgets/LadspaControlView.cpp | 1 + 8 files changed, 49 insertions(+), 4 deletions(-) diff --git a/include/LadspaBase.h b/include/LadspaBase.h index 67b595e2869..be4576f5503 100644 --- a/include/LadspaBase.h +++ b/include/LadspaBase.h @@ -45,6 +45,7 @@ typedef enum BufferRates typedef enum BufferData { TOGGLED, + ENUM, INTEGER, FLOATING, TIME, diff --git a/include/LadspaManager.h b/include/LadspaManager.h index 25d23b61e79..1d055c1d8c5 100644 --- a/include/LadspaManager.h +++ b/include/LadspaManager.h @@ -179,6 +179,12 @@ class EXPORT LadspaManager be described as [-0.1, 3.1]. */ bool isInteger( const ladspa_key_t & _plugin, uint32_t _port ); + /* Indicates that a user interface would probably wish to provide a + stepped control taking only integer values. This is equal to isInteger, + but the number of values is usually small and may be better depicted + with a combo box. */ + bool isEnum( const ladspa_key_t & _plugin, uint32_t _port ); + /* Returns the name of the port. */ QString getPortName( const ladspa_key_t & _plugin, uint32_t _port ); diff --git a/plugins/LadspaEffect/LadspaControlDialog.cpp b/plugins/LadspaEffect/LadspaControlDialog.cpp index f58ccb55b7e..ed16cf9e1c8 100644 --- a/plugins/LadspaEffect/LadspaControlDialog.cpp +++ b/plugins/LadspaEffect/LadspaControlDialog.cpp @@ -112,10 +112,10 @@ void LadspaControlDialog::updateEffectView( LadspaControls * _ctl ) { if( (*it)->port()->proc == proc ) { + buffer_data_t this_port = (*it)->port()->data_type; if( last_port != NONE && - (*it)->port()->data_type == TOGGLED && - !( (*it)->port()->data_type == TOGGLED && - last_port == TOGGLED ) ) + ( this_port == TOGGLED || this_port == ENUM ) && + ( last_port != TOGGLED && last_port != ENUM ) ) { ++row; col = 0; diff --git a/plugins/LadspaEffect/LadspaEffect.cpp b/plugins/LadspaEffect/LadspaEffect.cpp index 0ce66721322..408922521dc 100644 --- a/plugins/LadspaEffect/LadspaEffect.cpp +++ b/plugins/LadspaEffect/LadspaEffect.cpp @@ -371,6 +371,10 @@ void LadspaEffect::pluginInstantiation() } p->scale = 1.0f; + if( manager->isEnum( m_key, port ) ) + { + p->data_type = ENUM; + } if( manager->isPortToggled( m_key, port ) ) { p->data_type = TOGGLED; diff --git a/plugins/LadspaEffect/calf/veal b/plugins/LadspaEffect/calf/veal index d2943d34862..fd276e17fd7 160000 --- a/plugins/LadspaEffect/calf/veal +++ b/plugins/LadspaEffect/calf/veal @@ -1 +1 @@ -Subproject commit d2943d348624261202681d22c308f8ac106041ed +Subproject commit fd276e17fd7bc047fdf9eabcdcfd4b164b8e248b diff --git a/src/core/LadspaControl.cpp b/src/core/LadspaControl.cpp index d2d6e147a61..d7abfde4202 100644 --- a/src/core/LadspaControl.cpp +++ b/src/core/LadspaControl.cpp @@ -59,6 +59,7 @@ LadspaControl::LadspaControl( Model * _parent, port_desc_t * _port, break; case INTEGER: + case ENUM: m_knobModel.setRange( static_cast( m_port->max ), static_cast( m_port->min ), 1 + static_cast( m_port->max - @@ -117,6 +118,7 @@ LADSPA_Data LadspaControl::value() case TOGGLED: return static_cast( m_toggledModel.value() ); case INTEGER: + case ENUM: case FLOATING: return static_cast( m_knobModel.value() ); case TIME: @@ -136,6 +138,7 @@ ValueBuffer * LadspaControl::valueBuffer() { case TOGGLED: case INTEGER: + case ENUM: return NULL; case FLOATING: return m_knobModel.valueBuffer(); @@ -159,6 +162,7 @@ void LadspaControl::setValue( LADSPA_Data _value ) m_toggledModel.setValue( static_cast( _value ) ); break; case INTEGER: + case ENUM: m_knobModel.setValue( static_cast( _value ) ); break; case FLOATING: @@ -193,6 +197,7 @@ void LadspaControl::saveSettings( QDomDocument& doc, m_toggledModel.saveSettings( doc, e, "data" ); break; case INTEGER: + case ENUM: case FLOATING: m_knobModel.saveSettings( doc, e, "data" ); break; @@ -236,6 +241,7 @@ void LadspaControl::loadSettings( const QDomElement& parent, const QString& name m_toggledModel.loadSettings( e, dataModelName ); break; case INTEGER: + case ENUM: case FLOATING: m_knobModel.loadSettings( e, dataModelName ); break; @@ -259,6 +265,7 @@ void LadspaControl::linkControls( LadspaControl * _control ) BoolModel::linkModels( &m_toggledModel, _control->toggledModel() ); break; case INTEGER: + case ENUM: case FLOATING: FloatModel::linkModels( &m_knobModel, _control->knobModel() ); break; @@ -309,6 +316,7 @@ void LadspaControl::unlinkControls( LadspaControl * _control ) BoolModel::unlinkModels( &m_toggledModel, _control->toggledModel() ); break; case INTEGER: + case ENUM: case FLOATING: FloatModel::unlinkModels( &m_knobModel, _control->knobModel() ); break; diff --git a/src/core/LadspaManager.cpp b/src/core/LadspaManager.cpp index 4286c34aca0..fc06dfda9ac 100644 --- a/src/core/LadspaManager.cpp +++ b/src/core/LadspaManager.cpp @@ -749,6 +749,31 @@ bool LadspaManager::isInteger( const ladspa_key_t & _plugin, +bool LadspaManager::isEnum( const ladspa_key_t & _plugin, uint32_t _port ) +{ + if( m_ladspaManagerMap.contains( _plugin ) + && _port < getPortCount( _plugin ) ) + { + LADSPA_Descriptor_Function descriptorFunction = + m_ladspaManagerMap[_plugin]->descriptorFunction; + const LADSPA_Descriptor * descriptor = + descriptorFunction( + m_ladspaManagerMap[_plugin]->index ); + LADSPA_PortRangeHintDescriptor hintDescriptor = + descriptor->PortRangeHints[_port].HintDescriptor; + // This is an LMMS extension to ladspa + return( LADSPA_IS_HINT_INTEGER( hintDescriptor ) && + LADSPA_IS_HINT_TOGGLED( hintDescriptor ) ); + } + else + { + return( false ); + } +} + + + + QString LadspaManager::getPortName( const ladspa_key_t & _plugin, uint32_t _port ) { diff --git a/src/gui/widgets/LadspaControlView.cpp b/src/gui/widgets/LadspaControlView.cpp index a0f68ab2c29..b3bc1de3430 100644 --- a/src/gui/widgets/LadspaControlView.cpp +++ b/src/gui/widgets/LadspaControlView.cpp @@ -77,6 +77,7 @@ LadspaControlView::LadspaControlView( QWidget * _parent, } case INTEGER: + case ENUM: case FLOATING: knb = new Knob( knobBright_26, this, m_ctl->port()->name ); break; From ac14fa84397b72b518c518c8dbfdfba8b764cf55 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Thu, 4 Jan 2018 21:18:15 +0100 Subject: [PATCH 14/25] Fixes from the PR todo list * When loading, apply default values to knobs missing in the savefiles * Fix enumerated values not starting a new row * Separate fixes in submodule veal --- plugins/LadspaEffect/LadspaEffect.cpp | 2 +- plugins/LadspaEffect/calf/veal | 2 +- src/core/LadspaControl.cpp | 82 ++++++++++++++++++--------- 3 files changed, 58 insertions(+), 28 deletions(-) diff --git a/plugins/LadspaEffect/LadspaEffect.cpp b/plugins/LadspaEffect/LadspaEffect.cpp index 408922521dc..aceea2d4119 100644 --- a/plugins/LadspaEffect/LadspaEffect.cpp +++ b/plugins/LadspaEffect/LadspaEffect.cpp @@ -375,7 +375,7 @@ void LadspaEffect::pluginInstantiation() { p->data_type = ENUM; } - if( manager->isPortToggled( m_key, port ) ) + else if( manager->isPortToggled( m_key, port ) ) { p->data_type = TOGGLED; } diff --git a/plugins/LadspaEffect/calf/veal b/plugins/LadspaEffect/calf/veal index fd276e17fd7..7cf84e625cd 160000 --- a/plugins/LadspaEffect/calf/veal +++ b/plugins/LadspaEffect/calf/veal @@ -1 +1 @@ -Subproject commit fd276e17fd7bc047fdf9eabcdcfd4b164b8e248b +Subproject commit 7cf84e625cd152f8fc5b7115760c809b4aa640ea diff --git a/src/core/LadspaControl.cpp b/src/core/LadspaControl.cpp index d7abfde4202..cf8c6e4680b 100644 --- a/src/core/LadspaControl.cpp +++ b/src/core/LadspaControl.cpp @@ -48,6 +48,8 @@ LadspaControl::LadspaControl( Model * _parent, port_desc_t * _port, switch( m_port->data_type ) { case TOGGLED: + m_toggledModel.setInitValue( + static_cast( m_port->def ) ); connect( &m_toggledModel, SIGNAL( dataChanged() ), this, SLOT( ledChanged() ) ); if( m_port->def == 1.0f ) @@ -221,36 +223,64 @@ void LadspaControl::loadSettings( const QDomElement& parent, const QString& name QString linkModelName = "link"; QDomElement e = parent.namedItem( name ).toElement(); - // COMPAT < 1.0.0: detect old data format where there's either no dedicated sub - // element or there's a direct sub element with automation link information - if( e.isNull() || e.hasAttribute( "id" ) ) + if(e.isNull()) { - dataModelName = name; - linkModelName = name + "link"; - e = parent; + // the port exists in the current effect, but not in the + // savefile => it's a new port, so load the default value + if( m_link ) + m_linkEnabledModel.setValue(m_linkEnabledModel.initValue()); + switch( m_port->data_type ) + { + case TOGGLED: + m_toggledModel.setValue(m_toggledModel.initValue()); + break; + case INTEGER: + case ENUM: + case FLOATING: + m_knobModel.setValue(m_knobModel.initValue()); + break; + case TIME: + m_tempoSyncKnobModel.setValue(m_tempoSyncKnobModel.initValue()); + break; + default: + printf("LadspaControl::loadSettings BAD BAD BAD\n"); + break; + } } - - if( m_link ) + else { - m_linkEnabledModel.loadSettings( e, linkModelName ); - } - switch( m_port->data_type ) - { - case TOGGLED: - m_toggledModel.loadSettings( e, dataModelName ); - break; - case INTEGER: - case ENUM: - case FLOATING: - m_knobModel.loadSettings( e, dataModelName ); - break; - case TIME: - m_tempoSyncKnobModel.loadSettings( e, dataModelName ); - break; - default: - printf("LadspaControl::loadSettings BAD BAD BAD\n"); - break; + // COMPAT < 1.0.0: detect old data format where there's either no dedicated sub + // element or there's a direct sub element with automation link information + if( e.isNull() || e.hasAttribute( "id" ) ) + { + dataModelName = name; + linkModelName = name + "link"; + e = parent; + } + + if( m_link ) + { + m_linkEnabledModel.loadSettings( e, linkModelName ); + } + + switch( m_port->data_type ) + { + case TOGGLED: + m_toggledModel.loadSettings( e, dataModelName ); + break; + case INTEGER: + case ENUM: + case FLOATING: + m_knobModel.loadSettings( e, dataModelName ); + break; + case TIME: + m_tempoSyncKnobModel.loadSettings( e, dataModelName ); + break; + default: + printf("LadspaControl::loadSettings BAD BAD BAD\n"); + break; + } } } From 00b188eb74f7c1bac06c8fe8ed949a464d5d26b3 Mon Sep 17 00:00:00 2001 From: tresf Date: Mon, 5 Feb 2018 16:35:25 -0500 Subject: [PATCH 15/25] DataFile upgrades --- src/core/DataFile.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/core/DataFile.cpp b/src/core/DataFile.cpp index c66fe0d4981..355e57136e9 100644 --- a/src/core/DataFile.cpp +++ b/src/core/DataFile.cpp @@ -1016,6 +1016,31 @@ void DataFile::upgrade_1_3_0() { attribute.setAttribute( "value", "veal" ); } + else if( attribute.attribute( "name" ) == "plugin" && + attribute.attribute( "value" ) == "Sidechaincompressor" ) + { + attribute.setAttribute( "value", "SidechainCompressor" ); + } + else if( attribute.attribute( "name" ) == "plugin" && + attribute.attribute( "value" ) == "Sidechaingate" ) + { + attribute.setAttribute( "value", "SidechainGate" ); + } + else if( attribute.attribute( "name" ) == "plugin" && + attribute.attribute( "value" ) == "Multibandcompressor" ) + { + attribute.setAttribute( "value", "MultibandCompressor" ); + } + else if( attribute.attribute( "name" ) == "plugin" && + attribute.attribute( "value" ) == "Multibandgate" ) + { + attribute.setAttribute( "value", "MultibandGate" ); + } + else if( attribute.attribute( "name" ) == "plugin" && + attribute.attribute( "value" ) == "Multibandlimiter" ) + { + attribute.setAttribute( "value", "MultibandLimiter" ); + } } } } From ab72fe2c3c38caf8d7c7f4fd5469ba5c8406cf68 Mon Sep 17 00:00:00 2001 From: tresf Date: Thu, 8 Feb 2018 17:30:15 -0500 Subject: [PATCH 16/25] Add S&Q upgrades --- src/core/DataFile.cpp | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/core/DataFile.cpp b/src/core/DataFile.cpp index 355e57136e9..1e233cb2efa 100644 --- a/src/core/DataFile.cpp +++ b/src/core/DataFile.cpp @@ -1041,6 +1041,47 @@ void DataFile::upgrade_1_3_0() { attribute.setAttribute( "value", "MultibandLimiter" ); } + // Handle port changes + if( attribute.attribute( "name" ) == "plugin" && + ( attribute.attribute( "value" ) == "MultibandLimiter" || + attribute.attribute( "value" ) == "MultibandCompressor" || + attribute.attribute( "value" ) == "MultibandGate" ) ) + { + + // Head back up the DOM to upgrade ports + QDomNodeList ladspacontrols = effect.elementsByTagName( "ladspacontrols" ); + for( int m = 0; !ladspacontrols.item( m ).isNull(); ++m ) + { + QDomElement ladspacontrol = ladspacontrols.item( m ).toElement(); + for( QDomElement port = ladspacontrol.firstChild().toElement(); + !port.isNull(); port = port.nextSibling().toElement() ) + { + QStringList parts = port.tagName().split("port"); + // Not a "port" + if ( parts.size() < 2 ) + { + continue; + } + int num = parts[1].toInt(); + // Leave as-is + if ( num <= 17 ) + { + continue; + } + // Remove unused ports + if ( num >= 18 && num <= 23 ) + { + ladspacontrol.removeChild(port); + } + // Bump higher ports up 6 positions + else if ( num >= 24 ) + { + // port01...port010, etc + port.setTagName( "0" + ( num - 6 ) ); + } + } + } + } } } } From fb015115bca7da9365e902e48c3ca2e5b5611774 Mon Sep 17 00:00:00 2001 From: tresf Date: Fri, 9 Feb 2018 23:51:05 -0500 Subject: [PATCH 17/25] Fix looping logic --- src/core/DataFile.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/core/DataFile.cpp b/src/core/DataFile.cpp index 1e233cb2efa..2a2aafcc99f 100644 --- a/src/core/DataFile.cpp +++ b/src/core/DataFile.cpp @@ -1052,6 +1052,7 @@ void DataFile::upgrade_1_3_0() QDomNodeList ladspacontrols = effect.elementsByTagName( "ladspacontrols" ); for( int m = 0; !ladspacontrols.item( m ).isNull(); ++m ) { + QList removeList; QDomElement ladspacontrol = ladspacontrols.item( m ).toElement(); for( QDomElement port = ladspacontrol.firstChild().toElement(); !port.isNull(); port = port.nextSibling().toElement() ) @@ -1068,18 +1069,25 @@ void DataFile::upgrade_1_3_0() { continue; } - // Remove unused ports + // Mark ports for removal if ( num >= 18 && num <= 23 ) { - ladspacontrol.removeChild(port); + removeList << port; } // Bump higher ports up 6 positions else if ( num >= 24 ) { // port01...port010, etc - port.setTagName( "0" + ( num - 6 ) ); + QString name( "port0" ); + name.append( QString::number( num -6 ) ); + port.setTagName( name ); } } + // Remove ports marked for removal + for ( QDomElement e : removeList ) + { + ladspacontrol.removeChild( e ); + } } } } From ca4690b8a573ebb85095fc166345a1db7b57d718 Mon Sep 17 00:00:00 2001 From: tresf Date: Sat, 10 Feb 2018 22:12:04 -0500 Subject: [PATCH 18/25] Switch back to lmms fork --- .gitmodules | 6 +++--- plugins/LadspaEffect/calf/veal | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitmodules b/.gitmodules index 13b98c6529a..4a8c9adc1ee 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,6 +10,9 @@ [submodule "plugins/OpulenZ/adplug"] path = plugins/OpulenZ/adplug url = https://github.com/adplug/adplug.git +[submodule "plugins/LadspaEffect/calf/veal"] + path = plugins/LadspaEffect/calf/veal + url = https://github.com/lmms/veal [submodule "plugins/Xpressive/exprtk"] path = plugins/Xpressive/exprtk url = https://github.com/ArashPartow/exprtk @@ -22,6 +25,3 @@ [submodule "src/3rdparty/weakjack/weakjack"] path = src/3rdparty/weakjack/weakjack url = https://github.com/x42/weakjack.git -[submodule "plugins/LadspaEffect/calf/veal"] - path = plugins/LadspaEffect/calf/veal - url = https://github.com/tresf/veal diff --git a/plugins/LadspaEffect/calf/veal b/plugins/LadspaEffect/calf/veal index 7cf84e625cd..e61866dc8ab 160000 --- a/plugins/LadspaEffect/calf/veal +++ b/plugins/LadspaEffect/calf/veal @@ -1 +1 @@ -Subproject commit 7cf84e625cd152f8fc5b7115760c809b4aa640ea +Subproject commit e61866dc8abefbfd51a11546e0ade722871fa088 From c29d2a8d4e8426f3f18209e3577c6e981fd36c57 Mon Sep 17 00:00:00 2001 From: tresf Date: Sat, 10 Feb 2018 22:21:10 -0500 Subject: [PATCH 19/25] Try again to bump submodule --- plugins/LadspaEffect/calf/veal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/LadspaEffect/calf/veal b/plugins/LadspaEffect/calf/veal index e61866dc8ab..0114653cc72 160000 --- a/plugins/LadspaEffect/calf/veal +++ b/plugins/LadspaEffect/calf/veal @@ -1 +1 @@ -Subproject commit e61866dc8abefbfd51a11546e0ade722871fa088 +Subproject commit 0114653cc72dc5048c3cb98febd952536555991f From a1606acddb041facc16c1a235cf00baee63c06cb Mon Sep 17 00:00:00 2001 From: tresf Date: Fri, 5 Jan 2018 17:23:02 -0500 Subject: [PATCH 20/25] Move exprtk to non-volatile branch Fix Travis-CI for #4089 --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 4a8c9adc1ee..5c8e3563e83 100644 --- a/.gitmodules +++ b/.gitmodules @@ -15,7 +15,7 @@ url = https://github.com/lmms/veal [submodule "plugins/Xpressive/exprtk"] path = plugins/Xpressive/exprtk - url = https://github.com/ArashPartow/exprtk + url = https://github.com/tresf/exprtk [submodule "plugins/LadspaEffect/swh/ladspa"] path = plugins/LadspaEffect/swh/ladspa url = https://github.com/swh/ladspa From 85860ec512f764e7c94e16aeff294fc2eda0eb44 Mon Sep 17 00:00:00 2001 From: tresf Date: Sat, 10 Feb 2018 23:17:14 -0500 Subject: [PATCH 21/25] Enable C++11 to fix Windows builds --- plugins/LadspaEffect/calf/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/LadspaEffect/calf/CMakeLists.txt b/plugins/LadspaEffect/calf/CMakeLists.txt index 88361f735b1..776752bc5e6 100644 --- a/plugins/LadspaEffect/calf/CMakeLists.txt +++ b/plugins/LadspaEffect/calf/CMakeLists.txt @@ -1,6 +1,8 @@ # Note: # The last version of Calf that was LADSPA-capable is version 0.0.18.2 +SET(CMAKE_CXX_STANDARD 11) + # Parse version info from autoconf FILE(READ veal/configure.ac VERSION_FILE) STRING(REPLACE "[" ";" VERSION_FILE ${VERSION_FILE} ) From 021e60423be7f30c35a66cfd4b82f9f885522f52 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Fri, 16 Mar 2018 19:02:39 +0100 Subject: [PATCH 22/25] First attempt. Remove lists work, but adding has no effect. --- src/core/DataFile.cpp | 130 +++++++++++++++++++++++++++++++----------- 1 file changed, 97 insertions(+), 33 deletions(-) diff --git a/src/core/DataFile.cpp b/src/core/DataFile.cpp index 2a2aafcc99f..38624771e1d 100644 --- a/src/core/DataFile.cpp +++ b/src/core/DataFile.cpp @@ -968,6 +968,47 @@ void DataFile::upgrade_1_2_0_rc2_42() } +/** + * Helper function to call a functor for all effect ports' DomElements, + * providing the functor with lists to add and remove DomElements. Helpful for + * patching port values from savefiles. + */ +template +void iterate_ladspa_ports(QDomElement& effect, Ftor& ftor) +{ + // Head back up the DOM to upgrade ports + QDomNodeList ladspacontrols = effect.elementsByTagName( "ladspacontrols" ); + for( int m = 0; !ladspacontrols.item( m ).isNull(); ++m ) + { + QList addList, removeList; + QDomElement ladspacontrol = ladspacontrols.item( m ).toElement(); + for( QDomElement port = ladspacontrol.firstChild().toElement(); + !port.isNull(); port = port.nextSibling().toElement() ) + { + QStringList parts = port.tagName().split("port"); + // Not a "port" + if ( parts.size() < 2 ) + { + continue; + } + int num = parts[1].toInt(); + + ftor(port, num, addList, removeList); + } + // Add ports marked for adding + for ( QDomElement e : addList ) + { + puts("ADD"); + ladspacontrol.appendChild( e ); + } + // Remove ports marked for removal + for ( QDomElement e : removeList ) + { + ladspacontrol.removeChild( e ); + } + } +} + void DataFile::upgrade_1_3_0() { QDomNodeList list = elementsByTagName( "instrument" ); @@ -1009,6 +1050,7 @@ void DataFile::upgrade_1_3_0() QDomNodeList attributes = key.elementsByTagName( "attribute" ); for( int k = 0; !attributes.item( k ).isNull(); ++k ) { + // Effect name changes QDomElement attribute = attributes.item( k ).toElement(); if( attribute.attribute( "name" ) == "file" && ( attribute.attribute( "value" ) == "calf" || @@ -1041,55 +1083,77 @@ void DataFile::upgrade_1_3_0() { attribute.setAttribute( "value", "MultibandLimiter" ); } + + // Handle port changes if( attribute.attribute( "name" ) == "plugin" && ( attribute.attribute( "value" ) == "MultibandLimiter" || attribute.attribute( "value" ) == "MultibandCompressor" || attribute.attribute( "value" ) == "MultibandGate" ) ) { + auto fn = [&](QDomElement& port, int num, QList&, QList& removeList) + { + // Mark ports for removal + if ( num >= 18 && num <= 23 ) + { + removeList << port; + } + // Bump higher ports up 6 positions + else if ( num >= 24 ) + { + // port01...port010, etc + QString name( "port0" ); + name.append( QString::number( num -6 ) ); + port.setTagName( name ); + } + }; + iterate_ladspa_ports(effect, fn); + } - // Head back up the DOM to upgrade ports - QDomNodeList ladspacontrols = effect.elementsByTagName( "ladspacontrols" ); - for( int m = 0; !ladspacontrols.item( m ).isNull(); ++m ) + if( attribute.attribute( "name" ) == "plugin" && + ( attribute.attribute( "value" ) == "Pulsator" ) ) + { + auto fn = [&](QDomElement& port, int num, QList& addList, QList& removeList) { - QList removeList; - QDomElement ladspacontrol = ladspacontrols.item( m ).toElement(); - for( QDomElement port = ladspacontrol.firstChild().toElement(); - !port.isNull(); port = port.nextSibling().toElement() ) + switch(num) { - QStringList parts = port.tagName().split("port"); - // Not a "port" - if ( parts.size() < 2 ) - { - continue; - } - int num = parts[1].toInt(); - // Leave as-is - if ( num <= 17 ) - { - continue; - } - // Mark ports for removal - if ( num >= 18 && num <= 23 ) + case 16: { + // old freq is now at port 25 + QDomElement portCopy = createElement("port25"); + portCopy.setAttribute("data", port.attribute("data")); + addList << portCopy; + // remove old freq port removeList << port; + // set the "timing" port to choose port23+2=port25 (timing in Hz) + QDomElement timing = createElement("port22"); + timing.setAttribute("data", 2); + addList << timing; + break; } - // Bump higher ports up 6 positions - else if ( num >= 24 ) + // port 18 (modulation) => 17 + case 17: + port.setTagName("port16"); + break; + case 18: { - // port01...port010, etc - QString name( "port0" ); - name.append( QString::number( num -6 ) ); - port.setTagName( name ); + // leave port 18 (offsetr), but add port 17 (offsetl) + QDomElement offsetl = createElement("port17"); + offsetl.setAttribute("data", .0f); + addList << offsetl; + // additional: bash port 21 to 1 + QDomElement pulsewidth = createElement("port21"); + pulsewidth.setAttribute("data", 1.f); + addList << pulsewidth; + break; } } - // Remove ports marked for removal - for ( QDomElement e : removeList ) - { - ladspacontrol.removeChild( e ); - } - } + + + }; + iterate_ladspa_ports(effect, fn); } + } } } From 62e1d8f5af3f8e9ee0be78a7893ae3293cfdae6f Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Mon, 2 Apr 2018 13:41:51 +0200 Subject: [PATCH 23/25] Fix all CALF effects' port numbers, ranges and defaults --- src/core/DataFile.cpp | 216 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 209 insertions(+), 7 deletions(-) diff --git a/src/core/DataFile.cpp b/src/core/DataFile.cpp index 38624771e1d..cf6b9494b5a 100644 --- a/src/core/DataFile.cpp +++ b/src/core/DataFile.cpp @@ -993,12 +993,22 @@ void iterate_ladspa_ports(QDomElement& effect, Ftor& ftor) } int num = parts[1].toInt(); + // From Qt's docs of QDomNode: + // * copying a QDomNode is OK, they still have the same + // pointer to the "internal" QDomNodePrivate. + // * Also, they are using linked lists, which means + // deleting or appending QDomNode does not invalidate + // any other pointers. + // => Inside ftor, you can (and should) push back the + // QDomElements by value, not references + // => The loops below for adding and removing don't + // invalidate any other QDomElements ftor(port, num, addList, removeList); } + // Add ports marked for adding for ( QDomElement e : addList ) { - puts("ADD"); ladspacontrol.appendChild( e ); } // Remove ports marked for removal @@ -1009,6 +1019,16 @@ void iterate_ladspa_ports(QDomElement& effect, Ftor& ftor) } } +// helper function if you need to print a QDomNode +QDebug operator<<(QDebug dbg, const QDomNode& node) +{ + QString s; + QTextStream str(&s, QIODevice::WriteOnly); + node.save(str, 2); + dbg << qPrintable(s); + return dbg; +} + void DataFile::upgrade_1_3_0() { QDomNodeList list = elementsByTagName( "instrument" ); @@ -1051,6 +1071,7 @@ void DataFile::upgrade_1_3_0() for( int k = 0; !attributes.item( k ).isNull(); ++k ) { // Effect name changes + QDomElement attribute = attributes.item( k ).toElement(); if( attribute.attribute( "name" ) == "file" && ( attribute.attribute( "value" ) == "calf" || @@ -1084,8 +1105,8 @@ void DataFile::upgrade_1_3_0() attribute.setAttribute( "value", "MultibandLimiter" ); } - // Handle port changes + if( attribute.attribute( "name" ) == "plugin" && ( attribute.attribute( "value" ) == "MultibandLimiter" || attribute.attribute( "value" ) == "MultibandCompressor" || @@ -1120,29 +1141,29 @@ void DataFile::upgrade_1_3_0() case 16: { // old freq is now at port 25 - QDomElement portCopy = createElement("port25"); + QDomElement portCopy = createElement("port025"); portCopy.setAttribute("data", port.attribute("data")); addList << portCopy; // remove old freq port removeList << port; // set the "timing" port to choose port23+2=port25 (timing in Hz) - QDomElement timing = createElement("port22"); + QDomElement timing = createElement("port022"); timing.setAttribute("data", 2); addList << timing; break; } // port 18 (modulation) => 17 case 17: - port.setTagName("port16"); + port.setTagName("port016"); break; case 18: { // leave port 18 (offsetr), but add port 17 (offsetl) - QDomElement offsetl = createElement("port17"); + QDomElement offsetl = createElement("port017"); offsetl.setAttribute("data", .0f); addList << offsetl; // additional: bash port 21 to 1 - QDomElement pulsewidth = createElement("port21"); + QDomElement pulsewidth = createElement("port021"); pulsewidth.setAttribute("data", 1.f); addList << pulsewidth; break; @@ -1154,6 +1175,187 @@ void DataFile::upgrade_1_3_0() iterate_ladspa_ports(effect, fn); } + + if( attribute.attribute( "name" ) == "plugin" && + ( attribute.attribute( "value" ) == "VintageDelay" ) ) + { + auto fn = [&](QDomElement& port, int num, QList& addList, QList& ) + { + switch(num) + { + case 4: + { + // BPM is now port028 + port.setTagName("port028"); + // bash timing to BPM + QDomElement timing = createElement("port027"); + timing.setAttribute("data", 0); + addList << timing; + + // port 5 and 6 (in, out gain) need to be bashed to 1: + QDomElement input = createElement("port05"); + input.setAttribute("data", 1.f); + addList << input; + QDomElement output = createElement("port06"); + output.setAttribute("data", 1.f); + addList << output; + + break; + } + default: + // all other ports increase by 10 + QString name( "port0" ); + name.append( QString::number( num + 10 ) ); + port.setTagName( name ); + } + + + }; + iterate_ladspa_ports(effect, fn); + } + + if( attribute.attribute( "name" ) == "plugin" && + ( ( attribute.attribute( "value" ) == "Equalizer5Band" ) + || ( attribute.attribute( "value" ) == "Equalizer8Band" ) + || ( attribute.attribute( "value" ) == "Equalizer12Band" ) ) ) + { + // NBand equalizers got 4 q nobs inserted. We need to shift everything else... + // HOWEVER: 5 band eq has only 2 q nobs inserted (no LS/HS filters) + bool band5 = ( attribute.attribute( "value" ) == "Equalizer5Band" ); + auto fn = [&](QDomElement& port, int num, QList& addList, QList& ) + { + if(num == 4) + { + // don't modify port 4, but some other ones: + int zoom_port; + if(attribute.attribute( "value" ) == "Equalizer5Band") + zoom_port = 36; + else if(attribute.attribute( "value" ) == "Equalizer8Band") + zoom_port = 48; + else // 12 band + zoom_port = 64; + // bash zoom to 0.25 + QString name( "port0" ); + name.append( QString::number( zoom_port ) ); + QDomElement timing = createElement(name); + timing.setAttribute("data", 0.25f); + addList << timing; + } + // the following code could be refactored, but I did careful code-reading + // to prevent copy-paste-errors + if(num == 18) + { + // 18 => 19 + port.setTagName("port019"); + // insert port 18 (q) + QDomElement q = createElement("port018"); + q.setAttribute("data", 0.707f); + addList << q; + } + else if(num >= 19 && num <= 20) + { + // num += 1 + QString name( "port0" ); + name.append( QString::number( num + 1 ) ); + port.setTagName( name ); + } + else if(num == 21) + { + // 21 => 23 + port.setTagName("port023"); + // insert port 22 (q) + QDomElement q = createElement("port022"); + q.setAttribute("data", 0.707f); + addList << q; + } + else if(num >= 22 && (num <= 23 || band5)) + { + // num += 2 + QString name( "port0" ); + name.append( QString::number( num + 2 ) ); + port.setTagName( name ); + } + else if(num == 24 && !band5) + { + // 24 => 27 + port.setTagName("port027"); + // insert port 26 (q) + QDomElement q = createElement("port026"); + q.setAttribute("data", 0.707f); + addList << q; + } + else if(num >= 25 && num <= 26 && !band5) + { + // num += 3 + QString name( "port0" ); + name.append( QString::number( num + 3 ) ); + port.setTagName( name ); + } + else if(num == 27 && !band5) + { + // 27 => 31 + port.setTagName("port031"); + // insert port 30 (q) + QDomElement q = createElement("port030"); + q.setAttribute("data", 0.707f); + addList << q; + } + else if(num >= 28 && !band5) + { + // num += 4 + QString name( "port0" ); + name.append( QString::number( num + 4 ) ); + port.setTagName( name ); + } + }; + iterate_ladspa_ports(effect, fn); + } + + if( attribute.attribute( "name" ) == "plugin" && + attribute.attribute( "value" ) == "Saturator" ) + { + auto fn = [&](QDomElement& port, int num, QList&, QList& ) + { + // These ports have been shifted a bit weird... + if( num == 7 ) + { + port.setTagName("port015"); + } + else if(num == 12) + { + port.setTagName("port016"); + } + else if(num == 13) + { + port.setTagName("port017"); + } + else if ( num >= 15 ) + { + QString name( "port0" ); + name.append( QString::number( num + 3 ) ); + port.setTagName( name ); + } + }; + iterate_ladspa_ports(effect, fn); + } + + if( attribute.attribute( "name" ) == "plugin" && + attribute.attribute( "value" ) == "StereoTools" ) + { + auto fn = [&](QDomElement& port, int num, QList&, QList& ) + { + // This effect can not be back-ported due to bugs in the old version, + // or due to different behaviour. We thus port all parameters we can, + // and bash all new parameters (in this case, s.level and m.level) to + // their new defaults (both 1.0f in this case) + + if( num == 23 || num == 25 ) + { + port.setAttribute("data", 1.0f); + } + }; + iterate_ladspa_ports(effect, fn); + } } } } From e313d62cab421eadd995f25e04672b1ea4ee6b5e Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Mon, 2 Apr 2018 17:02:55 +0200 Subject: [PATCH 24/25] Update CALF module. Code reading rework. --- plugins/LadspaEffect/calf/veal | 2 +- src/core/DataFile.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/LadspaEffect/calf/veal b/plugins/LadspaEffect/calf/veal index 0114653cc72..2841b05a36e 160000 --- a/plugins/LadspaEffect/calf/veal +++ b/plugins/LadspaEffect/calf/veal @@ -1 +1 @@ -Subproject commit 0114653cc72dc5048c3cb98febd952536555991f +Subproject commit 2841b05a36e53116508a8a862f052e14dad00d67 diff --git a/src/core/DataFile.cpp b/src/core/DataFile.cpp index cf6b9494b5a..bf2a43e6e56 100644 --- a/src/core/DataFile.cpp +++ b/src/core/DataFile.cpp @@ -1160,11 +1160,11 @@ void DataFile::upgrade_1_3_0() { // leave port 18 (offsetr), but add port 17 (offsetl) QDomElement offsetl = createElement("port017"); - offsetl.setAttribute("data", .0f); + offsetl.setAttribute("data", 0.0f); addList << offsetl; // additional: bash port 21 to 1 QDomElement pulsewidth = createElement("port021"); - pulsewidth.setAttribute("data", 1.f); + pulsewidth.setAttribute("data", 1.0f); addList << pulsewidth; break; } @@ -1194,10 +1194,10 @@ void DataFile::upgrade_1_3_0() // port 5 and 6 (in, out gain) need to be bashed to 1: QDomElement input = createElement("port05"); - input.setAttribute("data", 1.f); + input.setAttribute("data", 1.0f); addList << input; QDomElement output = createElement("port06"); - output.setAttribute("data", 1.f); + output.setAttribute("data", 1.0f); addList << output; break; From b156a82171b6c924d65a89814df88603233ffd24 Mon Sep 17 00:00:00 2001 From: Tres Finocchiaro Date: Fri, 13 Apr 2018 14:51:38 -0400 Subject: [PATCH 25/25] Don't revert exprtk --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 5c8e3563e83..4a8c9adc1ee 100644 --- a/.gitmodules +++ b/.gitmodules @@ -15,7 +15,7 @@ url = https://github.com/lmms/veal [submodule "plugins/Xpressive/exprtk"] path = plugins/Xpressive/exprtk - url = https://github.com/tresf/exprtk + url = https://github.com/ArashPartow/exprtk [submodule "plugins/LadspaEffect/swh/ladspa"] path = plugins/LadspaEffect/swh/ladspa url = https://github.com/swh/ladspa