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

Adding Plugins to the CMT Library

The CMT LADSPA 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.

At the moment CMT is not under public version control, so please send changes to Richard Furse.

CMT plugins interpret LADSPA_Handle entities as pointers to objects derived from the CMT_PluginInstance class. Plugin instance structures are defined by subclassing this, so writing a descendent of CMT_PluginInstance is the first thing to do. The CMT library provides its own implementation of connect_port(), cleanup() and a templated form of instantiate() (see CMT_Instantiate<>()). These calls assume that any instantiation or cleanup mechanisms required will be written in the constructor or destructor of the class.

When writing a plugin module, an initialisation function should be included. To ensure this is called, add a call to the initialise_modules() function in descriptor.cpp. The module should also be added to the makefile.

Your initialisation function should construct new CMT_Desctiptor plugin descriptor structures and pass them to registerNewPluginDescriptor(). The CMT_Descriptor is directly descended from LADSPA_Descriptor but provides constructor, destructor and addPort() methods.

All plugins need unique IDs. During development, use values between 1 and 1000. When the plugin is ready, please request an ID from ladspa@muse.demon.co.uk. Please also add a brief description of your module to plugins.html.

In practice, CMT plugin writing is probably best learned by example. For a simple case, see the mixer.cpp module. This defines a SimpleMixer class to handle instance data, a runSimpleMixer() function for use with it and a mixer_descriptor() function to provide a description of the plugin to the CMT core. The mixer_descriptor() function is declared and referenced in the descriptor.cpp module. Additional information is available in cmt.h and ladspa.h.

CMT plugins are licenced under GPL version 2. Please read and understand this license before submitting plugins to the library.

cmt-1.16/doc/bugs.html000066400000000000000000000011011112274441100146050ustar00rootroot00000000000000

CMT Bugs

Please report bugs to richard@muse.demon.co.uk.

  • I'm not sure I've got attack & decay the right way around in the expander plugins.
  • Need to have a look at dynamic.cpp for handling of unusual arithmetic situation such as isnan(), isinf() etc.
  • Memory management is a little haphazard at present. What happens when new() fails? The host can use set_new_handler(), but I suspect this needs further thought anyway.
cmt-1.16/doc/changes.html000066400000000000000000000055411112274441100152710ustar00rootroot00000000000000

CMT Changes

Version 1.01 - 4 May 2000

  • Initial Release.

Version 1.02 - 11 May 2000

  • Use _init() and _fini(). To handle memory management automatically.
  • Change from *_descriptor() approach simpler initialise_*() approach. Use _init() and _fini() to handle memory management. Supply CMT_Descriptor::~CMT_Descriptor().
  • Make comments compatible with Doxygen.
  • Addition of Ambisonic encoder, decoder, converter and rotation plugins.
  • Addition of Sine Waveshaper and Granular Scatter Processor plugin.

Version 1.03 - 14 May 2000

  • Updated to correspond to http://www.ladspa.org/.

Version 1.04 - 18 May 2000

  • Bugfixes: Ambisonic encoder inputs, white noise amplitude/DC, Ambisonic rotation inplace support, sine oscillator frequency input inplace support.

Version 1.05 - 18 May 2000

  • Bugfix: use explicit pointer type when deleting ImplementationData in ~CMT_Descriptor.

Version 1.06 - 24 Sep 2000

  • Introduction of Identity plugins.

Version 1.07 - 30 Sep 2000

  • Use constructor/destructor rather than _fini() and _init(). Use C++ for linkage.

Version 1.08 - 30 Sep 2000

  • Fix to Ambisonic decode equations.

Version 1.09 - 4 Nov 2000

  • Addition of a port of Freeverb (version 3) and a collection of plugins by David Bartold (analogue, canyon_delay, organ, syndrum, vcf303).

Version 1.10 - 17 Feb 2001

  • Small compile fixes to some modules. Apologies to David who sent me a patch ages ago for the analogue module.

Version 1.11 - 8 May 2001

  • Addition of newline character to end of allpass.h.

Version 1.12 - 17 Sept 2001

  • Addition of new plugins by David: "Lo Fi" and "Phase Modulated Voice."

Version 1.13 - 7 May 2002

  • Fix to B-Format rotation algorithm.

Version 1.14 - 7 Aug 2002

  • Fix to B-Format rotation algorithm.
  • Update for LADSPA 1.1 (include default values).

Version 1.15 - 19 Dec 2002

  • Addition of a number of utility routines and namespaces by Nathaniel Virgo.
  • Addition of a number of plugins by Nathaniel Virgo.
  • Small change to trigger mechanism in syndrum plugin.

Version 1.16 - 6 Nov 2007

  • Remove -Werror from compile options in makefile.
  • Remove "local" part from install directories.
  • Small additional changes to makefile for robustness.
  • Replace strdup() with localStrdup() to avoid malloc/new mismatch.
cmt-1.16/doc/index.html000066400000000000000000000014011112274441100147570ustar00rootroot00000000000000

CMT Index

Other Links

Richard Furse can be emailed as richard@muse.demon.co.uk.

cmt-1.16/doc/installation.html000066400000000000000000000016261112274441100163620ustar00rootroot00000000000000

CMT Installation

To build the plugin library, enter the src/ directory and run make. The makefile expects to find the ladspa.h header file in your include path or /usr/local/include/. If you do not have this file it can be downloaded as part of the LADSPA SDK from http://www.ladspa.org/download/.

Running make will generate the CMT LADSPA plugin library (cmt.so) in the plugins/ directory. This can be moved to an appropriate location depending on the application you are using. Running make install from the src/ directory as root will install to /usr/local/lib/ladspa/ which is on the search path recommended for hosts looking for plugin libraries. Some applications may not search this directory automatically.

cmt-1.16/doc/license.html000066400000000000000000000012511112274441100152750ustar00rootroot00000000000000

CMT License

The CMT toolkit is licensed under GPL version 2.

As I understand it (I'm not a lawyer) this means that, once built, the CMT library may 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.

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 LADPSA license for further details.

cmt-1.16/doc/overview.html000066400000000000000000000012361112274441100155240ustar00rootroot00000000000000

Computer Music Toolkit (CMT) v1.16 Overview

The Computer Music Toolkit (CMT) is a collection of LADSPA plugins for use with software synthesis and recording packages on Linux. See the license before use.

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 contact Richard.

cmt-1.16/doc/plugins.html000077500000000000000000000247441112274441100153530ustar00rootroot00000000000000

CMT Library Plugins

The following plugins are provided in the CMT library:

Plugin ID Plugin Label Description
1051 lpf Low Pass Filter (One Pole).
1052 hpf High Pass Filter (One Pole).
1053 delay_0.01s Echo Delay Line. The delay time may be varied up to 0.01 seconds. No feedback is provided.
1054 delay_0.1s Echo Delay Line. The delay time may be varied up to 0.1 seconds. No feedback is provided.
1055 delay_1s Echo Delay Line. The delay time may be varied up to 1 second. No feedback is provided.
1056 delay_5s Echo Delay Line. The delay time may be varied up to 5 seconds. No feedback is provided.
1057 delay_60s Echo Delay Line. The delay time may be varied up to 60 seconds. No feedback is provided.
1058 fbdelay_0.01s Feedback Delay Line. The delay time may be varied up to 0.01 seconds.
1059 fbdelay_0.1s Feedback Delay Line. The delay time may be varied up to 0.1 seconds.
1060 fbdelay_1s Feedback Delay Line. The delay time may be varied up to 1 second.
1061 fbdelay_5s Feedback Delay Line. The delay time may be varied up to 5 seconds.
1062 fbdelay_60s Feedback Delay Line. The delay time may be varied up to 60 seconds.
1063 sine_faaa Sine Oscillator. Frequency input is audio, Amplitude input is audio.
1064 sine_faac Sine Oscillator. Frequency input is audio, Amplitude input is control.
1065 sine_fcaa Sine Oscillator. Frequency input is control, Amplitude input is audio.
1066 sine_fcac Sine Oscillator. Frequency input is control, Amplitude input is control.
1067 amp_mono Amplifier (Mono).
1068 amp_stereo Amplifier (Stereo).
1069 noise_source_white Noise Source (White).
1070 am Amplitude Modulator.
1071 mixer Mixer (Stereo to Mono).
1072 compress_peak Simple Compressor (Peak Envelope Tracking).
1073 compress_rms Simple Compressor (RMS Envelope Tracking).
1074 expand_peak Simple Expander (Peak Envelope Tracking).
1075 expand_rms Simple Expander (RMS Envelope Tracking).
1076 limit_peak Simple Limiter (Peak Envelope Tracking).
1077 limit_rms Simple Limiter (RMS Envelope Tracking).
1078 track_peak Envelope Tracker (Peak).
1079 track_rms Envelope Tracker (RMS).
1080 track_max_peak Envelope Tracker (Maximum Peak).
1081 track_max_rms Envelope Tracker (Maximum RMS).
1082 peak Peak Monitor.
1083 null_ci Null Plugin (Control Input).
1084 null_ai Null Plugin (Audio Input).
1085 null_co Null Plugin (Control Output).
1086 null_ao Null Plugin (Audio Output).
1087 encode_bformat B-Format Encoder. This plugin encodes ambisonic B-Format audio using the inverse square law but no filtering, reverb or delay.
1088 encode_fmh FMH-Format Encoder. This plugin encodes ambisonic FMH-Format audio using the inverse square law but no filtering, reverb or delay.
1089 fmh2bf FMH-Format to B-Format. This plugin simply discards the R, S, T, U and V channels but is included for clarity.
1090 bf2stereo B-Format to Stereo Ambisonic Decoder. This plugin only actually uses its W and Y input signals and does not use UHJ.
1091 bf2quad B-Format to Quad Ambisonic Decoder. This plugin only actually uses its W, Y and Z input signals.
1092 bf2cube B-Format to Cube Ambisonic Decoder.
1093 bf2oct FMH-Format to Octagon Ambisonic Decoder. This plugin only actually uses its W, X, Y, U and V inputs.
1094 bf_rotate_z B-Format Rotation (Horizontal). This plugin rotates an B-Format encoded soundfield around the Z-axis.
1095 fmh_rotate_z FMH-Format Rotation (Horizontal). This plugin rotates an FMH-Format encoded soundfield around the Z-axis.
1096 grain_scatter 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.
1097 wsshape_sine Wave Shaper (Sine-Based).
1098 identity_audio Identity (Audio).
1099 identity_control Identity (Control).
1123 freeverb3 Freeverb (Version 3). This reverb unit is a direct port of the free public domain source code available from Jezar at Dreampoint.
1221 analogue 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.
1222 organ 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.
1223 syndrum Drum Synthesizer.
1224 vcf303 VCF 303. A TB-303 resonant filter clone.
1225 canyon_delay Canyon Delay. A deep stereo crossdelay with built-in low pass filters.
1226 phasemod 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 -360o and 360o.
1227 lofi Lo Fi. Simulates old audio equipment. Adds distortion, bandwidth limiting, compression, and crackling to audio.
1841 pink_interpolated_audio 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.
1843 pink_sh Sample and hold pink noise. Similar to pink, but with stepped instead of interpolated output.
1844 pink_full_frequency 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.
1845 hard_gate Hard noise gate. If the absolute value of the signal falls below "threshold", it is set to zero. There is no antialiasing.
1846 disintegrator 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.
1848 sledgehammer 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.
1849 logistic Logistic Map chaotic stepped control generator. The logistic map is a classic example from chaos theory. It can be summarised by the formula
x := r*x*(1-x).
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.

"Ambisonics" is a registered trademark of Nimbus Communications International.

cmt-1.16/doc/tasks.html000066400000000000000000000007131112274441100150020ustar00rootroot00000000000000

CMT Library Task List

Basic Plugins Needed

  • Noise Gate
  • Flanger
  • Phaser
  • Chorus
  • Unbounded Delay (echo & feedback)
  • Distortion
  • Overdrive
  • Exciter
  • Resonant Filter
  • Graphic EQ
  • Envelope Generator

Other Plugins Planned

  • Vocoder

Other Tasks

  • Think up a better name than CMT.
cmt-1.16/src/000077500000000000000000000000001112274441100130105ustar00rootroot00000000000000cmt-1.16/src/am.cpp000066400000000000000000000061371112274441100141200ustar00rootroot00000000000000/* 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 #include /*****************************************************************************/ #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, 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 */ cmt-1.16/src/ambisonic.cpp000066400000000000000000001061561112274441100154710ustar00rootroot00000000000000/* ambisonic.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 simple plugins handling B-Format and FMH-Format audio. Ambisonics is a mathematical technique designed to capture the sound field around point. See http://www.muse.demon.co.uk/3daudio.html. "Ambisonics" is a registered trademark of Nimbus Communications International although. An exteremly `vanilla' approach is taken to encoding distance, using inverse square, but no filtering or delay. */ /*****************************************************************************/ #include #include #include /*****************************************************************************/ #include "cmt.h" /*****************************************************************************/ #define ENC_INPUT 0 #define ENC_IN_X 1 #define ENC_IN_Y 2 #define ENC_IN_Z 3 #define ENC_OUT_W 4 #define ENC_OUT_X 5 #define ENC_OUT_Y 6 #define ENC_OUT_Z 7 #define ENC_OUT_R 8 #define ENC_OUT_S 9 #define ENC_OUT_T 10 #define ENC_OUT_U 11 #define ENC_OUT_V 12 /*****************************************************************************/ /** This plugin encodes a signal to B-Format depending on where it is located in a virtual space. */ class BFormatEncoder : public CMT_PluginInstance { public: BFormatEncoder(const LADSPA_Descriptor *, unsigned long lSampleRate) : CMT_PluginInstance(8) { } friend void runBFormatEncoder(LADSPA_Handle Instance, unsigned long SampleCount); }; /** This plugin encodes a signal to FMH-Format depending on where it is located in a virtual space. */ class FMHFormatEncoder : public CMT_PluginInstance { public: FMHFormatEncoder(const LADSPA_Descriptor *, unsigned long lSampleRate) : CMT_PluginInstance(13) { } friend void runFMHFormatEncoder(LADSPA_Handle Instance, unsigned long SampleCount); }; /*****************************************************************************/ #define F2B_IN_W 0 #define F2B_IN_X 1 #define F2B_IN_Y 2 #define F2B_IN_Z 3 #define F2B_IN_R 4 #define F2B_IN_S 5 #define F2B_IN_T 6 #define F2B_IN_U 7 #define F2B_IN_V 8 #define F2B_OUT_W 9 #define F2B_OUT_X 10 #define F2B_OUT_Y 11 #define F2B_OUT_Z 12 /** This plugin coverts FMH-Format to B-Format. This is a trivial operation that can also be achieved simply by discarding RSTUV channels. */ class FMHToB : public CMT_PluginInstance { public: FMHToB(const LADSPA_Descriptor *, unsigned long lSampleRate) : CMT_PluginInstance(13) { } friend void runFMHToB(LADSPA_Handle Instance, unsigned long SampleCount); }; /*****************************************************************************/ #define DECST_IN_W 0 #define DECST_IN_X 1 #define DECST_IN_Y 2 #define DECST_IN_Z 3 #define DECST_OUT_L 4 #define DECST_OUT_R 5 /** This plugin decodes B-Format to produce a stereo speaker feed. */ class BFormatToStereo : public CMT_PluginInstance { public: BFormatToStereo(const LADSPA_Descriptor *, unsigned long lSampleRate) : CMT_PluginInstance(6) { } friend void runBFormatToStereo(LADSPA_Handle Instance, unsigned long SampleCount); }; /*****************************************************************************/ #define DECQ_IN_W 0 #define DECQ_IN_X 1 #define DECQ_IN_Y 2 #define DECQ_IN_Z 3 #define DECQ_OUT_FL 4 #define DECQ_OUT_FR 5 #define DECQ_OUT_BL 6 #define DECQ_OUT_BR 7 /** This plugin decodes B-Format to produce a quad (square) speaker feed. */ class BFormatToQuad : public CMT_PluginInstance { public: BFormatToQuad(const LADSPA_Descriptor *, unsigned long lSampleRate) : CMT_PluginInstance(8) { } friend void runBFormatToQuad(LADSPA_Handle Instance, unsigned long SampleCount); }; /*****************************************************************************/ #define DECC_IN_W 0 #define DECC_IN_X 1 #define DECC_IN_Y 2 #define DECC_IN_Z 3 #define DECC_OUT_BFL 4 #define DECC_OUT_BFR 5 #define DECC_OUT_BBL 6 #define DECC_OUT_BBR 7 #define DECC_OUT_TFL 8 #define DECC_OUT_TFR 9 #define DECC_OUT_TBL 10 #define DECC_OUT_TBR 11 /** This plugin decodes B-Format to produce a speaker feed for eight speakers arranged at the corners of a cube. */ class BFormatToCube : public CMT_PluginInstance { public: BFormatToCube(const LADSPA_Descriptor *, unsigned long lSampleRate) : CMT_PluginInstance(12) { } friend void runBFormatToCube(LADSPA_Handle Instance, unsigned long SampleCount); }; /*****************************************************************************/ #define DECO_IN_W 0 #define DECO_IN_X 1 #define DECO_IN_Y 2 #define DECO_IN_Z 3 #define DECO_IN_R 4 #define DECO_IN_S 5 #define DECO_IN_T 6 #define DECO_IN_U 7 #define DECO_IN_V 8 #define DECO_OUT_FFL 9 #define DECO_OUT_FFR 10 #define DECO_OUT_FRR 11 #define DECO_OUT_BRR 12 #define DECO_OUT_BBR 13 #define DECO_OUT_BBL 14 #define DECO_OUT_BLL 15 #define DECO_OUT_FLL 16 /** This plugin decodes FMH-Format to produce a speaker feed for eight speakers arranged at the corners of an octagon. */ class FMHFormatToOct : public CMT_PluginInstance { public: FMHFormatToOct(const LADSPA_Descriptor *, unsigned long lSampleRate) : CMT_PluginInstance(17) { } friend void runFMHFormatToOct(LADSPA_Handle Instance, unsigned long SampleCount); }; /*****************************************************************************/ #define BFROT_ANGLE 0 #define BFROT_IN_W 1 #define BFROT_IN_X 2 #define BFROT_IN_Y 3 #define BFROT_IN_Z 4 #define BFROT_OUT_W 5 #define BFROT_OUT_X 6 #define BFROT_OUT_Y 7 #define BFROT_OUT_Z 8 /** This plugin rotates an B-Format soundfield around the Z-axis. */ class BFormatRotation : public CMT_PluginInstance { public: BFormatRotation(const LADSPA_Descriptor *, unsigned long lSampleRate) : CMT_PluginInstance(9) { } friend void runBFormatRotation(LADSPA_Handle Instance, unsigned long SampleCount); }; /*****************************************************************************/ #define FMHROT_ANGLE 0 #define FMHROT_IN_W 1 #define FMHROT_IN_X 2 #define FMHROT_IN_Y 3 #define FMHROT_IN_Z 4 #define FMHROT_IN_R 5 #define FMHROT_IN_S 6 #define FMHROT_IN_T 7 #define FMHROT_IN_U 8 #define FMHROT_IN_V 9 #define FMHROT_OUT_W 10 #define FMHROT_OUT_X 11 #define FMHROT_OUT_Y 12 #define FMHROT_OUT_Z 13 #define FMHROT_OUT_R 14 #define FMHROT_OUT_S 15 #define FMHROT_OUT_T 16 #define FMHROT_OUT_U 17 #define FMHROT_OUT_V 18 /** This plugin rotates an FMH-Format soundfield around the Z-axis. */ class FMHFormatRotation : public CMT_PluginInstance { public: FMHFormatRotation(const LADSPA_Descriptor *, unsigned long lSampleRate) : CMT_PluginInstance(19) { } friend void runFMHFormatRotation(LADSPA_Handle Instance, unsigned long SampleCount); }; /*****************************************************************************/ void runBFormatEncoder(LADSPA_Handle Instance, unsigned long SampleCount) { BFormatEncoder * poProcessor = (BFormatEncoder *)Instance; LADSPA_Data * pfInput = poProcessor->m_ppfPorts[ENC_INPUT]; LADSPA_Data * pfOutW = poProcessor->m_ppfPorts[ENC_OUT_W]; LADSPA_Data * pfOutX = poProcessor->m_ppfPorts[ENC_OUT_X]; LADSPA_Data * pfOutY = poProcessor->m_ppfPorts[ENC_OUT_Y]; LADSPA_Data * pfOutZ = poProcessor->m_ppfPorts[ENC_OUT_Z]; LADSPA_Data fX = *(poProcessor->m_ppfPorts[ENC_IN_X]); LADSPA_Data fY = *(poProcessor->m_ppfPorts[ENC_IN_Y]); LADSPA_Data fZ = *(poProcessor->m_ppfPorts[ENC_IN_Z]); LADSPA_Data fDistanceSquared = fX * fX + fY * fY + fZ * fZ; const LADSPA_Data fWScalar = 0.707107; LADSPA_Data fXScalar, fYScalar, fZScalar; if (fDistanceSquared > 1e-10) { LADSPA_Data fOneOverDistanceSquared = 1 / fDistanceSquared; fXScalar = fX * fOneOverDistanceSquared; fYScalar = fY * fOneOverDistanceSquared; fZScalar = fZ * fOneOverDistanceSquared; } else { /* Avoid division by zero issues. */ fXScalar = fYScalar = fZScalar = 0; } for (unsigned long lSampleIndex = 0; lSampleIndex < SampleCount; lSampleIndex++) { LADSPA_Data fInput = *(pfInput++); *(pfOutW++) = fWScalar * fInput; *(pfOutX++) = fXScalar * fInput; *(pfOutY++) = fYScalar * fInput; *(pfOutZ++) = fZScalar * fInput; } } /*****************************************************************************/ void runFMHFormatEncoder(LADSPA_Handle Instance, unsigned long SampleCount) { FMHFormatEncoder * poProcessor = (FMHFormatEncoder *)Instance; LADSPA_Data * pfInput = poProcessor->m_ppfPorts[ENC_INPUT]; LADSPA_Data * pfOutW = poProcessor->m_ppfPorts[ENC_OUT_W]; LADSPA_Data * pfOutX = poProcessor->m_ppfPorts[ENC_OUT_X]; LADSPA_Data * pfOutY = poProcessor->m_ppfPorts[ENC_OUT_Y]; LADSPA_Data * pfOutZ = poProcessor->m_ppfPorts[ENC_OUT_Z]; LADSPA_Data * pfOutR = poProcessor->m_ppfPorts[ENC_OUT_R]; LADSPA_Data * pfOutS = poProcessor->m_ppfPorts[ENC_OUT_S]; LADSPA_Data * pfOutT = poProcessor->m_ppfPorts[ENC_OUT_T]; LADSPA_Data * pfOutU = poProcessor->m_ppfPorts[ENC_OUT_U]; LADSPA_Data * pfOutV = poProcessor->m_ppfPorts[ENC_OUT_V]; LADSPA_Data fX = *(poProcessor->m_ppfPorts[ENC_IN_X]); LADSPA_Data fY = *(poProcessor->m_ppfPorts[ENC_IN_Y]); LADSPA_Data fZ = *(poProcessor->m_ppfPorts[ENC_IN_Z]); LADSPA_Data fDistanceSquared = fX * fX + fY * fY + fZ * fZ; const LADSPA_Data fWScalar = 0.707107; LADSPA_Data fXScalar, fYScalar, fZScalar; LADSPA_Data fRScalar, fSScalar, fTScalar; LADSPA_Data fUScalar, fVScalar; if (fDistanceSquared > 1e-10) { LADSPA_Data fOneOverDistanceSquared = 1 / fDistanceSquared; LADSPA_Data fOneOverDistanceCubed = LADSPA_Data(pow(fDistanceSquared, -1.5)); fXScalar = fX * fOneOverDistanceSquared; fYScalar = fY * fOneOverDistanceSquared; fZScalar = fZ * fOneOverDistanceSquared; fRScalar = ((fZ * fZ) * fOneOverDistanceSquared - 0.5) * sqrt(fOneOverDistanceSquared); fSScalar = 2 * (fZ * fX) * fOneOverDistanceCubed; fTScalar = 2 * (fY * fX) * fOneOverDistanceCubed; fUScalar = (fX * fX - fY * fY) * fOneOverDistanceCubed; fVScalar = 2 * (fX * fY) * fOneOverDistanceCubed; } else { /* Avoid division by zero issues. */ fXScalar = fYScalar = fZScalar = fRScalar = fSScalar = fTScalar = fUScalar = fVScalar = 0; } for (unsigned long lSampleIndex = 0; lSampleIndex < SampleCount; lSampleIndex++) { LADSPA_Data fInput = *(pfInput++); *(pfOutW++) = fWScalar * fInput; *(pfOutX++) = fXScalar * fInput; *(pfOutY++) = fYScalar * fInput; *(pfOutZ++) = fZScalar * fInput; *(pfOutR++) = fRScalar * fInput; *(pfOutS++) = fSScalar * fInput; *(pfOutT++) = fTScalar * fInput; *(pfOutU++) = fUScalar * fInput; *(pfOutV++) = fVScalar * fInput; } } /*****************************************************************************/ void runFMHToB(LADSPA_Handle Instance, unsigned long SampleCount) { FMHToB * poProcessor = (FMHToB *)Instance; LADSPA_Data * pfInW = poProcessor->m_ppfPorts[F2B_IN_W]; LADSPA_Data * pfInX = poProcessor->m_ppfPorts[F2B_IN_X]; LADSPA_Data * pfInY = poProcessor->m_ppfPorts[F2B_IN_Y]; LADSPA_Data * pfInZ = poProcessor->m_ppfPorts[F2B_IN_Z]; LADSPA_Data * pfOutW = poProcessor->m_ppfPorts[F2B_OUT_W]; LADSPA_Data * pfOutX = poProcessor->m_ppfPorts[F2B_OUT_X]; LADSPA_Data * pfOutY = poProcessor->m_ppfPorts[F2B_OUT_Y]; LADSPA_Data * pfOutZ = poProcessor->m_ppfPorts[F2B_OUT_Z]; int iSize = sizeof(LADSPA_Data) * SampleCount; memcpy(pfOutW, pfInW, iSize); memcpy(pfOutX, pfInX, iSize); memcpy(pfOutY, pfInY, iSize); memcpy(pfOutZ, pfInZ, iSize); } /*****************************************************************************/ void runBFormatToStereo(LADSPA_Handle Instance, unsigned long SampleCount) { BFormatToStereo * poProcessor = (BFormatToStereo *)Instance; LADSPA_Data * pfInW = poProcessor->m_ppfPorts[DECST_IN_W]; LADSPA_Data * pfInY = poProcessor->m_ppfPorts[DECST_IN_Y]; LADSPA_Data * pfOutL = poProcessor->m_ppfPorts[DECST_OUT_L]; LADSPA_Data * pfOutR = poProcessor->m_ppfPorts[DECST_OUT_R]; for (unsigned long lSampleIndex = 0; lSampleIndex < SampleCount; lSampleIndex++) { LADSPA_Data fA = 0.707107 * *(pfInW++); LADSPA_Data fB = 0.5 * *(pfInY++); *(pfOutL++) = fA + fB; *(pfOutR++) = fA - fB; } } /*****************************************************************************/ void runBFormatToQuad(LADSPA_Handle Instance, unsigned long SampleCount) { BFormatToQuad * poProcessor = (BFormatToQuad *)Instance; LADSPA_Data * pfInW = poProcessor->m_ppfPorts[DECQ_IN_W]; LADSPA_Data * pfInX = poProcessor->m_ppfPorts[DECQ_IN_X]; LADSPA_Data * pfInY = poProcessor->m_ppfPorts[DECQ_IN_Y]; LADSPA_Data * pfOutFL = poProcessor->m_ppfPorts[DECQ_OUT_FL]; LADSPA_Data * pfOutFR = poProcessor->m_ppfPorts[DECQ_OUT_FR]; LADSPA_Data * pfOutBL = poProcessor->m_ppfPorts[DECQ_OUT_BL]; LADSPA_Data * pfOutBR = poProcessor->m_ppfPorts[DECQ_OUT_BR]; for (unsigned long lSampleIndex = 0; lSampleIndex < SampleCount; lSampleIndex++) { LADSPA_Data fW = 0.353553 * *(pfInW++); LADSPA_Data fX = 0.243361 * *(pfInX++); LADSPA_Data fY = 0.243361 * *(pfInY++); LADSPA_Data fV = 0.096383 * *(pfInY++); *(pfOutFL++) = fW + fX + fY + fV; *(pfOutFR++) = fW + fX - fY - fV; *(pfOutBL++) = fW - fX + fY + fV; *(pfOutBR++) = fW - fX - fY - fV; } } /*****************************************************************************/ void runBFormatToCube(LADSPA_Handle Instance, unsigned long SampleCount) { BFormatToCube * poProcessor = (BFormatToCube *)Instance; LADSPA_Data * pfInW = poProcessor->m_ppfPorts[DECC_IN_W]; LADSPA_Data * pfInX = poProcessor->m_ppfPorts[DECC_IN_X]; LADSPA_Data * pfInY = poProcessor->m_ppfPorts[DECC_IN_Y]; LADSPA_Data * pfInZ = poProcessor->m_ppfPorts[DECC_IN_Z]; LADSPA_Data * pfOutBFL = poProcessor->m_ppfPorts[DECC_OUT_BFL]; LADSPA_Data * pfOutBFR = poProcessor->m_ppfPorts[DECC_OUT_BFR]; LADSPA_Data * pfOutBBL = poProcessor->m_ppfPorts[DECC_OUT_BBL]; LADSPA_Data * pfOutBBR = poProcessor->m_ppfPorts[DECC_OUT_BBR]; LADSPA_Data * pfOutTFL = poProcessor->m_ppfPorts[DECC_OUT_BFL]; LADSPA_Data * pfOutTFR = poProcessor->m_ppfPorts[DECC_OUT_BFR]; LADSPA_Data * pfOutTBL = poProcessor->m_ppfPorts[DECC_OUT_BBL]; LADSPA_Data * pfOutTBR = poProcessor->m_ppfPorts[DECC_OUT_BBR]; for (unsigned long lSampleIndex = 0; lSampleIndex < SampleCount; lSampleIndex++) { LADSPA_Data fW = 0.176777 * *(pfInW++); LADSPA_Data fX = 0.113996 * *(pfInX++); LADSPA_Data fY = 0.113996 * *(pfInY++); LADSPA_Data fZ = 0.113996 * *(pfInZ++); LADSPA_Data fS = 0.036859 * *(pfInX++); LADSPA_Data fT = 0.036859 * *(pfInY++); LADSPA_Data fV = 0.036859 * *(pfInZ++); *(pfOutBFL++) = fW + fX + fY - fZ + fV - fT - fS; *(pfOutBFR++) = fW + fX - fY - fZ - fV + fT - fS; *(pfOutBBL++) = fW - fX + fY - fZ + fV + fT + fS; *(pfOutBBR++) = fW - fX - fY - fZ - fV - fT + fS; *(pfOutTFL++) = fW + fX + fY + fZ + fV + fT + fS; *(pfOutTFR++) = fW + fX - fY + fZ - fV - fT + fS; *(pfOutTBL++) = fW - fX + fY + fZ + fV - fT - fS; *(pfOutTBR++) = fW - fX - fY + fZ - fV + fT - fS; } } /*****************************************************************************/ void runFMHFormatToOct(LADSPA_Handle Instance, unsigned long SampleCount) { FMHFormatToOct * poProcessor = (FMHFormatToOct *)Instance; LADSPA_Data * pfInW = poProcessor->m_ppfPorts[DECO_IN_W]; LADSPA_Data * pfInX = poProcessor->m_ppfPorts[DECO_IN_X]; LADSPA_Data * pfInY = poProcessor->m_ppfPorts[DECO_IN_Y]; LADSPA_Data * pfInU = poProcessor->m_ppfPorts[DECO_IN_U]; LADSPA_Data * pfInV = poProcessor->m_ppfPorts[DECO_IN_V]; LADSPA_Data * pfOutFFL = poProcessor->m_ppfPorts[DECO_OUT_FFL]; LADSPA_Data * pfOutFFR = poProcessor->m_ppfPorts[DECO_OUT_FFR]; LADSPA_Data * pfOutFRR = poProcessor->m_ppfPorts[DECO_OUT_FRR]; LADSPA_Data * pfOutBRR = poProcessor->m_ppfPorts[DECO_OUT_BRR]; LADSPA_Data * pfOutBBR = poProcessor->m_ppfPorts[DECO_OUT_BBR]; LADSPA_Data * pfOutBBL = poProcessor->m_ppfPorts[DECO_OUT_BBL]; LADSPA_Data * pfOutBLL = poProcessor->m_ppfPorts[DECO_OUT_BLL]; LADSPA_Data * pfOutFLL = poProcessor->m_ppfPorts[DECO_OUT_FLL]; for (unsigned long lSampleIndex = 0; lSampleIndex < SampleCount; lSampleIndex++) { LADSPA_Data fW = 0.176777 * *(pfInW++); LADSPA_Data fX1 = 0.065888 * *pfInX; LADSPA_Data fX2 = 0.159068 * *(pfInX++); LADSPA_Data fY1 = 0.065888 * *pfInY; LADSPA_Data fY2 = 0.159068 * *(pfInY++); LADSPA_Data fU = 0.034175 * *(pfInU++); LADSPA_Data fV = 0.034175 * *(pfInV++); *(pfOutFFL++) = fW + fX2 + fY1 + fU + fV; *(pfOutFFR++) = fW + fX2 - fY1 + fU - fV; *(pfOutFRR++) = fW + fX1 - fY2 - fU - fV; *(pfOutBRR++) = fW - fX1 + fY2 - fU + fV; *(pfOutBBR++) = fW - fX2 + fY1 + fU + fV; *(pfOutBBL++) = fW - fX2 - fY1 + fU - fV; *(pfOutBLL++) = fW - fX1 - fY2 - fU - fV; *(pfOutFLL++) = fW + fX1 + fY2 - fU + fV; } } /*****************************************************************************/ void runBFormatRotation(LADSPA_Handle Instance, unsigned long SampleCount) { BFormatRotation * poProcessor = (BFormatRotation *)Instance; /* Work in radians. */ LADSPA_Data fAngle = LADSPA_Data(M_PI / 180.0) * *(poProcessor->m_ppfPorts[FMHROT_ANGLE]); LADSPA_Data fSin = sin(fAngle); LADSPA_Data fCos = cos(fAngle); LADSPA_Data * pfInW = poProcessor->m_ppfPorts[BFROT_IN_W]; LADSPA_Data * pfInX = poProcessor->m_ppfPorts[BFROT_IN_X]; LADSPA_Data * pfInY = poProcessor->m_ppfPorts[BFROT_IN_Y]; LADSPA_Data * pfInZ = poProcessor->m_ppfPorts[BFROT_IN_Z]; LADSPA_Data * pfOutW = poProcessor->m_ppfPorts[BFROT_OUT_W]; LADSPA_Data * pfOutX = poProcessor->m_ppfPorts[BFROT_OUT_X]; LADSPA_Data * pfOutY = poProcessor->m_ppfPorts[BFROT_OUT_Y]; LADSPA_Data * pfOutZ = poProcessor->m_ppfPorts[BFROT_OUT_Z]; int iSize = sizeof(LADSPA_Data) * SampleCount; memcpy(pfOutW, pfInW, iSize); memcpy(pfOutZ, pfInZ, iSize); for (unsigned long lSampleIndex = 0; lSampleIndex < SampleCount; lSampleIndex++) { float fInX = *(pfInX++); float fInY = *(pfInY++); *(pfOutX++) = fCos * fInX - fSin * fInY; *(pfOutY++) = fSin * fInX + fCos * fInY; } } /*****************************************************************************/ void runFMHFormatRotation(LADSPA_Handle Instance, unsigned long SampleCount) { FMHFormatRotation * poProcessor = (FMHFormatRotation *)Instance; /* Work in radians. */ LADSPA_Data fAngle = LADSPA_Data(M_PI / 180.0) * *(poProcessor->m_ppfPorts[FMHROT_ANGLE]); LADSPA_Data fSin = sin(fAngle); LADSPA_Data fCos = cos(fAngle); LADSPA_Data fSin2 = sin(fAngle * 2); LADSPA_Data fCos2 = cos(fAngle * 2); LADSPA_Data * pfInW = poProcessor->m_ppfPorts[FMHROT_IN_W]; LADSPA_Data * pfInX = poProcessor->m_ppfPorts[FMHROT_IN_X]; LADSPA_Data * pfInY = poProcessor->m_ppfPorts[FMHROT_IN_Y]; LADSPA_Data * pfInZ = poProcessor->m_ppfPorts[FMHROT_IN_Z]; LADSPA_Data * pfInR = poProcessor->m_ppfPorts[FMHROT_IN_R]; LADSPA_Data * pfInS = poProcessor->m_ppfPorts[FMHROT_IN_S]; LADSPA_Data * pfInT = poProcessor->m_ppfPorts[FMHROT_IN_T]; LADSPA_Data * pfInU = poProcessor->m_ppfPorts[FMHROT_IN_U]; LADSPA_Data * pfInV = poProcessor->m_ppfPorts[FMHROT_IN_V]; LADSPA_Data * pfOutW = poProcessor->m_ppfPorts[FMHROT_OUT_W]; LADSPA_Data * pfOutX = poProcessor->m_ppfPorts[FMHROT_OUT_X]; LADSPA_Data * pfOutY = poProcessor->m_ppfPorts[FMHROT_OUT_Y]; LADSPA_Data * pfOutZ = poProcessor->m_ppfPorts[FMHROT_OUT_Z]; LADSPA_Data * pfOutR = poProcessor->m_ppfPorts[FMHROT_OUT_R]; LADSPA_Data * pfOutS = poProcessor->m_ppfPorts[FMHROT_OUT_S]; LADSPA_Data * pfOutT = poProcessor->m_ppfPorts[FMHROT_OUT_T]; LADSPA_Data * pfOutU = poProcessor->m_ppfPorts[FMHROT_OUT_U]; LADSPA_Data * pfOutV = poProcessor->m_ppfPorts[FMHROT_OUT_V]; int iSize = sizeof(LADSPA_Data) * SampleCount; memcpy(pfOutW, pfInW, iSize); memcpy(pfOutZ, pfInZ, iSize); memcpy(pfOutR, pfInR, iSize); for (unsigned long lSampleIndex = 0; lSampleIndex < SampleCount; lSampleIndex++) { float fInX = *(pfInX++); float fInY = *(pfInY++); float fInS = *(pfInS++); float fInT = *(pfInT++); float fInU = *(pfInU++); float fInV = *(pfInV++); *(pfOutX++) = fCos * fInX - fSin * fInY; *(pfOutY++) = fSin * fInX + fCos * fInY; *(pfOutS++) = fCos * fInS - fSin * fInT; *(pfOutT++) = fSin * fInS + fCos * fInT; *(pfOutU++) = fCos2 * fInU - fSin2 * fInV; *(pfOutV++) = fSin2 * fInU + fCos2 * fInV; } } /*****************************************************************************/ void initialise_ambisonic() { CMT_Descriptor * psDescriptor; psDescriptor = new CMT_Descriptor (1087, "encode_bformat", LADSPA_PROPERTY_HARD_RT_CAPABLE, "Ambisonic Encoder (B-Format)", CMT_MAKER("Richard W.E. Furse"), CMT_COPYRIGHT("2000-2002", "Richard W.E. Furse"), NULL, CMT_Instantiate, NULL, runBFormatEncoder, NULL, NULL, NULL); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input"); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL, "Sound Source X Coordinate", LADSPA_HINT_DEFAULT_1); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL, "Sound Source Y Coordinate", LADSPA_HINT_DEFAULT_0); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL, "Sound Source Z Coordinate", LADSPA_HINT_DEFAULT_0); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (W)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (X)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (Y)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (Z)"); registerNewPluginDescriptor(psDescriptor); psDescriptor = new CMT_Descriptor (1088, "encode_fmh", LADSPA_PROPERTY_HARD_RT_CAPABLE, "Ambisonic Encoder (FMH-Format)", CMT_MAKER("Richard W.E. Furse"), CMT_COPYRIGHT("2000-2002", "Richard W.E. Furse"), NULL, CMT_Instantiate, NULL, runFMHFormatEncoder, NULL, NULL, NULL); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input"); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL, "Sound Source X Coordinate", LADSPA_HINT_DEFAULT_1); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL, "Sound Source Y Coordinate", LADSPA_HINT_DEFAULT_0); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL, "Sound Source Z Coordinate", LADSPA_HINT_DEFAULT_0); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (W)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (X)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (Y)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (Z)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (R)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (S)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (T)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (U)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (V)"); registerNewPluginDescriptor(psDescriptor); psDescriptor = new CMT_Descriptor (1089, "fmh2bf", LADSPA_PROPERTY_HARD_RT_CAPABLE, "FMH-Format to B-Format (Discards RSTUV Channels)", CMT_MAKER("Richard W.E. Furse"), CMT_COPYRIGHT("2000", "Richard W.E. Furse"), NULL, CMT_Instantiate, NULL, runFMHToB, NULL, NULL, NULL); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (W)"); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (X)"); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (Y)"); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (Z)"); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (R)"); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (S)"); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (T)"); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (U)"); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (V)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (W)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (X)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (Y)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (Z)"); registerNewPluginDescriptor(psDescriptor); psDescriptor = new CMT_Descriptor (1090, "bf2stereo", LADSPA_PROPERTY_HARD_RT_CAPABLE, "Ambisonic Decoder (B-Format to Stereo)", CMT_MAKER("Richard W.E. Furse"), CMT_COPYRIGHT("2000", "Richard W.E. Furse"), NULL, CMT_Instantiate, NULL, runBFormatToStereo, NULL, NULL, NULL); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (W)"); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (X)"); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (Y)"); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (Z)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (Left)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (Right)"); registerNewPluginDescriptor(psDescriptor); psDescriptor = new CMT_Descriptor (1091, "bf2quad", LADSPA_PROPERTY_HARD_RT_CAPABLE, "Ambisonic Decoder (B-Format to Quad)", CMT_MAKER("Richard W.E. Furse"), CMT_COPYRIGHT("2000", "Richard W.E. Furse"), NULL, CMT_Instantiate, NULL, runBFormatToQuad, NULL, NULL, NULL); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (W)"); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (X)"); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (Y)"); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (Z)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (Front Left)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (Front Right)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (Back Left)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (Back Right)"); registerNewPluginDescriptor(psDescriptor); psDescriptor = new CMT_Descriptor (1092, "bf2cube", LADSPA_PROPERTY_HARD_RT_CAPABLE, "Ambisonic Decoder (B-Format to Cube)", CMT_MAKER("Richard W.E. Furse"), CMT_COPYRIGHT("2000", "Richard W.E. Furse"), NULL, CMT_Instantiate, NULL, runBFormatToCube, NULL, NULL, NULL); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (W)"); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (X)"); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (Y)"); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (Z)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (Base Front Left)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (Base Front Right)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (Base Back Left)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (Base Back Right)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (Top Front Left)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (Top Front Right)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (Top Back Left)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (Top Back Right)"); registerNewPluginDescriptor(psDescriptor); psDescriptor = new CMT_Descriptor (1093, "fmh2oct", LADSPA_PROPERTY_HARD_RT_CAPABLE, "Ambisonic Decoder (FMH-Format to Octagon)", CMT_MAKER("Richard W.E. Furse"), CMT_COPYRIGHT("2000", "Richard W.E. Furse"), NULL, CMT_Instantiate, NULL, runFMHFormatToOct, NULL, NULL, NULL); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (W)"); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (X)"); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (Y)"); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (Z)"); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (R)"); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (S)"); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (T)"); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (U)"); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (V)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (Front Front Left)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (Front Front Right)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (Front Right Right)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (Back Right Right)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (Back Back Right)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (Back Back Left)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (Back Left Left)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (Front Left Left)"); registerNewPluginDescriptor(psDescriptor); psDescriptor = new CMT_Descriptor (1094, "bf_rotate_z", LADSPA_PROPERTY_HARD_RT_CAPABLE, "Ambisonic Rotation (B-Format, Horizontal)", CMT_MAKER("Richard W.E. Furse"), CMT_COPYRIGHT("2000-2002", "Richard W.E. Furse"), NULL, CMT_Instantiate, NULL, runBFormatRotation, NULL, NULL, NULL); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL, "Angle of Rotation (Degrees Anticlockwise)", (LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_HIGH), -180, 180); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (W)"); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (X)"); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (Y)"); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (Z)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (W)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (X)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (Y)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (Z)"); registerNewPluginDescriptor(psDescriptor); psDescriptor = new CMT_Descriptor (1095, "fmh_rotate_z", LADSPA_PROPERTY_HARD_RT_CAPABLE, "Ambisonic Rotation (FMH-Format, Horizontal)", CMT_MAKER("Richard W.E. Furse"), CMT_COPYRIGHT("2000-2002", "Richard W.E. Furse"), NULL, CMT_Instantiate, NULL, runFMHFormatRotation, NULL, NULL, NULL); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL, "Angle of Rotation (Degrees Anticlockwise)", (LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_HIGH), -180, 180); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (W)"); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (X)"); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (Y)"); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (Z)"); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (R)"); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (S)"); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (T)"); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (U)"); psDescriptor->addPort (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, "Input (V)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (W)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (X)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (Y)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (Z)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (R)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (S)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (T)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (U)"); psDescriptor->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output (V)"); registerNewPluginDescriptor(psDescriptor); } /*****************************************************************************/ /* EOF */ cmt-1.16/src/amp.cpp000066400000000000000000000122571112274441100143000ustar00rootroot00000000000000/* 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 /*****************************************************************************/ #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, 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, 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 */ cmt-1.16/src/analogue.cpp000066400000000000000000000362441112274441100153200ustar00rootroot00000000000000/* 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 #include #include #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, b, c; 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::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); } cmt-1.16/src/canyondelay.cpp000066400000000000000000000144411112274441100160260ustar00rootroot00000000000000/* 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 #include #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::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); } cmt-1.16/src/cmt.cpp000066400000000000000000000135261112274441100143060ustar00rootroot00000000000000/* 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 /*****************************************************************************/ #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 */ cmt-1.16/src/cmt.h000066400000000000000000000152601112274441100137500ustar00rootroot00000000000000/* 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". */ template 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 */ cmt-1.16/src/delay.cpp000066400000000000000000000236361112274441100146240ustar00rootroot00000000000000/* 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 #include #include /*****************************************************************************/ #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(4), 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 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 */ cmt-1.16/src/descriptor.cpp000066400000000000000000000071741112274441100157030ustar00rootroot00000000000000/* 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 */ cmt-1.16/src/disintegrator.cpp000066400000000000000000000077641112274441100164100ustar00rootroot00000000000000/* 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 /*****************************************************************************/ #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 friend void run(LADSPA_Handle instance, unsigned long sample_count); friend void set_run_adding_gain(LADSPA_Handle instance, LADSPA_Data new_gain); }; template 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(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, NULL, run, run, 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 */ cmt-1.16/src/dynamic.cpp000066400000000000000000000557101112274441100151500ustar00rootroot00000000000000/* 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 #include #include /*****************************************************************************/ #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, 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, 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, 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, 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, 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, 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 */ cmt-1.16/src/filter.cpp000066400000000000000000000174021112274441100150050ustar00rootroot00000000000000/* 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 #include /*****************************************************************************/ #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, 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, 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 */ cmt-1.16/src/freeverb/000077500000000000000000000000001112274441100146105ustar00rootroot00000000000000cmt-1.16/src/freeverb/Components/000077500000000000000000000000001112274441100167355ustar00rootroot00000000000000cmt-1.16/src/freeverb/Components/allpass.cpp000066400000000000000000000007371112274441100211070ustar00rootroot00000000000000// 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) bufidx = 0; return output; } #endif//_allpass //ends cmt-1.16/src/freeverb/Components/comb.cpp000066400000000000000000000011101112274441100203520ustar00rootroot00000000000000// 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) bufidx = 0; return output; } #endif //_comb_ //ends cmt-1.16/src/freeverb/Components/denormals.h000077500000000000000000000005571112274441100211040ustar00rootroot00000000000000// 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 #endif//_denormals_ //ends cmt-1.16/src/freeverb/Components/revmodel.cpp000066400000000000000000000123131112274441100212560ustar00rootroot00000000000000// 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() { // Tie the components to their buffers combL[0].setbuffer(bufcombL1,combtuningL1); combR[0].setbuffer(bufcombR1,combtuningR1); combL[1].setbuffer(bufcombL2,combtuningL2); combR[1].setbuffer(bufcombR2,combtuningR2); combL[2].setbuffer(bufcombL3,combtuningL3); combR[2].setbuffer(bufcombR3,combtuningR3); combL[3].setbuffer(bufcombL4,combtuningL4); combR[3].setbuffer(bufcombR4,combtuningR4); combL[4].setbuffer(bufcombL5,combtuningL5); combR[4].setbuffer(bufcombR5,combtuningR5); combL[5].setbuffer(bufcombL6,combtuningL6); combR[5].setbuffer(bufcombR6,combtuningR6); combL[6].setbuffer(bufcombL7,combtuningL7); combR[6].setbuffer(bufcombR7,combtuningR7); combL[7].setbuffer(bufcombL8,combtuningL8); combR[7].setbuffer(bufcombR8,combtuningR8); allpassL[0].setbuffer(bufallpassL1,allpasstuningL1); allpassR[0].setbuffer(bufallpassR1,allpasstuningR1); allpassL[1].setbuffer(bufallpassL2,allpasstuningL2); allpassR[1].setbuffer(bufallpassR2,allpasstuningR2); allpassL[2].setbuffer(bufallpassL3,allpasstuningL3); allpassR[2].setbuffer(bufallpassR3,allpasstuningR3); allpassL[3].setbuffer(bufallpassL4,allpasstuningL4); allpassR[3].setbuffer(bufallpassR4,allpasstuningR4); // 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 0) { outL = outR = 0; input = (*inputL + *inputR) * gain; // Accumulate comb filters in parallel for(i=0; i 0) { outL = outR = 0; input = (*inputL + *inputR) * gain; // Accumulate comb filters in parallel for(i=0; i= freezemode) { roomsize1 = 1; damp1 = 0; gain = muted; } else { roomsize1 = roomsize; damp1 = damp; gain = fixedgain; } for(i=0; i= freezemode) return 1; else return 0; } //ends cmt-1.16/src/freeverb/Components/revmodel.h000066400000000000000000000041761112274441100207330ustar00rootroot00000000000000// 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" class revmodel { public: revmodel(); 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; // 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]; float bufcombR1[combtuningR1]; float bufcombL2[combtuningL2]; float bufcombR2[combtuningR2]; float bufcombL3[combtuningL3]; float bufcombR3[combtuningR3]; float bufcombL4[combtuningL4]; float bufcombR4[combtuningR4]; float bufcombL5[combtuningL5]; float bufcombR5[combtuningR5]; float bufcombL6[combtuningL6]; float bufcombR6[combtuningR6]; float bufcombL7[combtuningL7]; float bufcombR7[combtuningR7]; float bufcombL8[combtuningL8]; float bufcombR8[combtuningR8]; // Buffers for the allpasses float bufallpassL1[allpasstuningL1]; float bufallpassR1[allpasstuningR1]; float bufallpassL2[allpasstuningL2]; float bufallpassR2[allpasstuningR2]; float bufallpassL3[allpasstuningL3]; float bufallpassR3[allpasstuningR3]; float bufallpassL4[allpasstuningL4]; float bufallpassR4[allpasstuningR4]; }; #endif//_revmodel_ //ends cmt-1.16/src/freeverb/Components/tuning.h000077500000000000000000000035671112274441100204300ustar00rootroot00000000000000// 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 cmt-1.16/src/freeverb/freeverb.cpp000066400000000000000000000132551112274441100171220ustar00rootroot00000000000000/* 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 /*****************************************************************************/ #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) { /* Richard's note 17/5/2000. Hmm - not sure I like the fact that lSampleRate isn't actually used in this function! */ } 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, 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 */ cmt-1.16/src/freeverb/readme.txt000077500000000000000000000155301112274441100166150ustar00rootroot00000000000000Freeverb - 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 cmt-1.16/src/grain.cpp000066400000000000000000000271241112274441100146220ustar00rootroot00000000000000/* 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 #include /*****************************************************************************/ #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, 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 */ cmt-1.16/src/hardgate.cpp000066400000000000000000000057101112274441100152760ustar00rootroot00000000000000/* 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 /*****************************************************************************/ #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, 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 */ cmt-1.16/src/init.cpp000066400000000000000000000074311112274441100144640ustar00rootroot00000000000000/* 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 #include #include /*****************************************************************************/ #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(); } } g_oStartupShutdownHandler; /*****************************************************************************/ const LADSPA_Descriptor * ladspa_descriptor(unsigned long Index) { if (Index < g_lPluginCount) return g_ppsRegisteredDescriptors[Index]; else return NULL; } /*****************************************************************************/ /* EOF */ cmt-1.16/src/ladspa_types.h000066400000000000000000000047731112274441100156640ustar00rootroot00000000000000/* 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 /* 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 */ cmt-1.16/src/lofi.cpp000066400000000000000000000214711112274441100144520ustar00rootroot00000000000000/* 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 #include #include #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; int last_trigger; 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::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); } cmt-1.16/src/logistic.cpp000066400000000000000000000077111112274441100153370ustar00rootroot00000000000000/* 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 /*****************************************************************************/ #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, 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 */ cmt-1.16/src/makefile000066400000000000000000000056141112274441100145160ustar00rootroot00000000000000############################################################################### # # INSTALLATION DIRECTORIES # # Change this if you want to install somewhere else. INSTALL_PLUGINS_DIR = /usr/lib/ladspa/ ############################################################################### # # GENERAL # CFLAGS = $(INCLUDES) -Wall -O3 -fPIC CXXFLAGS = $(CFLAGS) PLUGIN_LIB = ../plugins/cmt.so ############################################################################### # # OBJECT FILES # PLUGIN_OBJECTS = \ am.o \ ambisonic.o \ amp.o \ analogue.o \ canyondelay.o \ cmt.o \ descriptor.o \ delay.o \ dynamic.o \ filter.o \ freeverb/Components/allpass.o \ freeverb/Components/comb.o \ freeverb/Components/revmodel.o \ freeverb/freeverb.o \ grain.o \ init.o \ lofi.o \ mixer.o \ noise.o \ null.o \ organ.o \ peak.o \ phasemod.o \ sine.o \ syndrum.o \ vcf303.o \ wshape_sine.o \ hardgate.o \ disintegrator.o \ pink.o \ pink_full.o \ pink_sh.o \ sledgehammer.o \ logistic.o \ ############################################################################### # # TARGETS # plugin: $(PLUGIN_LIB) targets: $(PLUGIN_LIB) $(PLUGIN_LIB): $(PLUGIN_OBJECTS) $(CXX) -shared \ -o $(PLUGIN_LIB) \ $(PLUGIN_OBJECTS) install: $(PLUGIN_LIB) -strip $(PLUGIN_LIB) cp $(PLUGIN_LIB) $(INSTALL_PLUGINS_DIR) test: /tmp/test.wav ../../ladspa_sdk/snd/noise.wav always @echo --------------------------------------------- @echo First listen to the white noise input signal: @echo --------------------------------------------- play ../../ladspa_sdk/snd/noise.wav @echo ------------------------- @echo Compare to plugin output. @echo ------------------------- @echo Should be a noise band around 6000Hz, repeated quietly after 1s. play /tmp/test.wav /tmp/test.wav: $(PLUGIN_LIB) ../../ladspa_sdk/snd/noise.wav analyseplugin $(PLUGIN_LIB) echo;analyseplugin -l $(PLUGIN_LIB);echo time applyplugin -s 1 \ ../../ladspa_sdk/snd/noise.wav \ /tmp/test.wav \ $(PLUGIN_LIB) lpf 500 \ $(PLUGIN_LIB) lpf 500 \ $(PLUGIN_LIB) sine_fcaa 6000 \ $(PLUGIN_LIB) delay_5s 1 0.1 \ $(PLUGIN_LIB) amp_mono 4 \ ############################################################################### # # UTILITIES # depend: $(MACHINE_GENERATED_CODE) makedepend `find . -name "*.cpp"` $(INCLUDES) always: clean: -rm -f `find . -name "*.o"` ../bin/* ../plugins/* -rm -f `find .. -name "*~"` -rm -f *.bak core score.srt -rm -f *.bb *.bbg *.da *-ann gmon.out bb.out -rm -f `find .. -name "*.class"` backup: clean (cd ../../; \ tar czvf `date '+../backup/cmt.%Y%m%d%H%M.tgz'` cmt/) ############################################################################### cmt-1.16/src/mixer.cpp000066400000000000000000000057431112274441100146510ustar00rootroot00000000000000/* 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 #include /*****************************************************************************/ #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, 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 */ cmt-1.16/src/noise.cpp000066400000000000000000000076061112274441100146420ustar00rootroot00000000000000/* 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 /*****************************************************************************/ #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, 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 */ cmt-1.16/src/null.cpp000066400000000000000000000157241112274441100144770ustar00rootroot00000000000000/* 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 #include /*****************************************************************************/ #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, 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, 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, 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, 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, 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, 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 */ cmt-1.16/src/organ.cpp000066400000000000000000000277721112274441100146410ustar00rootroot00000000000000/* 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 #include #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::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); } cmt-1.16/src/peak.cpp000066400000000000000000000252761112274441100144500ustar00rootroot00000000000000/* 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 #include #include /*****************************************************************************/ #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, 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, 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, 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, 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, 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 */ cmt-1.16/src/phasemod.cpp000066400000000000000000000325631112274441100153250ustar00rootroot00000000000000/* 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 #include #include #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::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); } cmt-1.16/src/pink.cpp000066400000000000000000000161121112274441100144560ustar00rootroot00000000000000/* 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 /*****************************************************************************/ #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; im_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, 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, 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 */ cmt-1.16/src/pink_full.cpp000066400000000000000000000056761112274441100155150ustar00rootroot00000000000000/* 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 /*****************************************************************************/ #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: LADSPA_Data sample_rate; PinkNoise noise_source; 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(); } 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, activate, run, NULL, NULL, NULL); d->addPort (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, "Output"); registerNewPluginDescriptor(d); } } // end of namespace /*****************************************************************************/ /* EOF */ cmt-1.16/src/pink_sh.cpp000066400000000000000000000074421112274441100151560ustar00rootroot00000000000000/* 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 /*****************************************************************************/ #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, 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 */ cmt-1.16/src/pinknoise.h000066400000000000000000000052271112274441100151660ustar00rootroot00000000000000/* 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 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>= 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 cmt-1.16/src/run_adding.h000066400000000000000000000115571112274441100153040ustar00rootroot00000000000000/* 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 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; and the run_adding function as run_foo; 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 /*****************************************************************************/ 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(pfOutput, fValue, poFoo->m_fRunAddingGain); instead of just write_output(...); I realise this feels a bit hacky, but it works. */ template inline void write_control(LADSPA_Data *const, const LADSPA_Data &, const LADSPA_Data &); template <> inline void write_control(LADSPA_Data *const out, const LADSPA_Data &value, const LADSPA_Data &run_adding_gain) { *out = value; } template <> inline void write_control(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(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 fOutputGain will be multiplied by m_fRunAddingGain and in run_foo it will be left alone. This does not make for very clear code, sorry about that. See disintegrator.cpp for an example. */ template inline float get_gain(const LADSPA_Data &); template <> inline float get_gain(const LADSPA_Data &) { return 1.0f; } template <> inline float get_gain(const LADSPA_Data &run_adding_gain) { return run_adding_gain; } cmt-1.16/src/sine.cpp000066400000000000000000000233751112274441100144640ustar00rootroot00000000000000/* 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 #include /*****************************************************************************/ #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, 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 */ cmt-1.16/src/sledgehammer.cpp000066400000000000000000000120271112274441100161530ustar00rootroot00000000000000/* 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 #include /*****************************************************************************/ #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 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 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, activate, run, run, 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 */ cmt-1.16/src/syndrum.cpp000066400000000000000000000113231112274441100152150ustar00rootroot00000000000000/* 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 #include #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::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); } cmt-1.16/src/utils.h000066400000000000000000000060251112274441100143240ustar00rootroot00000000000000/* 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 #include /*****************************************************************************/ #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 */ cmt-1.16/src/vcf303.cpp000066400000000000000000000133141112274441100145220ustar00rootroot00000000000000/* 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 #include #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::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); } cmt-1.16/src/wshape_sine.cpp000066400000000000000000000062331112274441100160250ustar00rootroot00000000000000/* 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 #include /*****************************************************************************/ #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, 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 */