diff --git a/.gitmodules b/.gitmodules index 000a2dffb91..1ed1eead067 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,3 +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/lmms/veal diff --git a/plugins/LadspaEffect/calf/AUTHORS b/plugins/LadspaEffect/calf/AUTHORS deleted file mode 100644 index e28cf0bba63..00000000000 --- a/plugins/LadspaEffect/calf/AUTHORS +++ /dev/null @@ -1,16 +0,0 @@ -Krzysztof Foltman -Hermann Meyer -Thor Harald Johansen -Thorsten Wilms -Hans Baier -Torben Hohn -Markus Schmidt -Tom Szilagyi -Damien Zammit -Christian Holschuh - -Additional bugfixes/enhancement patches: -David Täht -Dave Robillard -Alexandre Prokoudine -Carl Hetherington diff --git a/plugins/LadspaEffect/calf/CMakeLists.txt b/plugins/LadspaEffect/calf/CMakeLists.txt index b78a3817540..eaccd87aee8 100644 --- a/plugins/LadspaEffect/calf/CMakeLists.txt +++ b/plugins/LadspaEffect/calf/CMakeLists.txt @@ -1,22 +1,45 @@ -FILE(GLOB SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp") +# 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) -ADD_LIBRARY(calf MODULE ${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_SOURCE_DIR}" - "${CMAKE_CURRENT_SOURCE_DIR}/src") -INSTALL(TARGETS calf LIBRARY DESTINATION "${PLUGIN_DIR}/ladspa") -SET_TARGET_PROPERTIES(calf PROPERTIES PREFIX "") + "${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") + SET(INLINE_FLAGS "-finline-functions-called-once -finline-limit=80") ENDIF() -SET_TARGET_PROPERTIES(calf PROPERTIES COMPILE_FLAGS "-O2 -finline-functions ${INLINE_FLAGS}") +SET_TARGET_PROPERTIES(veal PROPERTIES COMPILE_FLAGS "-fexceptions -O2 -finline-functions ${INLINE_FLAGS}") -IF(LMMS_BUILD_WIN32) - ADD_CUSTOM_COMMAND(TARGET calf POST_BUILD COMMAND "${STRIP}" "$") -ENDIF(LMMS_BUILD_WIN32) +# 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(calf PROPERTIES LINK_FLAGS "${LINK_FLAGS} -shared -Wl,-no-undefined") -ENDIF(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/COPYING b/plugins/LadspaEffect/calf/COPYING deleted file mode 100644 index 223ede7de3e..00000000000 --- a/plugins/LadspaEffect/calf/COPYING +++ /dev/null @@ -1,504 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 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. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -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 and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, 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 library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete 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 distribute a copy of this License along with the -Library. - - 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 Library or any portion -of it, thus forming a work based on the Library, 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) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -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 Library, 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 Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you 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. - - If distribution of 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 satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be 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. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library 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. - - 9. 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 Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -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 with -this License. - - 11. 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 Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library 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 Library. - -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. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library 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. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser 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 Library -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 Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -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 - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "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 -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. 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 LIBRARY 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 -LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. 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) - - This library 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 library 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 library; 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. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - diff --git a/plugins/LadspaEffect/calf/COPYING.GPL b/plugins/LadspaEffect/calf/COPYING.GPL deleted file mode 100644 index d60c31a97a5..00000000000 --- a/plugins/LadspaEffect/calf/COPYING.GPL +++ /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) - - 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) year 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. diff --git a/plugins/LadspaEffect/calf/ChangeLog b/plugins/LadspaEffect/calf/ChangeLog deleted file mode 100644 index 8d5bc92edb7..00000000000 --- a/plugins/LadspaEffect/calf/ChangeLog +++ /dev/null @@ -1,220 +0,0 @@ -Version 0.0.60.0 (unreleased) -+ Awesome new bitmap-based GUI by Markus Schmidt -+ New plugins by Markus Schmidt: - * several EQs (5, 8, 12 bands) - * new compressors (sidechain, multiband, deesser) - * new distortion plugins (based on code by Tom Szilagyi) - * amplitude modulator plugin (pulsator) -+ New experimental plugin - a simple wrapper for Fluidsynth -+ JACK host: save/load of sessions -+ Vintage Delay: fix another reinitialisation bug that caused, - noise bursts on enable/disable, add Width and LR/RL modes -+ many improvements to Monosynth: - * modulation matrix (not compatible with all plugin standards yet) - * PWM in both oscillators - * stretch (pseudo-hard-sync) for oscillator 1 - * detune scaling (depending on pitch) - * second envelope -+ envelopes now have an extra stage called 'Fade': when enabled, - it replaces Sustain with either ramp down to 0% or ramp up to 100% -+ more options in the build system (LASH use can now be disabled) -+ support for LADISH level 1 in calfjackhost (SIGUSR1-triggered Save) -+ uses more recent LV2 extensions (external UI, persist and others) -+ many bugfixes -- removed small plugins - if anyone's interested, please use the old code - in some new project - -Version 0.0.18.6 - -+ LADSPA: do not delete singletons after .so is unloaded -+ Rotary speaker: fix spelling of plugin class - -Version 0.0.18.5 - -+ Vintage Delay: clear buffer on startup and reactivation -+ GUI: fix dodgy icons -+ JACK host: fix a problem with numeric variant of -M option and the new - versions of JACK - -Version 0.0.18.4 - -+ Framework: gcc-4.4 compilation fix (Orcan Ogetbil) - -Version 0.0.18.3 - -+ Framework: do not use x86 assembler code on non-x86 platforms -+ Monosynth, Organ: fix serious audio quality issues -+ Monosynth: implement inertia for cutoff knob and pitch bend, make - pitch bend range adjustable -+ Organ: fix polyphony limit bug - -Version 0.0.18.2 - -+ Organ: fix voice stealing of released notes, sort out GUI, add quadratic - mode for amplitude envelope (enabled by default) - sounds more natural -+ Monosynth: fix the bug that caused JACK to kick the client out due - to precalculating waves in a completely wrong place, fix portamento - for off-stack notes -+ Presets: 3 new presets for Organ, 4 for Monosynth, 2 for Reverb - -Version 0.0.18.1 - -+ Filter: fixed subtle redraw bugs -+ Icons: fixed packaging-incompatible paths - -Version 0.0.18 - -+ Filterclavier: new plugin (a MIDI controlled filter) by Hans Baier -+ DSSI: added a basic implementation of live graphs. The graphs have a - limited resolution (128 data points), and are rather inefficient - (as the graph data need to be transmitted via OSC to a different - process), but it's better than nothing -+ GUI: Torben Hohn's drawing optimizations (critical for Intel graphics - cards, but should also reduce CPU usage on other hardware) -+ Phaser: added frequency response graph -+ JACK host: discontinue the broken option -p; allow giving preset names - after a colon sign (reverb:DiscoVerb instead of -p DiscoVerb reverb) -+ Reverb: less modulation; tone controls; 2 more room types -+ MultiChorus: add double bandpass filter on input -+ GUI: added frequency grid -+ Organ: added progress reporting on load (works with JACK host and LV2) -+ JACK host: use sensible port names (possibly breaking new LASH sessions) -+ Organ: added polyphony limit -+ Small plugins: added support for polymorphic port extension to allow - the same plugins to be used for control and audio signals -+ DSSI: renamed all the plugins from "plugin LADSPA" to "plugin DSSI" -+ LADSPA: more reasonable default value hints, fixed locale issue in LRDF -+ JACK host: added icons by Thorsten Wilms (thanks!) -+ Organ, Monosynth: better memory usage -+ LV2: attempt at supporting configure-like parameters (key mapping curve - in Organ) by the new String Port extension -+ AutoHell: header files are not installed anymore (they are of little - use anyway) -+ AutoHell: configure script prints if --enable-experimental was specified - -Version 0.0.17 - -+ Compressor: new plugin by Thor Harald Johansen -+ GUI: control improvements (new LED control, improved VU meter, XML - improvements, line graph with dots and grid lines - no legend yet), move - autolayout code from the plugin libraries to makerdf executable, -+ Most plugins: use custom GUI layouts instead of autogenerated ones -+ Most plugins: add dry amount (for aux bus type uses) -+ Flanger, Filter, MultiChorus: added live graphs displaying frequency - response and (in case of MultiChorus) LFO positions -+ LV2 GUI: added a way to display live graphs in Ardour and Zynjacku/LV2Rack - (only works when the plugin and the GUI are in the same process) -+ Framework: general improvements/cleanups to reduce the chance of the - kind of errors that were introduced in 0.0.16 and reduce dependencies -+ Monosynth: removed soft clipper on output - -Version 0.0.16.3 - -+ Fixed compilation without LV2 core installed - -Version 0.0.16.2 - -+ Fixed DSSI GUI for MultiChorus -+ Fixed LV2 GUI for MultiChorus -+ Make knob control mouse wheel handling work better in Ingen - -Version 0.0.16 - -+ New MultiChorus plugin (stereo multitap chorus with maximum of 8 voices) -+ Experimental set of plugins for modular synthesizers like Ingen by - Dave Robillard (enabled using --enable-experimental option in configure - script) -+ Minor improvements to other plugins (like Rotary Speaker) -+ More work on API documentation - -Version 0.0.15 - -+ Organ: new percussive section, using 2-operator FM synthesis for - monophonic or polyphonic percussive attack; added global transpose and - detune; rearrangement of controls between sections -+ Rotary Speaker: another attempt at making it useful (thanks FishB8) -+ JACK host: eliminate deadlock on exit -+ GUI: bipolar knobs now have a "dead zone" (magnet) in the middle point -+ GUI: dragging a knob with SHIFT held allows for fine adjustments -+ GUI: new controls - curve editor and keyboard -+ LV2: improved extension support (supports my "extended port properties" - extension now) -+ Added some API documentation - -Version 0.0.14 -+ OSC: totally new OSC wrapper, to allow for realtime-safe parsing (doesn't - matter as far as functionality goes, will probably be rewritten again - anyway) -+ Everything: memory management fixes (should improve stability and - compatibility) -+ Organ: improved memory usage -+ GUI: improved bipolar knobs, added endless knobs -+ Presets: separate 'built-in' and 'user' presets (so that built-in presets - can be upgraded without affecting user's own presets) -+ Monosynth: new presets - -Version 0.0.13 -+ Fixed several problems related to 64-bit environments and OpenSUSE (thanks -oc2pus!) -+ Added NOCONFIGURE environment variable support to autogen.sh - -Version 0.0.12 -+ RotarySpeaker: work in progress; enabled by default just in case it's - useful for anyone -+ Organ: reworked to add a complete subtractive synth section, a selection - of waveform (settable on a per-drawbar basis), individual settings of - phase, detune, panning, routing for each drawbar, as well as improved(?) - percussive section and vibrato/phaser section. It is usable (and sounds - good!), but some parameters, waveform set etc. may change in future. May - take up to 100 MB of RAM due to pre-calculated bandlimited waveforms. -+ Added half-complete implementation of LV2 (including GUI and events). -+ Lots of small "polishing" kind of fixes in many places (like proper - rounding of values in the GUIs, another set of hold/sostenuto fixes etc) - -Version 0.0.11 - -+ Fixed x86-64 bugs -+ JackHost: implemented LASH support -+ RotarySpeaker: fixed panning bug, implemented acceleration/decceleration - for "off" state - -Version 0.0.10 - -+ First attempt at DSSI GUI, does not support some features from JACK host, - but that's inevitable because of API limitations -+ Reverb: improvements (more parameters, fixed denormals) -+ Knob: added custom support for scroll wheel (instead of one inherited from - GtkRange) - -Version 0.0.9 - -+ started creating an XML-based GUI -+ LineGraph: new GTK+ control for displaying waveforms and filter response - graphs in Monosynth (and maybe others in future) -+ Monosynth: notch filter changes (made notch bandwidth proportional to Q, - just for fun, might be a bad idea) -+ Monosynth: more waveforms (these might be final?) -+ Monosynth: capped Sustain level to 0.999 so that decay time actually means - something with Sustain = 100% (not a great way to do it, but acceptable in - this case) -+ Monosynth: GUI refreshes less often (which means less CPU use) -+ Monosynth: less clicks on sounds using LP filter with very low cutoff - (using ramp of 256 samples instead of 64 samples as before) -+ Knob: new GTK+ control based on GtkRange, with my primitive bitmap set - (generated with Python and Cairo) -+ Organ: added a GUI too, very provisional -+ Organ: fixed Hold pedal (doesn't release the notes which are still depressed) -+ RotarySpeaker: new effect (split off Organ) -+ all: denormal fixes (still some denormals present in reverb) -+ Reverb: better time setting (decay time somewhat corresponds to -60dB - attenuation time) -+ JackHost: -M switch allows for automatic connection to JACK MIDI event source - (use -M system:midi_capture_2 or -M 2 for autoconnection to - system:midi_capture_2; of course, the short numeric form only work for - system:midi_capture_ ports) -+ JackHost: -p switch selects a preset automatically -+ JackHost: better size setting algorithm -+ JackHost: duplicate client name (causing JACK to rename the client) doesn't - break autoconnecting functionality -+ autotools configuration update (detect Cairo and require newer GTK+) -+ more presets diff --git a/plugins/LadspaEffect/calf/INSTALL b/plugins/LadspaEffect/calf/INSTALL deleted file mode 100644 index 9ac4dbad93c..00000000000 --- a/plugins/LadspaEffect/calf/INSTALL +++ /dev/null @@ -1,254 +0,0 @@ -Installation Instructions -************************* - -Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free -Software Foundation, Inc. -Copyright (C) 2007-2008 Krzysztof Foltman - -This file is free documentation; the Free Software Foundation gives -unlimited permission to copy, distribute and modify it. - -Prerequisites -============= - -To compile and install Calf, you need: - -- POSIX-compliant operating system -- G++ version 4.0 or higher (tested with 4.1.3) -- GTK+2 headers and libraries (glib 2.10, gtk+ 2.12) -- Cairo headers and libraries -- Glade 2 headers and libraries - -Optional but recommended: -- JACK header and libraries (tested with 0.109.0) -- LADSPA header -- DSSI header -- LV2 core - -Basic Installation -================== - -These are generic installation instructions. - - The `configure' shell script attempts to guess correct values for -various system-dependent variables used during compilation. It uses -those values to create a `Makefile' in each directory of the package. -It may also create one or more `.h' files containing system-dependent -definitions. Finally, it creates a shell script `config.status' that -you can run in the future to recreate the current configuration, and a -file `config.log' containing compiler output (useful mainly for -debugging `configure'). - - It can also use an optional file (typically called `config.cache' -and enabled with `--cache-file=config.cache' or simply `-C') that saves -the results of its tests to speed up reconfiguring. (Caching is -disabled by default to prevent problems with accidental use of stale -cache files.) - - If you need to do unusual things to compile the package, please try -to figure out how `configure' could check whether to do them, and mail -diffs or instructions to the address given in the `README' so they can -be considered for the next release. If you are using the cache, and at -some point `config.cache' contains results you don't want to keep, you -may remove or edit it. - - The file `configure.ac' (or `configure.in') is used to create -`configure' by a program called `autoconf'. You only need -`configure.ac' if you want to change it or regenerate `configure' using -a newer version of `autoconf'. - -The simplest way to compile this package is: - - 1. `cd' to the directory containing the package's source code and type - `./configure' to configure the package for your system. If you're - using `csh' on an old version of System V, you might need to type - `sh ./configure' instead to prevent `csh' from trying to execute - `configure' itself. - - Running `configure' takes awhile. While running, it prints some - messages telling which features it is checking for. - - 2. Type `make' to compile the package. - - 3. Optionally, type `make check' to run any self-tests that come with - the package. - - 4. Type `make install' to install the programs and any data files and - documentation. - - 5. You can remove the program binaries and object files from the - source code directory by typing `make clean'. To also remove the - files that `configure' created (so you can compile the package for - a different kind of computer), type `make distclean'. There is - also a `make maintainer-clean' target, but that is intended mainly - for the package's developers. If you use it, you may have to get - all sorts of other programs in order to regenerate files that came - with the distribution. - -Compilers and Options -===================== - -Some systems require unusual options for compilation or linking that the -`configure' script does not know about. Run `./configure --help' for -details on some of the pertinent environment variables. - - You can give `configure' initial values for configuration parameters -by setting variables in the command line or in the environment. Here -is an example: - - ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix - - *Note Defining Variables::, for more details. - -Compiling For Multiple Architectures -==================================== - -You can compile the package for more than one kind of computer at the -same time, by placing the object files for each architecture in their -own directory. To do this, you must use a version of `make' that -supports the `VPATH' variable, such as GNU `make'. `cd' to the -directory where you want the object files and executables to go and run -the `configure' script. `configure' automatically checks for the -source code in the directory that `configure' is in and in `..'. - - If you have to use a `make' that does not support the `VPATH' -variable, you have to compile the package for one architecture at a -time in the source code directory. After you have installed the -package for one architecture, use `make distclean' before reconfiguring -for another architecture. - -Installation Names -================== - -By default, `make install' installs the package's commands under -`/usr/local/bin', include files under `/usr/local/include', etc. You -can specify an installation prefix other than `/usr/local' by giving -`configure' the option `--prefix=PREFIX'. - - You can specify separate installation prefixes for -architecture-specific files and architecture-independent files. If you -pass the option `--exec-prefix=PREFIX' to `configure', the package uses -PREFIX as the prefix for installing programs and libraries. -Documentation and other data files still use the regular prefix. - - In addition, if you use an unusual directory layout you can give -options like `--bindir=DIR' to specify different values for particular -kinds of files. Run `configure --help' for a list of the directories -you can set and what kinds of files go in them. - - If the package supports it, you can cause programs to be installed -with an extra prefix or suffix on their names by giving `configure' the -option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. - -Optional Features -================= - -Some packages pay attention to `--enable-FEATURE' options to -`configure', where FEATURE indicates an optional part of the package. -They may also pay attention to `--with-PACKAGE' options, where PACKAGE -is something like `gnu-as' or `x' (for the X Window System). The -`README' should mention any `--enable-' and `--with-' options that the -package recognizes. - - For packages that use the X Window System, `configure' can usually -find the X include and library files automatically, but if it doesn't, -you can use the `configure' options `--x-includes=DIR' and -`--x-libraries=DIR' to specify their locations. - -Specifying the System Type -========================== - -There may be some features `configure' cannot figure out automatically, -but needs to determine by the type of machine the package will run on. -Usually, assuming the package is built to be run on the _same_ -architectures, `configure' can figure that out, but if it prints a -message saying it cannot guess the machine type, give it the -`--build=TYPE' option. TYPE can either be a short name for the system -type, such as `sun4', or a canonical name which has the form: - - CPU-COMPANY-SYSTEM - -where SYSTEM can have one of these forms: - - OS KERNEL-OS - - See the file `config.sub' for the possible values of each field. If -`config.sub' isn't included in this package, then this package doesn't -need to know the machine type. - - If you are _building_ compiler tools for cross-compiling, you should -use the option `--target=TYPE' to select the type of system they will -produce code for. - - If you want to _use_ a cross compiler, that generates code for a -platform different from the build platform, you should specify the -"host" platform (i.e., that on which the generated programs will -eventually be run) with `--host=TYPE'. - -Sharing Defaults -================ - -If you want to set default values for `configure' scripts to share, you -can create a site shell script called `config.site' that gives default -values for variables like `CC', `cache_file', and `prefix'. -`configure' looks for `PREFIX/share/config.site' if it exists, then -`PREFIX/etc/config.site' if it exists. Or, you can set the -`CONFIG_SITE' environment variable to the location of the site script. -A warning: not all `configure' scripts look for a site script. - -Defining Variables -================== - -Variables not defined in a site shell script can be set in the -environment passed to `configure'. However, some packages may run -configure again during the build, and the customized values of these -variables may be lost. In order to avoid this problem, you should set -them in the `configure' command line, using `VAR=value'. For example: - - ./configure CC=/usr/local2/bin/gcc - -causes the specified `gcc' to be used as the C compiler (unless it is -overridden in the site shell script). Here is a another example: - - /bin/bash ./configure CONFIG_SHELL=/bin/bash - -Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent -configuration-related scripts to be executed by `/bin/bash'. - -`configure' Invocation -====================== - -`configure' recognizes the following options to control how it operates. - -`--help' -`-h' - Print a summary of the options to `configure', and exit. - -`--version' -`-V' - Print the version of Autoconf used to generate the `configure' - script, and exit. - -`--cache-file=FILE' - Enable the cache: use and save the results of the tests in FILE, - traditionally `config.cache'. FILE defaults to `/dev/null' to - disable caching. - -`--config-cache' -`-C' - Alias for `--cache-file=config.cache'. - -`--quiet' -`--silent' -`-q' - Do not print messages saying which checks are being made. To - suppress all normal output, redirect it to `/dev/null' (any error - messages will still be shown). - -`--srcdir=DIR' - Look for the package's source code in directory DIR. Usually - `configure' can determine that directory automatically. - -`configure' also accepts some other, not widely useful, options. Run -`configure --help' for more details. - diff --git a/plugins/LadspaEffect/calf/NEWS b/plugins/LadspaEffect/calf/NEWS deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/plugins/LadspaEffect/calf/README b/plugins/LadspaEffect/calf/README deleted file mode 100644 index 4cba953e65b..00000000000 --- a/plugins/LadspaEffect/calf/README +++ /dev/null @@ -1,49 +0,0 @@ -Calf is a pack of audio plugins - effects and instruments, currently in -development. The goal is to create a set of plugins using decent algorithms -and parameter settings, available in a form which is compatible with as many -open source applications as possible. - -How to use Calf plugins: - -* LADSPA plugins - -Calf is installed as calf.so library in your LADSPA directory (typically -/usr/lib/ladspa). It means that typical LADSPA host should be able to find -Calf's plugins. - -* DSSI plugins - -Calf .so module is also installed in your DSSI plugin directory, which means -your DSSI host (like jack-dssi-host or rosegarden) should find it and -include its plugins in the plugin list. - -* JACK client application - -You can also use Calf plugins as separate applications, connecting to other -applications using JACK Audio Connection Kit (version 0.103 or newer is -required). To run the client, type: - - calfjackhost monosynth ! - -(! means "connect", last "!" means "connect to output") - -Other examples: - - calfjackhost monosynth ! vintagedelay ! flanger ! - -(runs monosynth into vintagedelay and vintagedelay into flanger, then to -output) - - calfjackhost ! reverb ! - -(takes signal from system:capture_1 and _2, puts it through reverb, and then -sends to system:playback_1 and _2) - -You can also change client name or input/output port names with command-line -options (type calfjackhost --help). Use qjackctl, patchage or jack_connect -to connect the Calf JACK client to your sound card or other applications, if -"!" is inadequate for any reason (if I didn't explain it properly, or if it -doesn't provide the connectivity options needed). - -Keep in mind this project is in the early development phase. It is usable -for certain purposes, but drop me a note if you need something. diff --git a/plugins/LadspaEffect/calf/TODO b/plugins/LadspaEffect/calf/TODO deleted file mode 100644 index 55bcfb1ca70..00000000000 --- a/plugins/LadspaEffect/calf/TODO +++ /dev/null @@ -1,40 +0,0 @@ -1. More effects - -- auto-wah (might be integrated into filter) -- envelope follower -- better reverb (more features, use nested allpasses, use 1-pole - 1-zero allpass instead of fractional delays) -- dynamics processing (Thor already did the compressor) -- distortion? -- windy rotary speakery stuff -- filter: more types - -2. Some instruments - -- some virtual analogue thing (something larger than Monosynth) -- FM (by reusing my MMX code, or something) - -3. DSP library - -- profiling framework -- optimized code (the one I have now only pretends to be optimized :) ) -- underflow handling - -4. Wrappers - -- LADSPA: proper rdf (get clearance from drobilla ;) ) -- better jack host (controls etc) -- BSE -- buzztard -- Linux VST -- LV2 - Message Context (for Organ) - EPP (the rest of them) - Mixing Controls - -5. Organization stuff (autotools etc) - -- correct compilation and installation of LADSPA plugins (current version is a hack!) -- switch to -O3 -- get to work on 64-bit architectures -- i18n (gettext or whatever) diff --git a/plugins/LadspaEffect/calf/config.h.in b/plugins/LadspaEffect/calf/config.h.in new file mode 100644 index 00000000000..a636660e583 --- /dev/null +++ b/plugins/LadspaEffect/calf/config.h.in @@ -0,0 +1,3 @@ +#define VERSION "${VERSION}" +#define PACKAGE_NAME "veal" +#define USE_LADSPA 1 diff --git a/plugins/LadspaEffect/calf/src/audio_fx.cpp b/plugins/LadspaEffect/calf/src/audio_fx.cpp deleted file mode 100644 index f42ccc0a834..00000000000 --- a/plugins/LadspaEffect/calf/src/audio_fx.cpp +++ /dev/null @@ -1,845 +0,0 @@ -/* Calf DSP Library - * Reusable audio effect classes - implementation. - * - * Copyright (C) 2001-2010 Krzysztof Foltman, Markus Schmidt, Thor Harald Johansen and others - * - * 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 02110-1301 USA - */ - -#include -#include -#include -#include -#include - -using namespace calf_plugins; -using namespace dsp; - -simple_phaser::simple_phaser(int _max_stages, float *x1vals, float *y1vals) -{ - max_stages = _max_stages; - x1 = x1vals; - y1 = y1vals; - - set_base_frq(1000); - set_mod_depth(1000); - set_fb(0); - state = 0; - cnt = 0; - stages = 0; - set_stages(_max_stages); -} - -void simple_phaser::set_stages(int _stages) -{ - if (_stages > stages) - { - assert(_stages <= max_stages); - if (_stages > max_stages) - _stages = max_stages; - for (int i = stages; i < _stages; i++) - { - x1[i] = x1[stages-1]; - y1[i] = y1[stages-1]; - } - } - stages = _stages; -} - -void simple_phaser::reset() -{ - cnt = 0; - state = 0; - phase.set(0); - for (int i = 0; i < max_stages; i++) - x1[i] = y1[i] = 0; - control_step(); -} - -void simple_phaser::control_step() -{ - cnt = 0; - int v = phase.get() + 0x40000000; - int sign = v >> 31; - v ^= sign; - // triangle wave, range from 0 to INT_MAX - double vf = (double)((v >> 16) * (1.0 / 16384.0) - 1); - - float freq = base_frq * pow(2.0, vf * mod_depth / 1200.0); - freq = dsp::clip(freq, 10.0, 0.49 * sample_rate); - stage1.set_ap_w(freq * (M_PI / 2.0) * odsr); - phase += dphase * 32; - for (int i = 0; i < stages; i++) - { - dsp::sanitize(x1[i]); - dsp::sanitize(y1[i]); - } - dsp::sanitize(state); -} - -void simple_phaser::process(float *buf_out, float *buf_in, int nsamples) -{ - for (int i=0; i cfloat; - freq *= 2.0 * M_PI / sr; - cfloat z = 1.0 / exp(cfloat(0.0, freq)); // z^-1 - - cfloat p = cfloat(1.0); - cfloat stg = stage1.h_z(z); - - for (int i = 0; i < stages; i++) - p = p * stg; - - p = p / (cfloat(1.0) - cfloat(fb) * p); - return std::abs(cfloat(gs_dry.get_last()) + cfloat(gs_wet.get_last()) * p); -} - -/////////////////////////////////////////////////////////////////////////////////// - -void biquad_filter_module::calculate_filter(float freq, float q, int mode, float gain) -{ - if (mode <= mode_36db_lp) { - order = mode + 1; - left[0].set_lp_rbj(freq, pow(q, 1.0 / order), srate, gain); - } else if ( mode_12db_hp <= mode && mode <= mode_36db_hp ) { - order = mode - mode_12db_hp + 1; - left[0].set_hp_rbj(freq, pow(q, 1.0 / order), srate, gain); - } else if ( mode_6db_bp <= mode && mode <= mode_18db_bp ) { - order = mode - mode_6db_bp + 1; - left[0].set_bp_rbj(freq, pow(q, 1.0 / order), srate, gain); - } else { // mode_6db_br <= mode <= mode_18db_br - order = mode - mode_6db_br + 1; - left[0].set_br_rbj(freq, order * 0.1 * q, srate, gain); - } - - right[0].copy_coeffs(left[0]); - for (int i = 1; i < order; i++) { - left[i].copy_coeffs(left[0]); - right[i].copy_coeffs(left[0]); - } -} - -void biquad_filter_module::filter_activate() -{ - for (int i=0; i < order; i++) { - left[i].reset(); - right[i].reset(); - } -} - -void biquad_filter_module::sanitize() -{ - for (int i=0; i < order; i++) { - left[i].sanitize(); - right[i].sanitize(); - } -} - -int biquad_filter_module::process_channel(uint16_t channel_no, const float *in, float *out, uint32_t numsamples, int inmask) { - dsp::biquad_d1 *filter; - switch (channel_no) { - case 0: - filter = left; - break; - - case 1: - filter = right; - break; - - default: - assert(false); - return 0; - } - - if (inmask) { - switch(order) { - case 1: - for (uint32_t i = 0; i < numsamples; i++) - out[i] = filter[0].process(in[i]); - break; - case 2: - for (uint32_t i = 0; i < numsamples; i++) - out[i] = filter[1].process(filter[0].process(in[i])); - break; - case 3: - for (uint32_t i = 0; i < numsamples; i++) - out[i] = filter[2].process(filter[1].process(filter[0].process(in[i]))); - break; - } - } else { - if (filter[order - 1].empty()) - return 0; - switch(order) { - case 1: - for (uint32_t i = 0; i < numsamples; i++) - out[i] = filter[0].process_zeroin(); - break; - case 2: - if (filter[0].empty()) - for (uint32_t i = 0; i < numsamples; i++) - out[i] = filter[1].process_zeroin(); - else - for (uint32_t i = 0; i < numsamples; i++) - out[i] = filter[1].process(filter[0].process_zeroin()); - break; - case 3: - if (filter[1].empty()) - for (uint32_t i = 0; i < numsamples; i++) - out[i] = filter[2].process_zeroin(); - else - for (uint32_t i = 0; i < numsamples; i++) - out[i] = filter[2].process(filter[1].process(filter[0].process_zeroin())); - break; - } - } - for (int i = 0; i < order; i++) - filter[i].sanitize(); - return filter[order - 1].empty() ? 0 : inmask; -} - -float biquad_filter_module::freq_gain(int subindex, float freq, float srate) const -{ - float level = 1.0; - for (int j = 0; j < order; j++) - level *= left[j].freq_gain(freq, srate); - return level; -} - -///////////////////////////////////////////////////////////////////////////////////////////////////////// - -void reverb::update_times() -{ - switch(type) - { - case 0: - tl[0] = 397 << 16, tr[0] = 383 << 16; - tl[1] = 457 << 16, tr[1] = 429 << 16; - tl[2] = 549 << 16, tr[2] = 631 << 16; - tl[3] = 649 << 16, tr[3] = 756 << 16; - tl[4] = 773 << 16, tr[4] = 803 << 16; - tl[5] = 877 << 16, tr[5] = 901 << 16; - break; - case 1: - tl[0] = 697 << 16, tr[0] = 783 << 16; - tl[1] = 957 << 16, tr[1] = 929 << 16; - tl[2] = 649 << 16, tr[2] = 531 << 16; - tl[3] = 1049 << 16, tr[3] = 1177 << 16; - tl[4] = 473 << 16, tr[4] = 501 << 16; - tl[5] = 587 << 16, tr[5] = 681 << 16; - break; - case 2: - default: - tl[0] = 697 << 16, tr[0] = 783 << 16; - tl[1] = 957 << 16, tr[1] = 929 << 16; - tl[2] = 649 << 16, tr[2] = 531 << 16; - tl[3] = 1249 << 16, tr[3] = 1377 << 16; - tl[4] = 1573 << 16, tr[4] = 1671 << 16; - tl[5] = 1877 << 16, tr[5] = 1781 << 16; - break; - case 3: - tl[0] = 1097 << 16, tr[0] = 1087 << 16; - tl[1] = 1057 << 16, tr[1] = 1031 << 16; - tl[2] = 1049 << 16, tr[2] = 1039 << 16; - tl[3] = 1083 << 16, tr[3] = 1055 << 16; - tl[4] = 1075 << 16, tr[4] = 1099 << 16; - tl[5] = 1003 << 16, tr[5] = 1073 << 16; - break; - case 4: - tl[0] = 197 << 16, tr[0] = 133 << 16; - tl[1] = 357 << 16, tr[1] = 229 << 16; - tl[2] = 549 << 16, tr[2] = 431 << 16; - tl[3] = 949 << 16, tr[3] = 1277 << 16; - tl[4] = 1173 << 16, tr[4] = 1671 << 16; - tl[5] = 1477 << 16, tr[5] = 1881 << 16; - break; - case 5: - tl[0] = 197 << 16, tr[0] = 133 << 16; - tl[1] = 257 << 16, tr[1] = 179 << 16; - tl[2] = 549 << 16, tr[2] = 431 << 16; - tl[3] = 619 << 16, tr[3] = 497 << 16; - tl[4] = 1173 << 16, tr[4] = 1371 << 16; - tl[5] = 1577 << 16, tr[5] = 1881 << 16; - break; - } - - float fDec=1000 + 2400.f * diffusion; - for (int i = 0 ; i < 6; i++) { - ldec[i]=exp(-float(tl[i] >> 16) / fDec), - rdec[i]=exp(-float(tr[i] >> 16) / fDec); - } -} - -void reverb::reset() -{ - apL1.reset();apR1.reset(); - apL2.reset();apR2.reset(); - apL3.reset();apR3.reset(); - apL4.reset();apR4.reset(); - apL5.reset();apR5.reset(); - apL6.reset();apR6.reset(); - lp_left.reset();lp_right.reset(); - old_left = 0; old_right = 0; -} - -void reverb::process(float &left, float &right) -{ - unsigned int ipart = phase.ipart(); - - // the interpolated LFO might be an overkill here - int lfo = phase.lerp_by_fract_int(sine.data[ipart], sine.data[ipart+1]) >> 2; - phase += dphase; - - left += old_right; - left = apL1.process_allpass_comb_lerp16(left, tl[0] - 45*lfo, ldec[0]); - left = apL2.process_allpass_comb_lerp16(left, tl[1] + 47*lfo, ldec[1]); - float out_left = left; - left = apL3.process_allpass_comb_lerp16(left, tl[2] + 54*lfo, ldec[2]); - left = apL4.process_allpass_comb_lerp16(left, tl[3] - 69*lfo, ldec[3]); - left = apL5.process_allpass_comb_lerp16(left, tl[4] + 69*lfo, ldec[4]); - left = apL6.process_allpass_comb_lerp16(left, tl[5] - 46*lfo, ldec[5]); - old_left = lp_left.process(left * fb); - sanitize(old_left); - - right += old_left; - right = apR1.process_allpass_comb_lerp16(right, tr[0] - 45*lfo, rdec[0]); - right = apR2.process_allpass_comb_lerp16(right, tr[1] + 47*lfo, rdec[1]); - float out_right = right; - right = apR3.process_allpass_comb_lerp16(right, tr[2] + 54*lfo, rdec[2]); - right = apR4.process_allpass_comb_lerp16(right, tr[3] - 69*lfo, rdec[3]); - right = apR5.process_allpass_comb_lerp16(right, tr[4] + 69*lfo, rdec[4]); - right = apR6.process_allpass_comb_lerp16(right, tr[5] - 46*lfo, rdec[5]); - old_right = lp_right.process(right * fb); - sanitize(old_right); - - left = out_left, right = out_right; -} - -/// Distortion Module by Tom Szilagyi -/// -/// This module provides a blendable saturation stage -/////////////////////////////////////////////////////////////////////////////////////////////// - -tap_distortion::tap_distortion() -{ - is_active = false; - srate = 0; - meter = 0.f; - prev_med = prev_out = 0.f; - drive_old = blend_old = -1.f; -} - -void tap_distortion::activate() -{ - is_active = true; - set_params(0.f, 0.f); -} -void tap_distortion::deactivate() -{ - is_active = false; -} - -void tap_distortion::set_params(float blend, float drive) -{ - // set distortion coeffs - if ((drive_old != drive) || (blend_old != blend)) { - rdrive = 12.0f / drive; - rbdr = rdrive / (10.5f - blend) * 780.0f / 33.0f; - kpa = D(2.0f * (rdrive*rdrive) - 1.0f) + 1.0f; - kpb = (2.0f - kpa) / 2.0f; - ap = ((rdrive*rdrive) - kpa + 1.0f) / 2.0f; - kc = kpa / D(2.0f * D(2.0f * (rdrive*rdrive) - 1.0f) - 2.0f * rdrive*rdrive); - - srct = (0.1f * srate) / (0.1f * srate + 1.0f); - sq = kc*kc + 1.0f; - knb = -1.0f * rbdr / D(sq); - kna = 2.0f * kc * rbdr / D(sq); - an = rbdr*rbdr / sq; - imr = 2.0f * knb + D(2.0f * kna + 4.0f * an - 1.0f); - pwrq = 2.0f / (imr + 1.0f); - - drive_old = drive; - blend_old = blend; - } -} - -void tap_distortion::set_sample_rate(uint32_t sr) -{ - srate = sr; -} - -float tap_distortion::process(float in) -{ - meter = 0.f; - float out = 0.f; - float proc = in; - float med; - if (proc >= 0.0f) { - med = (D(ap + proc * (kpa - proc)) + kpb) * pwrq; - } else { - med = (D(an - proc * (kna + proc)) + knb) * pwrq * -1.0f; - } - proc = srct * (med - prev_med + prev_out); - prev_med = M(med); - prev_out = M(proc); - out = proc; - meter = proc; - return out; -} - -float tap_distortion::get_distortion_level() -{ - return meter; -} - -//////////////////////////////////////////////////////////////////////////////// - -simple_lfo::simple_lfo() -{ - is_active = false; - phase = 0.f; -} - -void simple_lfo::activate() -{ - is_active = true; - phase = 0.f; -} - -void simple_lfo::deactivate() -{ - is_active = false; -} - -float simple_lfo::get_value() -{ - return get_value_from_phase(phase, offset) * amount; -} - -float simple_lfo::get_value_from_phase(float ph, float off) const -{ - float val = 0.f; - float phs = ph + off; - if (phs >= 1.0) - phs = fmod(phs, 1.f); - switch (mode) { - default: - case 0: - // sine - val = sin((phs * 360.f) * M_PI / 180); - break; - case 1: - // triangle - if(phs > 0.75) - val = (phs - 0.75) * 4 - 1; - else if(phs > 0.5) - val = (phs - 0.5) * 4 * -1; - else if(phs > 0.25) - val = 1 - (phs - 0.25) * 4; - else - val = phs * 4; - break; - case 2: - // square - val = (phs < 0.5) ? -1 : +1; - break; - case 3: - // saw up - val = phs * 2.f - 1; - break; - case 4: - // saw down - val = 1 - phs * 2.f; - break; - } - return val; -} - -void simple_lfo::advance(uint32_t count) -{ - //this function walks from 0.f to 1.f and starts all over again - phase += count * freq * (1.0 / srate); - if (phase >= 1.0) - phase = fmod(phase, 1.f); -} - -void simple_lfo::set_phase(float ph) -{ - //set the phase from outsinde - phase = fabs(ph); - if (phase >= 1.0) - phase = fmod(phase, 1.f); -} - -void simple_lfo::set_params(float f, int m, float o, uint32_t sr, float a) -{ - // freq: a value in Hz - // mode: sine=0, triangle=1, square=2, saw_up=3, saw_down=4 - // offset: value between 0.f and 1.f to offset the lfo in time - freq = f; - mode = m; - offset = o; - srate = sr; - amount = a; -} - -bool simple_lfo::get_graph(float *data, int points, cairo_iface *context) const -{ - if (!is_active) - return false; - for (int i = 0; i < points; i++) { - float ph = (float)i / (float)points; - data[i] = get_value_from_phase(ph, offset) * amount; - } - return true; -} - -bool simple_lfo::get_dot(float &x, float &y, int &size, cairo_iface *context) const -{ - if (!is_active) - return false; - float phs = phase + offset; - if (phs >= 1.0) - phs = fmod(phs, 1.f); - x = phase; - y = get_value_from_phase(phase, offset) * amount; - return true; -} - - -/// Lookahead Limiter by Christian Holschuh and Markus Schmidt - -lookahead_limiter::lookahead_limiter() { - is_active = false; - channels = 2; - id = 0; - buffer_size = 0; - overall_buffer_size = 0; - att = 1.f; - att_max = 1.0; - pos = 0; - delta = 0.f; - _delta = 0.f; - peak = 0.f; - over_s = 0; - over_c = 1.f; - attack = 0.005; - use_multi = false; - weight = 1.f; - _sanitize = false; - auto_release = false; - asc_active = false; - nextiter = 0; - nextlen = 0; - asc = 0.f; - asc_c = 0; - asc_pos = -1; - asc_changed = false; - asc_coeff = 1.f; -} - -lookahead_limiter::~lookahead_limiter() -{ - if( buffer != NULL) - { - free(buffer); - } - if( nextpos != NULL) - { - free(nextpos); - } - if( nextdelta != NULL) - { - free(nextdelta); - } -} - -void lookahead_limiter::activate() -{ - is_active = true; - pos = 0; - -} - -void lookahead_limiter::set_multi(bool set) { use_multi = set; } - -void lookahead_limiter::deactivate() -{ - is_active = false; -} - -float lookahead_limiter::get_attenuation() -{ - float a = att_max; - att_max = 1.0; - return a; -} - -void lookahead_limiter::set_sample_rate(uint32_t sr) -{ - srate = sr; - // rebuild buffer - overall_buffer_size = (int)(srate * (100.f / 1000.f) * channels) + channels; // buffer size attack rate multiplied by 2 channels - buffer = (float*) calloc(overall_buffer_size, sizeof(float)); - memset(buffer, 0, overall_buffer_size * sizeof(float)); // reset buffer to zero - pos = 0; - - nextpos = (int*) calloc(overall_buffer_size, sizeof(int)); - nextdelta = (float*) calloc(overall_buffer_size, sizeof(float)); - memset(nextpos, -1, overall_buffer_size * sizeof(int)); -} - -void lookahead_limiter::set_params(float l, float a, float r, float w, bool ar, float arc, bool d) -{ - limit = l; - attack = a / 1000.f; - release = r / 1000.f; - auto_release = ar; - asc_coeff = arc; - debug = d; - weight = w; -} - -void lookahead_limiter::reset() { - int bs = (int)(srate * attack * channels); - buffer_size = bs - bs % channels; // buffer size attack rate - _sanitize = true; - pos = 0; - nextpos[0] = -1; - nextlen = 0; - nextiter = 0; - delta = 0.f; - att = 1.f; - reset_asc(); -} - -void lookahead_limiter::reset_asc() { - asc = 0.f; - asc_c = 0; - asc_pos = pos; - asc_changed = true; -} - -void lookahead_limiter::process(float &left, float &right, float * multi_buffer) -{ - // PROTIP: harming paying customers enough to make them develop a competing - // product may be considered an example of a less than sound business practice. - - // fill lookahead buffer - if(_sanitize) { - // if we're sanitizing (zeroing) the buffer on attack time change, - // don't write the samples to the buffer - buffer[pos] = 0.f; - buffer[pos + 1] = 0.f; - } else { - buffer[pos] = left; - buffer[pos + 1] = right; - } - - // are we using multiband? get the multiband coefficient or use 1.f - float multi_coeff = (use_multi) ? multi_buffer[pos] : 1.f; - - // input peak - impact higher in left or right channel? - peak = fabs(left) > fabs(right) ? fabs(left) : fabs(right); - - // calc the real limit including weight and multi coeff - float _limit = limit * multi_coeff * weight; - - // add an eventually appearing peak to the asc fake buffer if asc active - if(auto_release and peak > _limit) { - asc += peak; - asc_c ++; - } - - if(peak > _limit or multi_coeff < 1.0) { - float _multi_coeff = 1.f; - float _peak; - - // calc the attenuation needed to reduce incoming peak - float _att = std::min(_limit / peak, 1.f); - - - // calc a release delta from this attenuation - float _rdelta = (1.0 - _att) / (srate * release); - if(auto_release and asc_c > 0) { - // check if releasing to average level of peaks is steeper than - // releasing to 1.f - float _delta = std::max((limit * weight) / (asc_coeff * asc) * (float)asc_c - _att, 0.000001f) / (srate * release); - if(_delta < _rdelta) { - asc_active = true; - _rdelta = _delta; - } - } - - // calc the delta for walking to incoming peak attenuation - float _delta = (_limit / peak - att) / buffer_size * channels; - - if(_delta < delta) { - // is the delta more important than the actual one? - // if so, we can forget about all stored deltas (because they can't - // be more important - we already checked that earlier) and use this - // delta now. and we have to create a release delta in nextpos buffer - nextpos[0] = pos; - nextpos[1] = -1; - nextdelta[0] = _rdelta; - nextlen = 1; - nextiter = 0; - delta = _delta; - } else { - // we have a peak on input its delta is less important than the - // actual delta. But what about the stored deltas we're following? - bool _found = false; - int i = 0; - for(i = nextiter; i < nextiter + nextlen; i++) { - // walk through our nextpos buffer - int j = i % buffer_size; - // calculate a delta for the next stored peak - // are we using multiband? then get the multi_coeff for the - // stored position - _multi_coeff = (use_multi) ? multi_buffer[nextpos[j]] : 1.f; - // is the left or the right channel on this position more - // important? - _peak = fabs(buffer[nextpos[j]]) > fabs(buffer[nextpos[j] + 1]) ? fabs(buffer[nextpos[j]]) : fabs(buffer[nextpos[j] + 1]); - // calc a delta to use to reach our incoming peak from the - // stored position - _delta = (_limit / peak - (limit * _multi_coeff * weight) / _peak) / (((buffer_size - nextpos[j] + pos) % buffer_size) / channels); - if(_delta < nextdelta[j]) { - // if the buffered delta is more important than the delta - // used to reach our peak from the stored position, store - // the new delta at that position and stop the loop - nextdelta[j] = _delta; - _found = true; - break; - } - } - if(_found) { - // there was something more important in the next-buffer. - // throw away any position and delta after the important - // position and add a new release delta - nextlen = i - nextiter + 1; - nextpos[(nextiter + nextlen) % buffer_size] = pos; - nextdelta[(nextiter + nextlen) % buffer_size] = _rdelta; - // set the next following position value to -1 (cleaning up the - // nextpos buffer) - nextpos[(nextiter + nextlen + 1) % buffer_size] = -1; - // and raise the length of our nextpos buffer for keeping the - // release value - nextlen ++; - } - } - } - - // switch left and right pointers in buffer to output position - left = buffer[(pos + channels) % buffer_size]; - right = buffer[(pos + channels + 1) % buffer_size]; - - // if a peak leaves the buffer, remove it from asc fake buffer - // but only if we're not sanitizing asc buffer - float _peak = fabs(left) > fabs(right) ? fabs(left) : fabs(right); - float _multi_coeff = (use_multi) ? multi_buffer[(pos + channels) % buffer_size] : 1.f; - if(pos == asc_pos and !asc_changed) { - asc_pos = -1; - } - if(auto_release and asc_pos == -1 and _peak > (limit * weight * _multi_coeff)) { - asc -= _peak; - asc_c --; - } - - // change the attenuation level - att += delta; - - // ...and calculate outpout from it - left *= att; - right *= att; - - if((pos + channels) % buffer_size == nextpos[nextiter]) { - // if we reach a buffered position, change the actual delta and erase - // this (the first) element from nextpos and nextdelta buffer - delta = nextdelta[nextiter]; - nextlen = (nextlen - 1) % buffer_size; - nextpos[nextiter] = -1; - nextiter = (nextiter + 1) % buffer_size; - } - - if (att > 1.0f) { - // release time seems over, reset attenuation and delta - att = 1.0f; - delta = 0.0f; - } - - // main limiting party is over, let's cleanup the puke - - if(_sanitize) { - // we're sanitizing? then send 0.f as output - left = 0.f; - right = 0.f; - } - - // security personnel pawing your values - if(att <= 0.f) { - // if this happens we're doomed!! - // may happen on manually lowering attack - att = 0.0000000000001; - delta = (1.0f - att) / (srate * release); - } - - if(att != 1.f and 1 - att < 0.0000000000001) { - // denormalize att - att = 1.f; - } - - if(delta != 0.f and fabs(delta) < 0.00000000000001) { - // denormalize delta - delta = 0.f; - } - - // post treatment (denormal, limit) - denormal(&left); - denormal(&right); - - // store max attenuation for meter output - att_max = (att < att_max) ? att : att_max; - - // step forward in our sample ring buffer - pos = (pos + channels) % buffer_size; - - // sanitizing is always done after a full cycle through the lookahead buffer - if(_sanitize and pos == 0) _sanitize = false; - - asc_changed = false; -} - -bool lookahead_limiter::get_asc() { - if(!asc_active) return false; - asc_active = false; - return true; -} diff --git a/plugins/LadspaEffect/calf/src/calf/audio_fx.h b/plugins/LadspaEffect/calf/src/calf/audio_fx.h deleted file mode 100644 index 1799de944ad..00000000000 --- a/plugins/LadspaEffect/calf/src/calf/audio_fx.h +++ /dev/null @@ -1,626 +0,0 @@ -/* Calf DSP Library - * Reusable audio effect classes. - * - * Copyright (C) 2001-2010 Krzysztof Foltman, Markus Schmidt, Thor Harald Johansen and others - * - * 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 02110-1301 USA - */ -#ifndef CALF_AUDIOFX_H -#define CALF_AUDIOFX_H - -#include "biquad.h" -#include "delay.h" -#include "fixed_point.h" -#include "inertia.h" -#include "onepole.h" -#include - -namespace calf_plugins { - struct cairo_iface; -}; - -namespace dsp { -#if 0 -}; to keep editor happy -#endif - -/** - * Audio effect base class. Not really useful until it gets more developed. - */ -class audio_effect -{ -public: - virtual void setup(int sample_rate)=0; - virtual ~audio_effect() {} -}; - -class modulation_effect: public audio_effect -{ -protected: - int sample_rate; - float rate, wet, dry, odsr; - gain_smoothing gs_wet, gs_dry; -public: - fixed_point phase, dphase; - float get_rate() const { - return rate; - } - void set_rate(float rate) { - this->rate = rate; - dphase = rate/sample_rate*4096; - } - float get_wet() const { - return wet; - } - void set_wet(float wet) { - this->wet = wet; - gs_wet.set_inertia(wet); - } - float get_dry() const { - return dry; - } - void set_dry(float dry) { - this->dry = dry; - gs_dry.set_inertia(dry); - } - void reset_phase(float req_phase) - { - phase = req_phase * 4096.0; - } - void inc_phase(float req_phase) - { - phase += fixed_point(req_phase * 4096.0); - } - void setup(int sample_rate) - { - this->sample_rate = sample_rate; - this->odsr = 1.0 / sample_rate; - phase = 0; - set_rate(get_rate()); - } -}; - -/** - * A monophonic phaser. If you want stereo, combine two :) - * Also, gave up on using template args for signal type. - */ -class simple_phaser: public modulation_effect -{ -protected: - float base_frq, mod_depth, fb; - float state; - int cnt, stages, max_stages; - dsp::onepole stage1; - float *x1, *y1; -public: - simple_phaser(int _max_stages, float *x1vals, float *y1vals); - - float get_base_frq() const { - return base_frq; - } - void set_base_frq(float _base_frq) { - base_frq = _base_frq; - } - int get_stages() const { - return stages; - } - void set_stages(int _stages); - - float get_mod_depth() const { - return mod_depth; - } - void set_mod_depth(float _mod_depth) { - mod_depth = _mod_depth; - } - - float get_fb() const { - return fb; - } - void set_fb(float fb) { - this->fb = fb; - } - - virtual void setup(int sample_rate) { - modulation_effect::setup(sample_rate); - reset(); - } - void reset(); - void control_step(); - void process(float *buf_out, float *buf_in, int nsamples); - float freq_gain(float freq, float sr) const; -}; - -/** - * Base class for chorus and flanger. Wouldn't be needed if it wasn't - * for odd behaviour of GCC when deriving templates from template - * base classes (not seeing fields from base classes!). - */ -class chorus_base: public modulation_effect -{ -protected: - int min_delay_samples, mod_depth_samples; - float min_delay, mod_depth; - sine_table sine; -public: - float get_min_delay() const { - return min_delay; - } - void set_min_delay(float min_delay) { - this->min_delay = min_delay; - this->min_delay_samples = (int)(min_delay * 65536.0 * sample_rate); - } - float get_mod_depth() const { - return mod_depth; - } - void set_mod_depth(float mod_depth) { - this->mod_depth = mod_depth; - // 128 because it's then multiplied by (hopefully) a value of 32768..-32767 - this->mod_depth_samples = (int)(mod_depth * 32.0 * sample_rate); - } -}; - -/** - * Single-tap chorus without feedback. - * Perhaps MaxDelay should be a bit longer! - */ -template -class simple_chorus: public chorus_base -{ -protected: - simple_delay delay; -public: - simple_chorus() { - rate = 0.63f; - dry = 0.5f; - wet = 0.5f; - min_delay = 0.005f; - mod_depth = 0.0025f; - setup(44100); - } - void reset() { - delay.reset(); - } - virtual void setup(int sample_rate) { - modulation_effect::setup(sample_rate); - delay.reset(); - set_min_delay(get_min_delay()); - set_mod_depth(get_mod_depth()); - } - template - void process(OutIter buf_out, InIter buf_in, int nsamples) { - int mds = min_delay_samples + mod_depth_samples * 1024 + 2*65536; - int mdepth = mod_depth_samples; - for (int i=0; i(sine.data[ipart], sine.data[ipart+1]); - int v = mds + (mdepth * lfo >> 6); - // if (!(i & 7)) printf("%d\n", v); - int ifv = v >> 16; - delay.put(in); - T fd; // signal from delay's output - delay.get_interp(fd, ifv, (v & 0xFFFF)*(1.0/65536.0)); - T sdry = in * gs_dry.get(); - T swet = fd * gs_wet.get(); - *buf_out++ = sdry + swet; - } - } -}; - -/** - * Single-tap flanger (chorus plus feedback). - */ -template -class simple_flanger: public chorus_base -{ -protected: - simple_delay delay; - float fb; - int last_delay_pos, last_actual_delay_pos; - int ramp_pos, ramp_delay_pos; -public: - simple_flanger() - : fb(0) {} - void reset() { - delay.reset(); - last_delay_pos = last_actual_delay_pos = ramp_delay_pos = 0; - ramp_pos = 1024; - } - virtual void setup(int sample_rate) { - this->sample_rate = sample_rate; - this->odsr = 1.0 / sample_rate; - delay.reset(); - phase = 0; - set_rate(get_rate()); - set_min_delay(get_min_delay()); - } - float get_fb() const { - return fb; - } - void set_fb(float fb) { - this->fb = fb; - } - template - void process(OutIter buf_out, InIter buf_in, int nsamples) { - if (!nsamples) - return; - int mds = this->min_delay_samples + this->mod_depth_samples * 1024 + 2 * 65536; - int mdepth = this->mod_depth_samples; - int delay_pos; - unsigned int ipart = this->phase.ipart(); - int lfo = phase.lerp_by_fract_int(this->sine.data[ipart], this->sine.data[ipart+1]); - delay_pos = mds + (mdepth * lfo >> 6); - - if (delay_pos != last_delay_pos || ramp_pos < 1024) - { - if (delay_pos != last_delay_pos) { - // we need to ramp from what the delay tap length actually was, - // not from old (ramp_delay_pos) or desired (delay_pos) tap length - ramp_delay_pos = last_actual_delay_pos; - ramp_pos = 0; - } - - int64_t dp = 0; - for (int i=0; i> 10; - ramp_pos++; - if (ramp_pos > 1024) ramp_pos = 1024; - this->delay.get_interp(fd, dp >> 16, (dp & 0xFFFF)*(1.0/65536.0)); - sanitize(fd); - T sdry = in * this->dry; - T swet = fd * this->wet; - *buf_out++ = sdry + swet; - this->delay.put(in+fb*fd); - - this->phase += this->dphase; - ipart = this->phase.ipart(); - lfo = phase.lerp_by_fract_int(this->sine.data[ipart], this->sine.data[ipart+1]); - delay_pos = mds + (mdepth * lfo >> 6); - } - last_actual_delay_pos = dp; - } - else { - for (int i=0; idelay.get_interp(fd, delay_pos >> 16, (delay_pos & 0xFFFF)*(1.0/65536.0)); - sanitize(fd); - T sdry = in * this->gs_dry.get(); - T swet = fd * this->gs_wet.get(); - *buf_out++ = sdry + swet; - this->delay.put(in+fb*fd); - - this->phase += this->dphase; - ipart = this->phase.ipart(); - lfo = phase.lerp_by_fract_int(this->sine.data[ipart], this->sine.data[ipart+1]); - delay_pos = mds + (mdepth * lfo >> 6); - } - last_actual_delay_pos = delay_pos; - } - last_delay_pos = delay_pos; - } - float freq_gain(float freq, float sr) const - { - typedef std::complex cfloat; - freq *= 2.0 * M_PI / sr; - cfloat z = 1.0 / exp(cfloat(0.0, freq)); // z^-1 - - float ldp = last_delay_pos / 65536.0; - float fldp = floor(ldp); - cfloat zn = std::pow(z, fldp); // z^-N - cfloat zn1 = zn * z; // z^-(N+1) - // simulate a lerped comb filter - H(z) = 1 / (1 + fb * (lerp(z^-N, z^-(N+1), fracpos))), N = int(pos), fracpos = pos - int(pos) - cfloat delayed = zn + (zn1 - zn) * cfloat(ldp - fldp); - cfloat h = cfloat(delayed) / (cfloat(1.0) - cfloat(fb) * delayed); - // mix with dry signal - float v = std::abs(cfloat(gs_dry.get_last()) + cfloat(gs_wet.get_last()) * h); - return v; - } -}; - -/** - * A classic allpass loop reverb with modulated allpass filter. - * Just started implementing it, so there is no control over many - * parameters. - */ -class reverb: public audio_effect -{ - simple_delay<2048, float> apL1, apL2, apL3, apL4, apL5, apL6; - simple_delay<2048, float> apR1, apR2, apR3, apR4, apR5, apR6; - fixed_point phase, dphase; - sine_table sine; - onepole lp_left, lp_right; - float old_left, old_right; - int type; - float time, fb, cutoff, diffusion; - int tl[6], tr[6]; - float ldec[6], rdec[6]; - - int sr; -public: - reverb() - { - phase = 0.0; - time = 1.0; - cutoff = 9000; - type = 2; - diffusion = 1.f; - setup(44100); - } - virtual void setup(int sample_rate) { - sr = sample_rate; - set_time(time); - set_cutoff(cutoff); - phase = 0.0; - dphase = 0.5*128/sr; - update_times(); - } - void update_times(); - float get_time() const { - return time; - } - void set_time(float time) { - this->time = time; - // fb = pow(1.0f/4096.0f, (float)(1700/(time*sr))); - fb = 1.0 - 0.3 / (time * sr / 44100.0); - } - float get_type() const { - return type; - } - void set_type(int type) { - this->type = type; - update_times(); - } - float get_diffusion() const { - return diffusion; - } - void set_diffusion(float diffusion) { - this->diffusion = diffusion; - update_times(); - } - void set_type_and_diffusion(int type, float diffusion) { - this->type = type; - this->diffusion = diffusion; - update_times(); - } - float get_fb() const - { - return this->fb; - } - void set_fb(float fb) - { - this->fb = fb; - } - float get_cutoff() const { - return cutoff; - } - void set_cutoff(float cutoff) { - this->cutoff = cutoff; - lp_left.set_lp(cutoff,sr); - lp_right.set_lp(cutoff,sr); - } - void reset(); - void process(float &left, float &right); - void extra_sanitize() - { - lp_left.sanitize(); - lp_right.sanitize(); - } -}; - -class filter_module_iface -{ -public: - virtual void calculate_filter(float freq, float q, int mode, float gain = 1.0) = 0; - virtual void filter_activate() = 0; - virtual void sanitize() = 0; - virtual int process_channel(uint16_t channel_no, const float *in, float *out, uint32_t numsamples, int inmask) = 0; - virtual float freq_gain(int subindex, float freq, float srate) const = 0; - - virtual ~filter_module_iface() {} -}; - - -class biquad_filter_module: public filter_module_iface -{ -private: - dsp::biquad_d1 left[3], right[3]; - int order; - -public: - uint32_t srate; - - enum { mode_12db_lp = 0, mode_24db_lp = 1, mode_36db_lp = 2, - mode_12db_hp = 3, mode_24db_hp = 4, mode_36db_hp = 5, - mode_6db_bp = 6, mode_12db_bp = 7, mode_18db_bp = 8, - mode_6db_br = 9, mode_12db_br = 10, mode_18db_br = 11, - mode_count - }; - -public: - biquad_filter_module() - : order(0) {} - /// Calculate filter coefficients based on parameters - cutoff/center frequency, q, filter type, output gain - void calculate_filter(float freq, float q, int mode, float gain = 1.0); - /// Reset filter state - void filter_activate(); - /// Remove denormals - void sanitize(); - /// Process a single channel (float buffer) of data - int process_channel(uint16_t channel_no, const float *in, float *out, uint32_t numsamples, int inmask); - /// Determine gain (|H(z)|) for a given frequency - float freq_gain(int subindex, float freq, float srate) const; -}; - -class two_band_eq -{ -private: - dsp::onepole lowcut, highcut; - float low_gain, high_gain; - -public: - void reset() - { - lowcut.reset(); - highcut.reset(); - } - - inline float process(float v) - { - v = dsp::lerp(lowcut.process_hp(v), v, low_gain); - v = dsp::lerp(highcut.process_lp(v), v, high_gain); - return v; - } - - inline void copy_coeffs(const two_band_eq &src) - { - lowcut.copy_coeffs(src.lowcut); - highcut.copy_coeffs(src.highcut); - low_gain = src.low_gain; - high_gain = src.high_gain; - } - - void sanitize() - { - lowcut.sanitize(); - highcut.sanitize(); - } - - void set(float _low_freq, float _low_gain, float _high_freq, float _high_gain, float sr) - { - lowcut.set_hp(_low_freq, sr); - highcut.set_lp(_high_freq, sr); - low_gain = _low_gain; - high_gain = _high_gain; - } -}; - -/// Tom Szilagyi's distortion code, used with permission -/// KF: I'm not 100% sure how this is supposed to work, but it does. -/// I'm planning to rewrite it using more modular approach when I have more time. -class tap_distortion { -private: - float blend_old, drive_old; - float meter; - float rdrive, rbdr, kpa, kpb, kna, knb, ap, an, imr, kc, srct, sq, pwrq; - float prev_med, prev_out; -public: - uint32_t srate; - bool is_active; - tap_distortion(); - void activate(); - void deactivate(); - void set_params(float blend, float drive); - void set_sample_rate(uint32_t sr); - float process(float in); - float get_distortion_level(); - static inline float M(float x) - { - return (fabs(x) > 0.000000001f) ? x : 0.0f; - } - - static inline float D(float x) - { - x = fabs(x); - return (x > 0.000000001f) ? sqrtf(x) : 0.0f; - } -}; - -/// LFO module by Markus -/// This module provides simple LFO's (sine=0, triangle=1, square=2, saw_up=3, saw_down=4) -/// get_value() returns a value between -1 and 1 -class simple_lfo { -private: - float phase, freq, offset, amount; - int mode; - uint32_t srate; - bool is_active; -public: - simple_lfo(); - void set_params(float f, int m, float o, uint32_t sr, float amount = 1.f); - float get_value(); - void advance(uint32_t count); - void set_phase(float ph); - void activate(); - void deactivate(); - float get_value_from_phase(float ph, float off) const; - bool get_graph(float *data, int points, calf_plugins::cairo_iface *context) const; - bool get_dot(float &x, float &y, int &size, calf_plugins::cairo_iface *context) const; -}; - - -/// Lookahead Limiter by Markus Schmidt and Christian Holschuh -class lookahead_limiter { -private: -public: - float limit, attack, release, weight; - uint32_t srate; - float att; // a coefficient the output is multiplied with - float att_max; // a memory for the highest attenuation - used for display - int pos; // where we are actually in our sample buffer - int buffer_size; - int overall_buffer_size; - bool is_active; - bool debug; - bool auto_release; - bool asc_active; - float *buffer; - int channels; - float delta; - float _delta; - float peak; - unsigned int over_s; - float over_c; - bool use_multi; - unsigned int id; - bool _sanitize; - int nextiter; - int nextlen; - int * nextpos; - float * nextdelta; - int asc_c; - float asc; - int asc_pos; - bool asc_changed; - float asc_coeff; - static inline void denormal(volatile float *f) { - *f += 1e-18; - *f -= 1e-18; - } - void reset(); - void reset_asc(); - bool get_asc(); - lookahead_limiter(); - ~lookahead_limiter(); - void set_multi(bool set); - void process(float &left, float &right, float *multi_buffer); - void set_sample_rate(uint32_t sr); - void set_params(float l, float a, float r, float weight = 1.f, bool ar = false, float arc = 1.f, bool d = false); - float get_attenuation(); - void activate(); - void deactivate(); -}; - -#if 0 -{ to keep editor happy -#endif -} - -#endif diff --git a/plugins/LadspaEffect/calf/src/calf/biquad.h b/plugins/LadspaEffect/calf/src/calf/biquad.h deleted file mode 100644 index a6d5a959ca5..00000000000 --- a/plugins/LadspaEffect/calf/src/calf/biquad.h +++ /dev/null @@ -1,653 +0,0 @@ -/* Calf DSP Library - * Biquad filters - * Copyright (C) 2001-2007 Krzysztof Foltman - * - * Most of code in this file is based on freely - * available other work of other people (filter equations). - * - * 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 02110-1301 USA - */ -#ifndef __CALF_BIQUAD_H -#define __CALF_BIQUAD_H - -#include -#include "primitives.h" - -namespace dsp { - -/** - * Coefficients for two-pole two-zero filter, for floating point values, - * plus a bunch of functions to set them to typical values. - * - * Coefficient calculation is based on famous Robert Bristow-Johnson's equations, - * except where it's not. - * The coefficient calculation is NOT mine, the only exception is the lossy - * optimization in Zoelzer and rbj HP filter code. - * - * See http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt for reference. - * - * don't use this for integers because it won't work - */ -template -class biquad_coeffs -{ -public: - // filter coefficients - Coeff a0, a1, a2, b1, b2; - typedef std::complex cfloat; - - biquad_coeffs() - { - set_null(); - } - - inline void set_null() - { - a0 = 1.0; - b1 = b2 = a1 = a2 = 0.f; - } - - /** Lowpass filter based on Robert Bristow-Johnson's equations - * Perhaps every synth code that doesn't use SVF uses these - * equations :) - * @param fc resonant frequency - * @param q resonance (gain at fc) - * @param sr sample rate - * @param gain amplification (gain at 0Hz) - */ - inline void set_lp_rbj(float fc, float q, float sr, float gain = 1.0) - { - float omega=(float)(2*M_PI*fc/sr); - float sn=sin(omega); - float cs=cos(omega); - float alpha=(float)(sn/(2*q)); - float inv=(float)(1.0/(1.0+alpha)); - - a2 = a0 = (float)(gain*inv*(1 - cs)*0.5f); - a1 = a0 + a0; - b1 = (float)(-2*cs*inv); - b2 = (float)((1 - alpha)*inv); - } - - // different lowpass filter, based on Zoelzer's equations, modified by - // me (kfoltman) to use polynomials to approximate tangent function - // not very accurate, but perhaps good enough for synth work :) - // odsr is "one divided by samplerate" - // from how it looks, it perhaps uses bilinear transform - but who knows :) - inline void set_lp_zoelzer(float fc, float q, float odsr, float gain=1.0) - { - Coeff omega=(Coeff)(M_PI*fc*odsr); - Coeff omega2=omega*omega; - Coeff K=omega*(1+omega2*omega2*Coeff(1.0/1.45)); - Coeff KK=K*K; - Coeff QK=q*(KK+1.f); - Coeff iQK=1.0f/(QK+K); - Coeff inv=q*iQK; - b2 = (Coeff)(iQK*(QK-K)); - b1 = (Coeff)(2.f*(KK-1.f)*inv); - a2 = a0 = (Coeff)(inv*gain*KK); - a1 = a0 + a0; - } - - /** Highpass filter based on Robert Bristow-Johnson's equations - * @param fc resonant frequency - * @param q resonance (gain at fc) - * @param sr sample rate - * @param gain amplification (gain at sr/2) - */ - inline void set_hp_rbj(float fc, float q, float esr, float gain=1.0) - { - Coeff omega=(float)(2*M_PI*fc/esr); - Coeff sn=sin(omega); - Coeff cs=cos(omega); - Coeff alpha=(float)(sn/(2*q)); - - float inv=(float)(1.0/(1.0+alpha)); - - a0 = (Coeff)(gain*inv*(1 + cs)/2); - a1 = -2.f * a0; - a2 = a0; - b1 = (Coeff)(-2*cs*inv); - b2 = (Coeff)((1 - alpha)*inv); - } - - // this replaces sin/cos with polynomial approximation - inline void set_hp_rbj_optimized(float fc, float q, float esr, float gain=1.0) - { - Coeff omega=(float)(2*M_PI*fc/esr); - Coeff sn=omega+omega*omega*omega*(1.0/6.0)+omega*omega*omega*omega*omega*(1.0/120); - Coeff cs=1-omega*omega*(1.0/2.0)+omega*omega*omega*omega*(1.0/24); - Coeff alpha=(float)(sn/(2*q)); - - float inv=(float)(1.0/(1.0+alpha)); - - a0 = (Coeff)(gain*inv*(1 + cs)*(1.0/2.0)); - a1 = -2.f * a0; - a2 = a0; - b1 = (Coeff)(-2*cs*inv); - b2 = (Coeff)((1 - alpha)*inv); - } - - /** Bandpass filter based on Robert Bristow-Johnson's equations (normalized to 1.0 at center frequency) - * @param fc center frequency (gain at fc = 1.0) - * @param q =~ fc/bandwidth (not quite, but close) - 1/Q = 2*sinh(ln(2)/2*BW*w0/sin(w0)) - * @param sr sample rate - * @param gain amplification (gain at sr/2) - */ - inline void set_bp_rbj(double fc, double q, double esr, double gain=1.0) - { - float omega=(float)(2*M_PI*fc/esr); - float sn=sin(omega); - float cs=cos(omega); - float alpha=(float)(sn/(2*q)); - - float inv=(float)(1.0/(1.0+alpha)); - - a0 = (float)(gain*inv*alpha); - a1 = 0.f; - a2 = (float)(-gain*inv*alpha); - b1 = (float)(-2*cs*inv); - b2 = (float)((1 - alpha)*inv); - } - - // rbj's bandreject - inline void set_br_rbj(double fc, double q, double esr, double gain=1.0) - { - float omega=(float)(2*M_PI*fc/esr); - float sn=sin(omega); - float cs=cos(omega); - float alpha=(float)(sn/(2*q)); - - float inv=(float)(1.0/(1.0+alpha)); - - a0 = (Coeff)(gain*inv); - a1 = (Coeff)(-gain*inv*2*cs); - a2 = (Coeff)(gain*inv); - b1 = (Coeff)(-2*cs*inv); - b2 = (Coeff)((1 - alpha)*inv); - } - // this is mine (and, I guess, it sucks/doesn't work) - void set_allpass(float freq, float pole_r, float sr) - { - float a=prewarp(freq, sr); - float q=pole_r; - set_bilinear(a*a+q*q, -2.0f*a, 1, a*a+q*q, 2.0f*a, 1); - } - /// prewarping for bilinear transform, maps given digital frequency to analog counterpart for analog filter design - static inline float prewarp(float freq, float sr) - { - if (freq>sr*0.49) freq=(float)(sr*0.49); - return (float)(tan(M_PI*freq/sr)); - } - /// convert analog angular frequency value to digital - static inline float unwarp(float omega, float sr) - { - float T = 1.0 / sr; - return (2 / T) * atan(omega * T / 2); - } - /// convert analog filter time constant to digital counterpart - static inline float unwarpf(float t, float sr) - { - // this is most likely broken and works by pure accident! - float omega = 1.0 / t; - omega = unwarp(omega, sr); - // I really don't know why does it have to be M_PI and not 2 * M_PI! - float f = M_PI / omega; - return f / sr; - } - /// set digital filter parameters based on given analog filter parameters - void set_bilinear(float aa0, float aa1, float aa2, float ab0, float ab1, float ab2) - { - float q=(float)(1.0/(ab0+ab1+ab2)); - a0 = (aa0+aa1+aa2)*q; - a1 = 2*(aa0-aa2)*q; - a2 = (aa0-aa1+aa2)*q; - b1 = 2*(ab0-ab2)*q; - b2 = (ab0-ab1+ab2)*q; - } - - /// RBJ peaking EQ - /// @param freq peak frequency - /// @param q q (correlated to freq/bandwidth, @see set_bp_rbj) - /// @param peak peak gain (1.0 means no peak, >1.0 means a peak, less than 1.0 is a dip) - inline void set_peakeq_rbj(float freq, float q, float peak, float sr) - { - float A = sqrt(peak); - float w0 = freq * 2 * M_PI * (1.0 / sr); - float alpha = sin(w0) / (2 * q); - float ib0 = 1.0 / (1 + alpha/A); - a1 = b1 = -2*cos(w0) * ib0; - a0 = ib0 * (1 + alpha*A); - a2 = ib0 * (1 - alpha*A); - b2 = ib0 * (1 - alpha/A); - } - - /// RBJ low shelf EQ - amplitication of 'peak' at 0 Hz and of 1.0 (0dB) at sr/2 Hz - /// @param freq corner frequency (gain at freq is sqrt(peak)) - /// @param q q (relates bandwidth and peak frequency), the higher q, the louder the resonant peak (situated below fc) is - /// @param peak shelf gain (1.0 means no peak, >1.0 means a peak, less than 1.0 is a dip) - inline void set_lowshelf_rbj(float freq, float q, float peak, float sr) - { - float A = sqrt(peak); - float w0 = freq * 2 * M_PI * (1.0 / sr); - float alpha = sin(w0) / (2 * q); - float cw0 = cos(w0); - float tmp = 2 * sqrt(A) * alpha; - float b0 = 0.f, ib0 = 0.f; - - a0 = A*( (A+1) - (A-1)*cw0 + tmp); - a1 = 2*A*( (A-1) - (A+1)*cw0); - a2 = A*( (A+1) - (A-1)*cw0 - tmp); - b0 = (A+1) + (A-1)*cw0 + tmp; - b1 = -2*( (A-1) + (A+1)*cw0); - b2 = (A+1) + (A-1)*cw0 - tmp; - - ib0 = 1.0 / b0; - b1 *= ib0; - b2 *= ib0; - a0 *= ib0; - a1 *= ib0; - a2 *= ib0; - } - - /// RBJ high shelf EQ - amplitication of 0dB at 0 Hz and of peak at sr/2 Hz - /// @param freq corner frequency (gain at freq is sqrt(peak)) - /// @param q q (relates bandwidth and peak frequency), the higher q, the louder the resonant peak (situated above fc) is - /// @param peak shelf gain (1.0 means no peak, >1.0 means a peak, less than 1.0 is a dip) - inline void set_highshelf_rbj(float freq, float q, float peak, float sr) - { - float A = sqrt(peak); - float w0 = freq * 2 * M_PI * (1.0 / sr); - float alpha = sin(w0) / (2 * q); - float cw0 = cos(w0); - float tmp = 2 * sqrt(A) * alpha; - float b0 = 0.f, ib0 = 0.f; - - a0 = A*( (A+1) + (A-1)*cw0 + tmp); - a1 = -2*A*( (A-1) + (A+1)*cw0); - a2 = A*( (A+1) + (A-1)*cw0 - tmp); - b0 = (A+1) - (A-1)*cw0 + tmp; - b1 = 2*( (A-1) - (A+1)*cw0); - b2 = (A+1) - (A-1)*cw0 - tmp; - - ib0 = 1.0 / b0; - b1 *= ib0; - b2 *= ib0; - a0 *= ib0; - a1 *= ib0; - a2 *= ib0; - } - - /// copy coefficients from another biquad - template - inline void copy_coeffs(const biquad_coeffs &src) - { - a0 = src.a0; - a1 = src.a1; - a2 = src.a2; - b1 = src.b1; - b2 = src.b2; - } - - /// Return the filter's gain at frequency freq - /// @param freq Frequency to look up - /// @param sr Filter sample rate (used to convert frequency to angular frequency) - float freq_gain(float freq, float sr) const - { - typedef std::complex cfloat; - freq *= 2.0 * M_PI / sr; - cfloat z = 1.0 / exp(cfloat(0.0, freq)); - - return std::abs(h_z(z)); - } - - /// Return H(z) the filter's gain at frequency freq - /// @param z Z variable (e^jw) - cfloat h_z(const cfloat &z) const - { - - return (cfloat(a0) + double(a1) * z + double(a2) * z*z) / (cfloat(1.0) + double(b1) * z + double(b2) * z*z); - } - -}; - -/** - * Two-pole two-zero filter, for floating point values. - * Uses "traditional" Direct I form (separate FIR and IIR halves). - * don't use this for integers because it won't work - */ -template -struct biquad_d1: public biquad_coeffs -{ - using biquad_coeffs::a0; - using biquad_coeffs::a1; - using biquad_coeffs::a2; - using biquad_coeffs::b1; - using biquad_coeffs::b2; - /// input[n-1] - T x1; - /// input[n-2] - T x2; - /// output[n-1] - T y1; - /// output[n-2] - T y2; - /// Constructor (initializes state to all zeros) - biquad_d1() - { - reset(); - } - /// direct I form with four state variables - inline T process(T in) - { - T out = in * a0 + x1 * a1 + x2 * a2 - y1 * b1 - y2 * b2; - x2 = x1; - y2 = y1; - x1 = in; - y1 = out; - return out; - } - - /// direct I form with zero input - inline T process_zeroin() - { - T out = - y1 * b1 - y2 * b2; - y2 = y1; - y1 = out; - return out; - } - - /// simplified version for lowpass case with two zeros at -1 - inline T process_lp(T in) - { - T out = a0*(in + x1 + x1 + x2) - y1 * b1 - y2 * b2; - x2 = x1; - y2 = y1; - x1 = in; - y1 = out; - return out; - } - /// Sanitize (set to 0 if potentially denormal) filter state - inline void sanitize() - { - dsp::sanitize(x1); - dsp::sanitize(y1); - dsp::sanitize(x2); - dsp::sanitize(y2); - } - /// Reset state variables - inline void reset() - { - dsp::zero(x1); - dsp::zero(y1); - dsp::zero(x2); - dsp::zero(y2); - } - inline bool empty() const { - return (y1 == 0.f && y2 == 0.f); - } - -}; - -/** - * Two-pole two-zero filter, for floating point values. - * Uses slightly faster Direct II form (combined FIR and IIR halves). - * However, when used with wildly varying coefficients, it may - * make more zipper noise than Direct I form, so it's better to - * use it when filter coefficients are not changed mid-stream. - */ -template -struct biquad_d2: public biquad_coeffs -{ - using biquad_coeffs::a0; - using biquad_coeffs::a1; - using biquad_coeffs::a2; - using biquad_coeffs::b1; - using biquad_coeffs::b2; - /// state[n-1] - float w1; - /// state[n-2] - float w2; - /// Constructor (initializes state to all zeros) - biquad_d2() - { - reset(); - } - /// direct II form with two state variables - inline T process(T in) - { - dsp::sanitize_denormal(in); - dsp::sanitize(in); - dsp::sanitize(w1); - dsp::sanitize(w2); - - T tmp = in - w1 * b1 - w2 * b2; - T out = tmp * a0 + w1 * a1 + w2 * a2; - w2 = w1; - w1 = tmp; - return out; - } - - // direct II form with two state variables, lowpass version - // interesting fact: this is actually slower than the general version! - inline T process_lp(T in) - { - T tmp = in - w1 * b1 - w2 * b2; - T out = (tmp + w2 + w1* 2) * a0; - w2 = w1; - w1 = tmp; - return out; - } - - /// Is the filter state completely silent? (i.e. set to 0 by sanitize function) - inline bool empty() const { - return (w1 == 0.f && w2 == 0.f); - } - - - /// Sanitize (set to 0 if potentially denormal) filter state - inline void sanitize() - { - dsp::sanitize(w1); - dsp::sanitize(w2); - } - - /// Reset state variables - inline void reset() - { - dsp::zero(w1); - dsp::zero(w2); - } -}; - -/** - * Two-pole two-zero filter, for floating point values. - * Uses "traditional" Direct I form (separate FIR and IIR halves). - * don't use this for integers because it won't work - */ -template -struct biquad_d1_lerp: public biquad_coeffs -{ - using biquad_coeffs::a0; - using biquad_coeffs::a1; - using biquad_coeffs::a2; - using biquad_coeffs::b1; - using biquad_coeffs::b2; - Coeff a0cur, a1cur, a2cur, b1cur, b2cur; - Coeff a0delta, a1delta, a2delta, b1delta, b2delta; - /// input[n-1] - T x1; - /// input[n-2] - T x2; - /// output[n-1] - T y1; - /// output[n-2] - T y2; - /// Constructor (initializes state to all zeros) - biquad_d1_lerp() - { - reset(); - } - #define _DO_COEFF(coeff) coeff##delta = (coeff - coeff##cur) * (frac) - void big_step(Coeff frac) - { - _DO_COEFF(a0); - _DO_COEFF(a1); - _DO_COEFF(a2); - _DO_COEFF(b1); - _DO_COEFF(b2); - } - #undef _DO_COEFF - /// direct I form with four state variables - inline T process(T in) - { - T out = in * a0cur + x1 * a1cur + x2 * a2cur - y1 * b1cur - y2 * b2cur; - x2 = x1; - y2 = y1; - x1 = in; - y1 = out; - a0cur += a0delta; - a1cur += a1delta; - a2cur += a2delta; - b1cur += b1delta; - b2cur += b2delta; - return out; - } - - /// direct I form with zero input - inline T process_zeroin() - { - T out = - y1 * b1 - y2 * b2; - y2 = y1; - y1 = out; - b1cur += b1delta; - b2cur += b2delta; - return out; - } - - /// simplified version for lowpass case with two zeros at -1 - inline T process_lp(T in) - { - T out = a0*(in + x1 + x1 + x2) - y1 * b1 - y2 * b2; - x2 = x1; - y2 = y1; - x1 = in; - y1 = out; - return out; - } - /// Sanitize (set to 0 if potentially denormal) filter state - inline void sanitize() - { - dsp::sanitize(x1); - dsp::sanitize(y1); - dsp::sanitize(x2); - dsp::sanitize(y2); - dsp::sanitize(a0cur); - dsp::sanitize(a1cur); - dsp::sanitize(a2cur); - dsp::sanitize(b1cur); - dsp::sanitize(b2cur); - } - /// Reset state variables - inline void reset() - { - dsp::zero(x1); - dsp::zero(y1); - dsp::zero(x2); - dsp::zero(y2); - dsp::zero(a0cur); - dsp::zero(a1cur); - dsp::zero(a2cur); - dsp::zero(b1cur); - dsp::zero(b2cur); - } - inline bool empty() { - return (y1 == 0.f && y2 == 0.f); - } - -}; - -/// Compose two filters in series -template -class filter_compose { -public: - typedef std::complex cfloat; - F1 f1; - F2 f2; -public: - float process(float value) { - return f2.process(f1.process(value)); - } - - inline cfloat h_z(const cfloat &z) const { - return f1.h_z(z) * f2.h_z(z); - } - - /// Return the filter's gain at frequency freq - /// @param freq Frequency to look up - /// @param sr Filter sample rate (used to convert frequency to angular frequency) - float freq_gain(float freq, float sr) const - { - typedef std::complex cfloat; - freq *= 2.0 * M_PI / sr; - cfloat z = 1.0 / exp(cfloat(0.0, freq)); - - return std::abs(h_z(z)); - } - - void sanitize() { - f1.sanitize(); - f2.sanitize(); - } -}; - -/// Compose two filters in parallel -template -class filter_sum { -public: - typedef std::complex cfloat; - F1 f1; - F2 f2; -public: - float process(float value) { - return f2.process(value) + f1.process(value); - } - - inline cfloat h_z(const cfloat &z) const { - return f1.h_z(z) + f2.h_z(z); - } - - /// Return the filter's gain at frequency freq - /// @param freq Frequency to look up - /// @param sr Filter sample rate (used to convert frequency to angular frequency) - float freq_gain(float freq, float sr) const - { - typedef std::complex cfloat; - freq *= 2.0 * M_PI / sr; - cfloat z = 1.0 / exp(cfloat(0.0, freq)); - - return std::abs(h_z(z)); - } - - void sanitize() { - f1.sanitize(); - f2.sanitize(); - } -}; - -}; - -#endif diff --git a/plugins/LadspaEffect/calf/src/calf/buffer.h b/plugins/LadspaEffect/calf/src/calf/buffer.h deleted file mode 100644 index 1e7018f3ad3..00000000000 --- a/plugins/LadspaEffect/calf/src/calf/buffer.h +++ /dev/null @@ -1,229 +0,0 @@ -/* Calf DSP Library - * Buffer abstractions. - * - * Copyright (C) 2007 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 02110-1301 USA - */ -#ifndef __BUFFER_H -#define __BUFFER_H - -namespace dsp { - -/// decrease by N if >= N (useful for circular buffers) -template inline int wrap_around(int a) { - return (a >= N) ? a - N : a; -} - -// provide fast specializations for powers of 2 -template<> inline int wrap_around<2>(int a) { return a & 1; } -template<> inline int wrap_around<4>(int a) { return a & 3; } -template<> inline int wrap_around<8>(int a) { return a & 7; } -template<> inline int wrap_around<16>(int a) { return a & 15; } -template<> inline int wrap_around<32>(int a) { return a & 31; } -template<> inline int wrap_around<64>(int a) { return a & 63; } -template<> inline int wrap_around<128>(int a) { return a & 127; } -template<> inline int wrap_around<256>(int a) { return a & 255; } -template<> inline int wrap_around<512>(int a) { return a & 511; } -template<> inline int wrap_around<1024>(int a) { return a & 1023; } -template<> inline int wrap_around<2048>(int a) { return a & 2047; } -template<> inline int wrap_around<4096>(int a) { return a & 4095; } -template<> inline int wrap_around<8192>(int a) { return a & 8191; } -template<> inline int wrap_around<16384>(int a) { return a & 16383; } -template<> inline int wrap_around<32768>(int a) { return a & 32767; } -template<> inline int wrap_around<65536>(int a) { return a & 65535; } - -template -void fill(Buf &buf, T value) { - T* data = buf.data(); - int size = buf.size(); - for (int i=0; i -void fill(T *data, int size, T value) { - for (int i=0; i -void copy(T *dest, U *src, int size, T scale = 1, T add = 0) { - for (int i=0; i -struct sample_traits { - enum { - channels = 1, - bps = sizeof(T)*8 - }; -}; - -template -struct sample_traits > { - enum { - channels = 2, - bps = sizeof(T)*8 - }; -}; - -template -class fixed_size_buffer { -public: - typedef T data_type; - enum { buffer_size = N }; - inline int size() { return N; } -}; - -template -class mem_fixed_size_buffer: public fixed_size_buffer { - T *buf; -public: - mem_fixed_size_buffer(T ubuf[N]) { buf = ubuf; } - void set_data(T buf[N]) { this->buf = buf; } - inline T* data() { return buf; } - inline const T* data() const { return buf; } - inline T& operator[](int pos) { return buf[pos]; } - inline const T& operator[](int pos) const { return buf[pos]; } -}; - -template -class auto_buffer: public fixed_size_buffer { - T buf[N]; -public: - T* data() const { return buf; } - inline T& operator[](int pos) { return buf[pos]; } - inline const T& operator[](int pos) const { return buf[pos]; } -}; - -template -class dynamic_buffer { - T *buf; - int buf_size; - bool owns; -public: - dynamic_buffer() { owns = false; } - dynamic_buffer(T *_buf, int _buf_size, bool _own) - : buf(_buf), buf_size(_buf_size), owns(_own) { - } - dynamic_buffer(int _size) { - buf = new T[_size]; - buf_size = _size; - owns = true; - } - inline T* data() { return buf; } - inline const T* data() const { return buf; } - inline int size() { return buf_size; } - void resize(int new_size, bool fill_with_zeros = false) { - T *new_buf = new T[new_size]; - memcpy(new_buf, buf, std::min(buf_size, new_size)); - if (fill_with_zeros && buf_size < new_size) - dsp::zero(new_buf + buf_size, new_size - buf_size); - if (owns) - delete []buf; - buf = new_buf; - buf_size = new_size; - owns = true; - } - inline T& operator[](int pos) { return buf[pos]; } - inline const T& operator[](int pos) const { return buf[pos]; } - ~dynamic_buffer() { - if (owns) - delete []buf; - } -}; - -template -void copy_buf(T &dest_buf, const U &src_buf, T scale = 1, T add = 0) { - typedef typename T::data_type data_type; - data_type *dest = dest_buf.data(); - const data_type *src = src_buf.data(); - int size = src_buf.size(); - for (int i=0; i -struct buffer_traits { -}; - -/// this class template defines some basic position operations for fixed_size_buffers -template -struct buffer_traits > { - int inc_wrap(int pos) const { - return wrap_around(pos+1); - } - - int pos_diff(int pos1, int pos2) const { - int pos = pos1 - pos2; - if (pos < 0) pos += T::size; - return pos; - } -}; - -/// this is useless for now (and untested too) -template -class circular_buffer: public B { - typedef typename B::data_type data_type; - typedef class buffer_traits traits; - B buffer; - int rpos, wpos; - circular_buffer() { - clear(); - } - void clear() { - rpos = 0; - wpos = 0; - } - inline void put(data_type data) { - buffer[wpos] = data; - wpos = traits::inc_wrap(wpos); - } - inline bool empty() { - return rpos == wpos; - } - inline bool full() { - return rpos == traits::inc_wrap(wpos); - } - inline const data_type& get() { - int oldrpos = rpos; - rpos = traits::inc_wrap(rpos); - return buffer[oldrpos]; - } - inline int get_rbytes() { - return traits::pos_diff(wpos, rpos); - } - inline int get_wbytes() { - if (full()) return 0; - return traits::pos_diff(rpos, wpos); - } -}; - -/// this is useless for now -template -class mono_auto_buffer: public auto_buffer { -}; - -/// this is useless for now -template -class stereo_auto_buffer: public auto_buffer > { -}; - -}; - -#endif diff --git a/plugins/LadspaEffect/calf/src/calf/delay.h b/plugins/LadspaEffect/calf/src/calf/delay.h deleted file mode 100644 index 7ff6e7bb8f7..00000000000 --- a/plugins/LadspaEffect/calf/src/calf/delay.h +++ /dev/null @@ -1,185 +0,0 @@ -/* Calf DSP Library - * Reusable audio effect classes. - * - * Copyright (C) 2001-2007 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 02110-1301 USA - */ -#ifndef __CALF_DELAY_H -#define __CALF_DELAY_H - -#include "primitives.h" -#include "buffer.h" -#include "onepole.h" - -namespace dsp { - -/** - * Delay primitive. Can be used for most delay stuff, including - * variable (modulated) delays like chorus/flanger. Note that - * for modulated delay effects use of GetInterp is preferred, - * because it handles fractional positions and uses linear - * interpolation, which sounds better most of the time. - * - * @param N maximum length - * @param C number of channels read/written for each sample (1 mono, 2 stereo etc) - */ -template -struct simple_delay { - auto_buffer data; - int pos; - - simple_delay() { - reset(); - } - void reset() { - pos = 0; - for (int i=0; i(pos+1); - } - - /** - * Read one C-channel sample into odata[0], odata[1] etc into buffer. - * Don't use for modulated delays (chorus/flanger etc) unless you - * want them to crackle and generally sound ugly - * @param odata pointer to write into - * @param delay delay relative to current writing pos - */ - template - inline void get(U &odata, int delay) { - assert(delay >= 0 && delay < N); - int ppos = wrap_around(pos + N - delay); - odata = data[ppos]; - } - - /** - * Read and write during the same function call - */ - inline T process(T idata, int delay) - { - assert(delay >= 0 && delay < N); - int ppos = wrap_around(pos + N - delay); - T odata = data[ppos]; - data[pos] = idata; - pos = wrap_around(pos+1); - return odata; - } - - /** Read one C-channel sample at fractional position. - * This version can be used for modulated delays, because - * it uses linear interpolation. - * @param odata value to write into - * @param delay delay relative to current writing pos - * @param udelay fractional delay (0..1) - */ - template - inline void get_interp(U &odata, int delay, float udelay) { -// assert(delay >= 0 && delay <= N-1); - int ppos = wrap_around(pos + N - delay); - int pppos = wrap_around(ppos + N - 1); - odata = lerp(data[ppos], data[pppos], udelay); - } - - /** Read one C-channel sample at fractional position. - * This version can be used for modulated delays, because - * it uses linear interpolation. - * @param odata value to write into - * @param delay delay relative to current writing pos - * @param udelay fractional delay (0..1) - */ - inline T get_interp_1616(unsigned int delay) { - float udelay = (float)((delay & 0xFFFF) * (1.0 / 65536.0)); - delay = delay >> 16; -// assert(delay >= 0 && delay < N-1); - int ppos = wrap_around(pos + N - delay); - int pppos = wrap_around(ppos + N - 1); - return lerp(data[ppos], data[pppos], udelay); - } - - /** - * Comb filter. Feedback delay line with given delay and feedback values - * @param in input signal - * @param delay delay length (must be >16, dsp::fract16(delay)); - cur = in + fb*old; - sanitize(cur); - put(cur); - return old; - } - - /** - * Comb allpass filter. The comb filter with additional direct path, which is supposed to cancel the coloration. - * @param in input signal - * @param delay delay length (must be >16, dsp::fract16(delay)); - cur = in + fb*old; - sanitize(cur); - put(cur); - return old - fb * cur; - } -}; - -}; - -#endif diff --git a/plugins/LadspaEffect/calf/src/calf/envelope.h b/plugins/LadspaEffect/calf/src/calf/envelope.h deleted file mode 100644 index 302e4c06c13..00000000000 --- a/plugins/LadspaEffect/calf/src/calf/envelope.h +++ /dev/null @@ -1,282 +0,0 @@ -/* Calf DSP Library - * ADSR envelope class (and other envelopes in future) - * - * 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 02110-1301 USA - */ -#ifndef __CALF_ENVELOPE_H -#define __CALF_ENVELOPE_H - -#include "primitives.h" - -namespace dsp { - -/// Rate-based ADSFR envelope class. Note that if release rate is slower than decay -/// rate, this envelope won't use release rate until output level falls below sustain level -/// it's different to what certain hardware synth companies did, but it prevents the very -/// un-musical (IMHO) behaviour known from (for example) SoundFont 2. -class adsr -{ -public: - enum env_state { - STOP, ///< envelope is stopped - ATTACK, ///< attack - rise from 0 to 1 - DECAY, ///< decay - fall from 1 to sustain level - SUSTAIN, ///< sustain - remain at sustain level (unless sustain is 0 - then it gets stopped); with fade != 0 it goes towards 0% (positive fade) or 100% (negative fade) - RELEASE, ///< release - fall from sustain (or pre-sustain) level to 0 - LOCKDECAY, ///< locked decay - }; - - /// Current envelope stage - env_state state; - /// @note these are *rates*, not times - double attack, decay, sustain, release, fade; - /// Requested release time (not the rate!) in frames, used for recalculating the rate if sustain is changed - double release_time; - /// Current envelope (output) level - double value; - /// Release rate used for the current note (calculated from this note's sustain level, and not the current sustain level, - /// which may have changed after note has been released) - double thisrelease; - /// Sustain level used for the current note (used to calculate release rate if sustain changed during release stage - /// of the current note) - double thiss; - /// Value from the time before advance() was called last time - double old_value; - - adsr() - { - attack = decay = sustain = release = thisrelease = thiss = 0.f; - reset(); - } - /// Stop (reset) the envelope - inline void reset() - { - old_value = value = 0.0; - thiss = 0.0; - state = STOP; - } - /// Set the envelope parameters (updates rate member variables based on values passed) - /// @param a attack time - /// @param d decay time - /// @param s sustain level - /// @param r release time - /// @param er Envelope (update) rate - /// @param f fade time (if applicable) - inline void set(float a, float d, float s, float r, float er, float f = 0.f) - { - attack = 1.0 / (a * er); - decay = (1 - s) / (d * er); - sustain = s; - release_time = r * er; - release = s / release_time; - if (fabs(f) > small_value()) - fade = 1.0 / (f * er); - else - fade = 0.0; - // in release: - // lock thiss setting (start of release for current note) and unlock thisrelease setting (current note's release rate) - if (state != RELEASE) - thiss = s; - else - thisrelease = thiss / release_time; - } - /// @retval true if envelope is in released state (forced decay, release or stopped) - inline bool released() const - { - return state == LOCKDECAY || state == RELEASE || state == STOP; - } - /// @retval true if envelope is stopped (has not been started or has run till its end) - inline bool stopped() const - { - return state == STOP; - } - /// Start the envelope - inline void note_on() - { - state = ATTACK; - thiss = sustain; - } - /// Release the envelope - inline void note_off() - { - // Do nothing if envelope is already stopped - if (state == STOP) - return; - // XXXKF what if envelope is already released? (doesn't happen in any current synth, but who knows?) - // Raise sustain value if it has been changed... I'm not sure if it's needed - thiss = std::max(sustain, value); - // Calculate release rate from sustain level - thisrelease = thiss / release_time; - // we're in attack or decay, and if decay is faster than release - if (value > sustain && decay > thisrelease) { - // use standard release time later (because we'll be switching at sustain point) - thisrelease = release; - state = LOCKDECAY; - } else { - // in attack/decay, but use fixed release time - // in case value fell below sustain, assume it didn't (for the purpose of calculating release rate only) - state = RELEASE; - } - } - /// Calculate next envelope value - inline void advance() - { - old_value = value; - // XXXKF This may use a state array instead of a switch some day (at least for phases other than attack and possibly sustain) - switch(state) - { - case ATTACK: - value += attack; - if (value >= 1.0) { - value = 1.0; - state = DECAY; - } - break; - case DECAY: - value -= decay; - if (value < sustain) - { - value = sustain; - state = SUSTAIN; - } - break; - case LOCKDECAY: - value -= decay; - if (value < sustain) - { - if (value < 0.f) - value = 0.f; - state = RELEASE; - thisrelease = release; - } - break; - case SUSTAIN: - if (fade != 0.f) - { - value -= fade; - if (value > 1.f) - value = 1.f; - } - else - value = sustain; - if (value < 0.00001f) { - value = 0; - state = STOP; - } - break; - case RELEASE: - value -= thisrelease; - if (value <= 0.f) { - value = 0.f; - state = STOP; - } - break; - case STOP: - value = 0.f; - break; - } - } - /// Return a value between old_value (previous step) and value (current step) - /// @param pos between 0 and 1 - inline double interpolate(double pos) - { - return old_value + (value - old_value) * pos; - } - inline float get_amp_value() - { - if (state == RELEASE && sustain > 0 && value < sustain) - { - return value * value * value / (sustain * sustain); - } - return value; - } -}; - -/// Simple linear fade out for note tails -struct fadeout -{ - float value; - float step, step_orig; - bool done, undoing; - - fadeout(int steps = 256) - { - step_orig = (float)(1.f / steps); - value = 1.f; - reset(); - } - - /// Prepare fade out - void reset() - { - value = 1.f; - step = -step_orig; - done = false; - undoing = false; - } - - /// Fade back in with double speed (to prevent click on note restart) - void undo() - { - step = step_orig; - done = false; - undoing = true; - } - - /// Reset if fully faded out; fade back in if in the middle of fading out - void reset_soft() - { - if (value <= 0.f || value >= 1.f) - reset(); - else - undo(); - } - - void process(float *buffer, int len) - { - int i = 0; - if (!done) - { - for (; value > 0 && value <= 1.0 && i < len; i++) - { - buffer[i] *= value; - value += step; - } - if (value <= 0 || value > 1) - done = true; - } - if (done && value <= 0) - { - while (i < len) - buffer[i++] = 0.f; - } - if (done && undoing && value >= 1) - { - undoing = false; - done = false; - // prepare for the next fade-out - value = 1.f; - } - } -}; - -}; - -#endif - - diff --git a/plugins/LadspaEffect/calf/src/calf/fft.h b/plugins/LadspaEffect/calf/src/calf/fft.h deleted file mode 100644 index 5eef9fe8ec0..00000000000 --- a/plugins/LadspaEffect/calf/src/calf/fft.h +++ /dev/null @@ -1,113 +0,0 @@ -/* Calf DSP Library - * FFT class - * - * Copyright (C) 2007 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_FFT_H -#define __CALF_FFT_H - -#include - -namespace dsp { - -/// FFT routine copied from my old OneSignal library, modified to -/// match Calf's style. It's not fast at all, just a straightforward -/// implementation. -template -class fft -{ - typedef typename std::complex complex; - int scramble[1<= 4); - for (int i=0; i>(j+1)); - scramble[i]=v; - } - int N90 = N >> 2; - T divN = 2 * M_PI / N; - // use symmetry - for (int i=0; i>bits; }; -inline int32_t shr(int32_t v, int bits = 1) { return v>>bits; }; -inline uint64_t shr(uint64_t v, int bits = 1) { return v>>bits; }; -inline int64_t shr(int64_t v, int bits = 1) { return v>>bits; }; -inline float shr(float v, int bits = 1) { return v*(1.0/(1< -inline T shr(T v, int bits = 1) { - v.set(v >> bits); - return v; -} - -template class fixed_point { - T value; - enum { IntBits = (sizeof(T)*8) - FracBits }; - -public: - /// default constructor, does not initialize the value, just like - say - float doesn't - inline fixed_point() { - } - - /// copy constructor from any other fixed_point value - template inline fixed_point(const fixed_point &v) { - if (FracBits == FracBits2) value = v.get(); - else if (FracBits > FracBits2) value = v.get() << abs(FracBits - FracBits2); - else value = v.get() >> abs(FracBits - FracBits2); - } - - /* this would be way too confusing, it wouldn't be obvious if it expects a whole fixed point or an integer part - explicit inline fixed_point(T v) { - this->value = v; - } - */ - explicit inline fixed_point(double v) { - value = (T)(v*one()); - } - - /// Makes an instance from a representation value (ie. same type of value as is used for internal storage and get/set) - static inline fixed_point from_base(const T &v) - { - fixed_point result; - result.value = v; - return result; - } - - inline static T one() { - return (T)(1) << FracBits; - } - - inline void set(T value) { - this->value = value; - } - - inline T get() const { - return value; - } - - inline operator double() const { - return value * (1.0/one()); - } - - inline fixed_point &operator=(double v) { - value = (T)(v*one()); - return *this; - } - - template static inline T rebase(const fixed_point &v) { - if (FracBits == FracBits2) - return v.get(); - if (FracBits > FracBits2) - return v.get() << abs(FracBits - FracBits2); - return v.get() >> abs(FracBits2 - FracBits); - } - - template inline fixed_point &operator=(const fixed_point &v) { - value = rebase(v); - return *this; - } - - template inline fixed_point &operator+=(const fixed_point &v) { - value += rebase(v); - return *this; - } - - template inline fixed_point &operator-=(const fixed_point &v) { - value -= rebase(v); - return *this; - } - - template inline fixed_point operator+(const fixed_point &v) const { - fixed_point fpv; - fpv.set(value + rebase(v)); - return fpv; - } - - template inline fixed_point operator-(const fixed_point &v) const { - fixed_point fpv; - fpv.set(value - rebase(v)); - return fpv; - } - - /// multiply two fixed point values, using long long int to store the temporary multiplication result - template inline fixed_point operator*(const fixed_point &v) const { - fixed_point tmp; - tmp.set(((int64_t)value) * v.get() >> FracBits2); - return tmp; - } - - /// multiply two fixed point values, using BigType (usually 64-bit int) to store the temporary multiplication result - template inline fixed_point& operator*=(const fixed_point &v) { - value = (T)(((BigType)value) * v.get() >> FracBits2); - return *this; - } - - inline fixed_point operator+(int v) const { - fixed_point tmp; - tmp.set(value + (v << FracBits)); - return tmp; - } - - inline fixed_point operator-(int v) const { - fixed_point tmp; - tmp.set(value - (v << FracBits)); - return tmp; - } - - inline fixed_point operator*(int v) const { - fixed_point tmp; - tmp.value = value*v; - return tmp; - } - - inline fixed_point& operator+=(int v) { - value += (v << FracBits); - return *this; - } - - inline fixed_point& operator-=(int v) { - value -= (v << FracBits); - return *this; - } - - inline fixed_point& operator*=(int v) { - value *= v; - return *this; - } - - /// return integer part - inline T ipart() const { - return value >> FracBits; - } - - /// return integer part as unsigned int - inline unsigned int uipart() const { - return ((unsigned)value) >> FracBits; - } - - /// return integer part as unsigned int - inline unsigned int ui64part() const { - return ((uint64_t)value) >> FracBits; - } - - /// return fractional part as 0..(2^FracBits-1) - inline T fpart() const { - return value & ((1 << FracBits)-1); - } - - /// return fractional part as 0..(2^Bits-1) - template - inline T fpart() const { - int fbits = value & ((1 << FracBits)-1); - if (Bits == FracBits) return fbits; - int shift = abs(Bits-FracBits); - return (Bits < FracBits) ? (fbits >> shift) : (fbits << shift); - } - - /// return fractional part as 0..1 - inline double fpart_as_double() const { - return (value & ((1 << FracBits)-1)) * (1.0 / (1 << FracBits)); - } - - /// use fractional part (either whole or given number of most significant bits) for interpolating between two values - /// note that it uses integer arithmetic only, and isn't suitable for floating point or fixed point U! - /// @param UseBits can be used when there's a risk of exceeding range of U because max(fpart)*max(v1 or v2) > range of U - template - inline U lerp_by_fract_int(U v1, U v2) const { - int fp = fpart(); - assert ( fp >=0 && fp <= (1ULL< - inline U lerp_table_lookup_int(U data[(unsigned int)(1ULL<(data[pos], data[pos+1]); - } - - /// Untested... I've started it to get a sin/cos readout for rotaryorgan, but decided to use table-less solution instead - /// Do not assume it works, because it most probably doesn't - template - inline U lerp_table_lookup_int_shift(U data[(unsigned int)(1ULL<(data[pos], data[pos+1]); - } - - template - inline U lerp_table_lookup_float(U data[(unsigned int)(1ULL< - inline U lerp_table_lookup_float_mask(U data[(unsigned int)(1ULL< - inline U lerp_ptr_lookup_int(U *data) const { - unsigned int pos = ui64part(); - return lerp_by_fract_int(data[pos], data[pos+1]); - } - - template - inline U lerp_ptr_lookup_float(U *data) const { - unsigned int pos = ui64part(); - return data[pos] + (data[pos+1]-data[pos]) * fpart_as_double(); - } -}; - -template -inline fixed_point operator*(int v, fixed_point v2) { - v2 *= v; - return v2; -} - -/// wave position (unsigned 64-bit int including 24-bit fractional part) -typedef fixed_point wpos; - -}; - -#endif diff --git a/plugins/LadspaEffect/calf/src/calf/giface.h b/plugins/LadspaEffect/calf/src/calf/giface.h deleted file mode 100644 index b4c6e4186c0..00000000000 --- a/plugins/LadspaEffect/calf/src/calf/giface.h +++ /dev/null @@ -1,722 +0,0 @@ -/* Calf DSP Library - * Common plugin interface definitions (shared between LADSPA/LV2/DSSI/standalone). - * - * Copyright (C) 2007-2010 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_GIFACE_H -#define CALF_GIFACE_H - -#include -#include "primitives.h" -#include -#include -#include -#include - -namespace osctl { - struct osc_client; -} - -namespace calf_plugins { - -enum { - MAX_SAMPLE_RUN = 256 -}; - -/// Values ORed together for flags field in parameter_properties -enum parameter_flags -{ - PF_TYPEMASK = 0x000F, ///< bit mask for type - PF_FLOAT = 0x0000, ///< any float value - PF_INT = 0x0001, ///< integer value (still represented as float) - PF_BOOL = 0x0002, ///< bool value (usually >=0.5f is treated as TRUE, which is inconsistent with LV2 etc. which treats anything >0 as TRUE) - PF_ENUM = 0x0003, ///< enum value (min, min+1, ..., max, only guaranteed to work when min = 0) - PF_ENUM_MULTI = 0x0004, ///< SET / multiple-choice - - PF_SCALEMASK = 0xF0, ///< bit mask for scale - PF_SCALE_DEFAULT = 0x00, ///< no scale given - PF_SCALE_LINEAR = 0x10, ///< linear scale - PF_SCALE_LOG = 0x20, ///< log scale - PF_SCALE_GAIN = 0x30, ///< gain = -96dB..0 or -inf dB - PF_SCALE_PERC = 0x40, ///< percent - PF_SCALE_QUAD = 0x50, ///< quadratic scale (decent for some gain/amplitude values) - PF_SCALE_LOG_INF = 0x60, ///< log scale + +inf (FAKE_INFINITY) - - PF_CTLMASK = 0x0F00, ///< bit mask for control type - PF_CTL_DEFAULT = 0x0000, ///< try to figure out automatically - PF_CTL_KNOB = 0x0100, ///< knob - PF_CTL_FADER = 0x0200, ///< fader (slider) - PF_CTL_TOGGLE = 0x0300, ///< toggle button - PF_CTL_COMBO = 0x0400, ///< combo box - PF_CTL_RADIO = 0x0500, ///< radio button - PF_CTL_BUTTON = 0x0600, ///< push button - PF_CTL_METER = 0x0700, ///< volume meter - PF_CTL_LED = 0x0800, ///< light emitting diode - PF_CTL_LABEL = 0x0900, ///< label - - PF_CTLOPTIONS = 0x00F000, ///< bit mask for control (widget) options - PF_CTLO_HORIZ = 0x001000, ///< horizontal version of the control (unused) - PF_CTLO_VERT = 0x002000, ///< vertical version of the control (unused) - PF_CTLO_LABEL = 0x004000, ///< add a text display to the control (meters only) - PF_CTLO_REVERSE = 0x008000, ///< use VU_MONOCHROME_REVERSE mode (meters only) - - PF_PROP_NOBOUNDS = 0x010000, ///< no epp:hasStrictBounds - PF_PROP_EXPENSIVE = 0x020000, ///< epp:expensive, may trigger expensive calculation - PF_PROP_OUTPUT_GAIN=0x050000, ///< epp:outputGain + skip epp:hasStrictBounds - PF_PROP_OUTPUT = 0x080000, ///< output port - PF_PROP_OPTIONAL = 0x100000, ///< connection optional - PF_PROP_GRAPH = 0x200000, ///< add graph - - PF_UNITMASK = 0xFF000000, ///< bit mask for units \todo reduce to use only 5 bits - PF_UNIT_DB = 0x01000000, ///< decibels - PF_UNIT_COEF = 0x02000000, ///< multiply-by factor - PF_UNIT_HZ = 0x03000000, ///< Hertz - PF_UNIT_SEC = 0x04000000, ///< second - PF_UNIT_MSEC = 0x05000000, ///< millisecond - PF_UNIT_CENTS = 0x06000000, ///< cents (1/100 of a semitone, 1/1200 of an octave) - PF_UNIT_SEMITONES = 0x07000000,///< semitones - PF_UNIT_BPM = 0x08000000, ///< beats per minute - PF_UNIT_DEG = 0x09000000, ///< degrees - PF_UNIT_NOTE = 0x0A000000, ///< MIDI note number - PF_UNIT_RPM = 0x0B000000, ///< revolutions per minute -}; - -/// A fake infinity value (because real infinity may break some hosts) -#define FAKE_INFINITY (65536.0 * 65536.0) -/// Check for infinity (with appropriate-ish tolerance) -#define IS_FAKE_INFINITY(value) (fabs(value-FAKE_INFINITY) < 1.0) - -/// Information record about plugin's menu command -struct plugin_command_info -{ - const char *label; ///< short command name / label - const char *name; ///< human-readable command name - const char *description; ///< description (for status line etc.) -}; - -/// Range, default value, flags and names for a parameter -struct parameter_properties -{ - /// default value - float def_value; - /// minimum value - float min; - /// maximum value - float max; - /// number of steps (for an integer value from 0 to 100 this will be 101; for 0/90/180/270/360 this will be 5), or 0 for continuous - float step; - /// logical OR of parameter_flags - uint32_t flags; - /// for PF_ENUM: array of text values (from min to max step 1), otherwise NULL - const char **choices; - /// parameter label (for use in LV2 label field etc.) - const char *short_name; - /// parameter human-readable name - const char *name; - /// convert from [0, 1] range to [min, max] (applying scaling) - float from_01(double value01) const; - /// convert from [min, max] to [0, 1] range (applying reverse scaling) - double to_01(float value) const; - /// stringify (in sensible way) - std::string to_string(float value) const; - /// get required width (for reserving GUI space) - int get_char_count() const; - /// get increment step based on step value (if specified) and other factors - float get_increment() const; -}; - -struct cairo_iface -{ - virtual void set_source_rgba(float r, float g, float b, float a = 1.f) = 0; - virtual void set_line_width(float width) = 0; - virtual ~cairo_iface() {} -}; - -struct progress_report_iface -{ - virtual void report_progress(float percentage, const std::string &message) = 0; - virtual ~progress_report_iface() {} -}; - -/// 'provides live line graph values' interface -struct line_graph_iface -{ - /// Obtain subindex'th graph of parameter 'index' - /// @param index parameter/graph number (usually tied to particular plugin control port) - /// @param subindex graph number (there may be multiple overlaid graphs for one parameter, eg. for monosynth 2x12dB filters) - /// @param data buffer for normalized output values - /// @param points number of points to fill - /// @param context cairo context to adjust (for multicolour graphs etc.) - /// @retval true graph data was returned; subindex+1 graph may or may not be available - /// @retval false graph data was not returned; subindex+1 graph does not exist either - virtual bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const { return false; } - - /// Obtain subindex'th dot of parameter 'index' - /// @param index parameter/dot number (usually tied to particular plugin control port) - /// @param subindex dot number (there may be multiple dots graphs for one parameter) - virtual bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const { return false; } - - /// Obtain subindex'th dot of parameter 'index' - /// @param index parameter/dot number (usually tied to particular plugin control port) - /// @param subindex dot number (there may be multiple dots graphs for one parameter) - virtual bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const { return false; } - - /// Obtain subindex'th static graph of parameter index (static graphs are only dependent on parameter value, not plugin state) - /// @param index parameter/graph number (usually tied to particular plugin control port) - /// @param subindex graph number (there may be multiple overlaid graphs for one parameter, eg. for monosynth 2x12dB filters) - /// @param value parameter value to pick the graph for - /// @param data buffer for normalized output values - /// @param points number of points to fill - /// @param context cairo context to adjust (for multicolour graphs etc.) - /// @retval true graph data was returned; subindex+1 graph may or may not be available - /// @retval false graph data was not returned; subindex+1 graph does not exist either - virtual bool get_static_graph(int index, int subindex, float value, float *data, int points, cairo_iface *context) const { return false; } - - /// Return which graphs need to be redrawn and which can be cached for later reuse - /// @param index Parameter/graph number (usually tied to particular plugin control port) - /// @param generation 0 (at start) or the last value returned by the function (corresponds to a set of input values) - /// @param subindex_graph First graph that has to be redrawn (because it depends on values that might have changed) - /// @param subindex_dot First dot that has to be redrawn - /// @param subindex_gridline First gridline/legend that has to be redrawn - /// @retval Current generation (to pass when calling the function next time); if different than passed generation value, call the function again to retrieve which graph offsets should be put into cache - virtual int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const { subindex_graph = subindex_dot = subindex_gridline = 0; return 0; } - - /// Standard destructor to make compiler happy - virtual ~line_graph_iface() {} -}; - -enum table_column_type -{ - TCT_UNKNOWN, ///< guard invalid type - TCT_FLOAT, ///< float value (encoded as C locale string) - TCT_ENUM, ///< enum value (see: 'values' array in table_column_info) - encoded as string base 10 representation of integer - TCT_STRING, ///< string value (encoded as C-escaped string) - TCT_OBJECT, ///< external object, encoded as string - TCT_LABEL, ///< string value (encoded as C-escaped string) -}; - -/// parameters of -struct table_column_info -{ - const char *name; ///< column label - table_column_type type; ///< column data type - float min; ///< minimum value (for float) - float max; ///< maximum value (for float and enum) - float def_value; ///< default value (for float and enum) - const char **values; ///< NULL unless a TCT_ENUM, where it represents a NULL-terminated list of choices -}; - -/// 'has string parameters containing tabular data' interface -struct table_metadata_iface -{ - /// retrieve the table layout for specific parameter - virtual const table_column_info *get_table_columns() const = 0; - - /// return the fixed number of rows, or 0 if the number of rows is variable - virtual uint32_t get_table_rows() const = 0; - - virtual ~table_metadata_iface() {} -}; - -/// 'may receive configure variables' interface -struct send_configure_iface -{ - /// Called to set configure variable - /// @param key variable name - /// @param value variable content - virtual void send_configure(const char *key, const char *value) = 0; - - virtual ~send_configure_iface() {} -}; - -/// 'may receive new status values' interface -struct send_updates_iface -{ - /// Called to set configure variable - /// @param key variable name - /// @param value variable content - virtual void send_status(const char *key, const char *value) = 0; - - virtual ~send_updates_iface() {} -}; - -struct plugin_command_info; - -/// General information about the plugin - @todo XXXKF lacks the "new" id-label-name triple -struct ladspa_plugin_info -{ - /// LADSPA ID - uint32_t unique_id; - /// plugin short name (camel case) - const char *label; - /// plugin human-readable name - const char *name; - /// maker (author) - const char *maker; - /// copyright notice - const char *copyright; - /// plugin type for LRDF/LV2 - const char *plugin_type; -}; - -/// An interface returning metadata about a plugin -struct plugin_metadata_iface -{ - /// @return plugin long name - virtual const char *get_name() const = 0; - /// @return plugin LV2 label - virtual const char *get_id() const = 0; - /// @return plugin human-readable label - virtual const char *get_label() const = 0; - /// @return total number of parameters - virtual int get_param_count() const = 0; - /// Return custom XML - virtual const char *get_gui_xml() const = 0; - /// @return number of audio inputs - virtual int get_input_count() const =0; - /// @return number of audio outputs - virtual int get_output_count() const =0; - /// @return number of optional inputs - virtual int get_inputs_optional() const =0; - /// @return number of optional outputs - virtual int get_outputs_optional() const =0; - /// @return true if plugin can work in hard-realtime conditions - virtual bool is_rt_capable() const =0; - /// @return true if plugin has MIDI input - virtual bool get_midi() const =0; - /// @return true if plugin has MIDI input - virtual bool requires_midi() const =0; - /// @return port offset of first control (parameter) port (= number of audio inputs + number of audio outputs in all existing plugins as for 1 Aug 2008) - virtual int get_param_port_offset() const = 0; - /// @return NULL-terminated list of menu commands - virtual plugin_command_info *get_commands() const { return NULL; } - /// @return description structure for given parameter - virtual const parameter_properties *get_param_props(int param_no) const = 0; - /// @return retrieve names of audio ports (@note control ports are named in parameter_properties, not here) - virtual const char **get_port_names() const = 0; - /// @return description structure for the plugin - virtual const ladspa_plugin_info &get_plugin_info() const = 0; - /// is a given parameter a control voltage? - virtual bool is_cv(int param_no) const = 0; - /// is the given parameter non-interpolated? - virtual bool is_noisy(int param_no) const = 0; - /// does the plugin require string port extension? (or DSSI configure) may be slow - virtual bool requires_configure() const = 0; - /// obtain array of names of configure variables (or NULL is none needed) - virtual const char *const *get_configure_vars() const { return NULL; } - /// @return table_metadata_iface if any - virtual const table_metadata_iface *get_table_metadata_iface(const char *key) const { return NULL; } - - /// Do-nothing destructor to silence compiler warning - virtual ~plugin_metadata_iface() {} -}; - -/// Interface for host-GUI-plugin interaction (should be really split in two, but ... meh) -struct plugin_ctl_iface -{ - /// @return value of given parameter - virtual float get_param_value(int param_no) = 0; - /// Set value of given parameter - virtual void set_param_value(int param_no, float value) = 0; - /// Load preset with given number - virtual bool activate_preset(int bank, int program) = 0; - /// @return volume level for port'th port (if supported by the implementation, currently only jack_host implements that by measuring signal level on plugin ports) - virtual float get_level(unsigned int port)=0; - /// Execute menu command with given number - virtual void execute(int cmd_no)=0; - /// Set a configure variable on a plugin - virtual char *configure(const char *key, const char *value) = 0; - /// Send all configure variables set within a plugin to given destination (which may be limited to only those that plugin understands) - virtual void send_configures(send_configure_iface *)=0; - /// Restore all state (parameters and configure vars) to default values - implemented in giface.cpp - virtual void clear_preset(); - /// Call a named function in a plugin - this will most likely be redesigned soon - and never used - /// @retval false call has failed, result contains an error message - virtual bool blobcall(const char *command, const std::string &request, std::string &result) { result = "Call not supported"; return false; } - /// Update status variables changed since last_serial - /// @return new last_serial - virtual int send_status_updates(send_updates_iface *sui, int last_serial) = 0; - /// Return metadata object - virtual const plugin_metadata_iface *get_metadata_iface() const = 0; - /// @return line_graph_iface if any - virtual const line_graph_iface *get_line_graph_iface() const = 0; - /// Do-nothing destructor to silence compiler warning - virtual ~plugin_ctl_iface() {} -}; - -struct plugin_list_info_iface; - -/// A class to retrieve and query the list of Calf plugins -class plugin_registry -{ -public: - typedef std::vector plugin_vector; -private: - plugin_vector plugins; - plugin_registry(); -public: - /// Get the singleton object. - static plugin_registry &instance(); - - /// Get all plugin metadata objects - const plugin_vector &get_all() { return plugins; } - /// Get single plugin metadata object by URI - const plugin_metadata_iface *get_by_uri(const char *URI); - /// Get single plugin metadata object by URI - const plugin_metadata_iface *get_by_id(const char *id, bool case_sensitive = false); -}; - -/// Load and strdup a text file with GUI definition -extern const char *load_gui_xml(const std::string &plugin_id); - -/// Interface to audio processing plugins (the real things, not only metadata) -struct audio_module_iface -{ - /// Handle MIDI Note On - virtual void note_on(int channel, int note, int velocity) = 0; - /// Handle MIDI Note Off - virtual void note_off(int channel, int note, int velocity) = 0; - /// Handle MIDI Program Change - virtual void program_change(int channel, int program) = 0; - /// Handle MIDI Control Change - virtual void control_change(int channel, int controller, int value) = 0; - /// Handle MIDI Pitch Bend - /// @param value pitch bend value (-8192 to 8191, defined as in MIDI ie. 8191 = 200 ct by default) - virtual void pitch_bend(int channel, int value) = 0; - /// Handle MIDI Channel Pressure - /// @param value channel pressure (0 to 127) - virtual void channel_pressure(int channel, int value) = 0; - /// Called when params are changed (before processing) - virtual void params_changed() = 0; - /// LADSPA-esque activate function, except it is called after ports are connected, not before - virtual void activate() = 0; - /// LADSPA-esque deactivate function - virtual void deactivate() = 0; - /// Set sample rate for the plugin - virtual void set_sample_rate(uint32_t sr) = 0; - /// Execute menu command with given number - virtual void execute(int cmd_no) = 0; - /// DSSI configure call, value = NULL = reset to default - virtual char *configure(const char *key, const char *value) = 0; - /// Send all understood configure vars (none by default) - virtual void send_configures(send_configure_iface *sci) = 0; - /// Send all supported status vars (none by default) - virtual int send_status_updates(send_updates_iface *sui, int last_serial) = 0; - /// Reset parameter values for epp:trigger type parameters (ones activated by oneshot push button instead of check box) - virtual void params_reset() = 0; - /// Called after instantiating (after all the feature pointers are set - including interfaces like progress_report_iface) - virtual void post_instantiate() = 0; - /// Return the arrays of port buffer pointers - virtual void get_port_arrays(float **&ins_ptrs, float **&outs_ptrs, float **¶ms_ptrs) = 0; - /// Return metadata object - virtual const plugin_metadata_iface *get_metadata_iface() const = 0; - /// Set the progress report interface to communicate progress to - virtual void set_progress_report_iface(progress_report_iface *iface) = 0; - /// Clear a part of output buffers that have 0s at mask; subdivide the buffer so that no runs > MAX_SAMPLE_RUN are fed to process function - virtual uint32_t process_slice(uint32_t offset, uint32_t end) = 0; - /// The audio processing loop; assumes numsamples <= MAX_SAMPLE_RUN, for larger buffers, call process_slice - virtual uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) = 0; - /// Message port processing function - virtual uint32_t message_run(const void *valid_ports, void *output_ports) = 0; - /// @return line_graph_iface if any - virtual const line_graph_iface *get_line_graph_iface() const = 0; - virtual ~audio_module_iface() {} -}; - -/// Empty implementations for plugin functions. -template -class audio_module: public Metadata, public audio_module_iface -{ -public: - typedef Metadata metadata_type; - using Metadata::in_count; - using Metadata::out_count; - using Metadata::param_count; - float *ins[Metadata::in_count]; - float *outs[Metadata::out_count]; - float *params[Metadata::param_count]; - - progress_report_iface *progress_report; - - audio_module() { - progress_report = NULL; - memset(ins, 0, sizeof(ins)); - memset(outs, 0, sizeof(outs)); - memset(params, 0, sizeof(params)); - } - - /// Handle MIDI Note On - void note_on(int channel, int note, int velocity) {} - /// Handle MIDI Note Off - void note_off(int channel, int note, int velocity) {} - /// Handle MIDI Program Change - void program_change(int channel, int program) {} - /// Handle MIDI Control Change - void control_change(int channel, int controller, int value) {} - /// Handle MIDI Pitch Bend - /// @param value pitch bend value (-8192 to 8191, defined as in MIDI ie. 8191 = 200 ct by default) - void pitch_bend(int channel, int value) {} - /// Handle MIDI Channel Pressure - /// @param value channel pressure (0 to 127) - void channel_pressure(int channel, int value) {} - /// Called when params are changed (before processing) - void params_changed() {} - /// LADSPA-esque activate function, except it is called after ports are connected, not before - void activate() {} - /// LADSPA-esque deactivate function - void deactivate() {} - /// Set sample rate for the plugin - void set_sample_rate(uint32_t sr) { } - /// Execute menu command with given number - void execute(int cmd_no) {} - /// DSSI configure call - virtual char *configure(const char *key, const char *value) { return NULL; } - /// Send all understood configure vars (none by default) - void send_configures(send_configure_iface *sci) {} - /// Send all supported status vars (none by default) - int send_status_updates(send_updates_iface *sui, int last_serial) { return last_serial; } - /// Reset parameter values for epp:trigger type parameters (ones activated by oneshot push button instead of check box) - void params_reset() {} - /// Called after instantiating (after all the feature pointers are set - including interfaces like progress_report_iface) - void post_instantiate() {} - /// Handle 'message context' port message - /// @arg output_ports pointer to bit array of output port "changed" flags, note that 0 = first audio input, not first parameter (use input_count + output_count) - uint32_t message_run(const void *valid_ports, void *output_ports) { - fprintf(stderr, "ERROR: message run not implemented\n"); - return 0; - } - /// Return the array of input port pointers - virtual void get_port_arrays(float **&ins_ptrs, float **&outs_ptrs, float **¶ms_ptrs) - { - ins_ptrs = ins; - outs_ptrs = outs; - params_ptrs = params; - } - /// Return metadata object - virtual const plugin_metadata_iface *get_metadata_iface() const { return this; } - /// Set the progress report interface to communicate progress to - virtual void set_progress_report_iface(progress_report_iface *iface) { progress_report = iface; } - - /// utility function: zero port values if mask is 0 - inline void zero_by_mask(uint32_t mask, uint32_t offset, uint32_t nsamples) - { - for (int i=0; i(this); } -}; - -#if USE_EXEC_GUI || USE_DSSI - -enum line_graph_item -{ - LGI_END = 0, - LGI_GRAPH, - LGI_SUBGRAPH, - LGI_LEGEND, - LGI_DOT, - LGI_END_ITEM, - LGI_SET_RGBA, - LGI_SET_WIDTH, -}; - -/// A class to send status updates via OSC -struct dssi_feedback_sender -{ - /// OSC client object used to send updates - osctl::osc_client *client; - /// Is client shared with something else? - bool is_client_shared; - /// Quit flag (used to terminate the thread) - bool quit; - /// Indices of graphs to send - std::vector indices; - /// Source for the graph data (interface to marshal) - const calf_plugins::line_graph_iface *graph; - - /// Create using a new client - dssi_feedback_sender(const char *URI, const line_graph_iface *_graph); - dssi_feedback_sender(osctl::osc_client *_client, const line_graph_iface *_graph); - void add_graphs(const calf_plugins::parameter_properties *props, int num_params); - void update(); - ~dssi_feedback_sender(); -}; -#endif - -/// Metadata base class template, to provide default versions of interface functions -template -class plugin_metadata: public plugin_metadata_iface -{ -public: - static const char *port_names[]; - static parameter_properties param_props[]; - static ladspa_plugin_info plugin_info; - typedef plugin_metadata metadata_class; - - // These below are stock implementations based on enums and static members in Metadata classes - // they may be overridden to provide more interesting functionality - - const char *get_name() const { return Metadata::impl_get_name(); } - const char *get_id() const { return Metadata::impl_get_id(); } - const char *get_label() const { return Metadata::impl_get_label(); } - int get_input_count() const { return Metadata::in_count; } - int get_output_count() const { return Metadata::out_count; } - int get_inputs_optional() const { return Metadata::ins_optional; } - int get_outputs_optional() const { return Metadata::outs_optional; } - int get_param_count() const { return Metadata::param_count; } - bool get_midi() const { return Metadata::support_midi; } - bool requires_midi() const { return Metadata::require_midi; } - bool is_rt_capable() const { return Metadata::rt_capable; } - int get_param_port_offset() const { return Metadata::in_count + Metadata::out_count; } - const char *get_gui_xml() const { static const char *data_ptr = calf_plugins::load_gui_xml(get_id()); return data_ptr; } - plugin_command_info *get_commands() const { return NULL; } - const parameter_properties *get_param_props(int param_no) const { return ¶m_props[param_no]; } - const char **get_port_names() const { return port_names; } - bool is_cv(int param_no) const { return true; } - bool is_noisy(int param_no) const { return false; } - const ladspa_plugin_info &get_plugin_info() const { return plugin_info; } - bool requires_configure() const { return false; } -}; - -#define CALF_PORT_NAMES(name) template<> const char *::plugin_metadata::port_names[] -#define CALF_PORT_PROPS(name) template<> parameter_properties plugin_metadata::param_props[name##_metadata::param_count + 1] -#define CALF_PLUGIN_INFO(name) template<> calf_plugins::ladspa_plugin_info plugin_metadata::plugin_info -#define PLUGIN_NAME_ID_LABEL(name, id, label) \ - static const char *impl_get_name() { return name; } \ - static const char *impl_get_id() { return id; } \ - static const char *impl_get_label() { return label; } \ - -extern const char *calf_copyright_info; - -bool get_freq_gridline(int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context, bool use_frequencies = true, float res = 256, float ofs = 0.4); - -/// convert amplitude value to normalized grid-ish value -static inline float dB_grid(float amp, float res = 256, float ofs = 0.4) -{ - return log(amp) * (1.0 / log(res)) + ofs; -} - -template -static bool get_graph(Fx &fx, int subindex, float *data, int points, float res = 256, float ofs = 0.4) -{ - for (int i = 0; i < points; i++) - { - double freq = 20.0 * pow (20000.0 / 20.0, i * 1.0 / points); - data[i] = dB_grid(fx.freq_gain(subindex, freq, fx.srate), res, ofs); - } - return true; -} - -/// convert normalized grid-ish value back to amplitude value -static inline float dB_grid_inv(float pos) -{ - return pow(256.0, pos - 0.4); -} - -/// Line graph interface implementation for frequency response graphs -class frequency_response_line_graph: public line_graph_iface -{ -public: - bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const; - virtual int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const; -}; - -/// set drawing color based on channel index (0 or 1) -void set_channel_color(cairo_iface *context, int channel); - -struct preset_access_iface -{ - virtual void store_preset() = 0; - virtual void activate_preset(int preset, bool builtin) = 0; - virtual ~preset_access_iface() {} -}; - -/// Implementation of table_metadata_iface providing metadata for mod matrices -class mod_matrix_metadata: public table_metadata_iface -{ -public: - /// Mapping modes - enum mapping_mode { - map_positive, ///< 0..100% - map_bipolar, ///< -100%..100% - map_negative, ///< -100%..0% - map_squared, ///< x^2 - map_squared_bipolar, ///< x^2 scaled to -100%..100% - map_antisquared, ///< 1-(1-x)^2 scaled to 0..100% - map_antisquared_bipolar, ///< 1-(1-x)^2 scaled to -100..100% - map_parabola, ///< inverted parabola (peaks at 0.5, then decreases to 0) - map_type_count - }; - const char **mod_src_names, **mod_dest_names; - - mod_matrix_metadata(unsigned int _rows, const char **_src_names, const char **_dest_names); - virtual const table_column_info *get_table_columns() const; - virtual uint32_t get_table_rows() const; - -protected: - /// Column descriptions for table widget - table_column_info table_columns[6]; - - unsigned int matrix_rows; -}; - -/// Check if a given key is either prefix + rows or prefix + i2s(row) + "," + i2s(column) -/// @arg key key to parse -/// @arg prefix table prefix (e.g. "modmatrix:") -/// @arg is_rows[out] set to true if key == prefix + "rows" -/// @arg row[out] if key is of a form: prefix + row + "," + i2s(column), returns row, otherwise returns -1 -/// @arg column[out] if key is of a form: prefix + row + "," + i2s(column), returns row, otherwise returns -1 -/// @retval true if this is one of the recognized string forms -extern bool parse_table_key(const char *key, const char *prefix, bool &is_rows, int &row, int &column); - -#if USE_EXEC_GUI -class table_via_configure -{ -protected: - typedef std::pair coord; - std::vector columns; - std::map values; - int rows; -public: - table_via_configure(); - void configure(const char *key, const char *value); - virtual ~table_via_configure(); -}; -#endif - -}; - -#endif diff --git a/plugins/LadspaEffect/calf/src/calf/inertia.h b/plugins/LadspaEffect/calf/src/calf/inertia.h deleted file mode 100644 index 70ba9ede189..00000000000 --- a/plugins/LadspaEffect/calf/src/calf/inertia.h +++ /dev/null @@ -1,258 +0,0 @@ -/* Calf DSP Library - * Basic "inertia" (parameter smoothing) classes. - * Copyright (C) 2001-2007 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_INERTIA_H -#define __CALF_INERTIA_H - -#include "primitives.h" - -namespace dsp { - -/// Algorithm for a constant time linear ramp -class linear_ramp -{ -public: - int ramp_len; - float mul, delta; -public: - /// Construct for given ramp length - linear_ramp(int _ramp_len) { - ramp_len = _ramp_len; - mul = (float)(1.0f / ramp_len); - delta = 0.f; - } - /// Change ramp length - inline void set_length(int _ramp_len) { - ramp_len = _ramp_len; - mul = (float)(1.0f / ramp_len); - } - inline int length() - { - return ramp_len; - } - inline void start_ramp(float start, float end) - { - delta = mul * (end - start); - } - /// Return value after single step - inline float ramp(float value) - { - return value + delta; - } - /// Return value after many steps - inline float ramp_many(float value, int count) - { - return value + delta * count; - } -}; - -/// Algorithm for a constant time linear ramp -class exponential_ramp -{ -public: - int ramp_len; - float root, delta; -public: - exponential_ramp(int _ramp_len) { - ramp_len = _ramp_len; - root = (float)(1.0f / ramp_len); - delta = 1.0; - } - inline void set_length(int _ramp_len) { - ramp_len = _ramp_len; - root = (float)(1.0f / ramp_len); - } - inline int length() - { - return ramp_len; - } - inline void start_ramp(float start, float end) - { - delta = pow(end / start, root); - } - /// Return value after single step - inline float ramp(float value) - { - return value * delta; - } - /// Return value after many steps - inline float ramp_many(float value, float count) - { - return value * pow(delta, count); - } -}; - -/// Generic inertia using ramping algorithm specified as template argument. The basic idea -/// is producing smooth(ish) output for discrete input, using specified algorithm to go from -/// last output value to input value. It is not the same as classic running average lowpass -/// filter, because ramping time is finite and pre-determined (it calls ramp algorithm's length() -/// function to obtain the expected ramp length) -template -class inertia -{ -public: - float old_value; - float value; - unsigned int count; - Ramp ramp; - -public: - inertia(const Ramp &_ramp, float init_value = 0.f) - : ramp(_ramp) - { - value = old_value = init_value; - count = 0; - } - /// Set value immediately (no inertia) - void set_now(float _value) - { - value = old_value = _value; - count = 0; - } - /// Set with inertia - void set_inertia(float source) - { - if (source != old_value) { - ramp.start_ramp(value, source); - count = ramp.length(); - old_value = source; - } - } - /// Get smoothed value of given source value - inline float get(float source) - { - if (source != old_value) { - ramp.start_ramp(value, source); - count = ramp.length(); - old_value = source; - } - if (!count) - return old_value; - value = ramp.ramp(value); - count--; - if (!count) // finished ramping, set to desired value to get rid of accumulated rounding errors - value = old_value; - return value; - } - /// Get smoothed value assuming no new input - inline float get() - { - if (!count) - return old_value; - value = ramp.ramp(value); - count--; - if (!count) // finished ramping, set to desired value to get rid of accumulated rounding errors - value = old_value; - return value; - } - /// Do one inertia step, without returning the new value and without changing destination value - inline void step() - { - if (count) { - value = ramp.ramp(value); - count--; - if (!count) // finished ramping, set to desired value to get rid of accumulated rounding errors - value = old_value; - } - } - /// Do many inertia steps, without returning the new value and without changing destination value - inline void step_many(unsigned int steps) - { - if (steps < count) { - // Skip only a part of the current ramping period - value = ramp.ramp_many(value, steps); - count -= steps; - if (!count) // finished ramping, set to desired value to get rid of accumulated rounding errors - value = old_value; - } - else - { - // The whole ramping period has been skipped, just go to destination - value = old_value; - count = 0; - } - } - /// Get last smoothed value, without affecting anything - inline float get_last() const - { - return value; - } - /// Is it still ramping? - inline bool active() const - { - return count > 0; - } -}; - -class once_per_n -{ -public: - unsigned int frequency; - unsigned int left; -public: - once_per_n(unsigned int _frequency) - : frequency(_frequency), left(_frequency) - {} - inline void start() - { - left = frequency; - } - /// Set timer to "elapsed" state (elapsed() will return true during next call) - inline void signal() - { - left = 0; - } - inline unsigned int get(unsigned int desired) - { - if (desired > left) { - desired = left; - left = 0; - return desired; - } - left -= desired; - return desired; - } - inline bool elapsed() - { - if (!left) { - left = frequency; - return true; - } - return false; - } -}; - -class gain_smoothing: public inertia -{ -public: - gain_smoothing() - : inertia(linear_ramp(64)) - { - } - void set_sample_rate(int sr) - { - ramp = linear_ramp(sr / 100); - } - // to change param, use set_inertia(value) - // to read param, use get() -}; - -} - -#endif diff --git a/plugins/LadspaEffect/calf/src/calf/ladspa_wrap.h b/plugins/LadspaEffect/calf/src/calf/ladspa_wrap.h deleted file mode 100644 index daf7ae258f5..00000000000 --- a/plugins/LadspaEffect/calf/src/calf/ladspa_wrap.h +++ /dev/null @@ -1,131 +0,0 @@ -/* 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 ~ladspa_instance(); - 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/src/calf/loudness.h b/plugins/LadspaEffect/calf/src/calf/loudness.h deleted file mode 100644 index 62a00b5be83..00000000000 --- a/plugins/LadspaEffect/calf/src/calf/loudness.h +++ /dev/null @@ -1,90 +0,0 @@ -/* Calf DSP Library - * A-weighting filter for - * Copyright (C) 2001-2007 Krzysztof Foltman - * - * Most of code in this file is based on freely - * available other work of other people (filter equations). - * - * 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_LOUDNESS_H -#define __CALF_LOUDNESS_H - -#include "biquad.h" - -namespace dsp { - -class aweighter { -public: - biquad_d2 bq1, bq2, bq3; - - /// Produce one output sample from one input sample - float process(float sample) - { - return bq1.process(bq2.process(bq3.process(sample))); - } - - /// Set sample rate (updates filter coefficients) - void set(float sr) - { - // analog coeffs taken from: http://www.diracdelta.co.uk/science/source/a/w/aweighting/source.html - // first we need to adjust them by doing some obscene sort of reverse pre-warping (a broken one, too!) - float f1 = biquad_coeffs::unwarpf(20.6f, sr); - float f2 = biquad_coeffs::unwarpf(107.7f, sr); - float f3 = biquad_coeffs::unwarpf(738.f, sr); - float f4 = biquad_coeffs::unwarpf(12200.f, sr); - // then map s domain to z domain using bilinear transform - // note: f1 and f4 are double poles - bq1.set_bilinear(0, 0, 1, f1*f1, 2 * f1, 1); - bq2.set_bilinear(1, 0, 0, f2*f3, f2 + f3, 1); - bq3.set_bilinear(0, 0, 1, f4*f4, 2 * f4, 1); - // the coeffs above give non-normalized value, so it should be normalized to produce 0dB at 1 kHz - // find actual gain - float gain1kHz = freq_gain(1000.0, sr); - // divide one filter's x[n-m] coefficients by that value - float gc = 1.0 / gain1kHz; - bq1.a0 *= gc; - bq1.a1 *= gc; - bq1.a2 *= gc; - } - - /// Reset to zero if at risk of denormals - void sanitize() - { - bq1.sanitize(); - bq2.sanitize(); - bq3.sanitize(); - } - - /// Reset state to zero - void reset() - { - bq1.reset(); - bq2.reset(); - bq3.reset(); - } - - /// Gain and a given frequency - float freq_gain(float freq, float sr) - { - return bq1.freq_gain(freq, sr) * bq2.freq_gain(freq, sr) * bq3.freq_gain(freq, sr); - } - -}; - -}; - -#endif diff --git a/plugins/LadspaEffect/calf/src/calf/lv2_external_ui.h b/plugins/LadspaEffect/calf/src/calf/lv2_external_ui.h deleted file mode 100644 index 242271ecc46..00000000000 --- a/plugins/LadspaEffect/calf/src/calf/lv2_external_ui.h +++ /dev/null @@ -1,101 +0,0 @@ -/* -*- Mode: C ; c-basic-offset: 2 -*- */ -/***************************************************************************** - * - * This work is in public domain. - * - * This file 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. - * - * If you have questions, contact Nedko Arnaudov or - * ask in #lad channel, FreeNode IRC network. - * - *****************************************************************************/ - -#ifndef LV2_EXTERNAL_UI_H__5AFE09A5_0FB7_47AF_924E_2AF0F8DE8873__INCLUDED -#define LV2_EXTERNAL_UI_H__5AFE09A5_0FB7_47AF_924E_2AF0F8DE8873__INCLUDED - -/** UI extension suitable for out-of-process UIs */ -#define LV2_EXTERNAL_UI_URI "http://lv2plug.in/ns/extensions/ui#external" - -#ifdef __cplusplus -extern "C" { -#endif -#if 0 -} /* Adjust editor indent */ -#endif - -/** - * When LV2_EXTERNAL_UI_URI UI is instantiated, the returned - * LV2UI_Widget handle must be cast to pointer to struct lv2_external_ui. - * UI is created in invisible state. - */ -struct lv2_external_ui -{ - /** - * Host calls this function regulary. UI library implementing the - * callback may do IPC or redraw the UI. - * - * @param _this_ the UI context - */ - void (* run)(struct lv2_external_ui * _this_); - - /** - * Host calls this function to make the plugin UI visible. - * - * @param _this_ the UI context - */ - void (* show)(struct lv2_external_ui * _this_); - - /** - * Host calls this function to make the plugin UI invisible again. - * - * @param _this_ the UI context - */ - void (* hide)(struct lv2_external_ui * _this_); -}; - -#define LV2_EXTERNAL_UI_RUN(ptr) (ptr)->run(ptr) -#define LV2_EXTERNAL_UI_SHOW(ptr) (ptr)->show(ptr) -#define LV2_EXTERNAL_UI_HIDE(ptr) (ptr)->hide(ptr) - -/** - * On UI instantiation, host must supply LV2_EXTERNAL_UI_URI - * feature. LV2_Feature::data must be pointer to struct lv2_external_ui_host. */ -struct lv2_external_ui_host -{ - /** - * Callback that plugin UI will call - * when UI (GUI window) is closed by user. - * This callback wil; be called during execution of lv2_external_ui::run() - * (i.e. not from background thread). - * - * After this callback is called, UI is defunct. Host must call - * LV2UI_Descriptor::cleanup(). If host wants to make the UI visible - * again UI must be reinstantiated. - * - * @param controller Host context associated with plugin UI, as - * supplied to LV2UI_Descriptor::instantiate() - */ - void (* ui_closed)(LV2UI_Controller controller); - - /** - * Optional (may be NULL) "user friendly" identifier which the UI - * may display to allow a user to easily associate this particular - * UI instance with the correct plugin instance as it is represented - * by the host (e.g. "track 1" or "channel 4"). - * - * If supplied by host, the string will be referenced only during - * LV2UI_Descriptor::instantiate() - */ - const char * plugin_human_id; -}; - -#if 0 -{ /* Adjust editor indent */ -#endif -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* #ifndef LV2_EXTERNAL_UI_H__5AFE09A5_0FB7_47AF_924E_2AF0F8DE8873__INCLUDED */ diff --git a/plugins/LadspaEffect/calf/src/calf/lv2helpers.h b/plugins/LadspaEffect/calf/src/calf/lv2helpers.h deleted file mode 100644 index 21e6cfc00f1..00000000000 --- a/plugins/LadspaEffect/calf/src/calf/lv2helpers.h +++ /dev/null @@ -1,30 +0,0 @@ -/* Calf DSP Library - * LV2-related helper classes and functions - * - * Copyright (C) 2001-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_LV2HELPERS_H -#define CALF_LV2HELPERS_H - -#if USE_LV2 - -#include -#include - -#endif -#endif diff --git a/plugins/LadspaEffect/calf/src/calf/lv2wrap.h b/plugins/LadspaEffect/calf/src/calf/lv2wrap.h deleted file mode 100644 index f204db6ca43..00000000000 --- a/plugins/LadspaEffect/calf/src/calf/lv2wrap.h +++ /dev/null @@ -1,350 +0,0 @@ -/* Calf DSP Library - * LV2 wrapper templates - * - * Copyright (C) 2001-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_LV2WRAP_H -#define CALF_LV2WRAP_H - -#if USE_LV2 - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace calf_plugins { - -struct lv2_instance: public plugin_ctl_iface, public progress_report_iface -{ - const plugin_metadata_iface *metadata; - audio_module_iface *module; - bool set_srate; - int srate_to_set; - LV2_Event_Buffer *event_data; - LV2_URI_Map_Feature *uri_map; - LV2_Event_Feature *event_feature; - uint32_t midi_event_type; - LV2_Progress *progress_report_feature; - float **ins, **outs, **params; - int out_count; - int real_param_count; - lv2_instance(audio_module_iface *_module) - { - module = _module; - module->get_port_arrays(ins, outs, params); - metadata = module->get_metadata_iface(); - out_count = metadata->get_output_count(); - real_param_count = metadata->get_param_count(); - - uri_map = NULL; - event_data = NULL; - progress_report_feature = NULL; - midi_event_type = 0xFFFFFFFF; - - srate_to_set = 44100; - set_srate = true; - } - /// This, and not Module::post_instantiate, is actually called by lv2_wrapper class - void post_instantiate() - { - if (progress_report_feature) - module->set_progress_report_iface(this); - module->post_instantiate(); - } - virtual bool activate_preset(int bank, int program) { - return false; - } - virtual float get_level(unsigned int port) { return 0.f; } - virtual void execute(int cmd_no) { - module->execute(cmd_no); - } - virtual void report_progress(float percentage, const std::string &message) { - if (progress_report_feature) - (*progress_report_feature->progress)(progress_report_feature->context, percentage, !message.empty() ? message.c_str() : NULL); - } - void send_configures(send_configure_iface *sci) { - module->send_configures(sci); - } - void impl_restore(LV2_State_Retrieve_Function retrieve, void *callback_data) - { - const char *const *vars = module->get_metadata_iface()->get_configure_vars(); - if (!vars) - return; - assert(uri_map); - uint32_t string_type = uri_map->uri_to_id(uri_map->callback_data, NULL, "http://lv2plug.in/ns/ext/atom#String"); - assert(string_type); - for (unsigned int i = 0; vars[i]; i++) - { - const uint32_t key = uri_map->uri_to_id(uri_map->callback_data, NULL, vars[i]); - size_t len = 0; - uint32_t type = 0; - uint32_t flags = 0; - const void *ptr = (*retrieve)(callback_data, key, &len, &type, &flags); - if (ptr) - { - if (type != string_type) - fprintf(stderr, "Warning: type is %d, expected %d\n", (int)type, (int)string_type); - printf("Calling configure on %s\n", vars[i]); - configure(vars[i], std::string((const char *)ptr, len).c_str()); - } - else - configure(vars[i], NULL); - } - } - char *configure(const char *key, const char *value) { - // disambiguation - the plugin_ctl_iface version is just a stub, so don't use it - return module->configure(key, value); - } - - void process_events(uint32_t &offset) { - struct LV2_Midi_Event: public LV2_Event { - unsigned char data[1]; - }; - unsigned char *data = (unsigned char *)(event_data->data); - for (uint32_t i = 0; i < event_data->event_count; i++) { - LV2_Midi_Event *item = (LV2_Midi_Event *)data; - uint32_t ts = item->frames; - // printf("Event: timestamp %d subframes %d type %d vs %d\n", item->frames, item->subframes, item->type, mod->midi_event_type); - if (ts > offset) - { - module->process_slice(offset, ts); - offset = ts; - } - if (item->type == midi_event_type) - { - // printf("Midi message %x %x %x %x %d\n", item->data[0], item->data[1], item->data[2], item->data[3], item->size); - int channel = item->data[0] & 15; - switch(item->data[0] >> 4) - { - case 8: module->note_off(channel, item->data[1], item->data[2]); break; - case 9: module->note_on(channel, item->data[1], item->data[2]); break; - case 11: module->control_change(channel, item->data[1], item->data[2]); break; - case 12: module->program_change(channel, item->data[1]); break; - case 13: module->channel_pressure(channel, item->data[1]); break; - case 14: module->pitch_bend(channel, item->data[1] + 128 * item->data[2] - 8192); break; - } - } - else - if (item->type == 0 && event_feature) - event_feature->lv2_event_unref(event_feature->callback_data, item); - // printf("timestamp %f item size %d first byte %x\n", item->timestamp, item->size, item->data[0]); - data += ((sizeof(LV2_Event) + item->size + 7))&~7; - } - } - - virtual float get_param_value(int param_no) - { - // XXXKF hack - if (param_no >= real_param_count) - return 0; - return (*params)[param_no]; - } - virtual void set_param_value(int param_no, float value) - { - // XXXKF hack - if (param_no >= real_param_count) - return; - *params[param_no] = value; - } - virtual const plugin_metadata_iface *get_metadata_iface() const { return metadata; } - virtual const line_graph_iface *get_line_graph_iface() const { return module->get_line_graph_iface(); } - virtual int send_status_updates(send_updates_iface *sui, int last_serial) { return module->send_status_updates(sui, last_serial); } -}; - -struct LV2_Calf_Descriptor { - plugin_ctl_iface *(*get_pci)(LV2_Handle Instance); -}; - -template -struct lv2_wrapper -{ - typedef lv2_instance instance; - static LV2_Descriptor descriptor; - static LV2_Calf_Descriptor calf_descriptor; - static LV2_State_Interface state_iface; - std::string uri; - - lv2_wrapper() - { - ladspa_plugin_info &info = Module::plugin_info; - uri = "http://calf.sourceforge.net/plugins/" + std::string(info.label); - descriptor.URI = uri.c_str(); - descriptor.instantiate = cb_instantiate; - descriptor.connect_port = cb_connect; - descriptor.activate = cb_activate; - descriptor.run = cb_run; - descriptor.deactivate = cb_deactivate; - descriptor.cleanup = cb_cleanup; - descriptor.extension_data = cb_ext_data; - state_iface.save = cb_state_save; - state_iface.restore = cb_state_restore; - calf_descriptor.get_pci = cb_get_pci; - } - - static void cb_connect(LV2_Handle Instance, uint32_t port, void *DataLocation) - { - instance *const mod = (instance *)Instance; - const plugin_metadata_iface *md = mod->metadata; - unsigned long ins = md->get_input_count(); - unsigned long outs = md->get_output_count(); - unsigned long params = md->get_param_count(); - if (port < ins) - mod->ins[port] = (float *)DataLocation; - else if (port < ins + outs) - mod->outs[port - ins] = (float *)DataLocation; - else if (port < ins + outs + params) { - int i = port - ins - outs; - mod->params[i] = (float *)DataLocation; - } - else if (md->get_midi() && port == ins + outs + params) { - mod->event_data = (LV2_Event_Buffer *)DataLocation; - } - } - - static void cb_activate(LV2_Handle Instance) - { - instance *const mod = (instance *)Instance; - mod->set_srate = true; - } - - static void cb_deactivate(LV2_Handle Instance) - { - instance *const mod = (instance *)Instance; - mod->module->deactivate(); - } - - static LV2_Handle cb_instantiate(const LV2_Descriptor * Descriptor, double sample_rate, const char *bundle_path, const LV2_Feature *const *features) - { - instance *mod = new instance(new Module); - // XXXKF some people use fractional sample rates; we respect them ;-) - mod->srate_to_set = (uint32_t)sample_rate; - mod->set_srate = true; - while(*features) - { - if (!strcmp((*features)->URI, LV2_URI_MAP_URI)) - { - mod->uri_map = (LV2_URI_Map_Feature *)((*features)->data); - mod->midi_event_type = mod->uri_map->uri_to_id( - mod->uri_map->callback_data, - "http://lv2plug.in/ns/ext/event", - "http://lv2plug.in/ns/ext/midi#MidiEvent"); - } - else if (!strcmp((*features)->URI, LV2_EVENT_URI)) - { - mod->event_feature = (LV2_Event_Feature *)((*features)->data); - } - else if (!strcmp((*features)->URI, LV2_PROGRESS_URI)) - { - mod->progress_report_feature = (LV2_Progress *)((*features)->data); - } - features++; - } - mod->post_instantiate(); - return mod; - } - static plugin_ctl_iface *cb_get_pci(LV2_Handle Instance) - { - return static_cast(Instance); - } - - static void cb_run(LV2_Handle Instance, uint32_t SampleCount) - { - instance *const inst = (instance *)Instance; - audio_module_iface *mod = inst->module; - if (inst->set_srate) { - mod->set_sample_rate(inst->srate_to_set); - mod->activate(); - inst->set_srate = false; - } - mod->params_changed(); - uint32_t offset = 0; - if (inst->event_data) - { - inst->process_events(offset); - } - inst->module->process_slice(offset, SampleCount); - } - static void cb_cleanup(LV2_Handle Instance) - { - instance *const mod = (instance *)Instance; - delete mod; - } - static const void *cb_ext_data(const char *URI) - { - if (!strcmp(URI, "http://foltman.com/ns/calf-plugin-instance")) - return &calf_descriptor; - if (!strcmp(URI, LV2_STATE_INTERFACE_URI)) - return &state_iface; - return NULL; - } - static void cb_state_save(LV2_Handle Instance, - LV2_State_Store_Function store, LV2_State_Handle handle, - uint32_t flags, const LV2_Feature *const * features) - { - instance *const inst = (instance *)Instance; - struct store_state: public send_configure_iface - { - LV2_State_Store_Function store; - void *callback_data; - instance *inst; - uint32_t string_data_type; - - virtual void send_configure(const char *key, const char *value) - { - (*store)(callback_data, - inst->uri_map->uri_to_id(inst->uri_map->callback_data, NULL, key), - value, - strlen(value) + 1, - string_data_type, - LV2_STATE_IS_POD|LV2_STATE_IS_PORTABLE); - } - }; - // A host that supports State MUST support URI-Map as well. - assert(inst->uri_map); - store_state s; - s.store = store; - s.callback_data = handle; - s.inst = inst; - s.string_data_type = inst->uri_map->uri_to_id(inst->uri_map->callback_data, NULL, "http://lv2plug.in/ns/ext/atom#String"); - - inst->send_configures(&s); - } - static void cb_state_restore(LV2_Handle Instance, - LV2_State_Retrieve_Function retrieve, LV2_State_Handle callback_data, - uint32_t flags, const LV2_Feature *const * features) - { - instance *const inst = (instance *)Instance; - inst->impl_restore(retrieve, callback_data); - } - - static lv2_wrapper &get() { - static lv2_wrapper *instance = new lv2_wrapper; - return *instance; - } -}; - -}; - -#endif -#endif diff --git a/plugins/LadspaEffect/calf/src/calf/metadata.h b/plugins/LadspaEffect/calf/src/calf/metadata.h deleted file mode 100644 index d0035c07bbd..00000000000 --- a/plugins/LadspaEffect/calf/src/calf/metadata.h +++ /dev/null @@ -1,595 +0,0 @@ -/* Calf DSP Library - * Audio module (plugin) metadata - header file - * - * Copyright (C) 2007-2008 Krzysztof Foltman - * Copyright (C) 2008 Thor Harald Johansen - * - * 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_METADATA_H -#define __CALF_METADATA_H - -#include "giface.h" - -#define MONO_VU_METER_PARAMS param_meter_in, param_meter_out, param_clip_in, param_clip_out -#define STEREO_VU_METER_PARAMS param_meter_inL, param_meter_inR, param_meter_outL, param_meter_outR, param_clip_inL, param_clip_inR, param_clip_outL, param_clip_outR - -namespace calf_plugins { - -struct flanger_metadata: public plugin_metadata -{ -public: - enum { par_delay, par_depth, par_rate, par_fb, par_stereo, par_reset, par_amount, par_dryamount, param_count }; - enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true }; - PLUGIN_NAME_ID_LABEL("flanger", "flanger", "Flanger") -}; - -struct phaser_metadata: public plugin_metadata -{ - enum { par_freq, par_depth, par_rate, par_fb, par_stages, par_stereo, par_reset, par_amount, par_dryamount, param_count }; - enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true }; - PLUGIN_NAME_ID_LABEL("phaser", "phaser", "Phaser") -}; - -struct filter_metadata: public plugin_metadata -{ - enum { par_cutoff, par_resonance, par_mode, par_inertia, param_count }; - enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, rt_capable = true, require_midi = false, support_midi = false }; - PLUGIN_NAME_ID_LABEL("filter", "filter", "Filter") - /// do not export mode and inertia as CVs, as those are settings and not parameters - bool is_cv(int param_no) { return param_no != par_mode && param_no != par_inertia; } -}; - -/// Filterclavier - metadata -struct filterclavier_metadata: public plugin_metadata -{ - enum { par_transpose, par_detune, par_max_resonance, par_mode, par_inertia, param_count }; - enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, rt_capable = true, require_midi = true, support_midi = true }; - PLUGIN_NAME_ID_LABEL("filterclavier", "filterclavier", "Filterclavier") - /// do not export mode and inertia as CVs, as those are settings and not parameters - bool is_cv(int param_no) { return param_no != par_mode && param_no != par_inertia; } -}; - -struct reverb_metadata: public plugin_metadata -{ - enum { par_clip, par_meter_wet, par_meter_out, par_decay, par_hfdamp, par_roomsize, par_diffusion, par_amount, par_dry, par_predelay, par_basscut, par_treblecut, param_count }; - enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true }; - PLUGIN_NAME_ID_LABEL("reverb", "reverb", "Reverb") -}; - -struct vintage_delay_metadata: public plugin_metadata -{ - enum { par_bpm, par_divide, par_time_l, par_time_r, par_feedback, par_amount, par_mixmode, par_medium, par_dryamount, par_width, param_count }; - enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, rt_capable = true, support_midi = false, require_midi = false }; - PLUGIN_NAME_ID_LABEL("vintage_delay", "vintagedelay", "Vintage Delay") -}; - -struct rotary_speaker_metadata: public plugin_metadata -{ -public: - enum { par_speed, par_spacing, par_shift, par_moddepth, par_treblespeed, par_bassspeed, par_micdistance, par_reflection, par_am_depth, par_test, par_meter_l, par_meter_h, param_count }; - enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = true, require_midi = false, rt_capable = true }; - PLUGIN_NAME_ID_LABEL("rotary_speaker", "rotaryspeaker", "Rotary Speaker") -}; - -/// A multitap stereo chorus thing - metadata -struct multichorus_metadata: public plugin_metadata -{ -public: - enum { par_delay, par_depth, par_rate, par_stereo, par_voices, par_vphase, par_amount, par_dryamount, par_freq, par_freq2, par_q, par_overlap, param_count }; - enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, rt_capable = true, support_midi = false, require_midi = false }; - PLUGIN_NAME_ID_LABEL("multichorus", "multichorus", "Multi Chorus") -}; - -enum CalfEqMode { - MODE12DB, - MODE24DB, - MODE36DB -}; - -/// Monosynth - metadata -struct monosynth_metadata: public plugin_metadata -{ - enum { wave_saw, wave_sqr, wave_pulse, wave_sine, wave_triangle, wave_varistep, wave_skewsaw, wave_skewsqr, wave_test1, wave_test2, wave_test3, wave_test4, wave_test5, wave_test6, wave_test7, wave_test8, wave_count }; - enum { flt_lp12, flt_lp24, flt_2lp12, flt_hp12, flt_lpbr, flt_hpbr, flt_bp6, flt_2bp6 }; - enum { par_wave1, par_wave2, par_pw1, par_pw2, par_detune, par_osc2xpose, par_oscmode, par_oscmix, par_filtertype, par_cutoff, par_resonance, par_cutoffsep, par_env1tocutoff, par_env1tores, par_env1toamp, - par_env1attack, par_env1decay, par_env1sustain, par_env1fade, par_env1release, - par_keyfollow, par_legato, par_portamento, par_vel2filter, par_vel2amp, par_master, par_pwhlrange, - par_lforate, par_lfodelay, par_lfofilter, par_lfopitch, par_lfopw, par_mwhl_lfo, par_scaledetune, - par_env2tocutoff, par_env2tores, par_env2toamp, - par_env2attack, par_env2decay, par_env2sustain, par_env2fade, par_env2release, - par_stretch1, par_window1, - par_lfo1trig, par_lfo2trig, - par_lfo2rate, par_lfo2delay, - param_count }; - enum { in_count = 0, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = true, require_midi = true, rt_capable = true }; - enum { step_size = 64, step_shift = 6 }; - enum { mod_matrix_slots = 10 }; - enum { - modsrc_none, - modsrc_velocity, - modsrc_pressure, - modsrc_modwheel, - modsrc_env1, - modsrc_env2, - modsrc_lfo1, - modsrc_lfo2, - modsrc_count, - }; - enum { - moddest_none, - moddest_attenuation, - moddest_oscmix, - moddest_cutoff, - moddest_resonance, - moddest_o1detune, - moddest_o2detune, - moddest_o1pw, - moddest_o2pw, - moddest_o1stretch, - moddest_count, - }; - PLUGIN_NAME_ID_LABEL("monosynth", "monosynth", "Monosynth") - - mod_matrix_metadata mm_metadata; - - monosynth_metadata(); - /// Lookup of table edit interface - virtual const table_metadata_iface *get_table_metadata_iface(const char *key) const { if (!strcmp(key, "mod_matrix")) return &mm_metadata; else return NULL; } - const char *const *get_configure_vars() const; -}; - -/// Thor's compressor - metadata -/// Added some meters and stripped the weighting part -struct compressor_metadata: public plugin_metadata -{ - enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true }; - enum { param_bypass, param_level_in, MONO_VU_METER_PARAMS, - param_threshold, param_ratio, param_attack, param_release, param_makeup, param_knee, param_detection, param_stereo_link, param_compression, - param_count }; - PLUGIN_NAME_ID_LABEL("compressor", "compressor", "Compressor") -}; - -/// Markus's sidechain compressor - metadata -struct sidechaincompressor_metadata: public plugin_metadata -{ - enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true }; - enum { param_bypass, param_level_in, MONO_VU_METER_PARAMS, - param_threshold, param_ratio, param_attack, param_release, param_makeup, param_knee, param_detection, param_stereo_link, param_compression, - param_sc_mode, param_f1_freq, param_f2_freq, param_f1_level, param_f2_level, - param_sc_listen, param_f1_active, param_f2_active, param_sc_route, param_sc_level, param_count }; - PLUGIN_NAME_ID_LABEL("sidechaincompressor", "sidechaincompressor", "Sidechain Compressor") -}; - -/// Markus's multibandcompressor - metadata -struct multibandcompressor_metadata: public plugin_metadata -{ - enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true }; - enum { param_bypass, param_level_in, param_level_out, - STEREO_VU_METER_PARAMS, - param_freq0, param_freq1, param_freq2, - param_sep0, param_sep1, param_sep2, - param_q0, param_q1, param_q2, - param_mode, - param_threshold0, param_ratio0, param_attack0, param_release0, param_makeup0, param_knee0, - param_detection0, param_compression0, param_output0, param_bypass0, param_solo0, - param_threshold1, param_ratio1, param_attack1, param_release1, param_makeup1, param_knee1, - param_detection1, param_compression1, param_output1, param_bypass1, param_solo1, - param_threshold2, param_ratio2, param_attack2, param_release2, param_makeup2, param_knee2, - param_detection2, param_compression2, param_output2, param_bypass2, param_solo2, - param_threshold3, param_ratio3, param_attack3, param_release3, param_makeup3, param_knee3, - param_detection3, param_compression3, param_output3, param_bypass3, param_solo3, - param_count }; - PLUGIN_NAME_ID_LABEL("multiband_compressor", "multibandcompressor", "Multiband Compressor") -}; - -/// Markus's deesser - metadata -struct deesser_metadata: public plugin_metadata -{ - enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true }; - enum { param_bypass, param_detected, param_compression, param_detected_led, param_clip_out, - param_detection, param_mode, - param_threshold, param_ratio, param_laxity, param_makeup, - param_f1_freq, param_f2_freq, param_f1_level, param_f2_level, param_f2_q, - param_sc_listen, param_count }; - PLUGIN_NAME_ID_LABEL("deesser", "deesser", "Deesser") -}; - -/// Damiens' Gate - metadata -/// Added some meters and stripped the weighting part -struct gate_metadata: public plugin_metadata -{ - enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true }; - enum { param_bypass, param_level_in, MONO_VU_METER_PARAMS, - param_range, param_threshold, param_ratio, param_attack, param_release, param_makeup, param_knee, param_detection, param_stereo_link, param_gating, - param_count }; - PLUGIN_NAME_ID_LABEL("gate", "gate", "Gate") -}; - -/// Markus's sidechain gate - metadata -struct sidechaingate_metadata: public plugin_metadata -{ - enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true }; - enum { param_bypass, param_level_in, MONO_VU_METER_PARAMS, - param_range, param_threshold, param_ratio, param_attack, param_release, param_makeup, param_knee, param_detection, param_stereo_link, param_gating, - param_sc_mode, param_f1_freq, param_f2_freq, param_f1_level, param_f2_level, - param_sc_listen, param_f1_active, param_f2_active, param_sc_route, param_sc_level, param_count }; - PLUGIN_NAME_ID_LABEL("sidechaingate", "sidechaingate", "Sidechain Gate") -}; - -/// Markus's multiband gate - metadata -struct multibandgate_metadata: public plugin_metadata -{ - enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true }; - enum { param_bypass, param_level_in, param_level_out, - STEREO_VU_METER_PARAMS, - param_freq0, param_freq1, param_freq2, - param_sep0, param_sep1, param_sep2, - param_q0, param_q1, param_q2, - param_mode, - param_range0, param_threshold0, param_ratio0, param_attack0, param_release0, param_makeup0, param_knee0, - param_detection0, param_gating0, param_output0, param_bypass0, param_solo0, - param_range1, param_threshold1, param_ratio1, param_attack1, param_release1, param_makeup1, param_knee1, - param_detection1, param_gating1, param_output1, param_bypass1, param_solo1, - param_range2, param_threshold2, param_ratio2, param_attack2, param_release2, param_makeup2, param_knee2, - param_detection2, param_gating2, param_output2, param_bypass2, param_solo2, - param_range3, param_threshold3, param_ratio3, param_attack3, param_release3, param_makeup3, param_knee3, - param_detection3, param_gating3, param_output3, param_bypass3, param_solo3, - param_count }; - PLUGIN_NAME_ID_LABEL("multiband_gate", "multibandgate", "Multiband Gate") -}; - -/// Markus's limiter - metadata -struct limiter_metadata: public plugin_metadata -{ - enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true }; - enum { param_bypass, param_level_in, param_level_out, - STEREO_VU_METER_PARAMS, - param_limit, param_attack, param_release, - param_att, - param_asc, param_asc_led, param_asc_coeff, - param_count }; - PLUGIN_NAME_ID_LABEL("limiter", "limiter", "Limiter") -}; - -/// Markus's multibandlimiter - metadata -struct multibandlimiter_metadata: public plugin_metadata -{ - enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true }; - enum { param_bypass, param_level_in, param_level_out, - STEREO_VU_METER_PARAMS, - param_freq0, param_freq1, param_freq2, - param_sep0, param_sep1, param_sep2, - param_q0, param_q1, param_q2, - param_mode, - param_limit, param_attack, param_release, param_minrel, - param_att0, param_att1, param_att2, param_att3, - param_weight0, param_weight1, param_weight2, param_weight3, - param_release0, param_release1, param_release2, param_release3, - param_solo0, param_solo1, param_solo2, param_solo3, - param_effrelease0, param_effrelease1, param_effrelease2, param_effrelease3, - param_asc, param_asc_led, param_asc_coeff, - param_count }; - PLUGIN_NAME_ID_LABEL("multiband_limiter", "multibandlimiter", "Multiband Limiter") -}; - -/// Markus's 5-band EQ - metadata -struct equalizer5band_metadata: public plugin_metadata -{ - enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true }; - enum { param_bypass, param_level_in, param_level_out, STEREO_VU_METER_PARAMS, - param_ls_active, param_ls_level, param_ls_freq, - param_hs_active, param_hs_level, param_hs_freq, - param_p1_active, param_p1_level, param_p1_freq, param_p1_q, - param_p2_active, param_p2_level, param_p2_freq, param_p2_q, - param_p3_active, param_p3_level, param_p3_freq, param_p3_q, - param_count }; - // dummy parameter numbers, shouldn't be used EVER, they're only there to avoid pushing LP/HP filters to a separate class - // and potentially making inlining and optimization harder for the compiler - enum { param_lp_active = 0xDEADBEEF, param_hp_active, param_hp_mode, param_lp_mode, param_hp_freq, param_lp_freq }; - enum { PeakBands = 3, first_graph_param = param_ls_active, last_graph_param = param_p3_q }; - PLUGIN_NAME_ID_LABEL("equalizer5band", "eq5", "Equalizer 5 Band") -}; -/// Markus's 8-band EQ - metadata -struct equalizer8band_metadata: public plugin_metadata -{ - enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true }; - enum { param_bypass, param_level_in, param_level_out, - STEREO_VU_METER_PARAMS, - param_hp_active, param_hp_freq, param_hp_mode, - param_lp_active, param_lp_freq, param_lp_mode, - param_ls_active, param_ls_level, param_ls_freq, - param_hs_active, param_hs_level, param_hs_freq, - param_p1_active, param_p1_level, param_p1_freq, param_p1_q, - param_p2_active, param_p2_level, param_p2_freq, param_p2_q, - param_p3_active, param_p3_level, param_p3_freq, param_p3_q, - param_p4_active, param_p4_level, param_p4_freq, param_p4_q, - param_count }; - enum { PeakBands = 4, first_graph_param = param_hp_active, last_graph_param = param_p4_q }; - PLUGIN_NAME_ID_LABEL("equalizer8band", "eq8", "Equalizer 8 Band") -}; -/// Markus's 12-band EQ - metadata -struct equalizer12band_metadata: public plugin_metadata -{ - enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true }; - enum { param_bypass, param_level_in, param_level_out, - STEREO_VU_METER_PARAMS, - param_hp_active, param_hp_freq, param_hp_mode, - param_lp_active, param_lp_freq, param_lp_mode, - param_ls_active, param_ls_level, param_ls_freq, - param_hs_active, param_hs_level, param_hs_freq, - param_p1_active, param_p1_level, param_p1_freq, param_p1_q, - param_p2_active, param_p2_level, param_p2_freq, param_p2_q, - param_p3_active, param_p3_level, param_p3_freq, param_p3_q, - param_p4_active, param_p4_level, param_p4_freq, param_p4_q, - param_p5_active, param_p5_level, param_p5_freq, param_p5_q, - param_p6_active, param_p6_level, param_p6_freq, param_p6_q, - param_p7_active, param_p7_level, param_p7_freq, param_p7_q, - param_p8_active, param_p8_level, param_p8_freq, param_p8_q, - param_count }; - enum { PeakBands = 8, first_graph_param = param_hp_active, last_graph_param = param_p8_q }; - PLUGIN_NAME_ID_LABEL("equalizer12band", "eq12", "Equalizer 12 Band") -}; - -/// Markus's Pulsator - metadata -struct pulsator_metadata: public plugin_metadata -{ - enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true }; - enum { param_bypass, param_level_in, param_level_out, STEREO_VU_METER_PARAMS, - param_mode, param_freq, param_amount, param_offset, param_mono, param_reset, param_count }; - PLUGIN_NAME_ID_LABEL("pulsator", "pulsator", "Pulsator") -}; - -/// Markus's Saturator - metadata -struct saturator_metadata: public plugin_metadata -{ - enum { in_count = 2, out_count = 2, ins_optional = 1, outs_optional = 1, support_midi = false, require_midi = false, rt_capable = true }; - enum { param_bypass, param_level_in, param_level_out, param_mix, MONO_VU_METER_PARAMS, param_drive, param_blend, param_meter_drive, - param_lp_pre_freq, param_hp_pre_freq, param_lp_post_freq, param_hp_post_freq, - param_p_freq, param_p_level, param_p_q, param_count }; - PLUGIN_NAME_ID_LABEL("saturator", "saturator", "Saturator") -}; -/// Markus's Exciter - metadata -struct exciter_metadata: public plugin_metadata -{ - enum { in_count = 2, out_count = 2, ins_optional = 1, outs_optional = 1, support_midi = false, require_midi = false, rt_capable = true }; - enum { param_bypass, param_level_in, param_level_out, param_amount, MONO_VU_METER_PARAMS, param_drive, param_blend, param_meter_drive, - param_freq, param_listen, param_ceil_active, param_ceil, param_count }; - PLUGIN_NAME_ID_LABEL("exciter", "exciter", "Exciter") -}; -/// Markus's Bass Enhancer - metadata -struct bassenhancer_metadata: public plugin_metadata -{ - enum { in_count = 2, out_count = 2, ins_optional = 1, outs_optional = 1, support_midi = false, require_midi = false, rt_capable = true }; - enum { param_bypass, param_level_in, param_level_out, param_amount, MONO_VU_METER_PARAMS, param_drive, param_blend, param_meter_drive, - param_freq, param_listen, param_floor_active, param_floor, param_count }; - PLUGIN_NAME_ID_LABEL("bassenhancer", "bassenhancer", "Bass Enhancer") -}; -/// Markus's Mono Module - metadata -struct stereo_metadata: public plugin_metadata -{ - enum { in_count = 2, out_count = 2, ins_optional = 1, outs_optional = 1, support_midi = false, require_midi = false, rt_capable = true }; - enum { param_bypass, param_level_in, param_level_out, - STEREO_VU_METER_PARAMS, param_balance_in, param_balance_out, param_softclip, - param_mute_l, param_mute_r, param_phase_l, param_phase_r, - param_mode, param_slev, param_sbal, param_mlev, param_mpan, - param_widener, param_delay, - param_meter_phase, - param_count }; - PLUGIN_NAME_ID_LABEL("stereo", "stereo", "Stereo Tools") -}; -/// Markus's Mono Module - metadata -struct mono_metadata: public plugin_metadata -{ - enum { in_count = 1, out_count = 2, ins_optional = 1, outs_optional = 1, support_midi = false, require_midi = false, rt_capable = true }; - enum { param_bypass, param_level_in, param_level_out, - param_meter_in, param_meter_outL, param_meter_outR, param_clip_in,param_clip_outL, param_clip_outR, - param_balance_out, param_softclip, - param_mute_l, param_mute_r, param_phase_l, param_phase_r, - param_delay, - param_count }; - PLUGIN_NAME_ID_LABEL("mono", "mono", "Mono Input") -}; - -/// Organ - enums for parameter IDs etc. (this mess is caused by organ split between plugin and generic class - which was -/// a bad design decision and should be sorted out some day) XXXKF @todo -struct organ_enums -{ - enum { - par_drawbar1, par_drawbar2, par_drawbar3, par_drawbar4, par_drawbar5, par_drawbar6, par_drawbar7, par_drawbar8, par_drawbar9, - par_frequency1, par_frequency2, par_frequency3, par_frequency4, par_frequency5, par_frequency6, par_frequency7, par_frequency8, par_frequency9, - par_waveform1, par_waveform2, par_waveform3, par_waveform4, par_waveform5, par_waveform6, par_waveform7, par_waveform8, par_waveform9, - par_detune1, par_detune2, par_detune3, par_detune4, par_detune5, par_detune6, par_detune7, par_detune8, par_detune9, - par_phase1, par_phase2, par_phase3, par_phase4, par_phase5, par_phase6, par_phase7, par_phase8, par_phase9, - par_pan1, par_pan2, par_pan3, par_pan4, par_pan5, par_pan6, par_pan7, par_pan8, par_pan9, - par_routing1, par_routing2, par_routing3, par_routing4, par_routing5, par_routing6, par_routing7, par_routing8, par_routing9, - par_foldover, - par_percdecay, par_perclevel, par_percwave, par_percharm, par_percvel2amp, - par_percfmdecay, par_percfmdepth, par_percfmwave, par_percfmharm, par_percvel2fm, - par_perctrigger, par_percstereo, - par_filterchain, - par_filter1type, - par_master, - par_f1cutoff, par_f1res, par_f1env1, par_f1env2, par_f1env3, par_f1keyf, - par_f2cutoff, par_f2res, par_f2env1, par_f2env2, par_f2env3, par_f2keyf, - par_eg1attack, par_eg1decay, par_eg1sustain, par_eg1release, par_eg1velscl, par_eg1ampctl, - par_eg2attack, par_eg2decay, par_eg2sustain, par_eg2release, par_eg2velscl, par_eg2ampctl, - par_eg3attack, par_eg3decay, par_eg3sustain, par_eg3release, par_eg3velscl, par_eg3ampctl, - par_lforate, par_lfoamt, par_lfowet, par_lfophase, par_lfomode, par_lfotype, - par_transpose, par_detune, - par_polyphony, - par_quadenv, - par_pwhlrange, - par_bassfreq, - par_bassgain, - par_treblefreq, - par_treblegain, - param_count - }; - enum organ_waveform { - wave_sine, - wave_sinepl1, wave_sinepl2, wave_sinepl3, - wave_ssaw, wave_ssqr, wave_spls, wave_saw, wave_sqr, wave_pulse, wave_sinepl05, wave_sqr05, wave_halfsin, wave_clvg, wave_bell, wave_bell2, - wave_w1, wave_w2, wave_w3, wave_w4, wave_w5, wave_w6, wave_w7, wave_w8, wave_w9, - wave_dsaw, wave_dsqr, wave_dpls, - wave_count_small, - wave_strings = wave_count_small, - wave_strings2, - wave_sinepad, - wave_bellpad, - wave_space, - wave_choir, - wave_choir2, - wave_choir3, - wave_count, - wave_count_big = wave_count - wave_count_small - }; - enum { - ampctl_none, - ampctl_direct, - ampctl_f1, - ampctl_f2, - ampctl_all, - ampctl_count - }; - enum { - lfotype_allpass = 0, - lfotype_cv1, - lfotype_cv2, - lfotype_cv3, - lfotype_cvfull, - lfotype_count - }; - enum { - lfomode_off = 0, - lfomode_direct, - lfomode_filter1, - lfomode_filter2, - lfomode_voice, - lfomode_global, - lfomode_count - }; - enum { - perctrig_first = 0, - perctrig_each, - perctrig_eachplus, - perctrig_polyphonic, - perctrig_count - }; -}; - -/// Organ - metadata -struct organ_metadata: public organ_enums, public plugin_metadata -{ - enum { in_count = 0, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = true, require_midi = true, rt_capable = true }; - PLUGIN_NAME_ID_LABEL("organ", "organ", "Organ") - -public: - plugin_command_info *get_commands(); - const char *const *get_configure_vars() const; -}; - -/// FluidSynth - metadata -struct fluidsynth_metadata: public plugin_metadata -{ - enum { par_master, par_interpolation, par_reverb, par_chorus, param_count }; - enum { in_count = 0, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = true, require_midi = true, rt_capable = false }; - PLUGIN_NAME_ID_LABEL("fluidsynth", "fluidsynth", "Fluidsynth") - -public: - const char *const *get_configure_vars() const; -}; - -/// Wavetable - metadata -struct wavetable_metadata: public plugin_metadata -{ - enum { - wt_fmshiny, - wt_fmshiny2, - wt_rezo, - wt_metal, - wt_bell, - wt_blah, - wt_pluck, - wt_stretch, - wt_stretch2, - wt_hardsync, - wt_hardsync2, - wt_softsync, - wt_bell2, - wt_bell3, - wt_tine, - wt_tine2, - wt_clav, - wt_clav2, - wt_gtr, - wt_gtr2, - wt_gtr3, - wt_gtr4, - wt_gtr5, - wt_reed, - wt_reed2, - wt_silver, - wt_brass, - wt_multi, - wt_multi2, - wt_count - }; - enum { - modsrc_none, - modsrc_velocity, - modsrc_pressure, - modsrc_modwheel, - modsrc_env1, - modsrc_env2, - modsrc_env3, - modsrc_count, - }; - enum { - moddest_none, - moddest_attenuation, - moddest_oscmix, - moddest_cutoff, - moddest_resonance, - moddest_o1shift, - moddest_o2shift, - moddest_o1detune, - moddest_o2detune, - moddest_count, - }; - enum { - par_o1wave, par_o1offset, par_o1transpose, par_o1detune, par_o1level, - par_o2wave, par_o2offset, par_o2transpose, par_o2detune, par_o2level, - par_eg1attack, par_eg1decay, par_eg1sustain, par_eg1fade, par_eg1release, par_eg1velscl, - par_eg2attack, par_eg2decay, par_eg2sustain, par_eg2fade, par_eg2release, par_eg2velscl, - par_eg3attack, par_eg3decay, par_eg3sustain, par_eg3fade, par_eg3release, par_eg3velscl, - par_pwhlrange, - param_count }; - enum { in_count = 0, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = true, require_midi = true, rt_capable = true }; - enum { mod_matrix_slots = 10 }; - enum { step_size = 64 }; - PLUGIN_NAME_ID_LABEL("wavetable", "wavetable", "Wavetable") - mod_matrix_metadata mm_metadata; - - wavetable_metadata(); - /// Lookup of table edit interface - virtual const table_metadata_iface *get_table_metadata_iface(const char *key) const { if (!strcmp(key, "mod_matrix")) return &mm_metadata; else return NULL; } -}; - -}; - -#endif diff --git a/plugins/LadspaEffect/calf/src/calf/modmatrix.h b/plugins/LadspaEffect/calf/src/calf/modmatrix.h deleted file mode 100644 index 08b44cdf3c2..00000000000 --- a/plugins/LadspaEffect/calf/src/calf/modmatrix.h +++ /dev/null @@ -1,125 +0,0 @@ -/* Calf DSP Library - * Modulation matrix boilerplate code. - * - * Copyright (C) 2009 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_MODMATRIX_H -#define __CALF_MODMATRIX_H - -#include "giface.h" -#include - -namespace dsp { - -/// Single entry in modulation matrix -struct modulation_entry -{ - /// Mapped source - int src1; - /// Source mapping mode - calf_plugins::mod_matrix_metadata::mapping_mode mapping; - /// Unmapped modulating source - int src2; - /// Modulation amount - float amount; - /// Modulation destination - int dest; - - modulation_entry() { - reset(); - } - - /// Reset the row to default - void reset() { - src1 = 0; - src2 = 0; - mapping = calf_plugins::mod_matrix_metadata::map_positive; - amount = 0.f; - dest = 0; - } -}; - -}; - -namespace calf_plugins { - -class mod_matrix_impl -{ -protected: - dsp::modulation_entry *matrix; - mod_matrix_metadata *metadata; - unsigned int matrix_rows; - /// Polynomials for different scaling modes (1, x, x^2) - static const float scaling_coeffs[calf_plugins::mod_matrix_metadata::map_type_count][3]; - -public: - mod_matrix_impl(dsp::modulation_entry *_matrix, calf_plugins::mod_matrix_metadata *_metadata); - - /// Process modulation matrix, calculate outputs from inputs - inline void calculate_modmatrix(float *moddest, int moddest_count, float *modsrc) - { - for (int i = 0; i < moddest_count; i++) - moddest[i] = 0; - for (unsigned int i = 0; i < matrix_rows; i++) - { - dsp::modulation_entry &slot = matrix[i]; - if (slot.dest) { - float value = modsrc[slot.src1]; - const float *c = scaling_coeffs[slot.mapping]; - value = c[0] + c[1] * value + c[2] * value * value; - moddest[slot.dest] += value * modsrc[slot.src2] * slot.amount; - } - } - } - void send_configures(send_configure_iface *); - char *configure(const char *key, const char *value); - - /// Return a list of configure variables used by the modulation matrix - template - static const char **get_configure_vars() - { - static std::vector names_vector; - static const char *names[rows * 5 + 1]; - - if (names[0] == NULL) - { - for (int i = 0; i < rows; i++) - { - for (int j = 0; j < 5; j++) - { - char buf[40]; - sprintf(buf, "mod_matrix:%d,%d", i, j); - names_vector.push_back(buf); - } - } - for (size_t i = 0; i < names_vector.size(); i++) - names[i] = names_vector[i].c_str(); - names[names_vector.size()] = NULL; - } - - return names; - } - -private: - std::string get_cell(int row, int column) const; - void set_cell(int row, int column, const std::string &src, std::string &error); -}; - -}; - -#endif diff --git a/plugins/LadspaEffect/calf/src/calf/modulelist.h b/plugins/LadspaEffect/calf/src/calf/modulelist.h deleted file mode 100644 index 8425794f263..00000000000 --- a/plugins/LadspaEffect/calf/src/calf/modulelist.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifdef PER_MODULE_ITEM - PER_MODULE_ITEM(filter, false, "filter") - PER_MODULE_ITEM(filterclavier, false, "filterclavier") - PER_MODULE_ITEM(flanger, false, "flanger") - PER_MODULE_ITEM(reverb, false, "reverb") - PER_MODULE_ITEM(monosynth, true, "monosynth") - PER_MODULE_ITEM(vintage_delay, false, "vintagedelay") - PER_MODULE_ITEM(organ, true, "organ") - PER_MODULE_ITEM(rotary_speaker, false, "rotaryspeaker") - PER_MODULE_ITEM(phaser, false, "phaser") - PER_MODULE_ITEM(multichorus, false, "multichorus") - PER_MODULE_ITEM(compressor, false, "compressor") - PER_MODULE_ITEM(sidechaincompressor, false, "sidechaincompressor") - PER_MODULE_ITEM(multibandcompressor, false, "multibandcompressor") - PER_MODULE_ITEM(deesser, false, "deesser") - PER_MODULE_ITEM(gate, false, "gate") - PER_MODULE_ITEM(sidechaingate, false, "sidechaingate") - PER_MODULE_ITEM(multibandgate, false, "multibandgate") - PER_MODULE_ITEM(limiter, false, "limiter") - PER_MODULE_ITEM(multibandlimiter, false, "multibandlimiter") - PER_MODULE_ITEM(pulsator, false, "pulsator") - PER_MODULE_ITEM(equalizer5band, false, "eq5") - PER_MODULE_ITEM(equalizer8band, false, "eq8") - PER_MODULE_ITEM(equalizer12band, false, "eq12") - PER_MODULE_ITEM(saturator, false, "saturator") - PER_MODULE_ITEM(exciter, false, "exciter") - PER_MODULE_ITEM(bassenhancer, false, "bassenhancer") - PER_MODULE_ITEM(mono, false, "mono") - PER_MODULE_ITEM(stereo, false, "stereo") -#ifdef ENABLE_EXPERIMENTAL - PER_MODULE_ITEM(fluidsynth, true, "fluidsynth") - PER_MODULE_ITEM(wavetable, true, "wavetable") -#endif -#undef PER_MODULE_ITEM -#endif diff --git a/plugins/LadspaEffect/calf/src/calf/modules.h b/plugins/LadspaEffect/calf/src/calf/modules.h deleted file mode 100644 index 8cde47f6206..00000000000 --- a/plugins/LadspaEffect/calf/src/calf/modules.h +++ /dev/null @@ -1,305 +0,0 @@ -/* Calf DSP plugin pack - * Assorted plugins - * - * Copyright (C) 2001-2010 Krzysztof Foltman, Markus Schmidt, Thor Harald Johansen and others - * - * 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_MODULES_H -#define CALF_MODULES_H - -#include -#include -#include "biquad.h" -#include "inertia.h" -#include "audio_fx.h" -#include "giface.h" -#include "metadata.h" -#include "loudness.h" - -namespace calf_plugins { - -struct ladspa_plugin_info; - -class reverb_audio_module: public audio_module -{ -public: - dsp::reverb reverb; - dsp::simple_delay<16384, dsp::stereo_sample > pre_delay; - dsp::onepole left_lo, right_lo, left_hi, right_hi; - uint32_t srate; - dsp::gain_smoothing amount, dryamount; - int predelay_amt; - float meter_wet, meter_out; - uint32_t clip; - - void params_changed(); - uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask); - void activate(); - void set_sample_rate(uint32_t sr); - void deactivate(); -}; - -class vintage_delay_audio_module: public audio_module -{ -public: - // 1MB of delay memory per channel... uh, RAM is cheap - enum { MAX_DELAY = 262144, ADDR_MASK = MAX_DELAY - 1 }; - enum { MIXMODE_STEREO, MIXMODE_PINGPONG, MIXMODE_LR, MIXMODE_RL }; - float buffers[2][MAX_DELAY]; - int bufptr, deltime_l, deltime_r, mixmode, medium, old_medium; - /// number of table entries written (value is only important when it is less than MAX_DELAY, which means that the buffer hasn't been totally filled yet) - int age; - - dsp::gain_smoothing amt_left, amt_right, fb_left, fb_right, dry, chmix; - - dsp::biquad_d2 biquad_left[2], biquad_right[2]; - - uint32_t srate; - - vintage_delay_audio_module(); - - void params_changed(); - void activate(); - void deactivate(); - void set_sample_rate(uint32_t sr); - void calc_filters(); - uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask); -}; - -template -class filter_module_with_inertia: public audio_module, public FilterClass -{ -public: - /// These are pointers to the ins, outs, params arrays in the main class - typedef filter_module_with_inertia inertia_filter_module; - using audio_module::ins; - using audio_module::outs; - using audio_module::params; - - dsp::inertia inertia_cutoff, inertia_resonance, inertia_gain; - dsp::once_per_n timer; - bool is_active; - mutable volatile int last_generation, last_calculated_generation; - - filter_module_with_inertia(float **ins, float **outs, float **params) - : inertia_cutoff(dsp::exponential_ramp(128), 20) - , inertia_resonance(dsp::exponential_ramp(128), 20) - , inertia_gain(dsp::exponential_ramp(128), 1.0) - , timer(128) - , is_active(false) - , last_generation(-1) - , last_calculated_generation(-2) - {} - - void calculate_filter() - { - float freq = inertia_cutoff.get_last(); - // printf("freq=%g inr.cnt=%d timer.left=%d\n", freq, inertia_cutoff.count, timer.left); - // XXXKF this is resonance of a single stage, obviously for three stages, resonant gain will be different - float q = inertia_resonance.get_last(); - int mode = dsp::fastf2i_drm(*params[Metadata::par_mode]); - // printf("freq = %f q = %f mode = %d\n", freq, q, mode); - - int inertia = dsp::fastf2i_drm(*params[Metadata::par_inertia]); - if (inertia != inertia_cutoff.ramp.length()) { - inertia_cutoff.ramp.set_length(inertia); - inertia_resonance.ramp.set_length(inertia); - inertia_gain.ramp.set_length(inertia); - } - - FilterClass::calculate_filter(freq, q, mode, inertia_gain.get_last()); - } - - virtual void params_changed() - { - calculate_filter(); - } - - void on_timer() - { - int gen = last_generation; - inertia_cutoff.step(); - inertia_resonance.step(); - inertia_gain.step(); - calculate_filter(); - last_calculated_generation = gen; - } - - void activate() - { - params_changed(); - FilterClass::filter_activate(); - timer = dsp::once_per_n(FilterClass::srate / 1000); - timer.start(); - is_active = true; - } - - void set_sample_rate(uint32_t sr) - { - FilterClass::srate = sr; - } - - - void deactivate() - { - is_active = false; - } - - uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) { -// printf("sr=%d cutoff=%f res=%f mode=%f\n", FilterClass::srate, *params[Metadata::par_cutoff], *params[Metadata::par_resonance], *params[Metadata::par_mode]); - uint32_t ostate = 0; - numsamples += offset; - while(offset < numsamples) { - uint32_t numnow = numsamples - offset; - // if inertia's inactive, we can calculate the whole buffer at once - if (inertia_cutoff.active() || inertia_resonance.active() || inertia_gain.active()) - numnow = timer.get(numnow); - - if (outputs_mask & 1) { - ostate |= FilterClass::process_channel(0, ins[0] + offset, outs[0] + offset, numnow, inputs_mask & 1); - } - if (outputs_mask & 2) { - ostate |= FilterClass::process_channel(1, ins[1] + offset, outs[1] + offset, numnow, inputs_mask & 2); - } - - if (timer.elapsed()) { - on_timer(); - } - offset += numnow; - } - return ostate; - } -}; - -/// biquad filter module -class filter_audio_module: - public filter_module_with_inertia, - public frequency_response_line_graph -{ - mutable float old_cutoff, old_resonance, old_mode; -public: - filter_audio_module() - : filter_module_with_inertia(ins, outs, params) - { - last_generation = 0; - old_mode = old_resonance = old_cutoff = -1; - } - void params_changed() - { - inertia_cutoff.set_inertia(*params[par_cutoff]); - inertia_resonance.set_inertia(*params[par_resonance]); - inertia_filter_module::params_changed(); - } - - bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const; - int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const; -}; - -/// Filterclavier --- MIDI controlled filter by Hans Baier -class filterclavier_audio_module: - public filter_module_with_inertia, - public frequency_response_line_graph -{ - using audio_module::ins; - using audio_module::outs; - using audio_module::params; - - const float min_gain; - const float max_gain; - - int last_note; - int last_velocity; - -public: - filterclavier_audio_module(); - void params_changed(); - void activate(); - void set_sample_rate(uint32_t sr); - void deactivate(); - - /// MIDI control - virtual void note_on(int channel, int note, int vel); - virtual void note_off(int channel, int note, int vel); - - bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const; - -private: - void adjust_gain_according_to_filter_mode(int velocity); -}; - - -#define MATH_E 2.718281828 -class mono_audio_module: - public audio_module -{ - typedef mono_audio_module AM; - uint32_t srate; - bool active; - - uint32_t clip_in, clip_outL, clip_outR; - float meter_in, meter_outL, meter_outR; - - float * buffer; - unsigned int pos; - unsigned int buffer_size; - - void softclip(float &s) { - int ph = s / fabs(s); - s = s > 0.63 ? ((0.63 + 0.36) * ph * (1 - pow(MATH_E, (1.f / 3) * (0.63 + s * ph)))) : s; - } -public: - mono_audio_module(); - ~mono_audio_module(); - void params_changed(); - void activate(); - void set_sample_rate(uint32_t sr); - void deactivate(); - uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask); -}; - -class stereo_audio_module: - public audio_module -{ - typedef stereo_audio_module AM; - float LL, LR, RL, RR; - uint32_t srate; - bool active; - - uint32_t clip_inL, clip_inR, clip_outL, clip_outR; - float meter_inL, meter_inR, meter_outL, meter_outR, meter_phase; - - float * buffer; - unsigned int pos; - unsigned int buffer_size; - - void softclip(float &s) { - int ph = s / fabs(s); - s = s > 0.63 ? ((0.63 + 0.36) * ph * (1 - pow(MATH_E, (1.f / 3) * (0.63 + s * ph)))) : s; - } -public: - stereo_audio_module(); - ~stereo_audio_module(); - void params_changed(); - void activate(); - void set_sample_rate(uint32_t sr); - void deactivate(); - uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask); -}; - - -}; -#endif diff --git a/plugins/LadspaEffect/calf/src/calf/modules_comp.h b/plugins/LadspaEffect/calf/src/calf/modules_comp.h deleted file mode 100644 index decdf209709..00000000000 --- a/plugins/LadspaEffect/calf/src/calf/modules_comp.h +++ /dev/null @@ -1,334 +0,0 @@ -/* Calf DSP plugin pack - * Compression related plugins - * - * Copyright (C) 2001-2010 Krzysztof Foltman, Markus Schmidt, Thor Harald Johansen and others - * - * 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_MODULES_COMP_H -#define CALF_MODULES_COMP_H - -#include -#include -#include "biquad.h" -#include "inertia.h" -#include "audio_fx.h" -#include "giface.h" -#include "loudness.h" -#include "metadata.h" -#include "plugin_tools.h" - -namespace calf_plugins { - -/// Not a true _audio_module style class, just pretends to be one! -/// Main gain reduction routine by Thor called by various audio modules - -class gain_reduction_audio_module -{ -private: - float linSlope, detected, kneeSqrt, kneeStart, linKneeStart, kneeStop; - float compressedKneeStop, adjKneeStart, thres; - float attack, release, threshold, ratio, knee, makeup, detection, stereo_link, bypass, mute, meter_out, meter_comp; - mutable float old_threshold, old_ratio, old_knee, old_makeup, old_bypass, old_mute, old_detection, old_stereo_link; - mutable volatile int last_generation; - uint32_t srate; - bool is_active; - inline float output_level(float slope) const; - inline float output_gain(float linSlope, bool rms) const; -public: - gain_reduction_audio_module(); - void set_params(float att, float rel, float thr, float rat, float kn, float mak, float det, float stl, float byp, float mu); - void update_curve(); - void process(float &left, float &right, const float *det_left = NULL, const float *det_right = NULL); - void activate(); - void deactivate(); - int id; - void set_sample_rate(uint32_t sr); - float get_output_level(); - float get_comp_level(); - bool get_graph(int subindex, float *data, int points, cairo_iface *context) const; - bool get_dot(int subindex, float &x, float &y, int &size, cairo_iface *context) const; - bool get_gridline(int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const; - int get_changed_offsets(int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const; -}; - -/// Not a true _audio_module style class, just pretends to be one! -/// Main gate routine by Damien called by various audio modules -class expander_audio_module { -private: - float linSlope, peak, detected, kneeSqrt, kneeStart, linKneeStart, kneeStop, linKneeStop; - float compressedKneeStop, adjKneeStart, range, thres, attack_coeff, release_coeff; - float attack, release, threshold, ratio, knee, makeup, detection, stereo_link, bypass, mute, meter_out, meter_gate; - mutable float old_threshold, old_ratio, old_knee, old_makeup, old_bypass, old_range, old_trigger, old_mute, old_detection, old_stereo_link; - mutable volatile int last_generation; - inline float output_level(float slope) const; - inline float output_gain(float linSlope, bool rms) const; -public: - uint32_t srate; - bool is_active; - expander_audio_module(); - void set_params(float att, float rel, float thr, float rat, float kn, float mak, float det, float stl, float byp, float mu, float ran); - void update_curve(); - void process(float &left, float &right, const float *det_left = NULL, const float *det_right = NULL); - void activate(); - void deactivate(); - int id; - void set_sample_rate(uint32_t sr); - float get_output_level(); - float get_expander_level(); - bool get_graph(int subindex, float *data, int points, cairo_iface *context) const; - bool get_dot(int subindex, float &x, float &y, int &size, cairo_iface *context) const; - bool get_gridline(int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const; - int get_changed_offsets(int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const; -}; - -/// Compressor by Thor -class compressor_audio_module: public audio_module, public line_graph_iface { -private: - typedef compressor_audio_module AM; - stereo_in_out_metering meters; - gain_reduction_audio_module compressor; -public: - typedef std::complex cfloat; - uint32_t srate; - bool is_active; - mutable volatile int last_generation, last_calculated_generation; - compressor_audio_module(); - void activate(); - void deactivate(); - void params_changed(); - void set_sample_rate(uint32_t sr); - uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask); - bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const; - bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const; - bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const; - int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const; -}; - -/// Sidecain Compressor by Markus Schmidt (based on Thor's compressor and Krzysztof's filters) -class sidechaincompressor_audio_module: public audio_module, public frequency_response_line_graph { -private: - typedef sidechaincompressor_audio_module AM; - enum CalfScModes { - WIDEBAND, - DEESSER_WIDE, - DEESSER_SPLIT, - DERUMBLER_WIDE, - DERUMBLER_SPLIT, - WEIGHTED_1, - WEIGHTED_2, - WEIGHTED_3, - BANDPASS_1, - BANDPASS_2 - }; - enum CalfScRoute { - STEREO, - RIGHT_LEFT, - LEFT_RIGHT - }; - mutable float f1_freq_old, f2_freq_old, f1_level_old, f2_level_old; - mutable float f1_freq_old1, f2_freq_old1, f1_level_old1, f2_level_old1; - CalfScModes sc_mode; - mutable CalfScModes sc_mode_old, sc_mode_old1; - float f1_active, f2_active; - stereo_in_out_metering meters; - gain_reduction_audio_module compressor; - dsp::biquad_d2 f1L, f1R, f2L, f2R; -public: - typedef std::complex cfloat; - uint32_t srate; - bool is_active; - mutable volatile int last_generation, last_calculated_generation; - sidechaincompressor_audio_module(); - void activate(); - void deactivate(); - void params_changed(); - cfloat h_z(const cfloat &z) const; - float freq_gain(int index, double freq, uint32_t sr) const; - void set_sample_rate(uint32_t sr); - uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask); - bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const; - bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const; - bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const; - int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const; -}; - -/// Multibandcompressor by Markus Schmidt (based on Thor's compressor and Krzysztof's filters) -class multibandcompressor_audio_module: public audio_module, public line_graph_iface { -private: - typedef multibandcompressor_audio_module AM; - static const int strips = 4; - bool solo[strips]; - bool no_solo; - uint32_t clip_inL, clip_inR, clip_outL, clip_outR; - float meter_inL, meter_inR, meter_outL, meter_outR; - gain_reduction_audio_module strip[strips]; - dsp::biquad_d2 lpL[strips - 1][3], lpR[strips - 1][3], hpL[strips - 1][3], hpR[strips - 1][3]; - float freq_old[strips - 1], sep_old[strips - 1], q_old[strips - 1]; - int mode, mode_old; -public: - uint32_t srate; - bool is_active; - multibandcompressor_audio_module(); - void activate(); - void deactivate(); - void params_changed(); - uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask); - void set_sample_rate(uint32_t sr); - const gain_reduction_audio_module *get_strip_by_param_index(int index) const; - virtual bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const; - virtual bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const; - virtual bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const; - virtual int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const; -}; - -/// Deesser by Markus Schmidt (based on Thor's compressor and Krzyexpander_audio_modulesztof's filters) -class deesser_audio_module: public audio_module, public frequency_response_line_graph { -private: - enum CalfDeessModes { - WIDE, - SPLIT - }; - mutable float f1_freq_old, f2_freq_old, f1_level_old, f2_level_old, f2_q_old; - mutable float f1_freq_old1, f2_freq_old1, f1_level_old1, f2_level_old1, f2_q_old1; - uint32_t detected_led; - float detected, clip_out; - uint32_t clip_led; - gain_reduction_audio_module compressor; - dsp::biquad_d2 hpL, hpR, lpL, lpR, pL, pR; -public: - uint32_t srate; - bool is_active; - mutable volatile int last_generation, last_calculated_generation; - deesser_audio_module(); - void activate(); - void deactivate(); - void params_changed(); - float freq_gain(int index, double freq, uint32_t sr) const - { - return hpL.freq_gain(freq, sr) * pL.freq_gain(freq, sr); - } - void set_sample_rate(uint32_t sr); - uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask); - bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const; - bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const; - int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const; -}; - -/// Gate by Damien -class gate_audio_module: public audio_module, public line_graph_iface { -private: - typedef gate_audio_module AM; - stereo_in_out_metering meters; - expander_audio_module gate; -public: - typedef std::complex cfloat; - uint32_t srate; - bool is_active; - mutable volatile int last_generation, last_calculated_generation; - gate_audio_module(); - void activate(); - void deactivate(); - void params_changed(); - void set_sample_rate(uint32_t sr); - uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask); - bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const; - bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const; - bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const; - int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const; -}; - -/// Sidecain Gate by Markus Schmidt (based on Damiens's gate and Krzysztof's filters) -class sidechaingate_audio_module: public audio_module, public frequency_response_line_graph { -private: - typedef sidechaingate_audio_module AM; - enum CalfScModes { - WIDEBAND, - HIGHGATE_WIDE, - HIGHGATE_SPLIT, - LOWGATE_WIDE, - LOWGATE_SPLIT, - WEIGHTED_1, - WEIGHTED_2, - WEIGHTED_3, - BANDPASS_1, - BANDPASS_2 - }; - enum CalfScRoute { - STEREO, - RIGHT_LEFT, - LEFT_RIGHT - }; - mutable float f1_freq_old, f2_freq_old, f1_level_old, f2_level_old; - mutable float f1_freq_old1, f2_freq_old1, f1_level_old1, f2_level_old1; - CalfScModes sc_mode; - mutable CalfScModes sc_mode_old, sc_mode_old1; - float f1_active, f2_active; - stereo_in_out_metering meters; - expander_audio_module gate; - dsp::biquad_d2 f1L, f1R, f2L, f2R; -public: - typedef std::complex cfloat; - uint32_t srate; - bool is_active; - mutable volatile int last_generation, last_calculated_generation; - sidechaingate_audio_module(); - void activate(); - void deactivate(); - void params_changed(); - cfloat h_z(const cfloat &z) const; - float freq_gain(int index, double freq, uint32_t sr) const; - void set_sample_rate(uint32_t sr); - uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask); - bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const; - bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const; - bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const; - int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const; -}; - - -/// Multibandgate by Markus Schmidt (based on Damiens's gate and Krzysztof's filters) -class multibandgate_audio_module: public audio_module, public line_graph_iface { -private: - typedef multibandgate_audio_module AM; - static const int strips = 4; - bool solo[strips]; - bool no_solo; - uint32_t clip_inL, clip_inR, clip_outL, clip_outR; - float meter_inL, meter_inR, meter_outL, meter_outR; - expander_audio_module gate[strips]; - dsp::biquad_d2 lpL[strips - 1][3], lpR[strips - 1][3], hpL[strips - 1][3], hpR[strips - 1][3]; - float freq_old[strips - 1], sep_old[strips - 1], q_old[strips - 1]; - int mode, mode_old; -public: - uint32_t srate; - bool is_active; - multibandgate_audio_module(); - void activate(); - void deactivate(); - void params_changed(); - uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask); - void set_sample_rate(uint32_t sr); - const expander_audio_module *get_strip_by_param_index(int index) const; - virtual bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const; - virtual bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const; - virtual bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const; - virtual int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const; -}; - -}; - -#endif diff --git a/plugins/LadspaEffect/calf/src/calf/modules_dev.h b/plugins/LadspaEffect/calf/src/calf/modules_dev.h deleted file mode 100644 index 628fcd539af..00000000000 --- a/plugins/LadspaEffect/calf/src/calf/modules_dev.h +++ /dev/null @@ -1,113 +0,0 @@ -/* Calf DSP Library - * Prototype audio modules - * - * Copyright (C) 2008 Thor Harald Johansen - * - * 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_MODULES_DEV_H -#define __CALF_MODULES_DEV_H - -#include - -#if ENABLE_EXPERIMENTAL -#include -#endif - -namespace calf_plugins { - -#if ENABLE_EXPERIMENTAL - -/// Tiny wrapper for fluidsynth -class fluidsynth_audio_module: public audio_module -{ -protected: - /// Current sample rate - uint32_t srate; - /// FluidSynth Settings object - fluid_settings_t *settings; - /// FluidSynth Synth object - fluid_synth_t *synth; - /// Soundfont filename - std::string soundfont; - /// Soundfont filename (as received from Fluidsynth) - std::string soundfont_name; - /// TAB-separated preset list (preset+128*bank TAB preset name LF) - std::string soundfont_preset_list; - /// FluidSynth assigned SoundFont ID - int sfid; - /// Map of preset+128*bank to preset name - std::map sf_preset_names; - /// Last selected preset+128*bank - uint32_t last_selected_preset; - /// Serial number of status data - int status_serial; - /// Preset number to set on next process() call - volatile int set_preset; - - /// Update last_selected_preset based on synth object state - void update_preset_num(); - /// Create a fluidsynth object and load the current soundfont - fluid_synth_t *create_synth(int &new_sfid); -public: - /// Constructor to initialize handles to NULL - fluidsynth_audio_module(); - - void post_instantiate(); - void set_sample_rate(uint32_t sr) { srate = sr; } - /// Handle MIDI Note On message (by sending it to fluidsynth) - void note_on(int channel, int note, int vel); - /// Handle MIDI Note Off message (by sending it to fluidsynth) - void note_off(int channel, int note, int vel); - /// Handle pitch bend message. - inline void pitch_bend(int channel, int value) - { - fluid_synth_pitch_bend(synth, 0, value + 0x2000); - } - /// Handle control change messages. - void control_change(int channel, int controller, int value); - /// Handle program change messages. - void program_change(int channel, int program); - - /// Update variables from control ports. - void params_changed() { - } - void activate(); - void deactivate(); - /// No CV inputs for now - bool is_cv(int param_no) { return false; } - /// Practically all the stuff here is noisy... for now - bool is_noisy(int param_no) { return true; } - /// Main processing function - uint32_t process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask); - /// DSSI-style configure function for handling string port data - char *configure(const char *key, const char *value); - void send_configures(send_configure_iface *sci); - int send_status_updates(send_updates_iface *sui, int last_serial); - uint32_t message_run(const void *valid_inputs, void *output_ports) { - // silence a default printf (which is kind of a warning about unhandled message_run) - return 0; - } - ~fluidsynth_audio_module(); -}; - - - -#endif - -}; - -#endif diff --git a/plugins/LadspaEffect/calf/src/calf/modules_dist.h b/plugins/LadspaEffect/calf/src/calf/modules_dist.h deleted file mode 100644 index 2c46caa7871..00000000000 --- a/plugins/LadspaEffect/calf/src/calf/modules_dist.h +++ /dev/null @@ -1,101 +0,0 @@ -/* Calf DSP plugin pack - * Distortion related plugins - * - * Copyright (C) 2001-2010 Krzysztof Foltman, Markus Schmidt, Thor Harald Johansen and others - * - * 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_MODULES_DIST_H -#define CALF_MODULES_DIST_H - -#include -#include -#include "biquad.h" -#include "inertia.h" -#include "audio_fx.h" -#include "giface.h" -#include "metadata.h" -#include "plugin_tools.h" - -namespace calf_plugins { - -/// Saturator by Markus Schmidt (based on Krzysztof's filters and Tom's distortion algorythm) -class saturator_audio_module: public audio_module { -private: - float hp_pre_freq_old, lp_pre_freq_old; - float hp_post_freq_old, lp_post_freq_old; - float p_level_old, p_freq_old, p_q_old; - stereo_in_out_metering meters; - float meter_drive; - dsp::biquad_d2 lp[2][4], hp[2][4]; - dsp::biquad_d2 p[2]; - dsp::tap_distortion dist[2]; -public: - uint32_t srate; - bool is_active; - saturator_audio_module(); - void activate(); - void deactivate(); - void params_changed(); - void set_sample_rate(uint32_t sr); - uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask); -}; - -/// Exciter by Markus Schmidt (based on Krzysztof's filters and Tom's distortion algorythm) -class exciter_audio_module: public audio_module { -private: - float freq_old, ceil_old; - bool ceil_active_old; - stereo_in_out_metering meters; - float meter_drive; - dsp::biquad_d2 hp[2][4]; - dsp::biquad_d2 lp[2][2]; - dsp::tap_distortion dist[2]; -public: - uint32_t srate; - bool is_active; - exciter_audio_module(); - void activate(); - void deactivate(); - void params_changed(); - void set_sample_rate(uint32_t sr); - uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask); -}; - -/// Bass Enhancer by Markus Schmidt (based on Krzysztof's filters and Tom's distortion algorythm) -class bassenhancer_audio_module: public audio_module { -private: - float freq_old, floor_old; - bool floor_active_old; - stereo_in_out_metering meters; - float meter_drive; - dsp::biquad_d2 lp[2][4]; - dsp::biquad_d2 hp[2][2]; - dsp::tap_distortion dist[2]; -public: - uint32_t srate; - bool is_active; - bassenhancer_audio_module(); - void activate(); - void deactivate(); - void params_changed(); - void set_sample_rate(uint32_t sr); - uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask); -}; - -}; - -#endif diff --git a/plugins/LadspaEffect/calf/src/calf/modules_eq.h b/plugins/LadspaEffect/calf/src/calf/modules_eq.h deleted file mode 100644 index 61c6c2856d2..00000000000 --- a/plugins/LadspaEffect/calf/src/calf/modules_eq.h +++ /dev/null @@ -1,90 +0,0 @@ -/* Calf DSP plugin pack - * Equalization related plugins - * - * Copyright (C) 2001-2010 Krzysztof Foltman, Markus Schmidt, Thor Harald Johansen and others - * - * 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_MODULES_EQ_H -#define CALF_MODULES_EQ_H - -#include -#include -#include "biquad.h" -#include "inertia.h" -#include "audio_fx.h" -#include "giface.h" -#include "metadata.h" -#include "plugin_tools.h" - -namespace calf_plugins { - -/// Equalizer N Band by Markus Schmidt (based on Krzysztof's filters) -template -class equalizerNband_audio_module: public audio_module, public frequency_response_line_graph { -public: - typedef audio_module AM; - using AM::ins; - using AM::outs; - using AM::params; - using AM::in_count; - using AM::out_count; - using AM::param_count; - using AM::PeakBands; -private: - enum { graph_param_count = BaseClass::last_graph_param - BaseClass::first_graph_param + 1, params_per_band = AM::param_p2_active - AM::param_p1_active }; - float hp_mode_old, hp_freq_old; - float lp_mode_old, lp_freq_old; - float ls_level_old, ls_freq_old; - float hs_level_old, hs_freq_old; - float p_level_old[PeakBands], p_freq_old[PeakBands], p_q_old[PeakBands]; - mutable float old_params_for_graph[graph_param_count]; - dual_in_out_metering meters; - CalfEqMode hp_mode, lp_mode; - dsp::biquad_d2 hp[3][2], lp[3][2]; - dsp::biquad_d2 lsL, lsR, hsL, hsR; - dsp::biquad_d2 pL[PeakBands], pR[PeakBands]; - - inline void process_hplp(float &left, float &right); -public: - typedef std::complex cfloat; - uint32_t srate; - bool is_active; - mutable volatile int last_generation, last_calculated_generation; - equalizerNband_audio_module(); - void activate(); - void deactivate(); - - void params_changed(); - float freq_gain(int index, double freq, uint32_t sr) const; - void set_sample_rate(uint32_t sr) - { - srate = sr; - meters.set_sample_rate(sr); - } - uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask); - bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const; - bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const; - int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const; -}; - -typedef equalizerNband_audio_module equalizer5band_audio_module; -typedef equalizerNband_audio_module equalizer8band_audio_module; -typedef equalizerNband_audio_module equalizer12band_audio_module; - -}; - -#endif diff --git a/plugins/LadspaEffect/calf/src/calf/modules_limit.h b/plugins/LadspaEffect/calf/src/calf/modules_limit.h deleted file mode 100644 index 850aff80d7a..00000000000 --- a/plugins/LadspaEffect/calf/src/calf/modules_limit.h +++ /dev/null @@ -1,99 +0,0 @@ -/* Calf DSP plugin pack - * Limiter related plugins - * - * Copyright (C) 2001-2010 Krzysztof Foltman, Markus Schmidt, Thor Harald Johansen and others - * - * 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_MODULES_LIMIT_H -#define CALF_MODULES_LIMIT_H - -#include -#include -#include "biquad.h" -#include "inertia.h" -#include "audio_fx.h" -#include "giface.h" -#include "metadata.h" -#include "plugin_tools.h" - -namespace calf_plugins { - -/// Limiter by Markus Schmidt and Christian Holschuh -class limiter_audio_module: public audio_module, public line_graph_iface { -private: - typedef limiter_audio_module AM; - uint32_t clip_inL, clip_inR, clip_outL, clip_outR, asc_led; - int mode, mode_old; - float meter_inL, meter_inR, meter_outL, meter_outR; - dsp::lookahead_limiter limiter; -public: - uint32_t srate; - bool is_active; - float limit_old; - bool asc_old; - float attack_old; - limiter_audio_module(); - void activate(); - void deactivate(); - void params_changed(); - uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask); - void set_sample_rate(uint32_t sr); -}; - -/// Multiband Limiter by Markus Schmidt and Christian Holschuh -class multibandlimiter_audio_module: public audio_module, public line_graph_iface { -private: - typedef multibandlimiter_audio_module AM; - static const int strips = 4; - uint32_t clip_inL, clip_inR, clip_outL, clip_outR, asc_led; - int mode, mode_old; - bool solo[strips]; - bool no_solo; - float meter_inL, meter_inR, meter_outL, meter_outR; - dsp::lookahead_limiter strip[strips]; - dsp::lookahead_limiter broadband; - dsp::biquad_d2 lpL[strips - 1][3], lpR[strips - 1][3], hpL[strips - 1][3], hpR[strips - 1][3]; - float freq_old[strips - 1], sep_old[strips - 1], q_old[strips - 1]; - unsigned int pos; - unsigned int buffer_size; - unsigned int overall_buffer_size; - float *buffer; - int channels; - float striprel[strips]; - float weight[strips]; - float weight_old[strips]; - float limit_old; - bool asc_old; - float attack_old; - bool _sanitize; -public: - uint32_t srate; - bool is_active; - multibandlimiter_audio_module(); - ~multibandlimiter_audio_module(); - void activate(); - void deactivate(); - void params_changed(); - uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask); - void set_sample_rate(uint32_t sr); - bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const; - bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const; -}; - -}; - -#endif diff --git a/plugins/LadspaEffect/calf/src/calf/modules_mod.h b/plugins/LadspaEffect/calf/src/calf/modules_mod.h deleted file mode 100644 index bee6d37775e..00000000000 --- a/plugins/LadspaEffect/calf/src/calf/modules_mod.h +++ /dev/null @@ -1,190 +0,0 @@ -/* Calf DSP plugin pack - * Modulation effect plugins - * - * Copyright (C) 2001-2010 Krzysztof Foltman, Markus Schmidt, Thor Harald Johansen and others - * - * 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_MODULES_MOD_H -#define CALF_MODULES_MOD_H - -#include -#include -#include "biquad.h" -#include "inertia.h" -#include "audio_fx.h" -#include "giface.h" -#include "metadata.h" -#include "multichorus.h" - -namespace calf_plugins { - -class flanger_audio_module: public audio_module, public frequency_response_line_graph -{ -public: - dsp::simple_flanger left, right; - uint32_t srate; - bool clear_reset; - float last_r_phase; - bool is_active; -public: - flanger_audio_module() { - is_active = false; - } - void set_sample_rate(uint32_t sr); - void params_changed(); - void params_reset(); - void activate(); - void deactivate(); - uint32_t process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask) { - left.process(outs[0] + offset, ins[0] + offset, nsamples); - right.process(outs[1] + offset, ins[1] + offset, nsamples); - return outputs_mask; // XXXKF allow some delay after input going blank - } - bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const; - float freq_gain(int subindex, float freq, float srate) const; -}; - -class phaser_audio_module: public audio_module, public frequency_response_line_graph -{ -public: - enum { MaxStages = 12 }; - uint32_t srate; - bool clear_reset; - float last_r_phase; - dsp::simple_phaser left, right; - float x1vals[2][MaxStages], y1vals[2][MaxStages]; - bool is_active; -public: - phaser_audio_module(); - void params_changed(); - void params_reset(); - void activate(); - void set_sample_rate(uint32_t sr); - void deactivate(); - uint32_t process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask) { - left.process(outs[0] + offset, ins[0] + offset, nsamples); - right.process(outs[1] + offset, ins[1] + offset, nsamples); - return outputs_mask; // XXXKF allow some delay after input going blank - } - bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const; - bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const; - float freq_gain(int subindex, float freq, float srate) const; -}; - -class rotary_speaker_audio_module: public audio_module -{ -public: - /// Current phases and phase deltas for bass and treble rotors - uint32_t phase_l, dphase_l, phase_h, dphase_h; - dsp::simple_delay<1024, float> delay; - dsp::biquad_d2 crossover1l, crossover1r, crossover2l, crossover2r, damper1l, damper1r; - dsp::simple_delay<8, float> phaseshift; - uint32_t srate; - int vibrato_mode; - /// Current CC1 (Modulation) value, normalized to [0, 1] - float mwhl_value; - /// Current CC64 (Hold) value, normalized to [0, 1] - float hold_value; - /// Current rotation speed for bass rotor - automatic mode - float aspeed_l; - /// Current rotation speed for treble rotor - automatic mode - float aspeed_h; - /// Desired speed (0=slow, 1=fast) - automatic mode - float dspeed; - /// Current rotation speed for bass rotor - manual mode - float maspeed_l; - /// Current rotation speed for treble rotor - manual mode - float maspeed_h; - - int meter_l, meter_h; - - rotary_speaker_audio_module(); - void set_sample_rate(uint32_t sr); - void setup(); - void activate(); - void deactivate(); - - void params_changed(); - void set_vibrato(); - /// Convert RPM speed to delta-phase - uint32_t rpm2dphase(float rpm); - /// Set delta-phase variables based on current calculated (and interpolated) RPM speed - void update_speed(); - void update_speed_manual(float delta); - /// Increase or decrease aspeed towards raspeed, with required negative and positive rate - bool incr_towards(float &aspeed, float raspeed, float delta_decc, float delta_acc); - uint32_t process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask); - virtual void control_change(int channel, int ctl, int val); -}; - -/// A multitap stereo chorus thing -class multichorus_audio_module: public audio_module, public frequency_response_line_graph -{ -public: - uint32_t srate; - dsp::multichorus, dsp::filter_sum, dsp::biquad_d2<> >, 4096> left, right; - float last_r_phase; - float cutoff; - bool is_active; - -public: - multichorus_audio_module(); - void params_changed(); - uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask); - void activate(); - void deactivate(); - void set_sample_rate(uint32_t sr); - bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const; - float freq_gain(int subindex, float freq, float srate) const; - bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const; - bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const; -}; - -/// Pulsator by Markus Schmidt -class pulsator_audio_module: public audio_module, public frequency_response_line_graph { -private: - typedef pulsator_audio_module AM; - uint32_t clip_inL, clip_inR, clip_outL, clip_outR; - float meter_inL, meter_inR, meter_outL, meter_outR; - float offset_old; - int mode_old; - bool clear_reset; - dsp::simple_lfo lfoL, lfoR; -public: - uint32_t srate; - bool is_active; - pulsator_audio_module(); - void activate(); - void deactivate(); - void params_changed(); - void set_sample_rate(uint32_t sr); - void params_reset() - { - if (clear_reset) { - *params[param_reset] = 0.f; - clear_reset = false; - } - } - uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask); - bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const; - bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const; - bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const; -}; - -}; - -#endif diff --git a/plugins/LadspaEffect/calf/src/calf/modules_synths.h b/plugins/LadspaEffect/calf/src/calf/modules_synths.h deleted file mode 100644 index 161166813f3..00000000000 --- a/plugins/LadspaEffect/calf/src/calf/modules_synths.h +++ /dev/null @@ -1,193 +0,0 @@ -/* Calf DSP Library - * Audio modules - synthesizers - * - * Copyright (C) 2001-2007 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_MODULES_SYNTHS_H -#define __CALF_MODULES_SYNTHS_H - -#include "biquad.h" -#include "onepole.h" -#include "audio_fx.h" -#include "inertia.h" -#include "osc.h" -#include "synth.h" -#include "envelope.h" -#include "modmatrix.h" -#include "metadata.h" - -namespace calf_plugins { - -#define MONOSYNTH_WAVE_BITS 12 - -/// Monosynth-in-making. Parameters may change at any point, so don't make songs with it! -/// It lacks inertia for parameters, even for those that really need it. -class monosynth_audio_module: public audio_module, public line_graph_iface, public mod_matrix_impl -{ -public: - uint32_t srate, crate; - static dsp::waveform_family *waves; - dsp::waveform_oscillator osc1, osc2; - dsp::triangle_lfo lfo1, lfo2; - dsp::biquad_d1_lerp filter, filter2; - /// The step code is producing non-zero values - bool running; - /// This is the last non-zero buffer (set on calculate_step after fadeout is complete, the next calculate_step will zero running) - bool stopping; - /// A key is kept pressed - bool gate; - /// All notes off fadeout - bool force_fadeout; - /// Last triggered note - int last_key; - - /// Output buffers, used to ensure updates are done every step_size regardless of process buffer size - float buffer[step_size], buffer2[step_size]; - /// Read position within the buffers, on each '0' the buffers are being filled with new data by calculate_step - uint32_t output_pos; - /// Waveform number - OSC1 - int wave1; - /// Waveform number - OSC2 - int wave2; - /// Last used waveform number - OSC1 - int prev_wave1; - /// Last used waveform number - OSC2 - int prev_wave2; - /// Filter type - int filter_type; - /// Filter type on the last calculate_step - int last_filter_type; - float freq, start_freq, target_freq, cutoff, fgain, fgain_delta, separation; - float detune, xpose, xfade, ampctl, fltctl; - float odcr, porta_time, lfo_bend; - /// Modulation wheel position (0.f-1.f) - float modwheel_value; - /// Delay counter for LFOs - float lfo_clock; - /// Last value of phase shift for pulse width emulation for OSC1 - int32_t last_pwshift1; - /// Last value of phase shift for pulse width emulation for OSC2 - int32_t last_pwshift2; - /// Last value of stretch for osc sync emulation for OSC1 - int32_t last_stretch1; - /// Next note to play on the next calculate_step - int queue_note_on; - /// Whether the queued note has been already released - bool queue_note_on_and_off; - /// Velocity of the next note to play - float queue_vel; - /// Integer value for modwheel (0-16383, read from CC1 - MSBs and CC33 - LSBs) - int modwheel_value_int; - /// Legato mode (bitmask) - int legato; - /// Envelope Generators - dsp::adsr envelope1, envelope2; - dsp::keystack stack; - /// Smoothing for master volume - dsp::gain_smoothing master; - /// Fadeout for buffer 1 - dsp::fadeout fadeout; - /// Fadeout for buffer 2 - dsp::fadeout fadeout2; - /// Smoothed cutoff value - dsp::inertia inertia_cutoff; - /// Smoothed pitch bend value - dsp::inertia inertia_pitchbend; - /// Smoothed channel pressure value - dsp::inertia inertia_pressure; - /// Rows of the modulation matrix - dsp::modulation_entry mod_matrix_data[mod_matrix_slots]; - /// Currently used velocity - float velocity; - /// Last value of oscillator mix ratio - float last_xfade; - /// Current calculated mod matrix outputs - float moddest[moddest_count]; - - monosynth_audio_module(); - static void precalculate_waves(progress_report_iface *reporter); - void set_sample_rate(uint32_t sr); - void delayed_note_on(); - /// Release a note (physically), called from note-off handler or when note-off has been scheduled after note-on (very short queued note) - void end_note(); - /// Handle MIDI Note On message (does not immediately trigger a note, as it must start on - /// boundary of step_size samples). - void note_on(int channel, int note, int vel); - /// Handle MIDI Note Off message - void note_off(int channel, int note, int vel); - /// Handle MIDI Channel Pressure - void channel_pressure(int channel, int value); - /// Handle pitch bend message. - inline void pitch_bend(int /*channel*/, int value) - { - inertia_pitchbend.set_inertia(pow(2.0, (value * *params[par_pwhlrange]) / (1200.0 * 8192.0))); - } - /// Update oscillator frequency based on base frequency, detune amount, pitch bend scaling factor and sample rate. - void set_frequency(); - /// Handle control change messages. - void control_change(int channel, int controller, int value); - /// Update variables from control ports. - void params_changed(); - void activate(); - void deactivate(); - void post_instantiate() - { - precalculate_waves(progress_report); - } - /// Set waveform addresses for oscillators - void lookup_waveforms(); - /// Run oscillators - void calculate_buffer_oscs(float lfo); - /// Run two filters in series to produce mono output samples. - void calculate_buffer_ser(); - /// Run one filter to produce mono output samples. - void calculate_buffer_single(); - /// Run two filters (one per channel) to produce stereo output samples. - void calculate_buffer_stereo(); - /// Retrieve filter graph (which is 'live' so it cannot be generated by get_static_graph), or fall back to get_static_graph. - bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const; - /// @retval true if the filter 1 is to be used for the left channel and filter 2 for the right channel - /// @retval false if filters are to be connected in series and sent (mono) to both channels - inline bool is_stereo_filter() const - { - return filter_type == flt_2lp12 || filter_type == flt_2bp6; - } - /// No CV inputs for now - bool is_cv(int param_no) const { return false; } - /// Practically all the stuff here is noisy - bool is_noisy(int param_no) const { return param_no != par_cutoff; } - /// Calculate control signals and produce step_size samples of output. - void calculate_step(); - /// Apply anti-click'n'pop fadeout (used at the end of the sound) - void apply_fadeout(); - /// Main processing function - uint32_t process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask); - /// Send all configure variables set within a plugin to given destination (which may be limited to only those that plugin understands) - virtual void send_configures(send_configure_iface *sci) { return mod_matrix_impl::send_configures(sci); } - virtual char *configure(const char *key, const char *value) { return mod_matrix_impl::configure(key, value); } -}; - -}; - -#if ENABLE_EXPERIMENTAL - -#include "wavetable.h" - -#endif - -#endif diff --git a/plugins/LadspaEffect/calf/src/calf/multichorus.h b/plugins/LadspaEffect/calf/src/calf/multichorus.h deleted file mode 100644 index b954603ab3f..00000000000 --- a/plugins/LadspaEffect/calf/src/calf/multichorus.h +++ /dev/null @@ -1,213 +0,0 @@ -/* Calf DSP Library - * Multitap chorus class. - * - * Copyright (C) 2001-2007 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_MULTICHORUS_H -#define __CALF_MULTICHORUS_H - -#include "audio_fx.h" - -namespace dsp { - -typedef fixed_point chorus_phase; - -template -class sine_multi_lfo -{ -protected: - sine_table sine; - -public: - /// Current LFO phase - chorus_phase phase; - /// LFO phase increment - chorus_phase dphase; - /// LFO phase per-voice increment - chorus_phase vphase; - /// Current number of voices - uint32_t voices; - /// Current scale (output multiplier) - T scale; - /// Per-voice offset unit (the value that says how much the voices are offset with respect to each other in non-100% 'overlap' mode), scaled so that full range = 131072 - int32_t voice_offset; - /// LFO Range scaling for non-100% overlap - uint32_t voice_depth; -public: - sine_multi_lfo() - { - phase = dphase = vphase = 0.0; - voice_offset = 0; - voice_depth = 1U << 31; - - set_voices(Voices); - } - inline uint32_t get_voices() const - { - return voices; - } - inline void set_voices(uint32_t value) - { - voices = value; - // use sqrt, because some phases will cancel each other - so 1 / N is usually too low - scale = sqrt(1.0 / voices); - } - inline void set_overlap(float overlap) - { - // If we scale the delay amount so that full range of a single LFO is 0..1, all the overlapped LFOs will cover 0..range - // How it's calculated: - // 1. First voice is assumed to always cover the range of 0..1 - // 2. Each remaining voice contributes an interval of a width = 1 - overlap, starting from the end of the interval of the previous voice - // Coverage = non-overlapped part of the LFO range in the 1st voice - float range = 1.f + (1.f - overlap) * (voices - 1); - float scaling = 1.f / range; - voice_offset = (int)(131072 * (1 - overlap) / range); - voice_depth = (unsigned int)((1U << 30) * 1.0 * scaling); - } - /// Get LFO value for given voice, returns a values in range of [-65536, 65535] (or close) - inline int get_value(uint32_t voice) const { - // find this voice's phase (= phase + voice * 360 degrees / number of voices) - chorus_phase voice_phase = phase + vphase * (int)voice; - // find table offset - unsigned int ipart = voice_phase.ipart(); - // interpolate (use 14 bits of precision - because the table itself uses 17 bits and the result of multiplication must fit in int32_t) - // note, the result is still -65535 .. 65535, it's just interpolated - // it is never reaching -65536 - but that's acceptable - int intval = voice_phase.lerp_by_fract_int(sine.data[ipart], sine.data[ipart+1]); - // apply the voice offset/depth (rescale from -65535..65535 to appropriate voice's "band") - return -65535 + voice * voice_offset + ((voice_depth >> (30-13)) * (65536 + intval) >> 13); - } - inline void step() { - phase += dphase; - } - inline T get_scale() const { - return scale; - } - void reset() { - phase = 0.f; - } -}; - -/** - * Multi-tap chorus without feedback. - * Perhaps MaxDelay should be a bit longer! - */ -template -class multichorus: public chorus_base -{ -protected: - simple_delay delay; -public: - MultiLfo lfo; - Postprocessor post; -public: - multichorus() { - rate = 0.63f; - dry = 0.5f; - wet = 0.5f; - min_delay = 0.005f; - mod_depth = 0.0025f; - setup(44100); - } - void reset() { - delay.reset(); - lfo.reset(); - } - void set_rate(float rate) { - chorus_base::set_rate(rate); - lfo.dphase = dphase; - } - virtual void setup(int sample_rate) { - modulation_effect::setup(sample_rate); - delay.reset(); - lfo.reset(); - set_min_delay(get_min_delay()); - set_mod_depth(get_mod_depth()); - } - template - void process(OutIter buf_out, InIter buf_in, int nsamples) { - int mds = min_delay_samples + mod_depth_samples * 1024 + 2*65536; - int mdepth = mod_depth_samples; - // 1 sample peak-to-peak = mod_depth_samples of 32 (this scaling stuff is tricky and may - but shouldn't - be wrong) - // with 192 kHz sample rate, 1 ms = 192 samples, and the maximum 20 ms = 3840 samples (so, 4096 will be used) - // 3840 samples of mod depth = mdepth of 122880 (which multiplied by 65536 doesn't fit in int32_t) - // so, it will be right-shifted by 2, which gives it a safe range of 30720 - // NB: calculation of mod_depth_samples (and multiply-by-32) is in chorus_base::set_mod_depth - mdepth = mdepth >> 2; - T scale = lfo.get_scale(); - for (int i=0; i> 2) + 1 because the LFO value is in range of [-65535, 65535] (17 bits) - int dv = mds + (mdepth * lfo_output >> (3 + 1)); - int ifv = dv >> 16; - T fd; // signal from delay's output - delay.get_interp(fd, ifv, (dv & 0xFFFF)*(1.0/65536.0)); - out += fd; - } - // apply the post filter - out = post.process(out); - T sdry = in * gs_dry.get(); - T swet = out * gs_wet.get() * scale; - *buf_out++ = sdry + swet; - lfo.step(); - } - post.sanitize(); - } - float freq_gain(float freq, float sr) const - { - typedef std::complex cfloat; - freq *= 2.0 * M_PI / sr; - cfloat z = 1.0 / exp(cfloat(0.0, freq)); // z^-1 - cfloat h = 0.0; - int mds = min_delay_samples + mod_depth_samples * 1024 + 2*65536; - int mdepth = mod_depth_samples; - mdepth = mdepth >> 2; - T scale = lfo.get_scale(); - unsigned int nvoices = lfo.get_voices(); - for (unsigned int v = 0; v < nvoices; v++) - { - int lfo_output = lfo.get_value(v); - // 3 = log2(32 >> 2) + 1 because the LFO value is in range of [-65535, 65535] (17 bits) - int dv = mds + (mdepth * lfo_output >> (3 + 1)); - int fldp = dv >> 16; - cfloat zn = std::pow(z, fldp); // z^-N - h += zn + (zn * z - zn) * cfloat(dv / 65536.0 - fldp); - } - // apply the post filter - h *= post.h_z(z); - // mix with dry signal - float v = std::abs(cfloat(gs_dry.get_last()) + cfloat(scale * gs_wet.get_last()) * h); - return v; - } -}; - -}; - -#endif - - diff --git a/plugins/LadspaEffect/calf/src/calf/onepole.h b/plugins/LadspaEffect/calf/src/calf/onepole.h deleted file mode 100644 index 5fdc669421a..00000000000 --- a/plugins/LadspaEffect/calf/src/calf/onepole.h +++ /dev/null @@ -1,192 +0,0 @@ -/* Calf DSP Library - * Basic one-pole one-zero filters based on bilinear transform. - * Copyright (C) 2001-2007 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_ONEPOLE_H -#define __CALF_ONEPOLE_H - -#include "primitives.h" - -namespace dsp { - -/** - * one-pole filter, for floating point values - * coefficient calculation is based on bilinear transform, and the code itself is based on my very old OneSignal lib - * lp and hp are *somewhat* tested, allpass is not tested at all - * don't use this for integers because it won't work - */ -template -class onepole -{ -public: - typedef std::complex cfloat; - - T x1, y1; - Coeff a0, a1, b1; - - onepole() - { - reset(); - } - - /// Set coefficients for a lowpass filter - void set_lp(float fc, float sr) - { - // x x - // x+1 x-1 - Coeff x = tan (M_PI * fc / (2 * sr)); - Coeff q = 1/(1+x); - a0 = a1 = x*q; - b1 = (x-1)*q; - } - - /// Set coefficients for an allpass filter - void set_ap(float fc, float sr) - { - // x-1 x+1 - // x+1 x-1 - Coeff x = tan (M_PI * fc / (2 * sr)); - Coeff q = 1/(1+x); - b1 = a0 = (x-1)*q; - a1 = 1; - } - - /// Set coefficients for an allpass filter, using omega instead of fc and sr - /// omega = (PI / 2) * fc / sr - void set_ap_w(float w) - { - // x-1 x+1 - // x+1 x-1 - Coeff x = tan (w); - Coeff q = 1/(1+x); - b1 = a0 = (x-1)*q; - a1 = 1; - } - - /// Set coefficients for a highpass filter - void set_hp(float fc, float sr) - { - // x -x - // x+1 x-1 - Coeff x = tan (M_PI * fc / (2 * sr)); - Coeff q = 1/(1+x); - a0 = q; - a1 = -a0; - b1 = (x-1)*q; - } - - /// Process one sample - inline T process(T in) - { - T out = in * a0 + x1 * a1 - y1 * b1; - x1 = in; - y1 = out; - return out; - } - - /// Process one sample, assuming it's a lowpass filter (optimized special case) - inline T process_lp(T in) - { - T out = (in + x1) * a0 - y1 * b1; - x1 = in; - y1 = out; - return out; - } - - /// Process one sample, assuming it's a highpass filter (optimized special case) - inline T process_hp(T in) - { - T out = (in - x1) * a0 - y1 * b1; - x1 = in; - y1 = out; - return out; - } - - /// Process one sample, assuming it's an allpass filter (optimized special case) - inline T process_ap(T in) - { - T out = (in - y1) * a0 + x1; - x1 = in; - y1 = out; - return out; - } - - /// Process one sample using external state variables - inline T process_ap(T in, float &x1, float &y1) - { - T out = (in - y1) * a0 + x1; - x1 = in; - y1 = out; - return out; - } - - /// Process one sample using external state variables, including filter coeff - inline T process_ap(T in, float &x1, float &y1, float a0) - { - T out = (in - y1) * a0 + x1; - x1 = in; - y1 = out; - return out; - } - - inline bool empty() const { - return y1 == 0; - } - - inline void sanitize() - { - dsp::sanitize(x1); - dsp::sanitize(y1); - } - - inline void reset() - { - dsp::zero(x1); - dsp::zero(y1); - } - - template - inline void copy_coeffs(const onepole &src) - { - a0 = src.a0; - a1 = src.a1; - b1 = src.b1; - } - - /// Return the filter's gain at frequency freq - /// @param freq Frequency to look up - /// @param sr Filter sample rate (used to convert frequency to angular frequency) - float freq_gain(float freq, float sr) const - { - freq *= 2.0 * M_PI / sr; - cfloat z = 1.0 / exp(cfloat(0.0, freq)); - - return std::abs(h_z(z)); - } - - /// Return H(z) the filter's gain at frequency freq - /// @param z Z variable (e^jw) - cfloat h_z(const cfloat &z) const - { - return (cfloat(a0) + double(a1) * z) / (cfloat(1.0) + double(b1) * z); - } -}; - -}; - -#endif diff --git a/plugins/LadspaEffect/calf/src/calf/organ.h b/plugins/LadspaEffect/calf/src/calf/organ.h deleted file mode 100644 index fe830b1796b..00000000000 --- a/plugins/LadspaEffect/calf/src/calf/organ.h +++ /dev/null @@ -1,359 +0,0 @@ -/* Calf DSP Library - * Drawbar organ emulator. - * - * Copyright (C) 2007 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_ORGAN_H -#define __CALF_ORGAN_H - -#include "audio_fx.h" -#include "envelope.h" -#include "metadata.h" -#include "osc.h" -#include "synth.h" - -#define ORGAN_KEYTRACK_POINTS 4 - -namespace dsp -{ - -struct organ_parameters { - enum { FilterCount = 2, EnvCount = 3 }; - struct organ_filter_parameters - { - float cutoff; - float resonance; - float envmod[organ_parameters::EnvCount]; - float keyf; - }; - - struct organ_env_parameters - { - float attack, decay, sustain, release, velscale, ampctl; - }; - - ////////////////////////////////////////////////////////////////////////// - // these parameters are binary-copied from control ports (order is important!) - - float drawbars[9]; - float harmonics[9]; - float waveforms[9]; - float detune[9]; - float phase[9]; - float pan[9]; - float routing[9]; - float foldover; - float percussion_time; - float percussion_level; - float percussion_wave; - float percussion_harmonic; - float percussion_vel2amp; - float percussion_fm_time; - float percussion_fm_depth; - float percussion_fm_wave; - float percussion_fm_harmonic; - float percussion_vel2fm; - float percussion_trigger; - float percussion_stereo; - float filter_chain; - float filter1_type; - float master; - - organ_filter_parameters filters[organ_parameters::FilterCount]; - organ_env_parameters envs[organ_parameters::EnvCount]; - float lfo_rate; - float lfo_amt; - float lfo_wet; - float lfo_phase; - float lfo_mode; - float lfo_type; - - float global_transpose; - float global_detune; - - float polyphony; - - float quad_env; - - float pitch_bend_range; - - float bass_freq; - float bass_gain; - float treble_freq; - float treble_gain; - - float dummy_mapcurve; - - ////////////////////////////////////////////////////////////////////////// - // these parameters are calculated - - double perc_decay_const, perc_fm_decay_const; - float multiplier[9]; - int phaseshift[9]; - float cutoff; - unsigned int foldvalue; - float pitch_bend; - - float percussion_keytrack[ORGAN_KEYTRACK_POINTS][2]; - - organ_parameters() : pitch_bend(1.0f) {} - - inline int get_percussion_wave() { return dsp::fastf2i_drm(percussion_wave); } - inline int get_percussion_fm_wave() { return dsp::fastf2i_drm(percussion_fm_wave); } -}; - -#define ORGAN_WAVE_BITS 12 -#define ORGAN_WAVE_SIZE 4096 -#define ORGAN_BIG_WAVE_BITS 17 -#define ORGAN_BIG_WAVE_SIZE 131072 -/// 2^ORGAN_BIG_WAVE_SHIFT = how many (quasi)periods per sample -#define ORGAN_BIG_WAVE_SHIFT 5 - -class organ_voice_base: public calf_plugins::organ_enums -{ -public: - typedef waveform_family small_wave_family; - typedef waveform_family big_wave_family; -public: - organ_parameters *parameters; -protected: - static small_wave_family (*waves)[wave_count_small]; - static big_wave_family (*big_waves)[wave_count_big]; - - int note; - dsp::decay amp; - /// percussion FM carrier amplitude envelope - dsp::decay pamp; - /// percussion FM modulator amplitude envelope - dsp::decay fm_amp; - dsp::fixed_point pphase, dpphase; - dsp::fixed_point modphase, moddphase; - float fm_keytrack; - int &sample_rate_ref; - bool &released_ref; - /// pamp per-sample (linear) step during release stage (calculated on release so that it will take 30ms for it to go from "current value at release point" to 0) - float rel_age_const; - - organ_voice_base(organ_parameters *_parameters, int &_sample_rate_ref, bool &_released_ref); - - inline float wave(float *data, dsp::fixed_point ph) { - return ph.lerp_table_lookup_float(data); - } - inline float big_wave(float *data, dsp::fixed_point &ph) { - // wrap to fit within the wave - return ph.lerp_table_lookup_float_mask(data, ORGAN_BIG_WAVE_SIZE - 1); - } -public: - static inline small_wave_family &get_wave(int wave) { - return (*waves)[wave]; - } - static inline big_wave_family &get_big_wave(int wave) { - return (*big_waves)[wave]; - } - static void precalculate_waves(calf_plugins::progress_report_iface *reporter); - void update_pitch(); - // this doesn't really have a voice interface - void render_percussion_to(float (*buf)[2], int nsamples); - void perc_note_on(int note, int vel); - void perc_note_off(int note, int vel); - void perc_reset(); -}; - -/// A simple (and bad) simulation of scanner vibrato based on a series of modulated allpass filters -class organ_vibrato -{ -protected: - enum { VibratoSize = 6 }; - float vibrato_x1[VibratoSize][2], vibrato_y1[VibratoSize][2]; - float lfo_phase; - dsp::onepole vibrato[2]; -public: - void reset(); - void process(organ_parameters *parameters, float (*data)[2], unsigned int len, float sample_rate); -}; - -/// A more sophisticated simulation of scanner vibrato. Simulates a line box -/// and an interpolating scanner. The line box is a series of 18 2nd order -/// lowpass filters with cutoff frequency ~4kHz, with loss compensation. -/// The interpolating scanner uses linear interpolation to "slide" between -/// selected outputs of the line box. -/// -/// @note -/// This is a true CPU hog, and it should be optimised some day. -/// @note -/// The line box is mono. 36 lowpass filters might be an overkill. -/// @note -/// See also: http://www.jhaible.de/interpolating_scanner_and_scanvib/jh_interpolating_scanner_and_scanvib.html -/// (though it's a very loose adaptation of that version) -class scanner_vibrato -{ -protected: - enum { ScannerSize = 18 }; - float lfo_phase; - dsp::biquad_d2 scanner[ScannerSize]; - organ_vibrato legacy; -public: - void reset(); - void process(organ_parameters *parameters, float (*data)[2], unsigned int len, float sample_rate); -}; - -class organ_voice: public dsp::voice, public organ_voice_base { -protected: - enum { Channels = 2, BlockSize = 64, EnvCount = organ_parameters::EnvCount, FilterCount = organ_parameters::FilterCount }; - union { - float output_buffer[BlockSize][Channels]; - float aux_buffers[3][BlockSize][Channels]; - }; - dsp::fixed_point phase, dphase; - dsp::biquad_d1 filterL[2], filterR[2]; - adsr envs[EnvCount]; - dsp::inertia expression; - scanner_vibrato vibrato; - float velocity; - bool perc_released; - /// The envelopes have ended and the voice is in final fadeout stage - bool finishing; - dsp::inertia inertia_pitchbend; - -public: - organ_voice() - : organ_voice_base(NULL, sample_rate, perc_released) - , expression(dsp::linear_ramp(16)) - , inertia_pitchbend(dsp::exponential_ramp(1)) - { - inertia_pitchbend.set_now(1); - } - - void reset(); - void note_on(int note, int vel); - void note_off(int /* vel */); - virtual float get_priority() { return stolen ? 20000 : (perc_released ? 1 : (sostenuto ? 200 : 100)); } - virtual void steal(); - void render_block(); - - virtual int get_current_note() { - return note; - } - virtual bool get_active() { - // printf("note %d getactive %d use_percussion %d pamp active %d\n", note, amp.get_active(), use_percussion(), pamp.get_active()); - return (note != -1) && (amp.get_active() || (use_percussion() && pamp.get_active())); - } - void update_pitch(); - inline bool use_percussion() - { - return dsp::fastf2i_drm(parameters->percussion_trigger) == perctrig_polyphonic && parameters->percussion_level > 0; - } -}; - -/// Not a true voice, just something with similar-ish interface. -class percussion_voice: public organ_voice_base { -public: - int sample_rate; - bool released; - - percussion_voice(organ_parameters *_parameters) - : organ_voice_base(_parameters, sample_rate, released) - , released(false) - { - } - - bool get_active() { - return (note != -1) && pamp.get_active(); - } - bool get_noticable() { - return (note != -1) && (pamp.get() > 0.2 * parameters->percussion_level); - } - void setup(int sr) { - sample_rate = sr; - } -}; - -struct drawbar_organ: public dsp::basic_synth, public calf_plugins::organ_enums { - organ_parameters *parameters; - percussion_voice percussion; - scanner_vibrato global_vibrato; - two_band_eq eq_l, eq_r; - - drawbar_organ(organ_parameters *_parameters) - : parameters(_parameters) - , percussion(_parameters) { - } - void render_separate(float *output[], int nsamples); - dsp::voice *alloc_voice(); - virtual void percussion_note_on(int note, int vel); - virtual void params_changed() = 0; - virtual void setup(int sr); - void update_params(); - void control_change(int controller, int value) - { - dsp::basic_synth::control_change(controller, value); - } - void pitch_bend(int amt); - virtual bool check_percussion(); -}; - -}; - -namespace calf_plugins { - -struct organ_audio_module: public audio_module, public dsp::drawbar_organ, public line_graph_iface -{ -public: - using drawbar_organ::note_on; - using drawbar_organ::note_off; - using drawbar_organ::control_change; - enum { param_count = drawbar_organ::param_count}; - dsp::organ_parameters par_values; - uint32_t srate; - bool panic_flag; - /// Value for configure variable map_curve - std::string var_map_curve; - - organ_audio_module(); - - void post_instantiate(); - - void set_sample_rate(uint32_t sr) { - srate = sr; - } - void params_changed(); - - void activate(); - void deactivate(); - uint32_t process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask); - /// No CV inputs for now - bool is_cv(int param_no) { return false; } - /// Practically all the stuff here is noisy - bool is_noisy(int param_no) { return true; } - void execute(int cmd_no); - bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const; - char *configure(const char *key, const char *value); - void send_configures(send_configure_iface *); - uint32_t message_run(const void *valid_inputs, void *output_ports); -public: - // overrides - virtual void note_on(int /*channel*/, int note, int velocity) { dsp::drawbar_organ::note_on(note, velocity); } - virtual void note_off(int /*channel*/, int note, int velocity) { dsp::drawbar_organ::note_off(note, velocity); } - virtual void control_change(int /*channel*/, int controller, int value) { dsp::drawbar_organ::control_change(controller, value); } - virtual void pitch_bend(int /*channel*/, int value) { dsp::drawbar_organ::pitch_bend(value); } -}; - -}; - -#endif diff --git a/plugins/LadspaEffect/calf/src/calf/osc.h b/plugins/LadspaEffect/calf/src/calf/osc.h deleted file mode 100644 index 779f1c00974..00000000000 --- a/plugins/LadspaEffect/calf/src/calf/osc.h +++ /dev/null @@ -1,336 +0,0 @@ -/* Calf DSP Library - * Oscillators - * - * Copyright (C) 2001-2007 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_OSC_H -#define CALF_OSC_H - -#include "fft.h" -#include - -namespace dsp -{ - -/** Very simple, non-bandlimited saw oscillator. Should not be used for anything - * else than testing/prototyping. Unless get() function is replaced with something - * with "proper" oscillator code, as the frequency setting function is fine. - */ -struct simple_oscillator -{ - /// Phase (from 0 to 0xFFFFFFFF) - uint32_t phase; - /// Per-sample phase delta (phase increment), equal to 2^32*freq/sr. - uint32_t phasedelta; - /// Reset oscillator phase to zero. - void reset() - { - phase = 0; - } - /// Set phase delta based on oscillator frequency and sample rate. - void set_freq(float freq, float sr) - { - phasedelta = (int)(freq * 65536.0 * 256.0 * 16.0 / sr) << 4; - } - /// Set phase delta based on oscillator frequency and inverse of sample rate. - void set_freq_odsr(float freq, double odsr) - { - phasedelta = (int)(freq * 65536.0 * 256.0 * 16.0 * odsr) << 4; - } - inline float get() - { - float value = (phase >> 16 ) / 65535.0 - 0.5; - phase += phasedelta; - return value; - } -}; - -/** - * FFT-based bandlimiting helper class. Allows conversion between time and frequency domains and generating brickwall filtered - * versions of a waveform given a pre-computed spectrum. - * Waveform size must be a power of two, and template argument SIZE_BITS is log2 of waveform size. - */ -template -struct bandlimiter -{ - enum { SIZE = 1 << SIZE_BITS }; - static dsp::fft &get_fft() - { - static dsp::fft fft; - return fft; - } - - std::complex spectrum[SIZE]; - - /// Import time domain waveform and calculate spectrum from it - void compute_spectrum(float input[SIZE]) - { - dsp::fft &fft = get_fft(); - std::complex *data = new std::complex[SIZE]; - for (int i = 0; i < SIZE; i++) - data[i] = input[i]; - fft.calculate(data, spectrum, false); - delete []data; - } - - /// Generate the waveform from the contained spectrum. - void compute_waveform(float output[SIZE]) - { - dsp::fft &fft = get_fft(); - std::complex *data = new std::complex[SIZE]; - fft.calculate(spectrum, data, true); - for (int i = 0; i < SIZE; i++) - output[i] = data[i].real(); - delete []data; - } - - /// remove DC offset of the spectrum (it usually does more harm than good!) - void remove_dc() - { - spectrum[0] = 0.f; - } - - /// Very basic bandlimiting (brickwall filter) - /// might need to be improved much in future! - void make_waveform(float output[SIZE], int cutoff, bool foldover = false) - { - dsp::fft &fft = get_fft(); - std::vector > new_spec, iffted; - new_spec.resize(SIZE); - iffted.resize(SIZE); - // Copy original harmonics up to cutoff point - new_spec[0] = spectrum[0]; - for (int i = 1; i < cutoff; i++) - new_spec[i] = spectrum[i], - new_spec[SIZE - i] = spectrum[SIZE - i]; - // Fill the rest with zeros, optionally folding over harmonics over the - // cutoff point into the lower octaves while halving the amplitude. - // (I think it is almost nice for bell type waveforms when the original - // waveform has few widely spread harmonics) - if (foldover) - { - std::complex fatt(0.5); - cutoff /= 2; - if (cutoff < 2) - cutoff = 2; - for (int i = SIZE / 2; i >= cutoff; i--) - { - new_spec[i / 2] += new_spec[i] * fatt; - new_spec[SIZE - i / 2] += new_spec[SIZE - i] * fatt; - new_spec[i] = 0.f, - new_spec[SIZE - i] = 0.f; - } - } - else - { - if (cutoff < 1) - cutoff = 1; - for (int i = cutoff; i < SIZE / 2; i++) - new_spec[i] = 0.f, - new_spec[SIZE - i] = 0.f; - } - // convert back to time domain (IFFT) and extract only real part - fft.calculate(&new_spec.front(), &iffted.front(), true); - for (int i = 0; i < SIZE; i++) - output[i] = iffted[i].real(); - } -}; - -/// Set of bandlimited wavetables -template -struct waveform_family: public std::map -{ - enum { SIZE = 1 << SIZE_BITS }; - using std::map::iterator; - using std::map::end; - using std::map::lower_bound; - float original[SIZE]; - - /// Fill the family using specified bandlimiter and original waveform. Optionally apply foldover. - /// Does not produce harmonics over specified limit (limit = (SIZE / 2) / min_number_of_harmonics) - void make(bandlimiter &bl, float input[SIZE], bool foldover = false, uint32_t limit = SIZE / 2) - { - memcpy(original, input, sizeof(original)); - bl.compute_spectrum(input); - make_from_spectrum(bl, foldover); - } - - /// Fill the family using specified bandlimiter and spectrum contained within. Optionally apply foldover. - /// Does not produce harmonics over specified limit (limit = (SIZE / 2) / min_number_of_harmonics) - void make_from_spectrum(bandlimiter &bl, bool foldover = false, uint32_t limit = SIZE / 2) - { - bl.remove_dc(); - - uint32_t base = 1 << (32 - SIZE_BITS); - uint32_t cutoff = SIZE / 2, top = SIZE / 2; - float vmax = 0; - for (unsigned int i = 0; i < cutoff; i++) - vmax = std::max(vmax, abs(bl.spectrum[i])); - float vthres = vmax / 1024.0; // -60dB - float cumul = 0.f; - while(cutoff > (SIZE / limit)) { - if (!foldover) - { - // skip harmonics too quiet to be heard, but measure their loudness cumulatively, - // because even if a single harmonic is too quiet, a whole bunch of them may add up - // to considerable amount of space - cumul = 0.f; - while(cutoff > 1 && cumul + abs(bl.spectrum[cutoff - 1]) < vthres) - { - cumul += abs(bl.spectrum[cutoff - 1]); - cutoff--; - } - } - float *wf = new float[SIZE+1]; - bl.make_waveform(wf, cutoff, foldover); - wf[SIZE] = wf[0]; - (*this)[base * (top / cutoff)] = wf; - cutoff = (int)(0.75 * cutoff); - } - } - - /// Retrieve waveform pointer suitable for specified phase_delta - inline float *get_level(uint32_t phase_delta) - { - iterator i = upper_bound(phase_delta); - if (i == end()) - return NULL; - // printf("Level = %08x\n", i->first); - return i->second; - } - /// Destructor, deletes the waveforms and removes them from the map. - ~waveform_family() - { - for (iterator i = begin(); i != end(); i++) - delete []i->second; - clear(); - } -}; - -#if 0 -// cubic interpolation -static inline float cerp(float pm1, float p0, float p1, float p2, float t) -{ - return (-t*(t-1)*(t-2) * pm1 + 3*(t+1)*(t-1)*(t-2) * p0 - 3*(t+1)*t*(t-2) * p1 + (t+1)*t*(t-1) * p2) * (1.0 / 6.0); -} -#endif -/** - * Simple table-based lerping oscillator. Uses waveform of size 2^SIZE_BITS. - * Combine with waveform_family if bandlimited waveforms are needed. Because - * of linear interpolation, it's usually a good idea to use large tables - * (2048-4096 points), otherwise aliasing may be produced. - */ -template -struct waveform_oscillator: public simple_oscillator -{ - enum { SIZE = 1 << SIZE_BITS, MASK = SIZE - 1, SCALE = 1 << (32 - SIZE_BITS) }; - float *waveform; - waveform_oscillator() - { - waveform = NULL; - } - - /// Get the value from single oscillator at current position - inline float get() - { - uint32_t wpos = phase >> (32 - SIZE_BITS); - return dsp::lerp(waveform[wpos], waveform[(wpos + 1) & MASK], (phase & (SCALE - 1)) * (1.0f / SCALE)); - } - /// Add/substract two phase-shifted values - inline float get_phaseshifted(uint32_t shift, float mix) - { - uint32_t wpos = phase >> (32 - SIZE_BITS); - float value1 = dsp::lerp(waveform[wpos], waveform[(wpos + 1) & MASK], (phase & (SCALE - 1)) * (1.0f / SCALE)); - wpos = (phase + shift) >> (32 - SIZE_BITS); - float value2 = dsp::lerp(waveform[wpos], waveform[(wpos + 1) & MASK], ((phase + shift) & (SCALE - 1)) * (1.0f / SCALE)); - return value1 + mix * value2; - } - /// Get the value of a hard synced osc (65536 = 1:1 ratio) - inline float get_phasedist(uint32_t sync, uint32_t shift, float mix) - { - uint32_t phase_mod = (uint64_t(phase) * sync >> 16); - - uint32_t wpos = phase_mod >> (32 - SIZE_BITS); - float value1 = dsp::lerp(waveform[wpos], waveform[(wpos + 1) & MASK], (phase & (SCALE - 1)) * (1.0f / SCALE)); - wpos = (phase_mod + shift) >> (32 - SIZE_BITS); - float value2 = dsp::lerp(waveform[wpos], waveform[(wpos + 1) & MASK], ((phase + shift) & (SCALE - 1)) * (1.0f / SCALE)); - return value1 + mix * value2; - } - /// One step - inline void advance() - { - phase += phasedelta; - } -}; - -/** - * Simple triangle LFO without any smoothing or anything of this sort. - */ -struct triangle_lfo: public simple_oscillator -{ - /// Previous value (not stored here, but may be used by calling code) - float last; - - triangle_lfo() - { - reset(); - } - void reset() - { - simple_oscillator::reset(); - last = 0; - } - inline float get() - { - uint32_t phase2 = phase; - // start at 90 degrees point of the "/\" wave (-1 to +1) - phase2 += 1<<30; - // if in second half, invert the wave (so it falls back into 0..0x7FFFFFFF) - phase2 ^= ((int32_t)phase2)>>31; - - float value = (phase2 >> 6) / 16777216.0 - 1.0; - phase += phasedelta; - return value; - } -}; - -/// Simple stupid inline function to normalize a waveform (by removing DC offset and ensuring max absolute value of 1). -static inline void normalize_waveform(float *table, unsigned int size) -{ - float dc = 0; - for (unsigned int i = 0; i < size; i++) - dc += table[i]; - dc /= size; - for (unsigned int i = 0; i < size; i++) - table[i] -= dc; - float thismax = 0; - for (unsigned int i = 0; i < size; i++) - thismax = std::max(thismax, fabsf(table[i])); - if (thismax < 0.000001f) - return; - double divv = 1.0 / thismax; - for (unsigned int i = 0; i < size; i++) - table[i] *= divv; -} - - - -}; - -#endif diff --git a/plugins/LadspaEffect/calf/src/calf/osctl.h b/plugins/LadspaEffect/calf/src/calf/osctl.h deleted file mode 100644 index 2b500174f54..00000000000 --- a/plugins/LadspaEffect/calf/src/calf/osctl.h +++ /dev/null @@ -1,561 +0,0 @@ -/* Calf DSP Library - * Open Sound Control primitives - * - * Copyright (C) 2007 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_OSCTL_H -#define __CALF_OSCTL_H - -#include -#include -#include -#include -#include -#include - -namespace osctl -{ - -enum osc_type -{ - osc_i32 = 'i', - osc_f32 = 'f', - osc_string = 's', - osc_blob = 'b', - - // unsupported - osc_i64 = 'h', - osc_ts = 't', - osc_f64 = 'd', - osc_string_alt = 'S', - osc_char = 'c', - osc_rgba = 'r', - osc_midi = 'm', - osc_true = 'T', - osc_false = 'F', - osc_nil = 'N', - osc_inf = 'I', - osc_start_array = '[', - osc_end_array = ']' -}; - -extern const char *osc_type_name(osc_type type); - -struct osc_exception: public std::exception -{ - virtual const char *what() const throw() { return "OSC parsing error"; } -}; - -struct osc_read_exception: public std::exception -{ - virtual const char *what() const throw() { return "OSC buffer underflow"; } -}; - -struct osc_write_exception: public std::exception -{ - virtual const char *what() const throw() { return "OSC buffer overflow"; } -}; - -struct null_buffer -{ - static bool read(uint8_t *dest, uint32_t bytes) - { - return false; - } - static bool write(uint8_t *dest, uint32_t bytes) - { - return true; - } - static void clear() - { - } -}; - -struct raw_buffer -{ - uint8_t *ptr; - uint32_t pos, count, size; - - raw_buffer() - { - ptr = NULL; - pos = count = size = 0; - } - raw_buffer(uint8_t *_ptr, uint32_t _count, uint32_t _size) - { - set(_ptr, _count, _size); - } - inline void set(uint8_t *_ptr, uint32_t _count, uint32_t _size) - { - ptr = _ptr; - pos = 0; - count = _count; - size = _size; - } - bool read(uint8_t *dest, uint32_t bytes) - { - if (pos + bytes > count) - return false; - memcpy(dest, ptr + pos, bytes); - pos += bytes; - return true; - } - bool write(const uint8_t *src, uint32_t bytes) - { - if (count + bytes > size) - return false; - memcpy(ptr + count, src, bytes); - count += bytes; - return true; - } - int read_left() - { - return count - pos; - } - int write_left() - { - return size - count; - } - inline int write_misalignment() - { - return 4 - (count & 3); - } - void clear() - { - pos = 0; - count = 0; - } - int tell() - { - return pos; - } - void seek(int _pos) - { - pos = _pos; - } -}; - -struct string_buffer -{ - std::string data; - uint32_t pos, size; - - string_buffer() - { - pos = 0; - size = 1048576; - } - string_buffer(std::string _data, int _size = 1048576) - { - data = _data; - pos = 0; - size = _size; - } - bool read(uint8_t *dest, uint32_t bytes) - { - if (pos + bytes > data.length()) - return false; - memcpy(dest, &data[pos], bytes); - pos += bytes; - return true; - } - bool write(const uint8_t *src, uint32_t bytes) - { - if (data.length() + bytes > size) - return false; - uint32_t wpos = data.length(); - data.resize(wpos + bytes); - memcpy(&data[wpos], src, bytes); - return true; - } - inline int read_left() - { - return data.length() - pos; - } - inline int write_left() - { - return size - data.length(); - } - inline int write_misalignment() - { - return 4 - (data.length() & 3); - } - void clear() - { - data.clear(); - pos = 0; - } - int tell() - { - return pos; - } - void seek(int _pos) - { - pos = _pos; - } -}; - -template -struct osc_stream -{ - Buffer &buffer; - TypeBuffer *type_buffer; - bool error; - - osc_stream(Buffer &_buffer) : buffer(_buffer), type_buffer(NULL), error(false) {} - osc_stream(Buffer &_buffer, TypeBuffer &_type_buffer) : buffer(_buffer), type_buffer(&_type_buffer), error(false) {} - inline void pad() - { - uint32_t zero = 0; - write(&zero, buffer.write_misalignment()); - } - inline void read(void *dest, uint32_t bytes) - { - if (!buffer.read((uint8_t *)dest, bytes)) - { -#if 0 - if (Throw) - throw osc_read_exception(); - else -#endif - { - error = true; - memset(dest, 0, bytes); - } - } - } - inline void write(const void *src, uint32_t bytes) - { - if (!buffer.write((const uint8_t *)src, bytes)) - { -#if 0 - if (Throw) - throw osc_write_exception(); - else -#endif - error = true; - } - } - inline void clear() - { - buffer.clear(); - if (type_buffer) - type_buffer->clear(); - } - inline void write_type(char ch) - { - if (type_buffer) - type_buffer->write((uint8_t *)&ch, 1); - } -}; - -typedef osc_stream osc_strstream; -typedef osc_stream osc_typed_strstream; - -struct osc_inline_strstream: public string_buffer, public osc_strstream -{ - osc_inline_strstream() - : string_buffer(), osc_strstream(static_cast(*this)) - { - } -}; - -struct osc_str_typed_buffer_pair -{ - string_buffer buf_data, buf_types; -}; - -struct osc_inline_typed_strstream: public osc_str_typed_buffer_pair, public osc_typed_strstream -{ - osc_inline_typed_strstream() - : osc_str_typed_buffer_pair(), osc_typed_strstream(buf_data, buf_types) - { - } -}; - -template -inline osc_stream & -operator <<(osc_stream &s, uint32_t val) -{ -#if 0 - val = htonl(val); - s.write(&val, 4); - s.write_type(osc_i32); -#endif - return s; -} - -template -inline osc_stream & -operator >>(osc_stream &s, uint32_t &val) -{ -#if 0 - s.read(&val, 4); - val = htonl(val); -#endif - return s; -} - -template -inline osc_stream & -operator >>(osc_stream &s, int32_t &val) -{ -#if 0 - s.read(&val, 4); - val = htonl(val); -#endif - return s; -} - -template -inline osc_stream & -operator <<(osc_stream &s, float val) -{ - union { float v; uint32_t i; } val2; - val2.v = val; - val2.i = htonl(val2.i); - s.write(&val2.i, 4); - s.write_type(osc_f32); - return s; -} - -template -inline osc_stream & -operator >>(osc_stream &s, float &val) -{ - union { float v; uint32_t i; } val2; - s.read(&val2.i, 4); - val2.i = htonl(val2.i); - val = val2.v; - return s; -} - -template -inline osc_stream & -operator <<(osc_stream &s, const std::string &str) -{ - s.write(&str[0], str.length()); - s.pad(); - s.write_type(osc_string); - return s; -} - -template -inline osc_stream & -operator >>(osc_stream &s, std::string &str) -{ - // inefficient... - char five[5]; - five[4] = '\0'; - str.resize(0); - while(1) - { - s.read(five, 4); - if (five[0] == '\0') - break; - str += five; - if (!five[1] || !five[2] || !five[3]) - break; - } - return s; -} - -template -inline osc_stream & -read_buffer_from_osc_stream(osc_stream &s, DestBuffer &buf) -{ -#if 0 - uint32_t nlen = 0; - s.read(&nlen, 4); - uint32_t len = htonl(nlen); - // write length in network order - for (uint32_t i = 0; i < len; i += 1024) - { - uint8_t tmp[1024]; - uint32_t part = std::min((uint32_t)1024, len - i); - s.read(tmp, part); - buf.write(tmp, part); - } - // pad - s.read(&nlen, 4 - (len & 3)); -#endif - return s; -} - -template -inline osc_stream & -write_buffer_to_osc_stream(osc_stream &s, SrcBuffer &buf) -{ -#if 0 - uint32_t len = buf.read_left(); - uint32_t nlen = ntohl(len); - s.write(&nlen, 4); - // write length in network order - for (uint32_t i = 0; i < len; i += 1024) - { - uint8_t tmp[1024]; - uint32_t part = std::min((uint32_t)1024, len - i); - buf.read(tmp, part); - s.write(tmp, part); - } - s.pad(); - s.write_type(osc_blob); -#endif - return s; -} - -template -inline osc_stream & -operator >>(osc_stream &s, raw_buffer &str) -{ - return read_buffer_from_osc_stream(s, str); -} - -template -inline osc_stream & -operator >>(osc_stream &s, string_buffer &str) -{ - return read_buffer_from_osc_stream(s, str); -} - -template -inline osc_stream & -operator <<(osc_stream &s, raw_buffer &str) -{ - return write_buffer_to_osc_stream(s, str); -} - -template -inline osc_stream & -operator <<(osc_stream &s, string_buffer &str) -{ - return write_buffer_to_osc_stream(s, str); -} - -// XXXKF: I don't support reading binary blobs yet - -struct osc_net_bad_address: public std::exception -{ - std::string addr, error_msg; - osc_net_bad_address(const char *_addr) - { - addr = _addr; - error_msg = "Incorrect OSC URI: " + addr; - } - virtual const char *what() const throw() { return error_msg.c_str(); } - virtual ~osc_net_bad_address() throw () {} -}; - -struct osc_net_exception: public std::exception -{ - int net_errno; - std::string command, error_msg; - osc_net_exception(const char *cmd, int _errno = errno) - { - command = cmd; - net_errno = _errno; - error_msg = "OSC error in "+command+": "+strerror(_errno); - } - virtual const char *what() const throw() { return error_msg.c_str(); } - virtual ~osc_net_exception() throw () {} -}; - -struct osc_net_dns_exception: public std::exception -{ -#if 0 - int net_errno; - std::string command, error_msg; - osc_net_dns_exception(const char *cmd, int _errno = h_errno) - { - command = cmd; - net_errno = _errno; - error_msg = "OSC error in "+command+": "+hstrerror(_errno); - } - virtual const char *what() const throw() { return error_msg.c_str(); } - virtual ~osc_net_dns_exception() throw () {} -#endif -}; - -template -struct osc_message_sink -{ - virtual void receive_osc_message(std::string address, std::string type_tag, OscStream &buffer)=0; - virtual ~osc_message_sink() {} -}; - -template -struct osc_message_dump: public osc_message_sink -{ - DumpStream &stream; - osc_message_dump(DumpStream &_stream) : stream(_stream) {} - - virtual void receive_osc_message(std::string address, std::string type_tag, OscStream &buffer) - { - int pos = buffer.buffer.tell(); - stream << "address: " << address << ", type tag: " << type_tag << std::endl; - for (unsigned int i = 0; i < type_tag.size(); i++) - { - stream << "Argument " << i << " is "; - switch(type_tag[i]) - { - case 'i': - { - uint32_t val; - buffer >> val; - stream << val; - break; - } - case 'f': - { - float val; - buffer >> val; - stream << val; - break; - } - case 's': - { - std::string val; - buffer >> val; - stream << val; - break; - } - case 'b': - { - osctl::string_buffer val; - buffer >> val; - stream << "blob (" << val.data.length() << " bytes)"; - break; - } - default: - { - stream << "unknown - cannot parse more arguments" << std::endl; - i = type_tag.size(); - break; - } - } - stream << std::endl; - } - stream << std::flush; - buffer.buffer.seek(pos); - } -}; - -}; - -#endif diff --git a/plugins/LadspaEffect/calf/src/calf/plugin_tools.h b/plugins/LadspaEffect/calf/src/calf/plugin_tools.h deleted file mode 100644 index 9fff2a5b8d9..00000000000 --- a/plugins/LadspaEffect/calf/src/calf/plugin_tools.h +++ /dev/null @@ -1,133 +0,0 @@ -/* Calf DSP plugin pack - * Tools to use in plugins - * - * Copyright (C) 2001-2010 Krzysztof Foltman, Markus Schmidt, Thor Harald Johansen and others - * - * 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_PLUGIN_TOOLS_H -#define CALF_PLUGIN_TOOLS_H - -#include - -#include "giface.h" -#include "vumeter.h" - -namespace calf_plugins { - -template -struct in_out_metering_base -{ - typedef Meter meter; - meter vumeter_in, vumeter_out; - in_out_metering_base() - { - reset(); - } - void reset() - { - vumeter_in.reset(); - vumeter_out.reset(); - } - void set_sample_rate(double sample_rate) - { - vumeter_in.set_falloff(0.f, sample_rate); - vumeter_out.copy_falloff(vumeter_in); - } -}; - -/// Universal single stereo level metering for a specific plugin -template -class stereo_in_out_metering: public in_out_metering_base -{ -public: - inline void process(float *const *params, const float *const *inputs, const float *const *outputs, unsigned int offset, unsigned int nsamples) - { - if (params[Metadata::param_meter_in] || params[Metadata::param_clip_in]) { - if (inputs) - vumeter_in.update_stereo(inputs[0] ? inputs[0] + offset : NULL, inputs[1] ? inputs[1] + offset : NULL, nsamples); - else - vumeter_in.update_zeros(nsamples); - if (params[Metadata::param_meter_in]) - *params[Metadata::param_meter_in] = vumeter_in.level; - if (params[Metadata::param_clip_in]) - *params[Metadata::param_clip_in] = vumeter_in.clip > 0 ? 1.f : 0.f; - } - if (params[Metadata::param_meter_out] || params[Metadata::param_clip_out]) { - if (outputs) - vumeter_out.update_stereo(outputs[0] ? outputs[0] + offset : NULL, outputs[1] ? outputs[1] + offset : NULL, nsamples); - else - vumeter_out.update_zeros(nsamples); - if (params[Metadata::param_meter_out]) - *params[Metadata::param_meter_out] = vumeter_out.level; - if (params[Metadata::param_clip_out]) - *params[Metadata::param_clip_out] = vumeter_out.clip > 0 ? 1.f : 0.f; - } - } - void bypassed(float *const *params, unsigned int nsamples) - { - reset(); - process(params, NULL, NULL, 0, nsamples); - } -}; - -/// Universal dual level metering for a specific plugin -template -class dual_in_out_metering: public in_out_metering_base -{ -public: - inline void process(float *const *params, const float *const *inputs, const float *const *outputs, unsigned int offset, unsigned int nsamples) - { - if (params[Metadata::param_meter_inL] || params[Metadata::param_clip_inL] || params[Metadata::param_meter_inR] || params[Metadata::param_clip_inR]) { - if (inputs) - vumeter_in.update_stereo(inputs[0] ? inputs[0] + offset : NULL, inputs[1] ? inputs[1] + offset : NULL, nsamples); - else - vumeter_in.update_zeros(nsamples); - if (params[Metadata::param_meter_inL]) - *params[Metadata::param_meter_inL] = vumeter_in.left.level; - if (params[Metadata::param_meter_inR]) - *params[Metadata::param_meter_inR] = vumeter_in.right.level; - if (params[Metadata::param_clip_inL]) - *params[Metadata::param_clip_inL] = vumeter_in.left.clip > 0 ? 1.f : 0.f; - if (params[Metadata::param_clip_inR]) - *params[Metadata::param_clip_inR] = vumeter_in.right.clip > 0 ? 1.f : 0.f; - } - if (params[Metadata::param_meter_outL] || params[Metadata::param_clip_outL] || params[Metadata::param_meter_outR] || params[Metadata::param_clip_outR]) { - if (outputs) - vumeter_out.update_stereo(outputs[0] ? outputs[0] + offset : NULL, outputs[1] ? outputs[1] + offset : NULL, nsamples); - else - vumeter_out.update_zeros(nsamples); - if (params[Metadata::param_meter_outL]) - *params[Metadata::param_meter_outL] = vumeter_out.left.level; - if (params[Metadata::param_meter_outR]) - *params[Metadata::param_meter_outR] = vumeter_out.right.level; - if (params[Metadata::param_clip_outL]) - *params[Metadata::param_clip_outL] = vumeter_out.left.clip > 0 ? 1.f : 0.f; - if (params[Metadata::param_clip_outR]) - *params[Metadata::param_clip_outR] = vumeter_out.right.clip > 0 ? 1.f : 0.f; - } - } - void bypassed(float *const *params, unsigned int nsamples) - { - reset(); - process(params, NULL, NULL, 0, nsamples); - } -}; - -}; - -#endif - diff --git a/plugins/LadspaEffect/calf/src/calf/preset.h b/plugins/LadspaEffect/calf/src/calf/preset.h deleted file mode 100644 index c6b93a72241..00000000000 --- a/plugins/LadspaEffect/calf/src/calf/preset.h +++ /dev/null @@ -1,167 +0,0 @@ -/* Calf DSP Library - * Preset management - * - * Copyright (C) 2007 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_PRESET_H -#define __CALF_PRESET_H - -#include -#include -#include "utils.h" - -namespace calf_plugins { - -class plugin_ctl_iface; - -/// Contents of single preset -struct plugin_preset -{ - /// Bank the preset belongs to (not used yet) - int bank; - /// Program number of the preset (not used yet) - int program; - /// Name of the preset - std::string name; - /// Name of the plugin the preset is for - std::string plugin; - /// Names of parameters in values array (for each item in param_names there should be a counterpart in values) - std::vector param_names; - /// Values of parameters - std::vector values; - /// DSSI configure-style variables - std::map variables; - - plugin_preset() : bank(0), program(0) {} - /// Export preset as XML - std::string to_xml(); - /// "Upload" preset content to the plugin - void activate(plugin_ctl_iface *plugin); - /// "Download" preset content from the plugin - void get_from(plugin_ctl_iface *plugin); - - std::string get_safe_name(); -}; - -/// Exception thrown by preset system -struct preset_exception -{ - std::string message, param, fulltext; - int error; - preset_exception(const std::string &_message, const std::string &_param, int _error) - : message(_message), param(_param), error(_error) - { - } - const char *what() { - if (error) - fulltext = message + " " + param + " (" + strerror(error) + ")"; - else - fulltext = message + " " + param; - return fulltext.c_str(); - } - ~preset_exception() - { - } -}; - -/// A vector of presets -typedef std::vector preset_vector; - -/// A single list of presets (usually there are two - @see get_builtin_presets(), get_user_presets() ) -struct preset_list -{ - /// Plugin list item - struct plugin_snapshot - { - /// Preset offset - int preset_offset; - /// Plugin type - std::string type; - /// Instance name - std::string instance_name; - /// Index of the first input port - int input_index; - /// Index of the first output port - int output_index; - /// Index of the first MIDI port - int midi_index; - - /// Reset to initial values - void reset(); - }; - - /// Parser states - enum parser_state - { - START, ///< Beginning of parsing process (before root element) - LIST, ///< Inside root element - PRESET, ///< Inside preset definition - VALUE, ///< Inside (empty) param tag - VAR, ///< Inside (non-empty) var tag - PLUGIN, ///< Inside plugin element (calfjackhost snapshots only) - RACK, ///< Inside rack element (calfjackhost snapshots only) - } state; - - /// Contained presets (usually for all plugins) - preset_vector presets; - /// Temporary preset used during parsing process - plugin_preset parser_preset; - /// Temporary plugin desc used during parsing process - plugin_snapshot parser_plugin; - /// Preset number counters for DSSI (currently broken) - std::map last_preset_ids; - /// The key used in current tag (for state == VAR) - std::string current_key; - /// The file is loaded in rack mode (and rack/plugin elements are expected) - bool rack_mode; - /// List of plugin states for rack mode - std::vector plugins; - - /// Return the name of the built-in or user-defined preset file - static std::string get_preset_filename(bool builtin); - /// Load default preset list (built-in or user-defined) - bool load_defaults(bool builtin); - /// Load preset list from an in-memory XML string - void parse(const std::string &data, bool in_rack_mode); - /// Load preset list from XML file - void load(const char *filename, bool in_rack_mode); - /// Save preset list as XML file - void save(const char *filename); - /// Append or replace a preset (replaces a preset with the same plugin and preset name) - void add(const plugin_preset &sp); - /// Get a sublist of presets for a given plugin (those with plugin_preset::plugin == plugin) - void get_for_plugin(preset_vector &vec, const char *plugin); - -protected: - /// Internal function: start element handler for expat - static void xml_start_element_handler(void *user_data, const char *name, const char *attrs[]); - /// Internal function: end element handler for expat - static void xml_end_element_handler(void *user_data, const char *name); - /// Internal function: character data (tag text content) handler for expat - static void xml_character_data_handler(void *user_data, const char *data, int len); -}; - -/// Return the current list of built-in (factory) presets (these are loaded from system-wide file) -extern preset_list &get_builtin_presets(); - -/// Return the current list of user-defined presets (these are loaded from ~/.calfpresets) -extern preset_list &get_user_presets(); - -}; - -#endif diff --git a/plugins/LadspaEffect/calf/src/calf/primitives.h b/plugins/LadspaEffect/calf/src/calf/primitives.h deleted file mode 100644 index 0bffd859434..00000000000 --- a/plugins/LadspaEffect/calf/src/calf/primitives.h +++ /dev/null @@ -1,533 +0,0 @@ -/* Calf DSP Library - * DSP primitives. - * - * Copyright (C) 2001-2007 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_PRIMITIVES_H -#define __CALF_PRIMITIVES_H - -#include -#include -#include -#include -#include -#include -#include - -namespace dsp { - -/// Set a float to zero -inline void zero(float &v) { - v = 0; -}; - -/// Set a double to zero -inline void zero(double &v) { - v = 0; -}; - -/// Set 64-bit unsigned integer value to zero -inline void zero(uint64_t &v) { v = 0; }; -/// Set 32-bit unsigned integer value to zero -inline void zero(uint32_t &v) { v = 0; }; -/// Set 16-bit unsigned integer value to zero -inline void zero(uint16_t &v) { v = 0; }; -/// Set 8-bit unsigned integer value to zero -inline void zero(uint8_t &v) { v = 0; }; -/// Set 64-bit signed integer value to zero -inline void zero(int64_t &v) { v = 0; }; -/// Set 32-bit signed integer value to zero -inline void zero(int32_t &v) { v = 0; }; -/// Set 16-bit signed integer value to zero -inline void zero(int16_t &v) { v = 0; }; -/// Set 8-bit signed integer value to zero -inline void zero(int8_t &v) { v = 0; }; - -/// Set array (buffer or anything similar) to vector of zeroes -template -void zero(T *data, unsigned int size) { - T value; - dsp::zero(value); - for (unsigned int i=0; istruct stereo_sample { - T left; - T right; - /// default constructor - preserves T's semantics (ie. no implicit initialization to 0) - inline stereo_sample() { - } - inline stereo_sample(T _left, T _right) { - left = _left; - right = _right; - } - inline stereo_sample(T _both) { - left = right = _both; - } - template - inline stereo_sample(const stereo_sample &value) { - left = value.left; - right = value.right; - } - inline stereo_sample& operator=(const T &value) { - left = right = value; - return *this; - } - template - inline stereo_sample& operator=(const stereo_sample &value) { - left = value.left; - right = value.right; - return *this; - } -/* - inline operator T() const { - return (left+right)/2; - } -*/ - inline stereo_sample& operator*=(const T &multiplier) { - left *= multiplier; - right *= multiplier; - return *this; - } - inline stereo_sample& operator+=(const stereo_sample &value) { - left += value.left; - right += value.right; - return *this; - } - inline stereo_sample& operator-=(const stereo_sample &value) { - left -= value.left; - right -= value.right; - return *this; - } - template inline stereo_sample operator*(const U &value) const { - return stereo_sample(left*value, right*value); - } - /*inline stereo_sample operator*(float value) const { - return stereo_sample(left*value, right*value); - } - inline stereo_sample operator*(double value) const { - return stereo_sample(left*value, right*value); - }*/ - inline stereo_sample operator+(const stereo_sample &value) { - return stereo_sample(left+value.left, right+value.right); - } - inline stereo_sample operator-(const stereo_sample &value) { - return stereo_sample(left-value.left, right-value.right); - } - inline stereo_sample operator+(const T &value) { - return stereo_sample(left+value, right+value); - } - inline stereo_sample operator-(const T &value) { - return stereo_sample(left-value, right-value); - } - inline stereo_sample operator+(float value) { - return stereo_sample(left+value, right+value); - } - inline stereo_sample operator-(float value) { - return stereo_sample(left-value, right-value); - } - inline stereo_sample operator+(double value) { - return stereo_sample(left+value, right+value); - } - inline stereo_sample operator-(double value) { - return stereo_sample(left-value, right-value); - } -}; - -/// Multiply constant by stereo_value -template -inline stereo_sample operator*(const T &value, const stereo_sample &value2) { - return stereo_sample(value2.left*value, value2.right*value); -} - -/// Add constant to stereo_value -template -inline stereo_sample operator+(const T &value, const stereo_sample &value2) { - return stereo_sample(value2.left+value, value2.right+value); -} - -/// Subtract stereo_value from constant (yields stereo_value of course) -template -inline stereo_sample operator-(const T &value, const stereo_sample &value2) { - return stereo_sample(value-value2.left, value-value2.right); -} - -/// Shift value right by 'bits' bits (multiply by 2^-bits) -template -inline stereo_sample shr(stereo_sample v, int bits = 1) { - v.left = shr(v.left, bits); - v.right = shr(v.right, bits); - return v; -} - -/// Set a stereo_sample value to zero -template -inline void zero(stereo_sample &v) { - dsp::zero(v.left); - dsp::zero(v.right); -} - -/// 'Small value' for integer and other types -template -inline T small_value() { - return 0; -} - -/// 'Small value' for floats (2^-24) - used for primitive underrun prevention. The value is pretty much arbitrary (allowing for 24-bit signals normalized to 1.0). -template<> -inline float small_value() { - return (1.0/16777216.0); // allows for 2^-24, should be enough for 24-bit DACs at least :) -} - -/// 'Small value' for doubles (2^-24) - used for primitive underrun prevention. The value is pretty much arbitrary. -template<> -inline double small_value() { - return (1.0/16777216.0); -} - -/// Convert a single value to single value = do nothing :) (but it's a generic with specialisation for stereo_sample) -template -inline float mono(T v) { - return v; -} - -/// Convert a stereo_sample to single value by averaging two channels -template -inline T mono(stereo_sample v) { - return shr(v.left+v.right); -} - -/// Clip a value to [min, max] -template -inline T clip(T value, T min, T max) { - if (value < min) return min; - if (value > max) return max; - return value; -} - -/// Clip a double to [-1.0, +1.0] -inline double clip11(double value) { - double a = fabs(value); - if (a<=1) return value; - return (value<0) ? -1.0 : 1.0; -} - -/// Clip a float to [-1.0f, +1.0f] -inline float clip11(float value) { - float a = fabsf(value); - if (a<=1) return value; - return (value<0) ? -1.0f : 1.0f; -} - -/// Clip a double to [0.0, +1.0] -inline double clip01(double value) { - double a = fabs(value-0.5); - if (a<=0.5) return value; - return (a<0) ? -0.0 : 1.0; -} - -/// Clip a float to [0.0f, +1.0f] -inline float clip01(float value) { - float a = fabsf(value-0.5f); - if (a<=0.5f) return value; - return (value < 0) ? -0.0f : 1.0f; -} - -// Linear interpolation (mix-way between v1 and v2). -template -inline T lerp(T v1, T v2, U mix) { - return v1+(v2-v1)*mix; -} - -// Linear interpolation for stereo values (mix-way between v1 and v2). -template -inline stereo_sample lerp(stereo_sample &v1, stereo_sample &v2, float mix) { - return stereo_sample(v1.left+(v2.left-v1.left)*mix, v1.right+(v2.right-v1.right)*mix); -} - -/** - * decay-only envelope (linear or exponential); deactivates itself when it goes below a set point (epsilon) - */ -class decay -{ - double value, initial; - unsigned int age, mask; - bool active; -public: - decay() { - active = false; - mask = 127; - initial = value = 0.0; - } - inline bool get_active() { - return active; - } - inline double get() { - return active ? value : 0.0; - } - inline void set(double v) { - initial = value = v; - active = true; - age = 0; - } - /// reinitialise envelope (must be called if shape changes from linear to exponential or vice versa in the middle of envelope) - inline void reinit() - { - initial = value; - age = 1; - } - inline void add(double v) { - if (active) - value += v; - else - value = v; - initial = value; - age = 0; - active = true; - } - static inline double calc_exp_constant(double times, double cycles) - { - if (cycles < 1.0) - cycles = 1.0; - return pow(times, 1.0 / cycles); - } - inline void age_exp(double constant, double epsilon) { - if (active) { - if (!(age & mask)) - value = initial * pow(constant, (double)age); - else - value *= constant; - if (value < epsilon) - active = false; - age++; - } - } - inline void age_lin(double constant, double epsilon) { - if (active) { - if (!(age & mask)) - value = initial - constant * age; - else - value -= constant; - if (value < epsilon) - active = false; - age++; - } - } - inline void deactivate() { - active = false; - value = 0; - } -}; - -class scheduler; - -class task { -public: - virtual void execute(scheduler *s)=0; - virtual void dispose() { delete this; } - virtual ~task() {} -}; - -/// this scheduler is based on std::multimap, so it isn't very fast, I guess -/// maybe some day it should be rewritten to use heapsort or something -/// work in progress, don't use! -class scheduler { - std::multimap timeline; - unsigned int time, next_task; - bool eob; - class end_buf_task: public task { - public: - scheduler *p; - end_buf_task(scheduler *_p) : p(_p) {} - virtual void execute(scheduler *s) { p->eob = true; } - virtual void dispose() { } - } eobt; -public: - - scheduler() - : time(0) - , next_task((unsigned)-1) - , eob(true) - , eobt (this) - { - time = 0; - next_task = (unsigned)-1; - eob = false; - } - inline bool is_next_tick() { - if (time < next_task) - return true; - do_tasks(); - } - inline void next_tick() { - time++; - } - void set(int pos, task *t) { - timeline.insert(std::pair(time+pos, t)); - next_task = timeline.begin()->first; - } - void do_tasks() { - std::multimap::iterator i = timeline.begin(); - while(i != timeline.end() && i->first == time) { - i->second->execute(this); - i->second->dispose(); - timeline.erase(i); - } - } - bool is_eob() { - return eob; - } - void set_buffer_size(int count) { - set(count, &eobt); - } -}; - -/** - * Force "small enough" float value to zero - */ -inline void sanitize(float &value) -{ - if (std::abs(value) < small_value()) - value = 0.f; -} - -/** - * Force already-denormal float value to zero - */ -inline void sanitize_denormal(float& value) -{ - if (((*(unsigned int *) &value) & 0x7f800000) == 0) { - value = 0; - } -} - -/** - * Force "small enough" double value to zero - */ -inline void sanitize(double &value) -{ - if (std::abs(value) < small_value()) - value = 0.f; -} - -/** - * Force "small enough" stereo value to zero - */ -template -inline void sanitize(stereo_sample &value) -{ - sanitize(value.left); - sanitize(value.right); -} - -inline float fract16(unsigned int value) -{ - return (value & 0xFFFF) * (1.0 / 65536.0); -} - -/** - * typical precalculated sine table - */ -template -class sine_table -{ -public: - static bool initialized; - static T data[N+1]; - sine_table() { - if (initialized) - return; - initialized = true; - for (int i=0; i -bool sine_table::initialized = false; - -template -T sine_table::data[N+1]; - -/// fast float to int conversion using default rounding mode -inline int fastf2i_drm(float f) -{ -#ifdef __X86__ - volatile int v; - __asm ( "flds %1; fistpl %0" : "=m"(v) : "m"(f)); - return v; -#else - return (int)nearbyintf(f); -#endif -} - -/// Convert MIDI note to frequency in Hz. -inline float note_to_hz(double note, double detune_cents = 0.0) -{ - return 440 * pow(2.0, (note - 69 + detune_cents/100.0) / 12.0); -} - -/// Hermite interpolation between two points and slopes in normalized range (written after Wikipedia article) -/// @arg t normalized x coordinate (0-1 over the interval in question) -/// @arg p0 first point -/// @arg p1 second point -/// @arg m0 first slope (multiply by interval width when using over non-1-wide interval) -/// @arg m1 second slope (multiply by interval width when using over non-1-wide interval) -inline float normalized_hermite(float t, float p0, float p1, float m0, float m1) -{ - float t2 = t*t; - float t3 = t2*t; - return (2*t3 - 3*t2 + 1) * p0 + (t3 - 2*t2 + t) * m0 + (-2*t3 + 3*t2) * p1 + (t3-t2) * m1; -} - -/// Hermite interpolation between two points and slopes -/// @arg x point within interval (x0 <= x <= x1) -/// @arg x0 interval start -/// @arg x1 interval end -/// @arg p0 value at x0 -/// @arg p1 value at x1 -/// @arg m0 slope (steepness, tangent) at x0 -/// @arg m1 slope at x1 -inline float hermite_interpolation(float x, float x0, float x1, float p0, float p1, float m0, float m1) -{ - float width = x1 - x0; - float t = (x - x0) / width; - m0 *= width; - m1 *= width; - float t2 = t*t; - float t3 = t2*t; - - float ct0 = p0; - float ct1 = m0; - float ct2 = -3 * p0 - 2 * m0 + 3 * p1 - m1; - float ct3 = 2 * p0 + m0 - 2 * p1 + m1; - - return ct3 * t3 + ct2 * t2 + ct1 * t + ct0; - //return (2*t3 - 3*t2 + 1) * p0 + (t3 - 2*t2 + t) * m0 + (-2*t3 + 3*t2) * p1 + (t3-t2) * m1; -} - -/// convert amplitude value to dB -inline float amp2dB(float amp) -{ - return 6.0 * log(amp) / log(2); -} - -}; - -#endif diff --git a/plugins/LadspaEffect/calf/src/calf/synth.h b/plugins/LadspaEffect/calf/src/calf/synth.h deleted file mode 100644 index 85fb35404bc..00000000000 --- a/plugins/LadspaEffect/calf/src/calf/synth.h +++ /dev/null @@ -1,230 +0,0 @@ -/* Calf DSP Library - * Framework for synthesizer-like plugins. This is based - * on my earlier work on Drawbar electric organ emulator. - * - * Copyright (C) 2007 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_SYNTH_H -#define CALF_SYNTH_H - -#include -#include -#include -#include -#include -#include -#include - -namespace dsp { - -/** - * A kind of set with fast non-ordered iteration, used for storing lists of pressed keys. - */ -class keystack { -private: - int dcount; - uint8_t active[128]; - uint8_t states[128]; -public: - keystack() { - memset(states, 0xFF, sizeof(states)); - dcount = 0; - } - void clear() { - for (int i=0; i= 0 && key <= 127); - if (states[key] != 0xFF) { - return true; - } - states[key] = dcount; - active[dcount++] = key; - return false; - } - bool pop(int key) { - if (states[key] == 0xFF) - return false; - int pos = states[key]; - if (pos != dcount-1) { - // reuse the popped item's stack position for stack top - int last = active[dcount-1]; - active[pos] = last; - // mark that position's new place on stack - states[last] = pos; - } - states[key] = 0xFF; - dcount--; - return true; - } - inline bool has(int key) { - return states[key] != 0xFF; - } - inline int count() { - return dcount; - } - inline bool empty() { - return (dcount == 0); - } - inline int nth(int n) { - return active[n]; - } -}; - -/** - * Convert MIDI note number to normalized UINT phase (where 1<<32 is full cycle). - * @param MIDI note number - * @param cents detune in cents (1/100 of a semitone) - * @param sr sample rate - */ -inline unsigned int midi_note_to_phase(int note, double cents, int sr) { - double incphase = 440*pow(2.0, (note-69)/12.0 + cents/1200.0)/sr; - if (incphase >= 1.0) incphase = fmod(incphase, 1.0); - incphase *= 65536.0*65536.0; - return (unsigned int)incphase; -} - -// Base class for all voice objects -class voice { -public: - int sample_rate; - bool released, sostenuto, stolen; - - voice() : sample_rate(-1), released(false), sostenuto(false), stolen(false) {} - - /// reset voice to default state (used when a voice is to be reused) - virtual void setup(int sr) { sample_rate = sr; } - /// reset voice to default state (used when a voice is to be reused) - virtual void reset()=0; - /// a note was pressed - virtual void note_on(int note, int vel)=0; - /// a note was released - virtual void note_off(int vel)=0; - /// check if voice can be removed from active voice list - virtual bool get_active()=0; - /// render voice data to buffer - virtual void render_to(float (*buf)[2], int nsamples)=0; - /// very fast note off - virtual void steal()=0; - /// return the note used by this voice - virtual int get_current_note()=0; - virtual float get_priority() { return stolen ? 20000 : (released ? 1 : (sostenuto ? 200 : 100)); } - /// empty virtual destructor - virtual ~voice() {} -}; - -/// An "optimized" voice class using fixed-size processing units -/// and fixed number of channels. The drawback is that voice -/// control is not sample-accurate, and no modulation input -/// is possible, but it should be good enough for most cases -/// (like Calf Organ). -template -class block_voice: public Base { -public: - // derived from Base - // enum { Channels = 2 }; - using Base::Channels; - // enum { BlockSize = 16 }; - using Base::BlockSize; - // float output_buffer[BlockSize][Channels]; - using Base::output_buffer; - // void render_block(); - using Base::render_block; - unsigned int read_ptr; - - block_voice() - { - read_ptr = BlockSize; - } - virtual void reset() - { - Base::reset(); - read_ptr = BlockSize; - } - virtual void render_to(float (*buf)[2], int nsamples) - { - int p = 0; - while(p < nsamples) - { - if (read_ptr == BlockSize) - { - render_block(); - read_ptr = 0; - } - int ncopy = std::min(BlockSize - read_ptr, nsamples - p); - for (int i = 0; i < ncopy; i++) - for (int c = 0; c < Channels; c++) - buf[p + i][c] += output_buffer[read_ptr + i][c]; - p += ncopy; - read_ptr += ncopy; - } - } -}; - -/// Base class for all kinds of polyphonic instruments, provides -/// somewhat reasonable voice management, pedal support - and -/// little else. It's implemented as a base class with virtual -/// functions, so there's some performance loss, but it shouldn't -/// be horrible. -/// @todo it would make sense to support all notes off controller too -struct basic_synth { -protected: - /// Current sample rate - int sample_rate; - /// Hold pedal state - bool hold; - /// Sostenuto pedal state - bool sostenuto; - /// Voices currently playing - std::list active_voices; - /// Voices allocated, but not used - std::stack unused_voices; - /// Gate values for all 128 MIDI notes - std::bitset<128> gate; - /// Maximum allocated number of channels - unsigned int polyphony_limit; - - void kill_note(int note, int vel, bool just_one); -public: - virtual void setup(int sr) { - sample_rate = sr; - hold = false; - sostenuto = false; - polyphony_limit = (unsigned)-1; - } - virtual void trim_voices(); - virtual dsp::voice *give_voice(); - virtual dsp::voice *alloc_voice()=0; - virtual dsp::voice *steal_voice(); - virtual void render_to(float (*output)[2], int nsamples); - virtual void note_on(int note, int vel); - virtual void percussion_note_on(int note, int vel) {} - virtual void control_change(int ctl, int val); - virtual void note_off(int note, int vel); - /// amt = -8192 to 8191 - virtual void pitch_bend(int amt) {} - virtual void on_pedal_release(); - virtual bool check_percussion() { return active_voices.empty(); } - virtual ~basic_synth(); -}; - -} - -#endif diff --git a/plugins/LadspaEffect/calf/src/calf/utils.h b/plugins/LadspaEffect/calf/src/calf/utils.h deleted file mode 100644 index 783a98ad357..00000000000 --- a/plugins/LadspaEffect/calf/src/calf/utils.h +++ /dev/null @@ -1,191 +0,0 @@ -/* Calf DSP Library - * Utilities - * - * Copyright (C) 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_UTILS_H -#define __CALF_UTILS_H - -#include -#include -#include -#include - -namespace calf_utils -{ - -/// Pthreads based mutex class -class ptmutex -{ -public: - pthread_mutex_t pm; - - ptmutex(int type = PTHREAD_MUTEX_RECURSIVE) - { - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); - pthread_mutexattr_settype(&attr, type); - pthread_mutex_init(&pm, &attr); - pthread_mutexattr_destroy(&attr); - } - - bool lock() - { - return pthread_mutex_lock(&pm) == 0; - } - - bool trylock() - { - return pthread_mutex_trylock(&pm) == 0; - } - - void unlock() - { - pthread_mutex_unlock(&pm); - } - - ~ptmutex() - { - pthread_mutex_destroy(&pm); - } -}; - -class ptlock_base -{ -protected: - ptmutex &mutex; - bool locked; - - ptlock_base(ptmutex &_m) - : mutex(_m) - , locked(false) - { - } - -public: - bool is_locked() - { - return locked; - } - void unlock() - { - mutex.unlock(); - locked = false; - } - void unlocked() - { - locked = false; - } - ~ptlock_base() - { - if (locked) - mutex.unlock(); - } -}; - -/// Exception-safe mutex lock -class ptlock: public ptlock_base -{ -public: - ptlock(ptmutex &_m) : ptlock_base(_m) - { - locked = mutex.lock(); - } -}; - -/// Exception-safe polling mutex lock -class pttrylock: public ptlock_base -{ -public: - pttrylock(ptmutex &_m) : ptlock_base(_m) - { - locked = mutex.trylock(); - } -}; - -/// Exception-safe temporary assignment -template -class scope_assign -{ - Tref data; - T old_value; -public: - scope_assign(Tref _data, T new_value) - : data(_data), old_value(_data) - { - data = new_value; - } - ~scope_assign() - { - data = old_value; - } -}; - -struct text_exception: public std::exception -{ - const char *text; - std::string container; -public: - text_exception(const std::string &t) : container(t) { text = container.c_str(); } - virtual const char *what() const throw () { return text; } - virtual ~text_exception() throw () {} -}; - -struct file_exception: public std::exception -{ - const char *text; - std::string message, filename, container; -public: - file_exception(const std::string &f); - file_exception(const std::string &f, const std::string &t); - virtual const char *what() const throw () { return text; } - virtual ~file_exception() throw () {} -}; - -/// String-to-string mapping -typedef std::map dictionary; - -/// Serialize a dictonary to a string -extern std::string encode_map(const dictionary &data); -/// Deserialize a dictonary from a string -extern void decode_map(dictionary &data, const std::string &src); - -/// int-to-string -extern std::string i2s(int value); - -/// float-to-string -extern std::string f2s(double value); - -/// float-to-string-that-doesn't-resemble-an-int -extern std::string ff2s(double value); - -/// Encode a key-value pair as XML attribute -std::string to_xml_attr(const std::string &key, const std::string &value); - -/// Escape a string to be used in XML file -std::string xml_escape(const std::string &src); - -/// Load file from disk into a std::string blob, or throw file_exception -std::string load_file(const std::string &src); - -/// Indent a string by another string (prefix each line) -std::string indent(const std::string &src, const std::string &indent); - -}; - -#endif diff --git a/plugins/LadspaEffect/calf/src/calf/vumeter.h b/plugins/LadspaEffect/calf/src/calf/vumeter.h deleted file mode 100644 index 64536598e7e..00000000000 --- a/plugins/LadspaEffect/calf/src/calf/vumeter.h +++ /dev/null @@ -1,147 +0,0 @@ -/* Calf DSP Library - * Peak metering facilities. - * - * Copyright (C) 2007 Krzysztof Foltman - * - * 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ -#ifndef __CALF_VUMETER_H -#define __CALF_VUMETER_H - -#include - -namespace dsp { - -/// Peak meter class -struct vumeter -{ - /// Measured signal level - float level; - /// Falloff of signal level (b1 coefficient of a 1-pole filter) - float falloff; - /// Clip indicator (set to 1 when |value| >= 1, fading otherwise) - float clip; - /// Falloff of clip indicator (b1 coefficient of a 1-pole filter); set to 1 if no falloff is required (manual reset of clip indicator) - float clip_falloff; - - vumeter() - { - falloff = 0.999f; - clip_falloff = 0.999f; - reset(); - } - - void reset() - { - level = 0; - clip = 0; - } - - /// Set falloff so that the meter falls 20dB in time_20dB seconds, assuming sample rate of sample_rate - /// @arg time_20dB time for the meter to move by 20dB (default 300ms if <= 0) - void set_falloff(double time_20dB, double sample_rate) - { - if (time_20dB <= 0) - time_20dB = 0.3; - // 20dB = 10x +/- --> 0.1 = pow(falloff, sample_rate * time_20dB) = exp(sample_rate * ln(falloff)) - // ln(0.1) = sample_rate * ln(falloff) - falloff = pow(0.1, 1 / (sample_rate * time_20dB)); - clip_falloff = falloff; - } - /// Copy falloff from another object - void copy_falloff(const vumeter &src) - { - falloff = src.falloff; - clip_falloff = src.clip_falloff; - } - - /// Update peak meter based on input signal - inline void update(const float *src, unsigned int len) - { - update_stereo(src, NULL, len); - } - /// Update peak meter based on louder of two input signals - inline void update_stereo(const float *src1, const float *src2, unsigned int len) - { - // "Age" the old level by falloff^length - level *= pow(falloff, len); - // Same for clip level (using different fade constant) - clip *= pow(clip_falloff, len); - dsp::sanitize(level); - dsp::sanitize(clip); - // Process input samples - to get peak value, take a max of all values in the input signal and "aged" old peak - // Clip is set to 1 if any sample is out-of-range, if no clip occurs, the "aged" value is assumed - if (src1) - run_sample_loop(src1, len); - if (src2) - run_sample_loop(src2, len); - } - inline void run_sample_loop(const float *src, unsigned int len) - { - float tmp = level; - for (unsigned int i = 0; i < len; i++) { - float sig = fabs(src[i]); - tmp = std::max(tmp, sig); - if (sig >= 1.f) - clip = 1.f; - } - level = tmp; - } - /// Update clip meter as if update was called with all-zero input signal - inline void update_zeros(unsigned int len) - { - level *= pow((double)falloff, (double)len); - clip *= pow((double)clip_falloff, (double)len); - dsp::sanitize(level); - dsp::sanitize(clip); - } -}; - -struct dual_vumeter -{ - vumeter left, right; - - inline void update_stereo(const float *src1, const float *src2, unsigned int len) - { - left.update_stereo(src1, NULL, len); - right.update_stereo(NULL, src2, len); - } - inline void update_zeros(unsigned int len) - { - left.update_zeros(len); - right.update_zeros(len); - } - inline void reset() - { - left.reset(); - right.reset(); - } - inline void set_falloff(double time_20dB, double sample_rate) - { - left.set_falloff(time_20dB, sample_rate); - right.copy_falloff(left); - } - inline void copy_falloff(const dual_vumeter &src) - { - left.copy_falloff(src.left); - right.copy_falloff(src.right); - } - -}; - -}; - -#endif diff --git a/plugins/LadspaEffect/calf/src/calf/waveshaping.h b/plugins/LadspaEffect/calf/src/calf/waveshaping.h deleted file mode 100644 index 914637c0afe..00000000000 --- a/plugins/LadspaEffect/calf/src/calf/waveshaping.h +++ /dev/null @@ -1,37 +0,0 @@ -/* Calf DSP Library - * Placeholder for waveshaping classes - * - * Copyright (C) 2001-2009 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_WAVESHAPING_H -#define __CALF_WAVESHAPING_H - -/// This will be a waveshaper... when I'll code it (-: -/// (or get Tom Szlagyi's permission to use his own) -class waveshaper { -public: - waveshaper(); - void activate() {} - void deactivate() {} - void set_params(float blend, float drive) {} - void set_sample_rate(uint32_t sr) {} - float process(float in) { return in; } - float get_distortion_level() { return 1; } -}; - -#endif diff --git a/plugins/LadspaEffect/calf/src/calf/wavetable.h b/plugins/LadspaEffect/calf/src/calf/wavetable.h deleted file mode 100644 index 836585acbfc..00000000000 --- a/plugins/LadspaEffect/calf/src/calf/wavetable.h +++ /dev/null @@ -1,167 +0,0 @@ -#ifndef __CALF_WAVETABLE_H -#define __CALF_WAVETABLE_H - -#include -#include "biquad.h" -#include "onepole.h" -#include "audio_fx.h" -#include "inertia.h" -#include "osc.h" -#include "synth.h" -#include "envelope.h" -#include "modmatrix.h" - -namespace calf_plugins { - -#define WAVETABLE_WAVE_BITS 8 - -class wavetable_audio_module; - -struct wavetable_oscillator: public dsp::simple_oscillator -{ - enum { SIZE = 1 << 8, MASK = SIZE - 1, SCALE = 1 << (32 - 8) }; - int16_t (*tables)[256]; - inline float get(uint16_t slice) - { - float fracslice = (slice & 255) * (1.0 / 256.0); - slice = slice >> 8; - int16_t *waveform = tables[slice]; - int16_t *waveform2 = tables[slice + 1]; - float value1 = 0.f, value2 = 0.f; - uint32_t cphase = phase, cphasedelta = phasedelta >> 3; - for (int j = 0; j < 8; j++) - { - uint32_t wpos = cphase >> (32 - 8); - uint32_t wpos2 = (wpos + 1) & MASK; - float frac = (cphase & (SCALE - 1)) * (1.0f / SCALE); - value1 += dsp::lerp((float)waveform[wpos], (float)waveform[wpos2], frac); - value2 += dsp::lerp((float)waveform2[wpos], (float)waveform2[wpos2], frac); - cphase += cphasedelta; - } - phase += phasedelta; - return dsp::lerp(value1, value2, fracslice) * (1.0 / 8.0) * (1.0 / 32768.0);; - } -}; - -class wavetable_voice: public dsp::voice -{ -public: - enum { Channels = 2, BlockSize = 64, EnvCount = 3, OscCount = 2 }; - float output_buffer[BlockSize][Channels]; -protected: - int note; - wavetable_audio_module *parent; - float **params; - dsp::decay amp; - wavetable_oscillator oscs[OscCount]; - dsp::adsr envs[EnvCount]; - /// Current MIDI velocity - float velocity; - /// Current calculated mod matrix outputs - float moddest[wavetable_metadata::moddest_count]; - /// Last oscillator shift (wavetable index) of each oscillator - float last_oscshift[OscCount]; - /// Last oscillator amplitude of each oscillator - float last_oscamp[OscCount]; - /// Current osc amplitude - float cur_oscamp[OscCount]; -public: - wavetable_voice(); - void set_params_ptr(wavetable_audio_module *_parent, int _srate); - void reset(); - void note_on(int note, int vel); - void note_off(int /* vel */); - void channel_pressure(int value); - void steal(); - void render_block(); - virtual int get_current_note() { - return note; - } - virtual bool get_active() { - // printf("note %d getactive %d use_percussion %d pamp active %d\n", note, amp.get_active(), use_percussion(), pamp.get_active()); - return (note != -1) && (amp.get_active()) && !envs[0].stopped(); - } - inline void calc_derived_dests() { - float cv = dsp::clip(0.5f + moddest[wavetable_metadata::moddest_oscmix], 0.f, 1.f); - cur_oscamp[0] = (cv) * *params[wavetable_metadata::par_o1level]; - cur_oscamp[1] = (1 - cv) * *params[wavetable_metadata::par_o2level]; - } -}; - -class wavetable_audio_module: public audio_module, public dsp::basic_synth, public mod_matrix_impl -{ -public: - using dsp::basic_synth::note_on; - using dsp::basic_synth::note_off; - using dsp::basic_synth::control_change; - using dsp::basic_synth::pitch_bend; - -protected: - uint32_t crate; - bool panic_flag; - -public: - int16_t tables[wt_count][129][256]; // one dummy level for interpolation - /// Rows of the modulation matrix - dsp::modulation_entry mod_matrix_data[mod_matrix_slots]; - /// Smoothed cutoff value - dsp::inertia inertia_cutoff; - /// Smoothed pitch bend value - dsp::inertia inertia_pitchbend; - /// Smoothed channel pressure value - dsp::inertia inertia_pressure; - /// Unsmoothed mod wheel value - float modwheel_value; - -public: - wavetable_audio_module(); - - dsp::voice *alloc_voice() { - dsp::block_voice *v = new dsp::block_voice(); - v->set_params_ptr(this, sample_rate); - return v; - } - - /// process function copied from Organ (will probably need some adjustments as well as implementing the panic flag elsewhere - uint32_t process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask) { - float *o[2] = { outs[0] + offset, outs[1] + offset }; - if (panic_flag) - { - control_change(120, 0); // stop all sounds - control_change(121, 0); // reset all controllers - panic_flag = false; - } - float buf[4096][2]; - dsp::zero(&buf[0][0], 2 * nsamples); - basic_synth::render_to(buf, nsamples); - float gain = 1.0f; - for (uint32_t i=0; i -#include -#include -#include - -using namespace std; -using namespace calf_utils; -using namespace calf_plugins; - -float parameter_properties::from_01(double value01) const -{ - double value = dsp::clip(value01, 0., 1.); - switch(flags & PF_SCALEMASK) - { - case PF_SCALE_DEFAULT: - case PF_SCALE_LINEAR: - case PF_SCALE_PERC: - default: - value = min + (max - min) * value01; - break; - case PF_SCALE_QUAD: - value = min + (max - min) * value01 * value01; - break; - case PF_SCALE_LOG: - value = min * pow(double(max / min), value01); - break; - case PF_SCALE_GAIN: - if (value01 < 0.00001) - value = min; - else { - float rmin = std::max(1.0f / 1024.0f, min); - value = rmin * pow(double(max / rmin), value01); - } - break; - case PF_SCALE_LOG_INF: - assert(step); - if (value01 > (step - 1.0) / step) - value = FAKE_INFINITY; - else - value = min * pow(double(max / min), value01 * step / (step - 1.0)); - break; - } - switch(flags & PF_TYPEMASK) - { - case PF_INT: - case PF_BOOL: - case PF_ENUM: - case PF_ENUM_MULTI: - if (value > 0) - value = (int)(value + 0.5); - else - value = (int)(value - 0.5); - break; - } - return value; -} - -double parameter_properties::to_01(float value) const -{ - switch(flags & PF_SCALEMASK) - { - case PF_SCALE_DEFAULT: - case PF_SCALE_LINEAR: - case PF_SCALE_PERC: - default: - return double(value - min) / (max - min); - case PF_SCALE_QUAD: - return sqrt(double(value - min) / (max - min)); - case PF_SCALE_LOG: - value /= min; - return log((double)value) / log((double)max / min); - case PF_SCALE_LOG_INF: - if (IS_FAKE_INFINITY(value)) - return max; - value /= min; - assert(step); - return (step - 1.0) * log((double)value) / (step * log((double)max / min)); - case PF_SCALE_GAIN: - if (value < 1.0 / 1024.0) // new bottom limit - 60 dB - return 0; - double rmin = std::max(1.0f / 1024.0f, min); - value /= rmin; - return log((double)value) / log(max / rmin); - } -} - -float parameter_properties::get_increment() const -{ - float increment = 0.01; - if (step > 1) - increment = 1.0 / (step - 1); - else - if (step > 0 && step < 1) - increment = step; - else - if ((flags & PF_TYPEMASK) != PF_FLOAT) - increment = 1.0 / (max - min); - return increment; -} - -int parameter_properties::get_char_count() const -{ - if ((flags & PF_SCALEMASK) == PF_SCALE_PERC) - return 6; - if ((flags & PF_SCALEMASK) == PF_SCALE_GAIN) { - char buf[256]; - size_t len = 0; - sprintf(buf, "%0.0f dB", 6.0 * log(min) / log(2)); - len = strlen(buf); - sprintf(buf, "%0.0f dB", 6.0 * log(max) / log(2)); - len = std::max(len, strlen(buf)) + 2; - return (int)len; - } - return std::max(to_string(min).length(), std::max(to_string(max).length(), to_string(min + (max-min) * 0.987654).length())); -} - -std::string parameter_properties::to_string(float value) const -{ - char buf[32]; - if ((flags & PF_SCALEMASK) == PF_SCALE_PERC) { - sprintf(buf, "%0.f%%", 100.0 * value); - return string(buf); - } - if ((flags & PF_SCALEMASK) == PF_SCALE_GAIN) { - if (value < 1.0 / 1024.0) // new bottom limit - 60 dB - return "-inf dB"; // XXXKF change to utf-8 infinity - sprintf(buf, "%0.1f dB", 6.0 * log(value) / log(2)); - return string(buf); - } - switch(flags & PF_TYPEMASK) - { - case PF_INT: - case PF_BOOL: - case PF_ENUM: - case PF_ENUM_MULTI: - value = (int)value; - break; - } - - if ((flags & PF_SCALEMASK) == PF_SCALE_LOG_INF && IS_FAKE_INFINITY(value)) - sprintf(buf, "+inf"); // XXXKF change to utf-8 infinity - else - sprintf(buf, "%g", value); - - switch(flags & PF_UNITMASK) { - case PF_UNIT_DB: return string(buf) + " dB"; - case PF_UNIT_HZ: return string(buf) + " Hz"; - case PF_UNIT_SEC: return string(buf) + " s"; - case PF_UNIT_MSEC: return string(buf) + " ms"; - case PF_UNIT_CENTS: return string(buf) + " ct"; - case PF_UNIT_SEMITONES: return string(buf) + "#"; - case PF_UNIT_BPM: return string(buf) + " bpm"; - case PF_UNIT_RPM: return string(buf) + " rpm"; - case PF_UNIT_DEG: return string(buf) + " deg"; - case PF_UNIT_NOTE: - { - static const char *notes = "C C#D D#E F F#G G#A A#B "; - int note = (int)value; - if (note < 0 || note > 127) - return "---"; - return string(notes + 2 * (note % 12), 2) + i2s(note / 12 - 2); - } - } - - return string(buf); -} - -void calf_plugins::plugin_ctl_iface::clear_preset() { - int param_count = get_metadata_iface()->get_param_count(); - for (int i = 0; i < param_count; i++) - { - const parameter_properties &pp = *get_metadata_iface()->get_param_props(i); - set_param_value(i, pp.def_value); - } - const char *const *vars = get_metadata_iface()->get_configure_vars(); - if (vars) - { - for (int i = 0; vars[i]; i++) - configure(vars[i], NULL); - } -} - -const char *calf_plugins::load_gui_xml(const std::string &plugin_id) -{ -#if 0 - try { - return strdup(calf_utils::load_file((std::string(PKGLIBDIR) + "/gui-" + plugin_id + ".xml").c_str()).c_str()); - } - catch(file_exception e) -#endif - { - return NULL; - } -} - -bool calf_plugins::get_freq_gridline(int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context, bool use_frequencies, float res, float ofs) -{ - if (subindex < 0 ) - return false; - if (use_frequencies) - { - if (subindex < 28) - { - vertical = true; - if (subindex == 9) legend = "100 Hz"; - if (subindex == 18) legend = "1 kHz"; - if (subindex == 27) legend = "10 kHz"; - float freq = 100; - if (subindex < 9) - freq = 10 * (subindex + 1); - else if (subindex < 18) - freq = 100 * (subindex - 9 + 1); - else if (subindex < 27) - freq = 1000 * (subindex - 18 + 1); - else - freq = 10000 * (subindex - 27 + 1); - pos = log(freq / 20.0) / log(1000); - if (!legend.empty()) - context->set_source_rgba(0, 0, 0, 0.2); - else - context->set_source_rgba(0, 0, 0, 0.1); - return true; - } - subindex -= 28; - } - if (subindex >= 32) - return false; - float gain = 16.0 / (1 << subindex); - pos = dB_grid(gain, res, ofs); - if (pos < -1) - return false; - if (subindex != 4) - context->set_source_rgba(0, 0, 0, subindex & 1 ? 0.1 : 0.2); - if (!(subindex & 1)) - { - std::stringstream ss; - ss << (24 - 6 * subindex) << " dB"; - legend = ss.str(); - } - vertical = false; - return true; -} - -void calf_plugins::set_channel_color(cairo_iface *context, int channel) -{ - if (channel & 1) - context->set_source_rgba(0.35, 0.4, 0.2, 1); - else - context->set_source_rgba(0.35, 0.4, 0.2, 0.5); - context->set_line_width(1.5); -} - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -bool frequency_response_line_graph::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const -{ - return get_freq_gridline(subindex, pos, vertical, legend, context); -} - -int frequency_response_line_graph::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const -{ - subindex_graph = 0; - subindex_dot = 0; - subindex_gridline = generation ? INT_MAX : 0; - return 1; -} - -/////////////////////////////////////////////////////////////////////////////////////// - -calf_plugins::plugin_registry &calf_plugins::plugin_registry::instance() -{ - static calf_plugins::plugin_registry registry; - return registry; -} - -const plugin_metadata_iface *calf_plugins::plugin_registry::get_by_uri(const char *plugin_uri) -{ - static const char prefix[] = "http://calf.sourceforge.net/plugins/"; - if (strncmp(plugin_uri, prefix, sizeof(prefix) - 1)) - return NULL; - const char *label = plugin_uri + sizeof(prefix) - 1; - for (unsigned int i = 0; i < plugins.size(); i++) - { - if (!strcmp(plugins[i]->get_plugin_info().label, label)) - return plugins[i]; - } - return NULL; -} - -const plugin_metadata_iface *calf_plugins::plugin_registry::get_by_id(const char *id, bool case_sensitive) -{ - typedef int (*comparator)(const char *, const char *); - comparator comp = case_sensitive ? strcmp : strcasecmp; - for (unsigned int i = 0; i < plugins.size(); i++) - { - if (!comp(plugins[i]->get_id(), id)) - return plugins[i]; - } - return NULL; -} - -/////////////////////////////////////////////////////////////////////////////////////// - -bool calf_plugins::parse_table_key(const char *key, const char *prefix, bool &is_rows, int &row, int &column) -{ - is_rows = false; - row = -1; - column = -1; - if (0 != strncmp(key, prefix, strlen(prefix))) - return false; - - key += strlen(prefix); - - if (!strcmp(key, "rows")) - { - is_rows = true; - return true; - } - - const char *comma = strchr(key, ','); - if (comma) - { - row = atoi(string(key, comma - key).c_str()); - column = atoi(comma + 1); - return true; - } - - printf("Unknown key %s under prefix %s", key, prefix); - - return false; -} - -/////////////////////////////////////////////////////////////////////////////////////// - -const char *mod_mapping_names[] = { "0..1", "-1..1", "-1..0", "x^2", "2x^2-1", "ASqr", "ASqrBip", "Para", NULL }; - -mod_matrix_metadata::mod_matrix_metadata(unsigned int _rows, const char **_src_names, const char **_dest_names) -: mod_src_names(_src_names) -, mod_dest_names(_dest_names) -, matrix_rows(_rows) -{ - table_column_info tci[6] = { - { "Source", TCT_ENUM, 0, 0, 0, mod_src_names }, - { "Mapping", TCT_ENUM, 0, 0, 0, mod_mapping_names }, - { "Modulator", TCT_ENUM, 0, 0, 0, mod_src_names }, - { "Amount", TCT_FLOAT, 0, 1, 1, NULL}, - { "Destination", TCT_ENUM, 0, 0, 0, mod_dest_names }, - { NULL } - }; - assert(sizeof(table_columns) == sizeof(tci)); - memcpy(table_columns, tci, sizeof(table_columns)); -} - -const table_column_info *mod_matrix_metadata::get_table_columns() const -{ - return table_columns; -} - -uint32_t mod_matrix_metadata::get_table_rows() const -{ - return matrix_rows; -} - -/////////////////////////////////////////////////////////////////////////////////////// - -#if USE_EXEC_GUI - -table_via_configure::table_via_configure() -{ - rows = 0; -} - -table_via_configure::~table_via_configure() -{ -} - -#endif diff --git a/plugins/LadspaEffect/calf/src/metadata.cpp b/plugins/LadspaEffect/calf/src/metadata.cpp deleted file mode 100644 index 45891e96e4c..00000000000 --- a/plugins/LadspaEffect/calf/src/metadata.cpp +++ /dev/null @@ -1,1446 +0,0 @@ -/* Calf DSP Library - * Example audio modules - parameters and LADSPA wrapper instantiation - * - * Copyright (C) 2001-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 02110-1301 USA - */ -#include -#include -#include -#include -#include - -using namespace dsp; -using namespace calf_plugins; - -const char *calf_plugins::calf_copyright_info = "(C) 2001-2009 Krzysztof Foltman, Thor Harald Johanssen, Markus Schmidt and others; license: LGPL"; - -//////////////////////////////////////////////////////////////////////////// - -CALF_PORT_NAMES(flanger) = {"In L", "In R", "Out L", "Out R"}; - -CALF_PORT_PROPS(flanger) = { - { 0.1, 0.1, 10, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC | PF_PROP_GRAPH, NULL, "min_delay", "Min delay" }, - { 0.5, 0.1, 10, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "mod_depth", "Mod depth" }, - { 0.25, 0.01, 20, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "mod_rate", "Mod rate" }, - { 0.90, -0.99, 0.99, 0, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "feedback", "Feedback" }, - { 0, 0, 360, 9, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_DEG, NULL, "stereo", "Stereo phase" }, - { 0, 0, 1, 2, PF_BOOL | PF_CTL_BUTTON , NULL, "reset", "Reset" }, - { 1, 0, 4, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "amount", "Amount" }, - { 1.0, 0, 4, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "dry", "Dry Amount" }, - {} -}; - -CALF_PLUGIN_INFO(flanger) = { 0x847d, "Flanger", "Calf Flanger", "Krzysztof Foltman", calf_plugins::calf_copyright_info, "FlangerPlugin" }; - -//////////////////////////////////////////////////////////////////////////// - -CALF_PORT_NAMES(phaser) = {"In L", "In R", "Out L", "Out R"}; - -CALF_PORT_PROPS(phaser) = { - { 1000, 20, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "base_freq", "Center Freq" }, - { 4000, 0, 10800, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "mod_depth", "Mod depth" }, - { 0.25, 0.01, 20, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "mod_rate", "Mod rate" }, - { 0.25, -0.99, 0.99, 0, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "feedback", "Feedback" }, - { 6, 1, 12, 12, PF_INT | PF_SCALE_LINEAR | PF_CTL_KNOB, NULL, "stages", "# Stages" }, - { 180, 0, 360, 9, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_DEG, NULL, "stereo", "Stereo phase" }, - { 0, 0, 1, 2, PF_BOOL | PF_CTL_BUTTON , NULL, "reset", "Reset" }, - { 1, 0, 4, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "amount", "Amount" }, - { 1.0, 0, 4, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "dry", "Dry Amount" }, -}; - -CALF_PLUGIN_INFO(phaser) = { 0x8484, "Phaser", "Calf Phaser", "Krzysztof Foltman", calf_plugins::calf_copyright_info, "PhaserPlugin" }; - -//////////////////////////////////////////////////////////////////////////// - -CALF_PORT_NAMES(reverb) = {"In L", "In R", "Out L", "Out R"}; - -const char *reverb_room_sizes[] = { "Small", "Medium", "Large", "Tunnel-like", "Large/smooth", "Experimental" }; - -CALF_PORT_PROPS(reverb) = { - { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip", "0dB" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_wet", "Wet amount" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_out", "Output" }, - { 1.5, 0.4, 15.0, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_SEC, NULL, "decay_time", "Decay time" }, - { 5000, 2000,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "hf_damp", "High Frq Damp" }, - { 2, 0, 5, 0, PF_ENUM | PF_CTL_COMBO , reverb_room_sizes, "room_size", "Room size", }, - { 0.5, 0, 1, 0, PF_FLOAT | PF_CTL_KNOB | PF_SCALE_PERC, NULL, "diffusion", "Diffusion" }, - { 0.25, 0, 2, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "amount", "Wet Amount" }, - { 1.0, 0, 2, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "dry", "Dry Amount" }, - { 0, 0, 50, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "predelay", "Pre Delay" }, - { 300, 20, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "bass_cut", "Bass Cut" }, - { 5000, 20, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "treble_cut", "Treble Cut" }, - {} -}; - -CALF_PLUGIN_INFO(reverb) = { 0x847e, "Reverb", "Calf Reverb", "Krzysztof Foltman", calf_plugins::calf_copyright_info, "ReverbPlugin" }; - -//////////////////////////////////////////////////////////////////////////// - -CALF_PORT_NAMES(filter) = {"In L", "In R", "Out L", "Out R"}; - -const char *filter_choices[] = { - "12dB/oct Lowpass", - "24dB/oct Lowpass", - "36dB/oct Lowpass", - "12dB/oct Highpass", - "24dB/oct Highpass", - "36dB/oct Highpass", - "6dB/oct Bandpass", - "12dB/oct Bandpass", - "18dB/oct Bandpass", - "6dB/oct Bandreject", - "12dB/oct Bandreject", - "18dB/oct Bandreject", -}; - -CALF_PORT_PROPS(filter) = { - { 2000, 10,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "freq", "Frequency" }, - { 0.707, 0.707, 32, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "res", "Resonance" }, - { biquad_filter_module::mode_12db_lp, - biquad_filter_module::mode_12db_lp, - biquad_filter_module::mode_count - 1, - 1, PF_ENUM | PF_CTL_COMBO, filter_choices, "mode", "Mode" }, - { 20, 5, 100, 20, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "inertia", "Inertia"}, -}; - -CALF_PLUGIN_INFO(filter) = { 0x847f, "Filter", "Calf Filter", "Krzysztof Foltman", calf_plugins::calf_copyright_info, "FilterPlugin" }; - -//////////////////////////////////////////////////////////////////////////// - -CALF_PORT_NAMES(filterclavier) = {"In L", "In R", "Out L", "Out R"}; - -CALF_PORT_PROPS(filterclavier) = { - { 0, -48, 48, 48*2+1, PF_INT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_SEMITONES, NULL, "transpose", "Transpose" }, - { 0, -100, 100, 0, PF_INT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "detune", "Detune" }, - { 32, 0.707, 32, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "maxres", "Max. Resonance" }, - { biquad_filter_module::mode_6db_bp, - biquad_filter_module::mode_12db_lp, - biquad_filter_module::mode_count - 1, - 1, PF_ENUM | PF_CTL_COMBO | PF_PROP_GRAPH, filter_choices, "mode", "Mode" }, - { 20, 1, 2000, 20, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "inertia", "Portamento time"}, - {} -}; - -CALF_PLUGIN_INFO(filterclavier) = { 0x849f, "Filterclavier", "Calf Filterclavier", "Krzysztof Foltman / Hans Baier", calf_plugins::calf_copyright_info, "FilterclavierPlugin" }; - -//////////////////////////////////////////////////////////////////////////// - -CALF_PORT_NAMES(vintage_delay) = {"In L", "In R", "Out L", "Out R"}; - -const char *vintage_delay_mixmodes[] = { - "Stereo", - "Ping-Pong", - "L then R", - "R then L", -}; - -const char *vintage_delay_fbmodes[] = { - "Plain", - "Tape", - "Old Tape", -}; - -CALF_PORT_PROPS(vintage_delay) = { - { 120, 30, 300, 1, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_BPM, NULL, "bpm", "Tempo" }, - { 4, 1, 16, 1, PF_INT | PF_SCALE_LINEAR | PF_CTL_FADER, NULL, "subdiv", "Subdivide"}, - { 3, 1, 16, 1, PF_INT | PF_SCALE_LINEAR | PF_CTL_FADER, NULL, "time_l", "Time L"}, - { 5, 1, 16, 1, PF_INT | PF_SCALE_LINEAR | PF_CTL_FADER, NULL, "time_r", "Time R"}, - { 0.5, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB, NULL, "feedback", "Feedback" }, - { 0.25, 0, 4, 100, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "amount", "Amount" }, - { 1, 0, 3, 0, PF_ENUM | PF_CTL_COMBO, vintage_delay_mixmodes, "mix_mode", "Mix mode" }, - { 1, 0, 2, 0, PF_ENUM | PF_CTL_COMBO, vintage_delay_fbmodes, "medium", "Medium" }, - { 1.0, 0, 4, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "dry", "Dry Amount" }, - { 1.0, -1, 1, 0, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB , NULL, "width", "Stereo Width" }, - {} -}; - -CALF_PLUGIN_INFO(vintage_delay) = { 0x8482, "VintageDelay", "Calf Vintage Delay", "Krzysztof Foltman", calf_plugins::calf_copyright_info, "DelayPlugin" }; - -//////////////////////////////////////////////////////////////////////////// - -CALF_PORT_NAMES(rotary_speaker) = {"In L", "In R", "Out L", "Out R"}; - -const char *rotary_speaker_speed_names[] = { "Off", "Chorale", "Tremolo", "HoldPedal", "ModWheel", "Manual" }; - -CALF_PORT_PROPS(rotary_speaker) = { - { 5, 0, 5, 1.01, PF_ENUM | PF_CTL_COMBO, rotary_speaker_speed_names, "vib_speed", "Speed Mode" }, - { 0.5, 0, 1, 0, PF_FLOAT | PF_CTL_KNOB | PF_SCALE_PERC, NULL, "spacing", "Tap Spacing" }, - { 0.5, 0, 1, 0, PF_FLOAT | PF_CTL_KNOB | PF_SCALE_PERC, NULL, "shift", "Tap Offset" }, - { 0.45, 0, 1, 0, PF_FLOAT | PF_CTL_KNOB | PF_SCALE_PERC, NULL, "mod_depth", "FM Depth" }, - { 36, 10, 600, 0, PF_FLOAT | PF_CTL_KNOB | PF_SCALE_LOG | PF_UNIT_RPM, NULL, "treble_speed", "Treble Motor" }, - { 30, 10, 600, 0, PF_FLOAT | PF_CTL_KNOB | PF_SCALE_LOG | PF_UNIT_RPM, NULL, "bass_speed", "Bass Motor" }, - { 0.7, 0, 1, 101, PF_FLOAT | PF_CTL_KNOB | PF_SCALE_PERC, NULL, "mic_distance", "Mic Distance" }, - { 0.3, 0, 1, 101, PF_FLOAT | PF_CTL_KNOB | PF_SCALE_PERC, NULL, "reflection", "Reflection" }, - { 0.45, 0, 1, 0, PF_FLOAT | PF_CTL_KNOB | PF_SCALE_PERC, NULL, "am_depth", "AM Depth" }, - { 0, 0, 1, 0, PF_FLOAT | PF_CTL_KNOB | PF_SCALE_PERC, NULL, "test", "Test" }, - { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_l", "Low rotor" }, - { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_h", "High rotor" }, - {} -}; - -CALF_PLUGIN_INFO(rotary_speaker) = { 0x8483, "RotarySpeaker", "Calf Rotary Speaker", "Krzysztof Foltman", calf_plugins::calf_copyright_info, "SimulatorPlugin" }; - -//////////////////////////////////////////////////////////////////////////// - -CALF_PORT_NAMES(multichorus) = {"In L", "In R", "Out L", "Out R"}; - -CALF_PORT_PROPS(multichorus) = { - { 5, 0.1, 10, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC | PF_PROP_GRAPH, NULL, "min_delay", "Min delay" }, - { 6, 0.1, 10, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC| PF_PROP_GRAPH, NULL, "mod_depth", "Mod depth" }, - { 0.5, 0.01, 20, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ| PF_PROP_GRAPH, NULL, "mod_rate", "Modulation rate" }, - { 180, 0, 360, 91, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_DEG, NULL, "stereo", "Stereo phase" }, - { 4, 1, 8, 8, PF_INT | PF_SCALE_LINEAR | PF_CTL_FADER, NULL, "voices", "Voices"}, - { 64, 0, 360, 91, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_DEG, NULL, "vphase", "Inter-voice phase" }, - { 2, 0, 4, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "amount", "Amount" }, - { 1.0, 0, 4, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "dry", "Dry Amount" }, - { 100, 10,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "freq", "Center Frq 1" }, - { 5000, 10,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "freq2", "Center Frq 2" }, - { 0.125, 0.125, 8, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "q", "Q" }, - { 1, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB, NULL, "overlap", "Overlap" }, -}; - -CALF_PLUGIN_INFO(multichorus) = { 0x8501, "MultiChorus", "Calf MultiChorus", "Krzysztof Foltman", calf_plugins::calf_copyright_info, "ChorusPlugin" }; - -//////////////////////////////////////////////////////////////////////////// - -CALF_PORT_NAMES(compressor) = {"In L", "In R", "Out L", "Out R"}; - -const char *compressor_detection_names[] = { "RMS", "Peak" }; -const char *compressor_stereo_link_names[] = { "Average", "Maximum" }; - -CALF_PORT_PROPS(compressor) = { - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass", "Bypass" }, - { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_in", "Input" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_in", "Input" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_out", "Output" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_in", "0dB-In" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_out", "0dB-Out" }, - { 0.125, 0.000976563, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "threshold", "Threshold" }, - { 2, 1, 20, 21, PF_FLOAT | PF_SCALE_LOG_INF | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "ratio", "Ratio" }, - { 20, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "attack", "Attack" }, - { 250, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "release", "Release" }, - { 2, 1, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "makeup", "Makeup Gain" }, - { 2.828427125, 1, 8, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "knee", "Knee" }, - { 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, compressor_detection_names, "detection", "Detection" }, - { 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, compressor_stereo_link_names, "stereo_link", "Stereo Link" }, - { 0, 0.03125, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "compression", "Reduction" }, - {} -}; - -CALF_PLUGIN_INFO(compressor) = { 0x8502, "Compressor", "Calf Compressor", "Thor Harald Johansen", calf_plugins::calf_copyright_info, "CompressorPlugin" }; - -//////////////////////////////////////////////////////////////////////////// - -CALF_PORT_NAMES(sidechaincompressor) = {"In L", "In R", "Out L", "Out R"}; - -const char *sidechaincompressor_detection_names[] = { "RMS", "Peak" }; -const char *sidechaincompressor_stereo_link_names[] = { "Average", "Maximum" }; -const char *sidechaincompressor_mode_names[] = {"Wideband (F1:off / F2:off)", - "Deesser wide (F1:Bell / F2:HP)", - "Deesser split (F1:off / F2:HP)", - "Derumbler wide (F1:LP / F2:Bell)", - "Derumbler split (F1:LP / F2:off)", - "Weighted #1 (F1:Shelf / F2:Shelf)", - "Weighted #2 (F1:Shelf / F2:Bell)", - "Weighted #3 (F1:Bell / F2:Shelf)", - "Bandpass #1 (F1:BP / F2:off)", - "Bandpass #2 (F1:HP / F2:LP)"}; -const char *sidechaincompressor_route_names[] = {"Stereo Input (Default)", - "R ▸ L (L: Signal / R: S/C)", - "L ▸ R (L: S/C / R: Signal)"}; -const char *sidechaincompressor_filter_choices[] = { "12dB", "24dB", "36dB"}; - - -CALF_PORT_PROPS(sidechaincompressor) = { - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass", "Bypass" }, - { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_in", "Input" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_in", "Input" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_out", "Output" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_in", "0dB-In" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_out", "0dB-Out" }, - { 0.125, 0.000976563, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "threshold", "Threshold" }, - { 2, 1, 20, 21, PF_FLOAT | PF_SCALE_LOG_INF | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "ratio", "Ratio" }, - { 20, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "attack", "Attack" }, - { 250, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "release", "Release" }, - { 2, 1, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "makeup", "Makeup Gain" }, - { 2.828427125, 1, 8, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "knee", "Knee" }, - { 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, sidechaincompressor_detection_names, "detection", "Detection" }, - { 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, sidechaincompressor_stereo_link_names, "stereo_link", "Stereo Link" }, - { 0, 0.03125, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "compression", "Gain Reduction" }, - { 0, 0, 9, 0, PF_ENUM | PF_CTL_COMBO, sidechaincompressor_mode_names, "sc_mode", "S/C Mode" }, - { 250, 10,18000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "f1_freq", "F1 Freq" }, - { 4500, 10,18000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "f2_freq", "F2 Freq" }, - { 1, 0.0625, 16, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "f1_level", "F1 Level" }, - { 1, 0.0625, 16, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "f2_level", "F2 Level" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "sc_listen", "S/C-Listen" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "f1_active", "F1 Active" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "f2_active", "F2 Active" }, - { 0, 0, 2, 0, PF_ENUM | PF_CTL_COMBO, sidechaincompressor_route_names, "sc_route", "S/C Route" }, - { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "sc_level", "S/C Level" }, - {} -}; - -CALF_PLUGIN_INFO(sidechaincompressor) = { 0x8517, "Sidechaincompressor", "Calf Sidechain Compressor", "Markus Schmidt / Thor Harald Johansen", calf_plugins::calf_copyright_info, "CompressorPlugin" }; - -//////////////////////////////////////////////////////////////////////////// - -CALF_PORT_NAMES(multibandcompressor) = {"In L", "In R", "Out L", "Out R"}; - -const char *multibandcompressor_detection_names[] = { "RMS", "Peak" }; -const char *multibandcompressor_filter_choices[] = { "12dB", "36dB"}; - -CALF_PORT_PROPS(multibandcompressor) = { - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass", "Bypass" }, - { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_in", "Input" }, - { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_out", "Output" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_inL", "Input L" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_inR", "Input R" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_outL", "Output L" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_outR", "Output R" }, - { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_inL", "0dB-InL" }, - { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_inR", "0dB-InR" }, - { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outL", "0dB-OutL" }, - { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outR", "0dB-OutR" }, - - { 120, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "freq0", "Split 1/2" }, - { 1000, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "freq1", "Split 2/3" }, - { 6000, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "freq2", "Split 3/4" }, - - { -0.17, -0.5, 0.5, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "sep0", "S1" }, - { -0.17, -0.5, 0.5, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "sep1", "S2" }, - { -0.17, -0.5, 0.5, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "sep2", "S3" }, - - { 0.7762471166286917, 0.25, 4, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB | PF_PROP_GRAPH, NULL, "q0", "Q1" }, - { 0.7762471166286917, 0.25, 4, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB | PF_PROP_GRAPH, NULL, "q1", "Q2" }, - { 0.7762471166286917, 0.25, 4, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB | PF_PROP_GRAPH, NULL, "q2", "Q3" }, - - { 1, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, multibandcompressor_filter_choices, "mode", "Filter Mode" }, - - { 0.25, 0.000976563, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "threshold0", "Threshold 1" }, - { 2, 1, 20, 21, PF_FLOAT | PF_SCALE_LOG_INF | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "ratio0", "Ratio 1" }, - { 150, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "attack0", "Attack 1" }, - { 300, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "release0", "Release 1" }, - { 2, 1, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "makeup0", "Makeup 1" }, - { 2.828427125, 1, 8, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "knee0", "Knee 1" }, - { 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, multibandcompressor_detection_names, "detection0", "Detection 1" }, - { 1, 0.0625, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "compression0", "Gain Reduction 1" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "output0", "Output 1" }, - { 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass0", "Bypass 1" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "solo0", "Solo 1" }, - - - { 0.125, 0.000976563, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "threshold1", "Threshold 2" }, - { 2, 1, 20, 21, PF_FLOAT | PF_SCALE_LOG_INF | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "ratio1", "Ratio 2" }, - { 100, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "attack1", "Attack 2" }, - { 200, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "release1", "Release 2" }, - { 2, 1, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "makeup1", "Makeup 2" }, - { 2.828427125, 1, 8, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "knee1", "Knee 2" }, - { 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, multibandcompressor_detection_names, "detection1", "Detection 2" }, - { 1, 0.0625, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "compression1", "Gain Reduction 2" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "output1", "Output 2" }, - { 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass1", "Bypass 2" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "solo1", "Solo 2" }, - - - { 0.0625, 0.000976563, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "threshold2", "Threshold 3" }, - { 2, 1, 20, 21, PF_FLOAT | PF_SCALE_LOG_INF | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "ratio2", "Ratio 3" }, - { 50, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "attack2", "Attack 3" }, - { 100, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "release2", "Release 3" }, - { 2, 1, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "makeup2", "Makeup 3" }, - { 2.828427125, 1, 8, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "knee2", "Knee 3" }, - { 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, multibandcompressor_detection_names, "detection2", "Detection 3" }, - { 1, 0.0625, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "compression2", "Gain Reduction 3" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "output2", "Output 3" }, - { 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass2", "Bypass 3" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "solo2", "Solo 3" }, - - - { 0.03125, 0.000976563, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "threshold3", "Threshold 4" }, - { 2, 1, 20, 21, PF_FLOAT | PF_SCALE_LOG_INF | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "ratio3", "Ratio 4" }, - { 25, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "attack3", "Attack 4" }, - { 50, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "release3", "Release 4" }, - { 2, 1, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "makeup3", "Makeup 4" }, - { 2.828427125, 1, 8, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "knee3", "Knee 4" }, - { 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, multibandcompressor_detection_names, "detection3", "Detection 4" }, - { 1, 0.0625, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "compression3", "Gain Reduction 4" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "output3", "Output 4" }, - { 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass3", "Bypass 4" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "solo3", "Solo 4" }, - {} -}; - -CALF_PLUGIN_INFO(multibandcompressor) = { 0x8516, "Multibandcompressor", "Calf Multiband Compressor", "Markus Schmidt / Thor Harald Johansen", calf_plugins::calf_copyright_info, "CompressorPlugin" }; - -//////////////////////////////////////////////////////////////////////////// - -CALF_PORT_NAMES(deesser) = {"In L", "In R", "Out L", "Out R"}; - -const char *deesser_detection_names[] = { "RMS", "Peak" }; -const char *deesser_mode_names[] = { "Wide", "Split" }; - - -CALF_PORT_PROPS(deesser) = { - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass", "Bypass" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "detected", "Detected" }, - { 0, 0.0625, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "compression", "Gain Reduction" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "detected_led", "Active" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_out", "Out" }, - { 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, deesser_detection_names, "detection", "Detection" }, - { 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, deesser_mode_names, "mode", "Mode" }, - { 0.125, 0.000976563, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "threshold", "Threshold" }, - { 3, 1, 20, 21, PF_FLOAT | PF_SCALE_LOG_INF | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "ratio", "Ratio" }, - { 15, 1, 100, 1, PF_INT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "laxity", "Laxity" }, - { 1, 1, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "makeup", "Makeup" }, - - { 6000, 10, 18000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "f1_freq", "Split" }, - { 4500, 10, 18000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "f2_freq", "Peak" }, - { 1, 0.0625, 16, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "f1_level", "Gain" }, - { 4, 0.0625, 16, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "f2_level", "Level" }, - { 1, 0.1, 100,1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "f2_q", "Peak Q" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "sc_listen", "S/C-Listen" }, - {} -}; - -CALF_PLUGIN_INFO(deesser) = { 0x8515, "Deesser", "Calf Deesser", "Markus Schmidt / Thor Harald Johansen", calf_plugins::calf_copyright_info, "CompressorPlugin" }; - -//////////////////////////////////////////////////////////////////////////// - -CALF_PORT_NAMES(gate) = {"In L", "In R", "Out L", "Out R"}; - -const char *gate_detection_names[] = { "RMS", "Peak" }; -const char *gate_stereo_link_names[] = { "Average", "Maximum" }; - -CALF_PORT_PROPS(gate) = { - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass", "Bypass" }, - { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_in", "Input" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_in", "Input" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_out", "Output" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_in", "0dB-In" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_out", "0dB-Out" }, - { 0.06125, 0.000015849, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "range", "Max Gain Reduction" }, - { 0.125, 0.000976563, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "threshold", "Threshold" }, - { 2, 1, 20, 21, PF_FLOAT | PF_SCALE_LOG_INF | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "ratio", "Ratio" }, - { 20, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "attack", "Attack" }, - { 250, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "release", "Release" }, - { 1, 1, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "makeup", "Makeup Gain" }, - { 2.828427125, 1, 8, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "knee", "Knee" }, - { 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, gate_detection_names, "detection", "Detection" }, - { 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, gate_stereo_link_names, "stereo_link", "Stereo Link" }, - { 0, 0.03125, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "gating", "Gating" }, - {} -}; - -CALF_PLUGIN_INFO(gate) = { 0x8503, "Gate", "Calf Gate", "Damien Zammit / Thor Harald Johansen", calf_plugins::calf_copyright_info, "ExpanderPlugin" }; - -//////////////////////////////////////////////////////////////////////////// - -CALF_PORT_NAMES(sidechaingate) = {"In L", "In R", "Out L", "Out R"}; - -const char *sidechaingate_detection_names[] = { "RMS", "Peak" }; -const char *sidechaingate_stereo_link_names[] = { "Average", "Maximum" }; -const char *sidechaingate_mode_names[] = {"Wideband (F1:off / F2:off)", - "High gate wide (F1:Bell / F2:HP)", - "High gate split (F1:off / F2:HP)", - "Low Gate wide (F1:LP / F2:Bell)", - "Low gate split (F1:LP / F2:off)", - "Weighted #1 (F1:Shelf / F2:Shelf)", - "Weighted #2 (F1:Shelf / F2:Bell)", - "Weighted #3 (F1:Bell / F2:Shelf)", - "Bandpass #1 (F1:BP / F2:off)", - "Bandpass #2 (F1:HP / F2:LP)"}; -const char *sidechaingate_route_names[] = {"Stereo Input (Default)", - "R ▸ L (L: Signal / R: S/C)", - "L ▸ R (L: S/C / R: Signal)"}; -const char *sidechaingate_filter_choices[] = { "12dB", "24dB", "36dB"}; - - -CALF_PORT_PROPS(sidechaingate) = { - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass", "Bypass" }, - { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_in", "Input" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_in", "Input" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_out", "Output" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_in", "0dB-In" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_out", "0dB-Out" }, - { 0.06125, 0.000015849, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "range", "Max Gain Reduction" }, - { 0.125, 0.000976563, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "threshold", "Threshold" }, - { 2, 1, 20, 21, PF_FLOAT | PF_SCALE_LOG_INF | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "ratio", "Ratio" }, - { 20, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "attack", "Attack" }, - { 250, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "release", "Release" }, - { 1, 1, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "makeup", "Makeup Gain" }, - { 2.828427125, 1, 8, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "knee", "Knee" }, - { 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, sidechaingate_detection_names, "detection", "Detection" }, - { 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, sidechaingate_stereo_link_names, "stereo_link", "Stereo Link" }, - { 0, 0.03125, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "gating", "Gating" }, - { 0, 0, 9, 0, PF_ENUM | PF_CTL_COMBO, sidechaingate_mode_names, "sc_mode", "S/C Mode" }, - { 250, 10,18000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "f1_freq", "F1 Freq" }, - { 4500, 10,18000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "f2_freq", "F2 Freq" }, - { 1, 0.0625, 16, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "f1_level", "F1 Level" }, - { 1, 0.0625, 16, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "f2_level", "F2 Level" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "sc_listen", "S/C-Listen" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "f1_active", "F1 Active" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "f2_active", "F2 Active" }, - { 0, 0, 2, 0, PF_ENUM | PF_CTL_COMBO, sidechaingate_route_names, "sc_route", "S/C Route" }, - { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "sc_level", "S/C Level" }, - {} -}; - -CALF_PLUGIN_INFO(sidechaingate) = { 0x8504, "Sidechaingate", "Calf Sidechain Gate", "Markus Schmidt / Damien Zammit / Thor Harald Johansen", calf_plugins::calf_copyright_info, "ExpanderPlugin" }; - -//////////////////////////////////////////////////////////////////////////// - -CALF_PORT_NAMES(multibandgate) = {"In L", "In R", "Out L", "Out R"}; - -const char *multibandgate_detection_names[] = { "RMS", "Peak" }; -const char *multibandgate_filter_choices[] = { "12dB", "36dB"}; - -CALF_PORT_PROPS(multibandgate) = { - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass", "Bypass" }, - { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_in", "Input" }, - { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_out", "Output" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_inL", "Input L" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_inR", "Input R" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_outL", "Output L" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_outR", "Output R" }, - { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_inL", "0dB-InL" }, - { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_inR", "0dB-InR" }, - { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outL", "0dB-OutL" }, - { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outR", "0dB-OutR" }, - - { 120, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "freq0", "Split 1/2" }, - { 1000, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "freq1", "Split 2/3" }, - { 6000, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "freq2", "Split 3/4" }, - - { -0.17, -0.5, 0.5, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "sep0", "S1" }, - { -0.17, -0.5, 0.5, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "sep1", "S2" }, - { -0.17, -0.5, 0.5, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "sep2", "S3" }, - - { 0.7762471166286917, 0.25, 4, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB | PF_PROP_GRAPH, NULL, "q0", "Q1" }, - { 0.7762471166286917, 0.25, 4, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB | PF_PROP_GRAPH, NULL, "q1", "Q2" }, - { 0.7762471166286917, 0.25, 4, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB | PF_PROP_GRAPH, NULL, "q2", "Q3" }, - - { 1, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, multibandgate_filter_choices, "mode", "Filter Mode" }, - - { 0.06125, 0.000015849, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "range0", "Reduction 1" }, - { 0.25, 0.000976563, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "threshold0", "Threshold 1" }, - { 2, 1, 20, 21, PF_FLOAT | PF_SCALE_LOG_INF | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "ratio0", "Ratio 1" }, - { 150, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "attack0", "Attack 1" }, - { 300, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "release0", "Release 1" }, - { 1, 1, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "makeup0", "Makeup 1" }, - { 2.828427125, 1, 8, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "knee0", "Knee 1" }, - { 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, multibandcompressor_detection_names, "detection0", "Detection 1" }, - { 1, 0.0625, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "gating0", "Gating 1" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "output0", "Output 1" }, - { 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass0", "Bypass 1" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "solo0", "Solo 1" }, - - { 0.06125, 0.000015849, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "range1", "Reduction 2" }, - { 0.125, 0.000976563, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "threshold1", "Threshold 2" }, - { 2, 1, 20, 21, PF_FLOAT | PF_SCALE_LOG_INF | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "ratio1", "Ratio 2" }, - { 100, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "attack1", "Attack 2" }, - { 200, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "release1", "Release 2" }, - { 1, 1, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "makeup1", "Makeup 2" }, - { 2.828427125, 1, 8, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "knee1", "Knee 2" }, - { 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, multibandcompressor_detection_names, "detection1", "Detection 2" }, - { 1, 0.0625, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "gating1", "Gating 2" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "output1", "Output 2" }, - { 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass1", "Bypass 2" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "solo1", "Solo 2" }, - - { 0.06125, 0.000015849, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "range2", "Reduction 3" }, - { 0.0625, 0.000976563, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "threshold2", "Threshold 3" }, - { 2, 1, 20, 21, PF_FLOAT | PF_SCALE_LOG_INF | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "ratio2", "Ratio 3" }, - { 50, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "attack2", "Attack 3" }, - { 100, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "release2", "Release 3" }, - { 1, 1, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "makeup2", "Makeup 3" }, - { 2.828427125, 1, 8, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "knee2", "Knee 3" }, - { 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, multibandcompressor_detection_names, "detection2", "Detection 3" }, - { 1, 0.0625, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "gating2", "Gating 3" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "output2", "Output 3" }, - { 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass2", "Bypass 3" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "solo2", "Solo 3" }, - - { 0.06125, 0.000015849, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "range3", "Reduction 4" }, - { 0.03125, 0.000976563, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "threshold3", "Threshold 4" }, - { 2, 1, 20, 21, PF_FLOAT | PF_SCALE_LOG_INF | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "ratio3", "Ratio 4" }, - { 25, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "attack3", "Attack 4" }, - { 50, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "release3", "Release 4" }, - { 1, 1, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "makeup3", "Makeup 4" }, - { 2.828427125, 1, 8, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "knee3", "Knee 4" }, - { 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, multibandcompressor_detection_names, "detection3", "Detection 4" }, - { 1, 0.0625, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "gating3", "Gating 4" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "output3", "Output 4" }, - { 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass3", "Bypass 4" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "solo3", "Solo 4" }, - {} -}; - -CALF_PLUGIN_INFO(multibandgate) = { 0x8505, "Multibandgate", "Calf Multiband Gate", "Markus Schmidt / Damien Zammit / Thor Harald Johansen", calf_plugins::calf_copyright_info, "ExpanderPlugin" }; - -//////////////////////////////////////////////////////////////////////////// - -CALF_PORT_NAMES(limiter) = {"In L", "In R", "Out L", "Out R"}; - -CALF_PORT_PROPS(limiter) = { - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass", "Bypass" }, - { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_in", "Input" }, - { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_out", "Output" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_inL", "Input L" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_inR", "Input R" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_outL", "Output L" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_outR", "Output R" }, - { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_inL", "0dB-InL" }, - { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_inR", "0dB-InR" }, - { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outL", "0dB-OutL" }, - { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outR", "0dB-OutR" }, - - { 1, 0.0625, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "limit", "Limit" }, - { 5, 0.1, 10, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "attack", "Lookahead" }, - { 50, 1, 1000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "release", "Release" }, - - { 1, 0.125, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "att", "Attenuation" }, - - { 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "asc", "ASC" }, - - { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "asc_led", "asc active" }, - - { 0.5f, 0.f, 1.f, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "asc_coeff", "ASC Level" }, - - {} -}; - -CALF_PLUGIN_INFO(limiter) = { 0x8521, "Limiter", "Calf Limiter", "Christian Holschuh / Markus Schmidt", calf_plugins::calf_copyright_info, "LimiterPlugin" }; - -//////////////////////////////////////////////////////////////////////////// - -CALF_PORT_NAMES(multibandlimiter) = {"In L", "In R", "Out L", "Out R"}; -const char *multibandlimiter_filter_choices[] = { "12dB", "36dB"}; - -CALF_PORT_PROPS(multibandlimiter) = { - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass", "Bypass" }, - { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_in", "Input" }, - { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_out", "Output" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_inL", "Input L" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_inR", "Input R" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_outL", "Output L" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_outR", "Output R" }, - { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_inL", "0dB-InL" }, - { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_inR", "0dB-InR" }, - { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outL", "0dB-OutL" }, - { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outR", "0dB-OutR" }, - - { 100, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "freq0", "Split 1/2" }, - { 750, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "freq1", "Split 2/3" }, - { 5000, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "freq2", "Split 3/4" }, - - { -0.17, -0.5, 0.5, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "sep0", "S1" }, - { -0.17, -0.5, 0.5, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "sep1", "S2" }, - { -0.17, -0.5, 0.5, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "sep2", "S3" }, - - { 0.7762471166286917, 0.25, 4, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB | PF_PROP_GRAPH, NULL, "q0", "Q1" }, - { 0.7762471166286917, 0.25, 4, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB | PF_PROP_GRAPH, NULL, "q1", "Q2" }, - { 0.7762471166286917, 0.25, 4, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB | PF_PROP_GRAPH, NULL, "q2", "Q3" }, - - { 1, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, multibandlimiter_filter_choices, "mode", "Filter Mode" }, - - { 1, 0.0625, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "limit", "Limit" }, - { 4, 0.1, 10, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "attack", "Lookahead" }, - { 30, 1, 1000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "release", "Release" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "minrel", "Min Release" }, - - { 1, 0.125, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "att0", "Low" }, - { 1, 0.125, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "att1", "LMid" }, - { 1, 0.125, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "att2", "HMid" }, - { 1, 0.125, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "att3", "Hi" }, - - { 0.f, -1.f, 1.f, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "weight0", "Weight 1" }, - { 0.f, -1.f, 1.f, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "weight1", "Weight 2" }, - { 0.f, -1.f, 1.f, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "weight2", "Weight 3" }, - { 0.f, -1.f, 1.f, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "weight3", "Weight 4" }, - - { 0.5f, -1.f, 1.f, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "release0", "Release 1" }, - { 0.2f, -1.f, 1.f, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "release1", "Release 2" }, - { -0.2f, -1.f, 1.f, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "release2", "Release 3" }, - { -0.5f, -1.f, 1.f, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "release3", "Release 4" }, - - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "solo0", "Solo 1" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "solo1", "Solo 2" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "solo2", "Solo 3" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "solo3", "Solo 4" }, - - { 1, 0.f, 1000, 0, PF_FLOAT | PF_UNIT_MSEC | PF_PROP_OUTPUT, NULL, "effrelease0", "Effectively Release 1" }, - { 1, 0.f, 1000, 0, PF_FLOAT | PF_UNIT_MSEC | PF_PROP_OUTPUT, NULL, "effrelease1", "Effectively Release 2" }, - { 1, 0.f, 1000, 0, PF_FLOAT | PF_UNIT_MSEC | PF_PROP_OUTPUT, NULL, "effrelease2", "Effectively Release 3" }, - { 1, 0.f, 1000, 0, PF_FLOAT | PF_UNIT_MSEC | PF_PROP_OUTPUT, NULL, "effrelease3", "Effectively Release 4" }, - - { 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "asc", "ASC" }, - - { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "asc_led", "asc active" }, - - { 0.5f, 0.f, 1.f, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "asc_coeff", "ASC Level" }, - - {} -}; - -CALF_PLUGIN_INFO(multibandlimiter) = { 0x8520, "Multibandlimiter", "Calf Multiband Limiter", "Markus Schmidt / Christian Holschuh", calf_plugins::calf_copyright_info, "LimiterPlugin" }; - -//////////////////////////////////////////////////////////////////////////// -// A few macros to make - -#define BYPASS_AND_LEVEL_PARAMS \ - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass", "Bypass" }, \ - { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_in", "Input Gain" }, \ - { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_out", "Output Gain" }, - -#define METERING_PARAMS \ - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_inL", "Meter-InL" }, \ - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_inR", "Meter-InR" }, \ - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_outL", "Meter-OutL" }, \ - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_outR", "Meter-OutR" }, \ - { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_inL", "0dB-InL" }, \ - { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_inR", "0dB-InR" }, \ - { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outL", "0dB-OutL" }, \ - { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outR", "0dB-OutR" }, - -#define LPHP_PARAMS \ - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "hp_active", "HP Active" }, \ - { 30, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "hp_freq", "HP Freq" }, \ - { 1, 0, 2, 0, PF_ENUM | PF_CTL_COMBO, rolloff_mode_names, "hp_mode", "HP Mode" }, \ - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "lp_active", "LP Active" }, \ - { 18000, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "lp_freq", "LP Freq" }, \ - { 1, 0, 2, 0, PF_ENUM | PF_CTL_COMBO, rolloff_mode_names, "lp_mode", "LP Mode" }, \ - -#define SHELF_PARAMS \ - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "ls_active", "LS Active" }, \ - { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "ls_level", "Level L" }, \ - { 200, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "ls_freq", "Freq L" }, \ - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "hs_active", "HS Active" }, \ - { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "hs_level", "Level H" }, \ - { 4000, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "hs_freq", "Freq H" }, - -#define EQ_BAND_PARAMS(band, frequency) \ - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "p" #band "_active", "F" #band " Active" }, \ - { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "p" #band "_level", "Level " #band }, \ - { frequency, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "p" #band "_freq", "Freq " #band }, \ - { 1, 0.1, 100, 1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "p" #band "_q", "Q " #band }, - -//////////////////////////////////////////////////////////////////////////// - -CALF_PORT_NAMES(equalizer5band) = {"In L", "In R", "Out L", "Out R"}; - -CALF_PORT_PROPS(equalizer5band) = { - BYPASS_AND_LEVEL_PARAMS - METERING_PARAMS - SHELF_PARAMS - EQ_BAND_PARAMS(1, 250) - EQ_BAND_PARAMS(2, 1000) - EQ_BAND_PARAMS(3, 2500) - {} -}; - -CALF_PLUGIN_INFO(equalizer5band) = { 0x8511, "Equalizer5Band", "Calf Equalizer 5 Band", "Markus Schmidt", calf_plugins::calf_copyright_info, "EqualizerPlugin" }; - -////////////////////////////////////////////////////////////////////////////// - - -CALF_PORT_NAMES(equalizer8band) = {"In L", "In R", "Out L", "Out R"}; -const char *rolloff_mode_names[] = {"12dB/oct", "24dB/oct", "36dB/oct"}; - -CALF_PORT_PROPS(equalizer8band) = { - BYPASS_AND_LEVEL_PARAMS - METERING_PARAMS - LPHP_PARAMS - SHELF_PARAMS - EQ_BAND_PARAMS(1, 250) - EQ_BAND_PARAMS(2, 1000) - EQ_BAND_PARAMS(3, 2500) - EQ_BAND_PARAMS(4, 5000) - {} -}; - -CALF_PLUGIN_INFO(equalizer8band) = { 0x8512, "Equalizer8Band", "Calf Equalizer 8 Band", "Markus Schmidt", calf_plugins::calf_copyright_info, "EqualizerPlugin" }; - -//////////////////////////////////////////////////////////////////////////// - -CALF_PORT_NAMES(equalizer12band) = {"In L", "In R", "Out L", "Out R"}; - -CALF_PORT_PROPS(equalizer12band) = { - BYPASS_AND_LEVEL_PARAMS - METERING_PARAMS - LPHP_PARAMS - SHELF_PARAMS - EQ_BAND_PARAMS(1, 60) - EQ_BAND_PARAMS(2, 120) - EQ_BAND_PARAMS(3, 250) - EQ_BAND_PARAMS(4, 500) - EQ_BAND_PARAMS(5, 1000) - EQ_BAND_PARAMS(6, 2500) - EQ_BAND_PARAMS(7, 4000) - EQ_BAND_PARAMS(8, 6000) - {} -}; - -CALF_PLUGIN_INFO(equalizer12band) = { 0x8513, "Equalizer12Band", "Calf Equalizer 12 Band", "Markus Schmidt", calf_plugins::calf_copyright_info, "EqualizerPlugin" }; - -//////////////////////////////////////////////////////////////////////////// - -CALF_PORT_NAMES(pulsator) = {"In L", "In R", "Out L", "Out R"}; - -const char *pulsator_mode_names[] = { "Sine", "Triangle", "Square", "Saw up", "Saw down" }; - -CALF_PORT_PROPS(pulsator) = { - BYPASS_AND_LEVEL_PARAMS - METERING_PARAMS - { 0, 0, 4, 0, PF_ENUM | PF_CTL_COMBO, pulsator_mode_names, "mode", "Mode" }, - { 1, 0.01, 100, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "freq", "Frequency" }, - { 1, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "amount", "Modulation" }, - { 0.5, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "offset", "Offset L/R" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "mono", "Mono-in" }, - { 0, 0, 1, 2, PF_BOOL | PF_CTL_BUTTON , NULL, "reset", "Reset" }, - {} -}; - -CALF_PLUGIN_INFO(pulsator) = { 0x8514, "Pulsator", "Calf Pulsator", "Markus Schmidt", calf_plugins::calf_copyright_info, "ModulationPlugin" }; - -//////////////////////////////////////////////////////////////////////////// - -CALF_PORT_NAMES(saturator) = {"In L", "In R", "Out L", "Out R"}; - -CALF_PORT_PROPS(saturator) = { - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass", "Bypass" }, - { 1, 1, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_in", "Activation" }, - { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_out", "Master" }, - { 1, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB , NULL, "mix", "Mix" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_in", "Input" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_out", "Output" }, - { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_in", "0dB" }, - { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_out", "0dB" }, - - { 5, 0.1, 10, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "drive", "Saturation" }, - { 10, -10, 10, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_FADER | PF_UNIT_COEF, NULL, "blend", "Blend" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_drive", "Drive" }, - - { 20000, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "lp_pre_freq", "Lowpass" }, - { 10, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "hp_pre_freq", "Highpass" }, - - { 20000, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "lp_post_freq", "Lowpass" }, - { 10, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "hp_post_freq", "Highpass" }, - - { 2000, 80, 8000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "p_freq", "Tone" }, - { 1, 0.0625, 16, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "p_level", "Amount" }, - { 1, 0.1, 10, 1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "p_q", "Gradient" }, - {} -}; - -CALF_PLUGIN_INFO(saturator) = { 0x8530, "Saturator", "Calf Saturator", "Markus Schmidt / Krzysztof Foltman", calf_plugins::calf_copyright_info, "DistortionPlugin" }; - -//////////////////////////////////////////////////////////////////////////// - -CALF_PORT_NAMES(exciter) = {"In L", "In R", "Out L", "Out R"}; - -CALF_PORT_PROPS(exciter) = { - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass", "Bypass" }, - { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_in", "Input" }, - { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_out", "Output" }, - { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB | PF_PROP_NOBOUNDS, NULL, "amount", "Amount" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_in", "Input" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_out", "Output" }, - { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_in", "0dB" }, - { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_out", "0dB" }, - - { 8.5, 0.1, 10, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "drive", "Harmonics" }, - { 0, -10, 10, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_FADER | PF_UNIT_COEF, NULL, "blend", "Blend harmonics" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_drive", "Harmonics level" }, - - { 6000, 2000, 12000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "freq", "Scope" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "listen", "Listen" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "ceil_active", "Ceiling active" }, - { 16000, 10000, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "ceil", "Ceiling" }, - {} -}; - -CALF_PLUGIN_INFO(exciter) = { 0x8531, "Exciter", "Calf Exciter", "Markus Schmidt / Krzysztof Foltman", calf_plugins::calf_copyright_info, "DistortionPlugin" }; - -//////////////////////////////////////////////////////////////////////////// - -CALF_PORT_NAMES(bassenhancer) = {"In L", "In R", "Out L", "Out R"}; - -CALF_PORT_PROPS(bassenhancer) = { - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass", "Bypass" }, - { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_in", "Input" }, - { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_out", "Output" }, - { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB | PF_PROP_NOBOUNDS, NULL, "amount", "Amount" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_in", "Input" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_out", "Output" }, - { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_in", "0dB" }, - { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_out", "0dB" }, - - { 8.5, 0.1, 10, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "drive", "Harmonics" }, - { 0, -10, 10, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_FADER | PF_UNIT_COEF, NULL, "blend", "Blend harmonics" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_drive", "Harmonics level" }, - - { 120, 10, 250, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "freq", "Scope" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "listen", "Listen" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "floor_active", "Floor active" }, - { 30, 10, 120, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "floor", "Floor" }, - {} -}; - -CALF_PLUGIN_INFO(bassenhancer) = { 0x8532, "BassEnhancer", "Calf Bass Enhancer", "Markus Schmidt / Krzysztof Foltman", calf_plugins::calf_copyright_info, "DistortionPlugin" }; - -//////////////////////////////////////////////////////////////////////////// - -CALF_PORT_NAMES(mono) = {"In", "Out L", "Out R"}; -CALF_PORT_PROPS(mono) = { - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass", "Bypass" }, - { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_in", "Input" }, - { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_out", "Output" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_in", "Input" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_outL", "Output L" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_outR", "Output R" }, - { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_in", "0dB-In" }, - { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outL", "0dB-OutL" }, - { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outR", "0dB-OutR" }, - - { 0.f, -1.f, 1.f, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "balance_out", "Balance" }, - - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "softclip", "Softclip" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "mutel", "Mute L" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "muter", "Mute R" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "phasel", "Phase L" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "phaser", "Phase R" }, - - { 0.f, -20.f, 20.f, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "delay", "Delay" }, - {} -}; - -CALF_PLUGIN_INFO(mono) = { 0x8589, "MonoInput", "Calf Mono Input", "Markus Schmidt", calf_plugins::calf_copyright_info, "Utility" }; - - -//////////////////////////////////////////////////////////////////////////// - -CALF_PORT_NAMES(stereo) = {"In L", "In R", "Out L", "Out R"}; -const char *stereo_mode_names[] = { "LR ▸ LR (Stereo Default)", "LR ▸ MS (Stereo to Mid-Side)", "MS ▸ LR (Mid-Side to Stereo)", "LR ▸ LL (Mono Left Channel)", "LR ▸ RR (Mono Right Channel)", "LR ▸ L+R (Mono Sum L+R)", "LR ▸ RL (Stereo Flip Channels)" }; -CALF_PORT_PROPS(stereo) = { - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass", "Bypass" }, - { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_in", "Input" }, - { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_out", "Output" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_inL", "Input L" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_inR", "Input R" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_outL", "Output L" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_outR", "Output R" }, - { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_inL", "0dB-InL" }, - { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_inR", "0dB-InR" }, - { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outL", "0dB-OutL" }, - { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outR", "0dB-OutR" }, - - { 0.f, -1.f, 1.f, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "balance_in", "Balance In" }, - { 0.f, -1.f, 1.f, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "balance_out", "Balance Out" }, - - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "softclip", "Softclip" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "mutel", "Mute L" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "muter", "Mute R" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "phasel", "Phase L" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "phaser", "Phase R" }, - - { 0, 0, 6, 0, PF_ENUM | PF_CTL_COMBO, stereo_mode_names, "mode", "Mode" }, - - { 0.f, -1.f, 1.f, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "slev", "S Level" }, - { 0.f, -1.f, 1.f, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "sbal", "S Balance" }, - { 0.f, -1.f, 1.f, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "mlev", "M Level" }, - { 0.f, -1.f, 1.f, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "mpan", "M Panorama" }, - - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "widener", "Widener" }, - { 0.f, -20.f, 20.f, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "delay", "Delay" }, - - { 0.f, 0.f, 1.f, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_COEF | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_phase", "Phase Correlation" }, - - {} -}; - -CALF_PLUGIN_INFO(stereo) = { 0x8588, "StereoTools", "Calf Stereo Tools", "Markus Schmidt", calf_plugins::calf_copyright_info, "Utility" }; - - -//////////////////////////////////////////////////////////////////////////// - -CALF_PORT_NAMES(monosynth) = { - "Out L", "Out R", -}; - -const char *monosynth_waveform_names[] = { "Sawtooth", "Square", "Pulse", "Sine", "Triangle", "Varistep", "Skewed Saw", "Skewed Square", - "Smooth Brass", "Bass", "Dark FM", "Multiwave", "Bell FM", "Dark Pad", "DCO Saw", "DCO Maze" }; -const char *monosynth_mode_names[] = { "0\xC2\xB0 : 0\xC2\xB0", "0\xC2\xB0 : 180\xC2\xB0", "0\xC2\xB0 : 90\xC2\xB0", "90\xC2\xB0 : 90\xC2\xB0", "90\xC2\xB0 : 270\xC2\xB0", "Random" }; -const char *monosynth_legato_names[] = { "Retrig", "Legato", "Fng Retrig", "Fng Legato" }; -const char *monosynth_lfotrig_names[] = { "Retrig", "Free" }; - -const char *monosynth_filter_choices[] = { - "12dB/oct Lowpass", - "24dB/oct Lowpass", - "2x12dB/oct Lowpass", - "12dB/oct Highpass", - "Lowpass+Notch", - "Highpass+Notch", - "6dB/oct Bandpass", - "2x6dB/oct Bandpass", -}; - -CALF_PLUGIN_INFO(monosynth) = { 0x8480, "Monosynth", "Calf Monosynth", "Krzysztof Foltman", calf_plugins::calf_copyright_info, "SynthesizerPlugin" }; - -CALF_PORT_PROPS(monosynth) = { - { monosynth_metadata::wave_saw, 0, monosynth_metadata::wave_count - 1, 1, PF_ENUM | PF_CTL_COMBO | PF_PROP_GRAPH, monosynth_waveform_names, "o1_wave", "Osc1 Wave" }, - { monosynth_metadata::wave_sqr, 0, monosynth_metadata::wave_count - 1, 1, PF_ENUM | PF_CTL_COMBO | PF_PROP_GRAPH, monosynth_waveform_names, "o2_wave", "Osc2 Wave" }, - - { 0, -1, 1, 0.1, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB, NULL, "o1_pw", "Osc1 PW" }, - { 0, -1, 1, 0.1, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB, NULL, "o2_pw", "Osc2 PW" }, - - { 10, 0, 100, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "o12_detune", "O1<>2 Detune" }, - { 12, -24, 24, 0, PF_INT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_SEMITONES, NULL, "o2_xpose", "Osc 2 transpose" }, - { 0, 0, 5, 0, PF_ENUM | PF_CTL_COMBO, monosynth_mode_names, "phase_mode", "Phase mode" }, - { 0.5, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "o12_mix", "O1<>2 Mix" }, - { 1, 0, 7, 0, PF_ENUM | PF_CTL_COMBO | PF_PROP_GRAPH, monosynth_filter_choices, "filter", "Filter" }, - { 33, 10,16000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "cutoff", "Cutoff" }, - { 3, 0.7, 8, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB, NULL, "res", "Resonance" }, - { 0, -2400, 2400, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "filter_sep", "Separation" }, - { 8000, -10800,10800, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "env2cutoff", "Env->Cutoff" }, - { 1, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB, NULL, "env2res", "Env->Res" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "env2amp", "Env->Amp" }, - - { 1, 1,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_FADER | PF_UNIT_MSEC, NULL, "adsr_a", "EG1 Attack" }, - { 350, 10,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_FADER | PF_UNIT_MSEC, NULL, "adsr_d", "EG1 Decay" }, - { 0.5, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "adsr_s", "EG1 Sustain" }, - { 0, -10000,10000, 21, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_FADER | PF_UNIT_MSEC, NULL, "adsr_f", "EG1 Fade" }, - { 100, 10,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_FADER | PF_UNIT_MSEC, NULL, "adsr_r", "EG1 Release" }, - - { 0, 0, 2, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "key_follow", "Key Follow" }, - { 0, 0, 3, 0, PF_ENUM | PF_CTL_COMBO, monosynth_legato_names, "legato", "Legato Mode" }, - { 1, 1, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "portamento", "Portamento" }, - - { 0.5, 0, 1, 0.1, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB, NULL, "vel2filter", "Vel->Filter" }, - { 0, 0, 1, 0.1, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB, NULL, "vel2amp", "Vel->Amp" }, - - { 0.5, 0, 1, 100, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_PROP_OUTPUT_GAIN, NULL, "master", "Volume" }, - - { 200, 0, 2400, 25, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "pbend_range", "PBend Range" }, - - { 5, 0.01, 20, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "lfo_rate", "LFO1 Rate" }, - { 0.5, 0, 5, 0, PF_FLOAT | PF_SCALE_QUAD | PF_CTL_KNOB | PF_UNIT_SEC, NULL, "lfo_delay", "LFO1 Delay" }, - { 0, -4800, 4800, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "lfo2filter", "LFO1->Filter" }, - { 100, 0, 1200, 0, PF_FLOAT | PF_SCALE_QUAD | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "lfo2pitch", "LFO1->Pitch" }, - { 0, 0, 1, 0.1, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB, NULL, "lfo2pw", "LFO1->PW" }, - { 1, 0, 1, 0.1, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB, NULL, "mwhl2lfo", "ModWheel->LFO1" }, - - { 1, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB, NULL, "scale_detune", "Scale Detune" }, - - { 0, -10800,10800, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "adsr2_cutoff", "EG2->Cutoff" }, - { 0.3, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB, NULL, "adsr2_res", "EG2->Res" }, - { 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "adsr2_amp", "EG2->Amp" }, - - { 1, 1,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_FADER | PF_UNIT_MSEC, NULL, "adsr2_a", "EG2 Attack" }, - { 100, 10,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_FADER | PF_UNIT_MSEC, NULL, "adsr2_d", "EG2 Decay" }, - { 0.5, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "adsr2_s", "EG2 Sustain" }, - { 0, -10000,10000, 21, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_FADER | PF_UNIT_MSEC, NULL, "adsr2_f", "EG2 Fade" }, - { 50, 10,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_FADER | PF_UNIT_MSEC, NULL, "adsr2_r", "Release" }, - - { 1, 1, 16, 0, PF_FLOAT | PF_SCALE_LOG | PF_UNIT_COEF | PF_CTL_KNOB, NULL, "o1_stretch", "Osc1 Stretch" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB, NULL, "o1_window", "Osc1 Window" }, - - { 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, monosynth_lfotrig_names, "lfo1_trig", "LFO1 Trigger Mode" }, - { 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, monosynth_lfotrig_names, "lfo2_trig", "LFO2 Trigger Mode" }, - { 5, 0.01, 20, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "lfo2_rate", "LFO1 Rate" }, - { 0.5, 0.1, 5, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_SEC, NULL, "lfo2_delay", "LFO1 Delay" }, - {} -}; - -static const char *monosynth_mod_src_names[] = { - "None", - "Velocity", - "Pressure", - "ModWheel", - "Envelope 1", - "Envelope 2", - "LFO 1", - "LFO 2", - NULL -}; - -static const char *monosynth_mod_dest_names[] = { - "None", - "Attenuation", - "Osc Mix Ratio (%)", - "Cutoff [ct]", - "Resonance", - "O1: Detune [ct]", - "O2: Detune [ct]", - "O1: PW (%)", - "O2: PW (%)", - "O1: Stretch", - NULL -}; - -monosynth_metadata::monosynth_metadata() -: mm_metadata(mod_matrix_slots, monosynth_mod_src_names, monosynth_mod_dest_names) -{ -} - -const char *const *monosynth_metadata::get_configure_vars() const -{ - return mod_matrix_impl::get_configure_vars(); -} - -//////////////////////////////////////////////////////////////////////////// - -CALF_PLUGIN_INFO(organ) = { 0x8481, "Organ", "Calf Organ", "Krzysztof Foltman", calf_plugins::calf_copyright_info, "SynthesizerPlugin" }; - -plugin_command_info *organ_metadata::get_commands() -{ - static plugin_command_info cmds[] = { - { "cmd_panic", "Panic!", "Stop all sounds and reset all controllers" }, - { NULL } - }; - return cmds; -} - -CALF_PORT_NAMES(organ) = {"Out L", "Out R"}; - -const char *organ_percussion_trigger_names[] = { "First note", "Each note", "Each, no retrig", "Polyphonic" }; - -const char *organ_wave_names[] = { - "Sin", - "S0", "S00", "S000", - "SSaw", "SSqr", "SPls", - "Saw", "Sqr", "Pls", - "S(", "Sq(", "S+", "Clvg", - "Bell", "Bell2", - "W1", "W2", "W3", "W4", "W5", "W6", "W7", "W8", "W9", - "DSaw", "DSqr", "DPls", - "P:SynStr","P:WideStr","P:Sine","P:Bell","P:Space","P:Voice","P:Hiss","P:Chant", -}; - -const char *organ_routing_names[] = { "Out", "Flt 1", "Flt 2" }; - -const char *organ_ampctl_names[] = { "None", "Direct", "Flt 1", "Flt 2", "All" }; - -const char *organ_vibrato_mode_names[] = { "None", "Direct", "Flt 1", "Flt 2", "Voice", "Global" }; - -const char *organ_vibrato_type_names[] = { "Allpass", "Scanner (V1/C1)", "Scanner (V2/C2)", "Scanner (V3/C3)", "Scanner (Full)" }; - -const char *organ_filter_type_names[] = { "12dB/oct LP", "12dB/oct HP" }; - -const char *organ_filter_send_names[] = { "Output", "Filter 2" }; - -const char *organ_init_map_curve = "2\n0 1\n1 1\n"; - -CALF_PORT_PROPS(organ) = { - { 8, 0, 8, 80, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_FADER, NULL, "l1", "16'" }, - { 8, 0, 8, 80, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_FADER, NULL, "l2", "5 1/3'" }, - { 8, 0, 8, 80, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_FADER, NULL, "l3", "8'" }, - { 0, 0, 8, 80, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_FADER, NULL, "l4", "4'" }, - { 0, 0, 8, 80, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_FADER, NULL, "l5", "2 2/3'" }, - { 0, 0, 8, 80, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_FADER, NULL, "l6", "2'" }, - { 0, 0, 8, 80, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_FADER, NULL, "l7", "1 3/5'" }, - { 0, 0, 8, 80, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_FADER, NULL, "l8", "1 1/3'" }, - { 8, 0, 8, 80, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_FADER, NULL, "l9", "1'" }, - - { 1, 1, 32, 32, PF_INT | PF_SCALE_LINEAR | PF_CTL_KNOB, NULL, "f1", "Freq 1" }, - { 3, 1, 32, 32, PF_INT | PF_SCALE_LINEAR | PF_CTL_KNOB, NULL, "f2", "Freq 2" }, - { 2, 1, 32, 32, PF_INT | PF_SCALE_LINEAR | PF_CTL_KNOB, NULL, "f3", "Freq 3" }, - { 4, 1, 32, 32, PF_INT | PF_SCALE_LINEAR | PF_CTL_KNOB, NULL, "f4", "Freq 4" }, - { 6, 1, 32, 32, PF_INT | PF_SCALE_LINEAR | PF_CTL_KNOB, NULL, "f5", "Freq 5" }, - { 8, 1, 32, 32, PF_INT | PF_SCALE_LINEAR | PF_CTL_KNOB, NULL, "f6", "Freq 6" }, - { 10, 1, 32, 32, PF_INT | PF_SCALE_LINEAR | PF_CTL_KNOB, NULL, "f7", "Freq 7" }, - { 12, 1, 32, 32, PF_INT | PF_SCALE_LINEAR | PF_CTL_KNOB, NULL, "f8", "Freq 8" }, - { 16, 1, 32, 32, PF_INT | PF_SCALE_LINEAR | PF_CTL_KNOB, NULL, "f9", "Freq 9" }, - - { 0, 0, organ_enums::wave_count - 1, 0, PF_ENUM | PF_SCALE_LINEAR | PF_CTL_COMBO, organ_wave_names, "w1", "Wave 1" }, - { 0, 0, organ_enums::wave_count - 1, 0, PF_ENUM | PF_SCALE_LINEAR | PF_CTL_COMBO, organ_wave_names, "w2", "Wave 2" }, - { 0, 0, organ_enums::wave_count - 1, 0, PF_ENUM | PF_SCALE_LINEAR | PF_CTL_COMBO, organ_wave_names, "w3", "Wave 3" }, - { 0, 0, organ_enums::wave_count - 1, 0, PF_ENUM | PF_SCALE_LINEAR | PF_CTL_COMBO, organ_wave_names, "w4", "Wave 4" }, - { 0, 0, organ_enums::wave_count - 1, 0, PF_ENUM | PF_SCALE_LINEAR | PF_CTL_COMBO, organ_wave_names, "w5", "Wave 5" }, - { 0, 0, organ_enums::wave_count - 1, 0, PF_ENUM | PF_SCALE_LINEAR | PF_CTL_COMBO, organ_wave_names, "w6", "Wave 6" }, - { 0, 0, organ_enums::wave_count - 1, 0, PF_ENUM | PF_SCALE_LINEAR | PF_CTL_COMBO, organ_wave_names, "w7", "Wave 7" }, - { 0, 0, organ_enums::wave_count - 1, 0, PF_ENUM | PF_SCALE_LINEAR | PF_CTL_COMBO, organ_wave_names, "w8", "Wave 8" }, - { 0, 0, organ_enums::wave_count - 1, 0, PF_ENUM | PF_SCALE_LINEAR | PF_CTL_COMBO, organ_wave_names, "w9", "Wave 9" }, - - { 0, -100,100, 401, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "detune1", "Detune 1" }, - { 0, -100,100, 401, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "detune2", "Detune 2" }, - { 0, -100,100, 401, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "detune3", "Detune 3" }, - { 0, -100,100, 401, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "detune4", "Detune 4" }, - { 0, -100,100, 401, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "detune5", "Detune 5" }, - { 0, -100,100, 401, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "detune6", "Detune 6" }, - { 0, -100,100, 401, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "detune7", "Detune 7" }, - { 0, -100,100, 401, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "detune8", "Detune 8" }, - { 0, -100,100, 401, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "detune9", "Detune 9" }, - - { 0, 0,360, 361, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_DEG, NULL, "phase1", "Phase 1" }, - { 0, 0,360, 361, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_DEG, NULL, "phase2", "Phase 2" }, - { 0, 0,360, 361, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_DEG, NULL, "phase3", "Phase 3" }, - { 0, 0,360, 361, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_DEG, NULL, "phase4", "Phase 4" }, - { 0, 0,360, 361, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_DEG, NULL, "phase5", "Phase 5" }, - { 0, 0,360, 361, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_DEG, NULL, "phase6", "Phase 6" }, - { 0, 0,360, 361, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_DEG, NULL, "phase7", "Phase 7" }, - { 0, 0,360, 361, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_DEG, NULL, "phase8", "Phase 8" }, - { 0, 0,360, 361, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_DEG, NULL, "phase9", "Phase 9" }, - - { 0, -1, 1, 201, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB, NULL, "pan1", "Pan 1" }, - { 0, -1, 1, 201, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB, NULL, "pan2", "Pan 2" }, - { 0, -1, 1, 201, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB, NULL, "pan3", "Pan 3" }, - { 0, -1, 1, 201, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB, NULL, "pan4", "Pan 4" }, - { 0, -1, 1, 201, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB, NULL, "pan5", "Pan 5" }, - { 0, -1, 1, 201, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB, NULL, "pan6", "Pan 6" }, - { 0, -1, 1, 201, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB, NULL, "pan7", "Pan 7" }, - { 0, -1, 1, 201, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB, NULL, "pan8", "Pan 8" }, - { 0, -1, 1, 201, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB, NULL, "pan9", "Pan 9" }, - - { 0, 0, 2, 0, PF_ENUM | PF_SCALE_LINEAR | PF_CTL_COMBO, organ_routing_names, "routing1", "Routing 1" }, - { 0, 0, 2, 0, PF_ENUM | PF_SCALE_LINEAR | PF_CTL_COMBO, organ_routing_names, "routing2", "Routing 2" }, - { 0, 0, 2, 0, PF_ENUM | PF_SCALE_LINEAR | PF_CTL_COMBO, organ_routing_names, "routing3", "Routing 3" }, - { 0, 0, 2, 0, PF_ENUM | PF_SCALE_LINEAR | PF_CTL_COMBO, organ_routing_names, "routing4", "Routing 4" }, - { 0, 0, 2, 0, PF_ENUM | PF_SCALE_LINEAR | PF_CTL_COMBO, organ_routing_names, "routing5", "Routing 5" }, - { 0, 0, 2, 0, PF_ENUM | PF_SCALE_LINEAR | PF_CTL_COMBO, organ_routing_names, "routing6", "Routing 6" }, - { 0, 0, 2, 0, PF_ENUM | PF_SCALE_LINEAR | PF_CTL_COMBO, organ_routing_names, "routing7", "Routing 7" }, - { 0, 0, 2, 0, PF_ENUM | PF_SCALE_LINEAR | PF_CTL_COMBO, organ_routing_names, "routing8", "Routing 8" }, - { 0, 0, 2, 0, PF_ENUM | PF_SCALE_LINEAR | PF_CTL_COMBO, organ_routing_names, "routing9", "Routing 9" }, - - { 96 + 12, 0, 127, 128, PF_INT | PF_CTL_KNOB | PF_UNIT_NOTE, NULL, "foldnote", "Foldover" }, - - { 200, 10, 3000, 100, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "perc_decay", "P: Carrier Decay" }, - { 0.25, 0, 1, 100, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB, NULL, "perc_level", "P: Level" }, - { 0, 0, organ_enums::wave_count_small - 1, 1, PF_ENUM | PF_CTL_COMBO, organ_wave_names, "perc_waveform", "P: Carrier Wave" }, - { 6, 1, 32, 32, PF_INT | PF_SCALE_LINEAR | PF_CTL_KNOB, NULL, "perc_harmonic", "P: Carrier Frq" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "perc_vel2amp", "P: Vel->Amp" }, - - { 200, 10, 3000, 100, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "perc_fm_decay", "P: Modulator Decay" }, - { 0, 0, 4, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "perc_fm_depth", "P: FM Depth" }, - { 0, 0, organ_enums::wave_count_small - 1, 1, PF_ENUM | PF_CTL_COMBO, organ_wave_names, "perc_fm_waveform", "P: Modulator Wave" }, - { 6, 1, 32, 32, PF_INT | PF_SCALE_LINEAR | PF_CTL_KNOB, NULL, "perc_fm_harmonic", "P: Modulator Frq" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "perc_vel2fm", "P: Vel->FM" }, - - { 0, 0, organ_enums::perctrig_count - 1, 0, PF_ENUM | PF_CTL_COMBO, organ_percussion_trigger_names, "perc_trigger", "P: Trigger" }, - { 90, 0,360, 361, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_DEG, NULL, "perc_stereo", "P: Stereo Phase" }, - - { 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, organ_filter_send_names, "filter_chain", "Filter 1 To" }, - { 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, organ_filter_type_names, "filter1_type", "Filter 1 Type" }, - { 0.1, 0, 1, 100, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_PROP_OUTPUT_GAIN | PF_PROP_GRAPH, NULL, "master", "Volume" }, - - { 2000, 20, 20000, 100, PF_FLOAT | PF_SCALE_LOG | PF_UNIT_HZ | PF_CTL_KNOB, NULL, "f1_cutoff", "F1 Cutoff" }, - { 2, 0.7, 8, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB, NULL, "f1_res", "F1 Res" }, - { 8000, -10800,10800, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "f1_env1", "F1 Env1" }, - { 0, -10800,10800, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "f1_env2", "F1 Env2" }, - { 0, -10800,10800, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "f1_env3", "F1 Env3" }, - { 0, 0, 2, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "f1_keyf", "F1 KeyFollow" }, - - { 2000, 20, 20000, 100, PF_FLOAT | PF_SCALE_LOG | PF_UNIT_HZ | PF_CTL_KNOB, NULL, "f2_cutoff", "F2 Cutoff" }, - { 2, 0.7, 8, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB, NULL, "f2_res", "F2 Res" }, - { 0, -10800,10800, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "f2_env1", "F2 Env1" }, - { 8000, -10800,10800, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "f2_env2", "F2 Env2" }, - { 0, -10800,10800, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "f2_env3", "F2 Env3" }, - { 0, 0, 2, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "f2_keyf", "F2 KeyFollow" }, - - { 1, 1,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr_a", "EG1 Attack" }, - { 350, 10,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr_d", "EG1 Decay" }, - { 0.5, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "adsr_s", "EG1 Sustain" }, - { 50, 10,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr_r", "EG1 Release" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "adsr_v", "EG1 VelMod" }, - { 0, 0, organ_enums::ampctl_count - 1, - 0, PF_INT | PF_CTL_COMBO, organ_ampctl_names, "eg1_amp_ctl", "EG1 To Amp"}, - - { 1, 1,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr2_a", "EG2 Attack" }, - { 350, 10,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr2_d", "EG2 Decay" }, - { 0.5, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "adsr2_s", "EG2 Sustain" }, - { 50, 10,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr2_r", "EG2 Release" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "adsr2_v", "EG2 VelMod" }, - { 0, 0, organ_enums::ampctl_count - 1, - 0, PF_INT | PF_CTL_COMBO, organ_ampctl_names, "eg2_amp_ctl", "EG2 To Amp"}, - - { 1, 1,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr3_a", "EG3 Attack" }, - { 350, 10,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr3_d", "EG3 Decay" }, - { 0.5, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "adsr3_s", "EG3 Sustain" }, - { 50, 10,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr3_r", "EG3 Release" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "adsr3_v", "EG3 VelMod" }, - { 0, 0, organ_enums::ampctl_count - 1, - 0, PF_INT | PF_CTL_COMBO, organ_ampctl_names, "eg3_amp_ctl", "EG3 To Amp"}, - - { 6.6, 0.01, 240, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "vib_rate", "Vib Rate" }, - { 1.0, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB , NULL, "vib_amt", "Vib Mod Amt" }, - { 0.5, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB , NULL, "vib_wet", "Vib Wet" }, - { 180, 0, 360, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_DEG, NULL, "vib_phase", "Vib Stereo" }, - { organ_enums::lfomode_global, 0, organ_enums::lfomode_count - 1, 0, PF_ENUM | PF_CTL_COMBO, organ_vibrato_mode_names, "vib_mode", "Vib Mode" }, - { organ_enums::lfotype_cv3, 0, organ_enums::lfotype_count - 1, 0, PF_ENUM | PF_CTL_COMBO, organ_vibrato_type_names, "vib_type", "Vib Type" }, -// { 0, 0, organ_enums::ampctl_count - 1, -// 0, PF_INT | PF_CTL_COMBO, organ_ampctl_names, "vel_amp_ctl", "Vel To Amp"}, - - { -12, -24, 24, 49, PF_INT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_SEMITONES, NULL, "transpose", "Transpose" }, - { 0, -100, 100, 201, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "detune", "Detune" }, - - { 16, 1, 32, 32, PF_INT | PF_SCALE_LINEAR | PF_CTL_KNOB, NULL, "polyphony", "Polyphony" }, - - { 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "quad_env", "Quadratic AmpEnv" }, - - { 200, 0, 2400, 25, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "pbend_range", "PBend Range" }, - - { 80, 20, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "bass_freq", "Bass Freq" }, - { 1, 0.1, 10, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "bass_gain", "Bass Gain" }, - { 12000, 20, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "treble_freq", "Treble Freq" }, - { 1, 0.1, 10, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "treble_gain", "Treble Gain" }, -}; - -const char *const *organ_metadata::get_configure_vars() const -{ - static const char *names[] = {"map_curve", NULL}; - return names; -} - -//////////////////////////////////////////////////////////////////////////// - -const char *fluidsynth_init_soundfont = ""; -const char *fluidsynth_init_presetkeyset = ""; - -const char *fluidsynth_interpolation_names[] = { "None (zero-hold)", "Linear", "Cubic", "7-point" }; - -CALF_PORT_NAMES(fluidsynth) = { - "Out L", "Out R", -}; - -CALF_PLUGIN_INFO(fluidsynth) = { 0x8700, "Fluidsynth", "Calf Fluidsynth", "FluidSynth Team / Krzysztof Foltman", calf_plugins::calf_copyright_info, "SynthesizerPlugin" }; - -CALF_PORT_PROPS(fluidsynth) = { - { 0.5, 0, 1, 100, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_PROP_OUTPUT_GAIN, NULL, "master", "Volume" }, - { 2, 0, 3, 0, PF_ENUM | PF_CTL_COMBO, fluidsynth_interpolation_names, "interpolation", "Interpolation" }, - { 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "reverb", "Reverb" }, - { 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "chorus", "Chorus" }, -}; - -const char *const *fluidsynth_metadata::get_configure_vars() const -{ - static const char *names[] = {"soundfont", "preset_key_set", NULL}; - return names; -} - -//////////////////////////////////////////////////////////////////////////// - -const char *wavetable_names[] = { - "Shiny1", - "Shiny2", - "Rezo", - "Metal", - "Bell", - "Blah", - "Pluck", - "Stretch", - "Stretch 2", - "Hard Sync", - "Hard Sync 2", - "Soft Sync", - "Bell 2", - "Bell 3", - "Tine", - "Tine 2", - "Clav", - "Clav 2", - "Gtr", - "Gtr 2", - "Gtr 3", - "Gtr 4", - "Gtr 5", - "Reed", - "Reed 2", - "Silver", - "Brass", - "Multi", - "Multi 2", -}; - -static const char *wavetable_mod_src_names[] = { - "None", - "Velocity", - "Pressure", - "ModWheel", - "Env 1", - "Env 2", - "Env 3", - NULL -}; - -static const char *wavetable_mod_dest_names[] = { - "None", - "Attenuation", - "Osc Mix Ratio (%)", - "Cutoff [ct]", - "Resonance", - "O1: Shift (%)", - "O2: Shift (%)", - "O1: Detune [ct]", - "O2: Detune [ct]", - NULL -}; - -CALF_PORT_NAMES(wavetable) = { - "Out L", "Out R", -}; - -CALF_PLUGIN_INFO(wavetable) = { 0x8701, "Wavetable", "Calf Wavetable", "Krzysztof Foltman", calf_plugins::calf_copyright_info, "SynthesizerPlugin" }; - -CALF_PORT_PROPS(wavetable) = { - { wavetable_metadata::wt_count - 1, 0, wavetable_metadata::wt_count - 1, 0, PF_ENUM | PF_SCALE_LINEAR | PF_CTL_COMBO, wavetable_names, "o1wave", "Osc1 Wave" }, - { 0.2, -1, 1, 0, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "o1offset", "Osc1 Ctl"}, - { 0, -48, 48, 48*2+1, PF_INT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_SEMITONES, NULL, "o1trans", "Osc1 Transpose" }, - { 6, -100, 100, 0, PF_INT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "o1detune", "Osc1 Detune" }, - { 0.1, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "o1level", "Osc1 Level" }, - - { 0, 0, wavetable_metadata::wt_count - 1, 0, PF_ENUM | PF_SCALE_LINEAR | PF_CTL_COMBO, wavetable_names, "o2wave", "Osc2 Wave" }, - { 0.4, -1, 1, 0, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "o2offset", "Osc2 Ctl"}, - { 0, -48, 48, 48*2+1, PF_INT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_SEMITONES, NULL, "o2trans", "Osc2 Transpose" }, - { -6, -100, 100, 0, PF_INT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "o2detune", "Osc2 Detune" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "o2level", "Osc2 Level" }, - - { 1, 1,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr_a", "EG1 Attack" }, - { 350, 10,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr_d", "EG1 Decay" }, - { 0.5, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "adsr_s", "EG1 Sustain" }, - { 0, -10000,10000, 21, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr_f", "EG1 Fade" }, - { 50, 10,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr_r", "EG1 Release" }, - { 1, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "adsr_v", "EG1 VelMod" }, - - { 1, 1,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr2_a", "EG2 Attack" }, - { 350, 10,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr2_d", "EG2 Decay" }, - { 0.5, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "adsr2_s", "EG2 Sustain" }, - { 0, -10000,10000, 21, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr2_f", "EG2 Fade" }, - { 50, 10,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr2_r", "EG2 Release" }, - { 1, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "adsr2_v", "EG2 VelMod" }, - - { 1, 1,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr3_a", "EG3 Attack" }, - { 350, 10,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr3_d", "EG3 Decay" }, - { 0.5, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "adsr3_s", "EG3 Sustain" }, - { 0, -10000,10000, 21, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr3_f", "EG3 Fade" }, - { 50, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr3_r", "EG3 Release" }, - { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "adsr3_v", "EG3 VelMod" }, - - { 200, 0, 2400, 25, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "pbend_range", "PBend Range" }, - {} -}; - -wavetable_metadata::wavetable_metadata() -: mm_metadata(mod_matrix_slots, wavetable_mod_src_names, wavetable_mod_dest_names) -{ -} - -//////////////////////////////////////////////////////////////////////////// - -calf_plugins::plugin_registry::plugin_registry() -{ - #define PER_MODULE_ITEM(name, isSynth, jackname) plugins.push_back((new name##_metadata)); - #include -} diff --git a/plugins/LadspaEffect/calf/src/modmatrix.cpp b/plugins/LadspaEffect/calf/src/modmatrix.cpp deleted file mode 100644 index 0a320c220e2..00000000000 --- a/plugins/LadspaEffect/calf/src/modmatrix.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* Calf DSP Library - * Modulation matrix boilerplate code. - * - * Copyright (C) 2001-2007 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 02110-1301 USA - */ -#include -#include -#include -#include - -using namespace std; -using namespace dsp; -using namespace calf_plugins; -using namespace calf_utils; - -mod_matrix_impl::mod_matrix_impl(dsp::modulation_entry *_matrix, mod_matrix_metadata *_metadata) -: matrix(_matrix) -, metadata(_metadata) -{ - matrix_rows = metadata->get_table_rows(); - for (unsigned int i = 0; i < matrix_rows; i++) - matrix[i].reset(); -} - -const float mod_matrix_impl::scaling_coeffs[mod_matrix_metadata::map_type_count][3] = { - { 0, 1, 0 }, - { -1, 2, 0 }, - { -1, 1, 0 }, - { 0, 0, 1 }, - { -1, 0, 1 }, - { 0, 2, -1 }, - { -1, 4, -2 }, - { 0, 4, -4 }, -}; - -std::string mod_matrix_impl::get_cell(int row, int column) const -{ - assert(row >= 0 && row < (int)matrix_rows); - modulation_entry &slot = matrix[row]; - const char **arr = metadata->get_table_columns()[column].values; - switch(column) { - case 0: // source 1 - return arr[slot.src1]; - case 1: // mapping mode - return arr[slot.mapping]; - case 2: // source 2 - return arr[slot.src2]; - case 3: // amount - return calf_utils::f2s(slot.amount); - case 4: // destination - return arr[slot.dest]; - default: - assert(0); - return ""; - } -} - -void mod_matrix_impl::set_cell(int row, int column, const std::string &src, std::string &error) -{ - assert(row >= 0 && row < (int)matrix_rows); - modulation_entry &slot = matrix[row]; - const char **arr = metadata->get_table_columns()[column].values; - switch(column) { - case 0: - case 1: - case 2: - case 4: - { - for (int i = 0; arr[i]; i++) - { - if (src == arr[i]) - { - if (column == 0) - slot.src1 = i; - else if (column == 1) - slot.mapping = (mod_matrix_metadata::mapping_mode)i; - else if (column == 2) - slot.src2 = i; - else if (column == 4) - slot.dest = i; - error.clear(); - return; - } - } - error = "Invalid name: " + src; - return; - } - case 3: - { - stringstream ss(src); - ss >> slot.amount; - error.clear(); - return; - } - } -} - -void mod_matrix_impl::send_configures(send_configure_iface *sci) -{ - for (int i = 0; i < (int)matrix_rows; i++) - { - for (int j = 0; j < 5; j++) - { - string key = "mod_matrix:" + i2s(i) + "," + i2s(j); - sci->send_configure(key.c_str(), get_cell(i, j).c_str()); - } - } -} - -char *mod_matrix_impl::configure(const char *key, const char *value) -{ - bool is_rows; - int row, column; - if (!parse_table_key(key, "mod_matrix:", is_rows, row, column)) - return NULL; - if (is_rows) - return strdup("Unexpected key"); - - if (row != -1 && column != -1) - { - string error; - string value_text; - if (value == NULL) - { - const table_column_info &ci = metadata->get_table_columns()[column]; - if (ci.type == TCT_ENUM) - value_text = ci.values[(int)ci.def_value]; - else - if (ci.type == TCT_FLOAT) - value_text = f2s(ci.def_value); - value = value_text.c_str(); - } - set_cell(row, column, value, error); - if (!error.empty()) - return strdup(error.c_str()); - } - return NULL; -} diff --git a/plugins/LadspaEffect/calf/src/modules.cpp b/plugins/LadspaEffect/calf/src/modules.cpp deleted file mode 100644 index 98b4b8df33c..00000000000 --- a/plugins/LadspaEffect/calf/src/modules.cpp +++ /dev/null @@ -1,813 +0,0 @@ -/* Calf DSP plugin pack - * Assorted plugins - * - * Copyright (C) 2001-2010 Krzysztof Foltman, Markus Schmidt, Thor Harald Johansen - * - * 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 02110-1301 USA - */ -#include -#include -#include -#include -#include - -using namespace dsp; -using namespace calf_plugins; - -#define SET_IF_CONNECTED(name) if (params[AM::param_##name] != NULL) *params[AM::param_##name] = name; - -/////////////////////////////////////////////////////////////////////////////////////////////// - -void reverb_audio_module::activate() -{ - reverb.reset(); -} - -void reverb_audio_module::deactivate() -{ -} - -void reverb_audio_module::set_sample_rate(uint32_t sr) -{ - srate = sr; - reverb.setup(sr); - amount.set_sample_rate(sr); -} - -void reverb_audio_module::params_changed() -{ - reverb.set_type_and_diffusion(fastf2i_drm(*params[par_roomsize]), *params[par_diffusion]); - reverb.set_time(*params[par_decay]); - reverb.set_cutoff(*params[par_hfdamp]); - amount.set_inertia(*params[par_amount]); - dryamount.set_inertia(*params[par_dry]); - left_lo.set_lp(dsp::clip(*params[par_treblecut], 20.f, (float)(srate * 0.49f)), srate); - left_hi.set_hp(dsp::clip(*params[par_basscut], 20.f, (float)(srate * 0.49f)), srate); - right_lo.copy_coeffs(left_lo); - right_hi.copy_coeffs(left_hi); - predelay_amt = (int) (srate * (*params[par_predelay]) * (1.0f / 1000.0f) + 1); -} - -uint32_t reverb_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) -{ - numsamples += offset; - clip -= std::min(clip, numsamples); - for (uint32_t i = offset; i < numsamples; i++) { - float dry = dryamount.get(); - float wet = amount.get(); - stereo_sample s(ins[0][i], ins[1][i]); - stereo_sample s2 = pre_delay.process(s, predelay_amt); - - float rl = s2.left, rr = s2.right; - rl = left_lo.process(left_hi.process(rl)); - rr = right_lo.process(right_hi.process(rr)); - reverb.process(rl, rr); - outs[0][i] = dry*s.left + wet*rl; - outs[1][i] = dry*s.right + wet*rr; - meter_wet = std::max(fabs(wet*rl), fabs(wet*rr)); - meter_out = std::max(fabs(outs[0][i]), fabs(outs[1][i])); - if(outs[0][i] > 1.f or outs[1][i] > 1.f) { - clip = srate >> 3; - } - } - reverb.extra_sanitize(); - left_lo.sanitize(); - left_hi.sanitize(); - right_lo.sanitize(); - right_hi.sanitize(); - if(params[par_meter_wet] != NULL) { - *params[par_meter_wet] = meter_wet; - } - if(params[par_meter_out] != NULL) { - *params[par_meter_out] = meter_out; - } - if(params[par_clip] != NULL) { - *params[par_clip] = clip; - } - return outputs_mask; -} - -/////////////////////////////////////////////////////////////////////////////////////////////// - -vintage_delay_audio_module::vintage_delay_audio_module() -{ - old_medium = -1; - for (int i = 0; i < MAX_DELAY; i++) { - buffers[0][i] = 0.f; - buffers[1][i] = 0.f; - } -} - -void vintage_delay_audio_module::params_changed() -{ - float unit = 60.0 * srate / (*params[par_bpm] * *params[par_divide]); - deltime_l = dsp::fastf2i_drm(unit * *params[par_time_l]); - deltime_r = dsp::fastf2i_drm(unit * *params[par_time_r]); - int deltime_fb = deltime_l + deltime_r; - float fb = *params[par_feedback]; - dry.set_inertia(*params[par_dryamount]); - mixmode = dsp::fastf2i_drm(*params[par_mixmode]); - medium = dsp::fastf2i_drm(*params[par_medium]); - switch(mixmode) - { - case MIXMODE_STEREO: - fb_left.set_inertia(fb); - fb_right.set_inertia(pow(fb, *params[par_time_r] / *params[par_time_l])); - amt_left.set_inertia(*params[par_amount]); - amt_right.set_inertia(*params[par_amount]); - break; - case MIXMODE_PINGPONG: - fb_left.set_inertia(fb); - fb_right.set_inertia(fb); - amt_left.set_inertia(*params[par_amount]); - amt_right.set_inertia(*params[par_amount]); - break; - case MIXMODE_LR: - fb_left.set_inertia(fb); - fb_right.set_inertia(fb); - amt_left.set_inertia(*params[par_amount]); // L is straight 'amount' - amt_right.set_inertia(*params[par_amount] * pow(fb, 1.0 * deltime_r / deltime_fb)); // R is amount with feedback based dampening as if it ran through R/FB*100% of delay line's dampening - // deltime_l <<< deltime_r -> pow() = fb -> full delay line worth of dampening - // deltime_l >>> deltime_r -> pow() = 1 -> no dampening - break; - case MIXMODE_RL: - fb_left.set_inertia(fb); - fb_right.set_inertia(fb); - amt_left.set_inertia(*params[par_amount] * pow(fb, 1.0 * deltime_l / deltime_fb)); - amt_right.set_inertia(*params[par_amount]); - break; - } - chmix.set_inertia((1 - *params[par_width]) * 0.5); - if (medium != old_medium) - calc_filters(); -} - -void vintage_delay_audio_module::activate() -{ - bufptr = 0; - age = 0; -} - -void vintage_delay_audio_module::deactivate() -{ -} - -void vintage_delay_audio_module::set_sample_rate(uint32_t sr) -{ - srate = sr; - old_medium = -1; - amt_left.set_sample_rate(sr); amt_right.set_sample_rate(sr); - fb_left.set_sample_rate(sr); fb_right.set_sample_rate(sr); -} - -void vintage_delay_audio_module::calc_filters() -{ - // parameters are heavily influenced by gordonjcp and his tape delay unit - // although, don't blame him if it sounds bad - I've messed with them too :) - biquad_left[0].set_lp_rbj(6000, 0.707, srate); - biquad_left[1].set_bp_rbj(4500, 0.250, srate); - biquad_right[0].copy_coeffs(biquad_left[0]); - biquad_right[1].copy_coeffs(biquad_left[1]); -} - -/// Single delay line with feedback at the same tap -static inline void delayline_impl(int age, int deltime, float dry_value, const float &delayed_value, float &out, float &del, gain_smoothing &amt, gain_smoothing &fb) -{ - // if the buffer hasn't been cleared yet (after activation), pretend we've read zeros - if (age <= deltime) { - out = 0; - del = dry_value; - amt.step(); - fb.step(); - } - else - { - float delayed = delayed_value; // avoid dereferencing the pointer in 'then' branch of the if() - dsp::sanitize(delayed); - out = delayed * amt.get(); - del = dry_value + delayed * fb.get(); - } -} - -/// Single delay line with tap output -static inline void delayline2_impl(int age, int deltime, float dry_value, const float &delayed_value, const float &delayed_value_for_fb, float &out, float &del, gain_smoothing &amt, gain_smoothing &fb) -{ - if (age <= deltime) { - out = 0; - del = dry_value; - amt.step(); - fb.step(); - } - else - { - out = delayed_value * amt.get(); - del = dry_value + delayed_value_for_fb * fb.get(); - dsp::sanitize(out); - dsp::sanitize(del); - } -} - -static inline void delay_mix(float dry_left, float dry_right, float &out_left, float &out_right, float dry, float chmix) -{ - float tmp_left = lerp(out_left, out_right, chmix); - float tmp_right = lerp(out_right, out_left, chmix); - out_left = dry_left * dry + tmp_left; - out_right = dry_right * dry + tmp_right; -} - -uint32_t vintage_delay_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) -{ - uint32_t ostate = 3; // XXXKF optimize! - uint32_t end = offset + numsamples; - int orig_bufptr = bufptr; - float out_left, out_right, del_left, del_right; - - switch(mixmode) - { - case MIXMODE_STEREO: - case MIXMODE_PINGPONG: - { - int v = mixmode == MIXMODE_PINGPONG ? 1 : 0; - for(uint32_t i = offset; i < end; i++) - { - delayline_impl(age, deltime_l, ins[0][i], buffers[v][(bufptr - deltime_l) & ADDR_MASK], out_left, del_left, amt_left, fb_left); - delayline_impl(age, deltime_r, ins[1][i], buffers[1 - v][(bufptr - deltime_r) & ADDR_MASK], out_right, del_right, amt_right, fb_right); - delay_mix(ins[0][i], ins[1][i], out_left, out_right, dry.get(), chmix.get()); - - age++; - outs[0][i] = out_left; outs[1][i] = out_right; buffers[0][bufptr] = del_left; buffers[1][bufptr] = del_right; - bufptr = (bufptr + 1) & (MAX_DELAY - 1); - } - } - break; - - case MIXMODE_LR: - case MIXMODE_RL: - { - int v = mixmode == MIXMODE_RL ? 1 : 0; - int deltime_fb = deltime_l + deltime_r; - int deltime_l_corr = mixmode == MIXMODE_RL ? deltime_fb : deltime_l; - int deltime_r_corr = mixmode == MIXMODE_LR ? deltime_fb : deltime_r; - - for(uint32_t i = offset; i < end; i++) - { - delayline2_impl(age, deltime_l, ins[0][i], buffers[v][(bufptr - deltime_l_corr) & ADDR_MASK], buffers[v][(bufptr - deltime_fb) & ADDR_MASK], out_left, del_left, amt_left, fb_left); - delayline2_impl(age, deltime_r, ins[1][i], buffers[1 - v][(bufptr - deltime_r_corr) & ADDR_MASK], buffers[1-v][(bufptr - deltime_fb) & ADDR_MASK], out_right, del_right, amt_right, fb_right); - delay_mix(ins[0][i], ins[1][i], out_left, out_right, dry.get(), chmix.get()); - - age++; - outs[0][i] = out_left; outs[1][i] = out_right; buffers[0][bufptr] = del_left; buffers[1][bufptr] = del_right; - bufptr = (bufptr + 1) & (MAX_DELAY - 1); - } - } - } - if (age >= MAX_DELAY) - age = MAX_DELAY; - if (medium > 0) { - bufptr = orig_bufptr; - if (medium == 2) - { - for(uint32_t i = offset; i < end; i++) - { - buffers[0][bufptr] = biquad_left[0].process_lp(biquad_left[1].process(buffers[0][bufptr])); - buffers[1][bufptr] = biquad_right[0].process_lp(biquad_right[1].process(buffers[1][bufptr])); - bufptr = (bufptr + 1) & (MAX_DELAY - 1); - } - biquad_left[0].sanitize();biquad_right[0].sanitize(); - } else { - for(uint32_t i = offset; i < end; i++) - { - buffers[0][bufptr] = biquad_left[1].process(buffers[0][bufptr]); - buffers[1][bufptr] = biquad_right[1].process(buffers[1][bufptr]); - bufptr = (bufptr + 1) & (MAX_DELAY - 1); - } - } - biquad_left[1].sanitize();biquad_right[1].sanitize(); - - } - return ostate; -} - -/////////////////////////////////////////////////////////////////////////////////////////////// - -bool filter_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const -{ - if (!is_active) - return false; - if (index == par_cutoff && !subindex) { - context->set_line_width(1.5); - return ::get_graph(*this, subindex, data, points); - } - return false; -} - -int filter_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const -{ - if (fabs(inertia_cutoff.get_last() - old_cutoff) + 100 * fabs(inertia_resonance.get_last() - old_resonance) + fabs(*params[par_mode] - old_mode) > 0.1f) - { - old_cutoff = inertia_cutoff.get_last(); - old_resonance = inertia_resonance.get_last(); - old_mode = *params[par_mode]; - last_generation++; - subindex_graph = 0; - subindex_dot = INT_MAX; - subindex_gridline = INT_MAX; - } - else { - subindex_graph = 0; - subindex_dot = subindex_gridline = generation ? INT_MAX : 0; - } - if (generation == last_calculated_generation) - subindex_graph = INT_MAX; - return last_generation; -} - - -/////////////////////////////////////////////////////////////////////////////////////////////// - -filterclavier_audio_module::filterclavier_audio_module() -: filter_module_with_inertia(ins, outs, params) -, min_gain(1.0) -, max_gain(32.0) -, last_note(-1) -, last_velocity(-1) -{ -} - -void filterclavier_audio_module::params_changed() -{ - inertia_filter_module::inertia_cutoff.set_inertia( - note_to_hz(last_note + *params[par_transpose], *params[par_detune])); - - float min_resonance = param_props[par_max_resonance].min; - inertia_filter_module::inertia_resonance.set_inertia( - (float(last_velocity) / 127.0) - // 0.001: see below - * (*params[par_max_resonance] - min_resonance + 0.001) - + min_resonance); - - adjust_gain_according_to_filter_mode(last_velocity); - - inertia_filter_module::calculate_filter(); -} - -void filterclavier_audio_module::activate() -{ - inertia_filter_module::activate(); -} - -void filterclavier_audio_module::set_sample_rate(uint32_t sr) -{ - inertia_filter_module::set_sample_rate(sr); -} - -void filterclavier_audio_module::deactivate() -{ - inertia_filter_module::deactivate(); -} - - -void filterclavier_audio_module::note_on(int channel, int note, int vel) -{ - last_note = note; - last_velocity = vel; - inertia_filter_module::inertia_cutoff.set_inertia( - note_to_hz(note + *params[par_transpose], *params[par_detune])); - - float min_resonance = param_props[par_max_resonance].min; - inertia_filter_module::inertia_resonance.set_inertia( - (float(vel) / 127.0) - // 0.001: if the difference is equal to zero (which happens - // when the max_resonance knom is at minimum position - // then the filter gain doesnt seem to snap to zero on most note offs - * (*params[par_max_resonance] - min_resonance + 0.001) - + min_resonance); - - adjust_gain_according_to_filter_mode(vel); - - inertia_filter_module::calculate_filter(); -} - -void filterclavier_audio_module::note_off(int channel, int note, int vel) -{ - if (note == last_note) { - inertia_filter_module::inertia_resonance.set_inertia(param_props[par_max_resonance].min); - inertia_filter_module::inertia_gain.set_inertia(min_gain); - inertia_filter_module::calculate_filter(); - last_velocity = 0; - } -} - -void filterclavier_audio_module::adjust_gain_according_to_filter_mode(int velocity) -{ - int mode = dsp::fastf2i_drm(*params[par_mode]); - - // for bandpasses: boost gain for velocities > 0 - if ( (mode_6db_bp <= mode) && (mode <= mode_18db_bp) ) { - // gain for velocity 0: 1.0 - // gain for velocity 127: 32.0 - float mode_max_gain = max_gain; - // max_gain is right for mode_6db_bp - if (mode == mode_12db_bp) - mode_max_gain /= 6.0; - if (mode == mode_18db_bp) - mode_max_gain /= 10.5; - - inertia_filter_module::inertia_gain.set_now( - (float(velocity) / 127.0) * (mode_max_gain - min_gain) + min_gain); - } else { - inertia_filter_module::inertia_gain.set_now(min_gain); - } -} - -bool filterclavier_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const -{ - if (!is_active || index != par_mode) { - return false; - } - if (!subindex) { - context->set_line_width(1.5); - return ::get_graph(*this, subindex, data, points); - } - return false; -} - - -/////////////////////////////////////////////////////////////////////////////////////////////// - -stereo_audio_module::stereo_audio_module() { - active = false; - clip_inL = 0.f; - clip_inR = 0.f; - clip_outL = 0.f; - clip_outR = 0.f; - meter_inL = 0.f; - meter_inR = 0.f; - meter_outL = 0.f; - meter_outR = 0.f; -} - -stereo_audio_module::~stereo_audio_module() -{ - if( buffer != NULL ) - { - free(buffer); - } -} - -void stereo_audio_module::activate() { - active = true; -} - -void stereo_audio_module::deactivate() { - active = false; -} - -void stereo_audio_module::params_changed() { - float slev = 2 * *params[param_slev]; // stereo level ( -2 -> 2 ) - float sbal = 1 + *params[param_sbal]; // stereo balance ( 0 -> 2 ) - float mlev = 2 * *params[param_mlev]; // mono level ( -2 -> 2 ) - float mpan = 1 + *params[param_mpan]; // mono pan ( 0 -> 2 ) - - switch((int)*params[param_mode]) - { - case 0: - default: - //LR->LR - LL = (mlev * (2.f - mpan) + slev * (2.f - sbal)); - LR = (mlev * mpan - slev * sbal); - RL = (mlev * (2.f - mpan) - slev * (2.f - sbal)); - RR = (mlev * mpan + slev * sbal); - break; - case 1: - //LR->MS - LL = (2.f - mpan) * (2.f - sbal); - LR = mpan * (2.f - sbal) * -1; - RL = (2.f - mpan) * sbal; - RR = mpan * sbal; - break; - case 2: - //MS->LR - LL = mlev * (2.f - sbal); - LR = mlev * mpan; - RL = slev * (2.f - sbal); - RR = slev * sbal * -1; - break; - case 3: - case 4: - case 5: - case 6: - //LR->LL - LL = 0.f; - LR = 0.f; - RL = 0.f; - RR = 0.f; - break; - } -} - -uint32_t stereo_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) { - for(uint32_t i = offset; i < offset + numsamples; i++) { - if(*params[param_bypass] > 0.5) { - outs[0][i] = ins[0][i]; - outs[1][i] = ins[1][i]; - clip_inL = 0.f; - clip_inR = 0.f; - clip_outL = 0.f; - clip_outR = 0.f; - meter_inL = 0.f; - meter_inR = 0.f; - meter_outL = 0.f; - meter_outR = 0.f; - } else { - // let meters fall a bit - clip_inL -= std::min(clip_inL, numsamples); - clip_inR -= std::min(clip_inR, numsamples); - clip_outL -= std::min(clip_outL, numsamples); - clip_outR -= std::min(clip_outR, numsamples); - meter_inL = 0.f; - meter_inR = 0.f; - meter_outL = 0.f; - meter_outR = 0.f; - - float L = ins[0][i]; - float R = ins[1][i]; - - // levels in - L *= *params[param_level_in]; - R *= *params[param_level_in]; - - // balance in - L *= (1.f - std::max(0.f, *params[param_balance_in])); - R *= (1.f + std::min(0.f, *params[param_balance_in])); - - // copy / flip / mono ... - switch((int)*params[param_mode]) - { - case 0: - default: - // LR > LR - break; - case 1: - // LR > MS - break; - case 2: - // MS > LR - break; - case 3: - // LR > LL - R = L; - break; - case 4: - // LR > RR - L = R; - break; - case 5: - // LR > L+R - L = (L + R) / 2; - R = L; - break; - case 6: - // LR > RL - float tmp = L; - L = R; - R = tmp; - break; - } - - // softclip - if(*params[param_softclip]) { - int ph; - ph = L / fabs(L); - L = L > 0.63 ? ph * (0.63 + 0.36 * (1 - pow(MATH_E, (1.f / 3) * (0.63 + L * ph)))) : L; - ph = R / fabs(R); - R = R > 0.63 ? ph * (0.63 + 0.36 * (1 - pow(MATH_E, (1.f / 3) * (0.63 + R * ph)))) : R; - } - - // GUI stuff - if(L > meter_inL) meter_inL = L; - if(R > meter_inR) meter_inR = R; - if(L > 1.f) clip_inL = srate >> 3; - if(R > 1.f) clip_inR = srate >> 3; - - // mute - L *= (1 - floor(*params[param_mute_l] + 0.5)); - R *= (1 - floor(*params[param_mute_r] + 0.5)); - - // phase - L *= (2 * (1 - floor(*params[param_phase_l] + 0.5))) - 1; - R *= (2 * (1 - floor(*params[param_phase_r] + 0.5))) - 1; - - // LR/MS - L += LL*L + RL*R; - R += RR*R + LR*L; - - // widener - L += *params[param_widener] * R * -1; - R += *params[param_widener] * L * -1; - - // delay - buffer[pos] = L; - buffer[pos + 1] = R; - - int nbuf = srate * (fabs(*params[param_delay]) / 1000.f); - nbuf -= nbuf % 2; - if(*params[param_delay] > 0.f) { - R = buffer[(pos - (int)nbuf + 1 + buffer_size) % buffer_size]; - } else if (*params[param_delay] < 0.f) { - L = buffer[(pos - (int)nbuf + buffer_size) % buffer_size]; - } - - pos = (pos + 2) % buffer_size; - - // balance out - L *= (1.f - std::max(0.f, *params[param_balance_out])); - R *= (1.f + std::min(0.f, *params[param_balance_out])); - - // level - L *= *params[param_level_out]; - R *= *params[param_level_out]; - - //output - outs[0][i] = L; - outs[1][i] = R; - - // clip LED's - if(L > 1.f) clip_outL = srate >> 3; - if(R > 1.f) clip_outR = srate >> 3; - if(L > meter_outL) meter_outL = L; - if(R > meter_outR) meter_outR = R; - - // phase meter - if(fabs(L) > 0.001 and fabs(R) > 0.001) { - meter_phase = fabs(fabs(L+R) > 0.000000001 ? sin(fabs((L-R)/(L+R))) : 0.f); - } else { - meter_phase = 0.f; - } - } - } - // draw meters - SET_IF_CONNECTED(clip_inL); - SET_IF_CONNECTED(clip_inR); - SET_IF_CONNECTED(clip_outL); - SET_IF_CONNECTED(clip_outR); - SET_IF_CONNECTED(meter_inL); - SET_IF_CONNECTED(meter_inR); - SET_IF_CONNECTED(meter_outL); - SET_IF_CONNECTED(meter_outR); - SET_IF_CONNECTED(meter_phase); - return outputs_mask; -} - -void stereo_audio_module::set_sample_rate(uint32_t sr) -{ - srate = sr; - // rebuild buffer - buffer_size = (int)(srate * 0.05 * 2.f); // buffer size attack rate multiplied by 2 channels - buffer = (float*) calloc(buffer_size, sizeof(float)); - memset(buffer, 0, buffer_size * sizeof(float)); // reset buffer to zero - pos = 0; -} - -/////////////////////////////////////////////////////////////////////////////////////////////// - -mono_audio_module::mono_audio_module() { - active = false; - clip_in = 0.f; - clip_outL = 0.f; - clip_outR = 0.f; - meter_in = 0.f; - meter_outL = 0.f; - meter_outR = 0.f; -} - -mono_audio_module::~mono_audio_module() -{ - if( buffer != NULL ) - { - free(buffer); - } -} - -void mono_audio_module::activate() { - active = true; -} - -void mono_audio_module::deactivate() { - active = false; -} - -void mono_audio_module::params_changed() { - -} - -uint32_t mono_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) { - for(uint32_t i = offset; i < offset + numsamples; i++) { - if(*params[param_bypass] > 0.5) { - outs[0][i] = ins[0][i]; - outs[1][i] = ins[0][i]; - clip_in = 0.f; - clip_outL = 0.f; - clip_outR = 0.f; - meter_in = 0.f; - meter_outL = 0.f; - meter_outR = 0.f; - } else { - // let meters fall a bit - clip_in -= std::min(clip_in, numsamples); - clip_outL -= std::min(clip_outL, numsamples); - clip_outR -= std::min(clip_outR, numsamples); - meter_in = 0.f; - meter_outL = 0.f; - meter_outR = 0.f; - - float L = ins[0][i]; - - // levels in - L *= *params[param_level_in]; - - // softclip - if(*params[param_softclip]) { - int ph = L / fabs(L); - L = L > 0.63 ? ph * (0.63 + 0.36 * (1 - pow(MATH_E, (1.f / 3) * (0.63 + L * ph)))) : L; - } - - // GUI stuff - if(L > meter_in) meter_in = L; - if(L > 1.f) clip_in = srate >> 3; - - float R = L; - - // mute - L *= (1 - floor(*params[param_mute_l] + 0.5)); - R *= (1 - floor(*params[param_mute_r] + 0.5)); - - // phase - L *= (2 * (1 - floor(*params[param_phase_l] + 0.5))) - 1; - R *= (2 * (1 - floor(*params[param_phase_r] + 0.5))) - 1; - - // delay - buffer[pos] = L; - buffer[pos + 1] = R; - - int nbuf = srate * (fabs(*params[param_delay]) / 1000.f); - nbuf -= nbuf % 2; - if(*params[param_delay] > 0.f) { - R = buffer[(pos - (int)nbuf + 1 + buffer_size) % buffer_size]; - } else if (*params[param_delay] < 0.f) { - L = buffer[(pos - (int)nbuf + buffer_size) % buffer_size]; - } - - pos = (pos + 2) % buffer_size; - - // balance out - L *= (1.f - std::max(0.f, *params[param_balance_out])); - R *= (1.f + std::min(0.f, *params[param_balance_out])); - - // level - L *= *params[param_level_out]; - R *= *params[param_level_out]; - - //output - outs[0][i] = L; - outs[1][i] = R; - - // clip LED's - if(L > 1.f) clip_outL = srate >> 3; - if(R > 1.f) clip_outR = srate >> 3; - if(L > meter_outL) meter_outL = L; - if(R > meter_outR) meter_outR = R; - } - } - // draw meters - SET_IF_CONNECTED(clip_in); - SET_IF_CONNECTED(clip_outL); - SET_IF_CONNECTED(clip_outR); - SET_IF_CONNECTED(meter_in); - SET_IF_CONNECTED(meter_outL); - SET_IF_CONNECTED(meter_outR); - return outputs_mask; -} - -void mono_audio_module::set_sample_rate(uint32_t sr) -{ - srate = sr; - // rebuild buffer - buffer_size = (int)srate * 0.05 * 2; // delay buffer size multiplied by 2 channels - buffer = (float*) calloc(buffer_size, sizeof(float)); - memset(buffer, 0, buffer_size * sizeof(float)); // reset buffer to zero - pos = 0; -} diff --git a/plugins/LadspaEffect/calf/src/modules_comp.cpp b/plugins/LadspaEffect/calf/src/modules_comp.cpp deleted file mode 100644 index 85797706e87..00000000000 --- a/plugins/LadspaEffect/calf/src/modules_comp.cpp +++ /dev/null @@ -1,2577 +0,0 @@ -/* Calf DSP plugin pack - * Compression related plugins - * - * Copyright (C) 2001-2010 Krzysztof Foltman, Markus Schmidt, Thor Harald Johansen and others - * - * 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 02110-1301 USA - */ -#include -#include -#include -#include - -using namespace dsp; -using namespace calf_plugins; - -#define SET_IF_CONNECTED(name) if (params[AM::param_##name] != NULL) *params[AM::param_##name] = name; - -/// Multiband Compressor by Markus Schmidt -/// -/// This module splits the signal in four different bands -/// and sends them through multiple filters (implemented by -/// Krzysztof). They are processed by a compressing routine -/// (implemented by Thor) afterwards and summed up to the -/// final output again. -/////////////////////////////////////////////////////////////////////////////////////////////// - -multibandcompressor_audio_module::multibandcompressor_audio_module() -{ - is_active = false; - srate = 0; - // zero all displays - clip_inL = 0.f; - clip_inR = 0.f; - clip_outL = 0.f; - clip_outR = 0.f; - meter_inL = 0.f; - meter_inR = 0.f; - meter_outL = 0.f; - meter_outR = 0.f; - for(int i = 0; i < strips - 1; i ++) { - freq_old[i] = -1; - sep_old[i] = -1; - q_old[i] = -1; - } - mode_old = -1; -} - -void multibandcompressor_audio_module::activate() -{ - is_active = true; - // set all filters and strips - params_changed(); - // activate all strips - for (int j = 0; j < strips; j ++) { - strip[j].activate(); - strip[j].id = j; - } -} - -void multibandcompressor_audio_module::deactivate() -{ - is_active = false; - // deactivate all strips - for (int j = 0; j < strips; j ++) { - strip[j].deactivate(); - } -} - -void multibandcompressor_audio_module::params_changed() -{ - // determine mute/solo states - solo[0] = *params[param_solo0] > 0.f ? true : false; - solo[1] = *params[param_solo1] > 0.f ? true : false; - solo[2] = *params[param_solo2] > 0.f ? true : false; - solo[3] = *params[param_solo3] > 0.f ? true : false; - no_solo = (*params[param_solo0] > 0.f || - *params[param_solo1] > 0.f || - *params[param_solo2] > 0.f || - *params[param_solo3] > 0.f) ? false : true; - int i; - int j1; - switch(mode) { - case 0: - default: - j1 = 0; - break; - case 1: - j1 = 2; - break; - } - // set the params of all filters - if(*params[param_freq0] != freq_old[0] or *params[param_sep0] != sep_old[0] or *params[param_q0] != q_old[0] or *params[param_mode] != mode_old) { - lpL[0][0].set_lp_rbj((float)(*params[param_freq0] * (1 - *params[param_sep0])), *params[param_q0], (float)srate); - hpL[0][0].set_hp_rbj((float)(*params[param_freq0] * (1 + *params[param_sep0])), *params[param_q0], (float)srate); - lpR[0][0].copy_coeffs(lpL[0][0]); - hpR[0][0].copy_coeffs(hpL[0][0]); - for(i = 1; i <= j1; i++) { - lpL[0][i].copy_coeffs(lpL[0][0]); - hpL[0][i].copy_coeffs(hpL[0][0]); - lpR[0][i].copy_coeffs(lpL[0][0]); - hpR[0][i].copy_coeffs(hpL[0][0]); - } - freq_old[0] = *params[param_freq0]; - sep_old[0] = *params[param_sep0]; - q_old[0] = *params[param_q0]; - } - if(*params[param_freq1] != freq_old[1] or *params[param_sep1] != sep_old[1] or *params[param_q1] != q_old[1] or *params[param_mode] != mode_old) { - lpL[1][0].set_lp_rbj((float)(*params[param_freq1] * (1 - *params[param_sep1])), *params[param_q1], (float)srate); - hpL[1][0].set_hp_rbj((float)(*params[param_freq1] * (1 + *params[param_sep1])), *params[param_q1], (float)srate); - lpR[1][0].copy_coeffs(lpL[1][0]); - hpR[1][0].copy_coeffs(hpL[1][0]); - for(i = 1; i <= j1; i++) { - lpL[1][i].copy_coeffs(lpL[1][0]); - hpL[1][i].copy_coeffs(hpL[1][0]); - lpR[1][i].copy_coeffs(lpL[1][0]); - hpR[1][i].copy_coeffs(hpL[1][0]); - } - freq_old[1] = *params[param_freq1]; - sep_old[1] = *params[param_sep1]; - q_old[1] = *params[param_q1]; - } - if(*params[param_freq2] != freq_old[2] or *params[param_sep2] != sep_old[2] or *params[param_q2] != q_old[2] or *params[param_mode] != mode_old) { - lpL[2][0].set_lp_rbj((float)(*params[param_freq2] * (1 - *params[param_sep2])), *params[param_q2], (float)srate); - hpL[2][0].set_hp_rbj((float)(*params[param_freq2] * (1 + *params[param_sep2])), *params[param_q2], (float)srate); - lpR[2][0].copy_coeffs(lpL[2][0]); - hpR[2][0].copy_coeffs(hpL[2][0]); - for(i = 1; i <= j1; i++) { - lpL[2][i].copy_coeffs(lpL[2][0]); - hpL[2][i].copy_coeffs(hpL[2][0]); - lpR[2][i].copy_coeffs(lpL[2][0]); - hpR[2][i].copy_coeffs(hpL[2][0]); - } - freq_old[2] = *params[param_freq2]; - sep_old[2] = *params[param_sep2]; - q_old[2] = *params[param_q2]; - } - // set the params of all strips - strip[0].set_params(*params[param_attack0], *params[param_release0], *params[param_threshold0], *params[param_ratio0], *params[param_knee0], *params[param_makeup0], *params[param_detection0], 1.f, *params[param_bypass0], !(solo[0] || no_solo)); - strip[1].set_params(*params[param_attack1], *params[param_release1], *params[param_threshold1], *params[param_ratio1], *params[param_knee1], *params[param_makeup1], *params[param_detection1], 1.f, *params[param_bypass1], !(solo[1] || no_solo)); - strip[2].set_params(*params[param_attack2], *params[param_release2], *params[param_threshold2], *params[param_ratio2], *params[param_knee2], *params[param_makeup2], *params[param_detection2], 1.f, *params[param_bypass2], !(solo[2] || no_solo)); - strip[3].set_params(*params[param_attack3], *params[param_release3], *params[param_threshold3], *params[param_ratio3], *params[param_knee3], *params[param_makeup3], *params[param_detection3], 1.f, *params[param_bypass3], !(solo[3] || no_solo)); -} - -void multibandcompressor_audio_module::set_sample_rate(uint32_t sr) -{ - srate = sr; - // set srate of all strips - for (int j = 0; j < strips; j ++) { - strip[j].set_sample_rate(srate); - } -} - -#define BYPASSED_COMPRESSION(index) \ - if(params[param_compression##index] != NULL) \ - *params[param_compression##index] = 1.0; \ - if(params[param_output##index] != NULL) \ - *params[param_output##index] = 0.0; - -#define ACTIVE_COMPRESSION(index) \ - if(params[param_compression##index] != NULL) \ - *params[param_compression##index] = strip[index].get_comp_level(); \ - if(params[param_output##index] != NULL) \ - *params[param_output##index] = strip[index].get_output_level(); - -uint32_t multibandcompressor_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) -{ - bool bypass = *params[param_bypass] > 0.5f; - numsamples += offset; - for (int i = 0; i < strips; i++) - strip[i].update_curve(); - if(bypass) { - // everything bypassed - while(offset < numsamples) { - outs[0][offset] = ins[0][offset]; - outs[1][offset] = ins[1][offset]; - ++offset; - } - // displays, too - clip_inL = 0.f; - clip_inR = 0.f; - clip_outL = 0.f; - clip_outR = 0.f; - meter_inL = 0.f; - meter_inR = 0.f; - meter_outL = 0.f; - meter_outR = 0.f; - } else { - // process all strips - - // let meters fall a bit - clip_inL -= std::min(clip_inL, numsamples); - clip_inR -= std::min(clip_inR, numsamples); - clip_outL -= std::min(clip_outL, numsamples); - clip_outR -= std::min(clip_outR, numsamples); - meter_inL = 0.f; - meter_inR = 0.f; - meter_outL = 0.f; - meter_outR = 0.f; - while(offset < numsamples) { - // cycle through samples - float inL = ins[0][offset]; - float inR = ins[1][offset]; - // in level - inR *= *params[param_level_in]; - inL *= *params[param_level_in]; - // out vars - float outL = 0.f; - float outR = 0.f; - int j1; - for (int i = 0; i < strips; i ++) { - // cycle trough strips - if (solo[i] || no_solo) { - // strip unmuted - float left = inL; - float right = inR; - // send trough filters - switch(mode) { - case 0: - default: - j1 = 0; - break; - case 1: - j1 = 2; - break; - } - for (int j = 0; j <= j1; j++){ - if(i + 1 < strips) { - left = lpL[i][j].process(left); - right = lpR[i][j].process(right); - lpL[i][j].sanitize(); - lpR[i][j].sanitize(); - } - if(i - 1 >= 0) { - left = hpL[i - 1][j].process(left); - right = hpR[i - 1][j].process(right); - hpL[i - 1][j].sanitize(); - hpR[i - 1][j].sanitize(); - } - } - // process gain reduction - strip[i].process(left, right); - // sum up output - outL += left; - outR += right; - } else { - // strip muted - - } - - - } // process single strip - - // even out filters gain reduction - // 3dB - levelled manually (based on default sep and q settings) - switch(mode) { - case 0: - outL *= 1.414213562; - outR *= 1.414213562; - break; - case 1: - outL *= 0.88; - outR *= 0.88; - break; - } - - // out level - outL *= *params[param_level_out]; - outR *= *params[param_level_out]; - - // send to output - outs[0][offset] = outL; - outs[1][offset] = outR; - - // clip LED's - if(inL > 1.f) { - clip_inL = srate >> 3; - } - if(inR > 1.f) { - clip_inR = srate >> 3; - } - if(outL > 1.f) { - clip_outL = srate >> 3; - } - if(outR > 1.f) { - clip_outR = srate >> 3; - } - // set up in / out meters - if(inL > meter_inL) { - meter_inL = inL; - } - if(inR > meter_inR) { - meter_inR = inR; - } - if(outL > meter_outL) { - meter_outL = outL; - } - if(outR > meter_outR) { - meter_outR = outR; - } - // next sample - ++offset; - } // cycle trough samples - - } // process all strips (no bypass) - - // draw meters - SET_IF_CONNECTED(clip_inL); - SET_IF_CONNECTED(clip_inR); - SET_IF_CONNECTED(clip_outL); - SET_IF_CONNECTED(clip_outR); - SET_IF_CONNECTED(meter_inL); - SET_IF_CONNECTED(meter_inR); - SET_IF_CONNECTED(meter_outL); - SET_IF_CONNECTED(meter_outR); - // draw strip meters - if(bypass > 0.5f) { - BYPASSED_COMPRESSION(0) - BYPASSED_COMPRESSION(1) - BYPASSED_COMPRESSION(2) - BYPASSED_COMPRESSION(3) - } else { - ACTIVE_COMPRESSION(0) - ACTIVE_COMPRESSION(1) - ACTIVE_COMPRESSION(2) - ACTIVE_COMPRESSION(3) - } - // whatever has to be returned x) - return outputs_mask; -} - -const gain_reduction_audio_module *multibandcompressor_audio_module::get_strip_by_param_index(int index) const -{ - // let's handle by the corresponding strip - switch (index) { - case param_compression0: - return &strip[0]; - case param_compression1: - return &strip[1]; - case param_compression2: - return &strip[2]; - case param_compression3: - return &strip[3]; - } - return NULL; -} - -bool multibandcompressor_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const -{ - const gain_reduction_audio_module *m = get_strip_by_param_index(index); - if (m) - return m->get_graph(subindex, data, points, context); - return false; -} - -bool multibandcompressor_audio_module::get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const -{ - const gain_reduction_audio_module *m = get_strip_by_param_index(index); - if (m) - return m->get_dot(subindex, x, y, size, context); - return false; -} - -bool multibandcompressor_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const -{ - const gain_reduction_audio_module *m = get_strip_by_param_index(index); - if (m) - return m->get_gridline(subindex, pos, vertical, legend, context); - return false; -} - -int multibandcompressor_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const -{ - const gain_reduction_audio_module *m = get_strip_by_param_index(index); - if (m) - return m->get_changed_offsets(generation, subindex_graph, subindex_dot, subindex_gridline); - return 0; -} - -/// Compressor originally by Thor -/// -/// This module provides Thor's original compressor without any sidechain or weighting -/////////////////////////////////////////////////////////////////////////////////////////////// - -compressor_audio_module::compressor_audio_module() -{ - is_active = false; - srate = 0; - last_generation = 0; - meters.reset(); -} - -void compressor_audio_module::activate() -{ - is_active = true; - // set all filters and strips - compressor.activate(); - params_changed(); - meters.reset(); -} -void compressor_audio_module::deactivate() -{ - is_active = false; - compressor.deactivate(); -} - -void compressor_audio_module::params_changed() -{ - compressor.set_params(*params[param_attack], *params[param_release], *params[param_threshold], *params[param_ratio], *params[param_knee], *params[param_makeup], *params[param_detection], *params[param_stereo_link], *params[param_bypass], 0.f); -} - -void compressor_audio_module::set_sample_rate(uint32_t sr) -{ - srate = sr; - compressor.set_sample_rate(srate); - meters.set_sample_rate(srate); -} - -uint32_t compressor_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) -{ - uint32_t orig_offset = offset; - uint32_t orig_numsamples = numsamples; - bool bypass = *params[param_bypass] > 0.5f; - numsamples += offset; - if(bypass) { - // everything bypassed - while(offset < numsamples) { - outs[0][offset] = ins[0][offset]; - outs[1][offset] = ins[1][offset]; - ++offset; - } - // displays, too - meters.bypassed(params, orig_numsamples); - } else { - // process - - compressor.update_curve(); - - while(offset < numsamples) { - // cycle through samples - float outL = 0.f; - float outR = 0.f; - float inL = ins[0][offset]; - float inR = ins[1][offset]; - // in level - inR *= *params[param_level_in]; - inL *= *params[param_level_in]; - - float leftAC = inL; - float rightAC = inR; - - compressor.process(leftAC, rightAC); - - outL = leftAC; - outR = rightAC; - - // send to output - outs[0][offset] = outL; - outs[1][offset] = outR; - - // next sample - ++offset; - } // cycle trough samples - meters.process(params, ins, outs, orig_offset, orig_numsamples); - } - // draw strip meter - if(bypass > 0.5f) { - if(params[param_compression] != NULL) { - *params[param_compression] = 1.0f; - } - } else { - if(params[param_compression] != NULL) { - *params[param_compression] = compressor.get_comp_level(); - } - } - // whatever has to be returned x) - return outputs_mask; -} -bool compressor_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const -{ - if (!is_active) - return false; - return compressor.get_graph(subindex, data, points, context); -} - -bool compressor_audio_module::get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const -{ - if (!is_active) - return false; - return compressor.get_dot(subindex, x, y, size, context); -} - -bool compressor_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const -{ - if (!is_active) - return false; - return compressor.get_gridline(subindex, pos, vertical, legend, context); -} - -int compressor_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const -{ - if (!is_active) - return false; - return compressor.get_changed_offsets(generation, subindex_graph, subindex_dot, subindex_gridline); -} - -/// Sidecain Compressor by Markus Schmidt -/// -/// This module splits the signal in a sidechain- and a process signal. -/// The sidechain is processed through Krzystofs filters and compresses -/// the process signal via Thor's compression routine afterwards. -/////////////////////////////////////////////////////////////////////////////////////////////// - -sidechaincompressor_audio_module::sidechaincompressor_audio_module() -{ - is_active = false; - srate = 0; - last_generation = 0; - f1_freq_old1 = 0.f; - f2_freq_old1 = 0.f; - f1_level_old1 = 0.f; - f2_level_old1 = 0.f; - f1_freq_old = 0.f; - f2_freq_old = 0.f; - f1_level_old = 0.f; - f2_level_old = 0.f; - sc_mode_old1 = WIDEBAND; - meters.reset(); -} - -void sidechaincompressor_audio_module::activate() -{ - is_active = true; - // set all filters and strips - compressor.activate(); - params_changed(); - meters.reset(); -} -void sidechaincompressor_audio_module::deactivate() -{ - is_active = false; - compressor.deactivate(); -} - -sidechaincompressor_audio_module::cfloat sidechaincompressor_audio_module::h_z(const cfloat &z) const -{ - switch ((CalfScModes)sc_mode) { - default: - case WIDEBAND: - return false; - break; - case DEESSER_WIDE: - case DERUMBLER_WIDE: - case WEIGHTED_1: - case WEIGHTED_2: - case WEIGHTED_3: - case BANDPASS_2: - return f1L.h_z(z) * f2L.h_z(z); - break; - case DEESSER_SPLIT: - return f2L.h_z(z); - break; - case DERUMBLER_SPLIT: - case BANDPASS_1: - return f1L.h_z(z); - break; - } -} - -float sidechaincompressor_audio_module::freq_gain(int index, double freq, uint32_t sr) const -{ - typedef std::complex cfloat; - freq *= 2.0 * M_PI / sr; - cfloat z = 1.0 / exp(cfloat(0.0, freq)); - - return std::abs(h_z(z)); -} - -void sidechaincompressor_audio_module::params_changed() -{ - // set the params of all filters - if(*params[param_f1_freq] != f1_freq_old or *params[param_f1_level] != f1_level_old - or *params[param_f2_freq] != f2_freq_old or *params[param_f2_level] != f2_level_old - or *params[param_sc_mode] != sc_mode) { - float q = 0.707; - switch ((CalfScModes)*params[param_sc_mode]) { - default: - case WIDEBAND: - f1L.set_hp_rbj((float)*params[param_f1_freq], q, (float)srate, *params[param_f1_level]); - f1R.copy_coeffs(f1L); - f2L.set_lp_rbj((float)*params[param_f2_freq], q, (float)srate, *params[param_f2_level]); - f2R.copy_coeffs(f2L); - f1_active = 0.f; - f2_active = 0.f; - break; - case DEESSER_WIDE: - f1L.set_peakeq_rbj((float)*params[param_f1_freq], q, *params[param_f1_level], (float)srate); - f1R.copy_coeffs(f1L); - f2L.set_hp_rbj((float)*params[param_f2_freq], q, (float)srate, *params[param_f2_level]); - f2R.copy_coeffs(f2L); - f1_active = 0.5f; - f2_active = 1.f; - break; - case DEESSER_SPLIT: - f1L.set_lp_rbj((float)*params[param_f2_freq] * (1 + 0.17), q, (float)srate); - f1R.copy_coeffs(f1L); - f2L.set_hp_rbj((float)*params[param_f2_freq] * (1 - 0.17), q, (float)srate, *params[param_f2_level]); - f2R.copy_coeffs(f2L); - f1_active = 0.f; - f2_active = 1.f; - break; - case DERUMBLER_WIDE: - f1L.set_lp_rbj((float)*params[param_f1_freq], q, (float)srate, *params[param_f1_level]); - f1R.copy_coeffs(f1L); - f2L.set_peakeq_rbj((float)*params[param_f2_freq], q, *params[param_f2_level], (float)srate); - f2R.copy_coeffs(f2L); - f1_active = 1.f; - f2_active = 0.5f; - break; - case DERUMBLER_SPLIT: - f1L.set_lp_rbj((float)*params[param_f1_freq] * (1 + 0.17), q, (float)srate, *params[param_f1_level]); - f1R.copy_coeffs(f1L); - f2L.set_hp_rbj((float)*params[param_f1_freq] * (1 - 0.17), q, (float)srate); - f2R.copy_coeffs(f2L); - f1_active = 1.f; - f2_active = 0.f; - break; - case WEIGHTED_1: - f1L.set_lowshelf_rbj((float)*params[param_f1_freq], q, *params[param_f1_level], (float)srate); - f1R.copy_coeffs(f1L); - f2L.set_highshelf_rbj((float)*params[param_f2_freq], q, *params[param_f2_level], (float)srate); - f2R.copy_coeffs(f2L); - f1_active = 0.5f; - f2_active = 0.5f; - break; - case WEIGHTED_2: - f1L.set_lowshelf_rbj((float)*params[param_f1_freq], q, *params[param_f1_level], (float)srate); - f1R.copy_coeffs(f1L); - f2L.set_peakeq_rbj((float)*params[param_f2_freq], q, *params[param_f2_level], (float)srate); - f2R.copy_coeffs(f2L); - f1_active = 0.5f; - f2_active = 0.5f; - break; - case WEIGHTED_3: - f1L.set_peakeq_rbj((float)*params[param_f1_freq], q, *params[param_f1_level], (float)srate); - f1R.copy_coeffs(f1L); - f2L.set_highshelf_rbj((float)*params[param_f2_freq], q, *params[param_f2_level], (float)srate); - f2R.copy_coeffs(f2L); - f1_active = 0.5f; - f2_active = 0.5f; - break; - case BANDPASS_1: - f1L.set_bp_rbj((float)*params[param_f1_freq], q, (float)srate, *params[param_f1_level]); - f1R.copy_coeffs(f1L); - f2L.set_hp_rbj((float)*params[param_f2_freq], q, *params[param_f2_level], (float)srate); - f2R.copy_coeffs(f2L); - f1_active = 1.f; - f2_active = 0.f; - break; - case BANDPASS_2: - f1L.set_hp_rbj((float)*params[param_f1_freq], q, (float)srate, *params[param_f1_level]); - f1R.copy_coeffs(f1L); - f2L.set_lp_rbj((float)*params[param_f2_freq], q, (float)srate, *params[param_f2_level]); - f2R.copy_coeffs(f2L); - f1_active = 1.f; - f2_active = 1.f; - break; - } - f1_freq_old = *params[param_f1_freq]; - f1_level_old = *params[param_f1_level]; - f2_freq_old = *params[param_f2_freq]; - f2_level_old = *params[param_f2_level]; - sc_mode = (CalfScModes)*params[param_sc_mode]; - } - // light LED's - if(params[param_f1_active] != NULL) { - *params[param_f1_active] = f1_active; - } - if(params[param_f2_active] != NULL) { - *params[param_f2_active] = f2_active; - } - // and set the compressor module - compressor.set_params(*params[param_attack], *params[param_release], *params[param_threshold], *params[param_ratio], *params[param_knee], *params[param_makeup], *params[param_detection], *params[param_stereo_link], *params[param_bypass], 0.f); -} - -void sidechaincompressor_audio_module::set_sample_rate(uint32_t sr) -{ - srate = sr; - compressor.set_sample_rate(srate); - meters.set_sample_rate(srate); -} - -uint32_t sidechaincompressor_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) -{ - uint32_t orig_offset = offset; - uint32_t orig_numsamples = numsamples; - bool bypass = *params[param_bypass] > 0.5f; - numsamples += offset; - if(bypass) { - // everything bypassed - while(offset < numsamples) { - switch ((CalfScRoute)*params[param_sc_route]) { - case STEREO: - outs[0][offset] = ins[0][offset]; - outs[1][offset] = ins[1][offset]; - break; - case RIGHT_LEFT: - outs[0][offset] = ins[0][offset]; - outs[1][offset] = ins[0][offset]; - break; - case LEFT_RIGHT: - outs[0][offset] = ins[1][offset]; - outs[1][offset] = ins[1][offset]; - break; - } - ++offset; - } - // displays, too - meters.bypassed(params, orig_numsamples); - } else { - // process - - compressor.update_curve(); - - while(offset < numsamples) { - // cycle through samples - float outL = 0.f; - float outR = 0.f; - float inL = ins[0][offset]; - float inR = ins[1][offset]; - // in level - inR *= *params[param_level_in]; - inL *= *params[param_level_in]; - - float leftAC = inL; - float rightAC = inR; - float leftSC = inL; - float rightSC = inR; - float leftMC = inL; - float rightMC = inR; - - switch ((CalfScRoute)*params[param_sc_route]) { - case STEREO: - leftAC = inL; - rightAC = inR; - leftSC = inL; - rightSC = inR; - leftMC = inL; - rightMC = inR; - break; - case RIGHT_LEFT: - leftAC = inL; - rightAC = inL; - leftSC = inR; - rightSC = inR; - leftMC = inL; - rightMC = inL; - break; - case LEFT_RIGHT: - leftAC = inR; - rightAC = inR; - leftSC = inL; - rightSC = inL; - leftMC = inR; - rightMC = inR; - break; - } - - leftSC *= *params[param_sc_level]; - rightSC *= *params[param_sc_level]; - - switch ((CalfScModes)*params[param_sc_mode]) { - default: - case WIDEBAND: - compressor.process(leftAC, rightAC, &leftSC, &rightSC); - leftMC = leftSC; - rightMC = rightSC; - break; - case DEESSER_WIDE: - case DERUMBLER_WIDE: - case WEIGHTED_1: - case WEIGHTED_2: - case WEIGHTED_3: - case BANDPASS_2: - leftSC = f2L.process(f1L.process(leftSC)); - rightSC = f2R.process(f1R.process(rightSC)); - leftMC = leftSC; - rightMC = rightSC; - compressor.process(leftAC, rightAC, &leftSC, &rightSC); - break; - case DEESSER_SPLIT: - leftSC = f2L.process(leftSC); - rightSC = f2R.process(rightSC); - leftMC = leftSC; - rightMC = rightSC; - compressor.process(leftSC, rightSC, &leftSC, &rightSC); - leftAC = f1L.process(leftAC); - rightAC = f1R.process(rightAC); - leftAC += leftSC; - rightAC += rightSC; - break; - case DERUMBLER_SPLIT: - leftSC = f1L.process(leftSC); - rightSC = f1R.process(rightSC); - leftMC = leftSC; - rightMC = rightSC; - compressor.process(leftSC, rightSC, &leftSC, &rightSC); - leftAC = f2L.process(leftAC); - rightAC = f2R.process(rightAC); - leftAC += leftSC; - rightAC += rightSC; - break; - case BANDPASS_1: - leftSC = f1L.process(leftSC); - rightSC = f1R.process(rightSC); - leftMC = leftSC; - rightMC = rightSC; - compressor.process(leftAC, rightAC, &leftSC, &rightSC); - break; - } - - if(*params[param_sc_listen] > 0.f) { - outL = leftMC; - outR = rightMC; - } else { - outL = leftAC; - outR = rightAC; - } - - // send to output - outs[0][offset] = outL; - outs[1][offset] = outR; - - // next sample - ++offset; - } // cycle trough samples - meters.process(params, ins, outs, orig_offset, orig_numsamples); - f1L.sanitize(); - f1R.sanitize(); - f2L.sanitize(); - f2R.sanitize(); - } - // draw strip meter - if(bypass > 0.5f) { - if(params[param_compression] != NULL) { - *params[param_compression] = 1.0f; - } - } else { - if(params[param_compression] != NULL) { - *params[param_compression] = compressor.get_comp_level(); - } - } - // whatever has to be returned x) - return outputs_mask; -} -bool sidechaincompressor_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const -{ - if (!is_active) - return false; - if (index == param_f1_freq && !subindex) { - context->set_line_width(1.5); - return ::get_graph(*this, subindex, data, points); - } else if(index == param_compression) { - return compressor.get_graph(subindex, data, points, context); - } - return false; -} - -bool sidechaincompressor_audio_module::get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const -{ - if (!is_active) - return false; - if (index == param_compression) { - return compressor.get_dot(subindex, x, y, size, context); - } - return false; -} - -bool sidechaincompressor_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const -{ - if (!is_active) - return false; - if (index == param_compression) { - return compressor.get_gridline(subindex, pos, vertical, legend, context); - } else { - return get_freq_gridline(subindex, pos, vertical, legend, context); - } -// return false; -} - -int sidechaincompressor_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const -{ - if (!is_active) - return false; - if(index == param_compression) { - return compressor.get_changed_offsets(generation, subindex_graph, subindex_dot, subindex_gridline); - } else { - // (fabs(inertia_cutoff.get_last() - old_cutoff) + 100 * fabs(inertia_resonance.get_last() - old_resonance) + fabs(*params[par_mode] - old_mode) > 0.1f) - if (*params[param_f1_freq] != f1_freq_old1 - or *params[param_f2_freq] != f2_freq_old1 - or *params[param_f1_level] != f1_level_old1 - or *params[param_f2_level] != f2_level_old1 - or *params[param_sc_mode] !=sc_mode_old1) - { - f1_freq_old1 = *params[param_f1_freq]; - f2_freq_old1 = *params[param_f2_freq]; - f1_level_old1 = *params[param_f1_level]; - f2_level_old1 = *params[param_f2_level]; - sc_mode_old1 = (CalfScModes)*params[param_sc_mode]; - last_generation++; - subindex_graph = 0; - subindex_dot = INT_MAX; - subindex_gridline = INT_MAX; - } - else { - subindex_graph = 0; - subindex_dot = subindex_gridline = generation ? INT_MAX : 0; - } - if (generation == last_calculated_generation) - subindex_graph = INT_MAX; - return last_generation; - } - return false; -} - -/// Deesser by Markus Schmidt -/// -/// This module splits the signal in a sidechain- and a process signal. -/// The sidechain is processed through Krzystofs filters and compresses -/// the process signal via Thor's compression routine afterwards. -/////////////////////////////////////////////////////////////////////////////////////////////// - -deesser_audio_module::deesser_audio_module() -{ - is_active = false; - srate = 0; - last_generation = 0; - f1_freq_old1 = 0.f; - f2_freq_old1 = 0.f; - f1_level_old1 = 0.f; - f2_level_old1 = 0.f; - f2_q_old1 = 0.f; - f1_freq_old = 0.f; - f2_freq_old = 0.f; - f1_level_old = 0.f; - f2_level_old = 0.f; - f2_q_old = 0.f; - detected_led = 0; - clip_led = 0; -} - -void deesser_audio_module::activate() -{ - is_active = true; - // set all filters and strips - compressor.activate(); - params_changed(); - detected = 0.f; - detected_led = 0.f; - clip_out = 0.f; -} -void deesser_audio_module::deactivate() -{ - is_active = false; - compressor.deactivate(); -} - -void deesser_audio_module::params_changed() -{ - // set the params of all filters - if(*params[param_f1_freq] != f1_freq_old or *params[param_f1_level] != f1_level_old - or *params[param_f2_freq] != f2_freq_old or *params[param_f2_level] != f2_level_old - or *params[param_f2_q] != f2_q_old) { - float q = 0.707; - - hpL.set_hp_rbj((float)*params[param_f1_freq] * (1 - 0.17), q, (float)srate, *params[param_f1_level]); - hpR.copy_coeffs(hpL); - lpL.set_lp_rbj((float)*params[param_f1_freq] * (1 + 0.17), q, (float)srate); - lpR.copy_coeffs(lpL); - pL.set_peakeq_rbj((float)*params[param_f2_freq], *params[param_f2_q], *params[param_f2_level], (float)srate); - pR.copy_coeffs(pL); - f1_freq_old = *params[param_f1_freq]; - f1_level_old = *params[param_f1_level]; - f2_freq_old = *params[param_f2_freq]; - f2_level_old = *params[param_f2_level]; - f2_q_old = *params[param_f2_q]; - } - // and set the compressor module - compressor.set_params((float)*params[param_laxity], (float)*params[param_laxity] * 1.33, *params[param_threshold], *params[param_ratio], 2.8, *params[param_makeup], *params[param_detection], 0.f, *params[param_bypass], 0.f); -} - -void deesser_audio_module::set_sample_rate(uint32_t sr) -{ - srate = sr; - compressor.set_sample_rate(srate); -} - -uint32_t deesser_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) -{ - bool bypass = *params[param_bypass] > 0.5f; - numsamples += offset; - if(bypass) { - // everything bypassed81e8da266 - while(offset < numsamples) { - outs[0][offset] = ins[0][offset]; - outs[1][offset] = ins[1][offset]; - ++offset; - } - // displays, too - clip_out = 0.f; - detected = 0.f; - detected_led = 0.f; - } else { - // process - - detected_led -= std::min(detected_led, numsamples); - clip_led -= std::min(clip_led, numsamples); - compressor.update_curve(); - - while(offset < numsamples) { - // cycle through samples - float outL = 0.f; - float outR = 0.f; - float inL = ins[0][offset]; - float inR = ins[1][offset]; - - - float leftAC = inL; - float rightAC = inR; - float leftSC = inL; - float rightSC = inR; - float leftRC = inL; - float rightRC = inR; - float leftMC = inL; - float rightMC = inR; - - leftSC = pL.process(hpL.process(leftSC)); - rightSC = pR.process(hpR.process(rightSC)); - leftMC = leftSC; - rightMC = rightSC; - - switch ((int)*params[param_mode]) { - default: - case WIDE: - compressor.process(leftAC, rightAC, &leftSC, &rightSC); - break; - case SPLIT: - hpL.sanitize(); - hpR.sanitize(); - leftRC = hpL.process(leftRC); - rightRC = hpR.process(rightRC); - compressor.process(leftRC, rightRC, &leftSC, &rightSC); - leftAC = lpL.process(leftAC); - rightAC = lpR.process(rightAC); - leftAC += leftRC; - rightAC += rightRC; - break; - } - - if(*params[param_sc_listen] > 0.f) { - outL = leftMC; - outR = rightMC; - } else { - outL = leftAC; - outR = rightAC; - } - - // send to output - outs[0][offset] = outL; - outs[1][offset] = outR; - - if(std::max(fabs(leftSC), fabs(rightSC)) > *params[param_threshold]) { - detected_led = srate >> 3; - } - if(std::max(fabs(leftAC), fabs(rightAC)) > 1.f) { - clip_led = srate >> 3; - } - if(clip_led > 0) { - clip_out = 1.f; - } else { - clip_out = std::max(fabs(outL), fabs(outR)); - } - detected = std::max(fabs(leftMC), fabs(rightMC)); - - // next sample - ++offset; - } // cycle trough samples - hpL.sanitize(); - hpR.sanitize(); - lpL.sanitize(); - lpR.sanitize(); - pL.sanitize(); - pR.sanitize(); - } - // draw meters - if(params[param_detected_led] != NULL) { - *params[param_detected_led] = detected_led; - } - if(params[param_clip_out] != NULL) { - *params[param_clip_out] = clip_out; - } - if(params[param_detected] != NULL) { - *params[param_detected] = detected; - } - // draw strip meter - if(bypass > 0.5f) { - if(params[param_compression] != NULL) { - *params[param_compression] = 1.0f; - } - } else { - if(params[param_compression] != NULL) { - *params[param_compression] = compressor.get_comp_level(); - } - } - // whatever has to be returned x) - return outputs_mask; -} -bool deesser_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const -{ - if (!is_active) - return false; - if (index == param_f1_freq && !subindex) { - context->set_line_width(1.5); - return ::get_graph(*this, subindex, data, points); - } - return false; -} - -bool deesser_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const -{ - return get_freq_gridline(subindex, pos, vertical, legend, context); - -// return false; -} - -int deesser_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const -{ - if (!is_active) { - return false; - } else { - // (fabs(inertia_cutoff.get_last() - old_cutoff) + 100 * fabs(inertia_resonance.get_last() - old_resonance) + fabs(*params[par_mode] - old_mode) > 0.1f) - if (*params[param_f1_freq] != f1_freq_old1 - or *params[param_f2_freq] != f2_freq_old1 - or *params[param_f1_level] != f1_level_old1 - or *params[param_f2_level] != f2_level_old1 - or *params[param_f2_q] !=f2_q_old1) - { - f1_freq_old1 = *params[param_f1_freq]; - f2_freq_old1 = *params[param_f2_freq]; - f1_level_old1 = *params[param_f1_level]; - f2_level_old1 = *params[param_f2_level]; - f2_q_old1 = *params[param_f2_q]; - last_generation++; - subindex_graph = 0; - subindex_dot = INT_MAX; - subindex_gridline = INT_MAX; - } - else { - subindex_graph = 0; - subindex_dot = subindex_gridline = generation ? INT_MAX : 0; - } - if (generation == last_calculated_generation) - subindex_graph = INT_MAX; - return last_generation; - } - return false; -} - -/// Gate originally by Damien -/// -/// This module provides Damien's original expander based on Thor's compressor -/// without any weighting -/////////////////////////////////////////////////////////////////////////////////////////////// - -gate_audio_module::gate_audio_module() -{ - is_active = false; - srate = 0; - last_generation = 0; - meters.reset(); -} - -void gate_audio_module::activate() -{ - is_active = true; - // set all filters and strips - gate.activate(); - params_changed(); - meters.reset(); -} -void gate_audio_module::deactivate() -{ - is_active = false; - gate.deactivate(); -} - -void gate_audio_module::params_changed() -{ - gate.set_params(*params[param_attack], *params[param_release], *params[param_threshold], *params[param_ratio], *params[param_knee], *params[param_makeup], *params[param_detection], *params[param_stereo_link], *params[param_bypass], 0.f, *params[param_range]); -} - -void gate_audio_module::set_sample_rate(uint32_t sr) -{ - srate = sr; - gate.set_sample_rate(srate); - meters.set_sample_rate(srate); -} - -uint32_t gate_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) -{ - uint32_t orig_offset = offset; - uint32_t orig_numsamples = numsamples; - bool bypass = *params[param_bypass] > 0.5f; - numsamples += offset; - if(bypass) { - // everything bypassed - while(offset < numsamples) { - outs[0][offset] = ins[0][offset]; - outs[1][offset] = ins[1][offset]; - ++offset; - } - // displays, too - meters.bypassed(params, orig_numsamples); - } else { - // process - gate.update_curve(); - - while(offset < numsamples) { - // cycle through samples - float outL = 0.f; - float outR = 0.f; - float inL = ins[0][offset]; - float inR = ins[1][offset]; - // in level - inR *= *params[param_level_in]; - inL *= *params[param_level_in]; - - float leftAC = inL; - float rightAC = inR; - - gate.process(leftAC, rightAC); - - outL = leftAC; - outR = rightAC; - - // send to output - outs[0][offset] = outL; - outs[1][offset] = outR; - - // next sample - ++offset; - } // cycle trough samples - meters.process(params, ins, outs, orig_offset, orig_numsamples); - } - // draw strip meter - if(bypass > 0.5f) { - if(params[param_gating] != NULL) { - *params[param_gating] = 1.0f; - } - } else { - if(params[param_gating] != NULL) { - *params[param_gating] = gate.get_expander_level(); - } - } - // whatever has to be returned x) - return outputs_mask; -} -bool gate_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const -{ - if (!is_active) - return false; - return gate.get_graph(subindex, data, points, context); -} - -bool gate_audio_module::get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const -{ - if (!is_active) - return false; - return gate.get_dot(subindex, x, y, size, context); -} - -bool gate_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const -{ - if (!is_active) - return false; - return gate.get_gridline(subindex, pos, vertical, legend, context); -} - -int gate_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const -{ - if (!is_active) - return false; - return gate.get_changed_offsets(generation, subindex_graph, subindex_dot, subindex_gridline); -} - -/// Sidecain Gate by Markus Schmidt -/// -/// This module splits the signal in a sidechain- and a process signal. -/// The sidechain is processed through Krzystofs filters and gates -/// the process signal via Damiens's gating routine afterwards. -/////////////////////////////////////////////////////////////////////////////////////////////// - -sidechaingate_audio_module::sidechaingate_audio_module() -{ - is_active = false; - srate = 0; - last_generation = 0; - - f1_freq_old = f2_freq_old = f1_level_old = f2_level_old = 0; - f1_freq_old1 = f2_freq_old1 = f1_level_old1 = f2_level_old1 = 0; - sc_mode_old = sc_mode_old1 = WIDEBAND; // doesn't matter as long as it's sane - meters.reset(); -} - -void sidechaingate_audio_module::activate() -{ - is_active = true; - // set all filters and strips - gate.activate(); - params_changed(); - meters.reset(); -} -void sidechaingate_audio_module::deactivate() -{ - is_active = false; - gate.deactivate(); -} - -sidechaingate_audio_module::cfloat sidechaingate_audio_module::h_z(const cfloat &z) const -{ - switch ((CalfScModes)sc_mode) { - default: - case WIDEBAND: - return false; - break; - case HIGHGATE_WIDE: - case LOWGATE_WIDE: - case WEIGHTED_1: - case WEIGHTED_2: - case WEIGHTED_3: - case BANDPASS_2: - return f1L.h_z(z) * f2L.h_z(z); - break; - case HIGHGATE_SPLIT: - return f2L.h_z(z); - break; - case LOWGATE_SPLIT: - case BANDPASS_1: - return f1L.h_z(z); - break; - } -} - -float sidechaingate_audio_module::freq_gain(int index, double freq, uint32_t sr) const -{ - typedef std::complex cfloat; - freq *= 2.0 * M_PI / sr; - cfloat z = 1.0 / exp(cfloat(0.0, freq)); - - return std::abs(h_z(z)); -} - -void sidechaingate_audio_module::params_changed() -{ - // set the params of all filters - if(*params[param_f1_freq] != f1_freq_old or *params[param_f1_level] != f1_level_old - or *params[param_f2_freq] != f2_freq_old or *params[param_f2_level] != f2_level_old - or *params[param_sc_mode] != sc_mode) { - float q = 0.707; - switch ((CalfScModes)*params[param_sc_mode]) { - default: - case WIDEBAND: - f1L.set_hp_rbj((float)*params[param_f1_freq], q, (float)srate, *params[param_f1_level]); - f1R.copy_coeffs(f1L); - f2L.set_lp_rbj((float)*params[param_f2_freq], q, (float)srate, *params[param_f2_level]); - f2R.copy_coeffs(f2L); - f1_active = 0.f; - f2_active = 0.f; - break; - case HIGHGATE_WIDE: - f1L.set_peakeq_rbj((float)*params[param_f1_freq], q, *params[param_f1_level], (float)srate); - f1R.copy_coeffs(f1L); - f2L.set_hp_rbj((float)*params[param_f2_freq], q, (float)srate, *params[param_f2_level]); - f2R.copy_coeffs(f2L); - f1_active = 0.5f; - f2_active = 1.f; - break; - case HIGHGATE_SPLIT: - f1L.set_lp_rbj((float)*params[param_f2_freq] * (1 + 0.17), q, (float)srate); - f1R.copy_coeffs(f1L); - f2L.set_hp_rbj((float)*params[param_f2_freq] * (1 - 0.17), q, (float)srate, *params[param_f2_level]); - f2R.copy_coeffs(f2L); - f1_active = 0.f; - f2_active = 1.f; - break; - case LOWGATE_WIDE: - f1L.set_lp_rbj((float)*params[param_f1_freq], q, (float)srate, *params[param_f1_level]); - f1R.copy_coeffs(f1L); - f2L.set_peakeq_rbj((float)*params[param_f2_freq], q, *params[param_f2_level], (float)srate); - f2R.copy_coeffs(f2L); - f1_active = 1.f; - f2_active = 0.5f; - break; - case LOWGATE_SPLIT: - f1L.set_lp_rbj((float)*params[param_f1_freq] * (1 + 0.17), q, (float)srate, *params[param_f1_level]); - f1R.copy_coeffs(f1L); - f2L.set_hp_rbj((float)*params[param_f1_freq] * (1 - 0.17), q, (float)srate); - f2R.copy_coeffs(f2L); - f1_active = 1.f; - f2_active = 0.f; - break; - case WEIGHTED_1: - f1L.set_lowshelf_rbj((float)*params[param_f1_freq], q, *params[param_f1_level], (float)srate); - f1R.copy_coeffs(f1L); - f2L.set_highshelf_rbj((float)*params[param_f2_freq], q, *params[param_f2_level], (float)srate); - f2R.copy_coeffs(f2L); - f1_active = 0.5f; - f2_active = 0.5f; - break; - case WEIGHTED_2: - f1L.set_lowshelf_rbj((float)*params[param_f1_freq], q, *params[param_f1_level], (float)srate); - f1R.copy_coeffs(f1L); - f2L.set_peakeq_rbj((float)*params[param_f2_freq], q, *params[param_f2_level], (float)srate); - f2R.copy_coeffs(f2L); - f1_active = 0.5f; - f2_active = 0.5f; - break; - case WEIGHTED_3: - f1L.set_peakeq_rbj((float)*params[param_f1_freq], q, *params[param_f1_level], (float)srate); - f1R.copy_coeffs(f1L); - f2L.set_highshelf_rbj((float)*params[param_f2_freq], q, *params[param_f2_level], (float)srate); - f2R.copy_coeffs(f2L); - f1_active = 0.5f; - f2_active = 0.5f; - break; - case BANDPASS_1: - f1L.set_bp_rbj((float)*params[param_f1_freq], q, (float)srate, *params[param_f1_level]); - f1R.copy_coeffs(f1L); - f2L.set_hp_rbj((float)*params[param_f2_freq], q, *params[param_f2_level], (float)srate); - f2R.copy_coeffs(f2L); - f1_active = 1.f; - f2_active = 0.f; - break; - case BANDPASS_2: - f1L.set_hp_rbj((float)*params[param_f1_freq], q, (float)srate, *params[param_f1_level]); - f1R.copy_coeffs(f1L); - f2L.set_lp_rbj((float)*params[param_f2_freq], q, (float)srate, *params[param_f2_level]); - f2R.copy_coeffs(f2L); - f1_active = 1.f; - f2_active = 1.f; - break; - } - f1_freq_old = *params[param_f1_freq]; - f1_level_old = *params[param_f1_level]; - f2_freq_old = *params[param_f2_freq]; - f2_level_old = *params[param_f2_level]; - sc_mode = (CalfScModes)*params[param_sc_mode]; - } - // light LED's - if(params[param_f1_active] != NULL) { - *params[param_f1_active] = f1_active; - } - if(params[param_f2_active] != NULL) { - *params[param_f2_active] = f2_active; - } - // and set the expander module - gate.set_params(*params[param_attack], *params[param_release], *params[param_threshold], *params[param_ratio], *params[param_knee], *params[param_makeup], *params[param_detection], *params[param_stereo_link], *params[param_bypass], 0.f, *params[param_range]); -} - -void sidechaingate_audio_module::set_sample_rate(uint32_t sr) -{ - srate = sr; - gate.set_sample_rate(srate); - meters.set_sample_rate(srate); -} - -uint32_t sidechaingate_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) -{ - uint32_t orig_offset = offset; - uint32_t orig_numsamples = numsamples; - bool bypass = *params[param_bypass] > 0.5f; - numsamples += offset; - if(bypass) { - // everything bypassed - while(offset < numsamples) { - switch ((CalfScRoute)*params[param_sc_route]) { - case STEREO: - outs[0][offset] = ins[0][offset]; - outs[1][offset] = ins[1][offset]; - break; - case RIGHT_LEFT: - outs[0][offset] = ins[0][offset]; - outs[1][offset] = ins[0][offset]; - break; - case LEFT_RIGHT: - outs[0][offset] = ins[1][offset]; - outs[1][offset] = ins[1][offset]; - break; - } - outs[0][offset] = ins[0][offset]; - outs[1][offset] = ins[1][offset]; - ++offset; - } - // displays, too - meters.bypassed(params, orig_offset); - } else { - // process - - gate.update_curve(); - - while(offset < numsamples) { - // cycle through samples - float outL = 0.f; - float outR = 0.f; - float inL = ins[0][offset]; - float inR = ins[1][offset]; - // in level - inR *= *params[param_level_in]; - inL *= *params[param_level_in]; - - float leftAC = inL; - float rightAC = inR; - float leftSC = inL; - float rightSC = inR; - float leftMC = inL; - float rightMC = inR; - - switch ((CalfScRoute)*params[param_sc_route]) { - case STEREO: - leftAC = inL; - rightAC = inR; - leftSC = inL; - rightSC = inR; - leftMC = inL; - rightMC = inR; - break; - case RIGHT_LEFT: - leftAC = inL; - rightAC = inL; - leftSC = inR; - rightSC = inR; - leftMC = inL; - rightMC = inL; - break; - case LEFT_RIGHT: - leftAC = inR; - rightAC = inR; - leftSC = inL; - rightSC = inL; - leftMC = inR; - rightMC = inR; - break; - } - - leftSC *= *params[param_sc_level]; - rightSC *= *params[param_sc_level]; - - switch ((CalfScModes)*params[param_sc_mode]) { - default: - case WIDEBAND: - gate.process(leftAC, rightAC, &leftSC, &rightSC); - leftMC = leftSC; - rightMC = rightSC; - break; - case HIGHGATE_WIDE: - case LOWGATE_WIDE: - case WEIGHTED_1: - case WEIGHTED_2: - case WEIGHTED_3: - case BANDPASS_2: - leftSC = f2L.process(f1L.process(leftSC)); - rightSC = f2R.process(f1R.process(rightSC)); - leftMC = leftSC; - rightMC = rightSC; - gate.process(leftAC, rightAC, &leftSC, &rightSC); - break; - case HIGHGATE_SPLIT: - leftSC = f2L.process(leftSC); - rightSC = f2R.process(rightSC); - leftMC = leftSC; - rightMC = rightSC; - gate.process(leftSC, rightSC, &leftSC, &rightSC); - leftAC = f1L.process(leftAC); - rightAC = f1R.process(rightAC); - leftAC += leftSC; - rightAC += rightSC; - break; - case LOWGATE_SPLIT: - leftSC = f1L.process(leftSC); - rightSC = f1R.process(rightSC); - leftMC = leftSC; - rightMC = rightSC; - gate.process(leftSC, rightSC, &leftSC, &rightSC); - leftAC = f2L.process(leftAC); - rightAC = f2R.process(rightAC); - leftAC += leftSC; - rightAC += rightSC; - break; - case BANDPASS_1: - leftSC = f1L.process(leftSC); - rightSC = f1R.process(rightSC); - leftMC = leftSC; - rightMC = rightSC; - gate.process(leftAC, rightAC, &leftSC, &rightSC); - break; - } - - if(*params[param_sc_listen] > 0.f) { - outL = leftMC; - outR = rightMC; - } else { - outL = leftAC; - outR = rightAC; - } - - // send to output - outs[0][offset] = outL; - outs[1][offset] = outR; - - // next sample - ++offset; - } // cycle trough samples - meters.process(params, ins, outs, orig_offset, orig_numsamples); - f1L.sanitize(); - f1R.sanitize(); - f2L.sanitize(); - f2R.sanitize(); - - } - // draw strip meter - if(bypass > 0.5f) { - if(params[param_gating] != NULL) { - *params[param_gating] = 1.0f; - } - } else { - if(params[param_gating] != NULL) { - *params[param_gating] = gate.get_expander_level(); - } - } - // whatever has to be returned x) - return outputs_mask; -} -bool sidechaingate_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const -{ - if (!is_active) - return false; - if (index == param_f1_freq && !subindex) { - context->set_line_width(1.5); - return ::get_graph(*this, subindex, data, points); - } else if(index == param_gating) { - return gate.get_graph(subindex, data, points, context); - } - return false; -} - -bool sidechaingate_audio_module::get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const -{ - if (!is_active) - return false; - if (index == param_gating) { - return gate.get_dot(subindex, x, y, size, context); - } - return false; -} - -bool sidechaingate_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const -{ - if (!is_active) - return false; - if (index == param_gating) { - return gate.get_gridline(subindex, pos, vertical, legend, context); - } else { - return get_freq_gridline(subindex, pos, vertical, legend, context); - } -// return false; -} - -int sidechaingate_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const -{ - if (!is_active) - return false; - if(index == param_gating) { - return gate.get_changed_offsets(generation, subindex_graph, subindex_dot, subindex_gridline); - } else { - // (fabs(inertia_cutoff.get_last() - old_cutoff) + 100 * fabs(inertia_resonance.get_last() - old_resonance) + fabs(*params[par_mode] - old_mode) > 0.1f) - if (*params[param_f1_freq] != f1_freq_old1 - or *params[param_f2_freq] != f2_freq_old1 - or *params[param_f1_level] != f1_level_old1 - or *params[param_f2_level] != f2_level_old1 - or *params[param_sc_mode] !=sc_mode_old1) - { - f1_freq_old1 = *params[param_f1_freq]; - f2_freq_old1 = *params[param_f2_freq]; - f1_level_old1 = *params[param_f1_level]; - f2_level_old1 = *params[param_f2_level]; - sc_mode_old1 = (CalfScModes)*params[param_sc_mode]; - last_generation++; - subindex_graph = 0; - subindex_dot = INT_MAX; - subindex_gridline = INT_MAX; - } - else { - subindex_graph = 0; - subindex_dot = subindex_gridline = generation ? INT_MAX : 0; - } - if (generation == last_calculated_generation) - subindex_graph = INT_MAX; - return last_generation; - } - return false; -} - - -/// Multiband Compressor by Markus Schmidt -/// -/// This module splits the signal in four different bands -/// and sends them through multiple filters (implemented by -/// Krzysztof). They are processed by a compressing routine -/// (implemented by Thor) afterwards and summed up to the -/// final output again. -/////////////////////////////////////////////////////////////////////////////////////////////// - -multibandgate_audio_module::multibandgate_audio_module() -{ - is_active = false; - srate = 0; - // zero all displays - clip_inL = 0.f; - clip_inR = 0.f; - clip_outL = 0.f; - clip_outR = 0.f; - meter_inL = 0.f; - meter_inR = 0.f; - meter_outL = 0.f; - meter_outR = 0.f; - for(int i = 0; i < strips - 1; i ++) { - freq_old[i] = -1; - sep_old[i] = -1; - q_old[i] = -1; - } - mode_old = -1; -} - -void multibandgate_audio_module::activate() -{ - is_active = true; - // set all filters and strips - params_changed(); - // activate all strips - for (int j = 0; j < strips; j ++) { - gate[j].activate(); - gate[j].id = j; - } -} - -void multibandgate_audio_module::deactivate() -{ - is_active = false; - // deactivate all strips - for (int j = 0; j < strips; j ++) { - gate[j].deactivate(); - } -} - -void multibandgate_audio_module::params_changed() -{ - // determine mute/solo states - solo[0] = *params[param_solo0] > 0.f ? true : false; - solo[1] = *params[param_solo1] > 0.f ? true : false; - solo[2] = *params[param_solo2] > 0.f ? true : false; - solo[3] = *params[param_solo3] > 0.f ? true : false; - no_solo = (*params[param_solo0] > 0.f || - *params[param_solo1] > 0.f || - *params[param_solo2] > 0.f || - *params[param_solo3] > 0.f) ? false : true; - int i; - int j1; - switch(mode) { - case 0: - default: - j1 = 0; - break; - case 1: - j1 = 2; - break; - } - // set the params of all filters - if(*params[param_freq0] != freq_old[0] or *params[param_sep0] != sep_old[0] or *params[param_q0] != q_old[0] or *params[param_mode] != mode_old) { - lpL[0][0].set_lp_rbj((float)(*params[param_freq0] * (1 - *params[param_sep0])), *params[param_q0], (float)srate); - hpL[0][0].set_hp_rbj((float)(*params[param_freq0] * (1 + *params[param_sep0])), *params[param_q0], (float)srate); - lpR[0][0].copy_coeffs(lpL[0][0]); - hpR[0][0].copy_coeffs(hpL[0][0]); - for(i = 1; i <= j1; i++) { - lpL[0][i].copy_coeffs(lpL[0][0]); - hpL[0][i].copy_coeffs(hpL[0][0]); - lpR[0][i].copy_coeffs(lpL[0][0]); - hpR[0][i].copy_coeffs(hpL[0][0]); - } - freq_old[0] = *params[param_freq0]; - sep_old[0] = *params[param_sep0]; - q_old[0] = *params[param_q0]; - } - if(*params[param_freq1] != freq_old[1] or *params[param_sep1] != sep_old[1] or *params[param_q1] != q_old[1] or *params[param_mode] != mode_old) { - lpL[1][0].set_lp_rbj((float)(*params[param_freq1] * (1 - *params[param_sep1])), *params[param_q1], (float)srate); - hpL[1][0].set_hp_rbj((float)(*params[param_freq1] * (1 + *params[param_sep1])), *params[param_q1], (float)srate); - lpR[1][0].copy_coeffs(lpL[1][0]); - hpR[1][0].copy_coeffs(hpL[1][0]); - for(i = 1; i <= j1; i++) { - lpL[1][i].copy_coeffs(lpL[1][0]); - hpL[1][i].copy_coeffs(hpL[1][0]); - lpR[1][i].copy_coeffs(lpL[1][0]); - hpR[1][i].copy_coeffs(hpL[1][0]); - } - freq_old[1] = *params[param_freq1]; - sep_old[1] = *params[param_sep1]; - q_old[1] = *params[param_q1]; - } - if(*params[param_freq2] != freq_old[2] or *params[param_sep2] != sep_old[2] or *params[param_q2] != q_old[2] or *params[param_mode] != mode_old) { - lpL[2][0].set_lp_rbj((float)(*params[param_freq2] * (1 - *params[param_sep2])), *params[param_q2], (float)srate); - hpL[2][0].set_hp_rbj((float)(*params[param_freq2] * (1 + *params[param_sep2])), *params[param_q2], (float)srate); - lpR[2][0].copy_coeffs(lpL[2][0]); - hpR[2][0].copy_coeffs(hpL[2][0]); - for(i = 1; i <= j1; i++) { - lpL[2][i].copy_coeffs(lpL[2][0]); - hpL[2][i].copy_coeffs(hpL[2][0]); - lpR[2][i].copy_coeffs(lpL[2][0]); - hpR[2][i].copy_coeffs(hpL[2][0]); - } - freq_old[2] = *params[param_freq2]; - sep_old[2] = *params[param_sep2]; - q_old[2] = *params[param_q2]; - } - // set the params of all strips - gate[0].set_params(*params[param_attack0], *params[param_release0], *params[param_threshold0], *params[param_ratio0], *params[param_knee0], *params[param_makeup0], *params[param_detection0], 1.f, *params[param_bypass0], !(solo[0] || no_solo), *params[param_range0]); - gate[1].set_params(*params[param_attack1], *params[param_release1], *params[param_threshold1], *params[param_ratio1], *params[param_knee1], *params[param_makeup1], *params[param_detection1], 1.f, *params[param_bypass1], !(solo[1] || no_solo), *params[param_range1]); - gate[2].set_params(*params[param_attack2], *params[param_release2], *params[param_threshold2], *params[param_ratio2], *params[param_knee2], *params[param_makeup2], *params[param_detection2], 1.f, *params[param_bypass2], !(solo[2] || no_solo), *params[param_range2]); - gate[3].set_params(*params[param_attack3], *params[param_release3], *params[param_threshold3], *params[param_ratio3], *params[param_knee3], *params[param_makeup3], *params[param_detection3], 1.f, *params[param_bypass3], !(solo[3] || no_solo), *params[param_range3]); -} - -void multibandgate_audio_module::set_sample_rate(uint32_t sr) -{ - srate = sr; - // set srate of all strips - for (int j = 0; j < strips; j ++) { - gate[j].set_sample_rate(srate); - } -} - -#define BYPASSED_GATING(index) \ - if(params[param_gating##index] != NULL) \ - *params[param_gating##index] = 1.0; \ - if(params[param_output##index] != NULL) \ - *params[param_output##index] = 0.0; - -#define ACTIVE_GATING(index) \ - if(params[param_gating##index] != NULL) \ - *params[param_gating##index] = gate[index].get_expander_level(); \ - if(params[param_output##index] != NULL) \ - *params[param_output##index] = gate[index].get_output_level(); - -uint32_t multibandgate_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) -{ - bool bypass = *params[param_bypass] > 0.5f; - numsamples += offset; - for (int i = 0; i < strips; i++) - gate[i].update_curve(); - if(bypass) { - // everything bypassed - while(offset < numsamples) { - outs[0][offset] = ins[0][offset]; - outs[1][offset] = ins[1][offset]; - ++offset; - } - // displays, too - clip_inL = 0.f; - clip_inR = 0.f; - clip_outL = 0.f; - clip_outR = 0.f; - meter_inL = 0.f; - meter_inR = 0.f; - meter_outL = 0.f; - meter_outR = 0.f; - } else { - // process all strips - - // let meters fall a bit - clip_inL -= std::min(clip_inL, numsamples); - clip_inR -= std::min(clip_inR, numsamples); - clip_outL -= std::min(clip_outL, numsamples); - clip_outR -= std::min(clip_outR, numsamples); - meter_inL = 0.f; - meter_inR = 0.f; - meter_outL = 0.f; - meter_outR = 0.f; - while(offset < numsamples) { - // cycle through samples - float inL = ins[0][offset]; - float inR = ins[1][offset]; - // in level - inR *= *params[param_level_in]; - inL *= *params[param_level_in]; - // out vars - float outL = 0.f; - float outR = 0.f; - int j1; - for (int i = 0; i < strips; i ++) { - // cycle trough strips - if (solo[i] || no_solo) { - // strip unmuted - float left = inL; - float right = inR; - // send trough filters - switch(mode) { - case 0: - default: - j1 = 0; - break; - case 1: - j1 = 2; - break; - } - for (int j = 0; j <= j1; j++){ - if(i + 1 < strips) { - left = lpL[i][j].process(left); - right = lpR[i][j].process(right); - lpL[i][j].sanitize(); - lpR[i][j].sanitize(); - } - if(i - 1 >= 0) { - left = hpL[i - 1][j].process(left); - right = hpR[i - 1][j].process(right); - hpL[i - 1][j].sanitize(); - hpR[i - 1][j].sanitize(); - } - } - // process gain reduction - gate[i].process(left, right); - // sum up output - outL += left; - outR += right; - } else { - // strip muted - - } - - - } // process single strip - - // even out filters gain reduction - // 3dB - levelled manually (based on default sep and q settings) - switch(mode) { - case 0: - outL *= 1.414213562; - outR *= 1.414213562; - break; - case 1: - outL *= 0.88; - outR *= 0.88; - break; - } - - // out level - outL *= *params[param_level_out]; - outR *= *params[param_level_out]; - - // send to output - outs[0][offset] = outL; - outs[1][offset] = outR; - - // clip LED's - if(inL > 1.f) { - clip_inL = srate >> 3; - } - if(inR > 1.f) { - clip_inR = srate >> 3; - } - if(outL > 1.f) { - clip_outL = srate >> 3; - } - if(outR > 1.f) { - clip_outR = srate >> 3; - } - // set up in / out meters - if(inL > meter_inL) { - meter_inL = inL; - } - if(inR > meter_inR) { - meter_inR = inR; - } - if(outL > meter_outL) { - meter_outL = outL; - } - if(outR > meter_outR) { - meter_outR = outR; - } - // next sample - ++offset; - } // cycle trough samples - - } // process all strips (no bypass) - - // draw meters - SET_IF_CONNECTED(clip_inL); - SET_IF_CONNECTED(clip_inR); - SET_IF_CONNECTED(clip_outL); - SET_IF_CONNECTED(clip_outR); - SET_IF_CONNECTED(meter_inL); - SET_IF_CONNECTED(meter_inR); - SET_IF_CONNECTED(meter_outL); - SET_IF_CONNECTED(meter_outR); - // draw strip meters - if(bypass > 0.5f) { - BYPASSED_GATING(0) - BYPASSED_GATING(1) - BYPASSED_GATING(2) - BYPASSED_GATING(3) - } else { - ACTIVE_GATING(0) - ACTIVE_GATING(1) - ACTIVE_GATING(2) - ACTIVE_GATING(3) - } - // whatever has to be returned x) - return outputs_mask; -} - -const expander_audio_module *multibandgate_audio_module::get_strip_by_param_index(int index) const -{ - // let's handle by the corresponding strip - switch (index) { - case param_gating0: - return &gate[0]; - case param_gating1: - return &gate[1]; - case param_gating2: - return &gate[2]; - case param_gating3: - return &gate[3]; - } - return NULL; -} - -bool multibandgate_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const -{ - const expander_audio_module *m = get_strip_by_param_index(index); - if (m) - return m->get_graph(subindex, data, points, context); - return false; -} - -bool multibandgate_audio_module::get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const -{ - const expander_audio_module *m = get_strip_by_param_index(index); - if (m) - return m->get_dot(subindex, x, y, size, context); - return false; -} - -bool multibandgate_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const -{ - const expander_audio_module *m = get_strip_by_param_index(index); - if (m) - return m->get_gridline(subindex, pos, vertical, legend, context); - return false; -} - -int multibandgate_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const -{ - const expander_audio_module *m = get_strip_by_param_index(index); - if (m) - return m->get_changed_offsets(generation, subindex_graph, subindex_dot, subindex_gridline); - return 0; -} - - -/// Gain reduction module by Thor -/// All functions of this module are originally written -/// by Thor, while some features have been stripped (mainly stereo linking -/// and frequency correction as implemented in Sidechain Compressor above) -/// To save some CPU. -//////////////////////////////////////////////////////////////////////////////// -gain_reduction_audio_module::gain_reduction_audio_module() -{ - is_active = false; - srate = 0; - last_generation = 0; - old_threshold = 0.f; - old_ratio = 0.f; - old_knee = 0.f; - old_makeup = 0.f; - old_detection = 0.f; - old_bypass = 0.f; - old_mute = 0.f; - linSlope = 0.f; - attack = 0.f; - release = 0.f; - detection = -1; - stereo_link = -1; - threshold = -1; - ratio = -1; - knee = -1; - makeup = -1; - bypass = -1; - mute = -1; -} - -void gain_reduction_audio_module::activate() -{ - is_active = true; - linSlope = 0.f; - meter_out = 0.f; - meter_comp = 1.f; - float l, r; - l = r = 0.f; - float byp = bypass; - bypass = 0.0; - process(l, r, 0, 0); - bypass = byp; -} - -void gain_reduction_audio_module::deactivate() -{ - is_active = false; -} - -void gain_reduction_audio_module::update_curve() -{ - float linThreshold = threshold; - float linKneeSqrt = sqrt(knee); - linKneeStart = linThreshold / linKneeSqrt; - adjKneeStart = linKneeStart*linKneeStart; - float linKneeStop = linThreshold * linKneeSqrt; - thres = log(linThreshold); - kneeStart = log(linKneeStart); - kneeStop = log(linKneeStop); - compressedKneeStop = (kneeStop - thres) / ratio + thres; -} - -void gain_reduction_audio_module::process(float &left, float &right, const float *det_left, const float *det_right) -{ - if(!det_left) { - det_left = &left; - } - if(!det_right) { - det_right = &right; - } - if(bypass < 0.5f) { - // this routine is mainly copied from thor's compressor module - // greatest sounding compressor I've heard! - bool rms = (detection == 0); - bool average = (stereo_link == 0); - float attack_coeff = std::min(1.f, 1.f / (attack * srate / 4000.f)); - float release_coeff = std::min(1.f, 1.f / (release * srate / 4000.f)); - - float absample = average ? (fabs(*det_left) + fabs(*det_right)) * 0.5f : std::max(fabs(*det_left), fabs(*det_right)); - if(rms) absample *= absample; - - dsp::sanitize(linSlope); - - linSlope += (absample - linSlope) * (absample > linSlope ? attack_coeff : release_coeff); - float gain = 1.f; - if(linSlope > 0.f) { - gain = output_gain(linSlope, rms); - } - - left *= gain * makeup; - right *= gain * makeup; - meter_out = std::max(fabs(left), fabs(right));; - meter_comp = gain; - detected = rms ? sqrt(linSlope) : linSlope; - } -} - -float gain_reduction_audio_module::output_level(float slope) const { - return slope * output_gain(slope, false) * makeup; -} - -float gain_reduction_audio_module::output_gain(float linSlope, bool rms) const { - //this calculation is also thor's work - if(linSlope > (rms ? adjKneeStart : linKneeStart)) { - float slope = log(linSlope); - if(rms) slope *= 0.5f; - - float gain = 0.f; - float delta = 0.f; - if(IS_FAKE_INFINITY(ratio)) { - gain = thres; - delta = 0.f; - } else { - gain = (slope - thres) / ratio + thres; - delta = 1.f / ratio; - } - - if(knee > 1.f && slope < kneeStop) { - gain = hermite_interpolation(slope, kneeStart, kneeStop, kneeStart, compressedKneeStop, 1.f, delta); - } - - return exp(gain - slope); - } - - return 1.f; -} - -void gain_reduction_audio_module::set_sample_rate(uint32_t sr) -{ - srate = sr; -} -void gain_reduction_audio_module::set_params(float att, float rel, float thr, float rat, float kn, float mak, float det, float stl, float byp, float mu) -{ - // set all params - attack = att; - release = rel; - threshold = thr; - ratio = rat; - knee = kn; - makeup = mak; - detection = det; - stereo_link = stl; - bypass = byp; - mute = mu; - if(mute > 0.f) { - meter_out = 0.f; - meter_comp = 1.f; - } -} -float gain_reduction_audio_module::get_output_level() { - // returns output level (max(left, right)) - return meter_out; -} -float gain_reduction_audio_module::get_comp_level() { - // returns amount of compression - return meter_comp; -} - -bool gain_reduction_audio_module::get_graph(int subindex, float *data, int points, cairo_iface *context) const -{ - if (!is_active) - return false; - if (subindex > 1) // 1 - return false; - for (int i = 0; i < points; i++) - { - float input = dB_grid_inv(-1.0 + i * 2.0 / (points - 1)); - if (subindex == 0) - data[i] = dB_grid(input); - else { - float output = output_level(input); - data[i] = dB_grid(output); - } - } - if (subindex == (bypass > 0.5f ? 1 : 0) or mute > 0.1f) - context->set_source_rgba(0.35, 0.4, 0.2, 0.3); - else { - context->set_source_rgba(0.35, 0.4, 0.2, 1); - context->set_line_width(1.5); - } - return true; -} - -bool gain_reduction_audio_module::get_dot(int subindex, float &x, float &y, int &size, cairo_iface *context) const -{ - if (!is_active) - return false; - if (!subindex) - { - if(bypass > 0.5f or mute > 0.f) { - return false; - } else { - bool rms = (detection == 0); - float det = rms ? sqrt(detected) : detected; - x = 0.5 + 0.5 * dB_grid(det); - y = dB_grid(bypass > 0.5f or mute > 0.f ? det : output_level(det)); - return true; - } - } - return false; -} - -bool gain_reduction_audio_module::get_gridline(int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const -{ - bool tmp; - vertical = (subindex & 1) != 0; - bool result = get_freq_gridline(subindex >> 1, pos, tmp, legend, context, false); - if (result && vertical) { - if ((subindex & 4) && !legend.empty()) { - legend = ""; - } - else { - size_t pos = legend.find(" dB"); - if (pos != std::string::npos) - legend.erase(pos); - } - pos = 0.5 + 0.5 * pos; - } - return result; -} - -int gain_reduction_audio_module::get_changed_offsets(int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const -{ - subindex_graph = 0; - subindex_dot = 0; - subindex_gridline = generation ? INT_MAX : 0; - - if (fabs(threshold-old_threshold) + fabs(ratio - old_ratio) + fabs(knee - old_knee) + fabs(makeup - old_makeup) + fabs(detection - old_detection) + fabs(bypass - old_bypass) + fabs(mute - old_mute) > 0.000001f) - { - old_threshold = threshold; - old_ratio = ratio; - old_knee = knee; - old_makeup = makeup; - old_detection = detection; - old_bypass = bypass; - old_mute = mute; - last_generation++; - } - - if (generation == last_generation) - subindex_graph = 2; - return last_generation; -} - - -/// Gate module by Damien -/// All functions of this module are originally written -/// by Damien, while some features have been stripped (mainly stereo linking -/// and frequency correction as implemented in Sidechain Gate above) -/// To save some CPU. -//////////////////////////////////////////////////////////////////////////////// -expander_audio_module::expander_audio_module() -{ - is_active = false; - srate = 0; - last_generation = 0; - range = -1.f; - threshold = -1.f; - ratio = -1.f; - knee = -1.f; - makeup = -1.f; - detection = -1.f; - bypass = -1.f; - mute = -1.f; - stereo_link = -1.f; - old_range = 0.f; - old_threshold = 0.f; - old_ratio = 0.f; - old_knee = 0.f; - old_makeup = 0.f; - old_detection = 0.f; - old_bypass = 0.f; - old_mute = 0.f; - old_trigger = 0.f; - old_stereo_link = 0.f; - linSlope = -1; - linKneeStop = 0; -} - -void expander_audio_module::activate() -{ - is_active = true; - linSlope = 0.f; - meter_out = 0.f; - meter_gate = 1.f; - float l, r; - l = r = 0.f; - float byp = bypass; - bypass = 0.0; - process(l, r); - bypass = byp; -} - -void expander_audio_module::deactivate() -{ - is_active = false; -} - -void expander_audio_module::update_curve() -{ - bool rms = (detection == 0); - float linThreshold = threshold; - if (rms) - linThreshold = linThreshold * linThreshold; - attack_coeff = std::min(1.f, 1.f / (attack * srate / 4000.f)); - release_coeff = std::min(1.f, 1.f / (release * srate / 4000.f)); - float linKneeSqrt = sqrt(knee); - linKneeStart = linThreshold / linKneeSqrt; - adjKneeStart = linKneeStart*linKneeStart; - linKneeStop = linThreshold * linKneeSqrt; - thres = log(linThreshold); - kneeStart = log(linKneeStart); - kneeStop = log(linKneeStop); - compressedKneeStop = (kneeStop - thres) / ratio + thres; -} - -void expander_audio_module::process(float &left, float &right, const float *det_left, const float *det_right) -{ - if(!det_left) { - det_left = &left; - } - if(!det_right) { - det_right = &right; - } - if(bypass < 0.5f) { - // this routine is mainly copied from Damien's expander module based on Thor's compressor - bool rms = (detection == 0); - bool average = (stereo_link == 0); - float absample = average ? (fabs(*det_left) + fabs(*det_right)) * 0.5f : std::max(fabs(*det_left), fabs(*det_right)); - if(rms) absample *= absample; - - dsp::sanitize(linSlope); - - linSlope += (absample - linSlope) * (absample > linSlope ? attack_coeff : release_coeff); - float gain = 1.f; - if(linSlope > 0.f) { - gain = output_gain(linSlope, rms); - } - left *= gain * makeup; - right *= gain * makeup; - meter_out = std::max(fabs(left), fabs(right)); - meter_gate = gain; - detected = linSlope; - } -} - -float expander_audio_module::output_level(float slope) const { - bool rms = (detection == 0); - return slope * output_gain(rms ? slope*slope : slope, rms) * makeup; -} - -float expander_audio_module::output_gain(float linSlope, bool rms) const { - //this calculation is also Damiens's work based on Thor's compressor - if(linSlope < linKneeStop) { - float slope = log(linSlope); - //float tratio = rms ? sqrt(ratio) : ratio; - float tratio = ratio; - float gain = 0.f; - float delta = 0.f; - if(IS_FAKE_INFINITY(ratio)) - tratio = 1000.f; - gain = (slope-thres) * tratio + thres; - delta = tratio; - - if(knee > 1.f && slope > kneeStart ) { - gain = dsp::hermite_interpolation(slope, kneeStart, kneeStop, ((kneeStart - thres) * tratio + thres), kneeStop, delta,1.f); - } - return std::max(range, expf(gain-slope)); - } - return 1.f; -} - -void expander_audio_module::set_sample_rate(uint32_t sr) -{ - srate = sr; -} -void expander_audio_module::set_params(float att, float rel, float thr, float rat, float kn, float mak, float det, float stl, float byp, float mu, float ran) -{ - // set all params - attack = att; - release = rel; - threshold = thr; - ratio = rat; - knee = kn; - makeup = mak; - detection = det; - stereo_link = stl; - bypass = byp; - mute = mu; - range = ran; - if(mute > 0.f) { - meter_out = 0.f; - meter_gate = 1.f; - } -} -float expander_audio_module::get_output_level() { - // returns output level (max(left, right)) - return meter_out; -} -float expander_audio_module::get_expander_level() { - // returns amount of gating - return meter_gate; -} - -bool expander_audio_module::get_graph(int subindex, float *data, int points, cairo_iface *context) const -{ - if (!is_active) - return false; - if (subindex > 1) // 1 - return false; - for (int i = 0; i < points; i++) - { - float input = dB_grid_inv(-1.0 + i * 2.0 / (points - 1)); - if (subindex == 0) - data[i] = dB_grid(input); - else { - float output = output_level(input); - data[i] = dB_grid(output); - } - } - if (subindex == (bypass > 0.5f ? 1 : 0) or mute > 0.1f) - context->set_source_rgba(0.35, 0.4, 0.2, 0.3); - else { - context->set_source_rgba(0.35, 0.4, 0.2, 1); - context->set_line_width(1.5); - } - return true; -} - -bool expander_audio_module::get_dot(int subindex, float &x, float &y, int &size, cairo_iface *context) const -{ - if (!is_active) - return false; - if (!subindex) - { - if(bypass > 0.5f or mute > 0.f) { - return false; - } else { - bool rms = (detection == 0); - float det = rms ? sqrt(detected) : detected; - x = 0.5 + 0.5 * dB_grid(det); - y = dB_grid(bypass > 0.5f or mute > 0.f ? det : output_level(det)); - return true; - } - } - return false; -} - -bool expander_audio_module::get_gridline(int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const -{ - bool tmp; - vertical = (subindex & 1) != 0; - bool result = get_freq_gridline(subindex >> 1, pos, tmp, legend, context, false); - if (result && vertical) { - if ((subindex & 4) && !legend.empty()) { - legend = ""; - } - else { - size_t pos = legend.find(" dB"); - if (pos != std::string::npos) - legend.erase(pos); - } - pos = 0.5 + 0.5 * pos; - } - return result; -} - -int expander_audio_module::get_changed_offsets(int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const -{ - subindex_graph = 0; - subindex_dot = 0; - subindex_gridline = generation ? INT_MAX : 0; - - if (fabs(range-old_range) + fabs(threshold-old_threshold) + fabs(ratio - old_ratio) + fabs(knee - old_knee) + fabs(makeup - old_makeup) + fabs(detection - old_detection) + fabs(bypass - old_bypass) + fabs(mute - old_mute) > 0.000001f) - { - old_range = range; - old_threshold = threshold; - old_ratio = ratio; - old_knee = knee; - old_makeup = makeup; - old_detection = detection; - old_bypass = bypass; - old_mute = mute; - last_generation++; - } - if (generation == last_generation) - subindex_graph = 2; - return last_generation; -} diff --git a/plugins/LadspaEffect/calf/src/modules_dist.cpp b/plugins/LadspaEffect/calf/src/modules_dist.cpp deleted file mode 100644 index ddc147db73e..00000000000 --- a/plugins/LadspaEffect/calf/src/modules_dist.cpp +++ /dev/null @@ -1,644 +0,0 @@ -/* Calf DSP plugin pack - * Distortion related plugins - * - * Copyright (C) 2001-2010 Krzysztof Foltman, Markus Schmidt, Thor Harald Johansen and others - * - * 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 02110-1301 USA - */ -#include -#include -#include -#include - -using namespace dsp; -using namespace calf_plugins; - -/// Saturator Band by Markus Schmidt -/// -/// This module is based on Krzysztof's filters and Tom Szilagyi's distortion routine. -/// It provides a blendable saturation stage followed by a highpass, a lowpass and a peak filter -/////////////////////////////////////////////////////////////////////////////////////////////// - -saturator_audio_module::saturator_audio_module() -{ - is_active = false; - srate = 0; - meter_drive = 0.f; - lp_pre_freq_old = -1; - hp_pre_freq_old = -1; - lp_post_freq_old = -1; - hp_post_freq_old = -1; - p_freq_old = -1; - p_level_old = -1; -} - -void saturator_audio_module::activate() -{ - is_active = true; - // set all filters - params_changed(); - meters.reset(); - meter_drive = 0.f; -} -void saturator_audio_module::deactivate() -{ - is_active = false; -} - -void saturator_audio_module::params_changed() -{ - // set the params of all filters - if(*params[param_lp_pre_freq] != lp_pre_freq_old) { - lp[0][0].set_lp_rbj(*params[param_lp_pre_freq], 0.707, (float)srate); - if(in_count > 1 && out_count > 1) - lp[1][0].copy_coeffs(lp[0][0]); - lp[0][1].copy_coeffs(lp[0][0]); - if(in_count > 1 && out_count > 1) - lp[1][1].copy_coeffs(lp[0][0]); - lp_pre_freq_old = *params[param_lp_pre_freq]; - } - if(*params[param_hp_pre_freq] != hp_pre_freq_old) { - hp[0][0].set_hp_rbj(*params[param_hp_pre_freq], 0.707, (float)srate); - if(in_count > 1 && out_count > 1) - hp[1][0].copy_coeffs(hp[0][0]); - hp[0][1].copy_coeffs(hp[0][0]); - if(in_count > 1 && out_count > 1) - hp[1][1].copy_coeffs(hp[0][0]); - hp_pre_freq_old = *params[param_hp_pre_freq]; - } - if(*params[param_lp_post_freq] != lp_post_freq_old) { - lp[0][2].set_lp_rbj(*params[param_lp_post_freq], 0.707, (float)srate); - if(in_count > 1 && out_count > 1) - lp[1][2].copy_coeffs(lp[0][2]); - lp[0][3].copy_coeffs(lp[0][2]); - if(in_count > 1 && out_count > 1) - lp[1][3].copy_coeffs(lp[0][2]); - lp_post_freq_old = *params[param_lp_post_freq]; - } - if(*params[param_hp_post_freq] != hp_post_freq_old) { - hp[0][2].set_hp_rbj(*params[param_hp_post_freq], 0.707, (float)srate); - if(in_count > 1 && out_count > 1) - hp[1][2].copy_coeffs(hp[0][2]); - hp[0][3].copy_coeffs(hp[0][2]); - if(in_count > 1 && out_count > 1) - hp[1][3].copy_coeffs(hp[0][2]); - hp_post_freq_old = *params[param_hp_post_freq]; - } - if(*params[param_p_freq] != p_freq_old or *params[param_p_level] != p_level_old or *params[param_p_q] != p_q_old) { - p[0].set_peakeq_rbj((float)*params[param_p_freq], (float)*params[param_p_q], (float)*params[param_p_level], (float)srate); - if(in_count > 1 && out_count > 1) - p[1].copy_coeffs(p[0]); - p_freq_old = *params[param_p_freq]; - p_level_old = *params[param_p_level]; - p_q_old = *params[param_p_q]; - } - // set distortion - dist[0].set_params(*params[param_blend], *params[param_drive]); - if(in_count > 1 && out_count > 1) - dist[1].set_params(*params[param_blend], *params[param_drive]); -} - -void saturator_audio_module::set_sample_rate(uint32_t sr) -{ - srate = sr; - dist[0].set_sample_rate(sr); - if(in_count > 1 && out_count > 1) - dist[1].set_sample_rate(sr); - meters.set_sample_rate(srate); -} - -uint32_t saturator_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) -{ - bool bypass = *params[param_bypass] > 0.5f; - uint32_t orig_offset = offset; - uint32_t orig_numsamples = numsamples; - numsamples += offset; - if(bypass) { - // everything bypassed - while(offset < numsamples) { - if(in_count > 1 && out_count > 1) { - outs[0][offset] = ins[0][offset]; - outs[1][offset] = ins[1][offset]; - } else if(in_count > 1) { - outs[0][offset] = (ins[0][offset] + ins[1][offset]) / 2; - } else if(out_count > 1) { - outs[0][offset] = ins[0][offset]; - outs[1][offset] = ins[0][offset]; - } else { - outs[0][offset] = ins[0][offset]; - } - ++offset; - } - meters.bypassed(params, orig_numsamples); - } else { - meter_drive = 0.f; - float in_avg[2] = {0.f, 0.f}; - float out_avg[2] = {0.f, 0.f}; - float tube_avg = 0.f; - // process - while(offset < numsamples) { - // cycle through samples - float out[2], in[2] = {0.f, 0.f}; - int c = 0; - - if(in_count > 1 && out_count > 1) { - // stereo in/stereo out - // handle full stereo - in[0] = ins[0][offset]; - in[1] = ins[1][offset]; - c = 2; - } else { - // in and/or out mono - // handle mono - in[0] = ins[0][offset]; - in[1] = in[0]; - c = 1; - } - - float proc[2]; - proc[0] = in[0] * *params[param_level_in]; - proc[1] = in[1] * *params[param_level_in]; - - float onedivlevelin = 1.0 / *params[param_level_in]; - - for (int i = 0; i < c; ++i) { - // all pre filters in chain - proc[i] = lp[i][1].process(lp[i][0].process(proc[i])); - proc[i] = hp[i][1].process(hp[i][0].process(proc[i])); - - // get average for display purposes before... - in_avg[i] += fabs(pow(proc[i], 2.f)); - - // ...saturate... - proc[i] = dist[i].process(proc[i]); - - // ...and get average after... - out_avg[i] += fabs(pow(proc[i], 2.f)); - - // tone control - proc[i] = p[i].process(proc[i]); - - // all post filters in chain - proc[i] = lp[i][2].process(lp[i][3].process(proc[i])); - proc[i] = hp[i][2].process(hp[i][3].process(proc[i])); - - //subtract gain - proc[i] *= onedivlevelin; - } - - if(in_count > 1 && out_count > 1) { - // full stereo - out[0] = ((proc[0] * *params[param_mix]) + in[0] * (1 - *params[param_mix])) * *params[param_level_out]; - outs[0][offset] = out[0]; - out[1] = ((proc[1] * *params[param_mix]) + in[1] * (1 - *params[param_mix])) * *params[param_level_out]; - outs[1][offset] = out[1]; - } else if(out_count > 1) { - // mono -> pseudo stereo - out[0] = ((proc[0] * *params[param_mix]) + in[0] * (1 - *params[param_mix])) * *params[param_level_out]; - outs[0][offset] = out[0]; - out[1] = out[0]; - outs[1][offset] = out[1]; - } else { - // stereo -> mono - // or full mono - out[0] = ((proc[0] * *params[param_mix]) + in[0] * (1 - *params[param_mix])) * *params[param_level_out]; - outs[0][offset] = out[0]; - } - - // next sample - ++offset; - } // cycle trough samples - meters.process(params, ins, outs, orig_offset, orig_numsamples); - - tube_avg = (sqrt(std::max(out_avg[0], out_avg[1])) / numsamples) - (sqrt(std::max(in_avg[0], in_avg[1])) / numsamples); - meter_drive = (5.0f * fabs(tube_avg) * (float(*params[param_blend]) + 30.0f)); - // printf("out:%.6f in: %.6f avg: %.6f drv: %.3f\n", sqrt(std::max(out_avg[0], out_avg[1])) / numsamples, sqrt(std::max(in_avg[0], in_avg[1])) / numsamples, tube_avg, meter_drive); - // clean up - lp[0][0].sanitize(); - lp[1][0].sanitize(); - lp[0][1].sanitize(); - lp[1][1].sanitize(); - lp[0][2].sanitize(); - lp[1][2].sanitize(); - lp[0][3].sanitize(); - lp[1][3].sanitize(); - hp[0][0].sanitize(); - hp[1][0].sanitize(); - hp[0][1].sanitize(); - hp[1][1].sanitize(); - hp[0][2].sanitize(); - hp[1][2].sanitize(); - hp[0][3].sanitize(); - hp[1][3].sanitize(); - p[0].sanitize(); - p[1].sanitize(); - } - // draw meters - if(params[param_meter_drive] != NULL) { - *params[param_meter_drive] = meter_drive; - } - // whatever has to be returned x) - return outputs_mask; -} - -/// Exciter by Markus Schmidt -/// -/// This module is based on Krzysztof's filters and Tom Szilagyi's distortion routine. -/// It provides a blendable saturation stage followed by a highpass, a lowpass and a peak filter -/////////////////////////////////////////////////////////////////////////////////////////////// - -exciter_audio_module::exciter_audio_module() -{ - is_active = false; - srate = 0; - meter_drive = 0.f; -} - -void exciter_audio_module::activate() -{ - is_active = true; - // set all filters - params_changed(); -} - -void exciter_audio_module::deactivate() -{ - is_active = false; -} - -void exciter_audio_module::params_changed() -{ - // set the params of all filters - if(*params[param_freq] != freq_old) { - hp[0][0].set_hp_rbj(*params[param_freq], 0.707, (float)srate); - hp[0][1].copy_coeffs(hp[0][0]); - hp[0][2].copy_coeffs(hp[0][0]); - hp[0][3].copy_coeffs(hp[0][0]); - if(in_count > 1 && out_count > 1) { - hp[1][0].copy_coeffs(hp[0][0]); - hp[1][1].copy_coeffs(hp[0][0]); - hp[1][2].copy_coeffs(hp[0][0]); - hp[1][3].copy_coeffs(hp[0][0]); - } - freq_old = *params[param_freq]; - } - // set the params of all filters - if(*params[param_ceil] != ceil_old or *params[param_ceil_active] != ceil_active_old) { - lp[0][0].set_lp_rbj(*params[param_ceil], 0.707, (float)srate); - lp[0][1].copy_coeffs(lp[0][0]); - lp[1][0].copy_coeffs(lp[0][0]); - lp[1][1].copy_coeffs(lp[0][0]); - ceil_old = *params[param_ceil]; - ceil_active_old = *params[param_ceil_active]; - } - // set distortion - dist[0].set_params(*params[param_blend], *params[param_drive]); - if(in_count > 1 && out_count > 1) - dist[1].set_params(*params[param_blend], *params[param_drive]); -} - -void exciter_audio_module::set_sample_rate(uint32_t sr) -{ - srate = sr; - dist[0].set_sample_rate(sr); - if(in_count > 1 && out_count > 1) - dist[1].set_sample_rate(sr); - meters.set_sample_rate(srate); -} - -uint32_t exciter_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) -{ - uint32_t orig_offset = offset; - uint32_t orig_numsamples = numsamples; - bool bypass = *params[param_bypass] > 0.5f; - numsamples += offset; - if(bypass) { - // everything bypassed - while(offset < numsamples) { - if(in_count > 1 && out_count > 1) { - outs[0][offset] = ins[0][offset]; - outs[1][offset] = ins[1][offset]; - } else if(in_count > 1) { - outs[0][offset] = (ins[0][offset] + ins[1][offset]) / 2; - } else if(out_count > 1) { - outs[0][offset] = ins[0][offset]; - outs[1][offset] = ins[0][offset]; - } else { - outs[0][offset] = ins[0][offset]; - } - ++offset; - } - meters.bypassed(params, orig_numsamples); - // displays, too - meter_drive = 0.f; - } else { - - meter_drive = 0.f; - - float in2out = *params[param_listen] > 0.f ? 0.f : 1.f; - - // process - while(offset < numsamples) { - // cycle through samples - float out[2], in[2] = {0.f, 0.f}; - float maxDrive = 0.f; - int c = 0; - - if(in_count > 1 && out_count > 1) { - // stereo in/stereo out - // handle full stereo - in[0] = ins[0][offset]; - in[0] *= *params[param_level_in]; - in[1] = ins[1][offset]; - in[1] *= *params[param_level_in]; - c = 2; - } else { - // in and/or out mono - // handle mono - in[0] = ins[0][offset]; - in[0] *= *params[param_level_in]; - in[1] = in[0]; - c = 1; - } - - float proc[2]; - proc[0] = in[0]; - proc[1] = in[1]; - - for (int i = 0; i < c; ++i) { - // all pre filters in chain - proc[i] = hp[i][1].process(hp[i][0].process(proc[i])); - - // saturate - proc[i] = dist[i].process(proc[i]); - - // all post filters in chain - proc[i] = hp[i][2].process(hp[i][3].process(proc[i])); - - if(*params[param_ceil_active] > 0.5f) { - // all H/P post filters in chain - proc[i] = lp[i][0].process(lp[i][1].process(proc[i])); - - } - } - maxDrive = dist[0].get_distortion_level() * *params[param_amount]; - - if(in_count > 1 && out_count > 1) { - maxDrive = std::max(maxDrive, dist[1].get_distortion_level() * *params[param_amount]); - // full stereo - out[0] = (proc[0] * *params[param_amount] + in2out * in[0]) * *params[param_level_out]; - out[1] = (proc[1] * *params[param_amount] + in2out * in[1]) * *params[param_level_out]; - outs[0][offset] = out[0]; - outs[1][offset] = out[1]; - } else if(out_count > 1) { - // mono -> pseudo stereo - out[1] = out[0] = (proc[0] * *params[param_amount] + in2out * in[0]) * *params[param_level_out]; - outs[0][offset] = out[0]; - outs[1][offset] = out[1]; - } else { - // stereo -> mono - // or full mono - out[0] = (proc[0] * *params[param_amount] + in2out * in[0]) * *params[param_level_out]; - outs[0][offset] = out[0]; - } - - // set up in / out meters - if(maxDrive > meter_drive) { - meter_drive = maxDrive; - } - - // next sample - ++offset; - } // cycle trough samples - meters.process(params, ins, outs, orig_offset, orig_numsamples); - // clean up - hp[0][0].sanitize(); - hp[1][0].sanitize(); - hp[0][1].sanitize(); - hp[1][1].sanitize(); - hp[0][2].sanitize(); - hp[1][2].sanitize(); - hp[0][3].sanitize(); - hp[1][3].sanitize(); - } - // draw meters - if(params[param_meter_drive] != NULL) { - *params[param_meter_drive] = meter_drive; - } - // whatever has to be returned x) - return outputs_mask; -} - -/// Bass Enhancer by Markus Schmidt -/// -/// This module is based on Krzysztof's filters and Tom's distortion routine. -/// It sends the signal through a lowpass, saturates it and sends it through a lowpass again -/////////////////////////////////////////////////////////////////////////////////////////////// - -bassenhancer_audio_module::bassenhancer_audio_module() -{ - is_active = false; - srate = 0; - meters.reset(); - meter_drive = 0.f; -} - -void bassenhancer_audio_module::activate() -{ - is_active = true; - meters.reset(); - // set all filters - params_changed(); -} -void bassenhancer_audio_module::deactivate() -{ - is_active = false; -} - -void bassenhancer_audio_module::params_changed() -{ - // set the params of all filters - if(*params[param_freq] != freq_old) { - lp[0][0].set_lp_rbj(*params[param_freq], 0.707, (float)srate); - lp[0][1].copy_coeffs(lp[0][0]); - lp[0][2].copy_coeffs(lp[0][0]); - lp[0][3].copy_coeffs(lp[0][0]); - if(in_count > 1 && out_count > 1) { - lp[1][0].copy_coeffs(lp[0][0]); - lp[1][1].copy_coeffs(lp[0][0]); - lp[1][2].copy_coeffs(lp[0][0]); - lp[1][3].copy_coeffs(lp[0][0]); - } - freq_old = *params[param_freq]; - } - // set the params of all filters - if(*params[param_floor] != floor_old or *params[param_floor_active] != floor_active_old) { - hp[0][0].set_hp_rbj(*params[param_floor], 0.707, (float)srate); - hp[0][1].copy_coeffs(hp[0][0]); - hp[1][0].copy_coeffs(hp[0][0]); - hp[1][1].copy_coeffs(hp[0][0]); - floor_old = *params[param_floor]; - floor_active_old = *params[param_floor_active]; - } - // set distortion - dist[0].set_params(*params[param_blend], *params[param_drive]); - if(in_count > 1 && out_count > 1) - dist[1].set_params(*params[param_blend], *params[param_drive]); -} - -void bassenhancer_audio_module::set_sample_rate(uint32_t sr) -{ - srate = sr; - dist[0].set_sample_rate(sr); - if(in_count > 1 && out_count > 1) - dist[1].set_sample_rate(sr); - meters.set_sample_rate(srate); -} - -uint32_t bassenhancer_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) -{ - bool bypass = *params[param_bypass] > 0.5f; - uint32_t orig_offset = offset; - uint32_t orig_numsamples = numsamples; - numsamples += offset; - if(bypass) { - // everything bypassed - while(offset < numsamples) { - if(in_count > 1 && out_count > 1) { - outs[0][offset] = ins[0][offset]; - outs[1][offset] = ins[1][offset]; - } else if(in_count > 1) { - outs[0][offset] = (ins[0][offset] + ins[1][offset]) / 2; - } else if(out_count > 1) { - outs[0][offset] = ins[0][offset]; - outs[1][offset] = ins[0][offset]; - } else { - outs[0][offset] = ins[0][offset]; - } - ++offset; - } - // displays, too - meters.bypassed(params, orig_numsamples); - meter_drive = 0.f; - } else { - meter_drive = 0.f; - - // process - while(offset < numsamples) { - // cycle through samples - float out[2], in[2] = {0.f, 0.f}; - float maxDrive = 0.f; - int c = 0; - - if(in_count > 1 && out_count > 1) { - // stereo in/stereo out - // handle full stereo - in[0] = ins[0][offset]; - in[0] *= *params[param_level_in]; - in[1] = ins[1][offset]; - in[1] *= *params[param_level_in]; - c = 2; - } else { - // in and/or out mono - // handle mono - in[0] = ins[0][offset]; - in[0] *= *params[param_level_in]; - in[1] = in[0]; - c = 1; - } - - float proc[2]; - proc[0] = in[0]; - proc[1] = in[1]; - - for (int i = 0; i < c; ++i) { - // all pre filters in chain - proc[i] = lp[i][1].process(lp[i][0].process(proc[i])); - - // saturate - proc[i] = dist[i].process(proc[i]); - - // all post filters in chain - proc[i] = lp[i][2].process(lp[i][3].process(proc[i])); - - if(*params[param_floor_active] > 0.5f) { - // all H/P post filters in chain - proc[i] = hp[i][0].process(hp[i][1].process(proc[i])); - - } - } - - if(in_count > 1 && out_count > 1) { - // full stereo - if(*params[param_listen] > 0.f) - out[0] = proc[0] * *params[param_amount] * *params[param_level_out]; - else - out[0] = (proc[0] * *params[param_amount] + in[0]) * *params[param_level_out]; - outs[0][offset] = out[0]; - if(*params[param_listen] > 0.f) - out[1] = proc[1] * *params[param_amount] * *params[param_level_out]; - else - out[1] = (proc[1] * *params[param_amount] + in[1]) * *params[param_level_out]; - outs[1][offset] = out[1]; - maxDrive = std::max(dist[0].get_distortion_level() * *params[param_amount], - dist[1].get_distortion_level() * *params[param_amount]); - } else if(out_count > 1) { - // mono -> pseudo stereo - if(*params[param_listen] > 0.f) - out[0] = proc[0] * *params[param_amount] * *params[param_level_out]; - else - out[0] = (proc[0] * *params[param_amount] + in[0]) * *params[param_level_out]; - outs[0][offset] = out[0]; - out[1] = out[0]; - outs[1][offset] = out[1]; - maxDrive = dist[0].get_distortion_level() * *params[param_amount]; - } else { - // stereo -> mono - // or full mono - if(*params[param_listen] > 0.f) - out[0] = proc[0] * *params[param_amount] * *params[param_level_out]; - else - out[0] = (proc[0] * *params[param_amount] + in[0]) * *params[param_level_out]; - outs[0][offset] = out[0]; - maxDrive = dist[0].get_distortion_level() * *params[param_amount]; - } - - // set up in / out meters - if(maxDrive > meter_drive) { - meter_drive = maxDrive; - } - - // next sample - ++offset; - } // cycle trough samples - meters.process(params, ins, outs, orig_offset, orig_numsamples); - // clean up - lp[0][0].sanitize(); - lp[1][0].sanitize(); - lp[0][1].sanitize(); - lp[1][1].sanitize(); - lp[0][2].sanitize(); - lp[1][2].sanitize(); - lp[0][3].sanitize(); - lp[1][3].sanitize(); - } - // draw meters - if(params[param_meter_drive] != NULL) { - *params[param_meter_drive] = meter_drive; - } - // whatever has to be returned x) - return outputs_mask; -} diff --git a/plugins/LadspaEffect/calf/src/modules_eq.cpp b/plugins/LadspaEffect/calf/src/modules_eq.cpp deleted file mode 100644 index e3de22c2cb2..00000000000 --- a/plugins/LadspaEffect/calf/src/modules_eq.cpp +++ /dev/null @@ -1,343 +0,0 @@ -/* Calf DSP plugin pack - * Equalization related plugins - * - * Copyright (C) 2001-2010 Krzysztof Foltman, Markus Schmidt, Thor Harald Johansen and others - * - * 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 02110-1301 USA - */ -#include -#include -#include -#include - -using namespace dsp; -using namespace calf_plugins; - -/// Equalizer 12 Band by Markus Schmidt -/// -/// This module is based on Krzysztof's filters. It provides a couple -/// of different chained filters. -/////////////////////////////////////////////////////////////////////////////////////////////// - -template -equalizerNband_audio_module::equalizerNband_audio_module() -{ - is_active = false; - srate = 0; - last_generation = 0; - hp_freq_old = lp_freq_old = 0; - hs_freq_old = ls_freq_old = 0; - hs_level_old = ls_level_old = 0; - for (int i = 0; i < AM::PeakBands; i++) - { - p_freq_old[i] = 0; - p_level_old[i] = 0; - p_q_old[i] = 0; - } -} - -template -void equalizerNband_audio_module::activate() -{ - is_active = true; - // set all filters - params_changed(); - meters.reset(); -} - -template -void equalizerNband_audio_module::deactivate() -{ - is_active = false; -} - -static inline void copy_lphp(biquad_d2 filters[3][2]) -{ - for (int i = 0; i < 3; i++) - for (int j = 0; j < 2; j++) - if (i || j) - filters[i][j].copy_coeffs(filters[0][0]); -} - -template -void equalizerNband_audio_module::params_changed() -{ - // set the params of all filters - - // lp/hp first (if available) - if (has_lphp) - { - hp_mode = (CalfEqMode)(int)*params[AM::param_hp_mode]; - lp_mode = (CalfEqMode)(int)*params[AM::param_lp_mode]; - - float hpfreq = *params[AM::param_hp_freq], lpfreq = *params[AM::param_lp_freq]; - - if(hpfreq != hp_freq_old) { - hp[0][0].set_hp_rbj(hpfreq, 0.707, (float)srate, 1.0); - copy_lphp(hp); - hp_freq_old = hpfreq; - } - if(lpfreq != lp_freq_old) { - lp[0][0].set_lp_rbj(lpfreq, 0.707, (float)srate, 1.0); - copy_lphp(lp); - lp_freq_old = lpfreq; - } - } - - // then shelves - float hsfreq = *params[AM::param_hs_freq], hslevel = *params[AM::param_hs_level]; - float lsfreq = *params[AM::param_ls_freq], lslevel = *params[AM::param_ls_level]; - - if(lsfreq != ls_freq_old or lslevel != ls_level_old) { - lsL.set_lowshelf_rbj(lsfreq, 0.707, lslevel, (float)srate); - lsR.copy_coeffs(lsL); - ls_level_old = lslevel; - ls_freq_old = lsfreq; - } - if(hsfreq != hs_freq_old or hslevel != hs_level_old) { - hsL.set_highshelf_rbj(hsfreq, 0.707, hslevel, (float)srate); - hsR.copy_coeffs(hsL); - hs_level_old = hslevel; - hs_freq_old = hsfreq; - } - for (int i = 0; i < AM::PeakBands; i++) - { - int offset = i * params_per_band; - float freq = *params[AM::param_p1_freq + offset]; - float level = *params[AM::param_p1_level + offset]; - float q = *params[AM::param_p1_q + offset]; - if(freq != p_freq_old[i] or level != p_level_old[i] or q != p_q_old[i]) { - pL[i].set_peakeq_rbj(freq, q, level, (float)srate); - pR[i].copy_coeffs(pL[i]); - p_freq_old[i] = freq; - p_level_old[i] = level; - p_q_old[i] = q; - } - } -} - -template -inline void equalizerNband_audio_module::process_hplp(float &left, float &right) -{ - if (!has_lphp) - return; - if (*params[AM::param_lp_active] > 0.f) - { - switch(lp_mode) - { - case MODE12DB: - left = lp[0][0].process(left); - right = lp[0][1].process(right); - break; - case MODE24DB: - left = lp[1][0].process(lp[0][0].process(left)); - right = lp[1][1].process(lp[0][1].process(right)); - break; - case MODE36DB: - left = lp[2][0].process(lp[1][0].process(lp[0][0].process(left))); - right = lp[2][1].process(lp[1][1].process(lp[0][1].process(right))); - break; - } - } - if (*params[AM::param_hp_active] > 0.f) - { - switch(hp_mode) - { - case MODE12DB: - left = hp[0][0].process(left); - right = hp[0][1].process(right); - break; - case MODE24DB: - left = hp[1][0].process(hp[0][0].process(left)); - right = hp[1][1].process(hp[0][1].process(right)); - break; - case MODE36DB: - left = hp[2][0].process(hp[1][0].process(hp[0][0].process(left))); - right = hp[2][1].process(hp[1][1].process(hp[0][1].process(right))); - break; - } - } -} - -template -uint32_t equalizerNband_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) -{ - bool bypass = *params[AM::param_bypass] > 0.f; - uint32_t orig_offset = offset; - uint32_t orig_numsamples = numsamples; - numsamples += offset; - if(bypass) { - // everything bypassed - while(offset < numsamples) { - outs[0][offset] = ins[0][offset]; - outs[1][offset] = ins[1][offset]; - ++offset; - } - // displays, too - meters.bypassed(params, orig_numsamples); - } else { - // process - while(offset < numsamples) { - // cycle through samples - float outL = 0.f; - float outR = 0.f; - float inL = ins[0][offset]; - float inR = ins[1][offset]; - // in level - inR *= *params[AM::param_level_in]; - inL *= *params[AM::param_level_in]; - - float procL = inL; - float procR = inR; - - // all filters in chain - process_hplp(procL, procR); - if(*params[AM::param_ls_active] > 0.f) { - procL = lsL.process(procL); - procR = lsR.process(procR); - } - if(*params[AM::param_hs_active] > 0.f) { - procL = hsL.process(procL); - procR = hsR.process(procR); - } - for (int i = 0; i < AM::PeakBands; i++) - { - if(*params[AM::param_p1_active + i * params_per_band] > 0.f) { - procL = pL[i].process(procL); - procR = pR[i].process(procR); - } - } - - outL = procL * *params[AM::param_level_out]; - outR = procR * *params[AM::param_level_out]; - - // send to output - outs[0][offset] = outL; - outs[1][offset] = outR; - - // next sample - ++offset; - } // cycle trough samples - meters.process(params, ins, outs, orig_offset, orig_numsamples); - // clean up - for(int i = 0; i < 3; ++i) { - hp[i][0].sanitize(); - hp[i][1].sanitize(); - lp[i][0].sanitize(); - lp[i][1].sanitize(); - } - lsL.sanitize(); - hsR.sanitize(); - for(int i = 0; i < AM::PeakBands; ++i) { - pL[i].sanitize(); - pR[i].sanitize(); - } - } - // whatever has to be returned x) - return outputs_mask; -} - -template -bool equalizerNband_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const -{ - if (!is_active) - return false; - if (index == AM::param_p1_freq && !subindex) { - context->set_line_width(1.5); - return ::get_graph(*this, subindex, data, points, 32, 0); - } - return false; -} - -template -bool equalizerNband_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const -{ - if (!is_active) { - return false; - } else { - return get_freq_gridline(subindex, pos, vertical, legend, context, true, 32, 0); - } -} - -template -int equalizerNband_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const -{ - if (!is_active) { - return false; - } else { - bool changed = false; - for (int i = 0; i < graph_param_count && !changed; i++) - { - if (*params[AM::first_graph_param + i] != old_params_for_graph[i]) - changed = true; - } - if (changed) - { - for (int i = 0; i < graph_param_count; i++) - old_params_for_graph[i] = *params[AM::first_graph_param + i]; - - last_generation++; - subindex_graph = 0; - subindex_dot = INT_MAX; - subindex_gridline = INT_MAX; - } - else { - subindex_graph = 0; - subindex_dot = subindex_gridline = generation ? INT_MAX : 0; - } - if (generation == last_calculated_generation) - subindex_graph = INT_MAX; - return last_generation; - } - return false; -} - -static inline float adjusted_lphp_gain(const float *const *params, int param_active, int param_mode, const biquad_d2 &filter, float freq, float srate) -{ - if(*params[param_active] > 0.f) { - float gain = filter.freq_gain(freq, srate); - switch((int)*params[param_mode]) { - case MODE12DB: - return gain; - case MODE24DB: - return gain * gain; - case MODE36DB: - return gain * gain * gain; - } - } - return 1; -} - -template -float equalizerNband_audio_module::freq_gain(int index, double freq, uint32_t sr) const -{ - float ret = 1.f; - if (use_hplp) - { - ret *= adjusted_lphp_gain(params, AM::param_hp_active, AM::param_hp_mode, hp[0][0], freq, (float)sr); - ret *= adjusted_lphp_gain(params, AM::param_lp_active, AM::param_lp_mode, lp[0][0], freq, (float)sr); - } - ret *= (*params[AM::param_ls_active] > 0.f) ? lsL.freq_gain(freq, sr) : 1; - ret *= (*params[AM::param_hs_active] > 0.f) ? hsL.freq_gain(freq, sr) : 1; - for (int i = 0; i < PeakBands; i++) - ret *= (*params[AM::param_p1_active + i * params_per_band] > 0.f) ? pL[i].freq_gain(freq, (float)sr) : 1; - return ret; -} - -template class calf_plugins::equalizerNband_audio_module; -template class calf_plugins::equalizerNband_audio_module; -template class calf_plugins::equalizerNband_audio_module; - diff --git a/plugins/LadspaEffect/calf/src/modules_limit.cpp b/plugins/LadspaEffect/calf/src/modules_limit.cpp deleted file mode 100644 index cd3d6fa7b1b..00000000000 --- a/plugins/LadspaEffect/calf/src/modules_limit.cpp +++ /dev/null @@ -1,704 +0,0 @@ -/* Calf DSP plugin pack - * Limiter related plugins - * - * Copyright (C) 2001-2010 Krzysztof Foltman, Markus Schmidt, Thor Harald Johansen and others - * - * 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 02110-1301 USA - */ -#include -#include -#include -#include - -using namespace dsp; -using namespace calf_plugins; - -#define SET_IF_CONNECTED(name) if (params[AM::param_##name] != NULL) *params[AM::param_##name] = name; - -/// Limiter by Markus Schmidt and Christian Holschuh -/// -/// This module provides the lookahead limiter as a simple audio module -/// with choosable lookahead and release time. -/////////////////////////////////////////////////////////////////////////////////////////////// - -limiter_audio_module::limiter_audio_module() -{ - is_active = false; - srate = 0; - // zero all displays - clip_inL = 0.f; - clip_inR = 0.f; - clip_outL = 0.f; - clip_outR = 0.f; - meter_inL = 0.f; - meter_inR = 0.f; - meter_outL = 0.f; - meter_outR = 0.f; - asc_led = 0.f; - attack_old = -1.f; - limit_old = -1.f; - asc_old = true; -} - -void limiter_audio_module::activate() -{ - is_active = true; - // set all filters and strips - params_changed(); - limiter.activate(); -} - -void limiter_audio_module::deactivate() -{ - is_active = false; - limiter.deactivate(); -} - -void limiter_audio_module::params_changed() -{ - limiter.set_params(*params[param_limit], *params[param_attack], *params[param_release], 1.f, *params[param_asc], pow(0.5, (*params[param_asc_coeff] - 0.5) * 2 * -1), true); - if( *params[param_attack] != attack_old) { - attack_old = *params[param_attack]; - limiter.reset(); - } - if(*params[param_limit] != limit_old or *params[param_asc] != asc_old) { - asc_old = *params[param_asc]; - limit_old = *params[param_limit]; - limiter.reset_asc(); - } -} - -void limiter_audio_module::set_sample_rate(uint32_t sr) -{ - srate = sr; - limiter.set_sample_rate(srate); -} - -uint32_t limiter_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) -{ - bool bypass = *params[param_bypass] > 0.5f; - numsamples += offset; - if(bypass) { - // everything bypassed - while(offset < numsamples) { - outs[0][offset] = ins[0][offset]; - outs[1][offset] = ins[1][offset]; - ++offset; - } - // displays, too - clip_inL = 0.f; - clip_inR = 0.f; - clip_outL = 0.f; - clip_outR = 0.f; - meter_inL = 0.f; - meter_inR = 0.f; - meter_outL = 0.f; - meter_outR = 0.f; - asc_led = 0.f; - } else { - // let meters fall a bit - clip_inL -= std::min(clip_inL, numsamples); - clip_inR -= std::min(clip_inR, numsamples); - clip_outL -= std::min(clip_outL, numsamples); - clip_outR -= std::min(clip_outR, numsamples); - meter_inL = 0.f; - meter_inR = 0.f; - meter_outL = 0.f; - meter_outR = 0.f; - asc_led -= std::min(asc_led, numsamples); - - while(offset < numsamples) { - // cycle through samples - float inL = ins[0][offset]; - float inR = ins[1][offset]; - // in level - inR *= *params[param_level_in]; - inL *= *params[param_level_in]; - // out vars - float outL = inL; - float outR = inR; - - // process gain reduction - float fickdich[0]; - limiter.process(outL, outR, fickdich); - if(limiter.get_asc()) - asc_led = srate >> 3; - - // should never be used. but hackers are paranoid by default. - // so we make shure NOTHING is above limit - outL = std::max(outL, -*params[param_limit]); - outL = std::min(outL, *params[param_limit]); - outR = std::max(outR, -*params[param_limit]); - outR = std::min(outR, *params[param_limit]); - - // autolevel - outL /= *params[param_limit]; - outR /= *params[param_limit]; - - // out level - outL *= *params[param_level_out]; - outR *= *params[param_level_out]; - - // send to output - outs[0][offset] = outL; - outs[1][offset] = outR; - - // clip LED's - if(inL > 1.f) { - clip_inL = srate >> 3; - } - if(inR > 1.f) { - clip_inR = srate >> 3; - } - if(outL > 1.f) { - clip_outL = srate >> 3; - } - if(outR > 1.f) { - clip_outR = srate >> 3; - } - // set up in / out meters - if(inL > meter_inL) { - meter_inL = inL; - } - if(inR > meter_inR) { - meter_inR = inR; - } - if(outL > meter_outL) { - meter_outL = outL; - } - if(outR > meter_outR) { - meter_outR = outR; - } - // next sample - ++offset; - } // cycle trough samples - - } // process (no bypass) - - // draw meters - SET_IF_CONNECTED(clip_inL); - SET_IF_CONNECTED(clip_inR); - SET_IF_CONNECTED(clip_outL); - SET_IF_CONNECTED(clip_outR); - SET_IF_CONNECTED(meter_inL); - SET_IF_CONNECTED(meter_inR); - SET_IF_CONNECTED(meter_outL); - SET_IF_CONNECTED(meter_outR); - - if (params[param_asc_led] != NULL) *params[param_asc_led] = asc_led; - - if (*params[param_att]) { - if(bypass) - *params[param_att] = 1.f; - else - *params[param_att] = limiter.get_attenuation(); - } - - // whatever has to be returned x) - return outputs_mask; -} - -/// Multiband Limiter by Markus Schmidt and Christian Holschuh -/// -/// This module splits the signal in four different bands -/// and sends them through multiple filters (implemented by -/// Krzysztof). They are processed by a lookahead limiter module afterwards -/// and summed up to the final output again. -/////////////////////////////////////////////////////////////////////////////////////////////// - -multibandlimiter_audio_module::multibandlimiter_audio_module() -{ - is_active = false; - srate = 0; - // zero all displays - clip_inL = 0.f; - clip_inR = 0.f; - clip_outL = 0.f; - clip_outR = 0.f; - meter_inL = 0.f; - meter_inR = 0.f; - meter_outL = 0.f; - meter_outR = 0.f; - asc_led = 0.f; - attack_old = -1.f; - channels = 2; - buffer_size = 0; - overall_buffer_size = 0; - _sanitize = false; - for(int i = 0; i < strips - 1; i ++) { - freq_old[i] = -1; - sep_old[i] = -1; - q_old[i] = -1; - } - mode_old = 0; - for(int i = 0; i < strips; i ++) { - weight_old[i] = -1.f; - } - attack_old = -1.f; - limit_old = -1.f; - asc_old = true; -} - -multibandlimiter_audio_module::~multibandlimiter_audio_module() -{ - if( buffer != NULL) - { - free(buffer); - } -} - -void multibandlimiter_audio_module::activate() -{ - is_active = true; - // set all filters and strips - params_changed(); - // activate all strips - for (int j = 0; j < strips; j ++) { - strip[j].activate(); - strip[j].set_multi(true); - strip[j].id = j; - } - broadband.activate(); - pos = 0; -} - -void multibandlimiter_audio_module::deactivate() -{ - is_active = false; - // deactivate all strips - for (int j = 0; j < strips; j ++) { - strip[j].deactivate(); - } - broadband.deactivate(); -} - -void multibandlimiter_audio_module::params_changed() -{ - // determine mute/solo states - solo[0] = *params[param_solo0] > 0.f ? true : false; - solo[1] = *params[param_solo1] > 0.f ? true : false; - solo[2] = *params[param_solo2] > 0.f ? true : false; - solo[3] = *params[param_solo3] > 0.f ? true : false; - no_solo = (*params[param_solo0] > 0.f || - *params[param_solo1] > 0.f || - *params[param_solo2] > 0.f || - *params[param_solo3] > 0.f) ? false : true; - - mode_old = mode; - mode = *params[param_mode]; - int i; - int j1; - switch(mode) { - case 0: - default: - j1 = 0; - break; - case 1: - j1 = 2; - break; - } - // set the params of all filters - if(*params[param_freq0] != freq_old[0] or *params[param_sep0] != sep_old[0] or *params[param_q0] != q_old[0] or *params[param_mode] != mode_old) { - lpL[0][0].set_lp_rbj((float)(*params[param_freq0] * (1 - *params[param_sep0])), *params[param_q0], (float)srate); - hpL[0][0].set_hp_rbj((float)(*params[param_freq0] * (1 + *params[param_sep0])), *params[param_q0], (float)srate); - lpR[0][0].copy_coeffs(lpL[0][0]); - hpR[0][0].copy_coeffs(hpL[0][0]); - for(i = 1; i <= j1; i++) { - lpL[0][i].copy_coeffs(lpL[0][0]); - hpL[0][i].copy_coeffs(hpL[0][0]); - lpR[0][i].copy_coeffs(lpL[0][0]); - hpR[0][i].copy_coeffs(hpL[0][0]); - } - freq_old[0] = *params[param_freq0]; - sep_old[0] = *params[param_sep0]; - q_old[0] = *params[param_q0]; - } - if(*params[param_freq1] != freq_old[1] or *params[param_sep1] != sep_old[1] or *params[param_q1] != q_old[1] or *params[param_mode] != mode_old) { - lpL[1][0].set_lp_rbj((float)(*params[param_freq1] * (1 - *params[param_sep1])), *params[param_q1], (float)srate); - hpL[1][0].set_hp_rbj((float)(*params[param_freq1] * (1 + *params[param_sep1])), *params[param_q1], (float)srate); - lpR[1][0].copy_coeffs(lpL[1][0]); - hpR[1][0].copy_coeffs(hpL[1][0]); - for(i = 1; i <= j1; i++) { - lpL[1][i].copy_coeffs(lpL[1][0]); - hpL[1][i].copy_coeffs(hpL[1][0]); - lpR[1][i].copy_coeffs(lpL[1][0]); - hpR[1][i].copy_coeffs(hpL[1][0]); - } - freq_old[1] = *params[param_freq1]; - sep_old[1] = *params[param_sep1]; - q_old[1] = *params[param_q1]; - } - if(*params[param_freq2] != freq_old[2] or *params[param_sep2] != sep_old[2] or *params[param_q2] != q_old[2] or *params[param_mode] != mode_old) { - lpL[2][0].set_lp_rbj((float)(*params[param_freq2] * (1 - *params[param_sep2])), *params[param_q2], (float)srate); - hpL[2][0].set_hp_rbj((float)(*params[param_freq2] * (1 + *params[param_sep2])), *params[param_q2], (float)srate); - lpR[2][0].copy_coeffs(lpL[2][0]); - hpR[2][0].copy_coeffs(hpL[2][0]); - for(i = 1; i <= j1; i++) { - lpL[2][i].copy_coeffs(lpL[2][0]); - hpL[2][i].copy_coeffs(hpL[2][0]); - lpR[2][i].copy_coeffs(lpL[2][0]); - hpR[2][i].copy_coeffs(hpL[2][0]); - } - freq_old[2] = *params[param_freq2]; - sep_old[2] = *params[param_sep2]; - q_old[2] = *params[param_q2]; - } - // set the params of all strips - float rel; - - rel = *params[param_release] * pow(0.25, *params[param_release0] * -1); - rel = (*params[param_minrel] > 0.5) ? std::max(2500 * (1.f / 30), rel) : rel; - weight[0] = pow(0.25, *params[param_weight0] * -1); - strip[0].set_params(*params[param_limit], *params[param_attack], rel, weight[0], *params[param_asc], pow(0.5, (*params[param_asc_coeff] - 0.5) * 2 * -1), true); - *params[param_effrelease0] = rel; - rel = *params[param_release] * pow(0.25, *params[param_release1] * -1); - rel = (*params[param_minrel] > 0.5) ? std::max(2500 * (1.f / *params[param_freq0]), rel) : rel; - weight[1] = pow(0.25, *params[param_weight1] * -1); - strip[1].set_params(*params[param_limit], *params[param_attack], rel, weight[1], *params[param_asc], pow(0.5, (*params[param_asc_coeff] - 0.5) * 2 * -1)); - *params[param_effrelease1] = rel; - rel = *params[param_release] * pow(0.25, *params[param_release2] * -1); - rel = (*params[param_minrel] > 0.5) ? std::max(2500 * (1.f / *params[param_freq1]), rel) : rel; - weight[2] = pow(0.25, *params[param_weight2] * -1); - strip[2].set_params(*params[param_limit], *params[param_attack], rel, weight[2], *params[param_asc], pow(0.5, (*params[param_asc_coeff] - 0.5) * 2 * -1)); - *params[param_effrelease2] = rel; - rel = *params[param_release] * pow(0.25, *params[param_release3] * -1); - rel = (*params[param_minrel] > 0.5) ? std::max(2500 * (1.f / *params[param_freq2]), rel) : rel; - weight[3] = pow(0.25, *params[param_weight3] * -1); - strip[3].set_params(*params[param_limit], *params[param_attack], rel, weight[3], *params[param_asc], pow(0.5, (*params[param_asc_coeff] - 0.5) * 2 * -1)); - *params[param_effrelease3] = rel; - broadband.set_params(*params[param_limit], *params[param_attack], rel, 1.f, *params[param_asc], pow(0.5, (*params[param_asc_coeff] - 0.5) * 2 * -1)); - // rebuild multiband buffer - if( *params[param_attack] != attack_old) { - int bs = (int)(srate * (*params[param_attack] / 1000.f) * channels); - buffer_size = bs - bs % channels; // buffer size attack rate - attack_old = *params[param_attack]; - _sanitize = true; - pos = 0; - for (int j = 0; j < strips; j ++) { - strip[j].reset(); - } - broadband.reset(); - } - if(*params[param_limit] != limit_old or *params[param_asc] != asc_old or *params[param_weight0] != weight_old[0] or *params[param_weight1] != weight_old[1] or *params[param_weight2] != weight_old[2] or *params[param_weight3] != weight_old[3] ) { - asc_old = *params[param_asc]; - limit_old = *params[param_limit]; - weight_old[0] = *params[param_weight0]; - weight_old[1] = *params[param_weight1]; - weight_old[2] = *params[param_weight2]; - weight_old[3] = *params[param_weight3]; - for (int j = 0; j < strips; j ++) { - strip[j].reset_asc(); - } - broadband.reset_asc(); - } -} - -void multibandlimiter_audio_module::set_sample_rate(uint32_t sr) -{ - srate = sr; - // rebuild buffer - overall_buffer_size = (int)(srate * (100.f / 1000.f) * channels) + channels; // buffer size max attack rate - buffer = (float*) calloc(overall_buffer_size, sizeof(float)); - memset(buffer, 0, overall_buffer_size * sizeof(float)); // reset buffer to zero - pos = 0; - // set srate of all strips - for (int j = 0; j < strips; j ++) { - strip[j].set_sample_rate(srate); - } - broadband.set_sample_rate(srate); -} - -#define BYPASSED_COMPRESSION(index) \ - if(params[param_att##index] != NULL) \ - *params[param_att##index] = 1.0; \ - -#define ACTIVE_COMPRESSION(index) \ - if(params[param_att##index] != NULL) \ - *params[param_att##index] = strip[index].get_attenuation(); \ - -uint32_t multibandlimiter_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) -{ - bool bypass = *params[param_bypass] > 0.5f; - numsamples += offset; - float batt = 0.f; - if(bypass) { - // everything bypassed - while(offset < numsamples) { - outs[0][offset] = ins[0][offset]; - outs[1][offset] = ins[1][offset]; - ++offset; - } - // displays, too - clip_inL = 0.f; - clip_inR = 0.f; - clip_outL = 0.f; - clip_outR = 0.f; - meter_inL = 0.f; - meter_inR = 0.f; - meter_outL = 0.f; - meter_outR = 0.f; - asc_led = 0.f; - } else { - // process all strips - - // let meters fall a bit - clip_inL -= std::min(clip_inL, numsamples); - clip_inR -= std::min(clip_inR, numsamples); - clip_outL -= std::min(clip_outL, numsamples); - clip_outR -= std::min(clip_outR, numsamples); - asc_led -= std::min(asc_led, numsamples); - meter_inL = 0.f; - meter_inR = 0.f; - meter_outL = 0.f; - meter_outR = 0.f; - float _tmpL[channels]; - float _tmpR[channels]; - while(offset < numsamples) { - float inL = 0.f; - float inR = 0.f; - // cycle through samples - if(!_sanitize) { - inL = ins[0][offset]; - inR = ins[1][offset]; - } - // in level - inR *= *params[param_level_in]; - inL *= *params[param_level_in]; - // even out filters gain reduction - // 3dB - levelled manually (based on default sep and q settings) - switch(mode) { - case 0: - inL *= 1.414213562; - inR *= 1.414213562; - break; - case 1: - inL *= 0.88; - inR *= 0.88; - break; - } - // out vars - float outL = 0.f; - float outR = 0.f; - int j1; - float left; - float right; - float sum_left = 0.f; - float sum_right = 0.f; - bool asc_active = false; - for (int i = 0; i < strips; i++) { - left = inL; - right = inR; - // send trough filters - switch(mode) { - // how many filter passes? (12/36dB) - case 0: - default: - j1 = 0; - break; - case 1: - j1 = 2; - break; - } - for (int j = 0; j <= j1; j++){ - if(i + 1 < strips) { - // do lowpass on all bands except most high - left = lpL[i][j].process(left); - right = lpR[i][j].process(right); - lpL[i][j].sanitize(); - lpR[i][j].sanitize(); - } - if(i - 1 >= 0) { - // do highpass on all bands except most low - left = hpL[i - 1][j].process(left); - right = hpR[i - 1][j].process(right); - hpL[i - 1][j].sanitize(); - hpR[i - 1][j].sanitize(); - } - } - - // remember filtered values for limiting - // (we need multiband_coeff before we can call the limiter bands) - _tmpL[i] = left; - _tmpR[i] = right; - - // sum up for multiband coefficient - sum_left += ((fabs(left) > *params[param_limit]) ? *params[param_limit] * (fabs(left) / left) : left) * weight[i]; - sum_right += ((fabs(right) > *params[param_limit]) ? *params[param_limit] * (fabs(right) / right) : right) * weight[i]; - } // process single strip with filter - - // write multiband coefficient to buffer - float pre_buffer = *params[param_limit] / std::max(fabs(sum_left), fabs(sum_right)); - buffer[pos] = std::min(pre_buffer, 1.0f); - - for (int i = 0; i < strips; i++) { - // process gain reduction - strip[i].process(_tmpL[i], _tmpR[i], buffer); - // sum up output of limiters - if (solo[i] || no_solo) { - outL += _tmpL[i]; - outR += _tmpR[i]; - } - asc_active = asc_active || strip[i].get_asc(); - } // process single strip again for limiter - float fickdich[0]; - broadband.process(outL, outR, fickdich); - asc_active = asc_active || broadband.get_asc(); - - // should never be used. but hackers are paranoid by default. - // so we make shure NOTHING is above limit - outL = std::max(outL, -*params[param_limit]); - outL = std::min(outL, *params[param_limit]); - outR = std::max(outR, -*params[param_limit]); - outR = std::min(outR, *params[param_limit]); - - batt = broadband.get_attenuation(); - - // autolevel - outL /= *params[param_limit]; - outR /= *params[param_limit]; - - // out level - outL *= *params[param_level_out]; - outR *= *params[param_level_out]; - - // send to output - outs[0][offset] = outL; - outs[1][offset] = outR; - - // clip LED's - if(ins[0][offset] * *params[param_level_in] > 1.f) { - clip_inL = srate >> 3; - } - if(ins[1][offset] * *params[param_level_in] > 1.f) { - clip_inR = srate >> 3; - } - if(outL > 1.f) { - clip_outL = srate >> 3; - } - if(outR > 1.f) { - clip_outR = srate >> 3; - } - // set up in / out meters - if(ins[0][offset] * *params[param_level_in] > meter_inL) { - meter_inL = ins[0][offset] * *params[param_level_in]; - } - if(ins[1][offset] * *params[param_level_in] > meter_inR) { - meter_inR = ins[1][offset] * *params[param_level_in]; - } - if(outL > meter_outL) { - meter_outL = outL; - } - if(outR > meter_outR) { - meter_outR = outR; - } - if(asc_active) { - asc_led = srate >> 3; - } - // next sample - ++offset; - pos = (pos + channels) % buffer_size; - if(pos == 0) _sanitize = false; - } // cycle trough samples - - } // process all strips (no bypass) - - // draw meters - SET_IF_CONNECTED(clip_inL); - SET_IF_CONNECTED(clip_inR); - SET_IF_CONNECTED(clip_outL); - SET_IF_CONNECTED(clip_outR); - SET_IF_CONNECTED(meter_inL); - SET_IF_CONNECTED(meter_inR); - SET_IF_CONNECTED(meter_outL); - SET_IF_CONNECTED(meter_outR); - - if (params[param_asc_led] != NULL) *params[param_asc_led] = asc_led; - - // draw strip meters - if(bypass > 0.5f) { - if(params[param_att0] != NULL) *params[param_att0] = 1.0; - if(params[param_att1] != NULL) *params[param_att1] = 1.0; - if(params[param_att2] != NULL) *params[param_att2] = 1.0; - if(params[param_att3] != NULL) *params[param_att3] = 1.0; - - } else { - if(params[param_att0] != NULL) *params[param_att0] = strip[0].get_attenuation() * batt; - if(params[param_att1] != NULL) *params[param_att1] = strip[1].get_attenuation() * batt; - if(params[param_att2] != NULL) *params[param_att2] = strip[2].get_attenuation() * batt; - if(params[param_att3] != NULL) *params[param_att3] = strip[3].get_attenuation() * batt; - } - // whatever has to be returned x) - return outputs_mask; -} - -bool multibandlimiter_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const -{ - if (!is_active or subindex > 3) - return false; - float ret; - double freq; - int j1; - for (int i = 0; i < points; i++) - { - ret = 1.f; - freq = 20.0 * pow (20000.0 / 20.0, i * 1.0 / points); - switch(mode) { - case 0: - default: - j1 = 0; - break; - case 1: - j1 = 2; - break; - } - for(int j = 0; j <= j1; j ++) { - switch(subindex) { - case 0: - ret *= lpL[0][j].freq_gain(freq, (float)srate); - break; - case 1: - ret *= hpL[0][j].freq_gain(freq, (float)srate); - ret *= lpL[1][j].freq_gain(freq, (float)srate); - break; - case 2: - ret *= hpL[1][j].freq_gain(freq, (float)srate); - ret *= lpL[2][j].freq_gain(freq, (float)srate); - break; - case 3: - ret *= hpL[2][j].freq_gain(freq, (float)srate); - break; - } - } - data[i] = dB_grid(ret); - } - if (*params[param_bypass] > 0.5f) - context->set_source_rgba(0.35, 0.4, 0.2, 0.3); - else { - context->set_source_rgba(0.35, 0.4, 0.2, 1); - context->set_line_width(1.5); - } - return true; -} - -bool multibandlimiter_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const -{ - if (!is_active) { - return false; - } else { - vertical = (subindex & 1) != 0; - return get_freq_gridline(subindex, pos, vertical, legend, context); - } -} diff --git a/plugins/LadspaEffect/calf/src/modules_mod.cpp b/plugins/LadspaEffect/calf/src/modules_mod.cpp deleted file mode 100644 index 91c50df7031..00000000000 --- a/plugins/LadspaEffect/calf/src/modules_mod.cpp +++ /dev/null @@ -1,753 +0,0 @@ -/* Calf DSP plugin pack - * Modulation effect plugins - * - * Copyright (C) 2001-2010 Krzysztof Foltman, Markus Schmidt, Thor Harald Johansen and others - * - * 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 02110-1301 USA - */ -#include -#include -#include -#include - -using namespace dsp; -using namespace calf_plugins; - -#define SET_IF_CONNECTED(name) if (params[AM::param_##name] != NULL) *params[AM::param_##name] = name; - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -void flanger_audio_module::activate() { - left.reset(); - right.reset(); - last_r_phase = *params[par_stereo] * (1.f / 360.f); - left.reset_phase(0.f); - right.reset_phase(last_r_phase); - is_active = true; -} - -void flanger_audio_module::set_sample_rate(uint32_t sr) { - srate = sr; - left.setup(sr); - right.setup(sr); -} - -void flanger_audio_module::deactivate() { - is_active = false; -} - -bool flanger_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const -{ - if (!is_active) - return false; - if (index == par_delay && subindex < 2) - { - set_channel_color(context, subindex); - return ::get_graph(*this, subindex, data, points); - } - return false; -} - -float flanger_audio_module::freq_gain(int subindex, float freq, float srate) const -{ - return (subindex ? right : left).freq_gain(freq, srate); -} - -void flanger_audio_module::params_changed() -{ - float dry = *params[par_dryamount]; - float wet = *params[par_amount]; - float rate = *params[par_rate]; // 0.01*pow(1000.0f,*params[par_rate]); - float min_delay = *params[par_delay] / 1000.0; - float mod_depth = *params[par_depth] / 1000.0; - float fb = *params[par_fb]; - left.set_dry(dry); right.set_dry(dry); - left.set_wet(wet); right.set_wet(wet); - left.set_rate(rate); right.set_rate(rate); - left.set_min_delay(min_delay); right.set_min_delay(min_delay); - left.set_mod_depth(mod_depth); right.set_mod_depth(mod_depth); - left.set_fb(fb); right.set_fb(fb); - float r_phase = *params[par_stereo] * (1.f / 360.f); - clear_reset = false; - if (*params[par_reset] >= 0.5) { - clear_reset = true; - left.reset_phase(0.f); - right.reset_phase(r_phase); - } else { - if (fabs(r_phase - last_r_phase) > 0.0001f) { - right.phase = left.phase; - right.inc_phase(r_phase); - last_r_phase = r_phase; - } - } -} - -void flanger_audio_module::params_reset() -{ - if (clear_reset) { - *params[par_reset] = 0.f; - clear_reset = false; - } -} - -/////////////////////////////////////////////////////////////////////////////////////////////// - -phaser_audio_module::phaser_audio_module() -: left(MaxStages, x1vals[0], y1vals[0]) -, right(MaxStages, x1vals[1], y1vals[1]) -{ - is_active = false; -} - -void phaser_audio_module::set_sample_rate(uint32_t sr) -{ - srate = sr; - left.setup(sr); - right.setup(sr); -} - -void phaser_audio_module::activate() -{ - is_active = true; - left.reset(); - right.reset(); - last_r_phase = *params[par_stereo] * (1.f / 360.f); - left.reset_phase(0.f); - right.reset_phase(last_r_phase); -} - -void phaser_audio_module::deactivate() -{ - is_active = false; -} - -bool phaser_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const -{ - if (!is_active) - return false; - if (subindex < 2) - { - set_channel_color(context, subindex); - return ::get_graph(*this, subindex, data, points); - } - return false; -} - -float phaser_audio_module::freq_gain(int subindex, float freq, float srate) const -{ - return (subindex ? right : left).freq_gain(freq, srate); -} - -bool phaser_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const -{ - return get_freq_gridline(subindex, pos, vertical, legend, context); -} - -void phaser_audio_module::params_changed() -{ - float dry = *params[par_dryamount]; - float wet = *params[par_amount]; - float rate = *params[par_rate]; // 0.01*pow(1000.0f,*params[par_rate]); - float base_frq = *params[par_freq]; - float mod_depth = *params[par_depth]; - float fb = *params[par_fb]; - int stages = (int)*params[par_stages]; - left.set_dry(dry); right.set_dry(dry); - left.set_wet(wet); right.set_wet(wet); - left.set_rate(rate); right.set_rate(rate); - left.set_base_frq(base_frq); right.set_base_frq(base_frq); - left.set_mod_depth(mod_depth); right.set_mod_depth(mod_depth); - left.set_fb(fb); right.set_fb(fb); - left.set_stages(stages); right.set_stages(stages); - float r_phase = *params[par_stereo] * (1.f / 360.f); - clear_reset = false; - if (*params[par_reset] >= 0.5) { - clear_reset = true; - left.reset_phase(0.f); - right.reset_phase(r_phase); - } else { - if (fabs(r_phase - last_r_phase) > 0.0001f) { - right.phase = left.phase; - right.inc_phase(r_phase); - last_r_phase = r_phase; - } - } -} - -void phaser_audio_module::params_reset() -{ - if (clear_reset) { - *params[par_reset] = 0.f; - clear_reset = false; - } -} - -/////////////////////////////////////////////////////////////////////////////////////////////// - -rotary_speaker_audio_module::rotary_speaker_audio_module() -{ - mwhl_value = hold_value = 0.f; - phase_h = phase_l = 0.f; - aspeed_l = 1.f; - aspeed_h = 1.f; - dspeed = 0.f; -} - -void rotary_speaker_audio_module::set_sample_rate(uint32_t sr) -{ - srate = sr; - setup(); -} - -void rotary_speaker_audio_module::setup() -{ - crossover1l.set_lp_rbj(800.f, 0.7, (float)srate); - crossover1r.set_lp_rbj(800.f, 0.7, (float)srate); - crossover2l.set_hp_rbj(800.f, 0.7, (float)srate); - crossover2r.set_hp_rbj(800.f, 0.7, (float)srate); -} - -void rotary_speaker_audio_module::activate() -{ - phase_h = phase_l = 0.f; - maspeed_h = maspeed_l = 0.f; - setup(); -} - -void rotary_speaker_audio_module::deactivate() -{ -} - -void rotary_speaker_audio_module::control_change(int /*channel*/, int ctl, int val) -{ - if (vibrato_mode == 3 && ctl == 64) - { - hold_value = val / 127.f; - set_vibrato(); - return; - } - if (vibrato_mode == 4 && ctl == 1) - { - mwhl_value = val / 127.f; - set_vibrato(); - return; - } -} - -void rotary_speaker_audio_module::params_changed() -{ - set_vibrato(); -} - -void rotary_speaker_audio_module::set_vibrato() -{ - vibrato_mode = fastf2i_drm(*params[par_speed]); - // manual vibrato - do not recalculate speeds as they're not used anyway - if (vibrato_mode == 5) - return; - if (!vibrato_mode) - dspeed = -1; - else { - float speed = vibrato_mode - 1; - if (vibrato_mode == 3) - speed = hold_value; - if (vibrato_mode == 4) - speed = mwhl_value; - dspeed = (speed < 0.5f) ? 0 : 1; - } - update_speed(); -} - -/// Convert RPM speed to delta-phase -uint32_t rotary_speaker_audio_module::rpm2dphase(float rpm) -{ - return (uint32_t)((rpm / (60.0 * srate)) * (1 << 30)) << 2; -} - -/// Set delta-phase variables based on current calculated (and interpolated) RPM speed -void rotary_speaker_audio_module::update_speed() -{ - float speed_h = aspeed_h >= 0 ? (48 + (400-48) * aspeed_h) : (48 * (1 + aspeed_h)); - float speed_l = aspeed_l >= 0 ? 40 + (342-40) * aspeed_l : (40 * (1 + aspeed_l)); - dphase_h = rpm2dphase(speed_h); - dphase_l = rpm2dphase(speed_l); -} - -void rotary_speaker_audio_module::update_speed_manual(float delta) -{ - float ts = *params[par_treblespeed]; - float bs = *params[par_bassspeed]; - incr_towards(maspeed_h, ts, delta * 200, delta * 200); - incr_towards(maspeed_l, bs, delta * 200, delta * 200); - dphase_h = rpm2dphase(maspeed_h); - dphase_l = rpm2dphase(maspeed_l); -} - -/// map a ramp [int] to a sinusoid-like function [0, 65536] -static inline int pseudo_sine_scl(int counter) -{ - // premature optimization is a root of all evil; it can be done with integers only - but later :) - double v = counter * (1.0 / (65536.0 * 32768.0)); - return (int) (32768 + 32768 * (v - v*v*v) * (1.0 / 0.3849)); -} - -/// Increase or decrease aspeed towards raspeed, with required negative and positive rate -inline bool rotary_speaker_audio_module::incr_towards(float &aspeed, float raspeed, float delta_decc, float delta_acc) -{ - if (aspeed < raspeed) { - aspeed = std::min(raspeed, aspeed + delta_acc); - return true; - } - else if (aspeed > raspeed) - { - aspeed = std::max(raspeed, aspeed - delta_decc); - return true; - } - return false; -} - -uint32_t rotary_speaker_audio_module::process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask) -{ - if (true) - { - crossover2l.set_bp_rbj(2000.f, 0.7, (float)srate); - crossover2r.copy_coeffs(crossover2l); - damper1l.set_bp_rbj(1000.f*pow(4.0, *params[par_test]), 0.7, (float)srate); - damper1r.copy_coeffs(damper1l); - } - else - { - crossover2l.set_hp_rbj(800.f, 0.7, (float)srate); - crossover2r.copy_coeffs(crossover2l); - } - int shift = (int)(300000 * (*params[par_shift])), pdelta = (int)(300000 * (*params[par_spacing])); - int md = (int)(100 * (*params[par_moddepth])); - float mix = 0.5 * (1.0 - *params[par_micdistance]); - float mix2 = *params[par_reflection]; - float mix3 = mix2 * mix2; - float am_depth = *params[par_am_depth]; - for (unsigned int i = 0; i < nsamples; i++) { - float in_l = ins[0][i + offset], in_r = ins[1][i + offset]; - float in_mono = atan(0.5f * (in_l + in_r)); - - int xl = pseudo_sine_scl(phase_l), yl = pseudo_sine_scl(phase_l + 0x40000000); - int xh = pseudo_sine_scl(phase_h), yh = pseudo_sine_scl(phase_h + 0x40000000); - // printf("%d %d %d\n", shift, pdelta, shift + pdelta + 20 * xl); - meter_l = xl; - meter_h = xh; - // float out_hi_l = in_mono - delay.get_interp_1616(shift + md * xh) + delay.get_interp_1616(shift + md * 65536 + pdelta - md * yh) - delay.get_interp_1616(shift + md * 65536 + pdelta + pdelta - md * xh); - // float out_hi_r = in_mono + delay.get_interp_1616(shift + md * 65536 - md * yh) - delay.get_interp_1616(shift + pdelta + md * xh) + delay.get_interp_1616(shift + pdelta + pdelta + md * yh); - float fm_hi_l = delay.get_interp_1616(shift + md * xh) - mix2 * delay.get_interp_1616(shift + md * 65536 + pdelta - md * yh) + mix3 * delay.get_interp_1616(shift + md * 65536 + pdelta + pdelta - md * xh); - float fm_hi_r = delay.get_interp_1616(shift + md * 65536 - md * yh) - mix2 * delay.get_interp_1616(shift + pdelta + md * xh) + mix3 * delay.get_interp_1616(shift + pdelta + pdelta + md * yh); - float out_hi_l = lerp(in_mono, damper1l.process(fm_hi_l), lerp(0.5, xh * 1.0 / 65536.0, am_depth)); - float out_hi_r = lerp(in_mono, damper1r.process(fm_hi_r), lerp(0.5, yh * 1.0 / 65536.0, am_depth)); - - float out_lo_l = lerp(in_mono, delay.get_interp_1616(shift + (md * xl >> 2)), lerp(0.5, yl * 1.0 / 65536.0, am_depth)); // + delay.get_interp_1616(shift + md * 65536 + pdelta - md * yl); - float out_lo_r = lerp(in_mono, delay.get_interp_1616(shift + (md * yl >> 2)), lerp(0.5, xl * 1.0 / 65536.0, am_depth)); // + delay.get_interp_1616(shift + md * 65536 + pdelta - md * yl); - - out_hi_l = crossover2l.process(out_hi_l); // sanitize(out_hi_l); - out_hi_r = crossover2r.process(out_hi_r); // sanitize(out_hi_r); - out_lo_l = crossover1l.process(out_lo_l); // sanitize(out_lo_l); - out_lo_r = crossover1r.process(out_lo_r); // sanitize(out_lo_r); - - float out_l = out_hi_l + out_lo_l; - float out_r = out_hi_r + out_lo_r; - - float mic_l = out_l + mix * (out_r - out_l); - float mic_r = out_r + mix * (out_l - out_r); - - outs[0][i + offset] = mic_l; - outs[1][i + offset] = mic_r; - delay.put(in_mono); - phase_l += dphase_l; - phase_h += dphase_h; - } - crossover1l.sanitize(); - crossover1r.sanitize(); - crossover2l.sanitize(); - crossover2r.sanitize(); - damper1l.sanitize(); - damper1r.sanitize(); - float delta = nsamples * 1.0 / srate; - if (vibrato_mode == 5) - update_speed_manual(delta); - else - { - bool u1 = incr_towards(aspeed_l, dspeed, delta * 0.2, delta * 0.14); - bool u2 = incr_towards(aspeed_h, dspeed, delta, delta * 0.5); - if (u1 || u2) - set_vibrato(); - } - if(params[par_meter_l] != NULL) { - *params[par_meter_l] = (float)meter_l / 65536.0; - } - if(params[par_meter_h] != NULL) { - *params[par_meter_h] = (float)meter_h / 65536.0; - } - return outputs_mask; -} - -/////////////////////////////////////////////////////////////////////////////////////////////// - -multichorus_audio_module::multichorus_audio_module() -{ - is_active = false; - last_r_phase = -1; -} - -void multichorus_audio_module::activate() -{ - is_active = true; - params_changed(); -} - -void multichorus_audio_module::deactivate() -{ - is_active = false; -} - -void multichorus_audio_module::set_sample_rate(uint32_t sr) { - srate = sr; - left.setup(sr); - right.setup(sr); -} - -bool multichorus_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const -{ - if (!is_active) - return false; - int nvoices = (int)*params[par_voices]; - if (index == par_delay && subindex < 3) - { - if (subindex < 2) - set_channel_color(context, subindex); - else { - context->set_source_rgba(0.35, 0.4, 0.2); - context->set_line_width(1.0); - } - return ::get_graph(*this, subindex, data, points); - } - if (index == par_rate && subindex < nvoices) { - const sine_multi_lfo &lfo = left.lfo; - for (int i = 0; i < points; i++) { - float phase = i * 2 * M_PI / points; - // original -65536 to 65535 value - float orig = subindex * lfo.voice_offset + ((lfo.voice_depth >> (30-13)) * 65536.0 * (0.95 * sin(phase) + 1)/ 8192.0) - 65536; - // scale to -1..1 - data[i] = orig / 65536.0; - } - return true; - } - return false; -} - -bool multichorus_audio_module::get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const -{ - int voice = subindex >> 1; - int nvoices = (int)*params[par_voices]; - if ((index != par_rate && index != par_depth) || voice >= nvoices) - return false; - - float unit = (1 - *params[par_overlap]); - float scw = 1 + unit * (nvoices - 1); - set_channel_color(context, subindex); - const sine_multi_lfo &lfo = (subindex & 1 ? right : left).lfo; - if (index == par_rate) - { - x = (double)(lfo.phase + lfo.vphase * voice) / 4096.0; - y = 0.95 * sin(x * 2 * M_PI); - y = (voice * unit + (y + 1) / 2) / scw * 2 - 1; - } - else - { - double ph = (double)(lfo.phase + lfo.vphase * voice) / 4096.0; - x = 0.5 + 0.5 * sin(ph * 2 * M_PI); - y = subindex & 1 ? -0.75 : 0.75; - x = (voice * unit + x) / scw; - } - return true; -} - -bool multichorus_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const -{ - if (index == par_rate && !subindex) - { - pos = 0; - vertical = false; - return true; - } - if (index == par_delay) - return get_freq_gridline(subindex, pos, vertical, legend, context); - return false; -} - -float multichorus_audio_module::freq_gain(int subindex, float freq, float srate) const -{ - if (subindex == 2) - return *params[par_amount] * left.post.freq_gain(freq, srate); - return (subindex ? right : left).freq_gain(freq, srate); -} - -void multichorus_audio_module::params_changed() -{ - // delicious copy-pasta from flanger module - it'd be better to keep it common or something - float dry = *params[par_dryamount]; - float wet = *params[par_amount]; - float rate = *params[par_rate]; - float min_delay = *params[par_delay] / 1000.0; - float mod_depth = *params[par_depth] / 1000.0; - float overlap = *params[par_overlap]; - left.set_dry(dry); right.set_dry(dry); - left.set_wet(wet); right.set_wet(wet); - left.set_rate(rate); right.set_rate(rate); - left.set_min_delay(min_delay); right.set_min_delay(min_delay); - left.set_mod_depth(mod_depth); right.set_mod_depth(mod_depth); - int voices = (int)*params[par_voices]; - left.lfo.set_voices(voices); right.lfo.set_voices(voices); - left.lfo.set_overlap(overlap);right.lfo.set_overlap(overlap); - float vphase = *params[par_vphase] * (1.f / 360.f); - left.lfo.vphase = right.lfo.vphase = vphase * (4096 / std::max(voices - 1, 1)); - float r_phase = *params[par_stereo] * (1.f / 360.f); - if (fabs(r_phase - last_r_phase) > 0.0001f) { - right.lfo.phase = left.lfo.phase; - right.lfo.phase += chorus_phase(r_phase * 4096); - last_r_phase = r_phase; - } - left.post.f1.set_bp_rbj(*params[par_freq], *params[par_q], srate); - left.post.f2.set_bp_rbj(*params[par_freq2], *params[par_q], srate); - right.post.f1.copy_coeffs(left.post.f1); - right.post.f2.copy_coeffs(left.post.f2); -} - -uint32_t multichorus_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) -{ - left.process(outs[0] + offset, ins[0] + offset, numsamples); - right.process(outs[1] + offset, ins[1] + offset, numsamples); - return outputs_mask; // XXXKF allow some delay after input going blank -} - -/// Pulsator by Markus Schmidt -/// -/// This module provides a couple -/// of different LFO's for modulating the level of a signal. -/////////////////////////////////////////////////////////////////////////////////////////////// - -pulsator_audio_module::pulsator_audio_module() -{ - is_active = false; - srate = 0; -// last_generation = 0; - clip_inL = 0.f; - clip_inR = 0.f; - clip_outL = 0.f; - clip_outR = 0.f; - meter_inL = 0.f; - meter_inR = 0.f; - meter_outL = 0.f; - meter_outR = 0.f; -} - -void pulsator_audio_module::activate() -{ - is_active = true; - lfoL.activate(); - lfoR.activate(); - params_changed(); -} -void pulsator_audio_module::deactivate() -{ - is_active = false; - lfoL.deactivate(); - lfoR.deactivate(); -} - -void pulsator_audio_module::params_changed() -{ - lfoL.set_params(*params[param_freq], *params[param_mode], 0.f, srate, *params[param_amount]); - lfoR.set_params(*params[param_freq], *params[param_mode], *params[param_offset], srate, *params[param_amount]); - clear_reset = false; - if (*params[param_reset] >= 0.5) { - clear_reset = true; - lfoL.set_phase(0.f); - lfoR.set_phase(0.f); - } -} - -void pulsator_audio_module::set_sample_rate(uint32_t sr) -{ - srate = sr; -} - -uint32_t pulsator_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) -{ - bool bypass = *params[param_bypass] > 0.5f; - uint32_t samples = numsamples + offset; - if(bypass) { - // everything bypassed - while(offset < samples) { - outs[0][offset] = ins[0][offset]; - outs[1][offset] = ins[1][offset]; - ++offset; - } - // displays, too - clip_inL = 0.f; - clip_inR = 0.f; - clip_outL = 0.f; - clip_outR = 0.f; - meter_inL = 0.f; - meter_inR = 0.f; - meter_outL = 0.f; - meter_outR = 0.f; - - // LFO's should go on - lfoL.advance(numsamples); - lfoR.advance(numsamples); - - } else { - - clip_inL -= std::min(clip_inL, numsamples); - clip_inR -= std::min(clip_inR, numsamples); - clip_outL -= std::min(clip_outL, numsamples); - clip_outR -= std::min(clip_outR, numsamples); - meter_inL = 0.f; - meter_inR = 0.f; - meter_outL = 0.f; - meter_outR = 0.f; - - // process - while(offset < samples) { - // cycle through samples - float outL = 0.f; - float outR = 0.f; - float inL = ins[0][offset]; - float inR = ins[1][offset]; - // in level - inR *= *params[param_level_in]; - inL *= *params[param_level_in]; - - if(*params[param_mono] > 0.5) { - inL = (inL + inR) * 0.5; - inR = inL; - } - float procL = inL; - float procR = inR; - - procL *= (lfoL.get_value() * 0.5 + *params[param_amount] / 2); - procR *= (lfoR.get_value() * 0.5 + *params[param_amount] / 2); - - outL = procL + inL * (1 - *params[param_amount]); - outR = procR + inR * (1 - *params[param_amount]); - - outL *= *params[param_level_out]; - outR *= *params[param_level_out]; - - // send to output - outs[0][offset] = outL; - outs[1][offset] = outR; - - // clip LED's - if(inL > 1.f) { - clip_inL = srate >> 3; - } - if(inR > 1.f) { - clip_inR = srate >> 3; - } - if(outL > 1.f) { - clip_outL = srate >> 3; - } - if(outR > 1.f) { - clip_outR = srate >> 3; - } - // set up in / out meters - if(inL > meter_inL) { - meter_inL = inL; - } - if(inR > meter_inR) { - meter_inR = inR; - } - if(outL > meter_outL) { - meter_outL = outL; - } - if(outR > meter_outR) { - meter_outR = outR; - } - - // next sample - ++offset; - - // advance lfo's - lfoL.advance(1); - lfoR.advance(1); - } // cycle trough samples - } - // draw meters - SET_IF_CONNECTED(clip_inL) - SET_IF_CONNECTED(clip_inR) - SET_IF_CONNECTED(clip_outL) - SET_IF_CONNECTED(clip_outR) - SET_IF_CONNECTED(meter_inL) - SET_IF_CONNECTED(meter_inR) - SET_IF_CONNECTED(meter_outL) - SET_IF_CONNECTED(meter_outR) - // whatever has to be returned x) - return outputs_mask; -} - -bool pulsator_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const -{ - if (!is_active) { - return false; - } else if(index == param_freq) { - if(subindex == 0) { - context->set_source_rgba(0.35, 0.4, 0.2, 1); - return lfoL.get_graph(data, points, context); - } - if(subindex == 1) { - context->set_source_rgba(0.35, 0.4, 0.2, 0.5); - return lfoR.get_graph(data, points, context); - } - } - return false; -} - -bool pulsator_audio_module::get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) const -{ - if (!is_active) { - return false; - } else if(index == param_freq) { - if(subindex == 0) { - context->set_source_rgba(0.35, 0.4, 0.2, 1); - return lfoL.get_dot(x, y, size, context); - } - if(subindex == 1) { - context->set_source_rgba(0.35, 0.4, 0.2, 0.5); - return lfoR.get_dot(x, y, size, context); - } - return false; - } - return false; -} - -bool pulsator_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const -{ - if (index == param_freq && !subindex) - { - pos = 0; - vertical = false; - return true; - } - return false; -} diff --git a/plugins/LadspaEffect/calf/src/monosynth.cpp b/plugins/LadspaEffect/calf/src/monosynth.cpp deleted file mode 100644 index d8a0357bde3..00000000000 --- a/plugins/LadspaEffect/calf/src/monosynth.cpp +++ /dev/null @@ -1,802 +0,0 @@ -/* Calf DSP Library - * Example audio modules - monosynth - * - * Copyright (C) 2001-2007 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 02110-1301 USA - */ -#include -#include - -using namespace dsp; -using namespace calf_plugins; -using namespace std; - -float silence[4097]; - -monosynth_audio_module::monosynth_audio_module() -: mod_matrix_impl(mod_matrix_data, &mm_metadata) -, inertia_cutoff(1) -, inertia_pitchbend(1) -, inertia_pressure(64) -{ -} - -void monosynth_audio_module::activate() { - running = false; - output_pos = 0; - queue_note_on = -1; - inertia_pitchbend.set_now(1.f); - lfo_bend = 1.0; - modwheel_value = 0.f; - modwheel_value_int = 0; - inertia_cutoff.set_now(*params[par_cutoff]); - inertia_pressure.set_now(0); - filter.reset(); - filter2.reset(); - stack.clear(); - last_pwshift1 = last_pwshift2 = 0; - last_stretch1 = 65536; - queue_note_on_and_off = false; - prev_wave1 = -1; - prev_wave2 = -1; - wave1 = -1; - wave2 = -1; - queue_note_on = -1; - last_filter_type = -1; -} - -waveform_family *monosynth_audio_module::waves; - -void monosynth_audio_module::precalculate_waves(progress_report_iface *reporter) -{ - float data[1 << MONOSYNTH_WAVE_BITS]; - bandlimiter bl; - - if (waves) - return; - - static waveform_family waves_data[wave_count]; - waves = waves_data; - - enum { S = 1 << MONOSYNTH_WAVE_BITS, HS = S / 2, QS = S / 4, QS3 = 3 * QS }; - float iQS = 1.0 / QS; - - if (reporter) - reporter->report_progress(0, "Precalculating waveforms"); - - // yes these waves don't have really perfect 1/x spectrum because of aliasing - // (so what?) - for (int i = 0 ; i < HS; i++) - data[i] = (float)(i * 1.0 / HS), - data[i + HS] = (float)(i * 1.0 / HS - 1.0f); - waves[wave_saw].make(bl, data); - - // this one is dummy, fake and sham, we're using a difference of two sawtooths for square wave due to PWM - for (int i = 0 ; i < S; i++) - data[i] = (float)(i < HS ? -1.f : 1.f); - waves[wave_sqr].make(bl, data, 4); - - for (int i = 0 ; i < S; i++) - data[i] = (float)(i < (64 * S / 2048)? -1.f : 1.f); - waves[wave_pulse].make(bl, data); - - for (int i = 0 ; i < S; i++) - data[i] = (float)sin(i * M_PI / HS); - waves[wave_sine].make(bl, data); - - for (int i = 0 ; i < QS; i++) { - data[i] = i * iQS, - data[i + QS] = 1 - i * iQS, - data[i + HS] = - i * iQS, - data[i + QS3] = -1 + i * iQS; - } - waves[wave_triangle].make(bl, data); - - for (int i = 0, j = 1; i < S; i++) { - data[i] = -1 + j * 1.0 / HS; - if (i == j) - j *= 2; - } - waves[wave_varistep].make(bl, data); - - for (int i = 0; i < S; i++) { - data[i] = (min(1.f, (float)(i / 64.f))) * (1.0 - i * 1.0 / S) * (-1 + fmod (i * i * 8/ (S * S * 1.0), 2.0)); - } - waves[wave_skewsaw].make(bl, data); - for (int i = 0; i < S; i++) { - data[i] = (min(1.f, (float)(i / 64.f))) * (1.0 - i * 1.0 / S) * (fmod (i * i * 8/ (S * S * 1.0), 2.0) < 1.0 ? -1.0 : +1.0); - } - waves[wave_skewsqr].make(bl, data); - - if (reporter) - reporter->report_progress(50, "Precalculating waveforms"); - - for (int i = 0; i < S; i++) { - if (i < QS3) { - float p = i * 1.0 / QS3; - data[i] = sin(M_PI * p * p * p); - } else { - float p = (i - QS3 * 1.0) / QS; - data[i] = -0.5 * sin(3 * M_PI * p * p); - } - } - waves[wave_test1].make(bl, data); - for (int i = 0; i < S; i++) { - data[i] = exp(-i * 1.0 / HS) * sin(i * M_PI / HS) * cos(2 * M_PI * i / HS); - } - normalize_waveform(data, S); - waves[wave_test2].make(bl, data); - for (int i = 0; i < S; i++) { - //int ii = (i < HS) ? i : S - i; - int ii = HS; - data[i] = (ii * 1.0 / HS) * sin(i * 3 * M_PI / HS + 2 * M_PI * sin(M_PI / 4 + i * 4 * M_PI / HS)) * sin(i * 5 * M_PI / HS + 2 * M_PI * sin(M_PI / 8 + i * 6 * M_PI / HS)); - } - waves[wave_test3].make(bl, data); - for (int i = 0; i < S; i++) { - data[i] = sin(i * 2 * M_PI / HS + sin(i * 2 * M_PI / HS + 0.5 * M_PI * sin(i * 18 * M_PI / HS)) * sin(i * 1 * M_PI / HS + 0.5 * M_PI * sin(i * 11 * M_PI / HS))); - } - waves[wave_test4].make(bl, data); - for (int i = 0; i < S; i++) { - data[i] = sin(i * 2 * M_PI / HS + 0.2 * M_PI * sin(i * 13 * M_PI / HS) + 0.1 * M_PI * sin(i * 37 * M_PI / HS)) * sin(i * M_PI / HS + 0.2 * M_PI * sin(i * 15 * M_PI / HS)); - } - waves[wave_test5].make(bl, data); - for (int i = 0; i < S; i++) { - if (i < HS) - data[i] = sin(i * 2 * M_PI / HS); - else - if (i < 3 * S / 4) - data[i] = sin(i * 4 * M_PI / HS); - else - if (i < 7 * S / 8) - data[i] = sin(i * 8 * M_PI / HS); - else - data[i] = sin(i * 8 * M_PI / HS) * (S - i) / (S / 8); - } - waves[wave_test6].make(bl, data); - for (int i = 0; i < S; i++) { - int j = i >> (MONOSYNTH_WAVE_BITS - 11); - data[i] = (j ^ 0x1D0) * 1.0 / HS - 1; - } - waves[wave_test7].make(bl, data); - for (int i = 0; i < S; i++) { - int j = i >> (MONOSYNTH_WAVE_BITS - 11); - data[i] = -1 + 0.66 * (3 & ((j >> 8) ^ (j >> 10) ^ (j >> 6))); - } - waves[wave_test8].make(bl, data); - if (reporter) - reporter->report_progress(100, ""); - -} - -bool monosynth_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const -{ - monosynth_audio_module::precalculate_waves(NULL); - // printf("get_graph %d %p %d wave1=%d wave2=%d\n", index, data, points, wave1, wave2); - if (index == par_wave1 || index == par_wave2) { - if (subindex) - return false; - enum { S = 1 << MONOSYNTH_WAVE_BITS }; - float value = *params[index]; - int wave = dsp::clip(dsp::fastf2i_drm(value), 0, (int)wave_count - 1); - - uint32_t shift = index == par_wave1 ? last_pwshift1 : last_pwshift2; - if (!running) - shift = (int32_t)(0x78000000 * (*params[index == par_wave1 ? par_pw1 : par_pw2])); - int flag = (wave == wave_sqr); - - shift = (flag ? S/2 : 0) + (shift >> (32 - MONOSYNTH_WAVE_BITS)); - int sign = flag ? -1 : 1; - if (wave == wave_sqr) - wave = wave_saw; - float *waveform = waves[wave].original; - float rnd_start = 1 - *params[par_window1] * 0.5f; - float scl = rnd_start < 1.0 ? 1.f / (1 - rnd_start) : 0.f; - for (int i = 0; i < points; i++) - { - int pos = i * S / points; - float r = 1; - if (index == par_wave1) - { - float ph = i * 1.0 / points; - if (ph < 0.5f) - ph = 1.f - ph; - ph = (ph - rnd_start) * scl; - if (ph < 0) - ph = 0; - r = 1.0 - ph * ph; - pos = int(pos * 1.0 * last_stretch1 / 65536.0 ) % S; - } - data[i] = r * (sign * waveform[pos] + waveform[(pos + shift) & (S - 1)]) / (sign == -1 ? 1 : 2); - } - return true; - } - if (index == par_filtertype) { - if (!running) - return false; - if (subindex > (is_stereo_filter() ? 1 : 0)) - return false; - for (int i = 0; i < points; i++) - { - double freq = 20.0 * pow (20000.0 / 20.0, i * 1.0 / points); - - const dsp::biquad_d1_lerp &f = subindex ? filter2 : filter; - float level = f.freq_gain(freq, srate); - if (!is_stereo_filter()) - level *= filter2.freq_gain(freq, srate); - level *= fgain; - - data[i] = log(level) / log(1024.0) + 0.5; - } - return true; - } - return get_static_graph(index, subindex, *params[index], data, points, context); -} - -void monosynth_audio_module::calculate_buffer_oscs(float lfo1) -{ - int flag1 = (wave1 == wave_sqr); - int flag2 = (wave2 == wave_sqr); - - int32_t shift1 = last_pwshift1; - int32_t shift2 = last_pwshift2; - int32_t stretch1 = last_stretch1; - int32_t shift_target1 = (int32_t)(0x78000000 * dsp::clip11(*params[par_pw1] + lfo1 * *params[par_lfopw] + 0.01f * moddest[moddest_o1pw])); - int32_t shift_target2 = (int32_t)(0x78000000 * dsp::clip11(*params[par_pw2] + lfo1 * *params[par_lfopw] + 0.01f * moddest[moddest_o2pw])); - int32_t stretch_target1 = (int32_t)(65536 * dsp::clip(*params[par_stretch1] + 0.01f * moddest[moddest_o1stretch], 1.f, 16.f)); - int32_t shift_delta1 = ((shift_target1 >> 1) - (last_pwshift1 >> 1)) >> (step_shift - 1); - int32_t shift_delta2 = ((shift_target2 >> 1) - (last_pwshift2 >> 1)) >> (step_shift - 1); - int32_t stretch_delta1 = ((stretch_target1 >> 1) - (last_stretch1 >> 1)) >> (step_shift - 1); - last_pwshift1 = shift_target1; - last_pwshift2 = shift_target2; - last_stretch1 = stretch_target1; - lookup_waveforms(); - - shift1 += (flag1 << 31); - shift2 += (flag2 << 31); - float mix1 = 1 - 2 * flag1, mix2 = 1 - 2 * flag2; - - float new_xfade = dsp::clip(xfade + 0.01f * moddest[moddest_oscmix], 0.f, 1.f); - float cur_xfade = last_xfade; - float xfade_step = (new_xfade - cur_xfade) * (1.0 / step_size); - - float rnd_start = 1 - *params[par_window1] * 0.5f; - float scl = rnd_start < 1.0 ? 1.f / (1 - rnd_start) : 0.f; - - for (uint32_t i = 0; i < step_size; i++) - { - //buffer[i] = lerp(osc1.get_phaseshifted(shift1, mix1), osc2.get_phaseshifted(shift2, mix2), cur_xfade); - float o1phase = osc1.phase / (65536.0 * 65536.0); - if (o1phase < 0.5) - o1phase = 1 - o1phase; - o1phase = (o1phase - rnd_start) * scl; - if (o1phase < 0) - o1phase = 0; - float r = 1.0 - o1phase * o1phase; - buffer[i] = lerp(r * osc1.get_phasedist(stretch1, shift1, mix1), osc2.get_phaseshifted(shift2, mix2), cur_xfade); - osc1.advance(); - osc2.advance(); - shift1 += shift_delta1; - shift2 += shift_delta2; - stretch1 += stretch_delta1; - cur_xfade += xfade_step; - } - last_xfade = new_xfade; -} - -void monosynth_audio_module::calculate_buffer_ser() -{ - filter.big_step(1.0 / step_size); - filter2.big_step(1.0 / step_size); - for (uint32_t i = 0; i < step_size; i++) - { - float wave = buffer[i] * fgain; - wave = filter.process(wave); - wave = filter2.process(wave); - buffer[i] = wave; - fgain += fgain_delta; - } -} - -void monosynth_audio_module::calculate_buffer_single() -{ - filter.big_step(1.0 / step_size); - for (uint32_t i = 0; i < step_size; i++) - { - float wave = buffer[i] * fgain; - wave = filter.process(wave); - buffer[i] = wave; - fgain += fgain_delta; - } -} - -void monosynth_audio_module::calculate_buffer_stereo() -{ - filter.big_step(1.0 / step_size); - filter2.big_step(1.0 / step_size); - for (uint32_t i = 0; i < step_size; i++) - { - float wave1 = buffer[i] * fgain; - buffer[i] = fgain * filter.process(wave1); - buffer2[i] = fgain * filter2.process(wave1); - fgain += fgain_delta; - } -} - -void monosynth_audio_module::lookup_waveforms() -{ - osc1.waveform = waves[wave1 == wave_sqr ? wave_saw : wave1].get_level((uint32_t)(((uint64_t)osc1.phasedelta) * last_stretch1 >> 16)); - osc2.waveform = waves[wave2 == wave_sqr ? wave_saw : wave2].get_level(osc2.phasedelta); - if (!osc1.waveform) osc1.waveform = silence; - if (!osc2.waveform) osc2.waveform = silence; - prev_wave1 = wave1; - prev_wave2 = wave2; -} - -void monosynth_audio_module::delayed_note_on() -{ - force_fadeout = false; - fadeout.reset_soft(); - fadeout2.reset_soft(); - porta_time = 0.f; - start_freq = freq; - target_freq = freq = 440 * pow(2.0, (queue_note_on - 69) / 12.0); - velocity = queue_vel; - ampctl = 1.0 + (queue_vel - 1.0) * *params[par_vel2amp]; - fltctl = 1.0 + (queue_vel - 1.0) * *params[par_vel2filter]; - bool starting = false; - - if (!running) - { - starting = true; - if (legato >= 2) - porta_time = -1.f; - last_xfade = xfade; - osc1.reset(); - osc2.reset(); - filter.reset(); - filter2.reset(); - if (*params[par_lfo1trig] <= 0) - lfo1.reset(); - if (*params[par_lfo2trig] <= 0) - lfo2.reset(); - switch((int)*params[par_oscmode]) - { - case 1: - osc2.phase = 0x80000000; - break; - case 2: - osc2.phase = 0x40000000; - break; - case 3: - osc1.phase = osc2.phase = 0x40000000; - break; - case 4: - osc1.phase = 0x40000000; - osc2.phase = 0xC0000000; - break; - case 5: - // rand() is crap, but I don't have any better RNG in Calf yet - osc1.phase = rand() << 16; - osc2.phase = rand() << 16; - break; - default: - break; - } - running = true; - } - if (legato >= 2 && !gate) - porta_time = -1.f; - gate = true; - stopping = false; - if (starting || !(legato & 1) || envelope1.released()) - envelope1.note_on(); - if (starting || !(legato & 1) || envelope2.released()) - envelope2.note_on(); - envelope1.advance(); - envelope2.advance(); - queue_note_on = -1; - float modsrc[modsrc_count] = { - 1, - velocity, - inertia_pressure.get_last(), - modwheel_value, - (float)envelope1.value, - (float)envelope2.value, - (float)(0.5+0.5*lfo1.last), - (float)(0.5+0.5*lfo2.last) - }; - calculate_modmatrix(moddest, moddest_count, modsrc); - set_frequency(); - lookup_waveforms(); - - if (queue_note_on_and_off) - { - end_note(); - queue_note_on_and_off = false; - } -} - -void monosynth_audio_module::set_sample_rate(uint32_t sr) { - srate = sr; - crate = sr / step_size; - odcr = (float)(1.0 / crate); - fgain = 0.f; - fgain_delta = 0.f; - inertia_cutoff.ramp.set_length(crate / 30); // 1/30s - inertia_pitchbend.ramp.set_length(crate / 30); // 1/30s - master.set_sample_rate(sr); -} - -void monosynth_audio_module::calculate_step() -{ - if (queue_note_on != -1) - delayed_note_on(); - else - if (stopping || !running) - { - running = false; - envelope1.advance(); - envelope2.advance(); - lfo1.get(); - lfo2.get(); - float modsrc[modsrc_count] = { - 1, - velocity, - inertia_pressure.get_last(), - modwheel_value, - (float)envelope1.value, - (float)envelope2.value, - (float)(0.5+0.5*lfo1.last), - (float)(0.5+0.5*lfo2.last) - }; - calculate_modmatrix(moddest, moddest_count, modsrc); - last_stretch1 = (int32_t)(65536 * dsp::clip(*params[par_stretch1] + 0.01f * moddest[moddest_o1stretch], 1.f, 16.f)); - return; - } - lfo1.set_freq(*params[par_lforate], crate); - lfo2.set_freq(*params[par_lfo2rate], crate); - float porta_total_time = *params[par_portamento] * 0.001f; - - if (porta_total_time >= 0.00101f && porta_time >= 0) { - // XXXKF this is criminal, optimize! - float point = porta_time / porta_total_time; - if (point >= 1.0f) { - freq = target_freq; - porta_time = -1; - } else { - freq = start_freq + (target_freq - start_freq) * point; - // freq = start_freq * pow(target_freq / start_freq, point); - porta_time += odcr; - } - } - float lfov1 = lfo1.get() * std::min(1.0f, lfo_clock / *params[par_lfodelay]); - lfov1 = lfov1 * dsp::lerp(1.f, modwheel_value, *params[par_mwhl_lfo]); - float lfov2 = lfo2.get() * std::min(1.0f, lfo_clock / *params[par_lfo2delay]); - lfo_clock += odcr; - if (fabs(*params[par_lfopitch]) > small_value()) - lfo_bend = pow(2.0f, *params[par_lfopitch] * lfov1 * (1.f / 1200.0f)); - inertia_pitchbend.step(); - envelope1.advance(); - envelope2.advance(); - float env1 = envelope1.value, env2 = envelope2.value; - float aenv1 = envelope1.get_amp_value(), aenv2 = envelope2.get_amp_value(); - - // mod matrix - // this should be optimized heavily; I think I'll do it when MIDI in Ardour 3 gets stable :> - float modsrc[modsrc_count] = { - 1, - velocity, - inertia_pressure.get(), - modwheel_value, - (float)env1, - (float)env2, - (float)(0.5+0.5*lfov1), - (float)(0.5+0.5*lfov2) - }; - calculate_modmatrix(moddest, moddest_count, modsrc); - - set_frequency(); - inertia_cutoff.set_inertia(*params[par_cutoff]); - cutoff = inertia_cutoff.get() * pow(2.0f, (lfov1 * *params[par_lfofilter] + env1 * fltctl * *params[par_env1tocutoff] + env2 * fltctl * *params[par_env2tocutoff] + moddest[moddest_cutoff]) * (1.f / 1200.f)); - if (*params[par_keyfollow] > 0.01f) - cutoff *= pow(freq / 264.f, *params[par_keyfollow]); - cutoff = dsp::clip(cutoff , 10.f, 18000.f); - float resonance = *params[par_resonance]; - float e2r1 = *params[par_env1tores]; - resonance = resonance * (1 - e2r1) + (0.7 + (resonance - 0.7) * env1 * env1) * e2r1; - float e2r2 = *params[par_env2tores]; - resonance = resonance * (1 - e2r2) + (0.7 + (resonance - 0.7) * env2 * env2) * e2r2 + moddest[moddest_resonance]; - float cutoff2 = dsp::clip(cutoff * separation, 10.f, 18000.f); - float newfgain = 0.f; - if (filter_type != last_filter_type) - { - filter.y2 = filter.y1 = filter.x2 = filter.x1 = filter.y1; - filter2.y2 = filter2.y1 = filter2.x2 = filter2.x1 = filter2.y1; - last_filter_type = filter_type; - } - switch(filter_type) - { - case flt_lp12: - filter.set_lp_rbj(cutoff, resonance, srate); - filter2.set_null(); - newfgain = min(0.7f, 0.7f / resonance) * ampctl; - break; - case flt_hp12: - filter.set_hp_rbj(cutoff, resonance, srate); - filter2.set_null(); - newfgain = min(0.7f, 0.7f / resonance) * ampctl; - break; - case flt_lp24: - filter.set_lp_rbj(cutoff, resonance, srate); - filter2.set_lp_rbj(cutoff2, resonance, srate); - newfgain = min(0.5f, 0.5f / resonance) * ampctl; - break; - case flt_lpbr: - filter.set_lp_rbj(cutoff, resonance, srate); - filter2.set_br_rbj(cutoff2, 1.0 / resonance, srate); - newfgain = min(0.5f, 0.5f / resonance) * ampctl; - break; - case flt_hpbr: - filter.set_hp_rbj(cutoff, resonance, srate); - filter2.set_br_rbj(cutoff2, 1.0 / resonance, srate); - newfgain = min(0.5f, 0.5f / resonance) * ampctl; - break; - case flt_2lp12: - filter.set_lp_rbj(cutoff, resonance, srate); - filter2.set_lp_rbj(cutoff2, resonance, srate); - newfgain = min(0.7f, 0.7f / resonance) * ampctl; - break; - case flt_bp6: - filter.set_bp_rbj(cutoff, resonance, srate); - filter2.set_null(); - newfgain = ampctl; - break; - case flt_2bp6: - filter.set_bp_rbj(cutoff, resonance, srate); - filter2.set_bp_rbj(cutoff2, resonance, srate); - newfgain = ampctl; - break; - } - float e2a1 = *params[par_env1toamp]; - float e2a2 = *params[par_env2toamp]; - if (e2a1 > 0.f) - newfgain *= aenv1; - if (e2a2 > 0.f) - newfgain *= aenv2; - if (moddest[moddest_attenuation] != 0.f) - newfgain *= dsp::clip(1 - moddest[moddest_attenuation] * moddest[moddest_attenuation], 0.f, 1.f); - fgain_delta = (newfgain - fgain) * (1.0 / step_size); - calculate_buffer_oscs(lfov1); - lfo1.last = lfov1; - lfo2.last = lfov2; - switch(filter_type) - { - case flt_lp24: - case flt_lpbr: - case flt_hpbr: // Oomek's wish - calculate_buffer_ser(); - break; - case flt_lp12: - case flt_hp12: - case flt_bp6: - calculate_buffer_single(); - break; - case flt_2lp12: - case flt_2bp6: - calculate_buffer_stereo(); - break; - } - apply_fadeout(); -} - -void monosynth_audio_module::apply_fadeout() -{ - if (fadeout.undoing) - { - fadeout.process(buffer2, step_size); - if (is_stereo_filter()) - fadeout2.process(buffer2, step_size); - } - else - { - // stop the sound if the amplitude envelope is not running (if there's any) - bool aenv1_on = *params[par_env1toamp] > 0.f, aenv2_on = *params[par_env2toamp] > 0.f; - - bool do_fadeout = force_fadeout; - - // if there's no amplitude envelope at all, the fadeout starts at key release - if (!aenv1_on && !aenv2_on && !gate) - do_fadeout = true; - // if ENV1 modulates amplitude, the fadeout will start on ENV1 end too - if (aenv1_on && envelope1.state == adsr::STOP) - do_fadeout = true; - // if ENV2 modulates amplitude, the fadeout will start on ENV2 end too - if (aenv2_on && envelope2.state == adsr::STOP) - do_fadeout = true; - - if (do_fadeout || fadeout.undoing || fadeout2.undoing) - { - fadeout.process(buffer, step_size); - if (is_stereo_filter()) - fadeout2.process(buffer2, step_size); - if (fadeout.done) - stopping = true; - } - } -} - -void monosynth_audio_module::note_on(int /*channel*/, int note, int vel) -{ - queue_note_on = note; - queue_note_on_and_off = false; - last_key = note; - queue_vel = vel / 127.f; - stack.push(note); -} - -void monosynth_audio_module::note_off(int /*channel*/, int note, int vel) -{ - stack.pop(note); - if (note == queue_note_on) - { - queue_note_on_and_off = true; - return; - } - // If releasing the currently played note, try to get another one from note stack. - if (note == last_key) { - end_note(); - } -} - -void monosynth_audio_module::end_note() -{ - if (stack.count()) - { - int note; - last_key = note = stack.nth(stack.count() - 1); - start_freq = freq; - target_freq = freq = dsp::note_to_hz(note); - porta_time = 0; - set_frequency(); - if (!(legato & 1)) { - envelope1.note_on(); - envelope2.note_on(); - stopping = false; - running = true; - } - return; - } - gate = false; - envelope1.note_off(); - envelope2.note_off(); -} - -void monosynth_audio_module::channel_pressure(int /*channel*/, int value) -{ - inertia_pressure.set_inertia(value * (1.0 / 127.0)); -} - -void monosynth_audio_module::control_change(int /*channel*/, int controller, int value) -{ - switch(controller) - { - case 1: - modwheel_value_int = (modwheel_value_int & 127) | (value << 7); - modwheel_value = modwheel_value_int / 16383.0; - break; - case 33: - modwheel_value_int = (modwheel_value_int & (127 << 7)) | value; - modwheel_value = modwheel_value_int / 16383.0; - break; - case 120: // all sounds off - force_fadeout = true; - // fall through - case 123: // all notes off - gate = false; - queue_note_on = -1; - envelope1.note_off(); - envelope2.note_off(); - stack.clear(); - break; - } -} - -void monosynth_audio_module::deactivate() -{ - gate = false; - running = false; - stopping = false; - envelope1.reset(); - envelope2.reset(); - stack.clear(); -} - -void monosynth_audio_module::set_frequency() -{ - float detune_scaled = (detune - 1); // * log(freq / 440); - if (*params[par_scaledetune] > 0) - detune_scaled *= pow(20.0 / freq, (double)*params[par_scaledetune]); - float p1 = 1, p2 = 1; - if (moddest[moddest_o1detune] != 0) - p1 = pow(2.0, moddest[moddest_o1detune] * (1.0 / 1200.0)); - if (moddest[moddest_o2detune] != 0) - p2 = pow(2.0, moddest[moddest_o2detune] * (1.0 / 1200.0)); - osc1.set_freq(freq * (1 - detune_scaled) * p1 * inertia_pitchbend.get_last() * lfo_bend, srate); - osc2.set_freq(freq * (1 + detune_scaled) * p2 * inertia_pitchbend.get_last() * lfo_bend * xpose, srate); -} - - -void monosynth_audio_module::params_changed() -{ - float sf = 0.001f; - envelope1.set(*params[par_env1attack] * sf, *params[par_env1decay] * sf, std::min(0.999f, *params[par_env1sustain]), *params[par_env1release] * sf, srate / step_size, *params[par_env1fade] * sf); - envelope2.set(*params[par_env2attack] * sf, *params[par_env2decay] * sf, std::min(0.999f, *params[par_env2sustain]), *params[par_env2release] * sf, srate / step_size, *params[par_env2fade] * sf); - filter_type = dsp::fastf2i_drm(*params[par_filtertype]); - separation = pow(2.0, *params[par_cutoffsep] / 1200.0); - wave1 = dsp::clip(dsp::fastf2i_drm(*params[par_wave1]), 0, (int)wave_count - 1); - wave2 = dsp::clip(dsp::fastf2i_drm(*params[par_wave2]), 0, (int)wave_count - 1); - detune = pow(2.0, *params[par_detune] / 1200.0); - xpose = pow(2.0, *params[par_osc2xpose] / 12.0); - xfade = *params[par_oscmix]; - legato = dsp::fastf2i_drm(*params[par_legato]); - master.set_inertia(*params[par_master]); - if (running) - set_frequency(); - if (wave1 != prev_wave1 || wave2 != prev_wave2) - lookup_waveforms(); -} - - -uint32_t monosynth_audio_module::process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask) -{ - uint32_t op = offset; - uint32_t op_end = offset + nsamples; - int had_data = 0; - while(op < op_end) { - if (output_pos == 0) - calculate_step(); - if(op < op_end) { - uint32_t ip = output_pos; - uint32_t len = std::min(step_size - output_pos, op_end - op); - if (running) - { - had_data = 3; - if (is_stereo_filter()) - for(uint32_t i = 0 ; i < len; i++) { - float vol = master.get(); - outs[0][op + i] = buffer[ip + i] * vol; - outs[1][op + i] = buffer2[ip + i] * vol; - } - else - for(uint32_t i = 0 ; i < len; i++) - outs[0][op + i] = outs[1][op + i] = buffer[ip + i] * master.get(); - } - else - { - dsp::zero(&outs[0][op], len); - dsp::zero(&outs[1][op], len); - } - op += len; - output_pos += len; - if (output_pos == step_size) - output_pos = 0; - } - } - - return had_data; -} - diff --git a/plugins/LadspaEffect/calf/src/organ.cpp b/plugins/LadspaEffect/calf/src/organ.cpp deleted file mode 100644 index c90fc50bdb5..00000000000 --- a/plugins/LadspaEffect/calf/src/organ.cpp +++ /dev/null @@ -1,1095 +0,0 @@ -/* Calf DSP Library - * Example audio modules - organ - * - * Copyright (C) 2001-2007 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 02110-1301 USA - */ -#include - -#include -#include -#include - -using namespace std; -using namespace dsp; -using namespace calf_plugins; - -////////////////////////////////////////////////////////////////////////////////////////////////////////// - -organ_audio_module::organ_audio_module() -: drawbar_organ(&par_values) -{ - var_map_curve = "2\n0 1\n1 1\n"; // XXXKF hacky bugfix -} - -void organ_audio_module::activate() -{ - setup(srate); - panic_flag = false; -} - -void organ_audio_module::post_instantiate() -{ - dsp::organ_voice_base::precalculate_waves(progress_report); -} - - -uint32_t organ_audio_module::process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask) -{ - float *o[2] = { outs[0] + offset, outs[1] + offset }; - if (panic_flag) - { - control_change(120, 0); // stop all sounds - control_change(121, 0); // reset all controllers - panic_flag = false; - } - render_separate(o, nsamples); - return 3; -} - -void organ_audio_module::params_changed() { - for (int i = 0; i < param_count; i++) - ((float *)&par_values)[i] = *params[i]; - - unsigned int old_poly = polyphony_limit; - polyphony_limit = dsp::clip(dsp::fastf2i_drm(*params[par_polyphony]), 1, 32); - if (polyphony_limit < old_poly) - trim_voices(); - - update_params(); -} - -bool organ_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const -{ - if (index == par_master) { - organ_voice_base::precalculate_waves(progress_report); - if (subindex) - return false; - float *waveforms[9]; - int S[9], S2[9]; - enum { small_waves = organ_voice_base::wave_count_small}; - for (int i = 0; i < 9; i++) - { - int wave = dsp::clip((int)(parameters->waveforms[i]), 0, (int)organ_voice_base::wave_count - 1); - if (wave >= small_waves) - { - waveforms[i] = organ_voice_base::get_big_wave(wave - small_waves).original; - S[i] = ORGAN_BIG_WAVE_SIZE; - S2[i] = ORGAN_WAVE_SIZE / 64; - } - else - { - waveforms[i] = organ_voice_base::get_wave(wave).original; - S[i] = S2[i] = ORGAN_WAVE_SIZE; - } - } - for (int i = 0; i < points; i++) - { - float sum = 0.f; - for (int j = 0; j < 9; j++) - { - float shift = parameters->phase[j] * S[j] / 360.0; - sum += parameters->drawbars[j] * waveforms[j][int(parameters->harmonics[j] * i * S2[j] / points + shift) & (S[j] - 1)]; - } - data[i] = sum * 2 / (9 * 8); - } - return true; - } - return false; -} - -uint32_t organ_audio_module::message_run(const void *valid_inputs, void *output_ports) -{ - // silence a default printf (which is kind of a warning about unhandled message_run) - return 0; -} - - -//////////////////////////////////////////////////////////////////////////// - -organ_voice_base::small_wave_family (*organ_voice_base::waves)[organ_voice_base::wave_count_small]; -organ_voice_base::big_wave_family (*organ_voice_base::big_waves)[organ_voice_base::wave_count_big]; - -static void smoothen(bandlimiter &bl, float tmp[ORGAN_WAVE_SIZE]) -{ - bl.compute_spectrum(tmp); - for (int i = 1; i <= ORGAN_WAVE_SIZE / 2; i++) { - bl.spectrum[i] *= 1.0 / sqrt(i); - bl.spectrum[ORGAN_WAVE_SIZE - i] *= 1.0 / sqrt(i); - } - bl.compute_waveform(tmp); - normalize_waveform(tmp, ORGAN_WAVE_SIZE); -} - -static void phaseshift(bandlimiter &bl, float tmp[ORGAN_WAVE_SIZE]) -{ - bl.compute_spectrum(tmp); - for (int i = 1; i <= ORGAN_WAVE_SIZE / 2; i++) { - float frac = i * 2.0 / ORGAN_WAVE_SIZE; - float phase = M_PI / sqrt(frac) ; - complex shift = complex(cos(phase), sin(phase)); - bl.spectrum[i] *= shift; - bl.spectrum[ORGAN_WAVE_SIZE - i] *= conj(shift); - } - bl.compute_waveform(tmp); - normalize_waveform(tmp, ORGAN_WAVE_SIZE); -} - -static void padsynth(bandlimiter blSrc, bandlimiter &blDest, organ_voice_base::big_wave_family &result, int bwscale = 20, float bell_factor = 0, bool foldover = false) -{ - // kept in a vector to avoid putting large arrays on stack - vector >orig_spectrum; - orig_spectrum.resize(ORGAN_WAVE_SIZE / 2); - for (int i = 0; i < ORGAN_WAVE_SIZE / 2; i++) - { - orig_spectrum[i] = blSrc.spectrum[i]; -// printf("@%d = %f\n", i, abs(orig_spectrum[i])); - } - - int periods = (1 << ORGAN_BIG_WAVE_SHIFT) * ORGAN_BIG_WAVE_SIZE / ORGAN_WAVE_SIZE; - for (int i = 0; i <= ORGAN_BIG_WAVE_SIZE / 2; i++) { - blDest.spectrum[i] = 0; - } - int MAXHARM = (ORGAN_WAVE_SIZE >> (1 + ORGAN_BIG_WAVE_SHIFT)); - for (int i = 1; i <= MAXHARM; i++) { - //float esc = 0.25 * (1 + 0.5 * log(i)); - float esc = 0.5; - float amp = abs(blSrc.spectrum[i]); - // fade out starting from half - if (i >= MAXHARM / 2) { - float pos = (i - MAXHARM/2) * 1.0 / (MAXHARM / 2); - amp *= 1.0 - pos; - amp *= 1.0 - pos; - } - int bw = 1 + 20 * i; - float sum = 1; - int delta = 1; - if (bw > 20) delta = bw / 20; - for (int j = delta; j <= bw; j+=delta) - { - float p = j * 1.0 / bw; - sum += 2 * exp(-p * p * esc); - } - if (sum < 0.0001) - continue; - amp *= (ORGAN_BIG_WAVE_SIZE / ORGAN_WAVE_SIZE); - amp /= sum; - int orig = i * periods + bell_factor * cos(i); - if (orig > 0 && orig < ORGAN_BIG_WAVE_SIZE / 2) - blDest.spectrum[orig] += amp; - for (int j = delta; j <= bw; j += delta) - { - float p = j * 1.0 / bw; - float val = amp * exp(-p * p * esc); - int dist = j * bwscale / 40; - int pos = orig + dist; - if (pos < 1 || pos >= ORGAN_BIG_WAVE_SIZE / 2) - continue; - int pos2 = orig - dist; - if (pos2 < 1 || pos2 >= ORGAN_BIG_WAVE_SIZE / 2) - continue; - blDest.spectrum[pos] += val; - if (j) - blDest.spectrum[pos2] += val; - } - } - for (int i = 1; i <= ORGAN_BIG_WAVE_SIZE / 2; i++) { - float phase = M_PI * 2 * (rand() & 255) / 256; - complex shift = complex(cos(phase), sin(phase)); - blDest.spectrum[i] *= shift; -// printf("@%d = %f\n", i, abs(blDest.spectrum[i])); - - blDest.spectrum[ORGAN_BIG_WAVE_SIZE - i] = conj(blDest.spectrum[i]); - } - // same as above - put large array on heap to avoid stack overflow in ingen - vector tmp; - tmp.resize(ORGAN_BIG_WAVE_SIZE); - float *ptmp = &tmp.front(); - blDest.compute_waveform(ptmp); - normalize_waveform(ptmp, ORGAN_BIG_WAVE_SIZE); - blDest.compute_spectrum(ptmp); - - // limit is 1/2 of the number of harmonics of the original wave - result.make_from_spectrum(blDest, foldover, ORGAN_WAVE_SIZE >> (1 + ORGAN_BIG_WAVE_SHIFT)); - memcpy(result.original, result.begin()->second, sizeof(result.original)); - #if 0 - blDest.compute_waveform(result); - normalize_waveform(result, ORGAN_BIG_WAVE_SIZE); - result[ORGAN_BIG_WAVE_SIZE] = result[0]; - for (int i =0 ; ireport_progress(floor(progress / totalwaves), "Precalculating large waveforms"); } } while(0) - -void organ_voice_base::update_pitch() -{ - float phase = dsp::midi_note_to_phase(note, 100 * parameters->global_transpose + parameters->global_detune, sample_rate_ref); - dpphase.set((long int) (phase * parameters->percussion_harmonic * parameters->pitch_bend)); - moddphase.set((long int) (phase * parameters->percussion_fm_harmonic * parameters->pitch_bend)); -} - -void organ_voice_base::precalculate_waves(progress_report_iface *reporter) -{ - static bool inited = false; - if (!inited) - { - static organ_voice_base::small_wave_family waves[organ_voice_base::wave_count_small]; - static organ_voice_base::big_wave_family big_waves[organ_voice_base::wave_count_big]; - organ_voice_base::waves = &waves; - organ_voice_base::big_waves = &big_waves; - - float progress = 0.0; - int totalwaves = 1 + wave_count_big; - if (reporter) - reporter->report_progress(0, "Precalculating small waveforms"); - float tmp[ORGAN_WAVE_SIZE]; - static bandlimiter bl; - static bandlimiter blBig; - for (int i = 0; i < ORGAN_WAVE_SIZE; i++) - tmp[i] = sin(i * 2 * M_PI / ORGAN_WAVE_SIZE); - waves[wave_sine].make(bl, tmp); - for (int i = 0; i < ORGAN_WAVE_SIZE; i++) - tmp[i] = (i < (ORGAN_WAVE_SIZE / 16)) ? 1 : 0; - normalize_waveform(tmp, ORGAN_WAVE_SIZE); - waves[wave_pulse].make(bl, tmp); - for (int i = 0; i < ORGAN_WAVE_SIZE; i++) - tmp[i] = i < (ORGAN_WAVE_SIZE / 2) ? sin(i * 2 * 2 * M_PI / ORGAN_WAVE_SIZE) : 0; - waves[wave_sinepl1].make(bl, tmp); - for (int i = 0; i < ORGAN_WAVE_SIZE; i++) - tmp[i] = i < (ORGAN_WAVE_SIZE / 3) ? sin(i * 3 * 2 * M_PI / ORGAN_WAVE_SIZE) : 0; - waves[wave_sinepl2].make(bl, tmp); - for (int i = 0; i < ORGAN_WAVE_SIZE; i++) - tmp[i] = i < (ORGAN_WAVE_SIZE / 4) ? sin(i * 4 * 2 * M_PI / ORGAN_WAVE_SIZE) : 0; - waves[wave_sinepl3].make(bl, tmp); - for (int i = 0; i < ORGAN_WAVE_SIZE; i++) - tmp[i] = (i < (ORGAN_WAVE_SIZE / 2)) ? 1 : -1; - normalize_waveform(tmp, ORGAN_WAVE_SIZE); - waves[wave_sqr].make(bl, tmp); - for (int i = 0; i < ORGAN_WAVE_SIZE; i++) - tmp[i] = -1 + (i * 2.0 / ORGAN_WAVE_SIZE); - normalize_waveform(tmp, ORGAN_WAVE_SIZE); - waves[wave_saw].make(bl, tmp); - - for (int i = 0; i < ORGAN_WAVE_SIZE; i++) - tmp[i] = (i < (ORGAN_WAVE_SIZE / 2)) ? 1 : -1; - normalize_waveform(tmp, ORGAN_WAVE_SIZE); - smoothen(bl, tmp); - waves[wave_ssqr].make(bl, tmp); - - for (int i = 0; i < ORGAN_WAVE_SIZE; i++) - tmp[i] = -1 + (i * 2.0 / ORGAN_WAVE_SIZE); - normalize_waveform(tmp, ORGAN_WAVE_SIZE); - smoothen(bl, tmp); - waves[wave_ssaw].make(bl, tmp); - - for (int i = 0; i < ORGAN_WAVE_SIZE; i++) - tmp[i] = (i < (ORGAN_WAVE_SIZE / 16)) ? 1 : 0; - normalize_waveform(tmp, ORGAN_WAVE_SIZE); - smoothen(bl, tmp); - waves[wave_spls].make(bl, tmp); - for (int i = 0; i < ORGAN_WAVE_SIZE; i++) - tmp[i] = i < (ORGAN_WAVE_SIZE / 1.5) ? sin(i * 1.5 * 2 * M_PI / ORGAN_WAVE_SIZE) : 0; - normalize_waveform(tmp, ORGAN_WAVE_SIZE); - waves[wave_sinepl05].make(bl, tmp); - for (int i = 0; i < ORGAN_WAVE_SIZE; i++) - tmp[i] = i < (ORGAN_WAVE_SIZE / 1.5) ? (i < ORGAN_WAVE_SIZE / 3 ? -1 : +1) : 0; - normalize_waveform(tmp, ORGAN_WAVE_SIZE); - waves[wave_sqr05].make(bl, tmp); - for (int i = 0; i < ORGAN_WAVE_SIZE; i++) - tmp[i] = sin(i * M_PI / ORGAN_WAVE_SIZE); - normalize_waveform(tmp, ORGAN_WAVE_SIZE); - waves[wave_halfsin].make(bl, tmp); - for (int i = 0; i < ORGAN_WAVE_SIZE; i++) - tmp[i] = sin(i * 3 * M_PI / ORGAN_WAVE_SIZE); - normalize_waveform(tmp, ORGAN_WAVE_SIZE); - waves[wave_clvg].make(bl, tmp); - for (int i = 0; i < ORGAN_WAVE_SIZE; i++) - { - float ph = i * 2 * M_PI / ORGAN_WAVE_SIZE; - float fm = 0.3 * sin(6*ph) + 0.2 * sin(11*ph) + 0.2 * cos(17*ph) - 0.2 * cos(19*ph); - tmp[i] = sin(5*ph + fm) + 0.7 * cos(7*ph - fm); - } - normalize_waveform(tmp, ORGAN_WAVE_SIZE); - waves[wave_bell].make(bl, tmp, true); - for (int i = 0; i < ORGAN_WAVE_SIZE; i++) - { - float ph = i * 2 * M_PI / ORGAN_WAVE_SIZE; - float fm = 0.3 * sin(3*ph) + 0.3 * sin(11*ph) + 0.3 * cos(17*ph) - 0.3 * cos(19*ph) + 0.3 * cos(25*ph) - 0.3 * cos(31*ph) + 0.3 * cos(37*ph); - tmp[i] = sin(3*ph + fm) + cos(7*ph - fm); - } - normalize_waveform(tmp, ORGAN_WAVE_SIZE); - waves[wave_bell2].make(bl, tmp, true); - for (int i = 0; i < ORGAN_WAVE_SIZE; i++) - { - float ph = i * 2 * M_PI / ORGAN_WAVE_SIZE; - float fm = 0.5 * sin(3*ph) + 0.3 * sin(5*ph) + 0.3 * cos(6*ph) - 0.3 * cos(9*ph); - tmp[i] = sin(4*ph + fm) + cos(ph - fm); - } - normalize_waveform(tmp, ORGAN_WAVE_SIZE); - waves[wave_w1].make(bl, tmp); - for (int i = 0; i < ORGAN_WAVE_SIZE; i++) - { - float ph = i * 2 * M_PI / ORGAN_WAVE_SIZE; - tmp[i] = sin(ph) * sin(2 * ph) * sin(4 * ph) * sin(8 * ph); - } - normalize_waveform(tmp, ORGAN_WAVE_SIZE); - waves[wave_w2].make(bl, tmp); - for (int i = 0; i < ORGAN_WAVE_SIZE; i++) - { - float ph = i * 2 * M_PI / ORGAN_WAVE_SIZE; - tmp[i] = sin(ph) * sin(3 * ph) * sin(5 * ph) * sin(7 * ph) * sin(9 * ph); - } - normalize_waveform(tmp, ORGAN_WAVE_SIZE); - waves[wave_w3].make(bl, tmp); - for (int i = 0; i < ORGAN_WAVE_SIZE; i++) - { - float ph = i * 2 * M_PI / ORGAN_WAVE_SIZE; - tmp[i] = sin(ph + 2 * sin(ph + 2 * sin(ph))); - } - normalize_waveform(tmp, ORGAN_WAVE_SIZE); - waves[wave_w4].make(bl, tmp); - for (int i = 0; i < ORGAN_WAVE_SIZE; i++) - { - float ph = i * 2 * M_PI / ORGAN_WAVE_SIZE; - tmp[i] = ph * sin(ph); - } - normalize_waveform(tmp, ORGAN_WAVE_SIZE); - waves[wave_w5].make(bl, tmp); - for (int i = 0; i < ORGAN_WAVE_SIZE; i++) - { - float ph = i * 2 * M_PI / ORGAN_WAVE_SIZE; - tmp[i] = ph * sin(ph) + (2 * M_PI - ph) * sin(2 * ph); - } - normalize_waveform(tmp, ORGAN_WAVE_SIZE); - waves[wave_w6].make(bl, tmp); - for (int i = 0; i < ORGAN_WAVE_SIZE; i++) - { - float ph = i * 1.0 / ORGAN_WAVE_SIZE; - tmp[i] = exp(-ph * ph); - } - normalize_waveform(tmp, ORGAN_WAVE_SIZE); - waves[wave_w7].make(bl, tmp); - for (int i = 0; i < ORGAN_WAVE_SIZE; i++) - { - float ph = i * 1.0 / ORGAN_WAVE_SIZE; - tmp[i] = exp(-ph * sin(2 * M_PI * ph)); - } - normalize_waveform(tmp, ORGAN_WAVE_SIZE); - waves[wave_w8].make(bl, tmp); - for (int i = 0; i < ORGAN_WAVE_SIZE; i++) - { - float ph = i * 1.0 / ORGAN_WAVE_SIZE; - tmp[i] = sin(2 * M_PI * ph * ph); - } - normalize_waveform(tmp, ORGAN_WAVE_SIZE); - waves[wave_w9].make(bl, tmp); - - for (int i = 0; i < ORGAN_WAVE_SIZE; i++) - tmp[i] = -1 + (i * 2.0 / ORGAN_WAVE_SIZE); - normalize_waveform(tmp, ORGAN_WAVE_SIZE); - phaseshift(bl, tmp); - waves[wave_dsaw].make(bl, tmp); - - for (int i = 0; i < ORGAN_WAVE_SIZE; i++) - tmp[i] = (i < (ORGAN_WAVE_SIZE / 2)) ? 1 : -1; - normalize_waveform(tmp, ORGAN_WAVE_SIZE); - phaseshift(bl, tmp); - waves[wave_dsqr].make(bl, tmp); - - for (int i = 0; i < ORGAN_WAVE_SIZE; i++) - tmp[i] = (i < (ORGAN_WAVE_SIZE / 16)) ? 1 : 0; - normalize_waveform(tmp, ORGAN_WAVE_SIZE); - phaseshift(bl, tmp); - waves[wave_dpls].make(bl, tmp); - - LARGE_WAVEFORM_PROGRESS(); - for (int i = 0; i < ORGAN_WAVE_SIZE; i++) - tmp[i] = -1 + (i * 2.0 / ORGAN_WAVE_SIZE); - normalize_waveform(tmp, ORGAN_WAVE_SIZE); - bl.compute_spectrum(tmp); - padsynth(bl, blBig, big_waves[wave_strings - wave_count_small], 15); - - LARGE_WAVEFORM_PROGRESS(); - for (int i = 0; i < ORGAN_WAVE_SIZE; i++) - tmp[i] = -1 + (i * 2.0 / ORGAN_WAVE_SIZE); - normalize_waveform(tmp, ORGAN_WAVE_SIZE); - bl.compute_spectrum(tmp); - padsynth(bl, blBig, big_waves[wave_strings2 - wave_count_small], 40); - - LARGE_WAVEFORM_PROGRESS(); - for (int i = 0; i < ORGAN_WAVE_SIZE; i++) - tmp[i] = sin(i * 2 * M_PI / ORGAN_WAVE_SIZE); - normalize_waveform(tmp, ORGAN_WAVE_SIZE); - bl.compute_spectrum(tmp); - padsynth(bl, blBig, big_waves[wave_sinepad - wave_count_small], 20); - - LARGE_WAVEFORM_PROGRESS(); - for (int i = 0; i < ORGAN_WAVE_SIZE; i++) - { - float ph = i * 2 * M_PI / ORGAN_WAVE_SIZE; - float fm = 0.3 * sin(6*ph) + 0.2 * sin(11*ph) + 0.2 * cos(17*ph) - 0.2 * cos(19*ph); - tmp[i] = sin(5*ph + fm) + 0.7 * cos(7*ph - fm); - } - normalize_waveform(tmp, ORGAN_WAVE_SIZE); - bl.compute_spectrum(tmp); - padsynth(bl, blBig, big_waves[wave_bellpad - wave_count_small], 30, 30, true); - - LARGE_WAVEFORM_PROGRESS(); - for (int i = 0; i < ORGAN_WAVE_SIZE; i++) - { - float ph = i * 2 * M_PI / ORGAN_WAVE_SIZE; - float fm = 0.3 * sin(3*ph) + 0.2 * sin(4*ph) + 0.2 * cos(5*ph) - 0.2 * cos(6*ph); - tmp[i] = sin(2*ph + fm) + 0.7 * cos(3*ph - fm); - } - normalize_waveform(tmp, ORGAN_WAVE_SIZE); - bl.compute_spectrum(tmp); - padsynth(bl, blBig, big_waves[wave_space - wave_count_small], 30, 30); - - LARGE_WAVEFORM_PROGRESS(); - for (int i = 0; i < ORGAN_WAVE_SIZE; i++) - { - float ph = i * 2 * M_PI / ORGAN_WAVE_SIZE; - float fm = 0.5 * sin(ph) + 0.5 * sin(2*ph) + 0.5 * sin(3*ph); - tmp[i] = sin(ph + fm) + 0.5 * cos(7*ph - 2 * fm) + 0.25 * cos(13*ph - 4 * fm); - } - normalize_waveform(tmp, ORGAN_WAVE_SIZE); - bl.compute_spectrum(tmp); - padsynth(bl, blBig, big_waves[wave_choir - wave_count_small], 50, 10); - - LARGE_WAVEFORM_PROGRESS(); - for (int i = 0; i < ORGAN_WAVE_SIZE; i++) - { - float ph = i * 2 * M_PI / ORGAN_WAVE_SIZE; - float fm = sin(ph) ; - tmp[i] = sin(ph + fm) + 0.25 * cos(11*ph - 2 * fm) + 0.125 * cos(23*ph - 2 * fm) + 0.0625 * cos(49*ph - 2 * fm); - } - normalize_waveform(tmp, ORGAN_WAVE_SIZE); - bl.compute_spectrum(tmp); - padsynth(bl, blBig, big_waves[wave_choir2 - wave_count_small], 50, 10); - - LARGE_WAVEFORM_PROGRESS(); - for (int i = 0; i < ORGAN_WAVE_SIZE; i++) - { - float ph = i * 2 * M_PI / ORGAN_WAVE_SIZE; - float fm = sin(ph) ; - tmp[i] = sin(ph + 4 * fm) + 0.5 * sin(2 * ph + 4 * ph); - } - normalize_waveform(tmp, ORGAN_WAVE_SIZE); - bl.compute_spectrum(tmp); - padsynth(bl, blBig, big_waves[wave_choir3 - wave_count_small], 50, 10); - LARGE_WAVEFORM_PROGRESS(); - - inited = true; - } -} - -organ_voice_base::organ_voice_base(organ_parameters *_parameters, int &_sample_rate_ref, bool &_released_ref) -: parameters(_parameters) -, sample_rate_ref(_sample_rate_ref) -, released_ref(_released_ref) -{ - note = -1; -} - -void organ_voice_base::render_percussion_to(float (*buf)[2], int nsamples) -{ - if (note == -1) - return; - - if (!pamp.get_active()) - return; - if (parameters->percussion_level < small_value()) - return; - float level = parameters->percussion_level * 9; - static float zeros[ORGAN_WAVE_SIZE]; - // XXXKF the decay needs work! - double age_const = parameters->perc_decay_const; - double fm_age_const = parameters->perc_fm_decay_const; - int timbre = parameters->get_percussion_wave(); - if (timbre < 0 || timbre >= wave_count_small) - return; - int timbre2 = parameters->get_percussion_fm_wave(); - if (timbre2 < 0 || timbre2 >= wave_count_small) - timbre2 = wave_sine; - float *fmdata = (*waves)[timbre2].get_level(moddphase.get()); - if (!fmdata) - fmdata = zeros; - float *data = (*waves)[timbre].get_level(dpphase.get()); - if (!data) { - pamp.deactivate(); - return; - } - float s = parameters->percussion_stereo * ORGAN_WAVE_SIZE * (0.5 / 360.0); - for (int i = 0; i < nsamples; i++) { - float fm = wave(fmdata, modphase); - fm *= ORGAN_WAVE_SIZE * parameters->percussion_fm_depth * fm_amp.get(); - modphase += moddphase; - fm_amp.age_exp(fm_age_const, 1.0 / 32768.0); - - float lamp = level * pamp.get(); - buf[i][0] += lamp * wave(data, pphase + dsp::fixed_point(fm - s)); - buf[i][1] += lamp * wave(data, pphase + dsp::fixed_point(fm + s)); - if (released_ref) - pamp.age_lin(rel_age_const,0.0); - else - pamp.age_exp(age_const, 1.0 / 32768.0); - pphase += dpphase; - } -} - -void organ_voice_base::perc_reset() -{ - pphase = 0; - modphase = 0; - dpphase = 0; - moddphase = 0; - note = -1; -} - -////////////////////////////////////////////////////////////////////////////////////////////////////// - -void organ_vibrato::reset() -{ - for (int i = 0; i < VibratoSize; i++) - vibrato_x1[i][0] = vibrato_y1[i][0] = vibrato_x1[i][1] = vibrato_y1[i][1] = 0.f; - vibrato[0].a0 = vibrato[1].a0 = 0; - lfo_phase = 0.f; -} - -void organ_vibrato::process(organ_parameters *parameters, float (*data)[2], unsigned int len, float sample_rate) -{ - float lfo1 = lfo_phase < 0.5 ? 2 * lfo_phase : 2 - 2 * lfo_phase; - float lfo_phase2 = lfo_phase + parameters->lfo_phase * (1.0 / 360.0); - if (lfo_phase2 >= 1.0) - lfo_phase2 -= 1.0; - float lfo2 = lfo_phase2 < 0.5 ? 2 * lfo_phase2 : 2 - 2 * lfo_phase2; - lfo_phase += parameters->lfo_rate * len / sample_rate; - if (lfo_phase >= 1.0) - lfo_phase -= 1.0; - if (!len) - return; - float olda0[2] = {vibrato[0].a0, vibrato[1].a0}; - vibrato[0].set_ap(3000 + 7000 * parameters->lfo_amt * lfo1 * lfo1, sample_rate); - vibrato[1].set_ap(3000 + 7000 * parameters->lfo_amt * lfo2 * lfo2, sample_rate); - float ilen = 1.0 / len; - float deltaa0[2] = {(vibrato[0].a0 - olda0[0])*ilen, (vibrato[1].a0 - olda0[1])*ilen}; - - float vib_wet = parameters->lfo_wet; - for (int c = 0; c < 2; c++) - { - for (unsigned int i = 0; i < len; i++) - { - float v = data[i][c]; - float v0 = v; - float coeff = olda0[c] + deltaa0[c] * i; - for (int t = 0; t < VibratoSize; t++) - v = vibrato[c].process_ap(v, vibrato_x1[t][c], vibrato_y1[t][c], coeff); - - data[i][c] += (v - v0) * vib_wet; - } - for (int t = 0; t < VibratoSize; t++) - { - sanitize(vibrato_x1[t][c]); - sanitize(vibrato_y1[t][c]); - } - } -} - -void scanner_vibrato::reset() -{ - legacy.reset(); - for (int i = 0; i < ScannerSize; i++) - scanner[i].reset(); - lfo_phase = 0.f; -} - -void scanner_vibrato::process(organ_parameters *parameters, float (*data)[2], unsigned int len, float sample_rate) -{ - if (!len) - return; - - int vtype = (int)parameters->lfo_type; - if (!vtype || vtype > organ_enums::lfotype_cvfull) - { - legacy.process(parameters, data, len, sample_rate); - return; - } - - // I bet the original components of the line box had some tolerance, - // hence two different values of cutoff frequency - scanner[0].set_lp_rbj(4000, 0.707, sample_rate); - scanner[1].set_lp_rbj(4200, 0.707, sample_rate); - for (int t = 2; t < ScannerSize; t ++) - { - scanner[t].copy_coeffs(scanner[t & 1]); - } - - float lfo_phase2 = lfo_phase + parameters->lfo_phase * (1.0 / 360.0); - if (lfo_phase2 >= 1.0) - lfo_phase2 -= 1.0; - float vib_wet = parameters->lfo_wet; - float dphase = parameters->lfo_rate / sample_rate; - static const int v1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 8 }; - static const int v2[] = { 0, 1, 2, 4, 6, 8, 9, 10, 12 }; - static const int v3[] = { 0, 1, 3, 6, 11, 12, 15, 17, 18, 18, 18 }; - static const int vfull[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 18 }; - static const int *vtypes[] = { NULL, v1, v2, v3, vfull }; - const int *vib = vtypes[vtype]; - - float vibamt = 8 * parameters->lfo_amt; - if (vtype == organ_enums::lfotype_cvfull) - vibamt = 17 * parameters->lfo_amt; - for (unsigned int i = 0; i < len; i++) - { - float line[ScannerSize + 1]; - float v0 = (data[i][0] + data[i][1]) * 0.5; - - line[0] = v0; - for (int t = 0; t < ScannerSize; t++) - line[t + 1] = scanner[t].process(line[t]) * 1.03; - - float lfo1 = lfo_phase < 0.5 ? 2 * lfo_phase : 2 - 2 * lfo_phase; - float lfo2 = lfo_phase2 < 0.5 ? 2 * lfo_phase2 : 2 - 2 * lfo_phase2; - - float pos = vibamt * lfo1; - int ipos = (int)pos; - float vl = lerp(line[vib[ipos]], line[vib[ipos + 1]], pos - ipos); - - pos = vibamt * lfo2; - ipos = (int)pos; - float vr = lerp(line[vib[ipos]], line[vib[ipos + 1]], pos - ipos); - - lfo_phase += dphase; - if (lfo_phase >= 1.0) - lfo_phase -= 1.0; - lfo_phase2 += dphase; - if (lfo_phase2 >= 1.0) - lfo_phase2 -= 1.0; - - data[i][0] += (vl - v0) * vib_wet; - data[i][1] += (vr - v0) * vib_wet; - } - for (int t = 0; t < ScannerSize; t++) - { - scanner[t].sanitize(); - } -} -////////////////////////////////////////////////////////////////////////////////////////////////////// - -void organ_voice::update_pitch() -{ - organ_voice_base::update_pitch(); - dphase.set(dsp::midi_note_to_phase(note, 100 * parameters->global_transpose + parameters->global_detune, sample_rate) * inertia_pitchbend.get_last()); -} - -void organ_voice::render_block() { - if (note == -1) - return; - - dsp::zero(&output_buffer[0][0], Channels * BlockSize); - dsp::zero(&aux_buffers[1][0][0], 2 * Channels * BlockSize); - if (!amp.get_active()) - { - if (use_percussion()) - render_percussion_to(output_buffer, BlockSize); - return; - } - - inertia_pitchbend.set_inertia(parameters->pitch_bend); - inertia_pitchbend.step(); - update_pitch(); - dsp::fixed_point tphase, tdphase; - unsigned int foldvalue = parameters->foldvalue * inertia_pitchbend.get_last(); - int vibrato_mode = fastf2i_drm(parameters->lfo_mode); - for (int h = 0; h < 9; h++) - { - float amp = parameters->drawbars[h]; - if (amp < small_value()) - continue; - float *data; - dsp::fixed_point hm = dsp::fixed_point(parameters->multiplier[h]); - int waveid = (int)parameters->waveforms[h]; - if (waveid < 0 || waveid >= wave_count) - waveid = 0; - - uint32_t rate = (dphase * hm).get(); - if (waveid >= wave_count_small) - { - float *data = (*big_waves)[waveid - wave_count_small].get_level(rate >> (ORGAN_BIG_WAVE_BITS - ORGAN_WAVE_BITS + ORGAN_BIG_WAVE_SHIFT)); - if (!data) - continue; - hm.set(hm.get() >> ORGAN_BIG_WAVE_SHIFT); - dsp::fixed_point tphase, tdphase; - tphase.set(((phase * hm).get()) + parameters->phaseshift[h]); - tdphase.set(rate >> ORGAN_BIG_WAVE_SHIFT); - float ampl = amp * 0.5f * (1 - parameters->pan[h]); - float ampr = amp * 0.5f * (1 + parameters->pan[h]); - float (*out)[Channels] = aux_buffers[dsp::fastf2i_drm(parameters->routing[h])]; - - for (int i=0; i < (int)BlockSize; i++) { - float wv = big_wave(data, tphase); - out[i][0] += wv * ampl; - out[i][1] += wv * ampr; - tphase += tdphase; - } - } - else - { - unsigned int foldback = 0; - while (rate > foldvalue) - { - rate >>= 1; - foldback++; - } - hm.set(hm.get() >> foldback); - data = (*waves)[waveid].get_level(rate); - if (!data) - continue; - tphase.set((uint32_t)((phase * hm).get()) + parameters->phaseshift[h]); - tdphase.set((uint32_t)rate); - float ampl = amp * 0.5f * (1 - parameters->pan[h]); - float ampr = amp * 0.5f * (1 + parameters->pan[h]); - float (*out)[Channels] = aux_buffers[dsp::fastf2i_drm(parameters->routing[h])]; - - for (int i=0; i < (int)BlockSize; i++) { - float wv = wave(data, tphase); - out[i][0] += wv * ampl; - out[i][1] += wv * ampr; - tphase += tdphase; - } - } - } - - bool is_quad = parameters->quad_env >= 0.5f; - - expression.set_inertia(parameters->cutoff); - phase += dphase * BlockSize; - float escl[EnvCount], eval[EnvCount]; - for (int i = 0; i < EnvCount; i++) - escl[i] = (1.f + parameters->envs[i].velscale * (velocity - 1.f)); - - if (is_quad) - { - for (int i = 0; i < EnvCount; i++) - eval[i] = envs[i].value * envs[i].value * escl[i]; - } - else - { - for (int i = 0; i < EnvCount; i++) - eval[i] = envs[i].value * escl[i]; - } - for (int i = 0; i < FilterCount; i++) - { - float mod = parameters->filters[i].envmod[0] * eval[0] ; - mod += parameters->filters[i].keyf * 100 * (note - 60); - for (int j = 1; j < EnvCount; j++) - { - mod += parameters->filters[i].envmod[j] * eval[j]; - } - if (i) mod += expression.get() * 1200 * 4; - float fc = parameters->filters[i].cutoff * pow(2.0f, mod * (1.f / 1200.f)); - if (i == 0 && parameters->filter1_type >= 0.5f) - filterL[i].set_hp_rbj(dsp::clip(fc, 10, 18000), parameters->filters[i].resonance, sample_rate); - else - filterL[i].set_lp_rbj(dsp::clip(fc, 10, 18000), parameters->filters[i].resonance, sample_rate); - filterR[i].copy_coeffs(filterL[i]); - } - float amp_pre[ampctl_count - 1], amp_post[ampctl_count - 1]; - for (int i = 0; i < ampctl_count - 1; i++) - { - amp_pre[i] = 1.f; - amp_post[i] = 1.f; - } - bool any_running = false; - for (int i = 0; i < EnvCount; i++) - { - float pre = eval[i]; - envs[i].advance(); - int mode = fastf2i_drm(parameters->envs[i].ampctl); - if (!envs[i].stopped()) - any_running = true; - if (mode == ampctl_none) - continue; - float post = (is_quad ? envs[i].value : 1) * envs[i].value * escl[i]; - amp_pre[mode - 1] *= pre; - amp_post[mode - 1] *= post; - } - if (vibrato_mode >= lfomode_direct && vibrato_mode <= lfomode_filter2) - vibrato.process(parameters, aux_buffers[vibrato_mode - lfomode_direct], BlockSize, sample_rate); - if (!any_running) - finishing = true; - // calculate delta from pre and post - for (int i = 0; i < ampctl_count - 1; i++) - amp_post[i] = (amp_post[i] - amp_pre[i]) * (1.0 / BlockSize); - float a0 = amp_pre[0], a1 = amp_pre[1], a2 = amp_pre[2], a3 = amp_pre[3]; - float d0 = amp_post[0], d1 = amp_post[1], d2 = amp_post[2], d3 = amp_post[3]; - if (parameters->filter_chain >= 0.5f) - { - for (int i=0; i < (int) BlockSize; i++) { - output_buffer[i][0] = a3 * (a0 * output_buffer[i][0] + a2 * filterL[1].process(a1 * filterL[0].process(aux_buffers[1][i][0]) + aux_buffers[2][i][0])); - output_buffer[i][1] = a3 * (a0 * output_buffer[i][1] + a2 * filterR[1].process(a1 * filterR[0].process(aux_buffers[1][i][1]) + aux_buffers[2][i][1])); - a0 += d0, a1 += d1, a2 += d2, a3 += d3; - } - } - else - { - for (int i=0; i < (int) BlockSize; i++) { - output_buffer[i][0] = a3 * (a0 * output_buffer[i][0] + a1 * filterL[0].process(aux_buffers[1][i][0]) + a2 * filterL[1].process(aux_buffers[2][i][0])); - output_buffer[i][1] = a3 * (a0 * output_buffer[i][1] + a1 * filterR[0].process(aux_buffers[1][i][1]) + a2 * filterR[1].process(aux_buffers[2][i][1])); - a0 += d0, a1 += d1, a2 += d2, a3 += d3; - } - } - filterL[0].sanitize(); - filterR[0].sanitize(); - filterL[1].sanitize(); - filterR[1].sanitize(); - if (vibrato_mode == lfomode_voice) - vibrato.process(parameters, output_buffer, BlockSize, sample_rate); - - if (finishing) - { - for (int i = 0; i < (int) BlockSize; i++) { - output_buffer[i][0] *= amp.get(); - output_buffer[i][1] *= amp.get(); - amp.age_lin((1.0/44100.0)/0.03,0.0); - } - } - - if (use_percussion()) - render_percussion_to(output_buffer, BlockSize); - -} - -void organ_voice::note_on(int note, int vel) -{ - stolen = false; - finishing = false; - perc_released = false; - released = false; - reset(); - this->note = note; - const float sf = 0.001f; - for (int i = 0; i < EnvCount; i++) - { - organ_parameters::organ_env_parameters &p = parameters->envs[i]; - envs[i].set(sf * p.attack, sf * p.decay, p.sustain, sf * p.release, sample_rate / BlockSize); - envs[i].note_on(); - } - update_pitch(); - velocity = vel * 1.0 / 127.0; - amp.set(1.0f); - perc_note_on(note, vel); -} - -void organ_voice::note_off(int /* vel */) -{ - // reset age to 0 (because decay will turn from exponential to linear, necessary because of error cumulation prevention) - perc_released = true; - if (pamp.get_active()) - { - pamp.reinit(); - } - rel_age_const = pamp.get() * ((1.0/44100.0)/0.03); - for (int i = 0; i < EnvCount; i++) - envs[i].note_off(); -} - -void organ_voice::steal() -{ - perc_released = true; - finishing = true; - stolen = true; -} - -void organ_voice::reset() -{ - inertia_pitchbend.ramp.set_length(sample_rate / (BlockSize * 30)); // 1/30s - vibrato.reset(); - phase = 0; - for (int i = 0; i < FilterCount; i++) - { - filterL[i].reset(); - filterR[i].reset(); - } -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// - -void drawbar_organ::update_params() -{ - parameters->perc_decay_const = dsp::decay::calc_exp_constant(1.0 / 1024.0, 0.001 * parameters->percussion_time * sample_rate); - parameters->perc_fm_decay_const = dsp::decay::calc_exp_constant(1.0 / 1024.0, 0.001 * parameters->percussion_fm_time * sample_rate); - for (int i = 0; i < 9; i++) - { - parameters->multiplier[i] = parameters->harmonics[i] * pow(2.0, parameters->detune[i] * (1.0 / 1200.0)); - parameters->phaseshift[i] = int(parameters->phase[i] * 65536 / 360) << 16; - } - double dphase = dsp::midi_note_to_phase((int)parameters->foldover, 0, sample_rate); - parameters->foldvalue = (int)(dphase); -} - -dsp::voice *drawbar_organ::alloc_voice() -{ - block_voice *v = new block_voice(); - v->parameters = parameters; - return v; -} - -void drawbar_organ::percussion_note_on(int note, int vel) -{ - percussion.perc_note_on(note, vel); -} - -void drawbar_organ::setup(int sr) -{ - basic_synth::setup(sr); - percussion.setup(sr); - parameters->cutoff = 0; - params_changed(); - global_vibrato.reset(); -} - -bool drawbar_organ::check_percussion() { - switch(dsp::fastf2i_drm(parameters->percussion_trigger)) - { - case organ_voice_base::perctrig_first: - return active_voices.empty(); - case organ_voice_base::perctrig_each: - default: - return true; - case organ_voice_base::perctrig_eachplus: - return !percussion.get_noticable(); - case organ_voice_base::perctrig_polyphonic: - return false; - } -} - -void drawbar_organ::pitch_bend(int amt) -{ - parameters->pitch_bend = pow(2.0, (amt * parameters->pitch_bend_range) / (1200.0 * 8192.0)); - for (list::iterator i = active_voices.begin(); i != active_voices.end(); ++i) - { - organ_voice *v = dynamic_cast(*i); - v->update_pitch(); - } - percussion.update_pitch(); -} - -void organ_audio_module::execute(int cmd_no) -{ - switch(cmd_no) - { - case 0: - panic_flag = true; - break; - } -} - -void organ_voice_base::perc_note_on(int note, int vel) -{ - perc_reset(); - released_ref = false; - this->note = note; - if (parameters->percussion_level > 0) - pamp.set(1.0f + (vel - 127) * parameters->percussion_vel2amp / 127.0); - update_pitch(); - float (*kt)[2] = parameters->percussion_keytrack; - // assume last point (will be put there by padding) - fm_keytrack = kt[ORGAN_KEYTRACK_POINTS - 1][1]; - // yes binary search would be nice if we had more than those crappy 4 points - for (int i = 0; i < ORGAN_KEYTRACK_POINTS - 1; i++) - { - float &lower = kt[i][0], upper = kt[i + 1][0]; - if (note >= lower && note < upper) - { - fm_keytrack = kt[i][1] + (note - lower) * (kt[i + 1][1] - kt[i][1]) / (upper - lower); - break; - } - } - fm_amp.set(fm_keytrack * (1.0f + (vel - 127) * parameters->percussion_vel2fm / 127.0)); -} - -char *organ_audio_module::configure(const char *key, const char *value) -{ - if (!strcmp(key, "map_curve")) - { - if (!value) - value = "2\n0 1\n1 1\n"; - var_map_curve = value; - stringstream ss(value); - int i = 0; - float x = 0, y = 1; - if (*value) - { - int points; - ss >> points; - for (i = 0; i < points; i++) - { - static const int whites[] = { 0, 2, 4, 5, 7, 9, 11 }; - ss >> x >> y; - int wkey = (int)(x * 71); - x = whites[wkey % 7] + 12 * (wkey / 7); - parameters->percussion_keytrack[i][0] = x; - parameters->percussion_keytrack[i][1] = y; - // cout << "(" << x << ", " << y << ")" << endl; - } - } - // pad with constant Y - for (; i < ORGAN_KEYTRACK_POINTS; i++) { - parameters->percussion_keytrack[i][0] = x; - parameters->percussion_keytrack[i][1] = y; - } - return NULL; - } - cout << "Set unknown configure value " << key << " to " << value << endl; - return NULL; -} - -void organ_audio_module::send_configures(send_configure_iface *sci) -{ - sci->send_configure("map_curve", var_map_curve.c_str()); -} - -void organ_audio_module::deactivate() -{ - -} - -void drawbar_organ::render_separate(float *output[], int nsamples) -{ - float buf[MAX_SAMPLE_RUN][2]; - dsp::zero(&buf[0][0], 2 * nsamples); - basic_synth::render_to(buf, nsamples); - if (dsp::fastf2i_drm(parameters->lfo_mode) == organ_voice_base::lfomode_global) - { - for (int i = 0; i < nsamples; i += 64) - global_vibrato.process(parameters, buf + i, std::min(64, nsamples - i), sample_rate); - } - if (percussion.get_active()) - percussion.render_percussion_to(buf, nsamples); - float gain = parameters->master * (1.0 / 8); - eq_l.set(parameters->bass_freq, parameters->bass_gain, parameters->treble_freq, parameters->treble_gain, sample_rate); - eq_r.copy_coeffs(eq_l); - for (int i=0; i -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -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(); -} - -ladspa_instance::~ladspa_instance() -{ - delete module; -} - -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 -// instantiate descriptor templates -template LV2_Descriptor calf_plugins::lv2_wrapper::descriptor; -template LV2_Calf_Descriptor calf_plugins::lv2_wrapper::calf_descriptor; -template LV2_State_Interface calf_plugins::lv2_wrapper::state_iface; - -extern "C" { - -const LV2_Descriptor *lv2_descriptor(uint32_t index) -{ - #define PER_MODULE_ITEM(name, isSynth, jackname) if (!(index--)) return &lv2_wrapper::get().descriptor; - #include - return NULL; -} - -}; - -#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" { - -audio_module_iface *create_calf_plugin_by_name(const char *effect_name) -{ - #define PER_MODULE_ITEM(name, isSynth, jackname) if (!strcasecmp(effect_name, jackname)) return new name##_audio_module; - #include - return NULL; -} - -} - -#endif diff --git a/plugins/LadspaEffect/calf/src/synth.cpp b/plugins/LadspaEffect/calf/src/synth.cpp deleted file mode 100644 index d7074a7c379..00000000000 --- a/plugins/LadspaEffect/calf/src/synth.cpp +++ /dev/null @@ -1,220 +0,0 @@ -/* Calf DSP Library - * Generic polyphonic synthesizer framework. - * - * Copyright (C) 2007 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 02110-1301 USA - */ -#include - -using namespace dsp; -using namespace std; - -void basic_synth::kill_note(int note, int vel, bool just_one) -{ - for (list::iterator it = active_voices.begin(); it != active_voices.end(); ++it) { - // preserve sostenuto notes - if ((*it)->get_current_note() == note && !(sostenuto && (*it)->sostenuto)) { - (*it)->note_off(vel); - if (just_one) - return; - } - } -} - -dsp::voice *basic_synth::give_voice() -{ - if (active_voices.size() >= polyphony_limit) - { - dsp::voice *stolen = steal_voice(); - if (stolen) - return stolen; - } - if (unused_voices.empty()) - return alloc_voice(); - else { - dsp::voice *v = unused_voices.top(); - unused_voices.pop(); - v->reset(); - return v; - } -} - -dsp::voice *basic_synth::steal_voice() -{ - std::list::iterator found = active_voices.end(); - float priority = 10000; - //int idx = 0; - for(std::list::iterator i = active_voices.begin(); i != active_voices.end(); ++i) - { - //printf("Voice %d priority %f at %p\n", idx++, (*i)->get_priority(), *i); - if ((*i)->get_priority() < priority) - { - priority = (*i)->get_priority(); - found = i; - } - } - //printf("Found: %p\n\n", *found); - if (found == active_voices.end()) - return NULL; - - (*found)->steal(); - return NULL; -} - -void basic_synth::trim_voices() -{ - // count stealable voices - unsigned int count = 0; - for(std::list::iterator i = active_voices.begin(); i != active_voices.end(); ++i) - { - if ((*i)->get_priority() < 10000) - count++; - } - // printf("Count=%d limit=%d\n", count, polyphony_limit); - // steal any voices above polyphony limit - if (count > polyphony_limit) { - for (unsigned int i = 0; i < count - polyphony_limit; i++) - steal_voice(); - } -} - -void basic_synth::note_on(int note, int vel) -{ - if (!vel) { - note_off(note, 0); - return; - } - bool perc = check_percussion(); - dsp::voice *v = give_voice(); - v->setup(sample_rate); - v->released = false; - v->sostenuto = false; - gate.set(note); - v->note_on(note, vel); - active_voices.push_back(v); - if (perc) { - percussion_note_on(note, vel); - } -} - -void basic_synth::note_off(int note, int vel) -{ - gate.reset(note); - if (!hold) - kill_note(note, vel, false); -} - -#define for_all_voices(iter) for (std::list::iterator iter = active_voices.begin(); iter != active_voices.end(); ++iter) - -void basic_synth::on_pedal_release() -{ - for_all_voices(i) - { - int note = (*i)->get_current_note(); - if (note < 0 || note > 127) - continue; - bool still_held = gate[note]; - // sostenuto pedal released - if ((*i)->sostenuto && !sostenuto) - { - // mark note as non-sostenuto - (*i)->sostenuto = false; - // if key still pressed or hold pedal used, hold the note (as non-sostenuto so it can be released later by releasing the key or pedal) - // if key has been released and hold pedal is not depressed, release the note - if (!still_held && !hold) - (*i)->note_off(127); - } - else if (!hold && !still_held && !(*i)->released) - { - (*i)->released = true; - (*i)->note_off(127); - } - } -} - -void basic_synth::control_change(int ctl, int val) -{ - if (ctl == 64) { // HOLD controller - bool prev = hold; - hold = (val >= 64); - if (!hold && prev && !sostenuto) { - on_pedal_release(); - } - } - if (ctl == 66) { // SOSTENUTO controller - bool prev = sostenuto; - sostenuto = (val >= 64); - if (sostenuto && !prev) { - // SOSTENUTO was pressed - move all notes onto sustain stack - for_all_voices(i) { - (*i)->sostenuto = true; - } - } - if (!sostenuto && prev) { - // SOSTENUTO was released - release all keys which were previously held - on_pedal_release(); - } - } - if (ctl == 123 || ctl == 120) { // all notes off, all sounds off - if (ctl == 120) { // for "all sounds off", automatically release hold and sostenuto pedal - control_change(66, 0); - control_change(64, 0); - } - for_all_voices(i) - { - if (ctl == 123) - (*i)->note_off(127); - else - (*i)->steal(); - } - } - if (ctl == 121) { - control_change(1, 0); - control_change(7, 100); - control_change(10, 64); - control_change(11, 127); - // release hold..hold2 - for (int i = 64; i <= 69; i++) - control_change(i, 0); - } -} - -void basic_synth::render_to(float (*output)[2], int nsamples) -{ - // render voices, eliminate ones that aren't sounding anymore - for (list::iterator i = active_voices.begin(); i != active_voices.end();) { - dsp::voice *v = *i; - v->render_to(output, nsamples); - if (!v->get_active()) { - i = active_voices.erase(i); - unused_voices.push(v); - continue; - } - ++i; - } -} - -basic_synth::~basic_synth() -{ - while(!unused_voices.empty()) { - delete unused_voices.top(); - unused_voices.pop(); - } - for (list::iterator i = active_voices.begin(); i != active_voices.end(); ++i) - delete *i; -} - diff --git a/plugins/LadspaEffect/calf/src/utils.cpp b/plugins/LadspaEffect/calf/src/utils.cpp deleted file mode 100644 index 5d5f33b8705..00000000000 --- a/plugins/LadspaEffect/calf/src/utils.cpp +++ /dev/null @@ -1,156 +0,0 @@ -/* Calf DSP Library - * Various utility functions. - * Copyright (C) 2007 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 02110-1301 USA - */ -#include -#include -#include -#include -#include - -using namespace std; -using namespace osctl; - -namespace calf_utils { - -string encode_map(const dictionary &data) -{ - osctl::string_buffer sb; - osc_stream str(sb); - str << (uint32_t)data.size(); - for(dictionary::const_iterator i = data.begin(); i != data.end(); ++i) - { - str << i->first << i->second; - } - return sb.data; -} - -void decode_map(dictionary &data, const string &src) -{ - osctl::string_buffer sb(src); - osc_stream str(sb); - uint32_t count = 0; - str >> count; - string tmp, tmp2; - data.clear(); - for (uint32_t i = 0; i < count; i++) - { - str >> tmp; - str >> tmp2; - data[tmp] = tmp2; - } -} - -std::string xml_escape(const std::string &src) -{ - string dest; - for (size_t i = 0; i < src.length(); i++) { - // XXXKF take care of string encoding - if (src[i] < 0 || src[i] == '"' || src[i] == '<' || src[i] == '>' || src[i] == '&') - dest += "&"+i2s((uint8_t)src[i])+";"; - else - dest += src[i]; - } - return dest; -} - -std::string to_xml_attr(const std::string &key, const std::string &value) -{ - return " " + key + "=\"" + xml_escape(value) + "\""; -} - -std::string load_file(const std::string &src) -{ - std::string str; - FILE *f = fopen(src.c_str(), "rb"); -#if 0 - if (!f) - throw file_exception(src); -#endif - while(!feof(f)) - { - char buffer[1024]; - size_t len = fread(buffer, 1, sizeof(buffer), f); -#if 0 - if (len < 0) - throw file_exception(src); -#endif - str += string(buffer, len); - } - fclose(f); - return str; -} - -std::string i2s(int value) -{ - char buf[32]; - sprintf(buf, "%d", value); - - return std::string(buf); -} - -std::string f2s(double value) -{ - stringstream ss; - ss << value; - return ss.str(); -} - -std::string ff2s(double value) -{ - string s = f2s(value); - if (s.find('.') == string::npos) - s += ".0"; - return s; -} - -std::string indent(const std::string &src, const std::string &indent) -{ - std::string dest; - size_t pos = 0; - do { - size_t epos = src.find("\n", pos); - if (epos == string::npos) - break; - dest += indent + src.substr(pos, epos - pos) + "\n"; - pos = epos + 1; - } while(pos < src.length()); - if (pos < src.length()) - dest += indent + src.substr(pos); - return dest; -} - -////////////////////////////////////////////////////////////////////////////////// - -file_exception::file_exception(const std::string &f) -: message(strerror(errno)) -, filename(f) -, container(filename + ":" + message) -{ - text = container.c_str(); -} - -file_exception::file_exception(const std::string &f, const std::string &t) -: message(t) -, filename(f) -, container(filename + ":" + message) -{ - text = container.c_str(); -} - -} diff --git a/plugins/LadspaEffect/calf/src/wavetable.cpp b/plugins/LadspaEffect/calf/src/wavetable.cpp deleted file mode 100644 index 271fc3ea786..00000000000 --- a/plugins/LadspaEffect/calf/src/wavetable.cpp +++ /dev/null @@ -1,552 +0,0 @@ -/* Calf DSP Library - * Example audio modules - wavetable synthesizer - * - * Copyright (C) 2009 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 02110-1301 USA - */ - -#include - -#if ENABLE_EXPERIMENTAL - -#include -#include -#include - -using namespace dsp; -using namespace calf_plugins; - -wavetable_voice::wavetable_voice() -{ - sample_rate = -1; -} - -void wavetable_voice::set_params_ptr(wavetable_audio_module *_parent, int _srate) -{ - parent = _parent; - params = parent->params; - sample_rate = _srate; -} - -void wavetable_voice::reset() -{ - note = -1; -} - -void wavetable_voice::note_on(int note, int vel) -{ - typedef wavetable_metadata md; - this->note = note; - velocity = vel / 127.0; - amp.set(1.0); - for (int i = 0; i < OscCount; i++) { - oscs[i].reset(); - oscs[i].set_freq(note_to_hz(note, 0), sample_rate); - last_oscshift[i] = 0; - } - int cr = sample_rate / BlockSize; - for (int i = 0; i < EnvCount; i++) { - envs[i].set(0.01, 0.1, 0.5, 1, cr); - envs[i].note_on(); - } - float modsrc[wavetable_metadata::modsrc_count] = { 1, velocity, parent->inertia_pressure.get_last(), parent->modwheel_value, envs[0].value, envs[1].value, envs[2].value}; - parent->calculate_modmatrix(moddest, md::moddest_count, modsrc); - calc_derived_dests(); - - float oscshift[2] = { moddest[md::moddest_o1shift], moddest[md::moddest_o2shift] }; - memcpy(last_oscshift, oscshift, sizeof(oscshift)); - memcpy(last_oscamp, cur_oscamp, sizeof(cur_oscamp)); -} - -void wavetable_voice::note_off(int vel) -{ - for (int i = 0; i < EnvCount; i++) - envs[i].note_off(); -} - -void wavetable_voice::steal() -{ -} - -void wavetable_voice::render_block() -{ - typedef wavetable_metadata md; - - const float step = 1.f / BlockSize; - - float s = 0.001; - float scl[EnvCount]; - int espc = md::par_eg2attack - md::par_eg1attack; - for (int j = 0; j < EnvCount; j++) { - int o = j*espc; - envs[j].set(*params[md::par_eg1attack + o] * s, *params[md::par_eg1decay + o] * s, *params[md::par_eg1sustain + o], *params[md::par_eg1release + o] * s, sample_rate / BlockSize, *params[md::par_eg1fade + o] * s); - scl[j] = dsp::lerp(1.f, velocity, *params[md::par_eg1velscl + o]);; - } - - for (int i = 0; i < EnvCount; i++) - envs[i].advance(); - - float modsrc[wavetable_metadata::modsrc_count] = { 1, velocity, parent->inertia_pressure.get_last(), parent->modwheel_value, envs[0].value, envs[1].value, envs[2].value}; - parent->calculate_modmatrix(moddest, md::moddest_count, modsrc); - calc_derived_dests(); - - int ospc = md::par_o2level - md::par_o1level; - for (int j = 0; j < OscCount; j++) { - oscs[j].tables = parent->tables[(int)*params[md::par_o1wave + j * ospc]]; - oscs[j].set_freq(note_to_hz(note, *params[md::par_o1transpose + j * ospc] * 100+ *params[md::par_o1detune + j * ospc] + moddest[md::moddest_o1detune]), sample_rate); - } - - float oscshift[2] = { moddest[md::moddest_o1shift], moddest[md::moddest_o2shift] }; - float osstep[2] = { (oscshift[0] - last_oscshift[0]) * step, (oscshift[1] - last_oscshift[1]) * step }; - float oastep[2] = { (cur_oscamp[0] - last_oscamp[0]) * step, (cur_oscamp[1] - last_oscamp[1]) * step }; - for (int i = 0; i < BlockSize; i++) { - float value = 0.f; - - for (int j = 0; j < OscCount; j++) { - float o = last_oscshift[j] * 0.01; - value += last_oscamp[j] * oscs[j].get(dsp::clip(fastf2i_drm((o + *params[md::par_o1offset + j * ospc]) * 127.0 * 256), 0, 127 * 256)); - last_oscshift[j] += osstep[j]; - last_oscamp[j] += oastep[j]; - } - - output_buffer[i][0] = output_buffer[i][1] = value; - } - if (envs[0].stopped()) - released = true; - memcpy(last_oscshift, oscshift, sizeof(oscshift)); - memcpy(last_oscamp, cur_oscamp, sizeof(cur_oscamp)); -} - -///////////////////////////////////////////////////////////////////////////////////////////////////// - -static inline float sincl(float x, float clip) -{ - if (fabs(x) > clip) - return 0; - return sin(M_PI * x); -} - -static inline float blip(float x, float center, float range) -{ - if (x < center - range || x > center + range) - return 0; - return 1 - fabs(x - center)/range; -} - -static void interpolate_wt(int16_t table[129][256], int step) -{ - for (int i = 0; i < 128; i++) - { - if (!(i % step)) - continue; - int prev = i - i % step; - int next = prev + step; - for (int j = 0; j < 256; j++) - { - table[i][j] = table[prev][j] + (i - prev) * (table[next][j] - table[prev][j]) / step; - } - } -} - -wavetable_audio_module::wavetable_audio_module() -: mod_matrix_impl(mod_matrix_data, &mm_metadata) -, inertia_cutoff(1) -, inertia_pitchbend(1) -, inertia_pressure(64) -{ - panic_flag = false; - modwheel_value = 0.; - for (int i = 0; i < 129; i += 8) - { - for (int j = 0; j < 256; j++) - { - float ph = j * 2 * M_PI / 256; - int harm = 1 + 2 * (i / 8); - float ii = i / 128.0; - float rezo1 = sin(harm * ph) * sin(ph); - float rezo2 = sin((harm+1) * ph) * sin(ph * 2); - float rezo3 = sin((harm+3) * ph) * sin(ph * 4); - float rezo = (rezo1 + rezo2 + rezo3) / 3; - float v = (sin (ph) + ii * ii * rezo) / 2; - tables[0][i][j] = 32767 * v; - } - } - interpolate_wt(tables[0], 8); - for (int i = 0; i < 129; i += 4) - { - for (int j = 0; j < 256; j++) - { - float ph = j * 2 * M_PI / 256; - int harm = 1 + (i / 4); - float ii = i / 128.0; - float h = sin(harm * ph); - float rezo1 = h * sin(ph); - float rezo2 = h * sin(ph * 2)/2; - float rezo3 = h * sin(ph * 3)/3; - float rezo4 = h * sin(ph * 4)/4; - float rezo5 = h * sin(ph * 5)/5; - float rezo = (rezo1 + rezo2 + rezo3 + rezo4 + rezo5) / 3; - float v = sin (ph + ii * rezo); - tables[1][i][j] = 32767 * v; - } - } - interpolate_wt(tables[1], 4); - for (int i = 0; i < 129; i++) - { - for (int j = 0; j < 256; j++) - { - float ph = j * 2 * M_PI / 256; - float ii = (i & ~3) / 128.0; - float ii2 = ((i & ~3) + 4) / 128.0; - float peak = (32 * ii); - float rezo1 = sin(floor(peak) * ph); - float rezo2 = sin(floor(peak + 1) * ph); - float widener = (0.5 + 0.3 * sin(ph) + 0.2 * sin (3 * ph)); - float v1 = 0.5 * sin (ph) + 0.5 * ii * ii * rezo1 * widener; - float v2 = 0.5 * sin (ph) + 0.5 * ii2 * ii2 * rezo2 * widener; - tables[wavetable_metadata::wt_rezo][i][j] = 32767 * lerp(v1, v2, (i & 3) / 4.0); - } - } - for (int i = 0; i < 129; i++) - { - for (int j = 0; j < 256; j++) - { - float ph = j * 2 * M_PI / 256; - float ii = i / 128.0; - float v = (sin(ph) + ii * sin(ph + 2 * ii * sin(ph)) + ii * ii * sin(ph + 6 * ii * ii * sin(6 * ph)) + ii * ii * ii * ii * sin(ph + 11 * ii * ii * ii * ii * sin(11 * ph))) / 4; - tables[wavetable_metadata::wt_metal][i][j] = 32767 * v; - } - } - for (int i = 0; i < 129; i++) - { - for (int j = 0; j < 256; j++) - { - float ph = j * 2 * M_PI / 256; - float ii = i / 128.0; - float v = (sin(ph) + ii * sin(ph - 3 * ii * sin(ph)) + ii * ii * sin(5 * ph - 5 * ii * ii * ii * ii * sin(11 * ph))) / 3; - tables[wavetable_metadata::wt_bell][i][j] = 32767 * v; - } - } - for (int i = 0; i < 129; i++) - { - for (int j = 0; j < 256; j++) - { - float ph = j * 2 * M_PI / 256; - float ii = i / 128.0; - //float v = (sin(ph) + ii * sin(ph + 2 * ii * sin(ph)) + ii * ii * sin(ph + 3 * ii * ii * sin(3 * ph)) + ii * ii * ii * sin(ph + 5 * ii * ii * ii * sin(5 * ph))) / 4; - float v = (sin(ph) + sin(ph - 3 * sin(ii * 5 - 2) * sin(ph)) + sin(ii * 4 - 1.3) * sin(5 * ph + 3 * ii * ii * sin(6 * ph))) / 3; - tables[wavetable_metadata::wt_blah][i][j] = 32767 * v; - } - } - for (int i = 0; i < 256; i++) - { - tables[wavetable_metadata::wt_pluck][128][i] = (i < 128) ? 32000 * fabs(sin(i / 32.0 * M_PI) * sin(i / 13.0 * M_PI) * sin(i / 19.0 * M_PI)) : 0; - } - for (int i = 127; i >= 0; i--) - { - int16_t *parent = tables[wavetable_metadata::wt_pluck][i + 1]; - float damp = 0.05; - for (int j = 0; j < 256; j++) - { - tables[wavetable_metadata::wt_pluck][i][j] = (1 - 2*damp) * parent[j] + damp * parent[(j+1)&255] + damp * parent[(j+2)&255];// + 0.1 * parent[(j-1)&255]+ 0.1 * parent[(j-2)&255]; - } - } - for (int i = 0; i < 129; i++) - { - for (int j = 0; j < 256; j++) - { - float ph = j / 128.0 - 1.0; - float ii = i / 128.0; - float v = sincl(ph * (1 + 15 * ii), 1); - tables[wavetable_metadata::wt_stretch][i][j] = 32767 * v; - } - } - for (int i = 0; i < 129; i++) - { - for (int j = 0; j < 256; j++) - { - float ph = j / 128.0 - 1.0; - float ii = i / 128.0; - float v = sincl(ph * (1 + 15 * ii), 4) * sincl(j / 256.0, 1); - tables[wavetable_metadata::wt_stretch2][i][j] = 32000 * v; - } - } - for (int i = 0; i < 129; i++) - { - for (int j = 0; j < 256; j++) - { - float ph = j / 128.0 - 1.0; - float ii = i / 128.0; - float w = sincl(ph * (1 + 15 * ii), 4); - float v = pow(w, 9) * sincl(j / 256.0, 1); - tables[wavetable_metadata::wt_hardsync][i][j] = 32000 * v; - } - } - for (int i = 0; i < 129; i++) - { - for (int j = 0; j < 256; j++) - { - float ph = j / 128.0 - 1.0; - float ii = i / 128.0; - float w = sincl(ph * (1 + 31 * ii), 3); - float v = pow(w, 5) * sincl(j / 256.0, 1); - tables[wavetable_metadata::wt_hardsync2][i][j] = 32000 * v; - } - } - for (int i = 0; i < 129; i++) - { - for (int j = 0; j < 256; j++) - { - float ph = j / 128.0 - 1.0; - float ii = i / 128.0; - float w = sincl(ph * ph * (1 + 15 * ii), 2); - float v = pow(w, 4) * sincl(j / 256.0, 1); - tables[wavetable_metadata::wt_softsync][i][j] = 32000 * v; - } - } - for (int i = 0; i < 129; i++) - { - for (int j = 0; j < 256; j++) - { - float ph = j * 2 * M_PI / 256; - float ii = i / 128.0; - float v = (sin(ph) + ii * sin(ph - 3 * ii * sin(ph)) + ii * ii * ii * sin(7 * ph - 2 * ii * ii * ii * ii * sin(13 * ph))) / 3; - tables[wavetable_metadata::wt_bell2][i][j] = 32767 * v; - } - } - for (int i = 0; i < 129; i++) - { - for (int j = 0; j < 256; j++) - { - float ph = j * 2 * M_PI / 256; - float ii = i / 128.0; - float v = (sin(ph) + ii * sin(ph - 3 * ii * sin(ph)) + ii * ii * ii * sin(9 * ph - ii * ii * sin(11 * ph))) / 3; - tables[wavetable_metadata::wt_bell3][i][j] = 32767 * v; - } - } - for (int i = 0; i < 129; i++) - { - for (int j = 0; j < 256; j++) - { - float ph = j * 2 * M_PI / 256; - float ii = i / 128.0; - float v = (sin(ph + ii * sin(ph - 3 * ii * sin(ph) + ii * ii * ii * sin(5 * ph - ii * ii * sin(7 * ph))))); - tables[wavetable_metadata::wt_tine][i][j] = 32767 * v; - } - } - for (int i = 0; i < 129; i++) - { - for (int j = 0; j < 256; j++) - { - float ph = j * 2 * M_PI / 256; - float ii = i / 128.0; - float v = (sin(ph + ii * sin(ph - 2 * ii * sin(ph) + ii * ii * ii * sin(3 * ph - ii * ii * sin(4 * ph))))); - tables[wavetable_metadata::wt_tine2][i][j] = 32767 * v; - } - } - for (int i = 0; i < 129; i++) - { - for (int j = 0; j < 256; j++) - { - float ph = j * 2 * M_PI / 256; - float ph2 = j / 128.0 - 1; - float ii = i / 128.0; - float w = sincl(ph2 * (1 + 7 * ii * ii), 4) * pow(sincl(j / 256.0, 1), 2); - float v = sin(ph + ii * sin(ph - 2 * ii * w)); - tables[wavetable_metadata::wt_clav][i][j] = 32767 * v; - } - } - for (int i = 0; i < 129; i++) - { - for (int j = 0; j < 256; j++) - { - float ph = j * 2 * M_PI / 256; - float ph2 = j / 128.0 - 1; - float ii = i / 128.0; - float w = sincl(ph2 * (1 + 7 * ii * ii), 6) * sincl(j / 256.0, 1); - float v = sin(ph + ii * sin(3 * ph - 2 * ii * w)); - tables[wavetable_metadata::wt_clav2][i][j] = 32767 * v; - } - } - /* - for (int i = 0; i < 129; i++) - { - for (int j = 0; j < 256; j++) - { - float ph = j * 2 * M_PI / 256; - float ph2 = j / 128.0 - 1; - float ii = i / 128.0; - float w = sincl(ph2 * (1 + 7 * ii * ii), 6) * pow(sincl(j / 256.0, 1), 1); - float v = sin(ph + ii * ii * ii * sin(3 * ph - ii * ii * ii * w)); - tables[wavetable_metadata::wt_gtr][i][j] = 32767 * v; - } - } - */ - for (int i = 0; i < 129; i++) - { - for (int j = 0; j < 256; j++) - { - float ph = j * 2 * M_PI / 256; - float ii = i / 128.0; - float ii2 = ii; - float w = pow(sincl(j / 256.0, 1), 1); - float v = sin(ph + ii2 * ii2 * ii2 * sin(3 * ph - ii2 * ii2 * ii2 * w * sin(ph + sin(3 * ph) + ii * sin(11 * ph) + ii * ii * sin(25 * ph)))); - tables[wavetable_metadata::wt_gtr][i][j] = 32767 * v; - } - } - for (int i = 0; i < 129; i++) - { - for (int j = 0; j < 256; j++) - { - float ph = j * 2 * M_PI / 256; - float ii = i / 128.0; - float ii2 = dsp::clip(ii - 0.5, 0.0, 1.0); - float w = pow(sincl(j / 256.0, 1), 1); - float v = sin(ph + ii * ii * ii * sin(3 * ph - ii * ii * ii * w * sin(ph + sin(3 * ph + ii2 * sin(13 * ph))))); - tables[wavetable_metadata::wt_gtr2][i][j] = 32767 * v; - } - } - for (int i = 0; i < 129; i++) - { - for (int j = 0; j < 256; j++) - { - float ph = j * 2 * M_PI / 256; - float ii = i / 128.0; - float ii2 = dsp::clip(2 * (ii - 0.5), 0.0, 1.0); - //float w = sincl(ph2 * (1 + 15 * ii2 * ii2), 4) * pow(sincl(j / 256.0, 1), 1); - float w = pow(sincl(j / 256.0, 1), 1); - float v = sin(ph + ii * sin(3 * ph - ii * w * sin(ph + sin(3 * ph + 0.5 * ii2 * sin(13 * ph + 0.5 * sin(4 * ph)))))); - tables[wavetable_metadata::wt_gtr3][i][j] = 32767 * v; - } - } - for (int i = 0; i < 129; i++) - { - for (int j = 0; j < 256; j++) - { - float ph = j * 2 * M_PI / 256; - float ii = i / 128.0; - float ii2 = dsp::clip(2 * (ii - 0.5), 0.0, 1.0); - //float w = sincl(ph2 * (1 + 15 * ii2 * ii2), 4) * pow(sincl(j / 256.0, 1), 1); - float w = pow(sincl(j / 256.0, 1), 1); - float v = sin(ph + ii * sin(3 * ph - ii * w * sin(2 * ph + sin(5 * ph + 0.5 * ii2 * sin(13 * ph + 0.5 * sin(4 * ph)))))); - tables[wavetable_metadata::wt_gtr4][i][j] = 32767 * v; - } - } - for (int i = 0; i < 129; i++) - { - for (int j = 0; j < 256; j++) - { - float ph = j * 2 * M_PI / 256; - float ii = i / 128.0; - float ii2 = dsp::clip((ii - 0.25)/0.75, 0.0, 1.0); - //float w = sincl(ph2 * (1 + 15 * ii2 * ii2), 4) * pow(sincl(j / 256.0, 1), 1); - float w = pow(sincl(j / 256.0, 1), 3); - float v = sin(ph + (ii + 0.05) * sin(3 * ph - 2 * ii * w * sin(5 * ph + sin(7 * ph + 0.5 * ii2 * sin(13 * ph + 0.5 * sin(11 * ph)))))); - tables[wavetable_metadata::wt_gtr5][i][j] = 32767 * v; - } - } - for (int i = 0; i < 129; i++) - { - for (int j = 0; j < 256; j++) - { - float ph = j * 2 * M_PI / 256; - float ii = i / 128.0; - float w = pow(sincl(2 * (j / 256.0), 2), 3); - float v = sin(ph + (ii + 0.05) * sin(7 * ph - 2 * ii * w * sin(11 * ph))); - tables[wavetable_metadata::wt_reed][i][j] = 32767 * v; - } - } - for (int i = 0; i < 129; i++) - { - for (int j = 0; j < 256; j++) - { - float ph = j * 2 * M_PI / 256; - float ii = i / 128.0; - float ii2 = dsp::clip((ii - 0.25)/0.75, 0.0, 1.0); - float ii3 = dsp::clip((ii - 0.5)/0.5, 0.0, 1.0); - float v = sin(ph + (ii + 0.05) * sin(ii * sin(2 * ph) - 2 * ii2 * sin(2 * ph + ii2 * sin(3 * ph)) + 3 * ii3 * sin(3 * ph))); - tables[wavetable_metadata::wt_reed2][i][j] = 32767 * v; - } - } - for (int i = 0; i < 129; i++) - { - for (int j = 0; j < 256; j++) - { - float ph = j * 2 * M_PI / 256; - float ii = i / 128.0; - float mod = 0; - for (int k = 0; k < 13; k++) - { - mod += blip(i, k * 10, 30) * sin (ph * (5 + 3 * k) + ii * cos(ph * (2 + 2 * k))); - } - float v = sin(ph + ii * mod); - tables[wavetable_metadata::wt_silver][i][j] = 32767 * v; - } - } - for (int i = 0; i < 129; i++) - { - for (int j = 0; j < 256; j++) - { - float ph = j * 2 * M_PI / 256; - float ii = i / 128.0; - float mod = 0; - for (int k = 0; k < 16; k++) - { - mod += 2 * blip(i, k * 8, k * 4 + 10) * cos (ph * (k + 1)); - } - float v = sin(ph + ii * mod); - tables[wavetable_metadata::wt_brass][i][j] = 32767 * v; - } - } - for (int i = 0; i < 129; i++) - { - for (int j = 0; j < 256; j++) - { - float ph = j * 2 * M_PI / 256; - float ii = i / 128.0; - float mod = 0; - for (int k = 0; k < 16; k++) - { - mod += 2 * blip(i, k * 8, 16) * cos (ph * (2 * k + 1)); - } - float v = (sin(ph + ii * mod) + ii * sin(2 * ph + ii * mod)) / 2; - tables[wavetable_metadata::wt_multi][i][j] = 32767 * v; - } - } - for (int i = 0; i < 129; i ++) - { - float h = 1 + i / 16.0; - for (int j = 0; j < 256; j++) - { - float ph = j * 2 * M_PI / 256; - float v = sin(ph), tv = 1; - for (int k = 1; k < 24; k++) { - float amp = blip(i, k * 6, 20) / k; - v += amp * sin((k + 1) * ph + h * sin(ph)); - tv += amp; - } - tables[wavetable_metadata::wt_multi2][i][j] = 32767 * v / tv; - } - } -} - -void wavetable_audio_module::channel_pressure(int /*channel*/, int value) -{ - inertia_pressure.set_inertia(value * (1.0 / 127.0)); -} - -#endif diff --git a/plugins/LadspaEffect/calf/veal b/plugins/LadspaEffect/calf/veal new file mode 160000 index 00000000000..b192af9bf76 --- /dev/null +++ b/plugins/LadspaEffect/calf/veal @@ -0,0 +1 @@ +Subproject commit b192af9bf7620730fe67d32dc668060e8dacb725 diff --git a/src/core/DataFile.cpp b/src/core/DataFile.cpp index cd73be05dc4..7d9f40fdeb9 100644 --- a/src/core/DataFile.cpp +++ b/src/core/DataFile.cpp @@ -995,6 +995,31 @@ void DataFile::upgrade_1_3_0() } } } + + list = elementsByTagName( "effect" ); + for( int i = 0; !list.item( i ).isNull(); ++i ) + { + QDomElement effect = list.item( i ).toElement(); + if( effect.attribute( "name" ) == "ladspaeffect" ) + { + QDomNodeList keys = effect.elementsByTagName( "key" ); + for( int j = 0; !keys.item( j ).isNull(); ++j ) + { + QDomElement key = keys.item( j ).toElement(); + QDomNodeList attributes = key.elementsByTagName( "attribute" ); + for( int k = 0; !attributes.item( k ).isNull(); ++k ) + { + QDomElement attribute = attributes.item( k ).toElement(); + if( attribute.attribute( "name" ) == "file" && + ( attribute.attribute( "value" ) == "calf" || + attribute.attribute( "value" ) == "calf.so" ) ) + { + attribute.setAttribute( "value", "veal" ); + } + } + } + } + } }