Add CMT Submodule (#5755)

Switch ladspa CMT plugins to submodule
This commit is contained in:
Tres Finocchiaro
2020-11-01 00:37:38 -04:00
committed by GitHub
parent 615d36b08b
commit afd037eaec
59 changed files with 10 additions and 11119 deletions

3
.gitmodules vendored
View File

@@ -46,3 +46,6 @@
[submodule "src/3rdparty/jack2"]
path = src/3rdparty/jack2
url = https://github.com/jackaudio/jack2
[submodule "plugins/LadspaEffect/cmt/cmt"]
path = plugins/LadspaEffect/cmt/cmt
url = https://github.com/lmms/cmt

View File

@@ -1,5 +1,5 @@
INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/include")
FILE(GLOB_RECURSE SOURCES src/*.cpp)
FILE(GLOB_RECURSE SOURCES cmt/src/*.cpp)
LIST(SORT SOURCES)
ADD_LIBRARY(cmt MODULE ${SOURCES})
INSTALL(TARGETS cmt LIBRARY DESTINATION "${PLUGIN_DIR}/ladspa")
@@ -7,13 +7,13 @@ INSTALL(TARGETS cmt LIBRARY DESTINATION "${PLUGIN_DIR}/ladspa")
SET_TARGET_PROPERTIES(cmt PROPERTIES PREFIX "")
SET_TARGET_PROPERTIES(cmt PROPERTIES COMPILE_FLAGS "-Wall -O3 -fno-strict-aliasing")
IF(LMMS_BUILD_WIN32)
ADD_CUSTOM_COMMAND(TARGET cmt POST_BUILD COMMAND "${STRIP}" \"$<TARGET_FILE:cmt>\")
ELSE(LMMS_BUILD_WIN32)
IF(LMMS_BUILD_WIN32 AND NOT CMAKE_BUILD_TYPE MATCHES "Deb")
ADD_CUSTOM_COMMAND(TARGET cmt POST_BUILD COMMAND "${STRIP}" "$<TARGET_FILE:cmt>")
ELSE()
SET_TARGET_PROPERTIES(cmt PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} -fPIC")
ENDIF(LMMS_BUILD_WIN32)
ENDIF()
IF(NOT LMMS_BUILD_APPLE AND NOT LMMS_BUILD_OPENBSD)
SET_TARGET_PROPERTIES(cmt PROPERTIES LINK_FLAGS "${LINK_FLAGS} -shared -Wl,-no-undefined")
ENDIF(NOT LMMS_BUILD_APPLE AND NOT LMMS_BUILD_OPENBSD)
ENDIF()

View File

@@ -1,7 +0,0 @@
Computer Music Toolkit (CMT)
----------------------------
This toolkit is a set of musical sound processing and synthesis tools
presented as a LADSPA plugin library. See the doc/ directory for
documentation and installation instructions. See http://www.ladspa.org
for LADSPA information. See http://www.ladspa.org/cmt for CMT updates.

View File

@@ -1,340 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <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) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<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.

View File

@@ -1,54 +0,0 @@
<H1>Adding Plugins to the CMT Library</H1>
<P>The CMT <A HREF="http://www.ladspa.org">
LADSPA</A> plugin collection is written in C++ and uses a little
additional sophistication to make plugin writing easier. This document
describes how to add a new plugin to the toolkit.</P>
<P>At the moment CMT is not under public version control, so please
send changes to <A HREF="mailto:richard@muse.demon.co.uk">Richard
Furse</A>.</P>
<P>CMT plugins interpret <CODE>LADSPA_Handle</CODE> entities as
pointers to objects derived from the <CODE>CMT_PluginInstance</CODE>
class. Plugin instance structures are defined by subclassing this, so
writing a descendent of <CODE>CMT_PluginInstance</CODE> is the first
thing to do. The CMT library provides its own implementation of
<CODE>connect_port()</CODE>, <CODE>cleanup()</CODE> and a templated
form of <CODE>instantiate()</CODE> (see
<CODE>CMT_Instantiate<>()</CODE>). These calls assume that any
instantiation or cleanup mechanisms required will be written in the
constructor or destructor of the class.</P>
<P>When writing a plugin module, an initialisation function should be
included. To ensure this is called, add a call to the
<CODE>initialise_modules()</CODE> function in
<CODE>descriptor.cpp</CODE>. The module should also be added to the
<CODE>makefile</CODE>.</P>
<P>Your initialisation function should construct new
<CODE>CMT_Desctiptor</CODE> plugin descriptor structures and pass them
to <CODE>registerNewPluginDescriptor()</CODE>. The
<CODE>CMT_Descriptor</CODE> is directly descended from
<CODE>LADSPA_Descriptor</CODE> but provides constructor, destructor
and <CODE>addPort()</CODE> methods.</P>
<P>All plugins need unique IDs. During development, use values between
1 and 1000. When the plugin is ready, please request an ID from <A
HREF="mailto:ladspa@muse.demon.co.uk">ladspa@muse.demon.co.uk</A>. Please
also add a brief description of your module to <A
HREF="plugins.html"><CODE>plugins.html</CODE></A>.</P>
<P>In practice, CMT plugin writing is probably best learned by
example. For a simple case, see the <CODE>mixer.cpp</CODE>
module. This defines a <CODE>SimpleMixer</CODE> class to handle
instance data, a <CODE>runSimpleMixer()</CODE> function for use with
it and a <CODE>mixer_descriptor()</CODE> function to provide a
description of the plugin to the CMT core. The
<CODE>mixer_descriptor()</CODE> function is declared and referenced in
the <CODE>descriptor.cpp</CODE> module. Additional information is
available in <CODE>cmt.h</CODE> and <CODE>ladspa.h</CODE>.</P>
<P>CMT plugins are <A HREF="license.html">licenced</A> under GPL
version 2. Please read and understand this license before submitting
plugins to the library.</P>

View File

@@ -1,20 +0,0 @@
<H1>CMT Bugs</H1>
<P>Please report bugs to <A HREF="mailto:richard@muse.demon.co.uk">
richard@muse.demon.co.uk</A>.</P>
<UL>
<LI>I'm not sure I've got attack & decay the right way around in the
expander plugins.</LI>
<LI>Need to have a look at dynamic.cpp for handling of unusual
arithmetic situation such as <CODE>isnan()</CODE>,
<CODE>isinf()</CODE> etc.</LI>
<LI>Memory management is a little haphazard at present. What happens
when <CODE>new()</CODE> fails? The host can use
<CODE>set_new_handler()</CODE>, but I suspect this needs further
thought anyway.</LI>
</UL>

View File

@@ -1,149 +0,0 @@
<H1>CMT Changes</H1>
<H2>Version 1.01 - 4 May 2000</H2>
<UL>
<LI>Initial Release.</LI>
</UL>
<H2>Version 1.02 - 11 May 2000</H2>
<UL>
<LI>Use <CODE>_init()</CODE> and <CODE>_fini()</CODE>. To handle
memory management automatically.</LI>
<LI>Change from <CODE>*_descriptor()</CODE> approach simpler
initialise_*() approach. Use <CODE>_init()</CODE> and
<CODE>_fini()</CODE> to handle memory management. Supply
<CODE>CMT_Descriptor::~CMT_Descriptor()</CODE>.</LI>
<LI>Make comments compatible with Doxygen.</LI>
<LI>Addition of Ambisonic encoder, decoder, converter and rotation
plugins.</LI>
<LI>Addition of Sine Waveshaper and Granular Scatter Processor
plugin.</LI>
</UL>
<H2>Version 1.03 - 14 May 2000</H2>
<UL>
<LI>Updated to correspond to http://www.ladspa.org/.</LI>
</UL>
<H2>Version 1.04 - 18 May 2000</H2>
<UL>
<LI>Bugfixes: Ambisonic encoder inputs, white noise amplitude/DC,
Ambisonic rotation inplace support, sine oscillator frequency input
inplace support.</LI>
</UL>
<H2>Version 1.05 - 18 May 2000</H2>
<UL>
<LI>Bugfix: use explicit pointer type when deleting
<CODE>ImplementationData</CODE> in <CODE>~CMT_Descriptor</CODE>.</LI>
</UL>
<H2>Version 1.06 - 24 Sep 2000</H2>
<UL>
<LI>Introduction of Identity plugins.</LI>
</UL>
<H2>Version 1.07 - 30 Sep 2000</H2>
<UL>
<LI>Use constructor/destructor rather than _fini() and _init(). Use
C++ for linkage.</LI>
</UL>
<H2>Version 1.08 - 30 Sep 2000</H2>
<UL>
<LI>Fix to Ambisonic decode equations.</LI>
</UL>
<H2>Version 1.09 - 4 Nov 2000</H2>
<UL>
<LI>Addition of a port of Freeverb (version 3) and a collection of
plugins by David Bartold (analogue, canyon_delay, organ, syndrum,
vcf303).</LI>
</UL>
<H2>Version 1.10 - 17 Feb 2001</H2>
<UL>
<LI>Small compile fixes to some modules. Apologies to David who sent
me a patch ages ago for the analogue module.</LI>
</UL>
<H2>Version 1.11 - 8 May 2001</H2>
<UL>
<LI>Addition of newline character to end of allpass.h.</LI>
</UL>
<H2>Version 1.12 - 17 Sept 2001</H2>
<UL>
<LI>Addition of new plugins by David: "Lo Fi" and "Phase Modulated
Voice."</LI>
</UL>
<H2>Version 1.13 - 7 May 2002</H2>
<UL>
<LI>Fix to B-Format rotation algorithm.</LI>
</UL>
<H2>Version 1.14 - 7 Aug 2002</H2>
<UL>
<LI>Fix to B-Format rotation algorithm.</LI>
<LI>Update for LADSPA 1.1 (include default values).</LI>
</UL>
<H2> Version 1.15 - 19 Dec 2002 </H2>
<UL>
<LI>Addition of a number of utility routines and namespaces by
Nathaniel Virgo.</LI>
<LI>Addition of a number of plugins by Nathaniel Virgo.</LI>
<LI>Small change to trigger mechanism in syndrum plugin.</LI>
</UL>
<H2> Version 1.16 - 6 Nov 2007 </H2>
<UL>
<LI>Remove -Werror from compile options in makefile.</LI>
<LI>Remove "local" part from install directories.</LI>
<LI>Small additional changes to makefile for robustness.</LI>
<LI>Replace strdup() with localStrdup() to avoid malloc/new
mismatch.</LI>
</UL>

View File

@@ -1,26 +0,0 @@
<H1>CMT Index</H1>
<UL>
<LI><A HREF="overview.html">Overview</A></LI>
<LI><A HREF="http://www.ladspa.org/download/">Download</A></LI>
<LI><A HREF="installation.html">Installation</A></LI>
<LI><A HREF="license.html">License (LGPL)</A></LI>
<LI><A HREF="plugins.html">Plugins in the Library</A></LI>
<LI><A HREF="adding_plugins.html">Adding Plugins to the Library</A></LI>
<LI><A HREF="changes.html">Change History</A></LI>
<LI><A HREF="bugs.html">Bugs</A></LI>
<LI><A HREF="tasks.html">Task List</A></LI>
</UL>
<H2>Other Links</H2>
<UL>
<LI>The <A HREF="http://www.ladspa.org/ladspa_sdk">LADSPA Software
Development Kit</A></LI>
</UL>
<P><AUTHOR>Richard Furse</AUTHOR> can be emailed as <A
HREF="mailto:richard@muse.demon.co.uk">richard@muse.demon.co.uk</A>.
</P>

View File

@@ -1,19 +0,0 @@
<H1>CMT Installation</H1>
<P>To build the plugin library, enter the <CODE>src/</CODE> directory
and run <CODE>make</CODE>. The makefile expects to find the
<CODE>ladspa.h</CODE> header file in your include path or
<CODE>/usr/local/include/</CODE>. If you do not have this file it can
be downloaded as part of the LADSPA SDK from <A
HREF="http://www.ladspa.org/download/">
http://www.ladspa.org/download/</A>.</P>
<P>Running <CODE>make</CODE> will generate the CMT LADSPA plugin
library (<CODE>cmt.so</CODE>) in the <CODE>plugins/</CODE>
directory. This can be moved to an appropriate location depending on
the application you are using. Running <CODE>make install</CODE> from
the <CODE>src/</CODE> directory as root will install to
<CODE>/usr/local/lib/ladspa/</CODE> which is on the search path
recommended for hosts looking for plugin libraries. Some applications
may not search this directory automatically.</P>

View File

@@ -1,16 +0,0 @@
<H1>CMT License</H1>
<P>The CMT toolkit is licensed under <A HREF="COPYING">GPL version
2</A>.</P>
<P>As I understand it (I'm not a lawyer) this means that, once built,
the CMT library <EM>may</EM> be used with non-GPL'd applications as
long as it is built and loaded using the standard LADSPA
dynamic-linking approach without modification. In my opinion this is a
good thing for the toolkit, if not for the GPL.</P>
<P>The above may not be correct when built against the LGPL version of
the ladpsa.h header file, but it is certainly the way we would like
things to be. See the <A
HREF="http://www.ladspa.org/ladspa_sdk/license.html">LADPSA
license</A> for further details.</P>

View File

@@ -1,14 +0,0 @@
<H1>Computer Music Toolkit (CMT) v1.16 Overview</H1>
<P>The Computer Music Toolkit (CMT) is a collection of <A
HREF="http://www.ladspa.org">LADSPA</A> plugins for use with software
synthesis and recording packages on Linux. See the <A
HREF="license.html">license</A> before use.</P>
<P>The CMT was initially designed and developed by Richard W.E. Furse
(who was also the principal designer of the LADSPA standard) and
further plugins have been provided by by Jezar, David Bartold and
Nathaniel Virgo. If you are a programmer or can write documentation
and would like to help out, please feel free to <A
HREF="mailto:richard@muse.demon.co.uk">contact Richard</A>.</P>

View File

@@ -1,477 +0,0 @@
<H1>CMT Library Plugins</H1>
<P>The following plugins are provided in the CMT library:</P>
<TABLE BORDER=1>
<TR>
<TH>Plugin ID</TH>
<TH>Plugin Label</TH>
<TH>Description</TH>
</TR>
<TR>
<TD>1051</TD>
<TD>lpf</TD>
<TD>Low Pass Filter (One Pole).</TD>
</TR>
<TR>
<TD>1052</TD>
<TD>hpf</TD>
<TD>High Pass Filter (One Pole).</TD>
</TR>
<TR>
<TD>1053</TD>
<TD>delay_0.01s</TD>
<TD>Echo Delay Line. The delay time may be varied up to 0.01
seconds. No feedback is provided.</TD>
</TR>
<TR>
<TD>1054</TD>
<TD>delay_0.1s</TD>
<TD>Echo Delay Line. The delay time may be varied up to 0.1
seconds. No feedback is provided.</TD>
</TR>
<TR>
<TD>1055</TD>
<TD>delay_1s</TD>
<TD>Echo Delay Line. The delay time may be varied up to 1
second. No feedback is provided.</TD>
</TR>
<TR>
<TD>1056</TD>
<TD>delay_5s</TD>
<TD>Echo Delay Line. The delay time may be varied up to 5
seconds. No feedback is provided.</TD>
</TR>
<TR>
<TD>1057</TD>
<TD>delay_60s</TD>
<TD>Echo Delay Line. The delay time may be varied up to 60
seconds. No feedback is provided.</TD>
</TR>
<TR>
<TD>1058</TD>
<TD>fbdelay_0.01s</TD>
<TD>Feedback Delay Line. The delay time may be varied up to 0.01
seconds.</TD>
</TR>
<TR>
<TD>1059</TD>
<TD>fbdelay_0.1s</TD>
<TD>Feedback Delay Line. The delay time may be varied up to 0.1
seconds.</TD>
</TR>
<TR>
<TD>1060</TD>
<TD>fbdelay_1s</TD>
<TD>Feedback Delay Line. The delay time may be varied up to 1
second.</TD>
</TR>
<TR>
<TD>1061</TD>
<TD>fbdelay_5s</TD>
<TD>Feedback Delay Line. The delay time may be varied up to 5
seconds.</TD>
</TR>
<TR>
<TD>1062</TD>
<TD>fbdelay_60s</TD>
<TD>Feedback Delay Line. The delay time may be varied up to 60
seconds.</TD>
</TR>
<TR>
<TD>1063</TD>
<TD>sine_faaa</TD>
<TD>Sine Oscillator. Frequency input is audio, Amplitude input is
audio.</TD>
</TR>
<TR>
<TD>1064</TD>
<TD>sine_faac</TD>
<TD>Sine Oscillator. Frequency input is audio, Amplitude input is
control.</TD>
</TR>
<TR>
<TD>1065</TD>
<TD>sine_fcaa</TD>
<TD>Sine Oscillator. Frequency input is control, Amplitude input is
audio.</TD>
</TR>
<TR>
<TD>1066</TD>
<TD>sine_fcac</TD>
<TD>Sine Oscillator. Frequency input is control, Amplitude input is
control.</TD>
</TR>
<TR>
<TD>1067</TD>
<TD>amp_mono</TD>
<TD>Amplifier (Mono).</TD>
</TR>
<TR>
<TD>1068</TD>
<TD>amp_stereo</TD>
<TD>Amplifier (Stereo).</TD>
</TR>
<TR>
<TD>1069</TD>
<TD>noise_source_white</TD>
<TD>Noise Source (White).</TD>
</TR>
<TR>
<TD>1070</TD>
<TD>am</TD>
<TD>Amplitude Modulator.</TD>
</TR>
<TR>
<TD>1071</TD>
<TD>mixer</TD>
<TD>Mixer (Stereo to Mono).</TD>
</TR>
<TR>
<TD>1072</TD>
<TD>compress_peak</TD>
<TD>Simple Compressor (Peak Envelope Tracking).</TD>
</TR>
<TR>
<TD>1073</TD>
<TD>compress_rms</TD>
<TD>Simple Compressor (RMS Envelope Tracking).</TD>
</TR>
<TR>
<TD>1074</TD>
<TD>expand_peak</TD>
<TD>Simple Expander (Peak Envelope Tracking).</TD>
</TR>
<TR>
<TD>1075</TD>
<TD>expand_rms</TD>
<TD>Simple Expander (RMS Envelope Tracking).</TD>
</TR>
<TR>
<TD>1076</TD>
<TD>limit_peak</TD>
<TD>Simple Limiter (Peak Envelope Tracking).</TD>
</TR>
<TR>
<TD>1077</TD>
<TD>limit_rms</TD>
<TD>Simple Limiter (RMS Envelope Tracking).</TD>
</TR>
<TR>
<TD>1078</TD>
<TD>track_peak</TD>
<TD>Envelope Tracker (Peak).</TD>
</TR>
<TR>
<TD>1079</TD>
<TD>track_rms</TD>
<TD>Envelope Tracker (RMS).</TD>
</TR>
<TR>
<TD>1080</TD>
<TD>track_max_peak</TD>
<TD>Envelope Tracker (Maximum Peak).</TD>
</TR>
<TR>
<TD>1081</TD>
<TD>track_max_rms</TD>
<TD>Envelope Tracker (Maximum RMS).</TD>
</TR>
<TR>
<TD>1082</TD>
<TD>peak</TD>
<TD>Peak Monitor.</TD>
</TR>
<TR>
<TD>1083</TD>
<TD>null_ci</TD>
<TD>Null Plugin (Control Input).</TD>
</TR>
<TR>
<TD>1084</TD>
<TD>null_ai</TD>
<TD>Null Plugin (Audio Input).</TD>
</TR>
<TR>
<TD>1085</TD>
<TD>null_co</TD>
<TD>Null Plugin (Control Output).</TD>
</TR>
<TR>
<TD>1086</TD>
<TD>null_ao</TD>
<TD>Null Plugin (Audio Output).</TD>
</TR>
<TR>
<TD>1087</TD>
<TD>encode_bformat</TD>
<TD>B-Format Encoder. This plugin encodes ambisonic B-Format audio
using the inverse square law but no filtering, reverb or delay.</TD>
</TR>
<TR>
<TD>1088</TD>
<TD>encode_fmh</TD>
<TD>FMH-Format Encoder. This plugin encodes ambisonic FMH-Format audio
using the inverse square law but no filtering, reverb or delay.</TD>
</TR>
<TR>
<TD>1089</TD>
<TD>fmh2bf</TD>
<TD>FMH-Format to B-Format. This plugin simply discards the R, S, T, U
and V channels but is included for clarity.</TD>
</TR>
<TR>
<TD>1090</TD>
<TD>bf2stereo</TD>
<TD>B-Format to Stereo Ambisonic Decoder. This plugin only actually
uses its W and Y input signals and does not use UHJ.</TD>
</TR>
<TR>
<TD>1091</TD>
<TD>bf2quad</TD>
<TD>B-Format to Quad Ambisonic Decoder. This plugin only actually uses
its W, Y and Z input signals.</TD>
</TR>
<TR>
<TD>1092</TD>
<TD>bf2cube</TD>
<TD>B-Format to Cube Ambisonic Decoder.</TD>
</TR>
<TR>
<TD>1093</TD>
<TD>bf2oct</TD>
<TD>FMH-Format to Octagon Ambisonic Decoder. This plugin only actually
uses its W, X, Y, U and V inputs.</TD>
</TR>
<TR>
<TD>1094</TD>
<TD>bf_rotate_z</TD>
<TD>B-Format Rotation (Horizontal). This plugin rotates an B-Format
encoded soundfield around the Z-axis.</TD>
</TR>
<TR>
<TD>1095</TD>
<TD>fmh_rotate_z</TD>
<TD>FMH-Format Rotation (Horizontal). This plugin rotates an
FMH-Format encoded soundfield around the Z-axis.</TD>
</TR>
<TR>
<TD>1096</TD>
<TD>grain_scatter</TD>
<TD>Granular Scattering Processor. This plugin generates an output
audio stream by scattering short `grains' of sound from an input
stream. It is possible to control the length and envelope of these
grains, how far away from their source time grains may be scattered
and the density (grains/sec) of the texture produced.</TD>
</TR>
<TR>
<TD>1097</TD>
<TD>wsshape_sine</TD>
<TD>Wave Shaper (Sine-Based).</TD>
</TR>
<TR>
<TD>1098</TD>
<TD>identity_audio</TD>
<TD>Identity (Audio).</TD>
</TR>
<TR>
<TD>1099</TD>
<TD>identity_control</TD>
<TD>Identity (Control).</TD>
</TR>
<TR>
<TD>1123</TD>
<TD>freeverb3</TD>
<TD>Freeverb (Version 3). This reverb unit is a direct port of the
free public domain source code available from <A
HREF="http://www.dreampoint.co.uk">Jezar at Dreampoint</A>.</TD>
</TR>
<TR>
<TD>1221</TD>
<TD>analogue</TD>
<TD>Analogue Synthesizer Voice. Contains two audio oscillators, one LFO,
and three ADSRs. There are five waveforms available for the DCOs:
Sine, Triangle, Square, Sawtooth, and Fullwave rectified sine. The DCOs
may be frequency modulated and/or pulse width modulated by the LFO.</TD>
</TR>
<TR>
<TD>1222</TD>
<TD>organ</TD>
<TD>Organ Voice with Configurable Harmonics. The user may control the
loudness of the harmonics. There are three additional tones that may
be enabled and combined: brass, flute, and reed. Two ADSRs control
the envelope for the upper and lower harmonics.</TD>
</TR>
<TR>
<TD>1223</TD>
<TD>syndrum</TD>
<TD>Drum Synthesizer.</TD>
</TR>
<TR>
<TD>1224</TD>
<TD>vcf303</TD>
<TD>VCF 303. A TB-303 resonant filter clone.</TD>
</TR>
<TR>
<TD>1225</TD>
<TD>canyon_delay</TD>
<TD>Canyon Delay. A deep stereo crossdelay with built-in low pass
filters.</TD>
</TR>
<TR>
<TD>1226</TD>
<TD>phasemod</TD>
<TD>Phase Modulated Synthesizer Voice. Contains six audio oscillators, each
oscillator phase modulates the next. If a modulation coefficient is zero,
then the former oscillator's output is summed with the module's output.
DCO1's phase modulation parameter specifies an offset not a coefficient.
Example modulation parameters {1.0, 0.5, 0.0, 0.5, 0.2, 0.0} for all
six oscillators results in the output function: DCO2 (phase = DCO1 (phase =
1.0) * 0.5) + DCO5 (phase = DCO4 (phase = DCO3 (phase = 0.0) * 0.5) * 0.2) +
DCO6 (phase = 0.0). Each oscillator's output is bounded by -1.0 and 1.0,
or -360<SUP>o</SUP> and 360<SUP>o</SUP>.</TD>
</TR>
<TR>
<TD>1227</TD>
<TD>lofi</TD>
<TD>Lo Fi. Simulates old audio equipment. Adds distortion,
bandwidth limiting, compression, and crackling to audio.</TD>
</TR>
<TR>
<TD>1841</TD>
<TD>pink_interpolated_audio</TD>
<TD>Interpolated pink noise. Pink noise is a kind of random
one-dimensional fractal. This plugin approximates the effect of an
extreme low pass filter on a pink noise signal. It is useful as a
natural-sounding continuously varying control signal with long-term
trends as well as short-term variation. If you use it to control the
pitch of a sine wave it can sound a bit like wind blowing. Notice that
the average value tends to gradually drift over long periods of
time. This is in the nature of pink noise, and so can't be
helped.</TD>
</TR>
<TR>
<TD>1843</TD>
<TD>pink_sh</TD>
<TD>Sample and hold pink noise. Similar to pink, but with stepped
instead of interpolated output.</TD>
</TR>
<TR>
<TD>1844</TD>
<TD>pink_full_frequency</TD>
<TD>Pink noise simulation with a full frequency range. You can low
pass filter this to get a similar effect to the interpolated pink
noise generator.</TD>
</TR>
<TR>
<TD>1845</TD>
<TD>hard_gate</TD>
<TD>Hard noise gate. If the absolute value of the signal falls below
"threshold", it is set to zero. There is no antialiasing.</TD>
</TR>
<TR>
<TD>1846</TD>
<TD>disintegrator</TD>
<TD>Amplifies random half-cycles of it's input by multiplier. Set
multiplier to 0 and vary probability for a weird fade effect, or set
multiplier to -1 and probability to 0.5 to turn pitched sounds into
noise.</TD>
</TR>
<TR>
<TD>1848</TD>
<TD>sledgehammer</TD>
<TD>A Dynamic Sledgehammer, which you can use to bash your signals
into shape. It's basically a very simple and heavy compressor with a
sidechain. Try it with a pad sound as the carrier and a drum loop as
the modulator. Also, you can get some nice "Satan Maximiser"-style
distortion by not connecting the modulator (set it's influence to 0)
and putting the rate up to around 0.1.</TD>
</TR>
<TR>
<TD>1849</TD>
<TD>logistic</TD>
<TD>Logistic Map chaotic stepped control generator. The logistic map
is a classic example from chaos theory. It can be summarised by the
formula <pre>x := r*x*(1-x).</pre> With r<3, x just converges to a
constant value. With r just greater than 3 it oscillates with period
2. at about 3.45 the period doubles again to 4. These period doublings
occur at smaller and smaller increments of r, until at about 3.5699
there have been an infinite number and the signal never
repeates. Between this value and 4 the system exhibits chaotic
behaviour (although there are regions of periodicity). Papers are
still being published today on the subject of this system's
behaviour. This plugin iterates this map at a given frequency to
produce a stepped signal, which is scaled to lie in the range
(-1,1). When this signal is used as a frequency control it can
sometimes sound quite musical.</TD>
</TR>
</TABLE>
<P>"Ambisonics" is a registered trademark of Nimbus Communications
International.</P>

View File

@@ -1,36 +0,0 @@
<H1>CMT Library Task List</H1>
<H2>Basic Plugins Needed</H2>
<UL>
<LI>Noise Gate</LI>
<LI>Flanger</LI>
<LI>Phaser</LI>
<LI>Chorus</LI>
<LI>Unbounded Delay (echo & feedback)</LI>
<LI>Distortion</LI>
<LI>Overdrive</LI>
<LI>Exciter</LI>
<LI>Resonant Filter</LI>
<LI>Graphic EQ</LI>
<LI>Envelope Generator</LI>
</UL>
<H2>Other Plugins Planned</H2>
<UL>
<LI>Vocoder</LI>
</UL>
<H2>Other Tasks</H2>
<UL>
<LI>Think up a better name than CMT.</LI>
</UL>

View File

@@ -1,103 +0,0 @@
/* am.cpp
Computer Music Toolkit - a library of LADSPA plugins. Copyright (C)
2000 Richard W.E. Furse. The author may be contacted at
richard@muse.demon.co.uk.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public Licence as
published by the Free Software Foundation; either version 2 of the
Licence, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA. */
/*****************************************************************************/
#include <stdlib.h>
#include <string.h>
/*****************************************************************************/
#include "cmt.h"
/*****************************************************************************/
#define AM_INPUT1 0
#define AM_INPUT2 1
#define AM_OUTPUT 2
/** This plugin multiplies two signals together to produce a third. */
class AmplitudeModulator : public CMT_PluginInstance {
public:
AmplitudeModulator(const LADSPA_Descriptor *,
unsigned long)
: CMT_PluginInstance(3) {
}
friend void runAmplitudeModulator(LADSPA_Handle Instance,
unsigned long SAmplitudeModulatorpleCount);
};
/*****************************************************************************/
void
runAmplitudeModulator(LADSPA_Handle Instance,
unsigned long SAmplitudeModulatorpleCount) {
AmplitudeModulator * poAmplitudeModulator = (AmplitudeModulator *)Instance;
LADSPA_Data * pfInput1 = poAmplitudeModulator->m_ppfPorts[AM_INPUT1];
LADSPA_Data * pfInput2 = poAmplitudeModulator->m_ppfPorts[AM_INPUT2];
LADSPA_Data * pfOutput = poAmplitudeModulator->m_ppfPorts[AM_OUTPUT];
for (unsigned long lSAmplitudeModulatorpleIndex = 0;
lSAmplitudeModulatorpleIndex < SAmplitudeModulatorpleCount;
lSAmplitudeModulatorpleIndex++)
*(pfOutput++) = *(pfInput1++) * *(pfInput2++);
}
/*****************************************************************************/
void
initialise_am() {
CMT_Descriptor * psDescriptor = new CMT_Descriptor
(1070,
"am",
LADSPA_PROPERTY_HARD_RT_CAPABLE,
"Amplitude Modulator",
CMT_MAKER("Richard W.E. Furse"),
CMT_COPYRIGHT("2000", "Richard W.E. Furse"),
NULL,
CMT_Instantiate<AmplitudeModulator>,
NULL,
runAmplitudeModulator,
NULL,
NULL,
NULL);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
"Input 1");
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
"Input 2");
psDescriptor->addPort
(LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
"Output");
registerNewPluginDescriptor(psDescriptor);
}
/*****************************************************************************/
/* EOF */

File diff suppressed because it is too large Load Diff

View File

@@ -1,186 +0,0 @@
/* amp.cpp
Computer Music Toolkit - a library of LADSPA plugins. Copyright (C)
2000-2002 Richard W.E. Furse. The author may be contacted at
richard@muse.demon.co.uk.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public Licence as
published by the Free Software Foundation; either version 2 of the
Licence, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA. */
/*****************************************************************************/
#include <stdlib.h>
/*****************************************************************************/
#include "cmt.h"
/*****************************************************************************/
#define AMP_CONTROL 0
#define AMP_INPUT1 1
#define AMP_OUTPUT1 2
/** This plugin applies a gain to a mono signal. */
class MonoAmplifier : public CMT_PluginInstance {
public:
MonoAmplifier(const LADSPA_Descriptor *,
unsigned long)
: CMT_PluginInstance(3) {
}
friend void runMonoAmplifier(LADSPA_Handle Instance,
unsigned long SampleCount);
};
/*****************************************************************************/
/* Ports as above, plus... */
#define AMP_INPUT2 3
#define AMP_OUTPUT2 4
/** This plugin applies a gain to a stereo signal. */
class StereoAmplifier : public CMT_PluginInstance {
public:
StereoAmplifier(const LADSPA_Descriptor *,
unsigned long)
: CMT_PluginInstance(5) {
}
friend void runStereoAmplifier(LADSPA_Handle Instance,
unsigned long SampleCount);
};
/*****************************************************************************/
void
runMonoAmplifier(LADSPA_Handle Instance,
unsigned long SampleCount) {
MonoAmplifier * poAmplifier = (MonoAmplifier *)Instance;
LADSPA_Data * pfInput = poAmplifier->m_ppfPorts[AMP_INPUT1];
LADSPA_Data * pfOutput = poAmplifier->m_ppfPorts[AMP_OUTPUT1];
LADSPA_Data fGain = *(poAmplifier->m_ppfPorts[AMP_CONTROL]);
for (unsigned long lSampleIndex = 0;
lSampleIndex < SampleCount;
lSampleIndex++)
*(pfOutput++) = *(pfInput++) * fGain;
}
/*****************************************************************************/
void
runStereoAmplifier(LADSPA_Handle Instance,
unsigned long SampleCount) {
unsigned long lSampleIndex;
StereoAmplifier * poAmplifier = (StereoAmplifier *)Instance;
LADSPA_Data fGain = *(poAmplifier->m_ppfPorts[AMP_CONTROL]);
LADSPA_Data * pfInput = poAmplifier->m_ppfPorts[AMP_INPUT1];
LADSPA_Data * pfOutput = poAmplifier->m_ppfPorts[AMP_OUTPUT1];
for (lSampleIndex = 0; lSampleIndex < SampleCount; lSampleIndex++)
*(pfOutput++) = *(pfInput++) * fGain;
pfInput = poAmplifier->m_ppfPorts[AMP_INPUT2];
pfOutput = poAmplifier->m_ppfPorts[AMP_OUTPUT2];
for (lSampleIndex = 0; lSampleIndex < SampleCount; lSampleIndex++)
*(pfOutput++) = *(pfInput++) * fGain;
}
/*****************************************************************************/
void
initialise_amp() {
CMT_Descriptor * psDescriptor;
psDescriptor = new CMT_Descriptor
(1067,
"amp_mono",
LADSPA_PROPERTY_HARD_RT_CAPABLE,
"Amplifier (Mono)",
CMT_MAKER("Richard W.E. Furse"),
CMT_COPYRIGHT("2000-2002", "Richard W.E. Furse"),
NULL,
CMT_Instantiate<MonoAmplifier>,
NULL,
runMonoAmplifier,
NULL,
NULL,
NULL);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Gain",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_LOGARITHMIC
| LADSPA_HINT_DEFAULT_1),
0,
0);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
"Input");
psDescriptor->addPort
(LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
"Output");
registerNewPluginDescriptor(psDescriptor);
psDescriptor = new CMT_Descriptor
(1068,
"amp_stereo",
LADSPA_PROPERTY_HARD_RT_CAPABLE,
"Amplifier (Stereo)",
CMT_MAKER("Richard W.E. Furse"),
CMT_COPYRIGHT("2000-2002", "Richard W.E. Furse"),
NULL,
CMT_Instantiate<StereoAmplifier>,
NULL,
runStereoAmplifier,
NULL,
NULL,
NULL);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Gain",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_LOGARITHMIC
| LADSPA_HINT_DEFAULT_1),
0,
0);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
"Input (Left)");
psDescriptor->addPort
(LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
"Output (Left)");
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
"Input (Right)");
psDescriptor->addPort
(LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
"Output (Right)");
registerNewPluginDescriptor(psDescriptor);
}
/*****************************************************************************/
/* EOF */

View File

@@ -1,504 +0,0 @@
/* analogue.cpp
Analogue Voice - Analog synthesizer voice
Copyright (c) 2000 David A. Bartold
Computer Music Toolkit - a library of LADSPA plugins. Copyright (C)
2000 Richard W.E. Furse. The author may be contacted at
richard@muse.demon.co.uk.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public Licence as
published by the Free Software Foundation; either version 2 of the
Licence, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA. */
/*****************************************************************************/
#include <math.h>
#include <stdlib.h>
#include "cmt.h"
#define PORT_OUT 0
#define PORT_GATE 1
#define PORT_VELOCITY 2
#define PORT_FREQ 3
#define PORT_DCO1_OCTAVE 4
#define PORT_DCO1_WAVEFORM 5
#define PORT_DCO1_FM 6
#define PORT_DCO1_PWM 7
#define PORT_DCO1_ATTACK 8
#define PORT_DCO1_DECAY 9
#define PORT_DCO1_SUSTAIN 10
#define PORT_DCO1_RELEASE 11
#define PORT_DCO2_OCTAVE 12
#define PORT_DCO2_WAVEFORM 13
#define PORT_DCO2_FM 14
#define PORT_DCO2_PWM 15
#define PORT_DCO2_ATTACK 16
#define PORT_DCO2_DECAY 17
#define PORT_DCO2_SUSTAIN 18
#define PORT_DCO2_RELEASE 19
#define PORT_LFO_FREQ 20
#define PORT_LFO_FADEIN 21
#define PORT_FILT_ENV_MOD 22
#define PORT_FILT_LFO_MOD 23
#define PORT_FILT_RES 24
#define PORT_FILT_ATTACK 25
#define PORT_FILT_DECAY 26
#define PORT_FILT_SUSTAIN 27
#define PORT_FILT_RELEASE 28
#define NUM_PORTS 29
#ifndef PI
#define PI 3.14159265358979F
#endif
typedef struct Envelope
{
int envelope_decay;
LADSPA_Data envelope;
Envelope () : envelope_decay (0), envelope (0.0) {}
} Envelope;
class Analogue : public CMT_PluginInstance
{
LADSPA_Data sample_rate;
int trigger;
Envelope dco1_env;
Envelope dco2_env;
Envelope filt_env;
LADSPA_Data d1;
LADSPA_Data d2;
LADSPA_Data dco1_accum;
LADSPA_Data dco2_accum;
LADSPA_Data lfo_accum;
LADSPA_Data lfo_vol;
public:
Analogue(const LADSPA_Descriptor * Descriptor,
unsigned long SampleRate)
: CMT_PluginInstance(NUM_PORTS),
sample_rate (SampleRate),
trigger (0),
d1 (0.0), d2 (0.0),
dco1_accum (0.0), dco2_accum (0.0), lfo_accum (0.0) {
}
~Analogue () {
}
/* Third-order approximation of a sine wave. */
static inline LADSPA_Data
fast_sin(LADSPA_Data x) {
if (x > PI)
x = (x < PI * 1.5F) ? (PI - x) : (x - 2.0F * PI);
else if (x > PI * 0.5F)
x = PI - x;
return x * (1.05F - x * x * 0.175F);
}
static inline LADSPA_Data
tri(LADSPA_Data x) {
if (x > 0.75F)
x = x - 1.0F;
else if (x > 0.25F)
x = 0.5F - x;
return x * 4.0F;
}
static inline LADSPA_Data
envelope(Envelope *env,
int gate,
LADSPA_Data attack,
LADSPA_Data decay,
LADSPA_Data sustain,
LADSPA_Data release)
{
if (gate)
if (env->envelope_decay == 0)
{
env->envelope += (1.0F - env->envelope) * attack;
if (env->envelope >= 0.95F)
env->envelope_decay = 1;
}
else
env->envelope += (sustain - env->envelope) * decay;
else
env->envelope += -env->envelope * release;
return env->envelope;
}
static void
activate(LADSPA_Handle Instance) {
Analogue *analogue = (Analogue*) Instance;
analogue->trigger = 0;
analogue->dco1_env.envelope_decay = 0;
analogue->dco1_env.envelope = 0.0;
analogue->dco2_env.envelope_decay = 0;
analogue->dco2_env.envelope = 0.0;
analogue->filt_env.envelope_decay = 0;
analogue->filt_env.envelope = 0.0;
analogue->d1 = 0.0F;
analogue->d2 = 0.0F;
analogue->dco1_accum = 0.0F;
analogue->dco2_accum = 0.0F;
analogue->lfo_accum = 0.0F;
analogue->lfo_vol = 0.0F;
}
static inline LADSPA_Data
osc(int waveform,
LADSPA_Data inc,
LADSPA_Data width,
LADSPA_Data *accum) {
*accum += inc;
while (*accum >= 1.0F)
*accum -= 1.0F;
/* 0 = Sine wave */
if (waveform == 0)
if (*accum < width)
return fast_sin (*accum / width * PI);
else
return fast_sin (PI + (*accum - width) / (1.0F - width) * PI);
/* 1 = Triangle wave */
else if (waveform == 1)
if (*accum < width)
return tri (*accum / width * 0.5);
else
return tri (0.5 + (*accum - width) * 0.5 / (1.0F - width));
/* 2 = Square wave */
else if (waveform == 2)
return (*accum > width) ? 1.0F : -1.0F;
/* 3 = Sawtooth wave */
else if (waveform == 3)
if (*accum < width)
return *accum / width * 2.0F - 1.0F;
else
return (*accum - width) / (1.0F - width) * 2.0F - 1.0F;
/* 4 = Fullwave Rectified Sine wave */
else if (waveform == 4)
if (*accum < width)
return fast_sin (*accum / width * PI);
else
return fast_sin ((*accum - width) / (1.0F - width) * PI);
/* 5 = Static */
else
return (rand () & 1) ? -1.0F : 1.0F;
}
static LADSPA_Data
inc(LADSPA_Data oct,
LADSPA_Data freq,
LADSPA_Data sample_rate) {
return pow (2.0, oct) * freq / sample_rate;
}
static void
calc_a_b_c(Analogue *analogue,
LADSPA_Data freq,
LADSPA_Data *a,
LADSPA_Data *b,
LADSPA_Data *c) {
LADSPA_Data top_freq, k, res;
top_freq = freq;
top_freq *= PI / analogue->sample_rate;
res = exp (-1.20 + 3.455 * *analogue->m_ppfPorts[PORT_FILT_RES]);
k = exp (-top_freq / res);
*a = 2.0 * cos (2.0 * top_freq) * k;
*b = -k * k;
*c = (1.0 - *a - *b) * 0.2;
}
static inline LADSPA_Data
multiplier(Analogue *analogue,
LADSPA_Data value) {
return 1.0 - pow (0.05, 1.0 / (analogue->sample_rate * value));
}
static void
run(LADSPA_Handle Instance,
unsigned long SampleCount) {
Analogue *analogue = (Analogue*) Instance;
unsigned long i;
int waveform1, waveform2;
int gate;
LADSPA_Data lfo_inc, inc1, inc2;
LADSPA_Data attack1, decay1, release1;
LADSPA_Data attack2, decay2, release2;
LADSPA_Data filt_attack, filt_decay, filt_release;
LADSPA_Data lfo_fadein, a = 0, b = 0, c = 0;
LADSPA_Data dco1_pwm, dco2_pwm;
LADSPA_Data dco1_fm, dco2_fm;
LADSPA_Data filt_lfo_mod;
LADSPA_Data **ports;
ports = analogue->m_ppfPorts;
gate = (*ports[PORT_GATE] > 0.0);
if (gate == 1 && analogue->trigger == 0)
{
analogue->lfo_vol = 0.0F;
analogue->dco1_env.envelope_decay = 0;
analogue->dco1_env.envelope = 0.0;
analogue->dco2_env.envelope_decay = 0;
analogue->dco2_env.envelope = 0.0;
analogue->filt_env.envelope_decay = 0;
analogue->filt_env.envelope = 0.0;
}
analogue->trigger = gate;
waveform1 = (int) *ports[PORT_DCO1_WAVEFORM];
waveform2 = (int) *ports[PORT_DCO2_WAVEFORM];
inc1 = inc (*ports[PORT_DCO1_OCTAVE],
*ports[PORT_FREQ],
analogue->sample_rate);
inc2 = inc (*ports[PORT_DCO2_OCTAVE],
*ports[PORT_FREQ],
analogue->sample_rate);
lfo_inc = 2.0F * PI * *ports[PORT_LFO_FREQ] / analogue->sample_rate;
attack1 = multiplier (analogue, *ports[PORT_DCO1_ATTACK]);
decay1 = multiplier (analogue, *ports[PORT_DCO1_DECAY]);
release1 = multiplier (analogue, *ports[PORT_DCO1_RELEASE]);
attack2 = multiplier (analogue, *ports[PORT_DCO2_ATTACK]);
decay2 = multiplier (analogue, *ports[PORT_DCO2_DECAY]);
release2 = multiplier (analogue, *ports[PORT_DCO2_RELEASE]);
filt_attack = multiplier (analogue, *ports[PORT_FILT_ATTACK]);
filt_decay = multiplier (analogue, *ports[PORT_FILT_DECAY]);
filt_release = multiplier (analogue, *ports[PORT_FILT_RELEASE]);
lfo_fadein = 1.0 / (*ports[PORT_LFO_FADEIN] * analogue->sample_rate);
dco1_pwm = *analogue->m_ppfPorts[PORT_DCO1_PWM] * 0.225F;
dco2_pwm = *analogue->m_ppfPorts[PORT_DCO2_PWM] * 0.225F;
dco1_fm = *analogue->m_ppfPorts[PORT_DCO1_FM] * inc1 * 0.45F;
dco2_fm = *analogue->m_ppfPorts[PORT_DCO2_FM] * inc2 * 0.45F;
filt_lfo_mod = *analogue->m_ppfPorts[PORT_FILT_LFO_MOD] * 0.45F;
for (i = 0; i < SampleCount; i++)
{
LADSPA_Data lfo, sample;
analogue->lfo_accum += lfo_inc;
while (analogue->lfo_accum >= 2.0F * PI)
analogue->lfo_accum -= 2.0F * PI;
lfo = fast_sin (analogue->lfo_accum) * analogue->lfo_vol;
analogue->lfo_vol += lfo_fadein;
if (analogue->lfo_vol >= 1.0F)
analogue->lfo_vol = 1.0F;
envelope (&analogue->filt_env,
gate, filt_attack, filt_decay,
*ports[PORT_FILT_SUSTAIN], filt_release);
if ((i & 0x000f) == 0)
calc_a_b_c (analogue,
*ports[PORT_FREQ] * 0.25F + (analogue->filt_env.envelope *
*ports[PORT_FILT_ENV_MOD] * *ports[PORT_VELOCITY] *
(1.5 + filt_lfo_mod * lfo)) * *ports[PORT_FREQ] * 10.0F, &a, &b, &c);
sample = osc (waveform1, inc1 * (1.0 + lfo * dco1_fm),
0.5F + lfo * dco1_pwm,
&analogue->dco1_accum)
* envelope (&analogue->dco1_env,
gate, attack1, decay1,
*ports[PORT_DCO1_SUSTAIN], release1)
+ osc (waveform2, inc2 * (1.0 + lfo * dco2_fm),
0.5F + lfo * dco2_pwm,
&analogue->dco2_accum)
* envelope (&analogue->dco2_env,
gate, attack2, decay2,
*ports[PORT_DCO2_SUSTAIN], release2);
sample = a * analogue->d1 +
b * analogue->d2 +
c * *ports[PORT_VELOCITY] * sample;
analogue->d2 = analogue->d1;
analogue->d1 = sample;
ports[PORT_OUT][i] = sample;
}
}
};
static LADSPA_PortDescriptor g_psPortDescriptors[] =
{
LADSPA_PORT_AUDIO | LADSPA_PORT_OUTPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT
};
static const char * const g_psPortNames[] =
{
"Out",
"Gate",
"Velocity",
"Frequency (Hz)",
"DCO1 Octave",
"DCO1 Waveform",
"DCO1 LFO Frequency Modulation",
"DCO1 LFO Pulse Width Modulation",
"DCO1 Attack",
"DCO1 Decay",
"DCO1 Sustain",
"DCO1 Release",
"DCO2 Octave",
"DCO2 Waveform",
"DCO2 LFO Frequency Modulation",
"DCO2 LFO Pulse Width Modulation",
"DCO2 Attack",
"DCO2 Decay",
"DCO2 Sustain",
"DCO2 Release",
"LFO Frequency (Hz)",
"LFO Fadein",
"Filter Envelope Modulation",
"Filter LFO Modulation",
"Filter Resonance",
"Filter Attack",
"Filter Decay",
"Filter Sustain",
"Filter Release"
};
static LADSPA_PortRangeHint g_psPortRangeHints[] =
{
/* Hints, Lower bound, Upper bound */
{ 0, 0.0, 0.0 },
{ LADSPA_HINT_TOGGLED, 0.0, 0.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 20000.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.001, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 10.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, -2.0, 2.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW |
LADSPA_HINT_INTEGER, -0.1, 5.1 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.01, 8.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.01, 8.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.00, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.01, 8.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, -2.0, 2.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW |
LADSPA_HINT_INTEGER, -0.1, 5.1 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.01, 8.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.01, 8.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.00, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.01, 8.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 20.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.01, 8.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.01, 8.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.01, 8.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.00, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.01, 8.0 }
};
void
initialise_analogue() {
CMT_Descriptor * psDescriptor;
psDescriptor = new CMT_Descriptor
(1221,
"analogue",
LADSPA_PROPERTY_HARD_RT_CAPABLE,
"Analogue Voice",
CMT_MAKER("David A. Bartold"),
CMT_COPYRIGHT("2000", "David A. Bartold"),
NULL,
CMT_Instantiate<Analogue>,
Analogue::activate,
Analogue::run,
NULL,
NULL,
NULL);
for (int i = 0; i < NUM_PORTS; i++)
psDescriptor->addPort(
g_psPortDescriptors[i],
g_psPortNames[i],
g_psPortRangeHints[i].HintDescriptor,
g_psPortRangeHints[i].LowerBound,
g_psPortRangeHints[i].UpperBound);
registerNewPluginDescriptor(psDescriptor);
}

View File

@@ -1,223 +0,0 @@
/* canyondelay.cpp
Canyon Delay - Deep Stereo Cross Delay
Copyright (c) 1999, 2000 David A. Bartold
Computer Music Toolkit - a library of LADSPA plugins. Copyright (C)
2000 Richard W.E. Furse. The author may be contacted at
richard@muse.demon.co.uk.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public Licence as
published by the Free Software Foundation; either version 2 of the
Licence, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA. */
/*****************************************************************************/
#include <stdlib.h>
#include <math.h>
#include "cmt.h"
#define PORT_IN_LEFT 0
#define PORT_IN_RIGHT 1
#define PORT_OUT_LEFT 2
#define PORT_OUT_RIGHT 3
#define PORT_LTR_TIME 4
#define PORT_LTR_FEEDBACK 5
#define PORT_RTL_TIME 6
#define PORT_RTL_FEEDBACK 7
#define PORT_CUTOFF 8
#define NUM_PORTS 9
#ifndef PI
#define PI 3.14159265358979
#endif
class CanyonDelay : public CMT_PluginInstance {
LADSPA_Data sample_rate;
long datasize;
LADSPA_Data *data_l;
LADSPA_Data *data_r;
LADSPA_Data accum_l;
LADSPA_Data accum_r;
int pos;
public:
CanyonDelay(const LADSPA_Descriptor *,
unsigned long s_rate)
: CMT_PluginInstance(NUM_PORTS),
sample_rate(s_rate),
datasize(s_rate),
data_l(new LADSPA_Data[datasize]),
data_r(new LADSPA_Data[datasize]),
accum_l(0.0),
accum_r(0.0),
pos(0) {
for (long i = 0; i < datasize; i++)
data_l[i] = data_r[i] = 0.0;
}
~CanyonDelay() {
delete[] data_l;
delete[] data_r;
}
static void
activate(LADSPA_Handle Instance) {
CanyonDelay *delay = (CanyonDelay*) Instance;
for (long i = 0; i < delay->datasize; i++)
delay->data_l[i] = delay->data_r[i] = 0.0;
delay->accum_l = 0.0;
delay->accum_r = 0.0;
delay->pos = 0;
}
static void
run(LADSPA_Handle Instance,
unsigned long SampleCount) {
CanyonDelay *delay = (CanyonDelay*) Instance;
LADSPA_Data **ports;
unsigned long i;
int l_to_r_offset, r_to_l_offset;
LADSPA_Data ltr_invmag, rtl_invmag;
LADSPA_Data filter_mag, filter_invmag;
ports = delay->m_ppfPorts;
l_to_r_offset = (int) (*ports[PORT_LTR_TIME] * delay->sample_rate);
r_to_l_offset = (int) (*ports[PORT_RTL_TIME] * delay->sample_rate);
ltr_invmag = 1.0 - fabs (*ports[PORT_LTR_FEEDBACK]);
rtl_invmag = 1.0 - fabs (*ports[PORT_RTL_FEEDBACK]);
filter_invmag = pow (0.5, (4.0 * PI * *ports[PORT_CUTOFF]) / delay->sample_rate);
filter_mag = 1.0 - filter_invmag;
for (i = 0; i < SampleCount; i++)
{
LADSPA_Data accum_l, accum_r;
int pos1, pos2;
accum_l = ports[PORT_IN_LEFT][i];
accum_r = ports[PORT_IN_RIGHT][i];
pos1 = delay->pos - r_to_l_offset + delay->datasize;
while (pos1 >= delay->datasize)
pos1 -= delay->datasize;
pos2 = delay->pos - l_to_r_offset + delay->datasize;
while (pos2 >= delay->datasize)
pos2 -= delay->datasize;
/* Mix channels with past samples. */
accum_l = accum_l * rtl_invmag + delay->data_r[pos1] * *ports[PORT_RTL_FEEDBACK];
accum_r = accum_r * ltr_invmag + delay->data_l[pos2] * *ports[PORT_LTR_FEEDBACK];
/* Low-pass filter output. */
accum_l = delay->accum_l * filter_invmag + accum_l * filter_mag;
accum_r = delay->accum_r * filter_invmag + accum_r * filter_mag;
/* Store IIR samples. */
delay->accum_l = accum_l;
delay->accum_r = accum_r;
/* Store samples in arrays. */
delay->data_l[delay->pos] = accum_l;
delay->data_r[delay->pos] = accum_r;
ports[PORT_OUT_LEFT][i] = accum_l;
ports[PORT_OUT_RIGHT][i] = accum_r;
delay->pos++;
if (delay->pos >= delay->datasize)
delay->pos -= delay->datasize;
}
}
};
static LADSPA_PortDescriptor g_psPortDescriptors[] =
{
LADSPA_PORT_AUDIO | LADSPA_PORT_INPUT,
LADSPA_PORT_AUDIO | LADSPA_PORT_INPUT,
LADSPA_PORT_AUDIO | LADSPA_PORT_OUTPUT,
LADSPA_PORT_AUDIO | LADSPA_PORT_OUTPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT
};
static const char * const g_psPortNames[] =
{
"In (Left)",
"In (Right)",
"Out (Left)",
"Out (Right)",
"Left to Right Time (Seconds)",
"Left to Right Feedback (Percent)",
"Right to Left Time (Seconds)",
"Right to Left Feedback (Percent)",
"Low-Pass Cutoff (Hz)"
};
static LADSPA_PortRangeHint g_psPortRangeHints[] =
{
/* Hints, Lower bound, Upper bound */
{ 0, 0.0, 0.0 },
{ 0, 0.0, 0.0 },
{ 0, 0.0, 0.0 },
{ 0, 0.0, 0.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.01, 0.99 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, -1.0, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.01, 0.99 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, -1.0, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 1.0, 5000.0 }
};
void
initialise_canyondelay() {
CMT_Descriptor * psDescriptor;
psDescriptor = new CMT_Descriptor
(1225,
"canyon_delay",
LADSPA_PROPERTY_HARD_RT_CAPABLE,
"Canyon Delay",
CMT_MAKER("David A. Bartold"),
CMT_COPYRIGHT("1999, 2000", "David A. Bartold"),
NULL,
CMT_Instantiate<CanyonDelay>,
CanyonDelay::activate,
CanyonDelay::run,
NULL,
NULL,
NULL);
for (int i = 0; i < NUM_PORTS; i++)
psDescriptor->addPort(
g_psPortDescriptors[i],
g_psPortNames[i],
g_psPortRangeHints[i].HintDescriptor,
g_psPortRangeHints[i].LowerBound,
g_psPortRangeHints[i].UpperBound);
registerNewPluginDescriptor(psDescriptor);
}

View File

@@ -1,184 +0,0 @@
/* cmt.cpp
Computer Music Toolkit - a library of LADSPA plugins. Copyright (C)
2000-2002 Richard W.E. Furse. The author may be contacted at
richard@muse.demon.co.uk.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public Licence as
published by the Free Software Foundation; either version 2 of the
Licence, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA. */
/*****************************************************************************/
#include <string.h>
/*****************************************************************************/
#include "cmt.h"
/*****************************************************************************/
inline char *
localStrdup(const char * input) {
char * output = new char[strlen(input) + 1];
strcpy(output, input);
return output;
}
/*****************************************************************************/
CMT_Descriptor::
~CMT_Descriptor() {
if (Label)
delete [] Label;
if (Name)
delete [] Name;
if (Maker)
delete [] Maker;
if (Copyright)
delete [] Copyright;
if (ImplementationData)
delete (CMT_ImplementationData *)ImplementationData;
if (PortDescriptors)
delete [] PortDescriptors;
if (PortNames) {
for (unsigned long lIndex = 0; lIndex < PortCount; lIndex++)
if (PortNames[lIndex])
delete [] PortNames[lIndex];
delete [] PortNames;
}
if (PortRangeHints)
delete [] PortRangeHints;
}
/*****************************************************************************/
void
CMT_ConnectPort(LADSPA_Handle Instance,
unsigned long Port,
LADSPA_Data * DataLocation) {
CMT_PluginInstance * poInstance = (CMT_PluginInstance *)Instance;
poInstance->m_ppfPorts[Port] = DataLocation;
}
/*****************************************************************************/
void
CMT_Cleanup(LADSPA_Handle Instance) {
CMT_PluginInstance * poInstance = (CMT_PluginInstance *)Instance;
delete poInstance;
}
/*****************************************************************************/
CMT_Descriptor::
CMT_Descriptor(unsigned long lUniqueID,
const char * pcLabel,
LADSPA_Properties iProperties,
const char * pcName,
const char * pcMaker,
const char * pcCopyright,
CMT_ImplementationData * poImplementationData,
LADSPA_Instantiate_Function fInstantiate,
LADSPA_Activate_Function fActivate,
LADSPA_Run_Function fRun,
LADSPA_Run_Adding_Function fRunAdding,
LADSPA_Set_Run_Adding_Gain_Function fSetRunAddingGain,
LADSPA_Deactivate_Function fDeactivate) {
UniqueID = lUniqueID;
Label = localStrdup(pcLabel);
Properties = iProperties;
Name = localStrdup(pcName);
Maker = localStrdup(pcMaker);
Copyright = localStrdup(pcCopyright);
PortCount = 0;
ImplementationData = poImplementationData;
instantiate = fInstantiate;
connect_port = CMT_ConnectPort;
activate = fActivate;
run = fRun;
run_adding = fRunAdding;
set_run_adding_gain = fSetRunAddingGain;
deactivate = fDeactivate;
cleanup = CMT_Cleanup;
};
/*****************************************************************************/
typedef char * char_ptr;
void CMT_Descriptor::
addPort(LADSPA_PortDescriptor iPortDescriptor,
const char * pcPortName,
LADSPA_PortRangeHintDescriptor iHintDescriptor,
LADSPA_Data fLowerBound,
LADSPA_Data fUpperBound) {
unsigned long lOldPortCount = PortCount;
unsigned long lNewPortCount = PortCount + 1;
LADSPA_PortDescriptor * piOldPortDescriptors
= (LADSPA_PortDescriptor *)PortDescriptors;
char ** ppcOldPortNames
= (char **)PortNames;
LADSPA_PortRangeHint * psOldPortRangeHints
= (LADSPA_PortRangeHint *)PortRangeHints;
LADSPA_PortDescriptor * piNewPortDescriptors
= new LADSPA_PortDescriptor[lNewPortCount];
char ** ppcNewPortNames
= new char_ptr[lNewPortCount];
LADSPA_PortRangeHint * psNewPortRangeHints
= new LADSPA_PortRangeHint[lNewPortCount];
if (piNewPortDescriptors == NULL
|| ppcNewPortNames == NULL
|| psNewPortRangeHints == NULL) {
/* Memory allocation failure that we cannot handle. Best option is
probably just to get out while the going is reasonably good. */
return;
}
for (unsigned long lPortIndex = 0;
lPortIndex < lOldPortCount;
lPortIndex++) {
piNewPortDescriptors[lPortIndex] = piOldPortDescriptors[lPortIndex];
ppcNewPortNames[lPortIndex] = ppcOldPortNames[lPortIndex];
psNewPortRangeHints[lPortIndex] = psOldPortRangeHints[lPortIndex];
}
if (lOldPortCount > 0) {
delete [] piOldPortDescriptors;
delete [] ppcOldPortNames;
delete [] psOldPortRangeHints;
}
piNewPortDescriptors[lOldPortCount] = iPortDescriptor;
ppcNewPortNames[lOldPortCount] = localStrdup(pcPortName);
psNewPortRangeHints[lOldPortCount].HintDescriptor = iHintDescriptor;
psNewPortRangeHints[lOldPortCount].LowerBound = fLowerBound;
psNewPortRangeHints[lOldPortCount].UpperBound = fUpperBound;
PortDescriptors = piNewPortDescriptors;
PortNames = ppcNewPortNames;
PortRangeHints = psNewPortRangeHints;
PortCount++;
}
/*****************************************************************************/
/* EOF */

View File

@@ -1,180 +0,0 @@
/* cmt.h
Computer Music Toolkit - a library of LADSPA plugins. Copyright (C)
2000-2002 Richard W.E. Furse. The author may be contacted at
richard@muse.demon.co.uk.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public Licence as
published by the Free Software Foundation; either version 2 of the
Licence, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA. */
#ifndef CMT_BASE_INCLUDED
#define CMT_BASE_INCLUDED
/*****************************************************************************/
#include "ladspa_types.h"
/*****************************************************************************/
/** This class is the baseclass of all CMT plugin implementation
data. Baseclassed so virtual destructors can be used. */
class CMT_ImplementationData {
public:
virtual ~CMT_ImplementationData() {
}
};
/*****************************************************************************/
/** This structure describes a CMT LADSPA Plugin. It is a direct
ancestor of the _LADSPA_Descriptor structure which allows direct
casting. A rich constructor function is provided make it easier to
write LADSPA_Descriptor objects. (Less code is required and the
compiler will tell you when you have missed an entry.) An
addPort() function makes configuration of ports more
straightforward than using the _LADSPA_Descriptor structure
directly. */
struct CMT_Descriptor : public _LADSPA_Descriptor {
private:
CMT_Descriptor &operator=(const CMT_Descriptor &) {
return *this;
}
CMT_Descriptor(const CMT_Descriptor &) {
}
public:
~CMT_Descriptor();
/** The basic constructor for a CMT_Descriptor object. If you do not
know what the parameters mean, please see the fields in the
LADSPA_Descriptor structure, described in ladspa.h. Note that
some parameters may be NULL. Note also that a template is
provided to generate instantiate functions automatically (see
CMT_Instantiate<>() below). Implementation data must be NULL if
not allocated. */
CMT_Descriptor(unsigned long lUniqueID,
const char * pcLabel,
LADSPA_Properties iProperties,
const char * pcName,
const char * pcMaker,
const char * pcCopyright,
CMT_ImplementationData * poImplementationData,
LADSPA_Instantiate_Function fInstantiate,
LADSPA_Activate_Function fActivate,
LADSPA_Run_Function fRun,
LADSPA_Run_Adding_Function fRunAdding,
LADSPA_Set_Run_Adding_Gain_Function fSetRunAddingGain,
LADSPA_Deactivate_Function fDeactivate);
/** This method adds a new port to the descriptor. If you do not
know what the parameters mean, please see the fields in the
LADSPA_Descriptor structure, described in ladspa.h. */
void addPort(LADSPA_PortDescriptor iPortDescriptor,
const char * pcPortName,
LADSPA_PortRangeHintDescriptor iHintDescriptor = 0,
LADSPA_Data fLowerBound = 0,
LADSPA_Data fUpperBound = 0);
};
typedef CMT_Descriptor * CMT_Descriptor_ptr;
/*****************************************************************************/
/** Each plugin type must register itself with the descriptor
registry. This is done by calling the following function, passing
a newly allocated structure (that will be cleaned up on library
unload automatically).
Each module needs to be initialised in order to have a chance to
register new plugins. This can be achieved by modifying the list
of initialiser functions in descriptor.cpp. */
void registerNewPluginDescriptor(CMT_Descriptor * psDescriptor);
/*****************************************************************************/
/** This class is the baseclass of all CMT plugins. It provides
functionality to handle LADSPA connect_port() and cleanup()
requirements (as long as plugins have correctly written
destructors!) A CMT_Instantiate<>() template is provided also,
which makes LADSPA instantiate() methods easier to write.
Derived classes access port data through the m_ppfPorts[]
array. This contains one entry for each port, in the order in
which ports were added to the corresponding CMT_Descriptor
object. */
class CMT_PluginInstance {
private:
CMT_PluginInstance &operator=(const CMT_PluginInstance &) {
return *this;
}
CMT_PluginInstance(const CMT_PluginInstance &) {
}
protected:
LADSPA_Data ** m_ppfPorts;
CMT_PluginInstance(const unsigned long lPortCount)
: m_ppfPorts(new LADSPA_Data_ptr[lPortCount]) {
}
virtual ~CMT_PluginInstance() {
delete [] m_ppfPorts;
}
friend void CMT_ConnectPort(LADSPA_Handle Instance,
unsigned long Port,
LADSPA_Data * DataLocation);
friend void CMT_Cleanup(LADSPA_Handle Instance);
};
/*****************************************************************************/
/** This template can be used to generate functions to instantiate CMT
plugins. To be used with this function, the plugin must accept two
parameters (a LADSPA_Descriptor pointer and a sample rate). See
the SimpleMixer class and mixer_descriptor() in mixer.cpp for a
simple example of this: the instantiate function for the mixer
class is generated within the mixer_descriptor() function as
"CMT_Instantiate<SimpleMixer>". */
template <class T> LADSPA_Handle
CMT_Instantiate(const LADSPA_Descriptor * Descriptor,
unsigned long SampleRate) {
return new T(Descriptor, SampleRate);
}
/*****************************************************************************/
/** This macro should be used to fill in the `Maker' field in the
CMT_Descriptor. */
#define CMT_MAKER(AUTHORS) \
"CMT (http://www.ladspa.org/cmt, plugin by " AUTHORS ")"
/** This macro should be used to fill in the `Copyright' field in the
CMT_Descriptor. */
#define CMT_COPYRIGHT(YEARS, AUTHORS) \
"(C)" YEARS ", " AUTHORS ". " \
"GNU General Public Licence Version 2 applies."
/*****************************************************************************/
#endif
/* EOF */

View File

@@ -1,351 +0,0 @@
/* delay.cpp
Computer Music Toolkit - a library of LADSPA plugins. Copyright (C)
2000-2002 Richard W.E. Furse. The author may be contacted at
richard@muse.demon.co.uk.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public Licence as
published by the Free Software Foundation; either version 2 of the
Licence, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA. */
/*****************************************************************************/
/* This module provides delays and delays with feedback. A variety of
maximum delay times are available. (The plugins reserve different
amounts of memory space on this basis.) */
/*****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*****************************************************************************/
#include "cmt.h"
/*****************************************************************************/
#define DELAY_TYPE_COUNT 2
#define DELAY_LENGTH_COUNT 5
/*****************************************************************************/
#define LIMIT_BETWEEN(x, a, b) \
(((x) < a) ? a : (((x) > b) ? b : (x)))
/*****************************************************************************/
#define DL_DELAY_LENGTH 0
#define DL_DRY_WET 1
#define DL_INPUT 2
#define DL_OUTPUT 3
/* Present only on feedback delays: */
#define DL_FEEDBACK 4
/** This class is used to implement delay line plugins. Different
maximum delay times are supported as are both echo and feedback
delays. */
class DelayLine : public CMT_PluginInstance {
private:
LADSPA_Data m_fSampleRate;
LADSPA_Data m_fMaximumDelay;
LADSPA_Data * m_pfBuffer;
/** Buffer size, a power of two. */
unsigned long m_lBufferSize;
/** Write pointer in buffer. */
unsigned long m_lWritePointer;
friend void activateDelayLine(LADSPA_Handle Instance);
friend void runSimpleDelayLine(LADSPA_Handle Instance,
unsigned long SampleCount);
friend void runFeedbackDelayLine(LADSPA_Handle Instance,
unsigned long SampleCount);
public:
DelayLine(const unsigned long lSampleRate,
const LADSPA_Data fMaximumDelay)
: CMT_PluginInstance(5),
m_fSampleRate(LADSPA_Data(lSampleRate)),
m_fMaximumDelay(fMaximumDelay) {
/* Buffer size is a power of two bigger than max delay time. */
unsigned long lMinimumBufferSize
= (unsigned long)((LADSPA_Data)lSampleRate * m_fMaximumDelay);
m_lBufferSize = 1;
while (m_lBufferSize < lMinimumBufferSize)
m_lBufferSize <<= 1;
m_pfBuffer = new LADSPA_Data[m_lBufferSize];
}
~DelayLine() {
delete [] m_pfBuffer;
}
};
/*****************************************************************************/
/* Initialise and activate a plugin instance. */
void
activateDelayLine(LADSPA_Handle Instance) {
DelayLine * poDelayLine = (DelayLine *)Instance;
/* Need to reset the delay history in this function rather than
instantiate() in case deactivate() followed by activate() have
been called to reinitialise a delay line. */
memset(poDelayLine->m_pfBuffer,
0,
sizeof(LADSPA_Data) * poDelayLine->m_lBufferSize);
poDelayLine->m_lWritePointer = 0;
}
/*****************************************************************************/
/* Run a delay line instance for a block of SampleCount samples. */
void
runSimpleDelayLine(LADSPA_Handle Instance,
unsigned long SampleCount) {
DelayLine * poDelayLine = (DelayLine *)Instance;
unsigned long lBufferSizeMinusOne = poDelayLine->m_lBufferSize - 1;
unsigned long lDelay = (unsigned long)
(LIMIT_BETWEEN(*(poDelayLine->m_ppfPorts[DL_DELAY_LENGTH]),
0,
poDelayLine->m_fMaximumDelay)
* poDelayLine->m_fSampleRate);
LADSPA_Data * pfInput
= poDelayLine->m_ppfPorts[DL_INPUT];
LADSPA_Data * pfOutput
= poDelayLine->m_ppfPorts[DL_OUTPUT];
LADSPA_Data * pfBuffer
= poDelayLine->m_pfBuffer;
unsigned long lBufferWriteOffset
= poDelayLine->m_lWritePointer;
unsigned long lBufferReadOffset
= lBufferWriteOffset + poDelayLine->m_lBufferSize - lDelay;
LADSPA_Data fWet
= LIMIT_BETWEEN(*(poDelayLine->m_ppfPorts[DL_DRY_WET]),
0,
1);
LADSPA_Data fDry
= 1 - fWet;
for (unsigned long lSampleIndex = 0;
lSampleIndex < SampleCount;
lSampleIndex++) {
LADSPA_Data fInputSample = *(pfInput++);
*(pfOutput++) = (fDry * fInputSample
+ fWet * pfBuffer[((lSampleIndex + lBufferReadOffset)
& lBufferSizeMinusOne)]);
pfBuffer[((lSampleIndex + lBufferWriteOffset)
& lBufferSizeMinusOne)] = fInputSample;
}
poDelayLine->m_lWritePointer
= ((poDelayLine->m_lWritePointer + SampleCount)
& lBufferSizeMinusOne);
}
/*****************************************************************************/
/** Run a feedback delay line instance for a block of SampleCount samples. */
void
runFeedbackDelayLine(LADSPA_Handle Instance,
unsigned long SampleCount) {
DelayLine * poDelayLine = (DelayLine *)Instance;
unsigned long lBufferSizeMinusOne = poDelayLine->m_lBufferSize - 1;
unsigned long lDelay = (unsigned long)
(LIMIT_BETWEEN(*(poDelayLine->m_ppfPorts[DL_DELAY_LENGTH]),
0,
poDelayLine->m_fMaximumDelay)
* poDelayLine->m_fSampleRate);
LADSPA_Data * pfInput
= poDelayLine->m_ppfPorts[DL_INPUT];
LADSPA_Data * pfOutput
= poDelayLine->m_ppfPorts[DL_OUTPUT];
LADSPA_Data * pfBuffer
= poDelayLine->m_pfBuffer;
unsigned long lBufferWriteOffset
= poDelayLine->m_lWritePointer;
unsigned long lBufferReadOffset
= lBufferWriteOffset + poDelayLine->m_lBufferSize - lDelay;
LADSPA_Data fWet
= LIMIT_BETWEEN(*(poDelayLine->m_ppfPorts[DL_DRY_WET]),
0,
1);
LADSPA_Data fDry
= 1 - fWet;
LADSPA_Data fFeedback
= LIMIT_BETWEEN(*(poDelayLine->m_ppfPorts[DL_FEEDBACK]),
-1,
1);
for (unsigned long lSampleIndex = 0;
lSampleIndex < SampleCount;
lSampleIndex++) {
LADSPA_Data fInputSample = *(pfInput++);
LADSPA_Data &fDelayedSample = pfBuffer[((lSampleIndex + lBufferReadOffset)
& lBufferSizeMinusOne)];
*(pfOutput++) = (fDry * fInputSample + fWet * fDelayedSample);
pfBuffer[((lSampleIndex + lBufferWriteOffset)
& lBufferSizeMinusOne)]
= fInputSample + fDelayedSample * fFeedback;
}
poDelayLine->m_lWritePointer
= ((poDelayLine->m_lWritePointer + SampleCount)
& lBufferSizeMinusOne);
}
/*****************************************************************************/
template <long lMaximumDelayMilliseconds> LADSPA_Handle
CMT_Delay_Instantiate(const LADSPA_Descriptor * Descriptor,
unsigned long SampleRate) {
return new DelayLine(SampleRate,
LADSPA_Data(lMaximumDelayMilliseconds
* 0.001));
}
/*****************************************************************************/
void
initialise_delay() {
CMT_Descriptor * psDescriptor;
const char * apcDelayTypeNames[DELAY_TYPE_COUNT] = {
"Echo",
"Feedback"
};
const char * apcDelayTypeLabels[DELAY_TYPE_COUNT] = {
"delay",
"fbdelay"
};
LADSPA_Run_Function afRunFunctions[DELAY_TYPE_COUNT] = {
runSimpleDelayLine,
runFeedbackDelayLine
};
LADSPA_Data afMaximumDelays[DELAY_LENGTH_COUNT] = {
0.01,
0.1,
1,
5,
60
};
LADSPA_Instantiate_Function afInstantiateFunctions[DELAY_LENGTH_COUNT] = {
CMT_Delay_Instantiate<10>,
CMT_Delay_Instantiate<100>,
CMT_Delay_Instantiate<1000>,
CMT_Delay_Instantiate<5000>,
CMT_Delay_Instantiate<60000>
};
for (long lDelayTypeIndex = 0;
lDelayTypeIndex < DELAY_TYPE_COUNT;
lDelayTypeIndex++) {
for (long lDelayLengthIndex = 0;
lDelayLengthIndex < DELAY_LENGTH_COUNT;
lDelayLengthIndex++) {
long lPluginIndex
= lDelayTypeIndex * DELAY_LENGTH_COUNT + lDelayLengthIndex;
char acLabel[100];
sprintf(acLabel,
"%s_%gs",
apcDelayTypeLabels[lDelayTypeIndex],
afMaximumDelays[lDelayLengthIndex]);
char acName[100];
sprintf(acName,
"%s Delay Line (Maximum Delay %gs)",
apcDelayTypeNames[lDelayTypeIndex],
afMaximumDelays[lDelayLengthIndex]);
psDescriptor = new CMT_Descriptor
(1053 + lPluginIndex,
acLabel,
LADSPA_PROPERTY_HARD_RT_CAPABLE,
acName,
CMT_MAKER("Richard W.E. Furse"),
CMT_COPYRIGHT("2000-2002", "Richard W.E. Furse"),
NULL,
afInstantiateFunctions[lDelayLengthIndex],
activateDelayLine,
afRunFunctions[lDelayTypeIndex],
NULL,
NULL,
NULL);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Delay (Seconds)",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_BOUNDED_ABOVE
| LADSPA_HINT_DEFAULT_1),
0,
afMaximumDelays[lDelayLengthIndex]);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Dry/Wet Balance",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_BOUNDED_ABOVE
| LADSPA_HINT_DEFAULT_MIDDLE),
0,
1);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
"Input");
psDescriptor->addPort
(LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
"Output");
if (lDelayTypeIndex == 1)
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Feedback",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_BOUNDED_ABOVE
| LADSPA_HINT_DEFAULT_HIGH),
-1,
1);
registerNewPluginDescriptor(psDescriptor);
}
}
}
/*****************************************************************************/
/* EOF */

View File

@@ -1,116 +0,0 @@
/* descriptor.cpp
Computer Music Toolkit - a library of LADSPA plugins. Copyright (C)
2000 Richard W.E. Furse. The author may be contacted at
richard@muse.demon.co.uk.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public Licence as
published by the Free Software Foundation; either version 2 of the
Licence, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA. */
/*****************************************************************************/
/* This module contains code providing and supporting the
CMT_Descriptor() function that provides hosts with initial access
to LADSPA plugins. ALL PLUGINS MUST BE REGISTERED IN THIS FILE (see
below). */
/*****************************************************************************/
/* Module Initialisation:
---------------------- */
void initialise_am();
void initialise_ambisonic();
void initialise_amp();
void initialise_analogue();
void initialise_canyondelay();
void initialise_delay();
void initialise_dynamic();
void initialise_filter();
void initialise_freeverb3();
void initialise_grain();
void initialise_lofi();
void initialise_mixer();
void initialise_noise();
void initialise_null();
void initialise_organ();
void initialise_peak();
void initialise_phasemod();
void initialise_sine();
void initialise_syndrum();
void initialise_vcf303();
void initialise_wshape_sine();
namespace hardgate { void initialise(); }
namespace disintegrator { void initialise(); }
namespace pink { void initialise(); }
namespace pink_full { void initialise(); }
namespace pink_sh { void initialise(); }
namespace sledgehammer { void initialise(); }
namespace logistic { void initialise(); }
/** This function should initialise all modules in the library. This
will lead to all plugin descriptors being registered. If you write
a new plugin you should initialise it here. If the module has
structures it wishes to remove also then these should be included
in finalise_modules(). */
void
initialise_modules() {
initialise_am();
initialise_ambisonic();
initialise_amp();
initialise_analogue();
initialise_canyondelay();
initialise_delay();
initialise_dynamic();
initialise_filter();
initialise_freeverb3();
initialise_grain();
initialise_lofi();
initialise_mixer();
initialise_noise();
initialise_null();
initialise_organ();
initialise_peak();
initialise_phasemod();
initialise_sine();
initialise_syndrum();
initialise_vcf303();
initialise_wshape_sine();
hardgate::initialise();
disintegrator::initialise();
pink::initialise();
pink_full::initialise();
pink_sh::initialise();
sledgehammer::initialise();
logistic::initialise();
}
/*****************************************************************************/
/* Module Finalisation:
-------------------- */
void finalise_sine();
/** Finalise any structures allocated by the modules. This does not
include descriptors passed to registerNewPluginDescriptor(). */
void
finalise_modules() {
finalise_sine();
}
/*****************************************************************************/
/* EOF */

View File

@@ -1,151 +0,0 @@
/* disintegrator.cpp
(c) 2002 Nathaniel Virgo
Computer Music Toolkit - a library of LADSPA plugins. Copyright (C)
2000-2002 Richard W.E. Furse. The author may be contacted at
richard@muse.demon.co.uk.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public Licence as
published by the Free Software Foundation; either version 2 of the
Licence, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA. */
/*****************************************************************************/
#include <stdlib.h>
/*****************************************************************************/
#include "cmt.h"
#include "run_adding.h"
/*****************************************************************************/
namespace disintegrator {
enum {
port_probability = 0,
port_multiplier = 1,
port_input = 2,
port_output = 3,
n_ports = 4
};
/** This plugin multiplies random half-waveforms by port_multiplier,
with probability port_probability */
class Plugin : public CMT_PluginInstance {
LADSPA_Data run_adding_gain;
bool active;
LADSPA_Data last_input;
public:
Plugin(const LADSPA_Descriptor *,
unsigned long)
: CMT_PluginInstance(n_ports) {
active = false; last_input = 0.0f;
}
template<OutputFunction write_output>
friend void run(LADSPA_Handle instance,
unsigned long sample_count);
friend void set_run_adding_gain(LADSPA_Handle instance,
LADSPA_Data new_gain);
};
template<OutputFunction write_output>
void run(LADSPA_Handle instance,
unsigned long sample_count) {
Plugin *pp = (Plugin *) instance;
Plugin &p = *pp;
LADSPA_Data prob = *pp->m_ppfPorts[port_probability];
LADSPA_Data mult = *pp->m_ppfPorts[port_multiplier];
LADSPA_Data * in = pp->m_ppfPorts[port_input];
LADSPA_Data * out = pp->m_ppfPorts[port_output];
mult *= get_gain<write_output>(p.run_adding_gain);
for ( unsigned long i = 0; i < sample_count ; ++i ) {
LADSPA_Data insig = *(in++);
if ( ( p.last_input>0 && insig<0 ) || ( p.last_input<0 && insig>0 ) )
p.active = rand() < prob*RAND_MAX;
p.last_input = insig;
if (p.active)
write_output(out, insig*mult, 1.0f);
else
write_output(out, insig, p.run_adding_gain);
}
}
void set_run_adding_gain(LADSPA_Handle instance,
LADSPA_Data new_gain) {
((Plugin *) instance)->run_adding_gain = new_gain;
}
void
initialise() {
CMT_Descriptor * d = new CMT_Descriptor
(1846,
"disintegrator",
LADSPA_PROPERTY_HARD_RT_CAPABLE,
"Disintegrator",
CMT_MAKER("Nathaniel Virgo"),
CMT_COPYRIGHT("2002", "Nathaniel Virgo"),
NULL,
CMT_Instantiate<Plugin>,
NULL,
run<write_output_normal>,
run<write_output_adding>,
set_run_adding_gain,
NULL);
d->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Probability",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_BOUNDED_ABOVE
| LADSPA_HINT_DEFAULT_0),
0,
1);
d->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Multiplier",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_BOUNDED_ABOVE
| LADSPA_HINT_DEFAULT_0),
-1,
1);
d->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
"Input");
d->addPort
(LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
"Output");
registerNewPluginDescriptor(d);
}
} // end of namespace
/*****************************************************************************/
/* EOF */

View File

@@ -1,800 +0,0 @@
/* dynamic.cpp
Computer Music Toolkit - a library of LADSPA plugins. Copyright (C)
2000-2002 Richard W.E. Furse. The author may be contacted at
richard@muse.demon.co.uk.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public Licence as
published by the Free Software Foundation; either version 2 of the
Licence, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA. */
/*****************************************************************************/
/* This module provides unsophisticated implementations of compressor,
expander and limiter plugins. Note that attack and decay times are
applied at the LEVEL DETECTION stage rather than at gain processing
(the reason no noise gate is provided). No delay is applied to the
main signal. These are useful (and efficient) tools and extended
compressors should probably allocate new IDs rather than break
compatibility in parameter set and sound for this set. */
// Having said this, I'm not sure the attack/decay parameters are the
// right way around.
/*****************************************************************************/
#include <math.h>
#include <stdlib.h>
#include <string.h>
/*****************************************************************************/
#include "cmt.h"
#include "utils.h"
/*****************************************************************************/
class DynamicProcessor {
protected:
/** This state variable is used to track the input envelope (peak or
rms). The state is stored here so that the run function can
perform low-pass filtering to produce a smoothed envelope. */
LADSPA_Data m_fEnvelopeState;
/** The sample rate in the world this instance exists in. */
LADSPA_Data m_fSampleRate;
DynamicProcessor(const LADSPA_Data fSampleRate)
: m_fSampleRate(fSampleRate) {
}
};
/*****************************************************************************/
#define CE_THRESHOLD 0
#define CE_RATIO 1
#define CE_ATTACK 2
#define CE_DECAY 3
#define CE_INPUT 4
#define CE_OUTPUT 5
/** This class is used to implement simple compressor and expander
plugins. Attack and decay times are applied at the level detection
stage rather than at gain processing. No delay is applied to the
main signal. Both peak and RMS support is included. */
class CompressorExpander
: public CMT_PluginInstance, public DynamicProcessor {
public:
CompressorExpander(const LADSPA_Descriptor *,
unsigned long lSampleRate)
: CMT_PluginInstance(6),
DynamicProcessor(lSampleRate) {
}
friend void activateCompressorExpander(void * pvHandle);
friend void runCompressor_Peak(LADSPA_Handle Instance,
unsigned long SampleCount);
friend void runCompressor_RMS(LADSPA_Handle Instance,
unsigned long SampleCount);
friend void runExpander_Peak(LADSPA_Handle Instance,
unsigned long SampleCount);
friend void runExpander_RMS(LADSPA_Handle Instance,
unsigned long SampleCount);
};
/*****************************************************************************/
#define LN_THRESHOLD 0
#define LN_ATTACK 1
#define LN_DECAY 2
#define LN_INPUT 3
#define LN_OUTPUT 4
/** This class is used to implement simple limiter plugins. Attack and
decay times are applied at the level detection stage rather than
at gain processing. No delay is applied to the main signal. Both
peak and RMS support is included. */
class Limiter
: public CMT_PluginInstance, public DynamicProcessor {
public:
Limiter(const LADSPA_Descriptor *,
unsigned long lSampleRate)
: CMT_PluginInstance(5),
DynamicProcessor(lSampleRate) {
}
friend void activateLimiter(void * pvHandle);
friend void runLimiter_Peak(LADSPA_Handle Instance,
unsigned long SampleCount);
friend void runLimiter_RMS(LADSPA_Handle Instance,
unsigned long SampleCount);
};
/*****************************************************************************/
void
activateCompressorExpander(void * pvHandle) {
CompressorExpander * poProcessor = (CompressorExpander *)pvHandle;
poProcessor->m_fEnvelopeState = 0;
}
/*****************************************************************************/
void
activateLimiter(void * pvHandle) {
Limiter * poProcessor = (Limiter *)pvHandle;
poProcessor->m_fEnvelopeState = 0;
}
/*****************************************************************************/
void
runCompressor_Peak(LADSPA_Handle Instance,
unsigned long SampleCount) {
CompressorExpander * poProcessor = (CompressorExpander *)Instance;
LADSPA_Data fThreshold
= BOUNDED_BELOW(*(poProcessor->m_ppfPorts[CE_THRESHOLD]),
0);
LADSPA_Data fOneOverThreshold
= 1 / fThreshold;
LADSPA_Data fRatioMinusOne
= *(poProcessor->m_ppfPorts[CE_RATIO]) - 1;
LADSPA_Data * pfInput
= poProcessor->m_ppfPorts[CE_INPUT];
LADSPA_Data * pfOutput
= poProcessor->m_ppfPorts[CE_OUTPUT];
LADSPA_Data fEnvelopeDrag_Attack
= calculate60dBDrag(*(poProcessor->m_ppfPorts[CE_ATTACK]),
poProcessor->m_fSampleRate);
LADSPA_Data fEnvelopeDrag_Decay
= calculate60dBDrag(*(poProcessor->m_ppfPorts[CE_DECAY]),
poProcessor->m_fSampleRate);
LADSPA_Data &rfEnvelopeState
= poProcessor->m_fEnvelopeState;
for (unsigned long lSampleIndex = 0;
lSampleIndex < SampleCount;
lSampleIndex++) {
LADSPA_Data fInput = *(pfInput++);
LADSPA_Data fEnvelopeTarget = fabs(fInput);
if (fEnvelopeTarget > rfEnvelopeState)
rfEnvelopeState = (rfEnvelopeState * fEnvelopeDrag_Attack
+ fEnvelopeTarget * (1 - fEnvelopeDrag_Attack));
else
rfEnvelopeState = (rfEnvelopeState * fEnvelopeDrag_Decay
+ fEnvelopeTarget * (1 - fEnvelopeDrag_Decay));
/* Perform the mapping. This questions this plugin's claim of
being `hard-realtime.' */
LADSPA_Data fGain;
if (rfEnvelopeState < fThreshold)
fGain = 1;
else {
fGain = pow(rfEnvelopeState * fOneOverThreshold, fRatioMinusOne);
if (isnan(fGain))
fGain = 0;
}
/* Perform output. */
*(pfOutput++) = fInput * fGain;
}
}
/*****************************************************************************/
void
runCompressor_RMS(LADSPA_Handle Instance,
unsigned long SampleCount) {
CompressorExpander * poProcessor = (CompressorExpander *)Instance;
LADSPA_Data fThreshold
= BOUNDED_BELOW(*(poProcessor->m_ppfPorts[CE_THRESHOLD]),
0);
LADSPA_Data fOneOverThreshold
= 1 / fThreshold;
LADSPA_Data fRatioMinusOne
= *(poProcessor->m_ppfPorts[CE_RATIO]) - 1;
LADSPA_Data * pfInput
= poProcessor->m_ppfPorts[CE_INPUT];
LADSPA_Data * pfOutput
= poProcessor->m_ppfPorts[CE_OUTPUT];
LADSPA_Data fEnvelopeDrag_Attack
= calculate60dBDrag(*(poProcessor->m_ppfPorts[CE_ATTACK]),
poProcessor->m_fSampleRate);
LADSPA_Data fEnvelopeDrag_Decay
= calculate60dBDrag(*(poProcessor->m_ppfPorts[CE_DECAY]),
poProcessor->m_fSampleRate);
LADSPA_Data &rfEnvelopeState
= poProcessor->m_fEnvelopeState;
for (unsigned long lSampleIndex = 0;
lSampleIndex < SampleCount;
lSampleIndex++) {
LADSPA_Data fInput = *(pfInput++);
LADSPA_Data fEnvelopeTarget = fInput * fInput;
if (fEnvelopeTarget > rfEnvelopeState)
rfEnvelopeState = (rfEnvelopeState * fEnvelopeDrag_Attack
+ fEnvelopeTarget * (1 - fEnvelopeDrag_Attack));
else
rfEnvelopeState = (rfEnvelopeState * fEnvelopeDrag_Decay
+ fEnvelopeTarget * (1 - fEnvelopeDrag_Decay));
LADSPA_Data fEnvelopeAmplitude = sqrt(rfEnvelopeState);
/* Perform the mapping. This questions this plugin's claim of
being `hard-realtime.' */
LADSPA_Data fGain;
if (fEnvelopeAmplitude < fThreshold)
fGain = 1;
else {
fGain = pow(fEnvelopeAmplitude * fOneOverThreshold, fRatioMinusOne);
if (isnan(fGain))
fGain = 0;
}
/* Perform output. */
*(pfOutput++) = fInput * fGain;
}
}
/*****************************************************************************/
void
runExpander_Peak(LADSPA_Handle Instance,
unsigned long SampleCount) {
CompressorExpander * poProcessor = (CompressorExpander *)Instance;
LADSPA_Data fThreshold
= BOUNDED_BELOW(*(poProcessor->m_ppfPorts[CE_THRESHOLD]),
0);
LADSPA_Data fOneOverThreshold
= 1 / fThreshold;
LADSPA_Data fOneMinusRatio
= 1 - *(poProcessor->m_ppfPorts[CE_RATIO]);
LADSPA_Data * pfInput
= poProcessor->m_ppfPorts[CE_INPUT];
LADSPA_Data * pfOutput
= poProcessor->m_ppfPorts[CE_OUTPUT];
LADSPA_Data fEnvelopeDrag_Attack
= calculate60dBDrag(*(poProcessor->m_ppfPorts[CE_ATTACK]),
poProcessor->m_fSampleRate);
LADSPA_Data fEnvelopeDrag_Decay
= calculate60dBDrag(*(poProcessor->m_ppfPorts[CE_DECAY]),
poProcessor->m_fSampleRate);
LADSPA_Data &rfEnvelopeState
= poProcessor->m_fEnvelopeState;
for (unsigned long lSampleIndex = 0;
lSampleIndex < SampleCount;
lSampleIndex++) {
LADSPA_Data fInput = *(pfInput++);
LADSPA_Data fEnvelopeTarget = fabs(fInput);
if (fEnvelopeTarget > rfEnvelopeState)
rfEnvelopeState = (rfEnvelopeState * fEnvelopeDrag_Attack
+ fEnvelopeTarget * (1 - fEnvelopeDrag_Attack));
else
rfEnvelopeState = (rfEnvelopeState * fEnvelopeDrag_Decay
+ fEnvelopeTarget * (1 - fEnvelopeDrag_Decay));
/* Perform the mapping. This questions this plugin's claim of
being `hard-realtime.' */
LADSPA_Data fGain;
if (rfEnvelopeState > fThreshold)
fGain = 1;
else {
fGain = pow(rfEnvelopeState * fOneOverThreshold, fOneMinusRatio);
if (isnan(fGain))
fGain = 0;
}
/* Perform output. */
*(pfOutput++) = fInput * fGain;
}
}
/*****************************************************************************/
void
runExpander_RMS(LADSPA_Handle Instance,
unsigned long SampleCount) {
CompressorExpander * poProcessor = (CompressorExpander *)Instance;
LADSPA_Data fThreshold
= BOUNDED_BELOW(*(poProcessor->m_ppfPorts[CE_THRESHOLD]),
0);
LADSPA_Data fOneOverThreshold
= 1 / fThreshold;
LADSPA_Data fOneMinusRatio
= 1 - *(poProcessor->m_ppfPorts[CE_RATIO]);
LADSPA_Data * pfInput
= poProcessor->m_ppfPorts[CE_INPUT];
LADSPA_Data * pfOutput
= poProcessor->m_ppfPorts[CE_OUTPUT];
LADSPA_Data fEnvelopeDrag_Attack
= calculate60dBDrag(*(poProcessor->m_ppfPorts[CE_ATTACK]),
poProcessor->m_fSampleRate);
LADSPA_Data fEnvelopeDrag_Decay
= calculate60dBDrag(*(poProcessor->m_ppfPorts[CE_DECAY]),
poProcessor->m_fSampleRate);
LADSPA_Data &rfEnvelopeState
= poProcessor->m_fEnvelopeState;
for (unsigned long lSampleIndex = 0;
lSampleIndex < SampleCount;
lSampleIndex++) {
LADSPA_Data fInput = *(pfInput++);
LADSPA_Data fEnvelopeTarget = fInput * fInput;
if (fEnvelopeTarget > rfEnvelopeState)
rfEnvelopeState = (rfEnvelopeState * fEnvelopeDrag_Attack
+ fEnvelopeTarget * (1 - fEnvelopeDrag_Attack));
else
rfEnvelopeState = (rfEnvelopeState * fEnvelopeDrag_Decay
+ fEnvelopeTarget * (1 - fEnvelopeDrag_Decay));
LADSPA_Data fEnvelopeAmplitude = sqrt(rfEnvelopeState);
/* Perform the mapping. This questions this plugin's claim of
being `hard-realtime.' */
LADSPA_Data fGain;
if (fEnvelopeAmplitude > fThreshold)
fGain = 1;
else {
fGain = pow(fEnvelopeAmplitude * fOneOverThreshold, fOneMinusRatio);
if (isnan(fGain))
fGain = 0;
}
/* Perform output. */
*(pfOutput++) = fInput * fGain;
}
}
/*****************************************************************************/
void
runLimiter_Peak(LADSPA_Handle Instance,
unsigned long SampleCount) {
Limiter * poProcessor = (Limiter *)Instance;
LADSPA_Data fThreshold
= BOUNDED_BELOW(*(poProcessor->m_ppfPorts[LN_THRESHOLD]),
0);
LADSPA_Data * pfInput
= poProcessor->m_ppfPorts[LN_INPUT];
LADSPA_Data * pfOutput
= poProcessor->m_ppfPorts[LN_OUTPUT];
LADSPA_Data fEnvelopeDrag_Attack
= calculate60dBDrag(*(poProcessor->m_ppfPorts[CE_ATTACK]),
poProcessor->m_fSampleRate);
LADSPA_Data fEnvelopeDrag_Decay
= calculate60dBDrag(*(poProcessor->m_ppfPorts[CE_DECAY]),
poProcessor->m_fSampleRate);
LADSPA_Data &rfEnvelopeState
= poProcessor->m_fEnvelopeState;
for (unsigned long lSampleIndex = 0;
lSampleIndex < SampleCount;
lSampleIndex++) {
LADSPA_Data fInput = *(pfInput++);
LADSPA_Data fEnvelopeTarget = fabs(fInput);
if (fEnvelopeTarget > rfEnvelopeState)
rfEnvelopeState = (rfEnvelopeState * fEnvelopeDrag_Attack
+ fEnvelopeTarget * (1 - fEnvelopeDrag_Attack));
else
rfEnvelopeState = (rfEnvelopeState * fEnvelopeDrag_Decay
+ fEnvelopeTarget * (1 - fEnvelopeDrag_Decay));
/* Perform the mapping. This questions this plugin's claim of
being `hard-realtime.' */
LADSPA_Data fGain;
if (rfEnvelopeState < fThreshold)
fGain = 1;
else {
fGain = fThreshold / rfEnvelopeState;
if (isnan(fGain))
fGain = 0;
}
/* Perform output. */
*(pfOutput++) = fInput * fGain;
}
}
/*****************************************************************************/
void
runLimiter_RMS(LADSPA_Handle Instance,
unsigned long SampleCount) {
Limiter * poProcessor = (Limiter *)Instance;
LADSPA_Data fThreshold
= BOUNDED_BELOW(*(poProcessor->m_ppfPorts[LN_THRESHOLD]),
0);
LADSPA_Data * pfInput
= poProcessor->m_ppfPorts[LN_INPUT];
LADSPA_Data * pfOutput
= poProcessor->m_ppfPorts[LN_OUTPUT];
LADSPA_Data fEnvelopeDrag_Attack
= calculate60dBDrag(*(poProcessor->m_ppfPorts[CE_ATTACK]),
poProcessor->m_fSampleRate);
LADSPA_Data fEnvelopeDrag_Decay
= calculate60dBDrag(*(poProcessor->m_ppfPorts[CE_DECAY]),
poProcessor->m_fSampleRate);
LADSPA_Data &rfEnvelopeState
= poProcessor->m_fEnvelopeState;
for (unsigned long lSampleIndex = 0;
lSampleIndex < SampleCount;
lSampleIndex++) {
LADSPA_Data fInput = *(pfInput++);
LADSPA_Data fEnvelopeTarget = fInput * fInput;
if (fEnvelopeTarget > rfEnvelopeState)
rfEnvelopeState = (rfEnvelopeState * fEnvelopeDrag_Attack
+ fEnvelopeTarget * (1 - fEnvelopeDrag_Attack));
else
rfEnvelopeState = (rfEnvelopeState * fEnvelopeDrag_Decay
+ fEnvelopeTarget * (1 - fEnvelopeDrag_Decay));
LADSPA_Data fEnvelopeAmplitude = sqrt(rfEnvelopeState);
/* Perform the mapping. This questions this plugin's claim of
being `hard-realtime.' */
LADSPA_Data fGain;
if (fEnvelopeAmplitude < fThreshold)
fGain = 1;
else {
fGain = fThreshold / fEnvelopeAmplitude;
if (isnan(fGain))
fGain = 0;
}
/* Perform output. */
*(pfOutput++) = fInput * fGain;
}
}
/*****************************************************************************/
void
initialise_dynamic() {
CMT_Descriptor * psDescriptor;
psDescriptor = new CMT_Descriptor
(1072,
"compress_peak",
LADSPA_PROPERTY_HARD_RT_CAPABLE,
"Simple Compressor (Peak Envelope Tracking)",
CMT_MAKER("Richard W.E. Furse"),
CMT_COPYRIGHT("2000-2002", "Richard W.E. Furse"),
NULL,
CMT_Instantiate<CompressorExpander>,
activateCompressorExpander,
runCompressor_Peak,
NULL,
NULL,
NULL);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Threshold",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_LOGARITHMIC
| LADSPA_HINT_DEFAULT_1),
0,
0);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Compression Ratio",
(LADSPA_HINT_BOUNDED_ABOVE
| LADSPA_HINT_DEFAULT_MIDDLE),
0,
1);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Output Envelope Attack (s)",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_DEFAULT_MAXIMUM),
0,
0.1f);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Output Envelope Decay (s)",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_DEFAULT_MAXIMUM),
0,
0.1f);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
"Input");
psDescriptor->addPort
(LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
"Output");
registerNewPluginDescriptor(psDescriptor);
psDescriptor = new CMT_Descriptor
(1073,
"compress_rms",
LADSPA_PROPERTY_HARD_RT_CAPABLE,
"Simple Compressor (RMS Envelope Tracking)",
CMT_MAKER("Richard W.E. Furse"),
CMT_COPYRIGHT("2000-2002", "Richard W.E. Furse"),
NULL,
CMT_Instantiate<CompressorExpander>,
activateCompressorExpander,
runCompressor_RMS,
NULL,
NULL,
NULL);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Threshold",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_LOGARITHMIC
| LADSPA_HINT_DEFAULT_1),
0,
0);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Compression Ratio",
(LADSPA_HINT_BOUNDED_ABOVE
| LADSPA_HINT_DEFAULT_MIDDLE),
0,
1);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Output Envelope Attack (s)",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_DEFAULT_MAXIMUM),
0,
0.1f);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Output Envelope Decay (s)",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_DEFAULT_MAXIMUM),
0,
0.1f);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
"Input");
psDescriptor->addPort
(LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
"Output");
registerNewPluginDescriptor(psDescriptor);
psDescriptor = new CMT_Descriptor
(1074,
"expand_peak",
LADSPA_PROPERTY_HARD_RT_CAPABLE,
"Simple Expander (Peak Envelope Tracking)",
CMT_MAKER("Richard W.E. Furse"),
CMT_COPYRIGHT("2000-2002", "Richard W.E. Furse"),
NULL,
CMT_Instantiate<CompressorExpander>,
activateCompressorExpander,
runExpander_Peak,
NULL,
NULL,
NULL);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Threshold",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_LOGARITHMIC
| LADSPA_HINT_DEFAULT_1),
0,
0);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Expansion Ratio",
(LADSPA_HINT_BOUNDED_ABOVE
| LADSPA_HINT_DEFAULT_MIDDLE),
0,
1);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Output Envelope Attack (s)",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_DEFAULT_MAXIMUM),
0,
0.1f);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Output Envelope Decay (s)",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_DEFAULT_MAXIMUM),
0,
0.1f);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
"Input");
psDescriptor->addPort
(LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
"Output");
registerNewPluginDescriptor(psDescriptor);
psDescriptor = new CMT_Descriptor
(1075,
"expand_rms",
LADSPA_PROPERTY_HARD_RT_CAPABLE,
"Simple Expander (RMS Envelope Tracking)",
CMT_MAKER("Richard W.E. Furse"),
CMT_COPYRIGHT("2000-2002", "Richard W.E. Furse"),
NULL,
CMT_Instantiate<CompressorExpander>,
activateCompressorExpander,
runExpander_RMS,
NULL,
NULL,
NULL);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Threshold",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_LOGARITHMIC
| LADSPA_HINT_DEFAULT_1),
0,
0);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Expansion Ratio",
(LADSPA_HINT_BOUNDED_ABOVE
| LADSPA_HINT_DEFAULT_MIDDLE),
0,
1);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Output Envelope Attack (s)",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_DEFAULT_MAXIMUM),
0,
0.1f);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Output Envelope Decay (s)",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_DEFAULT_MAXIMUM),
0,
0.1f);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
"Input");
psDescriptor->addPort
(LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
"Output");
registerNewPluginDescriptor(psDescriptor);
psDescriptor = new CMT_Descriptor
(1076,
"limit_peak",
LADSPA_PROPERTY_HARD_RT_CAPABLE,
"Simple Limiter (Peak Envelope Tracking)",
CMT_MAKER("Richard W.E. Furse"),
CMT_COPYRIGHT("2000-2002", "Richard W.E. Furse"),
NULL,
CMT_Instantiate<Limiter>,
activateLimiter,
runLimiter_Peak,
NULL,
NULL,
NULL);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Threshold",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_LOGARITHMIC
| LADSPA_HINT_DEFAULT_1),
0,
0);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Output Envelope Attack (s)",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_DEFAULT_MAXIMUM),
0,
0.1f);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Output Envelope Decay (s)",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_DEFAULT_MAXIMUM),
0,
0.1f);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
"Input");
psDescriptor->addPort
(LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
"Output");
registerNewPluginDescriptor(psDescriptor);
psDescriptor = new CMT_Descriptor
(1077,
"limit_rms",
LADSPA_PROPERTY_HARD_RT_CAPABLE,
"Simple Limiter (RMS Envelope Tracking)",
CMT_MAKER("Richard W.E. Furse"),
CMT_COPYRIGHT("2000-2002", "Richard W.E. Furse"),
NULL,
CMT_Instantiate<Limiter>,
activateLimiter,
runLimiter_RMS,
NULL,
NULL,
NULL);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Threshold",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_LOGARITHMIC
| LADSPA_HINT_DEFAULT_1),
0,
0);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Output Envelope Attack (s)",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_DEFAULT_MAXIMUM),
0,
0.1f);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Output Envelope Decay (s)",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_DEFAULT_MAXIMUM),
0,
0.1f);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
"Input");
psDescriptor->addPort
(LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
"Output");
registerNewPluginDescriptor(psDescriptor);
}
/*****************************************************************************/
/* EOF */

View File

@@ -1,250 +0,0 @@
/* filter.cpp
Computer Music Toolkit - a library of LADSPA plugins. Copyright (C)
2000-2002 Richard W.E. Furse. The author may be contacted at
richard@muse.demon.co.uk.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public Licence as
published by the Free Software Foundation; either version 2 of the
Licence, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA. */
/*****************************************************************************/
#include <math.h>
#include <stdlib.h>
/*****************************************************************************/
#include "cmt.h"
/*****************************************************************************/
#define SF_CUTOFF 0
#define SF_INPUT 1
#define SF_OUTPUT 2
/** Instance data for the OnePoll filter (one-poll, low or high
pass). We can get away with using this structure for both low- and
high-pass filters because the data stored is the same. Note that
the actual run() calls differ however. */
class OnePollFilter : public CMT_PluginInstance {
private:
LADSPA_Data m_fSampleRate;
LADSPA_Data m_fTwoPiOverSampleRate;
LADSPA_Data m_fLastOutput;
LADSPA_Data m_fLastCutoff;
LADSPA_Data m_fAmountOfCurrent;
LADSPA_Data m_fAmountOfLast;
public:
OnePollFilter(const LADSPA_Descriptor *,
unsigned long lSampleRate)
: CMT_PluginInstance(3),
m_fSampleRate(LADSPA_Data(lSampleRate)),
m_fTwoPiOverSampleRate(LADSPA_Data((2 * M_PI) / lSampleRate)),
m_fLastCutoff(0),
m_fAmountOfCurrent(0),
m_fAmountOfLast(0) {
}
friend void activateOnePollFilter(LADSPA_Handle Instance);
friend void runOnePollLowPassFilter(LADSPA_Handle Instance,
unsigned long SampleCount);
friend void runOnePollHighPassFilter(LADSPA_Handle Instance,
unsigned long SampleCount);
};
/*****************************************************************************/
void
activateOnePollFilter(LADSPA_Handle Instance) {
((OnePollFilter *)Instance)->m_fLastOutput = 0;
}
/*****************************************************************************/
/** Run the LPF algorithm for a block of SampleCount samples. */
void
runOnePollLowPassFilter(LADSPA_Handle Instance,
unsigned long SampleCount) {
OnePollFilter * poFilter = (OnePollFilter *)Instance;
LADSPA_Data * pfInput = poFilter->m_ppfPorts[SF_INPUT];
LADSPA_Data * pfOutput = poFilter->m_ppfPorts[SF_OUTPUT];
if (poFilter->m_fLastCutoff != *(poFilter->m_ppfPorts[SF_CUTOFF])) {
poFilter->m_fLastCutoff = *(poFilter->m_ppfPorts[SF_CUTOFF]);
if (poFilter->m_fLastCutoff <= 0) {
/* Reject everything. */
poFilter->m_fAmountOfCurrent = poFilter->m_fAmountOfLast = 0;
}
else if (poFilter->m_fLastCutoff > poFilter->m_fSampleRate * 0.5) {
/* Above Nyquist frequency. Let everything through. */
poFilter->m_fAmountOfCurrent = 1;
poFilter->m_fAmountOfLast = 0;
}
else {
poFilter->m_fAmountOfLast = 0;
LADSPA_Data fComp = 2 - cos(poFilter->m_fTwoPiOverSampleRate
* poFilter->m_fLastCutoff);
poFilter->m_fAmountOfLast = fComp - (LADSPA_Data)sqrt(fComp * fComp - 1);
poFilter->m_fAmountOfCurrent = 1 - poFilter->m_fAmountOfLast;
}
}
LADSPA_Data fAmountOfCurrent = poFilter->m_fAmountOfCurrent;
LADSPA_Data fAmountOfLast = poFilter->m_fAmountOfLast;
LADSPA_Data fLastOutput = poFilter->m_fLastOutput;
for (unsigned long lSampleIndex = 0;
lSampleIndex < SampleCount;
lSampleIndex++) {
*(pfOutput++)
= fLastOutput
= (fAmountOfCurrent * *(pfInput++)
+ fAmountOfLast * fLastOutput);
}
poFilter->m_fLastOutput = fLastOutput;
}
/*****************************************************************************/
/** Run the HPF algorithm for a block of SampleCount samples. */
void
runOnePollHighPassFilter(LADSPA_Handle Instance,
unsigned long SampleCount) {
OnePollFilter * poFilter = (OnePollFilter *)Instance;
LADSPA_Data * pfInput = poFilter->m_ppfPorts[SF_INPUT];
LADSPA_Data * pfOutput = poFilter->m_ppfPorts[SF_OUTPUT];
if (poFilter->m_fLastCutoff != *(poFilter->m_ppfPorts[SF_CUTOFF])) {
poFilter->m_fLastCutoff = *(poFilter->m_ppfPorts[SF_CUTOFF]);
if (poFilter->m_fLastCutoff <= 0) {
/* Let everything through. */
poFilter->m_fAmountOfCurrent = 1;
poFilter->m_fAmountOfLast = 0;
}
else if (poFilter->m_fLastCutoff > poFilter->m_fSampleRate * 0.5) {
/* Above Nyquist frequency. Reject everything. */
poFilter->m_fAmountOfCurrent = poFilter->m_fAmountOfLast = 0;
}
else {
poFilter->m_fAmountOfLast = 0;
LADSPA_Data fComp = 2 - cos(poFilter->m_fTwoPiOverSampleRate
* poFilter->m_fLastCutoff);
poFilter->m_fAmountOfLast = fComp - (LADSPA_Data)sqrt(fComp * fComp - 1);
poFilter->m_fAmountOfCurrent = 1 - poFilter->m_fAmountOfLast;
}
}
LADSPA_Data fAmountOfCurrent = poFilter->m_fAmountOfCurrent;
LADSPA_Data fAmountOfLast = poFilter->m_fAmountOfLast;
LADSPA_Data fLastOutput = poFilter->m_fLastOutput;
for (unsigned long lSampleIndex = 0;
lSampleIndex < SampleCount;
lSampleIndex++) {
fLastOutput
= (fAmountOfCurrent * *pfInput
+ fAmountOfLast * fLastOutput);
*(pfOutput++) = *(pfInput++) - fLastOutput;
}
poFilter->m_fLastOutput = fLastOutput;
}
/*****************************************************************************/
void
initialise_filter() {
CMT_Descriptor * psDescriptor;
psDescriptor = new CMT_Descriptor
(1051,
"lpf",
LADSPA_PROPERTY_HARD_RT_CAPABLE,
"Low Pass Filter (One Pole)",
CMT_MAKER("Richard W.E. Furse"),
CMT_COPYRIGHT("2000-2002", "Richard W.E. Furse"),
NULL,
CMT_Instantiate<OnePollFilter>,
activateOnePollFilter,
runOnePollLowPassFilter,
NULL,
NULL,
NULL);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Cutoff Frequency (Hz)",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_BOUNDED_ABOVE
| LADSPA_HINT_SAMPLE_RATE
| LADSPA_HINT_LOGARITHMIC
| LADSPA_HINT_DEFAULT_440),
0,
0.5f); /* Nyquist frequency (half the sample rate) */
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
"Input");
psDescriptor->addPort
(LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
"Output");
registerNewPluginDescriptor(psDescriptor);
psDescriptor = new CMT_Descriptor
(1052,
"hpf",
LADSPA_PROPERTY_HARD_RT_CAPABLE,
"High Pass Filter (One Pole)",
CMT_MAKER("Richard W.E. Furse"),
CMT_COPYRIGHT("2000-2002", "Richard W.E. Furse"),
NULL,
CMT_Instantiate<OnePollFilter>,
activateOnePollFilter,
runOnePollHighPassFilter,
NULL,
NULL,
NULL);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Cutoff Frequency (Hz)",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_BOUNDED_ABOVE
| LADSPA_HINT_SAMPLE_RATE
| LADSPA_HINT_LOGARITHMIC
| LADSPA_HINT_DEFAULT_440),
0,
0.5f); /* Nyquist frequency (half the sample rate) */
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
"Input");
psDescriptor->addPort
(LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
"Output");
registerNewPluginDescriptor(psDescriptor);
}
/*****************************************************************************/
/* EOF */

View File

@@ -1,36 +0,0 @@
// Allpass filter implementation
//
// Written by Jezar at Dreampoint, June 2000
// http://www.dreampoint.co.uk
// This code is public domain
#include "allpass.h"
allpass::allpass()
{
bufidx = 0;
}
void allpass::setbuffer(float *buf, int size)
{
buffer = buf;
bufsize = size;
}
void allpass::mute()
{
for (int i=0; i<bufsize; i++)
buffer[i]=0;
}
void allpass::setfeedback(float val)
{
feedback = val;
}
float allpass::getfeedback()
{
return feedback;
}
//ends

View File

@@ -1,48 +0,0 @@
// Allpass filter declaration
//
// Written by Jezar at Dreampoint, June 2000
// http://www.dreampoint.co.uk
// This code is public domain
#ifndef _allpass_
#define _allpass_
#include "denormals.h"
class allpass
{
public:
allpass();
void setbuffer(float *buf, int size);
inline float process(float inp);
void mute();
void setfeedback(float val);
float getfeedback();
// private:
float feedback;
float *buffer;
int bufsize;
int bufidx;
};
// Big to inline - but crucial for speed
inline float allpass::process(float input)
{
float output;
float bufout;
bufout = buffer[bufidx];
undenormalise(&bufout);
output = -input + bufout;
buffer[bufidx] = input + (bufout*feedback);
if(++bufidx>=bufsize) bufidx = 0;
return output;
}
#endif//_allpass
//ends

View File

@@ -1,48 +0,0 @@
// Comb filter implementation
//
// Written by Jezar at Dreampoint, June 2000
// http://www.dreampoint.co.uk
// This code is public domain
#include "comb.h"
comb::comb()
{
filterstore = 0;
bufidx = 0;
}
void comb::setbuffer(float *buf, int size)
{
buffer = buf;
bufsize = size;
}
void comb::mute()
{
for (int i=0; i<bufsize; i++)
buffer[i]=0;
}
void comb::setdamp(float val)
{
damp1 = val;
damp2 = 1-val;
}
float comb::getdamp()
{
return damp1;
}
void comb::setfeedback(float val)
{
feedback = val;
}
float comb::getfeedback()
{
return feedback;
}
// ends

View File

@@ -1,55 +0,0 @@
// Comb filter class declaration
//
// Written by Jezar at Dreampoint, June 2000
// http://www.dreampoint.co.uk
// This code is public domain
#ifndef _comb_
#define _comb_
#include "denormals.h"
class comb
{
public:
comb();
void setbuffer(float *buf, int size);
inline float process(float inp);
void mute();
void setdamp(float val);
float getdamp();
void setfeedback(float val);
float getfeedback();
private:
float feedback;
float filterstore;
float damp1;
float damp2;
float *buffer;
int bufsize;
int bufidx;
};
// Big to inline - but crucial for speed
inline float comb::process(float input)
{
float output;
output = buffer[bufidx];
undenormalise(&output);
filterstore = (output*damp2) + (filterstore*damp1);
undenormalise(&filterstore);
buffer[bufidx] = input + (filterstore*feedback);
if(++bufidx>=bufsize) bufidx = 0;
return output;
}
#endif //_comb_
//ends

View File

@@ -1,20 +0,0 @@
// Macro for killing denormalled numbers
//
// Written by Jezar at Dreampoint, June 2000
// http://www.dreampoint.co.uk
// Based on IS_DENORMAL macro by Jon Watte
// This code is public domain
#ifndef _denormals_
#define _denormals_
/*#define undenormalise(sample) if(((*(unsigned int*)&sample)&0x7f800000)==0) sample=0.0f*/
static void inline undenormalise(float *sample)
{
if (((*(unsigned int*)sample) & 0x7f800000) == 0)
*sample = 0.0f;
}
#endif//_denormals_
//ends

View File

@@ -1,257 +0,0 @@
// Reverb model implementation
//
// Written by Jezar at Dreampoint, June 2000
// http://www.dreampoint.co.uk
// This code is public domain
#include "revmodel.h"
revmodel::revmodel( float sampleRatio ) :
m_sampleRatio( sampleRatio )
{
// Tie the components to their buffers
combL[0].setbuffer(bufcombL1,static_cast<int>( combtuningL1 * m_sampleRatio ));
combR[0].setbuffer(bufcombR1,static_cast<int>( combtuningR1 * m_sampleRatio ));
combL[1].setbuffer(bufcombL2,static_cast<int>( combtuningL2 * m_sampleRatio ));
combR[1].setbuffer(bufcombR2,static_cast<int>( combtuningR2 * m_sampleRatio ));
combL[2].setbuffer(bufcombL3,static_cast<int>( combtuningL3 * m_sampleRatio ));
combR[2].setbuffer(bufcombR3,static_cast<int>( combtuningR3 * m_sampleRatio ));
combL[3].setbuffer(bufcombL4,static_cast<int>( combtuningL4 * m_sampleRatio ));
combR[3].setbuffer(bufcombR4,static_cast<int>( combtuningR4 * m_sampleRatio ));
combL[4].setbuffer(bufcombL5,static_cast<int>( combtuningL5 * m_sampleRatio ));
combR[4].setbuffer(bufcombR5,static_cast<int>( combtuningR5 * m_sampleRatio ));
combL[5].setbuffer(bufcombL6,static_cast<int>( combtuningL6 * m_sampleRatio ));
combR[5].setbuffer(bufcombR6,static_cast<int>( combtuningR6 * m_sampleRatio ));
combL[6].setbuffer(bufcombL7,static_cast<int>( combtuningL7 * m_sampleRatio ));
combR[6].setbuffer(bufcombR7,static_cast<int>( combtuningR7 * m_sampleRatio ));
combL[7].setbuffer(bufcombL8,static_cast<int>( combtuningL8 * m_sampleRatio ));
combR[7].setbuffer(bufcombR8,static_cast<int>( combtuningR8 * m_sampleRatio ));
allpassL[0].setbuffer(bufallpassL1,static_cast<int>( allpasstuningL1 * m_sampleRatio ));
allpassR[0].setbuffer(bufallpassR1,static_cast<int>( allpasstuningR1 * m_sampleRatio ));
allpassL[1].setbuffer(bufallpassL2,static_cast<int>( allpasstuningL2 * m_sampleRatio ));
allpassR[1].setbuffer(bufallpassR2,static_cast<int>( allpasstuningR2 * m_sampleRatio ));
allpassL[2].setbuffer(bufallpassL3,static_cast<int>( allpasstuningL3 * m_sampleRatio ));
allpassR[2].setbuffer(bufallpassR3,static_cast<int>( allpasstuningR3 * m_sampleRatio ));
allpassL[3].setbuffer(bufallpassL4,static_cast<int>( allpasstuningL4 * m_sampleRatio ));
allpassR[3].setbuffer(bufallpassR4,static_cast<int>( allpasstuningR4 * m_sampleRatio ));
// Set default values
allpassL[0].setfeedback(0.5f);
allpassR[0].setfeedback(0.5f);
allpassL[1].setfeedback(0.5f);
allpassR[1].setfeedback(0.5f);
allpassL[2].setfeedback(0.5f);
allpassR[2].setfeedback(0.5f);
allpassL[3].setfeedback(0.5f);
allpassR[3].setfeedback(0.5f);
setwet(initialwet);
setroomsize(initialroom);
setdry(initialdry);
setdamp(initialdamp);
setwidth(initialwidth);
setmode(initialmode);
// Buffer will be full of rubbish - so we MUST mute them
mute();
}
void revmodel::mute()
{
int i;
if (getmode() >= freezemode)
return;
for (i=0;i<numcombs;i++)
{
combL[i].mute();
combR[i].mute();
}
for (i=0;i<numallpasses;i++)
{
allpassL[i].mute();
allpassR[i].mute();
}
}
void revmodel::processreplace(float *inputL, float *inputR, float *outputL, float *outputR, long numsamples, int skip)
{
float outL,outR,input;
int i;
while(numsamples-- > 0)
{
outL = outR = 0;
input = (*inputL + *inputR) * gain;
// Accumulate comb filters in parallel
for(i=0; i<numcombs; i++)
{
outL += combL[i].process(input);
outR += combR[i].process(input);
}
// Feed through allpasses in series
for(i=0; i<numallpasses; i++)
{
outL = allpassL[i].process(outL);
outR = allpassR[i].process(outR);
}
// Calculate output REPLACING anything already there
*outputL = outL*wet1 + outR*wet2 + *inputL*dry;
*outputR = outR*wet1 + outL*wet2 + *inputR*dry;
// Increment sample pointers, allowing for interleave (if any)
inputL += skip;
inputR += skip;
outputL += skip;
outputR += skip;
}
}
void revmodel::processmix(float *inputL, float *inputR, float *outputL, float *outputR, long numsamples, int skip)
{
float outL,outR,input;
int i;
while(numsamples-- > 0)
{
outL = outR = 0;
input = (*inputL + *inputR) * gain;
// Accumulate comb filters in parallel
for(i=0; i<numcombs; i++)
{
outL += combL[i].process(input);
outR += combR[i].process(input);
}
// Feed through allpasses in series
for(i=0; i<numallpasses; i++)
{
outL = allpassL[i].process(outL);
outR = allpassR[i].process(outR);
}
// Calculate output MIXING with anything already there
*outputL += outL*wet1 + outR*wet2 + *inputL*dry;
*outputR += outR*wet1 + outL*wet2 + *inputR*dry;
// Increment sample pointers, allowing for interleave (if any)
inputL += skip;
inputR += skip;
outputL += skip;
outputR += skip;
}
}
void revmodel::update()
{
// Recalculate internal values after parameter change
int i;
wet1 = wet*(width/2 + 0.5f);
wet2 = wet*((1-width)/2);
if (mode >= freezemode)
{
roomsize1 = 1;
damp1 = 0;
gain = muted;
}
else
{
roomsize1 = roomsize;
damp1 = damp;
gain = fixedgain;
}
for(i=0; i<numcombs; i++)
{
combL[i].setfeedback(roomsize1);
combR[i].setfeedback(roomsize1);
}
for(i=0; i<numcombs; i++)
{
combL[i].setdamp(damp1);
combR[i].setdamp(damp1);
}
}
// The following get/set functions are not inlined, because
// speed is never an issue when calling them, and also
// because as you develop the reverb model, you may
// wish to take dynamic action when they are called.
void revmodel::setroomsize(float value)
{
roomsize = (value*scaleroom) + offsetroom;
update();
}
float revmodel::getroomsize()
{
return (roomsize-offsetroom)/scaleroom;
}
void revmodel::setdamp(float value)
{
damp = value*scaledamp;
update();
}
float revmodel::getdamp()
{
return damp/scaledamp;
}
void revmodel::setwet(float value)
{
wet = value*scalewet;
update();
}
float revmodel::getwet()
{
return wet/scalewet;
}
void revmodel::setdry(float value)
{
dry = value*scaledry;
}
float revmodel::getdry()
{
return dry/scaledry;
}
void revmodel::setwidth(float value)
{
width = value;
update();
}
float revmodel::getwidth()
{
return width;
}
void revmodel::setmode(float value)
{
mode = value;
update();
}
float revmodel::getmode()
{
if (mode >= freezemode)
return 1;
else
return 0;
}
//ends

View File

@@ -1,91 +0,0 @@
// Reverb model declaration
//
// Written by Jezar at Dreampoint, June 2000
// http://www.dreampoint.co.uk
// This code is public domain
#ifndef _revmodel_
#define _revmodel_
#include "comb.h"
#include "allpass.h"
#include "tuning.h"
const int maxSampleRatio = 18; // enough for largest possible samplerate, 8 * 96000
class revmodel
{
public:
revmodel( float sampleRatio );
void mute();
void processmix(float *inputL, float *inputR, float *outputL, float *outputR, long numsamples, int skip);
void processreplace(float *inputL, float *inputR, float *outputL, float *outputR, long numsamples, int skip);
void setroomsize(float value);
float getroomsize();
void setdamp(float value);
float getdamp();
void setwet(float value);
float getwet();
void setdry(float value);
float getdry();
void setwidth(float value);
float getwidth();
void setmode(float value);
float getmode();
private:
void update();
private:
float gain;
float roomsize,roomsize1;
float damp,damp1;
float wet,wet1,wet2;
float dry;
float width;
float mode;
float m_sampleRatio;
// The following are all declared inline
// to remove the need for dynamic allocation
// with its subsequent error-checking messiness
// Comb filters
comb combL[numcombs];
comb combR[numcombs];
// Allpass filters
allpass allpassL[numallpasses];
allpass allpassR[numallpasses];
// Buffers for the combs
float bufcombL1[combtuningL1 * maxSampleRatio];
float bufcombR1[combtuningR1 * maxSampleRatio];
float bufcombL2[combtuningL2 * maxSampleRatio];
float bufcombR2[combtuningR2 * maxSampleRatio];
float bufcombL3[combtuningL3 * maxSampleRatio];
float bufcombR3[combtuningR3 * maxSampleRatio];
float bufcombL4[combtuningL4 * maxSampleRatio];
float bufcombR4[ combtuningR4 * maxSampleRatio ];
float bufcombL5[ combtuningL5 * maxSampleRatio ];
float bufcombR5[ combtuningR5 * maxSampleRatio ];
float bufcombL6[ combtuningL6 * maxSampleRatio ];
float bufcombR6[ combtuningR6 * maxSampleRatio ];
float bufcombL7[ combtuningL7 * maxSampleRatio ];
float bufcombR7[ combtuningR7 * maxSampleRatio ];
float bufcombL8[ combtuningL8 * maxSampleRatio ];
float bufcombR8[ combtuningR8 * maxSampleRatio ];
// Buffers for the allpasses
float bufallpassL1[ allpasstuningL1 * maxSampleRatio ];
float bufallpassR1[ allpasstuningR1 * maxSampleRatio ];
float bufallpassL2[ allpasstuningL2 * maxSampleRatio ];
float bufallpassR2[ allpasstuningR2 * maxSampleRatio ];
float bufallpassL3[ allpasstuningL3 * maxSampleRatio ];
float bufallpassR3[ allpasstuningR3 * maxSampleRatio ];
float bufallpassL4[ allpasstuningL4 * maxSampleRatio ];
float bufallpassR4[ allpasstuningR4 * maxSampleRatio ];
};
#endif//_revmodel_
//ends

View File

@@ -1,60 +0,0 @@
// Reverb model tuning values
//
// Written by Jezar at Dreampoint, June 2000
// http://www.dreampoint.co.uk
// This code is public domain
#ifndef _tuning_
#define _tuning_
const int numcombs = 8;
const int numallpasses = 4;
const float muted = 0;
const float fixedgain = 0.015f;
const float scalewet = 3;
const float scaledry = 2;
const float scaledamp = 0.4f;
const float scaleroom = 0.28f;
const float offsetroom = 0.7f;
const float initialroom = 0.5f;
const float initialdamp = 0.5f;
const float initialwet = 1/scalewet;
const float initialdry = 0;
const float initialwidth = 1;
const float initialmode = 0;
const float freezemode = 0.5f;
const int stereospread = 23;
// These values assume 44.1KHz sample rate
// they will probably be OK for 48KHz sample rate
// but would need scaling for 96KHz (or other) sample rates.
// The values were obtained by listening tests.
const int combtuningL1 = 1116;
const int combtuningR1 = 1116+stereospread;
const int combtuningL2 = 1188;
const int combtuningR2 = 1188+stereospread;
const int combtuningL3 = 1277;
const int combtuningR3 = 1277+stereospread;
const int combtuningL4 = 1356;
const int combtuningR4 = 1356+stereospread;
const int combtuningL5 = 1422;
const int combtuningR5 = 1422+stereospread;
const int combtuningL6 = 1491;
const int combtuningR6 = 1491+stereospread;
const int combtuningL7 = 1557;
const int combtuningR7 = 1557+stereospread;
const int combtuningL8 = 1617;
const int combtuningR8 = 1617+stereospread;
const int allpasstuningL1 = 556;
const int allpasstuningR1 = 556+stereospread;
const int allpasstuningL2 = 441;
const int allpasstuningR2 = 441+stereospread;
const int allpasstuningL3 = 341;
const int allpasstuningR3 = 341+stereospread;
const int allpasstuningL4 = 225;
const int allpasstuningR4 = 225+stereospread;
#endif//_tuning_
//ends

View File

@@ -1,199 +0,0 @@
/* freeverb.cpp
Computer Music Toolkit - a library of LADSPA plugins. Copyright (C)
2000-2002 Richard W.E. Furse. Freeverb is also Copyright (C) 2000
Jezar. Richard may be contacted at richard@muse.demon.co.uk. [V1
Ported to LADSPA 15/7/2000 Richard W.E. Furse, V3 ported to CMT
4/11/2000.]
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public Licence as
published by the Free Software Foundation; either version 2 of the
Licence, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA. */
/*****************************************************************************/
#include <stdlib.h>
/*****************************************************************************/
#include "../cmt.h"
#include "Components/revmodel.h"
/*****************************************************************************/
enum {
FV_Input1 = 0,
FV_Input2,
FV_Output1,
FV_Output2,
FV_Mode,
FV_RoomSize,
FV_Damping,
FV_Wet,
FV_Dry,
FV_Width,
FV_NumPorts
};
/*****************************************************************************/
/** This plugin wraps Jezar's Freeverb free reverberation module
(version 3). */
class Freeverb3 : public CMT_PluginInstance, public revmodel {
public:
Freeverb3(const LADSPA_Descriptor *, unsigned long lSampleRate)
: CMT_PluginInstance(FV_NumPorts),
revmodel( (float) lSampleRate / 44100.0f )
{}
friend void activateFreeverb3(LADSPA_Handle Instance);
friend void runFreeverb3(LADSPA_Handle Instance,
unsigned long SampleCount);
};
/*****************************************************************************/
void
activateFreeverb3(LADSPA_Handle Instance) {
Freeverb3 * poFreeverb = (Freeverb3 *)Instance;
poFreeverb->mute();
}
/*****************************************************************************/
void
runFreeverb3(LADSPA_Handle Instance,
const unsigned long SampleCount) {
Freeverb3 * poFreeverb = ((Freeverb3 *)Instance);
/* Handle control ports. Note that this isn't especially efficient
because of the way the update() code works in revmodel.cpp, but
at least this approach allows Freeverb to work with almost no
code changes. */
if (*(poFreeverb->m_ppfPorts[FV_Mode]) > 0)
poFreeverb->setmode(1);
else
poFreeverb->setmode(0);
poFreeverb->setdamp(*(poFreeverb->m_ppfPorts[FV_Damping]));
poFreeverb->setwet(*(poFreeverb->m_ppfPorts[FV_Wet]));
poFreeverb->setdry(*(poFreeverb->m_ppfPorts[FV_Dry]));
poFreeverb->setroomsize(*(poFreeverb->m_ppfPorts[FV_RoomSize]));
poFreeverb->setwidth(*(poFreeverb->m_ppfPorts[FV_Width]));
/* Connect to audio ports and run. */
poFreeverb->processreplace(poFreeverb->m_ppfPorts[FV_Input1],
poFreeverb->m_ppfPorts[FV_Input2],
poFreeverb->m_ppfPorts[FV_Output1],
poFreeverb->m_ppfPorts[FV_Output2],
SampleCount,
1);
}
/*****************************************************************************/
void
initialise_freeverb3() {
CMT_Descriptor * psDescriptor;
psDescriptor = new CMT_Descriptor
(1123,
"freeverb3",
LADSPA_PROPERTY_HARD_RT_CAPABLE,
"Freeverb (Version 3)",
CMT_MAKER("Jezar at Dreampoint, ported by Richard W.E. Furse"),
CMT_COPYRIGHT("2000", "Jezar at Dreampoint"),
NULL,
CMT_Instantiate<Freeverb3>,
activateFreeverb3,
runFreeverb3,
NULL,
NULL,
NULL);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
"Input (Left)");
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
"Input (Right)");
psDescriptor->addPort
(LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
"Output (Left)");
psDescriptor->addPort
(LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
"Output (Right)");
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Freeze Mode",
(LADSPA_HINT_TOGGLED
| LADSPA_HINT_DEFAULT_0),
0,
0);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Room Size",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_BOUNDED_ABOVE
| LADSPA_HINT_DEFAULT_MIDDLE),
0,
1);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Damping",
(LADSPA_HINT_LOGARITHMIC
| LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_BOUNDED_ABOVE
| LADSPA_HINT_DEFAULT_MIDDLE),
0,
1);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Wet Level",
(LADSPA_HINT_LOGARITHMIC
| LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_BOUNDED_ABOVE
| LADSPA_HINT_DEFAULT_MIDDLE),
0,
1);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Dry Level",
(LADSPA_HINT_LOGARITHMIC
| LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_BOUNDED_ABOVE
| LADSPA_HINT_DEFAULT_MAXIMUM),
0,
1);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Width",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_BOUNDED_ABOVE
| LADSPA_HINT_DEFAULT_MIDDLE),
0,
1);
registerNewPluginDescriptor(psDescriptor);
}
/*****************************************************************************/
/* EOF */

View File

@@ -1,67 +0,0 @@
Freeverb - Free, studio-quality reverb SOURCE CODE in the public domain
-----------------------------------------------------------------------
Written by Jezar at Dreampoint - http://www.dreampoint.co.uk
Introduction
------------
Hello.
I'll try to keep this "readme" reasonably small. There are few things in the world that I hate more than long "readme" files. Except "coding conventions" - but more on that later...
In this zip file you will find two folders of C++ source code:
"Components" - Contains files that should clean-compile ON ANY TYPE OF COMPUTER OR SYSTEM WHATSOEVER. It should not be necessary to make ANY changes to these files to get them to compile, except to make up for inadequacies of certain compilers. These files create three classes - a comb filter, an allpass filter, and a reverb model made up of a number of instances of the filters, with some features to control the filters at a macro level. You will need to link these classes into another program that interfaces with them. The files in the components drawer are completely independant, and can be built without dependancies on anything else. Because of the simple interface, it should be possible to interface these files to any system - VST, DirectX, anything - without changing them AT ALL.
"FreeverbVST" - Contains a Steinberg VST implementation of this version of Freeverb, using the components in (surprise) the components folder. It was built on a PC but may compile properly for the Macintosh with no problems. I don't know - I don't have a Macintosh. If you've figured out how to compile the examples in the Steinberg VST Development Kit, then you should easilly figure out how to bring the files into a project and get it working in a few minutes. It should be very simple.
Note that this version of Freeverb doesn't contain predelay, or any EQ. I thought that might make it difficult to understand the "reverb" part of the code. Once you figure out how Freeverb works, you should find it trivial to add such features with little CPU overhead.
Also, the code in this version of Freeverb has been optimised. This has changed the sound *slightly*, but not significantly compared to how much processing power it saves.
Finally, note that there is also a built copy of this version of Freeverb called "Freeverb3.dll" - this is a VST plugin for the PC. If you want a version for the Mac or anything else, then you'll need to build it yourself from the code.
Technical Explanation
---------------------
Freeverb is a simple implementation of the standard Schroeder/Moorer reverb model. I guess the only reason why it sounds better than other reverbs, is simply because I spent a long while doing listening tests in order to create the values found in "tuning.h". It uses 8 comb filters on both the left and right channels), and you might possibly be able to get away with less if CPU power is a serious constraint for you. It then feeds the result of the reverb through 4 allpass filters on both the left and right channels. These "smooth" the sound. Adding more than four allpasses doesn't seem to add anything significant to the sound, and if you use less, the sound gets a bit "grainy". The filters on the right channel are slightly detuned compared to the left channel in order to create a stereo effect.
Hopefully, you should find the code in the components drawer a model of brevity and clarity. Notice that I don't use any "coding conventions". Personally, I think that coding conventions suck. They are meant to make the code "clearer", but they inevitably do the complete opposite, making the code completely unfathomable. Anyone whose done Windows programming with its - frankly stupid - "Hungarian notation" will know exactly what I mean. Coding conventions typically promote issues that are irrelevant up to the status of appearing supremely important. It may have helped back people in the days when compilers where somewhat feeble in their type-safety, but not in the new millenium with advanced C++ compilers.
Imagine if we rewrote the English language to conform to coding conventions. After all, The arguments should be just as valid for the English language as they are for a computer language. For example, we could put a lower-case "n" in front of every noun, a lower-case "p" in front of a persons name, a lower-case "v" in front of every verb, and a lower-case "a" in front of every adjective. Can you imagine what the English language would look like? All in the name of "clarity". It's just as stupid to do this for computer code as it would be to do it for the English language. I hope that the code for Freeverb in the components drawer demonstrates this, and helps start a movement back towards sanity in coding practices.
Background
----------
Why is the Freeverb code now public domain? Simple. I only intended to create Freeverb to provide me and my friends with studio-quality reverb for free. I never intended to make any money out of it. However, I simply do not have the time to develop it any further. I'm working on a "concept album" at the moment, and I'll never finish it if I spend any more time programming.
In any case, I make more far money as a contract programmer - making Mobile Internet products - than I ever could writing plugins, so it simply doesn't make financial sense for me to spend any more time on it.
Rather than give Freeverb to any particular individual or organisation to profit from it, I've decided to give it away to the internet community at large, so that quality, FREE (or at the very least, low-cost) reverbs can be developed for all platforms.
Feel free to use the source code for Freeverb in any of your own products, whether they are also available for free, or even if they are commercial - I really don't mind. You may do with the code whatever you wish. If you use it in a product (whether commercial or not), it would be very nice of you, if you were to send me a copy of your product - although I appreciate that this isn't always possible in all circumstances.
HOWEVER, please don't bug me with questions about how to use this code. I gave away Freeverb because I don't have time to maintain it. That means I *certainly* don't have time to answer questions about the source code, so please don't email questions to me. I *will* ignore them. If you can't figure the code for Freeverb out - then find somebody who can. I hope that either way, you enjoy experimenting with it.
Disclaimer
----------
This software and source code is given away for free, without any warranties of any kind. It has been given away to the internet community as a free gift, so please treat it in the same spirit.
I hope this code is useful and interesting to you all!
I hope you have lots of fun experimenting with it and make good products!
Very best regards,
Jezar.
Technology Consultant
Dreampoint Design and Engineering
http://www.dreampoint.co.uk
//ends

View File

@@ -1,401 +0,0 @@
/* grain.cpp
Computer Music Toolkit - a library of LADSPA plugins. Copyright (C)
2000-2002 Richard W.E. Furse. The author may be contacted at
richard@muse.demon.co.uk.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public Licence as
published by the Free Software Foundation; either version 2 of the
Licence, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA. */
/*****************************************************************************/
#include <stdlib.h>
#include <string.h>
/*****************************************************************************/
#include "cmt.h"
#include "utils.h"
/*****************************************************************************/
/** Period (in seconds) from which grains are selected. */
#define GRAIN_MAXIMUM_HISTORY 6
#define GRAIN_MAXIMUM_BLOCK 1 /* (seconds) */
#define GRAIN_MAXIMUM_SCATTER (GRAIN_MAXIMUM_HISTORY - GRAIN_MAXIMUM_BLOCK)
#define GRAIN_MAXIMUM_LENGTH (GRAIN_MAXIMUM_HISTORY - GRAIN_MAXIMUM_BLOCK)
/** What quality should we require when sampling the normal
distribution to generate grain counts? */
#define GRAIN_NORMAL_RV_QUALITY 16
/*****************************************************************************/
/** Pointers to this can be used as linked list of grains. */
class Grain {
private:
long m_lReadPointer;
long m_lGrainLength;
long m_lAttackTime;
long m_lRunTime;
bool m_bFinished;
LADSPA_Data m_fAttackSlope;
LADSPA_Data m_fDecaySlope;
public:
Grain(const long lReadPointer,
const long lGrainLength,
const long lAttackTime)
: m_lReadPointer(lReadPointer),
m_lGrainLength(lGrainLength),
m_lAttackTime(lAttackTime),
m_lRunTime(0),
m_bFinished(false) {
if (lAttackTime <= 0) {
m_fAttackSlope = 0;
m_fDecaySlope = LADSPA_Data(1.0 / lGrainLength);
}
else {
m_fAttackSlope = LADSPA_Data(1.0 / lAttackTime);
if (lAttackTime >= lGrainLength)
m_fDecaySlope = 0;
else
m_fDecaySlope = LADSPA_Data(1.0 / (lGrainLength - lAttackTime));
}
}
bool isFinished() const {
return m_bFinished;
}
/** NULL if end of grain list. */
Grain * m_poNextGrain;
void run(const unsigned long lSampleCount,
float * pfOutput,
const float * pfHistoryBuffer,
const unsigned long lHistoryBufferSize) {
LADSPA_Data fAmp;
if (m_lRunTime < m_lAttackTime)
fAmp = m_fAttackSlope * m_lRunTime;
else
fAmp = m_fDecaySlope * (m_lGrainLength - m_lRunTime);
for (unsigned long lSampleIndex = 0;
lSampleIndex < lSampleCount;
lSampleIndex++) {
if (fAmp < 0) {
m_bFinished = true;
break;
}
*(pfOutput++) += fAmp * pfHistoryBuffer[m_lReadPointer];
m_lReadPointer = (m_lReadPointer + 1) & (lHistoryBufferSize - 1);
if (m_lRunTime < m_lAttackTime)
fAmp += m_fAttackSlope;
else
fAmp -= m_fDecaySlope;
m_lRunTime++;
}
}
};
/*****************************************************************************/
#define GRN_INPUT 0
#define GRN_OUTPUT 1
#define GRN_DENSITY 2
#define GRN_SCATTER 3
#define GRN_GRAIN_LENGTH 4
#define GRN_GRAIN_ATTACK 5
/** This plugin cuts an audio stream up and uses it to generate a
granular texture. */
class GrainScatter : public CMT_PluginInstance {
private:
Grain * m_poCurrentGrains;
long m_lSampleRate;
LADSPA_Data * m_pfBuffer;
/** Buffer size, a power of two. */
unsigned long m_lBufferSize;
/** Write pointer in buffer. */
unsigned long m_lWritePointer;
public:
GrainScatter(const LADSPA_Descriptor *,
unsigned long lSampleRate)
: CMT_PluginInstance(6),
m_poCurrentGrains(NULL),
m_lSampleRate(lSampleRate) {
/* Buffer size is a power of two bigger than max delay time. */
unsigned long lMinimumBufferSize
= (unsigned long)((LADSPA_Data)lSampleRate * GRAIN_MAXIMUM_HISTORY);
m_lBufferSize = 1;
while (m_lBufferSize < lMinimumBufferSize)
m_lBufferSize <<= 1;
m_pfBuffer = new LADSPA_Data[m_lBufferSize];
}
~GrainScatter() {
delete [] m_pfBuffer;
}
friend void activateGrainScatter(LADSPA_Handle Instance);
friend void runGrainScatter(LADSPA_Handle Instance,
unsigned long SampleCount);
};
/*****************************************************************************/
/** Initialise and activate a plugin instance. */
void
activateGrainScatter(LADSPA_Handle Instance) {
GrainScatter * poGrainScatter = (GrainScatter *)Instance;
/* Need to reset the delay history in this function rather than
instantiate() in case deactivate() followed by activate() have
been called to reinitialise a delay line. */
memset(poGrainScatter->m_pfBuffer,
0,
sizeof(LADSPA_Data) * poGrainScatter->m_lBufferSize);
poGrainScatter->m_lWritePointer = 0;
}
/*****************************************************************************/
void
runGrainScatter(LADSPA_Handle Instance,
unsigned long SampleCount) {
GrainScatter * poGrainScatter = (GrainScatter *)Instance;
LADSPA_Data * pfInput = poGrainScatter->m_ppfPorts[GRN_INPUT];
LADSPA_Data * pfOutput = poGrainScatter->m_ppfPorts[GRN_OUTPUT];
unsigned long lMaximumSampleCount
= (unsigned long)(poGrainScatter->m_lSampleRate
* GRAIN_MAXIMUM_BLOCK);
if (SampleCount > lMaximumSampleCount) {
/* We're beyond our capabilities. We're going to run out of delay
line for a large grain. Divide and conquer. */
runGrainScatter(Instance, lMaximumSampleCount);
poGrainScatter->m_ppfPorts[GRN_INPUT] += lMaximumSampleCount;
poGrainScatter->m_ppfPorts[GRN_OUTPUT] += lMaximumSampleCount;
runGrainScatter(Instance, SampleCount - lMaximumSampleCount);
poGrainScatter->m_ppfPorts[GRN_INPUT] = pfInput;
poGrainScatter->m_ppfPorts[GRN_OUTPUT] = pfOutput;
}
else {
/* Move the delay line along. */
if (poGrainScatter->m_lWritePointer
+ SampleCount
> poGrainScatter->m_lBufferSize) {
memcpy(poGrainScatter->m_pfBuffer + poGrainScatter->m_lWritePointer,
pfInput,
sizeof(LADSPA_Data) * (poGrainScatter->m_lBufferSize
- poGrainScatter->m_lWritePointer));
memcpy(poGrainScatter->m_pfBuffer,
pfInput + (poGrainScatter->m_lBufferSize
- poGrainScatter->m_lWritePointer),
sizeof(LADSPA_Data) * (SampleCount
- (poGrainScatter->m_lBufferSize
- poGrainScatter->m_lWritePointer)));
}
else {
memcpy(poGrainScatter->m_pfBuffer + poGrainScatter->m_lWritePointer,
pfInput,
sizeof(LADSPA_Data) * SampleCount);
}
poGrainScatter->m_lWritePointer
= ((poGrainScatter->m_lWritePointer + SampleCount)
& (poGrainScatter->m_lBufferSize - 1));
/* Empty the output buffer. */
memset(pfOutput, 0, SampleCount * sizeof(LADSPA_Data));
/* Process current grains. */
Grain ** ppoGrainReference = &(poGrainScatter->m_poCurrentGrains);
while (*ppoGrainReference != NULL) {
(*ppoGrainReference)->run(SampleCount,
pfOutput,
poGrainScatter->m_pfBuffer,
poGrainScatter->m_lBufferSize);
if ((*ppoGrainReference)->isFinished()) {
Grain *poNextGrain = (*ppoGrainReference)->m_poNextGrain;
delete *ppoGrainReference;
*ppoGrainReference = poNextGrain;
}
else {
ppoGrainReference = &((*ppoGrainReference)->m_poNextGrain);
}
}
LADSPA_Data fSampleRate = LADSPA_Data(poGrainScatter->m_lSampleRate);
LADSPA_Data fDensity
= BOUNDED_BELOW(*(poGrainScatter->m_ppfPorts[GRN_DENSITY]),
0);
/* We want to average fDensity new grains per second. We need to
use a RNG to generate a new grain count from the fraction of a
second we are dealing with. Use a normal distribution and
choose standard deviation also to be fDensity. This could be
separately parameterised but any guarantees could be confusing
given that individual grains are uniformly distributed within
the block. Note that fDensity isn't quite grains/sec as we
discard negative samples from the RV. */
double dGrainCountRV_Mean = fDensity * SampleCount / fSampleRate;
double dGrainCountRV_SD = dGrainCountRV_Mean;
double dGrainCountRV = sampleNormalDistribution(dGrainCountRV_Mean,
dGrainCountRV_SD,
GRAIN_NORMAL_RV_QUALITY);
unsigned long lNewGrainCount = 0;
if (dGrainCountRV > 0)
lNewGrainCount = (unsigned long)(0.5 + dGrainCountRV);
if (lNewGrainCount > 0) {
LADSPA_Data fScatter
= BOUNDED(*(poGrainScatter->m_ppfPorts[GRN_SCATTER]),
0,
GRAIN_MAXIMUM_SCATTER);
LADSPA_Data fGrainLength
= BOUNDED_BELOW(*(poGrainScatter->m_ppfPorts[GRN_GRAIN_LENGTH]),
0);
LADSPA_Data fAttack
= BOUNDED_BELOW(*(poGrainScatter->m_ppfPorts[GRN_GRAIN_ATTACK]),
0);
long lScatterSampleWidth
= long(fSampleRate * fScatter) + 1;
long lGrainLength
= long(fSampleRate * fGrainLength);
long lAttackTime
= long(fSampleRate * fAttack);
for (unsigned long lIndex = 0; lIndex < lNewGrainCount; lIndex++) {
long lOffset = rand() % SampleCount;
long lGrainReadPointer
= (poGrainScatter->m_lWritePointer
- SampleCount
+ lOffset
- (rand() % lScatterSampleWidth));
while (lGrainReadPointer < 0)
lGrainReadPointer += poGrainScatter->m_lBufferSize;
lGrainReadPointer &= (poGrainScatter->m_lBufferSize - 1);
Grain * poNewGrain = new Grain(lGrainReadPointer,
lGrainLength,
lAttackTime);
poNewGrain->m_poNextGrain = poGrainScatter->m_poCurrentGrains;
poGrainScatter->m_poCurrentGrains = poNewGrain;
poNewGrain->run(SampleCount - lOffset,
pfOutput + lOffset,
poGrainScatter->m_pfBuffer,
poGrainScatter->m_lBufferSize);
}
}
}
}
/*****************************************************************************/
void
initialise_grain() {
CMT_Descriptor * psDescriptor = new CMT_Descriptor
(1096,
"grain_scatter",
0,
"Granular Scatter Processor",
CMT_MAKER("Richard W.E. Furse"),
CMT_COPYRIGHT("2000-2002", "Richard W.E. Furse"),
NULL,
CMT_Instantiate<GrainScatter>,
activateGrainScatter,
runGrainScatter,
NULL,
NULL,
NULL);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
"Input");
psDescriptor->addPort
(LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
"Output");
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Density (Grains/s)",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_DEFAULT_MAXIMUM),
0,
10);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Scatter (s)",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_BOUNDED_ABOVE
| LADSPA_HINT_DEFAULT_MIDDLE),
0,
GRAIN_MAXIMUM_SCATTER);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Grain Length (s)",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_DEFAULT_MAXIMUM),
0,
0.2);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Grain Attack (s)",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_DEFAULT_MAXIMUM),
0,
0.05);
registerNewPluginDescriptor(psDescriptor);
}
/*****************************************************************************/
/* EOF */

View File

@@ -1,122 +0,0 @@
/* hardgate.cpp
(c) 2002 Nathaniel Virgo
Computer Music Toolkit - a library of LADSPA plugins. Copyright (C)
2000-2002 Richard W.E. Furse. The author may be contacted at
richard@muse.demon.co.uk.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public Licence as
published by the Free Software Foundation; either version 2 of the
Licence, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA. */
/*****************************************************************************/
#include <stdlib.h>
/*****************************************************************************/
#include "cmt.h"
/*****************************************************************************/
namespace hardgate {
enum {
port_threshold = 0,
port_input = 1,
port_output = 2,
n_ports = 3
};
/** This plugin sets its input signal to 0 if it falls below a threshold. */
class Plugin : public CMT_PluginInstance {
public:
Plugin(const LADSPA_Descriptor *,
unsigned long)
: CMT_PluginInstance(n_ports) {
}
friend void run(LADSPA_Handle instance,
unsigned long sample_count);
};
void run(LADSPA_Handle instance,
unsigned long sample_count) {
Plugin *pp = (Plugin *) instance;
LADSPA_Data threshold = *pp->m_ppfPorts[port_threshold];
LADSPA_Data * in = pp->m_ppfPorts[port_input];
LADSPA_Data * out = pp->m_ppfPorts[port_output];
for ( unsigned long i = 0; i < sample_count ; ++i )
{
LADSPA_Data insig = *(in++);
if ( insig < threshold && insig > -threshold )
*(out++) = 0.0f;
else
*(out++) = insig;
}
}
void
initialise() {
CMT_Descriptor * d = new CMT_Descriptor
(1845,
"hard_gate",
LADSPA_PROPERTY_HARD_RT_CAPABLE,
"Hard Gate",
CMT_MAKER("Nathaniel Virgo"),
CMT_COPYRIGHT("2002", "Nathaniel Virgo"),
NULL,
CMT_Instantiate<Plugin>,
NULL,
run,
NULL,
NULL,
NULL);
d->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Threshold",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_BOUNDED_ABOVE
| LADSPA_HINT_DEFAULT_0),
0,
1);
d->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
"Input");
d->addPort
(LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
"Output");
registerNewPluginDescriptor(d);
}
} // end of namespace
/*****************************************************************************/
/* EOF */

View File

@@ -1,133 +0,0 @@
/* init.cpp
Computer Music Toolkit - a library of LADSPA plugins. Copyright (C)
2000 Richard W.E. Furse. The author may be contacted at
richard@muse.demon.co.uk.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public Licence as
published by the Free Software Foundation; either version 2 of the
Licence, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA. */
/*****************************************************************************/
#include <ladspa.h>
#include <stdlib.h>
#include <string.h>
/*****************************************************************************/
#include "cmt.h"
/*****************************************************************************/
void initialise_modules();
void finalise_modules();
/*****************************************************************************/
int
pluginNameComparator(const void * pvDescriptor1, const void * pvDescriptor2) {
const CMT_Descriptor * psDescriptor1
= *(const CMT_Descriptor **)pvDescriptor1;
const CMT_Descriptor * psDescriptor2
= *(const CMT_Descriptor **)pvDescriptor2;
int iResult = strcmp(psDescriptor1->Name, psDescriptor2->Name);
if (iResult < 0)
return -1;
else if (iResult > 0)
return 1;
else
return 0;
}
/*****************************************************************************/
CMT_Descriptor ** g_ppsRegisteredDescriptors = NULL;
unsigned long g_lPluginCapacity = 0;
unsigned long g_lPluginCount = 0;
/*****************************************************************************/
#define CAPACITY_STEP 20
void
registerNewPluginDescriptor(CMT_Descriptor * psDescriptor) {
if (g_lPluginCapacity == g_lPluginCount) {
/* Full. Enlarge capacity. */
CMT_Descriptor ** ppsOldDescriptors
= g_ppsRegisteredDescriptors;
g_ppsRegisteredDescriptors
= new CMT_Descriptor_ptr[g_lPluginCapacity + CAPACITY_STEP];
if (g_lPluginCapacity > 0) {
memcpy(g_ppsRegisteredDescriptors,
ppsOldDescriptors,
g_lPluginCapacity * sizeof(CMT_Descriptor_ptr));
delete [] ppsOldDescriptors;
}
g_lPluginCapacity += CAPACITY_STEP;
}
g_ppsRegisteredDescriptors[g_lPluginCount++] = psDescriptor;
}
/*****************************************************************************/
/** A global object of this class is used to perform initialisation
and shutdown services for the entire library. The constructor is
run when the library is loaded and the destructor when it is
unloaded. */
class StartupShutdownHandler {
public:
StartupShutdownHandler() {
initialise_modules();
qsort(g_ppsRegisteredDescriptors,
g_lPluginCount,
sizeof(CMT_Descriptor_ptr),
pluginNameComparator);
}
~StartupShutdownHandler() {
if (g_ppsRegisteredDescriptors != NULL) {
for (unsigned long lIndex = 0; lIndex < g_lPluginCount; lIndex++)
delete g_ppsRegisteredDescriptors[lIndex];
delete [] g_ppsRegisteredDescriptors;
}
finalise_modules();
}
} ;
/*****************************************************************************/
extern "C"
{
const LADSPA_Descriptor *
ladspa_descriptor(unsigned long Index) {
static StartupShutdownHandler handler;
if (Index < g_lPluginCount)
return g_ppsRegisteredDescriptors[Index];
else
return NULL;
}
};
/*****************************************************************************/
/* EOF */

View File

@@ -1,80 +0,0 @@
/* ladspa_types.h
Computer Music Toolkit - a library of LADSPA plugins. Copyright (C)
2000 Richard W.E. Furse. The author may be contacted at
richard@muse.demon.co.uk.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public Licence as
published by the Free Software Foundation; either version 2 of the
Licence, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA. */
#ifndef CMT_LADSPA_TYPES_INCLUDED
#define CMT_LADSPA_TYPES_INCLUDED
/*****************************************************************************/
#include <ladspa.h>
/* Compatibility hack for version 1.0. */
#ifndef LADSPA_VERSION_MAJOR
#define LADSPA_HINT_DEFAULT_MINIMUM 0x40
#define LADSPA_HINT_DEFAULT_LOW 0x80
#define LADSPA_HINT_DEFAULT_MIDDLE 0xC0
#define LADSPA_HINT_DEFAULT_HIGH 0x100
#define LADSPA_HINT_DEFAULT_MAXIMUM 0x140
#define LADSPA_HINT_DEFAULT_0 0x200
#define LADSPA_HINT_DEFAULT_1 0x240
#define LADSPA_HINT_DEFAULT_100 0x280
#define LADSPA_HINT_DEFAULT_440 0x2C0
#endif
/*****************************************************************************/
typedef LADSPA_Handle (*LADSPA_Instantiate_Function)
(const struct _LADSPA_Descriptor * Descriptor,
unsigned long SampleRate);
typedef void (*LADSPA_Connect_Port_Function)
(LADSPA_Handle Instance,
unsigned long Port,
LADSPA_Data * DataLocation);
typedef void (*LADSPA_Activate_Function)
(LADSPA_Handle Instance);
typedef void (*LADSPA_Run_Function)
(LADSPA_Handle Instance,
unsigned long SampleCount);
typedef void (*LADSPA_Run_Adding_Function)
(LADSPA_Handle Instance,
unsigned long SampleCount);
typedef void (*LADSPA_Set_Run_Adding_Gain_Function)
(LADSPA_Handle Instance,
LADSPA_Data Gain);
typedef void (*LADSPA_Deactivate_Function)
(LADSPA_Handle Instance);
typedef void (*LADSPA_Cleanup_Function)
(LADSPA_Handle Instance);
typedef LADSPA_Data * LADSPA_Data_ptr;
/*****************************************************************************/
#endif
/* EOF */

View File

@@ -1,415 +0,0 @@
/* lofi.cpp
Lo Fi - Simulate low quality audio equipment
Copyright (c) 2001 David A. Bartold
Computer Music Toolkit - a library of LADSPA plugins. Copyright (C)
2000 Richard W.E. Furse. The author may be contacted at
richard@muse.demon.co.uk.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public Licence as
published by the Free Software Foundation; either version 2 of the
Licence, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA. */
/*****************************************************************************/
#include <math.h>
#include <stdlib.h>
#include "cmt.h"
#define PORT_IN_LEFT 0
#define PORT_IN_RIGHT 1
#define PORT_OUT_LEFT 2
#define PORT_OUT_RIGHT 3
#define PORT_CRACKLING 4
#define PORT_OVERLOADING 5
#define PORT_BANDWIDTH 6
#define NUM_PORTS 7
#ifndef PI
#define PI 3.14159265358979
#endif
#ifndef MIN
#define MIN(x,y) ((x)<(y)?(x):(y))
#endif
#ifndef MAX
#define MAX(x,y) ((x)>(y)?(x):(y))
#endif
class Pop
{
public:
float x;
float dx;
float amp;
float pwr;
Pop *next;
Pop (float dx, float amp, float pwr, Pop *next);
~Pop ();
};
Pop::Pop (float _dx,
float _amp,
float _pwr,
Pop *_next)
: x (0.0), dx (_dx), amp (_amp), pwr (_pwr), next (_next)
{
}
Pop::~Pop ()
{
delete next;
}
class Record
{
public:
int rate;
int amount; /* 0 -> 100% */
Pop *pops;
LADSPA_Data process (LADSPA_Data sample);
void setAmount (int _amount);
Record (int sample_rate);
~Record ();
};
Record::Record (int sample_rate)
: rate (sample_rate),
amount (0),
pops (NULL)
{
}
Record::~Record ()
{
delete pops;
}
static Pop *
record_pop_new (Record *record,
Pop *next)
{
return new Pop ((rand () % 1500 + 500.0) / record->rate,
(rand () % 50) / 10000.0,
1.0,
next);
}
static Pop *
record_pop_loud_new (Record *record,
Pop *next)
{
return new Pop ((rand () % 500 + 2500.0) / record->rate,
(rand () % 100) / 400.0 + 0.5,
(rand () % 50) / 20.0,
next);
}
LADSPA_Data
Record::process (LADSPA_Data sample)
{
Pop *pop;
Pop **pop_prev;
/* Add some crackle */
if (rand () % rate < rate * amount / 4000)
pops = record_pop_new (this, pops);
/* Add some loud pops */
if (rand () % (rate * 10) < rate * amount / 400000)
pops = record_pop_loud_new (this, pops);
/* Compute pops */
pop_prev = &pops;
pop = *pop_prev;
while (pop != NULL)
{
if (pop->x >= 0.5)
sample += (pow ((1.0 - pop->x) * 2.0, pop->pwr) - 0.5) * pop->amp;
else
sample += (pow (pop->x * 2.0, pop->pwr) - 0.5) * pop->amp;
pop->x += pop->dx;
if (pop->x > 1.0)
{
*pop_prev = pop->next;
pop->next = NULL;
delete pop;
}
else
pop_prev = &pop->next;
pop = *pop_prev;
}
return sample;
}
void
Record::setAmount (int _amount)
{
amount = _amount;
}
class Compressor
{
public:
int rate;
double amp;
double up;
double down;
float vol;
float clamp_hi;
float clamp_lo;
LADSPA_Data process (LADSPA_Data sample);
void setClamp (float clamp);
Compressor (int sample_rate, float clamp);
};
Compressor::Compressor (int sample_rate, float clamp)
: rate (sample_rate), amp (0.5),
up (1.0 / pow (0.5, 20.0 / sample_rate)),
down (pow (0.5, 50.0 / sample_rate)),
vol (0.5), clamp_hi (clamp), clamp_lo (1.0 / clamp)
{
}
LADSPA_Data
Compressor::process (LADSPA_Data sample)
{
sample *= amp;
if (fabs (sample) > vol)
{
amp *= down;
if (amp < clamp_lo)
amp = clamp_lo;
}
else
{
amp *= up;
if (amp > clamp_hi)
amp = clamp_hi;
}
return sample;
}
void
Compressor::setClamp (float clamp)
{
clamp_hi = clamp;
clamp_lo = 1.0 / clamp;
}
static inline LADSPA_Data
distort (LADSPA_Data in)
{
if (in > 0.0F)
return (in * 1.0F) / (in + 1.0F) * 2.0F;
else
return -(-in * 1.0F) / (-in + 1.0F) * 2.0F;
}
class BandwidthLimit
{
public:
int rate;
float x;
float dx;
void setFreq (float freq);
LADSPA_Data process (LADSPA_Data sample);
BandwidthLimit (int _rate, float _freq);
};
BandwidthLimit::BandwidthLimit (int _rate, float _freq)
: rate (_rate), x (0.0), dx (_freq / _rate)
{
}
LADSPA_Data
BandwidthLimit::process (LADSPA_Data sample)
{
if (sample >= x)
sample = MIN (x + dx, sample);
else
sample = MAX (x - dx, sample);
x = sample;
return sample;
}
void
BandwidthLimit::setFreq (float freq)
{
dx = freq / rate;
}
class LoFi : public CMT_PluginInstance {
Record *record;
Compressor *compressor;
BandwidthLimit *bandwidth_l;
BandwidthLimit *bandwidth_r;
public:
LoFi(const LADSPA_Descriptor *,
unsigned long s_rate)
: CMT_PluginInstance (NUM_PORTS),
record (new Record (s_rate * 2)),
compressor (new Compressor (s_rate * 2, 1.6)),
bandwidth_l (new BandwidthLimit (s_rate, 8000.0)),
bandwidth_r (new BandwidthLimit (s_rate, 8000.0)) {
}
~LoFi() {
delete bandwidth_l;
delete bandwidth_r;
delete compressor;
delete record;
}
static void
activate (LADSPA_Handle Instance) {
LoFi *lofi = (LoFi*) Instance;
lofi->bandwidth_l->setFreq (8000);
lofi->bandwidth_r->setFreq (8000);
lofi->compressor->setClamp (1.6);
lofi->record->setAmount (0);
}
static void
run(LADSPA_Handle Instance,
unsigned long SampleCount) {
LoFi *lofi = (LoFi*) Instance;
unsigned long i;
LADSPA_Data **ports = lofi->m_ppfPorts;
LADSPA_Data clamp;
lofi->bandwidth_l->setFreq (ports[PORT_BANDWIDTH][0]);
lofi->bandwidth_r->setFreq (ports[PORT_BANDWIDTH][0]);
if (ports[PORT_OVERLOADING][0] > 99.0)
clamp = 100.0;
else
clamp = 100.0 / (100.0 - ports[PORT_OVERLOADING][0]);
lofi->compressor->setClamp (clamp);
lofi->record->setAmount ((int) ports[PORT_CRACKLING][0]);
for (i = 0; i < SampleCount; i++)
{
LADSPA_Data sample_l, sample_r;
sample_l = ports[PORT_IN_LEFT][i];
sample_r = ports[PORT_IN_RIGHT][i];
sample_l = lofi->compressor->process (sample_l);
sample_r = lofi->compressor->process (sample_r);
sample_l = lofi->bandwidth_l->process (sample_l);
sample_r = lofi->bandwidth_r->process (sample_r);
sample_l = distort (sample_l);
sample_r = distort (sample_r);
sample_l = lofi->record->process (sample_l);
sample_r = lofi->record->process (sample_r);
ports[PORT_OUT_LEFT][i] = sample_l;
ports[PORT_OUT_RIGHT][i] = sample_r;
}
}
};
static LADSPA_PortDescriptor g_psPortDescriptors[] =
{
LADSPA_PORT_AUDIO | LADSPA_PORT_INPUT,
LADSPA_PORT_AUDIO | LADSPA_PORT_INPUT,
LADSPA_PORT_AUDIO | LADSPA_PORT_OUTPUT,
LADSPA_PORT_AUDIO | LADSPA_PORT_OUTPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT
};
static const char * const g_psPortNames[] =
{
"In (Left)",
"In (Right)",
"Out (Left)",
"Out (Right)",
"Crackling (%)",
"Powersupply Overloading (%)",
"Opamp Bandwidth Limiting (Hz)"
};
static LADSPA_PortRangeHint g_psPortRangeHints[] =
{
/* Hints, Lower bound, Upper bound */
{ 0, 0.0, 0.0 },
{ 0, 0.0, 0.0 },
{ 0, 0.0, 0.0 },
{ 0, 0.0, 0.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW |
LADSPA_HINT_INTEGER, -0.1, 100.1 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 100.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 1.0, 10000.0 }
};
void
initialise_lofi() {
CMT_Descriptor * psDescriptor;
psDescriptor = new CMT_Descriptor
(1227,
"lofi",
0 /* Sorry, this module is not RT capable, run() calls malloc() */,
"Lo Fi",
CMT_MAKER("David A. Bartold"),
CMT_COPYRIGHT("2001", "David A. Bartold"),
NULL,
CMT_Instantiate<LoFi>,
LoFi::activate,
LoFi::run,
NULL,
NULL,
NULL);
for (int i = 0; i < NUM_PORTS; i++)
psDescriptor->addPort(
g_psPortDescriptors[i],
g_psPortNames[i],
g_psPortRangeHints[i].HintDescriptor,
g_psPortRangeHints[i].LowerBound,
g_psPortRangeHints[i].UpperBound);
registerNewPluginDescriptor(psDescriptor);
}

View File

@@ -1,156 +0,0 @@
/* logistic.cpp
A sample-and-hold logistic map control generator
(c) 2002 Nathaniel Virgo
Part of the Computer Music Toolkit - a library of LADSPA plugins.
The Computer Music Toolkit is Copyright (C) 2000-2002
Richard W.E. Furse. The author may be contacted at
richard@muse.demon.co.uk.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public Licence as
published by the Free Software Foundation; either version 2 of the
Licence, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA. */
/*****************************************************************************/
#include <stdlib.h>
/*****************************************************************************/
#include "cmt.h"
#include "pinknoise.h"
#include "utils.h"
/*****************************************************************************/
namespace logistic {
enum {
port_r = 0,
port_frequency = 1,
port_output = 2,
n_ports = 3
};
/** This plugin uses the logistic map to generate periodic or
chaotic control signals. */
class Plugin : public CMT_PluginInstance {
private:
LADSPA_Data sample_rate;
LADSPA_Data x;
unsigned counter;
public:
Plugin(const LADSPA_Descriptor *,
unsigned long s_rate) :
CMT_PluginInstance(n_ports),
sample_rate(s_rate) {
}
~Plugin() {
}
friend void activate(LADSPA_Handle instance);
friend void run(LADSPA_Handle instance,
unsigned long sample_count);
};
void activate(LADSPA_Handle instance) {
Plugin *pp = (Plugin *) instance;
Plugin &p = *pp;
p.x = 0.3; // arbitrary non-zero value.
}
void run(LADSPA_Handle instance,
unsigned long sample_count) {
Plugin *pp = (Plugin *) instance;
Plugin &p = *pp;
LADSPA_Data r = *pp->m_ppfPorts[port_r];
LADSPA_Data frequency = *pp->m_ppfPorts[port_frequency];
LADSPA_Data * out = pp->m_ppfPorts[port_output];
frequency = BOUNDED_ABOVE(frequency,p.sample_rate);
r = BOUNDED_ABOVE(r,4);
unsigned remain = sample_count;
if (frequency > 0) {
while (remain) {
unsigned jump_samples = (remain<p.counter) ? remain : p.counter;
for (unsigned j=0; j<jump_samples; ++j) {
*(out++) = p.x*2-1;
}
p.counter -= jump_samples;
remain -= jump_samples;
if (p.counter==0) {
p.x = r*p.x*(1.0f - p.x);
p.counter = (unsigned)(p.sample_rate/frequency);
}
}
}
else
{
for (unsigned long i=0; i<sample_count; ++i)
*(out++) = p.x;
}
}
void initialise() {
CMT_Descriptor * d = new CMT_Descriptor
(1849,
"logistic",
0,
"Logistic Map Control Generator",
CMT_MAKER("Nathaniel Virgo"),
CMT_COPYRIGHT("2002", "Nathaniel Virgo"),
NULL,
CMT_Instantiate<Plugin>,
activate,
run,
NULL,
NULL,
NULL);
d->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"\"r\" parameter",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_BOUNDED_ABOVE
| LADSPA_HINT_DEFAULT_MAXIMUM),
2.9, 3.9999);
d->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Step frequency",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_BOUNDED_ABOVE
| LADSPA_HINT_SAMPLE_RATE
| LADSPA_HINT_DEFAULT_MIDDLE),
0, 0.001);
d->addPort
(LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
"Output");
registerNewPluginDescriptor(d);
}
} // end of namespace
/*****************************************************************************/
/* EOF */

View File

@@ -1,106 +0,0 @@
/* mixer.cpp
Computer Music Toolkit - a library of LADSPA plugins. Copyright (C)
2000 Richard W.E. Furse. The author may be contacted at
richard@muse.demon.co.uk.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public Licence as
published by the Free Software Foundation; either version 2 of the
Licence, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA. */
/*****************************************************************************/
#include <stdlib.h>
#include <string.h>
/*****************************************************************************/
#include "cmt.h"
/*****************************************************************************/
/* The port numbers for the plugin: */
#define MIXER_INPUT1 0
#define MIXER_INPUT2 1
#define MIXER_OUTPUT 2
/** This plugin adds two signals together to produce a third. */
class SimpleMixer : public CMT_PluginInstance {
public:
SimpleMixer(const LADSPA_Descriptor *,
unsigned long)
: CMT_PluginInstance(3) {
}
friend void runSimpleMixer(LADSPA_Handle Instance,
unsigned long SampleCount);
};
/*****************************************************************************/
void
runSimpleMixer(LADSPA_Handle Instance,
unsigned long SampleCount) {
SimpleMixer * poMixer = (SimpleMixer *)Instance;
LADSPA_Data * pfInput1 = poMixer->m_ppfPorts[MIXER_INPUT1];
LADSPA_Data * pfInput2 = poMixer->m_ppfPorts[MIXER_INPUT2];
LADSPA_Data * pfOutput = poMixer->m_ppfPorts[MIXER_OUTPUT];
for (unsigned long lSampleIndex = 0;
lSampleIndex < SampleCount;
lSampleIndex++)
*(pfOutput++) = *(pfInput1++) + *(pfInput2++);
}
/*****************************************************************************/
void
initialise_mixer() {
CMT_Descriptor * psDescriptor;
psDescriptor = new CMT_Descriptor
(1071,
"mixer",
LADSPA_PROPERTY_HARD_RT_CAPABLE,
"Mixer (Stereo to Mono)",
CMT_MAKER("Richard W.E. Furse"),
CMT_COPYRIGHT("2000", "Richard W.E. Furse"),
NULL,
CMT_Instantiate<SimpleMixer>,
NULL,
runSimpleMixer,
NULL,
NULL,
NULL);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
"Input 1");
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
"Input 2");
psDescriptor->addPort
(LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
"Output");
registerNewPluginDescriptor(psDescriptor);
}
/*****************************************************************************/
/* EOF */

View File

@@ -1,141 +0,0 @@
/* noise.cpp
Computer Music Toolkit - a library of LADSPA plugins. Copyright (C)
2000-2002 Richard W.E. Furse. The author may be contacted at
richard@muse.demon.co.uk.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public Licence as
published by the Free Software Foundation; either version 2 of the
Licence, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA. */
/*****************************************************************************/
#include <stdlib.h>
/*****************************************************************************/
#include "cmt.h"
/*****************************************************************************/
/* The port numbers for the plugin: */
#define NOISE_AMPLITUDE 0
#define NOISE_OUTPUT 1
/** Plugin that provides white noise output. This is provided by
calling rand() repeatedly. */
class WhiteNoise : public CMT_PluginInstance {
private:
LADSPA_Data m_fRunAddingGain;
public:
WhiteNoise(const LADSPA_Descriptor *,
unsigned long)
: CMT_PluginInstance(2) {
}
friend void runWhiteNoise(LADSPA_Handle Instance,
unsigned long SampleCount);
friend void runWhiteNoiseAdding(LADSPA_Handle Instance,
unsigned long SampleCount);
friend void setWhiteNoiseRunAddingGain(LADSPA_Handle Instance,
LADSPA_Data Gain);
};
/*****************************************************************************/
void
runWhiteNoise(LADSPA_Handle Instance,
unsigned long SampleCount) {
WhiteNoise * poNoise = (WhiteNoise *)Instance;
LADSPA_Data fAmplitude = *(poNoise->m_ppfPorts[NOISE_AMPLITUDE]);
LADSPA_Data fScalar = fAmplitude * LADSPA_Data(2.0 / RAND_MAX);
LADSPA_Data * pfOutput = poNoise->m_ppfPorts[NOISE_OUTPUT];
for (unsigned long lSampleIndex = 0;
lSampleIndex < SampleCount;
lSampleIndex++)
*(pfOutput++) = rand() * fScalar - fAmplitude;
}
void
runWhiteNoiseAdding(LADSPA_Handle Instance,
unsigned long SampleCount) {
WhiteNoise * poNoise = (WhiteNoise *)Instance;
LADSPA_Data fAmplitude
= *(poNoise->m_ppfPorts[NOISE_AMPLITUDE]);
LADSPA_Data fScalar
= poNoise->m_fRunAddingGain * fAmplitude * LADSPA_Data(2.0 / RAND_MAX);
LADSPA_Data * pfOutput = poNoise->m_ppfPorts[NOISE_OUTPUT];
for (unsigned long lSampleIndex = 0;
lSampleIndex < SampleCount;
lSampleIndex++)
*(pfOutput++) += rand() * fScalar - fAmplitude;
}
void
setWhiteNoiseRunAddingGain(LADSPA_Handle Instance,
LADSPA_Data Gain) {
}
/*****************************************************************************/
void
initialise_noise() {
CMT_Descriptor * psDescriptor;
psDescriptor = new CMT_Descriptor
(1069,
"noise_source_white",
LADSPA_PROPERTY_HARD_RT_CAPABLE,
"Noise Source (White)",
CMT_MAKER("Richard W.E. Furse"),
CMT_COPYRIGHT("2000-2002", "Richard W.E. Furse"),
NULL,
CMT_Instantiate<WhiteNoise>,
NULL,
runWhiteNoise,
runWhiteNoiseAdding,
setWhiteNoiseRunAddingGain,
NULL);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Amplitude",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_LOGARITHMIC
| LADSPA_HINT_DEFAULT_1),
0,
0);
psDescriptor->addPort
(LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
"Output");
registerNewPluginDescriptor(psDescriptor);
}
/*****************************************************************************/
/* EOF */

View File

@@ -1,260 +0,0 @@
/* null.cpp
Computer Music Toolkit - a library of LADSPA plugins. Copyright (C)
2000 Richard W.E. Furse. The author may be contacted at
richard@muse.demon.co.uk.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public Licence as
published by the Free Software Foundation; either version 2 of the
Licence, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA. */
/*****************************************************************************/
#include <stdlib.h>
#include <string.h>
/*****************************************************************************/
#include "cmt.h"
/*****************************************************************************/
/* The port numbers for the plugin: */
#define NULL_PORT 0
/** This plugin can be used to take care of unwanted connections in a
host's plugin network by generating zero data and audio or
accepting (but ignoring) data and audio. */
class NullPlugin : public CMT_PluginInstance {
public:
NullPlugin(const LADSPA_Descriptor *,
unsigned long)
: CMT_PluginInstance(1) {
}
friend void runNull_Nop(LADSPA_Handle Instance,
unsigned long SampleCount);
friend void runNull_OutputAudio(LADSPA_Handle Instance,
unsigned long SampleCount);
friend void runNull_OutputControl(LADSPA_Handle Instance,
unsigned long SampleCount);
};
/*****************************************************************************/
#define IDENTITY_INPUT 0
#define IDENTITY_OUTPUT 1
/* This plugin passes its input to its output. There are audio and
control varieties. */
class IdentityPlugin : public CMT_PluginInstance {
public:
IdentityPlugin(const LADSPA_Descriptor *,
unsigned long)
: CMT_PluginInstance(2) {
}
friend void runIdentity_Audio(LADSPA_Handle Instance,
unsigned long SampleCount);
friend void runIdentity_Control(LADSPA_Handle Instance,
unsigned long SampleCount);
};
/*****************************************************************************/
void
runNull_Nop(LADSPA_Handle Instance,
unsigned long SampleCount) {
/* Nothing to do. */
}
/*****************************************************************************/
void
runNull_OutputAudio(LADSPA_Handle Instance,
unsigned long SampleCount) {
NullPlugin * poPlugin = (NullPlugin *)Instance;
memset(poPlugin->m_ppfPorts[NULL_PORT],
0,
sizeof(LADSPA_Data) * SampleCount);
}
/*****************************************************************************/
void
runNull_OutputControl(LADSPA_Handle Instance,
unsigned long) {
NullPlugin * poPlugin = (NullPlugin *)Instance;
*(poPlugin->m_ppfPorts[NULL_PORT]) = 0;
}
/*****************************************************************************/
void
runIdentity_Audio(LADSPA_Handle Instance,
unsigned long SampleCount) {
IdentityPlugin * poPlugin = (IdentityPlugin *)Instance;
if (poPlugin->m_ppfPorts[IDENTITY_OUTPUT]
!= poPlugin->m_ppfPorts[IDENTITY_INPUT])
memcpy(poPlugin->m_ppfPorts[IDENTITY_OUTPUT],
poPlugin->m_ppfPorts[IDENTITY_INPUT],
sizeof(LADSPA_Data) * SampleCount);
}
/*****************************************************************************/
void
runIdentity_Control(LADSPA_Handle Instance,
unsigned long) {
IdentityPlugin * poPlugin = (IdentityPlugin *)Instance;
*(poPlugin->m_ppfPorts[IDENTITY_OUTPUT])
= *(poPlugin->m_ppfPorts[IDENTITY_INPUT]);
}
/*****************************************************************************/
void
initialise_null() {
CMT_Descriptor * psDescriptor;
psDescriptor = new CMT_Descriptor
(1083,
"null_ci",
LADSPA_PROPERTY_HARD_RT_CAPABLE,
"Null (Control Input)",
CMT_MAKER("Richard W.E. Furse"),
CMT_COPYRIGHT("2000", "Richard W.E. Furse"),
NULL,
CMT_Instantiate<NullPlugin>,
NULL,
runNull_Nop,
NULL,
NULL,
NULL);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Input");
registerNewPluginDescriptor(psDescriptor);
psDescriptor = new CMT_Descriptor
(1084,
"null_ai",
LADSPA_PROPERTY_HARD_RT_CAPABLE,
"Null (Audio Input)",
CMT_MAKER("Richard W.E. Furse"),
CMT_COPYRIGHT("2000", "Richard W.E. Furse"),
NULL,
CMT_Instantiate<NullPlugin>,
NULL,
runNull_Nop,
NULL,
NULL,
NULL);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
"Input");
registerNewPluginDescriptor(psDescriptor);
psDescriptor = new CMT_Descriptor
(1085,
"null_co",
LADSPA_PROPERTY_HARD_RT_CAPABLE,
"Null (Control Output)",
CMT_MAKER("Richard W.E. Furse"),
CMT_COPYRIGHT("2000", "Richard W.E. Furse"),
NULL,
CMT_Instantiate<NullPlugin>,
NULL,
runNull_OutputControl,
NULL,
NULL,
NULL);
psDescriptor->addPort
(LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL,
"Output");
registerNewPluginDescriptor(psDescriptor);
psDescriptor = new CMT_Descriptor
(1086,
"null_ao",
LADSPA_PROPERTY_HARD_RT_CAPABLE,
"Null (Audio Output)",
CMT_MAKER("Richard W.E. Furse"),
CMT_COPYRIGHT("2000", "Richard W.E. Furse"),
NULL,
CMT_Instantiate<NullPlugin>,
NULL,
runNull_OutputAudio,
NULL,
NULL,
NULL);
psDescriptor->addPort
(LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
"Output");
registerNewPluginDescriptor(psDescriptor);
psDescriptor = new CMT_Descriptor
(1098,
"identity_audio",
LADSPA_PROPERTY_HARD_RT_CAPABLE,
"Identity (Audio)",
CMT_MAKER("Richard W.E. Furse"),
CMT_COPYRIGHT("2000", "Richard W.E. Furse"),
NULL,
CMT_Instantiate<IdentityPlugin>,
NULL,
runIdentity_Audio,
NULL,
NULL,
NULL);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
"Input");
psDescriptor->addPort
(LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
"Output");
registerNewPluginDescriptor(psDescriptor);
psDescriptor = new CMT_Descriptor
(1099,
"identity_control",
LADSPA_PROPERTY_HARD_RT_CAPABLE,
"Identity (Control)",
CMT_MAKER("Richard W.E. Furse"),
CMT_COPYRIGHT("2000", "Richard W.E. Furse"),
NULL,
CMT_Instantiate<IdentityPlugin>,
NULL,
runIdentity_Control,
NULL,
NULL,
NULL);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Input");
psDescriptor->addPort
(LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL,
"Output");
registerNewPluginDescriptor(psDescriptor);
}
/*****************************************************************************/
/* EOF */

View File

@@ -1,375 +0,0 @@
/* organ.cpp
Organ - Additive Organ Synthesizer Voice
Copyright (c) 1999, 2000 David A. Bartold
Computer Music Toolkit - a library of LADSPA plugins. Copyright (C)
2000 Richard W.E. Furse. The author may be contacted at
richard@muse.demon.co.uk.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public Licence as
published by the Free Software Foundation; either version 2 of the
Licence, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA. */
/*****************************************************************************/
#include <math.h>
#include <stdlib.h>
#include "cmt.h"
#define PORT_OUT 0
#define PORT_GATE 1
#define PORT_VELOCITY 2
#define PORT_FREQ 3
#define PORT_BRASS 4
#define PORT_FLUTE 5
#define PORT_REED 6
#define PORT_HARM0 7
#define PORT_HARM1 8
#define PORT_HARM2 9
#define PORT_HARM3 10
#define PORT_HARM4 11
#define PORT_HARM5 12
#define PORT_ATTACK_LO 13
#define PORT_DECAY_LO 14
#define PORT_SUSTAIN_LO 15
#define PORT_RELEASE_LO 16
#define PORT_ATTACK_HI 17
#define PORT_DECAY_HI 18
#define PORT_SUSTAIN_HI 19
#define PORT_RELEASE_HI 20
#define NUM_PORTS 21
#define RESOLUTION 16384
#ifndef PI
#define PI 3.14159265358979
#endif
typedef struct Envelope
{
int envelope_decay;
double envelope;
Envelope () : envelope_decay (0), envelope (0.0) {}
} Envelope;
static LADSPA_Data *g_sine_table;
static LADSPA_Data *g_triangle_table;
static LADSPA_Data *g_pulse_table;
static int ref_count;
class Organ : CMT_PluginInstance
{
LADSPA_Data sample_rate;
Envelope env0;
Envelope env1;
unsigned long harm0_accum;
unsigned long harm1_accum;
unsigned long harm2_accum;
unsigned long harm3_accum;
unsigned long harm4_accum;
unsigned long harm5_accum;
public:
Organ(const LADSPA_Descriptor * Descriptor,
unsigned long SampleRate)
: CMT_PluginInstance(NUM_PORTS),
sample_rate(SampleRate),
harm0_accum(0), harm1_accum(0),
harm2_accum(0), harm3_accum(0),
harm4_accum(0), harm5_accum(0) {
if (ref_count++ == 0)
{
int size = RESOLUTION;
int half = size / 2;
int slope = size / 10;
int i;
/* Initialize sine table. */
g_sine_table = new LADSPA_Data[size];
for (i = 0; i < size; i++)
g_sine_table[i] = sin ((i * 2.0 * PI) / size) / 6.0;
/* Initialize triangle table. */
g_triangle_table = new LADSPA_Data[size];
for (i = 0; i < half; i++)
g_triangle_table[i] = (4.0 / size * i - 1.0) / 6.0;
for (; i < size; i++)
g_triangle_table[i] = (4.0 / size * (size - i) - 1.0) / 6.0;
/* Initialize pulse table. */
g_pulse_table = new LADSPA_Data[size];
for (i = 0; i < slope; i++)
g_pulse_table[i] = ((double) -i) / slope / 6.0;
for (; i < half - slope; i++)
g_pulse_table[i] = -1.0 / 6.0;
for (; i < half + slope; i++)
g_pulse_table[i] = ((double) i - half) / slope / 6.0;
for (; i < size - slope; i++)
g_pulse_table[i] = 1.0 / 6.0;
for (; i < size; i++)
g_pulse_table[i] = ((double) size - i) / slope / 6.0;
}
}
~Organ () {
if (--ref_count == 0)
{
delete[] g_pulse_table;
delete[] g_triangle_table;
delete[] g_sine_table;
}
}
static inline LADSPA_Data
table_pos (LADSPA_Data *table,
unsigned long freq_256,
unsigned long *accum) {
*accum += freq_256;
while (*accum >= RESOLUTION * 256)
*accum -= RESOLUTION * 256;
return table[*accum >> 8];
}
static inline LADSPA_Data
envelope(Envelope *env,
int gate,
LADSPA_Data attack,
LADSPA_Data decay,
LADSPA_Data sustain,
LADSPA_Data release)
{
if (gate)
if (env->envelope_decay == 0)
{
env->envelope += (1.0F - env->envelope) * attack;
if (env->envelope >= 0.95F)
env->envelope_decay = 1;
}
else
env->envelope += (sustain - env->envelope) * decay;
else
env->envelope += -env->envelope * release;
return env->envelope;
}
static inline LADSPA_Data
multiplier(Organ *organ,
LADSPA_Data value) {
return 1.0 - pow (0.05, 1.0 / (organ->sample_rate * value));
}
static void
activate(LADSPA_Handle Instance) {
Organ *organ = (Organ*) Instance;
organ->env0.envelope_decay = 0;
organ->env0.envelope = 0.0;
organ->env1.envelope_decay = 0;
organ->env1.envelope = 0.0;
organ->harm0_accum = 0;
organ->harm1_accum = 0;
organ->harm2_accum = 0;
organ->harm3_accum = 0;
organ->harm4_accum = 0;
organ->harm5_accum = 0;
}
static void
run(LADSPA_Handle Instance,
unsigned long SampleCount) {
Organ *organ = (Organ*) Instance;
unsigned long i;
LADSPA_Data **ports;
LADSPA_Data *sine_table;
LADSPA_Data *reed_table;
LADSPA_Data *flute_table;
unsigned long freq_256;
unsigned long freq_256_harm0, freq_256_harm1;
unsigned long freq_256_harm2, freq_256_harm3;
unsigned long freq_256_harm4, freq_256_harm5;
double attack0, decay0, release0;
double attack1, decay1, release1;
int gate;
ports = organ->m_ppfPorts;
gate = (*ports[PORT_GATE] > 0.0);
if (gate == 0)
{
organ->env0.envelope_decay = 0;
organ->env1.envelope_decay = 0;
}
sine_table = g_sine_table;
reed_table = (*ports[PORT_REED] > 0.0) ? g_pulse_table : sine_table;
flute_table = (*ports[PORT_FLUTE] > 0.0) ? g_triangle_table : sine_table;
freq_256 = (int) (*ports[PORT_FREQ] *
((double) RESOLUTION) /
organ->sample_rate * 256.0);
freq_256_harm0 = freq_256 / 2;
freq_256_harm1 = freq_256;
attack0 = multiplier (organ, *ports[PORT_ATTACK_LO]);
decay0 = multiplier (organ, *ports[PORT_DECAY_LO]);
release0 = multiplier (organ, *ports[PORT_RELEASE_LO]);
attack1 = multiplier (organ, *ports[PORT_ATTACK_HI]);
decay1 = multiplier (organ, *ports[PORT_DECAY_HI]);
release1 = multiplier (organ, *ports[PORT_RELEASE_HI]);
if (*ports[PORT_BRASS] > 0.0)
{
freq_256_harm2 = freq_256 * 2;
freq_256_harm3 = freq_256_harm2 * 2;
freq_256_harm4 = freq_256_harm3 * 2;
freq_256_harm5 = freq_256_harm4 * 2;
for (i = 0; i < SampleCount; i++)
ports[PORT_OUT][i] =
((table_pos (sine_table, freq_256_harm0, &organ->harm0_accum) * *ports[PORT_HARM0]
+ table_pos (sine_table, freq_256_harm1, &organ->harm1_accum) * *ports[PORT_HARM1]
+ table_pos (reed_table, freq_256_harm2, &organ->harm2_accum) * *ports[PORT_HARM2])
* envelope (&organ->env0, gate, attack0, decay0, *ports[PORT_SUSTAIN_LO], release0)
+ (table_pos (sine_table, freq_256_harm3, &organ->harm3_accum) * *ports[PORT_HARM3]
+ table_pos (flute_table, freq_256_harm4, &organ->harm4_accum) * *ports[PORT_HARM4]
+ table_pos (flute_table, freq_256_harm5, &organ->harm5_accum) * *ports[PORT_HARM5])
* envelope (&organ->env1, gate, attack1, decay1, *ports[PORT_SUSTAIN_HI], release1)) * *ports[PORT_VELOCITY];
}
else
{
freq_256_harm2 = freq_256 * 3 / 2;
freq_256_harm3 = freq_256 * 2;
freq_256_harm4 = freq_256 * 3;
freq_256_harm5 = freq_256_harm3 * 2;
for (i = 0; i < SampleCount; i++)
ports[PORT_OUT][i] =
((table_pos (sine_table, freq_256_harm0, &organ->harm0_accum) * *ports[PORT_HARM0]
+ table_pos (sine_table, freq_256_harm1, &organ->harm1_accum) * *ports[PORT_HARM1]
+ table_pos (sine_table, freq_256_harm2, &organ->harm2_accum) * *ports[PORT_HARM2])
* envelope (&organ->env0, gate, attack0, decay0, *ports[PORT_SUSTAIN_LO], release0)
+ (table_pos (reed_table, freq_256_harm3, &organ->harm3_accum) * *ports[PORT_HARM3]
+ table_pos (sine_table, freq_256_harm4, &organ->harm4_accum) * *ports[PORT_HARM4]
+ table_pos (flute_table, freq_256_harm5, &organ->harm5_accum) * *ports[PORT_HARM5])
* envelope (&organ->env1, gate, attack1, decay1, *ports[PORT_SUSTAIN_HI], release1)) * *ports[PORT_VELOCITY];
}
}
};
static LADSPA_PortDescriptor g_psPortDescriptors[] =
{
LADSPA_PORT_AUDIO | LADSPA_PORT_OUTPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT
};
static const char * const g_psPortNames[] =
{
"Out",
"Gate",
"Velocity",
"Frequency (Hz)",
"Brass", "Reed", "Flute",
"16th Harmonic", "8th Harmonic",
"5 1/3rd Harmonic", "4th Harmonic",
"2 2/3rd Harmonic", "2nd Harmonic",
"Attack Lo (Secs)", "Decay Lo (Secs)", "Sustain Lo (Level)", "Release Lo (Secs)",
"Attack Hi (Secs)", "Decay Hi (Secs)", "Sustain Hi (Level)", "Release Hi (Secs)",
};
static LADSPA_PortRangeHint g_psPortRangeHints[] =
{
/* Hints, Lower bound, Upper bound */
{ 0, 0.0, 0.0 },
{ LADSPA_HINT_TOGGLED, 0.0, 0.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 20000.0 },
{ LADSPA_HINT_TOGGLED, 0.0, 0.0 },
{ LADSPA_HINT_TOGGLED, 0.0, 0.0 },
{ LADSPA_HINT_TOGGLED, 0.0, 0.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.01, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.01, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.00, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.01, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.01, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.01, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.00, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.01, 1.0 }
};
void
initialise_organ() {
CMT_Descriptor * psDescriptor;
psDescriptor = new CMT_Descriptor
(1222,
"organ",
LADSPA_PROPERTY_HARD_RT_CAPABLE,
"Organ",
CMT_MAKER("David A. Bartold"),
CMT_COPYRIGHT("1999, 2000", "David A. Bartold"),
NULL,
CMT_Instantiate<Organ>,
Organ::activate,
Organ::run,
NULL,
NULL,
NULL);
for (int i = 0; i < NUM_PORTS; i++)
psDescriptor->addPort(
g_psPortDescriptors[i],
g_psPortNames[i],
g_psPortRangeHints[i].HintDescriptor,
g_psPortRangeHints[i].LowerBound,
g_psPortRangeHints[i].UpperBound);
registerNewPluginDescriptor(psDescriptor);
}

View File

@@ -1,371 +0,0 @@
/* peak.cpp
Computer Music Toolkit - a library of LADSPA plugins. Copyright (C)
2000-2002 Richard W.E. Furse. The author may be contacted at
richard@muse.demon.co.uk.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public Licence as
published by the Free Software Foundation; either version 2 of the
Licence, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA. */
/*****************************************************************************/
#include <math.h>
#include <stdlib.h>
#include <string.h>
/*****************************************************************************/
#include "cmt.h"
#include "utils.h"
/*****************************************************************************/
#define ET_INPUT 0
#define ET_OUTPUT 1
#define ET_FILTER 2
/** This class is used to provide plugins that perform envelope
tracking. Peak and RMS are supported and smoothed or smoothed
maximum approaches are available. */
class Tracker : public CMT_PluginInstance {
private:
LADSPA_Data m_fState;
LADSPA_Data m_fSampleRate;
public:
Tracker(const LADSPA_Descriptor *,
unsigned long lSampleRate)
: CMT_PluginInstance(3),
m_fSampleRate(LADSPA_Data(lSampleRate)) {
}
friend void activateTracker(void * pvHandle);
friend void runEnvelopeTracker_Peak(LADSPA_Handle Instance,
unsigned long SampleCount);
friend void runEnvelopeTracker_RMS(LADSPA_Handle Instance,
unsigned long SampleCount);
friend void runEnvelopeTracker_MaxPeak(LADSPA_Handle Instance,
unsigned long SampleCount);
friend void runEnvelopeTracker_MaxRMS(LADSPA_Handle Instance,
unsigned long SampleCount);
};
/** This class provides a simple peak monitor that records the highest
signal peak present ever. It can be useful to identify clipping
cases. */
class PeakMonitor : public CMT_PluginInstance {
private:
LADSPA_Data m_fState;
public:
PeakMonitor(const LADSPA_Descriptor *,
unsigned long lSampleRate)
: CMT_PluginInstance(2) {
}
friend void activatePeakMonitor(void * pvHandle);
friend void runPeakMonitor(LADSPA_Handle Instance,
unsigned long SampleCount);
};
/*****************************************************************************/
void
activateTracker(void * pvHandle) {
((Tracker *)pvHandle)->m_fState = 0;
}
/*****************************************************************************/
void
activatePeakMonitor(void * pvHandle) {
((PeakMonitor *)pvHandle)->m_fState = 0;
}
/*****************************************************************************/
void
runEnvelopeTracker_Peak(LADSPA_Handle Instance,
unsigned long SampleCount) {
Tracker * poProcessor = (Tracker *)Instance;
LADSPA_Data * pfInput = poProcessor->m_ppfPorts[ET_INPUT];
LADSPA_Data fDrag = *(poProcessor->m_ppfPorts[ET_FILTER]);
LADSPA_Data fOneMinusDrag = 1 - fDrag;
LADSPA_Data &rfState = poProcessor->m_fState;
for (unsigned long lSampleIndex = 0;
lSampleIndex < SampleCount;
lSampleIndex++) {
LADSPA_Data fInput = *(pfInput++);
LADSPA_Data fEnvelopeTarget = fabs(fInput);
rfState = rfState * fDrag + fEnvelopeTarget * fOneMinusDrag;
}
*(poProcessor->m_ppfPorts[ET_OUTPUT]) = rfState;
}
/*****************************************************************************/
void
runEnvelopeTracker_RMS(LADSPA_Handle Instance,
unsigned long SampleCount) {
Tracker * poProcessor = (Tracker *)Instance;
LADSPA_Data * pfInput = poProcessor->m_ppfPorts[ET_INPUT];
LADSPA_Data fDrag = *(poProcessor->m_ppfPorts[ET_FILTER]);
LADSPA_Data fOneMinusDrag = 1 - fDrag;
LADSPA_Data &rfState = poProcessor->m_fState;
for (unsigned long lSampleIndex = 0;
lSampleIndex < SampleCount;
lSampleIndex++) {
LADSPA_Data fInput = *(pfInput++);
LADSPA_Data fEnvelopeTarget = fInput * fInput;
rfState = rfState * fDrag + fEnvelopeTarget * fOneMinusDrag;
}
*(poProcessor->m_ppfPorts[ET_OUTPUT]) = sqrt(rfState);
}
/*****************************************************************************/
void
runEnvelopeTracker_MaxPeak(LADSPA_Handle Instance,
unsigned long SampleCount) {
Tracker * poProcessor = (Tracker *)Instance;
LADSPA_Data * pfInput = poProcessor->m_ppfPorts[ET_INPUT];
LADSPA_Data fDrag = calculate60dBDrag(*(poProcessor->m_ppfPorts[ET_FILTER]),
poProcessor->m_fSampleRate);
LADSPA_Data &rfState = poProcessor->m_fState;
for (unsigned long lSampleIndex = 0;
lSampleIndex < SampleCount;
lSampleIndex++) {
LADSPA_Data fInput = *(pfInput++);
LADSPA_Data fEnvelopeTarget = fabs(fInput);
if (fEnvelopeTarget > rfState)
rfState = fEnvelopeTarget;
else {
rfState *= fDrag;
if (fEnvelopeTarget > rfState)
rfState = fEnvelopeTarget;
}
}
*(poProcessor->m_ppfPorts[ET_OUTPUT]) = rfState;
}
/*****************************************************************************/
void
runEnvelopeTracker_MaxRMS(LADSPA_Handle Instance,
unsigned long SampleCount) {
Tracker * poProcessor = (Tracker *)Instance;
LADSPA_Data * pfInput = poProcessor->m_ppfPorts[ET_INPUT];
LADSPA_Data fDrag = calculate60dBDrag(*(poProcessor->m_ppfPorts[ET_FILTER]),
poProcessor->m_fSampleRate);
LADSPA_Data &rfState = poProcessor->m_fState;
for (unsigned long lSampleIndex = 0;
lSampleIndex < SampleCount;
lSampleIndex++) {
LADSPA_Data fInput = *(pfInput++);
LADSPA_Data fEnvelopeTarget = fInput * fInput;
if (fEnvelopeTarget > rfState)
rfState = fEnvelopeTarget;
else {
rfState *= fDrag;
if (fEnvelopeTarget > rfState)
rfState = fEnvelopeTarget;
}
}
*(poProcessor->m_ppfPorts[ET_OUTPUT]) = sqrt(rfState);
}
/*****************************************************************************/
void
runPeakMonitor(LADSPA_Handle Instance,
unsigned long SampleCount) {
PeakMonitor * poProcessor = (PeakMonitor *)Instance;
LADSPA_Data * pfInput = poProcessor->m_ppfPorts[ET_INPUT];
LADSPA_Data &rfState = poProcessor->m_fState;
for (unsigned long lSampleIndex = 0;
lSampleIndex < SampleCount;
lSampleIndex++) {
LADSPA_Data fInput = *(pfInput++);
LADSPA_Data fEnvelopeTarget = fabs(fInput);
if (rfState < fEnvelopeTarget)
rfState = fEnvelopeTarget;
}
*(poProcessor->m_ppfPorts[ET_OUTPUT]) = rfState;
}
/*****************************************************************************/
void
initialise_peak() {
CMT_Descriptor * psDescriptor;
psDescriptor = new CMT_Descriptor
(1078,
"track_peak",
LADSPA_PROPERTY_HARD_RT_CAPABLE,
"Envelope Tracker (Peak)",
CMT_MAKER("Richard W.E. Furse"),
CMT_COPYRIGHT("2000-2002", "Richard W.E. Furse"),
NULL,
CMT_Instantiate<Tracker>,
activateTracker,
runEnvelopeTracker_Peak,
NULL,
NULL,
NULL);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
"Input");
psDescriptor->addPort
(LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL,
"Output",
LADSPA_HINT_BOUNDED_BELOW,
0);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Smoothing Factor",
LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE,
0,
1);
registerNewPluginDescriptor(psDescriptor);
psDescriptor = new CMT_Descriptor
(1079,
"track_rms",
LADSPA_PROPERTY_HARD_RT_CAPABLE,
"Envelope Tracker (RMS)",
CMT_MAKER("Richard W.E. Furse"),
CMT_COPYRIGHT("2000-2002", "Richard W.E. Furse"),
NULL,
CMT_Instantiate<Tracker>,
activateTracker,
runEnvelopeTracker_RMS,
NULL,
NULL,
NULL);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
"Input");
psDescriptor->addPort
(LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL,
"Output",
LADSPA_HINT_BOUNDED_BELOW,
0);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Smoothing Factor",
LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE,
0,
1);
registerNewPluginDescriptor(psDescriptor);
psDescriptor = new CMT_Descriptor
(1080,
"track_max_peak",
LADSPA_PROPERTY_HARD_RT_CAPABLE,
"Envelope Tracker (Maximum Peak)",
CMT_MAKER("Richard W.E. Furse"),
CMT_COPYRIGHT("2000-2002", "Richard W.E. Furse"),
NULL,
CMT_Instantiate<Tracker>,
activateTracker,
runEnvelopeTracker_MaxPeak,
NULL,
NULL,
NULL);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
"Input");
psDescriptor->addPort
(LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL,
"Output",
LADSPA_HINT_BOUNDED_BELOW,
0);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Envelope Forgetting Factor (s/60dB)",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_DEFAULT_MAXIMUM),
0,
10);
registerNewPluginDescriptor(psDescriptor);
psDescriptor = new CMT_Descriptor
(1081,
"track_max_rms",
LADSPA_PROPERTY_HARD_RT_CAPABLE,
"Envelope Tracker (Maximum RMS)",
CMT_MAKER("Richard W.E. Furse"),
CMT_COPYRIGHT("2000-2002", "Richard W.E. Furse"),
NULL,
CMT_Instantiate<Tracker>,
activateTracker,
runEnvelopeTracker_MaxRMS,
NULL,
NULL,
NULL);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
"Input");
psDescriptor->addPort
(LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL,
"Output",
LADSPA_HINT_BOUNDED_BELOW,
0);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Envelope Forgetting Factor (s/60dB)",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_DEFAULT_MAXIMUM),
0,
10);
registerNewPluginDescriptor(psDescriptor);
psDescriptor = new CMT_Descriptor
(1082,
"peak",
LADSPA_PROPERTY_HARD_RT_CAPABLE,
"Peak Monitor",
CMT_MAKER("Richard W.E. Furse"),
CMT_COPYRIGHT("2000", "Richard W.E. Furse"),
NULL,
CMT_Instantiate<PeakMonitor>,
activatePeakMonitor,
runPeakMonitor,
NULL,
NULL,
NULL);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
"Input");
psDescriptor->addPort
(LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL,
"Peak",
LADSPA_HINT_BOUNDED_BELOW,
0);
registerNewPluginDescriptor(psDescriptor);
}
/*****************************************************************************/
/* EOF */

View File

@@ -1,465 +0,0 @@
/* phasemod.cpp
Phase Modulated Voice - Phase Modulation synthesizer voice
Copyright (c) 2001 David A. Bartold
Computer Music Toolkit - a library of LADSPA plugins. Copyright (C)
2000 Richard W.E. Furse. The author may be contacted at
richard@muse.demon.co.uk.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public Licence as
published by the Free Software Foundation; either version 2 of the
Licence, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA. */
/*****************************************************************************/
#include <math.h>
#include <stdlib.h>
#include "cmt.h"
#define PORT_OUT 0
#define PORT_GATE 1
#define PORT_VELOCITY 2
#define PORT_FREQ 3
#define PORT_DCO_MODULATION 4
#define PORT_DCO_OCTAVE 5
#define PORT_DCO_WAVEFORM 6
#define PORT_DCO_ATTACK 7
#define PORT_DCO_DECAY 8
#define PORT_DCO_SUSTAIN 9
#define PORT_DCO_RELEASE 10
#define DCO_MULTIPLIER 7
#define NUM_PORTS 46
#ifndef PI
#define PI 3.14159265358979F
#endif
typedef struct Envelope
{
int envelope_decay;
LADSPA_Data envelope;
Envelope () : envelope_decay (0), envelope (0.0) {}
} Envelope;
class PhaseMod : public CMT_PluginInstance
{
LADSPA_Data sample_rate;
int trigger;
Envelope dco_env[6];
LADSPA_Data dco_accum[6];
public:
PhaseMod(const LADSPA_Descriptor * Descriptor,
unsigned long SampleRate)
: CMT_PluginInstance(NUM_PORTS),
sample_rate (SampleRate),
trigger (0) {
int i;
for (i = 0; i < 6; i++)
dco_accum[i] = 0.0;
}
~PhaseMod () {
}
static inline LADSPA_Data
tri(LADSPA_Data x) {
if (x > 0.75F)
x = x - 1.0F;
else if (x > 0.25F)
x = 0.5F - x;
return x * 4.0F;
}
static inline LADSPA_Data
envelope(Envelope *env,
int gate,
LADSPA_Data attack,
LADSPA_Data decay,
LADSPA_Data sustain,
LADSPA_Data release)
{
if (gate)
if (env->envelope_decay == 0)
{
env->envelope += (1.0F - env->envelope) * attack;
if (env->envelope >= 0.95F)
env->envelope_decay = 1;
}
else
env->envelope += (sustain - env->envelope) * decay;
else
env->envelope += -env->envelope * release;
return env->envelope;
}
static void
activate(LADSPA_Handle Instance) {
PhaseMod *phasemod = (PhaseMod*) Instance;
int i;
phasemod->trigger = 0;
for (i = 0; i < 6; i++)
{
phasemod->dco_env[i].envelope_decay = 0;
phasemod->dco_env[i].envelope = 0.0;
phasemod->dco_accum[i] = 0.0;
}
}
static inline LADSPA_Data
osc(int waveform,
LADSPA_Data inc,
LADSPA_Data phasemod,
LADSPA_Data *accum) {
LADSPA_Data pos;
*accum += inc;
while (*accum >= 1.0F)
*accum -= 1.0F;
pos = *accum + phasemod;
while (pos < 0.0F) pos += 1.0F;
while (pos > 1.0F) pos -= 1.0F;
/* 0 = Sine wave */
if (waveform == 0)
return sin (pos * 2.0 * PI);
/* 1 = Triangle wave */
else if (waveform == 1)
return tri (pos);
/* 2 = Square wave */
else if (waveform == 2)
return (pos > 0.5) ? 1.0F : -1.0F;
/* 3 = Sawtooth wave */
else if (waveform == 3)
return pos * 2.0F - 1.0F;
/* 4 = Fullwave Rectified Sine wave */
else if (waveform == 4)
return fabs (pos * PI);
/* 5 = Static */
else
return (rand () & 1) ? -1.0F : 1.0F;
}
static LADSPA_Data
calc_inc(LADSPA_Data oct,
LADSPA_Data freq,
LADSPA_Data sample_rate) {
return pow (2.0, oct) * freq / sample_rate;
}
static inline LADSPA_Data
multiplier(PhaseMod *phasemod,
LADSPA_Data value) {
return 1.0 - pow (0.05, 1.0 / (phasemod->sample_rate * value));
}
static void
run(LADSPA_Handle Instance,
unsigned long SampleCount) {
PhaseMod *phasemod = (PhaseMod*) Instance;
unsigned long i, j;
int gate;
int waveform[6];
int store[6];
LADSPA_Data inc[6];
LADSPA_Data attack[6];
LADSPA_Data decay[6];
LADSPA_Data release[6];
LADSPA_Data **ports;
LADSPA_Data vol;
ports = phasemod->m_ppfPorts;
gate = (*ports[PORT_GATE] > 0.0);
if (gate == 1 && phasemod->trigger == 0)
for (i = 0; i < 6; i++)
phasemod->dco_env[i].envelope_decay = 0;
phasemod->trigger = gate;
for (i = 0; i < 6; i++)
{
int offset = DCO_MULTIPLIER * i;
waveform[i] = (int) *ports[PORT_DCO_WAVEFORM + offset];
inc[i] = calc_inc (*ports[PORT_DCO_OCTAVE + offset],
*ports[PORT_FREQ],
phasemod->sample_rate);
attack[i] = multiplier (phasemod, *ports[PORT_DCO_ATTACK + offset]);
decay[i] = multiplier (phasemod, *ports[PORT_DCO_DECAY + offset]);
release[i] = multiplier (phasemod, *ports[PORT_DCO_RELEASE + offset]);
}
j = 1;
for (i = 0; i < 5; i++)
if (*ports[PORT_DCO_MODULATION + (i + 1) * DCO_MULTIPLIER] < 0.0001)
store[i] = 1, j++;
else
store[i] = 0;
store[5] = 1;
vol = 1.0 / j;
for (i = 0; i < SampleCount; i++)
{
LADSPA_Data sample;
LADSPA_Data prev;
sample = 0.0;
prev = 1.0;
for (j = 0; j < 6; j++)
{
int offset = DCO_MULTIPLIER * j;
prev =
envelope (&phasemod->dco_env[j],
gate, attack[j], decay[j],
*ports[PORT_DCO_SUSTAIN + offset], release[j]) *
osc (waveform[j], inc[j],
prev * *ports[PORT_DCO_MODULATION + offset],
&phasemod->dco_accum[j]) *
*ports[PORT_VELOCITY];
if (store[j])
sample += prev;
}
ports[PORT_OUT][i] = sample * vol;
}
}
};
static LADSPA_PortDescriptor g_psPortDescriptors[] =
{
LADSPA_PORT_AUDIO | LADSPA_PORT_OUTPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT
};
static const char * const g_psPortNames[] =
{
"Out",
"Gate",
"Velocity",
"Frequency (Hz)",
"DCO1 Modulation",
"DCO1 Octave",
"DCO1 Waveform",
"DCO1 Attack",
"DCO1 Decay",
"DCO1 Sustain",
"DCO1 Release",
"DCO2 Modulation",
"DCO2 Octave",
"DCO2 Waveform",
"DCO2 Attack",
"DCO2 Decay",
"DCO2 Sustain",
"DCO2 Release",
"DCO3 Modulation",
"DCO3 Octave",
"DCO3 Waveform",
"DCO3 Attack",
"DCO3 Decay",
"DCO3 Sustain",
"DCO3 Release",
"DCO4 Modulation",
"DCO4 Octave",
"DCO4 Waveform",
"DCO4 Attack",
"DCO4 Decay",
"DCO4 Sustain",
"DCO4 Release",
"DCO5 Modulation",
"DCO5 Octave",
"DCO5 Waveform",
"DCO5 Attack",
"DCO5 Decay",
"DCO5 Sustain",
"DCO5 Release",
"DCO6 Modulation",
"DCO6 Octave",
"DCO6 Waveform",
"DCO6 Attack",
"DCO6 Decay",
"DCO6 Sustain",
"DCO6 Release"
};
static LADSPA_PortRangeHint g_psPortRangeHints[] =
{
/* Hints, Lower bound, Upper bound */
{ 0, 0.0, 0.0 },
{ LADSPA_HINT_TOGGLED, 0.0, 0.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 20000.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, -2.0, 2.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW |
LADSPA_HINT_INTEGER, -0.1, 5.1 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.01, 8.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.01, 8.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.01, 8.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, -2.0, 2.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW |
LADSPA_HINT_INTEGER, -0.1, 5.1 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.01, 8.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.01, 8.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.01, 8.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, -2.0, 2.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW |
LADSPA_HINT_INTEGER, -0.1, 5.1 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.01, 8.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.01, 8.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.01, 8.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, -2.0, 2.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW |
LADSPA_HINT_INTEGER, -0.1, 5.1 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.01, 8.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.01, 8.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.01, 8.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, -2.0, 2.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW |
LADSPA_HINT_INTEGER, -0.1, 5.1 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.01, 8.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.01, 8.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.01, 8.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, -2.0, 2.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW |
LADSPA_HINT_INTEGER, -0.1, 5.1 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.01, 8.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.01, 8.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.01, 8.0 }
};
void
initialise_phasemod() {
CMT_Descriptor * psDescriptor;
psDescriptor = new CMT_Descriptor
(1226,
"phasemod",
LADSPA_PROPERTY_HARD_RT_CAPABLE,
"Phase Modulated Voice",
CMT_MAKER("David A. Bartold"),
CMT_COPYRIGHT("2001", "David A. Bartold"),
NULL,
CMT_Instantiate<PhaseMod>,
PhaseMod::activate,
PhaseMod::run,
NULL,
NULL,
NULL);
for (int i = 0; i < NUM_PORTS; i++)
psDescriptor->addPort(
g_psPortDescriptors[i],
g_psPortNames[i],
g_psPortRangeHints[i].HintDescriptor,
g_psPortRangeHints[i].LowerBound,
g_psPortRangeHints[i].UpperBound);
registerNewPluginDescriptor(psDescriptor);
}

View File

@@ -1,245 +0,0 @@
/* pink.cpp
Interpolated pink noise plugins for use as control signals.
(c) 2002 Nathaniel Virgo
Computer Music Toolkit - a library of LADSPA plugins. Copyright (C)
2000-2002 Richard W.E. Furse. The author may be contacted at
richard@muse.demon.co.uk.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public Licence as
published by the Free Software Foundation; either version 2 of the
Licence, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA. */
/*****************************************************************************/
#include <stdlib.h>
/*****************************************************************************/
#include "cmt.h"
#include "pinknoise.h"
#include "utils.h"
/*****************************************************************************/
namespace pink {
enum {
port_frequency = 0,
port_output = 1,
n_ports = 2
};
/** This plugin generates a signal which approximates the effect of low-pass
filtered pink noise, which makes for an interesting randomly changing
control parameter. It should probably use sinc interpolation, but in fact
it uses third-order splines, which sound more-or-less okay to me. */
class Plugin : public CMT_PluginInstance {
private:
LADSPA_Data sample_rate;
PinkNoise noise_source;
LADSPA_Data *data_points;
int first_point;
unsigned long counter;
float multiplier; // 1/(max counter value)
public:
Plugin(const LADSPA_Descriptor *,
unsigned long s_rate) :
CMT_PluginInstance(n_ports),
sample_rate(s_rate) {
data_points = new LADSPA_Data[4];
}
~Plugin() {
delete [] data_points;
}
friend void activate(LADSPA_Handle instance);
friend void run_interpolated_audio(LADSPA_Handle instance,
unsigned long sample_count);
friend void run_interpolated_control(LADSPA_Handle instance,
unsigned long sample_count);
};
void activate(LADSPA_Handle instance) {
Plugin *pp = (Plugin *) instance;
Plugin &p = *pp;
p.noise_source.reset();
for (int i=0; i<4; ++i)
p.data_points[i] = p.noise_source.getValue();
p.first_point = 0;
p.counter = 0;
p.multiplier = 1;
}
inline float thirdInterp(const float &x,
const float &L1,const float &L0,
const float &H0,const float &H1) {
return
L0 +
.5f*
x*(H0-L1 +
x*(H0 + L0*(-2) + L1 +
x*( (H0 - L0)*9 + (L1 - H1)*3 +
x*((L0 - H0)*15 + (H1 - L1)*5 +
x*((H0 - L0)*6 + (L1 - H1)*2 )))));
}
void run_interpolated_audio(LADSPA_Handle instance,
unsigned long sample_count) {
Plugin *pp = (Plugin *) instance;
Plugin &p = *pp;
LADSPA_Data frequency = *pp->m_ppfPorts[port_frequency];
LADSPA_Data * out = pp->m_ppfPorts[port_output];
if (frequency<=0) {
LADSPA_Data value = thirdInterp( 1 - p.counter*p.multiplier,
p.data_points[ p.first_point ],
p.data_points[ (p.first_point+1) % 4 ],
p.data_points[ (p.first_point+2) % 4 ],
p.data_points[ (p.first_point+3) % 4 ] );
for (unsigned long i=0; i<sample_count; ++i)
*(out++) = value;
} else {
frequency = BOUNDED_ABOVE(frequency, p.sample_rate);
unsigned long remain = sample_count;
while (remain) {
unsigned long jump_samples = (remain<p.counter) ? remain : p.counter;
for (unsigned long j=0; j<jump_samples; ++j) {
*(out++) = thirdInterp( 1 - p.counter*p.multiplier,
p.data_points[ p.first_point ],
p.data_points[ (p.first_point+1) % 4 ],
p.data_points[ (p.first_point+2) % 4 ],
p.data_points[ (p.first_point+3) % 4 ] );
--p.counter;
}
remain -= jump_samples;
if (p.counter == 0) {
p.data_points[p.first_point] = p.noise_source.getValue();
p.first_point = (p.first_point + 1) % 4;
p.multiplier = frequency/p.sample_rate;
p.counter = (unsigned long)(p.sample_rate/frequency);
}
}
}
}
void run_interpolated_control(LADSPA_Handle instance,
unsigned long sample_count) {
Plugin *pp = (Plugin *) instance;
Plugin &p = *pp;
LADSPA_Data frequency = *pp->m_ppfPorts[port_frequency];
LADSPA_Data * out = pp->m_ppfPorts[port_output];
float value = thirdInterp( 1 - p.counter*p.multiplier,
p.data_points[ p.first_point ],
p.data_points[ (p.first_point+1) % 4 ],
p.data_points[ (p.first_point+2) % 4 ],
p.data_points[ (p.first_point+3) % 4 ] );
if (frequency>0) {
frequency = BOUNDED_ABOVE(frequency, p.sample_rate/sample_count);
while (p.counter <= sample_count) {
p.data_points[ p.first_point ] = p.noise_source.getValue();
p.first_point = (p.first_point + 1) % 4;
p.multiplier = frequency/p.sample_rate;
p.counter += (unsigned long)(p.sample_rate/frequency);
}
p.counter -= (p.counter < sample_count) ? p.counter : sample_count;
}
*(out)=value;
}
void initialise() {
CMT_Descriptor * d = new CMT_Descriptor
(1841,
"pink_interpolated_audio",
0,
"Pink Noise (Interpolated)",
CMT_MAKER("Nathaniel Virgo"),
CMT_COPYRIGHT("2002", "Nathaniel Virgo"),
NULL,
CMT_Instantiate<Plugin>,
activate,
run_interpolated_audio,
NULL,
NULL,
NULL);
d->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Highest frequency",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_BOUNDED_ABOVE
| LADSPA_HINT_SAMPLE_RATE
| LADSPA_HINT_DEFAULT_1),
0,
1);
d->addPort
(LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
"Output");
registerNewPluginDescriptor(d);
// the following has been commented out because I'm pretty sure that
// control-rate outputs don't make sense for the vast majority of hosts.
// (SSM being the notable exception)
/*
d = new CMT_Descriptor
(1842,
"pink_interpolated_control",
0,
"Pink Noise (Interpolated, control rate)",
CMT_MAKER("Nathaniel Virgo"),
CMT_COPYRIGHT("2002", "Nathaniel Virgo"),
NULL,
CMT_Instantiate<Plugin>,
activate,
run_interpolated_control,
NULL,
NULL,
NULL);
d->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Highest frequency",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_BOUNDED_ABOVE
| LADSPA_HINT_SAMPLE_RATE
| LADSPA_HINT_DEFAULT_1),
0,
0.002); // arbitrary low value (sensible for sample_count around 500)
d->addPort
(LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL,
"Output");
registerNewPluginDescriptor(d);
*/
}
} // end of namespace
/*****************************************************************************/
/* EOF */

View File

@@ -1,114 +0,0 @@
/* pink_full.cpp
A full-frequency pink noise generator.
(c) 2002 Nathaniel Virgo
Part of the Computer Music Toolkit - a library of LADSPA plugins.
The Computer Music Toolkit is Copyright (C) 2000-2002
Richard W.E. Furse. The author may be contacted at
richard@muse.demon.co.uk.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public Licence as
published by the Free Software Foundation; either version 2 of the
Licence, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA. */
/*****************************************************************************/
#include <stdlib.h>
/*****************************************************************************/
#include "cmt.h"
#include "pinknoise.h"
#include "utils.h"
/*****************************************************************************/
namespace pink_full {
enum {
port_output = 0,
n_ports = 1
};
/** This plugin generates a signal which approximates pink noise, using the
Voss-McCartney algorithm described at www.firstpr.com.au/dsp/pink-noise/ */
class Plugin : public CMT_PluginInstance {
private:
PinkNoise noise_source;
public:
Plugin(const LADSPA_Descriptor *,
unsigned long s_rate) :
CMT_PluginInstance(n_ports)
{
}
~Plugin() {
}
friend void activate(LADSPA_Handle instance);
friend void run(LADSPA_Handle instance,
unsigned long sample_count);
};
void activate(LADSPA_Handle instance) {
Plugin *pp = (Plugin *) instance;
Plugin &p = *pp;
p.noise_source.reset();
}
void run(LADSPA_Handle instance,
unsigned long sample_count) {
Plugin *pp = (Plugin *) instance;
Plugin &p = *pp;
LADSPA_Data * out = pp->m_ppfPorts[port_output];
for (unsigned long i=0; i<sample_count; ++i)
*(out++) = p.noise_source.getValue2();
}
void initialise() {
CMT_Descriptor * d = new CMT_Descriptor
(1844,
"pink_full_frequency",
0,
"Pink Noise (full frequency range)",
CMT_MAKER("Nathaniel Virgo"),
CMT_COPYRIGHT("2002", "Nathaniel Virgo"),
NULL,
CMT_Instantiate<Plugin>,
activate,
run,
NULL,
NULL,
NULL);
d->addPort
(LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
"Output");
registerNewPluginDescriptor(d);
}
} // end of namespace
/*****************************************************************************/
/* EOF */

View File

@@ -1,148 +0,0 @@
/* pink_sh.cpp
A sample-and-hold pink noise generator.
(c) 2002 Nathaniel Virgo
Part of the Computer Music Toolkit - a library of LADSPA plugins.
The Computer Music Toolkit is Copyright (C) 2000-2002
Richard W.E. Furse. The author may be contacted at
richard@muse.demon.co.uk.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public Licence as
published by the Free Software Foundation; either version 2 of the
Licence, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA. */
/*****************************************************************************/
#include <stdlib.h>
/*****************************************************************************/
#include "cmt.h"
#include "pinknoise.h"
#include "utils.h"
/*****************************************************************************/
namespace pink_sh {
enum {
port_frequency = 0,
port_output = 1,
n_ports = 2
};
/** This plugin generates a signal which approximates stepped
(sample-and-hold like) pink noise, using the
Voss-McCartney algorithm described at www.firstpr.com.au/dsp/pink-noise/ */
class Plugin : public CMT_PluginInstance {
private:
LADSPA_Data sample_rate;
PinkNoise noise_source;
unsigned counter;
public:
Plugin(const LADSPA_Descriptor *,
unsigned long s_rate) :
CMT_PluginInstance(n_ports),
sample_rate(s_rate) {
}
~Plugin() {
}
friend void activate(LADSPA_Handle instance);
friend void run(LADSPA_Handle instance,
unsigned long sample_count);
};
void activate(LADSPA_Handle instance) {
Plugin *pp = (Plugin *) instance;
Plugin &p = *pp;
p.noise_source.reset();
p.counter = 0;
}
void run(LADSPA_Handle instance,
unsigned long sample_count) {
Plugin *pp = (Plugin *) instance;
Plugin &p = *pp;
LADSPA_Data frequency = *pp->m_ppfPorts[port_frequency];
LADSPA_Data * out = pp->m_ppfPorts[port_output];
frequency = BOUNDED_ABOVE(frequency,p.sample_rate);
unsigned remain = sample_count;
if (frequency > 0) {
while (remain) {
unsigned jump_samples = (remain<p.counter) ? remain : p.counter;
for (unsigned j=0; j<jump_samples; ++j) {
*(out++) = p.noise_source.getLastValue();
}
p.counter -= jump_samples;
remain -= jump_samples;
if (p.counter==0) {
p.noise_source.getValue();
p.counter = (unsigned)(p.sample_rate/frequency);
}
}
}
else
{
for (unsigned long i=0; i<sample_count; ++i)
*(out++) = p.noise_source.getLastValue();
}
}
void initialise() {
CMT_Descriptor * d = new CMT_Descriptor
(1843,
"pink_sh",
0,
"Pink Noise (sample and hold)",
CMT_MAKER("Nathaniel Virgo"),
CMT_COPYRIGHT("2002", "Nathaniel Virgo"),
NULL,
CMT_Instantiate<Plugin>,
activate,
run,
NULL,
NULL,
NULL);
d->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Sample and hold frequency",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_BOUNDED_ABOVE
| LADSPA_HINT_SAMPLE_RATE
| LADSPA_HINT_DEFAULT_1),
0, 0.02);
d->addPort
(LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
"Output");
registerNewPluginDescriptor(d);
}
} // end of namespace
/*****************************************************************************/
/* EOF */

View File

@@ -1,111 +0,0 @@
/* pinknoise.h
pink noise generating class using the Voss-McCartney algorithm, as
described at www.firstpr.com.au/dsp/pink-noise/
(c) 2002 Nathaniel Virgo
Computer Music Toolkit - a library of LADSPA plugins. Copyright (C)
2000-2002 Richard W.E. Furse. The author may be contacted at
richard@muse.demon.co.uk.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public Licence as
published by the Free Software Foundation; either version 2 of the
Licence, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA. */
#ifndef _PINKNOISE_H
#define _PINKNOISE_H
#include <stdlib.h>
typedef unsigned int CounterType;
typedef float DataValue;
const int n_generators = 8*sizeof(CounterType);
class PinkNoise {
private:
CounterType counter;
DataValue * generators;
DataValue last_value;
public:
PinkNoise() {
generators = new DataValue[n_generators];
reset();
}
~PinkNoise() {delete [] generators;};
void reset() {
counter = 0;
last_value = 0;
for (int i=0; i<n_generators; ++i) {
generators[i] = 2*(rand()/DataValue(RAND_MAX))-1;
last_value += generators[i];
}
}
inline DataValue getUnscaledValue() {
if (counter != 0) {
// set index to number of trailing zeros in counter.
// hangs if counter==0, hence the slightly inefficient
// test above.
CounterType n = counter;
int index = 0;
while ( (n & 1) == 0 ) {
n >>= 1;
index++;
// this loop means that the plugins cannot be labelled as
// capable of hard real-time performance.
}
last_value -= generators[index];
generators[index] = 2*(rand()/DataValue(RAND_MAX))-1;
last_value += generators[index];
}
counter++;
return last_value;
}
inline DataValue getValue() {
return getUnscaledValue()/n_generators;
}
inline DataValue getLastValue() {
return last_value/n_generators;
}
inline DataValue getValue2() {
// adding some white noise gets rid of some nulls in the frequency spectrum
// but makes the signal spikier, so possibly not so good for control signals.
return (getUnscaledValue() + rand()/DataValue(RAND_MAX*0.5)-1)/(n_generators+1);
}
};
#endif

View File

@@ -1,159 +0,0 @@
/* run_adding.h
(c) 2002 Nathaniel Virgo
a few simple inline functions that can be used with templates
to get run_adding for free.
Computer Music Toolkit - a library of LADSPA plugins. Copyright (C)
2000-2002 Richard W.E. Furse. The author may be contacted at
richard@muse.demon.co.uk.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public Licence as
published by the Free Software Foundation; either version 2 of the
Licence, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA. */
/*****************************************************************************/
/*
How to use this
---------------
Templates can be used to automatically generate code for both the run and
run_adding LADSPA functions. Simply define the plugin's run function as
template<OutputFunction write_output>
void run_foo(LADSPA_Handle Instance, unsigned long SampleCount);
and in the body of the function use
write_output(pfOutput, fValue, poFoo->m_fRunAddingGain);
instead of
*(pfOutput++) = fValue.
and be sure to include a set_run_adding_gain function.
then set the LADSPA run function as
run_foo<write_output_normal>;
and the run_adding function as
run_foo<write_output_adding>;
With -O1 or greater g++ will inline the write_output function, and
although the code ends up slightly bigger there is no overhead compared to
having two seperate functions.
Sometimes the run_adding_gain function can be made more efficient than this
- for instance, if the output is multiplied by a gain already then you are
doing one more multiplication than necessary on every sample. It's a lot
less code to maintain, though, and it should still save some work for the
host compared to not having a run_adding function.
*/
/*****************************************************************************/
#include <ladspa.h>
/*****************************************************************************/
typedef void OutputFunction(LADSPA_Data *&, const LADSPA_Data &,
const LADSPA_Data &);
inline void write_output_normal(LADSPA_Data *&out, const LADSPA_Data &value,
const LADSPA_Data &run_adding_gain)
{
*(out++) = value;
}
inline void write_output_adding(LADSPA_Data *&out, const LADSPA_Data &value,
const LADSPA_Data &run_adding_gain)
{
*(out++) += value*run_adding_gain;
}
/*****************************************************************************/
/*
If the plugin has a control-rate ouput then you don't want the write_output
function to try to increment the pointer. To achieve this, use
write_control<write_output>(pfOutput, fValue, poFoo->m_fRunAddingGain);
instead of just
write_output(...);
I realise this feels a bit hacky, but it works.
*/
template <OutputFunction ouput_mode>
inline void write_control(LADSPA_Data *const,
const LADSPA_Data &, const LADSPA_Data &);
template <>
inline void write_control<write_output_normal>(LADSPA_Data *const out,
const LADSPA_Data &value,
const LADSPA_Data &run_adding_gain)
{
*out = value;
}
template <>
inline void write_control<write_output_adding>(LADSPA_Data *const out,
const LADSPA_Data &value,
const LADSPA_Data &run_adding_gain)
{
*out += value*run_adding_gain;
}
/*****************************************************************************/
/*
This next bit is an attempt to facilitate the writing of slightly
more efficent run_adding functions without writing two seperate pieces of
code. You can say something like
LADSPA_Data fOutputGain = ... ;
...
fOutputGain *= get_gain<write_output>(poFoo->m_fRunAddingGain);
...
write_output(pfOutput, fValue*fOutputGain, 1.0f);
in run_foo. With -O1 or greater g++ should inline the functions and
optimise away the multiplies by 1.0f, so in run_foo<write_output_adding>
fOutputGain will be multiplied by m_fRunAddingGain and in
run_foo<write_output_normal> it will be left alone.
This does not make for very clear code, sorry about that. See disintegrator.cpp
for an example.
*/
template <OutputFunction output_mode>
inline float get_gain(const LADSPA_Data &);
template <>
inline float get_gain<write_output_normal>(const LADSPA_Data &)
{
return 1.0f;
}
template <>
inline float get_gain<write_output_adding>(const LADSPA_Data &run_adding_gain)
{
return run_adding_gain;
}

View File

@@ -1,296 +0,0 @@
/* sine.cpp
Computer Music Toolkit - a library of LADSPA plugins. Copyright (C)
2000-2002 Richard W.E. Furse. The author may be contacted at
richard@muse.demon.co.uk.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public Licence as
published by the Free Software Foundation; either version 2 of the
Licence, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA. */
/*****************************************************************************/
#include <math.h>
#include <stdlib.h>
/*****************************************************************************/
#include "cmt.h"
/*****************************************************************************/
/* Sine table size is given by (1 << SINE_TABLE_BITS). */
#define SINE_TABLE_BITS 14
#define SINE_TABLE_SHIFT (8 * sizeof(unsigned long) - SINE_TABLE_BITS)
/*****************************************************************************/
LADSPA_Data * g_pfSineTable = NULL;
LADSPA_Data g_fPhaseStepBase = 0;
/*****************************************************************************/
void
initialise_sine_wavetable() {
if (g_pfSineTable == NULL) {
long lTableSize = (1 << SINE_TABLE_BITS);
double dShift = (double(M_PI) * 2) / lTableSize;
g_pfSineTable = new float[lTableSize];
if (g_pfSineTable != NULL)
for (long lIndex = 0; lIndex < lTableSize; lIndex++)
g_pfSineTable[lIndex] = LADSPA_Data(sin(dShift * lIndex));
}
if (g_fPhaseStepBase == 0) {
g_fPhaseStepBase = (LADSPA_Data)pow(2, sizeof(unsigned long) * 8);
}
}
/*****************************************************************************/
#define OSC_FREQUENCY 0
#define OSC_AMPLITUDE 1
#define OSC_OUTPUT 2
/* This class provides sine wavetable oscillator
plugins. Band-limiting to avoid aliasing is trivial because of the
waveform in use. Four versions of the oscillator are provided,
allowing the amplitude and frequency inputs of the oscillator to be
audio signals rather than controls (for use in AM and FM
synthesis). */
class SineOscillator : public CMT_PluginInstance{
private:
/* Oscillator state: */
unsigned long m_lPhase;
unsigned long m_lPhaseStep;
LADSPA_Data m_fCachedFrequency;
const LADSPA_Data m_fLimitFrequency;
const LADSPA_Data m_fPhaseStepScalar;
void setPhaseStepFromFrequency(const LADSPA_Data fFrequency) {
if (fFrequency != m_fCachedFrequency) {
if (fFrequency >= 0 && fFrequency < m_fLimitFrequency)
m_lPhaseStep = (unsigned long)(m_fPhaseStepScalar * fFrequency);
else
m_lPhaseStep = 0;
m_fCachedFrequency = fFrequency;
}
}
public:
SineOscillator(const LADSPA_Descriptor *,
unsigned long lSampleRate)
: CMT_PluginInstance(3),
m_lPhaseStep(0),
m_fCachedFrequency(0),
m_fLimitFrequency(LADSPA_Data(lSampleRate * 0.5)),
m_fPhaseStepScalar(LADSPA_Data(g_fPhaseStepBase / lSampleRate)) {
}
friend void activateSineOscillator(void * pvHandle);
friend void runSineOscillator_FreqAudio_AmpAudio(LADSPA_Handle Instance,
unsigned long SampleCount);
friend void runSineOscillator_FreqAudio_AmpCtrl(LADSPA_Handle Instance,
unsigned long SampleCount);
friend void runSineOscillator_FreqCtrl_AmpAudio(LADSPA_Handle Instance,
unsigned long SampleCount);
friend void runSineOscillator_FreqCtrl_AmpCtrl(LADSPA_Handle Instance,
unsigned long SampleCount);
};
/*****************************************************************************/
void
activateSineOscillator(void * pvHandle) {
((SineOscillator *)pvHandle)->m_lPhase = 0;
}
/*****************************************************************************/
void
runSineOscillator_FreqAudio_AmpAudio(LADSPA_Handle Instance,
unsigned long SampleCount) {
SineOscillator * poSineOscillator = (SineOscillator *)Instance;
LADSPA_Data * pfFrequency = poSineOscillator->m_ppfPorts[OSC_FREQUENCY];
LADSPA_Data * pfAmplitude = poSineOscillator->m_ppfPorts[OSC_AMPLITUDE];
LADSPA_Data * pfOutput = poSineOscillator->m_ppfPorts[OSC_OUTPUT];
for (unsigned long lIndex = 0; lIndex < SampleCount; lIndex++) {
/* Extract frequency at this point to guarantee inplace
support. */
LADSPA_Data fFrequency = *(pfFrequency++);
*(pfOutput++)
= (g_pfSineTable[poSineOscillator->m_lPhase >> SINE_TABLE_SHIFT]
* *(pfAmplitude++));
poSineOscillator->setPhaseStepFromFrequency(fFrequency);
poSineOscillator->m_lPhase
+= poSineOscillator->m_lPhaseStep;
}
}
/*****************************************************************************/
void
runSineOscillator_FreqAudio_AmpCtrl(LADSPA_Handle Instance,
unsigned long SampleCount) {
SineOscillator * poSineOscillator = (SineOscillator *)Instance;
LADSPA_Data fAmplitude = *(poSineOscillator->m_ppfPorts[OSC_AMPLITUDE]);
LADSPA_Data * pfFrequency = poSineOscillator->m_ppfPorts[OSC_FREQUENCY];
LADSPA_Data * pfOutput = poSineOscillator->m_ppfPorts[OSC_OUTPUT];
for (unsigned long lIndex = 0; lIndex < SampleCount; lIndex++) {
/* Extract frequency at this point to guarantee inplace
support. */
LADSPA_Data fFrequency = *(pfFrequency++);
*(pfOutput++)
= (g_pfSineTable[poSineOscillator->m_lPhase >> SINE_TABLE_SHIFT]
* fAmplitude);
poSineOscillator->setPhaseStepFromFrequency(fFrequency);
poSineOscillator->m_lPhase
+= poSineOscillator->m_lPhaseStep;
}
}
/*****************************************************************************/
void
runSineOscillator_FreqCtrl_AmpAudio(LADSPA_Handle Instance,
unsigned long SampleCount) {
SineOscillator * poSineOscillator = (SineOscillator *)Instance;
poSineOscillator->setPhaseStepFromFrequency
(*(poSineOscillator->m_ppfPorts[OSC_FREQUENCY]));
LADSPA_Data * pfAmplitude = poSineOscillator->m_ppfPorts[OSC_AMPLITUDE];
LADSPA_Data * pfOutput = poSineOscillator->m_ppfPorts[OSC_OUTPUT];
for (unsigned long lIndex = 0; lIndex < SampleCount; lIndex++) {
*(pfOutput++)
= (g_pfSineTable[poSineOscillator->m_lPhase >> SINE_TABLE_SHIFT]
* *(pfAmplitude++));
poSineOscillator->m_lPhase
+= poSineOscillator->m_lPhaseStep;
}
}
/*****************************************************************************/
void
runSineOscillator_FreqCtrl_AmpCtrl(LADSPA_Handle Instance,
unsigned long SampleCount) {
SineOscillator * poSineOscillator = (SineOscillator *)Instance;
LADSPA_Data fAmplitude = *(poSineOscillator->m_ppfPorts[OSC_AMPLITUDE]);
poSineOscillator->setPhaseStepFromFrequency
(*(poSineOscillator->m_ppfPorts[OSC_FREQUENCY]));
LADSPA_Data * pfOutput = poSineOscillator->m_ppfPorts[OSC_OUTPUT];
for (unsigned long lIndex = 0; lIndex < SampleCount; lIndex++) {
*(pfOutput++)
= (g_pfSineTable[poSineOscillator->m_lPhase >> SINE_TABLE_SHIFT]
* fAmplitude);
poSineOscillator->m_lPhase
+= poSineOscillator->m_lPhaseStep;
}
}
/*****************************************************************************/
void
initialise_sine() {
initialise_sine_wavetable();
const char * apcLabels[] = {
"sine_faaa",
"sine_faac",
"sine_fcaa",
"sine_fcac"
};
const char * apcNames[] = {
"Sine Oscillator (Freq:audio, Amp:audio)",
"Sine Oscillator (Freq:audio, Amp:control)",
"Sine Oscillator (Freq:control, Amp:audio)",
"Sine Oscillator (Freq:control, Amp:control)"
};
LADSPA_Run_Function afRunFunction[] = {
runSineOscillator_FreqAudio_AmpAudio,
runSineOscillator_FreqAudio_AmpCtrl,
runSineOscillator_FreqCtrl_AmpAudio,
runSineOscillator_FreqCtrl_AmpCtrl
};
LADSPA_PortDescriptor piFrequencyPortProperties[] = {
LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL
};
LADSPA_PortDescriptor piAmplitudePortProperties[] = {
LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL
};
for (long lPluginIndex = 0; lPluginIndex < 4; lPluginIndex++) {
CMT_Descriptor * psDescriptor;
psDescriptor = new CMT_Descriptor
(1063 + lPluginIndex,
apcLabels[lPluginIndex],
LADSPA_PROPERTY_HARD_RT_CAPABLE,
apcNames[lPluginIndex],
CMT_MAKER("Richard W.E. Furse"),
CMT_COPYRIGHT("2000-2002", "Richard W.E. Furse"),
NULL,
CMT_Instantiate<SineOscillator>,
activateSineOscillator,
afRunFunction[lPluginIndex],
NULL,
NULL,
NULL);
psDescriptor->addPort
(piFrequencyPortProperties[lPluginIndex],
"Frequency",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_BOUNDED_ABOVE
| LADSPA_HINT_SAMPLE_RATE
| LADSPA_HINT_LOGARITHMIC
| LADSPA_HINT_DEFAULT_440),
0,
0.5);
psDescriptor->addPort
(piAmplitudePortProperties[lPluginIndex],
"Amplitude",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_LOGARITHMIC
| LADSPA_HINT_DEFAULT_1),
0,
0);
psDescriptor->addPort
(LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
"Output");
registerNewPluginDescriptor(psDescriptor);
}
}
/*****************************************************************************/
void
finalise_sine() {
delete [] g_pfSineTable;
}
/*****************************************************************************/
/* EOF */

View File

@@ -1,186 +0,0 @@
/* sledgehammer.cpp
"Dynamic Sledgehammer" - a thing to brutally mangle the dynamics of
a sound.
(c) 2002 Nathaniel Virgo
Computer Music Toolkit - a library of LADSPA plugins. Copyright (C)
2000-2002 Richard W.E. Furse. The author may be contacted at
richard@muse.demon.co.uk.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public Licence as
published by the Free Software Foundation; either version 2 of the
Licence, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA. */
/*****************************************************************************/
#include <math.h>
#include <stdlib.h>
/*****************************************************************************/
#include "cmt.h"
#include "run_adding.h"
/*****************************************************************************/
namespace sledgehammer {
enum {
port_rate = 0,
port_mod_infl = 1, // modulator influence
port_car_infl = 2, // carrier influence (0 to 1 for compression)
port_modulator = 3,
port_carrier = 4,
port_output = 5,
n_ports = 6
};
/** This plugin imposes the dynamics of one sound onto another.
It can be seen as a brutal compressor with a sidechain, or
as a kind of one-band vocoder. */
class Plugin : public CMT_PluginInstance {
LADSPA_Data run_adding_gain;
LADSPA_Data running_ms_mod;
LADSPA_Data running_ms_car; // current mean square average
public:
Plugin(const LADSPA_Descriptor *,
unsigned long)
: CMT_PluginInstance(n_ports) {}
friend void activate(LADSPA_Handle instance);
template<OutputFunction write_output>
friend void run(LADSPA_Handle instance,
unsigned long sample_count);
friend void set_run_adding_gain(LADSPA_Handle instance,
LADSPA_Data new_gain);
};
void activate(LADSPA_Handle instance) {
Plugin *pp = (Plugin *) instance;
Plugin &p = *pp;
p.running_ms_mod = 0;
p.running_ms_car = 0;
}
template<OutputFunction write_output>
void run(LADSPA_Handle instance,
unsigned long sample_count) {
Plugin *pp = (Plugin *) instance;
Plugin &p = *pp;
LADSPA_Data rate = *pp->m_ppfPorts[port_rate];
LADSPA_Data mod_infl = *pp->m_ppfPorts[port_mod_infl];
LADSPA_Data car_infl = *pp->m_ppfPorts[port_car_infl];
LADSPA_Data * modptr = pp->m_ppfPorts[port_modulator];
LADSPA_Data * carptr = pp->m_ppfPorts[port_carrier];
LADSPA_Data * out = pp->m_ppfPorts[port_output];
for ( unsigned long i = 0; i < sample_count ; ++i ) {
LADSPA_Data mod = *(modptr++);
LADSPA_Data car = *(carptr++);
p.running_ms_mod = p.running_ms_mod*(1-rate) + (mod*mod)*rate;
p.running_ms_car = p.running_ms_car*(1-rate) + (car*car)*rate;
LADSPA_Data rms_mod = sqrt(p.running_ms_mod);
LADSPA_Data rms_car = sqrt(p.running_ms_car);
LADSPA_Data outsig = car;
if (rms_car>0)
outsig *= ((rms_car-0.5)*car_infl+0.5)/rms_car;
outsig *= ((rms_mod-0.5)*mod_infl+0.5);
write_output(out, outsig ,p.run_adding_gain);
}
}
void set_run_adding_gain(LADSPA_Handle instance,
LADSPA_Data new_gain) {
((Plugin *) instance)->run_adding_gain = new_gain;
}
void
initialise() {
CMT_Descriptor * d = new CMT_Descriptor
(1848,
"sledgehammer",
LADSPA_PROPERTY_HARD_RT_CAPABLE,
"Dynamic Sledgehammer",
CMT_MAKER("Nathaniel Virgo"),
CMT_COPYRIGHT("2002", "Nathaniel Virgo"),
NULL,
CMT_Instantiate<Plugin>,
activate,
run<write_output_normal>,
run<write_output_adding>,
set_run_adding_gain,
NULL);
d->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Rate",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_BOUNDED_ABOVE
| LADSPA_HINT_DEFAULT_MIDDLE),
0.00001,
0.001);
d->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Modulator influence",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_BOUNDED_ABOVE
| LADSPA_HINT_DEFAULT_0),
-1,
1);
d->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Carrier influence",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_BOUNDED_ABOVE
| LADSPA_HINT_DEFAULT_1),
-1,
1);
d->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
"Modulator");
d->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
"Carrier");
d->addPort
(LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
"Output");
registerNewPluginDescriptor(d);
}
} // end of namespace
/*****************************************************************************/
/* EOF */

View File

@@ -1,175 +0,0 @@
/* syndrum.cpp
SynDrum - Drum Synthesizer
Copyright (c) 1999, 2000 David A. Bartold
Computer Music Toolkit - a library of LADSPA plugins. Copyright (C)
2000 Richard W.E. Furse. The author may be contacted at
richard@muse.demon.co.uk.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public Licence as
published by the Free Software Foundation; either version 2 of the
Licence, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA. */
/*****************************************************************************/
#include <stdlib.h>
#include <math.h>
#include "cmt.h"
#define PORT_OUT 0
#define PORT_TRIGGER 1
#define PORT_VELOCITY 2
#define PORT_FREQ 3
#define PORT_RESONANCE 4
#define PORT_RATIO 5
#define NUM_PORTS 6
#ifndef PI
#define PI 3.14159265358979
#endif
class SynDrum : public CMT_PluginInstance {
LADSPA_Data sample_rate;
LADSPA_Data spring_vel;
LADSPA_Data spring_pos;
LADSPA_Data env;
int last_trigger;
public:
SynDrum(const LADSPA_Descriptor *,
unsigned long s_rate)
: CMT_PluginInstance(NUM_PORTS),
sample_rate(s_rate),
spring_vel(0.0F),
spring_pos(0.0F),
env(0.0F) {
}
~SynDrum() {
}
static void
activate(LADSPA_Handle Instance) {
SynDrum *syndrum = (SynDrum*) Instance;
syndrum->spring_vel = 0.0F;
syndrum->spring_pos = 0.0F;
syndrum->env = 0.0F;
syndrum->last_trigger = 0;
}
static void
run(LADSPA_Handle Instance,
unsigned long SampleCount) {
SynDrum *syndrum = (SynDrum*) Instance;
unsigned long i;
int trigger;
LADSPA_Data freq_shift;
LADSPA_Data factor;
LADSPA_Data res;
trigger = *syndrum->m_ppfPorts[PORT_TRIGGER] > 0.0;
if (trigger == 1 && syndrum->last_trigger == 0)
{
syndrum->spring_vel = *syndrum->m_ppfPorts[PORT_VELOCITY];
syndrum->env = *syndrum->m_ppfPorts[PORT_VELOCITY];
}
syndrum->last_trigger = trigger;
factor = 2.0 * PI / syndrum->sample_rate;
freq_shift = *syndrum->m_ppfPorts[PORT_FREQ] *
*syndrum->m_ppfPorts[PORT_RATIO];
res = pow (0.05, 1.0 / (syndrum->sample_rate * *syndrum->m_ppfPorts[PORT_RESONANCE]));
for (i = 0; i < SampleCount; i++)
{
LADSPA_Data cur_freq;
cur_freq = *syndrum->m_ppfPorts[PORT_FREQ] +
(syndrum->env * freq_shift);
cur_freq *= factor;
syndrum->spring_vel -= syndrum->spring_pos * cur_freq;
syndrum->spring_pos += syndrum->spring_vel * cur_freq;
syndrum->spring_vel *= res;
syndrum->env *= res;
syndrum->m_ppfPorts[PORT_OUT][i] = syndrum->spring_pos;
}
}
};
static LADSPA_PortDescriptor g_psPortDescriptors[] =
{
LADSPA_PORT_AUDIO | LADSPA_PORT_OUTPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT
};
static const char * const g_psPortNames[] =
{
"Out",
"Trigger",
"Velocity",
"Frequency (Hz)",
"Resonance",
"Frequency Ratio"
};
static LADSPA_PortRangeHint g_psPortRangeHints[] =
{
/* Hints, Lower bound, Upper bound */
{ 0, 0.0, 0.0 },
{ LADSPA_HINT_TOGGLED, 0.0, 0.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 10.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 20000.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.001, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 10.0 }
};
void
initialise_syndrum() {
CMT_Descriptor * psDescriptor;
psDescriptor = new CMT_Descriptor
(1223,
"syndrum",
LADSPA_PROPERTY_HARD_RT_CAPABLE,
"Syn Drum",
CMT_MAKER("David A. Bartold"),
CMT_COPYRIGHT("1999, 2000", "David A. Bartold"),
NULL,
CMT_Instantiate<SynDrum>,
SynDrum::activate,
SynDrum::run,
NULL,
NULL,
NULL);
for (int i = 0; i < NUM_PORTS; i++)
psDescriptor->addPort(
g_psPortDescriptors[i],
g_psPortNames[i],
g_psPortRangeHints[i].HintDescriptor,
g_psPortRangeHints[i].LowerBound,
g_psPortRangeHints[i].UpperBound);
registerNewPluginDescriptor(psDescriptor);
}

View File

@@ -1,103 +0,0 @@
/* utils.h
Computer Music Toolkit - a library of LADSPA plugins. Copyright (C)
2000 Richard W.E. Furse. The author may be contacted at
richard@muse.demon.co.uk.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public Licence as
published by the Free Software Foundation; either version 2 of the
Licence, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA. */
#ifndef CMT_UTILS_INCLUDED
#define CMT_UTILS_INCLUDED
/*****************************************************************************/
#include <math.h>
#include <stdlib.h>
/*****************************************************************************/
#include "ladspa_types.h"
/*****************************************************************************/
/** The drag setting is arranged so that the gain drops by a factor of
1e3 (60dB) in the time specified. This is a bit of an arbitrary
value but ties in with what the user will probably expect from
his/her experience with reverb units. */
inline LADSPA_Data
calculate60dBDrag(const LADSPA_Data fTime,
const LADSPA_Data fSampleRate) {
if (fTime <= 0)
return 0;
else
return pow(1e3, -1 / (fTime * fSampleRate));
}
/*****************************************************************************/
inline LADSPA_Data
BOUNDED_BELOW(const LADSPA_Data fData,
const LADSPA_Data fLowerBound) {
if (fData <= fLowerBound)
return fLowerBound;
else
return fData;
}
inline LADSPA_Data BOUNDED_ABOVE(const LADSPA_Data fData,
const LADSPA_Data fUpperBound) {
if (fData >= fUpperBound)
return fUpperBound;
else
return fData;
}
inline LADSPA_Data
BOUNDED(const LADSPA_Data fData,
const LADSPA_Data fLowerBound,
const LADSPA_Data fUpperBound) {
if (fData <= fLowerBound)
return fLowerBound;
else if (fData >= fUpperBound)
return fUpperBound;
else
return fData;
}
/*****************************************************************************/
/* Take a reading from a normal RV. The algorithm works by repeated
sampling of the uniform distribution, the lQuality variable giving
the number of samples. */
inline double
sampleNormalDistribution(const double dMean,
const double dStandardDeviation,
const long lQuality = 12) {
double dValue = 0;
for (long lIter = 0; lIter < lQuality; lIter++)
dValue += rand();
double dSampleFromNormal01 = (dValue / RAND_MAX) - (lQuality * 0.5);
return dMean + dStandardDeviation * dSampleFromNormal01;
}
/*****************************************************************************/
#endif
/* EOF */

View File

@@ -1,219 +0,0 @@
/* vcf303.cpp
VCF 303 - TB-303 Resonant Filter
Copyright (c) 1998 Andy Sloane
Copyright (c) 1999, 2000 David A. Bartold
Computer Music Toolkit - a library of LADSPA plugins. Copyright (C)
2000 Richard W.E. Furse. The author may be contacted at
richard@muse.demon.co.uk.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public Licence as
published by the Free Software Foundation; either version 2 of the
Licence, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA. */
/*****************************************************************************/
#include <stdlib.h>
#include <math.h>
#include "cmt.h"
#define PORT_IN 0
#define PORT_OUT 1
#define PORT_TRIGGER 2
#define PORT_CUTOFF 3
#define PORT_RESONANCE 4
#define PORT_ENV_MOD 5
#define PORT_DECAY 6
#define NUM_PORTS 7
#ifndef PI
#define PI 3.14159265358979
#endif
class Vcf303 : public CMT_PluginInstance {
LADSPA_Data sample_rate;
LADSPA_Data d1, d2, c0;
int last_trigger;
int envpos;
public:
Vcf303(const LADSPA_Descriptor *,
unsigned long s_rate)
: CMT_PluginInstance(NUM_PORTS),
sample_rate(s_rate),
d1(0.0), d2(0.0), c0(0.0),
last_trigger(0),
envpos(0) {
}
~Vcf303() {
}
static void
activate(LADSPA_Handle Instance) {
Vcf303 *vcf303 = (Vcf303*) Instance;
vcf303->d1 = 0.0;
vcf303->d2 = 0.0;
vcf303->c0 = 0.0;
vcf303->last_trigger = 0;
vcf303->envpos = 0;
}
static inline void
recalc_a_b_c (Vcf303 *filter,
LADSPA_Data e0,
LADSPA_Data c0,
LADSPA_Data resonance,
LADSPA_Data *a,
LADSPA_Data *b,
LADSPA_Data *c) {
LADSPA_Data whopping, k;
whopping = e0 + c0;
k = exp (-whopping / resonance);
*a = 2.0 * cos (2.0 * whopping) * k;
*b = -k * k;
*c = (1.0 - *a - *b) * 0.2;
}
static void
run(LADSPA_Handle Instance,
unsigned long SampleCount) {
Vcf303 *vcf303 = (Vcf303*) Instance;
unsigned long i;
LADSPA_Data e0, d, a, b, c;
LADSPA_Data decay, resonance;
LADSPA_Data **ports;
int trigger;
/* Update vars given envmod, cutoff, and reso. */
ports = vcf303->m_ppfPorts;
e0 = exp (5.613 - 0.8 * *ports[PORT_ENV_MOD] + 2.1553 *
*ports[PORT_CUTOFF] - 0.7696 * (1.0 - *ports[PORT_RESONANCE]));
e0 *= PI / vcf303->sample_rate;
trigger = (*ports[PORT_TRIGGER] > 0.0);
if (trigger == 1 && vcf303->last_trigger == 0)
{
LADSPA_Data e1;
e1 = exp (6.109 + 1.5876 * *ports[PORT_ENV_MOD] + 2.1553 *
*ports[PORT_CUTOFF] - 1.2 * (1.0 - *ports[PORT_RESONANCE]));
e1 *= PI / vcf303->sample_rate;
vcf303->c0 = e1 - e0;
}
vcf303->last_trigger = trigger;
/* Update decay given envdecay. */
d = 0.2 + (2.3 * *ports[PORT_DECAY]);
d *= vcf303->sample_rate;
d = pow (0.1, 1.0 / d);
decay = pow (d, 64);
/* Update resonance. */
resonance = exp (-1.20 + 3.455 * *ports[PORT_RESONANCE]);
recalc_a_b_c (vcf303, e0, vcf303->c0, resonance, &a, &b, &c);
for (i = 0; i < SampleCount; i++)
{
LADSPA_Data sample;
sample = a * vcf303->d1 + b * vcf303->d2 + c * ports[PORT_IN][i];
ports[PORT_OUT][i] = sample;
vcf303->d2 = vcf303->d1;
vcf303->d1 = sample;
vcf303->envpos++;
if (vcf303->envpos >= 64)
{
vcf303->envpos = 0;
vcf303->c0 *= decay;
recalc_a_b_c (vcf303, e0, vcf303->c0, resonance, &a, &b, &c);
}
}
}
};
static LADSPA_PortDescriptor g_psPortDescriptors[] =
{
LADSPA_PORT_AUDIO | LADSPA_PORT_INPUT,
LADSPA_PORT_AUDIO | LADSPA_PORT_OUTPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT,
LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT
};
static const char * const g_psPortNames[] =
{
"In",
"Out",
"Trigger",
"Cutoff",
"Resonance",
"Envelope Modulation",
"Decay"
};
static LADSPA_PortRangeHint g_psPortRangeHints[] =
{
/* Hints, Lower bound, Upper bound */
{ 0, 0.0, 0.0 },
{ 0, 0.0, 0.0 },
{ LADSPA_HINT_TOGGLED, 0.0, 0.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 1.0 },
{ LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW, 0.0, 1.0 }
};
void
initialise_vcf303() {
CMT_Descriptor * psDescriptor;
psDescriptor = new CMT_Descriptor
(1224,
"vcf303",
LADSPA_PROPERTY_HARD_RT_CAPABLE,
"VCF 303",
CMT_MAKER("David A. Bartold"),
CMT_COPYRIGHT("1998-2000", "Andy Sloane, David A. Bartold"),
NULL,
CMT_Instantiate<Vcf303>,
Vcf303::activate,
Vcf303::run,
NULL,
NULL,
NULL);
for (int i = 0; i < NUM_PORTS; i++)
psDescriptor->addPort(
g_psPortDescriptors[i],
g_psPortNames[i],
g_psPortRangeHints[i].HintDescriptor,
g_psPortRangeHints[i].LowerBound,
g_psPortRangeHints[i].UpperBound);
registerNewPluginDescriptor(psDescriptor);
}

View File

@@ -1,110 +0,0 @@
/* wshape_sine.cpp
Computer Music Toolkit - a library of LADSPA plugins. Copyright (C)
2000-2002 Richard W.E. Furse. The author may be contacted at
richard@muse.demon.co.uk.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public Licence as
published by the Free Software Foundation; either version 2 of the
Licence, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA. */
/*****************************************************************************/
#include <math.h>
#include <stdlib.h>
/*****************************************************************************/
#include "cmt.h"
/*****************************************************************************/
#define WSS_CONTROL 0
#define WSS_INPUT 1
#define WSS_OUTPUT 2
/** This plugin applies a gain to a mono signal. */
class SineWaveshaper : public CMT_PluginInstance {
public:
SineWaveshaper(const LADSPA_Descriptor *,
unsigned long)
: CMT_PluginInstance(3) {
}
friend void runSineWaveshaper(LADSPA_Handle Instance,
unsigned long SampleCount);
};
/*****************************************************************************/
void
runSineWaveshaper(LADSPA_Handle Instance,
unsigned long SampleCount) {
SineWaveshaper * poProcessor = (SineWaveshaper *)Instance;
LADSPA_Data * pfInput = poProcessor->m_ppfPorts[WSS_INPUT];
LADSPA_Data * pfOutput = poProcessor->m_ppfPorts[WSS_OUTPUT];
LADSPA_Data fLimit = *(poProcessor->m_ppfPorts[WSS_CONTROL]);
LADSPA_Data fOneOverLimit = 1 / fLimit;
for (unsigned long lSampleIndex = 0;
lSampleIndex < SampleCount;
lSampleIndex++)
*(pfOutput++) = fLimit * sin(*(pfInput++) * fOneOverLimit);
}
/*****************************************************************************/
void
initialise_wshape_sine() {
CMT_Descriptor * psDescriptor;
psDescriptor = new CMT_Descriptor
(1097,
"wshape_sine",
LADSPA_PROPERTY_HARD_RT_CAPABLE,
"Wave Shaper (Sine-Based)",
CMT_MAKER("Richard W.E. Furse"),
CMT_COPYRIGHT("2000-2002", "Richard W.E. Furse"),
NULL,
CMT_Instantiate<SineWaveshaper>,
NULL,
runSineWaveshaper,
NULL,
NULL,
NULL);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
"Limiting Amplitude",
(LADSPA_HINT_BOUNDED_BELOW
| LADSPA_HINT_LOGARITHMIC
| LADSPA_HINT_DEFAULT_1),
0,
0);
psDescriptor->addPort
(LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
"Input");
psDescriptor->addPort
(LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
"Output");
registerNewPluginDescriptor(psDescriptor);
}
/*****************************************************************************/
/* EOF */