From 6ac8759c6108dbef4374b5a03797a7b86b67b210 Mon Sep 17 00:00:00 2001 From: Tobias Doerffel Date: Sat, 20 Sep 2008 17:46:05 +0000 Subject: [PATCH] added a selection of nice SWH LADSPA plugins git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@1645 0778d3d1-df1d-0410-868b-ea421aaaa00d --- CMakeLists.txt | 11 +- ChangeLog | 17 + plugins/ladspa_effect/CMakeLists.txt | 4 + plugins/ladspa_effect/swh/AUTHORS | 18 + plugins/ladspa_effect/swh/CMakeLists.txt | 22 + plugins/ladspa_effect/swh/COPYING | 340 ++++ plugins/ladspa_effect/swh/README | 29 + plugins/ladspa_effect/swh/comb_1190.c | 351 +++++ plugins/ladspa_effect/swh/dc_remove_1207.c | 246 +++ plugins/ladspa_effect/swh/dj_eq_1901.c | 691 ++++++++ .../swh/fast_lookahead_limiter_1913.c | 714 +++++++++ plugins/ladspa_effect/swh/flanger_1191.c | 555 +++++++ plugins/ladspa_effect/swh/mbeq_1197.c | 894 +++++++++++ plugins/ladspa_effect/swh/phasers_1217.c | 1400 +++++++++++++++++ plugins/ladspa_effect/swh/util/biquad.h | 179 +++ plugins/ladspa_effect/swh/vynil_1905.c | 723 +++++++++ 16 files changed, 6193 insertions(+), 1 deletion(-) create mode 100644 plugins/ladspa_effect/swh/AUTHORS create mode 100644 plugins/ladspa_effect/swh/CMakeLists.txt create mode 100644 plugins/ladspa_effect/swh/COPYING create mode 100644 plugins/ladspa_effect/swh/README create mode 100644 plugins/ladspa_effect/swh/comb_1190.c create mode 100644 plugins/ladspa_effect/swh/dc_remove_1207.c create mode 100644 plugins/ladspa_effect/swh/dj_eq_1901.c create mode 100644 plugins/ladspa_effect/swh/fast_lookahead_limiter_1913.c create mode 100644 plugins/ladspa_effect/swh/flanger_1191.c create mode 100644 plugins/ladspa_effect/swh/mbeq_1197.c create mode 100644 plugins/ladspa_effect/swh/phasers_1217.c create mode 100644 plugins/ladspa_effect/swh/util/biquad.h create mode 100644 plugins/ladspa_effect/swh/vynil_1905.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 50e285c3d..a227131be 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,7 +39,8 @@ OPTION(WANT_SDL "Include SDL (Simple DirectMedia Layer) support" ON) OPTION(WANT_SF2 "Include SoundFont2 player plugin" ON) OPTION(WANT_STK "Include Stk (Synthesis Toolkit) support" ON) OPTION(WANT_SYSTEM_SR "Use system's libsamplerate" ON) -OPTION(WANT_TAP "Include Tom's Audio Processing (LADSPA plugins)" ON) +OPTION(WANT_SWH "Include Steve Harris's LADSPA plugins" ON) +OPTION(WANT_TAP "Include Tom's Audio Processing LADSPA plugins" ON) OPTION(WANT_VST "Include VST support" ON) OPTION(WANT_WINMM "Include WinMM MIDI support" OFF) OPTION(WANT_PCH "Use precompiled headers" OFF) @@ -113,6 +114,13 @@ ELSE(WANT_CAPS) SET(STATUS_CAPS "not built as requested") ENDIF(WANT_CAPS) +IF(WANT_SWH) +SET(LMMS_HAVE_SWH TRUE) +SET(STATUS_SWH "OK") +ELSE(WANT_SWH) +SET(STATUS_SWH "not built as requested") +ENDIF(WANT_SWH) + IF(WANT_TAP) SET(LMMS_HAVE_TAP TRUE) SET(STATUS_TAP "OK") @@ -549,6 +557,7 @@ MESSAGE( "* SpectrumAnalyzer : ${STATUS_FFTW3F}\n" "* CAPS LADSPA plugins : ${STATUS_CAPS}\n" "* TAP LADSPA plugins : ${STATUS_TAP}\n" +"* SWH LADSPA plugins : ${STATUS_SWH}\n" ) MESSAGE( diff --git a/ChangeLog b/ChangeLog index 18a4ec422..e11335fd3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,22 @@ 2008-09-20 Tobias Doerffel + * plugins/ladspa_effect/swh/phasers_1217.c: + * plugins/ladspa_effect/swh/vynil_1905.c: + * plugins/ladspa_effect/swh/mbeq_1197.c: + * plugins/ladspa_effect/swh/fast_lookahead_limiter_1913.c: + * plugins/ladspa_effect/swh/flanger_1191.c: + * plugins/ladspa_effect/swh/comb_1190.c: + * plugins/ladspa_effect/swh/dc_remove_1207.c: + * plugins/ladspa_effect/swh/dj_eq_1901.c: + * plugins/ladspa_effect/swh/util/biquad.h: + * plugins/ladspa_effect/swh/CMakeLists.txt: + * plugins/ladspa_effect/swh/AUTHORS: + * plugins/ladspa_effect/swh/COPYING: + * plugins/ladspa_effect/swh/README: + * plugins/ladspa_effect/CMakeLists.txt: + * CMakeLists.txt: + added a selection of nice SWH LADSPA plugins + * include/piano_roll.h: * src/gui/piano_roll.cpp: fixed quantization when moving selected notes (closes #2118371) diff --git a/plugins/ladspa_effect/CMakeLists.txt b/plugins/ladspa_effect/CMakeLists.txt index 0832287f2..487306f90 100644 --- a/plugins/ladspa_effect/CMakeLists.txt +++ b/plugins/ladspa_effect/CMakeLists.txt @@ -10,3 +10,7 @@ IF(WANT_TAP) ADD_SUBDIRECTORY(tap) ENDIF(WANT_TAP) +IF(WANT_SWH) +ADD_SUBDIRECTORY(swh) +ENDIF(WANT_SWH) + diff --git a/plugins/ladspa_effect/swh/AUTHORS b/plugins/ladspa_effect/swh/AUTHORS new file mode 100644 index 000000000..d4a8c78cd --- /dev/null +++ b/plugins/ladspa_effect/swh/AUTHORS @@ -0,0 +1,18 @@ +In no particular order: + +Steve Harris - general stuff +Frank Neumann - documentation, proofreading, DSP code +Juhana Sadeharju - DSP code +Joern Nettingsmeier - DSP code, bug reports and inspiration +Mark Knecht - testesting, docuementation +Pascal Haakmat - bugfixes, testing +Marcus Andersson - DSP code +Paul Winkler - documentation +Matthias Nagorni - testing, inspiration +Nathaniel Virgo - bugfixes +Patrick Shirkey - testing, inspiration + +Project maintainted by Steve Harris, Southampton UK. +steve@plugin.org.uk or swh@ecs.soton.ac.uk + +Plugin website at http://plugin.org.uk/ diff --git a/plugins/ladspa_effect/swh/CMakeLists.txt b/plugins/ladspa_effect/swh/CMakeLists.txt new file mode 100644 index 000000000..9d2ee74a6 --- /dev/null +++ b/plugins/ladspa_effect/swh/CMakeLists.txt @@ -0,0 +1,22 @@ +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}) +FILE(GLOB PLUGIN_SOURCES *.c) +ADD_DEFINITIONS(-DFFTW3) +FOREACH(_item ${PLUGIN_SOURCES}) + GET_FILENAME_COMPONENT(_plugin "${_item}" NAME_WE) + ADD_LIBRARY(${_plugin} MODULE ${_item}) + INSTALL(TARGETS ${_plugin} LIBRARY DESTINATION ${PLUGIN_DIR}/ladspa) + SET_TARGET_PROPERTIES(${_plugin} PROPERTIES PREFIX "") + SET_TARGET_PROPERTIES(${_plugin} PROPERTIES COMPILE_FLAGS "-O3 -Wall -fomit-frame-pointer -fstrength-reduce -funroll-loops -ffast-math -c -fPIC -DPIC") + IF(LMMS_BUILD_WIN32) + ADD_CUSTOM_COMMAND(TARGET ${_plugin} POST_BUILD COMMAND /opt/mingw/bin/i586-mingw32-strip ${CMAKE_CURRENT_BINARY_DIR}/${_plugin}.dll) + ENDIF(LMMS_BUILD_WIN32) + IF(LMMS_BUILD_APPLE) + SET_TARGET_PROPERTIES(${_plugin} PROPERTIES LINK_FLAGS "${LINK_FLAGS} -shared -no-undefined -Bsymbolic -lm") + ELSE(LMMS_BUILD_APPLE) + SET_TARGET_PROPERTIES(${_plugin} PROPERTIES LINK_FLAGS "${LINK_FLAGS} -shared -Wl,-no-undefined -Wl,-Bsymbolic -lm") + ENDIF(LMMS_BUILD_APPLE) + IF(LMMS_BUILD_LINUX) + SET_TARGET_PROPERTIES(${_plugin} PROPERTIES LINK_FLAGS "${LINK_FLAGS} -nostartfiles") + ENDIF(LMMS_BUILD_LINUX) +ENDFOREACH(_item ${PLUGIN_SOURCES}) + diff --git a/plugins/ladspa_effect/swh/COPYING b/plugins/ladspa_effect/swh/COPYING new file mode 100644 index 000000000..d60c31a97 --- /dev/null +++ b/plugins/ladspa_effect/swh/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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/ladspa_effect/swh/README b/plugins/ladspa_effect/swh/README new file mode 100644 index 000000000..35871c728 --- /dev/null +++ b/plugins/ladspa_effect/swh/README @@ -0,0 +1,29 @@ +Compiling +~~~~~~~~~ +You will need libfftw version 2 or 3 installed with 32 bit float support (eg. +for FFTW3 use --enable-float), for FFTW recommend you specify the approriate +SIMD isntruction set for your CPU with --enable-sse, --enable-sse2, --enable-k7 +or --enable-altivec. You can get FFTW from http://www.fftw.org/. + +Install with + ./configure + make + su -c "make install". + +This code is normally built from XML source, using Perl and XML::Parser. I +distribute the generated .c files, so you wont need perl, but if you want to +edit the XML source then you will need a copy of Perl and XML::Parser +installed. + +Homepage and docs +~~~~~~~~~~~~~~~~~ +The homepage for this project is http://plugin.org.uk/ + +Bug reports +~~~~~~~~~~~ +Please send bug reports or comments to steve@plugin.org.uk, except for bugs +relating to the gverb plugin, for that please send bug reports etc. to Juhana +Sadeharju, kouhia_at_nic.funet.fi. + +Enjoy, + Steve diff --git a/plugins/ladspa_effect/swh/comb_1190.c b/plugins/ladspa_effect/swh/comb_1190.c new file mode 100644 index 000000000..05fe340c2 --- /dev/null +++ b/plugins/ladspa_effect/swh/comb_1190.c @@ -0,0 +1,351 @@ +#include +#include +#ifndef WIN32 +#include "config.h" +#endif + +#ifdef ENABLE_NLS +#include +#endif + +#define _ISOC9X_SOURCE 1 +#define _ISOC99_SOURCE 1 +#define __USE_ISOC99 1 +#define __USE_ISOC9X 1 + +#include + +#include "ladspa.h" + +#ifdef WIN32 +#define _WINDOWS_DLL_EXPORT_ __declspec(dllexport) +int bIsFirstTime = 1; +void _init(); // forward declaration +#else +#define _WINDOWS_DLL_EXPORT_ +#endif + +#line 9 "comb_1190.xml" + +#include "ladspa-util.h" +#define COMB_SIZE 0x4000 +#define COMB_MASK 0x3FFF + +#define COMB_FREQ 0 +#define COMB_FB 1 +#define COMB_INPUT 2 +#define COMB_OUTPUT 3 + +static LADSPA_Descriptor *combDescriptor = NULL; + +typedef struct { + LADSPA_Data *freq; + LADSPA_Data *fb; + LADSPA_Data *input; + LADSPA_Data *output; + long comb_pos; + LADSPA_Data *comb_tbl; + float last_offset; + long sample_rate; + LADSPA_Data run_adding_gain; +} Comb; + +_WINDOWS_DLL_EXPORT_ +const LADSPA_Descriptor *ladspa_descriptor(unsigned long index) { + +#ifdef WIN32 + if (bIsFirstTime) { + _init(); + bIsFirstTime = 0; + } +#endif + switch (index) { + case 0: + return combDescriptor; + default: + return NULL; + } +} + +static void activateComb(LADSPA_Handle instance) { + Comb *plugin_data = (Comb *)instance; + long comb_pos = plugin_data->comb_pos; + LADSPA_Data *comb_tbl = plugin_data->comb_tbl; + float last_offset = plugin_data->last_offset; + long sample_rate = plugin_data->sample_rate; +#line 27 "comb_1190.xml" + int i; + + for (i = 0; i < COMB_SIZE; i++) { + comb_tbl[i] = 0; + } + comb_pos = 0; + last_offset = 1000; + plugin_data->comb_pos = comb_pos; + plugin_data->comb_tbl = comb_tbl; + plugin_data->last_offset = last_offset; + plugin_data->sample_rate = sample_rate; + +} + +static void cleanupComb(LADSPA_Handle instance) { +#line 37 "comb_1190.xml" + Comb *plugin_data = (Comb *)instance; + free(plugin_data->comb_tbl); + free(instance); +} + +static void connectPortComb( + LADSPA_Handle instance, + unsigned long port, + LADSPA_Data *data) { + Comb *plugin; + + plugin = (Comb *)instance; + switch (port) { + case COMB_FREQ: + plugin->freq = data; + break; + case COMB_FB: + plugin->fb = data; + break; + case COMB_INPUT: + plugin->input = data; + break; + case COMB_OUTPUT: + plugin->output = data; + break; + } +} + +static LADSPA_Handle instantiateComb( + const LADSPA_Descriptor *descriptor, + unsigned long s_rate) { + Comb *plugin_data = (Comb *)malloc(sizeof(Comb)); + long comb_pos; + LADSPA_Data *comb_tbl = NULL; + float last_offset; + long sample_rate; + +#line 20 "comb_1190.xml" + sample_rate = s_rate; + comb_tbl = malloc(sizeof(LADSPA_Data) * COMB_SIZE); + comb_pos = 0; + last_offset = 1000; + + plugin_data->comb_pos = comb_pos; + plugin_data->comb_tbl = comb_tbl; + plugin_data->last_offset = last_offset; + plugin_data->sample_rate = sample_rate; + + return (LADSPA_Handle)plugin_data; +} + +#undef buffer_write +#undef RUN_ADDING +#undef RUN_REPLACING + +#define buffer_write(b, v) (b = v) +#define RUN_ADDING 0 +#define RUN_REPLACING 1 + +static void runComb(LADSPA_Handle instance, unsigned long sample_count) { + Comb *plugin_data = (Comb *)instance; + + /* Band separation (Hz) (float value) */ + const LADSPA_Data freq = *(plugin_data->freq); + + /* Feedback (float value) */ + const LADSPA_Data fb = *(plugin_data->fb); + + /* Input (array of floats of length sample_count) */ + const LADSPA_Data * const input = plugin_data->input; + + /* Output (array of floats of length sample_count) */ + LADSPA_Data * const output = plugin_data->output; + long comb_pos = plugin_data->comb_pos; + LADSPA_Data * comb_tbl = plugin_data->comb_tbl; + float last_offset = plugin_data->last_offset; + long sample_rate = plugin_data->sample_rate; + +#line 41 "comb_1190.xml" + float offset; + int data_pos; + unsigned long pos; + float xf, xf_step, d_pos, fr, interp; + + offset = sample_rate / freq; + offset = f_clamp(offset, 0, COMB_SIZE - 1); + xf_step = 1.0f / (float)sample_count; + xf = 0.0f; + + for (pos = 0; pos < sample_count; pos++) { + xf += xf_step; + d_pos = comb_pos - LIN_INTERP(xf, last_offset, offset); + data_pos = f_trunc(d_pos); + fr = d_pos - data_pos; + interp = cube_interp(fr, comb_tbl[(data_pos - 1) & COMB_MASK], comb_tbl[data_pos & COMB_MASK], comb_tbl[(data_pos + 1) & COMB_MASK], comb_tbl[(data_pos + 2) & COMB_MASK]); + comb_tbl[comb_pos] = input[pos] + fb * interp; + buffer_write(output[pos], (input[pos] + interp) * 0.5f); + comb_pos = (comb_pos + 1) & COMB_MASK; + } + + plugin_data->comb_pos = comb_pos; + plugin_data->last_offset = offset; +} +#undef buffer_write +#undef RUN_ADDING +#undef RUN_REPLACING + +#define buffer_write(b, v) (b += (v) * run_adding_gain) +#define RUN_ADDING 1 +#define RUN_REPLACING 0 + +static void setRunAddingGainComb(LADSPA_Handle instance, LADSPA_Data gain) { + ((Comb *)instance)->run_adding_gain = gain; +} + +static void runAddingComb(LADSPA_Handle instance, unsigned long sample_count) { + Comb *plugin_data = (Comb *)instance; + LADSPA_Data run_adding_gain = plugin_data->run_adding_gain; + + /* Band separation (Hz) (float value) */ + const LADSPA_Data freq = *(plugin_data->freq); + + /* Feedback (float value) */ + const LADSPA_Data fb = *(plugin_data->fb); + + /* Input (array of floats of length sample_count) */ + const LADSPA_Data * const input = plugin_data->input; + + /* Output (array of floats of length sample_count) */ + LADSPA_Data * const output = plugin_data->output; + long comb_pos = plugin_data->comb_pos; + LADSPA_Data * comb_tbl = plugin_data->comb_tbl; + float last_offset = plugin_data->last_offset; + long sample_rate = plugin_data->sample_rate; + +#line 41 "comb_1190.xml" + float offset; + int data_pos; + unsigned long pos; + float xf, xf_step, d_pos, fr, interp; + + offset = sample_rate / freq; + offset = f_clamp(offset, 0, COMB_SIZE - 1); + xf_step = 1.0f / (float)sample_count; + xf = 0.0f; + + for (pos = 0; pos < sample_count; pos++) { + xf += xf_step; + d_pos = comb_pos - LIN_INTERP(xf, last_offset, offset); + data_pos = f_trunc(d_pos); + fr = d_pos - data_pos; + interp = cube_interp(fr, comb_tbl[(data_pos - 1) & COMB_MASK], comb_tbl[data_pos & COMB_MASK], comb_tbl[(data_pos + 1) & COMB_MASK], comb_tbl[(data_pos + 2) & COMB_MASK]); + comb_tbl[comb_pos] = input[pos] + fb * interp; + buffer_write(output[pos], (input[pos] + interp) * 0.5f); + comb_pos = (comb_pos + 1) & COMB_MASK; + } + + plugin_data->comb_pos = comb_pos; + plugin_data->last_offset = offset; +} + +void _init() { + char **port_names; + LADSPA_PortDescriptor *port_descriptors; + LADSPA_PortRangeHint *port_range_hints; + +#ifdef ENABLE_NLS +#define D_(s) dgettext(PACKAGE, s) + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, PACKAGE_LOCALE_DIR); +#else +#define D_(s) (s) +#endif + + + combDescriptor = + (LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor)); + + if (combDescriptor) { + combDescriptor->UniqueID = 1190; + combDescriptor->Label = "comb"; + combDescriptor->Properties = + LADSPA_PROPERTY_HARD_RT_CAPABLE; + combDescriptor->Name = + D_("Comb Filter"); + combDescriptor->Maker = + "Steve Harris "; + combDescriptor->Copyright = + "GPL"; + combDescriptor->PortCount = 4; + + port_descriptors = (LADSPA_PortDescriptor *)calloc(4, + sizeof(LADSPA_PortDescriptor)); + combDescriptor->PortDescriptors = + (const LADSPA_PortDescriptor *)port_descriptors; + + port_range_hints = (LADSPA_PortRangeHint *)calloc(4, + sizeof(LADSPA_PortRangeHint)); + combDescriptor->PortRangeHints = + (const LADSPA_PortRangeHint *)port_range_hints; + + port_names = (char **)calloc(4, sizeof(char*)); + combDescriptor->PortNames = + (const char **)port_names; + + /* Parameters for Band separation (Hz) */ + port_descriptors[COMB_FREQ] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[COMB_FREQ] = + D_("Band separation (Hz)"); + port_range_hints[COMB_FREQ].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_LOW; + port_range_hints[COMB_FREQ].LowerBound = 16; + port_range_hints[COMB_FREQ].UpperBound = 640; + + /* Parameters for Feedback */ + port_descriptors[COMB_FB] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[COMB_FB] = + D_("Feedback"); + port_range_hints[COMB_FB].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0; + port_range_hints[COMB_FB].LowerBound = -0.99; + port_range_hints[COMB_FB].UpperBound = 0.99; + + /* Parameters for Input */ + port_descriptors[COMB_INPUT] = + LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO; + port_names[COMB_INPUT] = + D_("Input"); + port_range_hints[COMB_INPUT].HintDescriptor = 0; + + /* Parameters for Output */ + port_descriptors[COMB_OUTPUT] = + LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO; + port_names[COMB_OUTPUT] = + D_("Output"); + port_range_hints[COMB_OUTPUT].HintDescriptor = 0; + + combDescriptor->activate = activateComb; + combDescriptor->cleanup = cleanupComb; + combDescriptor->connect_port = connectPortComb; + combDescriptor->deactivate = NULL; + combDescriptor->instantiate = instantiateComb; + combDescriptor->run = runComb; + combDescriptor->run_adding = runAddingComb; + combDescriptor->set_run_adding_gain = setRunAddingGainComb; + } +} + +void _fini() { + if (combDescriptor) { + free((LADSPA_PortDescriptor *)combDescriptor->PortDescriptors); + free((char **)combDescriptor->PortNames); + free((LADSPA_PortRangeHint *)combDescriptor->PortRangeHints); + free(combDescriptor); + } + +} diff --git a/plugins/ladspa_effect/swh/dc_remove_1207.c b/plugins/ladspa_effect/swh/dc_remove_1207.c new file mode 100644 index 000000000..099e5daf6 --- /dev/null +++ b/plugins/ladspa_effect/swh/dc_remove_1207.c @@ -0,0 +1,246 @@ +#include +#include +#ifndef WIN32 +#include "config.h" +#endif + +#ifdef ENABLE_NLS +#include +#endif + +#define _ISOC9X_SOURCE 1 +#define _ISOC99_SOURCE 1 +#define __USE_ISOC99 1 +#define __USE_ISOC9X 1 + +#include + +#include "ladspa.h" + +#ifdef WIN32 +#define _WINDOWS_DLL_EXPORT_ __declspec(dllexport) +int bIsFirstTime = 1; +void _init(); // forward declaration +#else +#define _WINDOWS_DLL_EXPORT_ +#endif + + +#define DCREMOVE_INPUT 0 +#define DCREMOVE_OUTPUT 1 + +static LADSPA_Descriptor *dcRemoveDescriptor = NULL; + +typedef struct { + LADSPA_Data *input; + LADSPA_Data *output; + LADSPA_Data itm1; + LADSPA_Data otm1; + LADSPA_Data run_adding_gain; +} DcRemove; + +_WINDOWS_DLL_EXPORT_ +const LADSPA_Descriptor *ladspa_descriptor(unsigned long index) { + +#ifdef WIN32 + if (bIsFirstTime) { + _init(); + bIsFirstTime = 0; + } +#endif + switch (index) { + case 0: + return dcRemoveDescriptor; + default: + return NULL; + } +} + +static void activateDcRemove(LADSPA_Handle instance) { + DcRemove *plugin_data = (DcRemove *)instance; + LADSPA_Data itm1 = plugin_data->itm1; + LADSPA_Data otm1 = plugin_data->otm1; +#line 17 "dc_remove_1207.xml" + itm1 = 0.0f; + otm1 = 0.0f; + plugin_data->itm1 = itm1; + plugin_data->otm1 = otm1; + +} + +static void cleanupDcRemove(LADSPA_Handle instance) { + free(instance); +} + +static void connectPortDcRemove( + LADSPA_Handle instance, + unsigned long port, + LADSPA_Data *data) { + DcRemove *plugin; + + plugin = (DcRemove *)instance; + switch (port) { + case DCREMOVE_INPUT: + plugin->input = data; + break; + case DCREMOVE_OUTPUT: + plugin->output = data; + break; + } +} + +static LADSPA_Handle instantiateDcRemove( + const LADSPA_Descriptor *descriptor, + unsigned long s_rate) { + DcRemove *plugin_data = (DcRemove *)malloc(sizeof(DcRemove)); + plugin_data->run_adding_gain = 1.0f; + + return (LADSPA_Handle)plugin_data; +} + +#undef buffer_write +#undef RUN_ADDING +#undef RUN_REPLACING + +#define buffer_write(b, v) (b = v) +#define RUN_ADDING 0 +#define RUN_REPLACING 1 + +static void runDcRemove(LADSPA_Handle instance, unsigned long sample_count) { + DcRemove *plugin_data = (DcRemove *)instance; + + /* Input (array of floats of length sample_count) */ + const LADSPA_Data * const input = plugin_data->input; + + /* Output (array of floats of length sample_count) */ + LADSPA_Data * const output = plugin_data->output; + LADSPA_Data itm1 = plugin_data->itm1; + LADSPA_Data otm1 = plugin_data->otm1; + +#line 22 "dc_remove_1207.xml" + unsigned long pos; + + for (pos = 0; pos < sample_count; pos++) { + otm1 = 0.999f * otm1 + input[pos] - itm1; + itm1 = input[pos]; + buffer_write(output[pos], otm1); + } + + plugin_data->itm1 = itm1; + plugin_data->otm1 = otm1; +} +#undef buffer_write +#undef RUN_ADDING +#undef RUN_REPLACING + +#define buffer_write(b, v) (b += (v) * run_adding_gain) +#define RUN_ADDING 1 +#define RUN_REPLACING 0 + +static void setRunAddingGainDcRemove(LADSPA_Handle instance, LADSPA_Data gain) { + ((DcRemove *)instance)->run_adding_gain = gain; +} + +static void runAddingDcRemove(LADSPA_Handle instance, unsigned long sample_count) { + DcRemove *plugin_data = (DcRemove *)instance; + LADSPA_Data run_adding_gain = plugin_data->run_adding_gain; + + /* Input (array of floats of length sample_count) */ + const LADSPA_Data * const input = plugin_data->input; + + /* Output (array of floats of length sample_count) */ + LADSPA_Data * const output = plugin_data->output; + LADSPA_Data itm1 = plugin_data->itm1; + LADSPA_Data otm1 = plugin_data->otm1; + +#line 22 "dc_remove_1207.xml" + unsigned long pos; + + for (pos = 0; pos < sample_count; pos++) { + otm1 = 0.999f * otm1 + input[pos] - itm1; + itm1 = input[pos]; + buffer_write(output[pos], otm1); + } + + plugin_data->itm1 = itm1; + plugin_data->otm1 = otm1; +} + +void _init() { + char **port_names; + LADSPA_PortDescriptor *port_descriptors; + LADSPA_PortRangeHint *port_range_hints; + +#ifdef ENABLE_NLS +#define D_(s) dgettext(PACKAGE, s) + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, PACKAGE_LOCALE_DIR); +#else +#define D_(s) (s) +#endif + + + dcRemoveDescriptor = + (LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor)); + + if (dcRemoveDescriptor) { + dcRemoveDescriptor->UniqueID = 1207; + dcRemoveDescriptor->Label = "dcRemove"; + dcRemoveDescriptor->Properties = + LADSPA_PROPERTY_HARD_RT_CAPABLE; + dcRemoveDescriptor->Name = + D_("DC Offset Remover"); + dcRemoveDescriptor->Maker = + "Steve Harris "; + dcRemoveDescriptor->Copyright = + "GPL"; + dcRemoveDescriptor->PortCount = 2; + + port_descriptors = (LADSPA_PortDescriptor *)calloc(2, + sizeof(LADSPA_PortDescriptor)); + dcRemoveDescriptor->PortDescriptors = + (const LADSPA_PortDescriptor *)port_descriptors; + + port_range_hints = (LADSPA_PortRangeHint *)calloc(2, + sizeof(LADSPA_PortRangeHint)); + dcRemoveDescriptor->PortRangeHints = + (const LADSPA_PortRangeHint *)port_range_hints; + + port_names = (char **)calloc(2, sizeof(char*)); + dcRemoveDescriptor->PortNames = + (const char **)port_names; + + /* Parameters for Input */ + port_descriptors[DCREMOVE_INPUT] = + LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO; + port_names[DCREMOVE_INPUT] = + D_("Input"); + port_range_hints[DCREMOVE_INPUT].HintDescriptor = 0; + + /* Parameters for Output */ + port_descriptors[DCREMOVE_OUTPUT] = + LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO; + port_names[DCREMOVE_OUTPUT] = + D_("Output"); + port_range_hints[DCREMOVE_OUTPUT].HintDescriptor = 0; + + dcRemoveDescriptor->activate = activateDcRemove; + dcRemoveDescriptor->cleanup = cleanupDcRemove; + dcRemoveDescriptor->connect_port = connectPortDcRemove; + dcRemoveDescriptor->deactivate = NULL; + dcRemoveDescriptor->instantiate = instantiateDcRemove; + dcRemoveDescriptor->run = runDcRemove; + dcRemoveDescriptor->run_adding = runAddingDcRemove; + dcRemoveDescriptor->set_run_adding_gain = setRunAddingGainDcRemove; + } +} + +void _fini() { + if (dcRemoveDescriptor) { + free((LADSPA_PortDescriptor *)dcRemoveDescriptor->PortDescriptors); + free((char **)dcRemoveDescriptor->PortNames); + free((LADSPA_PortRangeHint *)dcRemoveDescriptor->PortRangeHints); + free(dcRemoveDescriptor); + } + +} diff --git a/plugins/ladspa_effect/swh/dj_eq_1901.c b/plugins/ladspa_effect/swh/dj_eq_1901.c new file mode 100644 index 000000000..2184ae1cd --- /dev/null +++ b/plugins/ladspa_effect/swh/dj_eq_1901.c @@ -0,0 +1,691 @@ +#include +#include +#ifndef WIN32 +#include "config.h" +#endif + +#ifdef ENABLE_NLS +#include +#endif + +#define _ISOC9X_SOURCE 1 +#define _ISOC99_SOURCE 1 +#define __USE_ISOC99 1 +#define __USE_ISOC9X 1 + +#include + +#include "ladspa.h" + +#ifdef WIN32 +#define _WINDOWS_DLL_EXPORT_ __declspec(dllexport) +int bIsFirstTime = 1; +void _init(); // forward declaration +#else +#define _WINDOWS_DLL_EXPORT_ +#endif + +#line 10 "dj_eq_1901.xml" + +#include "ladspa-util.h" +#include "util/biquad.h" + +#define BANDS 3 + +#define PEAK_BW 0.3f /* Peak EQ bandwidth (octaves) */ +#define SHELF_SLOPE 1.5f /* Shelf EQ slope (arb. units) */ + +#define DJ_EQ_MONO_LO 0 +#define DJ_EQ_MONO_MID 1 +#define DJ_EQ_MONO_HI 2 +#define DJ_EQ_MONO_INPUT 3 +#define DJ_EQ_MONO_OUTPUT 4 +#define DJ_EQ_MONO_LATENCY 5 +#define DJ_EQ_LO 0 +#define DJ_EQ_MID 1 +#define DJ_EQ_HI 2 +#define DJ_EQ_LEFT_INPUT 3 +#define DJ_EQ_RIGHT_INPUT 4 +#define DJ_EQ_LEFT_OUTPUT 5 +#define DJ_EQ_RIGHT_OUTPUT 6 +#define DJ_EQ_LATENCY 7 + +static LADSPA_Descriptor *dj_eq_monoDescriptor = NULL; + +typedef struct { + LADSPA_Data *lo; + LADSPA_Data *mid; + LADSPA_Data *hi; + LADSPA_Data *input; + LADSPA_Data *output; + LADSPA_Data *latency; + biquad * filters; + float fs; + LADSPA_Data run_adding_gain; +} Dj_eq_mono; + +static LADSPA_Descriptor *dj_eqDescriptor = NULL; + +typedef struct { + LADSPA_Data *lo; + LADSPA_Data *mid; + LADSPA_Data *hi; + LADSPA_Data *left_input; + LADSPA_Data *right_input; + LADSPA_Data *left_output; + LADSPA_Data *right_output; + LADSPA_Data *latency; + biquad * filters; + float fs; + LADSPA_Data run_adding_gain; +} Dj_eq; + +_WINDOWS_DLL_EXPORT_ +const LADSPA_Descriptor *ladspa_descriptor(unsigned long index) { + +#ifdef WIN32 + if (bIsFirstTime) { + _init(); + bIsFirstTime = 0; + } +#endif + switch (index) { + case 0: + return dj_eq_monoDescriptor; + case 1: + return dj_eqDescriptor; + default: + return NULL; + } +} + +static void activateDj_eq_mono(LADSPA_Handle instance) { + Dj_eq_mono *plugin_data = (Dj_eq_mono *)instance; + biquad *filters = plugin_data->filters; + float fs = plugin_data->fs; +#line 33 "dj_eq_1901.xml" + biquad_init(&filters[0]); + eq_set_params(&filters[0], 100.0f, 0.0f, PEAK_BW, fs); + biquad_init(&filters[1]); + eq_set_params(&filters[1], 1000.0f, 0.0f, PEAK_BW, fs); + biquad_init(&filters[2]); + hs_set_params(&filters[2], 10000.0f, 0.0f, SHELF_SLOPE, fs); + plugin_data->filters = filters; + plugin_data->fs = fs; + +} + +static void cleanupDj_eq_mono(LADSPA_Handle instance) { + free(instance); +} + +static void connectPortDj_eq_mono( + LADSPA_Handle instance, + unsigned long port, + LADSPA_Data *data) { + Dj_eq_mono *plugin; + + plugin = (Dj_eq_mono *)instance; + switch (port) { + case DJ_EQ_MONO_LO: + plugin->lo = data; + break; + case DJ_EQ_MONO_MID: + plugin->mid = data; + break; + case DJ_EQ_MONO_HI: + plugin->hi = data; + break; + case DJ_EQ_MONO_INPUT: + plugin->input = data; + break; + case DJ_EQ_MONO_OUTPUT: + plugin->output = data; + break; + case DJ_EQ_MONO_LATENCY: + plugin->latency = data; + break; + } +} + +static LADSPA_Handle instantiateDj_eq_mono( + const LADSPA_Descriptor *descriptor, + unsigned long s_rate) { + Dj_eq_mono *plugin_data = (Dj_eq_mono *)malloc(sizeof(Dj_eq_mono)); + biquad *filters = NULL; + float fs; + +#line 27 "dj_eq_1901.xml" + fs = s_rate; + + filters = calloc(BANDS, sizeof(biquad)); + + plugin_data->filters = filters; + plugin_data->fs = fs; + + return (LADSPA_Handle)plugin_data; +} + +#undef buffer_write +#undef RUN_ADDING +#undef RUN_REPLACING + +#define buffer_write(b, v) (b = v) +#define RUN_ADDING 0 +#define RUN_REPLACING 1 + +static void runDj_eq_mono(LADSPA_Handle instance, unsigned long sample_count) { + Dj_eq_mono *plugin_data = (Dj_eq_mono *)instance; + + /* Lo gain (dB) (float value) */ + const LADSPA_Data lo = *(plugin_data->lo); + + /* Mid gain (dB) (float value) */ + const LADSPA_Data mid = *(plugin_data->mid); + + /* Hi gain (dB) (float value) */ + const LADSPA_Data hi = *(plugin_data->hi); + + /* Input (array of floats of length sample_count) */ + const LADSPA_Data * const input = plugin_data->input; + + /* Output (array of floats of length sample_count) */ + LADSPA_Data * const output = plugin_data->output; + biquad * filters = plugin_data->filters; + float fs = plugin_data->fs; + +#line 42 "dj_eq_1901.xml" + unsigned long pos; + float samp; + + eq_set_params(&filters[0], 100.0f, lo, PEAK_BW, fs); + eq_set_params(&filters[1], 1000.0f, mid, PEAK_BW, fs); + hs_set_params(&filters[2], 10000.0f, hi, SHELF_SLOPE, fs); + + for (pos = 0; pos < sample_count; pos++) { + samp = biquad_run(&filters[0], input[pos]); + samp = biquad_run(&filters[1], samp); + samp = biquad_run(&filters[2], samp); + buffer_write(output[pos], samp); + } + + *(plugin_data->latency) = 3; //XXX is this right? +} +#undef buffer_write +#undef RUN_ADDING +#undef RUN_REPLACING + +#define buffer_write(b, v) (b += (v) * run_adding_gain) +#define RUN_ADDING 1 +#define RUN_REPLACING 0 + +static void setRunAddingGainDj_eq_mono(LADSPA_Handle instance, LADSPA_Data gain) { + ((Dj_eq_mono *)instance)->run_adding_gain = gain; +} + +static void runAddingDj_eq_mono(LADSPA_Handle instance, unsigned long sample_count) { + Dj_eq_mono *plugin_data = (Dj_eq_mono *)instance; + LADSPA_Data run_adding_gain = plugin_data->run_adding_gain; + + /* Lo gain (dB) (float value) */ + const LADSPA_Data lo = *(plugin_data->lo); + + /* Mid gain (dB) (float value) */ + const LADSPA_Data mid = *(plugin_data->mid); + + /* Hi gain (dB) (float value) */ + const LADSPA_Data hi = *(plugin_data->hi); + + /* Input (array of floats of length sample_count) */ + const LADSPA_Data * const input = plugin_data->input; + + /* Output (array of floats of length sample_count) */ + LADSPA_Data * const output = plugin_data->output; + biquad * filters = plugin_data->filters; + float fs = plugin_data->fs; + +#line 42 "dj_eq_1901.xml" + unsigned long pos; + float samp; + + eq_set_params(&filters[0], 100.0f, lo, PEAK_BW, fs); + eq_set_params(&filters[1], 1000.0f, mid, PEAK_BW, fs); + hs_set_params(&filters[2], 10000.0f, hi, SHELF_SLOPE, fs); + + for (pos = 0; pos < sample_count; pos++) { + samp = biquad_run(&filters[0], input[pos]); + samp = biquad_run(&filters[1], samp); + samp = biquad_run(&filters[2], samp); + buffer_write(output[pos], samp); + } + + *(plugin_data->latency) = 3; //XXX is this right? +} + +static void activateDj_eq(LADSPA_Handle instance) { + Dj_eq *plugin_data = (Dj_eq *)instance; + biquad *filters = plugin_data->filters; + float fs = plugin_data->fs; +#line 33 "dj_eq_1901.xml" + int i; + + for (i=0; i<2; i++) { + biquad_init(&filters[i*BANDS + 0]); + eq_set_params(&filters[i*BANDS + 0], 100.0f, 0.0f, PEAK_BW, fs); + biquad_init(&filters[i*BANDS + 1]); + eq_set_params(&filters[i*BANDS + 1], 1000.0f, 0.0f, PEAK_BW, fs); + biquad_init(&filters[i*BANDS + 2]); + hs_set_params(&filters[i*BANDS + 2], 10000.0f, 0.0f, SHELF_SLOPE, fs); + } + plugin_data->filters = filters; + plugin_data->fs = fs; + +} + +static void cleanupDj_eq(LADSPA_Handle instance) { + free(instance); +} + +static void connectPortDj_eq( + LADSPA_Handle instance, + unsigned long port, + LADSPA_Data *data) { + Dj_eq *plugin; + + plugin = (Dj_eq *)instance; + switch (port) { + case DJ_EQ_LO: + plugin->lo = data; + break; + case DJ_EQ_MID: + plugin->mid = data; + break; + case DJ_EQ_HI: + plugin->hi = data; + break; + case DJ_EQ_LEFT_INPUT: + plugin->left_input = data; + break; + case DJ_EQ_RIGHT_INPUT: + plugin->right_input = data; + break; + case DJ_EQ_LEFT_OUTPUT: + plugin->left_output = data; + break; + case DJ_EQ_RIGHT_OUTPUT: + plugin->right_output = data; + break; + case DJ_EQ_LATENCY: + plugin->latency = data; + break; + } +} + +static LADSPA_Handle instantiateDj_eq( + const LADSPA_Descriptor *descriptor, + unsigned long s_rate) { + Dj_eq *plugin_data = (Dj_eq *)malloc(sizeof(Dj_eq)); + biquad *filters = NULL; + float fs; + +#line 27 "dj_eq_1901.xml" + fs = s_rate; + + filters = calloc(BANDS * 2, sizeof(biquad)); + + plugin_data->filters = filters; + plugin_data->fs = fs; + + return (LADSPA_Handle)plugin_data; +} + +#undef buffer_write +#undef RUN_ADDING +#undef RUN_REPLACING + +#define buffer_write(b, v) (b = v) +#define RUN_ADDING 0 +#define RUN_REPLACING 1 + +static void runDj_eq(LADSPA_Handle instance, unsigned long sample_count) { + Dj_eq *plugin_data = (Dj_eq *)instance; + + /* Lo gain (dB) (float value) */ + const LADSPA_Data lo = *(plugin_data->lo); + + /* Mid gain (dB) (float value) */ + const LADSPA_Data mid = *(plugin_data->mid); + + /* Hi gain (dB) (float value) */ + const LADSPA_Data hi = *(plugin_data->hi); + + /* Input L (array of floats of length sample_count) */ + const LADSPA_Data * const left_input = plugin_data->left_input; + + /* Input R (array of floats of length sample_count) */ + const LADSPA_Data * const right_input = plugin_data->right_input; + + /* Output L (array of floats of length sample_count) */ + LADSPA_Data * const left_output = plugin_data->left_output; + + /* Output R (array of floats of length sample_count) */ + LADSPA_Data * const right_output = plugin_data->right_output; + biquad * filters = plugin_data->filters; + float fs = plugin_data->fs; + +#line 42 "dj_eq_1901.xml" + unsigned long pos; + unsigned int i; + float samp; + + for (i=0; i<2; i++) { + eq_set_params(&filters[i*BANDS + 0], 100.0f, lo, PEAK_BW, fs); + eq_set_params(&filters[i*BANDS + 1], 1000.0f, mid, PEAK_BW, fs); + hs_set_params(&filters[i*BANDS + 2], 10000.0f, hi, SHELF_SLOPE, fs); + } + + for (pos = 0; pos < sample_count; pos++) { + samp = biquad_run(&filters[0], left_input[pos]); + samp = biquad_run(&filters[1], samp); + samp = biquad_run(&filters[2], samp); + buffer_write(left_output[pos], samp); + + samp = biquad_run(&filters[3], right_input[pos]); + samp = biquad_run(&filters[4], samp); + samp = biquad_run(&filters[5], samp); + buffer_write(right_output[pos], samp); + } + + *(plugin_data->latency) = 3; //XXX is this right? +} +#undef buffer_write +#undef RUN_ADDING +#undef RUN_REPLACING + +#define buffer_write(b, v) (b += (v) * run_adding_gain) +#define RUN_ADDING 1 +#define RUN_REPLACING 0 + +static void setRunAddingGainDj_eq(LADSPA_Handle instance, LADSPA_Data gain) { + ((Dj_eq *)instance)->run_adding_gain = gain; +} + +static void runAddingDj_eq(LADSPA_Handle instance, unsigned long sample_count) { + Dj_eq *plugin_data = (Dj_eq *)instance; + LADSPA_Data run_adding_gain = plugin_data->run_adding_gain; + + /* Lo gain (dB) (float value) */ + const LADSPA_Data lo = *(plugin_data->lo); + + /* Mid gain (dB) (float value) */ + const LADSPA_Data mid = *(plugin_data->mid); + + /* Hi gain (dB) (float value) */ + const LADSPA_Data hi = *(plugin_data->hi); + + /* Input L (array of floats of length sample_count) */ + const LADSPA_Data * const left_input = plugin_data->left_input; + + /* Input R (array of floats of length sample_count) */ + const LADSPA_Data * const right_input = plugin_data->right_input; + + /* Output L (array of floats of length sample_count) */ + LADSPA_Data * const left_output = plugin_data->left_output; + + /* Output R (array of floats of length sample_count) */ + LADSPA_Data * const right_output = plugin_data->right_output; + biquad * filters = plugin_data->filters; + float fs = plugin_data->fs; + +#line 42 "dj_eq_1901.xml" + unsigned long pos; + unsigned int i; + float samp; + + for (i=0; i<2; i++) { + eq_set_params(&filters[i*BANDS + 0], 100.0f, lo, PEAK_BW, fs); + eq_set_params(&filters[i*BANDS + 1], 1000.0f, mid, PEAK_BW, fs); + hs_set_params(&filters[i*BANDS + 2], 10000.0f, hi, SHELF_SLOPE, fs); + } + + for (pos = 0; pos < sample_count; pos++) { + samp = biquad_run(&filters[0], left_input[pos]); + samp = biquad_run(&filters[1], samp); + samp = biquad_run(&filters[2], samp); + buffer_write(left_output[pos], samp); + + samp = biquad_run(&filters[3], right_input[pos]); + samp = biquad_run(&filters[4], samp); + samp = biquad_run(&filters[5], samp); + buffer_write(right_output[pos], samp); + } + + *(plugin_data->latency) = 3; //XXX is this right? +} + +void _init() { + char **port_names; + LADSPA_PortDescriptor *port_descriptors; + LADSPA_PortRangeHint *port_range_hints; + +#ifdef ENABLE_NLS +#define D_(s) dgettext(PACKAGE, s) + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, PACKAGE_LOCALE_DIR); +#else +#define D_(s) (s) +#endif + + + dj_eq_monoDescriptor = + (LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor)); + + if (dj_eq_monoDescriptor) { + dj_eq_monoDescriptor->UniqueID = 1907; + dj_eq_monoDescriptor->Label = "dj_eq_mono"; + dj_eq_monoDescriptor->Properties = + LADSPA_PROPERTY_HARD_RT_CAPABLE; + dj_eq_monoDescriptor->Name = + D_("DJ EQ (mono)"); + dj_eq_monoDescriptor->Maker = + "Steve Harris "; + dj_eq_monoDescriptor->Copyright = + "GPL"; + dj_eq_monoDescriptor->PortCount = 6; + + port_descriptors = (LADSPA_PortDescriptor *)calloc(6, + sizeof(LADSPA_PortDescriptor)); + dj_eq_monoDescriptor->PortDescriptors = + (const LADSPA_PortDescriptor *)port_descriptors; + + port_range_hints = (LADSPA_PortRangeHint *)calloc(6, + sizeof(LADSPA_PortRangeHint)); + dj_eq_monoDescriptor->PortRangeHints = + (const LADSPA_PortRangeHint *)port_range_hints; + + port_names = (char **)calloc(6, sizeof(char*)); + dj_eq_monoDescriptor->PortNames = + (const char **)port_names; + + /* Parameters for Lo gain (dB) */ + port_descriptors[DJ_EQ_MONO_LO] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[DJ_EQ_MONO_LO] = + D_("Lo gain (dB)"); + port_range_hints[DJ_EQ_MONO_LO].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0; + port_range_hints[DJ_EQ_MONO_LO].LowerBound = -70; + port_range_hints[DJ_EQ_MONO_LO].UpperBound = +6; + + /* Parameters for Mid gain (dB) */ + port_descriptors[DJ_EQ_MONO_MID] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[DJ_EQ_MONO_MID] = + D_("Mid gain (dB)"); + port_range_hints[DJ_EQ_MONO_MID].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0; + port_range_hints[DJ_EQ_MONO_MID].LowerBound = -70; + port_range_hints[DJ_EQ_MONO_MID].UpperBound = +6; + + /* Parameters for Hi gain (dB) */ + port_descriptors[DJ_EQ_MONO_HI] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[DJ_EQ_MONO_HI] = + D_("Hi gain (dB)"); + port_range_hints[DJ_EQ_MONO_HI].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0; + port_range_hints[DJ_EQ_MONO_HI].LowerBound = -70; + port_range_hints[DJ_EQ_MONO_HI].UpperBound = +6; + + /* Parameters for Input */ + port_descriptors[DJ_EQ_MONO_INPUT] = + LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO; + port_names[DJ_EQ_MONO_INPUT] = + D_("Input"); + port_range_hints[DJ_EQ_MONO_INPUT].HintDescriptor = 0; + + /* Parameters for Output */ + port_descriptors[DJ_EQ_MONO_OUTPUT] = + LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO; + port_names[DJ_EQ_MONO_OUTPUT] = + D_("Output"); + port_range_hints[DJ_EQ_MONO_OUTPUT].HintDescriptor = 0; + + /* Parameters for latency */ + port_descriptors[DJ_EQ_MONO_LATENCY] = + LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL; + port_names[DJ_EQ_MONO_LATENCY] = + D_("latency"); + port_range_hints[DJ_EQ_MONO_LATENCY].HintDescriptor = 0; + + dj_eq_monoDescriptor->activate = activateDj_eq_mono; + dj_eq_monoDescriptor->cleanup = cleanupDj_eq_mono; + dj_eq_monoDescriptor->connect_port = connectPortDj_eq_mono; + dj_eq_monoDescriptor->deactivate = NULL; + dj_eq_monoDescriptor->instantiate = instantiateDj_eq_mono; + dj_eq_monoDescriptor->run = runDj_eq_mono; + dj_eq_monoDescriptor->run_adding = runAddingDj_eq_mono; + dj_eq_monoDescriptor->set_run_adding_gain = setRunAddingGainDj_eq_mono; + } + + dj_eqDescriptor = + (LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor)); + + if (dj_eqDescriptor) { + dj_eqDescriptor->UniqueID = 1901; + dj_eqDescriptor->Label = "dj_eq"; + dj_eqDescriptor->Properties = + LADSPA_PROPERTY_HARD_RT_CAPABLE; + dj_eqDescriptor->Name = + D_("DJ EQ"); + dj_eqDescriptor->Maker = + "Steve Harris "; + dj_eqDescriptor->Copyright = + "GPL"; + dj_eqDescriptor->PortCount = 8; + + port_descriptors = (LADSPA_PortDescriptor *)calloc(8, + sizeof(LADSPA_PortDescriptor)); + dj_eqDescriptor->PortDescriptors = + (const LADSPA_PortDescriptor *)port_descriptors; + + port_range_hints = (LADSPA_PortRangeHint *)calloc(8, + sizeof(LADSPA_PortRangeHint)); + dj_eqDescriptor->PortRangeHints = + (const LADSPA_PortRangeHint *)port_range_hints; + + port_names = (char **)calloc(8, sizeof(char*)); + dj_eqDescriptor->PortNames = + (const char **)port_names; + + /* Parameters for Lo gain (dB) */ + port_descriptors[DJ_EQ_LO] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[DJ_EQ_LO] = + D_("Lo gain (dB)"); + port_range_hints[DJ_EQ_LO].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0; + port_range_hints[DJ_EQ_LO].LowerBound = -70; + port_range_hints[DJ_EQ_LO].UpperBound = +6; + + /* Parameters for Mid gain (dB) */ + port_descriptors[DJ_EQ_MID] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[DJ_EQ_MID] = + D_("Mid gain (dB)"); + port_range_hints[DJ_EQ_MID].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0; + port_range_hints[DJ_EQ_MID].LowerBound = -70; + port_range_hints[DJ_EQ_MID].UpperBound = +6; + + /* Parameters for Hi gain (dB) */ + port_descriptors[DJ_EQ_HI] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[DJ_EQ_HI] = + D_("Hi gain (dB)"); + port_range_hints[DJ_EQ_HI].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0; + port_range_hints[DJ_EQ_HI].LowerBound = -70; + port_range_hints[DJ_EQ_HI].UpperBound = +6; + + /* Parameters for Input L */ + port_descriptors[DJ_EQ_LEFT_INPUT] = + LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO; + port_names[DJ_EQ_LEFT_INPUT] = + D_("Input L"); + port_range_hints[DJ_EQ_LEFT_INPUT].HintDescriptor = 0; + + /* Parameters for Input R */ + port_descriptors[DJ_EQ_RIGHT_INPUT] = + LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO; + port_names[DJ_EQ_RIGHT_INPUT] = + D_("Input R"); + port_range_hints[DJ_EQ_RIGHT_INPUT].HintDescriptor = 0; + + /* Parameters for Output L */ + port_descriptors[DJ_EQ_LEFT_OUTPUT] = + LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO; + port_names[DJ_EQ_LEFT_OUTPUT] = + D_("Output L"); + port_range_hints[DJ_EQ_LEFT_OUTPUT].HintDescriptor = 0; + + /* Parameters for Output R */ + port_descriptors[DJ_EQ_RIGHT_OUTPUT] = + LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO; + port_names[DJ_EQ_RIGHT_OUTPUT] = + D_("Output R"); + port_range_hints[DJ_EQ_RIGHT_OUTPUT].HintDescriptor = 0; + + /* Parameters for latency */ + port_descriptors[DJ_EQ_LATENCY] = + LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL; + port_names[DJ_EQ_LATENCY] = + D_("latency"); + port_range_hints[DJ_EQ_LATENCY].HintDescriptor = 0; + + dj_eqDescriptor->activate = activateDj_eq; + dj_eqDescriptor->cleanup = cleanupDj_eq; + dj_eqDescriptor->connect_port = connectPortDj_eq; + dj_eqDescriptor->deactivate = NULL; + dj_eqDescriptor->instantiate = instantiateDj_eq; + dj_eqDescriptor->run = runDj_eq; + dj_eqDescriptor->run_adding = runAddingDj_eq; + dj_eqDescriptor->set_run_adding_gain = setRunAddingGainDj_eq; + } +} + +void _fini() { + if (dj_eq_monoDescriptor) { + free((LADSPA_PortDescriptor *)dj_eq_monoDescriptor->PortDescriptors); + free((char **)dj_eq_monoDescriptor->PortNames); + free((LADSPA_PortRangeHint *)dj_eq_monoDescriptor->PortRangeHints); + free(dj_eq_monoDescriptor); + } + if (dj_eqDescriptor) { + free((LADSPA_PortDescriptor *)dj_eqDescriptor->PortDescriptors); + free((char **)dj_eqDescriptor->PortNames); + free((LADSPA_PortRangeHint *)dj_eqDescriptor->PortRangeHints); + free(dj_eqDescriptor); + } + +} diff --git a/plugins/ladspa_effect/swh/fast_lookahead_limiter_1913.c b/plugins/ladspa_effect/swh/fast_lookahead_limiter_1913.c new file mode 100644 index 000000000..33007e1b9 --- /dev/null +++ b/plugins/ladspa_effect/swh/fast_lookahead_limiter_1913.c @@ -0,0 +1,714 @@ +#include +#include +#ifndef WIN32 +#include "config.h" +#endif + +#ifdef ENABLE_NLS +#include +#endif + +#define _ISOC9X_SOURCE 1 +#define _ISOC99_SOURCE 1 +#define __USE_ISOC99 1 +#define __USE_ISOC9X 1 + +#include + +#include "ladspa.h" + +#ifdef WIN32 +#define _WINDOWS_DLL_EXPORT_ __declspec(dllexport) +int bIsFirstTime = 1; +void _init(); // forward declaration +#else +#define _WINDOWS_DLL_EXPORT_ +#endif + +#line 10 "fast_lookahead_limiter_1913.xml" + +#include "ladspa-util.h" + +//#define DEBUG + +#define NUM_CHUNKS 16 +#define BUFFER_TIME 0.0053 + +#ifdef DEBUG + #include "stdio.h" +#endif + +#define FASTLOOKAHEADLIMITER_INGAIN 0 +#define FASTLOOKAHEADLIMITER_LIMIT 1 +#define FASTLOOKAHEADLIMITER_RELEASE 2 +#define FASTLOOKAHEADLIMITER_ATTENUATION 3 +#define FASTLOOKAHEADLIMITER_IN_1 4 +#define FASTLOOKAHEADLIMITER_IN_2 5 +#define FASTLOOKAHEADLIMITER_OUT_1 6 +#define FASTLOOKAHEADLIMITER_OUT_2 7 +#define FASTLOOKAHEADLIMITER_LATENCY 8 + +static LADSPA_Descriptor *fastLookaheadLimiterDescriptor = NULL; + +typedef struct { + LADSPA_Data *ingain; + LADSPA_Data *limit; + LADSPA_Data *release; + LADSPA_Data *attenuation; + LADSPA_Data *in_1; + LADSPA_Data *in_2; + LADSPA_Data *out_1; + LADSPA_Data *out_2; + LADSPA_Data *latency; + float atten; + float atten_lp; + LADSPA_Data *buffer; + unsigned int buffer_len; + unsigned int buffer_pos; + unsigned int chunk_num; + unsigned int chunk_pos; + unsigned int chunk_size; + float * chunks; + unsigned int delay; + float delta; + unsigned int fs; + float peak; + LADSPA_Data run_adding_gain; +} FastLookaheadLimiter; + +_WINDOWS_DLL_EXPORT_ +const LADSPA_Descriptor *ladspa_descriptor(unsigned long index) { + +#ifdef WIN32 + if (bIsFirstTime) { + _init(); + bIsFirstTime = 0; + } +#endif + switch (index) { + case 0: + return fastLookaheadLimiterDescriptor; + default: + return NULL; + } +} + +static void activateFastLookaheadLimiter(LADSPA_Handle instance) { + FastLookaheadLimiter *plugin_data = (FastLookaheadLimiter *)instance; + float atten = plugin_data->atten; + float atten_lp = plugin_data->atten_lp; + LADSPA_Data *buffer = plugin_data->buffer; + unsigned int buffer_len = plugin_data->buffer_len; + unsigned int buffer_pos = plugin_data->buffer_pos; + unsigned int chunk_num = plugin_data->chunk_num; + unsigned int chunk_pos = plugin_data->chunk_pos; + unsigned int chunk_size = plugin_data->chunk_size; + float *chunks = plugin_data->chunks; + unsigned int delay = plugin_data->delay; + float delta = plugin_data->delta; + unsigned int fs = plugin_data->fs; + float peak = plugin_data->peak; +#line 56 "fast_lookahead_limiter_1913.xml" + memset(buffer, 0, NUM_CHUNKS * sizeof(float)); + + chunk_pos = 0; + chunk_num = 0; + peak = 0.0f; + atten = 1.0f; + atten_lp = 1.0f; + delta = 0.0f; + plugin_data->atten = atten; + plugin_data->atten_lp = atten_lp; + plugin_data->buffer = buffer; + plugin_data->buffer_len = buffer_len; + plugin_data->buffer_pos = buffer_pos; + plugin_data->chunk_num = chunk_num; + plugin_data->chunk_pos = chunk_pos; + plugin_data->chunk_size = chunk_size; + plugin_data->chunks = chunks; + plugin_data->delay = delay; + plugin_data->delta = delta; + plugin_data->fs = fs; + plugin_data->peak = peak; + +} + +static void cleanupFastLookaheadLimiter(LADSPA_Handle instance) { +#line 188 "fast_lookahead_limiter_1913.xml" + FastLookaheadLimiter *plugin_data = (FastLookaheadLimiter *)instance; + free(plugin_data->buffer); + free(instance); +} + +static void connectPortFastLookaheadLimiter( + LADSPA_Handle instance, + unsigned long port, + LADSPA_Data *data) { + FastLookaheadLimiter *plugin; + + plugin = (FastLookaheadLimiter *)instance; + switch (port) { + case FASTLOOKAHEADLIMITER_INGAIN: + plugin->ingain = data; + break; + case FASTLOOKAHEADLIMITER_LIMIT: + plugin->limit = data; + break; + case FASTLOOKAHEADLIMITER_RELEASE: + plugin->release = data; + break; + case FASTLOOKAHEADLIMITER_ATTENUATION: + plugin->attenuation = data; + break; + case FASTLOOKAHEADLIMITER_IN_1: + plugin->in_1 = data; + break; + case FASTLOOKAHEADLIMITER_IN_2: + plugin->in_2 = data; + break; + case FASTLOOKAHEADLIMITER_OUT_1: + plugin->out_1 = data; + break; + case FASTLOOKAHEADLIMITER_OUT_2: + plugin->out_2 = data; + break; + case FASTLOOKAHEADLIMITER_LATENCY: + plugin->latency = data; + break; + } +} + +static LADSPA_Handle instantiateFastLookaheadLimiter( + const LADSPA_Descriptor *descriptor, + unsigned long s_rate) { + FastLookaheadLimiter *plugin_data = (FastLookaheadLimiter *)malloc(sizeof(FastLookaheadLimiter)); + float atten; + float atten_lp; + LADSPA_Data *buffer = NULL; + unsigned int buffer_len; + unsigned int buffer_pos; + unsigned int chunk_num; + unsigned int chunk_pos; + unsigned int chunk_size; + float *chunks = NULL; + unsigned int delay; + float delta; + unsigned int fs; + float peak; + +#line 31 "fast_lookahead_limiter_1913.xml" + fs = s_rate; + buffer_len = 128; + buffer_pos = 0; + + /* Find size for power-of-two interleaved delay buffer */ + while(buffer_len < fs * BUFFER_TIME * 2) { + buffer_len *= 2; + } + buffer = calloc(buffer_len, sizeof(float)); + delay = (int)(0.005 * fs); + + chunk_pos = 0; + chunk_num = 0; + + /* find a chunk size (in smaples) thats roughly 0.5ms */ + chunk_size = s_rate / 2000; + chunks = calloc(NUM_CHUNKS, sizeof(float)); + + peak = 0.0f; + atten = 1.0f; + atten_lp = 1.0f; + delta = 0.0f; + + plugin_data->atten = atten; + plugin_data->atten_lp = atten_lp; + plugin_data->buffer = buffer; + plugin_data->buffer_len = buffer_len; + plugin_data->buffer_pos = buffer_pos; + plugin_data->chunk_num = chunk_num; + plugin_data->chunk_pos = chunk_pos; + plugin_data->chunk_size = chunk_size; + plugin_data->chunks = chunks; + plugin_data->delay = delay; + plugin_data->delta = delta; + plugin_data->fs = fs; + plugin_data->peak = peak; + + return (LADSPA_Handle)plugin_data; +} + +#undef buffer_write +#undef RUN_ADDING +#undef RUN_REPLACING + +#define buffer_write(b, v) (b = v) +#define RUN_ADDING 0 +#define RUN_REPLACING 1 + +static void runFastLookaheadLimiter(LADSPA_Handle instance, unsigned long sample_count) { + FastLookaheadLimiter *plugin_data = (FastLookaheadLimiter *)instance; + + /* Input gain (dB) (float value) */ + const LADSPA_Data ingain = *(plugin_data->ingain); + + /* Limit (dB) (float value) */ + const LADSPA_Data limit = *(plugin_data->limit); + + /* Release time (s) (float value) */ + const LADSPA_Data release = *(plugin_data->release); + + /* Input 1 (array of floats of length sample_count) */ + const LADSPA_Data * const in_1 = plugin_data->in_1; + + /* Input 2 (array of floats of length sample_count) */ + const LADSPA_Data * const in_2 = plugin_data->in_2; + + /* Output 1 (array of floats of length sample_count) */ + LADSPA_Data * const out_1 = plugin_data->out_1; + + /* Output 2 (array of floats of length sample_count) */ + LADSPA_Data * const out_2 = plugin_data->out_2; + float atten = plugin_data->atten; + float atten_lp = plugin_data->atten_lp; + LADSPA_Data * buffer = plugin_data->buffer; + unsigned int buffer_len = plugin_data->buffer_len; + unsigned int buffer_pos = plugin_data->buffer_pos; + unsigned int chunk_num = plugin_data->chunk_num; + unsigned int chunk_pos = plugin_data->chunk_pos; + unsigned int chunk_size = plugin_data->chunk_size; + float * chunks = plugin_data->chunks; + unsigned int delay = plugin_data->delay; + float delta = plugin_data->delta; + unsigned int fs = plugin_data->fs; + float peak = plugin_data->peak; + +#line 67 "fast_lookahead_limiter_1913.xml" + unsigned long pos; + const float max = DB_CO(limit); + const float trim = DB_CO(ingain); + float sig; + unsigned int i; + + #ifdef DEBUG + float clip = 0.0, clipp = 0.0; + int clipc = 0; + #endif + + for (pos = 0; pos < sample_count; pos++) { + if (chunk_pos++ == chunk_size) { + /* we've got a full chunk */ + + delta = (1.0f - atten) / (fs * release); + round_to_zero(&delta); + for (i=0; i<10; i++) { + const int p = (chunk_num - 9 + i) & (NUM_CHUNKS - 1); + const float this_delta = (max / chunks[p] - atten) / + ((float)(i+1) * fs * 0.0005f + 1.0f); + + if (this_delta < delta) { + delta = this_delta; + } + } + + chunks[chunk_num++ & (NUM_CHUNKS - 1)] = peak; + peak = 0.0f; + chunk_pos = 0; + } + + buffer[(buffer_pos * 2) & (buffer_len - 1)] = in_1[pos] * trim + + 1.0e-30; + buffer[(buffer_pos * 2 + 1) & (buffer_len - 1)] = in_2[pos] * trim + + 1.0e-30; + + sig = fabs(in_1[pos]) > fabs(in_2[pos]) ? fabs(in_1[pos]) : + fabs(in_2[pos]); + sig += 1.0e-30; + if (sig * trim > peak) { + peak = sig * trim; + } + //round_to_zero(&peak); + //round_to_zero(&sig); + + atten += delta; + atten_lp = atten * 0.1f + atten_lp * 0.9f; + //round_to_zero(&atten_lp); + if (delta > 0.0f && atten > 1.0f) { + atten = 1.0f; + delta = 0.0f; + } + + buffer_write(out_1[pos], buffer[(buffer_pos * 2 - delay * 2) & + (buffer_len - 1)] * atten_lp); + buffer_write(out_2[pos], buffer[(buffer_pos * 2 - delay * 2 + 1) & + (buffer_len - 1)] * atten_lp); + round_to_zero(&out_1[pos]); + round_to_zero(&out_2[pos]); + + if (out_1[pos] < -max) { + #ifdef DEBUG + clip += 20.0*log10(out_1[pos] / -max); + clipc++; + if (fabs(out_1[pos] - max) > clipp) { + clipp = fabs(out_1[pos] / -max); + } + #endif + buffer_write(out_1[pos], -max); + } else if (out_1[pos] > max) { + #ifdef DEBUG + clip += 20.0*log10(out_1[pos] / max); + clipc++; + if (fabs(out_1[pos] - max) > clipp) { + clipp = fabs(out_1[pos] / max); + } + #endif + buffer_write(out_1[pos], max); + } + if (out_2[pos] < -max) { + #ifdef DEBUG + clip += 20.0*log10(out_2[pos] / -max); + clipc++; + if (fabs(out_2[pos] - max) > clipp) { + clipp = fabs(out_2[pos] / -max); + } + #endif + buffer_write(out_2[pos], -max); + } else if (out_2[pos] > max) { + #ifdef DEBUG + clip += 20.0*log10(out_2[pos] / max); + clipc++; + if (fabs(out_2[pos] - max) > clipp) { + clipp = fabs(out_2[pos] / max); + } + #endif + buffer_write(out_2[pos], max); + } + + buffer_pos++; + } + + #ifdef DEBUG + if (clipc > 0) { + printf("%d overs: %fdB avg, %fdB peak\n", clipc, clip/(float)clipc, 20.0*log10(clipp)); + } + #endif + + plugin_data->buffer_pos = buffer_pos; + plugin_data->peak = peak; + plugin_data->atten = atten; + plugin_data->atten_lp = atten_lp; + plugin_data->chunk_pos = chunk_pos; + plugin_data->chunk_num = chunk_num; + + *(plugin_data->attenuation) = -CO_DB(atten); + *(plugin_data->latency) = delay; +} +#undef buffer_write +#undef RUN_ADDING +#undef RUN_REPLACING + +#define buffer_write(b, v) (b += (v) * run_adding_gain) +#define RUN_ADDING 1 +#define RUN_REPLACING 0 + +static void setRunAddingGainFastLookaheadLimiter(LADSPA_Handle instance, LADSPA_Data gain) { + ((FastLookaheadLimiter *)instance)->run_adding_gain = gain; +} + +static void runAddingFastLookaheadLimiter(LADSPA_Handle instance, unsigned long sample_count) { + FastLookaheadLimiter *plugin_data = (FastLookaheadLimiter *)instance; + LADSPA_Data run_adding_gain = plugin_data->run_adding_gain; + + /* Input gain (dB) (float value) */ + const LADSPA_Data ingain = *(plugin_data->ingain); + + /* Limit (dB) (float value) */ + const LADSPA_Data limit = *(plugin_data->limit); + + /* Release time (s) (float value) */ + const LADSPA_Data release = *(plugin_data->release); + + /* Input 1 (array of floats of length sample_count) */ + const LADSPA_Data * const in_1 = plugin_data->in_1; + + /* Input 2 (array of floats of length sample_count) */ + const LADSPA_Data * const in_2 = plugin_data->in_2; + + /* Output 1 (array of floats of length sample_count) */ + LADSPA_Data * const out_1 = plugin_data->out_1; + + /* Output 2 (array of floats of length sample_count) */ + LADSPA_Data * const out_2 = plugin_data->out_2; + float atten = plugin_data->atten; + float atten_lp = plugin_data->atten_lp; + LADSPA_Data * buffer = plugin_data->buffer; + unsigned int buffer_len = plugin_data->buffer_len; + unsigned int buffer_pos = plugin_data->buffer_pos; + unsigned int chunk_num = plugin_data->chunk_num; + unsigned int chunk_pos = plugin_data->chunk_pos; + unsigned int chunk_size = plugin_data->chunk_size; + float * chunks = plugin_data->chunks; + unsigned int delay = plugin_data->delay; + float delta = plugin_data->delta; + unsigned int fs = plugin_data->fs; + float peak = plugin_data->peak; + +#line 67 "fast_lookahead_limiter_1913.xml" + unsigned long pos; + const float max = DB_CO(limit); + const float trim = DB_CO(ingain); + float sig; + unsigned int i; + + #ifdef DEBUG + float clip = 0.0, clipp = 0.0; + int clipc = 0; + #endif + + for (pos = 0; pos < sample_count; pos++) { + if (chunk_pos++ == chunk_size) { + /* we've got a full chunk */ + + delta = (1.0f - atten) / (fs * release); + round_to_zero(&delta); + for (i=0; i<10; i++) { + const int p = (chunk_num - 9 + i) & (NUM_CHUNKS - 1); + const float this_delta = (max / chunks[p] - atten) / + ((float)(i+1) * fs * 0.0005f + 1.0f); + + if (this_delta < delta) { + delta = this_delta; + } + } + + chunks[chunk_num++ & (NUM_CHUNKS - 1)] = peak; + peak = 0.0f; + chunk_pos = 0; + } + + buffer[(buffer_pos * 2) & (buffer_len - 1)] = in_1[pos] * trim + + 1.0e-30; + buffer[(buffer_pos * 2 + 1) & (buffer_len - 1)] = in_2[pos] * trim + + 1.0e-30; + + sig = fabs(in_1[pos]) > fabs(in_2[pos]) ? fabs(in_1[pos]) : + fabs(in_2[pos]); + sig += 1.0e-30; + if (sig * trim > peak) { + peak = sig * trim; + } + //round_to_zero(&peak); + //round_to_zero(&sig); + + atten += delta; + atten_lp = atten * 0.1f + atten_lp * 0.9f; + //round_to_zero(&atten_lp); + if (delta > 0.0f && atten > 1.0f) { + atten = 1.0f; + delta = 0.0f; + } + + buffer_write(out_1[pos], buffer[(buffer_pos * 2 - delay * 2) & + (buffer_len - 1)] * atten_lp); + buffer_write(out_2[pos], buffer[(buffer_pos * 2 - delay * 2 + 1) & + (buffer_len - 1)] * atten_lp); + round_to_zero(&out_1[pos]); + round_to_zero(&out_2[pos]); + + if (out_1[pos] < -max) { + #ifdef DEBUG + clip += 20.0*log10(out_1[pos] / -max); + clipc++; + if (fabs(out_1[pos] - max) > clipp) { + clipp = fabs(out_1[pos] / -max); + } + #endif + buffer_write(out_1[pos], -max); + } else if (out_1[pos] > max) { + #ifdef DEBUG + clip += 20.0*log10(out_1[pos] / max); + clipc++; + if (fabs(out_1[pos] - max) > clipp) { + clipp = fabs(out_1[pos] / max); + } + #endif + buffer_write(out_1[pos], max); + } + if (out_2[pos] < -max) { + #ifdef DEBUG + clip += 20.0*log10(out_2[pos] / -max); + clipc++; + if (fabs(out_2[pos] - max) > clipp) { + clipp = fabs(out_2[pos] / -max); + } + #endif + buffer_write(out_2[pos], -max); + } else if (out_2[pos] > max) { + #ifdef DEBUG + clip += 20.0*log10(out_2[pos] / max); + clipc++; + if (fabs(out_2[pos] - max) > clipp) { + clipp = fabs(out_2[pos] / max); + } + #endif + buffer_write(out_2[pos], max); + } + + buffer_pos++; + } + + #ifdef DEBUG + if (clipc > 0) { + printf("%d overs: %fdB avg, %fdB peak\n", clipc, clip/(float)clipc, 20.0*log10(clipp)); + } + #endif + + plugin_data->buffer_pos = buffer_pos; + plugin_data->peak = peak; + plugin_data->atten = atten; + plugin_data->atten_lp = atten_lp; + plugin_data->chunk_pos = chunk_pos; + plugin_data->chunk_num = chunk_num; + + *(plugin_data->attenuation) = -CO_DB(atten); + *(plugin_data->latency) = delay; +} + +void _init() { + char **port_names; + LADSPA_PortDescriptor *port_descriptors; + LADSPA_PortRangeHint *port_range_hints; + +#ifdef ENABLE_NLS +#define D_(s) dgettext(PACKAGE, s) + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, PACKAGE_LOCALE_DIR); +#else +#define D_(s) (s) +#endif + + + fastLookaheadLimiterDescriptor = + (LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor)); + + if (fastLookaheadLimiterDescriptor) { + fastLookaheadLimiterDescriptor->UniqueID = 1913; + fastLookaheadLimiterDescriptor->Label = "fastLookaheadLimiter"; + fastLookaheadLimiterDescriptor->Properties = + LADSPA_PROPERTY_HARD_RT_CAPABLE; + fastLookaheadLimiterDescriptor->Name = + D_("Fast Lookahead limiter"); + fastLookaheadLimiterDescriptor->Maker = + "Steve Harris "; + fastLookaheadLimiterDescriptor->Copyright = + "GPL"; + fastLookaheadLimiterDescriptor->PortCount = 9; + + port_descriptors = (LADSPA_PortDescriptor *)calloc(9, + sizeof(LADSPA_PortDescriptor)); + fastLookaheadLimiterDescriptor->PortDescriptors = + (const LADSPA_PortDescriptor *)port_descriptors; + + port_range_hints = (LADSPA_PortRangeHint *)calloc(9, + sizeof(LADSPA_PortRangeHint)); + fastLookaheadLimiterDescriptor->PortRangeHints = + (const LADSPA_PortRangeHint *)port_range_hints; + + port_names = (char **)calloc(9, sizeof(char*)); + fastLookaheadLimiterDescriptor->PortNames = + (const char **)port_names; + + /* Parameters for Input gain (dB) */ + port_descriptors[FASTLOOKAHEADLIMITER_INGAIN] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[FASTLOOKAHEADLIMITER_INGAIN] = + D_("Input gain (dB)"); + port_range_hints[FASTLOOKAHEADLIMITER_INGAIN].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0; + port_range_hints[FASTLOOKAHEADLIMITER_INGAIN].LowerBound = -20; + port_range_hints[FASTLOOKAHEADLIMITER_INGAIN].UpperBound = 20; + + /* Parameters for Limit (dB) */ + port_descriptors[FASTLOOKAHEADLIMITER_LIMIT] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[FASTLOOKAHEADLIMITER_LIMIT] = + D_("Limit (dB)"); + port_range_hints[FASTLOOKAHEADLIMITER_LIMIT].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0; + port_range_hints[FASTLOOKAHEADLIMITER_LIMIT].LowerBound = -20; + port_range_hints[FASTLOOKAHEADLIMITER_LIMIT].UpperBound = 0; + + /* Parameters for Release time (s) */ + port_descriptors[FASTLOOKAHEADLIMITER_RELEASE] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[FASTLOOKAHEADLIMITER_RELEASE] = + D_("Release time (s)"); + port_range_hints[FASTLOOKAHEADLIMITER_RELEASE].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_LOW; + port_range_hints[FASTLOOKAHEADLIMITER_RELEASE].LowerBound = 0.01; + port_range_hints[FASTLOOKAHEADLIMITER_RELEASE].UpperBound = 2.0; + + /* Parameters for Attenuation (dB) */ + port_descriptors[FASTLOOKAHEADLIMITER_ATTENUATION] = + LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL; + port_names[FASTLOOKAHEADLIMITER_ATTENUATION] = + D_("Attenuation (dB)"); + port_range_hints[FASTLOOKAHEADLIMITER_ATTENUATION].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE; + port_range_hints[FASTLOOKAHEADLIMITER_ATTENUATION].LowerBound = 0; + port_range_hints[FASTLOOKAHEADLIMITER_ATTENUATION].UpperBound = 70; + + /* Parameters for Input 1 */ + port_descriptors[FASTLOOKAHEADLIMITER_IN_1] = + LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO; + port_names[FASTLOOKAHEADLIMITER_IN_1] = + D_("Input 1"); + port_range_hints[FASTLOOKAHEADLIMITER_IN_1].HintDescriptor = 0; + + /* Parameters for Input 2 */ + port_descriptors[FASTLOOKAHEADLIMITER_IN_2] = + LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO; + port_names[FASTLOOKAHEADLIMITER_IN_2] = + D_("Input 2"); + port_range_hints[FASTLOOKAHEADLIMITER_IN_2].HintDescriptor = 0; + + /* Parameters for Output 1 */ + port_descriptors[FASTLOOKAHEADLIMITER_OUT_1] = + LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO; + port_names[FASTLOOKAHEADLIMITER_OUT_1] = + D_("Output 1"); + port_range_hints[FASTLOOKAHEADLIMITER_OUT_1].HintDescriptor = 0; + + /* Parameters for Output 2 */ + port_descriptors[FASTLOOKAHEADLIMITER_OUT_2] = + LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO; + port_names[FASTLOOKAHEADLIMITER_OUT_2] = + D_("Output 2"); + port_range_hints[FASTLOOKAHEADLIMITER_OUT_2].HintDescriptor = 0; + + /* Parameters for latency */ + port_descriptors[FASTLOOKAHEADLIMITER_LATENCY] = + LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL; + port_names[FASTLOOKAHEADLIMITER_LATENCY] = + D_("latency"); + port_range_hints[FASTLOOKAHEADLIMITER_LATENCY].HintDescriptor = 0; + + fastLookaheadLimiterDescriptor->activate = activateFastLookaheadLimiter; + fastLookaheadLimiterDescriptor->cleanup = cleanupFastLookaheadLimiter; + fastLookaheadLimiterDescriptor->connect_port = connectPortFastLookaheadLimiter; + fastLookaheadLimiterDescriptor->deactivate = NULL; + fastLookaheadLimiterDescriptor->instantiate = instantiateFastLookaheadLimiter; + fastLookaheadLimiterDescriptor->run = runFastLookaheadLimiter; + fastLookaheadLimiterDescriptor->run_adding = runAddingFastLookaheadLimiter; + fastLookaheadLimiterDescriptor->set_run_adding_gain = setRunAddingGainFastLookaheadLimiter; + } +} + +void _fini() { + if (fastLookaheadLimiterDescriptor) { + free((LADSPA_PortDescriptor *)fastLookaheadLimiterDescriptor->PortDescriptors); + free((char **)fastLookaheadLimiterDescriptor->PortNames); + free((LADSPA_PortRangeHint *)fastLookaheadLimiterDescriptor->PortRangeHints); + free(fastLookaheadLimiterDescriptor); + } + +} diff --git a/plugins/ladspa_effect/swh/flanger_1191.c b/plugins/ladspa_effect/swh/flanger_1191.c new file mode 100644 index 000000000..cb91cadba --- /dev/null +++ b/plugins/ladspa_effect/swh/flanger_1191.c @@ -0,0 +1,555 @@ +#include +#include +#ifndef WIN32 +#include "config.h" +#endif + +#ifdef ENABLE_NLS +#include +#endif + +#define _ISOC9X_SOURCE 1 +#define _ISOC99_SOURCE 1 +#define __USE_ISOC99 1 +#define __USE_ISOC9X 1 + +#include + +#include "ladspa.h" + +#ifdef WIN32 +#define _WINDOWS_DLL_EXPORT_ __declspec(dllexport) +int bIsFirstTime = 1; +void _init(); // forward declaration +#else +#define _WINDOWS_DLL_EXPORT_ +#endif + +#line 10 "flanger_1191.xml" + +#include "ladspa-util.h" + +#define FLANGER_DELAY_BASE 0 +#define FLANGER_DETUNE 1 +#define FLANGER_LAW_FREQ 2 +#define FLANGER_FEEDBACK 3 +#define FLANGER_INPUT 4 +#define FLANGER_OUTPUT 5 + +static LADSPA_Descriptor *flangerDescriptor = NULL; + +typedef struct { + LADSPA_Data *delay_base; + LADSPA_Data *detune; + LADSPA_Data *law_freq; + LADSPA_Data *feedback; + LADSPA_Data *input; + LADSPA_Data *output; + long count; + long delay_pos; + long delay_size; + LADSPA_Data *delay_tbl; + float next_law_peak; + int next_law_pos; + long old_d_base; + float prev_law_peak; + int prev_law_pos; + long sample_rate; + LADSPA_Data run_adding_gain; +} Flanger; + +_WINDOWS_DLL_EXPORT_ +const LADSPA_Descriptor *ladspa_descriptor(unsigned long index) { + +#ifdef WIN32 + if (bIsFirstTime) { + _init(); + bIsFirstTime = 0; + } +#endif + switch (index) { + case 0: + return flangerDescriptor; + default: + return NULL; + } +} + +static void activateFlanger(LADSPA_Handle instance) { + Flanger *plugin_data = (Flanger *)instance; + long count = plugin_data->count; + long delay_pos = plugin_data->delay_pos; + long delay_size = plugin_data->delay_size; + LADSPA_Data *delay_tbl = plugin_data->delay_tbl; + float next_law_peak = plugin_data->next_law_peak; + int next_law_pos = plugin_data->next_law_pos; + long old_d_base = plugin_data->old_d_base; + float prev_law_peak = plugin_data->prev_law_peak; + int prev_law_pos = plugin_data->prev_law_pos; + long sample_rate = plugin_data->sample_rate; +#line 39 "flanger_1191.xml" + memset(delay_tbl, 0, sizeof(LADSPA_Data) * delay_size); + delay_pos = 0; + count = 0; + old_d_base = 0; + plugin_data->count = count; + plugin_data->delay_pos = delay_pos; + plugin_data->delay_size = delay_size; + plugin_data->delay_tbl = delay_tbl; + plugin_data->next_law_peak = next_law_peak; + plugin_data->next_law_pos = next_law_pos; + plugin_data->old_d_base = old_d_base; + plugin_data->prev_law_peak = prev_law_peak; + plugin_data->prev_law_pos = prev_law_pos; + plugin_data->sample_rate = sample_rate; + +} + +static void cleanupFlanger(LADSPA_Handle instance) { +#line 46 "flanger_1191.xml" + Flanger *plugin_data = (Flanger *)instance; + free(plugin_data->delay_tbl); + free(instance); +} + +static void connectPortFlanger( + LADSPA_Handle instance, + unsigned long port, + LADSPA_Data *data) { + Flanger *plugin; + + plugin = (Flanger *)instance; + switch (port) { + case FLANGER_DELAY_BASE: + plugin->delay_base = data; + break; + case FLANGER_DETUNE: + plugin->detune = data; + break; + case FLANGER_LAW_FREQ: + plugin->law_freq = data; + break; + case FLANGER_FEEDBACK: + plugin->feedback = data; + break; + case FLANGER_INPUT: + plugin->input = data; + break; + case FLANGER_OUTPUT: + plugin->output = data; + break; + } +} + +static LADSPA_Handle instantiateFlanger( + const LADSPA_Descriptor *descriptor, + unsigned long s_rate) { + Flanger *plugin_data = (Flanger *)malloc(sizeof(Flanger)); + long count; + long delay_pos; + long delay_size; + LADSPA_Data *delay_tbl = NULL; + float next_law_peak; + int next_law_pos; + long old_d_base; + float prev_law_peak; + int prev_law_pos; + long sample_rate; + +#line 21 "flanger_1191.xml" + int min_size; + + sample_rate = s_rate; + + prev_law_peak = 0.0f; + next_law_peak = 1.0f; + prev_law_pos = 0; + next_law_pos = 10; + + min_size = sample_rate * 0.04f; + for (delay_size = 1024; delay_size < min_size; delay_size *= 2); + delay_tbl = malloc(sizeof(LADSPA_Data) * delay_size); + delay_pos = 0; + count = 0; + old_d_base = 0; + + plugin_data->count = count; + plugin_data->delay_pos = delay_pos; + plugin_data->delay_size = delay_size; + plugin_data->delay_tbl = delay_tbl; + plugin_data->next_law_peak = next_law_peak; + plugin_data->next_law_pos = next_law_pos; + plugin_data->old_d_base = old_d_base; + plugin_data->prev_law_peak = prev_law_peak; + plugin_data->prev_law_pos = prev_law_pos; + plugin_data->sample_rate = sample_rate; + + return (LADSPA_Handle)plugin_data; +} + +#undef buffer_write +#undef RUN_ADDING +#undef RUN_REPLACING + +#define buffer_write(b, v) (b = v) +#define RUN_ADDING 0 +#define RUN_REPLACING 1 + +static void runFlanger(LADSPA_Handle instance, unsigned long sample_count) { + Flanger *plugin_data = (Flanger *)instance; + + /* Delay base (ms) (float value) */ + const LADSPA_Data delay_base = *(plugin_data->delay_base); + + /* Max slowdown (ms) (float value) */ + const LADSPA_Data detune = *(plugin_data->detune); + + /* LFO frequency (Hz) (float value) */ + const LADSPA_Data law_freq = *(plugin_data->law_freq); + + /* Feedback (float value) */ + const LADSPA_Data feedback = *(plugin_data->feedback); + + /* Input (array of floats of length sample_count) */ + const LADSPA_Data * const input = plugin_data->input; + + /* Output (array of floats of length sample_count) */ + LADSPA_Data * const output = plugin_data->output; + long count = plugin_data->count; + long delay_pos = plugin_data->delay_pos; + long delay_size = plugin_data->delay_size; + LADSPA_Data * delay_tbl = plugin_data->delay_tbl; + float next_law_peak = plugin_data->next_law_peak; + int next_law_pos = plugin_data->next_law_pos; + long old_d_base = plugin_data->old_d_base; + float prev_law_peak = plugin_data->prev_law_peak; + int prev_law_pos = plugin_data->prev_law_pos; + long sample_rate = plugin_data->sample_rate; + +#line 50 "flanger_1191.xml" + unsigned long pos; + long d_base, new_d_base; + LADSPA_Data out; + float delay_depth; + float dp; // float delay position + float dp_frac; // fractional part + long dp_idx; // integer delay index + long law_p; // period of law + float frac = 0.0f, step; // Portion the way through the block + float law; /* law amplitude */ + float n_ph, p_ph; + const float fb = f_clamp(feedback, -0.999f, 0.999f); + + // Set law params + law_p = (float)sample_rate / law_freq; + if (law_p < 1) { + law_p = 1; + } + + // Calculate base delay size in samples + new_d_base = (LIMIT(f_round(delay_base), 0, 25) * sample_rate) / 1000; + + // Calculate delay depth in samples + delay_depth = f_clamp(detune * (float)sample_rate * 0.001f, 0.0f, delay_size - new_d_base - 1.0f); + + step = 1.0f/sample_count; + for (pos = 0; pos < sample_count; pos++) { + if (count % law_p == 0) { + // Value for amplitude of law peak + next_law_peak = (float)rand() / (float)RAND_MAX; + next_law_pos = count + law_p; + } else if (count % law_p == law_p / 2) { + // Value for amplitude of law peak + prev_law_peak = (float)rand() / (float)RAND_MAX; + prev_law_pos = count + law_p; + } + + // Calculate position in delay table + d_base = LIN_INTERP(frac, old_d_base, new_d_base); + n_ph = (float)(law_p - abs(next_law_pos - count))/(float)law_p; + p_ph = n_ph + 0.5f; + while (p_ph > 1.0f) { + p_ph -= 1.0f; + } + law = f_sin_sq(3.1415926f*p_ph)*prev_law_peak + + f_sin_sq(3.1415926f*n_ph)*next_law_peak; + + dp = (float)(delay_pos - d_base) - (delay_depth * law); + // Get the integer part + dp_idx = f_round(dp - 0.5f); + // Get the fractional part + dp_frac = dp - dp_idx; + + // Accumulate into output buffer + out = cube_interp(dp_frac, delay_tbl[(dp_idx-1) & (delay_size-1)], delay_tbl[dp_idx & (delay_size-1)], delay_tbl[(dp_idx+1) & (delay_size-1)], delay_tbl[(dp_idx+2) & (delay_size-1)]); + + // Store new delayed value + delay_tbl[delay_pos] = flush_to_zero(input[pos] + (fb * out)); + // Sometimes the delay can pick up NaN values, I'm not sure why + // and this is easier than fixing it + if (isnan(delay_tbl[delay_pos])) { + delay_tbl[delay_pos] = 0.0f; + } + + out = f_clamp(delay_tbl[delay_pos] * 0.707f, -1.0, 1.0); + buffer_write(output[pos], out); + + frac += step; + delay_pos = (delay_pos + 1) & (delay_size-1); + + count++; + } + + plugin_data->count = count; + plugin_data->prev_law_peak = prev_law_peak; + plugin_data->next_law_peak = next_law_peak; + plugin_data->prev_law_pos = prev_law_pos; + plugin_data->next_law_pos = next_law_pos; + plugin_data->delay_pos = delay_pos; + plugin_data->old_d_base = new_d_base; +} +#undef buffer_write +#undef RUN_ADDING +#undef RUN_REPLACING + +#define buffer_write(b, v) (b += (v) * run_adding_gain) +#define RUN_ADDING 1 +#define RUN_REPLACING 0 + +static void setRunAddingGainFlanger(LADSPA_Handle instance, LADSPA_Data gain) { + ((Flanger *)instance)->run_adding_gain = gain; +} + +static void runAddingFlanger(LADSPA_Handle instance, unsigned long sample_count) { + Flanger *plugin_data = (Flanger *)instance; + LADSPA_Data run_adding_gain = plugin_data->run_adding_gain; + + /* Delay base (ms) (float value) */ + const LADSPA_Data delay_base = *(plugin_data->delay_base); + + /* Max slowdown (ms) (float value) */ + const LADSPA_Data detune = *(plugin_data->detune); + + /* LFO frequency (Hz) (float value) */ + const LADSPA_Data law_freq = *(plugin_data->law_freq); + + /* Feedback (float value) */ + const LADSPA_Data feedback = *(plugin_data->feedback); + + /* Input (array of floats of length sample_count) */ + const LADSPA_Data * const input = plugin_data->input; + + /* Output (array of floats of length sample_count) */ + LADSPA_Data * const output = plugin_data->output; + long count = plugin_data->count; + long delay_pos = plugin_data->delay_pos; + long delay_size = plugin_data->delay_size; + LADSPA_Data * delay_tbl = plugin_data->delay_tbl; + float next_law_peak = plugin_data->next_law_peak; + int next_law_pos = plugin_data->next_law_pos; + long old_d_base = plugin_data->old_d_base; + float prev_law_peak = plugin_data->prev_law_peak; + int prev_law_pos = plugin_data->prev_law_pos; + long sample_rate = plugin_data->sample_rate; + +#line 50 "flanger_1191.xml" + unsigned long pos; + long d_base, new_d_base; + LADSPA_Data out; + float delay_depth; + float dp; // float delay position + float dp_frac; // fractional part + long dp_idx; // integer delay index + long law_p; // period of law + float frac = 0.0f, step; // Portion the way through the block + float law; /* law amplitude */ + float n_ph, p_ph; + const float fb = f_clamp(feedback, -0.999f, 0.999f); + + // Set law params + law_p = (float)sample_rate / law_freq; + if (law_p < 1) { + law_p = 1; + } + + // Calculate base delay size in samples + new_d_base = (LIMIT(f_round(delay_base), 0, 25) * sample_rate) / 1000; + + // Calculate delay depth in samples + delay_depth = f_clamp(detune * (float)sample_rate * 0.001f, 0.0f, delay_size - new_d_base - 1.0f); + + step = 1.0f/sample_count; + for (pos = 0; pos < sample_count; pos++) { + if (count % law_p == 0) { + // Value for amplitude of law peak + next_law_peak = (float)rand() / (float)RAND_MAX; + next_law_pos = count + law_p; + } else if (count % law_p == law_p / 2) { + // Value for amplitude of law peak + prev_law_peak = (float)rand() / (float)RAND_MAX; + prev_law_pos = count + law_p; + } + + // Calculate position in delay table + d_base = LIN_INTERP(frac, old_d_base, new_d_base); + n_ph = (float)(law_p - abs(next_law_pos - count))/(float)law_p; + p_ph = n_ph + 0.5f; + while (p_ph > 1.0f) { + p_ph -= 1.0f; + } + law = f_sin_sq(3.1415926f*p_ph)*prev_law_peak + + f_sin_sq(3.1415926f*n_ph)*next_law_peak; + + dp = (float)(delay_pos - d_base) - (delay_depth * law); + // Get the integer part + dp_idx = f_round(dp - 0.5f); + // Get the fractional part + dp_frac = dp - dp_idx; + + // Accumulate into output buffer + out = cube_interp(dp_frac, delay_tbl[(dp_idx-1) & (delay_size-1)], delay_tbl[dp_idx & (delay_size-1)], delay_tbl[(dp_idx+1) & (delay_size-1)], delay_tbl[(dp_idx+2) & (delay_size-1)]); + + // Store new delayed value + delay_tbl[delay_pos] = flush_to_zero(input[pos] + (fb * out)); + // Sometimes the delay can pick up NaN values, I'm not sure why + // and this is easier than fixing it + if (isnan(delay_tbl[delay_pos])) { + delay_tbl[delay_pos] = 0.0f; + } + + out = f_clamp(delay_tbl[delay_pos] * 0.707f, -1.0, 1.0); + buffer_write(output[pos], out); + + frac += step; + delay_pos = (delay_pos + 1) & (delay_size-1); + + count++; + } + + plugin_data->count = count; + plugin_data->prev_law_peak = prev_law_peak; + plugin_data->next_law_peak = next_law_peak; + plugin_data->prev_law_pos = prev_law_pos; + plugin_data->next_law_pos = next_law_pos; + plugin_data->delay_pos = delay_pos; + plugin_data->old_d_base = new_d_base; +} + +void _init() { + char **port_names; + LADSPA_PortDescriptor *port_descriptors; + LADSPA_PortRangeHint *port_range_hints; + +#ifdef ENABLE_NLS +#define D_(s) dgettext(PACKAGE, s) + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, PACKAGE_LOCALE_DIR); +#else +#define D_(s) (s) +#endif + + + flangerDescriptor = + (LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor)); + + if (flangerDescriptor) { + flangerDescriptor->UniqueID = 1191; + flangerDescriptor->Label = "flanger"; + flangerDescriptor->Properties = + LADSPA_PROPERTY_HARD_RT_CAPABLE; + flangerDescriptor->Name = + D_("Flanger"); + flangerDescriptor->Maker = + "Steve Harris "; + flangerDescriptor->Copyright = + "GPL"; + flangerDescriptor->PortCount = 6; + + port_descriptors = (LADSPA_PortDescriptor *)calloc(6, + sizeof(LADSPA_PortDescriptor)); + flangerDescriptor->PortDescriptors = + (const LADSPA_PortDescriptor *)port_descriptors; + + port_range_hints = (LADSPA_PortRangeHint *)calloc(6, + sizeof(LADSPA_PortRangeHint)); + flangerDescriptor->PortRangeHints = + (const LADSPA_PortRangeHint *)port_range_hints; + + port_names = (char **)calloc(6, sizeof(char*)); + flangerDescriptor->PortNames = + (const char **)port_names; + + /* Parameters for Delay base (ms) */ + port_descriptors[FLANGER_DELAY_BASE] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[FLANGER_DELAY_BASE] = + D_("Delay base (ms)"); + port_range_hints[FLANGER_DELAY_BASE].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_LOW; + port_range_hints[FLANGER_DELAY_BASE].LowerBound = 0.1; + port_range_hints[FLANGER_DELAY_BASE].UpperBound = 25; + + /* Parameters for Max slowdown (ms) */ + port_descriptors[FLANGER_DETUNE] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[FLANGER_DETUNE] = + D_("Max slowdown (ms)"); + port_range_hints[FLANGER_DETUNE].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_LOW; + port_range_hints[FLANGER_DETUNE].LowerBound = 0; + port_range_hints[FLANGER_DETUNE].UpperBound = 10; + + /* Parameters for LFO frequency (Hz) */ + port_descriptors[FLANGER_LAW_FREQ] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[FLANGER_LAW_FREQ] = + D_("LFO frequency (Hz)"); + port_range_hints[FLANGER_LAW_FREQ].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_LOW | LADSPA_HINT_LOGARITHMIC; + port_range_hints[FLANGER_LAW_FREQ].LowerBound = 0.05; + port_range_hints[FLANGER_LAW_FREQ].UpperBound = 100; + + /* Parameters for Feedback */ + port_descriptors[FLANGER_FEEDBACK] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[FLANGER_FEEDBACK] = + D_("Feedback"); + port_range_hints[FLANGER_FEEDBACK].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0; + port_range_hints[FLANGER_FEEDBACK].LowerBound = -1; + port_range_hints[FLANGER_FEEDBACK].UpperBound = 1; + + /* Parameters for Input */ + port_descriptors[FLANGER_INPUT] = + LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO; + port_names[FLANGER_INPUT] = + D_("Input"); + port_range_hints[FLANGER_INPUT].HintDescriptor = 0; + + /* Parameters for Output */ + port_descriptors[FLANGER_OUTPUT] = + LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO; + port_names[FLANGER_OUTPUT] = + D_("Output"); + port_range_hints[FLANGER_OUTPUT].HintDescriptor = 0; + + flangerDescriptor->activate = activateFlanger; + flangerDescriptor->cleanup = cleanupFlanger; + flangerDescriptor->connect_port = connectPortFlanger; + flangerDescriptor->deactivate = NULL; + flangerDescriptor->instantiate = instantiateFlanger; + flangerDescriptor->run = runFlanger; + flangerDescriptor->run_adding = runAddingFlanger; + flangerDescriptor->set_run_adding_gain = setRunAddingGainFlanger; + } +} + +void _fini() { + if (flangerDescriptor) { + free((LADSPA_PortDescriptor *)flangerDescriptor->PortDescriptors); + free((char **)flangerDescriptor->PortNames); + free((LADSPA_PortRangeHint *)flangerDescriptor->PortRangeHints); + free(flangerDescriptor); + } + +} diff --git a/plugins/ladspa_effect/swh/mbeq_1197.c b/plugins/ladspa_effect/swh/mbeq_1197.c new file mode 100644 index 000000000..751e048cf --- /dev/null +++ b/plugins/ladspa_effect/swh/mbeq_1197.c @@ -0,0 +1,894 @@ +#include +#include +#ifndef WIN32 +#include "config.h" +#endif + +#ifdef ENABLE_NLS +#include +#endif + +#define _ISOC9X_SOURCE 1 +#define _ISOC99_SOURCE 1 +#define __USE_ISOC99 1 +#define __USE_ISOC9X 1 + +#include + +#include "ladspa.h" + +#ifdef WIN32 +#define _WINDOWS_DLL_EXPORT_ __declspec(dllexport) +int bIsFirstTime = 1; +void _init(); // forward declaration +#else +#define _WINDOWS_DLL_EXPORT_ +#endif + +#line 9 "mbeq_1197.xml" + +#include "config.h" + +#ifdef FFTW3 + +#include + +typedef fftwf_plan fft_plan; +typedef float fftw_real; + +#else + +#ifdef EXPLICIT_S +#include +#else +#include +#endif //EXPLICIT_S + +typedef rfftw_plan fft_plan; + +#endif //FFTW3 + +#include "ladspa-util.h" + +#define FFT_LENGTH 1024 +#define OVER_SAMP 4 +#define BANDS 15 + + +float bands[BANDS] = + { 50.00f, 100.00f, 155.56f, 220.00f, 311.13f, + 440.00f, 622.25f, 880.00f, 1244.51f, 1760.00f, 2489.02f, + 3519.95, 4978.04f, 9956.08f, 19912.16f }; + +#define MBEQ_BAND_1 0 +#define MBEQ_BAND_2 1 +#define MBEQ_BAND_3 2 +#define MBEQ_BAND_4 3 +#define MBEQ_BAND_5 4 +#define MBEQ_BAND_6 5 +#define MBEQ_BAND_7 6 +#define MBEQ_BAND_8 7 +#define MBEQ_BAND_9 8 +#define MBEQ_BAND_10 9 +#define MBEQ_BAND_11 10 +#define MBEQ_BAND_12 11 +#define MBEQ_BAND_13 12 +#define MBEQ_BAND_14 13 +#define MBEQ_BAND_15 14 +#define MBEQ_INPUT 15 +#define MBEQ_OUTPUT 16 +#define MBEQ_LATENCY 17 + +static LADSPA_Descriptor *mbeqDescriptor = NULL; + +typedef struct { + LADSPA_Data *band_1; + LADSPA_Data *band_2; + LADSPA_Data *band_3; + LADSPA_Data *band_4; + LADSPA_Data *band_5; + LADSPA_Data *band_6; + LADSPA_Data *band_7; + LADSPA_Data *band_8; + LADSPA_Data *band_9; + LADSPA_Data *band_10; + LADSPA_Data *band_11; + LADSPA_Data *band_12; + LADSPA_Data *band_13; + LADSPA_Data *band_14; + LADSPA_Data *band_15; + LADSPA_Data *input; + LADSPA_Data *output; + LADSPA_Data *latency; + int * bin_base; + float * bin_delta; + fftw_real * comp; + float * db_table; + long fifo_pos; + LADSPA_Data *in_fifo; + LADSPA_Data *out_accum; + LADSPA_Data *out_fifo; + fft_plan plan_cr; + fft_plan plan_rc; + fftw_real * real; + float * window; + LADSPA_Data run_adding_gain; +} Mbeq; + +_WINDOWS_DLL_EXPORT_ +const LADSPA_Descriptor *ladspa_descriptor(unsigned long index) { + +#ifdef WIN32 + if (bIsFirstTime) { + _init(); + bIsFirstTime = 0; + } +#endif + switch (index) { + case 0: + return mbeqDescriptor; + default: + return NULL; + } +} + +static void activateMbeq(LADSPA_Handle instance) { + Mbeq *plugin_data = (Mbeq *)instance; + int *bin_base = plugin_data->bin_base; + float *bin_delta = plugin_data->bin_delta; + fftw_real *comp = plugin_data->comp; + float *db_table = plugin_data->db_table; + long fifo_pos = plugin_data->fifo_pos; + LADSPA_Data *in_fifo = plugin_data->in_fifo; + LADSPA_Data *out_accum = plugin_data->out_accum; + LADSPA_Data *out_fifo = plugin_data->out_fifo; + fft_plan plan_cr = plugin_data->plan_cr; + fft_plan plan_rc = plugin_data->plan_rc; + fftw_real *real = plugin_data->real; + float *window = plugin_data->window; +#line 109 "mbeq_1197.xml" + fifo_pos = 0; + plugin_data->bin_base = bin_base; + plugin_data->bin_delta = bin_delta; + plugin_data->comp = comp; + plugin_data->db_table = db_table; + plugin_data->fifo_pos = fifo_pos; + plugin_data->in_fifo = in_fifo; + plugin_data->out_accum = out_accum; + plugin_data->out_fifo = out_fifo; + plugin_data->plan_cr = plan_cr; + plugin_data->plan_rc = plan_rc; + plugin_data->real = real; + plugin_data->window = window; + +} + +static void cleanupMbeq(LADSPA_Handle instance) { +#line 113 "mbeq_1197.xml" + Mbeq *plugin_data = (Mbeq *)instance; + free(plugin_data->in_fifo); + free(plugin_data->out_fifo); + free(plugin_data->out_accum); + free(plugin_data->real); + free(plugin_data->comp); + free(plugin_data->window); + free(plugin_data->bin_base); + free(plugin_data->bin_delta); + free(plugin_data->db_table); + free(instance); +} + +static void connectPortMbeq( + LADSPA_Handle instance, + unsigned long port, + LADSPA_Data *data) { + Mbeq *plugin; + + plugin = (Mbeq *)instance; + switch (port) { + case MBEQ_BAND_1: + plugin->band_1 = data; + break; + case MBEQ_BAND_2: + plugin->band_2 = data; + break; + case MBEQ_BAND_3: + plugin->band_3 = data; + break; + case MBEQ_BAND_4: + plugin->band_4 = data; + break; + case MBEQ_BAND_5: + plugin->band_5 = data; + break; + case MBEQ_BAND_6: + plugin->band_6 = data; + break; + case MBEQ_BAND_7: + plugin->band_7 = data; + break; + case MBEQ_BAND_8: + plugin->band_8 = data; + break; + case MBEQ_BAND_9: + plugin->band_9 = data; + break; + case MBEQ_BAND_10: + plugin->band_10 = data; + break; + case MBEQ_BAND_11: + plugin->band_11 = data; + break; + case MBEQ_BAND_12: + plugin->band_12 = data; + break; + case MBEQ_BAND_13: + plugin->band_13 = data; + break; + case MBEQ_BAND_14: + plugin->band_14 = data; + break; + case MBEQ_BAND_15: + plugin->band_15 = data; + break; + case MBEQ_INPUT: + plugin->input = data; + break; + case MBEQ_OUTPUT: + plugin->output = data; + break; + case MBEQ_LATENCY: + plugin->latency = data; + break; + } +} + +static LADSPA_Handle instantiateMbeq( + const LADSPA_Descriptor *descriptor, + unsigned long s_rate) { + Mbeq *plugin_data = (Mbeq *)malloc(sizeof(Mbeq)); + int *bin_base = NULL; + float *bin_delta = NULL; + fftw_real *comp = NULL; + float *db_table = NULL; + long fifo_pos; + LADSPA_Data *in_fifo = NULL; + LADSPA_Data *out_accum = NULL; + LADSPA_Data *out_fifo = NULL; + fft_plan plan_cr; + fft_plan plan_rc; + fftw_real *real = NULL; + float *window = NULL; + +#line 51 "mbeq_1197.xml" + int i, bin; + float last_bin, next_bin; + float db; + float hz_per_bin = (float)s_rate / (float)FFT_LENGTH; + + in_fifo = calloc(FFT_LENGTH, sizeof(LADSPA_Data)); + out_fifo = calloc(FFT_LENGTH, sizeof(LADSPA_Data)); + out_accum = calloc(FFT_LENGTH * 2, sizeof(LADSPA_Data)); + real = calloc(FFT_LENGTH, sizeof(fftw_real)); + comp = calloc(FFT_LENGTH, sizeof(fftw_real)); + window = calloc(FFT_LENGTH, sizeof(float)); + bin_base = calloc(FFT_LENGTH/2, sizeof(int)); + bin_delta = calloc(FFT_LENGTH/2, sizeof(float)); + fifo_pos = 0; + + #ifdef FFTW3 + plan_rc = fftwf_plan_r2r_1d(FFT_LENGTH, real, comp, FFTW_R2HC, FFTW_MEASURE); + plan_cr = fftwf_plan_r2r_1d(FFT_LENGTH, comp, real, FFTW_HC2R, FFTW_MEASURE); + #else + plan_rc = rfftw_create_plan(FFT_LENGTH, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE); + plan_cr = rfftw_create_plan(FFT_LENGTH, FFTW_COMPLEX_TO_REAL, FFTW_ESTIMATE); + #endif + + // Create raised cosine window table + for (i=0; i < FFT_LENGTH; i++) { + window[i] = -0.5f*cos(2.0f*M_PI*(double)i/(double)FFT_LENGTH)+0.5f; + window[i] *= 2.0f; + } + + // Create db->coeffiecnt lookup table + db_table = malloc(1000 * sizeof(float)); + for (i=0; i < 1000; i++) { + db = ((float)i/10) - 70; + db_table[i] = pow(10.0f, db/20.0f); + } + + // Create FFT bin -> band + delta tables + bin = 0; + while (bin <= bands[0]/hz_per_bin) { + bin_base[bin] = 0; + bin_delta[bin++] = 0.0f; + } + for (i = 1; i < BANDS-1 && bin < (FFT_LENGTH/2)-1 && bands[i+1] < s_rate/2; i++) { + last_bin = bin; + next_bin = (bands[i+1])/hz_per_bin; + while (bin <= next_bin) { + bin_base[bin] = i; + bin_delta[bin] = (float)(bin - last_bin) / (float)(next_bin - last_bin); + bin++; + } + } + for (; bin < (FFT_LENGTH/2); bin++) { + bin_base[bin] = BANDS-1; + bin_delta[bin] = 0.0f; + } + + plugin_data->bin_base = bin_base; + plugin_data->bin_delta = bin_delta; + plugin_data->comp = comp; + plugin_data->db_table = db_table; + plugin_data->fifo_pos = fifo_pos; + plugin_data->in_fifo = in_fifo; + plugin_data->out_accum = out_accum; + plugin_data->out_fifo = out_fifo; + plugin_data->plan_cr = plan_cr; + plugin_data->plan_rc = plan_rc; + plugin_data->real = real; + plugin_data->window = window; + + return (LADSPA_Handle)plugin_data; +} + +#undef buffer_write +#undef RUN_ADDING +#undef RUN_REPLACING + +#define buffer_write(b, v) (b = v) +#define RUN_ADDING 0 +#define RUN_REPLACING 1 + +static void runMbeq(LADSPA_Handle instance, unsigned long sample_count) { + Mbeq *plugin_data = (Mbeq *)instance; + + /* 50Hz gain (low shelving) (float value) */ + const LADSPA_Data band_1 = *(plugin_data->band_1); + + /* 100Hz gain (float value) */ + const LADSPA_Data band_2 = *(plugin_data->band_2); + + /* 156Hz gain (float value) */ + const LADSPA_Data band_3 = *(plugin_data->band_3); + + /* 220Hz gain (float value) */ + const LADSPA_Data band_4 = *(plugin_data->band_4); + + /* 311Hz gain (float value) */ + const LADSPA_Data band_5 = *(plugin_data->band_5); + + /* 440Hz gain (float value) */ + const LADSPA_Data band_6 = *(plugin_data->band_6); + + /* 622Hz gain (float value) */ + const LADSPA_Data band_7 = *(plugin_data->band_7); + + /* 880Hz gain (float value) */ + const LADSPA_Data band_8 = *(plugin_data->band_8); + + /* 1250Hz gain (float value) */ + const LADSPA_Data band_9 = *(plugin_data->band_9); + + /* 1750Hz gain (float value) */ + const LADSPA_Data band_10 = *(plugin_data->band_10); + + /* 2500Hz gain (float value) */ + const LADSPA_Data band_11 = *(plugin_data->band_11); + + /* 3500Hz gain (float value) */ + const LADSPA_Data band_12 = *(plugin_data->band_12); + + /* 5000Hz gain (float value) */ + const LADSPA_Data band_13 = *(plugin_data->band_13); + + /* 10000Hz gain (float value) */ + const LADSPA_Data band_14 = *(plugin_data->band_14); + + /* 20000Hz gain (float value) */ + const LADSPA_Data band_15 = *(plugin_data->band_15); + + /* Input (array of floats of length sample_count) */ + const LADSPA_Data * const input = plugin_data->input; + + /* Output (array of floats of length sample_count) */ + LADSPA_Data * const output = plugin_data->output; + int * bin_base = plugin_data->bin_base; + float * bin_delta = plugin_data->bin_delta; + fftw_real * comp = plugin_data->comp; + float * db_table = plugin_data->db_table; + long fifo_pos = plugin_data->fifo_pos; + LADSPA_Data * in_fifo = plugin_data->in_fifo; + LADSPA_Data * out_accum = plugin_data->out_accum; + LADSPA_Data * out_fifo = plugin_data->out_fifo; + fft_plan plan_cr = plugin_data->plan_cr; + fft_plan plan_rc = plugin_data->plan_rc; + fftw_real * real = plugin_data->real; + float * window = plugin_data->window; + +#line 125 "mbeq_1197.xml" + int i, bin, gain_idx; + float gains[BANDS + 1] = + { band_1, band_2, band_3, band_4, band_5, band_6, band_7, band_8, band_9, + band_10, band_11, band_12, band_13, band_14, band_15, 0.0f }; + float coefs[FFT_LENGTH / 2]; + unsigned long pos; + + int step_size = FFT_LENGTH / OVER_SAMP; + int fft_latency = FFT_LENGTH - step_size; + + // Convert gains from dB to co-efficents + for (i = 0; i < BANDS; i++) { + gain_idx = (int)((gains[i] * 10) + 700); + gains[i] = db_table[LIMIT(gain_idx, 0, 999)]; + } + + // Calculate coefficients for each bin of FFT + coefs[0] = 0.0f; + for (bin=1; bin < (FFT_LENGTH/2-1); bin++) { + coefs[bin] = ((1.0f-bin_delta[bin]) * gains[bin_base[bin]]) + + (bin_delta[bin] * gains[bin_base[bin]+1]); + } + + if (fifo_pos == 0) { + fifo_pos = fft_latency; + } + + for (pos = 0; pos < sample_count; pos++) { + in_fifo[fifo_pos] = input[pos]; + buffer_write(output[pos], out_fifo[fifo_pos-fft_latency]); + fifo_pos++; + + // If the FIFO is full + if (fifo_pos >= FFT_LENGTH) { + fifo_pos = fft_latency; + + // Window input FIFO + for (i=0; i < FFT_LENGTH; i++) { + real[i] = in_fifo[i] * window[i]; + } + + // Run the real->complex transform + #ifdef FFTW3 + fftwf_execute(plan_rc); + #else + rfftw_one(plan_rc, real, comp); + #endif + + // Multiply the bins magnitudes by the coeficients + for (i = 0; i < FFT_LENGTH/2; i++) { + comp[i] *= coefs[i]; + comp[FFT_LENGTH-i] *= coefs[i]; + } + + // Run the complex->real transform + #ifdef FFTW3 + fftwf_execute(plan_cr); + #else + rfftw_one(plan_cr, comp, real); + #endif + + // Window into the output accumulator + for (i = 0; i < FFT_LENGTH; i++) { + out_accum[i] += 0.9186162f * window[i] * real[i]/(FFT_LENGTH * OVER_SAMP); + } + for (i = 0; i < step_size; i++) { + out_fifo[i] = out_accum[i]; + } + + // Shift output accumulator + memmove(out_accum, out_accum + step_size, FFT_LENGTH*sizeof(LADSPA_Data)); + + // Shift input fifo + for (i = 0; i < fft_latency; i++) { + in_fifo[i] = in_fifo[i+step_size]; + } + } + } + + // Store the fifo_position + plugin_data->fifo_pos = fifo_pos; + + *(plugin_data->latency) = fft_latency; +} +#undef buffer_write +#undef RUN_ADDING +#undef RUN_REPLACING + +#define buffer_write(b, v) (b += (v) * run_adding_gain) +#define RUN_ADDING 1 +#define RUN_REPLACING 0 + +static void setRunAddingGainMbeq(LADSPA_Handle instance, LADSPA_Data gain) { + ((Mbeq *)instance)->run_adding_gain = gain; +} + +static void runAddingMbeq(LADSPA_Handle instance, unsigned long sample_count) { + Mbeq *plugin_data = (Mbeq *)instance; + LADSPA_Data run_adding_gain = plugin_data->run_adding_gain; + + /* 50Hz gain (low shelving) (float value) */ + const LADSPA_Data band_1 = *(plugin_data->band_1); + + /* 100Hz gain (float value) */ + const LADSPA_Data band_2 = *(plugin_data->band_2); + + /* 156Hz gain (float value) */ + const LADSPA_Data band_3 = *(plugin_data->band_3); + + /* 220Hz gain (float value) */ + const LADSPA_Data band_4 = *(plugin_data->band_4); + + /* 311Hz gain (float value) */ + const LADSPA_Data band_5 = *(plugin_data->band_5); + + /* 440Hz gain (float value) */ + const LADSPA_Data band_6 = *(plugin_data->band_6); + + /* 622Hz gain (float value) */ + const LADSPA_Data band_7 = *(plugin_data->band_7); + + /* 880Hz gain (float value) */ + const LADSPA_Data band_8 = *(plugin_data->band_8); + + /* 1250Hz gain (float value) */ + const LADSPA_Data band_9 = *(plugin_data->band_9); + + /* 1750Hz gain (float value) */ + const LADSPA_Data band_10 = *(plugin_data->band_10); + + /* 2500Hz gain (float value) */ + const LADSPA_Data band_11 = *(plugin_data->band_11); + + /* 3500Hz gain (float value) */ + const LADSPA_Data band_12 = *(plugin_data->band_12); + + /* 5000Hz gain (float value) */ + const LADSPA_Data band_13 = *(plugin_data->band_13); + + /* 10000Hz gain (float value) */ + const LADSPA_Data band_14 = *(plugin_data->band_14); + + /* 20000Hz gain (float value) */ + const LADSPA_Data band_15 = *(plugin_data->band_15); + + /* Input (array of floats of length sample_count) */ + const LADSPA_Data * const input = plugin_data->input; + + /* Output (array of floats of length sample_count) */ + LADSPA_Data * const output = plugin_data->output; + int * bin_base = plugin_data->bin_base; + float * bin_delta = plugin_data->bin_delta; + fftw_real * comp = plugin_data->comp; + float * db_table = plugin_data->db_table; + long fifo_pos = plugin_data->fifo_pos; + LADSPA_Data * in_fifo = plugin_data->in_fifo; + LADSPA_Data * out_accum = plugin_data->out_accum; + LADSPA_Data * out_fifo = plugin_data->out_fifo; + fft_plan plan_cr = plugin_data->plan_cr; + fft_plan plan_rc = plugin_data->plan_rc; + fftw_real * real = plugin_data->real; + float * window = plugin_data->window; + +#line 125 "mbeq_1197.xml" + int i, bin, gain_idx; + float gains[BANDS + 1] = + { band_1, band_2, band_3, band_4, band_5, band_6, band_7, band_8, band_9, + band_10, band_11, band_12, band_13, band_14, band_15, 0.0f }; + float coefs[FFT_LENGTH / 2]; + unsigned long pos; + + int step_size = FFT_LENGTH / OVER_SAMP; + int fft_latency = FFT_LENGTH - step_size; + + // Convert gains from dB to co-efficents + for (i = 0; i < BANDS; i++) { + gain_idx = (int)((gains[i] * 10) + 700); + gains[i] = db_table[LIMIT(gain_idx, 0, 999)]; + } + + // Calculate coefficients for each bin of FFT + coefs[0] = 0.0f; + for (bin=1; bin < (FFT_LENGTH/2-1); bin++) { + coefs[bin] = ((1.0f-bin_delta[bin]) * gains[bin_base[bin]]) + + (bin_delta[bin] * gains[bin_base[bin]+1]); + } + + if (fifo_pos == 0) { + fifo_pos = fft_latency; + } + + for (pos = 0; pos < sample_count; pos++) { + in_fifo[fifo_pos] = input[pos]; + buffer_write(output[pos], out_fifo[fifo_pos-fft_latency]); + fifo_pos++; + + // If the FIFO is full + if (fifo_pos >= FFT_LENGTH) { + fifo_pos = fft_latency; + + // Window input FIFO + for (i=0; i < FFT_LENGTH; i++) { + real[i] = in_fifo[i] * window[i]; + } + + // Run the real->complex transform + #ifdef FFTW3 + fftwf_execute(plan_rc); + #else + rfftw_one(plan_rc, real, comp); + #endif + + // Multiply the bins magnitudes by the coeficients + for (i = 0; i < FFT_LENGTH/2; i++) { + comp[i] *= coefs[i]; + comp[FFT_LENGTH-i] *= coefs[i]; + } + + // Run the complex->real transform + #ifdef FFTW3 + fftwf_execute(plan_cr); + #else + rfftw_one(plan_cr, comp, real); + #endif + + // Window into the output accumulator + for (i = 0; i < FFT_LENGTH; i++) { + out_accum[i] += 0.9186162f * window[i] * real[i]/(FFT_LENGTH * OVER_SAMP); + } + for (i = 0; i < step_size; i++) { + out_fifo[i] = out_accum[i]; + } + + // Shift output accumulator + memmove(out_accum, out_accum + step_size, FFT_LENGTH*sizeof(LADSPA_Data)); + + // Shift input fifo + for (i = 0; i < fft_latency; i++) { + in_fifo[i] = in_fifo[i+step_size]; + } + } + } + + // Store the fifo_position + plugin_data->fifo_pos = fifo_pos; + + *(plugin_data->latency) = fft_latency; +} + +void _init() { + char **port_names; + LADSPA_PortDescriptor *port_descriptors; + LADSPA_PortRangeHint *port_range_hints; + +#ifdef ENABLE_NLS +#define D_(s) dgettext(PACKAGE, s) + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, PACKAGE_LOCALE_DIR); +#else +#define D_(s) (s) +#endif + + + mbeqDescriptor = + (LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor)); + + if (mbeqDescriptor) { + mbeqDescriptor->UniqueID = 1197; + mbeqDescriptor->Label = "mbeq"; + mbeqDescriptor->Properties = + LADSPA_PROPERTY_HARD_RT_CAPABLE; + mbeqDescriptor->Name = + D_("Multiband EQ"); + mbeqDescriptor->Maker = + "Steve Harris "; + mbeqDescriptor->Copyright = + "GPL"; + mbeqDescriptor->PortCount = 18; + + port_descriptors = (LADSPA_PortDescriptor *)calloc(18, + sizeof(LADSPA_PortDescriptor)); + mbeqDescriptor->PortDescriptors = + (const LADSPA_PortDescriptor *)port_descriptors; + + port_range_hints = (LADSPA_PortRangeHint *)calloc(18, + sizeof(LADSPA_PortRangeHint)); + mbeqDescriptor->PortRangeHints = + (const LADSPA_PortRangeHint *)port_range_hints; + + port_names = (char **)calloc(18, sizeof(char*)); + mbeqDescriptor->PortNames = + (const char **)port_names; + + /* Parameters for 50Hz gain (low shelving) */ + port_descriptors[MBEQ_BAND_1] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[MBEQ_BAND_1] = + D_("50Hz gain (low shelving)"); + port_range_hints[MBEQ_BAND_1].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0; + port_range_hints[MBEQ_BAND_1].LowerBound = -70; + port_range_hints[MBEQ_BAND_1].UpperBound = +30; + + /* Parameters for 100Hz gain */ + port_descriptors[MBEQ_BAND_2] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[MBEQ_BAND_2] = + D_("100Hz gain"); + port_range_hints[MBEQ_BAND_2].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0; + port_range_hints[MBEQ_BAND_2].LowerBound = -70; + port_range_hints[MBEQ_BAND_2].UpperBound = +30; + + /* Parameters for 156Hz gain */ + port_descriptors[MBEQ_BAND_3] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[MBEQ_BAND_3] = + D_("156Hz gain"); + port_range_hints[MBEQ_BAND_3].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0; + port_range_hints[MBEQ_BAND_3].LowerBound = -70; + port_range_hints[MBEQ_BAND_3].UpperBound = +30; + + /* Parameters for 220Hz gain */ + port_descriptors[MBEQ_BAND_4] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[MBEQ_BAND_4] = + D_("220Hz gain"); + port_range_hints[MBEQ_BAND_4].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0; + port_range_hints[MBEQ_BAND_4].LowerBound = -70; + port_range_hints[MBEQ_BAND_4].UpperBound = +30; + + /* Parameters for 311Hz gain */ + port_descriptors[MBEQ_BAND_5] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[MBEQ_BAND_5] = + D_("311Hz gain"); + port_range_hints[MBEQ_BAND_5].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0; + port_range_hints[MBEQ_BAND_5].LowerBound = -70; + port_range_hints[MBEQ_BAND_5].UpperBound = +30; + + /* Parameters for 440Hz gain */ + port_descriptors[MBEQ_BAND_6] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[MBEQ_BAND_6] = + D_("440Hz gain"); + port_range_hints[MBEQ_BAND_6].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0; + port_range_hints[MBEQ_BAND_6].LowerBound = -70; + port_range_hints[MBEQ_BAND_6].UpperBound = +30; + + /* Parameters for 622Hz gain */ + port_descriptors[MBEQ_BAND_7] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[MBEQ_BAND_7] = + D_("622Hz gain"); + port_range_hints[MBEQ_BAND_7].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0; + port_range_hints[MBEQ_BAND_7].LowerBound = -70; + port_range_hints[MBEQ_BAND_7].UpperBound = +30; + + /* Parameters for 880Hz gain */ + port_descriptors[MBEQ_BAND_8] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[MBEQ_BAND_8] = + D_("880Hz gain"); + port_range_hints[MBEQ_BAND_8].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0; + port_range_hints[MBEQ_BAND_8].LowerBound = -70; + port_range_hints[MBEQ_BAND_8].UpperBound = +30; + + /* Parameters for 1250Hz gain */ + port_descriptors[MBEQ_BAND_9] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[MBEQ_BAND_9] = + D_("1250Hz gain"); + port_range_hints[MBEQ_BAND_9].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0; + port_range_hints[MBEQ_BAND_9].LowerBound = -70; + port_range_hints[MBEQ_BAND_9].UpperBound = +30; + + /* Parameters for 1750Hz gain */ + port_descriptors[MBEQ_BAND_10] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[MBEQ_BAND_10] = + D_("1750Hz gain"); + port_range_hints[MBEQ_BAND_10].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0; + port_range_hints[MBEQ_BAND_10].LowerBound = -70; + port_range_hints[MBEQ_BAND_10].UpperBound = +30; + + /* Parameters for 2500Hz gain */ + port_descriptors[MBEQ_BAND_11] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[MBEQ_BAND_11] = + D_("2500Hz gain"); + port_range_hints[MBEQ_BAND_11].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0; + port_range_hints[MBEQ_BAND_11].LowerBound = -70; + port_range_hints[MBEQ_BAND_11].UpperBound = +30; + + /* Parameters for 3500Hz gain */ + port_descriptors[MBEQ_BAND_12] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[MBEQ_BAND_12] = + D_("3500Hz gain"); + port_range_hints[MBEQ_BAND_12].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0; + port_range_hints[MBEQ_BAND_12].LowerBound = -70; + port_range_hints[MBEQ_BAND_12].UpperBound = +30; + + /* Parameters for 5000Hz gain */ + port_descriptors[MBEQ_BAND_13] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[MBEQ_BAND_13] = + D_("5000Hz gain"); + port_range_hints[MBEQ_BAND_13].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0; + port_range_hints[MBEQ_BAND_13].LowerBound = -70; + port_range_hints[MBEQ_BAND_13].UpperBound = +30; + + /* Parameters for 10000Hz gain */ + port_descriptors[MBEQ_BAND_14] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[MBEQ_BAND_14] = + D_("10000Hz gain"); + port_range_hints[MBEQ_BAND_14].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0; + port_range_hints[MBEQ_BAND_14].LowerBound = -70; + port_range_hints[MBEQ_BAND_14].UpperBound = +30; + + /* Parameters for 20000Hz gain */ + port_descriptors[MBEQ_BAND_15] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[MBEQ_BAND_15] = + D_("20000Hz gain"); + port_range_hints[MBEQ_BAND_15].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0; + port_range_hints[MBEQ_BAND_15].LowerBound = -70; + port_range_hints[MBEQ_BAND_15].UpperBound = +30; + + /* Parameters for Input */ + port_descriptors[MBEQ_INPUT] = + LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO; + port_names[MBEQ_INPUT] = + D_("Input"); + port_range_hints[MBEQ_INPUT].HintDescriptor = 0; + + /* Parameters for Output */ + port_descriptors[MBEQ_OUTPUT] = + LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO; + port_names[MBEQ_OUTPUT] = + D_("Output"); + port_range_hints[MBEQ_OUTPUT].HintDescriptor = 0; + + /* Parameters for latency */ + port_descriptors[MBEQ_LATENCY] = + LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL; + port_names[MBEQ_LATENCY] = + D_("latency"); + port_range_hints[MBEQ_LATENCY].HintDescriptor = 0; + + mbeqDescriptor->activate = activateMbeq; + mbeqDescriptor->cleanup = cleanupMbeq; + mbeqDescriptor->connect_port = connectPortMbeq; + mbeqDescriptor->deactivate = NULL; + mbeqDescriptor->instantiate = instantiateMbeq; + mbeqDescriptor->run = runMbeq; + mbeqDescriptor->run_adding = runAddingMbeq; + mbeqDescriptor->set_run_adding_gain = setRunAddingGainMbeq; + } +} + +void _fini() { + if (mbeqDescriptor) { + free((LADSPA_PortDescriptor *)mbeqDescriptor->PortDescriptors); + free((char **)mbeqDescriptor->PortNames); + free((LADSPA_PortRangeHint *)mbeqDescriptor->PortRangeHints); + free(mbeqDescriptor); + } + +} diff --git a/plugins/ladspa_effect/swh/phasers_1217.c b/plugins/ladspa_effect/swh/phasers_1217.c new file mode 100644 index 000000000..0d4cae64a --- /dev/null +++ b/plugins/ladspa_effect/swh/phasers_1217.c @@ -0,0 +1,1400 @@ +#include +#include +#ifndef WIN32 +#include "config.h" +#endif + +#ifdef ENABLE_NLS +#include +#endif + +#define _ISOC9X_SOURCE 1 +#define _ISOC99_SOURCE 1 +#define __USE_ISOC99 1 +#define __USE_ISOC9X 1 + +#include + +#include "ladspa.h" + +#ifdef WIN32 +#define _WINDOWS_DLL_EXPORT_ __declspec(dllexport) +int bIsFirstTime = 1; +void _init(); // forward declaration +#else +#define _WINDOWS_DLL_EXPORT_ +#endif + +#line 10 "phasers_1217.xml" + +#include "ladspa-util.h" + +#define LFO_SIZE 4096 + +typedef struct { + float a1; + float zm1; +} allpass; + +inline static float ap_run(allpass *a, float x) +{ + float y = x * -(a->a1) + a->zm1; + a->zm1 = y * a->a1 + x; + + return y; +} + +inline static void ap_set_delay(allpass *a, float d) +{ + a->a1 = (1.0f - d) / (1.0f + d); +} + +inline static void ap_clear(allpass *a) +{ + a->a1 = 0.0f; + a->zm1 = 0.0f; +} + +typedef struct { + float ga; + float gr; + float env; +} envelope; + +inline static float env_run(envelope *e, float in) +{ + float env_lvl = e->env; + + in = fabs(in); + + if (env_lvl < in) { + env_lvl = e->ga * (env_lvl - in) + in; + } else { + env_lvl = e->gr * (env_lvl - in) + in; + } + + e->env = env_lvl; + return env_lvl; +} + +// Set attack time in samples +inline static void env_set_attack(envelope *e, float a) +{ + e->ga = f_exp(-1.0f/a); +} + +// Set release time in samples +inline static void env_set_release(envelope *e, float r) +{ + e->gr = f_exp(-1.0f/r); +} + +#define LFOPHASER_LFO_RATE 0 +#define LFOPHASER_LFO_DEPTH 1 +#define LFOPHASER_FB 2 +#define LFOPHASER_SPREAD 3 +#define LFOPHASER_INPUT 4 +#define LFOPHASER_OUTPUT 5 +#define FOURBYFOURPOLE_F0 0 +#define FOURBYFOURPOLE_FB0 1 +#define FOURBYFOURPOLE_F1 2 +#define FOURBYFOURPOLE_FB1 3 +#define FOURBYFOURPOLE_F2 4 +#define FOURBYFOURPOLE_FB2 5 +#define FOURBYFOURPOLE_F3 6 +#define FOURBYFOURPOLE_FB3 7 +#define FOURBYFOURPOLE_INPUT 8 +#define FOURBYFOURPOLE_OUTPUT 9 +#define AUTOPHASER_ATTACK_P 0 +#define AUTOPHASER_DECAY_P 1 +#define AUTOPHASER_DEPTH_P 2 +#define AUTOPHASER_FB 3 +#define AUTOPHASER_SPREAD 4 +#define AUTOPHASER_INPUT 5 +#define AUTOPHASER_OUTPUT 6 + +static LADSPA_Descriptor *lfoPhaserDescriptor = NULL; + +typedef struct { + LADSPA_Data *lfo_rate; + LADSPA_Data *lfo_depth; + LADSPA_Data *fb; + LADSPA_Data *spread; + LADSPA_Data *input; + LADSPA_Data *output; + allpass * ap; + int count; + float f_per_lv; + int lfo_pos; + float * lfo_tbl; + float ym1; + LADSPA_Data run_adding_gain; +} LfoPhaser; + +static LADSPA_Descriptor *fourByFourPoleDescriptor = NULL; + +typedef struct { + LADSPA_Data *f0; + LADSPA_Data *fb0; + LADSPA_Data *f1; + LADSPA_Data *fb1; + LADSPA_Data *f2; + LADSPA_Data *fb2; + LADSPA_Data *f3; + LADSPA_Data *fb3; + LADSPA_Data *input; + LADSPA_Data *output; + allpass * ap; + float sr_r_2; + float y0; + float y1; + float y2; + float y3; + LADSPA_Data run_adding_gain; +} FourByFourPole; + +static LADSPA_Descriptor *autoPhaserDescriptor = NULL; + +typedef struct { + LADSPA_Data *attack_p; + LADSPA_Data *decay_p; + LADSPA_Data *depth_p; + LADSPA_Data *fb; + LADSPA_Data *spread; + LADSPA_Data *input; + LADSPA_Data *output; + allpass * ap; + envelope * env; + float sample_rate; + float ym1; + LADSPA_Data run_adding_gain; +} AutoPhaser; + +_WINDOWS_DLL_EXPORT_ +const LADSPA_Descriptor *ladspa_descriptor(unsigned long index) { + +#ifdef WIN32 + if (bIsFirstTime) { + _init(); + bIsFirstTime = 0; + } +#endif + switch (index) { + case 0: + return lfoPhaserDescriptor; + case 1: + return fourByFourPoleDescriptor; + case 2: + return autoPhaserDescriptor; + default: + return NULL; + } +} + +static void activateLfoPhaser(LADSPA_Handle instance) { + LfoPhaser *plugin_data = (LfoPhaser *)instance; + allpass *ap = plugin_data->ap; + int count = plugin_data->count; + float f_per_lv = plugin_data->f_per_lv; + int lfo_pos = plugin_data->lfo_pos; + float *lfo_tbl = plugin_data->lfo_tbl; + float ym1 = plugin_data->ym1; +#line 100 "phasers_1217.xml" + ap_clear(ap); + ap_clear(ap+1); + ap_clear(ap+2); + ap_clear(ap+3); + ap_clear(ap+4); + ap_clear(ap+5); + plugin_data->ap = ap; + plugin_data->count = count; + plugin_data->f_per_lv = f_per_lv; + plugin_data->lfo_pos = lfo_pos; + plugin_data->lfo_tbl = lfo_tbl; + plugin_data->ym1 = ym1; + +} + +static void cleanupLfoPhaser(LADSPA_Handle instance) { +#line 109 "phasers_1217.xml" + LfoPhaser *plugin_data = (LfoPhaser *)instance; + free(plugin_data->ap); + free(plugin_data->lfo_tbl); + free(instance); +} + +static void connectPortLfoPhaser( + LADSPA_Handle instance, + unsigned long port, + LADSPA_Data *data) { + LfoPhaser *plugin; + + plugin = (LfoPhaser *)instance; + switch (port) { + case LFOPHASER_LFO_RATE: + plugin->lfo_rate = data; + break; + case LFOPHASER_LFO_DEPTH: + plugin->lfo_depth = data; + break; + case LFOPHASER_FB: + plugin->fb = data; + break; + case LFOPHASER_SPREAD: + plugin->spread = data; + break; + case LFOPHASER_INPUT: + plugin->input = data; + break; + case LFOPHASER_OUTPUT: + plugin->output = data; + break; + } +} + +static LADSPA_Handle instantiateLfoPhaser( + const LADSPA_Descriptor *descriptor, + unsigned long s_rate) { + LfoPhaser *plugin_data = (LfoPhaser *)malloc(sizeof(LfoPhaser)); + allpass *ap = NULL; + int count; + float f_per_lv; + int lfo_pos; + float *lfo_tbl = NULL; + float ym1; + +#line 80 "phasers_1217.xml" + unsigned int i; + float p; + + ap = calloc(6, sizeof(allpass)); + ym1 = 0.0f; + lfo_tbl = malloc(sizeof(float) * LFO_SIZE); + p = 0.0f; + for (i=0; iap = ap; + plugin_data->count = count; + plugin_data->f_per_lv = f_per_lv; + plugin_data->lfo_pos = lfo_pos; + plugin_data->lfo_tbl = lfo_tbl; + plugin_data->ym1 = ym1; + + return (LADSPA_Handle)plugin_data; +} + +#undef buffer_write +#undef RUN_ADDING +#undef RUN_REPLACING + +#define buffer_write(b, v) (b = v) +#define RUN_ADDING 0 +#define RUN_REPLACING 1 + +static void runLfoPhaser(LADSPA_Handle instance, unsigned long sample_count) { + LfoPhaser *plugin_data = (LfoPhaser *)instance; + + /* LFO rate (Hz) (float value) */ + const LADSPA_Data lfo_rate = *(plugin_data->lfo_rate); + + /* LFO depth (float value) */ + const LADSPA_Data lfo_depth = *(plugin_data->lfo_depth); + + /* Feedback (float value) */ + const LADSPA_Data fb = *(plugin_data->fb); + + /* Spread (octaves) (float value) */ + const LADSPA_Data spread = *(plugin_data->spread); + + /* Input (array of floats of length sample_count) */ + const LADSPA_Data * const input = plugin_data->input; + + /* Output (array of floats of length sample_count) */ + LADSPA_Data * const output = plugin_data->output; + allpass * ap = plugin_data->ap; + int count = plugin_data->count; + float f_per_lv = plugin_data->f_per_lv; + int lfo_pos = plugin_data->lfo_pos; + float * lfo_tbl = plugin_data->lfo_tbl; + float ym1 = plugin_data->ym1; + +#line 114 "phasers_1217.xml" + unsigned long pos; + unsigned int mod; + float y, d, ofs; + + mod = f_round(f_per_lv / lfo_rate); + if (mod < 1) { + mod=1; + } + + d = lfo_tbl[lfo_pos]; + + for (pos = 0; pos < sample_count; pos++) { + // Get new value for LFO if needed + if (++count % mod == 0) { + lfo_pos++; + lfo_pos &= 0x7FF; + count = 0; + d = lfo_tbl[lfo_pos] * lfo_depth; + + ap_set_delay(ap, d); + ofs = spread * 0.01562f; + ap_set_delay(ap+1, d+ofs); + ofs *= 2.0f; + ap_set_delay(ap+2, d+ofs); + ofs *= 2.0f; + ap_set_delay(ap+3, d+ofs); + ofs *= 2.0f; + ap_set_delay(ap+4, d+ofs); + ofs *= 2.0f; + ap_set_delay(ap+5, d+ofs); + + } + //Run in series, doesn't quite sound as nice + y = ap_run(ap, input[pos] + ym1 * fb); + y = ap_run(ap+1, y); + y = ap_run(ap+2, y); + y = ap_run(ap+3, y); + y = ap_run(ap+4, y); + y = ap_run(ap+5, y); + + buffer_write(output[pos], y); + ym1 = y; + } + + plugin_data->ym1 = ym1; + plugin_data->count = count; + plugin_data->lfo_pos = lfo_pos; +} +#undef buffer_write +#undef RUN_ADDING +#undef RUN_REPLACING + +#define buffer_write(b, v) (b += (v) * run_adding_gain) +#define RUN_ADDING 1 +#define RUN_REPLACING 0 + +static void setRunAddingGainLfoPhaser(LADSPA_Handle instance, LADSPA_Data gain) { + ((LfoPhaser *)instance)->run_adding_gain = gain; +} + +static void runAddingLfoPhaser(LADSPA_Handle instance, unsigned long sample_count) { + LfoPhaser *plugin_data = (LfoPhaser *)instance; + LADSPA_Data run_adding_gain = plugin_data->run_adding_gain; + + /* LFO rate (Hz) (float value) */ + const LADSPA_Data lfo_rate = *(plugin_data->lfo_rate); + + /* LFO depth (float value) */ + const LADSPA_Data lfo_depth = *(plugin_data->lfo_depth); + + /* Feedback (float value) */ + const LADSPA_Data fb = *(plugin_data->fb); + + /* Spread (octaves) (float value) */ + const LADSPA_Data spread = *(plugin_data->spread); + + /* Input (array of floats of length sample_count) */ + const LADSPA_Data * const input = plugin_data->input; + + /* Output (array of floats of length sample_count) */ + LADSPA_Data * const output = plugin_data->output; + allpass * ap = plugin_data->ap; + int count = plugin_data->count; + float f_per_lv = plugin_data->f_per_lv; + int lfo_pos = plugin_data->lfo_pos; + float * lfo_tbl = plugin_data->lfo_tbl; + float ym1 = plugin_data->ym1; + +#line 114 "phasers_1217.xml" + unsigned long pos; + unsigned int mod; + float y, d, ofs; + + mod = f_round(f_per_lv / lfo_rate); + if (mod < 1) { + mod=1; + } + + d = lfo_tbl[lfo_pos]; + + for (pos = 0; pos < sample_count; pos++) { + // Get new value for LFO if needed + if (++count % mod == 0) { + lfo_pos++; + lfo_pos &= 0x7FF; + count = 0; + d = lfo_tbl[lfo_pos] * lfo_depth; + + ap_set_delay(ap, d); + ofs = spread * 0.01562f; + ap_set_delay(ap+1, d+ofs); + ofs *= 2.0f; + ap_set_delay(ap+2, d+ofs); + ofs *= 2.0f; + ap_set_delay(ap+3, d+ofs); + ofs *= 2.0f; + ap_set_delay(ap+4, d+ofs); + ofs *= 2.0f; + ap_set_delay(ap+5, d+ofs); + + } + //Run in series, doesn't quite sound as nice + y = ap_run(ap, input[pos] + ym1 * fb); + y = ap_run(ap+1, y); + y = ap_run(ap+2, y); + y = ap_run(ap+3, y); + y = ap_run(ap+4, y); + y = ap_run(ap+5, y); + + buffer_write(output[pos], y); + ym1 = y; + } + + plugin_data->ym1 = ym1; + plugin_data->count = count; + plugin_data->lfo_pos = lfo_pos; +} + +static void activateFourByFourPole(LADSPA_Handle instance) { + FourByFourPole *plugin_data = (FourByFourPole *)instance; + allpass *ap = plugin_data->ap; + float sr_r_2 = plugin_data->sr_r_2; + float y0 = plugin_data->y0; + float y1 = plugin_data->y1; + float y2 = plugin_data->y2; + float y3 = plugin_data->y3; +#line 100 "phasers_1217.xml" + ap_clear(ap); + ap_clear(ap+1); + ap_clear(ap+2); + ap_clear(ap+3); + ap_clear(ap+4); + ap_clear(ap+5); + ap_clear(ap+6); + ap_clear(ap+7); + ap_clear(ap+8); + ap_clear(ap+9); + ap_clear(ap+10); + ap_clear(ap+11); + ap_clear(ap+12); + ap_clear(ap+13); + ap_clear(ap+14); + ap_clear(ap+15); + plugin_data->ap = ap; + plugin_data->sr_r_2 = sr_r_2; + plugin_data->y0 = y0; + plugin_data->y1 = y1; + plugin_data->y2 = y2; + plugin_data->y3 = y3; + +} + +static void cleanupFourByFourPole(LADSPA_Handle instance) { +#line 109 "phasers_1217.xml" + FourByFourPole *plugin_data = (FourByFourPole *)instance; + free(plugin_data->ap); + free(instance); +} + +static void connectPortFourByFourPole( + LADSPA_Handle instance, + unsigned long port, + LADSPA_Data *data) { + FourByFourPole *plugin; + + plugin = (FourByFourPole *)instance; + switch (port) { + case FOURBYFOURPOLE_F0: + plugin->f0 = data; + break; + case FOURBYFOURPOLE_FB0: + plugin->fb0 = data; + break; + case FOURBYFOURPOLE_F1: + plugin->f1 = data; + break; + case FOURBYFOURPOLE_FB1: + plugin->fb1 = data; + break; + case FOURBYFOURPOLE_F2: + plugin->f2 = data; + break; + case FOURBYFOURPOLE_FB2: + plugin->fb2 = data; + break; + case FOURBYFOURPOLE_F3: + plugin->f3 = data; + break; + case FOURBYFOURPOLE_FB3: + plugin->fb3 = data; + break; + case FOURBYFOURPOLE_INPUT: + plugin->input = data; + break; + case FOURBYFOURPOLE_OUTPUT: + plugin->output = data; + break; + } +} + +static LADSPA_Handle instantiateFourByFourPole( + const LADSPA_Descriptor *descriptor, + unsigned long s_rate) { + FourByFourPole *plugin_data = (FourByFourPole *)malloc(sizeof(FourByFourPole)); + allpass *ap = NULL; + float sr_r_2; + float y0; + float y1; + float y2; + float y3; + +#line 80 "phasers_1217.xml" + ap = calloc(16, sizeof(allpass)); + y0 = 0.0f; + y1 = 0.0f; + y2 = 0.0f; + y3 = 0.0f; + sr_r_2 = 1.0f / s_rate; + + plugin_data->ap = ap; + plugin_data->sr_r_2 = sr_r_2; + plugin_data->y0 = y0; + plugin_data->y1 = y1; + plugin_data->y2 = y2; + plugin_data->y3 = y3; + + return (LADSPA_Handle)plugin_data; +} + +#undef buffer_write +#undef RUN_ADDING +#undef RUN_REPLACING + +#define buffer_write(b, v) (b = v) +#define RUN_ADDING 0 +#define RUN_REPLACING 1 + +static void runFourByFourPole(LADSPA_Handle instance, unsigned long sample_count) { + FourByFourPole *plugin_data = (FourByFourPole *)instance; + + /* Frequency 1 (float value) */ + const LADSPA_Data f0 = *(plugin_data->f0); + + /* Feedback 1 (float value) */ + const LADSPA_Data fb0 = *(plugin_data->fb0); + + /* Frequency 2 (float value) */ + const LADSPA_Data f1 = *(plugin_data->f1); + + /* Feedback 2 (float value) */ + const LADSPA_Data fb1 = *(plugin_data->fb1); + + /* Frequency 3 (float value) */ + const LADSPA_Data f2 = *(plugin_data->f2); + + /* Feedback 3 (float value) */ + const LADSPA_Data fb2 = *(plugin_data->fb2); + + /* Frequency 4 (float value) */ + const LADSPA_Data f3 = *(plugin_data->f3); + + /* Feedback 4 (float value) */ + const LADSPA_Data fb3 = *(plugin_data->fb3); + + /* Input (array of floats of length sample_count) */ + const LADSPA_Data * const input = plugin_data->input; + + /* Output (array of floats of length sample_count) */ + LADSPA_Data * const output = plugin_data->output; + allpass * ap = plugin_data->ap; + float sr_r_2 = plugin_data->sr_r_2; + float y0 = plugin_data->y0; + float y1 = plugin_data->y1; + float y2 = plugin_data->y2; + float y3 = plugin_data->y3; + +#line 114 "phasers_1217.xml" + unsigned long pos; + + ap_set_delay(ap, f0 * sr_r_2); + ap_set_delay(ap+1, f0 * sr_r_2); + ap_set_delay(ap+2, f0 * sr_r_2); + ap_set_delay(ap+3, f0 * sr_r_2); + ap_set_delay(ap+4, f1 * sr_r_2); + ap_set_delay(ap+5, f1 * sr_r_2); + ap_set_delay(ap+6, f1 * sr_r_2); + ap_set_delay(ap+7, f1 * sr_r_2); + ap_set_delay(ap+8, f2 * sr_r_2); + ap_set_delay(ap+9, f2 * sr_r_2); + ap_set_delay(ap+10, f2 * sr_r_2); + ap_set_delay(ap+11, f2 * sr_r_2); + ap_set_delay(ap+12, f3 * sr_r_2); + ap_set_delay(ap+13, f3 * sr_r_2); + ap_set_delay(ap+14, f3 * sr_r_2); + ap_set_delay(ap+15, f3 * sr_r_2); + + for (pos = 0; pos < sample_count; pos++) { + y0 = ap_run(ap, input[pos] + y0 * fb0); + y0 = ap_run(ap+1, y0); + y0 = ap_run(ap+2, y0); + y0 = ap_run(ap+3, y0); + + y1 = ap_run(ap+4, y0 + y1 * fb1); + y1 = ap_run(ap+5, y1); + y1 = ap_run(ap+6, y1); + y1 = ap_run(ap+7, y1); + + y2 = ap_run(ap+8, y1 + y2 * fb2); + y2 = ap_run(ap+9, y2); + y2 = ap_run(ap+10, y2); + y2 = ap_run(ap+11, y2); + + y3 = ap_run(ap+12, y2 + y3 * fb3); + y3 = ap_run(ap+13, y3); + y3 = ap_run(ap+14, y3); + y3 = ap_run(ap+15, y3); + + buffer_write(output[pos], y3); + } + + plugin_data->y0 = y0; + plugin_data->y1 = y1; + plugin_data->y2 = y2; + plugin_data->y3 = y3; +} +#undef buffer_write +#undef RUN_ADDING +#undef RUN_REPLACING + +#define buffer_write(b, v) (b += (v) * run_adding_gain) +#define RUN_ADDING 1 +#define RUN_REPLACING 0 + +static void setRunAddingGainFourByFourPole(LADSPA_Handle instance, LADSPA_Data gain) { + ((FourByFourPole *)instance)->run_adding_gain = gain; +} + +static void runAddingFourByFourPole(LADSPA_Handle instance, unsigned long sample_count) { + FourByFourPole *plugin_data = (FourByFourPole *)instance; + LADSPA_Data run_adding_gain = plugin_data->run_adding_gain; + + /* Frequency 1 (float value) */ + const LADSPA_Data f0 = *(plugin_data->f0); + + /* Feedback 1 (float value) */ + const LADSPA_Data fb0 = *(plugin_data->fb0); + + /* Frequency 2 (float value) */ + const LADSPA_Data f1 = *(plugin_data->f1); + + /* Feedback 2 (float value) */ + const LADSPA_Data fb1 = *(plugin_data->fb1); + + /* Frequency 3 (float value) */ + const LADSPA_Data f2 = *(plugin_data->f2); + + /* Feedback 3 (float value) */ + const LADSPA_Data fb2 = *(plugin_data->fb2); + + /* Frequency 4 (float value) */ + const LADSPA_Data f3 = *(plugin_data->f3); + + /* Feedback 4 (float value) */ + const LADSPA_Data fb3 = *(plugin_data->fb3); + + /* Input (array of floats of length sample_count) */ + const LADSPA_Data * const input = plugin_data->input; + + /* Output (array of floats of length sample_count) */ + LADSPA_Data * const output = plugin_data->output; + allpass * ap = plugin_data->ap; + float sr_r_2 = plugin_data->sr_r_2; + float y0 = plugin_data->y0; + float y1 = plugin_data->y1; + float y2 = plugin_data->y2; + float y3 = plugin_data->y3; + +#line 114 "phasers_1217.xml" + unsigned long pos; + + ap_set_delay(ap, f0 * sr_r_2); + ap_set_delay(ap+1, f0 * sr_r_2); + ap_set_delay(ap+2, f0 * sr_r_2); + ap_set_delay(ap+3, f0 * sr_r_2); + ap_set_delay(ap+4, f1 * sr_r_2); + ap_set_delay(ap+5, f1 * sr_r_2); + ap_set_delay(ap+6, f1 * sr_r_2); + ap_set_delay(ap+7, f1 * sr_r_2); + ap_set_delay(ap+8, f2 * sr_r_2); + ap_set_delay(ap+9, f2 * sr_r_2); + ap_set_delay(ap+10, f2 * sr_r_2); + ap_set_delay(ap+11, f2 * sr_r_2); + ap_set_delay(ap+12, f3 * sr_r_2); + ap_set_delay(ap+13, f3 * sr_r_2); + ap_set_delay(ap+14, f3 * sr_r_2); + ap_set_delay(ap+15, f3 * sr_r_2); + + for (pos = 0; pos < sample_count; pos++) { + y0 = ap_run(ap, input[pos] + y0 * fb0); + y0 = ap_run(ap+1, y0); + y0 = ap_run(ap+2, y0); + y0 = ap_run(ap+3, y0); + + y1 = ap_run(ap+4, y0 + y1 * fb1); + y1 = ap_run(ap+5, y1); + y1 = ap_run(ap+6, y1); + y1 = ap_run(ap+7, y1); + + y2 = ap_run(ap+8, y1 + y2 * fb2); + y2 = ap_run(ap+9, y2); + y2 = ap_run(ap+10, y2); + y2 = ap_run(ap+11, y2); + + y3 = ap_run(ap+12, y2 + y3 * fb3); + y3 = ap_run(ap+13, y3); + y3 = ap_run(ap+14, y3); + y3 = ap_run(ap+15, y3); + + buffer_write(output[pos], y3); + } + + plugin_data->y0 = y0; + plugin_data->y1 = y1; + plugin_data->y2 = y2; + plugin_data->y3 = y3; +} + +static void activateAutoPhaser(LADSPA_Handle instance) { + AutoPhaser *plugin_data = (AutoPhaser *)instance; + allpass *ap = plugin_data->ap; + envelope *env = plugin_data->env; + float sample_rate = plugin_data->sample_rate; + float ym1 = plugin_data->ym1; +#line 100 "phasers_1217.xml" + ap_clear(ap); + ap_clear(ap+1); + ap_clear(ap+2); + ap_clear(ap+3); + ap_clear(ap+4); + ap_clear(ap+5); + plugin_data->ap = ap; + plugin_data->env = env; + plugin_data->sample_rate = sample_rate; + plugin_data->ym1 = ym1; + +} + +static void cleanupAutoPhaser(LADSPA_Handle instance) { +#line 109 "phasers_1217.xml" + AutoPhaser *plugin_data = (AutoPhaser *)instance; + free(plugin_data->ap); + free(plugin_data->env); + free(instance); +} + +static void connectPortAutoPhaser( + LADSPA_Handle instance, + unsigned long port, + LADSPA_Data *data) { + AutoPhaser *plugin; + + plugin = (AutoPhaser *)instance; + switch (port) { + case AUTOPHASER_ATTACK_P: + plugin->attack_p = data; + break; + case AUTOPHASER_DECAY_P: + plugin->decay_p = data; + break; + case AUTOPHASER_DEPTH_P: + plugin->depth_p = data; + break; + case AUTOPHASER_FB: + plugin->fb = data; + break; + case AUTOPHASER_SPREAD: + plugin->spread = data; + break; + case AUTOPHASER_INPUT: + plugin->input = data; + break; + case AUTOPHASER_OUTPUT: + plugin->output = data; + break; + } +} + +static LADSPA_Handle instantiateAutoPhaser( + const LADSPA_Descriptor *descriptor, + unsigned long s_rate) { + AutoPhaser *plugin_data = (AutoPhaser *)malloc(sizeof(AutoPhaser)); + allpass *ap = NULL; + envelope *env = NULL; + float sample_rate; + float ym1; + +#line 80 "phasers_1217.xml" + ap = calloc(6, sizeof(allpass)); + env = calloc(1, sizeof(envelope)); + ym1 = 0.0f; + sample_rate = (float)s_rate; + + plugin_data->ap = ap; + plugin_data->env = env; + plugin_data->sample_rate = sample_rate; + plugin_data->ym1 = ym1; + + return (LADSPA_Handle)plugin_data; +} + +#undef buffer_write +#undef RUN_ADDING +#undef RUN_REPLACING + +#define buffer_write(b, v) (b = v) +#define RUN_ADDING 0 +#define RUN_REPLACING 1 + +static void runAutoPhaser(LADSPA_Handle instance, unsigned long sample_count) { + AutoPhaser *plugin_data = (AutoPhaser *)instance; + + /* Attack time (s) (float value) */ + const LADSPA_Data attack_p = *(plugin_data->attack_p); + + /* Decay time (s) (float value) */ + const LADSPA_Data decay_p = *(plugin_data->decay_p); + + /* Modulation depth (float value) */ + const LADSPA_Data depth_p = *(plugin_data->depth_p); + + /* Feedback (float value) */ + const LADSPA_Data fb = *(plugin_data->fb); + + /* Spread (octaves) (float value) */ + const LADSPA_Data spread = *(plugin_data->spread); + + /* Input (array of floats of length sample_count) */ + const LADSPA_Data * const input = plugin_data->input; + + /* Output (array of floats of length sample_count) */ + LADSPA_Data * const output = plugin_data->output; + allpass * ap = plugin_data->ap; + envelope * env = plugin_data->env; + float sample_rate = plugin_data->sample_rate; + float ym1 = plugin_data->ym1; + +#line 114 "phasers_1217.xml" + unsigned long pos; + float y, d, ofs; + float attack = attack_p; + float decay = decay_p; + const float depth = depth_p * 0.5f; + + if (attack < 0.01f) { + attack = 0.01f; + } + if (decay < 0.01f) { + decay = 0.01f; + } + env_set_attack(env, attack * sample_rate * 0.25f); + env_set_release(env, decay * sample_rate * 0.25f); + + + for (pos = 0; pos < sample_count; pos++) { + if (pos % 4 == 0) { + d = env_run(env, input[pos]) * depth; + ap_set_delay(ap, d); + ofs = spread * 0.01562f; + ap_set_delay(ap+1, d+ofs); + ofs *= 2.0f; + ap_set_delay(ap+2, d+ofs); + ofs *= 2.0f; + ap_set_delay(ap+3, d+ofs); + ofs *= 2.0f; + ap_set_delay(ap+4, d+ofs); + ofs *= 2.0f; + ap_set_delay(ap+5, d+ofs); + } + + //Run allpass filters in series + y = ap_run(ap, input[pos] + ym1 * fb); + y = ap_run(ap+1, y); + y = ap_run(ap+2, y); + y = ap_run(ap+3, y); + y = ap_run(ap+4, y); + y = ap_run(ap+5, y); + + buffer_write(output[pos], y); + ym1 = y; + } + + plugin_data->ym1 = ym1; +} +#undef buffer_write +#undef RUN_ADDING +#undef RUN_REPLACING + +#define buffer_write(b, v) (b += (v) * run_adding_gain) +#define RUN_ADDING 1 +#define RUN_REPLACING 0 + +static void setRunAddingGainAutoPhaser(LADSPA_Handle instance, LADSPA_Data gain) { + ((AutoPhaser *)instance)->run_adding_gain = gain; +} + +static void runAddingAutoPhaser(LADSPA_Handle instance, unsigned long sample_count) { + AutoPhaser *plugin_data = (AutoPhaser *)instance; + LADSPA_Data run_adding_gain = plugin_data->run_adding_gain; + + /* Attack time (s) (float value) */ + const LADSPA_Data attack_p = *(plugin_data->attack_p); + + /* Decay time (s) (float value) */ + const LADSPA_Data decay_p = *(plugin_data->decay_p); + + /* Modulation depth (float value) */ + const LADSPA_Data depth_p = *(plugin_data->depth_p); + + /* Feedback (float value) */ + const LADSPA_Data fb = *(plugin_data->fb); + + /* Spread (octaves) (float value) */ + const LADSPA_Data spread = *(plugin_data->spread); + + /* Input (array of floats of length sample_count) */ + const LADSPA_Data * const input = plugin_data->input; + + /* Output (array of floats of length sample_count) */ + LADSPA_Data * const output = plugin_data->output; + allpass * ap = plugin_data->ap; + envelope * env = plugin_data->env; + float sample_rate = plugin_data->sample_rate; + float ym1 = plugin_data->ym1; + +#line 114 "phasers_1217.xml" + unsigned long pos; + float y, d, ofs; + float attack = attack_p; + float decay = decay_p; + const float depth = depth_p * 0.5f; + + if (attack < 0.01f) { + attack = 0.01f; + } + if (decay < 0.01f) { + decay = 0.01f; + } + env_set_attack(env, attack * sample_rate * 0.25f); + env_set_release(env, decay * sample_rate * 0.25f); + + + for (pos = 0; pos < sample_count; pos++) { + if (pos % 4 == 0) { + d = env_run(env, input[pos]) * depth; + ap_set_delay(ap, d); + ofs = spread * 0.01562f; + ap_set_delay(ap+1, d+ofs); + ofs *= 2.0f; + ap_set_delay(ap+2, d+ofs); + ofs *= 2.0f; + ap_set_delay(ap+3, d+ofs); + ofs *= 2.0f; + ap_set_delay(ap+4, d+ofs); + ofs *= 2.0f; + ap_set_delay(ap+5, d+ofs); + } + + //Run allpass filters in series + y = ap_run(ap, input[pos] + ym1 * fb); + y = ap_run(ap+1, y); + y = ap_run(ap+2, y); + y = ap_run(ap+3, y); + y = ap_run(ap+4, y); + y = ap_run(ap+5, y); + + buffer_write(output[pos], y); + ym1 = y; + } + + plugin_data->ym1 = ym1; +} + +void _init() { + char **port_names; + LADSPA_PortDescriptor *port_descriptors; + LADSPA_PortRangeHint *port_range_hints; + +#ifdef ENABLE_NLS +#define D_(s) dgettext(PACKAGE, s) + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, PACKAGE_LOCALE_DIR); +#else +#define D_(s) (s) +#endif + + + lfoPhaserDescriptor = + (LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor)); + + if (lfoPhaserDescriptor) { + lfoPhaserDescriptor->UniqueID = 1217; + lfoPhaserDescriptor->Label = "lfoPhaser"; + lfoPhaserDescriptor->Properties = + LADSPA_PROPERTY_HARD_RT_CAPABLE; + lfoPhaserDescriptor->Name = + D_("LFO Phaser"); + lfoPhaserDescriptor->Maker = + "Steve Harris "; + lfoPhaserDescriptor->Copyright = + "GPL"; + lfoPhaserDescriptor->PortCount = 6; + + port_descriptors = (LADSPA_PortDescriptor *)calloc(6, + sizeof(LADSPA_PortDescriptor)); + lfoPhaserDescriptor->PortDescriptors = + (const LADSPA_PortDescriptor *)port_descriptors; + + port_range_hints = (LADSPA_PortRangeHint *)calloc(6, + sizeof(LADSPA_PortRangeHint)); + lfoPhaserDescriptor->PortRangeHints = + (const LADSPA_PortRangeHint *)port_range_hints; + + port_names = (char **)calloc(6, sizeof(char*)); + lfoPhaserDescriptor->PortNames = + (const char **)port_names; + + /* Parameters for LFO rate (Hz) */ + port_descriptors[LFOPHASER_LFO_RATE] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[LFOPHASER_LFO_RATE] = + D_("LFO rate (Hz)"); + port_range_hints[LFOPHASER_LFO_RATE].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_LOW; + port_range_hints[LFOPHASER_LFO_RATE].LowerBound = 0; + port_range_hints[LFOPHASER_LFO_RATE].UpperBound = 100; + + /* Parameters for LFO depth */ + port_descriptors[LFOPHASER_LFO_DEPTH] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[LFOPHASER_LFO_DEPTH] = + D_("LFO depth"); + port_range_hints[LFOPHASER_LFO_DEPTH].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_LOW; + port_range_hints[LFOPHASER_LFO_DEPTH].LowerBound = 0; + port_range_hints[LFOPHASER_LFO_DEPTH].UpperBound = 1; + + /* Parameters for Feedback */ + port_descriptors[LFOPHASER_FB] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[LFOPHASER_FB] = + D_("Feedback"); + port_range_hints[LFOPHASER_FB].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0; + port_range_hints[LFOPHASER_FB].LowerBound = -1; + port_range_hints[LFOPHASER_FB].UpperBound = 1; + + /* Parameters for Spread (octaves) */ + port_descriptors[LFOPHASER_SPREAD] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[LFOPHASER_SPREAD] = + D_("Spread (octaves)"); + port_range_hints[LFOPHASER_SPREAD].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_MIDDLE; + port_range_hints[LFOPHASER_SPREAD].LowerBound = 0; + port_range_hints[LFOPHASER_SPREAD].UpperBound = 2; + + /* Parameters for Input */ + port_descriptors[LFOPHASER_INPUT] = + LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO; + port_names[LFOPHASER_INPUT] = + D_("Input"); + port_range_hints[LFOPHASER_INPUT].HintDescriptor = 0; + + /* Parameters for Output */ + port_descriptors[LFOPHASER_OUTPUT] = + LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO; + port_names[LFOPHASER_OUTPUT] = + D_("Output"); + port_range_hints[LFOPHASER_OUTPUT].HintDescriptor = 0; + + lfoPhaserDescriptor->activate = activateLfoPhaser; + lfoPhaserDescriptor->cleanup = cleanupLfoPhaser; + lfoPhaserDescriptor->connect_port = connectPortLfoPhaser; + lfoPhaserDescriptor->deactivate = NULL; + lfoPhaserDescriptor->instantiate = instantiateLfoPhaser; + lfoPhaserDescriptor->run = runLfoPhaser; + lfoPhaserDescriptor->run_adding = runAddingLfoPhaser; + lfoPhaserDescriptor->set_run_adding_gain = setRunAddingGainLfoPhaser; + } + + fourByFourPoleDescriptor = + (LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor)); + + if (fourByFourPoleDescriptor) { + fourByFourPoleDescriptor->UniqueID = 1218; + fourByFourPoleDescriptor->Label = "fourByFourPole"; + fourByFourPoleDescriptor->Properties = + LADSPA_PROPERTY_HARD_RT_CAPABLE; + fourByFourPoleDescriptor->Name = + D_("4 x 4 pole allpass"); + fourByFourPoleDescriptor->Maker = + "Steve Harris "; + fourByFourPoleDescriptor->Copyright = + "GPL"; + fourByFourPoleDescriptor->PortCount = 10; + + port_descriptors = (LADSPA_PortDescriptor *)calloc(10, + sizeof(LADSPA_PortDescriptor)); + fourByFourPoleDescriptor->PortDescriptors = + (const LADSPA_PortDescriptor *)port_descriptors; + + port_range_hints = (LADSPA_PortRangeHint *)calloc(10, + sizeof(LADSPA_PortRangeHint)); + fourByFourPoleDescriptor->PortRangeHints = + (const LADSPA_PortRangeHint *)port_range_hints; + + port_names = (char **)calloc(10, sizeof(char*)); + fourByFourPoleDescriptor->PortNames = + (const char **)port_names; + + /* Parameters for Frequency 1 */ + port_descriptors[FOURBYFOURPOLE_F0] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[FOURBYFOURPOLE_F0] = + D_("Frequency 1"); + port_range_hints[FOURBYFOURPOLE_F0].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_LOW; + port_range_hints[FOURBYFOURPOLE_F0].LowerBound = 1; + port_range_hints[FOURBYFOURPOLE_F0].UpperBound = 20000; + + /* Parameters for Feedback 1 */ + port_descriptors[FOURBYFOURPOLE_FB0] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[FOURBYFOURPOLE_FB0] = + D_("Feedback 1"); + port_range_hints[FOURBYFOURPOLE_FB0].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0; + port_range_hints[FOURBYFOURPOLE_FB0].LowerBound = -1; + port_range_hints[FOURBYFOURPOLE_FB0].UpperBound = 1; + + /* Parameters for Frequency 2 */ + port_descriptors[FOURBYFOURPOLE_F1] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[FOURBYFOURPOLE_F1] = + D_("Frequency 2"); + port_range_hints[FOURBYFOURPOLE_F1].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_MIDDLE; + port_range_hints[FOURBYFOURPOLE_F1].LowerBound = 1; + port_range_hints[FOURBYFOURPOLE_F1].UpperBound = 20000; + + /* Parameters for Feedback 2 */ + port_descriptors[FOURBYFOURPOLE_FB1] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[FOURBYFOURPOLE_FB1] = + D_("Feedback 2"); + port_range_hints[FOURBYFOURPOLE_FB1].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0; + port_range_hints[FOURBYFOURPOLE_FB1].LowerBound = -1; + port_range_hints[FOURBYFOURPOLE_FB1].UpperBound = 1; + + /* Parameters for Frequency 3 */ + port_descriptors[FOURBYFOURPOLE_F2] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[FOURBYFOURPOLE_F2] = + D_("Frequency 3"); + port_range_hints[FOURBYFOURPOLE_F2].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_HIGH; + port_range_hints[FOURBYFOURPOLE_F2].LowerBound = 1; + port_range_hints[FOURBYFOURPOLE_F2].UpperBound = 20000; + + /* Parameters for Feedback 3 */ + port_descriptors[FOURBYFOURPOLE_FB2] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[FOURBYFOURPOLE_FB2] = + D_("Feedback 3"); + port_range_hints[FOURBYFOURPOLE_FB2].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0; + port_range_hints[FOURBYFOURPOLE_FB2].LowerBound = -1; + port_range_hints[FOURBYFOURPOLE_FB2].UpperBound = 1; + + /* Parameters for Frequency 4 */ + port_descriptors[FOURBYFOURPOLE_F3] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[FOURBYFOURPOLE_F3] = + D_("Frequency 4"); + port_range_hints[FOURBYFOURPOLE_F3].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_MAXIMUM; + port_range_hints[FOURBYFOURPOLE_F3].LowerBound = 1; + port_range_hints[FOURBYFOURPOLE_F3].UpperBound = 20000; + + /* Parameters for Feedback 4 */ + port_descriptors[FOURBYFOURPOLE_FB3] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[FOURBYFOURPOLE_FB3] = + D_("Feedback 4"); + port_range_hints[FOURBYFOURPOLE_FB3].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0; + port_range_hints[FOURBYFOURPOLE_FB3].LowerBound = -1; + port_range_hints[FOURBYFOURPOLE_FB3].UpperBound = 1; + + /* Parameters for Input */ + port_descriptors[FOURBYFOURPOLE_INPUT] = + LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO; + port_names[FOURBYFOURPOLE_INPUT] = + D_("Input"); + port_range_hints[FOURBYFOURPOLE_INPUT].HintDescriptor = 0; + + /* Parameters for Output */ + port_descriptors[FOURBYFOURPOLE_OUTPUT] = + LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO; + port_names[FOURBYFOURPOLE_OUTPUT] = + D_("Output"); + port_range_hints[FOURBYFOURPOLE_OUTPUT].HintDescriptor = 0; + + fourByFourPoleDescriptor->activate = activateFourByFourPole; + fourByFourPoleDescriptor->cleanup = cleanupFourByFourPole; + fourByFourPoleDescriptor->connect_port = connectPortFourByFourPole; + fourByFourPoleDescriptor->deactivate = NULL; + fourByFourPoleDescriptor->instantiate = instantiateFourByFourPole; + fourByFourPoleDescriptor->run = runFourByFourPole; + fourByFourPoleDescriptor->run_adding = runAddingFourByFourPole; + fourByFourPoleDescriptor->set_run_adding_gain = setRunAddingGainFourByFourPole; + } + + autoPhaserDescriptor = + (LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor)); + + if (autoPhaserDescriptor) { + autoPhaserDescriptor->UniqueID = 1219; + autoPhaserDescriptor->Label = "autoPhaser"; + autoPhaserDescriptor->Properties = + LADSPA_PROPERTY_HARD_RT_CAPABLE; + autoPhaserDescriptor->Name = + D_("Auto phaser"); + autoPhaserDescriptor->Maker = + "Steve Harris "; + autoPhaserDescriptor->Copyright = + "GPL"; + autoPhaserDescriptor->PortCount = 7; + + port_descriptors = (LADSPA_PortDescriptor *)calloc(7, + sizeof(LADSPA_PortDescriptor)); + autoPhaserDescriptor->PortDescriptors = + (const LADSPA_PortDescriptor *)port_descriptors; + + port_range_hints = (LADSPA_PortRangeHint *)calloc(7, + sizeof(LADSPA_PortRangeHint)); + autoPhaserDescriptor->PortRangeHints = + (const LADSPA_PortRangeHint *)port_range_hints; + + port_names = (char **)calloc(7, sizeof(char*)); + autoPhaserDescriptor->PortNames = + (const char **)port_names; + + /* Parameters for Attack time (s) */ + port_descriptors[AUTOPHASER_ATTACK_P] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[AUTOPHASER_ATTACK_P] = + D_("Attack time (s)"); + port_range_hints[AUTOPHASER_ATTACK_P].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_LOW; + port_range_hints[AUTOPHASER_ATTACK_P].LowerBound = 0; + port_range_hints[AUTOPHASER_ATTACK_P].UpperBound = 1; + + /* Parameters for Decay time (s) */ + port_descriptors[AUTOPHASER_DECAY_P] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[AUTOPHASER_DECAY_P] = + D_("Decay time (s)"); + port_range_hints[AUTOPHASER_DECAY_P].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_LOW; + port_range_hints[AUTOPHASER_DECAY_P].LowerBound = 0; + port_range_hints[AUTOPHASER_DECAY_P].UpperBound = 1; + + /* Parameters for Modulation depth */ + port_descriptors[AUTOPHASER_DEPTH_P] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[AUTOPHASER_DEPTH_P] = + D_("Modulation depth"); + port_range_hints[AUTOPHASER_DEPTH_P].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_LOW; + port_range_hints[AUTOPHASER_DEPTH_P].LowerBound = 0; + port_range_hints[AUTOPHASER_DEPTH_P].UpperBound = 1; + + /* Parameters for Feedback */ + port_descriptors[AUTOPHASER_FB] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[AUTOPHASER_FB] = + D_("Feedback"); + port_range_hints[AUTOPHASER_FB].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0; + port_range_hints[AUTOPHASER_FB].LowerBound = -1; + port_range_hints[AUTOPHASER_FB].UpperBound = 1; + + /* Parameters for Spread (octaves) */ + port_descriptors[AUTOPHASER_SPREAD] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[AUTOPHASER_SPREAD] = + D_("Spread (octaves)"); + port_range_hints[AUTOPHASER_SPREAD].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_1; + port_range_hints[AUTOPHASER_SPREAD].LowerBound = 0; + port_range_hints[AUTOPHASER_SPREAD].UpperBound = 2; + + /* Parameters for Input */ + port_descriptors[AUTOPHASER_INPUT] = + LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO; + port_names[AUTOPHASER_INPUT] = + D_("Input"); + port_range_hints[AUTOPHASER_INPUT].HintDescriptor = 0; + + /* Parameters for Output */ + port_descriptors[AUTOPHASER_OUTPUT] = + LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO; + port_names[AUTOPHASER_OUTPUT] = + D_("Output"); + port_range_hints[AUTOPHASER_OUTPUT].HintDescriptor = 0; + + autoPhaserDescriptor->activate = activateAutoPhaser; + autoPhaserDescriptor->cleanup = cleanupAutoPhaser; + autoPhaserDescriptor->connect_port = connectPortAutoPhaser; + autoPhaserDescriptor->deactivate = NULL; + autoPhaserDescriptor->instantiate = instantiateAutoPhaser; + autoPhaserDescriptor->run = runAutoPhaser; + autoPhaserDescriptor->run_adding = runAddingAutoPhaser; + autoPhaserDescriptor->set_run_adding_gain = setRunAddingGainAutoPhaser; + } +} + +void _fini() { + if (lfoPhaserDescriptor) { + free((LADSPA_PortDescriptor *)lfoPhaserDescriptor->PortDescriptors); + free((char **)lfoPhaserDescriptor->PortNames); + free((LADSPA_PortRangeHint *)lfoPhaserDescriptor->PortRangeHints); + free(lfoPhaserDescriptor); + } + if (fourByFourPoleDescriptor) { + free((LADSPA_PortDescriptor *)fourByFourPoleDescriptor->PortDescriptors); + free((char **)fourByFourPoleDescriptor->PortNames); + free((LADSPA_PortRangeHint *)fourByFourPoleDescriptor->PortRangeHints); + free(fourByFourPoleDescriptor); + } + if (autoPhaserDescriptor) { + free((LADSPA_PortDescriptor *)autoPhaserDescriptor->PortDescriptors); + free((char **)autoPhaserDescriptor->PortNames); + free((LADSPA_PortRangeHint *)autoPhaserDescriptor->PortRangeHints); + free(autoPhaserDescriptor); + } + +} diff --git a/plugins/ladspa_effect/swh/util/biquad.h b/plugins/ladspa_effect/swh/util/biquad.h new file mode 100644 index 000000000..64f890a81 --- /dev/null +++ b/plugins/ladspa_effect/swh/util/biquad.h @@ -0,0 +1,179 @@ +#ifndef BIQUAD_H +#define BIQUAD_H + +#define LN_2_2 0.34657359f // ln(2)/2 + +#include "ladspa-util.h" + +#ifndef LIMIT +#define LIMIT(v,l,u) (vu?u:v)) +#endif + +#ifndef BIQUAD_TYPE +#define BIQUAD_TYPE float +#endif + +typedef BIQUAD_TYPE bq_t; + +/* Biquad filter (adapted from lisp code by Eli Brandt, + http://www.cs.cmu.edu/~eli/) */ + +typedef struct { + bq_t a1; + bq_t a2; + bq_t b0; + bq_t b1; + bq_t b2; + bq_t x1; + bq_t x2; + bq_t y1; + bq_t y2; +} biquad; + +static inline void biquad_init(biquad *f) { + f->x1 = 0.0f; + f->x2 = 0.0f; + f->y1 = 0.0f; + f->y2 = 0.0f; +} + +static inline void eq_set_params(biquad *f, bq_t fc, bq_t gain, bq_t bw, + bq_t fs); +static inline void eq_set_params(biquad *f, bq_t fc, bq_t gain, bq_t bw, + bq_t fs) +{ + bq_t w = 2.0f * M_PI * LIMIT(fc, 1.0f, fs/2.0f) / fs; + bq_t cw = cosf(w); + bq_t sw = sinf(w); + bq_t J = pow(10.0f, gain * 0.025f); + bq_t g = sw * sinhf(LN_2_2 * LIMIT(bw, 0.0001f, 4.0f) * w / sw); + bq_t a0r = 1.0f / (1.0f + (g / J)); + + f->b0 = (1.0f + (g * J)) * a0r; + f->b1 = (-2.0f * cw) * a0r; + f->b2 = (1.0f - (g * J)) * a0r; + f->a1 = -(f->b1); + f->a2 = ((g / J) - 1.0f) * a0r; +} + +static inline void ls_set_params(biquad *f, bq_t fc, bq_t gain, bq_t slope, + bq_t fs); +static inline void ls_set_params(biquad *f, bq_t fc, bq_t gain, bq_t slope, + bq_t fs) +{ + bq_t w = 2.0f * M_PI * LIMIT(fc, 1.0, fs/2.0) / fs; + bq_t cw = cosf(w); + bq_t sw = sinf(w); + bq_t A = powf(10.0f, gain * 0.025f); + bq_t b = sqrt(((1.0f + A * A) / LIMIT(slope, 0.0001f, 1.0f)) - ((A - + 1.0f) * (A - 1.0))); + bq_t apc = cw * (A + 1.0f); + bq_t amc = cw * (A - 1.0f); + bq_t bs = b * sw; + bq_t a0r = 1.0f / (A + 1.0f + amc + bs); + + f->b0 = a0r * A * (A + 1.0f - amc + bs); + f->b1 = a0r * 2.0f * A * (A - 1.0f - apc); + f->b2 = a0r * A * (A + 1.0f - amc - bs); + f->a1 = a0r * 2.0f * (A - 1.0f + apc); + f->a2 = a0r * (-A - 1.0f - amc + bs); +} + +static inline void hs_set_params(biquad *f, bq_t fc, bq_t gain, bq_t slope, + bq_t fs); +static inline void hs_set_params(biquad *f, bq_t fc, bq_t gain, bq_t slope, + bq_t fs) +{ + bq_t w = 2.0f * M_PI * LIMIT(fc, 1.0, fs/2.0) / fs; + bq_t cw = cosf(w); + bq_t sw = sinf(w); + bq_t A = powf(10.0f, gain * 0.025f); + bq_t b = sqrt(((1.0f + A * A) / LIMIT(slope, 0.0001f, 1.0f)) - ((A - + 1.0f) * (A - 1.0f))); + bq_t apc = cw * (A + 1.0f); + bq_t amc = cw * (A - 1.0f); + bq_t bs = b * sw; + bq_t a0r = 1.0f / (A + 1.0f - amc + bs); + + f->b0 = a0r * A * (A + 1.0f + amc + bs); + f->b1 = a0r * -2.0f * A * (A - 1.0f + apc); + f->b2 = a0r * A * (A + 1.0f + amc - bs); + f->a1 = a0r * -2.0f * (A - 1.0f - apc); + f->a2 = a0r * (-A - 1.0f + amc + bs); +} + +static inline void lp_set_params(biquad *f, bq_t fc, bq_t bw, bq_t fs) +{ + bq_t omega = 2.0 * M_PI * fc/fs; + bq_t sn = sin(omega); + bq_t cs = cos(omega); + bq_t alpha = sn * sinh(M_LN2 / 2.0 * bw * omega / sn); + + const float a0r = 1.0 / (1.0 + alpha); + f->b0 = a0r * (1.0 - cs) * 0.5; + f->b1 = a0r * (1.0 - cs); + f->b2 = a0r * (1.0 - cs) * 0.5; + f->a1 = a0r * (2.0 * cs); + f->a2 = a0r * (alpha - 1.0); +} + +static inline void hp_set_params(biquad *f, bq_t fc, bq_t bw, bq_t fs) +{ + bq_t omega = 2.0 * M_PI * fc/fs; + bq_t sn = sin(omega); + bq_t cs = cos(omega); + bq_t alpha = sn * sinh(M_LN2 / 2.0 * bw * omega / sn); + + const float a0r = 1.0 / (1.0 + alpha); + f->b0 = a0r * (1.0 + cs) * 0.5; + f->b1 = a0r * -(1.0 + cs); + f->b2 = a0r * (1.0 + cs) * 0.5; + f->a1 = a0r * (2.0 * cs); + f->a2 = a0r * (alpha - 1.0); +} + +static inline void bp_set_params(biquad *f, bq_t fc, bq_t bw, bq_t fs) +{ + bq_t omega = 2.0 * M_PI * fc/fs; + bq_t sn = sin(omega); + bq_t cs = cos(omega); + bq_t alpha = sn * sinh(M_LN2 / 2.0 * bw * omega / sn); + + const float a0r = 1.0 / (1.0 + alpha); + f->b0 = a0r * alpha; + f->b1 = 0.0; + f->b2 = a0r * -alpha; + f->a1 = a0r * (2.0 * cs); + f->a2 = a0r * (alpha - 1.0); +} + +static inline bq_t biquad_run(biquad *f, const bq_t x) { + bq_t y; + + y = f->b0 * x + f->b1 * f->x1 + f->b2 * f->x2 + + f->a1 * f->y1 + f->a2 * f->y2; + y = flush_to_zero(y); + f->x2 = f->x1; + f->x1 = x; + f->y2 = f->y1; + f->y1 = y; + + return y; +} + +static inline bq_t biquad_run_fb(biquad *f, bq_t x, const bq_t fb) { + bq_t y; + + x += f->y1 * fb * 0.98; + y = f->b0 * x + f->b1 * f->x1 + f->b2 * f->x2 + + f->a1 * f->y1 + f->a2 * f->y2; + y = flush_to_zero(y); + f->x2 = f->x1; + f->x1 = x; + f->y2 = f->y1; + f->y1 = y; + + return y; +} + +#endif diff --git a/plugins/ladspa_effect/swh/vynil_1905.c b/plugins/ladspa_effect/swh/vynil_1905.c new file mode 100644 index 000000000..d42f8f6a3 --- /dev/null +++ b/plugins/ladspa_effect/swh/vynil_1905.c @@ -0,0 +1,723 @@ +#include +#include +#ifndef WIN32 +#include "config.h" +#endif + +#ifdef ENABLE_NLS +#include +#endif + +#define _ISOC9X_SOURCE 1 +#define _ISOC99_SOURCE 1 +#define __USE_ISOC99 1 +#define __USE_ISOC9X 1 + +#include + +#include "ladspa.h" + +#ifdef WIN32 +#define _WINDOWS_DLL_EXPORT_ __declspec(dllexport) +int bIsFirstTime = 1; +void _init(); // forward declaration +#else +#define _WINDOWS_DLL_EXPORT_ +#endif + +#line 10 "vynil_1905.xml" + +#include +#include + +#include "ladspa-util.h" +#include "util/biquad.h" + +#define BUF_LEN 0.1 +#define CLICK_BUF_SIZE 4096 + +#define df(x) ((sinf(x) + 1.0f) * 0.5f) + +inline static float noise(); +inline static float noise() +{ + static unsigned int randSeed = 23; + randSeed = (randSeed * 196314165) + 907633515; + return randSeed / (float)INT_MAX - 1.0f; +} + +#define VYNIL_YEAR 0 +#define VYNIL_RPM 1 +#define VYNIL_WARP 2 +#define VYNIL_CLICK 3 +#define VYNIL_WEAR 4 +#define VYNIL_IN_L 5 +#define VYNIL_IN_R 6 +#define VYNIL_OUT_L 7 +#define VYNIL_OUT_R 8 + +static LADSPA_Descriptor *vynilDescriptor = NULL; + +typedef struct { + LADSPA_Data *year; + LADSPA_Data *rpm; + LADSPA_Data *warp; + LADSPA_Data *click; + LADSPA_Data *wear; + LADSPA_Data *in_l; + LADSPA_Data *in_r; + LADSPA_Data *out_l; + LADSPA_Data *out_r; + LADSPA_Data *buffer_m; + unsigned int buffer_mask; + unsigned int buffer_pos; + LADSPA_Data *buffer_s; + LADSPA_Data *click_buffer; + fixp16 click_buffer_omega; + fixp16 click_buffer_pos; + float click_gain; + float def; + float def_target; + float fs; + biquad * highp; + biquad * lowp_m; + biquad * lowp_s; + biquad * noise_filt; + float phi; + unsigned int sample_cnt; + LADSPA_Data run_adding_gain; +} Vynil; + +_WINDOWS_DLL_EXPORT_ +const LADSPA_Descriptor *ladspa_descriptor(unsigned long index) { + +#ifdef WIN32 + if (bIsFirstTime) { + _init(); + bIsFirstTime = 0; + } +#endif + switch (index) { + case 0: + return vynilDescriptor; + default: + return NULL; + } +} + +static void activateVynil(LADSPA_Handle instance) { + Vynil *plugin_data = (Vynil *)instance; + LADSPA_Data *buffer_m = plugin_data->buffer_m; + unsigned int buffer_mask = plugin_data->buffer_mask; + unsigned int buffer_pos = plugin_data->buffer_pos; + LADSPA_Data *buffer_s = plugin_data->buffer_s; + LADSPA_Data *click_buffer = plugin_data->click_buffer; + fixp16 click_buffer_omega = plugin_data->click_buffer_omega; + fixp16 click_buffer_pos = plugin_data->click_buffer_pos; + float click_gain = plugin_data->click_gain; + float def = plugin_data->def; + float def_target = plugin_data->def_target; + float fs = plugin_data->fs; + biquad *highp = plugin_data->highp; + biquad *lowp_m = plugin_data->lowp_m; + biquad *lowp_s = plugin_data->lowp_s; + biquad *noise_filt = plugin_data->noise_filt; + float phi = plugin_data->phi; + unsigned int sample_cnt = plugin_data->sample_cnt; +#line 75 "vynil_1905.xml" + memset(buffer_m, 0, sizeof(LADSPA_Data) * (buffer_mask + 1)); + memset(buffer_s, 0, sizeof(LADSPA_Data) * (buffer_mask + 1)); + buffer_pos = 0; + click_buffer_pos.all = 0; + click_buffer_omega.all = 0; + click_gain = 0; + phi = 0.0f; + + lp_set_params(lowp_m, 16000.0, 0.5, fs); + lp_set_params(lowp_s, 16000.0, 0.5, fs); + lp_set_params(highp, 10.0, 0.5, fs); + lp_set_params(noise_filt, 1000.0, 0.5, fs); + plugin_data->buffer_m = buffer_m; + plugin_data->buffer_mask = buffer_mask; + plugin_data->buffer_pos = buffer_pos; + plugin_data->buffer_s = buffer_s; + plugin_data->click_buffer = click_buffer; + plugin_data->click_buffer_omega = click_buffer_omega; + plugin_data->click_buffer_pos = click_buffer_pos; + plugin_data->click_gain = click_gain; + plugin_data->def = def; + plugin_data->def_target = def_target; + plugin_data->fs = fs; + plugin_data->highp = highp; + plugin_data->lowp_m = lowp_m; + plugin_data->lowp_s = lowp_s; + plugin_data->noise_filt = noise_filt; + plugin_data->phi = phi; + plugin_data->sample_cnt = sample_cnt; + +} + +static void cleanupVynil(LADSPA_Handle instance) { +#line 179 "vynil_1905.xml" + Vynil *plugin_data = (Vynil *)instance; + free(plugin_data->buffer_m); + free(plugin_data->buffer_s); + free(plugin_data->click_buffer); + free(plugin_data->lowp_m); + free(plugin_data->lowp_s); + free(plugin_data->noise_filt); + free(instance); +} + +static void connectPortVynil( + LADSPA_Handle instance, + unsigned long port, + LADSPA_Data *data) { + Vynil *plugin; + + plugin = (Vynil *)instance; + switch (port) { + case VYNIL_YEAR: + plugin->year = data; + break; + case VYNIL_RPM: + plugin->rpm = data; + break; + case VYNIL_WARP: + plugin->warp = data; + break; + case VYNIL_CLICK: + plugin->click = data; + break; + case VYNIL_WEAR: + plugin->wear = data; + break; + case VYNIL_IN_L: + plugin->in_l = data; + break; + case VYNIL_IN_R: + plugin->in_r = data; + break; + case VYNIL_OUT_L: + plugin->out_l = data; + break; + case VYNIL_OUT_R: + plugin->out_r = data; + break; + } +} + +static LADSPA_Handle instantiateVynil( + const LADSPA_Descriptor *descriptor, + unsigned long s_rate) { + Vynil *plugin_data = (Vynil *)malloc(sizeof(Vynil)); + LADSPA_Data *buffer_m = NULL; + unsigned int buffer_mask; + unsigned int buffer_pos; + LADSPA_Data *buffer_s = NULL; + LADSPA_Data *click_buffer = NULL; + fixp16 click_buffer_omega; + fixp16 click_buffer_pos; + float click_gain; + float def; + float def_target; + float fs; + biquad *highp = NULL; + biquad *lowp_m = NULL; + biquad *lowp_s = NULL; + biquad *noise_filt = NULL; + float phi; + unsigned int sample_cnt; + +#line 37 "vynil_1905.xml" + unsigned int i; + unsigned int buffer_size; + + fs = (float)s_rate; + buffer_size = 4096; + while (buffer_size < s_rate * BUF_LEN) { + buffer_size *= 2; + } + buffer_m = malloc(sizeof(LADSPA_Data) * buffer_size); + buffer_s = malloc(sizeof(LADSPA_Data) * buffer_size); + buffer_mask = buffer_size - 1; + buffer_pos = 0; + click_gain = 0; + phi = 0.0f; /* Angular phase */ + + click_buffer = malloc(sizeof(LADSPA_Data) * CLICK_BUF_SIZE); + for (i=0; ibuffer_m = buffer_m; + plugin_data->buffer_mask = buffer_mask; + plugin_data->buffer_pos = buffer_pos; + plugin_data->buffer_s = buffer_s; + plugin_data->click_buffer = click_buffer; + plugin_data->click_buffer_omega = click_buffer_omega; + plugin_data->click_buffer_pos = click_buffer_pos; + plugin_data->click_gain = click_gain; + plugin_data->def = def; + plugin_data->def_target = def_target; + plugin_data->fs = fs; + plugin_data->highp = highp; + plugin_data->lowp_m = lowp_m; + plugin_data->lowp_s = lowp_s; + plugin_data->noise_filt = noise_filt; + plugin_data->phi = phi; + plugin_data->sample_cnt = sample_cnt; + + return (LADSPA_Handle)plugin_data; +} + +#undef buffer_write +#undef RUN_ADDING +#undef RUN_REPLACING + +#define buffer_write(b, v) (b = v) +#define RUN_ADDING 0 +#define RUN_REPLACING 1 + +static void runVynil(LADSPA_Handle instance, unsigned long sample_count) { + Vynil *plugin_data = (Vynil *)instance; + + /* Year (float value) */ + const LADSPA_Data year = *(plugin_data->year); + + /* RPM (float value) */ + const LADSPA_Data rpm = *(plugin_data->rpm); + + /* Surface warping (float value) */ + const LADSPA_Data warp = *(plugin_data->warp); + + /* Crackle (float value) */ + const LADSPA_Data click = *(plugin_data->click); + + /* Wear (float value) */ + const LADSPA_Data wear = *(plugin_data->wear); + + /* Input L (array of floats of length sample_count) */ + const LADSPA_Data * const in_l = plugin_data->in_l; + + /* Input R (array of floats of length sample_count) */ + const LADSPA_Data * const in_r = plugin_data->in_r; + + /* Output L (array of floats of length sample_count) */ + LADSPA_Data * const out_l = plugin_data->out_l; + + /* Output R (array of floats of length sample_count) */ + LADSPA_Data * const out_r = plugin_data->out_r; + LADSPA_Data * buffer_m = plugin_data->buffer_m; + unsigned int buffer_mask = plugin_data->buffer_mask; + unsigned int buffer_pos = plugin_data->buffer_pos; + LADSPA_Data * buffer_s = plugin_data->buffer_s; + LADSPA_Data * click_buffer = plugin_data->click_buffer; + fixp16 click_buffer_omega = plugin_data->click_buffer_omega; + fixp16 click_buffer_pos = plugin_data->click_buffer_pos; + float click_gain = plugin_data->click_gain; + float def = plugin_data->def; + float def_target = plugin_data->def_target; + float fs = plugin_data->fs; + biquad * highp = plugin_data->highp; + biquad * lowp_m = plugin_data->lowp_m; + biquad * lowp_s = plugin_data->lowp_s; + biquad * noise_filt = plugin_data->noise_filt; + float phi = plugin_data->phi; + unsigned int sample_cnt = plugin_data->sample_cnt; + +#line 90 "vynil_1905.xml" + unsigned long pos; + float deflec = def; + float deflec_target = def_target; + float src_m, src_s; + + /* angular velocity of platter * 16 */ + const float omega = 960.0f / (rpm * fs); + const float age = (2000 - year) * 0.01f; + const unsigned int click_prob = (age*age*(float)RAND_MAX)/10 + click * 0.02 * RAND_MAX; + const float noise_amp = (click + wear * 0.3f) * 0.12f + (1993.0f - year) * 0.0031f; + const float bandwidth = (year - 1880.0f) * (rpm * 1.9f); + const float noise_bandwidth = bandwidth * (0.25 - wear * 0.02) + click * 200.0 + 300.0; + const float stereo = f_clamp((year - 1940.0f) * 0.02f, 0.0f, 1.0f); + const float wrap_gain = age * 3.1f + 0.05f; + const float wrap_bias = age * 0.1f; + + lp_set_params(lowp_m, bandwidth * (1.0 - wear * 0.86), 2.0, fs); + lp_set_params(lowp_s, bandwidth * (1.0 - wear * 0.89), 2.0, fs); + hp_set_params(highp, (2000-year) * 8.0, 1.5, fs); + lp_set_params(noise_filt, noise_bandwidth, 4.0 + wear * 2.0, fs); + + for (pos = 0; pos < sample_count; pos++) { + unsigned int o1, o2; + float ofs; + + if ((sample_cnt & 15) == 0) { + const float ang = phi * 2.0f * M_PI; + const float w = warp * (2000.0f - year) * 0.01f; + deflec_target = w*df(ang)*0.5f + w*w*df(2.0f*ang)*0.31f + + w*w*w*df(3.0f*ang)*0.129f; + phi += omega; + while (phi > 1.0f) { + phi -= 1.0f; + } + if ((unsigned int)rand() < click_prob) { + click_buffer_omega.all = ((rand() >> 6) + 1000) * rpm; + click_gain = noise_amp * 5.0f * noise(); + } + } + deflec = deflec * 0.1f + deflec_target * 0.9f; + + /* matrix into mid_side representation (this is roughly what stereo + * LPs do) */ + buffer_m[buffer_pos] = in_l[pos] + in_r[pos]; + buffer_s[buffer_pos] = in_l[pos] - in_r[pos]; + + /* cacluate the effects of the surface warping */ + ofs = fs * 0.009f * deflec; + o1 = f_round(floorf(ofs)); + o2 = f_round(ceilf(ofs)); + ofs -= o1; + src_m = LIN_INTERP(ofs, buffer_m[(buffer_pos - o1 - 1) & buffer_mask], buffer_m[(buffer_pos - o2 - 1) & buffer_mask]); + src_s = LIN_INTERP(ofs, buffer_s[(buffer_pos - o1 - 1) & buffer_mask], buffer_s[(buffer_pos - o2 - 1) & buffer_mask]); + + src_m = biquad_run(lowp_m, src_m + click_buffer[click_buffer_pos.part.in & (CLICK_BUF_SIZE - 1)] * click_gain); + + /* waveshaper */ + src_m = LIN_INTERP(age, src_m, sinf(src_m * wrap_gain + wrap_bias)); + + /* output highpass */ + src_m = biquad_run(highp, src_m) + biquad_run(noise_filt, noise()) * noise_amp + click_buffer[click_buffer_pos.part.in & (CLICK_BUF_SIZE - 1)] * click_gain * 0.5f; + + /* stereo seperation filter */ + src_s = biquad_run(lowp_s, src_s) * stereo; + + buffer_write(out_l[pos], (src_s + src_m) * 0.5f); + buffer_write(out_r[pos], (src_m - src_s) * 0.5f); + + /* roll buffer indexes */ + buffer_pos = (buffer_pos + 1) & buffer_mask; + click_buffer_pos.all += click_buffer_omega.all; + if (click_buffer_pos.part.in >= CLICK_BUF_SIZE) { + click_buffer_pos.all = 0; + click_buffer_omega.all = 0; + } + sample_cnt++; + } + + plugin_data->buffer_pos = buffer_pos; + plugin_data->click_buffer_pos = click_buffer_pos; + plugin_data->click_buffer_omega = click_buffer_omega; + plugin_data->click_gain = click_gain; + plugin_data->sample_cnt = sample_cnt; + plugin_data->def_target = deflec_target; + plugin_data->def = deflec; + plugin_data->phi = phi; +} +#undef buffer_write +#undef RUN_ADDING +#undef RUN_REPLACING + +#define buffer_write(b, v) (b += (v) * run_adding_gain) +#define RUN_ADDING 1 +#define RUN_REPLACING 0 + +static void setRunAddingGainVynil(LADSPA_Handle instance, LADSPA_Data gain) { + ((Vynil *)instance)->run_adding_gain = gain; +} + +static void runAddingVynil(LADSPA_Handle instance, unsigned long sample_count) { + Vynil *plugin_data = (Vynil *)instance; + LADSPA_Data run_adding_gain = plugin_data->run_adding_gain; + + /* Year (float value) */ + const LADSPA_Data year = *(plugin_data->year); + + /* RPM (float value) */ + const LADSPA_Data rpm = *(plugin_data->rpm); + + /* Surface warping (float value) */ + const LADSPA_Data warp = *(plugin_data->warp); + + /* Crackle (float value) */ + const LADSPA_Data click = *(plugin_data->click); + + /* Wear (float value) */ + const LADSPA_Data wear = *(plugin_data->wear); + + /* Input L (array of floats of length sample_count) */ + const LADSPA_Data * const in_l = plugin_data->in_l; + + /* Input R (array of floats of length sample_count) */ + const LADSPA_Data * const in_r = plugin_data->in_r; + + /* Output L (array of floats of length sample_count) */ + LADSPA_Data * const out_l = plugin_data->out_l; + + /* Output R (array of floats of length sample_count) */ + LADSPA_Data * const out_r = plugin_data->out_r; + LADSPA_Data * buffer_m = plugin_data->buffer_m; + unsigned int buffer_mask = plugin_data->buffer_mask; + unsigned int buffer_pos = plugin_data->buffer_pos; + LADSPA_Data * buffer_s = plugin_data->buffer_s; + LADSPA_Data * click_buffer = plugin_data->click_buffer; + fixp16 click_buffer_omega = plugin_data->click_buffer_omega; + fixp16 click_buffer_pos = plugin_data->click_buffer_pos; + float click_gain = plugin_data->click_gain; + float def = plugin_data->def; + float def_target = plugin_data->def_target; + float fs = plugin_data->fs; + biquad * highp = plugin_data->highp; + biquad * lowp_m = plugin_data->lowp_m; + biquad * lowp_s = plugin_data->lowp_s; + biquad * noise_filt = plugin_data->noise_filt; + float phi = plugin_data->phi; + unsigned int sample_cnt = plugin_data->sample_cnt; + +#line 90 "vynil_1905.xml" + unsigned long pos; + float deflec = def; + float deflec_target = def_target; + float src_m, src_s; + + /* angular velocity of platter * 16 */ + const float omega = 960.0f / (rpm * fs); + const float age = (2000 - year) * 0.01f; + const unsigned int click_prob = (age*age*(float)RAND_MAX)/10 + click * 0.02 * RAND_MAX; + const float noise_amp = (click + wear * 0.3f) * 0.12f + (1993.0f - year) * 0.0031f; + const float bandwidth = (year - 1880.0f) * (rpm * 1.9f); + const float noise_bandwidth = bandwidth * (0.25 - wear * 0.02) + click * 200.0 + 300.0; + const float stereo = f_clamp((year - 1940.0f) * 0.02f, 0.0f, 1.0f); + const float wrap_gain = age * 3.1f + 0.05f; + const float wrap_bias = age * 0.1f; + + lp_set_params(lowp_m, bandwidth * (1.0 - wear * 0.86), 2.0, fs); + lp_set_params(lowp_s, bandwidth * (1.0 - wear * 0.89), 2.0, fs); + hp_set_params(highp, (2000-year) * 8.0, 1.5, fs); + lp_set_params(noise_filt, noise_bandwidth, 4.0 + wear * 2.0, fs); + + for (pos = 0; pos < sample_count; pos++) { + unsigned int o1, o2; + float ofs; + + if ((sample_cnt & 15) == 0) { + const float ang = phi * 2.0f * M_PI; + const float w = warp * (2000.0f - year) * 0.01f; + deflec_target = w*df(ang)*0.5f + w*w*df(2.0f*ang)*0.31f + + w*w*w*df(3.0f*ang)*0.129f; + phi += omega; + while (phi > 1.0f) { + phi -= 1.0f; + } + if ((unsigned int)rand() < click_prob) { + click_buffer_omega.all = ((rand() >> 6) + 1000) * rpm; + click_gain = noise_amp * 5.0f * noise(); + } + } + deflec = deflec * 0.1f + deflec_target * 0.9f; + + /* matrix into mid_side representation (this is roughly what stereo + * LPs do) */ + buffer_m[buffer_pos] = in_l[pos] + in_r[pos]; + buffer_s[buffer_pos] = in_l[pos] - in_r[pos]; + + /* cacluate the effects of the surface warping */ + ofs = fs * 0.009f * deflec; + o1 = f_round(floorf(ofs)); + o2 = f_round(ceilf(ofs)); + ofs -= o1; + src_m = LIN_INTERP(ofs, buffer_m[(buffer_pos - o1 - 1) & buffer_mask], buffer_m[(buffer_pos - o2 - 1) & buffer_mask]); + src_s = LIN_INTERP(ofs, buffer_s[(buffer_pos - o1 - 1) & buffer_mask], buffer_s[(buffer_pos - o2 - 1) & buffer_mask]); + + src_m = biquad_run(lowp_m, src_m + click_buffer[click_buffer_pos.part.in & (CLICK_BUF_SIZE - 1)] * click_gain); + + /* waveshaper */ + src_m = LIN_INTERP(age, src_m, sinf(src_m * wrap_gain + wrap_bias)); + + /* output highpass */ + src_m = biquad_run(highp, src_m) + biquad_run(noise_filt, noise()) * noise_amp + click_buffer[click_buffer_pos.part.in & (CLICK_BUF_SIZE - 1)] * click_gain * 0.5f; + + /* stereo seperation filter */ + src_s = biquad_run(lowp_s, src_s) * stereo; + + buffer_write(out_l[pos], (src_s + src_m) * 0.5f); + buffer_write(out_r[pos], (src_m - src_s) * 0.5f); + + /* roll buffer indexes */ + buffer_pos = (buffer_pos + 1) & buffer_mask; + click_buffer_pos.all += click_buffer_omega.all; + if (click_buffer_pos.part.in >= CLICK_BUF_SIZE) { + click_buffer_pos.all = 0; + click_buffer_omega.all = 0; + } + sample_cnt++; + } + + plugin_data->buffer_pos = buffer_pos; + plugin_data->click_buffer_pos = click_buffer_pos; + plugin_data->click_buffer_omega = click_buffer_omega; + plugin_data->click_gain = click_gain; + plugin_data->sample_cnt = sample_cnt; + plugin_data->def_target = deflec_target; + plugin_data->def = deflec; + plugin_data->phi = phi; +} + +void _init() { + char **port_names; + LADSPA_PortDescriptor *port_descriptors; + LADSPA_PortRangeHint *port_range_hints; + +#ifdef ENABLE_NLS +#define D_(s) dgettext(PACKAGE, s) + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, PACKAGE_LOCALE_DIR); +#else +#define D_(s) (s) +#endif + + + vynilDescriptor = + (LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor)); + + if (vynilDescriptor) { + vynilDescriptor->UniqueID = 1905; + vynilDescriptor->Label = "vynil"; + vynilDescriptor->Properties = + LADSPA_PROPERTY_HARD_RT_CAPABLE; + vynilDescriptor->Name = + D_("VyNil (Vinyl Effect)"); + vynilDescriptor->Maker = + "Steve Harris "; + vynilDescriptor->Copyright = + "GPL"; + vynilDescriptor->PortCount = 9; + + port_descriptors = (LADSPA_PortDescriptor *)calloc(9, + sizeof(LADSPA_PortDescriptor)); + vynilDescriptor->PortDescriptors = + (const LADSPA_PortDescriptor *)port_descriptors; + + port_range_hints = (LADSPA_PortRangeHint *)calloc(9, + sizeof(LADSPA_PortRangeHint)); + vynilDescriptor->PortRangeHints = + (const LADSPA_PortRangeHint *)port_range_hints; + + port_names = (char **)calloc(9, sizeof(char*)); + vynilDescriptor->PortNames = + (const char **)port_names; + + /* Parameters for Year */ + port_descriptors[VYNIL_YEAR] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[VYNIL_YEAR] = + D_("Year"); + port_range_hints[VYNIL_YEAR].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_MAXIMUM; + port_range_hints[VYNIL_YEAR].LowerBound = 1900; + port_range_hints[VYNIL_YEAR].UpperBound = 1990; + + /* Parameters for RPM */ + port_descriptors[VYNIL_RPM] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[VYNIL_RPM] = + D_("RPM"); + port_range_hints[VYNIL_RPM].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_MINIMUM; + port_range_hints[VYNIL_RPM].LowerBound = 33; + port_range_hints[VYNIL_RPM].UpperBound = 78; + + /* Parameters for Surface warping */ + port_descriptors[VYNIL_WARP] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[VYNIL_WARP] = + D_("Surface warping"); + port_range_hints[VYNIL_WARP].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0; + port_range_hints[VYNIL_WARP].LowerBound = 0.0; + port_range_hints[VYNIL_WARP].UpperBound = 1.0; + + /* Parameters for Crackle */ + port_descriptors[VYNIL_CLICK] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[VYNIL_CLICK] = + D_("Crackle"); + port_range_hints[VYNIL_CLICK].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0; + port_range_hints[VYNIL_CLICK].LowerBound = 0.0; + port_range_hints[VYNIL_CLICK].UpperBound = 1.0; + + /* Parameters for Wear */ + port_descriptors[VYNIL_WEAR] = + LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + port_names[VYNIL_WEAR] = + D_("Wear"); + port_range_hints[VYNIL_WEAR].HintDescriptor = + LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0; + port_range_hints[VYNIL_WEAR].LowerBound = 0.0; + port_range_hints[VYNIL_WEAR].UpperBound = 1.0; + + /* Parameters for Input L */ + port_descriptors[VYNIL_IN_L] = + LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO; + port_names[VYNIL_IN_L] = + D_("Input L"); + port_range_hints[VYNIL_IN_L].HintDescriptor = 0; + + /* Parameters for Input R */ + port_descriptors[VYNIL_IN_R] = + LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO; + port_names[VYNIL_IN_R] = + D_("Input R"); + port_range_hints[VYNIL_IN_R].HintDescriptor = 0; + + /* Parameters for Output L */ + port_descriptors[VYNIL_OUT_L] = + LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO; + port_names[VYNIL_OUT_L] = + D_("Output L"); + port_range_hints[VYNIL_OUT_L].HintDescriptor = 0; + + /* Parameters for Output R */ + port_descriptors[VYNIL_OUT_R] = + LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO; + port_names[VYNIL_OUT_R] = + D_("Output R"); + port_range_hints[VYNIL_OUT_R].HintDescriptor = 0; + + vynilDescriptor->activate = activateVynil; + vynilDescriptor->cleanup = cleanupVynil; + vynilDescriptor->connect_port = connectPortVynil; + vynilDescriptor->deactivate = NULL; + vynilDescriptor->instantiate = instantiateVynil; + vynilDescriptor->run = runVynil; + vynilDescriptor->run_adding = runAddingVynil; + vynilDescriptor->set_run_adding_gain = setRunAddingGainVynil; + } +} + +void _fini() { + if (vynilDescriptor) { + free((LADSPA_PortDescriptor *)vynilDescriptor->PortDescriptors); + free((char **)vynilDescriptor->PortNames); + free((LADSPA_PortRangeHint *)vynilDescriptor->PortRangeHints); + free(vynilDescriptor); + } + +}