integrated TAP-plugins to be shipped with LMMS
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@1070 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
39
ChangeLog
39
ChangeLog
@@ -1,3 +1,42 @@
|
||||
2008-06-05 Tobias Doerffel <tobydox/at/users/dot/sourceforge/dot/net>
|
||||
|
||||
* include/track.h:
|
||||
* src/core/track.cpp:
|
||||
re-arranged mute- and solo-buttons
|
||||
|
||||
* plugins/ladspa_effect/tap/tap_deesser.c:
|
||||
* plugins/ladspa_effect/tap/tap_reverb.h:
|
||||
* plugins/ladspa_effect/tap/tap_sigmoid.c:
|
||||
* plugins/ladspa_effect/tap/tap_doubler.c:
|
||||
* plugins/ladspa_effect/tap/tap_eqbw.c:
|
||||
* plugins/ladspa_effect/tap/tap_pinknoise.c:
|
||||
* plugins/ladspa_effect/tap/tap_reverb_presets.h:
|
||||
* plugins/ladspa_effect/tap/tap_chorusflanger.c:
|
||||
* plugins/ladspa_effect/tap/ladspa.h:
|
||||
* plugins/ladspa_effect/tap/tap_limiter.c:
|
||||
* plugins/ladspa_effect/tap/tap_utils.h:
|
||||
* plugins/ladspa_effect/tap/tap_eq.c:
|
||||
* plugins/ladspa_effect/tap/tap_vibrato.c:
|
||||
* plugins/ladspa_effect/tap/tap_autopan.c:
|
||||
* plugins/ladspa_effect/tap/tap_pitch.c:
|
||||
* plugins/ladspa_effect/tap/CREDITS:
|
||||
* plugins/ladspa_effect/tap/README:
|
||||
* plugins/ladspa_effect/tap/tap_dynamics_st.c:
|
||||
* plugins/ladspa_effect/tap/tap_echo.c:
|
||||
* plugins/ladspa_effect/tap/tap_tremolo.c:
|
||||
* plugins/ladspa_effect/tap/tap_dynamics_presets.h:
|
||||
* plugins/ladspa_effect/tap/tap_tubewarmth.c:
|
||||
* plugins/ladspa_effect/tap/COPYING:
|
||||
* plugins/ladspa_effect/tap/tap_dynamics_m.c:
|
||||
* plugins/ladspa_effect/tap/Makefile.am:
|
||||
* plugins/ladspa_effect/tap/tap_reflector.c:
|
||||
* plugins/ladspa_effect/tap/tap_reverb.c:
|
||||
* plugins/ladspa_effect/tap/tap_rotspeak.c:
|
||||
* plugins/ladspa_effect/Makefile.am:
|
||||
* configure.in:
|
||||
* Makefile.am:
|
||||
integrated TAP-plugins to be shipped with LMMS
|
||||
|
||||
2008-06-04 Paul Giblock <drfaygo/at/gmail/dot/com>
|
||||
|
||||
* src/gui/lmms_style.cpp:
|
||||
|
||||
@@ -26,6 +26,7 @@ win32-pkg: all
|
||||
cp lmms.exe tmp/lmms
|
||||
find plugins/ -name "*.dll" -maxdepth 2 -exec cp '{}' tmp/lmms/plugins/ ';'
|
||||
cp plugins/ladspa_effect/caps/caps.dll tmp/lmms/plugins/ladspa/
|
||||
cp plugins/ladspa_effect/tap/tap*.dll tmp/lmms/plugins/ladspa/
|
||||
PWD=`pwd`
|
||||
cd data && make DESTDIR=$(PWD)/tmp/lmms/ install
|
||||
mv tmp/lmms/usr/share/lmms/* tmp/lmms/data/ && rm -rf tmp/lmms/usr
|
||||
|
||||
20
configure.in
20
configure.in
@@ -2,8 +2,8 @@
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ(2.50)
|
||||
AC_INIT(lmms, 0.4.0-svn20080603, lmms-devel/at/lists/dot/sf/dot/net)
|
||||
AM_INIT_AUTOMAKE(lmms, 0.4.0-svn20080603)
|
||||
AC_INIT(lmms, 0.4.0-svn20080604, lmms-devel/at/lists/dot/sf/dot/net)
|
||||
AM_INIT_AUTOMAKE(lmms, 0.4.0-svn20080604)
|
||||
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
|
||||
@@ -592,7 +592,7 @@ else
|
||||
fi
|
||||
|
||||
|
||||
AC_MSG_CHECKING([whether to ship caps])
|
||||
AC_MSG_CHECKING([whether to ship CAPS])
|
||||
AC_ARG_WITH([caps],
|
||||
AS_HELP_STRING([--without-caps],
|
||||
[do not ship C* Audio Plugin Suite]), ,
|
||||
@@ -605,6 +605,19 @@ fi
|
||||
AM_CONDITIONAL(SHIP_CAPS, test "x$with_caps" = "xyes")
|
||||
|
||||
|
||||
AC_MSG_CHECKING([whether to ship TAP plugins])
|
||||
AC_ARG_WITH([tap],
|
||||
AS_HELP_STRING([--without-tap],
|
||||
[do not ship TAP plugins]), ,
|
||||
[ with_tap=yes ])
|
||||
if test "x$with_tap" = "xyes" ; then
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
AM_CONDITIONAL(SHIP_TAP, test "x$with_tap" = "xyes")
|
||||
|
||||
|
||||
if [ "$build_win32" = "true" ] ; then
|
||||
BIN2RES=`pwd`/buildtools/bin2res.exe
|
||||
else
|
||||
@@ -706,6 +719,7 @@ AC_CONFIG_FILES([Makefile
|
||||
plugins/ladspa_browser/Makefile
|
||||
plugins/ladspa_effect/Makefile
|
||||
plugins/ladspa_effect/caps/Makefile
|
||||
plugins/ladspa_effect/tap/Makefile
|
||||
plugins/lb302/Makefile
|
||||
plugins/live_tool/Makefile
|
||||
plugins/midi_import/Makefile
|
||||
|
||||
@@ -4,6 +4,10 @@ if SHIP_CAPS
|
||||
SUBDIRS = caps
|
||||
endif
|
||||
|
||||
if SHIP_TAP
|
||||
SUBDIRS = tap
|
||||
endif
|
||||
|
||||
PLUGIN_NAME = ladspaeffect
|
||||
|
||||
|
||||
|
||||
340
plugins/ladspa_effect/tap/COPYING
Normal file
340
plugins/ladspa_effect/tap/COPYING
Normal file
@@ -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.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
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.
|
||||
|
||||
<signature of Ty Coon>, 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.
|
||||
57
plugins/ladspa_effect/tap/CREDITS
Normal file
57
plugins/ladspa_effect/tap/CREDITS
Normal file
@@ -0,0 +1,57 @@
|
||||
The author would like to thank the following people for their help,
|
||||
support, comments, suggestions, patches etc.
|
||||
|
||||
If you discover yourself in the following list and would like to
|
||||
remain nameless instead, please write to the author.
|
||||
|
||||
In no particular order:
|
||||
|
||||
|
||||
Anand Kumria <akumria@debian.org> constantly maintains a Debian
|
||||
package of this software.
|
||||
|
||||
As the author of the lrdf library, Steve Harris <steve@plugin.org.uk>
|
||||
was kind enough to take a look at the RDF file describing these
|
||||
plugins.
|
||||
|
||||
Alexander Koenig <alex@lisas.de> discovered that the AutoPanner (and
|
||||
Tremolo) didn't work at very small frequency values, and sent a patch
|
||||
that became the base of the solution.
|
||||
|
||||
Forrest Cook <cook@lwn.net> suggested implementing an AutoPanner as a
|
||||
new TAP-plugin.
|
||||
|
||||
Nick Lamb <njl98r@ecs.soton.ac.uk> suggested using his Demolition
|
||||
[http://www.ecs.soton.ac.uk/~njl98r/code/ladspa/] program to
|
||||
sanity-check the TAP-plugins. Demolition proved essential, a must for
|
||||
any LADSPA plugin developer. It revealed bugs and LADSPA
|
||||
non-conformancies too many to mention in the TAP-plugins code, which
|
||||
could be fixed easily this way.
|
||||
|
||||
Linium <intent@netpratique.fr> discovered a bug in EQ and EQ-BW:
|
||||
the plugins reinitialized themselves on each transport stop, which
|
||||
resulted in the effect disappearing after every STOP->PLAY.
|
||||
|
||||
As a main Ardour developer, Taybin Rutkin <taybin@earthlink.net>
|
||||
implemented using RDF metadata to generate drop-down lists in LADSPA
|
||||
plugin GUIs in Ardour. This made it much easier to create good-looking
|
||||
and easy to use plugins; in particular TAP Reverberator and TAP
|
||||
Dynamics are among the "big winners".
|
||||
|
||||
Luke Yelavich <luke@audioslack.com> sent a patch that cleaned up the
|
||||
Makefile a bit by introducing the variables CFLAGS and LDFLAGS.
|
||||
|
||||
Jan Depner <eviltwin69@cableone.net> suggested implementing some kind
|
||||
of doubler plugin, and he gave me useful pointers about the Midpoint
|
||||
Displacement Algorithm with which a semi-random series of numbers
|
||||
following a fractal pattern can be generated. Without him, the TAP
|
||||
Fractal Doubler would have never been written. He also helped a lot
|
||||
with the CPU runaway problems in TAP Reverberator, by reporting the
|
||||
problem and trying out my solutions.
|
||||
|
||||
|
||||
And, of course, special thanks to the Ardour [http://ardour.org] and
|
||||
JACK [http://jackit.sf.net] development teams for their tireless
|
||||
efforts in creating one of the best Linux audio engineering platforms
|
||||
(and besides that, the recommended host for these plugins).
|
||||
TAP-plugins aims to be a very small contribution to this effort.
|
||||
58
plugins/ladspa_effect/tap/Makefile.am
Normal file
58
plugins/ladspa_effect/tap/Makefile.am
Normal file
@@ -0,0 +1,58 @@
|
||||
AUTOMAKE_OPTIONS = foreign 1.4
|
||||
|
||||
|
||||
AM_CFLAGS := $(AM_CFLAGS) -I../../../include -I. -O3 -Wall -fomit-frame-pointer -fno-strict-aliasing -fstrength-reduce -funroll-loops -ffast-math -c -fPIC -DPIC
|
||||
|
||||
DEST = $(DESTDIR)$(libdir)/$(PACKAGE)/ladspa
|
||||
|
||||
all: $(PLUGINS)
|
||||
|
||||
if BUILD_WIN32
|
||||
SHARED_EXT=dll
|
||||
LINKFLAGS=
|
||||
else
|
||||
SHARED_EXT=so
|
||||
LINKFLAGS=-nostartfiles
|
||||
endif
|
||||
|
||||
PLUGINS = tap_autopan.$(SHARED_EXT) \
|
||||
tap_chorusflanger.$(SHARED_EXT) \
|
||||
tap_deesser.$(SHARED_EXT) \
|
||||
tap_dynamics_m.$(SHARED_EXT) \
|
||||
tap_dynamics_st.$(SHARED_EXT) \
|
||||
tap_eq.$(SHARED_EXT) \
|
||||
tap_eqbw.$(SHARED_EXT) \
|
||||
tap_doubler.$(SHARED_EXT) \
|
||||
tap_pinknoise.$(SHARED_EXT) \
|
||||
tap_pitch.$(SHARED_EXT) \
|
||||
tap_reflector.$(SHARED_EXT) \
|
||||
tap_reverb.$(SHARED_EXT) \
|
||||
tap_rotspeak.$(SHARED_EXT) \
|
||||
tap_limiter.$(SHARED_EXT) \
|
||||
tap_sigmoid.$(SHARED_EXT) \
|
||||
tap_echo.$(SHARED_EXT) \
|
||||
tap_tremolo.$(SHARED_EXT) \
|
||||
tap_tubewarmth.$(SHARED_EXT) \
|
||||
tap_vibrato.$(SHARED_EXT)
|
||||
|
||||
|
||||
LDFLAGS = $(LINKFLAGS) -shared -Wl,-no-undefined -Wl,-Bsymbolic -lm
|
||||
|
||||
%.$(SHARED_EXT): %.c
|
||||
$(CC) $(AM_CFLAGS) -c $< -o $<.o
|
||||
$(CC) $(LDFLAGS) $<.o -o $@
|
||||
|
||||
clean:
|
||||
rm -f *.c.o *.$(SHARED_EXT)
|
||||
|
||||
|
||||
install: all
|
||||
install -d $(DEST)
|
||||
install -m 644 $(PLUGINS) $(DEST)
|
||||
|
||||
uninstall:
|
||||
-rm $(DEST)/tap_*.$(SHARED_EXT)
|
||||
|
||||
all: $(PLUGINS)
|
||||
|
||||
EXTRA_DIST = README COPYING CREDITS $(wildcard tap_*.c) $(wildcard tap_*.h) ladspa.h
|
||||
44
plugins/ladspa_effect/tap/README
Normal file
44
plugins/ladspa_effect/tap/README
Normal file
@@ -0,0 +1,44 @@
|
||||
TAP-plugins (Tom's Audio Processing plugins)
|
||||
--------------------------------------------
|
||||
|
||||
AUTHOR: Tom Szilagyi <tszilagyi@users.sourceforge.net>
|
||||
WEBPAGE: http://tap-plugins.sf.net
|
||||
|
||||
|
||||
Welcome!
|
||||
|
||||
TAP-plugins is a bunch of LADSPA plugins for audio processing. It runs
|
||||
on the GNU/Linux operating system, and possibly other UNIX-like
|
||||
operating systems.
|
||||
|
||||
LADSPA stands for Linux Audio Developers Simple Plugin API.
|
||||
Learn more about LADSPA at http://www.ladspa.org
|
||||
|
||||
You need a LADSPA-aware host program to use these plugins.
|
||||
I recommend using Ardour, which is a professional multichannel hard
|
||||
disc recorder and digital audio workstation for Linux. These plugins
|
||||
were developed and tested using Ardour, but they should work with any
|
||||
LADSPA-capable host. Learn more about Ardour at http://ardour.org
|
||||
|
||||
|
||||
|
||||
Installation and usage of the plugins is very simple. Please take a
|
||||
moment to edit the top of the Makefile if you wish to install the
|
||||
plugins in a directory other than /usr/local/lib/ladspa (the default
|
||||
place for plugins). A destination directory for RDF metadata is also
|
||||
set there (defaults to /usr/local/share/ladspa/rdf) which you may also
|
||||
want to change. Then run "make" and (as root) "make install". No
|
||||
special packages are needed to compile these plugins, so there is no
|
||||
./configure script.
|
||||
|
||||
A thorough manual is provided in html format. It is identical to the
|
||||
project website. There is no need to save that manually, though: it is
|
||||
provided as a separate package called tap-plugins-doc. After
|
||||
downloading and untarring it, just open index.html with your favorite
|
||||
Any Browser to view it.
|
||||
|
||||
Questions, comments, suggestions, bugreports and fixes are always
|
||||
welcome at: <tszilagyi@users.sourceforge.net>
|
||||
|
||||
|
||||
Have fun, turn up the volume and kick the shit out of your neighbours!
|
||||
36
plugins/ladspa_effect/tap/ladspa.h
Normal file
36
plugins/ladspa_effect/tap/ladspa.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* ladspa.h - include correct LADSPA-header
|
||||
*
|
||||
* Copyright (c) 2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
* 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 (see COPYING); if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LADSPA_H
|
||||
#include <ladspa.h>
|
||||
#else
|
||||
#include "ladspa-1.1.h"
|
||||
#endif
|
||||
|
||||
|
||||
361
plugins/ladspa_effect/tap/tap_autopan.c
Normal file
361
plugins/ladspa_effect/tap/tap_autopan.c
Normal file
@@ -0,0 +1,361 @@
|
||||
/* -*- linux-c -*-
|
||||
Copyright (C) 2004 Tom Szilagyi
|
||||
|
||||
Patches were received from:
|
||||
Alexander Koenig <alex@lisas.de>
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: tap_autopan.c,v 1.6 2004/02/21 17:33:36 tszilagyi Exp $
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "ladspa.h"
|
||||
#include "tap_utils.h"
|
||||
|
||||
/* The Unique ID of the plugin: */
|
||||
|
||||
#define ID_STEREO 2146
|
||||
|
||||
/* The port numbers for the plugin: */
|
||||
|
||||
#define CONTROL_FREQ 0
|
||||
#define CONTROL_DEPTH 1
|
||||
#define CONTROL_GAIN 2
|
||||
#define INPUT_L 3
|
||||
#define INPUT_R 4
|
||||
#define OUTPUT_L 5
|
||||
#define OUTPUT_R 6
|
||||
|
||||
|
||||
/* Total number of ports */
|
||||
|
||||
#define PORTCOUNT_STEREO 7
|
||||
|
||||
|
||||
/* cosine table for fast computations */
|
||||
LADSPA_Data cos_table[1024];
|
||||
|
||||
|
||||
/* The structure used to hold port connection information and state */
|
||||
|
||||
typedef struct {
|
||||
LADSPA_Data * freq;
|
||||
LADSPA_Data * depth;
|
||||
LADSPA_Data * gain;
|
||||
LADSPA_Data * input_L;
|
||||
LADSPA_Data * input_R;
|
||||
LADSPA_Data * output_L;
|
||||
LADSPA_Data * output_R;
|
||||
unsigned long SampleRate;
|
||||
LADSPA_Data Phase;
|
||||
LADSPA_Data run_adding_gain;
|
||||
} AutoPan;
|
||||
|
||||
|
||||
|
||||
/* Construct a new plugin instance. */
|
||||
LADSPA_Handle
|
||||
instantiate_AutoPan(const LADSPA_Descriptor * Descriptor,
|
||||
unsigned long SampleRate) {
|
||||
|
||||
LADSPA_Handle * ptr;
|
||||
|
||||
if ((ptr = malloc(sizeof(AutoPan))) != NULL) {
|
||||
((AutoPan *)ptr)->SampleRate = SampleRate;
|
||||
((AutoPan *)ptr)->run_adding_gain = 1.0;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
activate_AutoPan(LADSPA_Handle Instance) {
|
||||
|
||||
AutoPan * ptr;
|
||||
|
||||
ptr = (AutoPan *)Instance;
|
||||
ptr->Phase = 0.0f;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Connect a port to a data location. */
|
||||
void
|
||||
connect_port_AutoPan(LADSPA_Handle Instance,
|
||||
unsigned long Port,
|
||||
LADSPA_Data * DataLocation) {
|
||||
|
||||
AutoPan * ptr;
|
||||
|
||||
ptr = (AutoPan *)Instance;
|
||||
switch (Port) {
|
||||
case CONTROL_FREQ:
|
||||
ptr->freq = DataLocation;
|
||||
break;
|
||||
case CONTROL_DEPTH:
|
||||
ptr->depth = DataLocation;
|
||||
break;
|
||||
case CONTROL_GAIN:
|
||||
ptr->gain = DataLocation;
|
||||
break;
|
||||
case INPUT_L:
|
||||
ptr->input_L = DataLocation;
|
||||
break;
|
||||
case INPUT_R:
|
||||
ptr->input_R = DataLocation;
|
||||
break;
|
||||
case OUTPUT_L:
|
||||
ptr->output_L = DataLocation;
|
||||
break;
|
||||
case OUTPUT_R:
|
||||
ptr->output_R = DataLocation;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
run_AutoPan(LADSPA_Handle Instance,
|
||||
unsigned long SampleCount) {
|
||||
|
||||
AutoPan * ptr = (AutoPan *)Instance;
|
||||
|
||||
LADSPA_Data * input_L = ptr->input_L;
|
||||
LADSPA_Data * input_R = ptr->input_R;
|
||||
LADSPA_Data * output_L = ptr->output_L;
|
||||
LADSPA_Data * output_R = ptr->output_R;
|
||||
LADSPA_Data freq = LIMIT(*(ptr->freq),0.0f,20.0f);
|
||||
LADSPA_Data depth = LIMIT(*(ptr->depth),0.0f,100.0f);
|
||||
LADSPA_Data gain = db2lin(LIMIT(*(ptr->gain),-70.0f,20.0f));
|
||||
unsigned long sample_index;
|
||||
LADSPA_Data phase_L = 0;
|
||||
LADSPA_Data phase_R = 0;
|
||||
|
||||
for (sample_index = 0; sample_index < SampleCount; sample_index++) {
|
||||
phase_L = 1024.0f * freq * sample_index / ptr->SampleRate + ptr->Phase;
|
||||
while (phase_L >= 1024.0f)
|
||||
phase_L -= 1024.0f;
|
||||
phase_R = phase_L + 512.0f;
|
||||
while (phase_R >= 1024.0f)
|
||||
phase_R -= 1024.0f;
|
||||
|
||||
*(output_L++) = *(input_L++) * gain *
|
||||
(1 - 0.5*depth/100 + 0.5 * depth/100 * cos_table[(unsigned long) phase_L]);
|
||||
*(output_R++) = *(input_R++) * gain *
|
||||
(1 - 0.5*depth/100 + 0.5 * depth/100 * cos_table[(unsigned long) phase_R]);
|
||||
}
|
||||
ptr->Phase = phase_L;
|
||||
while (ptr->Phase >= 1024.0f)
|
||||
ptr->Phase -= 1024.0f;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
set_run_adding_gain_AutoPan(LADSPA_Handle Instance, LADSPA_Data gain) {
|
||||
|
||||
AutoPan * ptr;
|
||||
|
||||
ptr = (AutoPan *)Instance;
|
||||
|
||||
ptr->run_adding_gain = gain;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
run_adding_AutoPan(LADSPA_Handle Instance,
|
||||
unsigned long SampleCount) {
|
||||
|
||||
AutoPan * ptr = (AutoPan *)Instance;
|
||||
|
||||
LADSPA_Data * input_L = ptr->input_L;
|
||||
LADSPA_Data * input_R = ptr->input_R;
|
||||
LADSPA_Data * output_L = ptr->output_L;
|
||||
LADSPA_Data * output_R = ptr->output_R;
|
||||
LADSPA_Data freq = LIMIT(*(ptr->freq),0.0f,20.0f);
|
||||
LADSPA_Data depth = LIMIT(*(ptr->depth),0.0f,100.0f);
|
||||
LADSPA_Data gain = db2lin(LIMIT(*(ptr->gain),-70.0f,20.0f));
|
||||
unsigned long sample_index;
|
||||
LADSPA_Data phase_L = 0;
|
||||
LADSPA_Data phase_R = 0;
|
||||
|
||||
for (sample_index = 0; sample_index < SampleCount; sample_index++) {
|
||||
phase_L = 1024.0f * freq * sample_index / ptr->SampleRate + ptr->Phase;
|
||||
while (phase_L >= 1024.0f)
|
||||
phase_L -= 1024.0f;
|
||||
phase_R = phase_L + 512.0f;
|
||||
while (phase_R >= 1024.0f)
|
||||
phase_R -= 1024.0f;
|
||||
|
||||
*(output_L++) += *(input_L++) * gain * ptr->run_adding_gain *
|
||||
(1 - 0.5*depth/100 + 0.5 * depth/100 * cos_table[(unsigned long) phase_L]);
|
||||
*(output_R++) += *(input_R++) * gain * ptr->run_adding_gain *
|
||||
(1 - 0.5*depth/100 + 0.5 * depth/100 * cos_table[(unsigned long) phase_R]);
|
||||
}
|
||||
ptr->Phase = phase_L;
|
||||
while (ptr->Phase >= 1024.0f)
|
||||
ptr->Phase -= 1024.0f;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Throw away an AutoPan effect instance. */
|
||||
void
|
||||
cleanup_AutoPan(LADSPA_Handle Instance) {
|
||||
free(Instance);
|
||||
}
|
||||
|
||||
|
||||
|
||||
LADSPA_Descriptor * mono_descriptor = NULL;
|
||||
|
||||
|
||||
|
||||
/* _init() is called automatically when the plugin library is first
|
||||
loaded. */
|
||||
void
|
||||
_init() {
|
||||
|
||||
int i;
|
||||
char ** port_names;
|
||||
LADSPA_PortDescriptor * port_descriptors;
|
||||
LADSPA_PortRangeHint * port_range_hints;
|
||||
|
||||
if ((mono_descriptor =
|
||||
(LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor))) == NULL)
|
||||
exit(1);
|
||||
|
||||
for (i = 0; i < 1024; i++)
|
||||
cos_table[i] = cosf(i * M_PI / 512.0f);
|
||||
|
||||
|
||||
mono_descriptor->UniqueID = ID_STEREO;
|
||||
mono_descriptor->Label = strdup("tap_autopan");
|
||||
mono_descriptor->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
|
||||
mono_descriptor->Name = strdup("TAP AutoPanner");
|
||||
mono_descriptor->Maker = strdup("Tom Szilagyi");
|
||||
mono_descriptor->Copyright = strdup("GPL");
|
||||
mono_descriptor->PortCount = PORTCOUNT_STEREO;
|
||||
|
||||
if ((port_descriptors =
|
||||
(LADSPA_PortDescriptor *)calloc(PORTCOUNT_STEREO, sizeof(LADSPA_PortDescriptor))) == NULL)
|
||||
exit(1);
|
||||
|
||||
mono_descriptor->PortDescriptors = (const LADSPA_PortDescriptor *)port_descriptors;
|
||||
port_descriptors[CONTROL_FREQ] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[CONTROL_DEPTH] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[CONTROL_GAIN] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[INPUT_L] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
|
||||
port_descriptors[INPUT_R] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
|
||||
port_descriptors[OUTPUT_L] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
|
||||
port_descriptors[OUTPUT_R] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
|
||||
|
||||
if ((port_names =
|
||||
(char **)calloc(PORTCOUNT_STEREO, sizeof(char *))) == NULL)
|
||||
exit(1);
|
||||
|
||||
mono_descriptor->PortNames = (const char **)port_names;
|
||||
port_names[CONTROL_FREQ] = strdup("Frequency [Hz]");
|
||||
port_names[CONTROL_DEPTH] = strdup("Depth [%]");
|
||||
port_names[CONTROL_GAIN] = strdup("Gain [dB]");
|
||||
port_names[INPUT_L] = strdup("Input L");
|
||||
port_names[INPUT_R] = strdup("Input R");
|
||||
port_names[OUTPUT_L] = strdup("Output L");
|
||||
port_names[OUTPUT_R] = strdup("Output R");
|
||||
|
||||
if ((port_range_hints =
|
||||
((LADSPA_PortRangeHint *)calloc(PORTCOUNT_STEREO, sizeof(LADSPA_PortRangeHint)))) == NULL)
|
||||
exit(1);
|
||||
|
||||
mono_descriptor->PortRangeHints = (const LADSPA_PortRangeHint *)port_range_hints;
|
||||
port_range_hints[CONTROL_FREQ].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[CONTROL_DEPTH].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[CONTROL_GAIN].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[CONTROL_FREQ].LowerBound = 0;
|
||||
port_range_hints[CONTROL_FREQ].UpperBound = 20;
|
||||
port_range_hints[CONTROL_DEPTH].LowerBound = 0;
|
||||
port_range_hints[CONTROL_DEPTH].UpperBound = 100;
|
||||
port_range_hints[CONTROL_GAIN].LowerBound = -70;
|
||||
port_range_hints[CONTROL_GAIN].UpperBound = 20;
|
||||
port_range_hints[INPUT_L].HintDescriptor = 0;
|
||||
port_range_hints[INPUT_R].HintDescriptor = 0;
|
||||
port_range_hints[OUTPUT_L].HintDescriptor = 0;
|
||||
port_range_hints[OUTPUT_R].HintDescriptor = 0;
|
||||
mono_descriptor->instantiate = instantiate_AutoPan;
|
||||
mono_descriptor->connect_port = connect_port_AutoPan;
|
||||
mono_descriptor->activate = activate_AutoPan;
|
||||
mono_descriptor->run = run_AutoPan;
|
||||
mono_descriptor->run_adding = run_adding_AutoPan;
|
||||
mono_descriptor->set_run_adding_gain = set_run_adding_gain_AutoPan;
|
||||
mono_descriptor->deactivate = NULL;
|
||||
mono_descriptor->cleanup = cleanup_AutoPan;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
delete_descriptor(LADSPA_Descriptor * descriptor) {
|
||||
unsigned long index;
|
||||
if (descriptor) {
|
||||
free((char *)descriptor->Label);
|
||||
free((char *)descriptor->Name);
|
||||
free((char *)descriptor->Maker);
|
||||
free((char *)descriptor->Copyright);
|
||||
free((LADSPA_PortDescriptor *)descriptor->PortDescriptors);
|
||||
for (index = 0; index < descriptor->PortCount; index++)
|
||||
free((char *)(descriptor->PortNames[index]));
|
||||
free((char **)descriptor->PortNames);
|
||||
free((LADSPA_PortRangeHint *)descriptor->PortRangeHints);
|
||||
free(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* _fini() is called automatically when the library is unloaded. */
|
||||
void
|
||||
_fini() {
|
||||
delete_descriptor(mono_descriptor);
|
||||
}
|
||||
|
||||
|
||||
/* Return a descriptor of the requested plugin type. */
|
||||
const LADSPA_Descriptor *
|
||||
ladspa_descriptor(unsigned long Index) {
|
||||
|
||||
switch (Index) {
|
||||
case 0:
|
||||
return mono_descriptor;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
595
plugins/ladspa_effect/tap/tap_chorusflanger.c
Normal file
595
plugins/ladspa_effect/tap/tap_chorusflanger.c
Normal file
@@ -0,0 +1,595 @@
|
||||
/* -*- linux-c -*-
|
||||
Copyright (C) 2004 Tom Szilagyi
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: tap_chorusflanger.c,v 1.3 2004/08/17 09:15:21 tszilagyi Exp $
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "ladspa.h"
|
||||
#include "tap_utils.h"
|
||||
|
||||
|
||||
/* The Unique ID of the plugin: */
|
||||
|
||||
#define ID_STEREO 2159
|
||||
|
||||
/* The port numbers for the plugin: */
|
||||
|
||||
#define FREQ 0
|
||||
#define PHASE 1
|
||||
#define DEPTH 2
|
||||
#define DELAY 3
|
||||
#define CONTOUR 4
|
||||
#define DRYLEVEL 5
|
||||
#define WETLEVEL 6
|
||||
#define INPUT_L 7
|
||||
#define INPUT_R 8
|
||||
#define OUTPUT_L 9
|
||||
#define OUTPUT_R 10
|
||||
|
||||
/* Total number of ports */
|
||||
#define PORTCOUNT_STEREO 11
|
||||
|
||||
|
||||
/*
|
||||
* Largest buffer lengths needed (at 192 kHz).
|
||||
* These are summed up to determine the size of *one* buffer per channel.
|
||||
*/
|
||||
#define DEPTH_BUFLEN 450
|
||||
#define DELAY_BUFLEN 19200
|
||||
|
||||
/* Max. frequency setting */
|
||||
#define MAX_FREQ 5.0f
|
||||
|
||||
/* bandwidth of highpass filters (in octaves) */
|
||||
#define HP_BW 1
|
||||
|
||||
/* cosine table for fast computations */
|
||||
#define COS_TABLE_SIZE 1024
|
||||
LADSPA_Data cos_table[COS_TABLE_SIZE];
|
||||
|
||||
|
||||
/* The structure used to hold port connection information and state */
|
||||
typedef struct {
|
||||
LADSPA_Data * freq;
|
||||
LADSPA_Data * phase;
|
||||
LADSPA_Data * depth;
|
||||
LADSPA_Data * delay;
|
||||
LADSPA_Data * contour;
|
||||
LADSPA_Data * drylevel;
|
||||
LADSPA_Data * wetlevel;
|
||||
LADSPA_Data * input_L;
|
||||
LADSPA_Data * input_R;
|
||||
LADSPA_Data * output_L;
|
||||
LADSPA_Data * output_R;
|
||||
|
||||
LADSPA_Data * ring_L;
|
||||
unsigned long buflen_L;
|
||||
unsigned long pos_L;
|
||||
LADSPA_Data * ring_R;
|
||||
unsigned long buflen_R;
|
||||
unsigned long pos_R;
|
||||
|
||||
biquad highpass_L;
|
||||
biquad highpass_R;
|
||||
|
||||
float cm_phase;
|
||||
float dm_phase;
|
||||
|
||||
unsigned long sample_rate;
|
||||
LADSPA_Data run_adding_gain;
|
||||
} ChorusFlanger;
|
||||
|
||||
|
||||
/* Construct a new plugin instance. */
|
||||
LADSPA_Handle
|
||||
instantiate_ChorusFlanger(const LADSPA_Descriptor * Descriptor,
|
||||
unsigned long sample_rate) {
|
||||
|
||||
LADSPA_Handle * ptr;
|
||||
|
||||
if ((ptr = malloc(sizeof(ChorusFlanger))) != NULL) {
|
||||
((ChorusFlanger *)ptr)->sample_rate = sample_rate;
|
||||
((ChorusFlanger *)ptr)->run_adding_gain = 1.0f;
|
||||
|
||||
|
||||
if ((((ChorusFlanger *)ptr)->ring_L =
|
||||
calloc((DEPTH_BUFLEN + DELAY_BUFLEN) * sample_rate / 192000,
|
||||
sizeof(LADSPA_Data))) == NULL)
|
||||
return NULL;
|
||||
((ChorusFlanger *)ptr)->buflen_L = (DEPTH_BUFLEN + DELAY_BUFLEN) * sample_rate / 192000;
|
||||
((ChorusFlanger *)ptr)->pos_L = 0;
|
||||
|
||||
if ((((ChorusFlanger *)ptr)->ring_R =
|
||||
calloc((DEPTH_BUFLEN + DELAY_BUFLEN) * sample_rate / 192000,
|
||||
sizeof(LADSPA_Data))) == NULL)
|
||||
return NULL;
|
||||
((ChorusFlanger *)ptr)->buflen_R = (DEPTH_BUFLEN + DELAY_BUFLEN) * sample_rate / 192000;
|
||||
((ChorusFlanger *)ptr)->pos_R = 0;
|
||||
|
||||
|
||||
((ChorusFlanger *)ptr)->cm_phase = 0.0f;
|
||||
((ChorusFlanger *)ptr)->dm_phase = 0.0f;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
activate_ChorusFlanger(LADSPA_Handle Instance) {
|
||||
|
||||
ChorusFlanger * ptr = (ChorusFlanger *)Instance;
|
||||
unsigned long i;
|
||||
|
||||
for (i = 0; i < (DEPTH_BUFLEN + DELAY_BUFLEN) * ptr->sample_rate / 192000; i++) {
|
||||
ptr->ring_L[i] = 0.0f;
|
||||
ptr->ring_R[i] = 0.0f;
|
||||
}
|
||||
|
||||
biquad_init(&ptr->highpass_L);
|
||||
biquad_init(&ptr->highpass_R);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Connect a port to a data location. */
|
||||
void
|
||||
connect_port_ChorusFlanger(LADSPA_Handle Instance,
|
||||
unsigned long Port,
|
||||
LADSPA_Data * data) {
|
||||
|
||||
ChorusFlanger * ptr = (ChorusFlanger *)Instance;
|
||||
|
||||
switch (Port) {
|
||||
case FREQ:
|
||||
ptr->freq = data;
|
||||
break;
|
||||
case PHASE:
|
||||
ptr->phase = data;
|
||||
break;
|
||||
case DEPTH:
|
||||
ptr->depth = data;
|
||||
break;
|
||||
case DELAY:
|
||||
ptr->delay = data;
|
||||
break;
|
||||
case CONTOUR:
|
||||
ptr->contour = data;
|
||||
break;
|
||||
case DRYLEVEL:
|
||||
ptr->drylevel = data;
|
||||
break;
|
||||
case WETLEVEL:
|
||||
ptr->wetlevel = data;
|
||||
break;
|
||||
case INPUT_L:
|
||||
ptr->input_L = data;
|
||||
break;
|
||||
case INPUT_R:
|
||||
ptr->input_R = data;
|
||||
break;
|
||||
case OUTPUT_L:
|
||||
ptr->output_L = data;
|
||||
break;
|
||||
case OUTPUT_R:
|
||||
ptr->output_R = data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
run_ChorusFlanger(LADSPA_Handle Instance,
|
||||
unsigned long SampleCount) {
|
||||
|
||||
ChorusFlanger * ptr = (ChorusFlanger *)Instance;
|
||||
|
||||
LADSPA_Data freq = LIMIT(*(ptr->freq), 0.0f, MAX_FREQ);
|
||||
LADSPA_Data phase = LIMIT(*(ptr->phase), 0.0f, 180.0f) / 180.0f;
|
||||
LADSPA_Data depth = 100.0f * ptr->sample_rate / 44100.0f
|
||||
* LIMIT(*(ptr->depth),0.0f,100.0f) / 100.0f;
|
||||
LADSPA_Data delay = LIMIT(*(ptr->delay),0.0f,100.0f);
|
||||
LADSPA_Data contour = LIMIT(*(ptr->contour), 20.0f, 20000.0f);
|
||||
LADSPA_Data drylevel = db2lin(LIMIT(*(ptr->drylevel),-90.0f,20.0f));
|
||||
LADSPA_Data wetlevel = db2lin(LIMIT(*(ptr->wetlevel),-90.0f,20.0f));
|
||||
LADSPA_Data * input_L = ptr->input_L;
|
||||
LADSPA_Data * input_R = ptr->input_R;
|
||||
LADSPA_Data * output_L = ptr->output_L;
|
||||
LADSPA_Data * output_R = ptr->output_R;
|
||||
|
||||
unsigned long sample_index;
|
||||
unsigned long sample_count = SampleCount;
|
||||
|
||||
LADSPA_Data in_L = 0.0f;
|
||||
LADSPA_Data in_R = 0.0f;
|
||||
LADSPA_Data d_L = 0.0f;
|
||||
LADSPA_Data d_R = 0.0f;
|
||||
LADSPA_Data f_L = 0.0f;
|
||||
LADSPA_Data f_R = 0.0f;
|
||||
LADSPA_Data out_L = 0.0f;
|
||||
LADSPA_Data out_R = 0.0f;
|
||||
|
||||
float phase_L = 0.0f;
|
||||
float phase_R = 0.0f;
|
||||
float fpos_L = 0.0f;
|
||||
float fpos_R = 0.0f;
|
||||
float n_L = 0.0f;
|
||||
float n_R = 0.0f;
|
||||
float rem_L = 0.0f;
|
||||
float rem_R = 0.0f;
|
||||
float s_a_L, s_a_R, s_b_L, s_b_R;
|
||||
|
||||
float d_pos = 0.0f;
|
||||
|
||||
if (delay < 1.0f)
|
||||
delay = 1.0f;
|
||||
delay = 100.0f - delay;
|
||||
|
||||
hp_set_params(&ptr->highpass_L, contour, HP_BW, ptr->sample_rate);
|
||||
hp_set_params(&ptr->highpass_R, contour, HP_BW, ptr->sample_rate);
|
||||
|
||||
for (sample_index = 0; sample_index < sample_count; sample_index++) {
|
||||
|
||||
in_L = *(input_L++);
|
||||
in_R = *(input_R++);
|
||||
|
||||
push_buffer(in_L, ptr->ring_L, ptr->buflen_L, &(ptr->pos_L));
|
||||
push_buffer(in_R, ptr->ring_R, ptr->buflen_R, &(ptr->pos_R));
|
||||
|
||||
ptr->cm_phase += freq / ptr->sample_rate * COS_TABLE_SIZE;
|
||||
|
||||
while (ptr->cm_phase >= COS_TABLE_SIZE)
|
||||
ptr->cm_phase -= COS_TABLE_SIZE;
|
||||
|
||||
ptr->dm_phase = phase * COS_TABLE_SIZE / 2.0f;
|
||||
|
||||
phase_L = ptr->cm_phase;
|
||||
phase_R = ptr->cm_phase + ptr->dm_phase;
|
||||
while (phase_R >= COS_TABLE_SIZE)
|
||||
phase_R -= COS_TABLE_SIZE;
|
||||
|
||||
d_pos = delay * ptr->sample_rate / 1000.0f;
|
||||
fpos_L = d_pos + depth * (0.5f + 0.5f * cos_table[(unsigned long)phase_L]);
|
||||
fpos_R = d_pos + depth * (0.5f + 0.5f * cos_table[(unsigned long)phase_R]);
|
||||
|
||||
n_L = floorf(fpos_L);
|
||||
n_R = floorf(fpos_R);
|
||||
rem_L = fpos_L - n_L;
|
||||
rem_R = fpos_R - n_R;
|
||||
|
||||
s_a_L = read_buffer(ptr->ring_L, ptr->buflen_L,
|
||||
ptr->pos_L, (unsigned long) n_L);
|
||||
s_b_L = read_buffer(ptr->ring_L, ptr->buflen_L,
|
||||
ptr->pos_L, (unsigned long) n_L + 1);
|
||||
|
||||
s_a_R = read_buffer(ptr->ring_R, ptr->buflen_R,
|
||||
ptr->pos_R, (unsigned long) n_R);
|
||||
s_b_R = read_buffer(ptr->ring_R, ptr->buflen_R,
|
||||
ptr->pos_R, (unsigned long) n_R + 1);
|
||||
|
||||
d_L = ((1 - rem_L) * s_a_L + rem_L * s_b_L);
|
||||
d_R = ((1 - rem_R) * s_a_R + rem_R * s_b_R);
|
||||
|
||||
f_L = biquad_run(&ptr->highpass_L, d_L);
|
||||
f_R = biquad_run(&ptr->highpass_R, d_R);
|
||||
|
||||
out_L = drylevel * in_L + wetlevel * f_L;
|
||||
out_R = drylevel * in_R + wetlevel * f_R;
|
||||
|
||||
*(output_L++) = out_L;
|
||||
*(output_R++) = out_R;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
set_run_adding_gain_ChorusFlanger(LADSPA_Handle Instance, LADSPA_Data gain) {
|
||||
|
||||
ChorusFlanger * ptr = (ChorusFlanger *)Instance;
|
||||
|
||||
ptr->run_adding_gain = gain;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
run_adding_ChorusFlanger(LADSPA_Handle Instance,
|
||||
unsigned long SampleCount) {
|
||||
|
||||
ChorusFlanger * ptr = (ChorusFlanger *)Instance;
|
||||
|
||||
LADSPA_Data freq = LIMIT(*(ptr->freq), 0.0f, MAX_FREQ);
|
||||
LADSPA_Data phase = LIMIT(*(ptr->phase), 0.0f, 180.0f) / 180.0f;
|
||||
LADSPA_Data depth = 100.0f * ptr->sample_rate / 44100.0f
|
||||
* LIMIT(*(ptr->depth),0.0f,100.0f) / 100.0f;
|
||||
LADSPA_Data delay = LIMIT(*(ptr->delay),0.0f,100.0f);
|
||||
LADSPA_Data contour = LIMIT(*(ptr->contour), 20.0f, 20000.0f);
|
||||
LADSPA_Data drylevel = db2lin(LIMIT(*(ptr->drylevel),-90.0f,20.0f));
|
||||
LADSPA_Data wetlevel = db2lin(LIMIT(*(ptr->wetlevel),-90.0f,20.0f));
|
||||
LADSPA_Data * input_L = ptr->input_L;
|
||||
LADSPA_Data * input_R = ptr->input_R;
|
||||
LADSPA_Data * output_L = ptr->output_L;
|
||||
LADSPA_Data * output_R = ptr->output_R;
|
||||
|
||||
unsigned long sample_index;
|
||||
unsigned long sample_count = SampleCount;
|
||||
|
||||
LADSPA_Data in_L = 0.0f;
|
||||
LADSPA_Data in_R = 0.0f;
|
||||
LADSPA_Data d_L = 0.0f;
|
||||
LADSPA_Data d_R = 0.0f;
|
||||
LADSPA_Data f_L = 0.0f;
|
||||
LADSPA_Data f_R = 0.0f;
|
||||
LADSPA_Data out_L = 0.0f;
|
||||
LADSPA_Data out_R = 0.0f;
|
||||
|
||||
float phase_L = 0.0f;
|
||||
float phase_R = 0.0f;
|
||||
float fpos_L = 0.0f;
|
||||
float fpos_R = 0.0f;
|
||||
float n_L = 0.0f;
|
||||
float n_R = 0.0f;
|
||||
float rem_L = 0.0f;
|
||||
float rem_R = 0.0f;
|
||||
float s_a_L, s_a_R, s_b_L, s_b_R;
|
||||
|
||||
float d_pos = 0.0f;
|
||||
|
||||
if (delay < 1.0f)
|
||||
delay = 1.0f;
|
||||
delay = 100.0f - delay;
|
||||
|
||||
hp_set_params(&ptr->highpass_L, contour, HP_BW, ptr->sample_rate);
|
||||
hp_set_params(&ptr->highpass_R, contour, HP_BW, ptr->sample_rate);
|
||||
|
||||
for (sample_index = 0; sample_index < sample_count; sample_index++) {
|
||||
|
||||
in_L = *(input_L++);
|
||||
in_R = *(input_R++);
|
||||
|
||||
push_buffer(in_L, ptr->ring_L, ptr->buflen_L, &(ptr->pos_L));
|
||||
push_buffer(in_R, ptr->ring_R, ptr->buflen_R, &(ptr->pos_R));
|
||||
|
||||
ptr->cm_phase += freq / ptr->sample_rate * COS_TABLE_SIZE;
|
||||
|
||||
while (ptr->cm_phase >= COS_TABLE_SIZE)
|
||||
ptr->cm_phase -= COS_TABLE_SIZE;
|
||||
|
||||
ptr->dm_phase = phase * COS_TABLE_SIZE / 2.0f;
|
||||
|
||||
phase_L = ptr->cm_phase;
|
||||
phase_R = ptr->cm_phase + ptr->dm_phase;
|
||||
while (phase_R >= COS_TABLE_SIZE)
|
||||
phase_R -= COS_TABLE_SIZE;
|
||||
|
||||
d_pos = delay * ptr->sample_rate / 1000.0f;
|
||||
fpos_L = d_pos + depth * (0.5f + 0.5f * cos_table[(unsigned long)phase_L]);
|
||||
fpos_R = d_pos + depth * (0.5f + 0.5f * cos_table[(unsigned long)phase_R]);
|
||||
|
||||
n_L = floorf(fpos_L);
|
||||
n_R = floorf(fpos_R);
|
||||
rem_L = fpos_L - n_L;
|
||||
rem_R = fpos_R - n_R;
|
||||
|
||||
s_a_L = read_buffer(ptr->ring_L, ptr->buflen_L,
|
||||
ptr->pos_L, (unsigned long) n_L);
|
||||
s_b_L = read_buffer(ptr->ring_L, ptr->buflen_L,
|
||||
ptr->pos_L, (unsigned long) n_L + 1);
|
||||
|
||||
s_a_R = read_buffer(ptr->ring_R, ptr->buflen_R,
|
||||
ptr->pos_R, (unsigned long) n_R);
|
||||
s_b_R = read_buffer(ptr->ring_R, ptr->buflen_R,
|
||||
ptr->pos_R, (unsigned long) n_R + 1);
|
||||
|
||||
d_L = ((1 - rem_L) * s_a_L + rem_L * s_b_L);
|
||||
d_R = ((1 - rem_R) * s_a_R + rem_R * s_b_R);
|
||||
|
||||
f_L = biquad_run(&ptr->highpass_L, d_L);
|
||||
f_R = biquad_run(&ptr->highpass_R, d_R);
|
||||
|
||||
out_L = drylevel * in_L + wetlevel * f_L;
|
||||
out_R = drylevel * in_R + wetlevel * f_R;
|
||||
|
||||
*(output_L++) += ptr->run_adding_gain * out_L;
|
||||
*(output_R++) += ptr->run_adding_gain * out_R;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Throw away a ChorusFlanger effect instance. */
|
||||
void
|
||||
cleanup_ChorusFlanger(LADSPA_Handle Instance) {
|
||||
|
||||
ChorusFlanger * ptr = (ChorusFlanger *)Instance;
|
||||
free(ptr->ring_L);
|
||||
free(ptr->ring_R);
|
||||
free(Instance);
|
||||
}
|
||||
|
||||
|
||||
|
||||
LADSPA_Descriptor * stereo_descriptor = NULL;
|
||||
|
||||
|
||||
|
||||
/* _init() is called automatically when the plugin library is first
|
||||
loaded. */
|
||||
void
|
||||
_init() {
|
||||
|
||||
char ** port_names;
|
||||
LADSPA_PortDescriptor * port_descriptors;
|
||||
LADSPA_PortRangeHint * port_range_hints;
|
||||
int i;
|
||||
|
||||
if ((stereo_descriptor =
|
||||
(LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor))) == NULL)
|
||||
exit(1);
|
||||
|
||||
for (i = 0; i < COS_TABLE_SIZE; i++)
|
||||
cos_table[i] = cosf(i * 2.0f * M_PI / COS_TABLE_SIZE);
|
||||
|
||||
stereo_descriptor->UniqueID = ID_STEREO;
|
||||
stereo_descriptor->Label = strdup("tap_chorusflanger");
|
||||
stereo_descriptor->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
|
||||
stereo_descriptor->Name = strdup("TAP Chorus/Flanger");
|
||||
stereo_descriptor->Maker = strdup("Tom Szilagyi");
|
||||
stereo_descriptor->Copyright = strdup("GPL");
|
||||
stereo_descriptor->PortCount = PORTCOUNT_STEREO;
|
||||
|
||||
if ((port_descriptors =
|
||||
(LADSPA_PortDescriptor *)calloc(PORTCOUNT_STEREO, sizeof(LADSPA_PortDescriptor))) == NULL)
|
||||
exit(1);
|
||||
|
||||
stereo_descriptor->PortDescriptors = (const LADSPA_PortDescriptor *)port_descriptors;
|
||||
port_descriptors[FREQ] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[PHASE] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[DEPTH] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[DELAY] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[CONTOUR] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[DRYLEVEL] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[WETLEVEL] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[INPUT_L] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
|
||||
port_descriptors[INPUT_R] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
|
||||
port_descriptors[OUTPUT_L] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
|
||||
port_descriptors[OUTPUT_R] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
|
||||
|
||||
if ((port_names =
|
||||
(char **)calloc(PORTCOUNT_STEREO, sizeof(char *))) == NULL)
|
||||
exit(1);
|
||||
|
||||
stereo_descriptor->PortNames = (const char **)port_names;
|
||||
port_names[FREQ] = strdup("Frequency [Hz]");
|
||||
port_names[PHASE] = strdup("L/R Phase Shift [deg]");
|
||||
port_names[DEPTH] = strdup("Depth [%]");
|
||||
port_names[DELAY] = strdup("Delay [ms]");
|
||||
port_names[CONTOUR] = strdup("Contour [Hz]");
|
||||
port_names[DRYLEVEL] = strdup("Dry Level [dB]");
|
||||
port_names[WETLEVEL] = strdup("Wet Level [dB]");
|
||||
port_names[INPUT_L] = strdup("Input_L");
|
||||
port_names[INPUT_R] = strdup("Input_R");
|
||||
port_names[OUTPUT_L] = strdup("Output_L");
|
||||
port_names[OUTPUT_R] = strdup("Output_R");
|
||||
|
||||
if ((port_range_hints =
|
||||
((LADSPA_PortRangeHint *)calloc(PORTCOUNT_STEREO, sizeof(LADSPA_PortRangeHint)))) == NULL)
|
||||
exit(1);
|
||||
|
||||
stereo_descriptor->PortRangeHints = (const LADSPA_PortRangeHint *)port_range_hints;
|
||||
port_range_hints[FREQ].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_LOW);
|
||||
port_range_hints[PHASE].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_MIDDLE);
|
||||
port_range_hints[DEPTH].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_HIGH);
|
||||
port_range_hints[DELAY].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_LOW);
|
||||
port_range_hints[CONTOUR].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_100);
|
||||
port_range_hints[DRYLEVEL].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[WETLEVEL].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[FREQ].LowerBound = 0.0f;
|
||||
port_range_hints[FREQ].UpperBound = MAX_FREQ;
|
||||
port_range_hints[PHASE].LowerBound = 0.0f;
|
||||
port_range_hints[PHASE].UpperBound = 180.0f;
|
||||
port_range_hints[DEPTH].LowerBound = 0.0f;
|
||||
port_range_hints[DEPTH].UpperBound = 100.0f;
|
||||
port_range_hints[DELAY].LowerBound = 0.0f;
|
||||
port_range_hints[DELAY].UpperBound = 100.0f;
|
||||
port_range_hints[CONTOUR].LowerBound = 20.0f;
|
||||
port_range_hints[CONTOUR].UpperBound = 20000.0f;
|
||||
port_range_hints[DRYLEVEL].LowerBound = -90.0f;
|
||||
port_range_hints[DRYLEVEL].UpperBound = +20.0f;
|
||||
port_range_hints[WETLEVEL].LowerBound = -90.0f;
|
||||
port_range_hints[WETLEVEL].UpperBound = +20.0f;
|
||||
port_range_hints[INPUT_L].HintDescriptor = 0;
|
||||
port_range_hints[INPUT_R].HintDescriptor = 0;
|
||||
port_range_hints[OUTPUT_L].HintDescriptor = 0;
|
||||
port_range_hints[OUTPUT_R].HintDescriptor = 0;
|
||||
stereo_descriptor->instantiate = instantiate_ChorusFlanger;
|
||||
stereo_descriptor->connect_port = connect_port_ChorusFlanger;
|
||||
stereo_descriptor->activate = activate_ChorusFlanger;
|
||||
stereo_descriptor->run = run_ChorusFlanger;
|
||||
stereo_descriptor->run_adding = run_adding_ChorusFlanger;
|
||||
stereo_descriptor->set_run_adding_gain = set_run_adding_gain_ChorusFlanger;
|
||||
stereo_descriptor->deactivate = NULL;
|
||||
stereo_descriptor->cleanup = cleanup_ChorusFlanger;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
delete_descriptor(LADSPA_Descriptor * descriptor) {
|
||||
unsigned long index;
|
||||
if (descriptor) {
|
||||
free((char *)descriptor->Label);
|
||||
free((char *)descriptor->Name);
|
||||
free((char *)descriptor->Maker);
|
||||
free((char *)descriptor->Copyright);
|
||||
free((LADSPA_PortDescriptor *)descriptor->PortDescriptors);
|
||||
for (index = 0; index < descriptor->PortCount; index++)
|
||||
free((char *)(descriptor->PortNames[index]));
|
||||
free((char **)descriptor->PortNames);
|
||||
free((LADSPA_PortRangeHint *)descriptor->PortRangeHints);
|
||||
free(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* _fini() is called automatically when the library is unloaded. */
|
||||
void
|
||||
_fini() {
|
||||
delete_descriptor(stereo_descriptor);
|
||||
}
|
||||
|
||||
|
||||
/* Return a descriptor of the requested plugin type. */
|
||||
const LADSPA_Descriptor *
|
||||
ladspa_descriptor(unsigned long Index) {
|
||||
|
||||
switch (Index) {
|
||||
case 0:
|
||||
return stereo_descriptor;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
491
plugins/ladspa_effect/tap/tap_deesser.c
Normal file
491
plugins/ladspa_effect/tap/tap_deesser.c
Normal file
@@ -0,0 +1,491 @@
|
||||
/* -*- linux-c -*-
|
||||
Copyright (C) 2004 Tom Szilagyi
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: tap_deesser.c,v 1.7 2004/05/01 16:15:06 tszilagyi Exp $
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "ladspa.h"
|
||||
#include "tap_utils.h"
|
||||
|
||||
/* The Unique ID of the plugin: */
|
||||
|
||||
#define ID_MONO 2147
|
||||
|
||||
/* The port numbers for the plugin: */
|
||||
|
||||
#define THRESHOLD 0
|
||||
#define FREQ 1
|
||||
#define SIDECHAIN 2
|
||||
#define MONITOR 3
|
||||
#define ATTENUAT 4
|
||||
#define INPUT 5
|
||||
#define OUTPUT 6
|
||||
|
||||
|
||||
/* Total number of ports */
|
||||
|
||||
#define PORTCOUNT_MONO 7
|
||||
|
||||
|
||||
/* Bandwidth of sidechain lowpass/highpass filters */
|
||||
#define SIDECH_BW 0.3f
|
||||
|
||||
/* Used to hold 10 ms gain data, enough for sample rates up to 192 kHz */
|
||||
#define RINGBUF_SIZE 2000
|
||||
|
||||
|
||||
|
||||
/* 4 digits precision from 1.000 to 9.999 */
|
||||
LADSPA_Data log10_table[9000];
|
||||
|
||||
|
||||
/* The structure used to hold port connection information and state */
|
||||
|
||||
typedef struct {
|
||||
LADSPA_Data * threshold;
|
||||
LADSPA_Data * audiomode;
|
||||
LADSPA_Data * freq;
|
||||
LADSPA_Data * sidechain;
|
||||
LADSPA_Data * monitor;
|
||||
LADSPA_Data * attenuat;
|
||||
LADSPA_Data * input;
|
||||
LADSPA_Data * output;
|
||||
|
||||
biquad sidech_lo_filter;
|
||||
biquad sidech_hi_filter;
|
||||
LADSPA_Data * ringbuffer;
|
||||
unsigned long buflen;
|
||||
unsigned long pos;
|
||||
LADSPA_Data sum;
|
||||
LADSPA_Data old_freq;
|
||||
|
||||
unsigned long sample_rate;
|
||||
LADSPA_Data run_adding_gain;
|
||||
} DeEsser;
|
||||
|
||||
|
||||
/* fast linear to decibel conversion using log10_table[] */
|
||||
LADSPA_Data fast_lin2db(LADSPA_Data lin) {
|
||||
|
||||
unsigned long k;
|
||||
int exp = 0;
|
||||
LADSPA_Data mant = ABS(lin);
|
||||
|
||||
/* sanity checks */
|
||||
if (mant == 0.0f)
|
||||
return(-1.0f/0.0f); /* -inf */
|
||||
if (mant == 1.0f/0.0f) /* +inf */
|
||||
return(mant);
|
||||
|
||||
while (mant < 1.0f) {
|
||||
mant *= 10;
|
||||
exp --;
|
||||
}
|
||||
while (mant >= 10.0f) {
|
||||
mant /= 10;
|
||||
exp ++;
|
||||
}
|
||||
|
||||
k = (mant - 0.999999f) * 1000.0f;
|
||||
return 20.0f * (log10_table[k] + exp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Construct a new plugin instance. */
|
||||
LADSPA_Handle
|
||||
instantiate_DeEsser(const LADSPA_Descriptor * Descriptor,
|
||||
unsigned long SampleRate) {
|
||||
|
||||
LADSPA_Handle * ptr;
|
||||
|
||||
if ((ptr = malloc(sizeof(DeEsser))) != NULL) {
|
||||
((DeEsser *)ptr)->sample_rate = SampleRate;
|
||||
((DeEsser *)ptr)->run_adding_gain = 1.0f;
|
||||
|
||||
/* init filters */
|
||||
biquad_init(&((DeEsser *)ptr)->sidech_lo_filter);
|
||||
biquad_init(&((DeEsser *)ptr)->sidech_hi_filter);
|
||||
|
||||
/* alloc mem for ringbuffer */
|
||||
if ((((DeEsser *)ptr)->ringbuffer =
|
||||
calloc(RINGBUF_SIZE, sizeof(LADSPA_Data))) == NULL)
|
||||
return NULL;
|
||||
|
||||
/* 10 ms attenuation data is stored */
|
||||
((DeEsser *)ptr)->buflen = ((DeEsser *)ptr)->sample_rate / 100;
|
||||
|
||||
((DeEsser *)ptr)->pos = 0;
|
||||
((DeEsser *)ptr)->sum = 0.0f;
|
||||
((DeEsser *)ptr)->old_freq = 0;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
activate_DeEsser(LADSPA_Handle Instance) {
|
||||
|
||||
DeEsser * ptr = (DeEsser *)Instance;
|
||||
unsigned long i;
|
||||
|
||||
for (i = 0; i < RINGBUF_SIZE; i++)
|
||||
ptr->ringbuffer[i] = 0.0f;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Connect a port to a data location. */
|
||||
void
|
||||
connect_port_DeEsser(LADSPA_Handle Instance,
|
||||
unsigned long Port,
|
||||
LADSPA_Data * DataLocation) {
|
||||
|
||||
DeEsser * ptr;
|
||||
|
||||
ptr = (DeEsser *)Instance;
|
||||
switch (Port) {
|
||||
case THRESHOLD:
|
||||
ptr->threshold = DataLocation;
|
||||
break;
|
||||
case FREQ:
|
||||
ptr->freq = DataLocation;
|
||||
break;
|
||||
case SIDECHAIN:
|
||||
ptr->sidechain = DataLocation;
|
||||
break;
|
||||
case MONITOR:
|
||||
ptr->monitor = DataLocation;
|
||||
break;
|
||||
case ATTENUAT:
|
||||
ptr->attenuat = DataLocation;
|
||||
*(ptr->attenuat) = 0.0f;
|
||||
break;
|
||||
case INPUT:
|
||||
ptr->input = DataLocation;
|
||||
break;
|
||||
case OUTPUT:
|
||||
ptr->output = DataLocation;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
run_DeEsser(LADSPA_Handle Instance,
|
||||
unsigned long SampleCount) {
|
||||
|
||||
DeEsser * ptr = (DeEsser *)Instance;
|
||||
|
||||
LADSPA_Data * input = ptr->input;
|
||||
LADSPA_Data * output = ptr->output;
|
||||
LADSPA_Data threshold = LIMIT(*(ptr->threshold),-50.0f,10.0f);
|
||||
LADSPA_Data freq = LIMIT(*(ptr->freq),2000.0f,16000.0f);
|
||||
LADSPA_Data sidechain = LIMIT(*(ptr->sidechain),0.0f,1.0f);
|
||||
LADSPA_Data monitor = LIMIT(*(ptr->monitor),0.0f,1.0f);
|
||||
unsigned long sample_index;
|
||||
|
||||
LADSPA_Data in = 0;
|
||||
LADSPA_Data out = 0;
|
||||
LADSPA_Data sidech = 0;
|
||||
LADSPA_Data ampl_db = 0.0f;
|
||||
LADSPA_Data attn = 0.0f;
|
||||
LADSPA_Data max_attn = 0.0f;
|
||||
|
||||
|
||||
if (ptr->old_freq != freq) {
|
||||
lp_set_params(&ptr->sidech_lo_filter, freq, SIDECH_BW, ptr->sample_rate);
|
||||
hp_set_params(&ptr->sidech_hi_filter, freq, SIDECH_BW, ptr->sample_rate);
|
||||
ptr->old_freq = freq;
|
||||
}
|
||||
|
||||
for (sample_index = 0; sample_index < SampleCount; sample_index++) {
|
||||
|
||||
in = *(input++);
|
||||
|
||||
/* process sidechain filters */
|
||||
sidech = biquad_run(&ptr->sidech_hi_filter, in);
|
||||
if (sidechain > 0.1f)
|
||||
sidech = biquad_run(&ptr->sidech_lo_filter, sidech);
|
||||
|
||||
ampl_db = fast_lin2db(sidech);
|
||||
if (ampl_db <= threshold)
|
||||
attn = 0.0f;
|
||||
else
|
||||
attn = -0.5f * (ampl_db - threshold);
|
||||
|
||||
ptr->sum += attn;
|
||||
ptr->sum -= push_buffer(attn, ptr->ringbuffer, ptr->buflen, &ptr->pos);
|
||||
|
||||
if (-1.0f * ptr->sum > max_attn)
|
||||
max_attn = -0.01f * ptr->sum;
|
||||
|
||||
in *= db2lin(ptr->sum / 100.0f);
|
||||
|
||||
|
||||
/* output selector */
|
||||
if (monitor > 0.1f)
|
||||
out = sidech;
|
||||
else
|
||||
out = in;
|
||||
|
||||
*(output++) = out;
|
||||
*(ptr->attenuat) = LIMIT(max_attn,0,10);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
set_run_adding_gain_DeEsser(LADSPA_Handle Instance, LADSPA_Data gain) {
|
||||
|
||||
DeEsser * ptr = (DeEsser *)Instance;
|
||||
|
||||
ptr->run_adding_gain = gain;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
run_adding_DeEsser(LADSPA_Handle Instance,
|
||||
unsigned long SampleCount) {
|
||||
|
||||
DeEsser * ptr = (DeEsser *)Instance;
|
||||
|
||||
LADSPA_Data * input = ptr->input;
|
||||
LADSPA_Data * output = ptr->output;
|
||||
LADSPA_Data threshold = LIMIT(*(ptr->threshold),-50.0f,10.0f);
|
||||
LADSPA_Data freq = LIMIT(*(ptr->freq),2000.0f,16000.0f);
|
||||
LADSPA_Data sidechain = LIMIT(*(ptr->sidechain),0.0f,1.0f);
|
||||
LADSPA_Data monitor = LIMIT(*(ptr->monitor),0.0f,1.0f);
|
||||
unsigned long sample_index;
|
||||
|
||||
LADSPA_Data in = 0;
|
||||
LADSPA_Data out = 0;
|
||||
LADSPA_Data sidech = 0;
|
||||
LADSPA_Data ampl_db = 0.0f;
|
||||
LADSPA_Data attn = 0.0f;
|
||||
LADSPA_Data max_attn = 0.0f;
|
||||
|
||||
|
||||
if (ptr->old_freq != freq) {
|
||||
lp_set_params(&ptr->sidech_lo_filter, freq, SIDECH_BW, ptr->sample_rate);
|
||||
hp_set_params(&ptr->sidech_hi_filter, freq, SIDECH_BW, ptr->sample_rate);
|
||||
ptr->old_freq = freq;
|
||||
}
|
||||
|
||||
for (sample_index = 0; sample_index < SampleCount; sample_index++) {
|
||||
|
||||
in = *(input++);
|
||||
|
||||
/* process sidechain filters */
|
||||
sidech = biquad_run(&ptr->sidech_hi_filter, in);
|
||||
if (sidechain > 0.1f)
|
||||
sidech = biquad_run(&ptr->sidech_lo_filter, sidech);
|
||||
|
||||
ampl_db = 20.0f * log10f(sidech);
|
||||
if (ampl_db <= threshold)
|
||||
attn = 0.0f;
|
||||
else
|
||||
attn = -0.5f * (ampl_db - threshold);
|
||||
|
||||
ptr->sum += attn;
|
||||
ptr->sum -= push_buffer(attn, ptr->ringbuffer, ptr->buflen, &ptr->pos);
|
||||
|
||||
if (-1.0f * ptr->sum > max_attn)
|
||||
max_attn = -0.01f * ptr->sum;
|
||||
|
||||
in *= db2lin(ptr->sum / 100.0f);
|
||||
|
||||
|
||||
/* output selector */
|
||||
if (monitor > 0.1f)
|
||||
out = sidech;
|
||||
else
|
||||
out = in;
|
||||
|
||||
*(output++) += ptr->run_adding_gain * out;
|
||||
*(ptr->attenuat) = LIMIT(max_attn,0,10);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Throw away a DeEsser effect instance. */
|
||||
void
|
||||
cleanup_DeEsser(LADSPA_Handle Instance) {
|
||||
|
||||
DeEsser * ptr = (DeEsser *)Instance;
|
||||
free(ptr->ringbuffer);
|
||||
free(Instance);
|
||||
}
|
||||
|
||||
|
||||
|
||||
LADSPA_Descriptor * mono_descriptor = NULL;
|
||||
|
||||
|
||||
|
||||
/* _init() is called automatically when the plugin library is first
|
||||
loaded. */
|
||||
void
|
||||
_init() {
|
||||
|
||||
int i;
|
||||
char ** port_names;
|
||||
LADSPA_PortDescriptor * port_descriptors;
|
||||
LADSPA_PortRangeHint * port_range_hints;
|
||||
|
||||
if ((mono_descriptor =
|
||||
(LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor))) == NULL)
|
||||
exit(1);
|
||||
|
||||
|
||||
/* compute the log10 table */
|
||||
for (i = 0; i < 9000; i++)
|
||||
log10_table[i] = log10f(1.0f + i / 1000.0f);
|
||||
|
||||
|
||||
mono_descriptor->UniqueID = ID_MONO;
|
||||
mono_descriptor->Label = strdup("tap_deesser");
|
||||
mono_descriptor->Properties = 0;
|
||||
mono_descriptor->Name = strdup("TAP DeEsser");
|
||||
mono_descriptor->Maker = strdup("Tom Szilagyi");
|
||||
mono_descriptor->Copyright = strdup("GPL");
|
||||
mono_descriptor->PortCount = PORTCOUNT_MONO;
|
||||
|
||||
if ((port_descriptors =
|
||||
(LADSPA_PortDescriptor *)calloc(PORTCOUNT_MONO, sizeof(LADSPA_PortDescriptor))) == NULL)
|
||||
exit(1);
|
||||
|
||||
mono_descriptor->PortDescriptors = (const LADSPA_PortDescriptor *)port_descriptors;
|
||||
port_descriptors[THRESHOLD] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[FREQ] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[SIDECHAIN] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[MONITOR] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[ATTENUAT] = LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[INPUT] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
|
||||
port_descriptors[OUTPUT] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
|
||||
|
||||
if ((port_names =
|
||||
(char **)calloc(PORTCOUNT_MONO, sizeof(char *))) == NULL)
|
||||
exit(1);
|
||||
|
||||
mono_descriptor->PortNames = (const char **)port_names;
|
||||
port_names[THRESHOLD] = strdup("Threshold Level [dB]");
|
||||
port_names[FREQ] = strdup("Frequency [Hz]");
|
||||
port_names[SIDECHAIN] = strdup("Sidechain Filter");
|
||||
port_names[MONITOR] = strdup("Monitor");
|
||||
port_names[ATTENUAT] = strdup("Attenuation [dB]");
|
||||
port_names[INPUT] = strdup("Input");
|
||||
port_names[OUTPUT] = strdup("Output");
|
||||
|
||||
if ((port_range_hints =
|
||||
((LADSPA_PortRangeHint *)calloc(PORTCOUNT_MONO, sizeof(LADSPA_PortRangeHint)))) == NULL)
|
||||
exit(1);
|
||||
|
||||
mono_descriptor->PortRangeHints = (const LADSPA_PortRangeHint *)port_range_hints;
|
||||
port_range_hints[THRESHOLD].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[FREQ].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_LOW);
|
||||
port_range_hints[SIDECHAIN].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_INTEGER |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[MONITOR].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_INTEGER |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[ATTENUAT].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[THRESHOLD].LowerBound = -50;
|
||||
port_range_hints[THRESHOLD].UpperBound = 10;
|
||||
port_range_hints[FREQ].LowerBound = 2000;
|
||||
port_range_hints[FREQ].UpperBound = 16000;
|
||||
port_range_hints[SIDECHAIN].LowerBound = 0.0f;
|
||||
port_range_hints[SIDECHAIN].UpperBound = 1.01f;
|
||||
port_range_hints[MONITOR].LowerBound = 0.0f;
|
||||
port_range_hints[MONITOR].UpperBound = 1.01f;
|
||||
port_range_hints[ATTENUAT].LowerBound = 0.0f;
|
||||
port_range_hints[ATTENUAT].UpperBound = 10.0f;
|
||||
port_range_hints[INPUT].HintDescriptor = 0;
|
||||
port_range_hints[OUTPUT].HintDescriptor = 0;
|
||||
mono_descriptor->instantiate = instantiate_DeEsser;
|
||||
mono_descriptor->connect_port = connect_port_DeEsser;
|
||||
mono_descriptor->activate = activate_DeEsser;
|
||||
mono_descriptor->run = run_DeEsser;
|
||||
mono_descriptor->run_adding = run_adding_DeEsser;
|
||||
mono_descriptor->set_run_adding_gain = set_run_adding_gain_DeEsser;
|
||||
mono_descriptor->deactivate = NULL;
|
||||
mono_descriptor->cleanup = cleanup_DeEsser;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
delete_descriptor(LADSPA_Descriptor * descriptor) {
|
||||
unsigned long index;
|
||||
if (descriptor) {
|
||||
free((char *)descriptor->Label);
|
||||
free((char *)descriptor->Name);
|
||||
free((char *)descriptor->Maker);
|
||||
free((char *)descriptor->Copyright);
|
||||
free((LADSPA_PortDescriptor *)descriptor->PortDescriptors);
|
||||
for (index = 0; index < descriptor->PortCount; index++)
|
||||
free((char *)(descriptor->PortNames[index]));
|
||||
free((char **)descriptor->PortNames);
|
||||
free((LADSPA_PortRangeHint *)descriptor->PortRangeHints);
|
||||
free(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* _fini() is called automatically when the library is unloaded. */
|
||||
void
|
||||
_fini() {
|
||||
delete_descriptor(mono_descriptor);
|
||||
}
|
||||
|
||||
|
||||
/* Return a descriptor of the requested plugin type. */
|
||||
const LADSPA_Descriptor *
|
||||
ladspa_descriptor(unsigned long Index) {
|
||||
|
||||
switch (Index) {
|
||||
case 0:
|
||||
return mono_descriptor;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
737
plugins/ladspa_effect/tap/tap_doubler.c
Normal file
737
plugins/ladspa_effect/tap/tap_doubler.c
Normal file
@@ -0,0 +1,737 @@
|
||||
/* -*- linux-c -*-
|
||||
Copyright (C) 2004 Tom Szilagyi
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: tap_doubler.c,v 1.4 2004/08/13 18:34:31 tszilagyi Exp $
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "ladspa.h"
|
||||
#include "tap_utils.h"
|
||||
|
||||
|
||||
/* The Unique ID of the plugin: */
|
||||
|
||||
#define ID_STEREO 2156
|
||||
|
||||
/* The port numbers for the plugin: */
|
||||
|
||||
#define TIME 0
|
||||
#define PITCH 1
|
||||
#define DRYLEVEL 2
|
||||
#define DRYPOSL 3
|
||||
#define DRYPOSR 4
|
||||
#define WETLEVEL 5
|
||||
#define WETPOSL 6
|
||||
#define WETPOSR 7
|
||||
#define INPUT_L 8
|
||||
#define INPUT_R 9
|
||||
#define OUTPUT_L 10
|
||||
#define OUTPUT_R 11
|
||||
|
||||
/* Total number of ports */
|
||||
|
||||
|
||||
#define PORTCOUNT_STEREO 12
|
||||
|
||||
|
||||
/* Number of pink noise samples to be generated at once */
|
||||
#define NOISE_LEN 1024
|
||||
|
||||
/*
|
||||
* Largest buffer length needed (at 192 kHz).
|
||||
*/
|
||||
#define BUFLEN 11520
|
||||
|
||||
|
||||
|
||||
/* The structure used to hold port connection information and state */
|
||||
|
||||
typedef struct {
|
||||
LADSPA_Data * time;
|
||||
LADSPA_Data * pitch;
|
||||
LADSPA_Data * drylevel;
|
||||
LADSPA_Data * dryposl;
|
||||
LADSPA_Data * dryposr;
|
||||
LADSPA_Data * wetlevel;
|
||||
LADSPA_Data * wetposl;
|
||||
LADSPA_Data * wetposr;
|
||||
LADSPA_Data * input_L;
|
||||
LADSPA_Data * input_R;
|
||||
LADSPA_Data * output_L;
|
||||
LADSPA_Data * output_R;
|
||||
|
||||
LADSPA_Data old_time;
|
||||
LADSPA_Data old_pitch;
|
||||
|
||||
LADSPA_Data * ring_L;
|
||||
unsigned long buflen_L;
|
||||
unsigned long pos_L;
|
||||
|
||||
LADSPA_Data * ring_R;
|
||||
unsigned long buflen_R;
|
||||
unsigned long pos_R;
|
||||
|
||||
LADSPA_Data * ring_pnoise;
|
||||
unsigned long buflen_pnoise;
|
||||
unsigned long pos_pnoise;
|
||||
|
||||
LADSPA_Data * ring_dnoise;
|
||||
unsigned long buflen_dnoise;
|
||||
unsigned long pos_dnoise;
|
||||
|
||||
float delay;
|
||||
float d_delay;
|
||||
float p_delay;
|
||||
unsigned long n_delay;
|
||||
|
||||
float pitchmod;
|
||||
float d_pitch;
|
||||
float p_pitch;
|
||||
unsigned long n_pitch;
|
||||
|
||||
unsigned long p_stretch;
|
||||
unsigned long d_stretch;
|
||||
|
||||
unsigned long sample_rate;
|
||||
LADSPA_Data run_adding_gain;
|
||||
} Doubler;
|
||||
|
||||
|
||||
/* generate fractal pattern using Midpoint Displacement Method
|
||||
* v: buffer of floats to output fractal pattern to
|
||||
* N: length of v, MUST be integer power of 2 (ie 128, 256, ...)
|
||||
* H: Hurst constant, between 0 and 0.9999 (fractal dimension)
|
||||
*/
|
||||
void
|
||||
fractal(LADSPA_Data * v, int N, float H) {
|
||||
|
||||
int l = N;
|
||||
int k;
|
||||
float r = 1.0f;
|
||||
int c;
|
||||
|
||||
v[0] = 0;
|
||||
while (l > 1) {
|
||||
k = N / l;
|
||||
for (c = 0; c < k; c++) {
|
||||
v[c*l + l/2] = (v[c*l] + v[((c+1) * l) % N]) / 2.0f +
|
||||
2.0f * r * (rand() - (float)RAND_MAX/2.0f) / (float)RAND_MAX;
|
||||
v[c*l + l/2] = LIMIT(v[c*l + l/2], -1.0f, 1.0f);
|
||||
}
|
||||
l /= 2;
|
||||
r /= powf(2, H);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Construct a new plugin instance. */
|
||||
LADSPA_Handle
|
||||
instantiate_Doubler(const LADSPA_Descriptor * Descriptor,
|
||||
unsigned long sample_rate) {
|
||||
|
||||
LADSPA_Handle * ptr;
|
||||
|
||||
if ((ptr = malloc(sizeof(Doubler))) != NULL) {
|
||||
((Doubler *)ptr)->sample_rate = sample_rate;
|
||||
((Doubler *)ptr)->run_adding_gain = 1.0f;
|
||||
|
||||
if ((((Doubler *)ptr)->ring_L =
|
||||
calloc(BUFLEN * sample_rate / 192000, sizeof(LADSPA_Data))) == NULL)
|
||||
return NULL;
|
||||
((Doubler *)ptr)->buflen_L = BUFLEN * sample_rate / 192000;
|
||||
((Doubler *)ptr)->pos_L = 0;
|
||||
|
||||
if ((((Doubler *)ptr)->ring_R =
|
||||
calloc(BUFLEN * sample_rate / 192000, sizeof(LADSPA_Data))) == NULL)
|
||||
return NULL;
|
||||
((Doubler *)ptr)->buflen_R = BUFLEN * sample_rate / 192000;
|
||||
((Doubler *)ptr)->pos_R = 0;
|
||||
|
||||
if ((((Doubler *)ptr)->ring_pnoise =
|
||||
calloc(NOISE_LEN, sizeof(LADSPA_Data))) == NULL)
|
||||
return NULL;
|
||||
((Doubler *)ptr)->buflen_pnoise = NOISE_LEN;
|
||||
((Doubler *)ptr)->pos_pnoise = 0;
|
||||
|
||||
if ((((Doubler *)ptr)->ring_dnoise =
|
||||
calloc(NOISE_LEN, sizeof(LADSPA_Data))) == NULL)
|
||||
return NULL;
|
||||
((Doubler *)ptr)->buflen_dnoise = NOISE_LEN;
|
||||
((Doubler *)ptr)->pos_dnoise = 0;
|
||||
|
||||
((Doubler *)ptr)->d_stretch = sample_rate / 10;
|
||||
((Doubler *)ptr)->p_stretch = sample_rate / 1000;
|
||||
|
||||
((Doubler *)ptr)->delay = 0.0f;
|
||||
((Doubler *)ptr)->d_delay = 0.0f;
|
||||
((Doubler *)ptr)->p_delay = 0.0f;
|
||||
((Doubler *)ptr)->n_delay = ((Doubler *)ptr)->d_stretch;
|
||||
|
||||
((Doubler *)ptr)->pitchmod = 0.0f;
|
||||
((Doubler *)ptr)->d_pitch = 0.0f;
|
||||
((Doubler *)ptr)->p_pitch = 0.0f;
|
||||
((Doubler *)ptr)->n_pitch = ((Doubler *)ptr)->p_stretch;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
activate_Doubler(LADSPA_Handle Instance) {
|
||||
|
||||
Doubler * ptr = (Doubler *)Instance;
|
||||
unsigned long i;
|
||||
|
||||
for (i = 0; i < BUFLEN * ptr->sample_rate / 192000; i++) {
|
||||
ptr->ring_L[i] = 0.0f;
|
||||
ptr->ring_R[i] = 0.0f;
|
||||
}
|
||||
|
||||
ptr->old_time = -1.0f;
|
||||
ptr->old_pitch = -1.0f;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Connect a port to a data location. */
|
||||
void
|
||||
connect_port_Doubler(LADSPA_Handle Instance,
|
||||
unsigned long Port,
|
||||
LADSPA_Data * data) {
|
||||
|
||||
Doubler * ptr = (Doubler *)Instance;
|
||||
|
||||
switch (Port) {
|
||||
case TIME:
|
||||
ptr->time = data;
|
||||
break;
|
||||
case PITCH:
|
||||
ptr->pitch = data;
|
||||
break;
|
||||
case DRYLEVEL:
|
||||
ptr->drylevel = data;
|
||||
break;
|
||||
case DRYPOSL:
|
||||
ptr->dryposl = data;
|
||||
break;
|
||||
case DRYPOSR:
|
||||
ptr->dryposr = data;
|
||||
break;
|
||||
case WETLEVEL:
|
||||
ptr->wetlevel = data;
|
||||
break;
|
||||
case WETPOSL:
|
||||
ptr->wetposl = data;
|
||||
break;
|
||||
case WETPOSR:
|
||||
ptr->wetposr = data;
|
||||
break;
|
||||
case INPUT_L:
|
||||
ptr->input_L = data;
|
||||
break;
|
||||
case INPUT_R:
|
||||
ptr->input_R = data;
|
||||
break;
|
||||
case OUTPUT_L:
|
||||
ptr->output_L = data;
|
||||
break;
|
||||
case OUTPUT_R:
|
||||
ptr->output_R = data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
run_Doubler(LADSPA_Handle Instance,
|
||||
unsigned long SampleCount) {
|
||||
|
||||
Doubler * ptr = (Doubler *)Instance;
|
||||
|
||||
LADSPA_Data pitch = LIMIT(*(ptr->pitch),0.0f,1.0f) + 0.75f;
|
||||
LADSPA_Data depth = LIMIT(((1.0f - LIMIT(*(ptr->pitch),0.0f,1.0f)) * 1.75f + 0.25f) *
|
||||
ptr->sample_rate / 6000.0f / M_PI,
|
||||
0, ptr->buflen_L / 2);
|
||||
LADSPA_Data time = LIMIT(*(ptr->time), 0.0f, 1.0f) + 0.5f;
|
||||
LADSPA_Data drylevel = db2lin(LIMIT(*(ptr->drylevel),-90.0f,20.0f));
|
||||
LADSPA_Data wetlevel = db2lin(LIMIT(*(ptr->wetlevel),-90.0f,20.0f));
|
||||
LADSPA_Data dryposl = 1.0f - LIMIT(*(ptr->dryposl), 0.0f, 1.0f);
|
||||
LADSPA_Data dryposr = LIMIT(*(ptr->dryposr), 0.0f, 1.0f);
|
||||
LADSPA_Data wetposl = 1.0f - LIMIT(*(ptr->wetposl), 0.0f, 1.0f);
|
||||
LADSPA_Data wetposr = LIMIT(*(ptr->wetposr), 0.0f, 1.0f);
|
||||
LADSPA_Data * input_L = ptr->input_L;
|
||||
LADSPA_Data * input_R = ptr->input_R;
|
||||
LADSPA_Data * output_L = ptr->output_L;
|
||||
LADSPA_Data * output_R = ptr->output_R;
|
||||
|
||||
unsigned long sample_index;
|
||||
unsigned long sample_count = SampleCount;
|
||||
|
||||
LADSPA_Data in_L = 0.0f;
|
||||
LADSPA_Data in_R = 0.0f;
|
||||
LADSPA_Data out_L = 0.0f;
|
||||
LADSPA_Data out_R = 0.0f;
|
||||
|
||||
LADSPA_Data fpos = 0.0f;
|
||||
LADSPA_Data n = 0.0f;
|
||||
LADSPA_Data rem = 0.0f;
|
||||
LADSPA_Data s_a_L, s_a_R, s_b_L, s_b_R;
|
||||
LADSPA_Data prev_p_pitch = 0.0f;
|
||||
LADSPA_Data prev_p_delay = 0.0f;
|
||||
LADSPA_Data delay;
|
||||
|
||||
LADSPA_Data drystream_L = 0.0f;
|
||||
LADSPA_Data drystream_R = 0.0f;
|
||||
LADSPA_Data wetstream_L = 0.0f;
|
||||
LADSPA_Data wetstream_R = 0.0f;
|
||||
|
||||
if (ptr->old_pitch != pitch) {
|
||||
ptr->pitchmod = ptr->p_pitch;
|
||||
prev_p_pitch = ptr->p_pitch;
|
||||
fractal(ptr->ring_pnoise, NOISE_LEN, pitch);
|
||||
ptr->pos_pnoise = 0;
|
||||
ptr->p_pitch = push_buffer(0.0f, ptr->ring_pnoise,
|
||||
ptr->buflen_pnoise, &(ptr->pos_pnoise));
|
||||
ptr->d_pitch = (ptr->p_pitch - prev_p_pitch) / (float)(ptr->p_stretch);
|
||||
ptr->n_pitch = 0;
|
||||
|
||||
ptr->old_pitch = pitch;
|
||||
}
|
||||
|
||||
if (ptr->old_time != time) {
|
||||
ptr->delay = ptr->p_delay;
|
||||
prev_p_delay = ptr->p_delay;
|
||||
fractal(ptr->ring_dnoise, NOISE_LEN, time);
|
||||
ptr->pos_dnoise = 0;
|
||||
ptr->p_delay = push_buffer(0.0f, ptr->ring_dnoise,
|
||||
ptr->buflen_dnoise, &(ptr->pos_dnoise));
|
||||
ptr->d_delay = (ptr->p_delay - prev_p_delay) / (float)(ptr->d_stretch);
|
||||
ptr->n_delay = 0;
|
||||
|
||||
ptr->old_time = time;
|
||||
}
|
||||
|
||||
|
||||
for (sample_index = 0; sample_index < sample_count; sample_index++) {
|
||||
|
||||
in_L = *(input_L++);
|
||||
in_R = *(input_R++);
|
||||
|
||||
push_buffer(in_L, ptr->ring_L, ptr->buflen_L, &(ptr->pos_L));
|
||||
push_buffer(in_R, ptr->ring_R, ptr->buflen_R, &(ptr->pos_R));
|
||||
|
||||
if (ptr->n_pitch < ptr->p_stretch) {
|
||||
ptr->pitchmod += ptr->d_pitch;
|
||||
ptr->n_pitch++;
|
||||
} else {
|
||||
ptr->pitchmod = ptr->p_pitch;
|
||||
prev_p_pitch = ptr->p_pitch;
|
||||
if (!ptr->pos_pnoise) {
|
||||
fractal(ptr->ring_pnoise, NOISE_LEN, pitch);
|
||||
}
|
||||
ptr->p_pitch = push_buffer(0.0f, ptr->ring_pnoise,
|
||||
ptr->buflen_pnoise, &(ptr->pos_pnoise));
|
||||
ptr->d_pitch = (ptr->p_pitch - prev_p_pitch) / (float)(ptr->p_stretch);
|
||||
ptr->n_pitch = 0;
|
||||
}
|
||||
|
||||
if (ptr->n_delay < ptr->d_stretch) {
|
||||
ptr->delay += ptr->d_delay;
|
||||
ptr->n_delay++;
|
||||
} else {
|
||||
ptr->delay = ptr->p_delay;
|
||||
prev_p_delay = ptr->p_delay;
|
||||
if (!ptr->pos_dnoise) {
|
||||
fractal(ptr->ring_dnoise, NOISE_LEN, time);
|
||||
}
|
||||
ptr->p_delay = push_buffer(0.0f, ptr->ring_dnoise,
|
||||
ptr->buflen_dnoise, &(ptr->pos_dnoise));
|
||||
ptr->d_delay = (ptr->p_delay - prev_p_delay) / (float)(ptr->d_stretch);
|
||||
ptr->n_delay = 0;
|
||||
}
|
||||
|
||||
delay = (12.5f * ptr->delay + 37.5f) * ptr->sample_rate / 1000.0f;
|
||||
fpos = ptr->buflen_L - depth * (1.0f - ptr->pitchmod) - delay - 1.0f;
|
||||
n = floorf(fpos);
|
||||
rem = fpos - n;
|
||||
|
||||
s_a_L = read_buffer(ptr->ring_L, ptr->buflen_L,
|
||||
ptr->pos_L, (unsigned long) n);
|
||||
s_b_L = read_buffer(ptr->ring_L, ptr->buflen_L,
|
||||
ptr->pos_L, (unsigned long) n + 1);
|
||||
|
||||
s_a_R = read_buffer(ptr->ring_R, ptr->buflen_R,
|
||||
ptr->pos_R, (unsigned long) n);
|
||||
s_b_R = read_buffer(ptr->ring_R, ptr->buflen_R,
|
||||
ptr->pos_R, (unsigned long) n + 1);
|
||||
|
||||
drystream_L = drylevel * in_L;
|
||||
drystream_R = drylevel * in_R;
|
||||
wetstream_L = wetlevel * ((1 - rem) * s_a_L + rem * s_b_L);
|
||||
wetstream_R = wetlevel * ((1 - rem) * s_a_R + rem * s_b_R);
|
||||
|
||||
out_L = dryposl * drystream_L + (1.0f - dryposr) * drystream_R +
|
||||
wetposl * wetstream_L + (1.0f - wetposr) * wetstream_R;
|
||||
out_R = (1.0f - dryposl) * drystream_L + dryposr * drystream_R +
|
||||
(1.0f - wetposl) * wetstream_L + wetposr * wetstream_R;
|
||||
|
||||
*(output_L++) = out_L;
|
||||
*(output_R++) = out_R;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
set_run_adding_gain_Doubler(LADSPA_Handle Instance, LADSPA_Data gain) {
|
||||
|
||||
Doubler * ptr = (Doubler *)Instance;
|
||||
|
||||
ptr->run_adding_gain = gain;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
run_adding_Doubler(LADSPA_Handle Instance,
|
||||
unsigned long SampleCount) {
|
||||
|
||||
Doubler * ptr = (Doubler *)Instance;
|
||||
|
||||
LADSPA_Data pitch = LIMIT(*(ptr->pitch),0.0f,1.0f) + 0.75f;
|
||||
LADSPA_Data depth = LIMIT(((1.0f - LIMIT(*(ptr->pitch),0.0f,1.0f)) * 1.75f + 0.25f) *
|
||||
ptr->sample_rate / 6000.0f / M_PI,
|
||||
0, ptr->buflen_L / 2);
|
||||
LADSPA_Data time = LIMIT(*(ptr->time), 0.0f, 1.0f) + 0.5f;
|
||||
LADSPA_Data drylevel = db2lin(LIMIT(*(ptr->drylevel),-90.0f,20.0f));
|
||||
LADSPA_Data wetlevel = db2lin(LIMIT(*(ptr->wetlevel),-90.0f,20.0f));
|
||||
LADSPA_Data dryposl = 1.0f - LIMIT(*(ptr->dryposl), 0.0f, 1.0f);
|
||||
LADSPA_Data dryposr = LIMIT(*(ptr->dryposr), 0.0f, 1.0f);
|
||||
LADSPA_Data wetposl = 1.0f - LIMIT(*(ptr->wetposl), 0.0f, 1.0f);
|
||||
LADSPA_Data wetposr = LIMIT(*(ptr->wetposr), 0.0f, 1.0f);
|
||||
LADSPA_Data * input_L = ptr->input_L;
|
||||
LADSPA_Data * input_R = ptr->input_R;
|
||||
LADSPA_Data * output_L = ptr->output_L;
|
||||
LADSPA_Data * output_R = ptr->output_R;
|
||||
|
||||
unsigned long sample_index;
|
||||
unsigned long sample_count = SampleCount;
|
||||
|
||||
LADSPA_Data in_L = 0.0f;
|
||||
LADSPA_Data in_R = 0.0f;
|
||||
LADSPA_Data out_L = 0.0f;
|
||||
LADSPA_Data out_R = 0.0f;
|
||||
|
||||
LADSPA_Data fpos = 0.0f;
|
||||
LADSPA_Data n = 0.0f;
|
||||
LADSPA_Data rem = 0.0f;
|
||||
LADSPA_Data s_a_L, s_a_R, s_b_L, s_b_R;
|
||||
LADSPA_Data prev_p_pitch = 0.0f;
|
||||
LADSPA_Data prev_p_delay = 0.0f;
|
||||
LADSPA_Data delay;
|
||||
|
||||
LADSPA_Data drystream_L = 0.0f;
|
||||
LADSPA_Data drystream_R = 0.0f;
|
||||
LADSPA_Data wetstream_L = 0.0f;
|
||||
LADSPA_Data wetstream_R = 0.0f;
|
||||
|
||||
if (ptr->old_pitch != pitch) {
|
||||
ptr->pitchmod = ptr->p_pitch;
|
||||
prev_p_pitch = ptr->p_pitch;
|
||||
fractal(ptr->ring_pnoise, NOISE_LEN, pitch);
|
||||
ptr->pos_pnoise = 0;
|
||||
ptr->p_pitch = push_buffer(0.0f, ptr->ring_pnoise,
|
||||
ptr->buflen_pnoise, &(ptr->pos_pnoise));
|
||||
ptr->d_pitch = (ptr->p_pitch - prev_p_pitch) / (float)(ptr->p_stretch);
|
||||
ptr->n_pitch = 0;
|
||||
|
||||
ptr->old_pitch = pitch;
|
||||
}
|
||||
|
||||
if (ptr->old_time != time) {
|
||||
ptr->delay = ptr->p_delay;
|
||||
prev_p_delay = ptr->p_delay;
|
||||
fractal(ptr->ring_dnoise, NOISE_LEN, time);
|
||||
ptr->pos_dnoise = 0;
|
||||
ptr->p_delay = push_buffer(0.0f, ptr->ring_dnoise,
|
||||
ptr->buflen_dnoise, &(ptr->pos_dnoise));
|
||||
ptr->d_delay = (ptr->p_delay - prev_p_delay) / (float)(ptr->d_stretch);
|
||||
ptr->n_delay = 0;
|
||||
|
||||
ptr->old_time = time;
|
||||
}
|
||||
|
||||
|
||||
for (sample_index = 0; sample_index < sample_count; sample_index++) {
|
||||
|
||||
in_L = *(input_L++);
|
||||
in_R = *(input_R++);
|
||||
|
||||
push_buffer(in_L, ptr->ring_L, ptr->buflen_L, &(ptr->pos_L));
|
||||
push_buffer(in_R, ptr->ring_R, ptr->buflen_R, &(ptr->pos_R));
|
||||
|
||||
if (ptr->n_pitch < ptr->p_stretch) {
|
||||
ptr->pitchmod += ptr->d_pitch;
|
||||
ptr->n_pitch++;
|
||||
} else {
|
||||
ptr->pitchmod = ptr->p_pitch;
|
||||
prev_p_pitch = ptr->p_pitch;
|
||||
if (!ptr->pos_pnoise) {
|
||||
fractal(ptr->ring_pnoise, NOISE_LEN, pitch);
|
||||
}
|
||||
ptr->p_pitch = push_buffer(0.0f, ptr->ring_pnoise,
|
||||
ptr->buflen_pnoise, &(ptr->pos_pnoise));
|
||||
ptr->d_pitch = (ptr->p_pitch - prev_p_pitch) / (float)(ptr->p_stretch);
|
||||
ptr->n_pitch = 0;
|
||||
}
|
||||
|
||||
if (ptr->n_delay < ptr->d_stretch) {
|
||||
ptr->delay += ptr->d_delay;
|
||||
ptr->n_delay++;
|
||||
} else {
|
||||
ptr->delay = ptr->p_delay;
|
||||
prev_p_delay = ptr->p_delay;
|
||||
if (!ptr->pos_dnoise) {
|
||||
fractal(ptr->ring_dnoise, NOISE_LEN, time);
|
||||
}
|
||||
ptr->p_delay = push_buffer(0.0f, ptr->ring_dnoise,
|
||||
ptr->buflen_dnoise, &(ptr->pos_dnoise));
|
||||
ptr->d_delay = (ptr->p_delay - prev_p_delay) / (float)(ptr->d_stretch);
|
||||
ptr->n_delay = 0;
|
||||
}
|
||||
|
||||
delay = (12.5f * ptr->delay + 37.5f) * ptr->sample_rate / 1000.0f;
|
||||
fpos = ptr->buflen_L - depth * (1.0f - ptr->pitchmod) - delay - 1.0f;
|
||||
n = floorf(fpos);
|
||||
rem = fpos - n;
|
||||
|
||||
s_a_L = read_buffer(ptr->ring_L, ptr->buflen_L,
|
||||
ptr->pos_L, (unsigned long) n);
|
||||
s_b_L = read_buffer(ptr->ring_L, ptr->buflen_L,
|
||||
ptr->pos_L, (unsigned long) n + 1);
|
||||
|
||||
s_a_R = read_buffer(ptr->ring_R, ptr->buflen_R,
|
||||
ptr->pos_R, (unsigned long) n);
|
||||
s_b_R = read_buffer(ptr->ring_R, ptr->buflen_R,
|
||||
ptr->pos_R, (unsigned long) n + 1);
|
||||
|
||||
drystream_L = drylevel * in_L;
|
||||
drystream_R = drylevel * in_R;
|
||||
wetstream_L = wetlevel * ((1 - rem) * s_a_L + rem * s_b_L);
|
||||
wetstream_R = wetlevel * ((1 - rem) * s_a_R + rem * s_b_R);
|
||||
|
||||
out_L = dryposl * drystream_L + (1.0f - dryposr) * drystream_R +
|
||||
wetposl * wetstream_L + (1.0f - wetposr) * wetstream_R;
|
||||
out_R = (1.0f - dryposl) * drystream_L + dryposr * drystream_R +
|
||||
(1.0f - wetposl) * wetstream_L + wetposr * wetstream_R;
|
||||
|
||||
*(output_L++) += ptr->run_adding_gain * out_L;
|
||||
*(output_R++) += ptr->run_adding_gain * out_R;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Throw away a Doubler effect instance. */
|
||||
void
|
||||
cleanup_Doubler(LADSPA_Handle Instance) {
|
||||
|
||||
Doubler * ptr = (Doubler *)Instance;
|
||||
free(ptr->ring_L);
|
||||
free(ptr->ring_R);
|
||||
free(ptr->ring_pnoise);
|
||||
free(ptr->ring_dnoise);
|
||||
free(Instance);
|
||||
}
|
||||
|
||||
|
||||
|
||||
LADSPA_Descriptor * stereo_descriptor = NULL;
|
||||
|
||||
|
||||
|
||||
/* _init() is called automatically when the plugin library is first
|
||||
loaded. */
|
||||
void
|
||||
_init() {
|
||||
|
||||
char ** port_names;
|
||||
LADSPA_PortDescriptor * port_descriptors;
|
||||
LADSPA_PortRangeHint * port_range_hints;
|
||||
|
||||
if ((stereo_descriptor =
|
||||
(LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor))) == NULL)
|
||||
exit(1);
|
||||
|
||||
stereo_descriptor->UniqueID = ID_STEREO;
|
||||
stereo_descriptor->Label = strdup("tap_doubler");
|
||||
stereo_descriptor->Properties = 0;
|
||||
stereo_descriptor->Name = strdup("TAP Fractal Doubler");
|
||||
stereo_descriptor->Maker = strdup("Tom Szilagyi");
|
||||
stereo_descriptor->Copyright = strdup("GPL");
|
||||
stereo_descriptor->PortCount = PORTCOUNT_STEREO;
|
||||
|
||||
if ((port_descriptors =
|
||||
(LADSPA_PortDescriptor *)calloc(PORTCOUNT_STEREO, sizeof(LADSPA_PortDescriptor))) == NULL)
|
||||
exit(1);
|
||||
|
||||
stereo_descriptor->PortDescriptors = (const LADSPA_PortDescriptor *)port_descriptors;
|
||||
port_descriptors[TIME] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[PITCH] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[DRYLEVEL] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[DRYPOSL] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[DRYPOSR] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[WETLEVEL] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[WETPOSL] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[WETPOSR] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[INPUT_L] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
|
||||
port_descriptors[INPUT_R] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
|
||||
port_descriptors[OUTPUT_L] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
|
||||
port_descriptors[OUTPUT_R] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
|
||||
|
||||
if ((port_names =
|
||||
(char **)calloc(PORTCOUNT_STEREO, sizeof(char *))) == NULL)
|
||||
exit(1);
|
||||
|
||||
stereo_descriptor->PortNames = (const char **)port_names;
|
||||
port_names[TIME] = strdup("Time Tracking");
|
||||
port_names[PITCH] = strdup("Pitch Tracking");
|
||||
port_names[DRYLEVEL] = strdup("Dry Level [dB]");
|
||||
port_names[DRYPOSL] = strdup("Dry Left Position");
|
||||
port_names[DRYPOSR] = strdup("Dry Right Position");
|
||||
port_names[WETLEVEL] = strdup("Wet Level [dB]");
|
||||
port_names[WETPOSL] = strdup("Wet Left Position");
|
||||
port_names[WETPOSR] = strdup("Wet Right Position");
|
||||
port_names[INPUT_L] = strdup("Input_L");
|
||||
port_names[INPUT_R] = strdup("Input_R");
|
||||
port_names[OUTPUT_L] = strdup("Output_L");
|
||||
port_names[OUTPUT_R] = strdup("Output_R");
|
||||
|
||||
if ((port_range_hints =
|
||||
((LADSPA_PortRangeHint *)calloc(PORTCOUNT_STEREO, sizeof(LADSPA_PortRangeHint)))) == NULL)
|
||||
exit(1);
|
||||
|
||||
stereo_descriptor->PortRangeHints = (const LADSPA_PortRangeHint *)port_range_hints;
|
||||
port_range_hints[TIME].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_MIDDLE);
|
||||
port_range_hints[PITCH].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_MIDDLE);
|
||||
port_range_hints[DRYLEVEL].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[DRYPOSL].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_MINIMUM);
|
||||
port_range_hints[DRYPOSR].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_MAXIMUM);
|
||||
port_range_hints[WETLEVEL].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[WETPOSL].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_MINIMUM);
|
||||
port_range_hints[WETPOSR].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_MAXIMUM);
|
||||
port_range_hints[TIME].LowerBound = 0.0f;
|
||||
port_range_hints[TIME].UpperBound = 1.0f;
|
||||
port_range_hints[PITCH].LowerBound = 0.0f;
|
||||
port_range_hints[PITCH].UpperBound = 1.0f;
|
||||
port_range_hints[DRYLEVEL].LowerBound = -90.0f;
|
||||
port_range_hints[DRYLEVEL].UpperBound = +20.0f;
|
||||
port_range_hints[DRYPOSL].LowerBound = 0.0f;
|
||||
port_range_hints[DRYPOSL].UpperBound = 1.0f;
|
||||
port_range_hints[DRYPOSR].LowerBound = 0.0f;
|
||||
port_range_hints[DRYPOSR].UpperBound = 1.0f;
|
||||
port_range_hints[WETLEVEL].LowerBound = -90.0f;
|
||||
port_range_hints[WETLEVEL].UpperBound = +20.0f;
|
||||
port_range_hints[WETPOSL].LowerBound = 0.0f;
|
||||
port_range_hints[WETPOSL].UpperBound = 1.0f;
|
||||
port_range_hints[WETPOSR].LowerBound = 0.0f;
|
||||
port_range_hints[WETPOSR].UpperBound = 1.0f;
|
||||
port_range_hints[INPUT_L].HintDescriptor = 0;
|
||||
port_range_hints[INPUT_R].HintDescriptor = 0;
|
||||
port_range_hints[OUTPUT_L].HintDescriptor = 0;
|
||||
port_range_hints[OUTPUT_R].HintDescriptor = 0;
|
||||
stereo_descriptor->instantiate = instantiate_Doubler;
|
||||
stereo_descriptor->connect_port = connect_port_Doubler;
|
||||
stereo_descriptor->activate = activate_Doubler;
|
||||
stereo_descriptor->run = run_Doubler;
|
||||
stereo_descriptor->run_adding = run_adding_Doubler;
|
||||
stereo_descriptor->set_run_adding_gain = set_run_adding_gain_Doubler;
|
||||
stereo_descriptor->deactivate = NULL;
|
||||
stereo_descriptor->cleanup = cleanup_Doubler;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
delete_descriptor(LADSPA_Descriptor * descriptor) {
|
||||
unsigned long index;
|
||||
if (descriptor) {
|
||||
free((char *)descriptor->Label);
|
||||
free((char *)descriptor->Name);
|
||||
free((char *)descriptor->Maker);
|
||||
free((char *)descriptor->Copyright);
|
||||
free((LADSPA_PortDescriptor *)descriptor->PortDescriptors);
|
||||
for (index = 0; index < descriptor->PortCount; index++)
|
||||
free((char *)(descriptor->PortNames[index]));
|
||||
free((char **)descriptor->PortNames);
|
||||
free((LADSPA_PortRangeHint *)descriptor->PortRangeHints);
|
||||
free(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* _fini() is called automatically when the library is unloaded. */
|
||||
void
|
||||
_fini() {
|
||||
delete_descriptor(stereo_descriptor);
|
||||
}
|
||||
|
||||
|
||||
/* Return a descriptor of the requested plugin type. */
|
||||
const LADSPA_Descriptor *
|
||||
ladspa_descriptor(unsigned long Index) {
|
||||
|
||||
switch (Index) {
|
||||
case 0:
|
||||
return stereo_descriptor;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
666
plugins/ladspa_effect/tap/tap_dynamics_m.c
Normal file
666
plugins/ladspa_effect/tap/tap_dynamics_m.c
Normal file
@@ -0,0 +1,666 @@
|
||||
/* -*- linux-c -*-
|
||||
Copyright (C) 2004 Tom Szilagyi
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: tap_dynamics_m.c,v 1.2 2004/06/15 14:50:55 tszilagyi Exp $
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "ladspa.h"
|
||||
#include "tap_utils.h"
|
||||
|
||||
|
||||
/* ***** VERY IMPORTANT! *****
|
||||
*
|
||||
* If you enable this, the plugin will use float arithmetics in DSP
|
||||
* calculations. This usually yields lower average CPU usage, but
|
||||
* occasionaly may result in high CPU peaks which cause trouble to you
|
||||
* and your JACK server. The default is to use fixpoint arithmetics
|
||||
* (with the following #define commented out). But (depending on the
|
||||
* processor on which you run the code) you may find floating point
|
||||
* mode usable.
|
||||
*/
|
||||
/*#define DYN_CALC_FLOAT*/
|
||||
|
||||
|
||||
typedef signed int sample;
|
||||
|
||||
/* coefficient for float to sample (signed int) conversion */
|
||||
#define F2S 2147483
|
||||
|
||||
|
||||
#ifdef DYN_CALC_FLOAT
|
||||
typedef LADSPA_Data dyn_t;
|
||||
typedef float rms_t;
|
||||
#else
|
||||
typedef sample dyn_t;
|
||||
typedef int64_t rms_t;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* The Unique ID of the plugin: */
|
||||
|
||||
#define ID_MONO 2152
|
||||
|
||||
/* The port numbers for the plugin: */
|
||||
|
||||
#define ATTACK 0
|
||||
#define RELEASE 1
|
||||
#define OFFSGAIN 2
|
||||
#define MUGAIN 3
|
||||
#define RMSENV 4
|
||||
#define MODGAIN 5
|
||||
#define MODE 6
|
||||
#define INPUT 7
|
||||
#define OUTPUT 8
|
||||
|
||||
|
||||
/* Total number of ports */
|
||||
|
||||
#define PORTCOUNT_MONO 9
|
||||
|
||||
|
||||
#define TABSIZE 256
|
||||
#define RMSSIZE 64
|
||||
|
||||
|
||||
typedef struct {
|
||||
rms_t buffer[RMSSIZE];
|
||||
unsigned int pos;
|
||||
rms_t sum;
|
||||
} rms_env;
|
||||
|
||||
|
||||
/* max. number of breakpoints on in/out dB graph */
|
||||
#define MAX_POINTS 20
|
||||
|
||||
typedef struct {
|
||||
LADSPA_Data x;
|
||||
LADSPA_Data y;
|
||||
} GRAPH_POINT;
|
||||
|
||||
typedef struct {
|
||||
unsigned long num_points;
|
||||
GRAPH_POINT points[MAX_POINTS];
|
||||
} DYNAMICS_DATA;
|
||||
|
||||
#include "tap_dynamics_presets.h"
|
||||
|
||||
|
||||
/* The structure used to hold port connection information and state */
|
||||
|
||||
typedef struct {
|
||||
LADSPA_Data * attack;
|
||||
LADSPA_Data * release;
|
||||
LADSPA_Data * offsgain;
|
||||
LADSPA_Data * mugain;
|
||||
LADSPA_Data * rmsenv;
|
||||
LADSPA_Data * modgain;
|
||||
LADSPA_Data * mode;
|
||||
LADSPA_Data * input;
|
||||
LADSPA_Data * output;
|
||||
unsigned long sample_rate;
|
||||
|
||||
float * as;
|
||||
unsigned long count;
|
||||
dyn_t amp;
|
||||
dyn_t env;
|
||||
float gain;
|
||||
float gain_out;
|
||||
rms_env * rms;
|
||||
rms_t sum;
|
||||
|
||||
DYNAMICS_DATA graph;
|
||||
|
||||
LADSPA_Data run_adding_gain;
|
||||
} Dynamics;
|
||||
|
||||
|
||||
|
||||
/* RMS envelope stuff, grabbed without a second thought from Steve Harris's swh-plugins, util/rms.c */
|
||||
/* Adapted, though, to be able to use fixed-point arithmetics as well. */
|
||||
|
||||
rms_env *
|
||||
rms_env_new(void) {
|
||||
|
||||
rms_env * new = (rms_env *)calloc(1, sizeof(rms_env));
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
void
|
||||
rms_env_reset(rms_env *r) {
|
||||
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < RMSSIZE; i++) {
|
||||
r->buffer[i] = 0.0f;
|
||||
}
|
||||
r->pos = 0;
|
||||
r->sum = 0.0f;
|
||||
}
|
||||
|
||||
inline static
|
||||
dyn_t
|
||||
rms_env_process(rms_env *r, const rms_t x) {
|
||||
|
||||
r->sum -= r->buffer[r->pos];
|
||||
r->sum += x;
|
||||
r->buffer[r->pos] = x;
|
||||
r->pos = (r->pos + 1) & (RMSSIZE - 1);
|
||||
|
||||
#ifdef DYN_CALC_FLOAT
|
||||
return sqrt(r->sum / (float)RMSSIZE);
|
||||
#else
|
||||
return sqrt(r->sum / RMSSIZE);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline
|
||||
LADSPA_Data
|
||||
get_table_gain(int mode, LADSPA_Data level) {
|
||||
|
||||
LADSPA_Data x1 = -80.0f;
|
||||
LADSPA_Data y1 = -80.0f;
|
||||
LADSPA_Data x2 = 0.0f;
|
||||
LADSPA_Data y2 = 0.0f;
|
||||
int i = 0;
|
||||
|
||||
if (level <= -80.0f)
|
||||
return get_table_gain(mode, -79.9f);
|
||||
|
||||
while (i < dyn_data[mode].num_points && dyn_data[mode].points[i].x < level) {
|
||||
x1 = dyn_data[mode].points[i].x;
|
||||
y1 = dyn_data[mode].points[i].y;
|
||||
i++;
|
||||
}
|
||||
if (i < dyn_data[mode].num_points) {
|
||||
x2 = dyn_data[mode].points[i].x;
|
||||
y2 = dyn_data[mode].points[i].y;
|
||||
} else
|
||||
return 0.0f;
|
||||
|
||||
return y1 + ((level - x1) * (y2 - y1) / (x2 - x1)) - level;
|
||||
}
|
||||
|
||||
|
||||
/* Construct a new plugin instance. */
|
||||
LADSPA_Handle
|
||||
instantiate_Dynamics(const LADSPA_Descriptor * Descriptor, unsigned long sample_rate) {
|
||||
|
||||
LADSPA_Handle * ptr;
|
||||
|
||||
float * as = NULL;
|
||||
unsigned int count = 0;
|
||||
dyn_t amp = 0.0f;
|
||||
dyn_t env = 0.0f;
|
||||
float gain = 0.0f;
|
||||
float gain_out = 0.0f;
|
||||
rms_env * rms = NULL;
|
||||
rms_t sum = 0;
|
||||
int i;
|
||||
|
||||
if ((ptr = malloc(sizeof(Dynamics))) == NULL)
|
||||
return NULL;
|
||||
|
||||
((Dynamics *)ptr)->sample_rate = sample_rate;
|
||||
((Dynamics *)ptr)->run_adding_gain = 1.0;
|
||||
|
||||
if ((rms = rms_env_new()) == NULL)
|
||||
return NULL;
|
||||
|
||||
if ((as = malloc(TABSIZE * sizeof(float))) == NULL)
|
||||
return NULL;
|
||||
|
||||
as[0] = 1.0f;
|
||||
for (i = 1; i < TABSIZE; i++) {
|
||||
as[i] = expf(-1.0f / (sample_rate * (float)i / (float)TABSIZE));
|
||||
}
|
||||
|
||||
((Dynamics *)ptr)->as = as;
|
||||
((Dynamics *)ptr)->count = count;
|
||||
((Dynamics *)ptr)->amp = amp;
|
||||
((Dynamics *)ptr)->env = env;
|
||||
((Dynamics *)ptr)->gain = gain;
|
||||
((Dynamics *)ptr)->gain_out = gain_out;
|
||||
((Dynamics *)ptr)->rms = rms;
|
||||
((Dynamics *)ptr)->sum = sum;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Connect a port to a data location. */
|
||||
void
|
||||
connect_port_Dynamics(LADSPA_Handle Instance,
|
||||
unsigned long Port,
|
||||
LADSPA_Data * DataLocation) {
|
||||
|
||||
Dynamics * ptr = (Dynamics *)Instance;
|
||||
|
||||
switch (Port) {
|
||||
case ATTACK:
|
||||
ptr->attack = DataLocation;
|
||||
break;
|
||||
case RELEASE:
|
||||
ptr->release = DataLocation;
|
||||
break;
|
||||
case OFFSGAIN:
|
||||
ptr->offsgain = DataLocation;
|
||||
break;
|
||||
case MUGAIN:
|
||||
ptr->mugain = DataLocation;
|
||||
break;
|
||||
case RMSENV:
|
||||
ptr->rmsenv = DataLocation;
|
||||
*(ptr->rmsenv) = -60.0f;
|
||||
break;
|
||||
case MODGAIN:
|
||||
ptr->modgain = DataLocation;
|
||||
*(ptr->modgain) = 0.0f;
|
||||
break;
|
||||
case MODE:
|
||||
ptr->mode = DataLocation;
|
||||
break;
|
||||
case INPUT:
|
||||
ptr->input = DataLocation;
|
||||
break;
|
||||
case OUTPUT:
|
||||
ptr->output = DataLocation;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
run_Dynamics(LADSPA_Handle Instance,
|
||||
unsigned long sample_count) {
|
||||
|
||||
Dynamics * ptr = (Dynamics *)Instance;
|
||||
LADSPA_Data * input = ptr->input;
|
||||
LADSPA_Data * output = ptr->output;
|
||||
const float attack = LIMIT(*(ptr->attack), 4.0f, 500.0f);
|
||||
const float release = LIMIT(*(ptr->release), 4.0f, 1000.0f);
|
||||
const float offsgain = LIMIT(*(ptr->offsgain), -20.0f, 20.0f);
|
||||
const float mugain = db2lin(LIMIT(*(ptr->mugain), -20.0f, 20.0f));
|
||||
const int mode = LIMIT(*(ptr->mode), 0, NUM_MODES-1);
|
||||
unsigned long sample_index;
|
||||
|
||||
dyn_t amp = ptr->amp;
|
||||
dyn_t env = ptr->env;
|
||||
float * as = ptr->as;
|
||||
unsigned int count = ptr->count;
|
||||
float gain = ptr->gain;
|
||||
float gain_out = ptr->gain_out;
|
||||
rms_env * rms = ptr->rms;
|
||||
rms_t sum = ptr->sum;
|
||||
|
||||
const float ga = as[(unsigned int)(attack * 0.001f * (float)(TABSIZE-1))];
|
||||
const float gr = as[(unsigned int)(release * 0.001f * (float)(TABSIZE-1))];
|
||||
const float ef_a = ga * 0.25f;
|
||||
const float ef_ai = 1.0f - ef_a;
|
||||
|
||||
float level = 0.0f;
|
||||
float adjust = 0.0f;
|
||||
|
||||
for (sample_index = 0; sample_index < sample_count; sample_index++) {
|
||||
|
||||
#ifdef DYN_CALC_FLOAT
|
||||
sum += input[sample_index] * input[sample_index];
|
||||
if (amp > env) {
|
||||
env = env * ga + amp * (1.0f - ga);
|
||||
} else {
|
||||
env = env * gr + amp * (1.0f - gr);
|
||||
}
|
||||
#else
|
||||
sum += (rms_t)(input[sample_index] * F2S * input[sample_index] * F2S);
|
||||
if (amp) {
|
||||
if (amp > env) {
|
||||
env = (double)env * ga + (double)amp * (1.0f - ga);
|
||||
} else {
|
||||
env = (double)env * gr + (double)amp * (1.0f - gr);
|
||||
}
|
||||
} else
|
||||
env = 0;
|
||||
#endif
|
||||
|
||||
if (count++ % 4 == 3) {
|
||||
#ifdef DYN_CALC_FLOAT
|
||||
amp = rms_env_process(rms, sum / 4);
|
||||
#else
|
||||
if (sum)
|
||||
amp = rms_env_process(rms, sum / 4);
|
||||
else
|
||||
amp = 0;
|
||||
#endif
|
||||
|
||||
#ifdef DYN_CALC_FLOAT
|
||||
if (isnan(amp))
|
||||
amp = 0.0f;
|
||||
#endif
|
||||
sum = 0;
|
||||
|
||||
/* set gain_out according to the difference between
|
||||
the envelope volume level (env) and the corresponding
|
||||
output level (from graph) */
|
||||
#ifdef DYN_CALC_FLOAT
|
||||
level = 20 * log10f(2 * env);
|
||||
#else
|
||||
level = 20 * log10f(2 * (double)env / (double)F2S);
|
||||
#endif
|
||||
adjust = get_table_gain(mode, level + offsgain);
|
||||
gain_out = db2lin(adjust);
|
||||
|
||||
}
|
||||
gain = gain * ef_a + gain_out * ef_ai;
|
||||
output[sample_index] = input[sample_index] * gain * mugain;
|
||||
}
|
||||
ptr->sum = sum;
|
||||
ptr->amp = amp;
|
||||
ptr->gain = gain;
|
||||
ptr->gain_out = gain_out;
|
||||
ptr->env = env;
|
||||
ptr->count = count;
|
||||
|
||||
*(ptr->rmsenv) = LIMIT(level, -60.0f, 20.0f);
|
||||
*(ptr->modgain) = LIMIT(adjust, -60.0f, 20.0f);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
set_run_adding_gain_Dynamics(LADSPA_Handle Instance, LADSPA_Data gain) {
|
||||
|
||||
Dynamics * ptr = (Dynamics *)Instance;
|
||||
|
||||
ptr->run_adding_gain = gain;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
run_adding_Dynamics(LADSPA_Handle Instance,
|
||||
unsigned long sample_count) {
|
||||
|
||||
Dynamics * ptr = (Dynamics *)Instance;
|
||||
LADSPA_Data * input = ptr->input;
|
||||
LADSPA_Data * output = ptr->output;
|
||||
const float attack = LIMIT(*(ptr->attack), 4.0f, 500.0f);
|
||||
const float release = LIMIT(*(ptr->release), 4.0f, 1000.0f);
|
||||
const float offsgain = LIMIT(*(ptr->offsgain), -20.0f, 20.0f);
|
||||
const float mugain = db2lin(LIMIT(*(ptr->mugain), -20.0f, 20.0f));
|
||||
const int mode = LIMIT(*(ptr->mode), 0, NUM_MODES-1);
|
||||
unsigned long sample_index;
|
||||
|
||||
dyn_t amp = ptr->amp;
|
||||
dyn_t env = ptr->env;
|
||||
float * as = ptr->as;
|
||||
unsigned int count = ptr->count;
|
||||
float gain = ptr->gain;
|
||||
float gain_out = ptr->gain_out;
|
||||
rms_env * rms = ptr->rms;
|
||||
rms_t sum = ptr->sum;
|
||||
|
||||
const float ga = as[(unsigned int)(attack * 0.001f * (float)(TABSIZE-1))];
|
||||
const float gr = as[(unsigned int)(release * 0.001f * (float)(TABSIZE-1))];
|
||||
const float ef_a = ga * 0.25f;
|
||||
const float ef_ai = 1.0f - ef_a;
|
||||
|
||||
float level = 0.0f;
|
||||
float adjust = 0.0f;
|
||||
|
||||
for (sample_index = 0; sample_index < sample_count; sample_index++) {
|
||||
|
||||
#ifdef DYN_CALC_FLOAT
|
||||
sum += input[sample_index] * input[sample_index];
|
||||
if (amp > env) {
|
||||
env = env * ga + amp * (1.0f - ga);
|
||||
} else {
|
||||
env = env * gr + amp * (1.0f - gr);
|
||||
}
|
||||
#else
|
||||
sum += (rms_t)(input[sample_index] * F2S * input[sample_index] * F2S);
|
||||
if (amp) {
|
||||
if (amp > env) {
|
||||
env = (double)env * ga + (double)amp * (1.0f - ga);
|
||||
} else {
|
||||
env = (double)env * gr + (double)amp * (1.0f - gr);
|
||||
}
|
||||
} else
|
||||
env = 0;
|
||||
#endif
|
||||
|
||||
if (count++ % 4 == 3) {
|
||||
#ifdef DYN_CALC_FLOAT
|
||||
amp = rms_env_process(rms, sum / 4);
|
||||
#else
|
||||
if (sum)
|
||||
amp = rms_env_process(rms, sum / 4);
|
||||
else
|
||||
amp = 0;
|
||||
#endif
|
||||
|
||||
#ifdef DYN_CALC_FLOAT
|
||||
if (isnan(amp))
|
||||
amp = 0.0f;
|
||||
#endif
|
||||
sum = 0;
|
||||
|
||||
/* set gain_out according to the difference between
|
||||
the envelope volume level (env) and the corresponding
|
||||
output level (from graph) */
|
||||
#ifdef DYN_CALC_FLOAT
|
||||
level = 20 * log10f(2 * env);
|
||||
#else
|
||||
level = 20 * log10f(2 * (double)env / (double)F2S);
|
||||
#endif
|
||||
adjust = get_table_gain(mode, level + offsgain);
|
||||
gain_out = db2lin(adjust);
|
||||
|
||||
}
|
||||
gain = gain * ef_a + gain_out * ef_ai;
|
||||
output[sample_index] += ptr->run_adding_gain * input[sample_index] * gain * mugain;
|
||||
}
|
||||
ptr->sum = sum;
|
||||
ptr->amp = amp;
|
||||
ptr->gain = gain;
|
||||
ptr->gain_out = gain_out;
|
||||
ptr->env = env;
|
||||
ptr->count = count;
|
||||
|
||||
*(ptr->rmsenv) = LIMIT(level, -60.0f, 20.0f);
|
||||
*(ptr->modgain) = LIMIT(adjust, -60.0f, 20.0f);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Throw away a Dynamics effect instance. */
|
||||
void
|
||||
cleanup_Dynamics(LADSPA_Handle Instance) {
|
||||
|
||||
Dynamics * ptr = (Dynamics *)Instance;
|
||||
|
||||
free(ptr->rms);
|
||||
free(ptr->as);
|
||||
free(Instance);
|
||||
}
|
||||
|
||||
|
||||
|
||||
LADSPA_Descriptor * mono_descriptor = NULL;
|
||||
|
||||
|
||||
|
||||
/* _init() is called automatically when the plugin library is first
|
||||
loaded. */
|
||||
void
|
||||
_init() {
|
||||
|
||||
char ** port_names;
|
||||
LADSPA_PortDescriptor * port_descriptors;
|
||||
LADSPA_PortRangeHint * port_range_hints;
|
||||
|
||||
if ((mono_descriptor =
|
||||
(LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor))) == NULL)
|
||||
exit(1);
|
||||
|
||||
mono_descriptor->UniqueID = ID_MONO;
|
||||
mono_descriptor->Label = strdup("tap_dynamics_m");
|
||||
mono_descriptor->Properties = 0;
|
||||
mono_descriptor->Name = strdup("TAP Dynamics (M)");
|
||||
mono_descriptor->Maker = strdup("Tom Szilagyi");
|
||||
mono_descriptor->Copyright = strdup("GPL");
|
||||
mono_descriptor->PortCount = PORTCOUNT_MONO;
|
||||
|
||||
if ((port_descriptors =
|
||||
(LADSPA_PortDescriptor *)calloc(PORTCOUNT_MONO, sizeof(LADSPA_PortDescriptor))) == NULL)
|
||||
exit(1);
|
||||
|
||||
mono_descriptor->PortDescriptors = (const LADSPA_PortDescriptor *)port_descriptors;
|
||||
port_descriptors[ATTACK] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[RELEASE] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[OFFSGAIN] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[MUGAIN] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[MODE] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[RMSENV] = LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[MODGAIN] = LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[INPUT] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
|
||||
port_descriptors[OUTPUT] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
|
||||
|
||||
if ((port_names =
|
||||
(char **)calloc(PORTCOUNT_MONO, sizeof(char *))) == NULL)
|
||||
exit(1);
|
||||
|
||||
mono_descriptor->PortNames = (const char **)port_names;
|
||||
port_names[ATTACK] = strdup("Attack [ms]");
|
||||
port_names[RELEASE] = strdup("Release [ms]");
|
||||
port_names[OFFSGAIN] = strdup("Offset Gain [dB]");
|
||||
port_names[MUGAIN] = strdup("Makeup Gain [dB]");
|
||||
port_names[MODE] = strdup("Function");
|
||||
port_names[RMSENV] = strdup("Envelope Volume [dB]");
|
||||
port_names[MODGAIN] = strdup("Gain Adjustment [dB]");
|
||||
port_names[INPUT] = strdup("Input");
|
||||
port_names[OUTPUT] = strdup("Output");
|
||||
|
||||
if ((port_range_hints =
|
||||
((LADSPA_PortRangeHint *)calloc(PORTCOUNT_MONO, sizeof(LADSPA_PortRangeHint)))) == NULL)
|
||||
exit(1);
|
||||
|
||||
mono_descriptor->PortRangeHints = (const LADSPA_PortRangeHint *)port_range_hints;
|
||||
port_range_hints[ATTACK].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_LOW);
|
||||
port_range_hints[RELEASE].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_MIDDLE);
|
||||
port_range_hints[OFFSGAIN].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[MUGAIN].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[RMSENV].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[MODGAIN].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[MODE].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_INTEGER |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[ATTACK].LowerBound = 4.0f;
|
||||
port_range_hints[ATTACK].UpperBound = 500.0f;
|
||||
port_range_hints[RELEASE].LowerBound = 4.0f;
|
||||
port_range_hints[RELEASE].UpperBound = 1000.0f;
|
||||
port_range_hints[OFFSGAIN].LowerBound = -20.0f;
|
||||
port_range_hints[OFFSGAIN].UpperBound = 20.0f;
|
||||
port_range_hints[MUGAIN].LowerBound = -20.0f;
|
||||
port_range_hints[MUGAIN].UpperBound = 20.0f;
|
||||
port_range_hints[RMSENV].LowerBound = -60.0f;
|
||||
port_range_hints[RMSENV].UpperBound = 20.0f;
|
||||
port_range_hints[MODGAIN].LowerBound = -60.0f;
|
||||
port_range_hints[MODGAIN].UpperBound = 20.0f;
|
||||
port_range_hints[MODE].LowerBound = 0;
|
||||
port_range_hints[MODE].UpperBound = NUM_MODES - 0.9f;
|
||||
port_range_hints[INPUT].HintDescriptor = 0;
|
||||
port_range_hints[OUTPUT].HintDescriptor = 0;
|
||||
mono_descriptor->instantiate = instantiate_Dynamics;
|
||||
mono_descriptor->connect_port = connect_port_Dynamics;
|
||||
mono_descriptor->activate = NULL;
|
||||
mono_descriptor->run = run_Dynamics;
|
||||
mono_descriptor->run_adding = run_adding_Dynamics;
|
||||
mono_descriptor->set_run_adding_gain = set_run_adding_gain_Dynamics;
|
||||
mono_descriptor->deactivate = NULL;
|
||||
mono_descriptor->cleanup = cleanup_Dynamics;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
delete_descriptor(LADSPA_Descriptor * descriptor) {
|
||||
unsigned long index;
|
||||
if (descriptor) {
|
||||
free((char *)descriptor->Label);
|
||||
free((char *)descriptor->Name);
|
||||
free((char *)descriptor->Maker);
|
||||
free((char *)descriptor->Copyright);
|
||||
free((LADSPA_PortDescriptor *)descriptor->PortDescriptors);
|
||||
for (index = 0; index < descriptor->PortCount; index++)
|
||||
free((char *)(descriptor->PortNames[index]));
|
||||
free((char **)descriptor->PortNames);
|
||||
free((LADSPA_PortRangeHint *)descriptor->PortRangeHints);
|
||||
free(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* _fini() is called automatically when the library is unloaded. */
|
||||
void
|
||||
_fini() {
|
||||
delete_descriptor(mono_descriptor);
|
||||
}
|
||||
|
||||
|
||||
/* Return a descriptor of the requested plugin type. */
|
||||
const LADSPA_Descriptor *
|
||||
ladspa_descriptor(unsigned long Index) {
|
||||
|
||||
switch (Index) {
|
||||
case 0:
|
||||
return mono_descriptor;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
204
plugins/ladspa_effect/tap/tap_dynamics_presets.h
Normal file
204
plugins/ladspa_effect/tap/tap_dynamics_presets.h
Normal file
@@ -0,0 +1,204 @@
|
||||
/* -*- linux-c -*-
|
||||
Copyright (C) 2004 Tom Szilagyi
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: tap_dynamics_presets.h,v 1.1 2004/05/01 16:15:06 tszilagyi Exp $
|
||||
*/
|
||||
|
||||
|
||||
/* Number of dynamics presets */
|
||||
#define NUM_MODES 15
|
||||
|
||||
|
||||
/* Dynamics presets data */
|
||||
DYNAMICS_DATA dyn_data[NUM_MODES] = {
|
||||
|
||||
{ /* 2:1 compression starting at -6 dB */
|
||||
4,
|
||||
{
|
||||
{-80.0f, -80.0f},
|
||||
{-6.0f, -6.0f},
|
||||
{0.0f, -3.8f},
|
||||
{20.0f, 3.5f},
|
||||
},
|
||||
},
|
||||
|
||||
{ /* 2:1 compression starting at -9 dB */
|
||||
4,
|
||||
{
|
||||
{-80.0f, -80.0f},
|
||||
{-9.0f, -9.0f},
|
||||
{0.0f, -5.3f},
|
||||
{20.0f, 2.9f},
|
||||
},
|
||||
},
|
||||
|
||||
{ /* 2:1 compression starting at -12 dB */
|
||||
4,
|
||||
{
|
||||
{-80.0f, -80.0f},
|
||||
{-12.0f, -12.0f},
|
||||
{0.0f, -6.8f},
|
||||
{20.0f, 1.9f},
|
||||
},
|
||||
},
|
||||
|
||||
{ /* 2:1 compression starting at -18 dB */
|
||||
4,
|
||||
{
|
||||
{-80.0f, -80.0f},
|
||||
{-18.0f, -18.0f},
|
||||
{0.0f, -9.8f},
|
||||
{20.0f, -0.7f},
|
||||
},
|
||||
},
|
||||
|
||||
{ /* 2.5:1 compression starting at -12 dB */
|
||||
4,
|
||||
{
|
||||
{-80.0f, -80.0f},
|
||||
{-12.0f, -12.0f},
|
||||
{0.0f, -7.5f},
|
||||
{20.0f, 0.0f},
|
||||
},
|
||||
},
|
||||
|
||||
{ /* 3:1 compression starting at -12 dB */
|
||||
4,
|
||||
{
|
||||
{-80.0f, -80.0f},
|
||||
{-12.0f, -12.0f},
|
||||
{0.0f, -9.0f},
|
||||
{20.0f, -4.0f},
|
||||
},
|
||||
},
|
||||
|
||||
{ /* 3:1 compression starting at -15 dB */
|
||||
4,
|
||||
{
|
||||
{-80.0f, -80.0f},
|
||||
{-15.0f, -15.0f},
|
||||
{0.0f, -10.8f},
|
||||
{20.0f, -5.2f},
|
||||
},
|
||||
},
|
||||
|
||||
{ /* Compressor/Gate */
|
||||
5,
|
||||
{
|
||||
{-80.0f, -105.0f},
|
||||
{-62.0f, -80.0f},
|
||||
{-15.4f, -15.4f},
|
||||
{0.0f, -12.0f},
|
||||
{20.0f, -7.6f},
|
||||
},
|
||||
},
|
||||
|
||||
{ /* Expander */
|
||||
8,
|
||||
{
|
||||
{-80.0f, -169.0f},
|
||||
{-54.0f, -80.0f},
|
||||
{-49.5f, -64.6f},
|
||||
{-41.1f, -41.1f},
|
||||
{-25.8f, -15.0f},
|
||||
{-10.8f, -4.5f},
|
||||
{0.0f, 0.0f},
|
||||
{20.0f, 8.3f},
|
||||
},
|
||||
},
|
||||
|
||||
{ /* Hard limiter at -6 dB */
|
||||
3,
|
||||
{
|
||||
{-80.0f, -80.0f},
|
||||
{-6.0f, -6.0f},
|
||||
{20.0f, -6.0f},
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
{ /* Hard limiter at -12 dB */
|
||||
3,
|
||||
{
|
||||
{-80.0f, -80.0f},
|
||||
{-12.0f, -12.0f},
|
||||
{20.0f, -12.0f},
|
||||
},
|
||||
},
|
||||
|
||||
{ /* Hard noise gate at -35 dB */
|
||||
4,
|
||||
{
|
||||
{-80.0f, -115.0f},
|
||||
{-35.1f, -80.0f},
|
||||
{-35.0f, -35.0f},
|
||||
{20.0f, 20.0f},
|
||||
},
|
||||
},
|
||||
|
||||
{ /* Soft limiter */
|
||||
5,
|
||||
{
|
||||
{-80.0f, -80.0f},
|
||||
{-12.4f, -12.4f},
|
||||
{-6.0f, -8.0f},
|
||||
{0.0f, -6.8f},
|
||||
{20.0f, -2.8f},
|
||||
},
|
||||
},
|
||||
|
||||
{ /* Soft knee comp/gate (-24 dB threshold) */
|
||||
8,
|
||||
{
|
||||
{-80.0f, -113.7f},
|
||||
{-46.3f, -80.0f},
|
||||
{-42.0f, -56.8f},
|
||||
{-33.6f, -36.3f},
|
||||
{-24.0f, -24.0f},
|
||||
{-11.1f, -15.4f},
|
||||
{0.0f, -12.0f},
|
||||
{20.0f, -5.8f},
|
||||
},
|
||||
},
|
||||
|
||||
{ /* Soft noise gate below -36 dB */
|
||||
7,
|
||||
{
|
||||
{-80.0f, -104.0f},
|
||||
{-56.0f, -80.0f},
|
||||
{-51.8f, -67.2f},
|
||||
{-44.7f, -49.3f},
|
||||
{-34.0f, -34.0f},
|
||||
{0.0f, 0.0f},
|
||||
{20.0f, 20.0f},
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* You can add your own presets here.
|
||||
* Please read the docs about the format.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
877
plugins/ladspa_effect/tap/tap_dynamics_st.c
Normal file
877
plugins/ladspa_effect/tap/tap_dynamics_st.c
Normal file
@@ -0,0 +1,877 @@
|
||||
/* -*- linux-c -*-
|
||||
Copyright (C) 2004 Tom Szilagyi
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: tap_dynamics_st.c,v 1.2 2004/06/15 14:50:55 tszilagyi Exp $
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "ladspa.h"
|
||||
#include "tap_utils.h"
|
||||
|
||||
|
||||
/* ***** VERY IMPORTANT! *****
|
||||
*
|
||||
* If you enable this, the plugin will use float arithmetics in DSP
|
||||
* calculations. This usually yields lower average CPU usage, but
|
||||
* occasionaly may result in high CPU peaks which cause trouble to you
|
||||
* and your JACK server. The default is to use fixpoint arithmetics
|
||||
* (with the following #define commented out). But (depending on the
|
||||
* processor on which you run the code) you may find floating point
|
||||
* mode usable.
|
||||
*/
|
||||
/*#define DYN_CALC_FLOAT*/
|
||||
|
||||
|
||||
typedef signed int sample;
|
||||
|
||||
/* coefficient for float to sample (signed int) conversion */
|
||||
/* this allows for about 60 dB headroom above 0dB, if 0 dB is equivalent to 1.0f */
|
||||
/* As 2^31 equals more than 180 dB, about 120 dB dynamics remains below 0 dB */
|
||||
#define F2S 2147483
|
||||
|
||||
|
||||
#ifdef DYN_CALC_FLOAT
|
||||
typedef LADSPA_Data dyn_t;
|
||||
typedef float rms_t;
|
||||
#else
|
||||
typedef sample dyn_t;
|
||||
typedef int64_t rms_t;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* The Unique ID of the plugin: */
|
||||
|
||||
#define ID_STEREO 2153
|
||||
|
||||
/* The port numbers for the plugin: */
|
||||
|
||||
#define ATTACK 0
|
||||
#define RELEASE 1
|
||||
#define OFFSGAIN 2
|
||||
#define MUGAIN 3
|
||||
#define RMSENV_L 4
|
||||
#define RMSENV_R 5
|
||||
#define MODGAIN_L 6
|
||||
#define MODGAIN_R 7
|
||||
#define STEREO 8
|
||||
#define MODE 9
|
||||
#define INPUT_L 10
|
||||
#define INPUT_R 11
|
||||
#define OUTPUT_L 12
|
||||
#define OUTPUT_R 13
|
||||
|
||||
|
||||
/* Total number of ports */
|
||||
|
||||
#define PORTCOUNT_STEREO 14
|
||||
|
||||
|
||||
#define TABSIZE 256
|
||||
#define RMSSIZE 64
|
||||
|
||||
|
||||
typedef struct {
|
||||
rms_t buffer[RMSSIZE];
|
||||
unsigned int pos;
|
||||
rms_t sum;
|
||||
} rms_env;
|
||||
|
||||
|
||||
/* max. number of breakpoints on in/out dB graph */
|
||||
#define MAX_POINTS 20
|
||||
|
||||
typedef struct {
|
||||
LADSPA_Data x;
|
||||
LADSPA_Data y;
|
||||
} GRAPH_POINT;
|
||||
|
||||
typedef struct {
|
||||
unsigned long num_points;
|
||||
GRAPH_POINT points[MAX_POINTS];
|
||||
} DYNAMICS_DATA;
|
||||
|
||||
#include "tap_dynamics_presets.h"
|
||||
|
||||
|
||||
/* The structure used to hold port connection information and state */
|
||||
|
||||
typedef struct {
|
||||
LADSPA_Data * attack;
|
||||
LADSPA_Data * release;
|
||||
LADSPA_Data * offsgain;
|
||||
LADSPA_Data * mugain;
|
||||
LADSPA_Data * rmsenv_L;
|
||||
LADSPA_Data * rmsenv_R;
|
||||
LADSPA_Data * modgain_L;
|
||||
LADSPA_Data * modgain_R;
|
||||
LADSPA_Data * stereo;
|
||||
LADSPA_Data * mode;
|
||||
LADSPA_Data * input_L;
|
||||
LADSPA_Data * output_L;
|
||||
LADSPA_Data * input_R;
|
||||
LADSPA_Data * output_R;
|
||||
unsigned long sample_rate;
|
||||
|
||||
float * as;
|
||||
unsigned long count;
|
||||
dyn_t amp_L;
|
||||
dyn_t amp_R;
|
||||
dyn_t env_L;
|
||||
dyn_t env_R;
|
||||
float gain_L;
|
||||
float gain_R;
|
||||
float gain_out_L;
|
||||
float gain_out_R;
|
||||
rms_env * rms_L;
|
||||
rms_env * rms_R;
|
||||
rms_t sum_L;
|
||||
rms_t sum_R;
|
||||
|
||||
DYNAMICS_DATA graph;
|
||||
|
||||
LADSPA_Data run_adding_gain;
|
||||
} Dynamics;
|
||||
|
||||
|
||||
|
||||
/* RMS envelope stuff, grabbed without a second thought from Steve Harris's swh-plugins, util/rms.c */
|
||||
/* Adapted, though, to be able to use fixed-point arithmetics as well. */
|
||||
|
||||
rms_env *
|
||||
rms_env_new(void) {
|
||||
|
||||
rms_env * new = (rms_env *)calloc(1, sizeof(rms_env));
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
void
|
||||
rms_env_reset(rms_env *r) {
|
||||
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < RMSSIZE; i++) {
|
||||
r->buffer[i] = 0.0f;
|
||||
}
|
||||
r->pos = 0;
|
||||
r->sum = 0.0f;
|
||||
}
|
||||
|
||||
inline static
|
||||
dyn_t
|
||||
rms_env_process(rms_env *r, const rms_t x) {
|
||||
|
||||
r->sum -= r->buffer[r->pos];
|
||||
r->sum += x;
|
||||
r->buffer[r->pos] = x;
|
||||
r->pos = (r->pos + 1) & (RMSSIZE - 1);
|
||||
|
||||
#ifdef DYN_CALC_FLOAT
|
||||
return sqrt(r->sum / (float)RMSSIZE);
|
||||
#else
|
||||
return sqrt(r->sum / RMSSIZE);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline
|
||||
LADSPA_Data
|
||||
get_table_gain(int mode, LADSPA_Data level) {
|
||||
|
||||
LADSPA_Data x1 = -80.0f;
|
||||
LADSPA_Data y1 = -80.0f;
|
||||
LADSPA_Data x2 = 0.0f;
|
||||
LADSPA_Data y2 = 0.0f;
|
||||
int i = 0;
|
||||
|
||||
if (level <= -80.0f)
|
||||
return get_table_gain(mode, -79.9f);
|
||||
|
||||
while (i < dyn_data[mode].num_points && dyn_data[mode].points[i].x < level) {
|
||||
x1 = dyn_data[mode].points[i].x;
|
||||
y1 = dyn_data[mode].points[i].y;
|
||||
i++;
|
||||
}
|
||||
if (i < dyn_data[mode].num_points) {
|
||||
x2 = dyn_data[mode].points[i].x;
|
||||
y2 = dyn_data[mode].points[i].y;
|
||||
} else
|
||||
return 0.0f;
|
||||
|
||||
return y1 + ((level - x1) * (y2 - y1) / (x2 - x1)) - level;
|
||||
}
|
||||
|
||||
|
||||
/* Construct a new plugin instance. */
|
||||
LADSPA_Handle
|
||||
instantiate_Dynamics(const LADSPA_Descriptor * Descriptor, unsigned long sample_rate) {
|
||||
|
||||
LADSPA_Handle * ptr;
|
||||
|
||||
float * as = NULL;
|
||||
unsigned int count = 0;
|
||||
dyn_t amp_L = 0.0f;
|
||||
dyn_t amp_R = 0.0f;
|
||||
dyn_t env_L = 0.0f;
|
||||
dyn_t env_R = 0.0f;
|
||||
float gain_L = 0.0f;
|
||||
float gain_R = 0.0f;
|
||||
float gain_out_L = 0.0f;
|
||||
float gain_out_R = 0.0f;
|
||||
rms_env * rms_L = NULL;
|
||||
rms_env * rms_R = NULL;
|
||||
rms_t sum_L = 0.0f;
|
||||
rms_t sum_R = 0.0f;
|
||||
int i;
|
||||
|
||||
if ((ptr = malloc(sizeof(Dynamics))) == NULL)
|
||||
return NULL;
|
||||
|
||||
((Dynamics *)ptr)->sample_rate = sample_rate;
|
||||
((Dynamics *)ptr)->run_adding_gain = 1.0;
|
||||
|
||||
if ((rms_L = rms_env_new()) == NULL)
|
||||
return NULL;
|
||||
if ((rms_R = rms_env_new()) == NULL)
|
||||
return NULL;
|
||||
|
||||
if ((as = malloc(TABSIZE * sizeof(float))) == NULL)
|
||||
return NULL;
|
||||
|
||||
as[0] = 1.0f;
|
||||
for (i = 1; i < TABSIZE; i++) {
|
||||
as[i] = expf(-1.0f / (sample_rate * (float)i / (float)TABSIZE));
|
||||
}
|
||||
|
||||
((Dynamics *)ptr)->as = as;
|
||||
((Dynamics *)ptr)->count = count;
|
||||
((Dynamics *)ptr)->amp_L = amp_L;
|
||||
((Dynamics *)ptr)->amp_R = amp_R;
|
||||
((Dynamics *)ptr)->env_L = env_L;
|
||||
((Dynamics *)ptr)->env_R = env_R;
|
||||
((Dynamics *)ptr)->gain_L = gain_L;
|
||||
((Dynamics *)ptr)->gain_R = gain_R;
|
||||
((Dynamics *)ptr)->gain_out_L = gain_out_L;
|
||||
((Dynamics *)ptr)->gain_out_R = gain_out_R;
|
||||
((Dynamics *)ptr)->rms_L = rms_L;
|
||||
((Dynamics *)ptr)->rms_R = rms_R;
|
||||
((Dynamics *)ptr)->sum_L = sum_L;
|
||||
((Dynamics *)ptr)->sum_R = sum_R;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Connect a port to a data location. */
|
||||
void
|
||||
connect_port_Dynamics(LADSPA_Handle Instance,
|
||||
unsigned long Port,
|
||||
LADSPA_Data * DataLocation) {
|
||||
|
||||
Dynamics * ptr = (Dynamics *)Instance;
|
||||
|
||||
switch (Port) {
|
||||
case ATTACK:
|
||||
ptr->attack = DataLocation;
|
||||
break;
|
||||
case RELEASE:
|
||||
ptr->release = DataLocation;
|
||||
break;
|
||||
case OFFSGAIN:
|
||||
ptr->offsgain = DataLocation;
|
||||
break;
|
||||
case MUGAIN:
|
||||
ptr->mugain = DataLocation;
|
||||
break;
|
||||
case RMSENV_L:
|
||||
ptr->rmsenv_L = DataLocation;
|
||||
*(ptr->rmsenv_L) = -60.0f;
|
||||
break;
|
||||
case RMSENV_R:
|
||||
ptr->rmsenv_R = DataLocation;
|
||||
*(ptr->rmsenv_R) = -60.0f;
|
||||
break;
|
||||
case MODGAIN_L:
|
||||
ptr->modgain_L = DataLocation;
|
||||
*(ptr->modgain_L) = 0.0f;
|
||||
break;
|
||||
case MODGAIN_R:
|
||||
ptr->modgain_R = DataLocation;
|
||||
*(ptr->modgain_R) = 0.0f;
|
||||
break;
|
||||
case STEREO:
|
||||
ptr->stereo = DataLocation;
|
||||
break;
|
||||
case MODE:
|
||||
ptr->mode = DataLocation;
|
||||
break;
|
||||
case INPUT_L:
|
||||
ptr->input_L = DataLocation;
|
||||
break;
|
||||
case OUTPUT_L:
|
||||
ptr->output_L = DataLocation;
|
||||
break;
|
||||
case INPUT_R:
|
||||
ptr->input_R = DataLocation;
|
||||
break;
|
||||
case OUTPUT_R:
|
||||
ptr->output_R = DataLocation;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
run_Dynamics(LADSPA_Handle Instance,
|
||||
unsigned long sample_count) {
|
||||
|
||||
Dynamics * ptr = (Dynamics *)Instance;
|
||||
LADSPA_Data * input_L = ptr->input_L;
|
||||
LADSPA_Data * output_L = ptr->output_L;
|
||||
LADSPA_Data * input_R = ptr->input_R;
|
||||
LADSPA_Data * output_R = ptr->output_R;
|
||||
const float attack = LIMIT(*(ptr->attack), 4.0f, 500.0f);
|
||||
const float release = LIMIT(*(ptr->release), 4.0f, 1000.0f);
|
||||
const float offsgain = LIMIT(*(ptr->offsgain), -20.0f, 20.0f);
|
||||
const float mugain = db2lin(LIMIT(*(ptr->mugain), -20.0f, 20.0f));
|
||||
const int stereo = LIMIT(*(ptr->stereo), 0, 2);
|
||||
const int mode = LIMIT(*(ptr->mode), 0, NUM_MODES-1);
|
||||
unsigned long sample_index;
|
||||
|
||||
dyn_t amp_L = ptr->amp_L;
|
||||
dyn_t amp_R = ptr->amp_R;
|
||||
dyn_t env_L = ptr->env_L;
|
||||
dyn_t env_R = ptr->env_R;
|
||||
float * as = ptr->as;
|
||||
unsigned int count = ptr->count;
|
||||
float gain_L = ptr->gain_L;
|
||||
float gain_R = ptr->gain_R;
|
||||
float gain_out_L = ptr->gain_out_L;
|
||||
float gain_out_R = ptr->gain_out_R;
|
||||
rms_env * rms_L = ptr->rms_L;
|
||||
rms_env * rms_R = ptr->rms_R;
|
||||
rms_t sum_L = ptr->sum_L;
|
||||
rms_t sum_R = ptr->sum_R;
|
||||
|
||||
const float ga = as[(unsigned int)(attack * 0.001f * (LADSPA_Data)(TABSIZE-1))];
|
||||
const float gr = as[(unsigned int)(release * 0.001f * (LADSPA_Data)(TABSIZE-1))];
|
||||
const float ef_a = ga * 0.25f;
|
||||
const float ef_ai = 1.0f - ef_a;
|
||||
|
||||
float level_L = 0.0f;
|
||||
float level_R = 0.0f;
|
||||
float adjust_L = 0.0f;
|
||||
float adjust_R = 0.0f;
|
||||
|
||||
for (sample_index = 0; sample_index < sample_count; sample_index++) {
|
||||
|
||||
#ifdef DYN_CALC_FLOAT
|
||||
sum_L += input_L[sample_index] * input_L[sample_index];
|
||||
sum_R += input_R[sample_index] * input_R[sample_index];
|
||||
|
||||
if (amp_L > env_L) {
|
||||
env_L = env_L * ga + amp_L * (1.0f - ga);
|
||||
} else {
|
||||
env_L = env_L * gr + amp_L * (1.0f - gr);
|
||||
}
|
||||
if (amp_R > env_R) {
|
||||
env_R = env_R * ga + amp_R * (1.0f - ga);
|
||||
} else {
|
||||
env_R = env_R * gr + amp_R * (1.0f - gr);
|
||||
}
|
||||
#else
|
||||
sum_L += (rms_t)(input_L[sample_index] * F2S) * (rms_t)(input_L[sample_index] * F2S);
|
||||
sum_R += (rms_t)(input_R[sample_index] * F2S) * (rms_t)(input_R[sample_index] * F2S);
|
||||
|
||||
if (amp_L) {
|
||||
if (amp_L > env_L) {
|
||||
env_L = (double)env_L * ga + (double)amp_L * (1.0f - ga);
|
||||
} else {
|
||||
env_L = (double)env_L * gr + (double)amp_L * (1.0f - gr);
|
||||
}
|
||||
} else
|
||||
env_L = 0;
|
||||
|
||||
if (amp_R) {
|
||||
if (amp_R > env_R) {
|
||||
env_R = (double)env_R * ga + (double)amp_R * (1.0f - ga);
|
||||
} else {
|
||||
env_R = (double)env_R * gr + (double)amp_R * (1.0f - gr);
|
||||
}
|
||||
} else
|
||||
env_R = 0;
|
||||
#endif
|
||||
|
||||
if (count++ % 4 == 3) {
|
||||
#ifdef DYN_CALC_FLOAT
|
||||
amp_L = rms_env_process(rms_L, sum_L * 0.25f);
|
||||
amp_R = rms_env_process(rms_R, sum_R * 0.25f);
|
||||
#else
|
||||
if (sum_L)
|
||||
amp_L = rms_env_process(rms_L, sum_L * 0.25f);
|
||||
else
|
||||
amp_L = 0;
|
||||
|
||||
if (sum_R)
|
||||
amp_R = rms_env_process(rms_R, sum_R * 0.25f);
|
||||
else
|
||||
amp_R = 0;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef DYN_CALC_FLOAT
|
||||
if (isnan(amp_L))
|
||||
amp_L = 0.0f;
|
||||
if (isnan(amp_R))
|
||||
amp_R = 0.0f;
|
||||
#endif
|
||||
sum_L = sum_R = 0;
|
||||
|
||||
/* set gain_out according to the difference between
|
||||
the envelope volume level (env) and the corresponding
|
||||
output level (from graph) */
|
||||
#ifdef DYN_CALC_FLOAT
|
||||
level_L = 20 * log10f(2 * env_L);
|
||||
level_R = 20 * log10f(2 * env_R);
|
||||
#else
|
||||
level_L = 20 * log10f(2 * (double)env_L / (double)F2S);
|
||||
level_R = 20 * log10f(2 * (double)env_R / (double)F2S);
|
||||
#endif
|
||||
adjust_L = get_table_gain(mode, level_L + offsgain);
|
||||
adjust_R = get_table_gain(mode, level_R + offsgain);
|
||||
|
||||
/* set gains according to stereo mode */
|
||||
switch (stereo) {
|
||||
case 0:
|
||||
gain_out_L = db2lin(adjust_L);
|
||||
gain_out_R = db2lin(adjust_R);
|
||||
break;
|
||||
case 1:
|
||||
adjust_L = adjust_R = (adjust_L + adjust_R) / 2.0f;
|
||||
gain_out_L = gain_out_R = db2lin(adjust_L);
|
||||
break;
|
||||
case 2:
|
||||
adjust_L = adjust_R = (adjust_L > adjust_R) ? adjust_L : adjust_R;
|
||||
gain_out_L = gain_out_R = db2lin(adjust_L);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
gain_L = gain_L * ef_a + gain_out_L * ef_ai;
|
||||
gain_R = gain_R * ef_a + gain_out_R * ef_ai;
|
||||
output_L[sample_index] = input_L[sample_index] * gain_L * mugain;
|
||||
output_R[sample_index] = input_R[sample_index] * gain_R * mugain;
|
||||
}
|
||||
ptr->sum_L = sum_L;
|
||||
ptr->sum_R = sum_R;
|
||||
ptr->amp_L = amp_L;
|
||||
ptr->amp_R = amp_R;
|
||||
ptr->gain_L = gain_L;
|
||||
ptr->gain_R = gain_R;
|
||||
ptr->gain_out_L = gain_out_L;
|
||||
ptr->gain_out_R = gain_out_R;
|
||||
ptr->env_L = env_L;
|
||||
ptr->env_R = env_R;
|
||||
ptr->count = count;
|
||||
|
||||
*(ptr->rmsenv_L) = LIMIT(level_L, -60.0f, 20.0f);
|
||||
*(ptr->rmsenv_R) = LIMIT(level_R, -60.0f, 20.0f);
|
||||
*(ptr->modgain_L) = LIMIT(adjust_L, -60.0f, 20.0f);
|
||||
*(ptr->modgain_R) = LIMIT(adjust_R, -60.0f, 20.0f);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
set_run_adding_gain_Dynamics(LADSPA_Handle Instance, LADSPA_Data gain) {
|
||||
|
||||
Dynamics * ptr = (Dynamics *)Instance;
|
||||
|
||||
ptr->run_adding_gain = gain;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
run_adding_Dynamics(LADSPA_Handle Instance,
|
||||
unsigned long sample_count) {
|
||||
|
||||
Dynamics * ptr = (Dynamics *)Instance;
|
||||
LADSPA_Data * input_L = ptr->input_L;
|
||||
LADSPA_Data * output_L = ptr->output_L;
|
||||
LADSPA_Data * input_R = ptr->input_R;
|
||||
LADSPA_Data * output_R = ptr->output_R;
|
||||
const float attack = LIMIT(*(ptr->attack), 4.0f, 500.0f);
|
||||
const float release = LIMIT(*(ptr->release), 4.0f, 1000.0f);
|
||||
const float offsgain = LIMIT(*(ptr->offsgain), -20.0f, 20.0f);
|
||||
const float mugain = db2lin(LIMIT(*(ptr->mugain), -20.0f, 20.0f));
|
||||
const int stereo = LIMIT(*(ptr->stereo), 0, 2);
|
||||
const int mode = LIMIT(*(ptr->mode), 0, NUM_MODES-1);
|
||||
unsigned long sample_index;
|
||||
|
||||
dyn_t amp_L = ptr->amp_L;
|
||||
dyn_t amp_R = ptr->amp_R;
|
||||
dyn_t env_L = ptr->env_L;
|
||||
dyn_t env_R = ptr->env_R;
|
||||
float * as = ptr->as;
|
||||
unsigned int count = ptr->count;
|
||||
float gain_L = ptr->gain_L;
|
||||
float gain_R = ptr->gain_R;
|
||||
float gain_out_L = ptr->gain_out_L;
|
||||
float gain_out_R = ptr->gain_out_R;
|
||||
rms_env * rms_L = ptr->rms_L;
|
||||
rms_env * rms_R = ptr->rms_R;
|
||||
rms_t sum_L = ptr->sum_L;
|
||||
rms_t sum_R = ptr->sum_R;
|
||||
|
||||
const float ga = as[(unsigned int)(attack * 0.001f * (LADSPA_Data)(TABSIZE-1))];
|
||||
const float gr = as[(unsigned int)(release * 0.001f * (LADSPA_Data)(TABSIZE-1))];
|
||||
const float ef_a = ga * 0.25f;
|
||||
const float ef_ai = 1.0f - ef_a;
|
||||
|
||||
float level_L = 0.0f;
|
||||
float level_R = 0.0f;
|
||||
float adjust_L = 0.0f;
|
||||
float adjust_R = 0.0f;
|
||||
|
||||
for (sample_index = 0; sample_index < sample_count; sample_index++) {
|
||||
|
||||
#ifdef DYN_CALC_FLOAT
|
||||
sum_L += input_L[sample_index] * input_L[sample_index];
|
||||
sum_R += input_R[sample_index] * input_R[sample_index];
|
||||
|
||||
if (amp_L > env_L) {
|
||||
env_L = env_L * ga + amp_L * (1.0f - ga);
|
||||
} else {
|
||||
env_L = env_L * gr + amp_L * (1.0f - gr);
|
||||
}
|
||||
if (amp_R > env_R) {
|
||||
env_R = env_R * ga + amp_R * (1.0f - ga);
|
||||
} else {
|
||||
env_R = env_R * gr + amp_R * (1.0f - gr);
|
||||
}
|
||||
#else
|
||||
sum_L += (rms_t)(input_L[sample_index] * F2S) * (rms_t)(input_L[sample_index] * F2S);
|
||||
sum_R += (rms_t)(input_R[sample_index] * F2S) * (rms_t)(input_R[sample_index] * F2S);
|
||||
|
||||
if (amp_L) {
|
||||
if (amp_L > env_L) {
|
||||
env_L = (double)env_L * ga + (double)amp_L * (1.0f - ga);
|
||||
} else {
|
||||
env_L = (double)env_L * gr + (double)amp_L * (1.0f - gr);
|
||||
}
|
||||
} else
|
||||
env_L = 0;
|
||||
|
||||
if (amp_R) {
|
||||
if (amp_R > env_R) {
|
||||
env_R = (double)env_R * ga + (double)amp_R * (1.0f - ga);
|
||||
} else {
|
||||
env_R = (double)env_R * gr + (double)amp_R * (1.0f - gr);
|
||||
}
|
||||
} else
|
||||
env_R = 0;
|
||||
#endif
|
||||
|
||||
if (count++ % 4 == 3) {
|
||||
#ifdef DYN_CALC_FLOAT
|
||||
amp_L = rms_env_process(rms_L, sum_L * 0.25f);
|
||||
amp_R = rms_env_process(rms_R, sum_R * 0.25f);
|
||||
#else
|
||||
if (sum_L)
|
||||
amp_L = rms_env_process(rms_L, sum_L * 0.25f);
|
||||
else
|
||||
amp_L = 0;
|
||||
|
||||
if (sum_R)
|
||||
amp_R = rms_env_process(rms_R, sum_R * 0.25f);
|
||||
else
|
||||
amp_R = 0;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef DYN_CALC_FLOAT
|
||||
if (isnan(amp_L))
|
||||
amp_L = 0.0f;
|
||||
if (isnan(amp_R))
|
||||
amp_R = 0.0f;
|
||||
#endif
|
||||
sum_L = sum_R = 0;
|
||||
|
||||
/* set gain_out according to the difference between
|
||||
the envelope volume level (env) and the corresponding
|
||||
output level (from graph) */
|
||||
#ifdef DYN_CALC_FLOAT
|
||||
level_L = 20 * log10f(2 * env_L);
|
||||
level_R = 20 * log10f(2 * env_R);
|
||||
#else
|
||||
level_L = 20 * log10f(2 * (double)env_L / (double)F2S);
|
||||
level_R = 20 * log10f(2 * (double)env_R / (double)F2S);
|
||||
#endif
|
||||
adjust_L = get_table_gain(mode, level_L + offsgain);
|
||||
adjust_R = get_table_gain(mode, level_R + offsgain);
|
||||
|
||||
/* set gains according to stereo mode */
|
||||
switch (stereo) {
|
||||
case 0:
|
||||
gain_out_L = db2lin(adjust_L);
|
||||
gain_out_R = db2lin(adjust_R);
|
||||
break;
|
||||
case 1:
|
||||
adjust_L = adjust_R = (adjust_L + adjust_R) / 2.0f;
|
||||
gain_out_L = gain_out_R = db2lin(adjust_L);
|
||||
break;
|
||||
case 2:
|
||||
adjust_L = adjust_R = (adjust_L > adjust_R) ? adjust_L : adjust_R;
|
||||
gain_out_L = gain_out_R = db2lin(adjust_L);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
gain_L = gain_L * ef_a + gain_out_L * ef_ai;
|
||||
gain_R = gain_R * ef_a + gain_out_R * ef_ai;
|
||||
output_L[sample_index] += ptr->run_adding_gain * input_L[sample_index] * gain_L * mugain;
|
||||
output_R[sample_index] += ptr->run_adding_gain * input_R[sample_index] * gain_R * mugain;
|
||||
}
|
||||
ptr->sum_L = sum_L;
|
||||
ptr->sum_R = sum_R;
|
||||
ptr->amp_L = amp_L;
|
||||
ptr->amp_R = amp_R;
|
||||
ptr->gain_L = gain_L;
|
||||
ptr->gain_R = gain_R;
|
||||
ptr->gain_out_L = gain_out_L;
|
||||
ptr->gain_out_R = gain_out_R;
|
||||
ptr->env_L = env_L;
|
||||
ptr->env_R = env_R;
|
||||
ptr->count = count;
|
||||
|
||||
*(ptr->rmsenv_L) = LIMIT(level_L, -60.0f, 20.0f);
|
||||
*(ptr->rmsenv_R) = LIMIT(level_R, -60.0f, 20.0f);
|
||||
*(ptr->modgain_L) = LIMIT(adjust_L, -60.0f, 20.0f);
|
||||
*(ptr->modgain_R) = LIMIT(adjust_R, -60.0f, 20.0f);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Throw away a Dynamics effect instance. */
|
||||
void
|
||||
cleanup_Dynamics(LADSPA_Handle Instance) {
|
||||
|
||||
Dynamics * ptr = (Dynamics *)Instance;
|
||||
|
||||
free(ptr->rms_L);
|
||||
free(ptr->rms_R);
|
||||
free(ptr->as);
|
||||
free(Instance);
|
||||
}
|
||||
|
||||
|
||||
|
||||
LADSPA_Descriptor * stereo_descriptor = NULL;
|
||||
|
||||
|
||||
|
||||
/* _init() is called automatically when the plugin library is first
|
||||
loaded. */
|
||||
void
|
||||
_init() {
|
||||
|
||||
char ** port_names;
|
||||
LADSPA_PortDescriptor * port_descriptors;
|
||||
LADSPA_PortRangeHint * port_range_hints;
|
||||
|
||||
if ((stereo_descriptor =
|
||||
(LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor))) == NULL)
|
||||
exit(1);
|
||||
|
||||
stereo_descriptor->UniqueID = ID_STEREO;
|
||||
stereo_descriptor->Label = strdup("tap_dynamics_st");
|
||||
stereo_descriptor->Properties = 0;
|
||||
stereo_descriptor->Name = strdup("TAP Dynamics (St)");
|
||||
stereo_descriptor->Maker = strdup("Tom Szilagyi");
|
||||
stereo_descriptor->Copyright = strdup("GPL");
|
||||
stereo_descriptor->PortCount = PORTCOUNT_STEREO;
|
||||
|
||||
if ((port_descriptors =
|
||||
(LADSPA_PortDescriptor *)calloc(PORTCOUNT_STEREO, sizeof(LADSPA_PortDescriptor))) == NULL)
|
||||
exit(1);
|
||||
|
||||
stereo_descriptor->PortDescriptors = (const LADSPA_PortDescriptor *)port_descriptors;
|
||||
port_descriptors[ATTACK] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[RELEASE] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[OFFSGAIN] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[MUGAIN] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[STEREO] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[MODE] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[RMSENV_L] = LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[RMSENV_R] = LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[MODGAIN_L] = LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[MODGAIN_R] = LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[INPUT_L] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
|
||||
port_descriptors[INPUT_R] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
|
||||
port_descriptors[OUTPUT_L] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
|
||||
port_descriptors[OUTPUT_R] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
|
||||
|
||||
if ((port_names =
|
||||
(char **)calloc(PORTCOUNT_STEREO, sizeof(char *))) == NULL)
|
||||
exit(1);
|
||||
|
||||
stereo_descriptor->PortNames = (const char **)port_names;
|
||||
port_names[ATTACK] = strdup("Attack [ms]");
|
||||
port_names[RELEASE] = strdup("Release [ms]");
|
||||
port_names[OFFSGAIN] = strdup("Offset Gain [dB]");
|
||||
port_names[MUGAIN] = strdup("Makeup Gain [dB]");
|
||||
port_names[STEREO] = strdup("Stereo Mode");
|
||||
port_names[MODE] = strdup("Function");
|
||||
port_names[RMSENV_L] = strdup("Envelope Volume (L) [dB]");
|
||||
port_names[RMSENV_R] = strdup("Envelope Volume (R) [dB]");
|
||||
port_names[MODGAIN_L] = strdup("Gain Adjustment (L) [dB]");
|
||||
port_names[MODGAIN_R] = strdup("Gain Adjustment (R) [dB]");
|
||||
port_names[INPUT_L] = strdup("Input Left");
|
||||
port_names[INPUT_R] = strdup("Input Right");
|
||||
port_names[OUTPUT_L] = strdup("Output Left");
|
||||
port_names[OUTPUT_R] = strdup("Output Right");
|
||||
|
||||
if ((port_range_hints =
|
||||
((LADSPA_PortRangeHint *)calloc(PORTCOUNT_STEREO, sizeof(LADSPA_PortRangeHint)))) == NULL)
|
||||
exit(1);
|
||||
|
||||
stereo_descriptor->PortRangeHints = (const LADSPA_PortRangeHint *)port_range_hints;
|
||||
port_range_hints[ATTACK].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_LOW);
|
||||
port_range_hints[RELEASE].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_MIDDLE);
|
||||
port_range_hints[OFFSGAIN].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[MUGAIN].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[RMSENV_L].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[RMSENV_R].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[MODGAIN_L].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[MODGAIN_R].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[STEREO].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_INTEGER |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[MODE].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_INTEGER |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[ATTACK].LowerBound = 4.0f;
|
||||
port_range_hints[ATTACK].UpperBound = 500.0f;
|
||||
port_range_hints[RELEASE].LowerBound = 4.0f;
|
||||
port_range_hints[RELEASE].UpperBound = 1000.0f;
|
||||
port_range_hints[OFFSGAIN].LowerBound = -20.0f;
|
||||
port_range_hints[OFFSGAIN].UpperBound = 20.0f;
|
||||
port_range_hints[MUGAIN].LowerBound = -20.0f;
|
||||
port_range_hints[MUGAIN].UpperBound = 20.0f;
|
||||
port_range_hints[RMSENV_L].LowerBound = -60.0f;
|
||||
port_range_hints[RMSENV_L].UpperBound = 20.0f;
|
||||
port_range_hints[RMSENV_R].LowerBound = -60.0f;
|
||||
port_range_hints[RMSENV_R].UpperBound = 20.0f;
|
||||
port_range_hints[MODGAIN_L].LowerBound = -60.0f;
|
||||
port_range_hints[MODGAIN_L].UpperBound = 20.0f;
|
||||
port_range_hints[MODGAIN_R].LowerBound = -60.0f;
|
||||
port_range_hints[MODGAIN_R].UpperBound = 20.0f;
|
||||
port_range_hints[STEREO].LowerBound = 0;
|
||||
port_range_hints[STEREO].UpperBound = 2.1f;
|
||||
port_range_hints[MODE].LowerBound = 0;
|
||||
port_range_hints[MODE].UpperBound = NUM_MODES - 0.9f;
|
||||
port_range_hints[INPUT_L].HintDescriptor = 0;
|
||||
port_range_hints[INPUT_R].HintDescriptor = 0;
|
||||
port_range_hints[OUTPUT_L].HintDescriptor = 0;
|
||||
port_range_hints[OUTPUT_R].HintDescriptor = 0;
|
||||
stereo_descriptor->instantiate = instantiate_Dynamics;
|
||||
stereo_descriptor->connect_port = connect_port_Dynamics;
|
||||
stereo_descriptor->activate = NULL;
|
||||
stereo_descriptor->run = run_Dynamics;
|
||||
stereo_descriptor->run_adding = run_adding_Dynamics;
|
||||
stereo_descriptor->set_run_adding_gain = set_run_adding_gain_Dynamics;
|
||||
stereo_descriptor->deactivate = NULL;
|
||||
stereo_descriptor->cleanup = cleanup_Dynamics;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
delete_descriptor(LADSPA_Descriptor * descriptor) {
|
||||
unsigned long index;
|
||||
if (descriptor) {
|
||||
free((char *)descriptor->Label);
|
||||
free((char *)descriptor->Name);
|
||||
free((char *)descriptor->Maker);
|
||||
free((char *)descriptor->Copyright);
|
||||
free((LADSPA_PortDescriptor *)descriptor->PortDescriptors);
|
||||
for (index = 0; index < descriptor->PortCount; index++)
|
||||
free((char *)(descriptor->PortNames[index]));
|
||||
free((char **)descriptor->PortNames);
|
||||
free((LADSPA_PortRangeHint *)descriptor->PortRangeHints);
|
||||
free(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* _fini() is called automatically when the library is unloaded. */
|
||||
void
|
||||
_fini() {
|
||||
delete_descriptor(stereo_descriptor);
|
||||
}
|
||||
|
||||
|
||||
/* Return a descriptor of the requested plugin type. */
|
||||
const LADSPA_Descriptor *
|
||||
ladspa_descriptor(unsigned long Index) {
|
||||
|
||||
switch (Index) {
|
||||
case 0:
|
||||
return stereo_descriptor;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
630
plugins/ladspa_effect/tap/tap_echo.c
Normal file
630
plugins/ladspa_effect/tap/tap_echo.c
Normal file
@@ -0,0 +1,630 @@
|
||||
/* -*- linux-c -*-
|
||||
Copyright (C) 2004 Tom Szilagyi
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: tap_echo.c,v 1.6 2004/08/05 16:18:44 tszilagyi Exp $
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "ladspa.h"
|
||||
#include "tap_utils.h"
|
||||
|
||||
/* The Unique ID of the plugin: */
|
||||
|
||||
#define ID_STEREO 2143
|
||||
|
||||
/* The port numbers for the plugin: */
|
||||
|
||||
#define DELAYTIME_L 0
|
||||
#define FEEDBACK_L 1
|
||||
#define DELAYTIME_R 2
|
||||
#define FEEDBACK_R 3
|
||||
#define STRENGTH_L 4
|
||||
#define STRENGTH_R 5
|
||||
#define DRYLEVEL 6
|
||||
#define MODE 7
|
||||
#define HAAS 8
|
||||
#define REV_OUTCH 9
|
||||
|
||||
#define INPUT_L 10
|
||||
#define OUTPUT_L 11
|
||||
#define INPUT_R 12
|
||||
#define OUTPUT_R 13
|
||||
|
||||
/* Total number of ports */
|
||||
|
||||
#define PORTCOUNT_STEREO 14
|
||||
|
||||
|
||||
/* Maximum delay (ms) */
|
||||
|
||||
#define MAX_DELAY 2000
|
||||
|
||||
|
||||
/* The structure used to hold port connection information and state */
|
||||
|
||||
typedef struct {
|
||||
LADSPA_Data * delaytime_L;
|
||||
LADSPA_Data * delaytime_R;
|
||||
LADSPA_Data * feedback_L;
|
||||
LADSPA_Data * feedback_R;
|
||||
LADSPA_Data * strength_L;
|
||||
LADSPA_Data * strength_R;
|
||||
LADSPA_Data * drylevel;
|
||||
LADSPA_Data * mode;
|
||||
LADSPA_Data * haas;
|
||||
LADSPA_Data * rev_outch;
|
||||
|
||||
LADSPA_Data * input_L;
|
||||
LADSPA_Data * output_L;
|
||||
LADSPA_Data * input_R;
|
||||
LADSPA_Data * output_R;
|
||||
|
||||
unsigned long sample_rate;
|
||||
LADSPA_Data mpx_out_L;
|
||||
LADSPA_Data mpx_out_R;
|
||||
|
||||
LADSPA_Data * ringbuffer_L;
|
||||
LADSPA_Data * ringbuffer_R;
|
||||
unsigned long * buffer_pos_L;
|
||||
unsigned long * buffer_pos_R;
|
||||
|
||||
LADSPA_Data run_adding_gain;
|
||||
} Echo;
|
||||
|
||||
|
||||
|
||||
|
||||
/* Construct a new plugin instance. */
|
||||
LADSPA_Handle
|
||||
instantiate_Echo(const LADSPA_Descriptor * Descriptor,
|
||||
unsigned long SampleRate) {
|
||||
|
||||
LADSPA_Handle * ptr;
|
||||
|
||||
if ((ptr = malloc(sizeof(Echo))) != NULL) {
|
||||
((Echo *)ptr)->sample_rate = SampleRate;
|
||||
((Echo *)ptr)->run_adding_gain = 1.0f;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* activate a plugin instance */
|
||||
void
|
||||
activate_Echo(LADSPA_Handle Instance) {
|
||||
|
||||
Echo * ptr;
|
||||
|
||||
ptr = (Echo *)Instance;
|
||||
|
||||
ptr->mpx_out_L = 0;
|
||||
ptr->mpx_out_R = 0;
|
||||
|
||||
/* allocate memory for ringbuffers and related dynamic vars */
|
||||
if ((ptr->ringbuffer_L =
|
||||
calloc(MAX_DELAY * ptr->sample_rate / 1000,
|
||||
sizeof(LADSPA_Data))) == NULL)
|
||||
exit(1);
|
||||
if ((ptr->ringbuffer_R =
|
||||
calloc(MAX_DELAY * ptr->sample_rate / 1000,
|
||||
sizeof(LADSPA_Data))) == NULL)
|
||||
exit(1);
|
||||
if ((ptr->buffer_pos_L = calloc(1, sizeof(unsigned long))) == NULL)
|
||||
exit(1);
|
||||
if ((ptr->buffer_pos_R = calloc(1, sizeof(unsigned long))) == NULL)
|
||||
exit(1);
|
||||
|
||||
*(ptr->buffer_pos_L) = 0;
|
||||
*(ptr->buffer_pos_R) = 0;
|
||||
}
|
||||
|
||||
|
||||
/* deactivate a plugin instance */
|
||||
void
|
||||
deactivate_Echo(LADSPA_Handle Instance) {
|
||||
|
||||
Echo * ptr;
|
||||
|
||||
ptr = (Echo *)Instance;
|
||||
|
||||
/* free memory allocated for ringbuffers & co. in activate_Echo() */
|
||||
free(ptr->ringbuffer_L);
|
||||
free(ptr->ringbuffer_R);
|
||||
free(ptr->buffer_pos_L);
|
||||
free(ptr->buffer_pos_R);
|
||||
}
|
||||
|
||||
|
||||
/* Connect a port to a data location. */
|
||||
void
|
||||
connect_port_Echo(LADSPA_Handle Instance,
|
||||
unsigned long Port,
|
||||
LADSPA_Data * DataLocation) {
|
||||
|
||||
Echo * ptr;
|
||||
|
||||
ptr = (Echo *)Instance;
|
||||
switch (Port) {
|
||||
case DELAYTIME_L:
|
||||
ptr->delaytime_L = DataLocation;
|
||||
break;
|
||||
case DELAYTIME_R:
|
||||
ptr->delaytime_R = DataLocation;
|
||||
break;
|
||||
case FEEDBACK_L:
|
||||
ptr->feedback_L = DataLocation;
|
||||
break;
|
||||
case FEEDBACK_R:
|
||||
ptr->feedback_R = DataLocation;
|
||||
break;
|
||||
case STRENGTH_L:
|
||||
ptr->strength_L = DataLocation;
|
||||
break;
|
||||
case STRENGTH_R:
|
||||
ptr->strength_R = DataLocation;
|
||||
break;
|
||||
case MODE:
|
||||
ptr->mode = DataLocation;
|
||||
break;
|
||||
case HAAS:
|
||||
ptr->haas = DataLocation;
|
||||
break;
|
||||
case REV_OUTCH:
|
||||
ptr->rev_outch = DataLocation;
|
||||
break;
|
||||
case DRYLEVEL:
|
||||
ptr->drylevel = DataLocation;
|
||||
break;
|
||||
case INPUT_L:
|
||||
ptr->input_L = DataLocation;
|
||||
break;
|
||||
case OUTPUT_L:
|
||||
ptr->output_L = DataLocation;
|
||||
break;
|
||||
case INPUT_R:
|
||||
ptr->input_R = DataLocation;
|
||||
break;
|
||||
case OUTPUT_R:
|
||||
ptr->output_R = DataLocation;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define EPS 0.00000001f
|
||||
|
||||
static inline float
|
||||
M(float x) {
|
||||
|
||||
if ((x > EPS) || (x < -EPS))
|
||||
return x;
|
||||
else
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
void
|
||||
run_Echo(LADSPA_Handle Instance,
|
||||
unsigned long SampleCount) {
|
||||
|
||||
Echo * ptr;
|
||||
unsigned long sample_index;
|
||||
|
||||
LADSPA_Data delaytime_L;
|
||||
LADSPA_Data delaytime_R;
|
||||
LADSPA_Data feedback_L;
|
||||
LADSPA_Data feedback_R;
|
||||
LADSPA_Data strength_L;
|
||||
LADSPA_Data strength_R;
|
||||
LADSPA_Data drylevel;
|
||||
LADSPA_Data mode;
|
||||
LADSPA_Data haas;
|
||||
LADSPA_Data rev_outch;
|
||||
|
||||
LADSPA_Data * input_L;
|
||||
LADSPA_Data * output_L;
|
||||
LADSPA_Data * input_R;
|
||||
LADSPA_Data * output_R;
|
||||
|
||||
unsigned long sample_rate;
|
||||
unsigned long buflen_L;
|
||||
unsigned long buflen_R;
|
||||
|
||||
LADSPA_Data out_L = 0;
|
||||
LADSPA_Data out_R = 0;
|
||||
LADSPA_Data in_L = 0;
|
||||
LADSPA_Data in_R = 0;
|
||||
|
||||
ptr = (Echo *)Instance;
|
||||
|
||||
delaytime_L = LIMIT(*(ptr->delaytime_L),0.0f,2000.0f);
|
||||
delaytime_R = LIMIT(*(ptr->delaytime_R),0.0f,2000.0f);
|
||||
feedback_L = LIMIT(*(ptr->feedback_L) / 100.0, 0.0f, 100.0f);
|
||||
feedback_R = LIMIT(*(ptr->feedback_R) / 100.0, 0.0f, 100.0f);
|
||||
strength_L = db2lin(LIMIT(*(ptr->strength_L),-70.0f,10.0f));
|
||||
strength_R = db2lin(LIMIT(*(ptr->strength_R),-70.0f,10.0f));
|
||||
drylevel = db2lin(LIMIT(*(ptr->drylevel),-70.0f,10.0f));
|
||||
mode = LIMIT(*(ptr->mode),-2.0f,2.0f);
|
||||
haas = LIMIT(*(ptr->haas),-2.0f,2.0f);
|
||||
rev_outch = LIMIT(*(ptr->rev_outch),-2.0f,2.0f);
|
||||
|
||||
input_L = ptr->input_L;
|
||||
output_L = ptr->output_L;
|
||||
input_R = ptr->input_R;
|
||||
output_R = ptr->output_R;
|
||||
|
||||
sample_rate = ptr->sample_rate;
|
||||
buflen_L = delaytime_L * sample_rate / 1000;
|
||||
buflen_R = delaytime_R * sample_rate / 1000;
|
||||
|
||||
|
||||
for (sample_index = 0; sample_index < SampleCount; sample_index++) {
|
||||
|
||||
in_L = *(input_L++);
|
||||
in_R = *(input_R++);
|
||||
|
||||
out_L = in_L * drylevel + ptr->mpx_out_L * strength_L;
|
||||
out_R = in_R * drylevel + ptr->mpx_out_R * strength_R;
|
||||
|
||||
if (haas > 0.0f)
|
||||
in_R = 0.0f;
|
||||
|
||||
if (mode <= 0.0f) {
|
||||
ptr->mpx_out_L =
|
||||
M(push_buffer(in_L + ptr->mpx_out_L * feedback_L,
|
||||
ptr->ringbuffer_L, buflen_L, ptr->buffer_pos_L));
|
||||
ptr->mpx_out_R =
|
||||
M(push_buffer(in_R + ptr->mpx_out_R * feedback_R,
|
||||
ptr->ringbuffer_R, buflen_R, ptr->buffer_pos_R));
|
||||
} else {
|
||||
ptr->mpx_out_R =
|
||||
M(push_buffer(in_L + ptr->mpx_out_L * feedback_L,
|
||||
ptr->ringbuffer_L, buflen_L, ptr->buffer_pos_L));
|
||||
ptr->mpx_out_L =
|
||||
M(push_buffer(in_R + ptr->mpx_out_R * feedback_R,
|
||||
ptr->ringbuffer_R, buflen_R, ptr->buffer_pos_R));
|
||||
}
|
||||
|
||||
if (rev_outch <= 0.0f) {
|
||||
*(output_L++) = out_L;
|
||||
*(output_R++) = out_R;
|
||||
} else {
|
||||
*(output_L++) = out_R;
|
||||
*(output_R++) = out_L;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void
|
||||
set_run_adding_gain(LADSPA_Handle Instance, LADSPA_Data gain){
|
||||
|
||||
Echo * ptr;
|
||||
|
||||
ptr = (Echo *)Instance;
|
||||
|
||||
ptr->run_adding_gain = gain;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
run_adding_gain_Echo(LADSPA_Handle Instance,
|
||||
unsigned long SampleCount) {
|
||||
|
||||
Echo * ptr;
|
||||
unsigned long sample_index;
|
||||
|
||||
LADSPA_Data delaytime_L;
|
||||
LADSPA_Data delaytime_R;
|
||||
LADSPA_Data feedback_L;
|
||||
LADSPA_Data feedback_R;
|
||||
LADSPA_Data strength_L;
|
||||
LADSPA_Data strength_R;
|
||||
LADSPA_Data drylevel;
|
||||
LADSPA_Data mode;
|
||||
LADSPA_Data haas;
|
||||
LADSPA_Data rev_outch;
|
||||
|
||||
LADSPA_Data * input_L;
|
||||
LADSPA_Data * output_L;
|
||||
LADSPA_Data * input_R;
|
||||
LADSPA_Data * output_R;
|
||||
|
||||
unsigned long sample_rate;
|
||||
unsigned long buflen_L;
|
||||
unsigned long buflen_R;
|
||||
|
||||
LADSPA_Data out_L = 0;
|
||||
LADSPA_Data out_R = 0;
|
||||
LADSPA_Data in_L = 0;
|
||||
LADSPA_Data in_R = 0;
|
||||
|
||||
ptr = (Echo *)Instance;
|
||||
|
||||
delaytime_L = LIMIT(*(ptr->delaytime_L),0.0f,2000.0f);
|
||||
delaytime_R = LIMIT(*(ptr->delaytime_R),0.0f,2000.0f);
|
||||
feedback_L = LIMIT(*(ptr->feedback_L) / 100.0, 0.0f, 100.0f);
|
||||
feedback_R = LIMIT(*(ptr->feedback_R) / 100.0, 0.0f, 100.0f);
|
||||
strength_L = db2lin(LIMIT(*(ptr->strength_L),-70.0f,10.0f));
|
||||
strength_R = db2lin(LIMIT(*(ptr->strength_R),-70.0f,10.0f));
|
||||
drylevel = db2lin(LIMIT(*(ptr->drylevel),-70.0f,10.0f));
|
||||
mode = LIMIT(*(ptr->mode),-2.0f,2.0f);
|
||||
haas = LIMIT(*(ptr->haas),-2.0f,2.0f);
|
||||
rev_outch = LIMIT(*(ptr->rev_outch),-2.0f,2.0f);
|
||||
|
||||
input_L = ptr->input_L;
|
||||
output_L = ptr->output_L;
|
||||
input_R = ptr->input_R;
|
||||
output_R = ptr->output_R;
|
||||
|
||||
sample_rate = ptr->sample_rate;
|
||||
buflen_L = delaytime_L * sample_rate / 1000;
|
||||
buflen_R = delaytime_R * sample_rate / 1000;
|
||||
|
||||
|
||||
for (sample_index = 0; sample_index < SampleCount; sample_index++) {
|
||||
|
||||
in_L = *(input_L++);
|
||||
in_R = *(input_R++);
|
||||
|
||||
out_L = in_L * drylevel + ptr->mpx_out_L * strength_L;
|
||||
out_R = in_R * drylevel + ptr->mpx_out_R * strength_R;
|
||||
|
||||
if (haas > 0.0f)
|
||||
in_R = 0.0f;
|
||||
|
||||
if (mode <= 0.0f) {
|
||||
ptr->mpx_out_L =
|
||||
M(push_buffer(in_L + ptr->mpx_out_L * feedback_L,
|
||||
ptr->ringbuffer_L, buflen_L, ptr->buffer_pos_L));
|
||||
ptr->mpx_out_R =
|
||||
M(push_buffer(in_R + ptr->mpx_out_R * feedback_R,
|
||||
ptr->ringbuffer_R, buflen_R, ptr->buffer_pos_R));
|
||||
} else {
|
||||
ptr->mpx_out_R =
|
||||
M(push_buffer(in_L + ptr->mpx_out_L * feedback_L,
|
||||
ptr->ringbuffer_L, buflen_L, ptr->buffer_pos_L));
|
||||
ptr->mpx_out_L =
|
||||
M(push_buffer(in_R + ptr->mpx_out_R * feedback_R,
|
||||
ptr->ringbuffer_R, buflen_R, ptr->buffer_pos_R));
|
||||
}
|
||||
|
||||
if (rev_outch <= 0.0f) {
|
||||
*(output_L++) += out_L * ptr->run_adding_gain;
|
||||
*(output_R++) += out_R * ptr->run_adding_gain;
|
||||
} else {
|
||||
*(output_L++) += out_R * ptr->run_adding_gain;
|
||||
*(output_R++) += out_L * ptr->run_adding_gain;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Throw away an Echo effect instance. */
|
||||
void
|
||||
cleanup_Echo(LADSPA_Handle Instance) {
|
||||
|
||||
free(Instance);
|
||||
}
|
||||
|
||||
|
||||
|
||||
LADSPA_Descriptor * stereo_descriptor = NULL;
|
||||
|
||||
|
||||
|
||||
/* _init() is called automatically when the plugin library is first
|
||||
loaded. */
|
||||
void
|
||||
_init() {
|
||||
|
||||
char ** port_names;
|
||||
LADSPA_PortDescriptor * port_descriptors;
|
||||
LADSPA_PortRangeHint * port_range_hints;
|
||||
|
||||
if ((stereo_descriptor =
|
||||
(LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor))) == NULL)
|
||||
exit(1);
|
||||
|
||||
|
||||
/* init the stereo Echo */
|
||||
|
||||
stereo_descriptor->UniqueID = ID_STEREO;
|
||||
stereo_descriptor->Label = strdup("tap_stereo_echo");
|
||||
stereo_descriptor->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
|
||||
stereo_descriptor->Name = strdup("TAP Stereo Echo");
|
||||
stereo_descriptor->Maker = strdup("Tom Szilagyi");
|
||||
stereo_descriptor->Copyright = strdup("GPL");
|
||||
stereo_descriptor->PortCount = PORTCOUNT_STEREO;
|
||||
|
||||
if ((port_descriptors =
|
||||
(LADSPA_PortDescriptor *)calloc(PORTCOUNT_STEREO, sizeof(LADSPA_PortDescriptor))) == NULL)
|
||||
exit(1);
|
||||
|
||||
stereo_descriptor->PortDescriptors = (const LADSPA_PortDescriptor *)port_descriptors;
|
||||
port_descriptors[DELAYTIME_L] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[DELAYTIME_R] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[FEEDBACK_L] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[FEEDBACK_R] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[STRENGTH_L] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[STRENGTH_R] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[DRYLEVEL] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[MODE] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[HAAS] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[REV_OUTCH] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
|
||||
port_descriptors[INPUT_L] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
|
||||
port_descriptors[OUTPUT_L] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
|
||||
port_descriptors[INPUT_R] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
|
||||
port_descriptors[OUTPUT_R] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
|
||||
|
||||
if ((port_names =
|
||||
(char **)calloc(PORTCOUNT_STEREO, sizeof(char *))) == NULL)
|
||||
exit(1);
|
||||
|
||||
stereo_descriptor->PortNames = (const char **)port_names;
|
||||
|
||||
port_names[DELAYTIME_L] = strdup("L Delay [ms]");
|
||||
port_names[DELAYTIME_R] = strdup("R/Haas Delay [ms]");
|
||||
port_names[FEEDBACK_L] = strdup("L Feedback [%]");
|
||||
port_names[FEEDBACK_R] = strdup("R/Haas Feedback [%]");
|
||||
port_names[STRENGTH_L] = strdup("L Echo Level [dB]");
|
||||
port_names[STRENGTH_R] = strdup("R Echo Level [dB]");
|
||||
port_names[DRYLEVEL] = strdup("Dry Level [dB]");
|
||||
port_names[MODE] = strdup("Cross Mode");
|
||||
port_names[HAAS] = strdup("Haas Effect");
|
||||
port_names[REV_OUTCH] = strdup("Swap Outputs");
|
||||
|
||||
port_names[INPUT_L] = strdup("Input Left");
|
||||
port_names[OUTPUT_L] = strdup("Output Left");
|
||||
port_names[INPUT_R] = strdup("Input Right");
|
||||
port_names[OUTPUT_R] = strdup("Output Right");
|
||||
|
||||
if ((port_range_hints =
|
||||
((LADSPA_PortRangeHint *)calloc(PORTCOUNT_STEREO, sizeof(LADSPA_PortRangeHint)))) == NULL)
|
||||
exit(1);
|
||||
|
||||
stereo_descriptor->PortRangeHints = (const LADSPA_PortRangeHint *)port_range_hints;
|
||||
|
||||
port_range_hints[DELAYTIME_L].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_100);
|
||||
port_range_hints[DELAYTIME_L].LowerBound = 0;
|
||||
port_range_hints[DELAYTIME_L].UpperBound = MAX_DELAY;
|
||||
|
||||
port_range_hints[DELAYTIME_R].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_100);
|
||||
port_range_hints[DELAYTIME_R].LowerBound = 0;
|
||||
port_range_hints[DELAYTIME_R].UpperBound = MAX_DELAY;
|
||||
|
||||
port_range_hints[FEEDBACK_L].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[FEEDBACK_L].LowerBound = 0;
|
||||
port_range_hints[FEEDBACK_L].UpperBound = 100;
|
||||
|
||||
port_range_hints[FEEDBACK_R].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[FEEDBACK_R].LowerBound = 0;
|
||||
port_range_hints[FEEDBACK_R].UpperBound = 100;
|
||||
|
||||
port_range_hints[STRENGTH_L].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[STRENGTH_L].LowerBound = -70;
|
||||
port_range_hints[STRENGTH_L].UpperBound = 10;
|
||||
|
||||
port_range_hints[STRENGTH_R].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[STRENGTH_R].LowerBound = -70;
|
||||
port_range_hints[STRENGTH_R].UpperBound = 10;
|
||||
|
||||
port_range_hints[MODE].HintDescriptor =
|
||||
(LADSPA_HINT_TOGGLED |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
|
||||
port_range_hints[HAAS].HintDescriptor =
|
||||
(LADSPA_HINT_TOGGLED |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
|
||||
port_range_hints[REV_OUTCH].HintDescriptor =
|
||||
(LADSPA_HINT_TOGGLED |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
|
||||
port_range_hints[DRYLEVEL].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[DRYLEVEL].LowerBound = -70;
|
||||
port_range_hints[DRYLEVEL].UpperBound = 10;
|
||||
|
||||
|
||||
port_range_hints[INPUT_L].HintDescriptor = 0;
|
||||
port_range_hints[OUTPUT_L].HintDescriptor = 0;
|
||||
port_range_hints[INPUT_R].HintDescriptor = 0;
|
||||
port_range_hints[OUTPUT_R].HintDescriptor = 0;
|
||||
|
||||
|
||||
stereo_descriptor->instantiate = instantiate_Echo;
|
||||
stereo_descriptor->connect_port = connect_port_Echo;
|
||||
stereo_descriptor->activate = activate_Echo;
|
||||
stereo_descriptor->run = run_Echo;
|
||||
stereo_descriptor->run_adding = run_adding_gain_Echo;
|
||||
stereo_descriptor->set_run_adding_gain = set_run_adding_gain;
|
||||
stereo_descriptor->deactivate = deactivate_Echo;
|
||||
stereo_descriptor->cleanup = cleanup_Echo;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
delete_descriptor(LADSPA_Descriptor * descriptor) {
|
||||
unsigned long index;
|
||||
if (descriptor) {
|
||||
free((char *)descriptor->Label);
|
||||
free((char *)descriptor->Name);
|
||||
free((char *)descriptor->Maker);
|
||||
free((char *)descriptor->Copyright);
|
||||
free((LADSPA_PortDescriptor *)descriptor->PortDescriptors);
|
||||
for (index = 0; index < descriptor->PortCount; index++)
|
||||
free((char *)(descriptor->PortNames[index]));
|
||||
free((char **)descriptor->PortNames);
|
||||
free((LADSPA_PortRangeHint *)descriptor->PortRangeHints);
|
||||
free(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* _fini() is called automatically when the library is unloaded. */
|
||||
void
|
||||
_fini() {
|
||||
delete_descriptor(stereo_descriptor);
|
||||
}
|
||||
|
||||
|
||||
/* Return a descriptor of the requested plugin type. */
|
||||
|
||||
const
|
||||
LADSPA_Descriptor *
|
||||
ladspa_descriptor(unsigned long Index) {
|
||||
|
||||
switch (Index) {
|
||||
case 0:
|
||||
return stereo_descriptor;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
751
plugins/ladspa_effect/tap/tap_eq.c
Normal file
751
plugins/ladspa_effect/tap/tap_eq.c
Normal file
@@ -0,0 +1,751 @@
|
||||
/* -*- linux-c -*-
|
||||
Copyright (C) 2004 Tom Szilagyi
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: tap_eq.c,v 1.6 2004/04/18 19:56:56 tszilagyi Exp $
|
||||
*/
|
||||
|
||||
|
||||
/* Please note that this plugin was inspired by and its code based
|
||||
upon Steve Harris's "DJ EQ" plugin (no. 1901). While I give him
|
||||
credit for his excellent work, I reserve myself to be blamed for any
|
||||
bugs or malfunction. */
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "ladspa.h"
|
||||
#include "tap_utils.h"
|
||||
|
||||
/* The Unique ID of the plugin */
|
||||
#define ID_MONO 2141
|
||||
|
||||
|
||||
/* Bandwidth of EQ filters in octaves */
|
||||
#define BWIDTH 1.0f
|
||||
|
||||
|
||||
/* Port numbers */
|
||||
|
||||
#define EQ_CH0G 0
|
||||
#define EQ_CH1G 1
|
||||
#define EQ_CH2G 2
|
||||
#define EQ_CH3G 3
|
||||
#define EQ_CH4G 4
|
||||
#define EQ_CH5G 5
|
||||
#define EQ_CH6G 6
|
||||
#define EQ_CH7G 7
|
||||
|
||||
#define EQ_CH0F 8
|
||||
#define EQ_CH1F 9
|
||||
#define EQ_CH2F 10
|
||||
#define EQ_CH3F 11
|
||||
#define EQ_CH4F 12
|
||||
#define EQ_CH5F 13
|
||||
#define EQ_CH6F 14
|
||||
#define EQ_CH7F 15
|
||||
|
||||
#define EQ_INPUT 16
|
||||
#define EQ_OUTPUT 17
|
||||
|
||||
|
||||
/* Total number of ports */
|
||||
#define PORTCOUNT_MONO 18
|
||||
|
||||
|
||||
static LADSPA_Descriptor *eqDescriptor = NULL;
|
||||
|
||||
typedef struct {
|
||||
LADSPA_Data *ch0f;
|
||||
LADSPA_Data *ch0g;
|
||||
LADSPA_Data *ch1f;
|
||||
LADSPA_Data *ch1g;
|
||||
LADSPA_Data *ch2f;
|
||||
LADSPA_Data *ch2g;
|
||||
LADSPA_Data *ch3f;
|
||||
LADSPA_Data *ch3g;
|
||||
LADSPA_Data *ch4f;
|
||||
LADSPA_Data *ch4g;
|
||||
LADSPA_Data *ch5f;
|
||||
LADSPA_Data *ch5g;
|
||||
LADSPA_Data *ch6f;
|
||||
LADSPA_Data *ch6g;
|
||||
LADSPA_Data *ch7f;
|
||||
LADSPA_Data *ch7g;
|
||||
LADSPA_Data *input;
|
||||
LADSPA_Data *output;
|
||||
biquad * filters;
|
||||
float fs;
|
||||
LADSPA_Data old_ch0f;
|
||||
LADSPA_Data old_ch0g;
|
||||
LADSPA_Data old_ch1f;
|
||||
LADSPA_Data old_ch1g;
|
||||
LADSPA_Data old_ch2f;
|
||||
LADSPA_Data old_ch2g;
|
||||
LADSPA_Data old_ch3f;
|
||||
LADSPA_Data old_ch3g;
|
||||
LADSPA_Data old_ch4f;
|
||||
LADSPA_Data old_ch4g;
|
||||
LADSPA_Data old_ch5f;
|
||||
LADSPA_Data old_ch5g;
|
||||
LADSPA_Data old_ch6f;
|
||||
LADSPA_Data old_ch6g;
|
||||
LADSPA_Data old_ch7f;
|
||||
LADSPA_Data old_ch7g;
|
||||
|
||||
LADSPA_Data run_adding_gain;
|
||||
} eq;
|
||||
|
||||
const
|
||||
LADSPA_Descriptor *
|
||||
ladspa_descriptor(unsigned long index) {
|
||||
|
||||
switch (index) {
|
||||
case 0:
|
||||
return eqDescriptor;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
activate_eq(LADSPA_Handle instance) {
|
||||
|
||||
eq *ptr = (eq *)instance;
|
||||
biquad *filters = ptr->filters;
|
||||
|
||||
biquad_init(&filters[0]);
|
||||
biquad_init(&filters[1]);
|
||||
biquad_init(&filters[2]);
|
||||
biquad_init(&filters[3]);
|
||||
biquad_init(&filters[4]);
|
||||
biquad_init(&filters[5]);
|
||||
biquad_init(&filters[6]);
|
||||
biquad_init(&filters[7]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static
|
||||
void
|
||||
cleanup_eq(LADSPA_Handle instance) {
|
||||
|
||||
free(instance);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void
|
||||
connectPort_eq(LADSPA_Handle instance, unsigned long port, LADSPA_Data *data) {
|
||||
|
||||
eq *plugin;
|
||||
|
||||
plugin = (eq *)instance;
|
||||
switch (port) {
|
||||
case EQ_CH0F:
|
||||
plugin->ch0f = data;
|
||||
break;
|
||||
case EQ_CH0G:
|
||||
plugin->ch0g = data;
|
||||
break;
|
||||
case EQ_CH1F:
|
||||
plugin->ch1f = data;
|
||||
break;
|
||||
case EQ_CH1G:
|
||||
plugin->ch1g = data;
|
||||
break;
|
||||
case EQ_CH2F:
|
||||
plugin->ch2f = data;
|
||||
break;
|
||||
case EQ_CH2G:
|
||||
plugin->ch2g = data;
|
||||
break;
|
||||
case EQ_CH3F:
|
||||
plugin->ch3f = data;
|
||||
break;
|
||||
case EQ_CH3G:
|
||||
plugin->ch3g = data;
|
||||
break;
|
||||
case EQ_CH4F:
|
||||
plugin->ch4f = data;
|
||||
break;
|
||||
case EQ_CH4G:
|
||||
plugin->ch4g = data;
|
||||
break;
|
||||
case EQ_CH5F:
|
||||
plugin->ch5f = data;
|
||||
break;
|
||||
case EQ_CH5G:
|
||||
plugin->ch5g = data;
|
||||
break;
|
||||
case EQ_CH6F:
|
||||
plugin->ch6f = data;
|
||||
break;
|
||||
case EQ_CH6G:
|
||||
plugin->ch6g = data;
|
||||
break;
|
||||
case EQ_CH7F:
|
||||
plugin->ch7f = data;
|
||||
break;
|
||||
case EQ_CH7G:
|
||||
plugin->ch7g = data;
|
||||
break;
|
||||
case EQ_INPUT:
|
||||
plugin->input = data;
|
||||
break;
|
||||
case EQ_OUTPUT:
|
||||
plugin->output = data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
LADSPA_Handle
|
||||
instantiate_eq(const LADSPA_Descriptor *descriptor, unsigned long s_rate) {
|
||||
|
||||
eq *ptr = (eq *)malloc(sizeof(eq));
|
||||
biquad *filters = NULL;
|
||||
float fs;
|
||||
|
||||
fs = s_rate;
|
||||
|
||||
filters = calloc(8, sizeof(biquad));
|
||||
|
||||
ptr->filters = filters;
|
||||
ptr->fs = fs;
|
||||
ptr->run_adding_gain = 1.0f;
|
||||
|
||||
eq_set_params(&filters[0], 100.0f, 0.0f, BWIDTH, fs);
|
||||
eq_set_params(&filters[1], 200.0f, 0.0f, BWIDTH, fs);
|
||||
eq_set_params(&filters[2], 400.0f, 0.0f, BWIDTH, fs);
|
||||
eq_set_params(&filters[3], 1000.0f, 0.0f, BWIDTH, fs);
|
||||
eq_set_params(&filters[4], 3000.0f, 0.0f, BWIDTH, fs);
|
||||
eq_set_params(&filters[5], 6000.0f, 0.0f, BWIDTH, fs);
|
||||
eq_set_params(&filters[6], 12000.0f, 0.0f, BWIDTH, fs);
|
||||
eq_set_params(&filters[7], 15000.0f, 0.0f, BWIDTH, fs);
|
||||
|
||||
return (LADSPA_Handle)ptr;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void
|
||||
run_eq(LADSPA_Handle instance, unsigned long sample_count) {
|
||||
|
||||
eq * ptr = (eq *)instance;
|
||||
|
||||
const LADSPA_Data ch0f = LIMIT(*(ptr->ch0f),40.0f,280.0f);
|
||||
const LADSPA_Data ch0g = LIMIT(*(ptr->ch0g),-50.0f,20.0f);
|
||||
const LADSPA_Data ch1f = LIMIT(*(ptr->ch1f),100.0f,500.0f);
|
||||
const LADSPA_Data ch1g = LIMIT(*(ptr->ch1g),-50.0f,20.0f);
|
||||
const LADSPA_Data ch2f = LIMIT(*(ptr->ch2f),200.0f,1000.0f);
|
||||
const LADSPA_Data ch2g = LIMIT(*(ptr->ch2g),-50.0f,20.0f);
|
||||
const LADSPA_Data ch3f = LIMIT(*(ptr->ch3f),400.0f,2800.0f);
|
||||
const LADSPA_Data ch3g = LIMIT(*(ptr->ch3g),-50.0f,20.0f);
|
||||
const LADSPA_Data ch4f = LIMIT(*(ptr->ch4f),1000.0f,5000.0f);
|
||||
const LADSPA_Data ch4g = LIMIT(*(ptr->ch4g),-50.0f,20.0f);
|
||||
const LADSPA_Data ch5f = LIMIT(*(ptr->ch5f),3000.0f,9000.0f);
|
||||
const LADSPA_Data ch5g = LIMIT(*(ptr->ch5g),-50.0f,20.0f);
|
||||
const LADSPA_Data ch6f = LIMIT(*(ptr->ch6f),6000.0f,18000.0f);
|
||||
const LADSPA_Data ch6g = LIMIT(*(ptr->ch6g),-50.0f,20.0f);
|
||||
const LADSPA_Data ch7f = LIMIT(*(ptr->ch7f),10000.0f,20000.0f);
|
||||
const LADSPA_Data ch7g = LIMIT(*(ptr->ch7g),-50.0f,20.0f);
|
||||
|
||||
const LADSPA_Data * input = ptr->input;
|
||||
LADSPA_Data * output = ptr->output;
|
||||
|
||||
biquad * filters = ptr->filters;
|
||||
float fs = ptr->fs;
|
||||
|
||||
unsigned long pos;
|
||||
float samp;
|
||||
|
||||
|
||||
if ((ch0f != ptr->old_ch0f) ||
|
||||
(ch0g != ptr->old_ch0g)) {
|
||||
ptr->old_ch0f = ch0f;
|
||||
ptr->old_ch0g = ch0g;
|
||||
eq_set_params(&filters[0], ch0f, ch0g, BWIDTH, fs);
|
||||
}
|
||||
if ((ch1f != ptr->old_ch1f) ||
|
||||
(ch1g != ptr->old_ch1g)) {
|
||||
ptr->old_ch1f = ch1f;
|
||||
ptr->old_ch1g = ch1g;
|
||||
eq_set_params(&filters[1], ch1f, ch1g, BWIDTH, fs);
|
||||
}
|
||||
if ((ch2f != ptr->old_ch2f) ||
|
||||
(ch2g != ptr->old_ch2g)) {
|
||||
ptr->old_ch2f = ch2f;
|
||||
ptr->old_ch2g = ch2g;
|
||||
eq_set_params(&filters[2], ch2f, ch2g, BWIDTH, fs);
|
||||
}
|
||||
if ((ch3f != ptr->old_ch3f) ||
|
||||
(ch3g != ptr->old_ch3g)) {
|
||||
ptr->old_ch3f = ch3f;
|
||||
ptr->old_ch3g = ch3g;
|
||||
eq_set_params(&filters[3], ch3f, ch3g, BWIDTH, fs);
|
||||
}
|
||||
if ((ch4f != ptr->old_ch4f) ||
|
||||
(ch4g != ptr->old_ch4g)) {
|
||||
ptr->old_ch4f = ch4f;
|
||||
ptr->old_ch4g = ch4g;
|
||||
eq_set_params(&filters[4], ch4f, ch4g, BWIDTH, fs);
|
||||
}
|
||||
if ((ch5f != ptr->old_ch5f) ||
|
||||
(ch5g != ptr->old_ch5g)) {
|
||||
ptr->old_ch5f = ch5f;
|
||||
ptr->old_ch5g = ch5g;
|
||||
eq_set_params(&filters[5], ch5f, ch5g, BWIDTH, fs);
|
||||
}
|
||||
if ((ch6f != ptr->old_ch6f) ||
|
||||
(ch6g != ptr->old_ch6g)) {
|
||||
ptr->old_ch6f = ch6f;
|
||||
ptr->old_ch6g = ch6g;
|
||||
eq_set_params(&filters[6], ch6f, ch6g, BWIDTH, fs);
|
||||
}
|
||||
if ((ch7f != ptr->old_ch7f) ||
|
||||
(ch7g != ptr->old_ch7g)) {
|
||||
ptr->old_ch7f = ch7f;
|
||||
ptr->old_ch7g = ch7g;
|
||||
eq_set_params(&filters[7], ch7f, ch7g, BWIDTH, fs);
|
||||
}
|
||||
|
||||
for (pos = 0; pos < sample_count; pos++) {
|
||||
samp = input[pos];
|
||||
if (ch0g != 0.0f)
|
||||
samp = biquad_run(&filters[0], samp);
|
||||
if (ch1g != 0.0f)
|
||||
samp = biquad_run(&filters[1], samp);
|
||||
if (ch2g != 0.0f)
|
||||
samp = biquad_run(&filters[2], samp);
|
||||
if (ch3g != 0.0f)
|
||||
samp = biquad_run(&filters[3], samp);
|
||||
if (ch4g != 0.0f)
|
||||
samp = biquad_run(&filters[4], samp);
|
||||
if (ch5g != 0.0f)
|
||||
samp = biquad_run(&filters[5], samp);
|
||||
if (ch6g != 0.0f)
|
||||
samp = biquad_run(&filters[6], samp);
|
||||
if (ch7g != 0.0f)
|
||||
samp = biquad_run(&filters[7], samp);
|
||||
output[pos] = samp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
set_run_adding_gain(LADSPA_Handle instance, LADSPA_Data gain) {
|
||||
|
||||
eq * ptr = (eq *)instance;
|
||||
|
||||
ptr->run_adding_gain = gain;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static
|
||||
void
|
||||
run_adding_eq(LADSPA_Handle instance, unsigned long sample_count) {
|
||||
|
||||
eq * ptr = (eq *)instance;
|
||||
|
||||
const LADSPA_Data ch0f = LIMIT(*(ptr->ch0f),40.0f,280.0f);
|
||||
const LADSPA_Data ch0g = LIMIT(*(ptr->ch0g),-50.0f,20.0f);
|
||||
const LADSPA_Data ch1f = LIMIT(*(ptr->ch1f),100.0f,500.0f);
|
||||
const LADSPA_Data ch1g = LIMIT(*(ptr->ch1g),-50.0f,20.0f);
|
||||
const LADSPA_Data ch2f = LIMIT(*(ptr->ch2f),200.0f,1000.0f);
|
||||
const LADSPA_Data ch2g = LIMIT(*(ptr->ch2g),-50.0f,20.0f);
|
||||
const LADSPA_Data ch3f = LIMIT(*(ptr->ch3f),400.0f,2800.0f);
|
||||
const LADSPA_Data ch3g = LIMIT(*(ptr->ch3g),-50.0f,20.0f);
|
||||
const LADSPA_Data ch4f = LIMIT(*(ptr->ch4f),1000.0f,5000.0f);
|
||||
const LADSPA_Data ch4g = LIMIT(*(ptr->ch4g),-50.0f,20.0f);
|
||||
const LADSPA_Data ch5f = LIMIT(*(ptr->ch5f),3000.0f,9000.0f);
|
||||
const LADSPA_Data ch5g = LIMIT(*(ptr->ch5g),-50.0f,20.0f);
|
||||
const LADSPA_Data ch6f = LIMIT(*(ptr->ch6f),6000.0f,18000.0f);
|
||||
const LADSPA_Data ch6g = LIMIT(*(ptr->ch6g),-50.0f,20.0f);
|
||||
const LADSPA_Data ch7f = LIMIT(*(ptr->ch7f),10000.0f,20000.0f);
|
||||
const LADSPA_Data ch7g = LIMIT(*(ptr->ch7g),-50.0f,20.0f);
|
||||
|
||||
const LADSPA_Data * input = ptr->input;
|
||||
LADSPA_Data * output = ptr->output;
|
||||
|
||||
biquad * filters = ptr->filters;
|
||||
float fs = ptr->fs;
|
||||
|
||||
unsigned long pos;
|
||||
float samp;
|
||||
|
||||
|
||||
if ((ch0f != ptr->old_ch0f) ||
|
||||
(ch0g != ptr->old_ch0g)) {
|
||||
ptr->old_ch0f = ch0f;
|
||||
ptr->old_ch0g = ch0g;
|
||||
eq_set_params(&filters[0], ch0f, ch0g, BWIDTH, fs);
|
||||
}
|
||||
if ((ch1f != ptr->old_ch1f) ||
|
||||
(ch1g != ptr->old_ch1g)) {
|
||||
ptr->old_ch1f = ch1f;
|
||||
ptr->old_ch1g = ch1g;
|
||||
eq_set_params(&filters[1], ch1f, ch1g, BWIDTH, fs);
|
||||
}
|
||||
if ((ch2f != ptr->old_ch2f) ||
|
||||
(ch2g != ptr->old_ch2g)) {
|
||||
ptr->old_ch2f = ch2f;
|
||||
ptr->old_ch2g = ch2g;
|
||||
eq_set_params(&filters[2], ch2f, ch2g, BWIDTH, fs);
|
||||
}
|
||||
if ((ch3f != ptr->old_ch3f) ||
|
||||
(ch3g != ptr->old_ch3g)) {
|
||||
ptr->old_ch3f = ch3f;
|
||||
ptr->old_ch3g = ch3g;
|
||||
eq_set_params(&filters[3], ch3f, ch3g, BWIDTH, fs);
|
||||
}
|
||||
if ((ch4f != ptr->old_ch4f) ||
|
||||
(ch4g != ptr->old_ch4g)) {
|
||||
ptr->old_ch4f = ch4f;
|
||||
ptr->old_ch4g = ch4g;
|
||||
eq_set_params(&filters[4], ch4f, ch4g, BWIDTH, fs);
|
||||
}
|
||||
if ((ch5f != ptr->old_ch5f) ||
|
||||
(ch5g != ptr->old_ch5g)) {
|
||||
ptr->old_ch5f = ch5f;
|
||||
ptr->old_ch5g = ch5g;
|
||||
eq_set_params(&filters[5], ch5f, ch5g, BWIDTH, fs);
|
||||
}
|
||||
if ((ch6f != ptr->old_ch6f) ||
|
||||
(ch6g != ptr->old_ch6g)) {
|
||||
ptr->old_ch6f = ch6f;
|
||||
ptr->old_ch6g = ch6g;
|
||||
eq_set_params(&filters[6], ch6f, ch6g, BWIDTH, fs);
|
||||
}
|
||||
if ((ch7f != ptr->old_ch7f) ||
|
||||
(ch7g != ptr->old_ch7g)) {
|
||||
ptr->old_ch7f = ch7f;
|
||||
ptr->old_ch7g = ch7g;
|
||||
eq_set_params(&filters[7], ch7f, ch7g, BWIDTH, fs);
|
||||
}
|
||||
|
||||
for (pos = 0; pos < sample_count; pos++) {
|
||||
samp = input[pos];
|
||||
if (ch0g != 0.0f)
|
||||
samp = biquad_run(&filters[0], samp);
|
||||
if (ch1g != 0.0f)
|
||||
samp = biquad_run(&filters[1], samp);
|
||||
if (ch2g != 0.0f)
|
||||
samp = biquad_run(&filters[2], samp);
|
||||
if (ch3g != 0.0f)
|
||||
samp = biquad_run(&filters[3], samp);
|
||||
if (ch4g != 0.0f)
|
||||
samp = biquad_run(&filters[4], samp);
|
||||
if (ch5g != 0.0f)
|
||||
samp = biquad_run(&filters[5], samp);
|
||||
if (ch6g != 0.0f)
|
||||
samp = biquad_run(&filters[6], samp);
|
||||
if (ch7g != 0.0f)
|
||||
samp = biquad_run(&filters[7], samp);
|
||||
output[pos] += ptr->run_adding_gain * samp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void
|
||||
_init() {
|
||||
|
||||
char **port_names;
|
||||
LADSPA_PortDescriptor *port_descriptors;
|
||||
LADSPA_PortRangeHint *port_range_hints;
|
||||
|
||||
eqDescriptor =
|
||||
(LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor));
|
||||
|
||||
if (eqDescriptor) {
|
||||
eqDescriptor->UniqueID = ID_MONO;
|
||||
eqDescriptor->Label = "tap_equalizer";
|
||||
eqDescriptor->Properties = 0;
|
||||
eqDescriptor->Name = "TAP Equalizer";
|
||||
eqDescriptor->Maker = "Tom Szilagyi";
|
||||
eqDescriptor->Copyright = "GPL";
|
||||
eqDescriptor->PortCount = PORTCOUNT_MONO;
|
||||
|
||||
port_descriptors =
|
||||
(LADSPA_PortDescriptor *)calloc(PORTCOUNT_MONO,
|
||||
sizeof(LADSPA_PortDescriptor));
|
||||
eqDescriptor->PortDescriptors =
|
||||
(const LADSPA_PortDescriptor *)port_descriptors;
|
||||
|
||||
port_range_hints =
|
||||
(LADSPA_PortRangeHint *)calloc(PORTCOUNT_MONO,
|
||||
sizeof(LADSPA_PortRangeHint));
|
||||
eqDescriptor->PortRangeHints =
|
||||
(const LADSPA_PortRangeHint *)port_range_hints;
|
||||
|
||||
port_names = (char **)calloc(PORTCOUNT_MONO, sizeof(char*));
|
||||
eqDescriptor->PortNames =
|
||||
(const char **)port_names;
|
||||
|
||||
|
||||
|
||||
/* Parameters for CH0 freq [Hz] */
|
||||
port_descriptors[EQ_CH0F] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_names[EQ_CH0F] =
|
||||
"Band 1 Freq [Hz]";
|
||||
port_range_hints[EQ_CH0F].HintDescriptor =
|
||||
LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_LOW;
|
||||
port_range_hints[EQ_CH0F].LowerBound = 40;
|
||||
port_range_hints[EQ_CH0F].UpperBound = 280;
|
||||
/* Parameters for CH0 gain [dB] */
|
||||
port_descriptors[EQ_CH0G] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_names[EQ_CH0G] =
|
||||
"Band 1 Gain [dB]";
|
||||
port_range_hints[EQ_CH0G].HintDescriptor =
|
||||
LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0;
|
||||
port_range_hints[EQ_CH0G].LowerBound = -50;
|
||||
port_range_hints[EQ_CH0G].UpperBound = +20;
|
||||
|
||||
|
||||
|
||||
|
||||
/* Parameters for CH1 freq [Hz] */
|
||||
port_descriptors[EQ_CH1F] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_names[EQ_CH1F] =
|
||||
"Band 2 Freq [Hz]";
|
||||
port_range_hints[EQ_CH1F].HintDescriptor =
|
||||
LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_LOW;
|
||||
port_range_hints[EQ_CH1F].LowerBound = 100;
|
||||
port_range_hints[EQ_CH1F].UpperBound = 500;
|
||||
/* Parameters for CH1 gain [dB] */
|
||||
port_descriptors[EQ_CH1G] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_names[EQ_CH1G] =
|
||||
"Band 2 Gain [dB]";
|
||||
port_range_hints[EQ_CH1G].HintDescriptor =
|
||||
LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0;
|
||||
port_range_hints[EQ_CH1G].LowerBound = -50;
|
||||
port_range_hints[EQ_CH1G].UpperBound = +20;
|
||||
|
||||
|
||||
|
||||
|
||||
/* Parameters for CH2 freq [Hz] */
|
||||
port_descriptors[EQ_CH2F] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_names[EQ_CH2F] =
|
||||
"Band 3 Freq [Hz]";
|
||||
port_range_hints[EQ_CH2F].HintDescriptor =
|
||||
LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_LOW;
|
||||
port_range_hints[EQ_CH2F].LowerBound = 200;
|
||||
port_range_hints[EQ_CH2F].UpperBound = 1000;
|
||||
/* Parameters for CH2 gain [dB] */
|
||||
port_descriptors[EQ_CH2G] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_names[EQ_CH2G] =
|
||||
"Band 3 Gain [dB]";
|
||||
port_range_hints[EQ_CH2G].HintDescriptor =
|
||||
LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0;
|
||||
port_range_hints[EQ_CH2G].LowerBound = -50;
|
||||
port_range_hints[EQ_CH2G].UpperBound = +20;
|
||||
|
||||
|
||||
|
||||
|
||||
/* Parameters for CH3 freq [Hz] */
|
||||
port_descriptors[EQ_CH3F] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_names[EQ_CH3F] =
|
||||
"Band 4 Freq [Hz]";
|
||||
port_range_hints[EQ_CH3F].HintDescriptor =
|
||||
LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_LOW;
|
||||
port_range_hints[EQ_CH3F].LowerBound = 400;
|
||||
port_range_hints[EQ_CH3F].UpperBound = 2800;
|
||||
/* Parameters for CH3 gain [dB] */
|
||||
port_descriptors[EQ_CH3G] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_names[EQ_CH3G] =
|
||||
"Band 4 Gain [dB]";
|
||||
port_range_hints[EQ_CH3G].HintDescriptor =
|
||||
LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0;
|
||||
port_range_hints[EQ_CH3G].LowerBound = -50;
|
||||
port_range_hints[EQ_CH3G].UpperBound = +20;
|
||||
|
||||
|
||||
|
||||
|
||||
/* Parameters for CH4 freq [Hz] */
|
||||
port_descriptors[EQ_CH4F] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_names[EQ_CH4F] =
|
||||
"Band 5 Freq [Hz]";
|
||||
port_range_hints[EQ_CH4F].HintDescriptor =
|
||||
LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_MIDDLE;
|
||||
port_range_hints[EQ_CH4F].LowerBound = 1000;
|
||||
port_range_hints[EQ_CH4F].UpperBound = 5000;
|
||||
/* Parameters for CH4 gain [dB] */
|
||||
port_descriptors[EQ_CH4G] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_names[EQ_CH4G] =
|
||||
"Band 5 Gain [dB]";
|
||||
port_range_hints[EQ_CH4G].HintDescriptor =
|
||||
LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0;
|
||||
port_range_hints[EQ_CH4G].LowerBound = -50;
|
||||
port_range_hints[EQ_CH4G].UpperBound = +20;
|
||||
|
||||
|
||||
|
||||
|
||||
/* Parameters for CH5 freq [Hz] */
|
||||
port_descriptors[EQ_CH5F] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_names[EQ_CH5F] =
|
||||
"Band 6 Freq [Hz]";
|
||||
port_range_hints[EQ_CH5F].HintDescriptor =
|
||||
LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_MIDDLE;
|
||||
port_range_hints[EQ_CH5F].LowerBound = 3000;
|
||||
port_range_hints[EQ_CH5F].UpperBound = 9000;
|
||||
/* Parameters for CH5 gain [dB] */
|
||||
port_descriptors[EQ_CH5G] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_names[EQ_CH5G] =
|
||||
"Band 6 Gain [dB]";
|
||||
port_range_hints[EQ_CH5G].HintDescriptor =
|
||||
LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0;
|
||||
port_range_hints[EQ_CH5G].LowerBound = -50;
|
||||
port_range_hints[EQ_CH5G].UpperBound = +20;
|
||||
|
||||
|
||||
|
||||
|
||||
/* Parameters for CH6 freq [Hz] */
|
||||
port_descriptors[EQ_CH6F] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_names[EQ_CH6F] =
|
||||
"Band 7 Freq [Hz]";
|
||||
port_range_hints[EQ_CH6F].HintDescriptor =
|
||||
LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_MIDDLE;
|
||||
port_range_hints[EQ_CH6F].LowerBound = 6000;
|
||||
port_range_hints[EQ_CH6F].UpperBound = 18000;
|
||||
/* Parameters for CH6 gain [dB] */
|
||||
port_descriptors[EQ_CH6G] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_names[EQ_CH6G] =
|
||||
"Band 7 Gain [dB]";
|
||||
port_range_hints[EQ_CH6G].HintDescriptor =
|
||||
LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0;
|
||||
port_range_hints[EQ_CH6G].LowerBound = -50;
|
||||
port_range_hints[EQ_CH6G].UpperBound = +20;
|
||||
|
||||
|
||||
|
||||
|
||||
/* Parameters for CH7 freq [Hz] */
|
||||
port_descriptors[EQ_CH7F] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_names[EQ_CH7F] =
|
||||
"Band 8 Freq [Hz]";
|
||||
port_range_hints[EQ_CH7F].HintDescriptor =
|
||||
LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_MIDDLE;
|
||||
port_range_hints[EQ_CH7F].LowerBound = 10000;
|
||||
port_range_hints[EQ_CH7F].UpperBound = 20000;
|
||||
/* Parameters for CH7 gain [dB] */
|
||||
port_descriptors[EQ_CH7G] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_names[EQ_CH7G] =
|
||||
"Band 8 Gain [dB]";
|
||||
port_range_hints[EQ_CH7G].HintDescriptor =
|
||||
LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0;
|
||||
port_range_hints[EQ_CH7G].LowerBound = -50;
|
||||
port_range_hints[EQ_CH7G].UpperBound = +20;
|
||||
|
||||
|
||||
|
||||
|
||||
/* Parameters for Input */
|
||||
port_descriptors[EQ_INPUT] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
|
||||
port_names[EQ_INPUT] =
|
||||
"Input";
|
||||
port_range_hints[EQ_INPUT].HintDescriptor = 0;
|
||||
|
||||
/* Parameters for Output */
|
||||
port_descriptors[EQ_OUTPUT] =
|
||||
LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
|
||||
port_names[EQ_OUTPUT] =
|
||||
"Output";
|
||||
port_range_hints[EQ_OUTPUT].HintDescriptor = 0;
|
||||
|
||||
eqDescriptor->activate = activate_eq;
|
||||
eqDescriptor->cleanup = cleanup_eq;
|
||||
eqDescriptor->connect_port = connectPort_eq;
|
||||
eqDescriptor->deactivate = NULL;
|
||||
eqDescriptor->instantiate = instantiate_eq;
|
||||
eqDescriptor->run = run_eq;
|
||||
eqDescriptor->run_adding = run_adding_eq;
|
||||
eqDescriptor->set_run_adding_gain = set_run_adding_gain;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_fini() {
|
||||
|
||||
if (eqDescriptor) {
|
||||
free((LADSPA_PortDescriptor *)eqDescriptor->PortDescriptors);
|
||||
free((char **)eqDescriptor->PortNames);
|
||||
free((LADSPA_PortRangeHint *)eqDescriptor->PortRangeHints);
|
||||
free(eqDescriptor);
|
||||
}
|
||||
|
||||
}
|
||||
933
plugins/ladspa_effect/tap/tap_eqbw.c
Normal file
933
plugins/ladspa_effect/tap/tap_eqbw.c
Normal file
@@ -0,0 +1,933 @@
|
||||
/* -*- linux-c -*-
|
||||
Copyright (C) 2004 Tom Szilagyi
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: tap_eqbw.c,v 1.4 2004/04/18 19:56:56 tszilagyi Exp $
|
||||
*/
|
||||
|
||||
|
||||
/* This plugin is identical to TAP Equalizer (2141), but it has
|
||||
* separate user controls for setting the bandwidth of every filter.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "ladspa.h"
|
||||
#include "tap_utils.h"
|
||||
|
||||
/* The Unique ID of the plugin */
|
||||
#define ID_MONO 2151
|
||||
|
||||
|
||||
/* Default bandwidth of EQ filters in octaves */
|
||||
#define BWIDTH 1.0f
|
||||
|
||||
|
||||
/* Port numbers */
|
||||
|
||||
#define EQ_CH0G 0
|
||||
#define EQ_CH1G 1
|
||||
#define EQ_CH2G 2
|
||||
#define EQ_CH3G 3
|
||||
#define EQ_CH4G 4
|
||||
#define EQ_CH5G 5
|
||||
#define EQ_CH6G 6
|
||||
#define EQ_CH7G 7
|
||||
|
||||
#define EQ_CH0F 8
|
||||
#define EQ_CH1F 9
|
||||
#define EQ_CH2F 10
|
||||
#define EQ_CH3F 11
|
||||
#define EQ_CH4F 12
|
||||
#define EQ_CH5F 13
|
||||
#define EQ_CH6F 14
|
||||
#define EQ_CH7F 15
|
||||
|
||||
#define EQ_CH0B 16
|
||||
#define EQ_CH1B 17
|
||||
#define EQ_CH2B 18
|
||||
#define EQ_CH3B 19
|
||||
#define EQ_CH4B 20
|
||||
#define EQ_CH5B 21
|
||||
#define EQ_CH6B 22
|
||||
#define EQ_CH7B 23
|
||||
|
||||
#define EQ_INPUT 24
|
||||
#define EQ_OUTPUT 25
|
||||
|
||||
|
||||
/* Total number of ports */
|
||||
#define PORTCOUNT_MONO 26
|
||||
|
||||
|
||||
static LADSPA_Descriptor *eqDescriptor = NULL;
|
||||
|
||||
typedef struct {
|
||||
LADSPA_Data *ch0f;
|
||||
LADSPA_Data *ch0g;
|
||||
LADSPA_Data *ch0b;
|
||||
LADSPA_Data *ch1f;
|
||||
LADSPA_Data *ch1g;
|
||||
LADSPA_Data *ch1b;
|
||||
LADSPA_Data *ch2f;
|
||||
LADSPA_Data *ch2g;
|
||||
LADSPA_Data *ch2b;
|
||||
LADSPA_Data *ch3f;
|
||||
LADSPA_Data *ch3g;
|
||||
LADSPA_Data *ch3b;
|
||||
LADSPA_Data *ch4f;
|
||||
LADSPA_Data *ch4g;
|
||||
LADSPA_Data *ch4b;
|
||||
LADSPA_Data *ch5f;
|
||||
LADSPA_Data *ch5g;
|
||||
LADSPA_Data *ch5b;
|
||||
LADSPA_Data *ch6f;
|
||||
LADSPA_Data *ch6g;
|
||||
LADSPA_Data *ch6b;
|
||||
LADSPA_Data *ch7f;
|
||||
LADSPA_Data *ch7g;
|
||||
LADSPA_Data *ch7b;
|
||||
LADSPA_Data *input;
|
||||
LADSPA_Data *output;
|
||||
biquad * filters;
|
||||
float fs;
|
||||
LADSPA_Data old_ch0f;
|
||||
LADSPA_Data old_ch0g;
|
||||
LADSPA_Data old_ch0b;
|
||||
LADSPA_Data old_ch1f;
|
||||
LADSPA_Data old_ch1g;
|
||||
LADSPA_Data old_ch1b;
|
||||
LADSPA_Data old_ch2f;
|
||||
LADSPA_Data old_ch2g;
|
||||
LADSPA_Data old_ch2b;
|
||||
LADSPA_Data old_ch3f;
|
||||
LADSPA_Data old_ch3g;
|
||||
LADSPA_Data old_ch3b;
|
||||
LADSPA_Data old_ch4f;
|
||||
LADSPA_Data old_ch4g;
|
||||
LADSPA_Data old_ch4b;
|
||||
LADSPA_Data old_ch5f;
|
||||
LADSPA_Data old_ch5g;
|
||||
LADSPA_Data old_ch5b;
|
||||
LADSPA_Data old_ch6f;
|
||||
LADSPA_Data old_ch6g;
|
||||
LADSPA_Data old_ch6b;
|
||||
LADSPA_Data old_ch7f;
|
||||
LADSPA_Data old_ch7g;
|
||||
LADSPA_Data old_ch7b;
|
||||
|
||||
LADSPA_Data run_adding_gain;
|
||||
} eq;
|
||||
|
||||
const
|
||||
LADSPA_Descriptor *
|
||||
ladspa_descriptor(unsigned long index) {
|
||||
|
||||
switch (index) {
|
||||
case 0:
|
||||
return eqDescriptor;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
activate_eq(LADSPA_Handle instance) {
|
||||
|
||||
eq *ptr = (eq *)instance;
|
||||
biquad *filters = ptr->filters;
|
||||
|
||||
biquad_init(&filters[0]);
|
||||
biquad_init(&filters[1]);
|
||||
biquad_init(&filters[2]);
|
||||
biquad_init(&filters[3]);
|
||||
biquad_init(&filters[4]);
|
||||
biquad_init(&filters[5]);
|
||||
biquad_init(&filters[6]);
|
||||
biquad_init(&filters[7]);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void
|
||||
cleanup_eq(LADSPA_Handle instance) {
|
||||
|
||||
free(instance);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void
|
||||
connectPort_eq(LADSPA_Handle instance, unsigned long port, LADSPA_Data *data) {
|
||||
|
||||
eq *plugin;
|
||||
|
||||
plugin = (eq *)instance;
|
||||
switch (port) {
|
||||
case EQ_CH0F:
|
||||
plugin->ch0f = data;
|
||||
break;
|
||||
case EQ_CH0G:
|
||||
plugin->ch0g = data;
|
||||
break;
|
||||
case EQ_CH0B:
|
||||
plugin->ch0b = data;
|
||||
break;
|
||||
case EQ_CH1F:
|
||||
plugin->ch1f = data;
|
||||
break;
|
||||
case EQ_CH1G:
|
||||
plugin->ch1g = data;
|
||||
break;
|
||||
case EQ_CH1B:
|
||||
plugin->ch1b = data;
|
||||
break;
|
||||
case EQ_CH2F:
|
||||
plugin->ch2f = data;
|
||||
break;
|
||||
case EQ_CH2G:
|
||||
plugin->ch2g = data;
|
||||
break;
|
||||
case EQ_CH2B:
|
||||
plugin->ch2b = data;
|
||||
break;
|
||||
case EQ_CH3F:
|
||||
plugin->ch3f = data;
|
||||
break;
|
||||
case EQ_CH3G:
|
||||
plugin->ch3g = data;
|
||||
break;
|
||||
case EQ_CH3B:
|
||||
plugin->ch3b = data;
|
||||
break;
|
||||
case EQ_CH4F:
|
||||
plugin->ch4f = data;
|
||||
break;
|
||||
case EQ_CH4G:
|
||||
plugin->ch4g = data;
|
||||
break;
|
||||
case EQ_CH4B:
|
||||
plugin->ch4b = data;
|
||||
break;
|
||||
case EQ_CH5F:
|
||||
plugin->ch5f = data;
|
||||
break;
|
||||
case EQ_CH5G:
|
||||
plugin->ch5g = data;
|
||||
break;
|
||||
case EQ_CH5B:
|
||||
plugin->ch5b = data;
|
||||
break;
|
||||
case EQ_CH6F:
|
||||
plugin->ch6f = data;
|
||||
break;
|
||||
case EQ_CH6G:
|
||||
plugin->ch6g = data;
|
||||
break;
|
||||
case EQ_CH6B:
|
||||
plugin->ch6b = data;
|
||||
break;
|
||||
case EQ_CH7F:
|
||||
plugin->ch7f = data;
|
||||
break;
|
||||
case EQ_CH7G:
|
||||
plugin->ch7g = data;
|
||||
break;
|
||||
case EQ_CH7B:
|
||||
plugin->ch7b = data;
|
||||
break;
|
||||
case EQ_INPUT:
|
||||
plugin->input = data;
|
||||
break;
|
||||
case EQ_OUTPUT:
|
||||
plugin->output = data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
LADSPA_Handle
|
||||
instantiate_eq(const LADSPA_Descriptor *descriptor, unsigned long s_rate) {
|
||||
|
||||
eq *ptr = (eq *)malloc(sizeof(eq));
|
||||
biquad *filters = NULL;
|
||||
float fs;
|
||||
|
||||
fs = s_rate;
|
||||
|
||||
filters = calloc(8, sizeof(biquad));
|
||||
|
||||
ptr->filters = filters;
|
||||
ptr->fs = fs;
|
||||
ptr->run_adding_gain = 1.0f;
|
||||
|
||||
eq_set_params(&filters[0], 100.0f, 0.0f, BWIDTH, fs);
|
||||
eq_set_params(&filters[1], 200.0f, 0.0f, BWIDTH, fs);
|
||||
eq_set_params(&filters[2], 400.0f, 0.0f, BWIDTH, fs);
|
||||
eq_set_params(&filters[3], 1000.0f, 0.0f, BWIDTH, fs);
|
||||
eq_set_params(&filters[4], 3000.0f, 0.0f, BWIDTH, fs);
|
||||
eq_set_params(&filters[5], 6000.0f, 0.0f, BWIDTH, fs);
|
||||
eq_set_params(&filters[6], 12000.0f, 0.0f, BWIDTH, fs);
|
||||
eq_set_params(&filters[7], 15000.0f, 0.0f, BWIDTH, fs);
|
||||
|
||||
return (LADSPA_Handle)ptr;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void
|
||||
run_eq(LADSPA_Handle instance, unsigned long sample_count) {
|
||||
|
||||
eq * ptr = (eq *)instance;
|
||||
|
||||
const LADSPA_Data ch0f = LIMIT(*(ptr->ch0f),40.0f,280.0f);
|
||||
const LADSPA_Data ch0g = LIMIT(*(ptr->ch0g),-50.0f,20.0f);
|
||||
const LADSPA_Data ch0b = LIMIT(*(ptr->ch0b),0.1f,5.0f);
|
||||
const LADSPA_Data ch1f = LIMIT(*(ptr->ch1f),100.0f,500.0f);
|
||||
const LADSPA_Data ch1g = LIMIT(*(ptr->ch1g),-50.0f,20.0f);
|
||||
const LADSPA_Data ch1b = LIMIT(*(ptr->ch1b),0.1f,5.0f);
|
||||
const LADSPA_Data ch2f = LIMIT(*(ptr->ch2f),200.0f,1000.0f);
|
||||
const LADSPA_Data ch2g = LIMIT(*(ptr->ch2g),-50.0f,20.0f);
|
||||
const LADSPA_Data ch2b = LIMIT(*(ptr->ch2b),0.1f,5.0f);
|
||||
const LADSPA_Data ch3f = LIMIT(*(ptr->ch3f),400.0f,2800.0f);
|
||||
const LADSPA_Data ch3g = LIMIT(*(ptr->ch3g),-50.0f,20.0f);
|
||||
const LADSPA_Data ch3b = LIMIT(*(ptr->ch3b),0.1f,5.0f);
|
||||
const LADSPA_Data ch4f = LIMIT(*(ptr->ch4f),1000.0f,5000.0f);
|
||||
const LADSPA_Data ch4g = LIMIT(*(ptr->ch4g),-50.0f,20.0f);
|
||||
const LADSPA_Data ch4b = LIMIT(*(ptr->ch4b),0.1f,5.0f);
|
||||
const LADSPA_Data ch5f = LIMIT(*(ptr->ch5f),3000.0f,9000.0f);
|
||||
const LADSPA_Data ch5g = LIMIT(*(ptr->ch5g),-50.0f,20.0f);
|
||||
const LADSPA_Data ch5b = LIMIT(*(ptr->ch5b),0.1f,5.0f);
|
||||
const LADSPA_Data ch6f = LIMIT(*(ptr->ch6f),6000.0f,18000.0f);
|
||||
const LADSPA_Data ch6g = LIMIT(*(ptr->ch6g),-50.0f,20.0f);
|
||||
const LADSPA_Data ch6b = LIMIT(*(ptr->ch6b),0.1f,5.0f);
|
||||
const LADSPA_Data ch7f = LIMIT(*(ptr->ch7f),10000.0f,20000.0f);
|
||||
const LADSPA_Data ch7g = LIMIT(*(ptr->ch7g),-50.0f,20.0f);
|
||||
const LADSPA_Data ch7b = LIMIT(*(ptr->ch7b),0.1f,5.0f);
|
||||
|
||||
const LADSPA_Data * input = ptr->input;
|
||||
LADSPA_Data * output = ptr->output;
|
||||
|
||||
biquad * filters = ptr->filters;
|
||||
float fs = ptr->fs;
|
||||
|
||||
unsigned long pos;
|
||||
float samp;
|
||||
|
||||
|
||||
if ((ch0f != ptr->old_ch0f) ||
|
||||
(ch0g != ptr->old_ch0g) ||
|
||||
(ch0b != ptr->old_ch0b)) {
|
||||
ptr->old_ch0f = ch0f;
|
||||
ptr->old_ch0g = ch0g;
|
||||
ptr->old_ch0b = ch0b;
|
||||
eq_set_params(&filters[0], ch0f, ch0g, ch0b, fs);
|
||||
}
|
||||
if ((ch1f != ptr->old_ch1f) ||
|
||||
(ch1g != ptr->old_ch1g) ||
|
||||
(ch1b != ptr->old_ch1b)) {
|
||||
ptr->old_ch1f = ch1f;
|
||||
ptr->old_ch1g = ch1g;
|
||||
ptr->old_ch1b = ch1b;
|
||||
eq_set_params(&filters[1], ch1f, ch1g, ch1b, fs);
|
||||
}
|
||||
if ((ch2f != ptr->old_ch2f) ||
|
||||
(ch2g != ptr->old_ch2g) ||
|
||||
(ch2b != ptr->old_ch2b)) {
|
||||
ptr->old_ch2f = ch2f;
|
||||
ptr->old_ch2g = ch2g;
|
||||
ptr->old_ch2b = ch2b;
|
||||
eq_set_params(&filters[2], ch2f, ch2g, ch2b, fs);
|
||||
}
|
||||
if ((ch3f != ptr->old_ch3f) ||
|
||||
(ch3g != ptr->old_ch3g) ||
|
||||
(ch3b != ptr->old_ch3b)) {
|
||||
ptr->old_ch3f = ch3f;
|
||||
ptr->old_ch3g = ch3g;
|
||||
ptr->old_ch3b = ch3b;
|
||||
eq_set_params(&filters[3], ch3f, ch3g, ch3b, fs);
|
||||
}
|
||||
if ((ch4f != ptr->old_ch4f) ||
|
||||
(ch4g != ptr->old_ch4g) ||
|
||||
(ch4b != ptr->old_ch4b)) {
|
||||
ptr->old_ch4f = ch4f;
|
||||
ptr->old_ch4g = ch4g;
|
||||
ptr->old_ch4b = ch4b;
|
||||
eq_set_params(&filters[4], ch4f, ch4g, ch4b, fs);
|
||||
}
|
||||
if ((ch5f != ptr->old_ch5f) ||
|
||||
(ch5g != ptr->old_ch5g) ||
|
||||
(ch5b != ptr->old_ch5b)) {
|
||||
ptr->old_ch5f = ch5f;
|
||||
ptr->old_ch5g = ch5g;
|
||||
ptr->old_ch5b = ch5b;
|
||||
eq_set_params(&filters[5], ch5f, ch5g, ch5b, fs);
|
||||
}
|
||||
if ((ch6f != ptr->old_ch6f) ||
|
||||
(ch6g != ptr->old_ch6g) ||
|
||||
(ch6b != ptr->old_ch6b)) {
|
||||
ptr->old_ch6f = ch6f;
|
||||
ptr->old_ch6g = ch6g;
|
||||
ptr->old_ch6b = ch6b;
|
||||
eq_set_params(&filters[6], ch6f, ch6g, ch6b, fs);
|
||||
}
|
||||
if ((ch7f != ptr->old_ch7f) ||
|
||||
(ch7g != ptr->old_ch7g) ||
|
||||
(ch7b != ptr->old_ch7b)) {
|
||||
ptr->old_ch7f = ch7f;
|
||||
ptr->old_ch7g = ch7g;
|
||||
ptr->old_ch7b = ch7b;
|
||||
eq_set_params(&filters[7], ch7f, ch7g, ch7b, fs);
|
||||
}
|
||||
|
||||
for (pos = 0; pos < sample_count; pos++) {
|
||||
samp = input[pos];
|
||||
if (ch0g != 0.0f)
|
||||
samp = biquad_run(&filters[0], samp);
|
||||
if (ch1g != 0.0f)
|
||||
samp = biquad_run(&filters[1], samp);
|
||||
if (ch2g != 0.0f)
|
||||
samp = biquad_run(&filters[2], samp);
|
||||
if (ch3g != 0.0f)
|
||||
samp = biquad_run(&filters[3], samp);
|
||||
if (ch4g != 0.0f)
|
||||
samp = biquad_run(&filters[4], samp);
|
||||
if (ch5g != 0.0f)
|
||||
samp = biquad_run(&filters[5], samp);
|
||||
if (ch6g != 0.0f)
|
||||
samp = biquad_run(&filters[6], samp);
|
||||
if (ch7g != 0.0f)
|
||||
samp = biquad_run(&filters[7], samp);
|
||||
output[pos] = samp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
set_run_adding_gain(LADSPA_Handle instance, LADSPA_Data gain) {
|
||||
|
||||
eq * ptr = (eq *)instance;
|
||||
|
||||
ptr->run_adding_gain = gain;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static
|
||||
void
|
||||
run_adding_eq(LADSPA_Handle instance, unsigned long sample_count) {
|
||||
|
||||
eq * ptr = (eq *)instance;
|
||||
|
||||
const LADSPA_Data ch0f = LIMIT(*(ptr->ch0f),40.0f,280.0f);
|
||||
const LADSPA_Data ch0g = LIMIT(*(ptr->ch0g),-50.0f,20.0f);
|
||||
const LADSPA_Data ch0b = LIMIT(*(ptr->ch0b),0.1f,5.0f);
|
||||
const LADSPA_Data ch1f = LIMIT(*(ptr->ch1f),100.0f,500.0f);
|
||||
const LADSPA_Data ch1g = LIMIT(*(ptr->ch1g),-50.0f,20.0f);
|
||||
const LADSPA_Data ch1b = LIMIT(*(ptr->ch1b),0.1f,5.0f);
|
||||
const LADSPA_Data ch2f = LIMIT(*(ptr->ch2f),200.0f,1000.0f);
|
||||
const LADSPA_Data ch2g = LIMIT(*(ptr->ch2g),-50.0f,20.0f);
|
||||
const LADSPA_Data ch2b = LIMIT(*(ptr->ch2b),0.1f,5.0f);
|
||||
const LADSPA_Data ch3f = LIMIT(*(ptr->ch3f),400.0f,2800.0f);
|
||||
const LADSPA_Data ch3g = LIMIT(*(ptr->ch3g),-50.0f,20.0f);
|
||||
const LADSPA_Data ch3b = LIMIT(*(ptr->ch3b),0.1f,5.0f);
|
||||
const LADSPA_Data ch4f = LIMIT(*(ptr->ch4f),1000.0f,5000.0f);
|
||||
const LADSPA_Data ch4g = LIMIT(*(ptr->ch4g),-50.0f,20.0f);
|
||||
const LADSPA_Data ch4b = LIMIT(*(ptr->ch4b),0.1f,5.0f);
|
||||
const LADSPA_Data ch5f = LIMIT(*(ptr->ch5f),3000.0f,9000.0f);
|
||||
const LADSPA_Data ch5g = LIMIT(*(ptr->ch5g),-50.0f,20.0f);
|
||||
const LADSPA_Data ch5b = LIMIT(*(ptr->ch5b),0.1f,5.0f);
|
||||
const LADSPA_Data ch6f = LIMIT(*(ptr->ch6f),6000.0f,18000.0f);
|
||||
const LADSPA_Data ch6g = LIMIT(*(ptr->ch6g),-50.0f,20.0f);
|
||||
const LADSPA_Data ch6b = LIMIT(*(ptr->ch6b),0.1f,5.0f);
|
||||
const LADSPA_Data ch7f = LIMIT(*(ptr->ch7f),10000.0f,20000.0f);
|
||||
const LADSPA_Data ch7g = LIMIT(*(ptr->ch7g),-50.0f,20.0f);
|
||||
const LADSPA_Data ch7b = LIMIT(*(ptr->ch7b),0.1f,5.0f);
|
||||
|
||||
const LADSPA_Data * input = ptr->input;
|
||||
LADSPA_Data * output = ptr->output;
|
||||
|
||||
biquad * filters = ptr->filters;
|
||||
float fs = ptr->fs;
|
||||
|
||||
unsigned long pos;
|
||||
float samp;
|
||||
|
||||
|
||||
if ((ch0f != ptr->old_ch0f) ||
|
||||
(ch0g != ptr->old_ch0g) ||
|
||||
(ch0b != ptr->old_ch0b)) {
|
||||
ptr->old_ch0f = ch0f;
|
||||
ptr->old_ch0g = ch0g;
|
||||
ptr->old_ch0b = ch0b;
|
||||
eq_set_params(&filters[0], ch0f, ch0g, ch0b, fs);
|
||||
}
|
||||
if ((ch1f != ptr->old_ch1f) ||
|
||||
(ch1g != ptr->old_ch1g) ||
|
||||
(ch1b != ptr->old_ch1b)) {
|
||||
ptr->old_ch1f = ch1f;
|
||||
ptr->old_ch1g = ch1g;
|
||||
ptr->old_ch1b = ch1b;
|
||||
eq_set_params(&filters[1], ch1f, ch1g, ch1b, fs);
|
||||
}
|
||||
if ((ch2f != ptr->old_ch2f) ||
|
||||
(ch2g != ptr->old_ch2g) ||
|
||||
(ch2b != ptr->old_ch2b)) {
|
||||
ptr->old_ch2f = ch2f;
|
||||
ptr->old_ch2g = ch2g;
|
||||
ptr->old_ch2b = ch2b;
|
||||
eq_set_params(&filters[2], ch2f, ch2g, ch2b, fs);
|
||||
}
|
||||
if ((ch3f != ptr->old_ch3f) ||
|
||||
(ch3g != ptr->old_ch3g) ||
|
||||
(ch3b != ptr->old_ch3b)) {
|
||||
ptr->old_ch3f = ch3f;
|
||||
ptr->old_ch3g = ch3g;
|
||||
ptr->old_ch3b = ch3b;
|
||||
eq_set_params(&filters[3], ch3f, ch3g, ch3b, fs);
|
||||
}
|
||||
if ((ch4f != ptr->old_ch4f) ||
|
||||
(ch4g != ptr->old_ch4g) ||
|
||||
(ch4b != ptr->old_ch4b)) {
|
||||
ptr->old_ch4f = ch4f;
|
||||
ptr->old_ch4g = ch4g;
|
||||
ptr->old_ch4b = ch4b;
|
||||
eq_set_params(&filters[4], ch4f, ch4g, ch4b, fs);
|
||||
}
|
||||
if ((ch5f != ptr->old_ch5f) ||
|
||||
(ch5g != ptr->old_ch5g) ||
|
||||
(ch5b != ptr->old_ch5b)) {
|
||||
ptr->old_ch5f = ch5f;
|
||||
ptr->old_ch5g = ch5g;
|
||||
ptr->old_ch5b = ch5b;
|
||||
eq_set_params(&filters[5], ch5f, ch5g, ch5b, fs);
|
||||
}
|
||||
if ((ch6f != ptr->old_ch6f) ||
|
||||
(ch6g != ptr->old_ch6g) ||
|
||||
(ch6b != ptr->old_ch6b)) {
|
||||
ptr->old_ch6f = ch6f;
|
||||
ptr->old_ch6g = ch6g;
|
||||
ptr->old_ch6b = ch6b;
|
||||
eq_set_params(&filters[6], ch6f, ch6g, ch6b, fs);
|
||||
}
|
||||
if ((ch7f != ptr->old_ch7f) ||
|
||||
(ch7g != ptr->old_ch7g) ||
|
||||
(ch7b != ptr->old_ch7b)) {
|
||||
ptr->old_ch7f = ch7f;
|
||||
ptr->old_ch7g = ch7g;
|
||||
ptr->old_ch7b = ch7b;
|
||||
eq_set_params(&filters[7], ch7f, ch7g, ch7b, fs);
|
||||
}
|
||||
|
||||
for (pos = 0; pos < sample_count; pos++) {
|
||||
samp = input[pos];
|
||||
if (ch0g != 0.0f)
|
||||
samp = biquad_run(&filters[0], samp);
|
||||
if (ch1g != 0.0f)
|
||||
samp = biquad_run(&filters[1], samp);
|
||||
if (ch2g != 0.0f)
|
||||
samp = biquad_run(&filters[2], samp);
|
||||
if (ch3g != 0.0f)
|
||||
samp = biquad_run(&filters[3], samp);
|
||||
if (ch4g != 0.0f)
|
||||
samp = biquad_run(&filters[4], samp);
|
||||
if (ch5g != 0.0f)
|
||||
samp = biquad_run(&filters[5], samp);
|
||||
if (ch6g != 0.0f)
|
||||
samp = biquad_run(&filters[6], samp);
|
||||
if (ch7g != 0.0f)
|
||||
samp = biquad_run(&filters[7], samp);
|
||||
output[pos] += ptr->run_adding_gain * samp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void
|
||||
_init() {
|
||||
|
||||
char **port_names;
|
||||
LADSPA_PortDescriptor *port_descriptors;
|
||||
LADSPA_PortRangeHint *port_range_hints;
|
||||
|
||||
eqDescriptor =
|
||||
(LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor));
|
||||
|
||||
if (eqDescriptor) {
|
||||
eqDescriptor->UniqueID = ID_MONO;
|
||||
eqDescriptor->Label = "tap_equalizer_bw";
|
||||
eqDescriptor->Properties = 0;
|
||||
eqDescriptor->Name = "TAP Equalizer/BW";
|
||||
eqDescriptor->Maker = "Tom Szilagyi";
|
||||
eqDescriptor->Copyright = "GPL";
|
||||
eqDescriptor->PortCount = PORTCOUNT_MONO;
|
||||
|
||||
port_descriptors =
|
||||
(LADSPA_PortDescriptor *)calloc(PORTCOUNT_MONO,
|
||||
sizeof(LADSPA_PortDescriptor));
|
||||
eqDescriptor->PortDescriptors =
|
||||
(const LADSPA_PortDescriptor *)port_descriptors;
|
||||
|
||||
port_range_hints =
|
||||
(LADSPA_PortRangeHint *)calloc(PORTCOUNT_MONO,
|
||||
sizeof(LADSPA_PortRangeHint));
|
||||
eqDescriptor->PortRangeHints =
|
||||
(const LADSPA_PortRangeHint *)port_range_hints;
|
||||
|
||||
port_names = (char **)calloc(PORTCOUNT_MONO, sizeof(char*));
|
||||
eqDescriptor->PortNames =
|
||||
(const char **)port_names;
|
||||
|
||||
|
||||
|
||||
/* Parameters for CH0 freq [Hz] */
|
||||
port_descriptors[EQ_CH0F] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_names[EQ_CH0F] =
|
||||
"Band 1 Freq [Hz]";
|
||||
port_range_hints[EQ_CH0F].HintDescriptor =
|
||||
LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_LOW;
|
||||
port_range_hints[EQ_CH0F].LowerBound = 40;
|
||||
port_range_hints[EQ_CH0F].UpperBound = 280;
|
||||
/* Parameters for CH0 gain [dB] */
|
||||
port_descriptors[EQ_CH0G] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_names[EQ_CH0G] =
|
||||
"Band 1 Gain [dB]";
|
||||
port_range_hints[EQ_CH0G].HintDescriptor =
|
||||
LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0;
|
||||
port_range_hints[EQ_CH0G].LowerBound = -50;
|
||||
port_range_hints[EQ_CH0G].UpperBound = +20;
|
||||
/* Parameters for CH0 bandwidth [octaves] */
|
||||
port_descriptors[EQ_CH0B] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_names[EQ_CH0B] =
|
||||
"Band 1 Bandwidth [octaves]";
|
||||
port_range_hints[EQ_CH0B].HintDescriptor =
|
||||
LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_1;
|
||||
port_range_hints[EQ_CH0B].LowerBound = 0.1f;
|
||||
port_range_hints[EQ_CH0B].UpperBound = 5.0f;
|
||||
|
||||
|
||||
|
||||
|
||||
/* Parameters for CH1 freq [Hz] */
|
||||
port_descriptors[EQ_CH1F] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_names[EQ_CH1F] =
|
||||
"Band 2 Freq [Hz]";
|
||||
port_range_hints[EQ_CH1F].HintDescriptor =
|
||||
LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_LOW;
|
||||
port_range_hints[EQ_CH1F].LowerBound = 100;
|
||||
port_range_hints[EQ_CH1F].UpperBound = 500;
|
||||
/* Parameters for CH1 gain [dB] */
|
||||
port_descriptors[EQ_CH1G] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_names[EQ_CH1G] =
|
||||
"Band 2 Gain [dB]";
|
||||
port_range_hints[EQ_CH1G].HintDescriptor =
|
||||
LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0;
|
||||
port_range_hints[EQ_CH1G].LowerBound = -50;
|
||||
port_range_hints[EQ_CH1G].UpperBound = +20;
|
||||
/* Parameters for CH1 bandwidth [octaves] */
|
||||
port_descriptors[EQ_CH1B] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_names[EQ_CH1B] =
|
||||
"Band 2 Bandwidth [octaves]";
|
||||
port_range_hints[EQ_CH1B].HintDescriptor =
|
||||
LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_1;
|
||||
port_range_hints[EQ_CH1B].LowerBound = 0.1f;
|
||||
port_range_hints[EQ_CH1B].UpperBound = 5.0f;
|
||||
|
||||
|
||||
|
||||
|
||||
/* Parameters for CH2 freq [Hz] */
|
||||
port_descriptors[EQ_CH2F] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_names[EQ_CH2F] =
|
||||
"Band 3 Freq [Hz]";
|
||||
port_range_hints[EQ_CH2F].HintDescriptor =
|
||||
LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_LOW;
|
||||
port_range_hints[EQ_CH2F].LowerBound = 200;
|
||||
port_range_hints[EQ_CH2F].UpperBound = 1000;
|
||||
/* Parameters for CH2 gain [dB] */
|
||||
port_descriptors[EQ_CH2G] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_names[EQ_CH2G] =
|
||||
"Band 3 Gain [dB]";
|
||||
port_range_hints[EQ_CH2G].HintDescriptor =
|
||||
LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0;
|
||||
port_range_hints[EQ_CH2G].LowerBound = -50;
|
||||
port_range_hints[EQ_CH2G].UpperBound = +20;
|
||||
/* Parameters for CH2 bandwidth [octaves] */
|
||||
port_descriptors[EQ_CH2B] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_names[EQ_CH2B] =
|
||||
"Band 3 Bandwidth [octaves]";
|
||||
port_range_hints[EQ_CH2B].HintDescriptor =
|
||||
LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_1;
|
||||
port_range_hints[EQ_CH2B].LowerBound = 0.1f;
|
||||
port_range_hints[EQ_CH2B].UpperBound = 5.0f;
|
||||
|
||||
|
||||
|
||||
|
||||
/* Parameters for CH3 freq [Hz] */
|
||||
port_descriptors[EQ_CH3F] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_names[EQ_CH3F] =
|
||||
"Band 4 Freq [Hz]";
|
||||
port_range_hints[EQ_CH3F].HintDescriptor =
|
||||
LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_LOW;
|
||||
port_range_hints[EQ_CH3F].LowerBound = 400;
|
||||
port_range_hints[EQ_CH3F].UpperBound = 2800;
|
||||
/* Parameters for CH3 gain [dB] */
|
||||
port_descriptors[EQ_CH3G] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_names[EQ_CH3G] =
|
||||
"Band 4 Gain [dB]";
|
||||
port_range_hints[EQ_CH3G].HintDescriptor =
|
||||
LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0;
|
||||
port_range_hints[EQ_CH3G].LowerBound = -50;
|
||||
port_range_hints[EQ_CH3G].UpperBound = +20;
|
||||
/* Parameters for CH3 bandwidth [octaves] */
|
||||
port_descriptors[EQ_CH3B] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_names[EQ_CH3B] =
|
||||
"Band 4 Bandwidth [octaves]";
|
||||
port_range_hints[EQ_CH3B].HintDescriptor =
|
||||
LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_1;
|
||||
port_range_hints[EQ_CH3B].LowerBound = 0.1f;
|
||||
port_range_hints[EQ_CH3B].UpperBound = 5.0f;
|
||||
|
||||
|
||||
|
||||
|
||||
/* Parameters for CH4 freq [Hz] */
|
||||
port_descriptors[EQ_CH4F] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_names[EQ_CH4F] =
|
||||
"Band 5 Freq [Hz]";
|
||||
port_range_hints[EQ_CH4F].HintDescriptor =
|
||||
LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_MIDDLE;
|
||||
port_range_hints[EQ_CH4F].LowerBound = 1000;
|
||||
port_range_hints[EQ_CH4F].UpperBound = 5000;
|
||||
/* Parameters for CH4 gain [dB] */
|
||||
port_descriptors[EQ_CH4G] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_names[EQ_CH4G] =
|
||||
"Band 5 Gain [dB]";
|
||||
port_range_hints[EQ_CH4G].HintDescriptor =
|
||||
LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0;
|
||||
port_range_hints[EQ_CH4G].LowerBound = -50;
|
||||
port_range_hints[EQ_CH4G].UpperBound = +20;
|
||||
/* Parameters for CH4 bandwidth [octaves] */
|
||||
port_descriptors[EQ_CH4B] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_names[EQ_CH4B] =
|
||||
"Band 5 Bandwidth [octaves]";
|
||||
port_range_hints[EQ_CH4B].HintDescriptor =
|
||||
LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_1;
|
||||
port_range_hints[EQ_CH4B].LowerBound = 0.1f;
|
||||
port_range_hints[EQ_CH4B].UpperBound = 5.0f;
|
||||
|
||||
|
||||
|
||||
|
||||
/* Parameters for CH5 freq [Hz] */
|
||||
port_descriptors[EQ_CH5F] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_names[EQ_CH5F] =
|
||||
"Band 6 Freq [Hz]";
|
||||
port_range_hints[EQ_CH5F].HintDescriptor =
|
||||
LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_MIDDLE;
|
||||
port_range_hints[EQ_CH5F].LowerBound = 3000;
|
||||
port_range_hints[EQ_CH5F].UpperBound = 9000;
|
||||
/* Parameters for CH5 gain [dB] */
|
||||
port_descriptors[EQ_CH5G] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_names[EQ_CH5G] =
|
||||
"Band 6 Gain [dB]";
|
||||
port_range_hints[EQ_CH5G].HintDescriptor =
|
||||
LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0;
|
||||
port_range_hints[EQ_CH5G].LowerBound = -50;
|
||||
port_range_hints[EQ_CH5G].UpperBound = +20;
|
||||
/* Parameters for CH5 bandwidth [octaves] */
|
||||
port_descriptors[EQ_CH5B] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_names[EQ_CH5B] =
|
||||
"Band 6 Bandwidth [octaves]";
|
||||
port_range_hints[EQ_CH5B].HintDescriptor =
|
||||
LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_1;
|
||||
port_range_hints[EQ_CH5B].LowerBound = 0.1f;
|
||||
port_range_hints[EQ_CH5B].UpperBound = 5.0f;
|
||||
|
||||
|
||||
|
||||
|
||||
/* Parameters for CH6 freq [Hz] */
|
||||
port_descriptors[EQ_CH6F] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_names[EQ_CH6F] =
|
||||
"Band 7 Freq [Hz]";
|
||||
port_range_hints[EQ_CH6F].HintDescriptor =
|
||||
LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_MIDDLE;
|
||||
port_range_hints[EQ_CH6F].LowerBound = 6000;
|
||||
port_range_hints[EQ_CH6F].UpperBound = 18000;
|
||||
/* Parameters for CH6 gain [dB] */
|
||||
port_descriptors[EQ_CH6G] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_names[EQ_CH6G] =
|
||||
"Band 7 Gain [dB]";
|
||||
port_range_hints[EQ_CH6G].HintDescriptor =
|
||||
LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0;
|
||||
port_range_hints[EQ_CH6G].LowerBound = -50;
|
||||
port_range_hints[EQ_CH6G].UpperBound = +20;
|
||||
/* Parameters for CH6 bandwidth [octaves] */
|
||||
port_descriptors[EQ_CH6B] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_names[EQ_CH6B] =
|
||||
"Band 7 Bandwidth [octaves]";
|
||||
port_range_hints[EQ_CH6B].HintDescriptor =
|
||||
LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_1;
|
||||
port_range_hints[EQ_CH6B].LowerBound = 0.1f;
|
||||
port_range_hints[EQ_CH6B].UpperBound = 5.0f;
|
||||
|
||||
|
||||
|
||||
|
||||
/* Parameters for CH7 freq [Hz] */
|
||||
port_descriptors[EQ_CH7F] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_names[EQ_CH7F] =
|
||||
"Band 8 Freq [Hz]";
|
||||
port_range_hints[EQ_CH7F].HintDescriptor =
|
||||
LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_MIDDLE;
|
||||
port_range_hints[EQ_CH7F].LowerBound = 10000;
|
||||
port_range_hints[EQ_CH7F].UpperBound = 20000;
|
||||
/* Parameters for CH7 gain [dB] */
|
||||
port_descriptors[EQ_CH7G] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_names[EQ_CH7G] =
|
||||
"Band 8 Gain [dB]";
|
||||
port_range_hints[EQ_CH7G].HintDescriptor =
|
||||
LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0;
|
||||
port_range_hints[EQ_CH7G].LowerBound = -50;
|
||||
port_range_hints[EQ_CH7G].UpperBound = +20;
|
||||
/* Parameters for CH7 bandwidth [octaves] */
|
||||
port_descriptors[EQ_CH7B] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_names[EQ_CH7B] =
|
||||
"Band 8 Bandwidth [octaves]";
|
||||
port_range_hints[EQ_CH7B].HintDescriptor =
|
||||
LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_1;
|
||||
port_range_hints[EQ_CH7B].LowerBound = 0.1f;
|
||||
port_range_hints[EQ_CH7B].UpperBound = 5.0f;
|
||||
|
||||
|
||||
|
||||
|
||||
/* Parameters for Input */
|
||||
port_descriptors[EQ_INPUT] =
|
||||
LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
|
||||
port_names[EQ_INPUT] =
|
||||
"Input";
|
||||
port_range_hints[EQ_INPUT].HintDescriptor = 0;
|
||||
|
||||
/* Parameters for Output */
|
||||
port_descriptors[EQ_OUTPUT] =
|
||||
LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
|
||||
port_names[EQ_OUTPUT] =
|
||||
"Output";
|
||||
port_range_hints[EQ_OUTPUT].HintDescriptor = 0;
|
||||
|
||||
eqDescriptor->activate = activate_eq;
|
||||
eqDescriptor->cleanup = cleanup_eq;
|
||||
eqDescriptor->connect_port = connectPort_eq;
|
||||
eqDescriptor->deactivate = NULL;
|
||||
eqDescriptor->instantiate = instantiate_eq;
|
||||
eqDescriptor->run = run_eq;
|
||||
eqDescriptor->run_adding = run_adding_eq;
|
||||
eqDescriptor->set_run_adding_gain = set_run_adding_gain;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_fini() {
|
||||
|
||||
if (eqDescriptor) {
|
||||
free((LADSPA_PortDescriptor *)eqDescriptor->PortDescriptors);
|
||||
free((char **)eqDescriptor->PortNames);
|
||||
free((LADSPA_PortRangeHint *)eqDescriptor->PortRangeHints);
|
||||
free(eqDescriptor);
|
||||
}
|
||||
|
||||
}
|
||||
443
plugins/ladspa_effect/tap/tap_limiter.c
Normal file
443
plugins/ladspa_effect/tap/tap_limiter.c
Normal file
@@ -0,0 +1,443 @@
|
||||
/* -*- linux-c -*-
|
||||
Copyright (C) 2004 Tom Szilagyi
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: tap_limiter.c,v 1.5 2004/02/21 17:33:36 tszilagyi Exp $
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "ladspa.h"
|
||||
#include "tap_utils.h"
|
||||
|
||||
/* The Unique ID of the plugin: */
|
||||
|
||||
#define ID_MONO 2145
|
||||
|
||||
/* The port numbers for the plugin: */
|
||||
|
||||
#define LIMIT_VOL 0
|
||||
#define OUT_VOL 1
|
||||
#define LATENCY 2
|
||||
#define INPUT 3
|
||||
#define OUTPUT 4
|
||||
|
||||
/* Total number of ports */
|
||||
|
||||
#define PORTCOUNT_MONO 5
|
||||
|
||||
|
||||
/* Size of a ringbuffer that must be large enough to hold audio
|
||||
* between two zero-crosses in any case (or you'll hear
|
||||
* distortion). 40 Hz sound at 192kHz yields a half-period of 2400
|
||||
* samples, so this should be enough.
|
||||
*/
|
||||
#define RINGBUF_SIZE 2500
|
||||
|
||||
|
||||
/* The structure used to hold port connection information and state */
|
||||
|
||||
typedef struct {
|
||||
LADSPA_Data * limit_vol;
|
||||
LADSPA_Data * out_vol;
|
||||
LADSPA_Data * latency;
|
||||
LADSPA_Data * input;
|
||||
LADSPA_Data * output;
|
||||
|
||||
LADSPA_Data * ringbuffer;
|
||||
unsigned long buflen;
|
||||
unsigned long pos;
|
||||
unsigned long ready_num;
|
||||
|
||||
unsigned long sample_rate;
|
||||
LADSPA_Data run_adding_gain;
|
||||
} Limiter;
|
||||
|
||||
|
||||
|
||||
|
||||
/* Construct a new plugin instance. */
|
||||
LADSPA_Handle
|
||||
instantiate_Limiter(const LADSPA_Descriptor * Descriptor,
|
||||
unsigned long sample_rate) {
|
||||
|
||||
LADSPA_Handle * ptr;
|
||||
|
||||
if ((ptr = malloc(sizeof(Limiter))) != NULL) {
|
||||
((Limiter *)ptr)->sample_rate = sample_rate;
|
||||
((Limiter *)ptr)->run_adding_gain = 1.0f;
|
||||
|
||||
if ((((Limiter *)ptr)->ringbuffer =
|
||||
calloc(RINGBUF_SIZE, sizeof(LADSPA_Data))) == NULL)
|
||||
return NULL;
|
||||
|
||||
/* 80 Hz is the lowest frequency with which zero-crosses were
|
||||
* observed to occur (this corresponds to 40 Hz signal frequency).
|
||||
*/
|
||||
((Limiter *)ptr)->buflen = ((Limiter *)ptr)->sample_rate / 80;
|
||||
|
||||
((Limiter *)ptr)->pos = 0;
|
||||
((Limiter *)ptr)->ready_num = 0;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
activate_Limiter(LADSPA_Handle Instance) {
|
||||
|
||||
Limiter * ptr = (Limiter *)Instance;
|
||||
unsigned long i;
|
||||
|
||||
for (i = 0; i < RINGBUF_SIZE; i++)
|
||||
ptr->ringbuffer[i] = 0.0f;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Connect a port to a data location. */
|
||||
void
|
||||
connect_port_Limiter(LADSPA_Handle Instance,
|
||||
unsigned long Port,
|
||||
LADSPA_Data * DataLocation) {
|
||||
|
||||
Limiter * ptr = (Limiter *)Instance;
|
||||
|
||||
switch (Port) {
|
||||
case LIMIT_VOL:
|
||||
ptr->limit_vol = DataLocation;
|
||||
break;
|
||||
case OUT_VOL:
|
||||
ptr->out_vol = DataLocation;
|
||||
break;
|
||||
case LATENCY:
|
||||
ptr->latency = DataLocation;
|
||||
*(ptr->latency) = ptr->buflen; /* IS THIS LEGAL? */
|
||||
break;
|
||||
case INPUT:
|
||||
ptr->input = DataLocation;
|
||||
break;
|
||||
case OUTPUT:
|
||||
ptr->output = DataLocation;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
run_Limiter(LADSPA_Handle Instance,
|
||||
unsigned long SampleCount) {
|
||||
|
||||
Limiter * ptr = (Limiter *)Instance;
|
||||
|
||||
LADSPA_Data * input = ptr->input;
|
||||
LADSPA_Data * output = ptr->output;
|
||||
LADSPA_Data limit_vol = db2lin(LIMIT(*(ptr->limit_vol),-30.0f,20.0f));
|
||||
LADSPA_Data out_vol = db2lin(LIMIT(*(ptr->out_vol),-30.0f,20.0f));
|
||||
unsigned long sample_index;
|
||||
unsigned long sample_count = SampleCount;
|
||||
unsigned long index_offs = 0;
|
||||
unsigned long i;
|
||||
LADSPA_Data max_value = 0;
|
||||
LADSPA_Data section_gain = 0;
|
||||
unsigned long run_length;
|
||||
unsigned long total_length = 0;
|
||||
|
||||
|
||||
while (total_length < sample_count) {
|
||||
|
||||
run_length = ptr->buflen;
|
||||
if (total_length + run_length > sample_count)
|
||||
run_length = sample_count - total_length;
|
||||
|
||||
while (ptr->ready_num < run_length) {
|
||||
if (read_buffer(ptr->ringbuffer, ptr->buflen,
|
||||
ptr->pos, ptr->ready_num) >= 0.0f) {
|
||||
index_offs = 0;
|
||||
while ((read_buffer(ptr->ringbuffer, ptr->buflen, ptr->pos,
|
||||
ptr->ready_num + index_offs) >= 0.0f) &&
|
||||
(ptr->ready_num + index_offs < run_length)) {
|
||||
index_offs++;
|
||||
}
|
||||
} else {
|
||||
index_offs = 0;
|
||||
while ((read_buffer(ptr->ringbuffer, ptr->buflen, ptr->pos,
|
||||
ptr->ready_num + index_offs) <= 0.0f) &&
|
||||
(ptr->ready_num + index_offs < run_length)) {
|
||||
index_offs++;
|
||||
}
|
||||
}
|
||||
|
||||
/* search for max value in scanned halfcycle */
|
||||
max_value = 0;
|
||||
for (i = ptr->ready_num; i < ptr->ready_num + index_offs; i++) {
|
||||
if (fabs(read_buffer(ptr->ringbuffer, ptr->buflen,
|
||||
ptr->pos, i)) > max_value)
|
||||
max_value = fabs(read_buffer(ptr->ringbuffer,
|
||||
ptr->buflen, ptr->pos, i));
|
||||
}
|
||||
section_gain = limit_vol / max_value;
|
||||
if (max_value > limit_vol)
|
||||
for (i = ptr->ready_num; i < ptr->ready_num + index_offs; i++) {
|
||||
write_buffer(read_buffer(ptr->ringbuffer, ptr->buflen,
|
||||
ptr->pos, i) * section_gain,
|
||||
ptr->ringbuffer, ptr->buflen, ptr->pos, i);
|
||||
}
|
||||
ptr->ready_num += index_offs;
|
||||
}
|
||||
|
||||
/* push run_length values out of ringbuffer, feed with input */
|
||||
for (sample_index = 0; sample_index < run_length; sample_index++) {
|
||||
*(output++) = out_vol *
|
||||
push_buffer(*(input++), ptr->ringbuffer,
|
||||
ptr->buflen, &(ptr->pos));
|
||||
}
|
||||
ptr->ready_num -= run_length;
|
||||
total_length += run_length;
|
||||
}
|
||||
*(ptr->latency) = ptr->buflen;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
set_run_adding_gain_Limiter(LADSPA_Handle Instance, LADSPA_Data gain) {
|
||||
|
||||
Limiter * ptr = (Limiter *)Instance;
|
||||
|
||||
ptr->run_adding_gain = gain;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
run_adding_Limiter(LADSPA_Handle Instance,
|
||||
unsigned long SampleCount) {
|
||||
|
||||
Limiter * ptr = (Limiter *)Instance;
|
||||
|
||||
LADSPA_Data * input = ptr->input;
|
||||
LADSPA_Data * output = ptr->output;
|
||||
LADSPA_Data limit_vol = db2lin(LIMIT(*(ptr->limit_vol),-30.0f,20.0f));
|
||||
LADSPA_Data out_vol = db2lin(LIMIT(*(ptr->out_vol),-30.0f,20.0f));
|
||||
unsigned long sample_index;
|
||||
unsigned long sample_count = SampleCount;
|
||||
unsigned long index_offs = 0;
|
||||
unsigned long i;
|
||||
LADSPA_Data max_value = 0;
|
||||
LADSPA_Data section_gain = 0;
|
||||
unsigned long run_length;
|
||||
unsigned long total_length = 0;
|
||||
|
||||
|
||||
while (total_length < sample_count) {
|
||||
|
||||
run_length = ptr->buflen;
|
||||
if (total_length + run_length > sample_count)
|
||||
run_length = sample_count - total_length;
|
||||
|
||||
while (ptr->ready_num < run_length) {
|
||||
if (read_buffer(ptr->ringbuffer, ptr->buflen,
|
||||
ptr->pos, ptr->ready_num) >= 0.0f) {
|
||||
index_offs = 0;
|
||||
while ((read_buffer(ptr->ringbuffer, ptr->buflen, ptr->pos,
|
||||
ptr->ready_num + index_offs) >= 0.0f) &&
|
||||
(ptr->ready_num + index_offs < run_length)) {
|
||||
index_offs++;
|
||||
}
|
||||
} else {
|
||||
index_offs = 0;
|
||||
while ((read_buffer(ptr->ringbuffer, ptr->buflen, ptr->pos,
|
||||
ptr->ready_num + index_offs) <= 0.0f) &&
|
||||
(ptr->ready_num + index_offs < run_length)) {
|
||||
index_offs++;
|
||||
}
|
||||
}
|
||||
|
||||
/* search for max value in scanned halfcycle */
|
||||
max_value = 0;
|
||||
for (i = ptr->ready_num; i < ptr->ready_num + index_offs; i++) {
|
||||
if (fabs(read_buffer(ptr->ringbuffer, ptr->buflen,
|
||||
ptr->pos, i)) > max_value)
|
||||
max_value = fabs(read_buffer(ptr->ringbuffer,
|
||||
ptr->buflen, ptr->pos, i));
|
||||
}
|
||||
section_gain = limit_vol / max_value;
|
||||
if (max_value > limit_vol)
|
||||
for (i = ptr->ready_num; i < ptr->ready_num + index_offs; i++) {
|
||||
write_buffer(read_buffer(ptr->ringbuffer, ptr->buflen,
|
||||
ptr->pos, i) * section_gain,
|
||||
ptr->ringbuffer, ptr->buflen, ptr->pos, i);
|
||||
}
|
||||
ptr->ready_num += index_offs;
|
||||
}
|
||||
|
||||
/* push run_length values out of ringbuffer, feed with input */
|
||||
for (sample_index = 0; sample_index < run_length; sample_index++) {
|
||||
*(output++) += ptr->run_adding_gain * out_vol *
|
||||
push_buffer(*(input++), ptr->ringbuffer,
|
||||
ptr->buflen, &(ptr->pos));
|
||||
}
|
||||
ptr->ready_num -= run_length;
|
||||
total_length += run_length;
|
||||
}
|
||||
*(ptr->latency) = ptr->buflen;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Throw away a Limiter effect instance. */
|
||||
void
|
||||
cleanup_Limiter(LADSPA_Handle Instance) {
|
||||
|
||||
Limiter * ptr = (Limiter *)Instance;
|
||||
free(ptr->ringbuffer);
|
||||
free(Instance);
|
||||
}
|
||||
|
||||
|
||||
|
||||
LADSPA_Descriptor * mono_descriptor = NULL;
|
||||
|
||||
|
||||
|
||||
/* _init() is called automatically when the plugin library is first
|
||||
loaded. */
|
||||
void
|
||||
_init() {
|
||||
|
||||
char ** port_names;
|
||||
LADSPA_PortDescriptor * port_descriptors;
|
||||
LADSPA_PortRangeHint * port_range_hints;
|
||||
|
||||
if ((mono_descriptor =
|
||||
(LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor))) == NULL)
|
||||
exit(1);
|
||||
|
||||
|
||||
|
||||
mono_descriptor->UniqueID = ID_MONO;
|
||||
mono_descriptor->Label = strdup("tap_limiter");
|
||||
mono_descriptor->Properties = 0;
|
||||
mono_descriptor->Name = strdup("TAP Scaling Limiter");
|
||||
mono_descriptor->Maker = strdup("Tom Szilagyi");
|
||||
mono_descriptor->Copyright = strdup("GPL");
|
||||
mono_descriptor->PortCount = PORTCOUNT_MONO;
|
||||
|
||||
if ((port_descriptors =
|
||||
(LADSPA_PortDescriptor *)calloc(PORTCOUNT_MONO, sizeof(LADSPA_PortDescriptor))) == NULL)
|
||||
exit(1);
|
||||
|
||||
mono_descriptor->PortDescriptors = (const LADSPA_PortDescriptor *)port_descriptors;
|
||||
port_descriptors[LIMIT_VOL] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[OUT_VOL] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[LATENCY] = LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[INPUT] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
|
||||
port_descriptors[OUTPUT] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
|
||||
|
||||
if ((port_names =
|
||||
(char **)calloc(PORTCOUNT_MONO, sizeof(char *))) == NULL)
|
||||
exit(1);
|
||||
|
||||
mono_descriptor->PortNames = (const char **)port_names;
|
||||
port_names[LIMIT_VOL] = strdup("Limit Level [dB]");
|
||||
port_names[OUT_VOL] = strdup("Output Volume [dB]");
|
||||
port_names[LATENCY] = strdup("latency");
|
||||
port_names[INPUT] = strdup("Input");
|
||||
port_names[OUTPUT] = strdup("Output");
|
||||
|
||||
if ((port_range_hints =
|
||||
((LADSPA_PortRangeHint *)calloc(PORTCOUNT_MONO, sizeof(LADSPA_PortRangeHint)))) == NULL)
|
||||
exit(1);
|
||||
|
||||
mono_descriptor->PortRangeHints = (const LADSPA_PortRangeHint *)port_range_hints;
|
||||
port_range_hints[LIMIT_VOL].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[OUT_VOL].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[LATENCY].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_MAXIMUM);
|
||||
port_range_hints[LIMIT_VOL].LowerBound = -30;
|
||||
port_range_hints[LIMIT_VOL].UpperBound = +20;
|
||||
port_range_hints[OUT_VOL].LowerBound = -30;
|
||||
port_range_hints[OUT_VOL].UpperBound = +20;
|
||||
port_range_hints[LATENCY].LowerBound = 0;
|
||||
port_range_hints[LATENCY].UpperBound = RINGBUF_SIZE + 0.1f;
|
||||
port_range_hints[INPUT].HintDescriptor = 0;
|
||||
port_range_hints[OUTPUT].HintDescriptor = 0;
|
||||
mono_descriptor->instantiate = instantiate_Limiter;
|
||||
mono_descriptor->connect_port = connect_port_Limiter;
|
||||
mono_descriptor->activate = activate_Limiter;
|
||||
mono_descriptor->run = run_Limiter;
|
||||
mono_descriptor->run_adding = run_adding_Limiter;
|
||||
mono_descriptor->set_run_adding_gain = set_run_adding_gain_Limiter;
|
||||
mono_descriptor->deactivate = NULL;
|
||||
mono_descriptor->cleanup = cleanup_Limiter;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
delete_descriptor(LADSPA_Descriptor * descriptor) {
|
||||
unsigned long index;
|
||||
if (descriptor) {
|
||||
free((char *)descriptor->Label);
|
||||
free((char *)descriptor->Name);
|
||||
free((char *)descriptor->Maker);
|
||||
free((char *)descriptor->Copyright);
|
||||
free((LADSPA_PortDescriptor *)descriptor->PortDescriptors);
|
||||
for (index = 0; index < descriptor->PortCount; index++)
|
||||
free((char *)(descriptor->PortNames[index]));
|
||||
free((char **)descriptor->PortNames);
|
||||
free((LADSPA_PortRangeHint *)descriptor->PortRangeHints);
|
||||
free(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* _fini() is called automatically when the library is unloaded. */
|
||||
void
|
||||
_fini() {
|
||||
delete_descriptor(mono_descriptor);
|
||||
}
|
||||
|
||||
|
||||
/* Return a descriptor of the requested plugin type. */
|
||||
const LADSPA_Descriptor *
|
||||
ladspa_descriptor(unsigned long Index) {
|
||||
|
||||
switch (Index) {
|
||||
case 0:
|
||||
return mono_descriptor;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
345
plugins/ladspa_effect/tap/tap_pinknoise.c
Normal file
345
plugins/ladspa_effect/tap/tap_pinknoise.c
Normal file
@@ -0,0 +1,345 @@
|
||||
/* -*- linux-c -*-
|
||||
Copyright (C) 2004 Tom Szilagyi
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: tap_pinknoise.c,v 1.2 2004/08/13 18:34:31 tszilagyi Exp $
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "ladspa.h"
|
||||
#include "tap_utils.h"
|
||||
|
||||
/* The Unique ID of the plugin: */
|
||||
#define ID_MONO 2155
|
||||
|
||||
|
||||
/* The port numbers for the plugin: */
|
||||
#define HURST 0
|
||||
#define SIGNAL 1
|
||||
#define NOISE 2
|
||||
#define INPUT 3
|
||||
#define OUTPUT 4
|
||||
|
||||
|
||||
/* Total number of ports */
|
||||
#define PORTCOUNT_MONO 5
|
||||
|
||||
|
||||
#define NOISE_LEN 1024
|
||||
|
||||
|
||||
/* The structure used to hold port connection information and state */
|
||||
typedef struct {
|
||||
LADSPA_Data * hurst;
|
||||
LADSPA_Data * signal;
|
||||
LADSPA_Data * noise;
|
||||
LADSPA_Data * input;
|
||||
LADSPA_Data * output;
|
||||
|
||||
LADSPA_Data * ring;
|
||||
unsigned long buflen;
|
||||
unsigned long pos;
|
||||
|
||||
unsigned long sample_rate;
|
||||
LADSPA_Data run_adding_gain;
|
||||
} Pinknoise;
|
||||
|
||||
|
||||
|
||||
/* generate fractal pattern using Midpoint Displacement Method
|
||||
* v: buffer of floats to output fractal pattern to
|
||||
* N: length of v, MUST be integer power of 2 (ie 128, 256, ...)
|
||||
* H: Hurst constant, between 0 and 0.9999 (fractal dimension)
|
||||
*/
|
||||
void
|
||||
fractal(LADSPA_Data * v, int N, float H) {
|
||||
|
||||
int l = N;
|
||||
int k;
|
||||
float r = 2.0f * H*H + 0.3f;
|
||||
int c;
|
||||
|
||||
v[0] = 0;
|
||||
while (l > 1) {
|
||||
k = N / l;
|
||||
for (c = 0; c < k; c++) {
|
||||
v[c*l + l/2] = (v[c*l] + v[((c+1) * l) % N]) / 2.0f +
|
||||
2.0f * r * (rand() - (float)RAND_MAX/2.0f) / (float)RAND_MAX;
|
||||
v[c*l + l/2] = LIMIT(v[c*l + l/2], -1.0f, 1.0f);
|
||||
}
|
||||
l /= 2;
|
||||
r /= powf(2, H);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Construct a new plugin instance. */
|
||||
LADSPA_Handle
|
||||
instantiate_Pinknoise(const LADSPA_Descriptor * Descriptor,
|
||||
unsigned long SampleRate) {
|
||||
|
||||
LADSPA_Handle * ptr;
|
||||
|
||||
if ((ptr = malloc(sizeof(Pinknoise))) != NULL) {
|
||||
((Pinknoise *)ptr)->sample_rate = SampleRate;
|
||||
((Pinknoise *)ptr)->run_adding_gain = 1.0;
|
||||
|
||||
if ((((Pinknoise *)ptr)->ring =
|
||||
calloc(NOISE_LEN, sizeof(LADSPA_Data))) == NULL)
|
||||
return NULL;
|
||||
((Pinknoise *)ptr)->buflen = NOISE_LEN;
|
||||
((Pinknoise *)ptr)->pos = 0;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Connect a port to a data location. */
|
||||
void
|
||||
connect_port_Pinknoise(LADSPA_Handle Instance,
|
||||
unsigned long Port,
|
||||
LADSPA_Data * data) {
|
||||
|
||||
Pinknoise * ptr;
|
||||
|
||||
ptr = (Pinknoise *)Instance;
|
||||
switch (Port) {
|
||||
case HURST:
|
||||
ptr->hurst = data;
|
||||
break;
|
||||
case SIGNAL:
|
||||
ptr->signal = data;
|
||||
break;
|
||||
case NOISE:
|
||||
ptr->noise = data;
|
||||
break;
|
||||
case INPUT:
|
||||
ptr->input = data;
|
||||
break;
|
||||
case OUTPUT:
|
||||
ptr->output = data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
run_Pinknoise(LADSPA_Handle Instance,
|
||||
unsigned long SampleCount) {
|
||||
|
||||
Pinknoise * ptr = (Pinknoise *)Instance;
|
||||
|
||||
LADSPA_Data * input = ptr->input;
|
||||
LADSPA_Data * output = ptr->output;
|
||||
LADSPA_Data hurst = LIMIT(*(ptr->hurst), 0.0f, 1.0f);
|
||||
LADSPA_Data signal = db2lin(LIMIT(*(ptr->signal), -90.0f, 20.0f));
|
||||
LADSPA_Data noise = db2lin(LIMIT(*(ptr->noise), -90.0f, 20.0f));
|
||||
unsigned long sample_index;
|
||||
|
||||
for (sample_index = 0; sample_index < SampleCount; sample_index++) {
|
||||
|
||||
if (!ptr->pos)
|
||||
fractal(ptr->ring, NOISE_LEN, hurst);
|
||||
|
||||
*(output++) = signal * *(input++) +
|
||||
noise * push_buffer(0.0f, ptr->ring, ptr->buflen, &(ptr->pos));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
set_run_adding_gain_Pinknoise(LADSPA_Handle Instance, LADSPA_Data gain) {
|
||||
|
||||
Pinknoise * ptr;
|
||||
|
||||
ptr = (Pinknoise *)Instance;
|
||||
|
||||
ptr->run_adding_gain = gain;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
run_adding_Pinknoise(LADSPA_Handle Instance,
|
||||
unsigned long SampleCount) {
|
||||
|
||||
Pinknoise * ptr = (Pinknoise *)Instance;
|
||||
|
||||
LADSPA_Data * input = ptr->input;
|
||||
LADSPA_Data * output = ptr->output;
|
||||
LADSPA_Data hurst = LIMIT(*(ptr->hurst), 0.0f, 1.0f);
|
||||
LADSPA_Data signal = db2lin(LIMIT(*(ptr->signal), -90.0f, 20.0f));
|
||||
LADSPA_Data noise = db2lin(LIMIT(*(ptr->noise), -90.0f, 20.0f));
|
||||
unsigned long sample_index;
|
||||
|
||||
for (sample_index = 0; sample_index < SampleCount; sample_index++) {
|
||||
|
||||
if (!ptr->pos)
|
||||
fractal(ptr->ring, NOISE_LEN, hurst);
|
||||
|
||||
*(output++) += ptr->run_adding_gain * (signal * *(input++) +
|
||||
noise * push_buffer(0.0f, ptr->ring,
|
||||
ptr->buflen, &(ptr->pos)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Throw away a Pinknoise effect instance. */
|
||||
void
|
||||
cleanup_Pinknoise(LADSPA_Handle Instance) {
|
||||
Pinknoise * ptr = (Pinknoise *)Instance;
|
||||
free(ptr->ring);
|
||||
free(Instance);
|
||||
}
|
||||
|
||||
|
||||
|
||||
LADSPA_Descriptor * mono_descriptor = NULL;
|
||||
|
||||
|
||||
|
||||
/* _init() is called automatically when the plugin library is first
|
||||
loaded. */
|
||||
void
|
||||
_init() {
|
||||
|
||||
char ** port_names;
|
||||
LADSPA_PortDescriptor * port_descriptors;
|
||||
LADSPA_PortRangeHint * port_range_hints;
|
||||
|
||||
if ((mono_descriptor =
|
||||
(LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor))) == NULL)
|
||||
exit(1);
|
||||
|
||||
/* initialize RNG */
|
||||
srand(time(0));
|
||||
|
||||
mono_descriptor->UniqueID = ID_MONO;
|
||||
mono_descriptor->Label = strdup("tap_pinknoise");
|
||||
mono_descriptor->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
|
||||
mono_descriptor->Name = strdup("TAP Pink/Fractal Noise");
|
||||
mono_descriptor->Maker = strdup("Tom Szilagyi");
|
||||
mono_descriptor->Copyright = strdup("GPL");
|
||||
mono_descriptor->PortCount = PORTCOUNT_MONO;
|
||||
|
||||
if ((port_descriptors =
|
||||
(LADSPA_PortDescriptor *)calloc(PORTCOUNT_MONO, sizeof(LADSPA_PortDescriptor))) == NULL)
|
||||
exit(1);
|
||||
|
||||
mono_descriptor->PortDescriptors = (const LADSPA_PortDescriptor *)port_descriptors;
|
||||
port_descriptors[HURST] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[SIGNAL] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[NOISE] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[INPUT] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
|
||||
port_descriptors[OUTPUT] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
|
||||
|
||||
if ((port_names =
|
||||
(char **)calloc(PORTCOUNT_MONO, sizeof(char *))) == NULL)
|
||||
exit(1);
|
||||
|
||||
mono_descriptor->PortNames = (const char **)port_names;
|
||||
port_names[HURST] = strdup("Fractal Dimension");
|
||||
port_names[SIGNAL] = strdup("Signal Level [dB]");
|
||||
port_names[NOISE] = strdup("Noise Level [dB]");
|
||||
port_names[INPUT] = strdup("Input");
|
||||
port_names[OUTPUT] = strdup("Output");
|
||||
|
||||
if ((port_range_hints =
|
||||
((LADSPA_PortRangeHint *)calloc(PORTCOUNT_MONO, sizeof(LADSPA_PortRangeHint)))) == NULL)
|
||||
exit(1);
|
||||
|
||||
mono_descriptor->PortRangeHints = (const LADSPA_PortRangeHint *)port_range_hints;
|
||||
port_range_hints[HURST].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_MIDDLE);
|
||||
port_range_hints[SIGNAL].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[NOISE].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_MINIMUM);
|
||||
port_range_hints[HURST].LowerBound = 0.0f;
|
||||
port_range_hints[HURST].UpperBound = 1.0f;
|
||||
port_range_hints[SIGNAL].LowerBound = -90.0f;
|
||||
port_range_hints[SIGNAL].UpperBound = 20.0f;
|
||||
port_range_hints[NOISE].LowerBound = -90.0f;
|
||||
port_range_hints[NOISE].UpperBound = 20.0f;
|
||||
port_range_hints[INPUT].HintDescriptor = 0;
|
||||
port_range_hints[OUTPUT].HintDescriptor = 0;
|
||||
mono_descriptor->instantiate = instantiate_Pinknoise;
|
||||
mono_descriptor->connect_port = connect_port_Pinknoise;
|
||||
mono_descriptor->activate = NULL;
|
||||
mono_descriptor->run = run_Pinknoise;
|
||||
mono_descriptor->run_adding = run_adding_Pinknoise;
|
||||
mono_descriptor->set_run_adding_gain = set_run_adding_gain_Pinknoise;
|
||||
mono_descriptor->deactivate = NULL;
|
||||
mono_descriptor->cleanup = cleanup_Pinknoise;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
delete_descriptor(LADSPA_Descriptor * descriptor) {
|
||||
unsigned long index;
|
||||
if (descriptor) {
|
||||
free((char *)descriptor->Label);
|
||||
free((char *)descriptor->Name);
|
||||
free((char *)descriptor->Maker);
|
||||
free((char *)descriptor->Copyright);
|
||||
free((LADSPA_PortDescriptor *)descriptor->PortDescriptors);
|
||||
for (index = 0; index < descriptor->PortCount; index++)
|
||||
free((char *)(descriptor->PortNames[index]));
|
||||
free((char **)descriptor->PortNames);
|
||||
free((LADSPA_PortRangeHint *)descriptor->PortRangeHints);
|
||||
free(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* _fini() is called automatically when the library is unloaded. */
|
||||
void
|
||||
_fini() {
|
||||
delete_descriptor(mono_descriptor);
|
||||
}
|
||||
|
||||
|
||||
/* Return a descriptor of the requested plugin type. */
|
||||
const LADSPA_Descriptor *
|
||||
ladspa_descriptor(unsigned long Index) {
|
||||
|
||||
switch (Index) {
|
||||
case 0:
|
||||
return mono_descriptor;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
556
plugins/ladspa_effect/tap/tap_pitch.c
Normal file
556
plugins/ladspa_effect/tap/tap_pitch.c
Normal file
@@ -0,0 +1,556 @@
|
||||
/* -*- linux-c -*-
|
||||
Copyright (C) 2004 Tom Szilagyi
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: tap_pitch.c,v 1.2 2004/02/21 17:33:36 tszilagyi Exp $
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "ladspa.h"
|
||||
#include "tap_utils.h"
|
||||
|
||||
|
||||
/* The Unique ID of the plugin: */
|
||||
|
||||
#define ID_MONO 2150
|
||||
|
||||
/* The port numbers for the plugin: */
|
||||
|
||||
#define SEMITONE 0
|
||||
#define RATE 1
|
||||
#define DRYLEVEL 2
|
||||
#define WETLEVEL 3
|
||||
#define LATENCY 4
|
||||
#define INPUT 5
|
||||
#define OUTPUT 6
|
||||
|
||||
/* Total number of ports */
|
||||
|
||||
|
||||
#define PORTCOUNT_MONO 7
|
||||
|
||||
|
||||
/* depth of phase mod (yes, this is a magic number) */
|
||||
#define PM_DEPTH 3681.0f
|
||||
|
||||
|
||||
/* another magic number, derived from the above one */
|
||||
#define PM_BUFLEN 16027
|
||||
|
||||
|
||||
/* frequency of the modulation signal (Hz) */
|
||||
#define PM_FREQ 6.0f
|
||||
|
||||
|
||||
#define COS_TABLE_SIZE 1024
|
||||
LADSPA_Data cos_table[COS_TABLE_SIZE];
|
||||
|
||||
|
||||
/* \sqrt{12}{2} used for key frequency computing */
|
||||
#define ROOT_12_2 1.059463094f
|
||||
|
||||
|
||||
/* The structure used to hold port connection information and state */
|
||||
|
||||
typedef struct {
|
||||
LADSPA_Data * rate;
|
||||
LADSPA_Data * semitone;
|
||||
LADSPA_Data * drylevel;
|
||||
LADSPA_Data * wetlevel;
|
||||
LADSPA_Data * latency;
|
||||
LADSPA_Data * input;
|
||||
LADSPA_Data * output;
|
||||
|
||||
LADSPA_Data * ringbuffer;
|
||||
unsigned long buflen;
|
||||
unsigned long pos;
|
||||
LADSPA_Data phase;
|
||||
|
||||
unsigned long sample_rate;
|
||||
LADSPA_Data run_adding_gain;
|
||||
} Pitch;
|
||||
|
||||
|
||||
|
||||
/* Construct a new plugin instance. */
|
||||
LADSPA_Handle
|
||||
instantiate_Pitch(const LADSPA_Descriptor * Descriptor,
|
||||
unsigned long sample_rate) {
|
||||
|
||||
LADSPA_Handle * ptr;
|
||||
|
||||
if ((ptr = malloc(sizeof(Pitch))) != NULL) {
|
||||
((Pitch *)ptr)->sample_rate = sample_rate;
|
||||
((Pitch *)ptr)->run_adding_gain = 1.0f;
|
||||
|
||||
if ((((Pitch *)ptr)->ringbuffer =
|
||||
calloc(2 * PM_BUFLEN, sizeof(LADSPA_Data))) == NULL)
|
||||
return NULL;
|
||||
((Pitch *)ptr)->buflen = 2 * PM_BUFLEN * sample_rate / 192000;
|
||||
((Pitch *)ptr)->pos = 0;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
activate_Pitch(LADSPA_Handle Instance) {
|
||||
|
||||
Pitch * ptr = (Pitch *)Instance;
|
||||
unsigned long i;
|
||||
|
||||
for (i = 0; i < ptr->buflen; i++)
|
||||
ptr->ringbuffer[i] = 0.0f;
|
||||
|
||||
ptr->phase = 0.0f;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Connect a port to a data location. */
|
||||
void
|
||||
connect_port_Pitch(LADSPA_Handle Instance,
|
||||
unsigned long Port,
|
||||
LADSPA_Data * DataLocation) {
|
||||
|
||||
Pitch * ptr = (Pitch *)Instance;
|
||||
|
||||
switch (Port) {
|
||||
case RATE:
|
||||
ptr->rate = DataLocation;
|
||||
break;
|
||||
case SEMITONE:
|
||||
ptr->semitone = DataLocation;
|
||||
break;
|
||||
case DRYLEVEL:
|
||||
ptr->drylevel = DataLocation;
|
||||
break;
|
||||
case WETLEVEL:
|
||||
ptr->wetlevel = DataLocation;
|
||||
break;
|
||||
case LATENCY:
|
||||
ptr->latency = DataLocation;
|
||||
*(ptr->latency) = ptr->buflen / 2; /* IS THIS LEGAL? */
|
||||
break;
|
||||
case INPUT:
|
||||
ptr->input = DataLocation;
|
||||
break;
|
||||
case OUTPUT:
|
||||
ptr->output = DataLocation;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
run_Pitch(LADSPA_Handle Instance,
|
||||
unsigned long SampleCount) {
|
||||
|
||||
Pitch * ptr = (Pitch *)Instance;
|
||||
LADSPA_Data * input = ptr->input;
|
||||
LADSPA_Data * output = ptr->output;
|
||||
LADSPA_Data drylevel = db2lin(LIMIT(*(ptr->drylevel),-90.0f,20.0f));
|
||||
LADSPA_Data wetlevel = 0.333333f * db2lin(LIMIT(*(ptr->wetlevel),-90.0f,20.0f));
|
||||
LADSPA_Data buflen = ptr->buflen / 2.0f;
|
||||
LADSPA_Data semitone = LIMIT(*(ptr->semitone),-12.0f,12.0f);
|
||||
LADSPA_Data rate;
|
||||
LADSPA_Data r;
|
||||
LADSPA_Data depth;
|
||||
|
||||
unsigned long sample_index;
|
||||
unsigned long sample_count = SampleCount;
|
||||
|
||||
LADSPA_Data in = 0.0f;
|
||||
LADSPA_Data sign = 1.0f;
|
||||
LADSPA_Data phase_0 = 0.0f;
|
||||
LADSPA_Data phase_am_0 = 0.0f;
|
||||
LADSPA_Data phase_1 = 0.0f;
|
||||
LADSPA_Data phase_am_1 = 0.0f;
|
||||
LADSPA_Data phase_2 = 0.0f;
|
||||
LADSPA_Data phase_am_2 = 0.0f;
|
||||
LADSPA_Data fpos_0 = 0.0f, fpos_1 = 0.0f, fpos_2 = 0.0f;
|
||||
LADSPA_Data n_0 = 0.0f, n_1 = 0.0f, n_2 = 0.0f;
|
||||
LADSPA_Data rem_0 = 0.0f, rem_1 = 0.0f, rem_2 = 0.0f;
|
||||
LADSPA_Data sa_0, sb_0, sa_1, sb_1, sa_2, sb_2;
|
||||
|
||||
|
||||
if (semitone == 0.0f)
|
||||
rate = LIMIT(*(ptr->rate),-50.0f,100.0f);
|
||||
else
|
||||
rate = 100.0f * (powf(ROOT_12_2,semitone) - 1.0f);
|
||||
|
||||
r = -1.0f * ABS(rate);
|
||||
depth = buflen * LIMIT(ABS(r) / 100.0f, 0.0f, 1.0f);
|
||||
|
||||
|
||||
if (rate > 0.0f)
|
||||
sign = -1.0f;
|
||||
|
||||
for (sample_index = 0; sample_index < sample_count; sample_index++) {
|
||||
|
||||
in = *(input++);
|
||||
|
||||
phase_0 = COS_TABLE_SIZE * PM_FREQ * sample_index / ptr->sample_rate + ptr->phase;
|
||||
while (phase_0 >= COS_TABLE_SIZE)
|
||||
phase_0 -= COS_TABLE_SIZE;
|
||||
phase_am_0 = phase_0 + COS_TABLE_SIZE/2;
|
||||
while (phase_am_0 >= COS_TABLE_SIZE)
|
||||
phase_am_0 -= COS_TABLE_SIZE;
|
||||
|
||||
phase_1 = phase_0 + COS_TABLE_SIZE/3.0f;
|
||||
while (phase_1 >= COS_TABLE_SIZE)
|
||||
phase_1 -= COS_TABLE_SIZE;
|
||||
phase_am_1 = phase_1 + COS_TABLE_SIZE/2;
|
||||
while (phase_am_1 >= COS_TABLE_SIZE)
|
||||
phase_am_1 -= COS_TABLE_SIZE;
|
||||
|
||||
phase_2 = phase_0 + 2.0f*COS_TABLE_SIZE/3.0f;
|
||||
while (phase_2 >= COS_TABLE_SIZE)
|
||||
phase_2 -= COS_TABLE_SIZE;
|
||||
phase_am_2 = phase_2 + COS_TABLE_SIZE/2;
|
||||
while (phase_am_2 >= COS_TABLE_SIZE)
|
||||
phase_am_2 -= COS_TABLE_SIZE;
|
||||
|
||||
push_buffer(in, ptr->ringbuffer, ptr->buflen, &(ptr->pos));
|
||||
|
||||
fpos_0 = depth * (1.0f - sign * (2.0f * phase_0 / COS_TABLE_SIZE - 1.0f));
|
||||
n_0 = floorf(fpos_0);
|
||||
rem_0 = fpos_0 - n_0;
|
||||
|
||||
fpos_1 = depth * (1.0f - sign * (2.0f * phase_1 / COS_TABLE_SIZE - 1.0f));
|
||||
n_1 = floorf(fpos_1);
|
||||
rem_1 = fpos_1 - n_1;
|
||||
|
||||
fpos_2 = depth * (1.0f - sign * (2.0f * phase_2 / COS_TABLE_SIZE - 1.0f));
|
||||
n_2 = floorf(fpos_2);
|
||||
rem_2 = fpos_2 - n_2;
|
||||
|
||||
sa_0 = read_buffer(ptr->ringbuffer, ptr->buflen, ptr->pos, (unsigned long) n_0);
|
||||
sb_0 = read_buffer(ptr->ringbuffer, ptr->buflen, ptr->pos, (unsigned long) n_0 + 1);
|
||||
|
||||
sa_1 = read_buffer(ptr->ringbuffer, ptr->buflen, ptr->pos, (unsigned long) n_1);
|
||||
sb_1 = read_buffer(ptr->ringbuffer, ptr->buflen, ptr->pos, (unsigned long) n_1 + 1);
|
||||
|
||||
sa_2 = read_buffer(ptr->ringbuffer, ptr->buflen, ptr->pos, (unsigned long) n_2);
|
||||
sb_2 = read_buffer(ptr->ringbuffer, ptr->buflen, ptr->pos, (unsigned long) n_2 + 1);
|
||||
|
||||
*(output++) =
|
||||
wetlevel *
|
||||
((1.0f + cos_table[(unsigned long) phase_am_0]) *
|
||||
((1 - rem_0) * sa_0 + rem_0 * sb_0) +
|
||||
(1.0f + cos_table[(unsigned long) phase_am_1]) *
|
||||
((1 - rem_1) * sa_1 + rem_1 * sb_1) +
|
||||
(1.0f + cos_table[(unsigned long) phase_am_2]) *
|
||||
((1 - rem_2) * sa_2 + rem_2 * sb_2)) +
|
||||
drylevel *
|
||||
read_buffer(ptr->ringbuffer, ptr->buflen, ptr->pos, (unsigned long) depth);
|
||||
|
||||
}
|
||||
|
||||
ptr->phase += COS_TABLE_SIZE * PM_FREQ * sample_index / ptr->sample_rate;
|
||||
while (ptr->phase >= COS_TABLE_SIZE)
|
||||
ptr->phase -= COS_TABLE_SIZE;
|
||||
|
||||
*(ptr->latency) = buflen - (unsigned long) depth;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
set_run_adding_gain_Pitch(LADSPA_Handle Instance, LADSPA_Data gain) {
|
||||
|
||||
Pitch * ptr = (Pitch *)Instance;
|
||||
|
||||
ptr->run_adding_gain = gain;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
run_adding_Pitch(LADSPA_Handle Instance,
|
||||
unsigned long SampleCount) {
|
||||
|
||||
Pitch * ptr = (Pitch *)Instance;
|
||||
LADSPA_Data * input = ptr->input;
|
||||
LADSPA_Data * output = ptr->output;
|
||||
LADSPA_Data drylevel = db2lin(LIMIT(*(ptr->drylevel),-90.0f,20.0f));
|
||||
LADSPA_Data wetlevel = 0.333333f * db2lin(LIMIT(*(ptr->wetlevel),-90.0f,20.0f));
|
||||
LADSPA_Data buflen = ptr->buflen / 2.0f;
|
||||
LADSPA_Data semitone = LIMIT(*(ptr->semitone),-12.0f,12.0f);
|
||||
LADSPA_Data rate;
|
||||
LADSPA_Data r;
|
||||
LADSPA_Data depth;
|
||||
|
||||
unsigned long sample_index;
|
||||
unsigned long sample_count = SampleCount;
|
||||
|
||||
LADSPA_Data in = 0.0f;
|
||||
LADSPA_Data sign = 1.0f;
|
||||
LADSPA_Data phase_0 = 0.0f;
|
||||
LADSPA_Data phase_am_0 = 0.0f;
|
||||
LADSPA_Data phase_1 = 0.0f;
|
||||
LADSPA_Data phase_am_1 = 0.0f;
|
||||
LADSPA_Data phase_2 = 0.0f;
|
||||
LADSPA_Data phase_am_2 = 0.0f;
|
||||
LADSPA_Data fpos_0 = 0.0f, fpos_1 = 0.0f, fpos_2 = 0.0f;
|
||||
LADSPA_Data n_0 = 0.0f, n_1 = 0.0f, n_2 = 0.0f;
|
||||
LADSPA_Data rem_0 = 0.0f, rem_1 = 0.0f, rem_2 = 0.0f;
|
||||
LADSPA_Data sa_0, sb_0, sa_1, sb_1, sa_2, sb_2;
|
||||
|
||||
|
||||
if (semitone == 0.0f)
|
||||
rate = LIMIT(*(ptr->rate),-50.0f,100.0f);
|
||||
else
|
||||
rate = 100.0f * (powf(ROOT_12_2,semitone) - 1.0f);
|
||||
|
||||
r = -1.0f * ABS(rate);
|
||||
depth = buflen * LIMIT(ABS(r) / 100.0f, 0.0f, 1.0f);
|
||||
|
||||
|
||||
if (rate > 0.0f)
|
||||
sign = -1.0f;
|
||||
|
||||
for (sample_index = 0; sample_index < sample_count; sample_index++) {
|
||||
|
||||
in = *(input++);
|
||||
|
||||
phase_0 = COS_TABLE_SIZE * PM_FREQ * sample_index / ptr->sample_rate + ptr->phase;
|
||||
while (phase_0 >= COS_TABLE_SIZE)
|
||||
phase_0 -= COS_TABLE_SIZE;
|
||||
phase_am_0 = phase_0 + COS_TABLE_SIZE/2;
|
||||
while (phase_am_0 >= COS_TABLE_SIZE)
|
||||
phase_am_0 -= COS_TABLE_SIZE;
|
||||
|
||||
phase_1 = phase_0 + COS_TABLE_SIZE/3.0f;
|
||||
while (phase_1 >= COS_TABLE_SIZE)
|
||||
phase_1 -= COS_TABLE_SIZE;
|
||||
phase_am_1 = phase_1 + COS_TABLE_SIZE/2;
|
||||
while (phase_am_1 >= COS_TABLE_SIZE)
|
||||
phase_am_1 -= COS_TABLE_SIZE;
|
||||
|
||||
phase_2 = phase_0 + 2.0f*COS_TABLE_SIZE/3.0f;
|
||||
while (phase_2 >= COS_TABLE_SIZE)
|
||||
phase_2 -= COS_TABLE_SIZE;
|
||||
phase_am_2 = phase_2 + COS_TABLE_SIZE/2;
|
||||
while (phase_am_2 >= COS_TABLE_SIZE)
|
||||
phase_am_2 -= COS_TABLE_SIZE;
|
||||
|
||||
push_buffer(in, ptr->ringbuffer, ptr->buflen, &(ptr->pos));
|
||||
|
||||
fpos_0 = depth * (1.0f - sign * (2.0f * phase_0 / COS_TABLE_SIZE - 1.0f));
|
||||
n_0 = floorf(fpos_0);
|
||||
rem_0 = fpos_0 - n_0;
|
||||
|
||||
fpos_1 = depth * (1.0f - sign * (2.0f * phase_1 / COS_TABLE_SIZE - 1.0f));
|
||||
n_1 = floorf(fpos_1);
|
||||
rem_1 = fpos_1 - n_1;
|
||||
|
||||
fpos_2 = depth * (1.0f - sign * (2.0f * phase_2 / COS_TABLE_SIZE - 1.0f));
|
||||
n_2 = floorf(fpos_2);
|
||||
rem_2 = fpos_2 - n_2;
|
||||
|
||||
sa_0 = read_buffer(ptr->ringbuffer, ptr->buflen, ptr->pos, (unsigned long) n_0);
|
||||
sb_0 = read_buffer(ptr->ringbuffer, ptr->buflen, ptr->pos, (unsigned long) n_0 + 1);
|
||||
|
||||
sa_1 = read_buffer(ptr->ringbuffer, ptr->buflen, ptr->pos, (unsigned long) n_1);
|
||||
sb_1 = read_buffer(ptr->ringbuffer, ptr->buflen, ptr->pos, (unsigned long) n_1 + 1);
|
||||
|
||||
sa_2 = read_buffer(ptr->ringbuffer, ptr->buflen, ptr->pos, (unsigned long) n_2);
|
||||
sb_2 = read_buffer(ptr->ringbuffer, ptr->buflen, ptr->pos, (unsigned long) n_2 + 1);
|
||||
|
||||
*(output++) += ptr->run_adding_gain *
|
||||
wetlevel *
|
||||
((1.0f + cos_table[(unsigned long) phase_am_0]) *
|
||||
((1 - rem_0) * sa_0 + rem_0 * sb_0) +
|
||||
(1.0f + cos_table[(unsigned long) phase_am_1]) *
|
||||
((1 - rem_1) * sa_1 + rem_1 * sb_1) +
|
||||
(1.0f + cos_table[(unsigned long) phase_am_2]) *
|
||||
((1 - rem_2) * sa_2 + rem_2 * sb_2)) +
|
||||
drylevel *
|
||||
read_buffer(ptr->ringbuffer, ptr->buflen, ptr->pos, (unsigned long) depth);
|
||||
|
||||
}
|
||||
|
||||
ptr->phase += COS_TABLE_SIZE * PM_FREQ * sample_index / ptr->sample_rate;
|
||||
while (ptr->phase >= COS_TABLE_SIZE)
|
||||
ptr->phase -= COS_TABLE_SIZE;
|
||||
|
||||
*(ptr->latency) = buflen - (unsigned long) depth;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Throw away a Pitch effect instance. */
|
||||
void
|
||||
cleanup_Pitch(LADSPA_Handle Instance) {
|
||||
|
||||
Pitch * ptr = (Pitch *)Instance;
|
||||
free(ptr->ringbuffer);
|
||||
free(Instance);
|
||||
}
|
||||
|
||||
|
||||
|
||||
LADSPA_Descriptor * mono_descriptor = NULL;
|
||||
|
||||
|
||||
|
||||
/* _init() is called automatically when the plugin library is first
|
||||
loaded. */
|
||||
void
|
||||
_init() {
|
||||
|
||||
int i;
|
||||
char ** port_names;
|
||||
LADSPA_PortDescriptor * port_descriptors;
|
||||
LADSPA_PortRangeHint * port_range_hints;
|
||||
|
||||
if ((mono_descriptor =
|
||||
(LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor))) == NULL)
|
||||
exit(1);
|
||||
|
||||
for (i = 0; i < COS_TABLE_SIZE; i++)
|
||||
cos_table[i] = cosf(i * 2.0f * M_PI / COS_TABLE_SIZE);
|
||||
|
||||
|
||||
mono_descriptor->UniqueID = ID_MONO;
|
||||
mono_descriptor->Label = strdup("tap_pitch");
|
||||
mono_descriptor->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
|
||||
mono_descriptor->Name = strdup("TAP Pitch Shifter");
|
||||
mono_descriptor->Maker = strdup("Tom Szilagyi");
|
||||
mono_descriptor->Copyright = strdup("GPL");
|
||||
mono_descriptor->PortCount = PORTCOUNT_MONO;
|
||||
|
||||
if ((port_descriptors =
|
||||
(LADSPA_PortDescriptor *)calloc(PORTCOUNT_MONO, sizeof(LADSPA_PortDescriptor))) == NULL)
|
||||
exit(1);
|
||||
|
||||
mono_descriptor->PortDescriptors = (const LADSPA_PortDescriptor *)port_descriptors;
|
||||
port_descriptors[RATE] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[SEMITONE] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[DRYLEVEL] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[WETLEVEL] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[LATENCY] = LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[INPUT] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
|
||||
port_descriptors[OUTPUT] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
|
||||
|
||||
if ((port_names =
|
||||
(char **)calloc(PORTCOUNT_MONO, sizeof(char *))) == NULL)
|
||||
exit(1);
|
||||
|
||||
mono_descriptor->PortNames = (const char **)port_names;
|
||||
port_names[SEMITONE] = strdup("Semitone Shift");
|
||||
port_names[RATE] = strdup("Rate Shift [%]");
|
||||
port_names[DRYLEVEL] = strdup("Dry Level [dB]");
|
||||
port_names[WETLEVEL] = strdup("Wet Level [dB]");
|
||||
port_names[LATENCY] = strdup("latency");
|
||||
port_names[INPUT] = strdup("Input");
|
||||
port_names[OUTPUT] = strdup("Output");
|
||||
|
||||
if ((port_range_hints =
|
||||
((LADSPA_PortRangeHint *)calloc(PORTCOUNT_MONO, sizeof(LADSPA_PortRangeHint)))) == NULL)
|
||||
exit(1);
|
||||
|
||||
mono_descriptor->PortRangeHints = (const LADSPA_PortRangeHint *)port_range_hints;
|
||||
port_range_hints[RATE].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[SEMITONE].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[DRYLEVEL].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_MINIMUM);
|
||||
port_range_hints[WETLEVEL].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[LATENCY].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_MAXIMUM);
|
||||
port_range_hints[RATE].LowerBound = -50.0f;
|
||||
port_range_hints[RATE].UpperBound = 100.0f;
|
||||
port_range_hints[SEMITONE].LowerBound = -12.0f;
|
||||
port_range_hints[SEMITONE].UpperBound = 12.0f;
|
||||
port_range_hints[DRYLEVEL].LowerBound = -90.0f;
|
||||
port_range_hints[DRYLEVEL].UpperBound = 20.0f;
|
||||
port_range_hints[WETLEVEL].LowerBound = -90.0f;
|
||||
port_range_hints[WETLEVEL].UpperBound = 20.0f;
|
||||
port_range_hints[LATENCY].LowerBound = 0;
|
||||
port_range_hints[LATENCY].UpperBound = PM_BUFLEN;
|
||||
port_range_hints[INPUT].HintDescriptor = 0;
|
||||
port_range_hints[OUTPUT].HintDescriptor = 0;
|
||||
mono_descriptor->instantiate = instantiate_Pitch;
|
||||
mono_descriptor->connect_port = connect_port_Pitch;
|
||||
mono_descriptor->activate = activate_Pitch;
|
||||
mono_descriptor->run = run_Pitch;
|
||||
mono_descriptor->run_adding = run_adding_Pitch;
|
||||
mono_descriptor->set_run_adding_gain = set_run_adding_gain_Pitch;
|
||||
mono_descriptor->deactivate = NULL;
|
||||
mono_descriptor->cleanup = cleanup_Pitch;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
delete_descriptor(LADSPA_Descriptor * descriptor) {
|
||||
unsigned long index;
|
||||
if (descriptor) {
|
||||
free((char *)descriptor->Label);
|
||||
free((char *)descriptor->Name);
|
||||
free((char *)descriptor->Maker);
|
||||
free((char *)descriptor->Copyright);
|
||||
free((LADSPA_PortDescriptor *)descriptor->PortDescriptors);
|
||||
for (index = 0; index < descriptor->PortCount; index++)
|
||||
free((char *)(descriptor->PortNames[index]));
|
||||
free((char **)descriptor->PortNames);
|
||||
free((LADSPA_PortRangeHint *)descriptor->PortRangeHints);
|
||||
free(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* _fini() is called automatically when the library is unloaded. */
|
||||
void
|
||||
_fini() {
|
||||
delete_descriptor(mono_descriptor);
|
||||
}
|
||||
|
||||
|
||||
/* Return a descriptor of the requested plugin type. */
|
||||
const LADSPA_Descriptor *
|
||||
ladspa_descriptor(unsigned long Index) {
|
||||
|
||||
switch (Index) {
|
||||
case 0:
|
||||
return mono_descriptor;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
500
plugins/ladspa_effect/tap/tap_reflector.c
Normal file
500
plugins/ladspa_effect/tap/tap_reflector.c
Normal file
@@ -0,0 +1,500 @@
|
||||
/* -*- linux-c -*-
|
||||
Copyright (C) 2004 Tom Szilagyi
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: tap_reflector.c,v 1.1 2004/06/18 20:12:41 tszilagyi Exp $
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "ladspa.h"
|
||||
#include "tap_utils.h"
|
||||
|
||||
|
||||
/* The Unique ID of the plugin: */
|
||||
|
||||
#define ID_MONO 2154
|
||||
|
||||
/* The port numbers for the plugin: */
|
||||
|
||||
#define FRAGMENT 0
|
||||
#define DRYLEVEL 1
|
||||
#define WETLEVEL 2
|
||||
#define INPUT 3
|
||||
#define OUTPUT 4
|
||||
|
||||
/* Total number of ports */
|
||||
|
||||
|
||||
#define PORTCOUNT_MONO 5
|
||||
|
||||
|
||||
/* minimum & maximum fragment length [ms] */
|
||||
#define MIN_FRAGMENT_LEN 20
|
||||
#define MAX_FRAGMENT_LEN 1600
|
||||
|
||||
/* in kHz */
|
||||
#define MAX_SAMPLE_RATE 192
|
||||
|
||||
|
||||
#define COS_TABLE_SIZE 1024
|
||||
LADSPA_Data cos_table[COS_TABLE_SIZE];
|
||||
|
||||
|
||||
|
||||
/* The structure used to hold port connection information and state */
|
||||
|
||||
typedef struct {
|
||||
LADSPA_Data * fragment;
|
||||
LADSPA_Data * drylevel;
|
||||
LADSPA_Data * wetlevel;
|
||||
LADSPA_Data * input;
|
||||
LADSPA_Data * output;
|
||||
|
||||
LADSPA_Data * ring0;
|
||||
unsigned long buflen0;
|
||||
unsigned long pos0;
|
||||
LADSPA_Data * ring1;
|
||||
unsigned long buflen1;
|
||||
unsigned long pos1;
|
||||
LADSPA_Data * delay1;
|
||||
unsigned long delay_buflen1;
|
||||
unsigned long delay_pos1;
|
||||
LADSPA_Data * ring2;
|
||||
unsigned long buflen2;
|
||||
unsigned long pos2;
|
||||
LADSPA_Data * delay2;
|
||||
unsigned long delay_buflen2;
|
||||
unsigned long delay_pos2;
|
||||
|
||||
unsigned long fragment_pos;
|
||||
|
||||
unsigned long sample_rate;
|
||||
LADSPA_Data run_adding_gain;
|
||||
} Reflector;
|
||||
|
||||
|
||||
|
||||
/* Construct a new plugin instance. */
|
||||
LADSPA_Handle
|
||||
instantiate_Reflector(const LADSPA_Descriptor * Descriptor,
|
||||
unsigned long sample_rate) {
|
||||
|
||||
LADSPA_Handle * ptr;
|
||||
|
||||
if ((ptr = malloc(sizeof(Reflector))) != NULL) {
|
||||
((Reflector *)ptr)->sample_rate = sample_rate;
|
||||
((Reflector *)ptr)->run_adding_gain = 1.0f;
|
||||
|
||||
if ((((Reflector *)ptr)->ring0 =
|
||||
calloc(2 * MAX_FRAGMENT_LEN * MAX_SAMPLE_RATE, sizeof(LADSPA_Data))) == NULL)
|
||||
return NULL;
|
||||
((Reflector *)ptr)->buflen0 = 2 * MAX_FRAGMENT_LEN * sample_rate / 1000;
|
||||
((Reflector *)ptr)->pos0 = 0;
|
||||
|
||||
if ((((Reflector *)ptr)->ring1 =
|
||||
calloc(2 * MAX_FRAGMENT_LEN * MAX_SAMPLE_RATE, sizeof(LADSPA_Data))) == NULL)
|
||||
return NULL;
|
||||
((Reflector *)ptr)->buflen1 = 2 * MAX_FRAGMENT_LEN * sample_rate / 1000;
|
||||
((Reflector *)ptr)->pos1 = 0;
|
||||
|
||||
if ((((Reflector *)ptr)->delay1 =
|
||||
calloc(2 * MAX_FRAGMENT_LEN * MAX_SAMPLE_RATE, sizeof(LADSPA_Data))) == NULL)
|
||||
return NULL;
|
||||
((Reflector *)ptr)->delay_buflen1 = 2 * MAX_FRAGMENT_LEN * sample_rate / 3000;
|
||||
((Reflector *)ptr)->pos1 = 0;
|
||||
|
||||
if ((((Reflector *)ptr)->ring2 =
|
||||
calloc(2 * MAX_FRAGMENT_LEN * MAX_SAMPLE_RATE, sizeof(LADSPA_Data))) == NULL)
|
||||
return NULL;
|
||||
((Reflector *)ptr)->buflen2 = 2 * MAX_FRAGMENT_LEN * sample_rate / 1000;
|
||||
((Reflector *)ptr)->pos2 = 0;
|
||||
|
||||
if ((((Reflector *)ptr)->delay2 =
|
||||
calloc(2 * MAX_FRAGMENT_LEN * MAX_SAMPLE_RATE, sizeof(LADSPA_Data))) == NULL)
|
||||
return NULL;
|
||||
((Reflector *)ptr)->delay_buflen2 = 4 * MAX_FRAGMENT_LEN * sample_rate / 3000;
|
||||
((Reflector *)ptr)->pos2 = 0;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
activate_Reflector(LADSPA_Handle Instance) {
|
||||
|
||||
Reflector * ptr = (Reflector *)Instance;
|
||||
unsigned long i;
|
||||
|
||||
for (i = 0; i < ptr->buflen0; i++)
|
||||
ptr->ring0[i] = 0.0f;
|
||||
ptr->pos0 = 0;
|
||||
for (i = 0; i < ptr->buflen1; i++)
|
||||
ptr->ring1[i] = 0.0f;
|
||||
ptr->pos1 = 0;
|
||||
for (i = 0; i < ptr->buflen2; i++)
|
||||
ptr->ring2[i] = 0.0f;
|
||||
ptr->pos2 = 0;
|
||||
|
||||
for (i = 0; i < ptr->delay_buflen1; i++)
|
||||
ptr->delay1[i] = 0.0f;
|
||||
ptr->delay_pos1 = 0;
|
||||
for (i = 0; i < ptr->delay_buflen2; i++)
|
||||
ptr->delay2[i] = 0.0f;
|
||||
ptr->delay_pos2 = 0;
|
||||
|
||||
ptr->fragment_pos = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Connect a port to a data location. */
|
||||
void
|
||||
connect_port_Reflector(LADSPA_Handle Instance,
|
||||
unsigned long Port,
|
||||
LADSPA_Data * DataLocation) {
|
||||
|
||||
Reflector * ptr = (Reflector *)Instance;
|
||||
|
||||
switch (Port) {
|
||||
case FRAGMENT:
|
||||
ptr->fragment = DataLocation;
|
||||
break;
|
||||
case DRYLEVEL:
|
||||
ptr->drylevel = DataLocation;
|
||||
break;
|
||||
case WETLEVEL:
|
||||
ptr->wetlevel = DataLocation;
|
||||
break;
|
||||
case INPUT:
|
||||
ptr->input = DataLocation;
|
||||
break;
|
||||
case OUTPUT:
|
||||
ptr->output = DataLocation;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
run_Reflector(LADSPA_Handle Instance,
|
||||
unsigned long SampleCount) {
|
||||
|
||||
Reflector * ptr = (Reflector *)Instance;
|
||||
LADSPA_Data * input = ptr->input;
|
||||
LADSPA_Data * output = ptr->output;
|
||||
LADSPA_Data drylevel = db2lin(LIMIT(*(ptr->drylevel),-90.0f,20.0f));
|
||||
LADSPA_Data wetlevel = 0.333333f * db2lin(LIMIT(*(ptr->wetlevel),-90.0f,20.0f));
|
||||
LADSPA_Data fragment = LIMIT(*(ptr->fragment),(float)MIN_FRAGMENT_LEN,(float)MAX_FRAGMENT_LEN);
|
||||
|
||||
unsigned long sample_index;
|
||||
unsigned long sample_count = SampleCount;
|
||||
|
||||
LADSPA_Data in = 0.0f;
|
||||
LADSPA_Data in1 = 0.0f;
|
||||
LADSPA_Data in2 = 0.0f;
|
||||
LADSPA_Data out_0 = 0.0f;
|
||||
LADSPA_Data out_1 = 0.0f;
|
||||
LADSPA_Data out_2 = 0.0f;
|
||||
|
||||
unsigned long fragment_pos1 = 0;
|
||||
unsigned long fragment_pos2 = 0;
|
||||
|
||||
unsigned long arg_0 = 0;
|
||||
LADSPA_Data am_0 = 0.0f;
|
||||
unsigned long arg_1 = 0;
|
||||
LADSPA_Data am_1 = 0.0f;
|
||||
unsigned long arg_2 = 0;
|
||||
LADSPA_Data am_2 = 0.0f;
|
||||
|
||||
ptr->buflen0 = 2 * fragment * ptr->sample_rate / 1000.0f;
|
||||
ptr->buflen1 = ptr->buflen0;
|
||||
ptr->buflen2 = ptr->buflen0;
|
||||
ptr->delay_buflen1 = ptr->buflen0 / 3;
|
||||
ptr->delay_buflen2 = 2 * ptr->buflen0 / 3;
|
||||
|
||||
for (sample_index = 0; sample_index < sample_count; sample_index++) {
|
||||
|
||||
in = *(input++);
|
||||
in1 = push_buffer(in, ptr->delay1, ptr->delay_buflen1, &(ptr->delay_pos1));
|
||||
in2 = push_buffer(in, ptr->delay2, ptr->delay_buflen2, &(ptr->delay_pos2));
|
||||
|
||||
push_buffer(in2, ptr->ring0, ptr->buflen0, &(ptr->pos0));
|
||||
push_buffer(in1, ptr->ring1, ptr->buflen1, &(ptr->pos1));
|
||||
push_buffer(in, ptr->ring2, ptr->buflen2, &(ptr->pos2));
|
||||
|
||||
fragment_pos1 = (ptr->fragment_pos + ptr->buflen0 / 3) % ptr->buflen0;
|
||||
fragment_pos2 = (ptr->fragment_pos + 2 * ptr->buflen1 / 3) % ptr->buflen1;
|
||||
|
||||
out_0 = read_buffer(ptr->ring0, ptr->buflen0, ptr->pos0,
|
||||
ptr->buflen0 - ptr->fragment_pos - 1);
|
||||
out_1 = read_buffer(ptr->ring1, ptr->buflen1, ptr->pos1,
|
||||
ptr->buflen1 - fragment_pos1 - 1);
|
||||
out_2 = read_buffer(ptr->ring2, ptr->buflen2, ptr->pos2,
|
||||
ptr->buflen2 - fragment_pos2 - 1);
|
||||
|
||||
ptr->fragment_pos += 2;
|
||||
if (ptr->fragment_pos >= ptr->buflen0)
|
||||
ptr->fragment_pos = 0;
|
||||
|
||||
arg_0 = (float)ptr->fragment_pos / (float)ptr->buflen0 * COS_TABLE_SIZE;
|
||||
am_0 = 1.0f - cos_table[arg_0];
|
||||
arg_1 = (float)fragment_pos1 / (float)ptr->buflen1 * COS_TABLE_SIZE;
|
||||
am_1 = 1.0f - cos_table[arg_1];
|
||||
arg_2 = (float)fragment_pos2 / (float)ptr->buflen2 * COS_TABLE_SIZE;
|
||||
am_2 = 1.0f - cos_table[arg_2];
|
||||
|
||||
*(output++) = drylevel * in + wetlevel *
|
||||
(am_0 * out_0 + am_1 * out_1 + am_2 * out_2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
set_run_adding_gain_Reflector(LADSPA_Handle Instance, LADSPA_Data gain) {
|
||||
|
||||
Reflector * ptr = (Reflector *)Instance;
|
||||
|
||||
ptr->run_adding_gain = gain;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
run_adding_Reflector(LADSPA_Handle Instance,
|
||||
unsigned long SampleCount) {
|
||||
|
||||
Reflector * ptr = (Reflector *)Instance;
|
||||
LADSPA_Data * input = ptr->input;
|
||||
LADSPA_Data * output = ptr->output;
|
||||
LADSPA_Data drylevel = db2lin(LIMIT(*(ptr->drylevel),-90.0f,20.0f));
|
||||
LADSPA_Data wetlevel = 0.333333f * db2lin(LIMIT(*(ptr->wetlevel),-90.0f,20.0f));
|
||||
LADSPA_Data fragment = LIMIT(*(ptr->fragment),(float)MIN_FRAGMENT_LEN,(float)MAX_FRAGMENT_LEN);
|
||||
|
||||
unsigned long sample_index;
|
||||
unsigned long sample_count = SampleCount;
|
||||
|
||||
LADSPA_Data in = 0.0f;
|
||||
LADSPA_Data in1 = 0.0f;
|
||||
LADSPA_Data in2 = 0.0f;
|
||||
LADSPA_Data out_0 = 0.0f;
|
||||
LADSPA_Data out_1 = 0.0f;
|
||||
LADSPA_Data out_2 = 0.0f;
|
||||
|
||||
unsigned long fragment_pos1 = 0;
|
||||
unsigned long fragment_pos2 = 0;
|
||||
|
||||
unsigned long arg_0 = 0;
|
||||
LADSPA_Data am_0 = 0.0f;
|
||||
unsigned long arg_1 = 0;
|
||||
LADSPA_Data am_1 = 0.0f;
|
||||
unsigned long arg_2 = 0;
|
||||
LADSPA_Data am_2 = 0.0f;
|
||||
|
||||
ptr->buflen0 = 2 * fragment * ptr->sample_rate / 1000.0f;
|
||||
ptr->buflen1 = ptr->buflen0;
|
||||
ptr->buflen2 = ptr->buflen0;
|
||||
ptr->delay_buflen1 = ptr->buflen0 / 3;
|
||||
ptr->delay_buflen2 = 2 * ptr->buflen0 / 3;
|
||||
|
||||
for (sample_index = 0; sample_index < sample_count; sample_index++) {
|
||||
|
||||
in = *(input++);
|
||||
in1 = push_buffer(in, ptr->delay1, ptr->delay_buflen1, &(ptr->delay_pos1));
|
||||
in2 = push_buffer(in, ptr->delay2, ptr->delay_buflen2, &(ptr->delay_pos2));
|
||||
|
||||
push_buffer(in2, ptr->ring0, ptr->buflen0, &(ptr->pos0));
|
||||
push_buffer(in1, ptr->ring1, ptr->buflen1, &(ptr->pos1));
|
||||
push_buffer(in, ptr->ring2, ptr->buflen2, &(ptr->pos2));
|
||||
|
||||
fragment_pos1 = (ptr->fragment_pos + ptr->buflen0 / 3) % ptr->buflen0;
|
||||
fragment_pos2 = (ptr->fragment_pos + 2 * ptr->buflen1 / 3) % ptr->buflen1;
|
||||
|
||||
out_0 = read_buffer(ptr->ring0, ptr->buflen0, ptr->pos0,
|
||||
ptr->buflen0 - ptr->fragment_pos - 1);
|
||||
out_1 = read_buffer(ptr->ring1, ptr->buflen1, ptr->pos1,
|
||||
ptr->buflen1 - fragment_pos1 - 1);
|
||||
out_2 = read_buffer(ptr->ring2, ptr->buflen2, ptr->pos2,
|
||||
ptr->buflen2 - fragment_pos2 - 1);
|
||||
|
||||
ptr->fragment_pos += 2;
|
||||
if (ptr->fragment_pos >= ptr->buflen0)
|
||||
ptr->fragment_pos = 0;
|
||||
|
||||
arg_0 = (float)ptr->fragment_pos / (float)ptr->buflen0 * COS_TABLE_SIZE;
|
||||
am_0 = 1.0f - cos_table[arg_0];
|
||||
arg_1 = (float)fragment_pos1 / (float)ptr->buflen1 * COS_TABLE_SIZE;
|
||||
am_1 = 1.0f - cos_table[arg_1];
|
||||
arg_2 = (float)fragment_pos2 / (float)ptr->buflen2 * COS_TABLE_SIZE;
|
||||
am_2 = 1.0f - cos_table[arg_2];
|
||||
|
||||
*(output++) += ptr->run_adding_gain *
|
||||
(drylevel * in + wetlevel * (am_0 * out_0 + am_1 * out_1 + am_2 * out_2));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Throw away a Reflector effect instance. */
|
||||
void
|
||||
cleanup_Reflector(LADSPA_Handle Instance) {
|
||||
|
||||
Reflector * ptr = (Reflector *)Instance;
|
||||
free(ptr->ring0);
|
||||
free(ptr->ring1);
|
||||
free(ptr->ring2);
|
||||
free(ptr->delay1);
|
||||
free(ptr->delay2);
|
||||
free(Instance);
|
||||
}
|
||||
|
||||
|
||||
|
||||
LADSPA_Descriptor * mono_descriptor = NULL;
|
||||
|
||||
|
||||
|
||||
/* _init() is called automatically when the plugin library is first
|
||||
loaded. */
|
||||
void
|
||||
_init() {
|
||||
|
||||
int i;
|
||||
char ** port_names;
|
||||
LADSPA_PortDescriptor * port_descriptors;
|
||||
LADSPA_PortRangeHint * port_range_hints;
|
||||
|
||||
if ((mono_descriptor =
|
||||
(LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor))) == NULL)
|
||||
exit(1);
|
||||
|
||||
for (i = 0; i < COS_TABLE_SIZE; i++)
|
||||
cos_table[i] = cosf(i * 2.0f * M_PI / COS_TABLE_SIZE);
|
||||
|
||||
|
||||
mono_descriptor->UniqueID = ID_MONO;
|
||||
mono_descriptor->Label = strdup("tap_reflector");
|
||||
mono_descriptor->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
|
||||
mono_descriptor->Name = strdup("TAP Reflector");
|
||||
mono_descriptor->Maker = strdup("Tom Szilagyi");
|
||||
mono_descriptor->Copyright = strdup("GPL");
|
||||
mono_descriptor->PortCount = PORTCOUNT_MONO;
|
||||
|
||||
if ((port_descriptors =
|
||||
(LADSPA_PortDescriptor *)calloc(PORTCOUNT_MONO, sizeof(LADSPA_PortDescriptor))) == NULL)
|
||||
exit(1);
|
||||
|
||||
mono_descriptor->PortDescriptors = (const LADSPA_PortDescriptor *)port_descriptors;
|
||||
port_descriptors[FRAGMENT] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[DRYLEVEL] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[WETLEVEL] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[INPUT] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
|
||||
port_descriptors[OUTPUT] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
|
||||
|
||||
if ((port_names =
|
||||
(char **)calloc(PORTCOUNT_MONO, sizeof(char *))) == NULL)
|
||||
exit(1);
|
||||
|
||||
mono_descriptor->PortNames = (const char **)port_names;
|
||||
port_names[FRAGMENT] = strdup("Fragment Length [ms]");
|
||||
port_names[DRYLEVEL] = strdup("Dry Level [dB]");
|
||||
port_names[WETLEVEL] = strdup("Wet Level [dB]");
|
||||
port_names[INPUT] = strdup("Input");
|
||||
port_names[OUTPUT] = strdup("Output");
|
||||
|
||||
if ((port_range_hints =
|
||||
((LADSPA_PortRangeHint *)calloc(PORTCOUNT_MONO, sizeof(LADSPA_PortRangeHint)))) == NULL)
|
||||
exit(1);
|
||||
|
||||
mono_descriptor->PortRangeHints = (const LADSPA_PortRangeHint *)port_range_hints;
|
||||
port_range_hints[FRAGMENT].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_LOW);
|
||||
port_range_hints[DRYLEVEL].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_MINIMUM);
|
||||
port_range_hints[WETLEVEL].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[FRAGMENT].LowerBound = (float)MIN_FRAGMENT_LEN;
|
||||
port_range_hints[FRAGMENT].UpperBound = (float)MAX_FRAGMENT_LEN;
|
||||
port_range_hints[DRYLEVEL].LowerBound = -90.0f;
|
||||
port_range_hints[DRYLEVEL].UpperBound = 20.0f;
|
||||
port_range_hints[WETLEVEL].LowerBound = -90.0f;
|
||||
port_range_hints[WETLEVEL].UpperBound = 20.0f;
|
||||
port_range_hints[INPUT].HintDescriptor = 0;
|
||||
port_range_hints[OUTPUT].HintDescriptor = 0;
|
||||
mono_descriptor->instantiate = instantiate_Reflector;
|
||||
mono_descriptor->connect_port = connect_port_Reflector;
|
||||
mono_descriptor->activate = activate_Reflector;
|
||||
mono_descriptor->run = run_Reflector;
|
||||
mono_descriptor->run_adding = run_adding_Reflector;
|
||||
mono_descriptor->set_run_adding_gain = set_run_adding_gain_Reflector;
|
||||
mono_descriptor->deactivate = NULL;
|
||||
mono_descriptor->cleanup = cleanup_Reflector;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
delete_descriptor(LADSPA_Descriptor * descriptor) {
|
||||
unsigned long index;
|
||||
if (descriptor) {
|
||||
free((char *)descriptor->Label);
|
||||
free((char *)descriptor->Name);
|
||||
free((char *)descriptor->Maker);
|
||||
free((char *)descriptor->Copyright);
|
||||
free((LADSPA_PortDescriptor *)descriptor->PortDescriptors);
|
||||
for (index = 0; index < descriptor->PortCount; index++)
|
||||
free((char *)(descriptor->PortNames[index]));
|
||||
free((char **)descriptor->PortNames);
|
||||
free((LADSPA_PortRangeHint *)descriptor->PortRangeHints);
|
||||
free(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* _fini() is called automatically when the library is unloaded. */
|
||||
void
|
||||
_fini() {
|
||||
delete_descriptor(mono_descriptor);
|
||||
}
|
||||
|
||||
|
||||
/* Return a descriptor of the requested plugin type. */
|
||||
const LADSPA_Descriptor *
|
||||
ladspa_descriptor(unsigned long Index) {
|
||||
|
||||
switch (Index) {
|
||||
case 0:
|
||||
return mono_descriptor;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
835
plugins/ladspa_effect/tap/tap_reverb.c
Normal file
835
plugins/ladspa_effect/tap/tap_reverb.c
Normal file
@@ -0,0 +1,835 @@
|
||||
/* -*- linux-c -*-
|
||||
Copyright (C) 2004 Tom Szilagyi
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: tap_reverb.c,v 1.13 2004/06/15 14:50:55 tszilagyi Exp $
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "ladspa.h"
|
||||
|
||||
|
||||
/* ***** VERY IMPORTANT! *****
|
||||
*
|
||||
* If you enable this, the plugin will use float arithmetics in DSP
|
||||
* calculations. This usually yields lower average CPU usage, but
|
||||
* occasionaly may result in high CPU peaks which cause trouble to you
|
||||
* and your JACK server. The default is to use fixpoint arithmetics
|
||||
* (with the following #define commented out). But (depending on the
|
||||
* processor on which you run the code) you may find floating point
|
||||
* mode usable.
|
||||
*/
|
||||
/* #define REVERB_CALC_FLOAT */
|
||||
|
||||
|
||||
|
||||
#ifndef REVERB_CALC_FLOAT
|
||||
typedef signed int sample;
|
||||
#endif
|
||||
|
||||
#ifndef REVERB_CALC_FLOAT
|
||||
typedef sample rev_t;
|
||||
#else
|
||||
typedef LADSPA_Data rev_t;
|
||||
#endif
|
||||
|
||||
|
||||
#include "tap_reverb_presets.h"
|
||||
|
||||
|
||||
|
||||
#ifdef REVERB_CALC_FLOAT
|
||||
#define DENORM(x) (((unsigned char)(((*(unsigned int*)&(x))&0x7f800000)>>23))<103)?0.0f:(x)
|
||||
#else
|
||||
/* coefficient for float to sample (signed int) conversion */
|
||||
/* this allows for about 60 dB headroom above 0dB, if 0 dB is equivalent to 1.0f */
|
||||
/* As 2^31 equals more than 180 dB, about 120 dB dynamics remains below 0 dB */
|
||||
#define F2S 2147483
|
||||
#endif
|
||||
|
||||
|
||||
/* load plugin data from reverb_data[] into an instance */
|
||||
void
|
||||
load_plugin_data(LADSPA_Handle Instance) {
|
||||
|
||||
Reverb * ptr = (Reverb *)Instance;
|
||||
unsigned long m;
|
||||
int i;
|
||||
|
||||
|
||||
m = LIMIT(*(ptr->mode),0,NUM_MODES-1);
|
||||
|
||||
/* load combs data */
|
||||
ptr->num_combs = 2 * reverb_data[m].num_combs;
|
||||
for (i = 0; i < reverb_data[m].num_combs; i++) {
|
||||
((COMB_FILTER *)(ptr->combs + 2*i))->buflen =
|
||||
reverb_data[m].combs[i].delay * ptr->sample_rate;
|
||||
((COMB_FILTER *)(ptr->combs + 2*i))->feedback =
|
||||
reverb_data[m].combs[i].feedback;
|
||||
((COMB_FILTER *)(ptr->combs + 2*i))->freq_resp =
|
||||
LIMIT(reverb_data[m].combs[i].freq_resp
|
||||
* powf(ptr->sample_rate / 44100.0f, 0.8f),
|
||||
0.0f, 1.0f);
|
||||
|
||||
((COMB_FILTER *)(ptr->combs + 2*i+1))->buflen =
|
||||
((COMB_FILTER *)(ptr->combs + 2*i))->buflen;
|
||||
((COMB_FILTER *)(ptr->combs + 2*i+1))->feedback =
|
||||
((COMB_FILTER *)(ptr->combs + 2*i))->feedback;
|
||||
((COMB_FILTER *)(ptr->combs + 2*i+1))->feedback =
|
||||
((COMB_FILTER *)(ptr->combs + 2*i))->freq_resp;
|
||||
|
||||
/* set initial values: */
|
||||
*(((COMB_FILTER *)(ptr->combs + 2*i))->buffer_pos) = 0;
|
||||
*(((COMB_FILTER *)(ptr->combs + 2*i+1))->buffer_pos) = 0;
|
||||
((COMB_FILTER *)(ptr->combs + 2*i))->last_out = 0;
|
||||
((COMB_FILTER *)(ptr->combs + 2*i+1))->last_out = 0;
|
||||
|
||||
lp_set_params(((COMB_FILTER *)(ptr->combs + 2*i))->filter,
|
||||
2000.0f + 13000.0f * (1 - reverb_data[m].combs[i].freq_resp)
|
||||
* ptr->sample_rate / 44100.0f,
|
||||
BANDPASS_BWIDTH, ptr->sample_rate);
|
||||
lp_set_params(((COMB_FILTER *)(ptr->combs + 2*i+1))->filter,
|
||||
2000.0f + 13000.0f * (1 - reverb_data[m].combs[i].freq_resp)
|
||||
* ptr->sample_rate / 44100.0f,
|
||||
BANDPASS_BWIDTH, ptr->sample_rate);
|
||||
}
|
||||
|
||||
/* load allps data */
|
||||
ptr->num_allps = 2 * reverb_data[m].num_allps;
|
||||
for (i = 0; i < reverb_data[m].num_allps; i++) {
|
||||
((ALLP_FILTER *)(ptr->allps + 2*i))->buflen =
|
||||
reverb_data[m].allps[i].delay * ptr->sample_rate;
|
||||
((ALLP_FILTER *)(ptr->allps + 2*i))->feedback =
|
||||
reverb_data[m].allps[i].feedback;
|
||||
|
||||
((ALLP_FILTER *)(ptr->allps + 2*i+1))->buflen =
|
||||
((ALLP_FILTER *)(ptr->allps + 2*i))->buflen;
|
||||
((ALLP_FILTER *)(ptr->allps + 2*i+1))->feedback =
|
||||
((ALLP_FILTER *)(ptr->allps + 2*i))->feedback;
|
||||
|
||||
/* set initial values: */
|
||||
*(((ALLP_FILTER *)(ptr->allps + 2*i))->buffer_pos) = 0;
|
||||
*(((ALLP_FILTER *)(ptr->allps + 2*i+1))->buffer_pos) = 0;
|
||||
((ALLP_FILTER *)(ptr->allps + 2*i))->last_out = 0;
|
||||
((ALLP_FILTER *)(ptr->allps + 2*i+1))->last_out = 0;
|
||||
}
|
||||
|
||||
/* init bandpass filters */
|
||||
lp_set_params((biquad *)(ptr->low_pass), reverb_data[m].bandpass_high,
|
||||
BANDPASS_BWIDTH, ptr->sample_rate);
|
||||
hp_set_params((biquad *)(ptr->high_pass), reverb_data[m].bandpass_low,
|
||||
BANDPASS_BWIDTH, ptr->sample_rate);
|
||||
lp_set_params((biquad *)(ptr->low_pass + 1), reverb_data[m].bandpass_high,
|
||||
BANDPASS_BWIDTH, ptr->sample_rate);
|
||||
hp_set_params((biquad *)(ptr->high_pass + 1), reverb_data[m].bandpass_low,
|
||||
BANDPASS_BWIDTH, ptr->sample_rate);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* push a sample into a comb filter and return the sample falling out */
|
||||
rev_t
|
||||
comb_run(rev_t insample, COMB_FILTER * comb) {
|
||||
|
||||
rev_t outsample;
|
||||
rev_t pushin;
|
||||
|
||||
pushin = comb->fb_gain * insample + biquad_run(comb->filter, comb->fb_gain * comb->last_out);
|
||||
#ifdef REVERB_CALC_FLOAT
|
||||
pushin = DENORM(pushin);
|
||||
#endif
|
||||
outsample = push_buffer(pushin,
|
||||
comb->ringbuffer, comb->buflen, comb->buffer_pos);
|
||||
#ifdef REVERB_CALC_FLOAT
|
||||
outsample = DENORM(outsample);
|
||||
#endif
|
||||
comb->last_out = outsample;
|
||||
|
||||
return outsample;
|
||||
}
|
||||
|
||||
|
||||
/* push a sample into an allpass filter and return the sample falling out */
|
||||
rev_t
|
||||
allp_run(rev_t insample, ALLP_FILTER * allp) {
|
||||
|
||||
rev_t outsample;
|
||||
rev_t pushin;
|
||||
pushin = allp->in_gain * allp->fb_gain * insample + allp->fb_gain * allp->last_out;
|
||||
#ifdef REVERB_CALC_FLOAT
|
||||
pushin = DENORM(pushin);
|
||||
#endif
|
||||
outsample = push_buffer(pushin,
|
||||
allp->ringbuffer, allp->buflen, allp->buffer_pos);
|
||||
#ifdef REVERB_CALC_FLOAT
|
||||
outsample = DENORM(outsample);
|
||||
#endif
|
||||
allp->last_out = outsample;
|
||||
|
||||
return outsample;
|
||||
}
|
||||
|
||||
|
||||
/* compute user-input-dependent reverberator coefficients */
|
||||
void
|
||||
comp_coeffs(LADSPA_Handle Instance) {
|
||||
|
||||
Reverb * ptr = (Reverb *)Instance;
|
||||
int i;
|
||||
|
||||
|
||||
if (*(ptr->mode) != ptr->old_mode)
|
||||
load_plugin_data(Instance);
|
||||
|
||||
for (i = 0; i < ptr->num_combs / 2; i++) {
|
||||
((COMB_FILTER *)(ptr->combs + 2*i))->fb_gain =
|
||||
powf(0.001f,
|
||||
1000.0f * ((COMB_FILTER *)(ptr->combs + 2*i))->buflen
|
||||
* (1 + FR_R_COMP * ((COMB_FILTER *)(ptr->combs + 2*i))->freq_resp)
|
||||
/ powf(((COMB_FILTER *)(ptr->combs + 2*i))->feedback/100.0f, 0.89f)
|
||||
/ *(ptr->decay)
|
||||
/ ptr->sample_rate);
|
||||
|
||||
((COMB_FILTER *)(ptr->combs + 2*i+1))->fb_gain =
|
||||
((COMB_FILTER *)(ptr->combs + 2*i))->fb_gain;
|
||||
|
||||
if (*(ptr->stereo_enh) > 0.0f) {
|
||||
if (i % 2 == 0)
|
||||
((COMB_FILTER *)(ptr->combs + 2*i+1))->buflen =
|
||||
ENH_STEREO_RATIO * ((COMB_FILTER *)(ptr->combs + 2*i))->buflen;
|
||||
else
|
||||
((COMB_FILTER *)(ptr->combs + 2*i))->buflen =
|
||||
ENH_STEREO_RATIO * ((COMB_FILTER *)(ptr->combs + 2*i+1))->buflen;
|
||||
} else {
|
||||
if (i % 2 == 0)
|
||||
((COMB_FILTER *)(ptr->combs + 2*i+1))->buflen =
|
||||
((COMB_FILTER *)(ptr->combs + 2*i))->buflen;
|
||||
else
|
||||
((COMB_FILTER *)(ptr->combs + 2*i))->buflen =
|
||||
((COMB_FILTER *)(ptr->combs + 2*i+1))->buflen;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ptr->num_allps / 2; i++) {
|
||||
((ALLP_FILTER *)(ptr->allps + 2*i))->fb_gain =
|
||||
powf(0.001f, 11000.0f * ((ALLP_FILTER *)(ptr->allps + 2*i))->buflen
|
||||
/ powf(((ALLP_FILTER *)(ptr->allps + 2*i))->feedback/100.0f, 0.88f)
|
||||
/ *(ptr->decay)
|
||||
/ ptr->sample_rate);
|
||||
|
||||
((ALLP_FILTER *)(ptr->allps + 2*i+1))->fb_gain =
|
||||
((ALLP_FILTER *)(ptr->allps + 2*i))->fb_gain;
|
||||
|
||||
((ALLP_FILTER *)(ptr->allps + 2*i))->in_gain = -0.06f
|
||||
/ (((ALLP_FILTER *)(ptr->allps + 2 * i))->feedback/100.0f)
|
||||
/ powf((*(ptr->decay) + 3500.0f) / 10000.0f, 1.5f);
|
||||
|
||||
((ALLP_FILTER *)(ptr->allps + 2*i+1))->in_gain =
|
||||
((ALLP_FILTER *)(ptr->allps + 2*i))->in_gain;
|
||||
|
||||
if (*(ptr->stereo_enh) > 0.0f) {
|
||||
if (i % 2 == 0)
|
||||
((ALLP_FILTER *)(ptr->allps + 2*i+1))->buflen =
|
||||
ENH_STEREO_RATIO * ((ALLP_FILTER *)(ptr->allps + 2*i))->buflen;
|
||||
else
|
||||
((ALLP_FILTER *)(ptr->allps + 2*i))->buflen =
|
||||
ENH_STEREO_RATIO * ((ALLP_FILTER *)(ptr->allps + 2*i+1))->buflen;
|
||||
} else {
|
||||
if (i % 2 == 0)
|
||||
((ALLP_FILTER *)(ptr->allps + 2*i+1))->buflen =
|
||||
((ALLP_FILTER *)(ptr->allps + 2*i))->buflen;
|
||||
else
|
||||
((ALLP_FILTER *)(ptr->allps + 2*i))->buflen =
|
||||
((ALLP_FILTER *)(ptr->allps + 2*i+1))->buflen;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Construct a new plugin instance. */
|
||||
LADSPA_Handle
|
||||
instantiate_Reverb(const LADSPA_Descriptor * Descriptor,
|
||||
unsigned long SampleRate) {
|
||||
|
||||
unsigned long i;
|
||||
LADSPA_Handle * p;
|
||||
Reverb * ptr = NULL;
|
||||
|
||||
if ((p = malloc(sizeof(Reverb))) != NULL) {
|
||||
((Reverb *)p)->sample_rate = SampleRate;
|
||||
((Reverb *)p)->run_adding_gain = 1.0f;
|
||||
|
||||
ptr = (Reverb *)p;
|
||||
|
||||
/* allocate memory for comb/allpass filters and other dynamic vars */
|
||||
if ((ptr->combs =
|
||||
calloc(2 * MAX_COMBS, sizeof(COMB_FILTER))) == NULL)
|
||||
return NULL;
|
||||
for (i = 0; i < 2 * MAX_COMBS; i++) {
|
||||
if ((((COMB_FILTER *)(ptr->combs + i))->ringbuffer =
|
||||
calloc((unsigned long)MAX_COMB_DELAY * ptr->sample_rate / 1000,
|
||||
sizeof(LADSPA_Data))) == NULL)
|
||||
return NULL;
|
||||
if ((((COMB_FILTER *)(ptr->combs + i))->buffer_pos =
|
||||
calloc(1, sizeof(unsigned long))) == NULL)
|
||||
return NULL;
|
||||
if ((((COMB_FILTER *)(ptr->combs + i))->filter =
|
||||
calloc(1, sizeof(biquad))) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((ptr->allps =
|
||||
calloc(2 * MAX_ALLPS, sizeof(ALLP_FILTER))) == NULL)
|
||||
return NULL;
|
||||
for (i = 0; i < 2 * MAX_ALLPS; i++) {
|
||||
if ((((ALLP_FILTER *)(ptr->allps + i))->ringbuffer =
|
||||
calloc((unsigned long)MAX_ALLP_DELAY * ptr->sample_rate / 1000,
|
||||
sizeof(LADSPA_Data))) == NULL)
|
||||
return NULL;
|
||||
if ((((ALLP_FILTER *)(ptr->allps + i))->buffer_pos =
|
||||
calloc(1, sizeof(unsigned long))) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((ptr->low_pass =
|
||||
calloc(2, sizeof(biquad))) == NULL)
|
||||
return NULL;
|
||||
if ((ptr->high_pass =
|
||||
calloc(2, sizeof(biquad))) == NULL)
|
||||
return NULL;
|
||||
|
||||
return p;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* activate a plugin instance */
|
||||
void
|
||||
activate_Reverb(LADSPA_Handle Instance) {
|
||||
|
||||
Reverb * ptr = (Reverb *)Instance;
|
||||
unsigned long i,j;
|
||||
|
||||
for (i = 0; i < 2 * MAX_COMBS; i++) {
|
||||
for (j = 0; j < (unsigned long)MAX_COMB_DELAY * ptr->sample_rate / 1000; j++)
|
||||
((COMB_FILTER *)(ptr->combs + i))->ringbuffer[j] = 0.0f;
|
||||
*(((COMB_FILTER *)(ptr->combs + i))->buffer_pos) = 0;
|
||||
((COMB_FILTER *)(ptr->combs + i))->last_out = 0;
|
||||
biquad_init(((COMB_FILTER *)(ptr->combs + i))->filter);
|
||||
}
|
||||
|
||||
for (i = 0; i < 2 * MAX_ALLPS; i++) {
|
||||
for (j = 0; j < (unsigned long)MAX_ALLP_DELAY * ptr->sample_rate / 1000; j++)
|
||||
((ALLP_FILTER *)(ptr->allps + i))->ringbuffer[j] = 0.0f;
|
||||
*(((ALLP_FILTER *)(ptr->allps + i))->buffer_pos) = 0;
|
||||
((ALLP_FILTER *)(ptr->allps + i))->last_out = 0;
|
||||
}
|
||||
|
||||
biquad_init(ptr->low_pass);
|
||||
biquad_init((biquad *)(ptr->low_pass + 1));
|
||||
biquad_init(ptr->high_pass);
|
||||
biquad_init((biquad *)(ptr->high_pass + 1));
|
||||
|
||||
ptr->old_decay = -10.0f;
|
||||
ptr->old_stereo_enh = -10.0f;
|
||||
ptr->old_mode = -10.0f;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Connect a port to a data location. */
|
||||
void
|
||||
connect_port_Reverb(LADSPA_Handle Instance,
|
||||
unsigned long Port,
|
||||
LADSPA_Data * DataLocation) {
|
||||
|
||||
Reverb * ptr = (Reverb *)Instance;
|
||||
|
||||
switch (Port) {
|
||||
case DECAY:
|
||||
ptr->decay = DataLocation;
|
||||
break;
|
||||
case DRYLEVEL:
|
||||
ptr->drylevel = DataLocation;
|
||||
break;
|
||||
case WETLEVEL:
|
||||
ptr->wetlevel = DataLocation;
|
||||
break;
|
||||
case COMBS_EN:
|
||||
ptr->combs_en = DataLocation;
|
||||
break;
|
||||
case ALLPS_EN:
|
||||
ptr->allps_en = DataLocation;
|
||||
break;
|
||||
case BANDPASS_EN:
|
||||
ptr->bandpass_en = DataLocation;
|
||||
break;
|
||||
case STEREO_ENH:
|
||||
ptr->stereo_enh = DataLocation;
|
||||
break;
|
||||
case MODE:
|
||||
ptr->mode = DataLocation;
|
||||
break;
|
||||
case INPUT_L:
|
||||
ptr->input_L = DataLocation;
|
||||
break;
|
||||
case OUTPUT_L:
|
||||
ptr->output_L = DataLocation;
|
||||
break;
|
||||
case INPUT_R:
|
||||
ptr->input_R = DataLocation;
|
||||
break;
|
||||
case OUTPUT_R:
|
||||
ptr->output_R = DataLocation;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
run_Reverb(LADSPA_Handle Instance,
|
||||
unsigned long SampleCount) {
|
||||
|
||||
Reverb * ptr = (Reverb *)Instance;
|
||||
|
||||
unsigned long sample_index;
|
||||
int i;
|
||||
|
||||
LADSPA_Data decay = LIMIT(*(ptr->decay),0.0f,10000.0f);
|
||||
LADSPA_Data drylevel = db2lin(LIMIT(*(ptr->drylevel),-70.0f,10.0f));
|
||||
LADSPA_Data wetlevel = db2lin(LIMIT(*(ptr->wetlevel),-70.0f,10.0f));
|
||||
LADSPA_Data combs_en = LIMIT(*(ptr->combs_en),-2.0f,2.0f);
|
||||
LADSPA_Data allps_en = LIMIT(*(ptr->allps_en),-2.0f,2.0f);
|
||||
LADSPA_Data bandpass_en = LIMIT(*(ptr->bandpass_en),-2.0f,2.0f);
|
||||
LADSPA_Data stereo_enh = LIMIT(*(ptr->stereo_enh),-2.0f,2.0f);
|
||||
LADSPA_Data mode = LIMIT(*(ptr->mode),0,NUM_MODES-1);
|
||||
|
||||
LADSPA_Data * input_L = ptr->input_L;
|
||||
LADSPA_Data * output_L = ptr->output_L;
|
||||
LADSPA_Data * input_R = ptr->input_R;
|
||||
LADSPA_Data * output_R = ptr->output_R;
|
||||
|
||||
rev_t out_L = 0;
|
||||
rev_t out_R = 0;
|
||||
rev_t in_L = 0;
|
||||
rev_t in_R = 0;
|
||||
rev_t combs_out_L = 0;
|
||||
rev_t combs_out_R = 0;
|
||||
|
||||
|
||||
/* see if the user changed any control since last run */
|
||||
if ((ptr->old_decay != decay) ||
|
||||
(ptr->old_stereo_enh != stereo_enh) ||
|
||||
(ptr->old_mode != mode)) {
|
||||
|
||||
/* re-compute reverberator coefficients */
|
||||
comp_coeffs(Instance);
|
||||
|
||||
/* save new values */
|
||||
ptr->old_decay = decay;
|
||||
ptr->old_stereo_enh = stereo_enh;
|
||||
ptr->old_mode = mode;
|
||||
}
|
||||
|
||||
for (sample_index = 0; sample_index < SampleCount; sample_index++) {
|
||||
|
||||
#ifdef REVERB_CALC_FLOAT
|
||||
in_L = *(input_L++);
|
||||
in_R = *(input_R++);
|
||||
#else
|
||||
in_L = (sample)((float)F2S * *(input_L++));
|
||||
in_R = (sample)((float)F2S * *(input_R++));
|
||||
#endif
|
||||
|
||||
combs_out_L = in_L;
|
||||
combs_out_R = in_R;
|
||||
|
||||
/* process comb filters */
|
||||
if (combs_en > 0.0f) {
|
||||
for (i = 0; i < ptr->num_combs / 2; i++) {
|
||||
combs_out_L +=
|
||||
comb_run(in_L, ((COMB_FILTER *)(ptr->combs + 2*i)));
|
||||
combs_out_R +=
|
||||
comb_run(in_R, ((COMB_FILTER *)(ptr->combs + 2*i+1)));
|
||||
}
|
||||
}
|
||||
|
||||
/* process allpass filters */
|
||||
if (allps_en > 0.0f) {
|
||||
for (i = 0; i < ptr->num_allps / 2; i++) {
|
||||
combs_out_L += allp_run(combs_out_L,
|
||||
((ALLP_FILTER *)(ptr->allps + 2*i)));
|
||||
combs_out_R += allp_run(combs_out_R,
|
||||
((ALLP_FILTER *)(ptr->allps + 2*i+1)));
|
||||
}
|
||||
}
|
||||
|
||||
/* process bandpass filters */
|
||||
if (bandpass_en > 0.0f) {
|
||||
combs_out_L =
|
||||
biquad_run(((biquad *)(ptr->low_pass)), combs_out_L);
|
||||
combs_out_L =
|
||||
biquad_run(((biquad *)(ptr->high_pass)), combs_out_L);
|
||||
combs_out_R =
|
||||
biquad_run(((biquad *)(ptr->low_pass + 1)), combs_out_R);
|
||||
combs_out_R =
|
||||
biquad_run(((biquad *)(ptr->high_pass + 1)), combs_out_R);
|
||||
}
|
||||
|
||||
#ifdef REVERB_CALC_FLOAT
|
||||
out_L = in_L * drylevel + combs_out_L * wetlevel;
|
||||
out_R = in_R * drylevel + combs_out_R * wetlevel;
|
||||
*(output_L++) = out_L;
|
||||
*(output_R++) = out_R;
|
||||
#else
|
||||
out_L = (sample)((float)in_L * drylevel + (float)combs_out_L * wetlevel);
|
||||
out_R = (sample)((float)in_R * drylevel + (float)combs_out_R * wetlevel);
|
||||
*(output_L++) = (float)out_L / (float)F2S;
|
||||
*(output_R++) = (float)out_R / (float)F2S;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void
|
||||
set_run_adding_gain(LADSPA_Handle Instance, LADSPA_Data gain){
|
||||
|
||||
Reverb * ptr;
|
||||
|
||||
ptr = (Reverb *)Instance;
|
||||
|
||||
ptr->run_adding_gain = gain;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
run_adding_gain_Reverb(LADSPA_Handle Instance,
|
||||
unsigned long SampleCount) {
|
||||
|
||||
Reverb * ptr = (Reverb *)Instance;
|
||||
|
||||
unsigned long sample_index;
|
||||
int i;
|
||||
|
||||
LADSPA_Data decay = LIMIT(*(ptr->decay),0.0f,10000.0f);
|
||||
LADSPA_Data drylevel = db2lin(LIMIT(*(ptr->drylevel),-70.0f,10.0f));
|
||||
LADSPA_Data wetlevel = db2lin(LIMIT(*(ptr->wetlevel),-70.0f,10.0f));
|
||||
LADSPA_Data combs_en = LIMIT(*(ptr->combs_en),-2.0f,2.0f);
|
||||
LADSPA_Data allps_en = LIMIT(*(ptr->allps_en),-2.0f,2.0f);
|
||||
LADSPA_Data bandpass_en = LIMIT(*(ptr->bandpass_en),-2.0f,2.0f);
|
||||
LADSPA_Data stereo_enh = LIMIT(*(ptr->stereo_enh),-2.0f,2.0f);
|
||||
LADSPA_Data mode = LIMIT(*(ptr->mode),0,NUM_MODES-1);
|
||||
|
||||
LADSPA_Data * input_L = ptr->input_L;
|
||||
LADSPA_Data * output_L = ptr->output_L;
|
||||
LADSPA_Data * input_R = ptr->input_R;
|
||||
LADSPA_Data * output_R = ptr->output_R;
|
||||
|
||||
rev_t out_L = 0;
|
||||
rev_t out_R = 0;
|
||||
rev_t in_L = 0;
|
||||
rev_t in_R = 0;
|
||||
rev_t combs_out_L = 0;
|
||||
rev_t combs_out_R = 0;
|
||||
|
||||
|
||||
/* see if the user changed any control since last run */
|
||||
if ((ptr->old_decay != decay) ||
|
||||
(ptr->old_stereo_enh != stereo_enh) ||
|
||||
(ptr->old_mode != mode)) {
|
||||
|
||||
/* re-compute reverberator coefficients */
|
||||
comp_coeffs(Instance);
|
||||
|
||||
/* save new values */
|
||||
ptr->old_decay = decay;
|
||||
ptr->old_stereo_enh = stereo_enh;
|
||||
ptr->old_mode = mode;
|
||||
}
|
||||
|
||||
for (sample_index = 0; sample_index < SampleCount; sample_index++) {
|
||||
|
||||
#ifdef REVERB_CALC_FLOAT
|
||||
in_L = *(input_L++);
|
||||
in_R = *(input_R++);
|
||||
#else
|
||||
in_L = (sample)((float)F2S * *(input_L++));
|
||||
in_R = (sample)((float)F2S * *(input_R++));
|
||||
#endif
|
||||
|
||||
combs_out_L = in_L;
|
||||
combs_out_R = in_R;
|
||||
|
||||
/* process comb filters */
|
||||
if (combs_en > 0.0f) {
|
||||
for (i = 0; i < ptr->num_combs / 2; i++) {
|
||||
combs_out_L +=
|
||||
comb_run(in_L, ((COMB_FILTER *)(ptr->combs + 2*i)));
|
||||
combs_out_R +=
|
||||
comb_run(in_R, ((COMB_FILTER *)(ptr->combs + 2*i+1)));
|
||||
}
|
||||
}
|
||||
|
||||
/* process allpass filters */
|
||||
if (allps_en > 0.0f) {
|
||||
for (i = 0; i < ptr->num_allps / 2; i++) {
|
||||
combs_out_L += allp_run(combs_out_L,
|
||||
((ALLP_FILTER *)(ptr->allps + 2*i)));
|
||||
combs_out_R += allp_run(combs_out_R,
|
||||
((ALLP_FILTER *)(ptr->allps + 2*i+1)));
|
||||
}
|
||||
}
|
||||
|
||||
/* process bandpass filters */
|
||||
if (bandpass_en > 0.0f) {
|
||||
combs_out_L =
|
||||
biquad_run(((biquad *)(ptr->low_pass)), combs_out_L);
|
||||
combs_out_L =
|
||||
biquad_run(((biquad *)(ptr->high_pass)), combs_out_L);
|
||||
combs_out_R =
|
||||
biquad_run(((biquad *)(ptr->low_pass + 1)), combs_out_R);
|
||||
combs_out_R =
|
||||
biquad_run(((biquad *)(ptr->high_pass + 1)), combs_out_R);
|
||||
}
|
||||
|
||||
#ifdef REVERB_CALC_FLOAT
|
||||
out_L = in_L * drylevel + combs_out_L * wetlevel;
|
||||
out_R = in_R * drylevel + combs_out_R * wetlevel;
|
||||
*(output_L++) += out_L * ptr->run_adding_gain;
|
||||
*(output_R++) += out_R * ptr->run_adding_gain;
|
||||
#else
|
||||
out_L = (sample)((float)in_L * drylevel + (float)combs_out_L * wetlevel);
|
||||
out_R = (sample)((float)in_R * drylevel + (float)combs_out_R * wetlevel);
|
||||
*(output_L++) += (float)out_L * ptr->run_adding_gain / (float)F2S;
|
||||
*(output_R++) += (float)out_R * ptr->run_adding_gain / (float)F2S;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Throw away a Reverb effect instance. */
|
||||
void
|
||||
cleanup_Reverb(LADSPA_Handle Instance) {
|
||||
|
||||
int i;
|
||||
Reverb * ptr = (Reverb *)Instance;
|
||||
|
||||
/* free memory allocated for comb/allpass filters & co. in instantiate_Reverb() */
|
||||
for (i = 0; i < 2 * MAX_COMBS; i++) {
|
||||
free(((COMB_FILTER *)(ptr->combs + i))->ringbuffer);
|
||||
free(((COMB_FILTER *)(ptr->combs + i))->buffer_pos);
|
||||
free(((COMB_FILTER *)(ptr->combs + i))->filter);
|
||||
}
|
||||
for (i = 0; i < 2 * MAX_ALLPS; i++) {
|
||||
free(((ALLP_FILTER *)(ptr->allps + i))->ringbuffer);
|
||||
free(((ALLP_FILTER *)(ptr->allps + i))->buffer_pos);
|
||||
}
|
||||
|
||||
free(ptr->combs);
|
||||
free(ptr->allps);
|
||||
free(ptr->low_pass);
|
||||
free(ptr->high_pass);
|
||||
|
||||
free(Instance);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
LADSPA_Descriptor * stereo_descriptor = NULL;
|
||||
|
||||
|
||||
|
||||
/* _init() is called automatically when the plugin library is first
|
||||
loaded. */
|
||||
void
|
||||
_init() {
|
||||
|
||||
char ** port_names;
|
||||
LADSPA_PortDescriptor * port_descriptors;
|
||||
LADSPA_PortRangeHint * port_range_hints;
|
||||
|
||||
|
||||
if ((stereo_descriptor =
|
||||
(LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor))) == NULL)
|
||||
exit(1);
|
||||
|
||||
|
||||
/* init the stereo Reverb */
|
||||
|
||||
stereo_descriptor->UniqueID = ID_STEREO;
|
||||
stereo_descriptor->Label = strdup("tap_reverb");
|
||||
stereo_descriptor->Properties = 0;
|
||||
stereo_descriptor->Name = strdup("TAP Reverberator");
|
||||
stereo_descriptor->Maker = strdup("Tom Szilagyi");
|
||||
stereo_descriptor->Copyright = strdup("GPL");
|
||||
stereo_descriptor->PortCount = PORTCOUNT_STEREO;
|
||||
|
||||
if ((port_descriptors =
|
||||
(LADSPA_PortDescriptor *)calloc(PORTCOUNT_STEREO, sizeof(LADSPA_PortDescriptor))) == NULL)
|
||||
exit(1);
|
||||
|
||||
stereo_descriptor->PortDescriptors = (const LADSPA_PortDescriptor *)port_descriptors;
|
||||
port_descriptors[DECAY] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[DRYLEVEL] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[WETLEVEL] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[COMBS_EN] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[ALLPS_EN] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[BANDPASS_EN] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[STEREO_ENH] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[MODE] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
|
||||
port_descriptors[INPUT_L] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
|
||||
port_descriptors[OUTPUT_L] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
|
||||
port_descriptors[INPUT_R] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
|
||||
port_descriptors[OUTPUT_R] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
|
||||
|
||||
if ((port_names =
|
||||
(char **)calloc(PORTCOUNT_STEREO, sizeof(char *))) == NULL)
|
||||
exit(1);
|
||||
|
||||
stereo_descriptor->PortNames = (const char **)port_names;
|
||||
|
||||
port_names[DECAY] = strdup("Decay [ms]");
|
||||
port_names[DRYLEVEL] = strdup("Dry Level [dB]");
|
||||
port_names[WETLEVEL] = strdup("Wet Level [dB]");
|
||||
port_names[COMBS_EN] = strdup("Comb Filters");
|
||||
port_names[ALLPS_EN] = strdup("Allpass Filters");
|
||||
port_names[BANDPASS_EN] = strdup("Bandpass Filter");
|
||||
port_names[STEREO_ENH] = strdup("Enhanced Stereo");
|
||||
port_names[MODE] = strdup("Reverb Type");
|
||||
port_names[INPUT_L] = strdup("Input Left");
|
||||
port_names[OUTPUT_L] = strdup("Output Left");
|
||||
port_names[INPUT_R] = strdup("Input Right");
|
||||
port_names[OUTPUT_R] = strdup("Output Right");
|
||||
|
||||
if ((port_range_hints =
|
||||
((LADSPA_PortRangeHint *)calloc(PORTCOUNT_STEREO, sizeof(LADSPA_PortRangeHint)))) == NULL)
|
||||
exit(1);
|
||||
|
||||
stereo_descriptor->PortRangeHints = (const LADSPA_PortRangeHint *)port_range_hints;
|
||||
|
||||
port_range_hints[DECAY].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_LOW);
|
||||
port_range_hints[DECAY].LowerBound = 0;
|
||||
port_range_hints[DECAY].UpperBound = MAX_DECAY;
|
||||
|
||||
port_range_hints[DRYLEVEL].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[DRYLEVEL].LowerBound = -70.0f;
|
||||
port_range_hints[DRYLEVEL].UpperBound = +10.0f;
|
||||
|
||||
port_range_hints[WETLEVEL].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[WETLEVEL].LowerBound = -70.0f;
|
||||
port_range_hints[WETLEVEL].UpperBound = +10.0f;
|
||||
|
||||
port_range_hints[COMBS_EN].HintDescriptor =
|
||||
(LADSPA_HINT_TOGGLED |
|
||||
LADSPA_HINT_DEFAULT_1);
|
||||
|
||||
port_range_hints[ALLPS_EN].HintDescriptor =
|
||||
(LADSPA_HINT_TOGGLED |
|
||||
LADSPA_HINT_DEFAULT_1);
|
||||
|
||||
port_range_hints[BANDPASS_EN].HintDescriptor =
|
||||
(LADSPA_HINT_TOGGLED |
|
||||
LADSPA_HINT_DEFAULT_1);
|
||||
|
||||
port_range_hints[STEREO_ENH].HintDescriptor =
|
||||
(LADSPA_HINT_TOGGLED |
|
||||
LADSPA_HINT_DEFAULT_1);
|
||||
|
||||
port_range_hints[MODE].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_INTEGER |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[MODE].LowerBound = 0;
|
||||
port_range_hints[MODE].UpperBound = NUM_MODES - 0.9f;
|
||||
|
||||
port_range_hints[INPUT_L].HintDescriptor = 0;
|
||||
port_range_hints[OUTPUT_L].HintDescriptor = 0;
|
||||
port_range_hints[INPUT_R].HintDescriptor = 0;
|
||||
port_range_hints[OUTPUT_R].HintDescriptor = 0;
|
||||
|
||||
|
||||
stereo_descriptor->instantiate = instantiate_Reverb;
|
||||
stereo_descriptor->connect_port = connect_port_Reverb;
|
||||
stereo_descriptor->activate = activate_Reverb;
|
||||
stereo_descriptor->run = run_Reverb;
|
||||
stereo_descriptor->run_adding = run_adding_gain_Reverb;
|
||||
stereo_descriptor->set_run_adding_gain = set_run_adding_gain;
|
||||
stereo_descriptor->deactivate = NULL;
|
||||
stereo_descriptor->cleanup = cleanup_Reverb;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
delete_descriptor(LADSPA_Descriptor * descriptor) {
|
||||
unsigned long index;
|
||||
if (descriptor) {
|
||||
free((char *)descriptor->Label);
|
||||
free((char *)descriptor->Name);
|
||||
free((char *)descriptor->Maker);
|
||||
free((char *)descriptor->Copyright);
|
||||
free((LADSPA_PortDescriptor *)descriptor->PortDescriptors);
|
||||
for (index = 0; index < descriptor->PortCount; index++)
|
||||
free((char *)(descriptor->PortNames[index]));
|
||||
free((char **)descriptor->PortNames);
|
||||
free((LADSPA_PortRangeHint *)descriptor->PortRangeHints);
|
||||
free(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* _fini() is called automatically when the library is unloaded. */
|
||||
void
|
||||
_fini() {
|
||||
delete_descriptor(stereo_descriptor);
|
||||
}
|
||||
|
||||
|
||||
/* Return a descriptor of the requested plugin type. */
|
||||
const LADSPA_Descriptor *
|
||||
ladspa_descriptor(unsigned long Index) {
|
||||
|
||||
switch (Index) {
|
||||
case 0:
|
||||
return stereo_descriptor;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
287
plugins/ladspa_effect/tap/tap_reverb.h
Normal file
287
plugins/ladspa_effect/tap/tap_reverb.h
Normal file
@@ -0,0 +1,287 @@
|
||||
/* -*- linux-c -*-
|
||||
Copyright (C) 2004 Tom Szilagyi
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: tap_reverb.h,v 1.10 2004/06/14 16:43:55 tszilagyi Exp $
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* The Unique ID of the plugin: */
|
||||
|
||||
#define ID_STEREO 2142
|
||||
|
||||
/* The port numbers for the plugin: */
|
||||
|
||||
#define DECAY 0
|
||||
#define DRYLEVEL 1
|
||||
#define WETLEVEL 2
|
||||
#define COMBS_EN 3 /* comb filters on/off */
|
||||
#define ALLPS_EN 4 /* allpass filters on/off */
|
||||
#define BANDPASS_EN 5 /* bandpass filters on/off */
|
||||
#define STEREO_ENH 6 /* stereo enhanced mode on/off */
|
||||
#define MODE 7
|
||||
|
||||
#define INPUT_L 8
|
||||
#define OUTPUT_L 9
|
||||
#define INPUT_R 10
|
||||
#define OUTPUT_R 11
|
||||
|
||||
/* Total number of ports */
|
||||
|
||||
#define PORTCOUNT_STEREO 12
|
||||
|
||||
/* Global constants (times in ms, bwidth in octaves) */
|
||||
|
||||
#define MAX_COMBS 20
|
||||
#define MAX_ALLPS 20
|
||||
#define MAX_DECAY 10000.0f
|
||||
#define MAX_COMB_DELAY 250.0f
|
||||
#define MAX_ALLP_DELAY 20.0f
|
||||
#define BANDPASS_BWIDTH 1.5f
|
||||
#define FREQ_RESP_BWIDTH 3.0f
|
||||
#define ENH_STEREO_RATIO 0.998f
|
||||
|
||||
/* compensation ratio of freq_resp in fb_gain calc */
|
||||
#define FR_R_COMP 0.75f
|
||||
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846264338327
|
||||
#endif
|
||||
|
||||
|
||||
/* push a sample into a ringbuffer and return the sample falling out */
|
||||
static inline
|
||||
rev_t
|
||||
push_buffer(rev_t insample, rev_t * buffer,
|
||||
unsigned long buflen, unsigned long * pos) {
|
||||
|
||||
rev_t outsample;
|
||||
|
||||
outsample = buffer[*pos];
|
||||
buffer[(*pos)++] = insample;
|
||||
|
||||
if (*pos >= buflen)
|
||||
*pos = 0;
|
||||
|
||||
return outsample;
|
||||
}
|
||||
|
||||
/* read a value from a ringbuffer.
|
||||
* n == 0 returns the oldest sample from the buffer.
|
||||
* n == buflen-1 returns the sample written to the buffer
|
||||
* at the last push_buffer call.
|
||||
* n must not exceed buflen-1, or your computer will explode.
|
||||
*/
|
||||
static inline
|
||||
rev_t
|
||||
read_buffer(rev_t * buffer, unsigned long buflen,
|
||||
unsigned long pos, unsigned long n) {
|
||||
|
||||
while (n + pos >= buflen)
|
||||
n -= buflen;
|
||||
return buffer[n + pos];
|
||||
}
|
||||
|
||||
|
||||
/* overwrites a value in a ringbuffer, but pos stays the same.
|
||||
* n == 0 overwrites the oldest sample pushed in the buffer.
|
||||
* n == buflen-1 overwrites the sample written to the buffer
|
||||
* at the last push_buffer call.
|
||||
* n must not exceed buflen-1, or your computer... you know.
|
||||
*/
|
||||
static inline
|
||||
void
|
||||
write_buffer(rev_t insample, rev_t * buffer, unsigned long buflen,
|
||||
unsigned long pos, unsigned long n) {
|
||||
|
||||
while (n + pos >= buflen)
|
||||
n -= buflen;
|
||||
buffer[n + pos] = insample;
|
||||
}
|
||||
|
||||
#define db2lin(x) ((x) > -90.0f ? powf(10.0f, (x) * 0.05f) : 0.0f)
|
||||
#define ABS(x) (x)>0.0f?(x):-1.0f*(x)
|
||||
#define LN_2_2 0.34657359f
|
||||
#define FLUSH_TO_ZERO(x) (((*(unsigned int*)&(x))&0x7f800000)==0)?0.0f:(x)
|
||||
#define LIMIT(v,l,u) ((v)<(l)?(l):((v)>(u)?(u):(v)))
|
||||
|
||||
#define BIQUAD_TYPE float
|
||||
typedef BIQUAD_TYPE bq_t;
|
||||
|
||||
typedef struct {
|
||||
bq_t a1;
|
||||
bq_t a2;
|
||||
bq_t b0;
|
||||
bq_t b1;
|
||||
bq_t b2;
|
||||
rev_t x1;
|
||||
rev_t x2;
|
||||
rev_t y1;
|
||||
rev_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) {
|
||||
|
||||
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 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
|
||||
rev_t
|
||||
biquad_run(biquad *f, rev_t x) {
|
||||
|
||||
rev_t y;
|
||||
|
||||
y = f->b0 * x + f->b1 * f->x1 + f->b2 * f->x2
|
||||
+ f->a1 * f->y1 + f->a2 * f->y2;
|
||||
#ifdef REVERB_CALC_FLOAT
|
||||
y = FLUSH_TO_ZERO(y);
|
||||
#endif
|
||||
f->x2 = f->x1;
|
||||
f->x1 = x;
|
||||
f->y2 = f->y1;
|
||||
f->y1 = y;
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
float feedback;
|
||||
float fb_gain;
|
||||
float freq_resp;
|
||||
rev_t * ringbuffer;
|
||||
unsigned long buflen;
|
||||
unsigned long * buffer_pos;
|
||||
biquad * filter;
|
||||
rev_t last_out;
|
||||
} COMB_FILTER;
|
||||
|
||||
typedef struct {
|
||||
float feedback;
|
||||
float fb_gain;
|
||||
float in_gain;
|
||||
rev_t * ringbuffer;
|
||||
unsigned long buflen;
|
||||
unsigned long * buffer_pos;
|
||||
rev_t last_out;
|
||||
} ALLP_FILTER;
|
||||
|
||||
|
||||
/* The structure used to hold port connection information and state */
|
||||
|
||||
typedef struct {
|
||||
unsigned long num_combs; /* total number of comb filters */
|
||||
unsigned long num_allps; /* total number of allpass filters */
|
||||
COMB_FILTER * combs;
|
||||
ALLP_FILTER * allps;
|
||||
biquad * low_pass; /* ptr to 2 low-pass filters */
|
||||
biquad * high_pass; /* ptr to 2 high-pass filters */
|
||||
unsigned long sample_rate;
|
||||
|
||||
LADSPA_Data * decay;
|
||||
LADSPA_Data * drylevel;
|
||||
LADSPA_Data * wetlevel;
|
||||
LADSPA_Data * combs_en; /* on/off */
|
||||
LADSPA_Data * allps_en; /* on/off */
|
||||
LADSPA_Data * bandpass_en; /* on/off */
|
||||
LADSPA_Data * stereo_enh; /* on/off */
|
||||
LADSPA_Data * mode;
|
||||
|
||||
LADSPA_Data * input_L;
|
||||
LADSPA_Data * output_L;
|
||||
LADSPA_Data * input_R;
|
||||
LADSPA_Data * output_R;
|
||||
|
||||
LADSPA_Data old_decay;
|
||||
LADSPA_Data old_stereo_enh;
|
||||
LADSPA_Data old_mode;
|
||||
|
||||
LADSPA_Data run_adding_gain;
|
||||
} Reverb;
|
||||
|
||||
typedef struct {
|
||||
LADSPA_Data delay;
|
||||
LADSPA_Data feedback;
|
||||
LADSPA_Data freq_resp;
|
||||
} COMB_DATA;
|
||||
|
||||
typedef struct {
|
||||
LADSPA_Data delay;
|
||||
LADSPA_Data feedback;
|
||||
} ALLP_DATA;
|
||||
|
||||
typedef struct {
|
||||
unsigned long num_combs;
|
||||
unsigned long num_allps;
|
||||
COMB_DATA combs[MAX_COMBS];
|
||||
ALLP_DATA allps[MAX_ALLPS];
|
||||
LADSPA_Data bandpass_low;
|
||||
LADSPA_Data bandpass_high;
|
||||
} REVERB_DATA;
|
||||
914
plugins/ladspa_effect/tap/tap_reverb_presets.h
Normal file
914
plugins/ladspa_effect/tap/tap_reverb_presets.h
Normal file
@@ -0,0 +1,914 @@
|
||||
/*
|
||||
Copyright (C) 2004 Tom Szilagyi
|
||||
|
||||
This file is the output of TAP Reverb Editor, and is part of TAP Reverberator.
|
||||
Please use TAP Reverb Editor to re-generate this file, rather than editing by hand.
|
||||
Visit http://tap-plugins.sf.net for more info.
|
||||
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "tap_reverb.h"
|
||||
|
||||
|
||||
/* Number of reverb presets */
|
||||
#define NUM_MODES 43
|
||||
|
||||
|
||||
/* Reverb Type data */
|
||||
REVERB_DATA reverb_data[NUM_MODES] = {
|
||||
{
|
||||
5,
|
||||
5,
|
||||
{
|
||||
{0.1015f, 70.22f, 0.4845f},
|
||||
{0.1042f, 80.76f, 0.4000f},
|
||||
{0.1108f, 65.25f, 0.4000f},
|
||||
{0.1309f, 80.00f, 0.5342f},
|
||||
{0.1386f, 52.84f, 0.4000f},
|
||||
},
|
||||
{
|
||||
{0.0067f, 65.00f},
|
||||
{0.0061f, 65.00f},
|
||||
{0.0059f, 65.00f},
|
||||
{0.0055f, 65.00f},
|
||||
{0.0101f, 80.00f},
|
||||
},
|
||||
400.0f,
|
||||
10000.0f,
|
||||
},
|
||||
{
|
||||
5,
|
||||
5,
|
||||
{
|
||||
{0.1077f, 70.22f, 0.4845f},
|
||||
{0.1124f, 80.76f, 0.4000f},
|
||||
{0.1185f, 65.25f, 0.4000f},
|
||||
{0.1866f, 80.00f, 0.5342f},
|
||||
{0.1943f, 52.84f, 0.4000f},
|
||||
},
|
||||
{
|
||||
{0.0067f, 65.00f},
|
||||
{0.0061f, 65.00f},
|
||||
{0.0059f, 65.00f},
|
||||
{0.0055f, 65.00f},
|
||||
{0.0101f, 80.00f},
|
||||
},
|
||||
400.0f,
|
||||
10000.0f,
|
||||
},
|
||||
{
|
||||
6,
|
||||
4,
|
||||
{
|
||||
{0.0251f, 64.80f, 0.2026f},
|
||||
{0.0306f, 70.48f, 0.2731f},
|
||||
{0.0350f, 67.40f, 0.5727f},
|
||||
{0.0405f, 72.69f, 0.3128f},
|
||||
{0.0449f, 61.23f, 0.7225f},
|
||||
{0.0515f, 67.84f, 0.6167f},
|
||||
},
|
||||
{
|
||||
{0.0056f, 75.00f},
|
||||
{0.0051f, 90.00f},
|
||||
{0.0048f, 85.00f},
|
||||
{0.0044f, 70.00f},
|
||||
},
|
||||
80.0f,
|
||||
15000.0f,
|
||||
},
|
||||
{
|
||||
6,
|
||||
8,
|
||||
{
|
||||
{0.0251f, 64.80f, 0.2026f},
|
||||
{0.0306f, 70.48f, 0.2731f},
|
||||
{0.0350f, 67.40f, 0.5727f},
|
||||
{0.0405f, 72.69f, 0.3128f},
|
||||
{0.0449f, 61.23f, 0.7225f},
|
||||
{0.0515f, 67.84f, 0.6167f},
|
||||
},
|
||||
{
|
||||
{0.0056f, 75.00f},
|
||||
{0.0051f, 90.00f},
|
||||
{0.0048f, 85.00f},
|
||||
{0.0044f, 70.00f},
|
||||
{0.0014f, 45.51f},
|
||||
{0.0015f, 77.95f},
|
||||
{0.0017f, 65.47f},
|
||||
{0.0019f, 57.57f},
|
||||
},
|
||||
80.0f,
|
||||
15000.0f,
|
||||
},
|
||||
{
|
||||
8,
|
||||
11,
|
||||
{
|
||||
{0.0251f, 64.80f, 0.2026f},
|
||||
{0.0306f, 70.48f, 0.2731f},
|
||||
{0.0350f, 67.40f, 0.5727f},
|
||||
{0.0405f, 72.69f, 0.3128f},
|
||||
{0.0449f, 61.23f, 0.7225f},
|
||||
{0.0515f, 67.84f, 0.6167f},
|
||||
{0.0800f, 53.77f, 0.7048f},
|
||||
{0.0899f, 45.48f, 0.6960f},
|
||||
},
|
||||
{
|
||||
{0.0056f, 75.00f},
|
||||
{0.0051f, 90.00f},
|
||||
{0.0048f, 85.00f},
|
||||
{0.0044f, 70.00f},
|
||||
{0.0014f, 45.51f},
|
||||
{0.0015f, 77.95f},
|
||||
{0.0017f, 65.47f},
|
||||
{0.0019f, 57.57f},
|
||||
{0.0071f, 60.00f},
|
||||
{0.0111f, 80.00f},
|
||||
{0.0126f, 70.00f},
|
||||
},
|
||||
80.0f,
|
||||
15000.0f,
|
||||
},
|
||||
{
|
||||
8,
|
||||
4,
|
||||
{
|
||||
{0.2236f, 62.93f, 0.3416f},
|
||||
{0.2329f, 75.14f, 0.3602f},
|
||||
{0.2390f, 70.34f, 0.2687f},
|
||||
{0.2438f, 82.99f, 0.5093f},
|
||||
{0.2499f, 89.97f, 0.2467f},
|
||||
{0.2282f, 60.75f, 0.3416f},
|
||||
{0.1392f, 55.00f, 0.3744f},
|
||||
{0.1348f, 75.00f, 0.2467f},
|
||||
},
|
||||
{
|
||||
{0.0167f, 75.00f},
|
||||
{0.0163f, 65.00f},
|
||||
{0.0158f, 85.00f},
|
||||
{0.0155f, 80.00f},
|
||||
},
|
||||
100.0f,
|
||||
6500.0f,
|
||||
},
|
||||
{
|
||||
10,
|
||||
7,
|
||||
{
|
||||
{0.2236f, 62.93f, 0.3416f},
|
||||
{0.2329f, 75.14f, 0.3602f},
|
||||
{0.2390f, 70.34f, 0.2687f},
|
||||
{0.2438f, 82.99f, 0.5093f},
|
||||
{0.2499f, 89.97f, 0.2467f},
|
||||
{0.2282f, 60.75f, 0.3416f},
|
||||
{0.2352f, 52.90f, 0.3106f},
|
||||
{0.1392f, 55.00f, 0.3744f},
|
||||
{0.1469f, 68.00f, 0.5771f},
|
||||
{0.1348f, 75.00f, 0.2467f},
|
||||
},
|
||||
{
|
||||
{0.0167f, 75.00f},
|
||||
{0.0163f, 65.00f},
|
||||
{0.0158f, 85.00f},
|
||||
{0.0155f, 80.00f},
|
||||
{0.0064f, 85.00f},
|
||||
{0.0068f, 75.00f},
|
||||
{0.0072f, 65.00f},
|
||||
},
|
||||
100.0f,
|
||||
6500.0f,
|
||||
},
|
||||
{
|
||||
5,
|
||||
7,
|
||||
{
|
||||
{0.0520f, 70.22f, 0.4720f},
|
||||
{0.0598f, 80.76f, 0.4000f},
|
||||
{0.0644f, 65.25f, 0.4000f},
|
||||
{0.0737f, 80.00f, 0.6957f},
|
||||
{0.0845f, 52.84f, 0.7205f},
|
||||
},
|
||||
{
|
||||
{0.0049f, 67.11f},
|
||||
{0.0069f, 59.05f},
|
||||
{0.0073f, 87.59f},
|
||||
{0.0079f, 59.67f},
|
||||
{0.0085f, 65.87f},
|
||||
{0.0095f, 75.18f},
|
||||
{0.0100f, 71.46f},
|
||||
},
|
||||
400.0f,
|
||||
10000.0f,
|
||||
},
|
||||
{
|
||||
5,
|
||||
4,
|
||||
{
|
||||
{0.0280f, 82.20f, 0.4720f},
|
||||
{0.0303f, 80.20f, 0.5652f},
|
||||
{0.0325f, 77.30f, 0.6211f},
|
||||
{0.0389f, 75.30f, 0.5217f},
|
||||
{0.0415f, 59.67f, 0.6522f},
|
||||
},
|
||||
{
|
||||
{0.0067f, 65.00f},
|
||||
{0.0061f, 65.00f},
|
||||
{0.0059f, 65.00f},
|
||||
{0.0055f, 65.00f},
|
||||
},
|
||||
100.0f,
|
||||
10000.0f,
|
||||
},
|
||||
{
|
||||
5,
|
||||
5,
|
||||
{
|
||||
{0.0280f, 82.20f, 0.4720f},
|
||||
{0.0303f, 80.20f, 0.5652f},
|
||||
{0.0325f, 77.30f, 0.6211f},
|
||||
{0.0389f, 75.30f, 0.5217f},
|
||||
{0.0415f, 59.67f, 0.6522f},
|
||||
},
|
||||
{
|
||||
{0.0067f, 75.00f},
|
||||
{0.0061f, 65.00f},
|
||||
{0.0059f, 65.00f},
|
||||
{0.0055f, 65.00f},
|
||||
{0.0071f, 75.00f},
|
||||
},
|
||||
200.0f,
|
||||
15000.0f,
|
||||
},
|
||||
{
|
||||
6,
|
||||
5,
|
||||
{
|
||||
{0.1015f, 70.22f, 0.4845f},
|
||||
{0.1042f, 80.76f, 0.4000f},
|
||||
{0.1108f, 65.25f, 0.4000f},
|
||||
{0.1309f, 80.00f, 0.5342f},
|
||||
{0.1386f, 52.84f, 0.4000f},
|
||||
{0.0520f, 72.08f, 0.4000f},
|
||||
},
|
||||
{
|
||||
{0.0067f, 65.00f},
|
||||
{0.0061f, 65.00f},
|
||||
{0.0059f, 65.00f},
|
||||
{0.0055f, 65.00f},
|
||||
{0.0101f, 80.00f},
|
||||
},
|
||||
400.0f,
|
||||
10000.0f,
|
||||
},
|
||||
{
|
||||
7,
|
||||
4,
|
||||
{
|
||||
{0.0536f, 82.20f, 0.3416f},
|
||||
{0.0629f, 52.84f, 0.3602f},
|
||||
{0.0690f, 77.30f, 0.3168f},
|
||||
{0.0738f, 75.30f, 0.5093f},
|
||||
{0.0799f, 59.67f, 0.3106f},
|
||||
{0.1634f, 80.00f, 0.5652f},
|
||||
{0.1680f, 80.00f, 0.5714f},
|
||||
},
|
||||
{
|
||||
{0.0058f, 65.00f},
|
||||
{0.0055f, 65.00f},
|
||||
{0.0063f, 71.46f},
|
||||
{0.0069f, 80.00f},
|
||||
},
|
||||
600.0f,
|
||||
18000.0f,
|
||||
},
|
||||
{
|
||||
7,
|
||||
7,
|
||||
{
|
||||
{0.0536f, 82.20f, 0.3416f},
|
||||
{0.0629f, 52.84f, 0.3602f},
|
||||
{0.0690f, 77.30f, 0.3168f},
|
||||
{0.0738f, 75.30f, 0.5093f},
|
||||
{0.0799f, 59.67f, 0.3106f},
|
||||
{0.1634f, 80.00f, 0.5652f},
|
||||
{0.1680f, 80.00f, 0.5714f},
|
||||
},
|
||||
{
|
||||
{0.0058f, 65.00f},
|
||||
{0.0055f, 65.00f},
|
||||
{0.0063f, 71.46f},
|
||||
{0.0069f, 80.00f},
|
||||
{0.0121f, 80.00f},
|
||||
{0.0127f, 66.49f},
|
||||
{0.0137f, 88.21f},
|
||||
},
|
||||
600.0f,
|
||||
18000.0f,
|
||||
},
|
||||
{
|
||||
5,
|
||||
4,
|
||||
{
|
||||
{0.0536f, 82.20f, 0.4783f},
|
||||
{0.0629f, 52.84f, 0.4348f},
|
||||
{0.0690f, 77.30f, 0.5000f},
|
||||
{0.0738f, 75.30f, 0.4500f},
|
||||
{0.0799f, 59.67f, 0.4500f},
|
||||
},
|
||||
{
|
||||
{0.0067f, 65.00f},
|
||||
{0.0063f, 65.00f},
|
||||
{0.0058f, 65.00f},
|
||||
{0.0055f, 65.00f},
|
||||
},
|
||||
100.0f,
|
||||
8000.0f,
|
||||
},
|
||||
{
|
||||
5,
|
||||
4,
|
||||
{
|
||||
{0.0536f, 82.20f, 0.4000f},
|
||||
{0.0629f, 52.84f, 0.4348f},
|
||||
{0.0690f, 77.30f, 0.5000f},
|
||||
{0.0738f, 75.30f, 0.4500f},
|
||||
{0.0799f, 59.67f, 0.4500f},
|
||||
},
|
||||
{
|
||||
{0.0067f, 65.00f},
|
||||
{0.0063f, 65.00f},
|
||||
{0.0058f, 65.00f},
|
||||
{0.0055f, 65.00f},
|
||||
},
|
||||
100.0f,
|
||||
8000.0f,
|
||||
},
|
||||
{
|
||||
5,
|
||||
4,
|
||||
{
|
||||
{0.0586f, 82.20f, 0.4000f},
|
||||
{0.0679f, 52.84f, 0.4348f},
|
||||
{0.0740f, 77.30f, 0.5000f},
|
||||
{0.0788f, 75.30f, 0.4500f},
|
||||
{0.0849f, 59.67f, 0.4500f},
|
||||
},
|
||||
{
|
||||
{0.0067f, 65.00f},
|
||||
{0.0063f, 65.00f},
|
||||
{0.0058f, 65.00f},
|
||||
{0.0055f, 65.00f},
|
||||
},
|
||||
100.0f,
|
||||
8000.0f,
|
||||
},
|
||||
{
|
||||
5,
|
||||
7,
|
||||
{
|
||||
{0.0586f, 82.20f, 0.4000f},
|
||||
{0.0679f, 52.84f, 0.4348f},
|
||||
{0.0740f, 77.30f, 0.5000f},
|
||||
{0.0788f, 75.30f, 0.4500f},
|
||||
{0.0849f, 59.67f, 0.4500f},
|
||||
},
|
||||
{
|
||||
{0.0067f, 65.00f},
|
||||
{0.0063f, 65.00f},
|
||||
{0.0058f, 65.00f},
|
||||
{0.0055f, 65.00f},
|
||||
{0.0141f, 80.00f},
|
||||
{0.0133f, 57.19f},
|
||||
{0.0151f, 65.25f},
|
||||
},
|
||||
100.0f,
|
||||
8000.0f,
|
||||
},
|
||||
{
|
||||
5,
|
||||
4,
|
||||
{
|
||||
{0.0506f, 82.20f, 0.3416f},
|
||||
{0.0599f, 52.84f, 0.3602f},
|
||||
{0.0660f, 77.30f, 0.3168f},
|
||||
{0.0708f, 75.30f, 0.5093f},
|
||||
{0.0769f, 59.67f, 0.3106f},
|
||||
},
|
||||
{
|
||||
{0.0067f, 65.00f},
|
||||
{0.0063f, 65.00f},
|
||||
{0.0058f, 65.00f},
|
||||
{0.0055f, 65.00f},
|
||||
},
|
||||
100.0f,
|
||||
8000.0f,
|
||||
},
|
||||
{
|
||||
5,
|
||||
4,
|
||||
{
|
||||
{0.0536f, 82.20f, 0.3416f},
|
||||
{0.0629f, 52.84f, 0.3602f},
|
||||
{0.0690f, 77.30f, 0.3168f},
|
||||
{0.0738f, 75.30f, 0.5093f},
|
||||
{0.0799f, 59.67f, 0.3106f},
|
||||
},
|
||||
{
|
||||
{0.0067f, 65.00f},
|
||||
{0.0063f, 65.00f},
|
||||
{0.0058f, 65.00f},
|
||||
{0.0055f, 65.00f},
|
||||
},
|
||||
100.0f,
|
||||
8000.0f,
|
||||
},
|
||||
{
|
||||
7,
|
||||
4,
|
||||
{
|
||||
{0.0536f, 82.20f, 0.3416f},
|
||||
{0.0629f, 52.84f, 0.3602f},
|
||||
{0.0690f, 77.30f, 0.3168f},
|
||||
{0.0738f, 75.30f, 0.5093f},
|
||||
{0.0799f, 59.67f, 0.3106f},
|
||||
{0.0582f, 77.66f, 0.3416f},
|
||||
{0.0652f, 68.35f, 0.3106f},
|
||||
},
|
||||
{
|
||||
{0.0067f, 65.00f},
|
||||
{0.0063f, 65.00f},
|
||||
{0.0058f, 65.00f},
|
||||
{0.0055f, 65.00f},
|
||||
},
|
||||
100.0f,
|
||||
8000.0f,
|
||||
},
|
||||
{
|
||||
7,
|
||||
6,
|
||||
{
|
||||
{0.0536f, 82.20f, 0.3416f},
|
||||
{0.0629f, 52.84f, 0.3602f},
|
||||
{0.0690f, 77.30f, 0.3168f},
|
||||
{0.0738f, 75.30f, 0.5093f},
|
||||
{0.0799f, 59.67f, 0.3106f},
|
||||
{0.0582f, 77.66f, 0.3416f},
|
||||
{0.0652f, 68.35f, 0.3106f},
|
||||
},
|
||||
{
|
||||
{0.0067f, 65.00f},
|
||||
{0.0063f, 65.00f},
|
||||
{0.0058f, 65.00f},
|
||||
{0.0055f, 65.00f},
|
||||
{0.0126f, 70.84f},
|
||||
{0.0138f, 86.35f},
|
||||
},
|
||||
100.0f,
|
||||
8000.0f,
|
||||
},
|
||||
{
|
||||
4,
|
||||
4,
|
||||
{
|
||||
{0.0752f, 61.53f, 0.4000f},
|
||||
{0.0536f, 28.64f, 0.4000f},
|
||||
{0.0907f, 85.11f, 0.4000f},
|
||||
{0.0660f, 47.88f, 0.4000f},
|
||||
},
|
||||
{
|
||||
{0.0039f, 80.00f},
|
||||
{0.0043f, 70.84f},
|
||||
{0.0045f, 58.43f},
|
||||
{0.0049f, 43.53f},
|
||||
},
|
||||
50.0f,
|
||||
10000.0f,
|
||||
},
|
||||
{
|
||||
4,
|
||||
4,
|
||||
{
|
||||
{0.1742f, 47.26f, 0.4783f},
|
||||
{0.1526f, 23.06f, 0.1863f},
|
||||
{0.2021f, 72.08f, 0.4000f},
|
||||
{0.2175f, 90.07f, 0.4000f},
|
||||
},
|
||||
{
|
||||
{0.0039f, 80.00f},
|
||||
{0.0043f, 70.84f},
|
||||
{0.0045f, 58.43f},
|
||||
{0.0049f, 43.53f},
|
||||
},
|
||||
50.0f,
|
||||
10000.0f,
|
||||
},
|
||||
{
|
||||
4,
|
||||
2,
|
||||
{
|
||||
{0.0969f, 52.22f, 0.6149f},
|
||||
{0.0984f, 54.70f, 0.6025f},
|
||||
{0.1000f, 80.00f, 0.5217f},
|
||||
{0.1015f, 53.46f, 0.2671f},
|
||||
},
|
||||
{
|
||||
{0.0017f, 46.64f},
|
||||
{0.0021f, 47.88f},
|
||||
},
|
||||
100.0f,
|
||||
13000.0f,
|
||||
},
|
||||
{
|
||||
4,
|
||||
2,
|
||||
{
|
||||
{0.1526f, 52.22f, 0.6149f},
|
||||
{0.1541f, 65.87f, 0.6025f},
|
||||
{0.1557f, 80.00f, 0.5217f},
|
||||
{0.1572f, 53.46f, 0.2671f},
|
||||
},
|
||||
{
|
||||
{0.0075f, 46.64f},
|
||||
{0.0078f, 47.88f},
|
||||
},
|
||||
100.0f,
|
||||
13000.0f,
|
||||
},
|
||||
{
|
||||
4,
|
||||
2,
|
||||
{
|
||||
{0.2082f, 52.22f, 0.6149f},
|
||||
{0.2098f, 54.70f, 0.6025f},
|
||||
{0.2113f, 80.00f, 0.5217f},
|
||||
{0.2129f, 53.46f, 0.2671f},
|
||||
},
|
||||
{
|
||||
{0.0075f, 46.64f},
|
||||
{0.0078f, 47.88f},
|
||||
},
|
||||
100.0f,
|
||||
13000.0f,
|
||||
},
|
||||
{
|
||||
6,
|
||||
4,
|
||||
{
|
||||
{0.0536f, 82.20f, 0.4000f},
|
||||
{0.0629f, 75.80f, 0.5901f},
|
||||
{0.0690f, 77.30f, 0.5000f},
|
||||
{0.0738f, 75.30f, 0.4500f},
|
||||
{0.0799f, 59.67f, 0.4500f},
|
||||
{0.1170f, 74.56f, 0.4783f},
|
||||
},
|
||||
{
|
||||
{0.0067f, 65.00f},
|
||||
{0.0063f, 65.00f},
|
||||
{0.0058f, 65.00f},
|
||||
{0.0055f, 65.00f},
|
||||
},
|
||||
100.0f,
|
||||
13000.0f,
|
||||
},
|
||||
{
|
||||
6,
|
||||
4,
|
||||
{
|
||||
{0.0536f, 82.20f, 0.4000f},
|
||||
{0.0629f, 75.80f, 0.5901f},
|
||||
{0.0690f, 77.30f, 0.5000f},
|
||||
{0.0738f, 75.30f, 0.4500f},
|
||||
{0.0799f, 59.67f, 0.4500f},
|
||||
{0.1727f, 74.56f, 0.5590f},
|
||||
},
|
||||
{
|
||||
{0.0067f, 65.00f},
|
||||
{0.0063f, 65.00f},
|
||||
{0.0058f, 65.00f},
|
||||
{0.0055f, 65.00f},
|
||||
},
|
||||
100.0f,
|
||||
13000.0f,
|
||||
},
|
||||
{
|
||||
6,
|
||||
4,
|
||||
{
|
||||
{0.0814f, 82.20f, 0.4000f},
|
||||
{0.0892f, 75.80f, 0.5901f},
|
||||
{0.0953f, 77.30f, 0.5000f},
|
||||
{0.1046f, 75.30f, 0.5714f},
|
||||
{0.1108f, 59.67f, 0.4500f},
|
||||
{0.1912f, 39.81f, 0.6832f},
|
||||
},
|
||||
{
|
||||
{0.0073f, 65.00f},
|
||||
{0.0063f, 65.00f},
|
||||
{0.0058f, 65.00f},
|
||||
{0.0055f, 65.00f},
|
||||
},
|
||||
100.0f,
|
||||
13000.0f,
|
||||
},
|
||||
{
|
||||
6,
|
||||
6,
|
||||
{
|
||||
{0.0814f, 82.20f, 0.4000f},
|
||||
{0.0892f, 75.80f, 0.5901f},
|
||||
{0.0953f, 77.30f, 0.5000f},
|
||||
{0.1046f, 75.30f, 0.5714f},
|
||||
{0.1108f, 59.67f, 0.4500f},
|
||||
{0.1912f, 39.81f, 0.6832f},
|
||||
},
|
||||
{
|
||||
{0.0073f, 65.00f},
|
||||
{0.0063f, 65.00f},
|
||||
{0.0058f, 65.00f},
|
||||
{0.0055f, 65.00f},
|
||||
{0.0164f, 66.49f},
|
||||
{0.0181f, 56.57f},
|
||||
},
|
||||
100.0f,
|
||||
13000.0f,
|
||||
},
|
||||
{
|
||||
5,
|
||||
4,
|
||||
{
|
||||
{0.1170f, 82.20f, 0.5466f},
|
||||
{0.1232f, 75.18f, 0.4907f},
|
||||
{0.1309f, 69.60f, 0.6335f},
|
||||
{0.1417f, 49.74f, 0.6957f},
|
||||
{0.1526f, 59.67f, 0.5528f},
|
||||
},
|
||||
{
|
||||
{0.0067f, 65.00f},
|
||||
{0.0063f, 65.00f},
|
||||
{0.0058f, 65.00f},
|
||||
{0.0055f, 65.00f},
|
||||
},
|
||||
1000.0f,
|
||||
10000.0f,
|
||||
},
|
||||
{
|
||||
5,
|
||||
6,
|
||||
{
|
||||
{0.1170f, 82.20f, 0.5466f},
|
||||
{0.1232f, 75.18f, 0.4907f},
|
||||
{0.1309f, 69.60f, 0.6335f},
|
||||
{0.1417f, 49.74f, 0.6957f},
|
||||
{0.1526f, 59.67f, 0.5528f},
|
||||
},
|
||||
{
|
||||
{0.0067f, 65.00f},
|
||||
{0.0063f, 65.00f},
|
||||
{0.0058f, 65.00f},
|
||||
{0.0055f, 65.00f},
|
||||
{0.0143f, 56.57f},
|
||||
{0.0153f, 66.49f},
|
||||
},
|
||||
1000.0f,
|
||||
10000.0f,
|
||||
},
|
||||
{
|
||||
6,
|
||||
4,
|
||||
{
|
||||
{0.1170f, 82.20f, 0.6398f},
|
||||
{0.1232f, 75.18f, 0.7453f},
|
||||
{0.1309f, 69.60f, 0.6398f},
|
||||
{0.1417f, 49.74f, 0.6957f},
|
||||
{0.1526f, 59.67f, 0.7205f},
|
||||
{0.1634f, 84.49f, 0.7453f},
|
||||
},
|
||||
{
|
||||
{0.0067f, 65.00f},
|
||||
{0.0063f, 65.00f},
|
||||
{0.0058f, 65.00f},
|
||||
{0.0055f, 65.00f},
|
||||
},
|
||||
2000.0f,
|
||||
15000.0f,
|
||||
},
|
||||
{
|
||||
6,
|
||||
6,
|
||||
{
|
||||
{0.1170f, 82.20f, 0.6398f},
|
||||
{0.1232f, 75.18f, 0.7453f},
|
||||
{0.1309f, 69.60f, 0.6398f},
|
||||
{0.1417f, 49.74f, 0.6957f},
|
||||
{0.1526f, 59.67f, 0.7205f},
|
||||
{0.1634f, 84.49f, 0.7453f},
|
||||
},
|
||||
{
|
||||
{0.0067f, 65.00f},
|
||||
{0.0063f, 65.00f},
|
||||
{0.0058f, 65.00f},
|
||||
{0.0055f, 65.00f},
|
||||
{0.0128f, 80.00f},
|
||||
{0.0136f, 88.83f},
|
||||
},
|
||||
2000.0f,
|
||||
15000.0f,
|
||||
},
|
||||
{
|
||||
5,
|
||||
4,
|
||||
{
|
||||
{0.0506f, 82.20f, 0.6832f},
|
||||
{0.0599f, 73.94f, 0.6832f},
|
||||
{0.0660f, 61.53f, 0.7453f},
|
||||
{0.0708f, 75.30f, 0.7702f},
|
||||
{0.0769f, 59.67f, 0.8012f},
|
||||
},
|
||||
{
|
||||
{0.0067f, 65.00f},
|
||||
{0.0063f, 65.00f},
|
||||
{0.0058f, 65.00f},
|
||||
{0.0055f, 65.00f},
|
||||
},
|
||||
1000.0f,
|
||||
7000.0f,
|
||||
},
|
||||
{
|
||||
5,
|
||||
4,
|
||||
{
|
||||
{0.0536f, 82.20f, 0.6832f},
|
||||
{0.0629f, 73.94f, 0.6832f},
|
||||
{0.0690f, 61.53f, 0.7453f},
|
||||
{0.0738f, 75.30f, 0.7702f},
|
||||
{0.0799f, 59.67f, 0.8012f},
|
||||
},
|
||||
{
|
||||
{0.0067f, 65.00f},
|
||||
{0.0063f, 65.00f},
|
||||
{0.0058f, 65.00f},
|
||||
{0.0055f, 65.00f},
|
||||
},
|
||||
1000.0f,
|
||||
7000.0f,
|
||||
},
|
||||
{
|
||||
5,
|
||||
4,
|
||||
{
|
||||
{0.0586f, 82.20f, 0.6832f},
|
||||
{0.0679f, 73.94f, 0.6832f},
|
||||
{0.0740f, 61.53f, 0.7453f},
|
||||
{0.0788f, 75.30f, 0.7702f},
|
||||
{0.0849f, 59.67f, 0.8012f},
|
||||
},
|
||||
{
|
||||
{0.0067f, 65.00f},
|
||||
{0.0063f, 65.00f},
|
||||
{0.0058f, 65.00f},
|
||||
{0.0055f, 65.00f},
|
||||
},
|
||||
1000.0f,
|
||||
7000.0f,
|
||||
},
|
||||
{
|
||||
5,
|
||||
7,
|
||||
{
|
||||
{0.0586f, 82.20f, 0.6832f},
|
||||
{0.0679f, 73.94f, 0.6832f},
|
||||
{0.0740f, 61.53f, 0.7453f},
|
||||
{0.0788f, 75.30f, 0.7702f},
|
||||
{0.0849f, 59.67f, 0.8012f},
|
||||
},
|
||||
{
|
||||
{0.0067f, 65.00f},
|
||||
{0.0063f, 65.00f},
|
||||
{0.0058f, 65.00f},
|
||||
{0.0055f, 65.00f},
|
||||
{0.0122f, 80.00f},
|
||||
{0.0138f, 65.25f},
|
||||
{0.0143f, 75.00f},
|
||||
},
|
||||
1000.0f,
|
||||
7000.0f,
|
||||
},
|
||||
{
|
||||
5,
|
||||
4,
|
||||
{
|
||||
{0.0505f, 70.22f, 0.4720f},
|
||||
{0.0582f, 80.76f, 0.4000f},
|
||||
{0.0629f, 65.25f, 0.4000f},
|
||||
{0.0892f, 80.00f, 0.6957f},
|
||||
{0.0953f, 52.84f, 0.7205f},
|
||||
},
|
||||
{
|
||||
{0.0044f, 65.00f},
|
||||
{0.0037f, 67.11f},
|
||||
{0.0057f, 80.00f},
|
||||
{0.0060f, 56.57f},
|
||||
},
|
||||
400.0f,
|
||||
10000.0f,
|
||||
},
|
||||
{
|
||||
5,
|
||||
6,
|
||||
{
|
||||
{0.0505f, 70.22f, 0.4720f},
|
||||
{0.0582f, 80.76f, 0.4000f},
|
||||
{0.0629f, 65.25f, 0.4000f},
|
||||
{0.0892f, 80.00f, 0.6957f},
|
||||
{0.0953f, 52.84f, 0.7205f},
|
||||
},
|
||||
{
|
||||
{0.0044f, 65.00f},
|
||||
{0.0037f, 67.11f},
|
||||
{0.0057f, 80.00f},
|
||||
{0.0060f, 56.57f},
|
||||
{0.0142f, 80.00f},
|
||||
{0.0151f, 59.67f},
|
||||
},
|
||||
400.0f,
|
||||
10000.0f,
|
||||
},
|
||||
{
|
||||
5,
|
||||
4,
|
||||
{
|
||||
{0.2051f, 52.84f, 0.7826f},
|
||||
{0.2082f, 68.35f, 0.7019f},
|
||||
{0.2113f, 80.00f, 0.6832f},
|
||||
{0.2206f, 83.25f, 0.7081f},
|
||||
{0.2237f, 67.73f, 0.5280f},
|
||||
},
|
||||
{
|
||||
{0.0067f, 65.00f},
|
||||
{0.0061f, 65.00f},
|
||||
{0.0059f, 65.00f},
|
||||
{0.0055f, 65.00f},
|
||||
},
|
||||
400.0f,
|
||||
10000.0f,
|
||||
},
|
||||
{
|
||||
6,
|
||||
5,
|
||||
{
|
||||
{0.0280f, 82.20f, 0.4720f},
|
||||
{0.0304f, 80.20f, 0.5652f},
|
||||
{0.0329f, 77.30f, 0.6211f},
|
||||
{0.0389f, 75.30f, 0.5217f},
|
||||
{0.0415f, 59.67f, 0.6522f},
|
||||
{0.0768f, 80.00f, 0.7702f},
|
||||
},
|
||||
{
|
||||
{0.0057f, 65.00f},
|
||||
{0.0062f, 65.00f},
|
||||
{0.0066f, 77.04f},
|
||||
{0.0050f, 65.00f},
|
||||
{0.0038f, 56.57f},
|
||||
},
|
||||
100.0f,
|
||||
10000.0f,
|
||||
},
|
||||
{
|
||||
6,
|
||||
7,
|
||||
{
|
||||
{0.0280f, 82.20f, 0.4720f},
|
||||
{0.0304f, 80.20f, 0.5652f},
|
||||
{0.0329f, 77.30f, 0.6211f},
|
||||
{0.0389f, 75.30f, 0.5217f},
|
||||
{0.0415f, 59.67f, 0.6522f},
|
||||
{0.0768f, 80.00f, 0.7702f},
|
||||
},
|
||||
{
|
||||
{0.0057f, 65.00f},
|
||||
{0.0062f, 65.00f},
|
||||
{0.0137f, 77.04f},
|
||||
{0.0050f, 65.00f},
|
||||
{0.0038f, 56.57f},
|
||||
{0.0147f, 60.91f},
|
||||
{0.0164f, 52.84f},
|
||||
},
|
||||
100.0f,
|
||||
10000.0f,
|
||||
},
|
||||
};
|
||||
|
||||
720
plugins/ladspa_effect/tap/tap_rotspeak.c
Normal file
720
plugins/ladspa_effect/tap/tap_rotspeak.c
Normal file
@@ -0,0 +1,720 @@
|
||||
/* -*- linux-c -*-
|
||||
Copyright (C) 2004 Tom Szilagyi
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: tap_rotspeak.c,v 1.3 2004/02/21 17:33:36 tszilagyi Exp $
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "ladspa.h"
|
||||
#include "tap_utils.h"
|
||||
|
||||
/* The Unique ID of the plugin: */
|
||||
|
||||
#define ID_STEREO 2149
|
||||
|
||||
/* The port numbers for the plugin: */
|
||||
|
||||
#define BASSFREQ 0
|
||||
#define HORNFREQ 1
|
||||
#define STWIDTH 2
|
||||
#define HRBAL 3
|
||||
#define LATENCY 4
|
||||
#define INPUT_L 5
|
||||
#define INPUT_R 6
|
||||
#define OUTPUT_L 7
|
||||
#define OUTPUT_R 8
|
||||
|
||||
|
||||
/* Total number of ports */
|
||||
|
||||
#define PORTCOUNT_STEREO 9
|
||||
|
||||
/*
|
||||
* This has to be bigger than 0.3f * sample_rate / (2*PI) for any sample rate.
|
||||
* At 192 kHz 9168 is needed so this should be enough.
|
||||
*/
|
||||
#define PM_DEPTH 9200
|
||||
|
||||
/* maximum phase mod freq */
|
||||
#define PM_FREQ 30.0f
|
||||
|
||||
|
||||
/* splitting input signals into low and high freq components */
|
||||
#define SPLIT_FREQ 1000.0f
|
||||
#define SPLIT_BW 1.0f
|
||||
|
||||
|
||||
/* approx. sound velocity in air [m/s] */
|
||||
#define C_AIR 340.0f
|
||||
|
||||
/* coefficient between rotating frequency and pitch mod depth (aka. Doppler effect) */
|
||||
#define FREQ_PITCH 1.6f
|
||||
|
||||
/* cosine table for fast computations */
|
||||
LADSPA_Data cos_table[1024];
|
||||
|
||||
|
||||
/* The structure used to hold port connection information and state */
|
||||
|
||||
typedef struct {
|
||||
LADSPA_Data * hornfreq;
|
||||
LADSPA_Data * bassfreq;
|
||||
LADSPA_Data * stwidth;
|
||||
LADSPA_Data * hrbal;
|
||||
LADSPA_Data * latency;
|
||||
LADSPA_Data * input_L;
|
||||
LADSPA_Data * input_R;
|
||||
LADSPA_Data * output_L;
|
||||
LADSPA_Data * output_R;
|
||||
|
||||
LADSPA_Data * ringbuffer_h_L;
|
||||
unsigned long buflen_h_L;
|
||||
unsigned long pos_h_L;
|
||||
LADSPA_Data * ringbuffer_h_R;
|
||||
unsigned long buflen_h_R;
|
||||
unsigned long pos_h_R;
|
||||
|
||||
LADSPA_Data * ringbuffer_b_L;
|
||||
unsigned long buflen_b_L;
|
||||
unsigned long pos_b_L;
|
||||
LADSPA_Data * ringbuffer_b_R;
|
||||
unsigned long buflen_b_R;
|
||||
unsigned long pos_b_R;
|
||||
|
||||
biquad * eq_filter_L;
|
||||
biquad * lp_filter_L;
|
||||
biquad * hp_filter_L;
|
||||
|
||||
biquad * eq_filter_R;
|
||||
biquad * lp_filter_R;
|
||||
biquad * hp_filter_R;
|
||||
|
||||
unsigned long sample_rate;
|
||||
LADSPA_Data phase_h;
|
||||
LADSPA_Data phase_b;
|
||||
|
||||
LADSPA_Data run_adding_gain;
|
||||
} RotSpkr;
|
||||
|
||||
|
||||
|
||||
/* Construct a new plugin instance. */
|
||||
LADSPA_Handle
|
||||
instantiate_RotSpkr(const LADSPA_Descriptor * Descriptor,
|
||||
unsigned long sample_rate) {
|
||||
|
||||
LADSPA_Handle * ptr;
|
||||
|
||||
if ((ptr = malloc(sizeof(RotSpkr))) != NULL) {
|
||||
((RotSpkr *)ptr)->sample_rate = sample_rate;
|
||||
((RotSpkr *)ptr)->run_adding_gain = 1.0;
|
||||
|
||||
if ((((RotSpkr *)ptr)->ringbuffer_h_L =
|
||||
calloc(2 * PM_DEPTH, sizeof(LADSPA_Data))) == NULL)
|
||||
return NULL;
|
||||
if ((((RotSpkr *)ptr)->ringbuffer_h_R =
|
||||
calloc(2 * PM_DEPTH, sizeof(LADSPA_Data))) == NULL)
|
||||
return NULL;
|
||||
((RotSpkr *)ptr)->buflen_h_L = ceil(0.3f * sample_rate / M_PI);
|
||||
((RotSpkr *)ptr)->buflen_h_R = ceil(0.3f * sample_rate / M_PI);
|
||||
((RotSpkr *)ptr)->pos_h_L = 0;
|
||||
((RotSpkr *)ptr)->pos_h_R = 0;
|
||||
|
||||
if ((((RotSpkr *)ptr)->ringbuffer_b_L =
|
||||
calloc(2 * PM_DEPTH, sizeof(LADSPA_Data))) == NULL)
|
||||
return NULL;
|
||||
if ((((RotSpkr *)ptr)->ringbuffer_b_R =
|
||||
calloc(2 * PM_DEPTH, sizeof(LADSPA_Data))) == NULL)
|
||||
return NULL;
|
||||
((RotSpkr *)ptr)->buflen_b_L = ceil(0.3f * sample_rate / M_PI);
|
||||
((RotSpkr *)ptr)->buflen_b_R = ceil(0.3f * sample_rate / M_PI);
|
||||
((RotSpkr *)ptr)->pos_b_L = 0;
|
||||
((RotSpkr *)ptr)->pos_b_R = 0;
|
||||
|
||||
if ((((RotSpkr *)ptr)->eq_filter_L = calloc(1, sizeof(biquad))) == NULL)
|
||||
return NULL;
|
||||
if ((((RotSpkr *)ptr)->lp_filter_L = calloc(1, sizeof(biquad))) == NULL)
|
||||
return NULL;
|
||||
if ((((RotSpkr *)ptr)->hp_filter_L = calloc(1, sizeof(biquad))) == NULL)
|
||||
return NULL;
|
||||
|
||||
if ((((RotSpkr *)ptr)->eq_filter_R = calloc(1, sizeof(biquad))) == NULL)
|
||||
return NULL;
|
||||
if ((((RotSpkr *)ptr)->lp_filter_R = calloc(1, sizeof(biquad))) == NULL)
|
||||
return NULL;
|
||||
if ((((RotSpkr *)ptr)->hp_filter_R = calloc(1, sizeof(biquad))) == NULL)
|
||||
return NULL;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
activate_RotSpkr(LADSPA_Handle Instance) {
|
||||
|
||||
int i;
|
||||
RotSpkr * ptr;
|
||||
|
||||
ptr = (RotSpkr *)Instance;
|
||||
|
||||
for (i = 0; i < 2 * PM_DEPTH; i++) {
|
||||
ptr->ringbuffer_h_L[i] = 0.0f;
|
||||
ptr->ringbuffer_h_R[i] = 0.0f;
|
||||
ptr->ringbuffer_b_L[i] = 0.0f;
|
||||
ptr->ringbuffer_b_R[i] = 0.0f;
|
||||
}
|
||||
|
||||
ptr->phase_h = 0.0f;
|
||||
ptr->phase_b = 0.0f;
|
||||
|
||||
biquad_init(ptr->eq_filter_L);
|
||||
biquad_init(ptr->lp_filter_L);
|
||||
biquad_init(ptr->hp_filter_L);
|
||||
biquad_init(ptr->eq_filter_R);
|
||||
biquad_init(ptr->lp_filter_R);
|
||||
biquad_init(ptr->hp_filter_R);
|
||||
|
||||
eq_set_params(ptr->eq_filter_L, SPLIT_FREQ, +8.0f, SPLIT_BW, ptr->sample_rate);
|
||||
eq_set_params(ptr->eq_filter_R, SPLIT_FREQ, +8.0f, SPLIT_BW, ptr->sample_rate);
|
||||
lp_set_params(ptr->lp_filter_L, SPLIT_FREQ, SPLIT_BW, ptr->sample_rate);
|
||||
lp_set_params(ptr->lp_filter_R, SPLIT_FREQ, SPLIT_BW, ptr->sample_rate);
|
||||
hp_set_params(ptr->hp_filter_L, SPLIT_FREQ, SPLIT_BW, ptr->sample_rate);
|
||||
hp_set_params(ptr->hp_filter_R, SPLIT_FREQ, SPLIT_BW, ptr->sample_rate);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Connect a port to a data location. */
|
||||
void
|
||||
connect_port_RotSpkr(LADSPA_Handle Instance,
|
||||
unsigned long Port,
|
||||
LADSPA_Data * DataLocation) {
|
||||
|
||||
RotSpkr * ptr;
|
||||
|
||||
ptr = (RotSpkr *)Instance;
|
||||
switch (Port) {
|
||||
case HORNFREQ:
|
||||
ptr->hornfreq = DataLocation;
|
||||
break;
|
||||
case BASSFREQ:
|
||||
ptr->bassfreq = DataLocation;
|
||||
break;
|
||||
case STWIDTH:
|
||||
ptr->stwidth = DataLocation;
|
||||
break;
|
||||
case HRBAL:
|
||||
ptr->hrbal = DataLocation;
|
||||
break;
|
||||
case LATENCY:
|
||||
ptr->latency = DataLocation;
|
||||
*(ptr->latency) = ptr->buflen_h_L / 2; /* IS THIS LEGAL? */
|
||||
break;
|
||||
case INPUT_L:
|
||||
ptr->input_L = DataLocation;
|
||||
break;
|
||||
case INPUT_R:
|
||||
ptr->input_R = DataLocation;
|
||||
break;
|
||||
case OUTPUT_L:
|
||||
ptr->output_L = DataLocation;
|
||||
break;
|
||||
case OUTPUT_R:
|
||||
ptr->output_R = DataLocation;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
run_RotSpkr(LADSPA_Handle Instance,
|
||||
unsigned long SampleCount) {
|
||||
|
||||
RotSpkr * ptr = (RotSpkr *)Instance;
|
||||
|
||||
LADSPA_Data * input_L = ptr->input_L;
|
||||
LADSPA_Data * input_R = ptr->input_R;
|
||||
LADSPA_Data * output_L = ptr->output_L;
|
||||
LADSPA_Data * output_R = ptr->output_R;
|
||||
LADSPA_Data freq_h = LIMIT(*(ptr->hornfreq),0.0f,PM_FREQ);
|
||||
LADSPA_Data freq_b = LIMIT(*(ptr->bassfreq),0.0f,PM_FREQ);
|
||||
LADSPA_Data stwidth = LIMIT(*(ptr->stwidth),0.0f,100.0f);
|
||||
LADSPA_Data hrbal = LIMIT(*(ptr->hrbal),0.0f,1.0f);
|
||||
LADSPA_Data pmdepth_h =
|
||||
LIMIT(1.0f/(1.0f+FREQ_PITCH*freq_h/C_AIR) * ptr->sample_rate
|
||||
/ 200.0f / M_PI / freq_h, 0, ptr->buflen_h_L / 2);
|
||||
LADSPA_Data pmdepth_b =
|
||||
LIMIT(1.0f/(1.0f+FREQ_PITCH*freq_b/C_AIR) * ptr->sample_rate
|
||||
/ 200.0f / M_PI / freq_b, 0, ptr->buflen_b_L / 2);
|
||||
unsigned long sample_index;
|
||||
|
||||
LADSPA_Data in_L = 0.0f, in_R = 0.0f;
|
||||
LADSPA_Data lo_L = 0.0f, lo_R = 0.0f;
|
||||
LADSPA_Data hi_L = 0.0f, hi_R = 0.0f;
|
||||
|
||||
LADSPA_Data phase_h_L = 0.0f, phase_b_L = 0.0f;
|
||||
LADSPA_Data phase_h_R = 0.0f, phase_b_R = 0.0f;
|
||||
LADSPA_Data phase_pm_h_L = 0.0f, phase_pm_b_L = 0.0f;
|
||||
LADSPA_Data phase_pm_h_R = 0.0f, phase_pm_b_R = 0.0f;
|
||||
LADSPA_Data pm_h_L = 0.0f, pm_b_L = 0.0f;
|
||||
LADSPA_Data pm_h_R = 0.0f, pm_b_R = 0.0f;
|
||||
|
||||
LADSPA_Data fpos_h_L = 0.0f, fpos_b_L = 0.0f, fpos_h_R = 0.0f, fpos_b_R = 0.0f;
|
||||
LADSPA_Data n_h_L = 0.0f, n_b_L = 0.0f, n_h_R = 0.0f, n_b_R = 0.0f;
|
||||
LADSPA_Data rem_h_L = 0.0f, rem_b_L = 0.0f, rem_h_R = 0.0f, rem_b_R = 0.0f;
|
||||
LADSPA_Data sa_h_L = 0.0f, sa_b_L = 0.0f, sb_h_L = 0.0f, sb_b_L = 0.0f;
|
||||
LADSPA_Data sa_h_R = 0.0f, sa_b_R = 0.0f, sb_h_R = 0.0f, sb_b_R = 0.0f;
|
||||
|
||||
|
||||
for (sample_index = 0; sample_index < SampleCount; sample_index++) {
|
||||
|
||||
in_L = *(input_L++);
|
||||
in_R = *(input_R++);
|
||||
|
||||
in_L = biquad_run(ptr->eq_filter_L, in_L);
|
||||
in_R = biquad_run(ptr->eq_filter_R, in_R);
|
||||
lo_L = biquad_run(ptr->lp_filter_L, in_L);
|
||||
lo_R = biquad_run(ptr->lp_filter_R, in_R);
|
||||
hi_L = biquad_run(ptr->hp_filter_L, in_L);
|
||||
hi_R = biquad_run(ptr->hp_filter_R, in_R);
|
||||
|
||||
|
||||
phase_h_L = 1024.0f * freq_h * sample_index / ptr->sample_rate + ptr->phase_h;
|
||||
while (phase_h_L >= 1024.0f)
|
||||
phase_h_L -= 1024.0f;
|
||||
phase_pm_h_L = phase_h_L + 256.0f;
|
||||
while (phase_pm_h_L >= 1024.0f)
|
||||
phase_pm_h_L -= 1024.0f;
|
||||
phase_h_R = phase_h_L + 512.0f;
|
||||
while (phase_h_R >= 1024.0f)
|
||||
phase_h_R -= 1024.0f;
|
||||
phase_pm_h_R = phase_h_R + 256.0f;
|
||||
while (phase_pm_h_R >= 1024.0f)
|
||||
phase_pm_h_R -= 1024.0f;
|
||||
|
||||
phase_b_L = 1024.0f * freq_b * sample_index / ptr->sample_rate + ptr->phase_b;
|
||||
while (phase_b_L >= 1024.0f)
|
||||
phase_b_L -= 1024.0f;
|
||||
phase_pm_b_L = phase_b_L + 256.0f;
|
||||
while (phase_pm_b_L >= 1024.0f)
|
||||
phase_pm_b_L -= 1024.0f;
|
||||
phase_b_R = phase_b_L + 512.0f;
|
||||
while (phase_b_R >= 1024.0f)
|
||||
phase_b_R -= 1024.0f;
|
||||
phase_pm_b_R = phase_b_R + 256.0f;
|
||||
while (phase_pm_b_R >= 1024.0f)
|
||||
phase_pm_b_R -= 1024.0f;
|
||||
|
||||
push_buffer(hi_L, ptr->ringbuffer_h_L, ptr->buflen_h_L, &(ptr->pos_h_L));
|
||||
push_buffer(hi_R, ptr->ringbuffer_h_R, ptr->buflen_h_R, &(ptr->pos_h_R));
|
||||
push_buffer(lo_L, ptr->ringbuffer_b_L, ptr->buflen_b_L, &(ptr->pos_b_L));
|
||||
push_buffer(lo_R, ptr->ringbuffer_b_R, ptr->buflen_b_R, &(ptr->pos_b_R));
|
||||
|
||||
fpos_h_L = pmdepth_h * (1.0f - cos_table[(unsigned long) phase_pm_h_L]);
|
||||
n_h_L = floorf(fpos_h_L);
|
||||
rem_h_L = fpos_h_L - n_h_L;
|
||||
sa_h_L = read_buffer(ptr->ringbuffer_h_L,
|
||||
ptr->buflen_h_L, ptr->pos_h_L, (unsigned long) n_h_L);
|
||||
sb_h_L = read_buffer(ptr->ringbuffer_h_L,
|
||||
ptr->buflen_h_L, ptr->pos_h_L, (unsigned long) n_h_L + 1);
|
||||
pm_h_L = (1 - rem_h_L) * sa_h_L + rem_h_L * sb_h_L;
|
||||
|
||||
fpos_h_R = pmdepth_h * (1.0f - cos_table[(unsigned long) phase_pm_h_R]);
|
||||
n_h_R = floorf(fpos_h_R);
|
||||
rem_h_R = fpos_h_R - n_h_R;
|
||||
sa_h_R = read_buffer(ptr->ringbuffer_h_R,
|
||||
ptr->buflen_h_R, ptr->pos_h_R, (unsigned long) n_h_R);
|
||||
sb_h_R = read_buffer(ptr->ringbuffer_h_R,
|
||||
ptr->buflen_h_R, ptr->pos_h_R, (unsigned long) n_h_R + 1);
|
||||
pm_h_R = (1 - rem_h_R) * sa_h_R + rem_h_R * sb_h_R;
|
||||
|
||||
|
||||
fpos_b_L = pmdepth_b * (1.0f - cos_table[(unsigned long) phase_pm_b_L]);
|
||||
n_b_L = floorf(fpos_b_L);
|
||||
rem_b_L = fpos_b_L - n_b_L;
|
||||
sa_b_L = read_buffer(ptr->ringbuffer_b_L,
|
||||
ptr->buflen_b_L, ptr->pos_b_L, (unsigned long) n_b_L);
|
||||
sb_b_L = read_buffer(ptr->ringbuffer_b_L,
|
||||
ptr->buflen_b_L, ptr->pos_b_L, (unsigned long) n_b_L + 1);
|
||||
pm_b_L = (1 - rem_b_L) * sa_b_L + rem_b_L * sb_b_L;
|
||||
|
||||
fpos_b_R = pmdepth_b * (1.0f - cos_table[(unsigned long) phase_pm_b_R]);
|
||||
n_b_R = floorf(fpos_b_R);
|
||||
rem_b_R = fpos_b_R - n_b_R;
|
||||
sa_b_R = read_buffer(ptr->ringbuffer_b_R,
|
||||
ptr->buflen_b_R, ptr->pos_b_R, (unsigned long) n_b_R);
|
||||
sb_b_R = read_buffer(ptr->ringbuffer_b_R,
|
||||
ptr->buflen_b_R, ptr->pos_b_R, (unsigned long) n_b_R + 1);
|
||||
pm_b_R = (1 - rem_b_R) * sa_b_R + rem_b_R * sb_b_R;
|
||||
|
||||
|
||||
*(output_L++) =
|
||||
hrbal * pm_h_L * (1.0f + 0.5f * stwidth/100.0f *
|
||||
cos_table[(unsigned long) phase_h_L]) +
|
||||
(1.0f - hrbal) * pm_b_L * (1.0f + 0.5f * stwidth/100.0f *
|
||||
cos_table[(unsigned long) phase_b_L]);
|
||||
|
||||
*(output_R++) =
|
||||
hrbal * pm_h_R * (1.0f + 0.5f * stwidth/100.0f *
|
||||
cos_table[(unsigned long) phase_h_R]) +
|
||||
(1.0f - hrbal) * pm_b_R * (1.0f + 0.5f * stwidth/100.0f *
|
||||
cos_table[(unsigned long) phase_b_R]);
|
||||
}
|
||||
|
||||
ptr->phase_h += 1024.0f * freq_h * sample_index / ptr->sample_rate;
|
||||
while (ptr->phase_h >= 1024.0f)
|
||||
ptr->phase_h -= 1024.0f;
|
||||
ptr->phase_b += 1024.0f * freq_b * sample_index / ptr->sample_rate;
|
||||
while (ptr->phase_b >= 1024.0f)
|
||||
ptr->phase_b -= 1024.0f;
|
||||
|
||||
*(ptr->latency) = ptr->buflen_h_L / 2;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
set_run_adding_gain_RotSpkr(LADSPA_Handle Instance, LADSPA_Data gain) {
|
||||
|
||||
RotSpkr * ptr = (RotSpkr *)Instance;
|
||||
|
||||
ptr->run_adding_gain = gain;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
run_adding_RotSpkr(LADSPA_Handle Instance,
|
||||
unsigned long SampleCount) {
|
||||
|
||||
RotSpkr * ptr = (RotSpkr *)Instance;
|
||||
|
||||
LADSPA_Data * input_L = ptr->input_L;
|
||||
LADSPA_Data * input_R = ptr->input_R;
|
||||
LADSPA_Data * output_L = ptr->output_L;
|
||||
LADSPA_Data * output_R = ptr->output_R;
|
||||
LADSPA_Data freq_h = LIMIT(*(ptr->hornfreq),0.0f,PM_FREQ);
|
||||
LADSPA_Data freq_b = LIMIT(*(ptr->bassfreq),0.0f,PM_FREQ);
|
||||
LADSPA_Data stwidth = LIMIT(*(ptr->stwidth),0.0f,100.0f);
|
||||
LADSPA_Data hrbal = LIMIT(*(ptr->hrbal),0.0f,1.0f);
|
||||
LADSPA_Data pmdepth_h =
|
||||
LIMIT(1.0f/(1.0f+FREQ_PITCH*freq_h/C_AIR) * ptr->sample_rate
|
||||
/ 200.0f / M_PI / freq_h, 0, ptr->buflen_h_L / 2);
|
||||
LADSPA_Data pmdepth_b =
|
||||
LIMIT(1.0f/(1.0f+FREQ_PITCH*freq_b/C_AIR) * ptr->sample_rate
|
||||
/ 200.0f / M_PI / freq_b, 0, ptr->buflen_b_L / 2);
|
||||
unsigned long sample_index;
|
||||
|
||||
LADSPA_Data in_L = 0.0f, in_R = 0.0f;
|
||||
LADSPA_Data lo_L = 0.0f, lo_R = 0.0f;
|
||||
LADSPA_Data hi_L = 0.0f, hi_R = 0.0f;
|
||||
|
||||
LADSPA_Data phase_h_L = 0.0f, phase_b_L = 0.0f;
|
||||
LADSPA_Data phase_h_R = 0.0f, phase_b_R = 0.0f;
|
||||
LADSPA_Data phase_pm_h_L = 0.0f, phase_pm_b_L = 0.0f;
|
||||
LADSPA_Data phase_pm_h_R = 0.0f, phase_pm_b_R = 0.0f;
|
||||
LADSPA_Data pm_h_L = 0.0f, pm_b_L = 0.0f;
|
||||
LADSPA_Data pm_h_R = 0.0f, pm_b_R = 0.0f;
|
||||
|
||||
LADSPA_Data fpos_h_L = 0.0f, fpos_b_L = 0.0f, fpos_h_R = 0.0f, fpos_b_R = 0.0f;
|
||||
LADSPA_Data n_h_L = 0.0f, n_b_L = 0.0f, n_h_R = 0.0f, n_b_R = 0.0f;
|
||||
LADSPA_Data rem_h_L = 0.0f, rem_b_L = 0.0f, rem_h_R = 0.0f, rem_b_R = 0.0f;
|
||||
LADSPA_Data sa_h_L = 0.0f, sa_b_L = 0.0f, sb_h_L = 0.0f, sb_b_L = 0.0f;
|
||||
LADSPA_Data sa_h_R = 0.0f, sa_b_R = 0.0f, sb_h_R = 0.0f, sb_b_R = 0.0f;
|
||||
|
||||
|
||||
for (sample_index = 0; sample_index < SampleCount; sample_index++) {
|
||||
|
||||
in_L = *(input_L++);
|
||||
in_R = *(input_R++);
|
||||
|
||||
in_L = biquad_run(ptr->eq_filter_L, in_L);
|
||||
in_R = biquad_run(ptr->eq_filter_R, in_R);
|
||||
lo_L = biquad_run(ptr->lp_filter_L, in_L);
|
||||
lo_R = biquad_run(ptr->lp_filter_R, in_R);
|
||||
hi_L = biquad_run(ptr->hp_filter_L, in_L);
|
||||
hi_R = biquad_run(ptr->hp_filter_R, in_R);
|
||||
|
||||
|
||||
phase_h_L = 1024.0f * freq_h * sample_index / ptr->sample_rate + ptr->phase_h;
|
||||
while (phase_h_L >= 1024.0f)
|
||||
phase_h_L -= 1024.0f;
|
||||
phase_pm_h_L = phase_h_L + 256.0f;
|
||||
while (phase_pm_h_L >= 1024.0f)
|
||||
phase_pm_h_L -= 1024.0f;
|
||||
phase_h_R = phase_h_L + 512.0f;
|
||||
while (phase_h_R >= 1024.0f)
|
||||
phase_h_R -= 1024.0f;
|
||||
phase_pm_h_R = phase_h_R + 256.0f;
|
||||
while (phase_pm_h_R >= 1024.0f)
|
||||
phase_pm_h_R -= 1024.0f;
|
||||
|
||||
phase_b_L = 1024.0f * freq_b * sample_index / ptr->sample_rate + ptr->phase_b;
|
||||
while (phase_b_L >= 1024.0f)
|
||||
phase_b_L -= 1024.0f;
|
||||
phase_pm_b_L = phase_b_L + 256.0f;
|
||||
while (phase_pm_b_L >= 1024.0f)
|
||||
phase_pm_b_L -= 1024.0f;
|
||||
phase_b_R = phase_b_L + 512.0f;
|
||||
while (phase_b_R >= 1024.0f)
|
||||
phase_b_R -= 1024.0f;
|
||||
phase_pm_b_R = phase_b_R + 256.0f;
|
||||
while (phase_pm_b_R >= 1024.0f)
|
||||
phase_pm_b_R -= 1024.0f;
|
||||
|
||||
push_buffer(hi_L, ptr->ringbuffer_h_L, ptr->buflen_h_L, &(ptr->pos_h_L));
|
||||
push_buffer(hi_R, ptr->ringbuffer_h_R, ptr->buflen_h_R, &(ptr->pos_h_R));
|
||||
push_buffer(lo_L, ptr->ringbuffer_b_L, ptr->buflen_b_L, &(ptr->pos_b_L));
|
||||
push_buffer(lo_R, ptr->ringbuffer_b_R, ptr->buflen_b_R, &(ptr->pos_b_R));
|
||||
|
||||
fpos_h_L = pmdepth_h * (1.0f - cos_table[(unsigned long) phase_pm_h_L]);
|
||||
n_h_L = floorf(fpos_h_L);
|
||||
rem_h_L = fpos_h_L - n_h_L;
|
||||
sa_h_L = read_buffer(ptr->ringbuffer_h_L,
|
||||
ptr->buflen_h_L, ptr->pos_h_L, (unsigned long) n_h_L);
|
||||
sb_h_L = read_buffer(ptr->ringbuffer_h_L,
|
||||
ptr->buflen_h_L, ptr->pos_h_L, (unsigned long) n_h_L + 1);
|
||||
pm_h_L = (1 - rem_h_L) * sa_h_L + rem_h_L * sb_h_L;
|
||||
|
||||
fpos_h_R = pmdepth_h * (1.0f - cos_table[(unsigned long) phase_pm_h_R]);
|
||||
n_h_R = floorf(fpos_h_R);
|
||||
rem_h_R = fpos_h_R - n_h_R;
|
||||
sa_h_R = read_buffer(ptr->ringbuffer_h_R,
|
||||
ptr->buflen_h_R, ptr->pos_h_R, (unsigned long) n_h_R);
|
||||
sb_h_R = read_buffer(ptr->ringbuffer_h_R,
|
||||
ptr->buflen_h_R, ptr->pos_h_R, (unsigned long) n_h_R + 1);
|
||||
pm_h_R = (1 - rem_h_R) * sa_h_R + rem_h_R * sb_h_R;
|
||||
|
||||
|
||||
fpos_b_L = pmdepth_b * (1.0f - cos_table[(unsigned long) phase_pm_b_L]);
|
||||
n_b_L = floorf(fpos_b_L);
|
||||
rem_b_L = fpos_b_L - n_b_L;
|
||||
sa_b_L = read_buffer(ptr->ringbuffer_b_L,
|
||||
ptr->buflen_b_L, ptr->pos_b_L, (unsigned long) n_b_L);
|
||||
sb_b_L = read_buffer(ptr->ringbuffer_b_L,
|
||||
ptr->buflen_b_L, ptr->pos_b_L, (unsigned long) n_b_L + 1);
|
||||
pm_b_L = (1 - rem_b_L) * sa_b_L + rem_b_L * sb_b_L;
|
||||
|
||||
fpos_b_R = pmdepth_b * (1.0f - cos_table[(unsigned long) phase_pm_b_R]);
|
||||
n_b_R = floorf(fpos_b_R);
|
||||
rem_b_R = fpos_b_R - n_b_R;
|
||||
sa_b_R = read_buffer(ptr->ringbuffer_b_R,
|
||||
ptr->buflen_b_R, ptr->pos_b_R, (unsigned long) n_b_R);
|
||||
sb_b_R = read_buffer(ptr->ringbuffer_b_R,
|
||||
ptr->buflen_b_R, ptr->pos_b_R, (unsigned long) n_b_R + 1);
|
||||
pm_b_R = (1 - rem_b_R) * sa_b_R + rem_b_R * sb_b_R;
|
||||
|
||||
|
||||
*(output_L++) += ptr->run_adding_gain *
|
||||
hrbal * pm_h_L * (1.0f + 0.5f * stwidth/100.0f *
|
||||
cos_table[(unsigned long) phase_h_L]) +
|
||||
(1.0f - hrbal) * pm_b_L * (1.0f + 0.5f * stwidth/100.0f *
|
||||
cos_table[(unsigned long) phase_b_L]);
|
||||
|
||||
*(output_R++) += ptr->run_adding_gain *
|
||||
hrbal * pm_h_R * (1.0f + 0.5f * stwidth/100.0f *
|
||||
cos_table[(unsigned long) phase_h_R]) +
|
||||
(1.0f - hrbal) * pm_b_R * (1.0f + 0.5f * stwidth/100.0f *
|
||||
cos_table[(unsigned long) phase_b_R]);
|
||||
}
|
||||
|
||||
ptr->phase_h += 1024.0f * freq_h * sample_index / ptr->sample_rate;
|
||||
while (ptr->phase_h >= 1024.0f)
|
||||
ptr->phase_h -= 1024.0f;
|
||||
ptr->phase_b += 1024.0f * freq_b * sample_index / ptr->sample_rate;
|
||||
while (ptr->phase_b >= 1024.0f)
|
||||
ptr->phase_b -= 1024.0f;
|
||||
|
||||
*(ptr->latency) = ptr->buflen_h_L / 2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Throw away an RotSpkr effect instance. */
|
||||
void
|
||||
cleanup_RotSpkr(LADSPA_Handle Instance) {
|
||||
|
||||
RotSpkr * ptr = (RotSpkr *)Instance;
|
||||
|
||||
free(ptr->ringbuffer_h_L);
|
||||
free(ptr->ringbuffer_h_R);
|
||||
free(ptr->ringbuffer_b_L);
|
||||
free(ptr->ringbuffer_b_R);
|
||||
free(ptr->eq_filter_L);
|
||||
free(ptr->eq_filter_R);
|
||||
free(ptr->lp_filter_L);
|
||||
free(ptr->lp_filter_R);
|
||||
free(ptr->hp_filter_L);
|
||||
free(ptr->hp_filter_R);
|
||||
free(Instance);
|
||||
}
|
||||
|
||||
|
||||
|
||||
LADSPA_Descriptor * stereo_descriptor = NULL;
|
||||
|
||||
|
||||
|
||||
/* _init() is called automatically when the plugin library is first
|
||||
loaded. */
|
||||
void
|
||||
_init() {
|
||||
|
||||
int i;
|
||||
char ** port_names;
|
||||
LADSPA_PortDescriptor * port_descriptors;
|
||||
LADSPA_PortRangeHint * port_range_hints;
|
||||
|
||||
if ((stereo_descriptor =
|
||||
(LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor))) == NULL)
|
||||
exit(1);
|
||||
|
||||
for (i = 0; i < 1024; i++)
|
||||
cos_table[i] = cosf(i * M_PI / 512.0f);
|
||||
|
||||
|
||||
stereo_descriptor->UniqueID = ID_STEREO;
|
||||
stereo_descriptor->Label = strdup("tap_rotspeak");
|
||||
stereo_descriptor->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
|
||||
stereo_descriptor->Name = strdup("TAP Rotary Speaker");
|
||||
stereo_descriptor->Maker = strdup("Tom Szilagyi");
|
||||
stereo_descriptor->Copyright = strdup("GPL");
|
||||
stereo_descriptor->PortCount = PORTCOUNT_STEREO;
|
||||
|
||||
if ((port_descriptors =
|
||||
(LADSPA_PortDescriptor *)calloc(PORTCOUNT_STEREO, sizeof(LADSPA_PortDescriptor))) == NULL)
|
||||
exit(1);
|
||||
|
||||
stereo_descriptor->PortDescriptors = (const LADSPA_PortDescriptor *)port_descriptors;
|
||||
port_descriptors[HORNFREQ] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[BASSFREQ] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[STWIDTH] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[HRBAL] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[LATENCY] = LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[INPUT_L] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
|
||||
port_descriptors[INPUT_R] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
|
||||
port_descriptors[OUTPUT_L] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
|
||||
port_descriptors[OUTPUT_R] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
|
||||
|
||||
if ((port_names =
|
||||
(char **)calloc(PORTCOUNT_STEREO, sizeof(char *))) == NULL)
|
||||
exit(1);
|
||||
|
||||
stereo_descriptor->PortNames = (const char **)port_names;
|
||||
port_names[HORNFREQ] = strdup("Horn Frequency [Hz]");
|
||||
port_names[BASSFREQ] = strdup("Rotor Frequency [Hz]");
|
||||
port_names[STWIDTH] = strdup("Mic Distance [%]");
|
||||
port_names[HRBAL] = strdup("Rotor/Horn Mix");
|
||||
port_names[LATENCY] = strdup("latency");
|
||||
port_names[INPUT_L] = strdup("Input L");
|
||||
port_names[INPUT_R] = strdup("Input R");
|
||||
port_names[OUTPUT_L] = strdup("Output L");
|
||||
port_names[OUTPUT_R] = strdup("Output R");
|
||||
|
||||
if ((port_range_hints =
|
||||
((LADSPA_PortRangeHint *)calloc(PORTCOUNT_STEREO, sizeof(LADSPA_PortRangeHint)))) == NULL)
|
||||
exit(1);
|
||||
|
||||
stereo_descriptor->PortRangeHints = (const LADSPA_PortRangeHint *)port_range_hints;
|
||||
port_range_hints[HORNFREQ].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[BASSFREQ].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[STWIDTH].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_LOW);
|
||||
port_range_hints[HRBAL].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_MIDDLE);
|
||||
port_range_hints[LATENCY].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_MAXIMUM);
|
||||
port_range_hints[HORNFREQ].LowerBound = 0;
|
||||
port_range_hints[HORNFREQ].UpperBound = PM_FREQ;
|
||||
port_range_hints[BASSFREQ].LowerBound = 0;
|
||||
port_range_hints[BASSFREQ].UpperBound = PM_FREQ;
|
||||
port_range_hints[STWIDTH].LowerBound = 0;
|
||||
port_range_hints[STWIDTH].UpperBound = 100.0f;
|
||||
port_range_hints[HRBAL].LowerBound = 0;
|
||||
port_range_hints[HRBAL].UpperBound = 1.0f;
|
||||
port_range_hints[LATENCY].LowerBound = 0;
|
||||
port_range_hints[LATENCY].UpperBound = PM_DEPTH;
|
||||
port_range_hints[INPUT_L].HintDescriptor = 0;
|
||||
port_range_hints[INPUT_R].HintDescriptor = 0;
|
||||
port_range_hints[OUTPUT_L].HintDescriptor = 0;
|
||||
port_range_hints[OUTPUT_R].HintDescriptor = 0;
|
||||
stereo_descriptor->instantiate = instantiate_RotSpkr;
|
||||
stereo_descriptor->connect_port = connect_port_RotSpkr;
|
||||
stereo_descriptor->activate = activate_RotSpkr;
|
||||
stereo_descriptor->run = run_RotSpkr;
|
||||
stereo_descriptor->run_adding = run_adding_RotSpkr;
|
||||
stereo_descriptor->set_run_adding_gain = set_run_adding_gain_RotSpkr;
|
||||
stereo_descriptor->deactivate = NULL;
|
||||
stereo_descriptor->cleanup = cleanup_RotSpkr;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
delete_descriptor(LADSPA_Descriptor * descriptor) {
|
||||
unsigned long index;
|
||||
if (descriptor) {
|
||||
free((char *)descriptor->Label);
|
||||
free((char *)descriptor->Name);
|
||||
free((char *)descriptor->Maker);
|
||||
free((char *)descriptor->Copyright);
|
||||
free((LADSPA_PortDescriptor *)descriptor->PortDescriptors);
|
||||
for (index = 0; index < descriptor->PortCount; index++)
|
||||
free((char *)(descriptor->PortNames[index]));
|
||||
free((char **)descriptor->PortNames);
|
||||
free((LADSPA_PortRangeHint *)descriptor->PortRangeHints);
|
||||
free(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* _fini() is called automatically when the library is unloaded. */
|
||||
void
|
||||
_fini() {
|
||||
delete_descriptor(stereo_descriptor);
|
||||
}
|
||||
|
||||
|
||||
/* Return a descriptor of the requested plugin type. */
|
||||
const LADSPA_Descriptor *
|
||||
ladspa_descriptor(unsigned long Index) {
|
||||
|
||||
switch (Index) {
|
||||
case 0:
|
||||
return stereo_descriptor;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
297
plugins/ladspa_effect/tap/tap_sigmoid.c
Normal file
297
plugins/ladspa_effect/tap/tap_sigmoid.c
Normal file
@@ -0,0 +1,297 @@
|
||||
/* -*- linux-c -*-
|
||||
Copyright (C) 2004 Tom Szilagyi
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: tap_sigmoid.c,v 1.1 2004/08/02 18:14:50 tszilagyi Exp $
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "ladspa.h"
|
||||
#include "tap_utils.h"
|
||||
|
||||
|
||||
/* The Unique ID of the plugin: */
|
||||
|
||||
#define ID_MONO 2157
|
||||
|
||||
/* The port numbers for the plugin: */
|
||||
|
||||
#define PREGAIN 0
|
||||
#define POSTGAIN 1
|
||||
#define INPUT 2
|
||||
#define OUTPUT 3
|
||||
|
||||
/* Total number of ports */
|
||||
|
||||
|
||||
#define PORTCOUNT_MONO 4
|
||||
|
||||
|
||||
/* The structure used to hold port connection information and state */
|
||||
|
||||
typedef struct {
|
||||
LADSPA_Data * pregain;
|
||||
LADSPA_Data * postgain;
|
||||
LADSPA_Data * input;
|
||||
LADSPA_Data * output;
|
||||
|
||||
unsigned long sample_rate;
|
||||
LADSPA_Data run_adding_gain;
|
||||
} Sigmoid;
|
||||
|
||||
|
||||
|
||||
/* Construct a new plugin instance. */
|
||||
LADSPA_Handle
|
||||
instantiate_Sigmoid(const LADSPA_Descriptor * Descriptor,
|
||||
unsigned long sample_rate) {
|
||||
|
||||
LADSPA_Handle * ptr;
|
||||
|
||||
if ((ptr = malloc(sizeof(Sigmoid))) != NULL) {
|
||||
((Sigmoid *)ptr)->sample_rate = sample_rate;
|
||||
((Sigmoid *)ptr)->run_adding_gain = 1.0f;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Connect a port to a data location. */
|
||||
void
|
||||
connect_port_Sigmoid(LADSPA_Handle Instance,
|
||||
unsigned long Port,
|
||||
LADSPA_Data * DataLocation) {
|
||||
|
||||
Sigmoid * ptr = (Sigmoid *)Instance;
|
||||
|
||||
switch (Port) {
|
||||
case PREGAIN:
|
||||
ptr->pregain = DataLocation;
|
||||
break;
|
||||
case POSTGAIN:
|
||||
ptr->postgain = DataLocation;
|
||||
break;
|
||||
case INPUT:
|
||||
ptr->input = DataLocation;
|
||||
break;
|
||||
case OUTPUT:
|
||||
ptr->output = DataLocation;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
run_Sigmoid(LADSPA_Handle Instance,
|
||||
unsigned long SampleCount) {
|
||||
|
||||
Sigmoid * ptr = (Sigmoid *)Instance;
|
||||
LADSPA_Data * input = ptr->input;
|
||||
LADSPA_Data * output = ptr->output;
|
||||
LADSPA_Data pregain = db2lin(LIMIT(*(ptr->pregain),-90.0f,20.0f));
|
||||
LADSPA_Data postgain = db2lin(LIMIT(*(ptr->postgain),-90.0f,20.0f));
|
||||
|
||||
unsigned long sample_index;
|
||||
unsigned long sample_count = SampleCount;
|
||||
|
||||
LADSPA_Data in = 0.0f;
|
||||
LADSPA_Data out = 0.0f;
|
||||
|
||||
|
||||
for (sample_index = 0; sample_index < sample_count; sample_index++) {
|
||||
|
||||
in = *(input++) * pregain;
|
||||
|
||||
out = 2.0f / (1.0f + exp(-5.0*in)) - 1.0f;
|
||||
|
||||
*(output++) = out * postgain;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
set_run_adding_gain_Sigmoid(LADSPA_Handle Instance, LADSPA_Data gain) {
|
||||
|
||||
Sigmoid * ptr = (Sigmoid *)Instance;
|
||||
|
||||
ptr->run_adding_gain = gain;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
run_adding_Sigmoid(LADSPA_Handle Instance,
|
||||
unsigned long SampleCount) {
|
||||
|
||||
Sigmoid * ptr = (Sigmoid *)Instance;
|
||||
LADSPA_Data * input = ptr->input;
|
||||
LADSPA_Data * output = ptr->output;
|
||||
LADSPA_Data pregain = db2lin(LIMIT(*(ptr->pregain),-90.0f,20.0f));
|
||||
LADSPA_Data postgain = db2lin(LIMIT(*(ptr->postgain),-90.0f,20.0f));
|
||||
|
||||
unsigned long sample_index;
|
||||
unsigned long sample_count = SampleCount;
|
||||
|
||||
LADSPA_Data in = 0.0f;
|
||||
LADSPA_Data out = 0.0f;
|
||||
|
||||
|
||||
for (sample_index = 0; sample_index < sample_count; sample_index++) {
|
||||
|
||||
in = *(input++) * pregain;
|
||||
|
||||
out = 2.0f / (1.0f + exp(-5.0*in)) - 1.0f;
|
||||
|
||||
*(output++) += out * postgain * ptr->run_adding_gain;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Throw away a Sigmoid effect instance. */
|
||||
void
|
||||
cleanup_Sigmoid(LADSPA_Handle Instance) {
|
||||
|
||||
free(Instance);
|
||||
}
|
||||
|
||||
|
||||
|
||||
LADSPA_Descriptor * mono_descriptor = NULL;
|
||||
|
||||
|
||||
|
||||
/* _init() is called automatically when the plugin library is first
|
||||
loaded. */
|
||||
void
|
||||
_init() {
|
||||
|
||||
char ** port_names;
|
||||
LADSPA_PortDescriptor * port_descriptors;
|
||||
LADSPA_PortRangeHint * port_range_hints;
|
||||
|
||||
if ((mono_descriptor =
|
||||
(LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor))) == NULL)
|
||||
exit(1);
|
||||
|
||||
|
||||
mono_descriptor->UniqueID = ID_MONO;
|
||||
mono_descriptor->Label = strdup("tap_sigmoid");
|
||||
mono_descriptor->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
|
||||
mono_descriptor->Name = strdup("TAP Sigmoid Booster");
|
||||
mono_descriptor->Maker = strdup("Tom Szilagyi");
|
||||
mono_descriptor->Copyright = strdup("GPL");
|
||||
mono_descriptor->PortCount = PORTCOUNT_MONO;
|
||||
|
||||
if ((port_descriptors =
|
||||
(LADSPA_PortDescriptor *)calloc(PORTCOUNT_MONO, sizeof(LADSPA_PortDescriptor))) == NULL)
|
||||
exit(1);
|
||||
|
||||
mono_descriptor->PortDescriptors = (const LADSPA_PortDescriptor *)port_descriptors;
|
||||
port_descriptors[PREGAIN] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[POSTGAIN] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[INPUT] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
|
||||
port_descriptors[OUTPUT] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
|
||||
|
||||
if ((port_names =
|
||||
(char **)calloc(PORTCOUNT_MONO, sizeof(char *))) == NULL)
|
||||
exit(1);
|
||||
|
||||
mono_descriptor->PortNames = (const char **)port_names;
|
||||
port_names[PREGAIN] = strdup("Pre Gain [dB]");
|
||||
port_names[POSTGAIN] = strdup("Post Gain [dB]");
|
||||
port_names[INPUT] = strdup("Input");
|
||||
port_names[OUTPUT] = strdup("Output");
|
||||
|
||||
if ((port_range_hints =
|
||||
((LADSPA_PortRangeHint *)calloc(PORTCOUNT_MONO, sizeof(LADSPA_PortRangeHint)))) == NULL)
|
||||
exit(1);
|
||||
|
||||
mono_descriptor->PortRangeHints = (const LADSPA_PortRangeHint *)port_range_hints;
|
||||
port_range_hints[PREGAIN].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[POSTGAIN].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[PREGAIN].LowerBound = -90.0f;
|
||||
port_range_hints[PREGAIN].UpperBound = 20.0f;
|
||||
port_range_hints[POSTGAIN].LowerBound = -90.0f;
|
||||
port_range_hints[POSTGAIN].UpperBound = 20.0f;
|
||||
port_range_hints[INPUT].HintDescriptor = 0;
|
||||
port_range_hints[OUTPUT].HintDescriptor = 0;
|
||||
mono_descriptor->instantiate = instantiate_Sigmoid;
|
||||
mono_descriptor->connect_port = connect_port_Sigmoid;
|
||||
mono_descriptor->activate = NULL;
|
||||
mono_descriptor->run = run_Sigmoid;
|
||||
mono_descriptor->run_adding = run_adding_Sigmoid;
|
||||
mono_descriptor->set_run_adding_gain = set_run_adding_gain_Sigmoid;
|
||||
mono_descriptor->deactivate = NULL;
|
||||
mono_descriptor->cleanup = cleanup_Sigmoid;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
delete_descriptor(LADSPA_Descriptor * descriptor) {
|
||||
unsigned long index;
|
||||
if (descriptor) {
|
||||
free((char *)descriptor->Label);
|
||||
free((char *)descriptor->Name);
|
||||
free((char *)descriptor->Maker);
|
||||
free((char *)descriptor->Copyright);
|
||||
free((LADSPA_PortDescriptor *)descriptor->PortDescriptors);
|
||||
for (index = 0; index < descriptor->PortCount; index++)
|
||||
free((char *)(descriptor->PortNames[index]));
|
||||
free((char **)descriptor->PortNames);
|
||||
free((LADSPA_PortRangeHint *)descriptor->PortRangeHints);
|
||||
free(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* _fini() is called automatically when the library is unloaded. */
|
||||
void
|
||||
_fini() {
|
||||
delete_descriptor(mono_descriptor);
|
||||
}
|
||||
|
||||
|
||||
/* Return a descriptor of the requested plugin type. */
|
||||
const LADSPA_Descriptor *
|
||||
ladspa_descriptor(unsigned long Index) {
|
||||
|
||||
switch (Index) {
|
||||
case 0:
|
||||
return mono_descriptor;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
343
plugins/ladspa_effect/tap/tap_tremolo.c
Normal file
343
plugins/ladspa_effect/tap/tap_tremolo.c
Normal file
@@ -0,0 +1,343 @@
|
||||
/* -*- linux-c -*-
|
||||
Copyright (C) 2004 Tom Szilagyi
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: tap_tremolo.c,v 1.6 2004/02/21 17:33:36 tszilagyi Exp $
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "ladspa.h"
|
||||
#include "tap_utils.h"
|
||||
|
||||
/* The Unique ID of the plugin: */
|
||||
|
||||
#define ID_MONO 2144
|
||||
|
||||
/* The port numbers for the plugin: */
|
||||
|
||||
#define CONTROL_FREQ 0
|
||||
#define CONTROL_DEPTH 1
|
||||
#define CONTROL_GAIN 2
|
||||
#define INPUT_0 3
|
||||
#define OUTPUT_0 4
|
||||
|
||||
|
||||
/* Total number of ports */
|
||||
|
||||
#define PORTCOUNT_MONO 5
|
||||
|
||||
|
||||
/* cosine table for fast computations */
|
||||
LADSPA_Data cos_table[1024];
|
||||
|
||||
|
||||
/* The structure used to hold port connection information and state */
|
||||
|
||||
typedef struct {
|
||||
LADSPA_Data * Control_Freq;
|
||||
LADSPA_Data * Control_Depth;
|
||||
LADSPA_Data * Control_Gain;
|
||||
LADSPA_Data * InputBuffer_1;
|
||||
LADSPA_Data * OutputBuffer_1;
|
||||
unsigned long SampleRate;
|
||||
LADSPA_Data Phase;
|
||||
LADSPA_Data run_adding_gain;
|
||||
} Tremolo;
|
||||
|
||||
|
||||
|
||||
/* Construct a new plugin instance. */
|
||||
LADSPA_Handle
|
||||
instantiate_Tremolo(const LADSPA_Descriptor * Descriptor,
|
||||
unsigned long SampleRate) {
|
||||
|
||||
LADSPA_Handle * ptr;
|
||||
|
||||
if ((ptr = malloc(sizeof(Tremolo))) != NULL) {
|
||||
((Tremolo *)ptr)->SampleRate = SampleRate;
|
||||
((Tremolo *)ptr)->run_adding_gain = 1.0;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
activate_Tremolo(LADSPA_Handle Instance) {
|
||||
|
||||
Tremolo * ptr;
|
||||
|
||||
ptr = (Tremolo *)Instance;
|
||||
ptr->Phase = 0.0f;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Connect a port to a data location. */
|
||||
void
|
||||
connect_port_Tremolo(LADSPA_Handle Instance,
|
||||
unsigned long Port,
|
||||
LADSPA_Data * DataLocation) {
|
||||
|
||||
Tremolo * ptr;
|
||||
|
||||
ptr = (Tremolo *)Instance;
|
||||
switch (Port) {
|
||||
case CONTROL_FREQ:
|
||||
ptr->Control_Freq = DataLocation;
|
||||
break;
|
||||
case CONTROL_DEPTH:
|
||||
ptr->Control_Depth = DataLocation;
|
||||
break;
|
||||
case CONTROL_GAIN:
|
||||
ptr->Control_Gain = DataLocation;
|
||||
break;
|
||||
case INPUT_0:
|
||||
ptr->InputBuffer_1 = DataLocation;
|
||||
break;
|
||||
case OUTPUT_0:
|
||||
ptr->OutputBuffer_1 = DataLocation;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
run_Tremolo(LADSPA_Handle Instance,
|
||||
unsigned long SampleCount) {
|
||||
|
||||
LADSPA_Data * input;
|
||||
LADSPA_Data * output;
|
||||
LADSPA_Data freq;
|
||||
LADSPA_Data depth;
|
||||
LADSPA_Data gain;
|
||||
Tremolo * ptr;
|
||||
unsigned long sample_index;
|
||||
LADSPA_Data phase = 0.0f;
|
||||
|
||||
ptr = (Tremolo *)Instance;
|
||||
|
||||
input = ptr->InputBuffer_1;
|
||||
output = ptr->OutputBuffer_1;
|
||||
freq = LIMIT(*(ptr->Control_Freq),0.0f,20.0f);
|
||||
depth = LIMIT(*(ptr->Control_Depth),0.0f,100.0f);
|
||||
gain = db2lin(LIMIT(*(ptr->Control_Gain),-70.0f,20.0f));
|
||||
|
||||
for (sample_index = 0; sample_index < SampleCount; sample_index++) {
|
||||
phase = 1024.0f * freq * sample_index / ptr->SampleRate + ptr->Phase;
|
||||
|
||||
while (phase >= 1024.0f)
|
||||
phase -= 1024.0f;
|
||||
|
||||
*(output++) = *(input++) * gain *
|
||||
(1 - 0.5*depth/100 + 0.5 * depth/100 * cos_table[(unsigned long) phase]);
|
||||
}
|
||||
ptr->Phase = phase;
|
||||
while (ptr->Phase >= 1024.0f)
|
||||
ptr->Phase -= 1024.0f;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
set_run_adding_gain_Tremolo(LADSPA_Handle Instance, LADSPA_Data gain) {
|
||||
|
||||
Tremolo * ptr;
|
||||
|
||||
ptr = (Tremolo *)Instance;
|
||||
|
||||
ptr->run_adding_gain = gain;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
run_adding_Tremolo(LADSPA_Handle Instance,
|
||||
unsigned long SampleCount) {
|
||||
|
||||
LADSPA_Data * input;
|
||||
LADSPA_Data * output;
|
||||
LADSPA_Data freq;
|
||||
LADSPA_Data depth;
|
||||
LADSPA_Data gain;
|
||||
Tremolo * ptr;
|
||||
unsigned long sample_index;
|
||||
LADSPA_Data phase = 0.0f;
|
||||
|
||||
ptr = (Tremolo *)Instance;
|
||||
|
||||
input = ptr->InputBuffer_1;
|
||||
output = ptr->OutputBuffer_1;
|
||||
freq = LIMIT(*(ptr->Control_Freq),0.0f,20.0f);
|
||||
depth = LIMIT(*(ptr->Control_Depth),0.0f,100.0f);
|
||||
gain = db2lin(LIMIT(*(ptr->Control_Gain),-70.0f,20.0f));
|
||||
|
||||
for (sample_index = 0; sample_index < SampleCount; sample_index++) {
|
||||
phase = 1024.0f * freq * sample_index / ptr->SampleRate + ptr->Phase;
|
||||
|
||||
while (phase >= 1024.0f)
|
||||
phase -= 1024.0f;
|
||||
|
||||
*(output++) += *(input++) * ptr->run_adding_gain * gain *
|
||||
(1 - 0.5*depth/100 + 0.5 * depth/100 * cos_table[(unsigned long) phase]);
|
||||
}
|
||||
ptr->Phase = phase;
|
||||
while (ptr->Phase >= 1024.0f)
|
||||
ptr->Phase -= 1024.0f;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Throw away a Tremolo effect instance. */
|
||||
void
|
||||
cleanup_Tremolo(LADSPA_Handle Instance) {
|
||||
free(Instance);
|
||||
}
|
||||
|
||||
|
||||
|
||||
LADSPA_Descriptor * mono_descriptor = NULL;
|
||||
|
||||
|
||||
|
||||
/* _init() is called automatically when the plugin library is first
|
||||
loaded. */
|
||||
void
|
||||
_init() {
|
||||
|
||||
char ** port_names;
|
||||
LADSPA_PortDescriptor * port_descriptors;
|
||||
LADSPA_PortRangeHint * port_range_hints;
|
||||
int i;
|
||||
|
||||
if ((mono_descriptor =
|
||||
(LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor))) == NULL)
|
||||
exit(1);
|
||||
|
||||
|
||||
for (i = 0; i < 1024; i++)
|
||||
cos_table[i] = cosf(i * M_PI / 512.0f);
|
||||
|
||||
|
||||
mono_descriptor->UniqueID = ID_MONO;
|
||||
mono_descriptor->Label = strdup("tap_tremolo");
|
||||
mono_descriptor->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
|
||||
mono_descriptor->Name = strdup("TAP Tremolo");
|
||||
mono_descriptor->Maker = strdup("Tom Szilagyi");
|
||||
mono_descriptor->Copyright = strdup("GPL");
|
||||
mono_descriptor->PortCount = PORTCOUNT_MONO;
|
||||
|
||||
if ((port_descriptors =
|
||||
(LADSPA_PortDescriptor *)calloc(PORTCOUNT_MONO, sizeof(LADSPA_PortDescriptor))) == NULL)
|
||||
exit(1);
|
||||
|
||||
mono_descriptor->PortDescriptors = (const LADSPA_PortDescriptor *)port_descriptors;
|
||||
port_descriptors[CONTROL_FREQ] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[CONTROL_DEPTH] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[CONTROL_GAIN] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[INPUT_0] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
|
||||
port_descriptors[OUTPUT_0] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
|
||||
|
||||
if ((port_names =
|
||||
(char **)calloc(PORTCOUNT_MONO, sizeof(char *))) == NULL)
|
||||
exit(1);
|
||||
|
||||
mono_descriptor->PortNames = (const char **)port_names;
|
||||
port_names[CONTROL_FREQ] = strdup("Frequency [Hz]");
|
||||
port_names[CONTROL_DEPTH] = strdup("Depth [%]");
|
||||
port_names[CONTROL_GAIN] = strdup("Gain [dB]");
|
||||
port_names[INPUT_0] = strdup("Input_0");
|
||||
port_names[OUTPUT_0] = strdup("Output_0");
|
||||
|
||||
if ((port_range_hints =
|
||||
((LADSPA_PortRangeHint *)calloc(PORTCOUNT_MONO, sizeof(LADSPA_PortRangeHint)))) == NULL)
|
||||
exit(1);
|
||||
|
||||
mono_descriptor->PortRangeHints = (const LADSPA_PortRangeHint *)port_range_hints;
|
||||
port_range_hints[CONTROL_FREQ].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[CONTROL_DEPTH].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[CONTROL_GAIN].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[CONTROL_FREQ].LowerBound = 0;
|
||||
port_range_hints[CONTROL_FREQ].UpperBound = 20;
|
||||
port_range_hints[CONTROL_DEPTH].LowerBound = 0;
|
||||
port_range_hints[CONTROL_DEPTH].UpperBound = 100;
|
||||
port_range_hints[CONTROL_GAIN].LowerBound = -70;
|
||||
port_range_hints[CONTROL_GAIN].UpperBound = 20;
|
||||
port_range_hints[INPUT_0].HintDescriptor = 0;
|
||||
port_range_hints[OUTPUT_0].HintDescriptor = 0;
|
||||
mono_descriptor->instantiate = instantiate_Tremolo;
|
||||
mono_descriptor->connect_port = connect_port_Tremolo;
|
||||
mono_descriptor->activate = activate_Tremolo;
|
||||
mono_descriptor->run = run_Tremolo;
|
||||
mono_descriptor->run_adding = run_adding_Tremolo;
|
||||
mono_descriptor->set_run_adding_gain = set_run_adding_gain_Tremolo;
|
||||
mono_descriptor->deactivate = NULL;
|
||||
mono_descriptor->cleanup = cleanup_Tremolo;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
delete_descriptor(LADSPA_Descriptor * descriptor) {
|
||||
unsigned long index;
|
||||
if (descriptor) {
|
||||
free((char *)descriptor->Label);
|
||||
free((char *)descriptor->Name);
|
||||
free((char *)descriptor->Maker);
|
||||
free((char *)descriptor->Copyright);
|
||||
free((LADSPA_PortDescriptor *)descriptor->PortDescriptors);
|
||||
for (index = 0; index < descriptor->PortCount; index++)
|
||||
free((char *)(descriptor->PortNames[index]));
|
||||
free((char **)descriptor->PortNames);
|
||||
free((LADSPA_PortRangeHint *)descriptor->PortRangeHints);
|
||||
free(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* _fini() is called automatically when the library is unloaded. */
|
||||
void
|
||||
_fini() {
|
||||
delete_descriptor(mono_descriptor);
|
||||
}
|
||||
|
||||
|
||||
/* Return a descriptor of the requested plugin type. */
|
||||
const LADSPA_Descriptor *
|
||||
ladspa_descriptor(unsigned long Index) {
|
||||
|
||||
switch (Index) {
|
||||
case 0:
|
||||
return mono_descriptor;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
491
plugins/ladspa_effect/tap/tap_tubewarmth.c
Normal file
491
plugins/ladspa_effect/tap/tap_tubewarmth.c
Normal file
@@ -0,0 +1,491 @@
|
||||
/* -*- linux-c -*-
|
||||
Copyright (C) 2004 Tom Szilagyi
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: tap_tubewarmth.c,v 1.1 2004/08/02 18:14:50 tszilagyi Exp $
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "ladspa.h"
|
||||
#include "tap_utils.h"
|
||||
|
||||
|
||||
/* The Unique ID of the plugin: */
|
||||
|
||||
#define ID_MONO 2158
|
||||
|
||||
/* The port numbers for the plugin: */
|
||||
|
||||
#define DRIVE 0
|
||||
#define BLEND 1
|
||||
#define INPUT 2
|
||||
#define OUTPUT 3
|
||||
|
||||
/* Total number of ports */
|
||||
|
||||
|
||||
#define PORTCOUNT_MONO 4
|
||||
|
||||
|
||||
/* The structure used to hold port connection information and state */
|
||||
|
||||
typedef struct {
|
||||
LADSPA_Data * drive;
|
||||
LADSPA_Data * blend;
|
||||
LADSPA_Data * input;
|
||||
LADSPA_Data * output;
|
||||
|
||||
LADSPA_Data prev_med;
|
||||
LADSPA_Data prev_out;
|
||||
|
||||
LADSPA_Data rdrive;
|
||||
LADSPA_Data rbdr;
|
||||
LADSPA_Data kpa;
|
||||
LADSPA_Data kpb;
|
||||
LADSPA_Data kna;
|
||||
LADSPA_Data knb;
|
||||
LADSPA_Data ap;
|
||||
LADSPA_Data an;
|
||||
LADSPA_Data imr;
|
||||
LADSPA_Data kc;
|
||||
LADSPA_Data srct;
|
||||
LADSPA_Data sq;
|
||||
LADSPA_Data pwrq;
|
||||
|
||||
LADSPA_Data prev_drive;
|
||||
LADSPA_Data prev_blend;
|
||||
|
||||
unsigned long sample_rate;
|
||||
LADSPA_Data run_adding_gain;
|
||||
} TubeWarmth;
|
||||
|
||||
|
||||
|
||||
/* Construct a new plugin instance. */
|
||||
LADSPA_Handle
|
||||
instantiate_TubeWarmth(const LADSPA_Descriptor * Descriptor,
|
||||
unsigned long sample_rate) {
|
||||
|
||||
LADSPA_Handle * ptr;
|
||||
|
||||
if ((ptr = malloc(sizeof(TubeWarmth))) != NULL) {
|
||||
((TubeWarmth *)ptr)->sample_rate = sample_rate;
|
||||
((TubeWarmth *)ptr)->run_adding_gain = 1.0f;
|
||||
|
||||
((TubeWarmth *)ptr)->prev_med = 0.0f;
|
||||
((TubeWarmth *)ptr)->prev_out = 0.0f;
|
||||
|
||||
((TubeWarmth *)ptr)->rdrive = 0.0f;
|
||||
((TubeWarmth *)ptr)->rbdr = 0.0f;
|
||||
((TubeWarmth *)ptr)->kpa = 0.0f;
|
||||
((TubeWarmth *)ptr)->kpb = 0.0f;
|
||||
((TubeWarmth *)ptr)->kna = 0.0f;
|
||||
((TubeWarmth *)ptr)->knb = 0.0f;
|
||||
((TubeWarmth *)ptr)->ap = 0.0f;
|
||||
((TubeWarmth *)ptr)->an = 0.0f;
|
||||
((TubeWarmth *)ptr)->imr = 0.0f;
|
||||
((TubeWarmth *)ptr)->kc = 0.0f;
|
||||
((TubeWarmth *)ptr)->srct = 0.0f;
|
||||
((TubeWarmth *)ptr)->sq = 0.0f;
|
||||
((TubeWarmth *)ptr)->pwrq = 0.0f;
|
||||
|
||||
/* These are out of band to force param recalc upon first run() */
|
||||
((TubeWarmth *)ptr)->prev_drive = -1.0f;
|
||||
((TubeWarmth *)ptr)->prev_blend = -11.0f;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Connect a port to a data location. */
|
||||
void
|
||||
connect_port_TubeWarmth(LADSPA_Handle Instance,
|
||||
unsigned long Port,
|
||||
LADSPA_Data * DataLocation) {
|
||||
|
||||
TubeWarmth * ptr = (TubeWarmth *)Instance;
|
||||
|
||||
switch (Port) {
|
||||
case DRIVE:
|
||||
ptr->drive = DataLocation;
|
||||
break;
|
||||
case BLEND:
|
||||
ptr->blend = DataLocation;
|
||||
break;
|
||||
case INPUT:
|
||||
ptr->input = DataLocation;
|
||||
break;
|
||||
case OUTPUT:
|
||||
ptr->output = DataLocation;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define EPS 0.000000001f
|
||||
|
||||
static inline float
|
||||
M(float x) {
|
||||
|
||||
if ((x > EPS) || (x < -EPS))
|
||||
return x;
|
||||
else
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
static inline float
|
||||
D(float x) {
|
||||
|
||||
if (x > EPS)
|
||||
return sqrt(x);
|
||||
else if (x < -EPS)
|
||||
return sqrt(-x);
|
||||
else
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
void
|
||||
run_TubeWarmth(LADSPA_Handle Instance,
|
||||
unsigned long SampleCount) {
|
||||
|
||||
TubeWarmth * ptr = (TubeWarmth *)Instance;
|
||||
LADSPA_Data * input = ptr->input;
|
||||
LADSPA_Data * output = ptr->output;
|
||||
LADSPA_Data drive = LIMIT(*(ptr->drive),0.1f,10.0f);
|
||||
LADSPA_Data blend = LIMIT(*(ptr->blend),-10.0f,10.0f);
|
||||
|
||||
unsigned long sample_index;
|
||||
unsigned long sample_count = SampleCount;
|
||||
unsigned long sample_rate = ptr->sample_rate;
|
||||
|
||||
LADSPA_Data rdrive = ptr->rdrive;
|
||||
LADSPA_Data rbdr = ptr->rbdr;
|
||||
LADSPA_Data kpa = ptr->kpa;
|
||||
LADSPA_Data kpb = ptr->kpb;
|
||||
LADSPA_Data kna = ptr->kna;
|
||||
LADSPA_Data knb = ptr->knb;
|
||||
LADSPA_Data ap = ptr->ap;
|
||||
LADSPA_Data an = ptr->an;
|
||||
LADSPA_Data imr = ptr->imr;
|
||||
LADSPA_Data kc = ptr->kc;
|
||||
LADSPA_Data srct = ptr->srct;
|
||||
LADSPA_Data sq = ptr->sq;
|
||||
LADSPA_Data pwrq = ptr->pwrq;
|
||||
|
||||
LADSPA_Data prev_med;
|
||||
LADSPA_Data prev_out;
|
||||
LADSPA_Data in;
|
||||
LADSPA_Data med;
|
||||
LADSPA_Data out;
|
||||
|
||||
if ((ptr->prev_drive != drive) || (ptr->prev_blend != blend)) {
|
||||
|
||||
rdrive = 12.0f / drive;
|
||||
rbdr = rdrive / (10.5f - blend) * 780.0f / 33.0f;
|
||||
kpa = D(2.0f * (rdrive*rdrive) - 1.0f) + 1.0f;
|
||||
kpb = (2.0f - kpa) / 2.0f;
|
||||
ap = ((rdrive*rdrive) - kpa + 1.0f) / 2.0f;
|
||||
kc = kpa / D(2.0f * D(2.0f * (rdrive*rdrive) - 1.0f) - 2.0f * rdrive*rdrive);
|
||||
|
||||
srct = (0.1f * sample_rate) / (0.1f * sample_rate + 1.0f);
|
||||
sq = kc*kc + 1.0f;
|
||||
knb = -1.0f * rbdr / D(sq);
|
||||
kna = 2.0f * kc * rbdr / D(sq);
|
||||
an = rbdr*rbdr / sq;
|
||||
imr = 2.0f * knb + D(2.0f * kna + 4.0f * an - 1.0f);
|
||||
pwrq = 2.0f / (imr + 1.0f);
|
||||
|
||||
ptr->prev_drive = drive;
|
||||
ptr->prev_blend = blend;
|
||||
}
|
||||
|
||||
for (sample_index = 0; sample_index < sample_count; sample_index++) {
|
||||
|
||||
in = *(input++);
|
||||
prev_med = ptr->prev_med;
|
||||
prev_out = ptr->prev_out;
|
||||
|
||||
if (in >= 0.0f) {
|
||||
med = (D(ap + in * (kpa - in)) + kpb) * pwrq;
|
||||
} else {
|
||||
med = (D(an - in * (kna + in)) + knb) * pwrq * -1.0f;
|
||||
}
|
||||
|
||||
out = srct * (med - prev_med + prev_out);
|
||||
|
||||
if (out < -1.0f)
|
||||
out = -1.0f;
|
||||
|
||||
*(output++) = out;
|
||||
|
||||
ptr->prev_med = M(med);
|
||||
ptr->prev_out = M(out);
|
||||
}
|
||||
|
||||
ptr->rdrive = rdrive;
|
||||
ptr->rbdr = rbdr;
|
||||
ptr->kpa = kpa;
|
||||
ptr->kpb = kpb;
|
||||
ptr->kna = kna;
|
||||
ptr->knb = knb;
|
||||
ptr->ap = ap;
|
||||
ptr->an = an;
|
||||
ptr->imr = imr;
|
||||
ptr->kc = kc;
|
||||
ptr->srct = srct;
|
||||
ptr->sq = sq;
|
||||
ptr->pwrq = pwrq;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
set_run_adding_gain_TubeWarmth(LADSPA_Handle Instance, LADSPA_Data gain) {
|
||||
|
||||
TubeWarmth * ptr = (TubeWarmth *)Instance;
|
||||
|
||||
ptr->run_adding_gain = gain;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
run_adding_TubeWarmth(LADSPA_Handle Instance,
|
||||
unsigned long SampleCount) {
|
||||
|
||||
TubeWarmth * ptr = (TubeWarmth *)Instance;
|
||||
LADSPA_Data * input = ptr->input;
|
||||
LADSPA_Data * output = ptr->output;
|
||||
LADSPA_Data drive = LIMIT(*(ptr->drive),0.1f,10.0f);
|
||||
LADSPA_Data blend = LIMIT(*(ptr->blend),-10.0f,10.0f);
|
||||
|
||||
unsigned long sample_index;
|
||||
unsigned long sample_count = SampleCount;
|
||||
unsigned long sample_rate = ptr->sample_rate;
|
||||
|
||||
LADSPA_Data rdrive = ptr->rdrive;
|
||||
LADSPA_Data rbdr = ptr->rbdr;
|
||||
LADSPA_Data kpa = ptr->kpa;
|
||||
LADSPA_Data kpb = ptr->kpb;
|
||||
LADSPA_Data kna = ptr->kna;
|
||||
LADSPA_Data knb = ptr->knb;
|
||||
LADSPA_Data ap = ptr->ap;
|
||||
LADSPA_Data an = ptr->an;
|
||||
LADSPA_Data imr = ptr->imr;
|
||||
LADSPA_Data kc = ptr->kc;
|
||||
LADSPA_Data srct = ptr->srct;
|
||||
LADSPA_Data sq = ptr->sq;
|
||||
LADSPA_Data pwrq = ptr->pwrq;
|
||||
|
||||
LADSPA_Data prev_med;
|
||||
LADSPA_Data prev_out;
|
||||
LADSPA_Data in;
|
||||
LADSPA_Data med;
|
||||
LADSPA_Data out;
|
||||
|
||||
if ((ptr->prev_drive != drive) || (ptr->prev_blend != blend)) {
|
||||
|
||||
rdrive = 12.0f / drive;
|
||||
rbdr = rdrive / (10.5f - blend) * 780.0f / 33.0f;
|
||||
kpa = D(2.0f * (rdrive*rdrive) - 1.0f) + 1.0f;
|
||||
kpb = (2.0f - kpa) / 2.0f;
|
||||
ap = ((rdrive*rdrive) - kpa + 1.0f) / 2.0f;
|
||||
kc = kpa / D(2.0f * D(2.0f * (rdrive*rdrive) - 1.0f) - 2.0f * rdrive*rdrive);
|
||||
|
||||
srct = (0.1f * sample_rate) / (0.1f * sample_rate + 1.0f);
|
||||
sq = kc*kc + 1.0f;
|
||||
knb = -1.0f * rbdr / D(sq);
|
||||
kna = 2.0f * kc * rbdr / D(sq);
|
||||
an = rbdr*rbdr / sq;
|
||||
imr = 2.0f * knb + D(2.0f * kna + 4.0f * an - 1.0f);
|
||||
pwrq = 2.0f / (imr + 1.0f);
|
||||
|
||||
ptr->prev_drive = drive;
|
||||
ptr->prev_blend = blend;
|
||||
}
|
||||
|
||||
for (sample_index = 0; sample_index < sample_count; sample_index++) {
|
||||
|
||||
in = *(input++);
|
||||
prev_med = ptr->prev_med;
|
||||
prev_out = ptr->prev_out;
|
||||
|
||||
if (in >= 0.0f) {
|
||||
med = (D(ap + in * (kpa - in)) + kpb) * pwrq;
|
||||
} else {
|
||||
med = (D(an - in * (kna + in)) + knb) * pwrq * -1.0f;
|
||||
}
|
||||
|
||||
out = srct * (med - prev_med + prev_out);
|
||||
|
||||
if (out < -1.0f)
|
||||
out = -1.0f;
|
||||
|
||||
*(output++) += out * ptr->run_adding_gain;
|
||||
|
||||
ptr->prev_med = M(med);
|
||||
ptr->prev_out = M(out);
|
||||
}
|
||||
|
||||
ptr->rdrive = rdrive;
|
||||
ptr->rbdr = rbdr;
|
||||
ptr->kpa = kpa;
|
||||
ptr->kpb = kpb;
|
||||
ptr->kna = kna;
|
||||
ptr->knb = knb;
|
||||
ptr->ap = ap;
|
||||
ptr->an = an;
|
||||
ptr->imr = imr;
|
||||
ptr->kc = kc;
|
||||
ptr->srct = srct;
|
||||
ptr->sq = sq;
|
||||
ptr->pwrq = pwrq;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Throw away a TubeWarmth effect instance. */
|
||||
void
|
||||
cleanup_TubeWarmth(LADSPA_Handle Instance) {
|
||||
|
||||
free(Instance);
|
||||
}
|
||||
|
||||
|
||||
|
||||
LADSPA_Descriptor * mono_descriptor = NULL;
|
||||
|
||||
|
||||
|
||||
/* _init() is called automatically when the plugin library is first
|
||||
loaded. */
|
||||
void
|
||||
_init() {
|
||||
|
||||
char ** port_names;
|
||||
LADSPA_PortDescriptor * port_descriptors;
|
||||
LADSPA_PortRangeHint * port_range_hints;
|
||||
|
||||
if ((mono_descriptor =
|
||||
(LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor))) == NULL)
|
||||
exit(1);
|
||||
|
||||
|
||||
mono_descriptor->UniqueID = ID_MONO;
|
||||
mono_descriptor->Label = strdup("tap_tubewarmth");
|
||||
mono_descriptor->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
|
||||
mono_descriptor->Name = strdup("TAP TubeWarmth");
|
||||
mono_descriptor->Maker = strdup("Tom Szilagyi");
|
||||
mono_descriptor->Copyright = strdup("GPL");
|
||||
mono_descriptor->PortCount = PORTCOUNT_MONO;
|
||||
|
||||
if ((port_descriptors =
|
||||
(LADSPA_PortDescriptor *)calloc(PORTCOUNT_MONO, sizeof(LADSPA_PortDescriptor))) == NULL)
|
||||
exit(1);
|
||||
|
||||
mono_descriptor->PortDescriptors = (const LADSPA_PortDescriptor *)port_descriptors;
|
||||
port_descriptors[DRIVE] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[BLEND] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[INPUT] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
|
||||
port_descriptors[OUTPUT] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
|
||||
|
||||
if ((port_names =
|
||||
(char **)calloc(PORTCOUNT_MONO, sizeof(char *))) == NULL)
|
||||
exit(1);
|
||||
|
||||
mono_descriptor->PortNames = (const char **)port_names;
|
||||
port_names[DRIVE] = strdup("Drive");
|
||||
port_names[BLEND] = strdup("Tape--Tube Blend");
|
||||
port_names[INPUT] = strdup("Input");
|
||||
port_names[OUTPUT] = strdup("Output");
|
||||
|
||||
if ((port_range_hints =
|
||||
((LADSPA_PortRangeHint *)calloc(PORTCOUNT_MONO, sizeof(LADSPA_PortRangeHint)))) == NULL)
|
||||
exit(1);
|
||||
|
||||
mono_descriptor->PortRangeHints = (const LADSPA_PortRangeHint *)port_range_hints;
|
||||
port_range_hints[DRIVE].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_LOW);
|
||||
port_range_hints[BLEND].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_MAXIMUM);
|
||||
port_range_hints[DRIVE].LowerBound = 0.1f;
|
||||
port_range_hints[DRIVE].UpperBound = 10.0f;
|
||||
port_range_hints[BLEND].LowerBound = -10.0f;
|
||||
port_range_hints[BLEND].UpperBound = 10.0f;
|
||||
port_range_hints[INPUT].HintDescriptor = 0;
|
||||
port_range_hints[OUTPUT].HintDescriptor = 0;
|
||||
mono_descriptor->instantiate = instantiate_TubeWarmth;
|
||||
mono_descriptor->connect_port = connect_port_TubeWarmth;
|
||||
mono_descriptor->activate = NULL;
|
||||
mono_descriptor->run = run_TubeWarmth;
|
||||
mono_descriptor->run_adding = run_adding_TubeWarmth;
|
||||
mono_descriptor->set_run_adding_gain = set_run_adding_gain_TubeWarmth;
|
||||
mono_descriptor->deactivate = NULL;
|
||||
mono_descriptor->cleanup = cleanup_TubeWarmth;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
delete_descriptor(LADSPA_Descriptor * descriptor) {
|
||||
unsigned long index;
|
||||
if (descriptor) {
|
||||
free((char *)descriptor->Label);
|
||||
free((char *)descriptor->Name);
|
||||
free((char *)descriptor->Maker);
|
||||
free((char *)descriptor->Copyright);
|
||||
free((LADSPA_PortDescriptor *)descriptor->PortDescriptors);
|
||||
for (index = 0; index < descriptor->PortCount; index++)
|
||||
free((char *)(descriptor->PortNames[index]));
|
||||
free((char **)descriptor->PortNames);
|
||||
free((LADSPA_PortRangeHint *)descriptor->PortRangeHints);
|
||||
free(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* _fini() is called automatically when the library is unloaded. */
|
||||
void
|
||||
_fini() {
|
||||
delete_descriptor(mono_descriptor);
|
||||
}
|
||||
|
||||
|
||||
/* Return a descriptor of the requested plugin type. */
|
||||
const LADSPA_Descriptor *
|
||||
ladspa_descriptor(unsigned long Index) {
|
||||
|
||||
switch (Index) {
|
||||
case 0:
|
||||
return mono_descriptor;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
260
plugins/ladspa_effect/tap/tap_utils.h
Normal file
260
plugins/ladspa_effect/tap/tap_utils.h
Normal file
@@ -0,0 +1,260 @@
|
||||
/* -*- linux-c -*-
|
||||
Copyright (C) 2004 Tom Szilagyi
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: tap_utils.h,v 1.5 2004/02/21 17:33:36 tszilagyi Exp $
|
||||
*/
|
||||
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846264338327
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* push a sample into a ringbuffer and return the sample falling out */
|
||||
static inline
|
||||
LADSPA_Data
|
||||
push_buffer(LADSPA_Data insample, LADSPA_Data * buffer,
|
||||
unsigned long buflen, unsigned long * pos) {
|
||||
|
||||
LADSPA_Data outsample;
|
||||
|
||||
outsample = buffer[*pos];
|
||||
buffer[(*pos)++] = insample;
|
||||
|
||||
if (*pos >= buflen)
|
||||
*pos = 0;
|
||||
|
||||
return outsample;
|
||||
}
|
||||
|
||||
|
||||
/* read a value from a ringbuffer.
|
||||
* n == 0 returns the oldest sample from the buffer.
|
||||
* n == buflen-1 returns the sample written to the buffer
|
||||
* at the last push_buffer call.
|
||||
* n must not exceed buflen-1, or your computer will explode.
|
||||
*/
|
||||
static inline
|
||||
LADSPA_Data
|
||||
read_buffer(LADSPA_Data * buffer, unsigned long buflen,
|
||||
unsigned long pos, unsigned long n) {
|
||||
|
||||
while (n + pos >= buflen)
|
||||
n -= buflen;
|
||||
return buffer[n + pos];
|
||||
}
|
||||
|
||||
|
||||
/* overwrites a value in a ringbuffer, but pos stays the same.
|
||||
* n == 0 overwrites the oldest sample pushed in the buffer.
|
||||
* n == buflen-1 overwrites the sample written to the buffer
|
||||
* at the last push_buffer call.
|
||||
* n must not exceed buflen-1, or your computer... you know.
|
||||
*/
|
||||
static inline
|
||||
void
|
||||
write_buffer(LADSPA_Data insample, LADSPA_Data * buffer, unsigned long buflen,
|
||||
unsigned long pos, unsigned long n) {
|
||||
|
||||
while (n + pos >= buflen)
|
||||
n -= buflen;
|
||||
buffer[n + pos] = insample;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Please note that the majority of the definitions and helper
|
||||
functions below have been derived from the source code of Steve
|
||||
Harris's SWH plugins (particularly from the "biquad.h" file). While I
|
||||
give him credit for his excellent work, I reserve myself to be blamed
|
||||
for any bugs or malfunction. */
|
||||
|
||||
|
||||
#define db2lin(x) ((x) > -90.0f ? powf(10.0f, (x) * 0.05f) : 0.0f)
|
||||
|
||||
#define ABS(x) (x)>0.0f?(x):-1.0f*(x)
|
||||
|
||||
|
||||
#define LN_2_2 0.34657359f
|
||||
#define FLUSH_TO_ZERO(x) (((*(unsigned int*)&(x))&0x7f800000)==0)?0.0f:(x)
|
||||
#define LIMIT(v,l,u) ((v)<(l)?(l):((v)>(u)?(u):(v)))
|
||||
|
||||
#define BIQUAD_TYPE float
|
||||
typedef BIQUAD_TYPE bq_t;
|
||||
|
||||
|
||||
/* Biquad filter (adapted from lisp code by Eli Brandt,
|
||||
http://www.cs.cmu.edu/~eli/) */
|
||||
|
||||
/* The prev. comment has been preserved from Steve Harris's biquad.h */
|
||||
|
||||
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) {
|
||||
|
||||
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 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);
|
||||
#if 0
|
||||
b0 = (1 - cs) /2;
|
||||
b1 = 1 - cs;
|
||||
b2 = (1 - cs) /2;
|
||||
a0 = 1 + alpha;
|
||||
a1 = -2 * cs;
|
||||
a2 = 1 - alpha;
|
||||
#endif
|
||||
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);
|
||||
|
||||
#if 0
|
||||
b0 = (1 + cs) /2;
|
||||
b1 = -(1 + cs);
|
||||
b2 = (1 + cs) /2;
|
||||
a0 = 1 + alpha;
|
||||
a1 = -2 * cs;
|
||||
a2 = 1 - alpha;
|
||||
#endif
|
||||
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
|
||||
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) {
|
||||
|
||||
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
|
||||
bq_t
|
||||
biquad_run(biquad *f, 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;
|
||||
}
|
||||
442
plugins/ladspa_effect/tap/tap_vibrato.c
Normal file
442
plugins/ladspa_effect/tap/tap_vibrato.c
Normal file
@@ -0,0 +1,442 @@
|
||||
/* -*- linux-c -*-
|
||||
Copyright (C) 2004 Tom Szilagyi
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: tap_vibrato.c,v 1.3 2004/02/21 17:33:36 tszilagyi Exp $
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "ladspa.h"
|
||||
#include "tap_utils.h"
|
||||
|
||||
|
||||
/* The Unique ID of the plugin: */
|
||||
|
||||
#define ID_MONO 2148
|
||||
|
||||
/* The port numbers for the plugin: */
|
||||
|
||||
#define FREQ 0
|
||||
#define DEPTH 1
|
||||
#define DRYLEVEL 2
|
||||
#define WETLEVEL 3
|
||||
#define LATENCY 4
|
||||
#define INPUT 5
|
||||
#define OUTPUT 6
|
||||
|
||||
/* Total number of ports */
|
||||
|
||||
|
||||
#define PORTCOUNT_MONO 7
|
||||
|
||||
|
||||
/*
|
||||
* This has to be bigger than 0.2f * sample_rate / (2*PI) for any sample rate.
|
||||
* At 192 kHz 6238 is needed so this should be enough.
|
||||
*/
|
||||
#define PM_DEPTH 6300
|
||||
|
||||
|
||||
#define PM_FREQ 30.0f
|
||||
|
||||
|
||||
#define COS_TABLE_SIZE 1024
|
||||
LADSPA_Data cos_table[COS_TABLE_SIZE];
|
||||
|
||||
|
||||
/* The structure used to hold port connection information and state */
|
||||
|
||||
typedef struct {
|
||||
LADSPA_Data * depth;
|
||||
LADSPA_Data * freq;
|
||||
LADSPA_Data * drylevel;
|
||||
LADSPA_Data * wetlevel;
|
||||
LADSPA_Data * latency;
|
||||
LADSPA_Data * input;
|
||||
LADSPA_Data * output;
|
||||
|
||||
LADSPA_Data * ringbuffer;
|
||||
unsigned long buflen;
|
||||
unsigned long pos;
|
||||
LADSPA_Data phase;
|
||||
|
||||
unsigned long sample_rate;
|
||||
LADSPA_Data run_adding_gain;
|
||||
} Vibrato;
|
||||
|
||||
|
||||
|
||||
/* Construct a new plugin instance. */
|
||||
LADSPA_Handle
|
||||
instantiate_Vibrato(const LADSPA_Descriptor * Descriptor,
|
||||
unsigned long sample_rate) {
|
||||
|
||||
LADSPA_Handle * ptr;
|
||||
|
||||
if ((ptr = malloc(sizeof(Vibrato))) != NULL) {
|
||||
((Vibrato *)ptr)->sample_rate = sample_rate;
|
||||
((Vibrato *)ptr)->run_adding_gain = 1.0f;
|
||||
|
||||
if ((((Vibrato *)ptr)->ringbuffer =
|
||||
calloc(2 * PM_DEPTH, sizeof(LADSPA_Data))) == NULL)
|
||||
return NULL;
|
||||
((Vibrato *)ptr)->buflen = ceil(0.2f * sample_rate / M_PI);
|
||||
((Vibrato *)ptr)->pos = 0;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
activate_Vibrato(LADSPA_Handle Instance) {
|
||||
|
||||
Vibrato * ptr = (Vibrato *)Instance;
|
||||
unsigned long i;
|
||||
|
||||
for (i = 0; i < 2 * PM_DEPTH; i++)
|
||||
ptr->ringbuffer[i] = 0.0f;
|
||||
|
||||
ptr->phase = 0.0f;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Connect a port to a data location. */
|
||||
void
|
||||
connect_port_Vibrato(LADSPA_Handle Instance,
|
||||
unsigned long Port,
|
||||
LADSPA_Data * DataLocation) {
|
||||
|
||||
Vibrato * ptr = (Vibrato *)Instance;
|
||||
|
||||
switch (Port) {
|
||||
case DEPTH:
|
||||
ptr->depth = DataLocation;
|
||||
break;
|
||||
case FREQ:
|
||||
ptr->freq = DataLocation;
|
||||
break;
|
||||
case DRYLEVEL:
|
||||
ptr->drylevel = DataLocation;
|
||||
break;
|
||||
case WETLEVEL:
|
||||
ptr->wetlevel = DataLocation;
|
||||
break;
|
||||
case LATENCY:
|
||||
ptr->latency = DataLocation;
|
||||
*(ptr->latency) = ptr->buflen / 2; /* IS THIS LEGAL? */
|
||||
break;
|
||||
case INPUT:
|
||||
ptr->input = DataLocation;
|
||||
break;
|
||||
case OUTPUT:
|
||||
ptr->output = DataLocation;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
run_Vibrato(LADSPA_Handle Instance,
|
||||
unsigned long SampleCount) {
|
||||
|
||||
Vibrato * ptr = (Vibrato *)Instance;
|
||||
|
||||
LADSPA_Data freq = LIMIT(*(ptr->freq),0.0f,PM_FREQ);
|
||||
LADSPA_Data depth =
|
||||
LIMIT(LIMIT(*(ptr->depth),0.0f,20.0f) * ptr->sample_rate / 200.0f / M_PI / freq,
|
||||
0, ptr->buflen / 2);
|
||||
LADSPA_Data drylevel = db2lin(LIMIT(*(ptr->drylevel),-90.0f,20.0f));
|
||||
LADSPA_Data wetlevel = db2lin(LIMIT(*(ptr->wetlevel),-90.0f,20.0f));
|
||||
LADSPA_Data * input = ptr->input;
|
||||
LADSPA_Data * output = ptr->output;
|
||||
|
||||
unsigned long sample_index;
|
||||
unsigned long sample_count = SampleCount;
|
||||
|
||||
LADSPA_Data in = 0.0f;
|
||||
LADSPA_Data phase = 0.0f;
|
||||
LADSPA_Data fpos = 0.0f;
|
||||
LADSPA_Data n = 0.0f;
|
||||
LADSPA_Data rem = 0.0f;
|
||||
LADSPA_Data s_a, s_b;
|
||||
|
||||
|
||||
if (freq == 0.0f)
|
||||
depth = 0.0f;
|
||||
|
||||
for (sample_index = 0; sample_index < sample_count; sample_index++) {
|
||||
|
||||
in = *(input++);
|
||||
|
||||
phase = COS_TABLE_SIZE * freq * sample_index / ptr->sample_rate + ptr->phase;
|
||||
while (phase >= COS_TABLE_SIZE)
|
||||
phase -= COS_TABLE_SIZE;
|
||||
|
||||
push_buffer(in, ptr->ringbuffer, ptr->buflen, &(ptr->pos));
|
||||
|
||||
fpos = depth * (1.0f - cos_table[(unsigned long) phase]);
|
||||
n = floorf(fpos);
|
||||
rem = fpos - n;
|
||||
|
||||
s_a = read_buffer(ptr->ringbuffer, ptr->buflen, ptr->pos, (unsigned long) n);
|
||||
s_b = read_buffer(ptr->ringbuffer, ptr->buflen, ptr->pos, (unsigned long) n + 1);
|
||||
|
||||
*(output++) = wetlevel * ((1 - rem) * s_a + rem * s_b) +
|
||||
drylevel * read_buffer(ptr->ringbuffer, ptr->buflen,
|
||||
ptr->pos, ptr->buflen / 2);
|
||||
|
||||
}
|
||||
|
||||
ptr->phase += COS_TABLE_SIZE * freq * sample_index / ptr->sample_rate;
|
||||
while (ptr->phase >= COS_TABLE_SIZE)
|
||||
ptr->phase -= COS_TABLE_SIZE;
|
||||
|
||||
*(ptr->latency) = ptr->buflen / 2;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
set_run_adding_gain_Vibrato(LADSPA_Handle Instance, LADSPA_Data gain) {
|
||||
|
||||
Vibrato * ptr = (Vibrato *)Instance;
|
||||
|
||||
ptr->run_adding_gain = gain;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
run_adding_Vibrato(LADSPA_Handle Instance,
|
||||
unsigned long SampleCount) {
|
||||
|
||||
Vibrato * ptr = (Vibrato *)Instance;
|
||||
|
||||
LADSPA_Data freq = LIMIT(*(ptr->freq),0.0f,PM_FREQ);
|
||||
LADSPA_Data depth =
|
||||
LIMIT(LIMIT(*(ptr->depth),0.0f,20.0f) * ptr->sample_rate / 200.0f / M_PI / freq,
|
||||
0, ptr->buflen / 2);
|
||||
LADSPA_Data drylevel = db2lin(LIMIT(*(ptr->drylevel),-90.0f,20.0f));
|
||||
LADSPA_Data wetlevel = db2lin(LIMIT(*(ptr->wetlevel),-90.0f,20.0f));
|
||||
LADSPA_Data * input = ptr->input;
|
||||
LADSPA_Data * output = ptr->output;
|
||||
|
||||
unsigned long sample_index;
|
||||
unsigned long sample_count = SampleCount;
|
||||
|
||||
LADSPA_Data in = 0.0f;
|
||||
LADSPA_Data phase = 0.0f;
|
||||
LADSPA_Data fpos = 0.0f;
|
||||
LADSPA_Data n = 0.0f;
|
||||
LADSPA_Data rem = 0.0f;
|
||||
LADSPA_Data s_a, s_b;
|
||||
|
||||
|
||||
if (freq == 0.0f)
|
||||
depth = 0.0f;
|
||||
|
||||
for (sample_index = 0; sample_index < sample_count; sample_index++) {
|
||||
|
||||
in = *(input++);
|
||||
|
||||
phase = COS_TABLE_SIZE * freq * sample_index / ptr->sample_rate + ptr->phase;
|
||||
while (phase >= COS_TABLE_SIZE)
|
||||
phase -= COS_TABLE_SIZE;
|
||||
|
||||
push_buffer(in, ptr->ringbuffer, ptr->buflen, &(ptr->pos));
|
||||
|
||||
fpos = depth * (1.0f - cos_table[(unsigned long) phase]);
|
||||
n = floorf(fpos);
|
||||
rem = fpos - n;
|
||||
|
||||
s_a = read_buffer(ptr->ringbuffer, ptr->buflen, ptr->pos, (unsigned long) n);
|
||||
s_b = read_buffer(ptr->ringbuffer, ptr->buflen, ptr->pos, (unsigned long) n + 1);
|
||||
|
||||
*(output++) += ptr->run_adding_gain * wetlevel * ((1 - rem) * s_a + rem * s_b) +
|
||||
drylevel * read_buffer(ptr->ringbuffer, ptr->buflen,
|
||||
ptr->pos, ptr->buflen / 2);
|
||||
|
||||
}
|
||||
|
||||
ptr->phase += COS_TABLE_SIZE * freq * sample_index / ptr->sample_rate;
|
||||
while (ptr->phase >= COS_TABLE_SIZE)
|
||||
ptr->phase -= COS_TABLE_SIZE;
|
||||
|
||||
*(ptr->latency) = ptr->buflen / 2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Throw away a Vibrato effect instance. */
|
||||
void
|
||||
cleanup_Vibrato(LADSPA_Handle Instance) {
|
||||
|
||||
Vibrato * ptr = (Vibrato *)Instance;
|
||||
free(ptr->ringbuffer);
|
||||
free(Instance);
|
||||
}
|
||||
|
||||
|
||||
|
||||
LADSPA_Descriptor * mono_descriptor = NULL;
|
||||
|
||||
|
||||
|
||||
/* _init() is called automatically when the plugin library is first
|
||||
loaded. */
|
||||
void
|
||||
_init() {
|
||||
|
||||
int i;
|
||||
char ** port_names;
|
||||
LADSPA_PortDescriptor * port_descriptors;
|
||||
LADSPA_PortRangeHint * port_range_hints;
|
||||
|
||||
if ((mono_descriptor =
|
||||
(LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor))) == NULL)
|
||||
exit(1);
|
||||
|
||||
for (i = 0; i < COS_TABLE_SIZE; i++)
|
||||
cos_table[i] = cosf(i * 2.0f * M_PI / COS_TABLE_SIZE);
|
||||
|
||||
mono_descriptor->UniqueID = ID_MONO;
|
||||
mono_descriptor->Label = strdup("tap_vibrato");
|
||||
mono_descriptor->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
|
||||
mono_descriptor->Name = strdup("TAP Vibrato");
|
||||
mono_descriptor->Maker = strdup("Tom Szilagyi");
|
||||
mono_descriptor->Copyright = strdup("GPL");
|
||||
mono_descriptor->PortCount = PORTCOUNT_MONO;
|
||||
|
||||
if ((port_descriptors =
|
||||
(LADSPA_PortDescriptor *)calloc(PORTCOUNT_MONO, sizeof(LADSPA_PortDescriptor))) == NULL)
|
||||
exit(1);
|
||||
|
||||
mono_descriptor->PortDescriptors = (const LADSPA_PortDescriptor *)port_descriptors;
|
||||
port_descriptors[DEPTH] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[FREQ] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[DRYLEVEL] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[WETLEVEL] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[LATENCY] = LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL;
|
||||
port_descriptors[INPUT] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
|
||||
port_descriptors[OUTPUT] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
|
||||
|
||||
if ((port_names =
|
||||
(char **)calloc(PORTCOUNT_MONO, sizeof(char *))) == NULL)
|
||||
exit(1);
|
||||
|
||||
mono_descriptor->PortNames = (const char **)port_names;
|
||||
port_names[FREQ] = strdup("Frequency [Hz]");
|
||||
port_names[DEPTH] = strdup("Depth [%]");
|
||||
port_names[DRYLEVEL] = strdup("Dry Level [dB]");
|
||||
port_names[WETLEVEL] = strdup("Wet Level [dB]");
|
||||
port_names[LATENCY] = strdup("latency");
|
||||
port_names[INPUT] = strdup("Input");
|
||||
port_names[OUTPUT] = strdup("Output");
|
||||
|
||||
if ((port_range_hints =
|
||||
((LADSPA_PortRangeHint *)calloc(PORTCOUNT_MONO, sizeof(LADSPA_PortRangeHint)))) == NULL)
|
||||
exit(1);
|
||||
|
||||
mono_descriptor->PortRangeHints = (const LADSPA_PortRangeHint *)port_range_hints;
|
||||
port_range_hints[DEPTH].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[FREQ].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[DRYLEVEL].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_MINIMUM);
|
||||
port_range_hints[WETLEVEL].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_0);
|
||||
port_range_hints[LATENCY].HintDescriptor =
|
||||
(LADSPA_HINT_BOUNDED_BELOW |
|
||||
LADSPA_HINT_BOUNDED_ABOVE |
|
||||
LADSPA_HINT_DEFAULT_MAXIMUM);
|
||||
port_range_hints[DEPTH].LowerBound = 0;
|
||||
port_range_hints[DEPTH].UpperBound = 20.0f;
|
||||
port_range_hints[FREQ].LowerBound = 0;
|
||||
port_range_hints[FREQ].UpperBound = PM_FREQ;
|
||||
port_range_hints[DRYLEVEL].LowerBound = -90.0f;
|
||||
port_range_hints[DRYLEVEL].UpperBound = +20.0f;
|
||||
port_range_hints[WETLEVEL].LowerBound = -90.0f;
|
||||
port_range_hints[WETLEVEL].UpperBound = +20.0f;
|
||||
port_range_hints[LATENCY].LowerBound = 0;
|
||||
port_range_hints[LATENCY].UpperBound = PM_DEPTH;
|
||||
port_range_hints[INPUT].HintDescriptor = 0;
|
||||
port_range_hints[OUTPUT].HintDescriptor = 0;
|
||||
mono_descriptor->instantiate = instantiate_Vibrato;
|
||||
mono_descriptor->connect_port = connect_port_Vibrato;
|
||||
mono_descriptor->activate = activate_Vibrato;
|
||||
mono_descriptor->run = run_Vibrato;
|
||||
mono_descriptor->run_adding = run_adding_Vibrato;
|
||||
mono_descriptor->set_run_adding_gain = set_run_adding_gain_Vibrato;
|
||||
mono_descriptor->deactivate = NULL;
|
||||
mono_descriptor->cleanup = cleanup_Vibrato;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
delete_descriptor(LADSPA_Descriptor * descriptor) {
|
||||
unsigned long index;
|
||||
if (descriptor) {
|
||||
free((char *)descriptor->Label);
|
||||
free((char *)descriptor->Name);
|
||||
free((char *)descriptor->Maker);
|
||||
free((char *)descriptor->Copyright);
|
||||
free((LADSPA_PortDescriptor *)descriptor->PortDescriptors);
|
||||
for (index = 0; index < descriptor->PortCount; index++)
|
||||
free((char *)(descriptor->PortNames[index]));
|
||||
free((char **)descriptor->PortNames);
|
||||
free((LADSPA_PortRangeHint *)descriptor->PortRangeHints);
|
||||
free(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* _fini() is called automatically when the library is unloaded. */
|
||||
void
|
||||
_fini() {
|
||||
delete_descriptor(mono_descriptor);
|
||||
}
|
||||
|
||||
|
||||
/* Return a descriptor of the requested plugin type. */
|
||||
const LADSPA_Descriptor *
|
||||
ladspa_descriptor(unsigned long Index) {
|
||||
|
||||
switch (Index) {
|
||||
case 0:
|
||||
return mono_descriptor;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user