diff options
65 files changed, 11848 insertions, 0 deletions
@@ -0,0 +1,8 @@ +Blop LADSPA plugins: + +Mike Rawes <mike_rawes@yahoo.co.uk> + + +LV2 Port: + +David Robillard <d@drobilla.net>
\ No newline at end of file @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. 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 +them 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 prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. 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. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey 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; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If 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 convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU 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 that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + 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. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +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. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + 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 +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 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, see <http://www.gnu.org/licenses/>. + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + <program> Copyright (C) <year> <name of author> + This program 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, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<http://www.gnu.org/licenses/>. + + The GNU 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 Lesser General +Public License instead of this License. But first, please read +<http://www.gnu.org/philosophy/why-not-lgpl.html>. @@ -0,0 +1,35 @@ +This software requires only Python to build. + +Like an auto* project, building has three phases: + + +* Configure: ./waf configure [OPTIONS] + + Example: + ./waf configure --prefix=/some/where --debug --strict + + If --debug is not given, the flags from the environment variables + CFLAGS and CXXFLAGS will be used. + + The default prefix is /usr/local + + +* Build: ./waf [OPTIONS] + + Example: + ./waf -j4 + + +* Install: ./waf install [OPTIONS] + + The environment variable DESTDIR can be used to add any prefix to + the install paths (useful for packaging). Example: + + DESTDIR=/home/drobilla/packages ./waf install + + +*** IMPORTANT: You must use absolute paths everywhere + + +Run './waf --help' for detailed option information. + @@ -0,0 +1,3 @@ +An LV2 port of the "blop" collection of LADSPA plugins. + +This port is based on blop-0.2.8. diff --git a/blip.lv2/adsr.ttl b/blip.lv2/adsr.ttl new file mode 100644 index 0000000..48e2189 --- /dev/null +++ b/blip.lv2/adsr.ttl @@ -0,0 +1,89 @@ +@prefix blip: <http://drobilla.net/plugins/blip/> . +@prefix dc: <http://purl.org/dc/elements/1.1/> . +@prefix doap: <http://usefulinc.com/ns/doap#> . +@prefix foaf: <http://xmlns.com/foaf/0.1/> . +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . +@prefix owl: <http://www.w3.org/2002/07/owl#> . +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . +@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . +@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . + +blip:adsr + lv2:microVersion 0 ; + lv2:minorVersion 0 ; + lv2:optionalFeature lv2:hardRtCapable ; + lv2:port [ + lv2:index 0 ; + lv2:name "Driving Signal" ; + lv2:symbol "port0" ; + a lv2:AudioPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 1 ; + lv2:name "Trigger Threshold" ; + lv2:symbol "port1" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:default 0 ; + lv2:index 2 ; + lv2:minimum 0 ; + lv2:name "Attack Time (s)" ; + lv2:symbol "port2" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:default 0 ; + lv2:index 3 ; + lv2:minimum 0 ; + lv2:name "Decay Time (s)" ; + lv2:symbol "port3" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:default 1 ; + lv2:index 4 ; + lv2:maximum 1 ; + lv2:minimum 0 ; + lv2:name "Sustain Level" ; + lv2:symbol "port4" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:default 0 ; + lv2:index 5 ; + lv2:minimum 0 ; + lv2:name "Release Time (s)" ; + lv2:symbol "port5" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 6 ; + lv2:name "Envelope Out" ; + lv2:symbol "port6" ; + a lv2:AudioPort , + lv2:OutputPort , + lv2:Port + ] ; + dc:creator "Mike Rawes <mike_rawes[at]yahoo.co.uk>" ; + dc:replaces <urn:ladspa:1653> ; + dc:rights "GPL" ; + doap:name "ADSR Envelope" ; + lv2:documentation """ +<p>Generates an ADSR (Attack, Decay, Sustain and Release) envelope.</p> + +<p>Driven by a gate signal - if the level of the signal goes higher than the +Trigger Threshold, the attack stage begins, proceeds to the decay stage and +then holds at the sustain level. The release stage begins when the gate falls +below this theshold - even if the previous stages have not completed.</p> + +<p>The output is a signal between 0.0 (rest) and 1.0 (peak) and the transitions +are linear.</p> +""" ; + a lv2:Plugin . diff --git a/blip.lv2/adsr_gt.ttl b/blip.lv2/adsr_gt.ttl new file mode 100644 index 0000000..6507897 --- /dev/null +++ b/blip.lv2/adsr_gt.ttl @@ -0,0 +1,95 @@ +@prefix blip: <http://drobilla.net/plugins/blip/> . +@prefix dc: <http://purl.org/dc/elements/1.1/> . +@prefix doap: <http://usefulinc.com/ns/doap#> . +@prefix foaf: <http://xmlns.com/foaf/0.1/> . +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . +@prefix owl: <http://www.w3.org/2002/07/owl#> . +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . +@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . +@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . + +blip:adsr_gt + lv2:microVersion 0 ; + lv2:minorVersion 0 ; + lv2:optionalFeature lv2:hardRtCapable ; + lv2:port [ + lv2:index 0 ; + lv2:name "Gate" ; + lv2:symbol "port0" ; + a lv2:AudioPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 1 ; + lv2:name "Trigger" ; + lv2:symbol "port1" ; + a lv2:AudioPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:default 0 ; + lv2:index 2 ; + lv2:minimum 0 ; + lv2:name "Attack Time (s)" ; + lv2:symbol "port2" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:default 0 ; + lv2:index 3 ; + lv2:minimum 0 ; + lv2:name "Decay Time (s)" ; + lv2:symbol "port3" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:default 1 ; + lv2:index 4 ; + lv2:maximum 1 ; + lv2:minimum 0 ; + lv2:name "Sustain Level" ; + lv2:symbol "port4" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:default 0 ; + lv2:index 5 ; + lv2:minimum 0 ; + lv2:name "Release Time (s)" ; + lv2:symbol "port5" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 6 ; + lv2:name "Envelope Out" ; + lv2:symbol "port6" ; + a lv2:AudioPort , + lv2:OutputPort , + lv2:Port + ] ; + dc:creator "Mike Rawes <mike_rawes[at]yahoo.co.uk>" ; + dc:replaces <urn:ladspa:1680> ; + dc:rights "GPL" ; + doap:name "ADSR Envelope with Gate and Trigger" ; + lv2:documentation """ +<p>Generates an ADSR (Attack, Decay, Sustain and Release) +envelope.</p> + +<p>Does the same thing as the other ADSR (1658) above, except the +Trigger Threshold is fixed at zero, and the additional Trigger +input allows retriggering whilst the gate is still high.</p> + +<p>The reasoning behind this design is to remove the need for a keyboard player +to release a key before pressing another when using with a monosynth. <a +href="http://www.sospubs.co.uk/sos/nov99/articles/synthsecrets.htm">The +‘Synth Secrets’ article in the November 1999 issue of ‘Sound +on Sound’</a> explains this in detail.</p> + +<p>The output is a signal between 0.0 (rest) and 1.0 (peak) and the +transitions are linear.</p> +""" ; + a lv2:Plugin . diff --git a/blip.lv2/amp.ttl b/blip.lv2/amp.ttl new file mode 100644 index 0000000..385008f --- /dev/null +++ b/blip.lv2/amp.ttl @@ -0,0 +1,47 @@ +@prefix blip: <http://drobilla.net/plugins/blip/> . +@prefix dc: <http://purl.org/dc/elements/1.1/> . +@prefix doap: <http://usefulinc.com/ns/doap#> . +@prefix foaf: <http://xmlns.com/foaf/0.1/> . +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . +@prefix owl: <http://www.w3.org/2002/07/owl#> . +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . +@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . +@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . + +blip:amp + lv2:microVersion 0 ; + lv2:minorVersion 0 ; + lv2:optionalFeature lv2:hardRtCapable ; + lv2:port [ + lv2:index 0 ; + lv2:maximum 96 ; + lv2:minimum -96 ; + lv2:name "Gain (dB)" ; + lv2:symbol "port0" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 1 ; + lv2:name "Input" ; + lv2:symbol "port1" ; + a lv2:AudioPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 2 ; + lv2:name "Output" ; + lv2:symbol "port2" ; + a lv2:AudioPort , + lv2:OutputPort , + lv2:Port + ] ; + dc:creator "Mike Rawes <mike_rawes[at]yahoo.co.uk>" ; + dc:replaces <urn:ladspa:1654> , + <urn:ladspa:1655> ; + dc:rights "GPL" ; + doap:name "Amplifier" ; + lv2:documentation """ +<p>A simple monophonic amplifier.</p> +""" ; + a lv2:Plugin , lv2:AmplifierPlugin . diff --git a/blip.lv2/branch.ttl b/blip.lv2/branch.ttl new file mode 100644 index 0000000..69ec27a --- /dev/null +++ b/blip.lv2/branch.ttl @@ -0,0 +1,47 @@ +@prefix blip: <http://drobilla.net/plugins/blip/> . +@prefix dc: <http://purl.org/dc/elements/1.1/> . +@prefix doap: <http://usefulinc.com/ns/doap#> . +@prefix foaf: <http://xmlns.com/foaf/0.1/> . +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . +@prefix owl: <http://www.w3.org/2002/07/owl#> . +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . +@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . +@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . + +blip:branch + lv2:microVersion 0 ; + lv2:minorVersion 0 ; + lv2:optionalFeature lv2:hardRtCapable ; + lv2:port [ + lv2:index 0 ; + lv2:name "Input" ; + lv2:symbol "port0" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 1 ; + lv2:name "First Output" ; + lv2:symbol "port1" ; + a lv2:ControlPort , + lv2:OutputPort , + lv2:Port + ] , [ + lv2:index 2 ; + lv2:name "Second Output" ; + lv2:symbol "port2" ; + a lv2:ControlPort , + lv2:OutputPort , + lv2:Port + ] ; + dc:creator "Mike Rawes <mike_rawes[at]yahoo.co.uk>" ; + dc:replaces <urn:ladspa:1673> , + <urn:ladspa:1674> ; + dc:rights "GPL" ; + doap:name "Signal Branch" ; + lv2:documentation """ +<p>Splits an input signal into two identical signals. Somewhat redundant, as +most modular synth hosts allow you to connect an output to more than one input. +If your host of choice does not allow this, this plugin will do the job...</p> +""" ; + a lv2:Plugin , lv2:UtilityPlugin . diff --git a/blip.lv2/dahdsr.ttl b/blip.lv2/dahdsr.ttl new file mode 100644 index 0000000..3252a75 --- /dev/null +++ b/blip.lv2/dahdsr.ttl @@ -0,0 +1,115 @@ +@prefix blip: <http://drobilla.net/plugins/blip/> . +@prefix dc: <http://purl.org/dc/elements/1.1/> . +@prefix doap: <http://usefulinc.com/ns/doap#> . +@prefix foaf: <http://xmlns.com/foaf/0.1/> . +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . +@prefix owl: <http://www.w3.org/2002/07/owl#> . +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . +@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . +@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . + +blip:dahdsr + lv2:microVersion 0 ; + lv2:minorVersion 0 ; + lv2:optionalFeature lv2:hardRtCapable ; + lv2:port [ + lv2:index 0 ; + lv2:name "Gate" ; + lv2:symbol "port0" ; + a lv2:AudioPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 1 ; + lv2:name "Trigger" ; + lv2:symbol "port1" ; + a lv2:AudioPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:default 0 ; + lv2:index 2 ; + lv2:minimum 0 ; + lv2:name "Delay Time (s)" ; + lv2:symbol "port2" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:default 0 ; + lv2:index 3 ; + lv2:minimum 0 ; + lv2:name "Attack Time (s)" ; + lv2:symbol "port3" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:default 0 ; + lv2:index 4 ; + lv2:minimum 0 ; + lv2:name "Hold Time (s)" ; + lv2:symbol "port4" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:default 0 ; + lv2:index 5 ; + lv2:minimum 0 ; + lv2:name "Decay Time (s)" ; + lv2:symbol "port5" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:default 1 ; + lv2:index 6 ; + lv2:maximum 1 ; + lv2:minimum 0 ; + lv2:name "Sustain Level" ; + lv2:symbol "port6" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:default 0 ; + lv2:index 7 ; + lv2:minimum 0 ; + lv2:name "Release Time (s)" ; + lv2:symbol "port7" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 8 ; + lv2:name "Envelope Out" ; + lv2:symbol "port8" ; + a lv2:AudioPort , + lv2:OutputPort , + lv2:Port + ] ; + dc:creator "Mike Rawes <mike_rawes[at]yahoo.co.uk>" ; + dc:replaces <urn:ladspa:2021> , + <urn:ladspa:2022> , + <urn:ladspa:2038> ; + dc:rights "GPL" ; + doap:name "DAHDSR Envelope with Gate and Trigger" ; + lv2:documentation """ +<p>Generates a DAHDSR (Delay, Attack, Hold, Decay, Sustain, Release) +envelope.</p> + +<p>Another envelope generator, this time with two additional stages - Delay, +which delays the onset of the Attack stage, and Hold, which holds the output at +maximum before the Decay stage begins.</p> + +<p>Triggering works in subtly different ways to the <a href="#adsr_gnt">ADSR +(1680)</a> - the Trigger will restart the envelope even if the Gate is closed - +the effect of this is to proceed through the stages and begin the release stage +immediately after the decay stage.</p> + +<p>The final variant (ID 2038) uses control-rate gate and trigger, which is a +little less CPU hungry, but will cause timing errors that are dependent on the +block size being used by the host.</p> +""" ; + a lv2:Plugin . diff --git a/blip.lv2/difference.ttl b/blip.lv2/difference.ttl new file mode 100644 index 0000000..69c8252 --- /dev/null +++ b/blip.lv2/difference.ttl @@ -0,0 +1,47 @@ +@prefix blip: <http://drobilla.net/plugins/blip/> . +@prefix dc: <http://purl.org/dc/elements/1.1/> . +@prefix doap: <http://usefulinc.com/ns/doap#> . +@prefix foaf: <http://xmlns.com/foaf/0.1/> . +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . +@prefix owl: <http://www.w3.org/2002/07/owl#> . +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . +@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . +@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . + +blip:difference + lv2:microVersion 0 ; + lv2:minorVersion 0 ; + lv2:optionalFeature lv2:hardRtCapable ; + lv2:port [ + lv2:index 0 ; + lv2:name "Input" ; + lv2:symbol "port0" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 1 ; + lv2:name "Input to Subtract" ; + lv2:symbol "port1" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 2 ; + lv2:name "Difference Output" ; + lv2:symbol "port2" ; + a lv2:ControlPort , + lv2:OutputPort , + lv2:Port + ] ; + dc:creator "Mike Rawes <mike_rawes[at]yahoo.co.uk>" ; + dc:replaces <urn:ladspa:2030> , + <urn:ladspa:2031> , + <urn:ladspa:2032> , + <urn:ladspa:2033> ; + dc:rights "GPL" ; + doap:name "Signal Difference" ; + lv2:documentation """ +<p>Subtract two signals.</p> +""" ; + a lv2:Plugin , lv2:UtilityPlugin . diff --git a/blip.lv2/fmod.ttl b/blip.lv2/fmod.ttl new file mode 100644 index 0000000..6bcf033 --- /dev/null +++ b/blip.lv2/fmod.ttl @@ -0,0 +1,52 @@ +@prefix blip: <http://drobilla.net/plugins/blip/> . +@prefix dc: <http://purl.org/dc/elements/1.1/> . +@prefix doap: <http://usefulinc.com/ns/doap#> . +@prefix foaf: <http://xmlns.com/foaf/0.1/> . +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . +@prefix owl: <http://www.w3.org/2002/07/owl#> . +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . +@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . +@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . + +blip:fmod + lv2:microVersion 0 ; + lv2:minorVersion 0 ; + lv2:optionalFeature lv2:hardRtCapable ; + lv2:port [ + lv2:index 0 ; + lv2:maximum 0.5 ; + lv2:minimum "2.08333e-05"^^xsd:double ; + lv2:name "Frequency (Hz)" ; + lv2:portProperty <http://lv2plug.in/ns/dev/extportinfo#logarithmic> , + lv2:sampleRate ; + lv2:symbol "port0" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 1 ; + lv2:name "Modulation (Octaves)" ; + lv2:symbol "port1" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 2 ; + lv2:name "Modulated Frequency (Hz)" ; + lv2:symbol "port2" ; + a lv2:ControlPort , + lv2:OutputPort , + lv2:Port + ] ; + dc:creator "Mike Rawes <mike_rawes[at]yahoo.co.uk>" ; + dc:replaces <urn:ladspa:1656> , + <urn:ladspa:1657> , + <urn:ladspa:1658> , + <urn:ladspa:1659> ; + dc:rights "GPL" ; + doap:name "Frequency Modulator" ; + lv2:documentation """ +<p>Modulates an input frequency by a driving signal, transposing the frequency +by ±1 Octave per unit amplitude of signal.</p> +""" ; + a lv2:Plugin , lv2:SpectralPlugin . diff --git a/blip.lv2/interpolator.ttl b/blip.lv2/interpolator.ttl new file mode 100644 index 0000000..45cc987 --- /dev/null +++ b/blip.lv2/interpolator.ttl @@ -0,0 +1,38 @@ +@prefix blip: <http://drobilla.net/plugins/blip/> . +@prefix dc: <http://purl.org/dc/elements/1.1/> . +@prefix doap: <http://usefulinc.com/ns/doap#> . +@prefix foaf: <http://xmlns.com/foaf/0.1/> . +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . +@prefix owl: <http://www.w3.org/2002/07/owl#> . +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . +@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . +@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . + +blip:interpolator + lv2:microVersion 0 ; + lv2:minorVersion 0 ; + lv2:optionalFeature lv2:hardRtCapable ; + lv2:port [ + lv2:index 0 ; + lv2:name "Control Input" ; + lv2:symbol "port0" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 1 ; + lv2:name "Interpolated Output" ; + lv2:symbol "port1" ; + a lv2:AudioPort , + lv2:OutputPort , + lv2:Port + ] ; + dc:creator "Mike Rawes <mike_rawes[at]yahoo.co.uk>" ; + dc:replaces <urn:ladspa:1660> ; + dc:rights "GPL" ; + doap:name "Control to Audio Interpolator" ; + lv2:documentation """ +<p>Interpolates a control-rate (per-block) signal into a smooth audio +(per-sample) signal.</p> +""" ; + a lv2:Plugin , lv2:UtilityPlugin . diff --git a/blip.lv2/lp4pole.ttl b/blip.lv2/lp4pole.ttl new file mode 100644 index 0000000..4d90d5c --- /dev/null +++ b/blip.lv2/lp4pole.ttl @@ -0,0 +1,63 @@ +@prefix blip: <http://drobilla.net/plugins/blip/> . +@prefix dc: <http://purl.org/dc/elements/1.1/> . +@prefix doap: <http://usefulinc.com/ns/doap#> . +@prefix foaf: <http://xmlns.com/foaf/0.1/> . +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . +@prefix owl: <http://www.w3.org/2002/07/owl#> . +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . +@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . +@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . + +blip:lp4pole + lv2:microVersion 0 ; + lv2:minorVersion 0 ; + lv2:optionalFeature lv2:hardRtCapable ; + lv2:port [ + lv2:default 0.5 ; + lv2:index 0 ; + lv2:maximum 0.5 ; + lv2:minimum "2.08333e-05"^^xsd:double ; + lv2:name "Cutoff Frequency" ; + lv2:portProperty <http://lv2plug.in/ns/dev/extportinfo#logarithmic> , + lv2:sampleRate ; + lv2:symbol "port0" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:default 0 ; + lv2:index 1 ; + lv2:maximum 4 ; + lv2:minimum 0 ; + lv2:name "Resonance" ; + lv2:symbol "port1" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 2 ; + lv2:name "Input" ; + lv2:symbol "port2" ; + a lv2:AudioPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 3 ; + lv2:name "Output" ; + lv2:symbol "port3" ; + a lv2:AudioPort , + lv2:OutputPort , + lv2:Port + ] ; + dc:creator "Mike Rawes <mike_rawes[at]yahoo.co.uk>" ; + dc:replaces <urn:ladspa:1671> , + <urn:ladspa:1672> ; + dc:rights "GPL" ; + doap:name "4 Pole Resonant Low-Pass Filter" ; + lv2:documentation """ +<p>Emulates a low pass filter in popular analogue synthesisers. This particular +filter is derived from one of <a +href="http://www.musicdsp.org/archive.php?classid=3#24">many +implementations</a> of the Moog 4 pole filter.</p> +""" ; + a lv2:Plugin , lv2:LowpassPlugin . diff --git a/blip.lv2/manifest.ttl.in b/blip.lv2/manifest.ttl.in new file mode 100644 index 0000000..e1ceab7 --- /dev/null +++ b/blip.lv2/manifest.ttl.in @@ -0,0 +1,138 @@ +@prefix blip: <http://drobilla.net/plugins/blip/> . +@prefix doap: <http://usefulinc.com/ns/doap#> . +@prefix foaf: <http://xmlns.com/foaf/0.1/> . +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . +@prefix owl: <http://www.w3.org/2002/07/owl#> . +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . +@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . +@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . + +blip:adsr + a lv2:Plugin ; + rdfs:seeAlso <adsr.ttl> ; + lv2:binary <adsr@LIB_EXT@> . + +blip:adsr_gt + a lv2:Plugin ; + rdfs:seeAlso <adsr_gt.ttl> ; + lv2:binary <adsr_gt@LIB_EXT@> . + +blip:amp + a lv2:Plugin ; + rdfs:seeAlso <amp.ttl> ; + lv2:binary <amp@LIB_EXT@> . + +blip:branch + a lv2:Plugin ; + rdfs:seeAlso <branch.ttl> ; + lv2:binary <branch@LIB_EXT@> . + +blip:dahdsr + a lv2:Plugin ; + rdfs:seeAlso <dahdsr.ttl> ; + lv2:binary <dahdsr@LIB_EXT@> . + +blip:difference + a lv2:Plugin ; + rdfs:seeAlso <difference.ttl> ; + lv2:binary <difference@LIB_EXT@> . + +blip:fmod + a lv2:Plugin ; + rdfs:seeAlso <fmod.ttl> ; + lv2:binary <fmod@LIB_EXT@> . + +blip:interpolator + a lv2:Plugin ; + rdfs:seeAlso <interpolator.ttl> ; + lv2:binary <interpolator@LIB_EXT@> . + +blip:lp4pole + a lv2:Plugin ; + rdfs:seeAlso <lp4pole.ttl> ; + lv2:binary <lp4pole@LIB_EXT@> . + +blip:product + a lv2:Plugin ; + rdfs:seeAlso <product.ttl> ; + lv2:binary <product@LIB_EXT@> . + +blip:pulse + a lv2:Plugin ; + rdfs:seeAlso <pulse.ttl> ; + lv2:binary <pulse@LIB_EXT@> . + +blip:quantiser_20 + a lv2:Plugin ; + rdfs:seeAlso <quantiser_20.ttl> ; + lv2:binary <quantiser_20@LIB_EXT@> . + +blip:quantiser_50 + a lv2:Plugin ; + rdfs:seeAlso <quantiser_50.ttl> ; + lv2:binary <quantiser_50@LIB_EXT@> . + +blip:quantiser_100 + a lv2:Plugin ; + rdfs:seeAlso <quantiser_100.ttl> ; + lv2:binary <quantiser_100@LIB_EXT@> . + +blip:random + a lv2:Plugin ; + rdfs:seeAlso <random.ttl> ; + lv2:binary <random@LIB_EXT@> . + +blip:ratio + a lv2:Plugin ; + rdfs:seeAlso <ratio.ttl> ; + lv2:binary <ratio@LIB_EXT@> . + +blip:sawtooth + a lv2:Plugin ; + rdfs:seeAlso <sawtooth.ttl> ; + lv2:binary <sawtooth@LIB_EXT@> . + +blip:sequencer_16 + a lv2:Plugin ; + rdfs:seeAlso <sequencer_16.ttl> ; + lv2:binary <sequencer_16@LIB_EXT@> . + +blip:sequencer_32 + a lv2:Plugin ; + rdfs:seeAlso <sequencer_32.ttl> ; + lv2:binary <sequencer_32@LIB_EXT@> . + +blip:sequencer_64 + a lv2:Plugin ; + rdfs:seeAlso <sequencer_64.ttl> ; + lv2:binary <sequencer_64@LIB_EXT@> . + +blip:square + a lv2:Plugin ; + rdfs:seeAlso <square.ttl> ; + lv2:binary <square@LIB_EXT@> . + +blip:sum + a lv2:Plugin ; + rdfs:seeAlso <sum.ttl> ; + lv2:binary <sum@LIB_EXT@> . + +blip:sync_pulse + a lv2:Plugin ; + rdfs:seeAlso <sync_pulse.ttl> ; + lv2:binary <sync_pulse@LIB_EXT@> . + +blip:sync_square + a lv2:Plugin ; + rdfs:seeAlso <sync_square.ttl> ; + lv2:binary <sync_square@LIB_EXT@> . + +blip:tracker + a lv2:Plugin ; + rdfs:seeAlso <tracker.ttl> ; + lv2:binary <tracker@LIB_EXT@> . + +blip:triangle + a lv2:Plugin ; + rdfs:seeAlso <triangle.ttl> ; + lv2:binary <triangle@LIB_EXT@> . diff --git a/blip.lv2/product.ttl b/blip.lv2/product.ttl new file mode 100644 index 0000000..ee00258 --- /dev/null +++ b/blip.lv2/product.ttl @@ -0,0 +1,46 @@ +@prefix blip: <http://drobilla.net/plugins/blip/> . +@prefix dc: <http://purl.org/dc/elements/1.1/> . +@prefix doap: <http://usefulinc.com/ns/doap#> . +@prefix foaf: <http://xmlns.com/foaf/0.1/> . +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . +@prefix owl: <http://www.w3.org/2002/07/owl#> . +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . +@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . +@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . + +blip:product + lv2:microVersion 0 ; + lv2:minorVersion 0 ; + lv2:optionalFeature lv2:hardRtCapable ; + lv2:port [ + lv2:index 0 ; + lv2:name "First Input" ; + lv2:symbol "port0" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 1 ; + lv2:name "Second Input" ; + lv2:symbol "port1" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 2 ; + lv2:name "Product Output" ; + lv2:symbol "port2" ; + a lv2:ControlPort , + lv2:OutputPort , + lv2:Port + ] ; + dc:creator "Mike Rawes <mike_rawes[at]yahoo.co.uk>" ; + dc:replaces <urn:ladspa:1668> , + <urn:ladspa:1669> , + <urn:ladspa:1670> ; + dc:rights "GPL" ; + doap:name "Signal Product" ; + lv2:documentation """ +<p>Multiply two signals.</p> +""" ; + a lv2:Plugin , lv2:UtilityPlugin . diff --git a/blip.lv2/pulse.ttl b/blip.lv2/pulse.ttl new file mode 100644 index 0000000..0330ab2 --- /dev/null +++ b/blip.lv2/pulse.ttl @@ -0,0 +1,56 @@ +@prefix blip: <http://drobilla.net/plugins/blip/> . +@prefix dc: <http://purl.org/dc/elements/1.1/> . +@prefix doap: <http://usefulinc.com/ns/doap#> . +@prefix foaf: <http://xmlns.com/foaf/0.1/> . +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . +@prefix owl: <http://www.w3.org/2002/07/owl#> . +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . +@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . +@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . + +blip:pulse + lv2:microVersion 0 ; + lv2:minorVersion 0 ; + lv2:optionalFeature lv2:hardRtCapable ; + lv2:port [ + lv2:index 0 ; + lv2:maximum 0.5 ; + lv2:minimum 0.000001 ; + lv2:default 440.0 ; + lv2:name "Frequency" ; + lv2:portProperty <http://lv2plug.in/ns/dev/extportinfo#logarithmic> , + lv2:sampleRate ; + lv2:symbol "port0" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:default 0.5 ; + lv2:index 1 ; + lv2:maximum 1 ; + lv2:minimum 0 ; + lv2:name "Pulse Width" ; + lv2:symbol "port1" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 2 ; + lv2:name "Output" ; + lv2:symbol "port2" ; + a lv2:AudioPort , + lv2:OutputPort , + lv2:Port + ] ; + dc:creator "Mike Rawes <mike_rawes[at]yahoo.co.uk>" ; + dc:replaces <urn:ladspa:1645> , + <urn:ladspa:1646> , + <urn:ladspa:1647> , + <urn:ladspa:1648> ; + dc:rights "GPL" ; + doap:name "Variable Width Pulse Oscillator" ; + lv2:documentation """ +<p>Generates an alias-free pulse wave at given input frequency and pulse width +(duty).</p> +""" ; + a lv2:Plugin , lv2:OscillatorPlugin . diff --git a/blip.lv2/quantiser_100.ttl b/blip.lv2/quantiser_100.ttl new file mode 100644 index 0000000..ca3ee84 --- /dev/null +++ b/blip.lv2/quantiser_100.ttl @@ -0,0 +1,819 @@ +@prefix blip: <http://drobilla.net/plugins/blip/> . +@prefix dc: <http://purl.org/dc/elements/1.1/> . +@prefix doap: <http://usefulinc.com/ns/doap#> . +@prefix foaf: <http://xmlns.com/foaf/0.1/> . +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . +@prefix owl: <http://www.w3.org/2002/07/owl#> . +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . +@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . +@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . + +blip:quantiser_100 + lv2:microVersion 0 ; + lv2:minorVersion 0 ; + lv2:optionalFeature lv2:hardRtCapable ; + lv2:port [ + lv2:index 0 ; + lv2:name "Quantise Range Minimum" ; + lv2:symbol "port0" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 1 ; + lv2:name "Quantise Range Maximum" ; + lv2:symbol "port1" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 10 ; + lv2:name "Value 5" ; + lv2:symbol "port10" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 100 ; + lv2:name "Value 95" ; + lv2:symbol "port100" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 101 ; + lv2:name "Value 96" ; + lv2:symbol "port101" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 102 ; + lv2:name "Value 97" ; + lv2:symbol "port102" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 103 ; + lv2:name "Value 98" ; + lv2:symbol "port103" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 104 ; + lv2:name "Value 99" ; + lv2:symbol "port104" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 105 ; + lv2:name "Input" ; + lv2:symbol "port105" ; + a lv2:AudioPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 106 ; + lv2:name "Quantised Output" ; + lv2:symbol "port106" ; + a lv2:AudioPort , + lv2:OutputPort , + lv2:Port + ] , [ + lv2:index 107 ; + lv2:name "Output Changed" ; + lv2:symbol "port107" ; + a lv2:AudioPort , + lv2:OutputPort , + lv2:Port + ] , [ + lv2:index 11 ; + lv2:name "Value 6" ; + lv2:symbol "port11" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 12 ; + lv2:name "Value 7" ; + lv2:symbol "port12" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 13 ; + lv2:name "Value 8" ; + lv2:symbol "port13" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 14 ; + lv2:name "Value 9" ; + lv2:symbol "port14" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 15 ; + lv2:name "Value 10" ; + lv2:symbol "port15" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 16 ; + lv2:name "Value 11" ; + lv2:symbol "port16" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 17 ; + lv2:name "Value 12" ; + lv2:symbol "port17" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 18 ; + lv2:name "Value 13" ; + lv2:symbol "port18" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 19 ; + lv2:name "Value 14" ; + lv2:symbol "port19" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:default 0 ; + lv2:index 2 ; + lv2:minimum 0 ; + lv2:name "Match Range" ; + lv2:symbol "port2" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 20 ; + lv2:name "Value 15" ; + lv2:symbol "port20" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 21 ; + lv2:name "Value 16" ; + lv2:symbol "port21" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 22 ; + lv2:name "Value 17" ; + lv2:symbol "port22" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 23 ; + lv2:name "Value 18" ; + lv2:symbol "port23" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 24 ; + lv2:name "Value 19" ; + lv2:symbol "port24" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 25 ; + lv2:name "Value 20" ; + lv2:symbol "port25" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 26 ; + lv2:name "Value 21" ; + lv2:symbol "port26" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 27 ; + lv2:name "Value 22" ; + lv2:symbol "port27" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 28 ; + lv2:name "Value 23" ; + lv2:symbol "port28" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 29 ; + lv2:name "Value 24" ; + lv2:symbol "port29" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:default 0 ; + lv2:index 3 ; + lv2:maximum 2 ; + lv2:minimum 0 ; + lv2:name "Mode (0 = Extend, 1 = Wrap, 2 = Clip)" ; + lv2:portProperty lv2:integer ; + lv2:symbol "port3" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 30 ; + lv2:name "Value 25" ; + lv2:symbol "port30" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 31 ; + lv2:name "Value 26" ; + lv2:symbol "port31" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 32 ; + lv2:name "Value 27" ; + lv2:symbol "port32" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 33 ; + lv2:name "Value 28" ; + lv2:symbol "port33" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 34 ; + lv2:name "Value 29" ; + lv2:symbol "port34" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 35 ; + lv2:name "Value 30" ; + lv2:symbol "port35" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 36 ; + lv2:name "Value 31" ; + lv2:symbol "port36" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 37 ; + lv2:name "Value 32" ; + lv2:symbol "port37" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 38 ; + lv2:name "Value 33" ; + lv2:symbol "port38" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 39 ; + lv2:name "Value 34" ; + lv2:symbol "port39" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:default 100 ; + lv2:index 4 ; + lv2:maximum 100 ; + lv2:minimum 1 ; + lv2:name "Steps (1 - 100)" ; + lv2:portProperty lv2:integer ; + lv2:symbol "port4" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 40 ; + lv2:name "Value 35" ; + lv2:symbol "port40" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 41 ; + lv2:name "Value 36" ; + lv2:symbol "port41" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 42 ; + lv2:name "Value 37" ; + lv2:symbol "port42" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 43 ; + lv2:name "Value 38" ; + lv2:symbol "port43" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 44 ; + lv2:name "Value 39" ; + lv2:symbol "port44" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 45 ; + lv2:name "Value 40" ; + lv2:symbol "port45" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 46 ; + lv2:name "Value 41" ; + lv2:symbol "port46" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 47 ; + lv2:name "Value 42" ; + lv2:symbol "port47" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 48 ; + lv2:name "Value 43" ; + lv2:symbol "port48" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 49 ; + lv2:name "Value 44" ; + lv2:symbol "port49" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 5 ; + lv2:name "Value 0" ; + lv2:symbol "port5" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 50 ; + lv2:name "Value 45" ; + lv2:symbol "port50" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 51 ; + lv2:name "Value 46" ; + lv2:symbol "port51" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 52 ; + lv2:name "Value 47" ; + lv2:symbol "port52" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 53 ; + lv2:name "Value 48" ; + lv2:symbol "port53" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 54 ; + lv2:name "Value 49" ; + lv2:symbol "port54" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 55 ; + lv2:name "Value 50" ; + lv2:symbol "port55" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 56 ; + lv2:name "Value 51" ; + lv2:symbol "port56" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 57 ; + lv2:name "Value 52" ; + lv2:symbol "port57" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 58 ; + lv2:name "Value 53" ; + lv2:symbol "port58" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 59 ; + lv2:name "Value 54" ; + lv2:symbol "port59" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 6 ; + lv2:name "Value 1" ; + lv2:symbol "port6" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 60 ; + lv2:name "Value 55" ; + lv2:symbol "port60" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 61 ; + lv2:name "Value 56" ; + lv2:symbol "port61" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 62 ; + lv2:name "Value 57" ; + lv2:symbol "port62" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 63 ; + lv2:name "Value 58" ; + lv2:symbol "port63" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 64 ; + lv2:name "Value 59" ; + lv2:symbol "port64" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 65 ; + lv2:name "Value 60" ; + lv2:symbol "port65" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 66 ; + lv2:name "Value 61" ; + lv2:symbol "port66" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 67 ; + lv2:name "Value 62" ; + lv2:symbol "port67" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 68 ; + lv2:name "Value 63" ; + lv2:symbol "port68" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 69 ; + lv2:name "Value 64" ; + lv2:symbol "port69" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 7 ; + lv2:name "Value 2" ; + lv2:symbol "port7" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 70 ; + lv2:name "Value 65" ; + lv2:symbol "port70" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 71 ; + lv2:name "Value 66" ; + lv2:symbol "port71" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 72 ; + lv2:name "Value 67" ; + lv2:symbol "port72" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 73 ; + lv2:name "Value 68" ; + lv2:symbol "port73" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 74 ; + lv2:name "Value 69" ; + lv2:symbol "port74" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 75 ; + lv2:name "Value 70" ; + lv2:symbol "port75" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 76 ; + lv2:name "Value 71" ; + lv2:symbol "port76" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 77 ; + lv2:name "Value 72" ; + lv2:symbol "port77" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 78 ; + lv2:name "Value 73" ; + lv2:symbol "port78" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 79 ; + lv2:name "Value 74" ; + lv2:symbol "port79" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 8 ; + lv2:name "Value 3" ; + lv2:symbol "port8" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 80 ; + lv2:name "Value 75" ; + lv2:symbol "port80" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 81 ; + lv2:name "Value 76" ; + lv2:symbol "port81" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 82 ; + lv2:name "Value 77" ; + lv2:symbol "port82" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 83 ; + lv2:name "Value 78" ; + lv2:symbol "port83" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 84 ; + lv2:name "Value 79" ; + lv2:symbol "port84" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 85 ; + lv2:name "Value 80" ; + lv2:symbol "port85" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 86 ; + lv2:name "Value 81" ; + lv2:symbol "port86" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 87 ; + lv2:name "Value 82" ; + lv2:symbol "port87" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 88 ; + lv2:name "Value 83" ; + lv2:symbol "port88" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 89 ; + lv2:name "Value 84" ; + lv2:symbol "port89" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 9 ; + lv2:name "Value 4" ; + lv2:symbol "port9" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 90 ; + lv2:name "Value 85" ; + lv2:symbol "port90" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 91 ; + lv2:name "Value 86" ; + lv2:symbol "port91" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 92 ; + lv2:name "Value 87" ; + lv2:symbol "port92" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 93 ; + lv2:name "Value 88" ; + lv2:symbol "port93" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 94 ; + lv2:name "Value 89" ; + lv2:symbol "port94" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 95 ; + lv2:name "Value 90" ; + lv2:symbol "port95" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 96 ; + lv2:name "Value 91" ; + lv2:symbol "port96" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 97 ; + lv2:name "Value 92" ; + lv2:symbol "port97" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 98 ; + lv2:name "Value 93" ; + lv2:symbol "port98" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 99 ; + lv2:name "Value 94" ; + lv2:symbol "port99" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] ; + dc:creator "Mike Rawes <mike_rawes[at]yahoo.co.uk>" ; + dc:replaces <urn:ladspa:2029> ; + dc:rights "GPL" ; + doap:name "Quantiser (100 Steps)" ; + lv2:documentation """ +<p>Quantises a signal to a set of arbitrary values within a range.</p> + +<p>Match Range determines the distance from the quantised value that the input +can deviate before being altered. This allows small variations in input to get +through unmolested. If it is set to 0 the input is quantised to the nearest +exact match.</p> + +<p>Mode is one of Extend (0), Wrap (1) or Clip (2).</p> + +<p>Steps is the number of quantisation steps to use (up to a maximum of +100).</p> + +<p>For example, given the following settings:</p> +<ul> + <li>Range Minimum = 0.0</li> + <li>Range Maximum = 12.0</li> + <li>Match Range = 0.0</li> + <li>Steps = 4</li> + <li>Quantisation Values 3, 5, 7 and 10</li> +</ul> + +<p>and an input that is a line from -24 to 24, the output will be:</p> +<ul> + <li>Extend: -26, -21, -19, -17, -14, -9, -7, -5, -2, 3, 5, 7, 10, 15, 17, 19, + 22</li> + <li>Wrap: 10, 3, 5, 7, 10, 3, 5, 7, 10, 3, 5, 7, 10, 3, 5, 7, 10</li> + <li>Clip: 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 7, 10, 10, 10, 10, 10</li> +</ul> + +<p>The quantisation values should all be within the range minimum and maximum +for it to work!</p> +""" ; + a lv2:Plugin . diff --git a/blip.lv2/quantiser_20.ttl b/blip.lv2/quantiser_20.ttl new file mode 100644 index 0000000..5bded34 --- /dev/null +++ b/blip.lv2/quantiser_20.ttl @@ -0,0 +1,259 @@ +@prefix blip: <http://drobilla.net/plugins/blip/> . +@prefix dc: <http://purl.org/dc/elements/1.1/> . +@prefix doap: <http://usefulinc.com/ns/doap#> . +@prefix foaf: <http://xmlns.com/foaf/0.1/> . +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . +@prefix owl: <http://www.w3.org/2002/07/owl#> . +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . +@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . +@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . + +blip:quantiser_20 + lv2:microVersion 0 ; + lv2:minorVersion 0 ; + lv2:optionalFeature lv2:hardRtCapable ; + lv2:port [ + lv2:index 0 ; + lv2:name "Quantise Range Minimum" ; + lv2:symbol "port0" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 1 ; + lv2:name "Quantise Range Maximum" ; + lv2:symbol "port1" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 10 ; + lv2:name "Value 5" ; + lv2:symbol "port10" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 11 ; + lv2:name "Value 6" ; + lv2:symbol "port11" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 12 ; + lv2:name "Value 7" ; + lv2:symbol "port12" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 13 ; + lv2:name "Value 8" ; + lv2:symbol "port13" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 14 ; + lv2:name "Value 9" ; + lv2:symbol "port14" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 15 ; + lv2:name "Value 10" ; + lv2:symbol "port15" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 16 ; + lv2:name "Value 11" ; + lv2:symbol "port16" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 17 ; + lv2:name "Value 12" ; + lv2:symbol "port17" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 18 ; + lv2:name "Value 13" ; + lv2:symbol "port18" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 19 ; + lv2:name "Value 14" ; + lv2:symbol "port19" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:default 0 ; + lv2:index 2 ; + lv2:minimum 0 ; + lv2:name "Match Range" ; + lv2:symbol "port2" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 20 ; + lv2:name "Value 15" ; + lv2:symbol "port20" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 21 ; + lv2:name "Value 16" ; + lv2:symbol "port21" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 22 ; + lv2:name "Value 17" ; + lv2:symbol "port22" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 23 ; + lv2:name "Value 18" ; + lv2:symbol "port23" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 24 ; + lv2:name "Value 19" ; + lv2:symbol "port24" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 25 ; + lv2:name "Input" ; + lv2:symbol "port25" ; + a lv2:AudioPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 26 ; + lv2:name "Quantised Output" ; + lv2:symbol "port26" ; + a lv2:AudioPort , + lv2:OutputPort , + lv2:Port + ] , [ + lv2:index 27 ; + lv2:name "Output Changed" ; + lv2:symbol "port27" ; + a lv2:AudioPort , + lv2:OutputPort , + lv2:Port + ] , [ + lv2:default 0 ; + lv2:index 3 ; + lv2:maximum 2 ; + lv2:minimum 0 ; + lv2:name "Mode (0 = Extend, 1 = Wrap, 2 = Clip)" ; + lv2:portProperty lv2:integer ; + lv2:symbol "port3" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:default 20 ; + lv2:index 4 ; + lv2:maximum 20 ; + lv2:minimum 1 ; + lv2:name "Steps (1 - 20)" ; + lv2:portProperty lv2:integer ; + lv2:symbol "port4" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 5 ; + lv2:name "Value 0" ; + lv2:symbol "port5" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 6 ; + lv2:name "Value 1" ; + lv2:symbol "port6" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 7 ; + lv2:name "Value 2" ; + lv2:symbol "port7" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 8 ; + lv2:name "Value 3" ; + lv2:symbol "port8" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 9 ; + lv2:name "Value 4" ; + lv2:symbol "port9" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] ; + dc:creator "Mike Rawes <mike_rawes[at]yahoo.co.uk>" ; + dc:replaces <urn:ladspa:2027> ; + dc:rights "GPL" ; + doap:name "Quantiser (20 Steps)" ; + lv2:documentation """ +<p>Quantises a signal to a set of arbitrary values within a range.</p> + +<p>Match Range determines the distance from the quantised value that the input +can deviate before being altered. This allows small variations in input to get +through unmolested. If it is set to 0 the input is quantised to the nearest +exact match.</p> + +<p>Mode is one of Extend (0), Wrap (1) or Clip (2).</p> + +<p>Steps is the number of quantisation steps to use (up to a maximum of +20).</p> + +<p>For example, given the following settings:</p> +<ul> + <li>Range Minimum = 0.0</li> + <li>Range Maximum = 12.0</li> + <li>Match Range = 0.0</li> + <li>Steps = 4</li> + <li>Quantisation Values 3, 5, 7 and 10</li> +</ul> + +<p>and an input that is a line from -24 to 24, the output will be:</p> +<ul> + <li>Extend: -26, -21, -19, -17, -14, -9, -7, -5, -2, 3, 5, 7, 10, 15, 17, 19, + 22</li> + <li>Wrap: 10, 3, 5, 7, 10, 3, 5, 7, 10, 3, 5, 7, 10, 3, 5, 7, 10</li> + <li>Clip: 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 7, 10, 10, 10, 10, 10</li> +</ul> + +<p>The quantisation values should all be within the range minimum and maximum +for it to work!</p> +""" ; + a lv2:Plugin . diff --git a/blip.lv2/quantiser_50.ttl b/blip.lv2/quantiser_50.ttl new file mode 100644 index 0000000..223cb0e --- /dev/null +++ b/blip.lv2/quantiser_50.ttl @@ -0,0 +1,469 @@ +@prefix blip: <http://drobilla.net/plugins/blip/> . +@prefix dc: <http://purl.org/dc/elements/1.1/> . +@prefix doap: <http://usefulinc.com/ns/doap#> . +@prefix foaf: <http://xmlns.com/foaf/0.1/> . +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . +@prefix owl: <http://www.w3.org/2002/07/owl#> . +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . +@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . +@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . + +blip:quantiser_50 + lv2:microVersion 0 ; + lv2:minorVersion 0 ; + lv2:optionalFeature lv2:hardRtCapable ; + lv2:port [ + lv2:index 0 ; + lv2:name "Quantise Range Minimum" ; + lv2:symbol "port0" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 1 ; + lv2:name "Quantise Range Maximum" ; + lv2:symbol "port1" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 10 ; + lv2:name "Value 5" ; + lv2:symbol "port10" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 11 ; + lv2:name "Value 6" ; + lv2:symbol "port11" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 12 ; + lv2:name "Value 7" ; + lv2:symbol "port12" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 13 ; + lv2:name "Value 8" ; + lv2:symbol "port13" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 14 ; + lv2:name "Value 9" ; + lv2:symbol "port14" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 15 ; + lv2:name "Value 10" ; + lv2:symbol "port15" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 16 ; + lv2:name "Value 11" ; + lv2:symbol "port16" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 17 ; + lv2:name "Value 12" ; + lv2:symbol "port17" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 18 ; + lv2:name "Value 13" ; + lv2:symbol "port18" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 19 ; + lv2:name "Value 14" ; + lv2:symbol "port19" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:default 0 ; + lv2:index 2 ; + lv2:minimum 0 ; + lv2:name "Match Range" ; + lv2:symbol "port2" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 20 ; + lv2:name "Value 15" ; + lv2:symbol "port20" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 21 ; + lv2:name "Value 16" ; + lv2:symbol "port21" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 22 ; + lv2:name "Value 17" ; + lv2:symbol "port22" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 23 ; + lv2:name "Value 18" ; + lv2:symbol "port23" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 24 ; + lv2:name "Value 19" ; + lv2:symbol "port24" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 25 ; + lv2:name "Value 20" ; + lv2:symbol "port25" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 26 ; + lv2:name "Value 21" ; + lv2:symbol "port26" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 27 ; + lv2:name "Value 22" ; + lv2:symbol "port27" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 28 ; + lv2:name "Value 23" ; + lv2:symbol "port28" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 29 ; + lv2:name "Value 24" ; + lv2:symbol "port29" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:default 0 ; + lv2:index 3 ; + lv2:maximum 2 ; + lv2:minimum 0 ; + lv2:name "Mode (0 = Extend, 1 = Wrap, 2 = Clip)" ; + lv2:portProperty lv2:integer ; + lv2:symbol "port3" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 30 ; + lv2:name "Value 25" ; + lv2:symbol "port30" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 31 ; + lv2:name "Value 26" ; + lv2:symbol "port31" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 32 ; + lv2:name "Value 27" ; + lv2:symbol "port32" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 33 ; + lv2:name "Value 28" ; + lv2:symbol "port33" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 34 ; + lv2:name "Value 29" ; + lv2:symbol "port34" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 35 ; + lv2:name "Value 30" ; + lv2:symbol "port35" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 36 ; + lv2:name "Value 31" ; + lv2:symbol "port36" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 37 ; + lv2:name "Value 32" ; + lv2:symbol "port37" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 38 ; + lv2:name "Value 33" ; + lv2:symbol "port38" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 39 ; + lv2:name "Value 34" ; + lv2:symbol "port39" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:default 50 ; + lv2:index 4 ; + lv2:maximum 50 ; + lv2:minimum 1 ; + lv2:name "Steps (1 - 50)" ; + lv2:portProperty lv2:integer ; + lv2:symbol "port4" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 40 ; + lv2:name "Value 35" ; + lv2:symbol "port40" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 41 ; + lv2:name "Value 36" ; + lv2:symbol "port41" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 42 ; + lv2:name "Value 37" ; + lv2:symbol "port42" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 43 ; + lv2:name "Value 38" ; + lv2:symbol "port43" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 44 ; + lv2:name "Value 39" ; + lv2:symbol "port44" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 45 ; + lv2:name "Value 40" ; + lv2:symbol "port45" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 46 ; + lv2:name "Value 41" ; + lv2:symbol "port46" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 47 ; + lv2:name "Value 42" ; + lv2:symbol "port47" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 48 ; + lv2:name "Value 43" ; + lv2:symbol "port48" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 49 ; + lv2:name "Value 44" ; + lv2:symbol "port49" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 5 ; + lv2:name "Value 0" ; + lv2:symbol "port5" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 50 ; + lv2:name "Value 45" ; + lv2:symbol "port50" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 51 ; + lv2:name "Value 46" ; + lv2:symbol "port51" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 52 ; + lv2:name "Value 47" ; + lv2:symbol "port52" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 53 ; + lv2:name "Value 48" ; + lv2:symbol "port53" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 54 ; + lv2:name "Value 49" ; + lv2:symbol "port54" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 55 ; + lv2:name "Input" ; + lv2:symbol "port55" ; + a lv2:AudioPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 56 ; + lv2:name "Quantised Output" ; + lv2:symbol "port56" ; + a lv2:AudioPort , + lv2:OutputPort , + lv2:Port + ] , [ + lv2:index 57 ; + lv2:name "Output Changed" ; + lv2:symbol "port57" ; + a lv2:AudioPort , + lv2:OutputPort , + lv2:Port + ] , [ + lv2:index 6 ; + lv2:name "Value 1" ; + lv2:symbol "port6" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 7 ; + lv2:name "Value 2" ; + lv2:symbol "port7" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 8 ; + lv2:name "Value 3" ; + lv2:symbol "port8" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 9 ; + lv2:name "Value 4" ; + lv2:symbol "port9" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] ; + dc:creator "Mike Rawes <mike_rawes[at]yahoo.co.uk>" ; + dc:replaces <urn:ladspa:2028> ; + dc:rights "GPL" ; + doap:name "Quantiser (50 Steps)" ; + lv2:documentation """ +<p>Quantises a signal to a set of arbitrary values within a range.</p> + +<p>Match Range determines the distance from the quantised value that the input +can deviate before being altered. This allows small variations in input to get +through unmolested. If it is set to 0 the input is quantised to the nearest +exact match.</p> + +<p>Mode is one of Extend (0), Wrap (1) or Clip (2).</p> + +<p>Steps is the number of quantisation steps to use (up to a maximum of +50).</p> + +<p>For example, given the following settings:</p> +<ul> + <li>Range Minimum = 0.0</li> + <li>Range Maximum = 12.0</li> + <li>Match Range = 0.0</li> + <li>Steps = 4</li> + <li>Quantisation Values 3, 5, 7 and 10</li> +</ul> + +<p>and an input that is a line from -24 to 24, the output will be:</p> +<ul> + <li>Extend: -26, -21, -19, -17, -14, -9, -7, -5, -2, 3, 5, 7, 10, 15, 17, 19, + 22</li> + <li>Wrap: 10, 3, 5, 7, 10, 3, 5, 7, 10, 3, 5, 7, 10, 3, 5, 7, 10</li> + <li>Clip: 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 7, 10, 10, 10, 10, 10</li> +</ul> + +<p>The quantisation values should all be within the range minimum and maximum +for it to work!</p> +""" ; + a lv2:Plugin . diff --git a/blip.lv2/random.ttl b/blip.lv2/random.ttl new file mode 100644 index 0000000..9e44e4a --- /dev/null +++ b/blip.lv2/random.ttl @@ -0,0 +1,59 @@ +@prefix blip: <http://drobilla.net/plugins/blip/> . +@prefix dc: <http://purl.org/dc/elements/1.1/> . +@prefix doap: <http://usefulinc.com/ns/doap#> . +@prefix foaf: <http://xmlns.com/foaf/0.1/> . +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . +@prefix owl: <http://www.w3.org/2002/07/owl#> . +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . +@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . +@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . + +blip:random + lv2:microVersion 0 ; + lv2:minorVersion 0 ; + lv2:optionalFeature lv2:hardRtCapable ; + lv2:port [ + lv2:index 0 ; + lv2:maximum 0.5 ; + lv2:minimum 0.000001 ; + lv2:default 440.0 ; + lv2:name "Frequency (Hz)" ; + lv2:portProperty <http://lv2plug.in/ns/dev/extportinfo#logarithmic> , + lv2:sampleRate ; + lv2:symbol "port0" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:default 1 ; + lv2:index 1 ; + lv2:maximum 1 ; + lv2:minimum 0 ; + lv2:name "Wave Smoothness" ; + lv2:symbol "port1" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 2 ; + lv2:name "Output" ; + lv2:symbol "port2" ; + a lv2:AudioPort , + lv2:OutputPort , + lv2:Port + ] ; + dc:creator "Mike Rawes <mike_rawes[at]yahoo.co.uk>" ; + dc:replaces <urn:ladspa:1661> , + <urn:ladspa:1662> , + <urn:ladspa:1663> , + <urn:ladspa:1664> ; + dc:rights "GPL" ; + doap:name "Random Wave Generator" ; + lv2:documentation """ +<p>Generates a random waveform of varying frequency and smoothness. The +frequency determines how often the output changes. The smoothness, how quickly +a transition occurs.</p> + +<p>The output varies between ±1, with an even distribution.</p> +""" ; + a lv2:Plugin , lv2:OscillatorPlugin . diff --git a/blip.lv2/ratio.ttl b/blip.lv2/ratio.ttl new file mode 100644 index 0000000..712a27c --- /dev/null +++ b/blip.lv2/ratio.ttl @@ -0,0 +1,48 @@ +@prefix blip: <http://drobilla.net/plugins/blip/> . +@prefix dc: <http://purl.org/dc/elements/1.1/> . +@prefix doap: <http://usefulinc.com/ns/doap#> . +@prefix foaf: <http://xmlns.com/foaf/0.1/> . +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . +@prefix owl: <http://www.w3.org/2002/07/owl#> . +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . +@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . +@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . + +blip:ratio + lv2:microVersion 0 ; + lv2:minorVersion 0 ; + lv2:optionalFeature lv2:hardRtCapable ; + lv2:port [ + lv2:index 0 ; + lv2:name "Numerator" ; + lv2:symbol "port0" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 1 ; + lv2:name "Denominator" ; + lv2:symbol "port1" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 2 ; + lv2:name "Ratio Output" ; + lv2:symbol "port2" ; + a lv2:ControlPort , + lv2:OutputPort , + lv2:Port + ] ; + dc:creator "Mike Rawes <mike_rawes[at]yahoo.co.uk>" ; + dc:replaces <urn:ladspa:2034> , + <urn:ladspa:2035> , + <urn:ladspa:2036> , + <urn:ladspa:2037> ; + dc:rights "GPL" ; + doap:name "Signal Ratio" ; + lv2:documentation """ +<p>Get the ratio between two signals.</p> +<p>To avoid divisions by zero, 0 is treated as a really small number.</p> +""" ; + a lv2:Plugin , lv2:UtilityPlugin . diff --git a/blip.lv2/sawtooth.ttl b/blip.lv2/sawtooth.ttl new file mode 100644 index 0000000..097ffde --- /dev/null +++ b/blip.lv2/sawtooth.ttl @@ -0,0 +1,43 @@ +@prefix blip: <http://drobilla.net/plugins/blip/> . +@prefix dc: <http://purl.org/dc/elements/1.1/> . +@prefix doap: <http://usefulinc.com/ns/doap#> . +@prefix foaf: <http://xmlns.com/foaf/0.1/> . +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . +@prefix owl: <http://www.w3.org/2002/07/owl#> . +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . +@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . +@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . + +blip:sawtooth + lv2:microVersion 0 ; + lv2:minorVersion 0 ; + lv2:optionalFeature lv2:hardRtCapable ; + lv2:port [ + lv2:index 0 ; + lv2:maximum 0.5 ; + lv2:minimum 0.000001 ; + lv2:default 440.0 ; + lv2:name "Frequency" ; + lv2:portProperty <http://lv2plug.in/ns/dev/extportinfo#logarithmic> , + lv2:sampleRate ; + lv2:symbol "port0" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 1 ; + lv2:name "Output" ; + lv2:symbol "port1" ; + a lv2:AudioPort , + lv2:OutputPort , + lv2:Port + ] ; + dc:creator "Mike Rawes <mike_rawes[at]yahoo.co.uk>" ; + dc:replaces <urn:ladspa:1642> , + <urn:ladspa:1643> ; + dc:rights "GPL" ; + doap:name "Sawtooth Oscillator" ; + lv2:documentation """ +<p>Generates an alias-free sawtooth wave at given input frequency.</p> +""" ; + a lv2:Plugin , lv2:OscillatorPlugin . diff --git a/blip.lv2/sequencer_16.ttl b/blip.lv2/sequencer_16.ttl new file mode 100644 index 0000000..12eeb5c --- /dev/null +++ b/blip.lv2/sequencer_16.ttl @@ -0,0 +1,191 @@ +@prefix blip: <http://drobilla.net/plugins/blip/> . +@prefix dc: <http://purl.org/dc/elements/1.1/> . +@prefix doap: <http://usefulinc.com/ns/doap#> . +@prefix foaf: <http://xmlns.com/foaf/0.1/> . +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . +@prefix owl: <http://www.w3.org/2002/07/owl#> . +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . +@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . +@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . + +blip:sequencer_16 + lv2:microVersion 0 ; + lv2:minorVersion 0 ; + lv2:optionalFeature lv2:hardRtCapable ; + lv2:port [ + lv2:index 0 ; + lv2:name "Gate (Open > 0)" ; + lv2:symbol "port0" ; + a lv2:AudioPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 1 ; + lv2:name "Step Trigger" ; + lv2:symbol "port1" ; + a lv2:AudioPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 10 ; + lv2:name "Value Step 5" ; + lv2:symbol "port10" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 11 ; + lv2:name "Value Step 6" ; + lv2:symbol "port11" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 12 ; + lv2:name "Value Step 7" ; + lv2:symbol "port12" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 13 ; + lv2:name "Value Step 8" ; + lv2:symbol "port13" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 14 ; + lv2:name "Value Step 9" ; + lv2:symbol "port14" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 15 ; + lv2:name "Value Step 10" ; + lv2:symbol "port15" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 16 ; + lv2:name "Value Step 11" ; + lv2:symbol "port16" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 17 ; + lv2:name "Value Step 12" ; + lv2:symbol "port17" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 18 ; + lv2:name "Value Step 13" ; + lv2:symbol "port18" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 19 ; + lv2:name "Value Step 14" ; + lv2:symbol "port19" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:default 16 ; + lv2:index 2 ; + lv2:maximum 16 ; + lv2:minimum 1 ; + lv2:name "Loop Steps (1 - 16)" ; + lv2:portProperty lv2:integer ; + lv2:symbol "port2" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 20 ; + lv2:name "Value Step 15" ; + lv2:symbol "port20" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 21 ; + lv2:name "Value Out" ; + lv2:symbol "port21" ; + a lv2:AudioPort , + lv2:OutputPort , + lv2:Port + ] , [ + lv2:default 0 ; + lv2:index 3 ; + lv2:maximum 1 ; + lv2:minimum 0 ; + lv2:name "Reset to Value on Gate Close?" ; + lv2:portProperty lv2:integer ; + lv2:symbol "port3" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 4 ; + lv2:name "Closed Gate Value" ; + lv2:symbol "port4" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 5 ; + lv2:name "Value Step 0" ; + lv2:symbol "port5" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 6 ; + lv2:name "Value Step 1" ; + lv2:symbol "port6" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 7 ; + lv2:name "Value Step 2" ; + lv2:symbol "port7" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 8 ; + lv2:name "Value Step 3" ; + lv2:symbol "port8" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 9 ; + lv2:name "Value Step 4" ; + lv2:symbol "port9" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] ; + dc:creator "Mike Rawes <mike_rawes[at]yahoo.co.uk>" ; + dc:replaces <urn:ladspa:1677> ; + dc:rights "GPL" ; + doap:name "Analogue Style 16 Step Sequencer" ; + lv2:documentation """ +<p>Simulates an analogue step sequencer. The sequencer stores a number of +values which are stepped through using a trigger when the gate is open, looping +after a given number of steps. This variant has 16 steps.</p> + +<p>When the gate is closed, the sequencer returns to the start. Output when +the gate is closed can be set to a default value. If not, it will just output +the last value reached before the gate was closed.</p> +""" ; + a lv2:Plugin . diff --git a/blip.lv2/sequencer_32.ttl b/blip.lv2/sequencer_32.ttl new file mode 100644 index 0000000..7a29477 --- /dev/null +++ b/blip.lv2/sequencer_32.ttl @@ -0,0 +1,303 @@ +@prefix blip: <http://drobilla.net/plugins/blip/> . +@prefix dc: <http://purl.org/dc/elements/1.1/> . +@prefix doap: <http://usefulinc.com/ns/doap#> . +@prefix foaf: <http://xmlns.com/foaf/0.1/> . +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . +@prefix owl: <http://www.w3.org/2002/07/owl#> . +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . +@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . +@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . + +blip:sequencer_32 + lv2:microVersion 0 ; + lv2:minorVersion 0 ; + lv2:optionalFeature lv2:hardRtCapable ; + lv2:port [ + lv2:index 0 ; + lv2:name "Gate (Open > 0)" ; + lv2:symbol "port0" ; + a lv2:AudioPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 1 ; + lv2:name "Step Trigger" ; + lv2:symbol "port1" ; + a lv2:AudioPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 10 ; + lv2:name "Value Step 5" ; + lv2:symbol "port10" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 11 ; + lv2:name "Value Step 6" ; + lv2:symbol "port11" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 12 ; + lv2:name "Value Step 7" ; + lv2:symbol "port12" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 13 ; + lv2:name "Value Step 8" ; + lv2:symbol "port13" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 14 ; + lv2:name "Value Step 9" ; + lv2:symbol "port14" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 15 ; + lv2:name "Value Step 10" ; + lv2:symbol "port15" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 16 ; + lv2:name "Value Step 11" ; + lv2:symbol "port16" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 17 ; + lv2:name "Value Step 12" ; + lv2:symbol "port17" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 18 ; + lv2:name "Value Step 13" ; + lv2:symbol "port18" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 19 ; + lv2:name "Value Step 14" ; + lv2:symbol "port19" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:default 32 ; + lv2:index 2 ; + lv2:maximum 32 ; + lv2:minimum 1 ; + lv2:name "Loop Steps (1 - 32)" ; + lv2:portProperty lv2:integer ; + lv2:symbol "port2" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 20 ; + lv2:name "Value Step 15" ; + lv2:symbol "port20" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 21 ; + lv2:name "Value Step 16" ; + lv2:symbol "port21" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 22 ; + lv2:name "Value Step 17" ; + lv2:symbol "port22" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 23 ; + lv2:name "Value Step 18" ; + lv2:symbol "port23" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 24 ; + lv2:name "Value Step 19" ; + lv2:symbol "port24" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 25 ; + lv2:name "Value Step 20" ; + lv2:symbol "port25" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 26 ; + lv2:name "Value Step 21" ; + lv2:symbol "port26" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 27 ; + lv2:name "Value Step 22" ; + lv2:symbol "port27" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 28 ; + lv2:name "Value Step 23" ; + lv2:symbol "port28" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 29 ; + lv2:name "Value Step 24" ; + lv2:symbol "port29" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:default 0 ; + lv2:index 3 ; + lv2:maximum 1 ; + lv2:minimum 0 ; + lv2:name "Reset to Value on Gate Close?" ; + lv2:portProperty lv2:integer ; + lv2:symbol "port3" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 30 ; + lv2:name "Value Step 25" ; + lv2:symbol "port30" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 31 ; + lv2:name "Value Step 26" ; + lv2:symbol "port31" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 32 ; + lv2:name "Value Step 27" ; + lv2:symbol "port32" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 33 ; + lv2:name "Value Step 28" ; + lv2:symbol "port33" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 34 ; + lv2:name "Value Step 29" ; + lv2:symbol "port34" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 35 ; + lv2:name "Value Step 30" ; + lv2:symbol "port35" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 36 ; + lv2:name "Value Step 31" ; + lv2:symbol "port36" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 37 ; + lv2:name "Value Out" ; + lv2:symbol "port37" ; + a lv2:AudioPort , + lv2:OutputPort , + lv2:Port + ] , [ + lv2:index 4 ; + lv2:name "Closed Gate Value" ; + lv2:symbol "port4" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 5 ; + lv2:name "Value Step 0" ; + lv2:symbol "port5" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 6 ; + lv2:name "Value Step 1" ; + lv2:symbol "port6" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 7 ; + lv2:name "Value Step 2" ; + lv2:symbol "port7" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 8 ; + lv2:name "Value Step 3" ; + lv2:symbol "port8" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 9 ; + lv2:name "Value Step 4" ; + lv2:symbol "port9" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] ; + dc:creator "Mike Rawes <mike_rawes[at]yahoo.co.uk>" ; + dc:replaces <urn:ladspa:1676> ; + dc:rights "GPL" ; + doap:name "Analogue Style 32 Step Sequencer" ; + lv2:documentation """ +<p>Simulates an analogue step sequencer. The sequencer stores a number of +values which are stepped through using a trigger when the gate is open, looping +after a given number of steps. This variant has 32 steps.</p> + +<p>When the gate is closed, the sequencer returns to the start. Output when +the gate is closed can be set to a default value. If not, it will just output +the last value reached before the gate was closed.</p> +""" ; + a lv2:Plugin . diff --git a/blip.lv2/sequencer_64.ttl b/blip.lv2/sequencer_64.ttl new file mode 100644 index 0000000..5e8efe8 --- /dev/null +++ b/blip.lv2/sequencer_64.ttl @@ -0,0 +1,527 @@ +@prefix blip: <http://drobilla.net/plugins/blip/> . +@prefix dc: <http://purl.org/dc/elements/1.1/> . +@prefix doap: <http://usefulinc.com/ns/doap#> . +@prefix foaf: <http://xmlns.com/foaf/0.1/> . +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . +@prefix owl: <http://www.w3.org/2002/07/owl#> . +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . +@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . +@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . + +blip:sequencer_64 + lv2:microVersion 0 ; + lv2:minorVersion 0 ; + lv2:optionalFeature lv2:hardRtCapable ; + lv2:port [ + lv2:index 0 ; + lv2:name "Gate (Open > 0)" ; + lv2:symbol "port0" ; + a lv2:AudioPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 1 ; + lv2:name "Step Trigger" ; + lv2:symbol "port1" ; + a lv2:AudioPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 10 ; + lv2:name "Value Step 5" ; + lv2:symbol "port10" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 11 ; + lv2:name "Value Step 6" ; + lv2:symbol "port11" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 12 ; + lv2:name "Value Step 7" ; + lv2:symbol "port12" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 13 ; + lv2:name "Value Step 8" ; + lv2:symbol "port13" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 14 ; + lv2:name "Value Step 9" ; + lv2:symbol "port14" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 15 ; + lv2:name "Value Step 10" ; + lv2:symbol "port15" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 16 ; + lv2:name "Value Step 11" ; + lv2:symbol "port16" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 17 ; + lv2:name "Value Step 12" ; + lv2:symbol "port17" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 18 ; + lv2:name "Value Step 13" ; + lv2:symbol "port18" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 19 ; + lv2:name "Value Step 14" ; + lv2:symbol "port19" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:default 64 ; + lv2:index 2 ; + lv2:maximum 64 ; + lv2:minimum 1 ; + lv2:name "Loop Steps (1 - 64)" ; + lv2:portProperty lv2:integer ; + lv2:symbol "port2" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 20 ; + lv2:name "Value Step 15" ; + lv2:symbol "port20" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 21 ; + lv2:name "Value Step 16" ; + lv2:symbol "port21" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 22 ; + lv2:name "Value Step 17" ; + lv2:symbol "port22" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 23 ; + lv2:name "Value Step 18" ; + lv2:symbol "port23" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 24 ; + lv2:name "Value Step 19" ; + lv2:symbol "port24" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 25 ; + lv2:name "Value Step 20" ; + lv2:symbol "port25" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 26 ; + lv2:name "Value Step 21" ; + lv2:symbol "port26" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 27 ; + lv2:name "Value Step 22" ; + lv2:symbol "port27" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 28 ; + lv2:name "Value Step 23" ; + lv2:symbol "port28" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 29 ; + lv2:name "Value Step 24" ; + lv2:symbol "port29" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:default 0 ; + lv2:index 3 ; + lv2:maximum 1 ; + lv2:minimum 0 ; + lv2:name "Reset to Value on Gate Close?" ; + lv2:portProperty lv2:integer ; + lv2:symbol "port3" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 30 ; + lv2:name "Value Step 25" ; + lv2:symbol "port30" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 31 ; + lv2:name "Value Step 26" ; + lv2:symbol "port31" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 32 ; + lv2:name "Value Step 27" ; + lv2:symbol "port32" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 33 ; + lv2:name "Value Step 28" ; + lv2:symbol "port33" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 34 ; + lv2:name "Value Step 29" ; + lv2:symbol "port34" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 35 ; + lv2:name "Value Step 30" ; + lv2:symbol "port35" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 36 ; + lv2:name "Value Step 31" ; + lv2:symbol "port36" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 37 ; + lv2:name "Value Step 32" ; + lv2:symbol "port37" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 38 ; + lv2:name "Value Step 33" ; + lv2:symbol "port38" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 39 ; + lv2:name "Value Step 34" ; + lv2:symbol "port39" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 4 ; + lv2:name "Closed Gate Value" ; + lv2:symbol "port4" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 40 ; + lv2:name "Value Step 35" ; + lv2:symbol "port40" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 41 ; + lv2:name "Value Step 36" ; + lv2:symbol "port41" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 42 ; + lv2:name "Value Step 37" ; + lv2:symbol "port42" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 43 ; + lv2:name "Value Step 38" ; + lv2:symbol "port43" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 44 ; + lv2:name "Value Step 39" ; + lv2:symbol "port44" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 45 ; + lv2:name "Value Step 40" ; + lv2:symbol "port45" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 46 ; + lv2:name "Value Step 41" ; + lv2:symbol "port46" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 47 ; + lv2:name "Value Step 42" ; + lv2:symbol "port47" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 48 ; + lv2:name "Value Step 43" ; + lv2:symbol "port48" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 49 ; + lv2:name "Value Step 44" ; + lv2:symbol "port49" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 5 ; + lv2:name "Value Step 0" ; + lv2:symbol "port5" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 50 ; + lv2:name "Value Step 45" ; + lv2:symbol "port50" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 51 ; + lv2:name "Value Step 46" ; + lv2:symbol "port51" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 52 ; + lv2:name "Value Step 47" ; + lv2:symbol "port52" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 53 ; + lv2:name "Value Step 48" ; + lv2:symbol "port53" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 54 ; + lv2:name "Value Step 49" ; + lv2:symbol "port54" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 55 ; + lv2:name "Value Step 50" ; + lv2:symbol "port55" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 56 ; + lv2:name "Value Step 51" ; + lv2:symbol "port56" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 57 ; + lv2:name "Value Step 52" ; + lv2:symbol "port57" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 58 ; + lv2:name "Value Step 53" ; + lv2:symbol "port58" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 59 ; + lv2:name "Value Step 54" ; + lv2:symbol "port59" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 6 ; + lv2:name "Value Step 1" ; + lv2:symbol "port6" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 60 ; + lv2:name "Value Step 55" ; + lv2:symbol "port60" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 61 ; + lv2:name "Value Step 56" ; + lv2:symbol "port61" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 62 ; + lv2:name "Value Step 57" ; + lv2:symbol "port62" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 63 ; + lv2:name "Value Step 58" ; + lv2:symbol "port63" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 64 ; + lv2:name "Value Step 59" ; + lv2:symbol "port64" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 65 ; + lv2:name "Value Step 60" ; + lv2:symbol "port65" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 66 ; + lv2:name "Value Step 61" ; + lv2:symbol "port66" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 67 ; + lv2:name "Value Step 62" ; + lv2:symbol "port67" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 68 ; + lv2:name "Value Step 63" ; + lv2:symbol "port68" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 69 ; + lv2:name "Value Out" ; + lv2:symbol "port69" ; + a lv2:AudioPort , + lv2:OutputPort , + lv2:Port + ] , [ + lv2:index 7 ; + lv2:name "Value Step 2" ; + lv2:symbol "port7" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 8 ; + lv2:name "Value Step 3" ; + lv2:symbol "port8" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 9 ; + lv2:name "Value Step 4" ; + lv2:symbol "port9" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] ; + dc:creator "Mike Rawes <mike_rawes[at]yahoo.co.uk>" ; + dc:replaces <urn:ladspa:1675> ; + dc:rights "GPL" ; + doap:name "Analogue Style 64 Step Sequencer" ; + lv2:documentation """ +<p>Simulates an analogue step sequencer. The sequencer stores a number of +values which are stepped through using a trigger when the gate is open, looping +after a given number of steps. This variant has 64 steps.</p> + +<p>When the gate is closed, the sequencer returns to the start. Output when +the gate is closed can be set to a default value. If not, it will just output +the last value reached before the gate was closed.</p> +""" ; + a lv2:Plugin . diff --git a/blip.lv2/square.ttl b/blip.lv2/square.ttl new file mode 100644 index 0000000..709e83e --- /dev/null +++ b/blip.lv2/square.ttl @@ -0,0 +1,43 @@ +@prefix blip: <http://drobilla.net/plugins/blip/> . +@prefix dc: <http://purl.org/dc/elements/1.1/> . +@prefix doap: <http://usefulinc.com/ns/doap#> . +@prefix foaf: <http://xmlns.com/foaf/0.1/> . +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . +@prefix owl: <http://www.w3.org/2002/07/owl#> . +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . +@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . +@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . + +blip:square + lv2:microVersion 0 ; + lv2:minorVersion 0 ; + lv2:optionalFeature lv2:hardRtCapable ; + lv2:port [ + lv2:index 0 ; + lv2:maximum 0.5 ; + lv2:minimum 0.000001 ; + lv2:default 440.0 ; + lv2:name "Frequency" ; + lv2:portProperty <http://lv2plug.in/ns/dev/extportinfo#logarithmic> , + lv2:sampleRate ; + lv2:symbol "port0" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 1 ; + lv2:name "Output" ; + lv2:symbol "port1" ; + a lv2:AudioPort , + lv2:OutputPort , + lv2:Port + ] ; + dc:creator "Mike Rawes <mike_rawes[at]yahoo.co.uk>" ; + dc:replaces <urn:ladspa:1643> , + <urn:ladspa:1644> ; + dc:rights "GPL" ; + doap:name "Square Oscillator" ; + lv2:documentation """ +<p>Generates an alias-free square wave at given input frequency.</p> +""" ; + a lv2:Plugin , lv2:OscillatorPlugin . diff --git a/blip.lv2/sum.ttl b/blip.lv2/sum.ttl new file mode 100644 index 0000000..c6021ed --- /dev/null +++ b/blip.lv2/sum.ttl @@ -0,0 +1,46 @@ +@prefix blip: <http://drobilla.net/plugins/blip/> . +@prefix dc: <http://purl.org/dc/elements/1.1/> . +@prefix doap: <http://usefulinc.com/ns/doap#> . +@prefix foaf: <http://xmlns.com/foaf/0.1/> . +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . +@prefix owl: <http://www.w3.org/2002/07/owl#> . +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . +@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . +@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . + +blip:sum + lv2:microVersion 0 ; + lv2:minorVersion 0 ; + lv2:optionalFeature lv2:hardRtCapable ; + lv2:port [ + lv2:index 0 ; + lv2:name "First Input" ; + lv2:symbol "port0" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 1 ; + lv2:name "Second Input" ; + lv2:symbol "port1" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 2 ; + lv2:name "Summed Output" ; + lv2:symbol "port2" ; + a lv2:ControlPort , + lv2:OutputPort , + lv2:Port + ] ; + dc:creator "Mike Rawes <mike_rawes[at]yahoo.co.uk>" ; + dc:replaces <urn:ladspa:1665> , + <urn:ladspa:1666> , + <urn:ladspa:1667> ; + dc:rights "GPL" ; + doap:name "Signal Sum" ; + lv2:documentation """ +<p>Add two signals.</p> +""" ; + a lv2:Plugin , lv2:UtilityPlugin . diff --git a/blip.lv2/sync_pulse.ttl b/blip.lv2/sync_pulse.ttl new file mode 100644 index 0000000..3807222 --- /dev/null +++ b/blip.lv2/sync_pulse.ttl @@ -0,0 +1,59 @@ +@prefix blip: <http://drobilla.net/plugins/blip/> . +@prefix dc: <http://purl.org/dc/elements/1.1/> . +@prefix doap: <http://usefulinc.com/ns/doap#> . +@prefix foaf: <http://xmlns.com/foaf/0.1/> . +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . +@prefix owl: <http://www.w3.org/2002/07/owl#> . +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . +@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . +@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . + +blip:sync_pulse + lv2:microVersion 0 ; + lv2:minorVersion 0 ; + lv2:optionalFeature lv2:hardRtCapable ; + lv2:port [ + lv2:default 16 ; + lv2:index 0 ; + lv2:maximum 64 ; + lv2:minimum 0 ; + lv2:name "Frequency" ; + lv2:symbol "port0" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:default 0.5 ; + lv2:index 1 ; + lv2:maximum 1 ; + lv2:minimum 0 ; + lv2:name "Pulse Width" ; + lv2:symbol "port1" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 2 ; + lv2:name "Gate" ; + lv2:symbol "port2" ; + a lv2:AudioPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 3 ; + lv2:name "Output" ; + lv2:symbol "port3" ; + a lv2:AudioPort , + lv2:OutputPort , + lv2:Port + ] ; + dc:creator "Mike Rawes <mike_rawes[at]yahoo.co.uk>" ; + dc:replaces <urn:ladspa:2023> , + <urn:ladspa:2024> ; + dc:rights "GPL" ; + doap:name "Clock Pulse Oscillator with Gate" ; + lv2:documentation """ +<p>Same as the <a href="http://drobilla.net/plugins/blip/sync_square">Clock +Oscillator</a>, but with pulse-width modulation.</p> +""" ; + a lv2:Plugin , lv2:OscillatorPlugin . diff --git a/blip.lv2/sync_square.ttl b/blip.lv2/sync_square.ttl new file mode 100644 index 0000000..80cd65b --- /dev/null +++ b/blip.lv2/sync_square.ttl @@ -0,0 +1,52 @@ +@prefix blip: <http://drobilla.net/plugins/blip/> . +@prefix dc: <http://purl.org/dc/elements/1.1/> . +@prefix doap: <http://usefulinc.com/ns/doap#> . +@prefix foaf: <http://xmlns.com/foaf/0.1/> . +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . +@prefix owl: <http://www.w3.org/2002/07/owl#> . +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . +@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . +@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . + +blip:sync_square + lv2:microVersion 0 ; + lv2:minorVersion 0 ; + lv2:optionalFeature lv2:hardRtCapable ; + lv2:port [ + lv2:default 16 ; + lv2:index 0 ; + lv2:maximum 64 ; + lv2:minimum 0 ; + lv2:name "Frequency" ; + lv2:symbol "port0" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 1 ; + lv2:name "Gate" ; + lv2:symbol "port1" ; + a lv2:AudioPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 2 ; + lv2:name "Output" ; + lv2:symbol "port2" ; + a lv2:AudioPort , + lv2:OutputPort , + lv2:Port + ] ; + dc:creator "Mike Rawes <mike_rawes[at]yahoo.co.uk>" ; + dc:replaces <urn:ladspa:1678> , + <urn:ladspa:1679> ; + dc:rights "GPL" ; + doap:name "Clock Oscillator with Gate" ; + lv2:documentation """ +<p>Generates a non-bandlimited simple square waveform for use as a clock. +Useful for triggering the sequencers, or anything else that uses a clock +signal.</p> + +<p>When the gate is closed, it outputs silence, and the phase is reset.</p> +""" ; + a lv2:Plugin , lv2:OscillatorPlugin . diff --git a/blip.lv2/tracker.ttl b/blip.lv2/tracker.ttl new file mode 100644 index 0000000..9cb32e0 --- /dev/null +++ b/blip.lv2/tracker.ttl @@ -0,0 +1,115 @@ +@prefix blip: <http://drobilla.net/plugins/blip/> . +@prefix dc: <http://purl.org/dc/elements/1.1/> . +@prefix doap: <http://usefulinc.com/ns/doap#> . +@prefix foaf: <http://xmlns.com/foaf/0.1/> . +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . +@prefix owl: <http://www.w3.org/2002/07/owl#> . +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . +@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . +@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . + +blip:tracker + lv2:microVersion 0 ; + lv2:minorVersion 0 ; + lv2:optionalFeature lv2:hardRtCapable ; + lv2:port [ + lv2:index 0 ; + lv2:name "Gate" ; + lv2:symbol "port0" ; + a lv2:AudioPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:default 100 ; + lv2:index 1 ; + lv2:maximum 0.5 ; + lv2:minimum "2.08333e-05"^^xsd:double ; + lv2:name "Attack Rate (Hz) when Gate High" ; + lv2:portProperty <http://lv2plug.in/ns/dev/extportinfo#logarithmic> , + lv2:sampleRate ; + lv2:symbol "port1" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:default 100 ; + lv2:index 2 ; + lv2:maximum 0.5 ; + lv2:minimum "2.08333e-05"^^xsd:double ; + lv2:name "Decay Rate (Hz) when Gate High" ; + lv2:portProperty <http://lv2plug.in/ns/dev/extportinfo#logarithmic> , + lv2:sampleRate ; + lv2:symbol "port2" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:default 100 ; + lv2:index 3 ; + lv2:maximum 0.5 ; + lv2:minimum "2.08333e-05"^^xsd:double ; + lv2:name "Attack Rate (Hz) when Gate Low" ; + lv2:portProperty <http://lv2plug.in/ns/dev/extportinfo#logarithmic> , + lv2:sampleRate ; + lv2:symbol "port3" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:default 100 ; + lv2:index 4 ; + lv2:maximum 0.5 ; + lv2:minimum "2.08333e-05"^^xsd:double ; + lv2:name "Decay Rate (Hz) when Gate Low" ; + lv2:portProperty <http://lv2plug.in/ns/dev/extportinfo#logarithmic> , + lv2:sampleRate ; + lv2:symbol "port4" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 5 ; + lv2:name "Input" ; + lv2:symbol "port5" ; + a lv2:AudioPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 6 ; + lv2:name "Output" ; + lv2:symbol "port6" ; + a lv2:AudioPort , + lv2:OutputPort , + lv2:Port + ] ; + dc:creator "Mike Rawes <mike_rawes[at]yahoo.co.uk>" ; + dc:replaces <urn:ladspa:2025> , + <urn:ladspa:2026> ; + dc:rights "GPL" ; + doap:name "Signal Tracker" ; + lv2:documentation """ +<p>This tracks an incoming signal and outputs the result.</p> +<p>The rate controls tell the plugin how quickly to respond to a change in +input. Low values will mean a slower response - a setting of 0 will hold the +last value, and a very high value will track the input exactly.</p> +<p>Attack rate is how quickly an upward change is tracked, and Decay for +downward changes. There are two pairs of these - the one used depends on the +level of the Gate.</p> +<p>Example uses:</p> +<ul> + <li> + <em>An envelope tracker</em>- use the ‘Gate Low’ track rates with + the Gate held low, and run the output through a full-wave rectifier (an ABS() + operator) to get an estimate of the level of a signal.</li> + <li> + <em>Sample and Hold</em>- run a narrow pulse wave into the gate, set the + ‘Gate High’ rates to maximum, and the ‘Gate Low’ + rates set to 0.</li> + <li> + <em>Track and Hold</em>- run a variable pulse wave into the gate, set the + ‘Gate High’ rates to 0, and the ‘Gate Low’ rates set + high. Varying the pulsewidth will vary the time the input is tracked, and + when it is held.</li> +</ul> +""" ; + a lv2:Plugin . diff --git a/blip.lv2/triangle.ttl b/blip.lv2/triangle.ttl new file mode 100644 index 0000000..105fb82 --- /dev/null +++ b/blip.lv2/triangle.ttl @@ -0,0 +1,57 @@ +@prefix blip: <http://drobilla.net/plugins/blip/> . +@prefix dc: <http://purl.org/dc/elements/1.1/> . +@prefix doap: <http://usefulinc.com/ns/doap#> . +@prefix foaf: <http://xmlns.com/foaf/0.1/> . +@prefix lv2: <http://lv2plug.in/ns/lv2core#> . +@prefix owl: <http://www.w3.org/2002/07/owl#> . +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . +@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . +@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . + +blip:triangle + lv2:microVersion 0 ; + lv2:minorVersion 0 ; + lv2:optionalFeature lv2:hardRtCapable ; + lv2:port [ + lv2:index 0 ; + lv2:maximum 0.5 ; + lv2:minimum 0.000001 ; + lv2:default 440.0 ; + lv2:name "Frequency" ; + lv2:portProperty <http://lv2plug.in/ns/dev/extportinfo#logarithmic> , + lv2:sampleRate ; + lv2:symbol "port0" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:default 0.5 ; + lv2:index 1 ; + lv2:maximum 1 ; + lv2:minimum 0 ; + lv2:name "Slope" ; + lv2:symbol "port1" ; + a lv2:ControlPort , + lv2:InputPort , + lv2:Port + ] , [ + lv2:index 2 ; + lv2:name "Output" ; + lv2:symbol "port2" ; + a lv2:AudioPort , + lv2:OutputPort , + lv2:Port + ] ; + dc:creator "Mike Rawes <mike_rawes[at]yahoo.co.uk>" ; + dc:replaces <urn:ladspa:1649> , + <urn:ladspa:1650> , + <urn:ladspa:1651> , + <urn:ladspa:1652> ; + dc:rights "GPL" ; + doap:name "Variable Slope Triangle Oscillator" ; + lv2:documentation """ +<p>Generates an alias-free variable slope triangle wave at given input +frequency and slope. The slope changes the wave shape from sawtooth to +triangle.</p> +""" ; + a lv2:Plugin , lv2:OscillatorPlugin . diff --git a/src/adsr.c b/src/adsr.c new file mode 100644 index 0000000..ef4b27e --- /dev/null +++ b/src/adsr.c @@ -0,0 +1,256 @@ +/* + An LV2 plugin to generate ADSR envelopes. + Copyright 2011 David Robillard + Copyright 2002 Mike Rawes + + This 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 3 of the License, or + (at your option) any later version. + + This software 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 software. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdlib.h> +#include "lv2/lv2plug.in/ns/lv2core/lv2.h" +#include "common.h" + +#define ADSR_SIGNAL 0 +#define ADSR_TRIGGER 1 +#define ADSR_ATTACK 2 +#define ADSR_DECAY 3 +#define ADSR_SUSTAIN 4 +#define ADSR_RELEASE 5 +#define ADSR_OUTPUT 6 + +typedef enum { + IDLE, + ATTACK, + DECAY, + SUSTAIN, + RELEASE +} ADSRState; + +typedef struct { + float* signal; + float* trigger; + float* attack; + float* decay; + float* sustain; + float* release; + float* output; + float srate; + float inv_srate; + float from_level; + float level; + ADSRState state; + uint32_t samples; +} Adsr; + +static void +cleanup(LV2_Handle instance) +{ + free(instance); +} + +static void +connect_port(LV2_Handle instance, + uint32_t port, + void* data) +{ + Adsr* plugin = (Adsr*)instance; + + switch (port) { + case ADSR_SIGNAL: + plugin->signal = data; + break; + case ADSR_TRIGGER: + plugin->trigger = data; + break; + case ADSR_ATTACK: + plugin->attack = data; + break; + case ADSR_DECAY: + plugin->decay = data; + break; + case ADSR_SUSTAIN: + plugin->sustain = data; + break; + case ADSR_RELEASE: + plugin->release = data; + break; + case ADSR_OUTPUT: + plugin->output = data; + break; + } +} + +static LV2_Handle +instantiate(const LV2_Descriptor* descriptor, + double sample_rate, + const char* bundle_path, + const LV2_Feature* const* features) +{ + Adsr* plugin = (Adsr*)malloc(sizeof(Adsr)); + + plugin->srate = (float)sample_rate; + plugin->inv_srate = 1.0f / plugin->srate; + + return (LV2_Handle)plugin; +} + +static void +activate(LV2_Handle instance) +{ + Adsr* plugin = (Adsr*)instance; + + plugin->from_level = 0.0f; + plugin->level = 0.0f; + plugin->state = IDLE; + plugin->samples = 0; +} + +static void +runAdsr(LV2_Handle instance, + uint32_t sample_count) +{ + Adsr* plugin = (Adsr*)instance; + + /* Driving signal */ + float* signal = plugin->signal; + + /* Trigger Threshold */ + float trigger = *(plugin->trigger); + + /* Attack Time (s) */ + float attack = *(plugin->attack); + + /* Decay Time (s) */ + float decay = *(plugin->decay); + + /* Sustain Level */ + float sustain = f_clip(*(plugin->sustain), 0.0f, 1.0f); + + /* Release Time (s) */ + float release = *(plugin->release); + + /* Envelope Out */ + float* output = plugin->output; + + float srate = plugin->srate; + float inv_srate = plugin->inv_srate; + float from_level = plugin->from_level; + float level = plugin->level; + ADSRState state = plugin->state; + uint32_t samples = plugin->samples; + + float elapsed; + + /* Convert times into rates */ + attack = attack > 0.0f ? inv_srate / attack : srate; + decay = decay > 0.0f ? inv_srate / decay : srate; + release = release > 0.0f ? inv_srate / release : srate; + + for (uint32_t s = 0; s < sample_count; s++) { + /* Determine if attack or release happened */ + if ((state == IDLE) || (state == RELEASE)) { + if (signal[s] > trigger) { + if (attack < srate) { + state = ATTACK; + } else { + state = decay < srate ? DECAY : SUSTAIN; + level = 1.0f; + } + samples = 0; + } + } else { + if (signal[s] <= trigger) { + state = release < srate ? RELEASE : IDLE; + samples = 0; + } + } + + if (samples == 0) { + from_level = level; + } + + /* Calculate level of envelope from current state */ + switch (state) { + case IDLE: + level = 0; + break; + case ATTACK: + samples++; + elapsed = (float)samples * attack; + if (elapsed > 1.0f) { + state = decay < srate ? DECAY : SUSTAIN; + level = 1.0f; + samples = 0; + } else { + level = from_level + elapsed * (1.0f - from_level); + } + break; + case DECAY: + samples++; + elapsed = (float)samples * decay; + if (elapsed > 1.0f) { + state = SUSTAIN; + level = sustain; + samples = 0; + } else { + level = from_level + elapsed * (sustain - from_level); + } + break; + case SUSTAIN: + level = sustain; + break; + case RELEASE: + samples++; + elapsed = (float)samples * release; + if (elapsed > 1.0f) { + state = IDLE; + level = 0.0f; + samples = 0; + } else { + level = from_level - elapsed * from_level; + } + break; + default: + /* Should never happen */ + level = 0.0f; + } + + output[s] = level; + } + + plugin->from_level = from_level; + plugin->level = level; + plugin->state = state; + plugin->samples = samples; +} + +static const LV2_Descriptor descriptor = { + "http://drobilla.net/plugins/blip/adsr", + instantiate, + connect_port, + activate, + runAdsr, + NULL, + cleanup, + NULL, +}; + +LV2_SYMBOL_EXPORT const LV2_Descriptor* +lv2_descriptor(uint32_t index) +{ + switch (index) { + case 0: return &descriptor; + default: return NULL; + } +} diff --git a/src/adsr_gt.c b/src/adsr_gt.c new file mode 100644 index 0000000..f9aa225 --- /dev/null +++ b/src/adsr_gt.c @@ -0,0 +1,264 @@ +/* + An LV2 plugin to generate ADSR envelopes Gate and Trigger variant. + Copyright 2011 David Robillard + Copyright 2002 Mike Rawes + + This 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 3 of the License, or + (at your option) any later version. + + This software 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 software. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdlib.h> +#include "lv2/lv2plug.in/ns/lv2core/lv2.h" +#include "common.h" + +#define ADSR_GATE 0 +#define ADSR_TRIGGER 1 +#define ADSR_ATTACK 2 +#define ADSR_DECAY 3 +#define ADSR_SUSTAIN 4 +#define ADSR_RELEASE 5 +#define ADSR_OUTPUT 6 + +typedef enum { + IDLE, + ATTACK, + DECAY, + SUSTAIN, + RELEASE +} ADSRState; + +typedef struct { + float* gate; + float* trigger; + float* attack; + float* decay; + float* sustain; + float* release; + float* output; + float srate; + float inv_srate; + float last_trigger; + float from_level; + float level; + ADSRState state; + uint32_t samples; +} Adsr; + +static void +cleanup(LV2_Handle instance) +{ + free(instance); +} + +static void +connect_port(LV2_Handle instance, + uint32_t port, + void* data) +{ + Adsr* plugin = (Adsr*)instance; + + switch (port) { + case ADSR_GATE: + plugin->gate = data; + break; + case ADSR_TRIGGER: + plugin->trigger = data; + break; + case ADSR_ATTACK: + plugin->attack = data; + break; + case ADSR_DECAY: + plugin->decay = data; + break; + case ADSR_SUSTAIN: + plugin->sustain = data; + break; + case ADSR_RELEASE: + plugin->release = data; + break; + case ADSR_OUTPUT: + plugin->output = data; + break; + } +} + +static LV2_Handle +instantiate(const LV2_Descriptor* descriptor, + double sample_rate, + const char* bundle_path, + const LV2_Feature* const* features) +{ + Adsr* plugin = (Adsr*)malloc(sizeof(Adsr)); + + plugin->srate = (float)sample_rate; + plugin->inv_srate = 1.0f / plugin->srate; + + return (LV2_Handle)plugin; +} + +static void +activate(LV2_Handle instance) +{ + Adsr* plugin = (Adsr*)instance; + + plugin->last_trigger = 0.0f; + plugin->from_level = 0.0f; + plugin->level = 0.0f; + plugin->state = IDLE; + plugin->samples = 0; +} + +static void +runAdsr(LV2_Handle instance, + uint32_t sample_count) +{ + Adsr* plugin = (Adsr*)instance; + + /* Gate */ + float* gate = plugin->gate; + + /* Trigger */ + float* trigger = plugin->trigger; + + /* Attack Time (s) */ + float attack = *(plugin->attack); + + /* Decay Time (s) */ + float decay = *(plugin->decay); + + /* Sustain Level */ + float sustain = f_clip(*(plugin->sustain), 0.0f, 1.0f); + + /* Release Time (s) */ + float release = *(plugin->release); + + /* Envelope Out */ + float* output = plugin->output; + + float srate = plugin->srate; + float inv_srate = plugin->inv_srate; + float last_trigger = plugin->last_trigger; + float from_level = plugin->from_level; + float level = plugin->level; + ADSRState state = plugin->state; + uint32_t samples = plugin->samples; + + float elapsed; + + /* Convert times into rates */ + attack = attack > 0.0f ? inv_srate / attack : srate; + decay = decay > 0.0f ? inv_srate / decay : srate; + release = release > 0.0f ? inv_srate / release : srate; + + for (uint32_t s = 0; s < sample_count; ++s) { + /* Attack on trigger, if gate is open */ + if (trigger[s] > 0.0f + && !(last_trigger > 0.0f) + && gate[s] > 0.0f) { + if (attack < srate) { + state = ATTACK; + } else { + state = decay < srate ? DECAY : SUSTAIN; + level = 1.0f; + } + samples = 0; + } + + /* Release if gate closed */ + if (state != IDLE + && state != RELEASE + && !(gate[s] > 0.0f)) { + state = release < srate ? RELEASE : IDLE; + samples = 0; + } + + if (samples == 0) { + from_level = level; + } + + /* Calculate level of envelope from current state */ + switch (state) { + case IDLE: + level = 0; + break; + case ATTACK: + samples++; + elapsed = (float)samples * attack; + if (elapsed > 1.0f) { + state = decay < srate ? DECAY : SUSTAIN; + level = 1.0f; + samples = 0; + } else { + level = from_level + elapsed * (1.0f - from_level); + } + break; + case DECAY: + samples++; + elapsed = (float)samples * decay; + if (elapsed > 1.0f) { + state = SUSTAIN; + level = sustain; + samples = 0; + } else { + level = from_level + elapsed * (sustain - from_level); + } + break; + case SUSTAIN: + level = sustain; + break; + case RELEASE: + samples++; + elapsed = (float)samples * release; + if (elapsed > 1.0f) { + state = IDLE; + level = 0.0f; + samples = 0; + } else { + level = from_level - elapsed * from_level; + } + break; + default: + /* Should never happen */ + level = 0.0f; + } + + output[s] = level; + last_trigger = trigger[s]; + } + + plugin->last_trigger = last_trigger; + plugin->from_level = from_level; + plugin->level = level; + plugin->state = state; + plugin->samples = samples; +} + +static const LV2_Descriptor descriptor = { + "http://drobilla.net/plugins/blip/adsr_gt", + instantiate, + connect_port, + activate, + runAdsr, + NULL, + cleanup, + NULL, +}; + +LV2_SYMBOL_EXPORT const LV2_Descriptor* +lv2_descriptor(uint32_t index) +{ + switch (index) { + case 0: return &descriptor; + default: return NULL; + } +} diff --git a/src/amp.c b/src/amp.c new file mode 100644 index 0000000..4c528f9 --- /dev/null +++ b/src/amp.c @@ -0,0 +1,142 @@ +/* + An LV2 plugin representing a simple mono amplifier. + Copyright 2011 David Robillard + Copyright 2002 Mike Rawes + + This 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 3 of the License, or + (at your option) any later version. + + This software 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 software. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdlib.h> +#include "lv2/lv2plug.in/ns/lv2core/lv2.h" +#include "math_func.h" + +#define AMP_GAIN 0 +#define AMP_INPUT 1 +#define AMP_OUTPUT 2 + +typedef struct { + const float* gain; + const float* input; + float* output; +} Amp; + +static void +cleanup(LV2_Handle instance) +{ + free(instance); +} + +static void +connect_port(LV2_Handle instance, + uint32_t port, + void* data) +{ + Amp* plugin = (Amp*)instance; + + switch (port) { + case AMP_GAIN: + plugin->gain = data; + break; + case AMP_INPUT: + plugin->input = data; + break; + case AMP_OUTPUT: + plugin->output = data; + break; + } +} + +static LV2_Handle +instantiate(const LV2_Descriptor* descriptor, + double sample_rate, + const char* bundle_path, + const LV2_Feature* const* features) +{ + Amp* plugin = (Amp*)malloc(sizeof(Amp)); + + return (LV2_Handle)plugin; +} + +static void +runAmp_gaia_oa(LV2_Handle instance, + uint32_t sample_count) +{ + Amp* plugin = (Amp*)instance; + + /* Gain (dB) */ + const float* gain = plugin->gain; + + /* Input */ + const float* input = plugin->input; + + /* Output */ + float* output = plugin->output; + + float gn; + float in; + float scale; + + for (uint32_t s = 0; s < sample_count; ++s) { + gn = gain[s]; + in = input[s]; + + scale = (float)EXPF(M_LN10 * gn * 0.05f); + + output[s] = scale * in; + } +} + +static void +runAmp_gcia_oa(LV2_Handle instance, + uint32_t sample_count) +{ + Amp* plugin = (Amp*)instance; + + /* Gain (dB) */ + const float gain = *(plugin->gain); + + /* Input */ + const float* input = plugin->input; + + /* Output */ + float* output = plugin->output; + + float in; + float scale = (float)EXPF(M_LN10 * gain * 0.05f); + for (uint32_t s = 0; s < sample_count; s++) { + in = input[s]; + + output[s] = scale * in; + } +} + +static const LV2_Descriptor descriptor = { + "http://drobilla.net/plugins/blip/amp", + instantiate, + connect_port, + NULL, + runAmp_gcia_oa, + NULL, + cleanup, + NULL, +}; + +LV2_SYMBOL_EXPORT const LV2_Descriptor* +lv2_descriptor(uint32_t index) +{ + switch (index) { + case 0: return &descriptor; + default: return NULL; + } +} diff --git a/src/branch.c b/src/branch.c new file mode 100644 index 0000000..70329a2 --- /dev/null +++ b/src/branch.c @@ -0,0 +1,133 @@ +/* + An LV2 plugin to split a signal into two. + Copyright 2011 David Robillard + + Copyright 2002 Mike Rawes + + This 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 3 of the License, or + (at your option) any later version. + + This software 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 software. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdlib.h> +#include "lv2/lv2plug.in/ns/lv2core/lv2.h" + +#define BRANCH_INPUT 0 +#define BRANCH_OUTPUT1 1 +#define BRANCH_OUTPUT2 2 + +typedef struct { + float* input; + float* output1; + float* output2; +} Branch; + +static void +cleanup(LV2_Handle instance) +{ + free(instance); +} + +static void +connect_port(LV2_Handle instance, + uint32_t port, + void* data) +{ + Branch* plugin = (Branch*)instance; + + switch (port) { + case BRANCH_INPUT: + plugin->input = data; + break; + case BRANCH_OUTPUT1: + plugin->output1 = data; + break; + case BRANCH_OUTPUT2: + plugin->output2 = data; + break; + } +} + +static LV2_Handle +instantiate(const LV2_Descriptor* descriptor, + double sample_rate, + const char* bundle_path, + const LV2_Feature* const* features) +{ + Branch* plugin = (Branch*)malloc(sizeof(Branch)); + + return (LV2_Handle)plugin; +} + +static void +runBranch_ia_oaoa(LV2_Handle instance, + uint32_t sample_count) +{ + Branch* plugin = (Branch*)instance; + + /* Input (array of floats of length sample_count) */ + float* input = plugin->input; + + /* First Output (array of floats of length sample_count) */ + float* output1 = plugin->output1; + + /* Second Output (array of floats of length sample_count) */ + float* output2 = plugin->output2; + + float in; + + for (uint32_t s = 0; s < sample_count; ++s) { + in = input[s]; + + output1[s] = in; + output2[s] = in; + } +} + +static void +runBranch_ic_ococ(LV2_Handle instance, + uint32_t sample_count) +{ + Branch* plugin = (Branch*)instance; + + /* Input (float value) */ + float input = *(plugin->input); + + /* First Output (pointer to float value) */ + float* output1 = plugin->output1; + + /* Second Output (pointer to float value) */ + float* output2 = plugin->output2; + + output1[0] = input; + output2[0] = input; +} + +static const LV2_Descriptor descriptor = { + "http://drobilla.net/plugins/blip/branch", + instantiate, + connect_port, + NULL, + runBranch_ic_ococ, + NULL, + cleanup, + NULL, +}; + +LV2_SYMBOL_EXPORT const LV2_Descriptor* +lv2_descriptor(uint32_t index) +{ + switch (index) { + case 0: return &descriptor; + default: return NULL; + } +} diff --git a/src/dahdsr.c b/src/dahdsr.c new file mode 100644 index 0000000..01115bb --- /dev/null +++ b/src/dahdsr.c @@ -0,0 +1,685 @@ +/* + An LV2 plugin to generate DAHDSR envelopes Gate and (re)trigger + Copyright 2011 David Robillard + Copyright 2004 Mike Rawes + + This 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 3 of the License, or + (at your option) any later version. + + This software 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 software. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdlib.h> +#include "lv2/lv2plug.in/ns/lv2core/lv2.h" +#include "common.h" + +#define DAHDSR_GATE 0 +#define DAHDSR_TRIGGER 1 +#define DAHDSR_DELAY 2 +#define DAHDSR_ATTACK 3 +#define DAHDSR_HOLD 4 +#define DAHDSR_DECAY 5 +#define DAHDSR_SUSTAIN 6 +#define DAHDSR_RELEASE 7 +#define DAHDSR_OUTPUT 8 + +typedef enum { + IDLE, + DELAY, + ATTACK, + HOLD, + DECAY, + SUSTAIN, + RELEASE +} DAHDSRState; + +typedef struct { + float* gate; + float* trigger; + float* delay; + float* attack; + float* hold; + float* decay; + float* sustain; + float* release; + float* output; + float srate; + float inv_srate; + float last_gate; + float last_trigger; + float from_level; + float level; + DAHDSRState state; + uint32_t samples; +} Dahdsr; + +static void +cleanup(LV2_Handle instance) +{ + free(instance); +} + +static void +connect_port(LV2_Handle instance, + uint32_t port, + void* data) +{ + Dahdsr* plugin = (Dahdsr*)instance; + + switch (port) { + case DAHDSR_GATE: + plugin->gate = data; + break; + case DAHDSR_TRIGGER: + plugin->trigger = data; + break; + case DAHDSR_DELAY: + plugin->delay = data; + break; + case DAHDSR_ATTACK: + plugin->attack = data; + break; + case DAHDSR_HOLD: + plugin->hold = data; + break; + case DAHDSR_DECAY: + plugin->decay = data; + break; + case DAHDSR_SUSTAIN: + plugin->sustain = data; + break; + case DAHDSR_RELEASE: + plugin->release = data; + break; + case DAHDSR_OUTPUT: + plugin->output = data; + break; + } +} + +static LV2_Handle +instantiate(const LV2_Descriptor* descriptor, + double sample_rate, + const char* bundle_path, + const LV2_Feature* const* features) +{ + Dahdsr* plugin = (Dahdsr*)malloc(sizeof(Dahdsr)); + + plugin->srate = (float)sample_rate; + plugin->inv_srate = 1.0f / plugin->srate; + + return (LV2_Handle)plugin; +} + +static void +activate(LV2_Handle instance) +{ + Dahdsr* plugin = (Dahdsr*)instance; + + plugin->last_gate = 0.0f; + plugin->last_trigger = 0.0f; + plugin->from_level = 0.0f; + plugin->level = 0.0f; + plugin->state = IDLE; + plugin->samples = 0; +} + +static void +runDahdsr_Audio(LV2_Handle instance, + uint32_t sample_count) +{ + Dahdsr* plugin = (Dahdsr*)instance; + + /* Gate */ + float* gate = plugin->gate; + + /* Trigger */ + float* trigger = plugin->trigger; + + /* Delay Time (s) */ + float* delay = plugin->delay; + + /* Attack Time (s) */ + float* attack = plugin->attack; + + /* Hold Time (s) */ + float* hold = plugin->hold; + + /* Decay Time (s) */ + float* decay = plugin->decay; + + /* Sustain Level */ + float* sustain = plugin->sustain; + + /* Release Time (s) */ + float* release = plugin->release; + + /* Envelope Out */ + float* output = plugin->output; + + /* Instance Data */ + float srate = plugin->srate; + float inv_srate = plugin->inv_srate; + float last_gate = plugin->last_gate; + float last_trigger = plugin->last_trigger; + float from_level = plugin->from_level; + float level = plugin->level; + DAHDSRState state = plugin->state; + uint32_t samples = plugin->samples; + + float gat, trg, del, att, hld, dec, sus, rel; + float elapsed; + + for (uint32_t s = 0; s < sample_count; ++s) { + /* Convert times into rates */ + del = delay[s] > 0.0f ? inv_srate / delay[s] : srate; + att = attack[s] > 0.0f ? inv_srate / attack[s] : srate; + hld = hold[s] > 0.0f ? inv_srate / hold[s] : srate; + dec = decay[s] > 0.0f ? inv_srate / decay[s] : srate; + rel = release[s] > 0.0f ? inv_srate / release[s] : srate; + + gat = gate[s]; + trg = trigger[s]; + sus = f_clip(sustain[s], 0.0f, 1.0f); + + /* Initialise delay phase if gate is opened and was closed, or + we received a trigger */ + if ((trg > 0.0f && !(last_trigger > 0.0f)) + || (gat > 0.0f && !(last_gate > 0.0f))) { + if (del < srate) { + state = DELAY; + } else if (att < srate) { + state = ATTACK; + } else { + state = hld < srate ? HOLD + : (dec < srate ? DECAY + : (gat > 0.0f ? SUSTAIN + : (rel < srate ? RELEASE + : IDLE))); + level = 1.0f; + } + samples = 0; + } + + /* Release if gate was open and now closed */ + if (state != IDLE && state != RELEASE + && last_gate > 0.0f && !(gat > 0.0f)) { + state = rel < srate ? RELEASE : IDLE; + samples = 0; + } + + if (samples == 0) { + from_level = level; + } + + /* Calculate level of envelope from current state */ + switch (state) { + case IDLE: + level = 0; + break; + case DELAY: + samples++; + elapsed = (float)samples * del; + if (elapsed > 1.0f) { + state = att < srate ? ATTACK + : (hld < srate ? HOLD + : (dec < srate ? DECAY + : (gat > 0.0f ? SUSTAIN + : (rel < srate ? RELEASE + : IDLE)))); + samples = 0; + } + break; + case ATTACK: + samples++; + elapsed = (float)samples * att; + if (elapsed > 1.0f) { + state = hld < srate ? HOLD + : (dec < srate ? DECAY + : (gat > 0.0f ? SUSTAIN + : (rel < srate ? RELEASE + : IDLE))); + level = 1.0f; + samples = 0; + } else { + level = from_level + elapsed * (1.0f - from_level); + } + break; + case HOLD: + samples++; + elapsed = (float)samples * hld; + if (elapsed > 1.0f) { + state = dec < srate ? DECAY + : (gat > 0.0f ? SUSTAIN + : (rel < srate ? RELEASE + : IDLE)); + samples = 0; + } + break; + case DECAY: + samples++; + elapsed = (float)samples * dec; + if (elapsed > 1.0f) { + state = gat > 0.0f ? SUSTAIN + : (rel < srate ? RELEASE + : IDLE); + level = sus; + samples = 0; + } else { + level = from_level + elapsed * (sus - from_level); + } + break; + case SUSTAIN: + level = sus; + break; + case RELEASE: + samples++; + elapsed = (float)samples * rel; + if (elapsed > 1.0f) { + state = IDLE; + level = 0.0f; + samples = 0; + } else { + level = from_level - elapsed * from_level; + } + break; + default: + /* Should never happen */ + level = 0.0f; + } + + output[s] = level; + + last_gate = gate[s]; + last_trigger = trigger[s]; + } + + plugin->last_gate = last_gate; + plugin->last_trigger = last_trigger; + plugin->from_level = from_level; + plugin->level = level; + plugin->state = state; + plugin->samples = samples; +} + +static void +runDahdsr_Control(LV2_Handle instance, + uint32_t sample_count) +{ + Dahdsr* plugin = (Dahdsr*)instance; + + /* Gate */ + float* gate = plugin->gate; + + /* Trigger */ + float* trigger = plugin->trigger; + + /* Delay Time (s) */ + float delay = *(plugin->delay); + + /* Attack Time (s) */ + float attack = *(plugin->attack); + + /* Hold Time (s) */ + float hold = *(plugin->hold); + + /* Decay Time (s) */ + float decay = *(plugin->decay); + + /* Sustain Level */ + float sustain = *(plugin->sustain); + + /* Release Time (s) */ + float release = *(plugin->release); + + /* Envelope Out */ + float* output = plugin->output; + + /* Instance Data */ + float srate = plugin->srate; + float inv_srate = plugin->inv_srate; + float last_gate = plugin->last_gate; + float last_trigger = plugin->last_trigger; + float from_level = plugin->from_level; + float level = plugin->level; + DAHDSRState state = plugin->state; + uint32_t samples = plugin->samples; + + float gat, trg, del, att, hld, dec, sus, rel; + float elapsed; + + /* Convert times into rates */ + del = delay > 0.0f ? inv_srate / delay : srate; + att = attack > 0.0f ? inv_srate / attack : srate; + hld = hold > 0.0f ? inv_srate / hold : srate; + dec = decay > 0.0f ? inv_srate / decay : srate; + rel = release > 0.0f ? inv_srate / release : srate; + + sus = f_clip(sustain, 0.0f, 1.0f); + + for (uint32_t s = 0; s < sample_count; ++s) { + gat = gate[s]; + trg = trigger[s]; + + /* Initialise delay phase if gate is opened and was closed, or + we received a trigger */ + if ((trg > 0.0f && !(last_trigger > 0.0f)) + || (gat > 0.0f && !(last_gate > 0.0f))) { + if (del < srate) { + state = DELAY; + } else if (att < srate) { + state = ATTACK; + } else { + state = hld < srate ? HOLD + : (dec < srate ? DECAY + : (gat > 0.0f ? SUSTAIN + : (rel < srate ? RELEASE + : IDLE))); + level = 1.0f; + } + samples = 0; + } + + /* Release if gate was open and now closed */ + if (state != IDLE && state != RELEASE + && last_gate > 0.0f && !(gat > 0.0f)) { + state = rel < srate ? RELEASE : IDLE; + samples = 0; + } + + if (samples == 0) { + from_level = level; + } + + /* Calculate level of envelope from current state */ + switch (state) { + case IDLE: + level = 0; + break; + case DELAY: + samples++; + elapsed = (float)samples * del; + if (elapsed > 1.0f) { + state = att < srate ? ATTACK + : (hld < srate ? HOLD + : (dec < srate ? DECAY + : (gat > 0.0f ? SUSTAIN + : (rel < srate ? RELEASE + : IDLE)))); + samples = 0; + } + break; + case ATTACK: + samples++; + elapsed = (float)samples * att; + if (elapsed > 1.0f) { + state = hld < srate ? HOLD + : (dec < srate ? DECAY + : (gat > 0.0f ? SUSTAIN + : (rel < srate ? RELEASE + : IDLE))); + level = 1.0f; + samples = 0; + } else { + level = from_level + elapsed * (1.0f - from_level); + } + break; + case HOLD: + samples++; + elapsed = (float)samples * hld; + if (elapsed > 1.0f) { + state = dec < srate ? DECAY + : (gat > 0.0f ? SUSTAIN + : (rel < srate ? RELEASE + : IDLE)); + samples = 0; + } + break; + case DECAY: + samples++; + elapsed = (float)samples * dec; + if (elapsed > 1.0f) { + state = gat > 0.0f ? SUSTAIN + : (rel < srate ? RELEASE + : IDLE); + level = sus; + samples = 0; + } else { + level = from_level + elapsed * (sus - from_level); + } + break; + case SUSTAIN: + level = sus; + break; + case RELEASE: + samples++; + elapsed = (float)samples * rel; + if (elapsed > 1.0f) { + state = IDLE; + level = 0.0f; + samples = 0; + } else { + level = from_level - elapsed * from_level; + } + break; + default: + /* Should never happen */ + level = 0.0f; + } + + output[s] = level; + + last_gate = gat; + last_trigger = trg; + } + + plugin->last_gate = last_gate; + plugin->last_trigger = last_trigger; + plugin->from_level = from_level; + plugin->level = level; + plugin->state = state; + plugin->samples = samples; +} + +static void +runDahdsr_CGT_Control(LV2_Handle instance, + uint32_t sample_count) +{ + Dahdsr* plugin = (Dahdsr*)instance; + + /* Gate */ + float gate = *(plugin->gate); + + /* Trigger */ + float trigger = *(plugin->trigger); + + /* Delay Time (s) */ + float delay = *(plugin->delay); + + /* Attack Time (s) */ + float attack = *(plugin->attack); + + /* Hold Time (s) */ + float hold = *(plugin->hold); + + /* Decay Time (s) */ + float decay = *(plugin->decay); + + /* Sustain Level */ + float sustain = *(plugin->sustain); + + /* Release Time (s) */ + float release = *(plugin->release); + + /* Envelope Out */ + float* output = plugin->output; + + /* Instance Data */ + float srate = plugin->srate; + float inv_srate = plugin->inv_srate; + float last_gate = plugin->last_gate; + float last_trigger = plugin->last_trigger; + float from_level = plugin->from_level; + float level = plugin->level; + DAHDSRState state = plugin->state; + uint32_t samples = plugin->samples; + + float gat, trg, del, att, hld, dec, sus, rel; + float elapsed; + + /* Convert times into rates */ + del = delay > 0.0f ? inv_srate / delay : srate; + att = attack > 0.0f ? inv_srate / attack : srate; + hld = hold > 0.0f ? inv_srate / hold : srate; + dec = decay > 0.0f ? inv_srate / decay : srate; + rel = release > 0.0f ? inv_srate / release : srate; + + gat = gate; + trg = trigger; + sus = f_clip(sustain, 0.0f, 1.0f); + + /* Initialise delay phase if gate is opened and was closed, or + we received a trigger */ + if ((trg > 0.0f && !(last_trigger > 0.0f)) + || (gat > 0.0f && !(last_gate > 0.0f))) { + if (del < srate) { + state = DELAY; + } else if (att < srate) { + state = ATTACK; + } else { + state = hld < srate ? HOLD + : (dec < srate ? DECAY + : (gat > 0.0f ? SUSTAIN + : (rel < srate ? RELEASE + : IDLE))); + level = 1.0f; + } + samples = 0; + } + + /* Release if gate was open and now closed */ + if (state != IDLE && state != RELEASE + && last_gate > 0.0f && !(gat > 0.0f)) { + state = rel < srate ? RELEASE : IDLE; + samples = 0; + } + + for (uint32_t s = 0; s < sample_count; ++s) { + if (samples == 0) { + from_level = level; + } + + /* Calculate level of envelope from current state */ + switch (state) { + case IDLE: + level = 0; + break; + case DELAY: + samples++; + elapsed = (float)samples * del; + if (elapsed > 1.0f) { + state = att < srate ? ATTACK + : (hld < srate ? HOLD + : (dec < srate ? DECAY + : (gat > 0.0f ? SUSTAIN + : (rel < srate ? RELEASE + : IDLE)))); + samples = 0; + } + break; + case ATTACK: + samples++; + elapsed = (float)samples * att; + if (elapsed > 1.0f) { + state = hld < srate ? HOLD + : (dec < srate ? DECAY + : (gat > 0.0f ? SUSTAIN + : (rel < srate ? RELEASE + : IDLE))); + level = 1.0f; + samples = 0; + } else { + level = from_level + elapsed * (1.0f - from_level); + } + break; + case HOLD: + samples++; + elapsed = (float)samples * hld; + if (elapsed > 1.0f) { + state = dec < srate ? DECAY + : (gat > 0.0f ? SUSTAIN + : (rel < srate ? RELEASE + : IDLE)); + samples = 0; + } + break; + case DECAY: + samples++; + elapsed = (float)samples * dec; + if (elapsed > 1.0f) { + state = gat > 0.0f ? SUSTAIN + : (rel < srate ? RELEASE + : IDLE); + level = sus; + samples = 0; + } else { + level = from_level + elapsed * (sus - from_level); + } + break; + case SUSTAIN: + level = sus; + break; + case RELEASE: + samples++; + elapsed = (float)samples * rel; + if (elapsed > 1.0f) { + state = IDLE; + level = 0.0f; + samples = 0; + } else { + level = from_level - elapsed * from_level; + } + break; + default: + /* Should never happen */ + level = 0.0f; + } + + output[s] = level; + } + + plugin->last_gate = gat; + plugin->last_trigger = trg; + plugin->from_level = from_level; + plugin->level = level; + plugin->state = state; + plugin->samples = samples; +} + +static const LV2_Descriptor descriptor = { + "http://drobilla.net/plugins/blip/dahdsr", + instantiate, + connect_port, + activate, + runDahdsr_Control, + NULL, + cleanup, + NULL, +}; + +LV2_SYMBOL_EXPORT const LV2_Descriptor* +lv2_descriptor(uint32_t index) +{ + switch (index) { + case 0: return &descriptor; + default: return NULL; + } +} diff --git a/src/difference.c b/src/difference.c new file mode 100644 index 0000000..afa9183 --- /dev/null +++ b/src/difference.c @@ -0,0 +1,180 @@ +/* + An LV2 plugin to calculate the difference of two signals. + Copyright 2011 David Robillard + Copyright 2004 Mike Rawes + + This 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 3 of the License, or + (at your option) any later version. + + This software 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 software. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdlib.h> +#include "lv2/lv2plug.in/ns/lv2core/lv2.h" + +#define DIFFERENCE_INPUT 0 +#define DIFFERENCE_MINUS 1 +#define DIFFERENCE_OUTPUT 2 + +typedef struct { + float* input; + float* minus; + float* output; +} Difference; + +static void +cleanup(LV2_Handle instance) +{ + free(instance); +} + +static void +connect_port(LV2_Handle instance, + uint32_t port, + void* data) +{ + Difference* plugin = (Difference*)instance; + + switch (port) { + case DIFFERENCE_INPUT: + plugin->input = data; + break; + case DIFFERENCE_MINUS: + plugin->minus = data; + break; + case DIFFERENCE_OUTPUT: + plugin->output = data; + break; + } +} + +static LV2_Handle +instantiate(const LV2_Descriptor* descriptor, + double sample_rate, + const char* bundle_path, + const LV2_Feature* const* features) +{ + Difference* plugin = (Difference*)malloc(sizeof(Difference)); + + return (LV2_Handle)plugin; +} + +static void +runDifference_iama_oa(LV2_Handle instance, + uint32_t sample_count) +{ + Difference* plugin = (Difference*)instance; + + /* Input (array of floats of length sample_count) */ + float* input = plugin->input; + + /* Input to Subtract (array of floats of length sample_count) */ + float* minus = plugin->minus; + + /* Output (array of floats of length sample_count) */ + float* output = plugin->output; + + float in; + float mi; + + for (uint32_t s = 0; s < sample_count; ++s) { + in = input[s]; + mi = minus[s]; + + output[s] = in - mi; + } +} + +static void +runDifference_iamc_oa(LV2_Handle instance, + uint32_t sample_count) +{ + Difference* plugin = (Difference*)instance; + + /* Input (array of floats of length sample_count) */ + float* input = plugin->input; + + /* Input to Subtract (float value) */ + float minus = *(plugin->minus); + + /* Output (array of floats of length sample_count) */ + float* output = plugin->output; + + float in; + + for (uint32_t s = 0; s < sample_count; ++s) { + in = input[s]; + + output[s] = in - minus; + } +} + +static void +runDifference_icma_oa(LV2_Handle instance, + uint32_t sample_count) +{ + Difference* plugin = (Difference*)instance; + + /* Input (float value) */ + float input = *(plugin->input); + + /* Input to Subtract (array of floats of length sample_count) */ + float* minus = plugin->minus; + + /* Output (array of floats of length sample_count) */ + float* output = plugin->output; + + float mi; + + for (uint32_t s = 0; s < sample_count; ++s) { + mi = minus[s]; + + output[s] = input - mi; + } +} + +static void +runDifference_icmc_oc(LV2_Handle instance, + uint32_t sample_count) +{ + Difference* plugin = (Difference*)instance; + + /* Input (float value) */ + float input = *(plugin->input); + + /* Input to Subtract (float value) */ + float minus = *(plugin->minus); + + /* Output Frequency (pointer to float value) */ + float* output = plugin->output; + + output[0] = input - minus; +} + +static const LV2_Descriptor descriptor = { + "http://drobilla.net/plugins/blip/difference", + instantiate, + connect_port, + NULL, + runDifference_icmc_oc, + NULL, + cleanup, + NULL, +}; + +LV2_SYMBOL_EXPORT const LV2_Descriptor* +lv2_descriptor(uint32_t index) +{ + switch (index) { + case 0: return &descriptor; + default: return NULL; + } +} diff --git a/src/fmod.c b/src/fmod.c new file mode 100644 index 0000000..ce3a8f4 --- /dev/null +++ b/src/fmod.c @@ -0,0 +1,192 @@ +/* + An LV2 plugin to modulate a frequency by a signal. + Copyright 2011 David Robillard + Copyright 2002 Mike Rawes + + This 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 3 of the License, or + (at your option) any later version. + + This software 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 software. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdlib.h> +#include "lv2/lv2plug.in/ns/lv2core/lv2.h" +#include "math_func.h" + +#define FMOD_FREQUENCY 0 +#define FMOD_MODULATOR 1 +#define FMOD_OUTPUT 2 + +typedef struct { + float* frequency; + float* modulator; + float* output; +} Fmod; + +static void +cleanup(LV2_Handle instance) +{ + free(instance); +} + +static void +connect_port(LV2_Handle instance, + uint32_t port, + void* data) +{ + Fmod* plugin = (Fmod*)instance; + + switch (port) { + case FMOD_FREQUENCY: + plugin->frequency = data; + break; + case FMOD_MODULATOR: + plugin->modulator = data; + break; + case FMOD_OUTPUT: + plugin->output = data; + break; + } +} + +static LV2_Handle +instantiate(const LV2_Descriptor* descriptor, + double sample_rate, + const char* bundle_path, + const LV2_Feature* const* features) +{ + Fmod* plugin = (Fmod*)malloc(sizeof(Fmod)); + + return (LV2_Handle)plugin; +} + +static void +runFmod_fama_oa(LV2_Handle instance, + uint32_t sample_count) +{ + Fmod* plugin = (Fmod*)instance; + + /* Frequency to Modulate (array of floats of length sample_count) */ + float* frequency = plugin->frequency; + + /* LFO Input (array of floats of length sample_count) */ + float* modulator = plugin->modulator; + + /* Output Frequency (array of floats of length sample_count) */ + float* output = plugin->output; + + float freq; + float mod; + float scale; + + for (uint32_t s = 0; s < sample_count; ++s) { + freq = frequency[s]; + mod = modulator[s]; + + scale = (float)EXPF(M_LN2 * mod); + + output[s] = scale * freq; + } +} + +static void +runFmod_famc_oa(LV2_Handle instance, + uint32_t sample_count) +{ + Fmod* plugin = (Fmod*)instance; + + /* Frequency to Modulate (array of floats of length sample_count) */ + float* frequency = plugin->frequency; + + /* Shift (Octaves) (float value) */ + float modulator = *(plugin->modulator); + + /* Output Frequency (array of floats of length sample_count) */ + float* output = plugin->output; + + float freq; + float scale = (float)EXPF(M_LN2 * modulator); + + for (uint32_t s = 0; s < sample_count; ++s) { + freq = frequency[s]; + + output[s] = scale * freq; + } +} + +static void +runFmod_fcma_oa(LV2_Handle instance, + uint32_t sample_count) +{ + Fmod* plugin = (Fmod*)instance; + + /* Frequency to Modulate (float value) */ + float frequency = *(plugin->frequency); + + /* LFO Input (array of floats of length sample_count) */ + float* modulator = plugin->modulator; + + /* Output Frequency (array of floats of length sample_count) */ + float* output = plugin->output; + + float mod; + float scale; + + for (uint32_t s = 0; s < sample_count; ++s) { + mod = modulator[s]; + + scale = (float)EXPF(M_LN2 * mod); + + output[s] = scale * frequency; + } +} + +static void +runFmod_fcmc_oc(LV2_Handle instance, + uint32_t sample_count) +{ + Fmod* plugin = (Fmod*)instance; + + /* Frequency to Modulate (float value) */ + float frequency = *(plugin->frequency); + + /* Shift (Octaves) (float value) */ + float modulator = *(plugin->modulator); + + /* Output Frequency (pointer to float value) */ + float* output = plugin->output; + + float scale; + + scale = (float)EXPF(M_LN2 * modulator); + + output[0] = scale * frequency; +} + +static const LV2_Descriptor descriptor = { + "http://drobilla.net/plugins/blip/fmod", + instantiate, + connect_port, + NULL, + runFmod_fcmc_oc, + NULL, + cleanup, + NULL, +}; + +LV2_SYMBOL_EXPORT const LV2_Descriptor* +lv2_descriptor(uint32_t index) +{ + switch (index) { + case 0: return &descriptor; + default: return NULL; + } +} diff --git a/src/include/common.h b/src/include/common.h new file mode 100644 index 0000000..0f30aa1 --- /dev/null +++ b/src/include/common.h @@ -0,0 +1,54 @@ +/* + Common definitions. + Copyright 2011 David Robillard + Copyright 2002 Mike Rawes + + This 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 3 of the License, or + (at your option) any later version. + + This software 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 software. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef blip_common_h +#define blip_common_h + +#include "math_func.h" + +/* Handy constants and macros */ + +#ifndef SMALLEST_FLOAT +/** Smallest generated non-zero float, used for pre-empting denormals */ +#define SMALLEST_FLOAT (1.0 / (float)0xFFFFFFFF) +#endif + +/* + * Clip without branch (from http://musicdsp.org) + */ + +static inline float +f_min (float x, float a) +{ + return a - (a - x + FABSF (a - x)) * 0.5f; +} + +static inline float +f_max (float x, float b) +{ + return (x - b + FABSF (x - b)) * 0.5f + b; +} + +static inline float +f_clip (float x, float a, float b) +{ + return 0.5f * (FABSF (x - a) + a + b - FABSF (x - b)); +} + +#endif /* blip_common_h */ diff --git a/src/include/interpolate.h b/src/include/interpolate.h new file mode 100644 index 0000000..d61fb3e --- /dev/null +++ b/src/include/interpolate.h @@ -0,0 +1,75 @@ +#ifndef blip_interpolate_h +#define blip_interpolate_h + +#include "lv2/lv2plug.in/ns/lv2core/lv2.h" +#include <config.h> +#include "math_func.h" + +/** + Interpolate between p0 and n0 taking the previous (p1) and next (n1) points + into account, using a 3rd order polynomial (a.k.a. cubic spline). + @param interval Normalised time interval between intepolated sample and p0 + @param p1 Sample two previous to interpolated one + @param p0 Previous sample to interpolated one + @param n0 Sample following interpolated one + @param n1 Sample following n0 + @return Interpolated sample. + + Adapted from Steve Harris' plugin code + swh-plugins-0.2.7/ladspa-util.h::cube_interp + http://plugin.org.uk/releases/0.2.7/ +*/ +static inline float +interpolate_cubic(float interval, + float p1, + float p0, + float n0, + float n1) +{ + return p0 + 0.5f * interval * (n0 - p1 + + interval * (4.0f * n0 + 2.0f * p1 - 5.0f * p0 - n1 + + interval * (3.0f * (p0 - n0) - p1 + n1))); +} + +/** + Interpolate between p0 and n0 taking the previous (p1) and next (n1) points + into account, using a 5th order polynomial. + @param interval Normalised time interval between intepolated sample and p0 + @param p1 Sample two previous to interpolated one + @param p0 Previous sample to interpolated one + @param n0 Sample following interpolated one + @param n1 Sample following n0 + @return Interpolated sample. + + Adapted from http://www.musicdsp.org/archive.php?classid=5#62 +*/ +static inline float +interpolate_quintic(float interval, + float p1, + float p0, + float n0, + float n1) +{ + return p0 + 0.5f * interval * (n0 - p1 + + interval * (n0 - 2.0f * p0 + p1 + + interval * ( 9.0f * (n0 - p0) + 3.0f * (p1 - n1) + + interval * (15.0f * (p0 - n0) + 5.0f * (n1 - p1) + + interval * ( 6.0f * (n0 - p0) + 2.0f * (p1 - n1)))))); +} + +/** + Linear interpolation +*/ +static inline float +f_lerp (float value, + float v1, + float v2) +{ + value -= LRINTF (value - 0.5f); + value *= (v2 - v1); + value += v1; + + return value; +} + +#endif /* blip_interpolate_h */ diff --git a/src/include/lp4pole_filter.h b/src/include/lp4pole_filter.h new file mode 100644 index 0000000..adc5cba --- /dev/null +++ b/src/include/lp4pole_filter.h @@ -0,0 +1,137 @@ +/* + Header for lp4pole_filter struct, and functions to run instance. + Copyright 2011 David Robillard + Copyright 2003 Mike Rawes + + Originally originally appeared in CSound as Timo Tossavainen's (sp?) + implementation from the Stilson/Smith CCRMA paper. + + See http://musicdsp.org/archive.php?classid=3#26 + + Originally appeared in the arts softsynth by Stefan Westerfeld: + http://www.arts-project.org/ + + First ported to LADSPA by Reiner Klenk (pdq808[at]t-online.de) + + Tuning and stability issues (output NaN) and additional audio-rate + variant added by Mike Rawes (mike_rawes[at]yahoo.co.uk) + + This 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 3 of the License, or + (at your option) any later version. + + This software 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 software. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef blip_lp4pole_filter_h +#define blip_lp4pole_filter_h + +#include "lv2/lv2plug.in/ns/lv2core/lv2.h" +#include "common.h" + +typedef struct { + float f; + float coeff; + float fb; + float in1; + float in2; + float in3; + float in4; + float inv_nyquist; + float out1; + float out2; + float out3; + float out4; + float max_abs_in; +} LP4PoleFilter; + +/** + Allocate a new LP4PoleFilter instance. + @param sample_rate Intended playback (DAC) rate + @return Allocated LP4PoleFilter instance +*/ +LP4PoleFilter* lp4pole_new(double sample_rate); + +/** + Cleanup an existing LP4PoleFilter instance. + @param lpf Pointer to LP4PoleFilter instance allocated with initFilter +*/ +void lp4pole_cleanup(LP4PoleFilter* lpf); + +/** + Initialise filter. + @param lpf Pointer to LP4PoleFilter instance allocated with initFilter +*/ +void lp4pole_init(LP4PoleFilter* lpf); + +/** + Set up filter coefficients for given LP4Pole instance. + @param lpf Pointer to LP4PoleFilter instance + @param cutoff Cutoff frequency in Hz + @param resonance Resonance [Min=0.0, Max=4.0] +*/ +static inline void +lp4pole_set_params(LP4PoleFilter* lpf, + float cutoff, + float resonance) +{ + float fsqd; + float tuning; + + /* Normalise cutoff and find tuning - Magic numbers found empirically :) */ + lpf->f = cutoff * lpf->inv_nyquist; + tuning = f_clip(3.13f - (lpf->f * 4.24703592f), 1.56503274f, 3.13f); + + /* Clip to bounds */ + lpf->f = f_clip(lpf->f * tuning, lpf->inv_nyquist, 1.16f); + + fsqd = lpf->f * lpf->f; + lpf->coeff = fsqd * fsqd * 0.35013f; + + lpf->fb = f_clip(resonance, -1.3f, 4.0f) * (1.0f - 0.15f * fsqd); + + lpf->f = 1.0f - lpf->f; +} + +/** + Run given LP4PoleFilter instance for a single sample. + @param lpf Pointer to LP4PoleFilter instance + @param in Input sample + @return Filtered sample +*/ +static inline float +lp4pole_run(LP4PoleFilter* lpf, + float in) +{ + float abs_in = fabsf(16.0f * in); /* ~24dB unclipped headroom */ + + lpf->max_abs_in = f_max(lpf->max_abs_in, abs_in); + + in -= lpf->out4 * lpf->fb; + in *= lpf->coeff; + + lpf->out1 = in + 0.3f * lpf->in1 + lpf->f * lpf->out1; /* Pole 1 */ + lpf->in1 = in; + lpf->out2 = lpf->out1 + 0.3f * lpf->in2 + lpf->f * lpf->out2; /* Pole 2 */ + lpf->in2 = lpf->out1; + lpf->out3 = lpf->out2 + 0.3f * lpf->in3 + lpf->f * lpf->out3; /* Pole 3 */ + lpf->in3 = lpf->out2; + lpf->out4 = lpf->out3 + 0.3f * lpf->in4 + lpf->f * lpf->out4; /* Pole 4 */ + lpf->in4 = lpf->out3; + + /* Simple hard clip to prevent NaN */ + lpf->out4 = f_clip(lpf->out4, -lpf->max_abs_in, lpf->max_abs_in); + + lpf->max_abs_in *= 0.999f; + + return lpf->out4; +} + +#endif /* blip_lp4pole_filter_h */ diff --git a/src/include/math_func.h b/src/include/math_func.h new file mode 100644 index 0000000..c44075d --- /dev/null +++ b/src/include/math_func.h @@ -0,0 +1,36 @@ +/* + * Provide double fallbacks for environments lacking sinf and + * friends (e.g. Solaris) + */ + +#ifndef math_func_h +#define math_func_h + +#include <math.h> +#include "config.h" + +#ifdef HAVE_SINF +/* Use float functions */ +#define SINF(x) sinf(x) +#define COSF(x) cosf(x) +#define FABSF(x) fabsf(x) +#define FLOORF(x) floorf(x) +#define EXPF(x) expf(x) +#define POWF(x,p) powf(x,p) +#define COPYSIGNF(s,d) copysignf(s,d) +#define LRINTF(x) lrintf(x) + +#else +/* Use double functions */ +#define SINF(x) sin(x) +#define COSF(x) cos(x) +#define FABSF(x) fabs(x) +#define FLOORF(x) floor(x) +#define EXPF(x) exp(x) +#define POWF(x,p) pow(x) +#define COPYSIGNF(s,d) copysign(s,d) +#define LRINTF(x) lrint(x) + +#endif + +#endif diff --git a/src/include/wavedata.h b/src/include/wavedata.h new file mode 100644 index 0000000..82bc70f --- /dev/null +++ b/src/include/wavedata.h @@ -0,0 +1,192 @@ +/* + Structures to represent a set of wavetables. + Copyright 2011 David Robillard + Copyright 2003 Mike Rawes + + This 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 3 of the License, or + (at your option) any later version. + + This software 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 software. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef blip_wavedata_h +#define blip_wavedata_h + +#include "lv2/lv2plug.in/ns/lv2core/lv2.h" +#include <config.h> +#include "math_func.h" +#include "interpolate.h" +#include "common.h" + +/* Functions identifying wavedata dlls */ +#define BLOP_DLSYM_SAWTOOTH "blip_get_sawtooth" +#define BLOP_DLSYM_SQUARE "blip_get_square" +#define BLOP_DLSYM_PARABOLA "blip_get_parabola" + +/* + * Structure holding a single segment of sample data + * along with information relating to playback. + */ +typedef struct { + unsigned long sample_count; /* Sample count */ + float* samples_lf; /* Sample data played back at amplitude + inversely proportional to frequency */ + float* samples_hf; /* Sample data played back at amplitude + proportional to frequency */ + unsigned long harmonics; /* Max harmonic content of sample data */ + + float phase_scale_factor; /* Phase scale factor for playback */ + float min_frequency; /* Minimum playback frequency */ + float max_frequency; /* Maximum playback frequency */ + float range_scale_factor; /* Blend scale factor for cross fading */ +} Wavetable; + +/* + * Structure holding the wavetable data and playback state + */ +typedef struct { + void* data_handle; /* Data DLL handle */ + unsigned long table_count; /* Number of wavetables in wavedata */ + Wavetable** tables; /* One or more wavetables, plus pair of + extra tables for frequency extremes */ + unsigned long* lookup; /* Wavetable lookup vector */ + unsigned long lookup_max; /* For clipping lookup indices */ + + float sample_rate; /* Sample rate */ + float nyquist; /* Nyquist rate (sample_rate / 2) */ + + /* Playback state */ + float frequency; /* Current playback frequency */ + float abs_freq; /* Absolute playback frequency */ + float xfade; /* Crossfade factor for fading */ + Wavetable* table; /* Wavetable to playback */ +} Wavedata; + +#ifdef __cplusplus +extern "C" { +#endif + +int wavedata_load(Wavedata* w, + const char* wdat_descriptor_name, + unsigned long sample_rate); + +void wavedata_unload(Wavedata* w); + +/***************************************************************************** + * Description: Get interpolated sample from current wavetable in wavedata + * at given phase offset + * + * Arguments: w Wavedata containing playback state and data + * phase Phase offset [0.0, sample_rate] + * + * Returns: Interpolated sample + * + * Notes: Cubic (or quintic) interpolation requires four consecutive + * samples for operation: + * + * phase + * : + * p1 p0 : n0 n1 + * | | x | | + * : : + * <-o-> + * : + * interval + * + * Phase values less than one make p0 the first sample in + * the table - p1 will be the last sample, as a previous + * sample does not exist. To avoid checking for this case, + * a copy of the last sample is stored before the first + * sample in each table. + * Likewise, if the phase means p0 is the last sample, n0 + * and n1 will be the first and second samples respectively. + * Copies of these samples are stored after the last sample + * in each table. + * + *****************************************************************************/ +static inline float +wavedata_get_sample(Wavedata* w, + float phase) +{ + float* samples_hf = w->table->samples_hf; + float* samples_lf = w->table->samples_lf; + float p1, p0, n0, n1; + float phase_f; + long int index; + + /* Scale phase to map to position in wavetable */ + phase *= w->table->phase_scale_factor; + + /* Get position of first contributing sample (p1) */ + index = LRINTF((float)phase - 0.5f); + phase_f = (float)index; + + index %= w->table->sample_count; + + /* Cross-fade table pairs */ + /* Previous two samples */ + p1 = w->xfade * (samples_lf[index] - samples_hf[index]) + samples_hf[index]; + index++; + p0 = w->xfade * (samples_lf[index] - samples_hf[index]) + samples_hf[index]; + index++; + /* Next two samples */ + n0 = w->xfade * (samples_lf[index] - samples_hf[index]) + samples_hf[index]; + index++; + n1 = w->xfade * (samples_lf[index] - samples_hf[index]) + samples_hf[index]; + + /* Return interpolated sample */ + return interpolate_cubic(phase - phase_f, p1, p0, n0, n1); +} + +/***************************************************************************** + * Description: Get wavetable to use for playback frequency. + * + * Arguments: w Wavedata object (contains all table info) + * frequency Playback frequency + * + * Notes: The lookup vector used to determine the wavetable + * is indexed by harmonic number. + * + * The maximum playback frequency for a wavetable is + * determined by its harmonic content and the sample rate, + * and equals sample_rate / 2 / max_harmonic_in_table. + * + *****************************************************************************/ +static inline void +wavedata_get_table(Wavedata* w, + float frequency) +{ + unsigned long harmonic; + + w->frequency = frequency; + w->abs_freq = (float)FABSF((float)frequency); + + /* Get highest harmonic possible in frequency */ + harmonic = LRINTF(w->nyquist / w->abs_freq - 0.5f); + + /* Clip so lookup is within bounds */ + if (harmonic > w->lookup_max) { + harmonic = w->lookup_max; + } + + /* Set playback table */ + w->table = w->tables[w->lookup[harmonic]]; + + /* Get cross fade factor */ + w->xfade = f_max(w->table->max_frequency - w->abs_freq, 0.0f) * w->table->range_scale_factor; + w->xfade = f_min(w->xfade, 1.0f); +} + +#ifdef __cplusplus +} /* extern "C" { */ +#endif + +#endif /* blip_wavedata_h */ diff --git a/src/include/wdatutil.h b/src/include/wdatutil.h new file mode 100644 index 0000000..d7bca80 --- /dev/null +++ b/src/include/wdatutil.h @@ -0,0 +1,141 @@ +/* + Code to generate wavedata dl containing pre-calculated wavetables. + Copyright 2011 David Robillard + Copyright 2003 Mike Rawes + + This 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 3 of the License, or + (at your option) any later version. + + This software 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 software. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef blip_wdatutil_h +#define blip_wdatutil_h + +#include <stdio.h> +#include "lv2/lv2plug.in/ns/lv2core/lv2.h" +#include "math_func.h" +#include "wavedata.h" + +#define WAVE_TYPE_COUNT 3 + +extern char* wave_names[]; +extern char* wave_descriptions[]; +extern unsigned long wave_first_harmonics[]; +extern unsigned long wave_harmonic_intervals[]; + +/** Get actual maximum harmonic from given harmonic, h, and wavetype, w */ +#define ACTUAL_HARM(h, w) h - (h - wave_first_harmonics[w]) % wave_harmonic_intervals[w] + +/** Get minimum harmonic content in given wavetype, w */ +#define MIN_HARM(w) wave_first_harmonics[w] + +/** Get minimum extra harmonic content possible in given wavetype, w */ +#define MIN_EXTRA_HARM(w) wave_harmonic_intervals[w] + +/** Get frequency from MIDI note, n */ +#define FREQ_FROM_NOTE(n) 6.875f * POWF(2.0f, (float)(n + 3) / 12.0f) + +/** Get max harmonic from given frequency, f, at sample rate, r */ +#define HARM_FROM_FREQ(f, r) (unsigned long)((float)r / f / 2.0f) + +/* + * A single wavetable will have a range of pitches at which their samples + * may be played back. + * + * The upper bound is determined by the maximum harmonic present in the + * waveform - above this frequency, the higher harmonics will alias. + * + * The lower bound is chosen to be the higher bound of the previous wavetable + * (or a pre-defined limit if there is no such table). + */ + +typedef enum { + SAW, + SQUARE, + PARABOLA +} Wavetype; + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * Description: Allocate new wavedata struct + * + * Arguments: sample_rate Sample rate to use when generating data + * + * Returns: Pointer to wavedata on success + * NULL (0) on failure + * + * Notes: No wavetables are allocated. Use wavedata_add_table + ******************************************************************************/ +Wavedata* wavedata_new(unsigned long sample_rate); + +/******************************************************************************* + * Description: Destroy allocated wavedata and any tables + * + * Arguments: w Wavedata struct to cleanup + ******************************************************************************/ +void wavedata_cleanup(Wavedata* w); + +/******************************************************************************* + * Description: Add new wavetable information to wavedata file object + * + * Arguments: w Wavedata to add table to + * sample_count Number of samples in wavetable + * harmonics Maximum harmonics present in table + * + * Returns: 0 on success + * -1 otherwise + ******************************************************************************/ +int wavedata_add_table(Wavedata* w, + unsigned long sample_count, + unsigned long harmonics); + +/******************************************************************************* + * Description: Initialise all wavetables in wavedata with a waveform + * generated from Fourier series. + * + * Arguments: w Wavedata to generate data for + * wavetype Wavetype to generate + * gibbs_comp Compensation for Gibbs' effect: + * 0.0: none (wave will overshoot) + * 1.0: full (wave will not overshoot) + * + * Notes: Compensation for Gibbs' Effect will reduce the degree + * of overshoot and ripple at the transitions. A value of 1.0 + * will pretty much eliminate it. + ******************************************************************************/ +void wavedata_generate_tables(Wavedata* w, + Wavetype wavetype, + float gibbs_comp); + +/******************************************************************************* + * Description: Write wavedata as a c header file + * + * Arguments: w Wavedata to write + * wdat_fp Pointer to output file + * prefix Prefix to use in declarations. If this is null + * declarations are prefixed with 'wdat'. + * + * Returns: 0 on success + * -1 otherwise + ******************************************************************************/ +int wavedata_write(Wavedata* w, + FILE* wdat_fp, + char* prefix); + +#ifdef __cplusplus +} /* extern "C" { */ +#endif + +#endif /* blip_wdatutil_h */ diff --git a/src/interpolator.c b/src/interpolator.c new file mode 100644 index 0000000..0324239 --- /dev/null +++ b/src/interpolator.c @@ -0,0 +1,142 @@ +/* + An LV2 plugin to generate a smooth audio signal from a control source. + Copyright 2011 David Robillard + Copyright 2002 Mike Rawes + + This 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 3 of the License, or + (at your option) any later version. + + This software 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 software. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdlib.h> +#include "lv2/lv2plug.in/ns/lv2core/lv2.h" + +#define INTERPOLATOR_INPUT 0 +#define INTERPOLATOR_OUTPUT 1 + +/** + Mutated spline interpolator using only two previous samples and one next. + @param interval Normalised time interval between inteprolated sample and p0 + @param p1 Sample two previous to interpolated one + @param p0 Previous sample to interpolated one + @param n0 Sample following interpolated one + @return Interpolated sample. +*/ +static inline float +interpolate(float interval, + float p1, + float p0, + float n0) +{ + return p0 + 0.5f * interval * (n0 - p1 + + interval * (4.0f * n0 + 2.0f * p1 - 5.0f * p0 - n0 + + interval * (3.0f * (p0 - n0) - p1 + n0))); +} + +typedef struct { + float* input; + float* output; + float p1; + float p0; +} Interpolator; + +static void +cleanup(LV2_Handle instance) +{ + free(instance); +} + +static void +connect_port(LV2_Handle instance, + uint32_t port, + void* data) +{ + Interpolator* plugin = (Interpolator*)instance; + + switch (port) { + case INTERPOLATOR_INPUT: + plugin->input = data; + break; + case INTERPOLATOR_OUTPUT: + plugin->output = data; + break; + } +} + +static LV2_Handle +instantiate(const LV2_Descriptor* descriptor, + double sample_rate, + const char* bundle_path, + const LV2_Feature* const* features) +{ + Interpolator* plugin = (Interpolator*)malloc(sizeof(Interpolator)); + + return (LV2_Handle)plugin; +} + +static void +activate(LV2_Handle instance) +{ + Interpolator* plugin = (Interpolator*)instance; + + plugin->p1 = 0.0f; + plugin->p0 = 0.0f; +} + +static void +runInterpolator(LV2_Handle instance, + uint32_t sample_count) +{ + Interpolator* plugin = (Interpolator*)instance; + + /* Control Input (float value) */ + float input = *(plugin->input); + + /* Interpolated Output (pointer to float value) */ + float* output = plugin->output; + + /* We use two previous values and the input as the 'next' one */ + float p1 = plugin->p1; + float p0 = plugin->p0; + + float interval; + float inv_scount = 1.0f / (float)sample_count; + + for (uint32_t s = 0; s < sample_count; ++s) { + interval = (float)s * inv_scount; + + output[s] = interpolate(interval, p1, p0, input); + } + + plugin->p1 = p0; + plugin->p0 = input; +} + +static const LV2_Descriptor descriptor = { + "http://drobilla.net/plugins/blip/interpolator", + instantiate, + connect_port, + activate, + runInterpolator, + NULL, + cleanup, + NULL, +}; + +LV2_SYMBOL_EXPORT const LV2_Descriptor* +lv2_descriptor(uint32_t index) +{ + switch (index) { + case 0: return &descriptor; + default: return NULL; + } +} diff --git a/src/lp4pole.c b/src/lp4pole.c new file mode 100644 index 0000000..d72cb98 --- /dev/null +++ b/src/lp4pole.c @@ -0,0 +1,182 @@ +/* + An LV2 plugin simulating a 4 pole low pass resonant filter. + Copyright 2011 David Robillard + Copyright 2003 Mike Rawes + + This 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 3 of the License, or + (at your option) any later version. + + This software 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 software. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdlib.h> +#include "lv2/lv2plug.in/ns/lv2core/lv2.h" +#include "lp4pole_filter.h" +#include "common.h" + +#define LP4POLE_CUTOFF 0 +#define LP4POLE_RESONANCE 1 +#define LP4POLE_INPUT 2 +#define LP4POLE_OUTPUT 3 + +typedef struct { + float* cutoff; + float* resonance; + float* input; + float* output; + LP4PoleFilter* lpf; +} Lp4pole; + +static void +cleanup(LV2_Handle instance) +{ + Lp4pole* plugin = (Lp4pole*)instance; + + lp4pole_cleanup(plugin->lpf); + + free(instance); +} + +static void +connect_port(LV2_Handle instance, + uint32_t port, + void* data) +{ + Lp4pole* plugin = (Lp4pole*)instance; + + switch (port) { + case LP4POLE_CUTOFF: + plugin->cutoff = data; + break; + case LP4POLE_RESONANCE: + plugin->resonance = data; + break; + case LP4POLE_INPUT: + plugin->input = data; + break; + case LP4POLE_OUTPUT: + plugin->output = data; + break; + } +} + +static LV2_Handle +instantiate(const LV2_Descriptor* descriptor, + double sample_rate, + const char* bundle_path, + const LV2_Feature* const* features) +{ + Lp4pole* plugin = (Lp4pole*)malloc(sizeof(Lp4pole)); + + if (plugin) { + plugin->lpf = lp4pole_new(sample_rate); + if (!plugin->lpf) { + free(plugin); + plugin = 0; + } + } + return (LV2_Handle)plugin; +} + +static void +activate(LV2_Handle instance) +{ + Lp4pole* plugin = (Lp4pole*)instance; + + lp4pole_init(plugin->lpf); +} + +static void +runLp4pole_faraia_oa(LV2_Handle instance, + uint32_t sample_count) +{ + Lp4pole* plugin = (Lp4pole*)instance; + + /* Cutoff Frequency (array of floats of length sample_count) */ + float* cutoff = plugin->cutoff; + + /* Resonance (array of floats of length sample_count) */ + float* resonance = plugin->resonance; + + /* Input (array of floats of length sample_count) */ + float* input = plugin->input; + + /* Output (pointer to float value) */ + float* output = plugin->output; + + /* Instance data */ + LP4PoleFilter* lpf = plugin->lpf; + + float in; + float co; + float res; + + for (uint32_t s = 0; s < sample_count; ++s) { + co = cutoff[s]; + res = resonance[s]; + in = input[s]; + + lp4pole_set_params(lpf, co, res); + + output[s] = lp4pole_run(lpf, in); + } +} + +static void +runLp4pole_fcrcia_oa(LV2_Handle instance, + uint32_t sample_count) +{ + Lp4pole* plugin = (Lp4pole*)instance; + + /* Cutoff Frequency (float value) */ + float cutoff = *(plugin->cutoff); + + /* Resonance (float value) */ + float resonance = *(plugin->resonance); + + /* Input (array of floats of length sample_count) */ + float* input = plugin->input; + + /* Output (pointer to float value) */ + float* output = plugin->output; + + /* Instance data */ + LP4PoleFilter* lpf = plugin->lpf; + + float in; + + lp4pole_set_params(lpf, cutoff, resonance); + + for (uint32_t s = 0; s < sample_count; ++s) { + in = input[s]; + output[s] = lp4pole_run(lpf, in); + } +} + +static const LV2_Descriptor descriptor = { + "http://drobilla.net/plugins/blip/lp4pole", + instantiate, + connect_port, + activate, + runLp4pole_fcrcia_oa, + NULL, + cleanup, + NULL, +}; + +LV2_SYMBOL_EXPORT const LV2_Descriptor* +lv2_descriptor(uint32_t index) +{ + switch (index) { + case 0: return &descriptor; + default: return NULL; + } +} diff --git a/src/lp4pole_filter.c b/src/lp4pole_filter.c new file mode 100644 index 0000000..7d54691 --- /dev/null +++ b/src/lp4pole_filter.c @@ -0,0 +1,55 @@ +/* + lp4pole filter admin. + Copyright 2011 David Robillard + Copyright 2003 Mike Rawes + + See lp4pole_filter.h for history + + This 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 3 of the License, or + (at your option) any later version. + + This software 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 software. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdlib.h> +#include "lv2/lv2plug.in/ns/lv2core/lv2.h" +#include "lp4pole_filter.h" + +LP4PoleFilter* +lp4pole_new(double sample_rate) +{ + LP4PoleFilter* lpf; + + lpf = (LP4PoleFilter*)malloc(sizeof(LP4PoleFilter)); + + if (lpf) { + lpf->inv_nyquist = 2.0f / sample_rate; + lp4pole_init(lpf); + } + + return lpf; +} + +void +lp4pole_cleanup(LP4PoleFilter* lpf) +{ + if (lpf) { + free(lpf); + } +} + +void +lp4pole_init(LP4PoleFilter* lpf) +{ + lpf->in1 = lpf->in2 = lpf->in3 = lpf->in4 = 0.0f; + lpf->out1 = lpf->out2 = lpf->out3 = lpf->out4 = 0.0f; + lpf->max_abs_in = 0.0f; +} diff --git a/src/product.c b/src/product.c new file mode 100644 index 0000000..5c0b488 --- /dev/null +++ b/src/product.c @@ -0,0 +1,156 @@ +/* + An LV2 plugin to calculate the product of two signals. + Copyright 2011 David Robillard + Copyright 2002 Mike Rawes + + This 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 3 of the License, or + (at your option) any later version. + + This software 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 software. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdlib.h> +#include "lv2/lv2plug.in/ns/lv2core/lv2.h" + +#define PRODUCT_INPUT1 0 +#define PRODUCT_INPUT2 1 +#define PRODUCT_OUTPUT 2 + +typedef struct { + float* input1; + float* input2; + float* output; +} Product; + +static void +cleanup(LV2_Handle instance) +{ + free(instance); +} + +static void +connect_port(LV2_Handle instance, + uint32_t port, + void* data) +{ + Product* plugin = (Product*)instance; + + switch (port) { + case PRODUCT_INPUT1: + plugin->input1 = data; + break; + case PRODUCT_INPUT2: + plugin->input2 = data; + break; + case PRODUCT_OUTPUT: + plugin->output = data; + break; + } +} + +static LV2_Handle +instantiate(const LV2_Descriptor* descriptor, + double sample_rate, + const char* bundle_path, + const LV2_Feature* const* features) +{ + Product* plugin = (Product*)malloc(sizeof(Product)); + + return (LV2_Handle)plugin; +} + +static void +runProduct_iaia_oa(LV2_Handle instance, + uint32_t sample_count) +{ + Product* plugin = (Product*)instance; + + /* First Input (array of floats of length sample_count) */ + float* input1 = plugin->input1; + + /* Second Input (array of floats of length sample_count) */ + float* input2 = plugin->input2; + + /* Output (array of floats of length sample_count) */ + float* output = plugin->output; + + float in1; + float in2; + + for (uint32_t s = 0; s < sample_count; ++s) { + in1 = input1[s]; + in2 = input2[s]; + + output[s] = in1 * in2; + } +} + +static void +runProduct_iaic_oa(LV2_Handle instance, + uint32_t sample_count) +{ + Product* plugin = (Product*)instance; + + /* First Input (array of floats of length sample_count) */ + float* input1 = plugin->input1; + + /* Second Input (float value) */ + float input2 = *(plugin->input2); + + /* Output (array of floats of length sample_count) */ + float* output = plugin->output; + + float in1; + + for (uint32_t s = 0; s < sample_count; ++s) { + in1 = input1[s]; + + output[s] = in1 * input2; + } +} + +static void +runProduct_icic_oc(LV2_Handle instance, + uint32_t sample_count) +{ + Product* plugin = (Product*)instance; + + /* First Input (float value) */ + float input1 = *(plugin->input1); + + /* Second Input (float value) */ + float input2 = *(plugin->input2); + + /* Output (pointer to float value) */ + float* output = plugin->output; + + output[0] = input1 * input2; +} + +static const LV2_Descriptor descriptor = { + "http://drobilla.net/plugins/blip/product", + instantiate, + connect_port, + NULL, + runProduct_icic_oc, + NULL, + cleanup, + NULL, +}; + +LV2_SYMBOL_EXPORT const LV2_Descriptor* +lv2_descriptor(uint32_t index) +{ + switch (index) { + case 0: return &descriptor; + default: return NULL; + } +} diff --git a/src/pulse.c b/src/pulse.c new file mode 100644 index 0000000..17c8525 --- /dev/null +++ b/src/pulse.c @@ -0,0 +1,288 @@ +/* + An LV2 plugin to generate a bandlimited variable pulse waveform. + Copyright 2011 David Robillard + Copyright 2002 Mike Rawes + + This 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 3 of the License, or + (at your option) any later version. + + This software 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 software. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdlib.h> +#include "lv2/lv2plug.in/ns/lv2core/lv2.h" +#include "wavedata.h" + +#define PULSE_FREQUENCY 0 +#define PULSE_PULSEWIDTH 1 +#define PULSE_OUTPUT 2 + +typedef struct { + float* frequency; + float* pulsewidth; + float* output; + float phase; + Wavedata wdat; +} Pulse; + +static void +connect_port(LV2_Handle instance, + uint32_t port, + void* data) +{ + Pulse* plugin = (Pulse*)instance; + + switch (port) { + case PULSE_FREQUENCY: + plugin->frequency = data; + break; + case PULSE_PULSEWIDTH: + plugin->pulsewidth = data; + break; + case PULSE_OUTPUT: + plugin->output = data; + break; + } +} + +static LV2_Handle +instantiate(const LV2_Descriptor* descriptor, + double sample_rate, + const char* bundle_path, + const LV2_Feature* const* features) +{ + Pulse* plugin = (Pulse*)malloc(sizeof(Pulse)); + + if (wavedata_load(&plugin->wdat, BLOP_DLSYM_SAWTOOTH, sample_rate)) { + free(plugin); + return 0; + } + + return (LV2_Handle)plugin; +} + +static void +cleanup(LV2_Handle instance) +{ + Pulse* plugin = (Pulse*)instance; + + wavedata_unload(&plugin->wdat); + free(instance); +} + +static void +activate(LV2_Handle instance) +{ + Pulse* plugin = (Pulse*)instance; + + plugin->phase = 0.0f; +} + +static void +runPulse_fapa_oa(LV2_Handle instance, + uint32_t sample_count) +{ + Pulse* plugin = (Pulse*)instance; + + /* Frequency (array of float of length sample_count) */ + float* frequency = plugin->frequency; + + /* Pulse Width (array of float of length sample_count) */ + float* pulsewidth = plugin->pulsewidth; + + /* Output (pointer to float value) */ + float* output = plugin->output; + + /* Instance data */ + Wavedata* wdat = &plugin->wdat; + float phase = plugin->phase; + + float freq; + float pwidth; + float phase_shift; + + for (uint32_t s = 0; s < sample_count; ++s) { + freq = frequency[s]; + pwidth = f_clip(pulsewidth[s], 0.0f, 1.0f); + phase_shift = pwidth * wdat->sample_rate; + + /* Lookup which table to use from frequency */ + wavedata_get_table(wdat, freq); + + /* Get samples from sawtooth and phase shifted inverted sawtooth, + with approriate DC offset */ + output[s] = wavedata_get_sample(wdat, phase) + - wavedata_get_sample(wdat, phase + phase_shift) + + 1.0f - (2.0f * pwidth); + + /* Update phase, wrapping if necessary */ + phase += wdat->frequency; + if (phase < 0.0f) { + phase += wdat->sample_rate; + } else if (phase > wdat->sample_rate) { + phase -= wdat->sample_rate; + } + } + plugin->phase = phase; +} + +static void +runPulse_fapc_oa(LV2_Handle instance, + uint32_t sample_count) +{ + Pulse* plugin = (Pulse*)instance; + + /* Frequency (array of float of length sample_count) */ + float* frequency = plugin->frequency; + + /* Pulse Width (float value) */ + float pulsewidth = f_clip(*(plugin->pulsewidth), 0.0f, 1.0f); + + /* Output (pointer to float value) */ + float* output = plugin->output; + + /* Instance data */ + Wavedata* wdat = &plugin->wdat; + float phase = plugin->phase; + + float freq; + float dc_shift = 1.0 - (2.0 * pulsewidth); + float phase_shift = pulsewidth * wdat->sample_rate; + + for (uint32_t s = 0; s < sample_count; ++s) { + freq = frequency[s]; + + /* Lookup which table to use from frequency */ + wavedata_get_table(wdat, freq); + + /* Get samples from sawtooth and phase shifted inverted sawtooth, + with approriate DC offset */ + output[s] = wavedata_get_sample(wdat, phase) + - wavedata_get_sample(wdat, phase + phase_shift) + + dc_shift; + + /* Update phase, wrapping if necessary */ + phase += wdat->frequency; + if (phase < 0.0f) { + phase += wdat->sample_rate; + } else if (phase > wdat->sample_rate) { + phase -= wdat->sample_rate; + } + } + plugin->phase = phase; +} + +static void +runPulse_fcpa_oa(LV2_Handle instance, + uint32_t sample_count) +{ + Pulse* plugin = (Pulse*)instance; + + /* Frequency (float value) */ + float frequency = *(plugin->frequency); + + /* Pulse Width (array of float of length sample_count) */ + float* pulsewidth = plugin->pulsewidth; + + /* Output (pointer to float value) */ + float* output = plugin->output; + + /* Instance data */ + Wavedata* wdat = &plugin->wdat; + float phase = plugin->phase; + + float pwidth; + float phase_shift; + + wavedata_get_table(wdat, frequency); + + for (uint32_t s = 0; s < sample_count; ++s) { + pwidth = f_clip(pulsewidth[s], 0.0f, 1.0f); + phase_shift = pwidth * wdat->sample_rate; + + /* Get samples from sawtooth and phase shifted inverted sawtooth, + with approriate DC offset */ + output[s] = wavedata_get_sample(wdat, phase) + - wavedata_get_sample(wdat, phase + phase_shift) + + 1.0f - (2.0f * pwidth); + + /* Update phase, wrapping if necessary */ + phase += wdat->frequency; + if (phase < 0.0f) { + phase += wdat->sample_rate; + } else if (phase > wdat->sample_rate) { + phase -= wdat->sample_rate; + } + } + plugin->phase = phase; +} + +static void +runPulse_fcpc_oa(LV2_Handle instance, + uint32_t sample_count) +{ + Pulse* plugin = (Pulse*)instance; + + /* Frequency (float value) */ + float frequency = *(plugin->frequency); + + /* Pulse Width (float value) */ + float pulsewidth = f_clip(*(plugin->pulsewidth), 0.0f, 1.0f); + + /* Output (pointer to float value) */ + float* output = plugin->output; + + /* Instance data */ + Wavedata* wdat = &plugin->wdat; + float phase = plugin->phase; + + float dc_shift = 1.0f - (2.0f * pulsewidth); + float phase_shift = pulsewidth * wdat->sample_rate; + + wavedata_get_table(wdat, frequency); + + for (uint32_t s = 0; s < sample_count; ++s) { + /* Get samples from sawtooth and phase shifted inverted sawtooth, + with approriate DC offset */ + output[s] = wavedata_get_sample(wdat, phase) + - wavedata_get_sample(wdat, phase + phase_shift) + + dc_shift; + + /* Update phase, wrapping if necessary */ + phase += wdat->frequency; + if (phase < 0.0f) { + phase += wdat->sample_rate; + } else if (phase > wdat->sample_rate) { + phase -= wdat->sample_rate; + } + } + plugin->phase = phase; +} + +static const LV2_Descriptor descriptor = { + "http://drobilla.net/plugins/blip/pulse", + instantiate, + connect_port, + activate, + runPulse_fcpc_oa, + NULL, + cleanup, + NULL, +}; + +LV2_SYMBOL_EXPORT const LV2_Descriptor* +lv2_descriptor(uint32_t index) +{ + switch (index) { + case 0: return &descriptor; + default: return NULL; + } +} diff --git a/src/quantiser.c b/src/quantiser.c new file mode 100644 index 0000000..ce28866 --- /dev/null +++ b/src/quantiser.c @@ -0,0 +1,474 @@ +/* + An LV2 plugin to quantise an input to a set of fixed values. + Copyright 2011 David Robillard + Copyright 2003 Mike Rawes + + This 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 3 of the License, or + (at your option) any later version. + + This software 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 software. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdio.h> +#include <stdlib.h> +#include "lv2/lv2plug.in/ns/lv2core/lv2.h" +#include "math_func.h" +#include "common.h" + +#define QUANTISER_RANGE_MIN 0 +#define QUANTISER_RANGE_MAX 1 +#define QUANTISER_MATCH_RANGE 2 +#define QUANTISER_MODE 3 +#define QUANTISER_COUNT 4 +#define QUANTISER_VALUE_START 5 +#define QUANTISER_INPUT (QUANTISER_MAX_INPUTS + 5) +#define QUANTISER_OUTPUT (QUANTISER_MAX_INPUTS + 6) +#define QUANTISER_OUTPUT_CHANGED (QUANTISER_MAX_INPUTS + 7) + +typedef struct { + float* min; + float* max; + float* match_range; + float* mode; + float* count; + float* values[QUANTISER_MAX_INPUTS]; + float* input; + float* output_changed; + float* output; + float svalues[QUANTISER_MAX_INPUTS + 2]; + float temp[QUANTISER_MAX_INPUTS + 2]; + float last_found; +} Quantiser; + +/* + * f <= m <= l +*/ +static inline void +merge(float* v, + int f, + int m, + int l, + float* temp) +{ + int f1 = f; + int l1 = m; + int f2 = m + 1; + int l2 = l; + int i = f1; + + while ((f1 <= l1) && (f2 <= l2)) { + if (v[f1] < v[f2]) { + temp[i] = v[f1]; + f1++; + } else { + temp[i] = v[f2]; + f2++; + } + i++; + } + while (f1 <= l1) { + temp[i] = v[f1]; + f1++; + i++; + } + while (f2 <= l2) { + temp[i] = v[f2]; + f2++; + i++; + } + for (i = f; i <= l; i++) { + v[i] = temp[i]; + } +} + +/* + * Recursive Merge Sort + * Sort elements in unsorted vector v +*/ +static inline void +msort(float* v, + int f, + int l, + float* temp) +{ + int m; + + if (f < l) { + m = (f + l) / 2; + msort(v, f, m, temp); + msort(v, m + 1, l, temp); + merge(v, f, m, l, temp); + } +} + +/* + * Binary search for nearest match to sought value in + * ordered vector v of given size +*/ +static inline int +fuzzy_bsearch(float* v, + int size, + float sought) +{ + int f = 0; + int l = size - 1; + int m = ((l - f) / 2); + + while ((l - f) > 1) { + if (v[m] < sought) { + f = (l - f) / 2 + f; + } else { + l = (l - f) / 2 + f; + } + + m = ((l - f) / 2 + f); + } + + if (sought < v[m]) { + if (m > 0) { + if (FABSF(v[m] - sought) > FABSF(v[m - 1] - sought)) { + m--; + } + } + } else if (m < size - 1) { + if (FABSF(v[m] - sought) > FABSF(v[m + 1] - sought)) { + m++; + } + } + + return m; +} + +static void +cleanup(LV2_Handle instance) +{ + free(instance); +} + +static void +connect_port(LV2_Handle instance, + uint32_t port, + void* data) +{ + Quantiser* plugin = (Quantiser*)instance; + + switch (port) { + case QUANTISER_RANGE_MIN: + plugin->min = data; + break; + case QUANTISER_RANGE_MAX: + plugin->max = data; + break; + case QUANTISER_MATCH_RANGE: + plugin->match_range = data; + break; + case QUANTISER_MODE: + plugin->mode = data; + break; + case QUANTISER_COUNT: + plugin->count = data; + break; + case QUANTISER_INPUT: + plugin->input = data; + break; + case QUANTISER_OUTPUT: + plugin->output = data; + break; + case QUANTISER_OUTPUT_CHANGED: + plugin->output_changed = data; + break; + default: + if (port >= QUANTISER_VALUE_START && port < QUANTISER_OUTPUT) { + plugin->values[port - QUANTISER_VALUE_START] = data; + } + break; + } +} + +static LV2_Handle +instantiate(const LV2_Descriptor* descriptor, + double sample_rate, + const char* bundle_path, + const LV2_Feature* const* features) +{ + Quantiser* plugin = (Quantiser*)malloc(sizeof(Quantiser)); + + return (LV2_Handle)plugin; +} + +#if 0 +static void +runQuantiser_audio(LV2_Handle instance, + uint32_t sample_count) +{ + Quantiser* plugin = (Quantiser*)instance; + + /* Range Min (float value) */ + float min = *(plugin->min); + + /* Range Max (float value) */ + float max = *(plugin->max); + + /* Match Range (float value) */ + float match_range = *(plugin->match_range); + + /* Mode (float value) */ + float mode = *(plugin->mode); + + /* Count (float value) */ + float count = *(plugin->count); + + /* Input (array of float of length sample_count) */ + float* input = plugin->input; + + /* Values */ + float* values[QUANTISER_MAX_INPUTS]; + + /* Output (array of float of length sample_count) */ + float* output = plugin->output; + + /* Output Changed (array of float of length sample_count) */ + float* output_changed = plugin->output_changed; + + for (uint32_t s = 0; s < sample_count; s++) { + output[s] = input[s]; + } +} + +#endif + +static void +runQuantiser_control(LV2_Handle instance, + uint32_t sample_count) +{ + Quantiser* plugin = (Quantiser*)instance; + + /* Range Min (float value) */ + float min = *(plugin->min); + + /* Range Max (float value) */ + float max = *(plugin->max); + + /* Match Range (float value) */ + float match_range = FABSF(*(plugin->match_range)); + + /* Mode (float value) */ + float mode = *(plugin->mode); + + /* Count (float value) */ + float count = *(plugin->count); + + /* Input (array of float of length sample_count) */ + float* input = plugin->input; + + /* Output (array of float of length sample_count) */ + float* output = plugin->output; + + /* Output Changed (array of float of length sample_count) */ + float* output_changed = plugin->output_changed; + + /* Instance Data */ + float* temp = plugin->temp; + float* values = plugin->svalues; + float last_found = plugin->last_found; + + int md = LRINTF(mode); + int n = LRINTF(count); + int i; + float in; + float out_changed; + float range; + float offset; + float found; + int found_index = 0; + + /* Clip count if out of range */ + n = n < 1 ? 1 : (n > QUANTISER_MAX_INPUTS ? QUANTISER_MAX_INPUTS : n); + + /* Swap min and max if wrong way around */ + if (min > max) { + range = min; + min = max; + max = range; + } + range = max - min; + + /* Copy and sort required values */ + for (i = 0; i < n; i++) { + values[i + 1] = *(plugin->values[i]); + } + + msort(values, 1, n, temp); + + /* Add wrapped extremes */ + values[0] = values[n] - range; + values[n + 1] = values[1] + range; + + if (md < 1) { + /* Extend mode */ + for (uint32_t s = 0; s < sample_count; ++s) { + in = input[s]; + + if (range > 0.0f) { + if ((in < min) || (in > max)) { + offset = FLOORF((in - max) / range) + 1.0f; + offset *= range; + in -= offset; + + /* Quantise */ + found_index = fuzzy_bsearch(values, n + 2, in); + + /* Wrapped */ + if (found_index == 0) { + found_index = n; + offset -= range; + } else if (found_index == n + 1) { + found_index = 1; + offset += range; + } + + found = values[found_index]; + + /* Allow near misses */ + if (match_range > 0.0f) { + if (in < (found - match_range)) { + found -= match_range; + } else if (in > (found + match_range)) { + found += match_range; + } + } + found += offset; + } else { + /* Quantise */ + found_index = fuzzy_bsearch(values, n + 2, in); + if (found_index == 0) { + found_index = n; + found = values[n] - range; + } else if (found_index == n + 1) { + found_index = 1; + found = values[1] + range; + } else { + found = values[found_index]; + } + + if (match_range > 0.0f) { + if (in < (found - match_range)) { + found -= match_range; + } else if (in > (found + match_range)) { + found += match_range; + } + } + } + } else { + /* Min and max the same, so only one value to quantise to */ + found = min; + } + + /* Has quantised output changed? */ + if (FABSF(found - last_found) > 2.0001f * match_range) { + out_changed = 1.0f; + last_found = found; + } else { + out_changed = 0.0f; + } + + output[s] = found; + output_changed[s] = out_changed; + } + } else if (md == 1) { + /* Wrap mode */ + for (uint32_t s = 0; s < sample_count; ++s) { + in = input[s]; + + if (range > 0.0f) { + if ((in < min) || (in > max)) { + in -= (FLOORF((in - max) / range) + 1.0f) * range; + } + + /* Quantise */ + found_index = fuzzy_bsearch(values, n + 2, in); + if (found_index == 0) { + found_index = n; + } else if (found_index == n + 1) { + found_index = 1; + } + + found = values[found_index]; + + /* Allow near misses */ + if (match_range > 0.0f) { + if (in < (found - match_range)) { + found -= match_range; + } else if (in > (found + match_range)) { + found += match_range; + } + } + } else { + /* Min and max the same, so only one value to quantise to */ + found = min; + } + + /* Has quantised output changed? */ + if (FABSF(found - last_found) > match_range) { + out_changed = 1.0f; + last_found = found; + } else { + out_changed = 0.0f; + } + + output[s] = found; + output_changed[s] = out_changed; + } + } else { + /* Clip mode */ + for (uint32_t s = 0; s < sample_count; ++s) { + in = input[s]; + + if (range > 0.0f) { + /* Clip to range */ + if (in < min) { + found_index = 1; + } else if (in > max) { + found_index = n; + } else { + /* Quantise */ + found_index = fuzzy_bsearch(values + 1, n, in) + 1; + } + + found = values[found_index]; + + /* Allow near misses */ + if (match_range > 0.0f) { + if (in < (found - match_range)) { + found -= match_range; + } else if (in > (found + match_range)) { + found += match_range; + } + } + } else { + /* Min and max the same, so only one value to quantise to */ + found = min; + } + + /* Has quantised output changed? */ + if (FABSF(found - last_found) > match_range) { + out_changed = 1.0f; + last_found = found; + } else { + out_changed = 0.0f; + } + + output[s] = found; + output_changed[s] = out_changed; + } + } + plugin->last_found = last_found; +} diff --git a/src/random.c b/src/random.c new file mode 100644 index 0000000..9aab30a --- /dev/null +++ b/src/random.c @@ -0,0 +1,348 @@ +/* + An LV2 plugin to generate a random wave of varying frequency and smoothness. + Copyright 2011 David Robillard + Copyright 2002 Mike Rawes + + This 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 3 of the License, or + (at your option) any later version. + + This software 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 software. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdlib.h> +#include "lv2/lv2plug.in/ns/lv2core/lv2.h" +#include <time.h> +#include "math_func.h" +#include "common.h" + +#define RANDOM_FREQUENCY 0 +#define RANDOM_SMOOTH 1 +#define RANDOM_OUTPUT 2 + +typedef struct { + float* frequency; + float* smooth; + float* output; + float nyquist; + float inv_nyquist; + float phase; + float value1; + float value2; +} Random; + +float inv_rand_max; + +static void +cleanup(LV2_Handle instance) +{ + free(instance); +} + +static void +connect_port(LV2_Handle instance, + uint32_t port, + void* data) +{ + Random* plugin = (Random*)instance; + + switch (port) { + case RANDOM_FREQUENCY: + plugin->frequency = data; + break; + case RANDOM_SMOOTH: + plugin->smooth = data; + break; + case RANDOM_OUTPUT: + plugin->output = data; + break; + } +} + +static LV2_Handle +instantiate(const LV2_Descriptor* descriptor, + double sample_rate, + const char* bundle_path, + const LV2_Feature* const* features) +{ + Random* plugin = (Random*)malloc(sizeof(Random)); + + srand((int)time((time_t*)0)); + + inv_rand_max = 2.0f / (float)RAND_MAX; + + plugin->nyquist = (float)sample_rate / 2.0f; + plugin->inv_nyquist = 1.0f / plugin->nyquist; + + plugin->value1 = rand() * inv_rand_max - 1.0f; + plugin->value2 = rand() * inv_rand_max - 1.0f; + + return (LV2_Handle)plugin; +} + +static void +activate(LV2_Handle instance) +{ + Random* plugin = (Random*)instance; + + plugin->phase = 0.0f; +} + +static void +runRandom_fasa_oa(LV2_Handle instance, + uint32_t sample_count) +{ + Random* plugin = (Random*)instance; + + /* Frequency (Hz) (array of floats of length sample_count) */ + float* frequency = plugin->frequency; + + /* Wave smoothness (array of floats of length sample_count) */ + float* smooth = plugin->smooth; + + /* Output (array of floats of length sample_count) */ + float* output = plugin->output; + + /* Instance data */ + float nyquist = plugin->nyquist; + float inv_nyquist = plugin->inv_nyquist; + float phase = plugin->phase; + float value1 = plugin->value1; + float value2 = plugin->value2; + + float freq; + float smth; + float interval; + float result; + + for (uint32_t s = 0; s < sample_count; ++s) { + freq = f_clip(frequency[s], 0.0f, nyquist); + + smth = f_clip(smooth[s], 0.0f, 1.0f); + interval = (1.0f - smth) * 0.5f; + + if (phase < interval) { + result = 1.0f; + } else if (phase > (1.0f - interval)) { + result = -1.0f; + } else if (interval > 0.0f) { + result = COSF((phase - interval) / smth * M_PI); + } else { + result = COSF(phase * M_PI); + } + + result *= (value2 - value1) * 0.5f; + result -= (value2 + value1) * 0.5f; + + output[s] = result; + + phase += freq * inv_nyquist; + if (phase > 1.0f) { + phase -= 1.0f; + value1 = value2; + value2 = (float)rand() * inv_rand_max - 1.0f; + } + } + + plugin->phase = phase; + plugin->value1 = value1; + plugin->value2 = value2; +} + +static void +runRandom_fasc_oa(LV2_Handle instance, + uint32_t sample_count) +{ + Random* plugin = (Random*)instance; + + /* Frequency (Hz) (array of floats of length sample_count) */ + float* frequency = plugin->frequency; + + /* Wave smoothness (float value) */ + float smooth = f_clip(*(plugin->smooth), 0.0f, 1.0f); + + /* Output (array of floats of length sample_count) */ + float* output = plugin->output; + + /* Instance data */ + float nyquist = plugin->nyquist; + float inv_nyquist = plugin->inv_nyquist; + float phase = plugin->phase; + float value1 = plugin->value1; + float value2 = plugin->value2; + + float freq; + float interval = (1.0f - smooth) * 0.5f; + float result; + + for (uint32_t s = 0; s < sample_count; ++s) { + freq = f_clip(frequency[s], 0.0f, nyquist); + + if (phase < interval) { + result = 1.0f; + } else if (phase > (1.0f - interval)) { + result = -1.0f; + } else if (interval > 0.0f) { + result = COSF((phase - interval) / smooth * M_PI); + } else { + result = COSF(phase * M_PI); + } + + result *= (value2 - value1) * 0.5f; + result -= (value2 + value1) * 0.5f; + + output[s] = result; + + phase += freq * inv_nyquist; + if (phase > 1.0f) { + phase -= 1.0f; + value1 = value2; + value2 = (float)rand() * inv_rand_max - 1.0f; + } + } + + plugin->phase = phase; + plugin->value1 = value1; + plugin->value2 = value2; +} + +static void +runRandom_fcsa_oa(LV2_Handle instance, + uint32_t sample_count) +{ + Random* plugin = (Random*)instance; + + /* Frequency (Hz) (float value) */ + float frequency = *(plugin->frequency); + + /* Wave smoothness (array of floats of length sample_count) */ + float* smooth = plugin->smooth; + + /* Output (pointer to float value) */ + float* output = plugin->output; + + /* Instance data */ + float nyquist = plugin->nyquist; + float inv_nyquist = plugin->inv_nyquist; + float phase = plugin->phase; + float value1 = plugin->value1; + float value2 = plugin->value2; + + float phase_scale = f_clip(frequency, 0.0f, nyquist) * inv_nyquist; + float smth; + float interval; + float result; + + for (uint32_t s = 0; s < sample_count; ++s) { + smth = f_clip(smooth[s], 0.0f, 1.0f); + interval = (1.0f - smth) * 0.5f; + + if (phase < interval) { + result = 1.0f; + } else if (phase > (1.0f - interval)) { + result = -1.0f; + } else if (interval > 0.0f) { + result = COSF((phase - interval) / smth * M_PI); + } else { + result = COSF(phase * M_PI); + } + + result *= (value2 - value1) * 0.5f; + result -= (value2 + value1) * 0.5f; + + output[s] = result; + + phase += phase_scale; + if (phase > 1.0f) { + phase -= 1.0f; + value1 = value2; + value2 = (float)rand() * inv_rand_max - 1.0f; + } + } + + plugin->phase = phase; + plugin->value1 = value1; + plugin->value2 = value2; +} + +static void +runRandom_fcsc_oa(LV2_Handle instance, + uint32_t sample_count) +{ + Random* plugin = (Random*)instance; + + /* Frequency (Hz) (float value) */ + float frequency = *(plugin->frequency); + + /* Wave smoothness (float value) */ + float smooth = f_clip(*(plugin->smooth), 0.0f, 1.0f); + + /* Output (array of floats of length sample_count) */ + float* output = plugin->output; + + /* Instance data */ + float nyquist = plugin->nyquist; + float inv_nyquist = plugin->inv_nyquist; + float phase = plugin->phase; + float value1 = plugin->value1; + float value2 = plugin->value2; + + float phase_scale = f_clip(frequency, 0.0f, nyquist) * inv_nyquist; + float interval = (1.0f - smooth) * 0.5f; + float result; + + for (uint32_t s = 0; s < sample_count; ++s) { + if (phase < interval) { + result = 1.0f; + } else if (phase > (1.0f - interval)) { + result = -1.0f; + } else if (interval > 0.0f) { + result = COSF((phase - interval) / smooth * M_PI); + } else { + result = COSF(phase * M_PI); + } + + result *= (value2 - value1) * 0.5f; + result -= (value2 + value1) * 0.5f; + + output[s] = result; + + phase += phase_scale; + if (phase > 1.0f) { + phase -= 1.0f; + value1 = value2; + value2 = (float)rand() * inv_rand_max - 1.0f; + } + } + + plugin->phase = phase; + plugin->value1 = value1; + plugin->value2 = value2; +} + +static const LV2_Descriptor descriptor = { + "http://drobilla.net/plugins/blip/random", + instantiate, + connect_port, + activate, + runRandom_fcsc_oa, + NULL, + cleanup, + NULL, +}; + +LV2_SYMBOL_EXPORT const LV2_Descriptor* +lv2_descriptor(uint32_t index) +{ + switch (index) { + case 0: return &descriptor; + default: return NULL; + } +} diff --git a/src/ratio.c b/src/ratio.c new file mode 100644 index 0000000..33fc4e9 --- /dev/null +++ b/src/ratio.c @@ -0,0 +1,189 @@ +/* + An LV2 plugin to calculate the ratio of two signals. + Copyright 2011 David Robillard + Copyright 2004 Mike Rawes + + This 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 3 of the License, or + (at your option) any later version. + + This software 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 software. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdlib.h> +#include "lv2/lv2plug.in/ns/lv2core/lv2.h" +#include "math_func.h" +#include "common.h" + +#define RATIO_NUMERATOR 0 +#define RATIO_DENOMINATOR 1 +#define RATIO_OUTPUT 2 + +typedef struct { + float* numerator; + float* denominator; + float* output; +} Ratio; + +static void +cleanup(LV2_Handle instance) +{ + free(instance); +} + +static void +connect_port(LV2_Handle instance, + uint32_t port, + void* data) +{ + Ratio* plugin = (Ratio*)instance; + + switch (port) { + case RATIO_NUMERATOR: + plugin->numerator = data; + break; + case RATIO_DENOMINATOR: + plugin->denominator = data; + break; + case RATIO_OUTPUT: + plugin->output = data; + break; + } +} + +static LV2_Handle +instantiate(const LV2_Descriptor* descriptor, + double sample_rate, + const char* bundle_path, + const LV2_Feature* const* features) +{ + Ratio* plugin = (Ratio*)malloc(sizeof(Ratio)); + + return (LV2_Handle)plugin; +} + +static void +runRatio_nada_oa(LV2_Handle instance, + uint32_t sample_count) +{ + Ratio* plugin = (Ratio*)instance; + + /* Numerator (array of floats of length sample_count) */ + float* numerator = plugin->numerator; + + /* Denominator (array of floats of length sample_count) */ + float* denominator = plugin->denominator; + + /* Output (array of floats of length sample_count) */ + float* output = plugin->output; + + float n; + float d; + + for (uint32_t s = 0; s < sample_count; ++s) { + n = numerator[s]; + d = denominator[s]; + + d = COPYSIGNF(f_max(FABSF(d), 1e-16f), d); + + output[s] = n / d; + } +} + +static void +runRatio_nadc_oa(LV2_Handle instance, + uint32_t sample_count) +{ + Ratio* plugin = (Ratio*)instance; + + /* Numerator (array of floats of length sample_count) */ + float* numerator = plugin->numerator; + + /* Denominator (float value) */ + float denominator = *(plugin->denominator); + + /* Output (array of floats of length sample_count) */ + float* output = plugin->output; + + float n; + + denominator = COPYSIGNF(f_max(FABSF(denominator), 1e-16f), denominator); + + for (uint32_t s = 0; s < sample_count; ++s) { + n = numerator[s]; + + output[s] = n / denominator; + } +} + +static void +runRatio_ncda_oa(LV2_Handle instance, + uint32_t sample_count) +{ + Ratio* plugin = (Ratio*)instance; + + /* Numerator (float value) */ + float numerator = *(plugin->numerator); + + /* Denominator (array of floats of length sample_count) */ + float* denominator = plugin->denominator; + + /* Output (array of floats of length sample_count) */ + float* output = plugin->output; + + float d; + + for (uint32_t s = 0; s < sample_count; ++s) { + d = denominator[s]; + d = COPYSIGNF(f_max(FABSF(d), 1e-16f), d); + + output[s] = numerator / d; + } +} + +static void +runRatio_ncdc_oc(LV2_Handle instance, + uint32_t sample_count) +{ + Ratio* plugin = (Ratio*)instance; + + /* Numerator (float value) */ + float numerator = *(plugin->numerator); + + /* Denominator (float value) */ + float denominator = *(plugin->denominator); + + /* Output Frequency (pointer to float value) */ + float* output = plugin->output; + + denominator = COPYSIGNF(f_max(FABSF(denominator), 1e-16f), denominator); + + output[0] = numerator / denominator; +} + +static const LV2_Descriptor descriptor = { + "http://drobilla.net/plugins/blip/ratio", + instantiate, + connect_port, + NULL, + runRatio_ncdc_oc, + NULL, + cleanup, + NULL, +}; + +LV2_SYMBOL_EXPORT const LV2_Descriptor* +lv2_descriptor(uint32_t index) +{ + switch (index) { + case 0: return &descriptor; + default: return NULL; + } +} diff --git a/src/sawtooth.c b/src/sawtooth.c new file mode 100644 index 0000000..2e1a3ec --- /dev/null +++ b/src/sawtooth.c @@ -0,0 +1,171 @@ +/* + An LV2 plugin to generate a bandlimited sawtooth waveform. + Copyright 2011 David Robillard + Copyright 2002 Mike Rawes + + This 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 3 of the License, or + (at your option) any later version. + + This software 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 software. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdlib.h> +#include "lv2/lv2plug.in/ns/lv2core/lv2.h" +#include "wavedata.h" + +#define SAWTOOTH_FREQUENCY 0 +#define SAWTOOTH_OUTPUT 1 + +typedef struct { + float* frequency; + float* output; + float phase; + Wavedata wdat; +} Sawtooth; + +static void +connect_port(LV2_Handle instance, + uint32_t port, + void* data) +{ + Sawtooth* plugin = (Sawtooth*)instance; + + switch (port) { + case SAWTOOTH_FREQUENCY: + plugin->frequency = data; + break; + case SAWTOOTH_OUTPUT: + plugin->output = data; + break; + } +} + +static LV2_Handle +instantiate(const LV2_Descriptor* descriptor, + double sample_rate, + const char* bundle_path, + const LV2_Feature* const* features) +{ + Sawtooth* plugin = (Sawtooth*)malloc(sizeof(Sawtooth)); + + if (wavedata_load(&plugin->wdat, BLOP_DLSYM_SAWTOOTH, sample_rate)) { + free(plugin); + return 0; + } + + return (LV2_Handle)plugin; +} + +static void +cleanup(LV2_Handle instance) +{ + Sawtooth* plugin = (Sawtooth*)instance; + + wavedata_unload(&plugin->wdat); + free(instance); +} + +static void +activate(LV2_Handle instance) +{ + Sawtooth* plugin = (Sawtooth*)instance; + + plugin->phase = 0.0f; +} + +static void +runSawtooth_fa_oa(LV2_Handle instance, + uint32_t sample_count) +{ + Sawtooth* plugin = (Sawtooth*)instance; + + /* Frequency (array of float of length sample_count) */ + float* frequency = plugin->frequency; + + /* Output (pointer to float value) */ + float* output = plugin->output; + + /* Instance data */ + Wavedata* wdat = &plugin->wdat; + float phase = plugin->phase; + + float freq; + + for (uint32_t s = 0; s < sample_count; s++) { + freq = frequency[s]; + + /* Lookup table to play */ + wavedata_get_table(wdat, freq); + + output[s] = wavedata_get_sample(wdat, phase); + + /* Update phase, wrapping if necessary */ + phase += wdat->frequency; + if (phase < 0.0f) { + phase += wdat->sample_rate; + } else if (phase > wdat->sample_rate) { + phase -= wdat->sample_rate; + } + } + plugin->phase = phase; +} + +static void +runSawtooth_fc_oa(LV2_Handle instance, + uint32_t sample_count) +{ + Sawtooth* plugin = (Sawtooth*)instance; + + /* Frequency (float value) */ + float frequency = *(plugin->frequency); + + /* Output (pointer to float value) */ + float* output = plugin->output; + + /* Instance data */ + Wavedata* wdat = &plugin->wdat; + float phase = plugin->phase; + + wavedata_get_table(wdat, frequency); + + for (uint32_t s = 0; s < sample_count; s++) { + output[s] = wavedata_get_sample(wdat, phase); + + /* Update phase, wrapping if necessary */ + phase += wdat->frequency; + if (phase < 0.0f) { + phase += wdat->sample_rate; + } else if (phase > wdat->sample_rate) { + phase -= wdat->sample_rate; + } + } + plugin->phase = phase; +} + +static const LV2_Descriptor descriptor = { + "http://drobilla.net/plugins/blip/sawtooth", + instantiate, + connect_port, + activate, + runSawtooth_fc_oa, + NULL, + cleanup, + NULL, +}; + +LV2_SYMBOL_EXPORT const LV2_Descriptor* +lv2_descriptor(uint32_t index) +{ + switch (index) { + case 0: return &descriptor; + default: return NULL; + } +} diff --git a/src/sequencer.c b/src/sequencer.c new file mode 100644 index 0000000..7b39a50 --- /dev/null +++ b/src/sequencer.c @@ -0,0 +1,193 @@ +/* + An LV2 plugin to simulate an analogue style step sequencer. + Copyright 2011 David Robillard + Copyright 2002 Mike Rawes + + This 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 3 of the License, or + (at your option) any later version. + + This software 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 software. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdio.h> +#include <stdlib.h> +#include "lv2/lv2plug.in/ns/lv2core/lv2.h" +#include "math_func.h" +#include "common.h" + +#define SEQUENCER_GATE 0 +#define SEQUENCER_TRIGGER 1 +#define SEQUENCER_LOOP_POINT 2 +#define SEQUENCER_RESET 3 +#define SEQUENCER_VALUE_GATE_CLOSED 4 +#define SEQUENCER_VALUE_START 5 +#define SEQUENCER_OUTPUT (SEQUENCER_MAX_INPUTS + 5) + +typedef struct { + float* gate; + float* trigger; + float* loop_steps; + float* reset; + float* value_gate_closed; + float* values[SEQUENCER_MAX_INPUTS]; + float* output; + float srate; + float inv_srate; + float last_gate; + float last_trigger; + float last_value; + unsigned int step_index; +} Sequencer; + +static void +cleanup(LV2_Handle instance) +{ + free(instance); +} + +static void +connect_port(LV2_Handle instance, + uint32_t port, + void* data) +{ + Sequencer* plugin = (Sequencer*)instance; + + switch (port) { + case SEQUENCER_GATE: + plugin->gate = data; + break; + case SEQUENCER_TRIGGER: + plugin->trigger = data; + break; + case SEQUENCER_LOOP_POINT: + plugin->loop_steps = data; + break; + case SEQUENCER_OUTPUT: + plugin->output = data; + break; + case SEQUENCER_RESET: + plugin->reset = data; + break; + case SEQUENCER_VALUE_GATE_CLOSED: + plugin->value_gate_closed = data; + break; + default: + if (port >= SEQUENCER_VALUE_START && port < SEQUENCER_OUTPUT) { + plugin->values[port - SEQUENCER_VALUE_START] = data; + } + break; + } +} + +static LV2_Handle +instantiate(const LV2_Descriptor* descriptor, + double sample_rate, + const char* bundle_path, + const LV2_Feature* const* features) +{ + Sequencer* plugin = (Sequencer*)malloc(sizeof(Sequencer)); + + plugin->srate = (float)sample_rate; + plugin->inv_srate = 1.0f / plugin->srate; + + return (LV2_Handle)plugin; +} + +static void +activate(LV2_Handle instance) +{ + Sequencer* plugin = (Sequencer*)instance; + + plugin->last_gate = 0.0f; + plugin->last_trigger = 0.0f; + plugin->last_value = 0.0f; + plugin->step_index = 0; +} + +static void +runSequencer(LV2_Handle instance, + uint32_t sample_count) +{ + Sequencer* plugin = (Sequencer*)instance; + + /* Gate */ + float* gate = plugin->gate; + + /* Step Trigger */ + float* trigger = plugin->trigger; + + /* Loop Steps */ + float loop_steps = *(plugin->loop_steps); + + /* Reset to Value on Gate Close */ + float reset = *(plugin->reset); + + /* Value used when gate closed */ + float value_gate_closed = *(plugin->value_gate_closed); + + /* Step Values */ + float values[SEQUENCER_MAX_INPUTS]; + + /* Output */ + float* output = plugin->output; + + float last_gate = plugin->last_gate; + float last_trigger = plugin->last_trigger; + float last_value = plugin->last_value; + + unsigned int step_index = plugin->step_index; + unsigned int loop_index = LRINTF(loop_steps); + int rst = LRINTF(reset); + int i; + + loop_index = loop_index == 0 ? 1 : loop_index; + loop_index = (loop_index > SEQUENCER_MAX_INPUTS) + ? SEQUENCER_MAX_INPUTS + : loop_index; + + for (i = 0; i < SEQUENCER_MAX_INPUTS; i++) { + values[i] = *(plugin->values[i]); + } + + for (uint32_t s = 0; s < sample_count; ++s) { + if (gate[s] > 0.0f) { + if (trigger[s] > 0.0f && !(last_trigger > 0.0f)) { + if (last_gate > 0.0f) { + step_index++; + if (step_index >= loop_index) { + step_index = 0; + } + } else { + step_index = 0; + } + } + + output[s] = values[step_index]; + + last_value = values[step_index]; + } else { + if (rst) { + output[s] = value_gate_closed; + } else { + output[s] = last_value; + } + + step_index = 0; + } + last_gate = gate[s]; + last_trigger = trigger[s]; + } + + plugin->last_gate = last_gate; + plugin->last_trigger = last_trigger; + plugin->last_value = last_value; + plugin->step_index = step_index; +} diff --git a/src/square.c b/src/square.c new file mode 100644 index 0000000..001a47e --- /dev/null +++ b/src/square.c @@ -0,0 +1,172 @@ +/* + An LV2 plugin to generate a bandlimited square waveform. + Copyright 2011 David Robillard + Copyright 2002 Mike Rawes + + This 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 3 of the License, or + (at your option) any later version. + + This software 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 software. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdlib.h> +#include "lv2/lv2plug.in/ns/lv2core/lv2.h" +#include "wavedata.h" + +#define SQUARE_FREQUENCY 0 +#define SQUARE_OUTPUT 1 + +typedef struct { + float* frequency; + float* output; + float phase; + Wavedata wdat; +} Square; + +static void +connect_port(LV2_Handle instance, + uint32_t port, + void* data) +{ + Square* plugin = (Square*)instance; + + switch (port) { + case SQUARE_FREQUENCY: + plugin->frequency = data; + break; + case SQUARE_OUTPUT: + plugin->output = data; + break; + } +} + +static LV2_Handle +instantiate(const LV2_Descriptor* descriptor, + double sample_rate, + const char* bundle_path, + const LV2_Feature* const* features) +{ + Square* plugin = (Square*)malloc(sizeof(Square)); + + if (wavedata_load(&plugin->wdat, BLOP_DLSYM_SQUARE, sample_rate)) { + free(plugin); + return NULL; + } + + return (LV2_Handle)plugin; +} + +static void +cleanup(LV2_Handle instance) +{ + Square* plugin = (Square*)instance; + + wavedata_unload(&plugin->wdat); + free(instance); +} + +static void +activate(LV2_Handle instance) +{ + Square* plugin = (Square*)instance; + + plugin->phase = 0.0f; +} + +static void +runSquare_fa_oa(LV2_Handle instance, + uint32_t sample_count) +{ + Square* plugin = (Square*)instance; + + /* Frequency (array of float of length sample_count) */ + float* frequency = plugin->frequency; + + /* Output (pointer to float value) */ + float* output = plugin->output; + + /* Instance data */ + Wavedata* wdat = &plugin->wdat; + float phase = plugin->phase; + + float freq; + + for (uint32_t s = 0; s < sample_count; ++s) { + freq = frequency[s]; + + /* Get table to play */ + wavedata_get_table(wdat, freq); + + /* Get interpolated sample */ + output[s] = wavedata_get_sample(wdat, phase); + + /* Update phase, wrapping if necessary */ + phase += wdat->frequency; + if (phase < 0.0f) { + phase += wdat->sample_rate; + } else if (phase > wdat->sample_rate) { + phase -= wdat->sample_rate; + } + } + plugin->phase = phase; +} + +static void +runSquare_fc_oa(LV2_Handle instance, + uint32_t sample_count) +{ + Square* plugin = (Square*)instance; + + /* Frequency (float value) */ + float frequency = *(plugin->frequency); + + /* Output (pointer to float value) */ + float* output = plugin->output; + + /* Instance data */ + Wavedata* wdat = &plugin->wdat; + float phase = plugin->phase; + + wavedata_get_table(wdat, frequency); + + for (uint32_t s = 0; s < sample_count; ++s) { + output[s] = wavedata_get_sample(wdat, phase); + + /* Update phase, wrapping if necessary */ + phase += wdat->frequency; + if (phase < 0.0f) { + phase += wdat->sample_rate; + } else if (phase > wdat->sample_rate) { + phase -= wdat->sample_rate; + } + } + plugin->phase = phase; +} + +static const LV2_Descriptor descriptor = { + "http://drobilla.net/plugins/blip/square", + instantiate, + connect_port, + activate, + runSquare_fc_oa, + NULL, + cleanup, + NULL, +}; + +LV2_SYMBOL_EXPORT const LV2_Descriptor* +lv2_descriptor(uint32_t index) +{ + switch (index) { + case 0: return &descriptor; + default: return NULL; + } +} diff --git a/src/sum.c b/src/sum.c new file mode 100644 index 0000000..5f94796 --- /dev/null +++ b/src/sum.c @@ -0,0 +1,156 @@ +/* + An LV2 plugin to calculate the sum of two signals. + Copyright 2011 David Robillard + Copyright 2002 Mike Rawes + + This 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 3 of the License, or + (at your option) any later version. + + This software 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 software. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdlib.h> +#include "lv2/lv2plug.in/ns/lv2core/lv2.h" + +#define SUM_INPUT1 0 +#define SUM_INPUT2 1 +#define SUM_OUTPUT 2 + +typedef struct { + float* input1; + float* input2; + float* output; +} Sum; + +static void +cleanup(LV2_Handle instance) +{ + free(instance); +} + +static void +connect_port(LV2_Handle instance, + uint32_t port, + void* data) +{ + Sum* plugin = (Sum*)instance; + + switch (port) { + case SUM_INPUT1: + plugin->input1 = data; + break; + case SUM_INPUT2: + plugin->input2 = data; + break; + case SUM_OUTPUT: + plugin->output = data; + break; + } +} + +static LV2_Handle +instantiate(const LV2_Descriptor* descriptor, + double sample_rate, + const char* bundle_path, + const LV2_Feature* const* features) +{ + Sum* plugin = (Sum*)malloc(sizeof(Sum)); + + return (LV2_Handle)plugin; +} + +static void +runSum_iaia_oa(LV2_Handle instance, + uint32_t sample_count) +{ + Sum* plugin = (Sum*)instance; + + /* First Input (array of floats of length sample_count) */ + float* input1 = plugin->input1; + + /* Second Input (array of floats of length sample_count) */ + float* input2 = plugin->input2; + + /* Output (array of floats of length sample_count) */ + float* output = plugin->output; + + float in1; + float in2; + + for (uint32_t s = 0; s < sample_count; ++s) { + in1 = input1[s]; + in2 = input2[s]; + + output[s] = in1 + in2; + } +} + +static void +runSum_iaic_oa(LV2_Handle instance, + uint32_t sample_count) +{ + Sum* plugin = (Sum*)instance; + + /* First Input (array of floats of length sample_count) */ + float* input1 = plugin->input1; + + /* Second Input (float value) */ + float input2 = *(plugin->input2); + + /* Output (array of floats of length sample_count) */ + float* output = plugin->output; + + float in1; + + for (uint32_t s = 0; s < sample_count; ++s) { + in1 = input1[s]; + + output[s] = in1 + input2; + } +} + +static void +runSum_icic_oc(LV2_Handle instance, + uint32_t sample_count) +{ + Sum* plugin = (Sum*)instance; + + /* First Input (float value) */ + float input1 = *(plugin->input1); + + /* Second Input (float value) */ + float input2 = *(plugin->input2); + + /* Output (pointer to float value) */ + float* output = plugin->output; + + output[0] = input1 + input2; +} + +static const LV2_Descriptor descriptor = { + "http://drobilla.net/plugins/blip/sum", + instantiate, + connect_port, + NULL, + runSum_icic_oc, + NULL, + cleanup, + NULL, +}; + +LV2_SYMBOL_EXPORT const LV2_Descriptor* +lv2_descriptor(uint32_t index) +{ + switch (index) { + case 0: return &descriptor; + default: return NULL; + } +} diff --git a/src/sync_pulse.c b/src/sync_pulse.c new file mode 100644 index 0000000..4dc9dad --- /dev/null +++ b/src/sync_pulse.c @@ -0,0 +1,205 @@ +/* + An LV2 plugin to generate a non-bandlimited variable-pulse waveform with gate + for trigger and sync. + Copyright 2011 David Robillard + Copyright 2003 Mike Rawes + + This 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 3 of the License, or + (at your option) any later version. + + This software 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 software. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdlib.h> +#include "lv2/lv2plug.in/ns/lv2core/lv2.h" +#include "common.h" + +#define SYNCPULSE_FREQUENCY 0 +#define SYNCPULSE_PULSEWIDTH 1 +#define SYNCPULSE_GATE 2 +#define SYNCPULSE_OUTPUT 3 + +typedef struct { + float* frequency; + float* pulsewidth; + float* gate; + float* output; + float srate; + float phase; +} SyncPulse; + +static void +cleanup(LV2_Handle instance) +{ + free(instance); +} + +static void +connect_port(LV2_Handle instance, + uint32_t port, + void* data) +{ + SyncPulse* plugin = (SyncPulse*)instance; + + switch (port) { + case SYNCPULSE_FREQUENCY: + plugin->frequency = data; + break; + case SYNCPULSE_PULSEWIDTH: + plugin->pulsewidth = data; + break; + case SYNCPULSE_GATE: + plugin->gate = data; + break; + case SYNCPULSE_OUTPUT: + plugin->output = data; + break; + } +} + +static LV2_Handle +instantiate(const LV2_Descriptor* descriptor, + double sample_rate, + const char* bundle_path, + const LV2_Feature* const* features) +{ + SyncPulse* plugin = (SyncPulse*)malloc(sizeof(SyncPulse)); + + plugin->srate = (float)sample_rate; + + return (LV2_Handle)plugin; +} + +static void +activate(LV2_Handle instance) +{ + SyncPulse* plugin = (SyncPulse*)instance; + + plugin->phase = 0.0f; +} + +static void +runSyncPulse_fapaga_oa(LV2_Handle instance, + uint32_t sample_count) +{ + SyncPulse* plugin = (SyncPulse*)instance; + + /* Frequency (array of float of length sample_count) */ + float* frequency = plugin->frequency; + + /* Pulse Width (array of float of length sample_count) */ + float* pulsewidth = plugin->pulsewidth; + + /* Gate (array of float of length sample_count) */ + float* gate = plugin->gate; + + /* Output (pointer to float value) */ + float* output = plugin->output; + + /* Instance data */ + float phase = plugin->phase; + float srate = plugin->srate; + + float freq; + float pwidth; + + for (uint32_t s = 0; s < sample_count; ++s) { + if (gate[s] > 0.0f) { + freq = frequency[s]; + pwidth = f_clip(pulsewidth[s], 0.0f, 1.0f) * srate; + + if (phase < pwidth) { + output[s] = 1.0f; + } else { + output[s] = -1.0f; + } + + phase += freq; + if (phase < 0.0f) { + phase += srate; + } else if (phase > srate) { + phase -= srate; + } + } else { + output[s] = 0.0f; + phase = 0.0f; + } + } + + plugin->phase = phase; +} + +static void +runSyncPulse_fcpcga_oa(LV2_Handle instance, + uint32_t sample_count) +{ + SyncPulse* plugin = (SyncPulse*)instance; + + /* Frequency (float value) */ + float frequency = *(plugin->frequency); + + /* Pulse Width (float value) */ + float pulsewidth = f_clip(*(plugin->pulsewidth), 0.0f, 1.0f); + + /* Gate (array of float of length sample_count) */ + float* gate = plugin->gate; + + /* Output (pointer to float value) */ + float* output = plugin->output; + + /* Instance Data */ + float phase = plugin->phase; + float srate = plugin->srate; + + pulsewidth *= srate; + + for (uint32_t s = 0; s < sample_count; ++s) { + if (gate[s] > 0.0f) { + if (phase < pulsewidth) { + output[s] = 1.0f; + } else { + output[s] = -1.0f; + } + + phase += frequency; + if (phase < 0.0f) { + phase += srate; + } else if (phase > srate) { + phase -= srate; + } + } else { + output[s] = 0.0f; + phase = 0.0f; + } + } + + plugin->phase = phase; +} + +static const LV2_Descriptor descriptor = { + "http://drobilla.net/plugins/blip/sync_pulse", + instantiate, + connect_port, + activate, + runSyncPulse_fcpcga_oa, + NULL, + cleanup, + NULL, +}; + +LV2_SYMBOL_EXPORT const LV2_Descriptor* +lv2_descriptor(uint32_t index) +{ + switch (index) { + case 0: return &descriptor; + default: return NULL; + } +} diff --git a/src/sync_square.c b/src/sync_square.c new file mode 100644 index 0000000..df33a09 --- /dev/null +++ b/src/sync_square.c @@ -0,0 +1,193 @@ +/* + An LV2 plugin to generate a non-bandlimited square waveform with gate for + trigger and sync. + Copyright 2011 David Robillard + Copyright 2002 Mike Rawes + + This 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 3 of the License, or + (at your option) any later version. + + This software 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 software. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdlib.h> +#include "lv2/lv2plug.in/ns/lv2core/lv2.h" + +#define SYNCSQUARE_FREQUENCY 0 +#define SYNCSQUARE_GATE 1 +#define SYNCSQUARE_OUTPUT 2 + +typedef struct { + float* frequency; + float* gate; + float* output; + float srate; + float nyquist; + float phase; +} SyncSquare; + +static void +cleanup(LV2_Handle instance) +{ + free(instance); +} + +static void +connect_port(LV2_Handle instance, + uint32_t port, + void* data) +{ + SyncSquare* plugin = (SyncSquare*)instance; + + switch (port) { + case SYNCSQUARE_FREQUENCY: + plugin->frequency = data; + break; + case SYNCSQUARE_GATE: + plugin->gate = data; + break; + case SYNCSQUARE_OUTPUT: + plugin->output = data; + break; + } +} + +static LV2_Handle +instantiate(const LV2_Descriptor* descriptor, + double sample_rate, + const char* bundle_path, + const LV2_Feature* const* features) +{ + SyncSquare* plugin = (SyncSquare*)malloc(sizeof(SyncSquare)); + + plugin->srate = (float)sample_rate; + plugin->nyquist = (float)(sample_rate / 2); + + return (LV2_Handle)plugin; +} + +static void +activate(LV2_Handle instance) +{ + SyncSquare* plugin = (SyncSquare*)instance; + + plugin->phase = 0.0f; +} + +static void +runSyncSquare_faga_oa(LV2_Handle instance, + uint32_t sample_count) +{ + SyncSquare* plugin = (SyncSquare*)instance; + + /* Frequency (array of float of length sample_count) */ + float* frequency = plugin->frequency; + + /* Gate (array of float of length sample_count) */ + float* gate = plugin->gate; + + /* Output (pointer to float value) */ + float* output = plugin->output; + + /* Instance data */ + float phase = plugin->phase; + float srate = plugin->srate; + float nyquist = plugin->nyquist; + + float freq; + + for (uint32_t s = 0; s < sample_count; ++s) { + if (gate[s] > 0.0f) { + freq = frequency[s]; + + if (phase < nyquist) { + output[s] = 1.0f; + } else { + output[s] = -1.0f; + } + + phase += freq; + if (phase < 0.0f) { + phase += srate; + } else if (phase > srate) { + phase -= srate; + } + } else { + output[s] = 0.0f; + phase = 0.0f; + } + } + + plugin->phase = phase; +} + +static void +runSyncSquare_fcga_oa(LV2_Handle instance, + uint32_t sample_count) +{ + SyncSquare* plugin = (SyncSquare*)instance; + + /* Frequency (float value) */ + float frequency = *(plugin->frequency); + + /* Gate (array of float of length sample_count) */ + float* gate = plugin->gate; + + /* Output (pointer to float value) */ + float* output = plugin->output; + + /* Instance Data */ + float phase = plugin->phase; + float srate = plugin->srate; + float nyquist = plugin->nyquist; + + for (uint32_t s = 0; s < sample_count; ++s) { + if (gate[s] > 0.0f) { + if (phase < nyquist) { + output[s] = 1.0f; + } else { + output[s] = -1.0f; + } + + phase += frequency; + if (phase < 0.0f) { + phase += srate; + } else if (phase > srate) { + phase -= srate; + } + } else { + output[s] = 0.0f; + phase = 0.0f; + } + } + + plugin->phase = phase; +} + +static const LV2_Descriptor descriptor = { + "http://drobilla.net/plugins/blip/sync_square", + instantiate, + connect_port, + activate, + runSyncSquare_fcga_oa, + NULL, + cleanup, + NULL, +}; + +LV2_SYMBOL_EXPORT const LV2_Descriptor* +lv2_descriptor(uint32_t index) +{ + switch (index) { + case 0: return &descriptor; + default: return NULL; + } +} diff --git a/src/tracker.c b/src/tracker.c new file mode 100644 index 0000000..4460a34 --- /dev/null +++ b/src/tracker.c @@ -0,0 +1,229 @@ +/* + An LV2 plugin to shape a signal in various ways. + Copyright 2011 David Robillard + Copyright 2003 Mike Rawes + + This 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 3 of the License, or + (at your option) any later version. + + This software 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 software. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdlib.h> +#include "lv2/lv2plug.in/ns/lv2core/lv2.h" +#include "common.h" + +#define TRACKER_GATE 0 +#define TRACKER_HATTACK 1 +#define TRACKER_HDECAY 2 +#define TRACKER_LATTACK 3 +#define TRACKER_LDECAY 4 +#define TRACKER_INPUT 5 +#define TRACKER_OUTPUT 6 + +typedef struct { + float* gate; + float* hattack; + float* hdecay; + float* lattack; + float* ldecay; + float* input; + float* output; + float coeff; + float last_value; +} Tracker; + +static void +cleanup(LV2_Handle instance) +{ + free(instance); +} + +static void +connect_port(LV2_Handle instance, + uint32_t port, + void* data) +{ + Tracker* plugin = (Tracker*)instance; + + switch (port) { + case TRACKER_GATE: + plugin->gate = data; + break; + case TRACKER_HATTACK: + plugin->hattack = data; + break; + case TRACKER_HDECAY: + plugin->hdecay = data; + break; + case TRACKER_LATTACK: + plugin->lattack = data; + break; + case TRACKER_LDECAY: + plugin->ldecay = data; + break; + case TRACKER_INPUT: + plugin->input = data; + break; + case TRACKER_OUTPUT: + plugin->output = data; + break; + } +} + +static LV2_Handle +instantiate(const LV2_Descriptor* descriptor, + double sample_rate, + const char* bundle_path, + const LV2_Feature* const* features) +{ + Tracker* plugin = (Tracker*)malloc(sizeof(Tracker)); + + plugin->coeff = 2.0f * M_PI / (float)sample_rate; + + return (LV2_Handle)plugin; +} + +static void +activate(LV2_Handle instance) +{ + Tracker* plugin = (Tracker*)instance; + + plugin->last_value = 0.0f; +} + +static void +runTracker_gaaadaia_oa(LV2_Handle instance, + uint32_t sample_count) +{ + Tracker* plugin = (Tracker*)instance; + + /* Gate (array of floats of length sample_count) */ + float* gate = plugin->gate; + + /* Gate High Attack Rate (array of floats of length sample_count) */ + float* hattack = plugin->hattack; + + /* Gate High Decay Rate (array of floats of length sample_count) */ + float* hdecay = plugin->hdecay; + + /* Gate Low Attack Rate (array of floats of length sample_count) */ + float* lattack = plugin->lattack; + + /* Gate Low Decay Rate (array of floats of length sample_count) */ + float* ldecay = plugin->ldecay; + + /* Input (array of floats of length sample_count) */ + float* input = plugin->input; + + /* Output (array of floats of length sample_count) */ + float* output = plugin->output; + + /* Instance Data */ + float coeff = plugin->coeff; + float last_value = plugin->last_value; + + float rate; + float in; + + for (uint32_t s = 0; s < sample_count; ++s) { + in = input[s]; + + if (gate[s] > 0.0f) { + rate = in > last_value ? hattack[s] : hdecay[s]; + } else { + rate = in > last_value ? lattack[s] : ldecay[s]; + } + + rate = f_min(1.0f, rate * coeff); + last_value = last_value * (1.0f - rate) + in * rate; + + output[s] = last_value; + } + + plugin->last_value = last_value; +} + +static void +runTracker_gaacdcia_oa(LV2_Handle instance, + uint32_t sample_count) +{ + Tracker* plugin = (Tracker*)instance; + + /* Gate (array of floats of length sample_count) */ + float* gate = plugin->gate; + + /* Gate High Attack Rate (float value) */ + float hattack = *(plugin->hattack); + + /* Gate High Decay Rate (float value) */ + float hdecay = *(plugin->hdecay); + + /* Gate Low Attack Rate (float value) */ + float lattack = *(plugin->lattack); + + /* Gate Low Decay Rate (float value) */ + float ldecay = *(plugin->ldecay); + + /* Input (array of floats of length sample_count) */ + float* input = plugin->input; + + /* Output (array of floats of length sample_count) */ + float* output = plugin->output; + + /* Instance Data */ + float coeff = plugin->coeff; + float last_value = plugin->last_value; + + float in; + float rate; + + hattack = f_min(1.0f, hattack * coeff); + hdecay = f_min(1.0f, hdecay * coeff); + lattack = f_min(1.0f, lattack * coeff); + ldecay = f_min(1.0f, ldecay * coeff); + + for (uint32_t s = 0; s < sample_count; ++s) { + in = input[s]; + + if (gate[s] > 0.0f) { + rate = in > last_value ? hattack : hdecay; + } else { + rate = in > last_value ? lattack : ldecay; + } + + last_value = last_value * (1.0f - rate) + in * rate; + + output[s] = last_value; + } + + plugin->last_value = last_value; +} + +static const LV2_Descriptor descriptor = { + "http://drobilla.net/plugins/blip/tracker", + instantiate, + connect_port, + activate, + runTracker_gaacdcia_oa, + NULL, + cleanup, + NULL, +}; + +LV2_SYMBOL_EXPORT const LV2_Descriptor* +lv2_descriptor(uint32_t index) +{ + switch (index) { + case 0: return &descriptor; + default: return NULL; + } +} diff --git a/src/triangle.c b/src/triangle.c new file mode 100644 index 0000000..718369a --- /dev/null +++ b/src/triangle.c @@ -0,0 +1,307 @@ +/* + An LV2 plugin to generate a bandlimited slope-variable triangle waveform. + Copyright 2011 David Robillard + Copyright 2002 Mike Rawes + + This 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 3 of the License, or + (at your option) any later version. + + This software 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 software. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdlib.h> +#include "lv2/lv2plug.in/ns/lv2core/lv2.h" +#include "wavedata.h" + +#define TRIANGLE_FREQUENCY 0 +#define TRIANGLE_SLOPE 1 +#define TRIANGLE_OUTPUT 2 + +typedef struct { + float* frequency; + float* slope; + float* output; + float phase; + float min_slope; + float max_slope; + Wavedata wdat; +} Triangle; + +static void +connect_port(LV2_Handle instance, + uint32_t port, + void* data) +{ + Triangle* plugin = (Triangle*)instance; + + switch (port) { + case TRIANGLE_FREQUENCY: + plugin->frequency = data; + break; + case TRIANGLE_SLOPE: + plugin->slope = data; + break; + case TRIANGLE_OUTPUT: + plugin->output = data; + break; + } +} + +static LV2_Handle +instantiate(const LV2_Descriptor* descriptor, + double sample_rate, + const char* bundle_path, + const LV2_Feature* const* features) +{ + Triangle* plugin = (Triangle*)malloc(sizeof(Triangle)); + + if (wavedata_load(&plugin->wdat, BLOP_DLSYM_PARABOLA, sample_rate)) { + free(plugin); + return 0; + } + + plugin->min_slope = 2.0f / plugin->wdat.sample_rate; + plugin->max_slope = 1.0f - plugin->min_slope; + + return (LV2_Handle)plugin; +} + +static void +cleanup(LV2_Handle instance) +{ + Triangle* plugin = (Triangle*)instance; + + wavedata_unload(&plugin->wdat); + free(instance); +} + +static void +activate(LV2_Handle instance) +{ + Triangle* plugin = (Triangle*)instance; + + plugin->phase = 0.0f; +} + +static void +runTriangle_fasa_oa(LV2_Handle instance, + uint32_t sample_count) +{ + Triangle* plugin = (Triangle*)instance; + + /* Frequency (array of float of length sample_count) */ + float* frequency = plugin->frequency; + + /* Slope (array of float of length sample_count) */ + float* slope = plugin->slope; + + /* Output (pointer to float value) */ + float* output = plugin->output; + + /* Instance data */ + Wavedata* wdat = &plugin->wdat; + float phase = plugin->phase; + float min_slope = plugin->min_slope; + float max_slope = plugin->max_slope; + + float freq; + float slp; + float phase_shift; + + for (uint32_t s = 0; s < sample_count; ++s) { + freq = frequency[s]; + slp = f_clip(slope[s], min_slope, max_slope); + phase_shift = slp * wdat->sample_rate; + + /* Lookup which table to use from frequency */ + wavedata_get_table(wdat, freq); + + /* Get samples from parabola and phase shifted inverted parabola, + and scale to compensate */ + output[s] = (wavedata_get_sample(wdat, phase) + - wavedata_get_sample(wdat, phase + phase_shift)) + / (8.0f * (slp - (slp * slp))); + + /* Update phase, wrapping if necessary */ + phase += wdat->frequency; + if (phase < 0.0f) { + phase += wdat->sample_rate; + } else if (phase > wdat->sample_rate) { + phase -= wdat->sample_rate; + } + } + plugin->phase = phase; +} + +static void +runTriangle_fasc_oa(LV2_Handle instance, + uint32_t sample_count) +{ + Triangle* plugin = (Triangle*)instance; + + /* Frequency (array of float of length sample_count) */ + float* frequency = plugin->frequency; + + /* Slope (float value) */ + float slope = *(plugin->slope); + + /* Output (pointer to float value) */ + float* output = plugin->output; + + /* Instance data */ + Wavedata* wdat = &plugin->wdat; + float phase = plugin->phase; + float min_slope = plugin->min_slope; + float max_slope = plugin->max_slope; + + float freq; + float phase_shift; + float scale; + + slope = f_clip(slope, min_slope, max_slope); + scale = 1.0f / (8.0f * (slope - (slope * slope))); + phase_shift = slope * wdat->sample_rate; + + for (uint32_t s = 0; s < sample_count; ++s) { + freq = frequency[s]; + + /* Lookup which table to use from frequency */ + wavedata_get_table(wdat, freq); + + /* Get samples from parabola and phase shifted inverted parabola, + and scale to compensate */ + output[s] = (wavedata_get_sample(wdat, phase) + - wavedata_get_sample(wdat, phase + phase_shift)) * scale; + + /* Update phase, wrapping if necessary */ + phase += wdat->frequency; + if (phase < 0.0f) { + phase += wdat->sample_rate; + } else if (phase > wdat->sample_rate) { + phase -= wdat->sample_rate; + } + } + plugin->phase = phase; +} + +static void +runTriangle_fcsa_oa(LV2_Handle instance, + uint32_t sample_count) +{ + Triangle* plugin = (Triangle*)instance; + + /* Frequency (float value) */ + float frequency = *(plugin->frequency); + + /* Slope (array of float of length sample_count) */ + float* slope = plugin->slope; + + /* Output (pointer to float value) */ + float* output = plugin->output; + + /* Instance data */ + Wavedata* wdat = &plugin->wdat; + float phase = plugin->phase; + float min_slope = plugin->min_slope; + float max_slope = plugin->max_slope; + + float slp; + float phase_shift; + + wavedata_get_table(wdat, frequency); + + for (uint32_t s = 0; s < sample_count; ++s) { + slp = f_clip(slope[s], min_slope, max_slope); + phase_shift = slp * wdat->sample_rate; + + /* Get samples from parabola and phase shifted inverted parabola, + and scale to compensate */ + output[s] = (wavedata_get_sample(wdat, phase) + - wavedata_get_sample(wdat, phase + phase_shift)) + / (8.0f * (slp - (slp * slp))); + + /* Update phase, wrapping if necessary */ + phase += wdat->frequency; + if (phase < 0.0f) { + phase += wdat->sample_rate; + } else if (phase > wdat->sample_rate) { + phase -= wdat->sample_rate; + } + } + plugin->phase = phase; +} + +static void +runTriangle_fcsc_oa(LV2_Handle instance, + uint32_t sample_count) +{ + Triangle* plugin = (Triangle*)instance; + + /* Frequency (float value) */ + float frequency = *(plugin->frequency); + + /* Slope (float value) */ + float slope = *(plugin->slope); + + /* Output (pointer to float value) */ + float* output = plugin->output; + + /* Instance data */ + Wavedata* wdat = &plugin->wdat; + float phase = plugin->phase; + float min_slope = plugin->min_slope; + float max_slope = plugin->max_slope; + + float scale; + float phase_shift; + + slope = f_clip(slope, min_slope, max_slope); + scale = 1.0f / (8.0f * (slope - (slope * slope))); + phase_shift = slope * wdat->sample_rate; + + wavedata_get_table(wdat, frequency); + + for (uint32_t s = 0; s < sample_count; ++s) { + /* Get samples from parabola and phase shifted inverted parabola, + and scale to compensate */ + output[s] = (wavedata_get_sample(wdat, phase) + - wavedata_get_sample(wdat, phase + phase_shift)) * scale; + + /* Update phase, wrapping if necessary */ + phase += wdat->frequency; + if (phase < 0.0f) { + phase += wdat->sample_rate; + } else if (phase > wdat->sample_rate) { + phase -= wdat->sample_rate; + } + } + plugin->phase = phase; +} + +static const LV2_Descriptor descriptor = { + "http://drobilla.net/plugins/blip/triangle", + instantiate, + connect_port, + activate, + runTriangle_fcsc_oa, + NULL, + cleanup, + NULL, +}; + +LV2_SYMBOL_EXPORT const LV2_Descriptor* +lv2_descriptor(uint32_t index) +{ + switch (index) { + case 0: return &descriptor; + default: return NULL; + } +} diff --git a/src/wavedata.c b/src/wavedata.c new file mode 100644 index 0000000..8f7e359 --- /dev/null +++ b/src/wavedata.c @@ -0,0 +1,141 @@ +/* + Oscillator wave data generation. + Copyright 2011 David Robillard + Copyright 2002 Mike Rawes + + This 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 3 of the License, or + (at your option) any later version. + + This software 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 software. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <sys/types.h> +#include <sys/stat.h> +#include <dirent.h> +#include <dlfcn.h> +#include <stdlib.h> +#include <string.h> +#include "lv2/lv2plug.in/ns/lv2core/lv2.h" +#include <config.h> +#include "wavedata.h" + +#ifndef WAVEDATA_SUBDIR +#warning *** No wavedata subdir given, using default 'blip_files' +#define WAVEDATA_SUBDIR "blip_files" +#endif + +int +wavedata_load(Wavedata* w, + const char* wdat_descriptor_name, + unsigned long sample_rate) +{ + const char* subdir = WAVEDATA_SUBDIR; + char* ladspa_path; + const char* start; + const char* end; + int extra; + size_t subdirlen = strlen(WAVEDATA_SUBDIR); + size_t length; + size_t pathlen; + char* path; + char* filename; + DIR* dp; + struct dirent* ep; + struct stat sb; + void* handle; + int (*desc_func)(Wavedata*, unsigned long); + int retval = -1; + + /* Get LADPSA_PATH, if available */ + ladspa_path = getenv("LV2_PATH"); + if (!ladspa_path) { + ladspa_path = "/usr/lib/ladspa:/usr/local/lib/ladspa"; + } + + start = ladspa_path; + while (*start != '\0') { + while (*start == ':') { + start++; + } + end = start; + while (*end != ':' && *end != '\0') { + end++; + } + if (end - start > 0) { + extra = (*(end - 1) == '/') ? 0 : 1; + path = (char*)malloc(end - start + extra + subdirlen + 1 + 1); + if (path) { + strncpy(path, start, end - start); + if (extra == 1) { + path[end - start] = '/'; + } + + path[end - start + extra] = '\0'; + + if (subdirlen > 0) { + strncat(path, subdir, subdirlen); + path[end - start + extra + subdirlen] = '/'; + path[end - start + extra + subdirlen + 1] = '\0'; + } else { + path[end - start + extra + subdirlen] = '\0'; + } + + dp = opendir(path); + if (dp) { + pathlen = strlen(path); + while ((ep = readdir(dp))) { + /* Stat file to get type */ + length = pathlen + strlen(ep->d_name); + filename = (char*)malloc(length + 1); + if (filename) { + strncpy(filename, path, pathlen); + + filename[pathlen] = '\0'; + filename = strncat(filename, ep->d_name, strlen(ep->d_name)); + filename[length] = '\0'; + + if (!stat(filename, &sb)) { + /* We only want regular files */ + if (S_ISREG(sb.st_mode)) { + /* Whew. Now see if we've got the right dll */ + handle = dlopen(filename, RTLD_NOW); + + if (handle) { + desc_func = dlsym(handle, wdat_descriptor_name); + + if (desc_func) { + free(filename); + free(path); + retval = desc_func(w, sample_rate); + w->data_handle = handle; + return retval; + } + } + } + } + free(filename); + } + } + closedir(dp); + } + free(path); + } + } + start = end; + } + return retval; +} + +void +wavedata_unload(Wavedata* w) +{ + dlclose(w->data_handle); +} diff --git a/src/wavegen.c b/src/wavegen.c new file mode 100644 index 0000000..3728920 --- /dev/null +++ b/src/wavegen.c @@ -0,0 +1,319 @@ +/* + A program to generate c header files containing pre-calculated wavedata. + Copyright 2011 David Robillard + Copyright 2002 Mike Rawes + + This 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 3 of the License, or + (at your option) any later version. + + This software 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 software. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <getopt.h> +#include "lv2/lv2plug.in/ns/lv2core/lv2.h" +#include "wdatutil.h" +#include "wavedata.h" +#include "common.h" + +static void +usage(void) +{ + int i; + + fprintf(stderr, "\n"); + fprintf(stderr, "Generate bandlimited wavedata and write as c header file\n"); + fprintf(stderr, "\n"); + fprintf(stderr, "Usage: wavegen -w <Wavename> -r <Sample Rate> -f <Note> -s <Note Step>\n"); + fprintf(stderr, " -m <Samples> [-o <Output Filename>] [-p <Prefix>]\n"); + fprintf(stderr, " [-g <Factor>] [-q] [-t] [-h]\n"); + fprintf(stderr, "\n"); + fprintf(stderr, " -w, --wave Name of wave to generate (case insensitive)\n"); + fprintf(stderr, " -r, --rate Intended playback rate in Samples/Second\n"); + fprintf(stderr, " -f, --first First MIDI note to generate table for\n"); + fprintf(stderr, " -s, --step Number of MIDI notes to skip for next table\n"); + fprintf(stderr, " -m, --min Minimum table size in samples\n"); + fprintf(stderr, " -o, --output Output Filename, name of file to output\n"); + fprintf(stderr, " If not given, output is to stdout\n"); + fprintf(stderr, " -p, --prefix Prefix for declarations in header\n"); + fprintf(stderr, " -g, --gibbs Compensate for Gibbs' effect\n"); + fprintf(stderr, " -q, --quiet Surpress stderr output\n"); + fprintf(stderr, " -t, --test Don't actually generate data\n"); + fprintf(stderr, " -h, --help Print this text and exit\n"); + fprintf(stderr, "\n"); + fprintf(stderr, "Supported waves:\n"); + + for (i = 0; i < WAVE_TYPE_COUNT; i++) { + fprintf(stderr, " %s (%s)\n", wave_names[i], wave_descriptions[i]); + } + + fprintf(stderr, "\n"); + fprintf(stderr, "Gibbs' Effect\n"); + fprintf(stderr, " Gibbs' effect causes overshoot in waves generated from finite\n"); + fprintf(stderr, " Fourier Series. Compensation can be applied, which will result in\n"); + fprintf(stderr, " a waveform that sounds slightly less bright.\n"); + fprintf(stderr, " Use the --gibbs option to set degree of compensatation, from 0.0\n"); + fprintf(stderr, " (no compensation) to 1.0 (full compensation)\n"); + fprintf(stderr, "\n"); +} + +/** + Create bandlimited wavedata header files for various + waveforms +*/ +int +main(int argc, + char** argv) +{ + int option_index; + int opt; + const char* options = "w:r:f:s:m:o:p:g:qth"; + struct option long_options[] = { + { "wave", 1, 0, 'w' }, + { "rate", 1, 0, 'r' }, + { "first", 1, 0, 'f' }, + { "step", 1, 0, 's' }, + { "min", 1, 0, 'm' }, + { "output", 1, 0, 'o' }, + { "prefix", 0, 0, 'p' }, + { "gibbs", 1, 0, 'g' }, + { "quiet", 0, 0, 'q' }, + { "test", 0, 0, 't' }, + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } + }; + int wavetype = -1; + long sample_rate = -1; + long first_note = -1; + long note_step = -1; + long min_table_size = -1; + char* filename = NULL; + FILE* file; + char* prefix = NULL; + float gibbs = 0.0f; + int quiet = 0; + int test = 0; + + Wavedata* w; + float freq; + uint32_t sample_count; + unsigned long max_harmonic_hf; + unsigned long max_harmonic_lf; + unsigned long i; + + size_t strcmplen; + size_t len1; + size_t len2; + + /* Parse arguments */ + if (argc == 1) { + usage(); + exit(-1); + } + + opterr = 0; + while ((opt = getopt_long(argc, argv, options, long_options, &option_index)) != -1) { + switch (opt) { + case 'w': + for (i = 0; i < WAVE_TYPE_COUNT; i++) { + len1 = strlen(optarg); + len2 = strlen(wave_names[i]); + strcmplen = len1 < len2 ? len1 : len2; + + if (!strncasecmp(optarg, wave_names[i], strcmplen)) { + wavetype = i; + } + } + if (wavetype == -1) { + fprintf(stderr, "Unrecognised option for Wave: %s\n", optarg); + exit(-1); + } + break; + case 'r': + sample_rate = (long)atoi(optarg); + break; + case 'f': + first_note = (long)atoi(optarg); + break; + case 's': + note_step = (long)atoi(optarg); + break; + case 'm': + min_table_size = (long)atoi(optarg); + break; + case 'o': + filename = strdup(optarg); + break; + case 'p': + prefix = strdup(optarg); + break; + case 'g': + gibbs = atof(optarg); + break; + case 'q': + quiet = -1; + break; + case 't': + test = -1; + break; + case 'h': + usage(); + exit(0); + break; + default: + usage(); + exit(-1); + } + } + + /* Check basic arguments */ + if (wavetype == -1) { + if (!quiet) { + fprintf(stderr, "No wavetype specified.\n"); + } + exit(-1); + } + + if (sample_rate == -1) { + if (!quiet) { + fprintf(stderr, "No sample rate specified.\n"); + } + exit(-1); + } + + if (first_note == -1) { + if (!quiet) { + fprintf(stderr, "No first note specified.\n"); + } + exit(-1); + } + + if (note_step == -1) { + if (!quiet) { + fprintf(stderr, "No note step specified.\n"); + } + exit(-1); + } + + if (min_table_size == -1) { + if (!quiet) { + fprintf(stderr, "No minimum table size specified.\n"); + } + exit(-1); + } + + if (gibbs < 0.0f || gibbs > 1.0f) { + if (!quiet) { + fprintf(stderr, "Gibbs compensation clamped to [0.0, 1.0]\n"); + fprintf(stderr, " Supplied value: %.2f\n", gibbs); + } + gibbs = gibbs < 0.0f ? 0.0f : gibbs; + gibbs = gibbs > 1.0f ? 1.0f : gibbs; + if (!quiet) { + fprintf(stderr, " Clamped to: %.2f\n", gibbs); + } + } + + if (note_step < 1) { + if (!quiet) { + fprintf(stderr, "Using minimum note step of 1\n"); + } + note_step = 1; + } + + /* Get file to write to */ + if (!filename) { + file = stdout; + } else { + file = fopen(filename, "w"); + } + + w = wavedata_new(sample_rate); + + if (!w) { + if (!quiet) { + fprintf(stderr, "Unable to create wavedata\n"); + } + + exit(-1); + } + + freq = FREQ_FROM_NOTE(first_note); + max_harmonic_lf = HARM_FROM_FREQ(freq, sample_rate); + max_harmonic_hf = max_harmonic_lf; + + for (i = 0; max_harmonic_hf > MIN_HARM(wavetype); i += note_step) { + freq = FREQ_FROM_NOTE(first_note + i + note_step); + max_harmonic_hf = HARM_FROM_FREQ(freq, sample_rate); + + max_harmonic_hf = ACTUAL_HARM(max_harmonic_hf, wavetype); + max_harmonic_lf = ACTUAL_HARM(max_harmonic_lf, wavetype); + + while (max_harmonic_lf == max_harmonic_hf) { + i += note_step; + freq = FREQ_FROM_NOTE(first_note + i + note_step); + max_harmonic_hf = HARM_FROM_FREQ(freq, sample_rate); + max_harmonic_hf = ACTUAL_HARM(max_harmonic_hf, wavetype); + } + + if (max_harmonic_lf > MIN_EXTRA_HARM(wavetype)) { + sample_count = max_harmonic_lf * 2; + sample_count = sample_count < min_table_size ? min_table_size : sample_count; + + if (wavedata_add_table(w, sample_count, max_harmonic_lf)) { + if (!quiet) { + fprintf(stderr, "Could not add wavetable to wavedata\n"); + } + + wavedata_cleanup(w); + exit(-1); + } + } + max_harmonic_lf = max_harmonic_hf; + } + + if (!quiet) { + fprintf(stderr, "\n"); + fprintf(stderr, "Generating %s wave\n", wave_names[wavetype]); + fprintf(stderr, " Sample Rate: %ld\n", sample_rate); + if (gibbs > 0.0f) { + fprintf(stderr, " Gibbs' compensation factor: %+.2f\n\n", gibbs); + } + } + + wavedata_generate_tables(w, wavetype, gibbs); + + if (!test) { + if (wavedata_write(w, file, prefix)) { + if (!quiet) { + fprintf(stderr, "Could not write to file %s!\n\n", filename); + } + } else { + if (!quiet) { + fprintf(stderr, "Written to file %s\n\n", filename); + } + } + } + + if (filename) { + free(filename); + } + + if (prefix) { + free(prefix); + } + + wavedata_cleanup(w); + + return 0; +} diff --git a/src/wdatutil.c b/src/wdatutil.c new file mode 100644 index 0000000..190e8f5 --- /dev/null +++ b/src/wdatutil.c @@ -0,0 +1,672 @@ +/* + Code to generate wavedata for bandlimited waveforms. + Copyright 2011 David Robillard + Copyright 2003 Mike Rawes + + This 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 3 of the License, or + (at your option) any later version. + + This software 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 software. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include "lv2/lv2plug.in/ns/lv2core/lv2.h" +#include "common.h" +#include "wavedata.h" +#include "wdatutil.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void generate_sine(float* samples, + uint32_t sample_count); +void generate_sawtooth(float* samples, + uint32_t sample_count, + unsigned long harmonics, + float gibbs_comp); +void generate_square(float* samples, + uint32_t sample_count, + unsigned long harmonics, + float gibbs_comp); +void generate_parabola(float* samples, + uint32_t sample_count, + unsigned long harmonics, + float gibbs_comp); + +#ifdef __cplusplus +} /* extern "C" { */ +#endif + +char* wave_names[] = { + "Saw", + "Square", + "Parabola" +}; + +char* wave_descriptions[] = { + "Sawtooth Wave", + "Square Wave", + "Parabola Wave" +}; + +unsigned long wave_first_harmonics[] = { + 1, + 1, + 1 +}; + +unsigned long wave_harmonic_intervals[] = { + 1, + 2, + 1 +}; + +Wavedata* +wavedata_new(double sample_rate, + const char* bundle_path, + const LV2_Feature* const* features) +{ + Wavedata* w; + + w = (Wavedata*)malloc(sizeof(Wavedata)); + + if (!w) { + return 0; + } + + w->data_handle = 0; + w->table_count = 0; + w->tables = 0; + w->lookup = 0; + w->lookup_max = 0; + w->sample_rate = (float)sample_rate; + w->nyquist = w->sample_rate * 0.5f; + + return w; +} + +static void +wavedata_cleanup(Wavedata* w) +{ + unsigned long ti; + Wavetable* t; + + for (ti = 0; ti < w->table_count; ti++) { + t = w->tables[ti]; + if (t) { + if (t->samples_hf) { + free(t->samples_hf); + } + + if (t->samples_lf) { + free(t->samples_lf); + } + + free(t); + } + } + + free(w); +} + +int +wavedata_add_table(Wavedata* w, + uint32_t sample_count, + unsigned long harmonics) +{ + Wavetable** tables; + Wavetable* t; + size_t bytes; + + t = (Wavetable*)malloc(sizeof(Wavetable)); + + if (!t) { + return -1; + } + + /* Extra 3 samples for interpolation */ + bytes = (sample_count + 3) * sizeof(float); + + t->samples_lf = (float*)malloc(bytes); + + if (!t->samples_lf) { + free(t); + return -1; + } + + t->samples_hf = (float*)malloc(bytes); + + if (!t->samples_hf) { + free(t->samples_lf); + free(t); + return -1; + } + + bytes = (w->table_count + 1) * sizeof(Wavetable*); + if (w->table_count == 0) { + tables = (Wavetable**)malloc(bytes); + } else { + tables = (Wavetable**)realloc(w->tables, bytes); + } + + if (!tables) { + free(t); + return -1; + } + + t->sample_count = sample_count; + t->harmonics = harmonics; + + if (w->lookup_max < harmonics) { + w->lookup_max = harmonics; + } + + tables[w->table_count] = t; + w->tables = tables; + w->table_count++; + + return 0; +} + +static void +wavedata_generate_tables(Wavedata* w, + Wavetype wavetype, + float gibbs_comp) +{ + Wavetable* t; + float* samples_lf; + float* samples_hf; + unsigned long h_lf; + unsigned long h_hf; + unsigned long s; + unsigned long i; + + for (i = 0; i < w->table_count; i++) { + t = w->tables[i]; + + h_lf = t->harmonics; + + if (i < w->table_count - 1) { + h_hf = w->tables[i + 1]->harmonics; + } else { + h_hf = 1; + } + + samples_lf = t->samples_lf; + samples_hf = t->samples_hf; + samples_lf++; + samples_hf++; + + switch (wavetype) { + case SAW: + generate_sawtooth(samples_lf, t->sample_count, h_lf, gibbs_comp); + generate_sawtooth(samples_hf, t->sample_count, h_hf, gibbs_comp); + break; + case SQUARE: + generate_square(samples_lf, t->sample_count, h_lf, gibbs_comp); + generate_square(samples_hf, t->sample_count, h_hf, gibbs_comp); + break; + case PARABOLA: + generate_parabola(samples_lf, t->sample_count, h_lf, gibbs_comp); + generate_parabola(samples_hf, t->sample_count, h_hf, gibbs_comp); + break; + } + + /* Basic denormalization */ + for (uint32_t s = 0; s < t->sample_count; s++) { + samples_lf[s] = FABSF(samples_lf[s]) < SMALLEST_FLOAT ? 0.0 : samples_lf[s]; + } + + samples_lf--; + samples_lf[0] = samples_lf[t->sample_count]; + samples_lf[t->sample_count + 1] = samples_hf[1]; + samples_lf[t->sample_count + 2] = samples_hf[2]; + + for (uint32_t s = 0; s < t->sample_count; s++) { + samples_hf[s] = FABSF(samples_hf[s]) < SMALLEST_FLOAT ? 0.0 : samples_hf[s]; + } + + samples_hf--; + samples_hf[0] = samples_hf[t->sample_count]; + samples_hf[t->sample_count + 1] = samples_hf[1]; + samples_hf[t->sample_count + 2] = samples_hf[2]; + } +} + +int +wavedata_write(Wavedata* w, + FILE* wdat_fp, + char* data_name) +{ + Wavetable* t = 0; + unsigned long table_count; + unsigned long i; + unsigned long j; + unsigned long s; + int column; + /* + * Extra table at end + */ + table_count = w->table_count + 1; + + fprintf(wdat_fp, "#include "lv 2 / lv2plug.in / ns / lv2core / lv2.h "\n"); + fprintf(wdat_fp, "#include <stdio.h>\n"); + fprintf(wdat_fp, "#include \"wavedata.h\"\n"); + fprintf(wdat_fp, "\n"); + /* + * Fixed data and tables + */ + fprintf(wdat_fp, "unsigned long ref_count = 0;\n"); + fprintf(wdat_fp, "unsigned long first_sample_rate = 0;\n"); + fprintf(wdat_fp, "unsigned long table_count = %ld;\n", table_count); + fprintf(wdat_fp, "Wavetable tables[%ld];\n", table_count); + fprintf(wdat_fp, "Wavetable * ptables[%ld];\n", table_count); + fprintf(wdat_fp, "unsigned long lookup[%ld];\n", w->lookup_max + 1); + fprintf(wdat_fp, "unsigned long lookup_max = %ld;\n", w->lookup_max); + fprintf(wdat_fp, "\n"); + /* + * Sample data + * Each table has an extra 3 samples for interpolation + */ + for (i = 0; i < w->table_count; i++) { + t = w->tables[i]; + + fprintf(wdat_fp, "static float samples_lf_%ld[%ld] = {\n", i, t->sample_count + 3); + + column = 0; + for (uint32_t s = 0; s < t->sample_count + 3 - 1; s++, column++) { + if (column == 5) { + fprintf(wdat_fp, "\n"); + column = 0; + } + fprintf(wdat_fp, "%+.8ef,", t->samples_lf[s]); + } + + if (column == 5) { + fprintf(wdat_fp, "\n"); + } + + fprintf(wdat_fp, "%+.8ef\n", t->samples_lf[s]); + fprintf(wdat_fp, "};\n"); + fprintf(wdat_fp, "\n"); + + fprintf(wdat_fp, "static float samples_hf_%ld[%ld] = {\n", i, t->sample_count + 3); + + column = 0; + for (uint32_t s = 0; s < t->sample_count + 3 - 1; s++, column++) { + if (column == 5) { + fprintf(wdat_fp, "\n"); + column = 0; + } + fprintf(wdat_fp, "%+.8ef,", t->samples_hf[s]); + } + + if (column == 5) { + fprintf(wdat_fp, "\n"); + } + + fprintf(wdat_fp, "%+.8ef\n", t->samples_hf[s]); + fprintf(wdat_fp, "};\n"); + fprintf(wdat_fp, "\n"); + } + + fprintf(wdat_fp, "float samples_zero[%ld];\n", t->sample_count + 3); + fprintf(wdat_fp, "\n"); + /* + * Function to get Wavedata - the sample rate is needed to calculate + * frequencies and related things + */ + fprintf(wdat_fp, "int\n"); + fprintf( + wdat_fp, + "blip_get_%s (Wavedata * w, double sample_rate, + const char* bundle_path, + const LV2_Feature* const* features)\n" , + data_name); + fprintf(wdat_fp, "{\n"); + fprintf(wdat_fp, "\tWavetable * t;\n"); + fprintf(wdat_fp, "\tunsigned long ti;\n"); + fprintf(wdat_fp, "\n"); + /* + * Sample rate must be > 0 + */ + fprintf(wdat_fp, "\tif (sample_rate == 0)\n"); + fprintf(wdat_fp, "\t\treturn -1;\n"); + fprintf(wdat_fp, "\n"); + /* + * First time call - set up all sample rate dependent data + */ + fprintf(wdat_fp, "\tif (first_sample_rate == 0)\n"); + fprintf(wdat_fp, "\t{\n"); + fprintf(wdat_fp, "\t\tfirst_sample_rate = sample_rate;\n"); + fprintf(wdat_fp, "\t\tw->sample_rate = (float) sample_rate;\n"); + fprintf(wdat_fp, "\t\tw->nyquist = w->sample_rate / 2.0f;\n"); + fprintf(wdat_fp, "\t\tw->table_count = table_count;\n"); + fprintf(wdat_fp, "\t\tw->tables = ptables;\n"); + fprintf(wdat_fp, "\t\tw->lookup = lookup;\n"); + fprintf(wdat_fp, "\t\tw->lookup_max = lookup_max;\n"); + fprintf(wdat_fp, "\n"); + fprintf(wdat_fp, "\t\tfor (ti = 1; ti < table_count - 1; ti++)\n"); + fprintf(wdat_fp, "\t\t{\n"); + fprintf(wdat_fp, "\t\t\tt = ptables[ti];\n"); + fprintf(wdat_fp, + "\t\t\tt->min_frequency = w->nyquist / (float) (ptables[ti - 1]->harmonics);\n"); + fprintf(wdat_fp, "\t\t\tt->max_frequency = w->nyquist / (float) (t->harmonics);\n"); + fprintf(wdat_fp, "\t\t}\n"); + fprintf(wdat_fp, "\n"); + fprintf(wdat_fp, "\t\tt = w->tables[0];\n"); + fprintf(wdat_fp, "\t\tt->min_frequency = 0.0f;\n"); + fprintf(wdat_fp, "\t\tt->max_frequency = ptables[1]->min_frequency;\n"); + fprintf(wdat_fp, "\n"); + fprintf(wdat_fp, "\t\tt = ptables[table_count - 1];\n"); + fprintf(wdat_fp, "\t\tt->min_frequency = ptables[w->table_count - 2]->max_frequency;\n"); + fprintf(wdat_fp, "\t\tt->max_frequency = w->nyquist;\n"); + fprintf(wdat_fp, "\t\n"); + fprintf(wdat_fp, "\t\tfor (ti = 0; ti < w->table_count; ti++)\n"); + fprintf(wdat_fp, "\t\t{\n"); + fprintf(wdat_fp, "\t\t\tt = w->tables[ti];\n"); + fprintf(wdat_fp, "\t\t\tt->phase_scale_factor = (float) (t->sample_count) / w->sample_rate;\n"); + fprintf(wdat_fp, + "\t\t\tt->range_scale_factor = 1.0f / (t->max_frequency - t->min_frequency);\n"); + fprintf(wdat_fp, "\t\t}\n"); + fprintf(wdat_fp, "\n"); + fprintf(wdat_fp, "\t\treturn 0;\n"); + fprintf(wdat_fp, "\t}\n"); + /* + * Already called at least once, so just set up wavedata + */ + fprintf(wdat_fp, "\telse if (sample_rate == first_sample_rate)\n"); + fprintf(wdat_fp, "\t{\n"); + fprintf(wdat_fp, "\t\tw->sample_rate = (float) sample_rate;\n"); + fprintf(wdat_fp, "\t\tw->nyquist = w->sample_rate / 2.0f;\n"); + fprintf(wdat_fp, "\t\tw->table_count = table_count;\n"); + fprintf(wdat_fp, "\t\tw->tables = ptables;\n"); + fprintf(wdat_fp, "\t\tw->lookup = lookup;\n"); + fprintf(wdat_fp, "\t\tw->lookup_max = lookup_max;\n"); + fprintf(wdat_fp, "\n"); + fprintf(wdat_fp, "\t\treturn 0;\n"); + fprintf(wdat_fp, "\t}\n"); + /* + * Sample rate does not match, so fail + * + * NOTE: This means multiple sample rates are not supported + * This should not present any problems + */ + fprintf(wdat_fp, "\telse\n"); + fprintf(wdat_fp, "\t{\n"); + fprintf(wdat_fp, "\t\treturn -1;\n"); + fprintf(wdat_fp, "\t}\n"); + fprintf(wdat_fp, "}\n"); + fprintf(wdat_fp, "\n"); + /* + * _init() + * Assemble tables and lookup + */ + fprintf(wdat_fp, "void\n"); + fprintf(wdat_fp, "_init (void)\n"); + fprintf(wdat_fp, "{\n"); + fprintf(wdat_fp, "\tunsigned long max_harmonic;\n"); + fprintf(wdat_fp, "\tunsigned long ti;\n"); + fprintf(wdat_fp, "\tunsigned long li;\n"); + fprintf(wdat_fp, "\tunsigned long s;\n"); + fprintf(wdat_fp, "\n"); + + for (i = 0; i < w->table_count; i++) { + t = w->tables[i]; + + fprintf(wdat_fp, "\ttables[%ld].sample_count = %ld;\n", i, t->sample_count); + fprintf(wdat_fp, "\ttables[%ld].samples_lf = samples_lf_%ld;\n", i, i); + fprintf(wdat_fp, "\ttables[%ld].samples_hf = samples_hf_%ld;\n", i, i); + fprintf(wdat_fp, "\ttables[%ld].harmonics = %ld;\n", i, t->harmonics); + fprintf(wdat_fp, "\n"); + } + /* + * Last table - uses same sample data as previous table for lf data, + * and zeroes for hf data + */ + i = w->table_count - 1; + j = i + 1; + t = w->tables[i]; + /* + * Zero silent samples + */ + fprintf(wdat_fp, "\tfor (uint32_t s = 0; s < %ld; s++)\n", t->sample_count + 3); + fprintf(wdat_fp, "\t\tsamples_zero[s] = 0.0f;\n"); + fprintf(wdat_fp, "\n"); + + fprintf(wdat_fp, "\ttables[%ld].sample_count = %ld;\n", j, t->sample_count); + fprintf(wdat_fp, "\ttables[%ld].samples_lf = samples_hf_%ld;\n", j, i); + fprintf(wdat_fp, "\ttables[%ld].samples_hf = samples_zero;\n", j); + fprintf(wdat_fp, "\ttables[%ld].harmonics = 1;\n", j); + fprintf(wdat_fp, "\n"); + /* + * Get pointers to each wavetable and put them in the pointer array + */ + fprintf(wdat_fp, "\tfor (ti = 0; ti < table_count; ti++)\n"); + fprintf(wdat_fp, "\t\tptables[ti] = &tables[ti];\n"); + fprintf(wdat_fp, "\n"); + /* + * Shift all sample offsets forward by one sample + * !!! NO! Don't! + fprintf (wdat_fp, "\tfor (ti = 0; ti < table_count; ti++)\n"); + fprintf (wdat_fp, "\t{\n"); + fprintf (wdat_fp, "\t\tptables[ti]->samples_lf++;\n"); + fprintf (wdat_fp, "\t\tptables[ti]->samples_hf++;\n"); + fprintf (wdat_fp, "\t}\n"); + fprintf (wdat_fp, "\n"); + */ + /* + * Table lookup vector indexed by harmonic + * Add lookup data to vector + */ + fprintf(wdat_fp, "\tli = 0;"); + fprintf(wdat_fp, "\n"); + fprintf(wdat_fp, "\tfor (ti = table_count - 1; ti > 0; ti--)\n"); + fprintf(wdat_fp, "\t{\n"); + fprintf(wdat_fp, "\t\tmax_harmonic = ptables[ti]->harmonics;\n"); + fprintf(wdat_fp, "\n"); + fprintf(wdat_fp, "\t\tfor ( ; li <= max_harmonic; li++)\n"); + fprintf(wdat_fp, "\t\t\tlookup[li] = ti;\n"); + fprintf(wdat_fp, "\t}\n"); + fprintf(wdat_fp, "\n"); + fprintf(wdat_fp, "\tfor ( ; li <= lookup_max; li++)\n"); + fprintf(wdat_fp, "\t\tlookup[li] = 0;\n"); + fprintf(wdat_fp, "}\n"); + + return 0; +} + +static void +generate_sawtooth(float* samples, + uint32_t sample_count, + unsigned long harmonics, + float gibbs_comp) +{ + double phase_scale = 2.0 * M_PI / (double)sample_count; + float scale = 2.0f / M_PI; + unsigned long i; + unsigned long h; + double mhf; + double hf; + double k; + double m; + double phase; + double partial; + + if (gibbs_comp > 0.0f) { + /* Degree of Gibbs Effect compensation */ + mhf = (double)harmonics; + k = M_PI * (double)gibbs_comp / mhf; + + for (i = 0; i < sample_count; i++) { + samples[i] = 0.0f; + } + + for (h = 1; h <= harmonics; h++) { + hf = (double)h; + + /* Gibbs Effect compensation - Hamming window */ + /* Modified slightly for smoother fade at highest frequencies */ + m = 0.54 + 0.46 * cos((hf - 0.5 / mhf) * k); + + for (i = 0; i < sample_count; i++) { + phase = (double)i * phase_scale; + partial = (m / hf) * sin(phase * hf); + samples[i] += (float)partial; + } + } + + for (i = 0; i < sample_count; i++) { + samples[i] *= scale; + } + } else { + /* Allow overshoot */ + for (i = 0; i < sample_count; i++) { + phase = (double)i * phase_scale; + samples[i] = 0.0f; + + for (h = 1; h <= harmonics; h++) { + hf = (double)h; + partial = (1.0 / hf) * sin(phase * hf); + samples[i] += (float)partial; + } + samples[i] *= scale; + } + } +} + +static void +generate_square(float* samples, + uint32_t sample_count, + unsigned long harmonics, + float gibbs_comp) +{ + double phase_scale = 2.0 * M_PI / (double)sample_count; + float scale = 4.0f / M_PI; + unsigned long i; + unsigned long h; + double mhf; + double hf; + double k; + double m; + double phase; + double partial; + + if (gibbs_comp > 0.0f) { + /* Degree of Gibbs Effect compensation */ + mhf = (double)harmonics; + k = M_PI * (double)gibbs_comp / mhf; + + for (i = 0; i < sample_count; i++) { + samples[i] = 0.0f; + } + + for (h = 1; h <= harmonics; h += 2) { + hf = (double)h; + + /* Gibbs Effect compensation - Hamming window */ + /* Modified slightly for smoother fade at highest frequencies */ + m = 0.54 + 0.46 * cos((hf - 0.5 / pow(mhf, 2.2)) * k); + + for (i = 0; i < sample_count; i++) { + phase = (double)i * phase_scale; + partial = (m / hf) * sin(phase * hf); + samples[i] += (float)partial; + } + } + + for (i = 0; i < sample_count; i++) { + samples[i] *= scale; + } + } else { + /* Allow overshoot */ + for (i = 0; i < sample_count; i++) { + phase = (double)i * phase_scale; + samples[i] = 0.0f; + + for (h = 1; h <= harmonics; h += 2) { + hf = (double)h; + partial = (1.0 / hf) * sin(phase * hf); + samples[i] += (float)partial; + } + samples[i] *= scale; + } + } +} + +static void +generate_parabola(float* samples, + uint32_t sample_count, + unsigned long harmonics, + float gibbs_comp) +{ + double phase_scale = 2.0 * M_PI / (double)sample_count; + float scale = 2.0f / (M_PI * M_PI); + unsigned long i; + unsigned long h; + double mhf; + double hf; + double k; + double m; + double phase; + double partial; + double sign; + + if (gibbs_comp > 0.0f) { + /* Degree of Gibbs Effect compensation */ + mhf = (double)harmonics; + k = M_PI * (double)gibbs_comp / mhf; + + for (i = 0; i < sample_count; i++) { + samples[i] = 0.0f; + } + + sign = -1.0; + + for (h = 1; h <= harmonics; h++) { + hf = (double)h; + + /* Gibbs Effect compensation - Hamming window */ + /* Modified slightly for smoother fade at highest frequencies */ + m = 0.54 + 0.46 * cos((hf - 0.5 / mhf) * k); + + for (i = 0; i < sample_count; i++) { + phase = (double)i * phase_scale; + partial = (sign * 4.0 / (hf * hf)) * cos(phase * hf); + samples[i] += (float)partial; + } + sign = -sign; + } + + for (i = 0; i < sample_count; i++) { + samples[i] *= scale; + } + } else { + /* Allow overshoot */ + for (i = 0; i < sample_count; i++) { + phase = (double)i * phase_scale; + samples[i] = 0.0f; + sign = -1.0; + + for (h = 1; h <= harmonics; h++) { + hf = (double)h; + partial = (sign * 4.0 / (hf * hf)) * cos(phase * hf); + samples[i] += (float)partial; + sign = -sign; + } + samples[i] *= scale; + } + } +} Binary files differ@@ -0,0 +1,126 @@ +#!/usr/bin/env python +import os +import shutil +import subprocess +from waflib.extras import autowaf as autowaf + +# Version of this package (even if built as a child) +BLIP_VERSION = '0.0.0' + +# Variables for 'waf dist' +APPNAME = 'blip.lv2' +VERSION = BLIP_VERSION + +# Mandatory variables +top = '.' +out = 'build' + +def options(opt): + opt.load('compiler_c') + autowaf.set_options(opt) + +def configure(conf): + conf.load('compiler_c') + autowaf.configure(conf) + autowaf.display_header('Blip Configuration') + + autowaf.check_header(conf, 'c', 'lv2/lv2plug.in/ns/lv2core/lv2.h') + + conf.check(function_name = 'sinf', + header_name = 'math.h', + linkflags = '-lm', + define_name = 'HAVE_SINF', + mandatory = False) + + conf.env.append_unique('CFLAGS', '-std=c99') + conf.env.append_unique('CFLAGS', '-D_XOPEN_SOURCE') + + conf.write_config_header('config.h', remove=False) + + # Set env['pluginlib_PATTERN'] + pat = conf.env['cshlib_PATTERN'] + if pat[0:3] == 'lib': + pat = pat[3:] + conf.env['pluginlib_PATTERN'] = pat + conf.env['pluginlib_EXT'] = pat[pat.rfind('.'):] + + autowaf.display_msg(conf, "LV2 bundle directory", + conf.env['LV2DIR']) + print('') + +def build_plugin(bld, lang, bundle, name, source, cflags=[], libs=[]): + # Build plugin library + penv = bld.env.derive() + penv['cshlib_PATTERN'] = bld.env['pluginlib_PATTERN'] + obj = bld(features = '%s %sshlib' % (lang,lang)) + obj.env = penv + obj.source = source + obj.includes = [ '.', './src/include' ] + obj.name = name + obj.target = os.path.join(bundle, name) + obj.linkflags = [ '-nostartfiles' ] + if cflags != []: + obj.cflags = cflags + if libs != []: + autowaf.use_lib(bld, obj, libs) + obj.install_path = '${LV2DIR}/' + bundle + + # Install data file + data_file = '%s.ttl' % name + bld.install_files('${LV2DIR}/' + bundle, os.path.join(bundle, data_file)) + +def build(bld): + # Copy data files to build bundle (build/blip.lv2) + def do_copy(task): + src = task.inputs[0].abspath() + tgt = task.outputs[0].abspath() + return shutil.copy(src, tgt) + + for i in bld.path.ant_glob('blip.lv2/*.ttl'): + bld(rule = do_copy, + source = i, + target = bld.path.get_bld().make_node('blip.lv2/%s' % i), + install_path = '${LV2DIR}/blip.lv2') + + bld(features = 'subst', + source = 'blip.lv2/manifest.ttl.in', + target = bld.path.get_bld().make_node('blip.lv2/manifest.ttl'), + LIB_EXT = bld.env['pluginlib_EXT'], + install_path = '${LV2DIR}/blip.lv2') + + plugins = ''' + adsr + adsr_gt + amp + branch + dahdsr + difference + fmod + interpolator + product + random + ratio + sum + sync_pulse + sync_square + tracker + '''.split() +# quantiser.so +# sequencer.so + + # Simple (single source file) plugins + for i in plugins: + build_plugin(bld, 'c', 'blip.lv2', i, + ['src/%s.c' % i]) + + # Low pass filter + build_plugin(bld, 'c', 'blip.lv2', 'lp4pole', + ['src/lp4pole.c', 'src/lp4pole_filter.c']) + + # Oscillators + for i in ['pulse', 'sawtooth', 'square', 'triangle']: + build_plugin(bld, 'c', 'blip.lv2', i, + ['src/%s.c' % i, 'src/wavedata.c']) + +def lint(ctx): + subprocess.call('cpplint.py --filter=+whitespace/comments,-whitespace/tab,-whitespace/braces,-whitespace/labels,-build/header_guard,-readability/casting,-readability/todo,-build/include src/* serd/*', shell=True) |