Audio-Nama-1.208/0000755000175000017500000000000012644673607012514 5ustar jrothjrothAudio-Nama-1.208/MANIFEST0000644000175000017500000000577112641065474013651 0ustar jrothjrothBUILD Changes COPYING inc/Module/Install.pm inc/Module/Install/Base.pm inc/Module/Install/Can.pm inc/Module/Install/Fetch.pm inc/Module/Install/Makefile.pm inc/Module/Install/Metadata.pm inc/Module/Install/Scripts.pm inc/Module/Install/Win32.pm inc/Module/Install/WriteAll.pm lib/Audio/Nama/AnalyseLV2.pm lib/Audio/Nama/Assign.pm lib/Audio/Nama/Bunch.pm lib/Audio/Nama/Bus.pm lib/Audio/Nama/CacheTrack.pm lib/Audio/Nama/ChainSetup.pm lib/Audio/Nama/Config.pm lib/Audio/Nama/Custom.pm lib/Audio/Nama/Edit.pm lib/Audio/Nama/EffectChain.pm lib/Audio/Nama/Effect.pm lib/Audio/Nama/EffectsRegistry.pm lib/Audio/Nama/EngineCleanup.pm lib/Audio/Nama/Engine.pm lib/Audio/Nama/EngineRun.pm lib/Audio/Nama/EngineSetup.pm lib/Audio/Nama/Fade.pm lib/Audio/Nama/Git.pm lib/Audio/Nama/Globals.pm lib/Audio/Nama/Grammar.pm lib/Audio/Nama/Graphical.pm lib/Audio/Nama/Graph.pm lib/Audio/Nama/Help.pm lib/Audio/Nama/Initializations.pm lib/Audio/Nama/Insert.pm lib/Audio/Nama/IO.pm lib/Audio/Nama/Jack.pm lib/Audio/Nama/Latency.pm lib/Audio/Nama/Lat.pm lib/Audio/Nama/Log.pm lib/Audio/Nama/Mark.pm lib/Audio/Nama/Memoize.pm lib/Audio/Nama/Midi.pm lib/Audio/Nama/Mix.pm lib/Audio/Nama/Modes.pm lib/Audio/Nama/MuteSoloFade.pm lib/Audio/Nama/Object.pm lib/Audio/Nama/Options.pm lib/Audio/Nama/Persistence.pm lib/Audio/Nama/Plug.pm lib/Audio/Nama.pm lib/Audio/Nama/Project.pm lib/Audio/Nama/RegionComp.pm lib/Audio/Nama/Regions.pm lib/Audio/Nama/Sequence.pm lib/Audio/Nama/Terminal.pm lib/Audio/Nama/Text.pm lib/Audio/Nama/Track.pm lib/Audio/Nama/Util.pm lib/Audio/Nama/Wavinfo.pm lib/Audio/Nama/Wav.pm Makefile.PL MANIFEST This list of files META.yml README script/nama t/01_symbols.t t/02_assign.t t/03_wav.t t/04_object.t t/06_latency.t t/11_mark.t t/12_nama.t t/13_io.t t/data/fake_effects_cache.json lib/Audio/Nama/Assign.pm lib/Audio/Nama/Bus.pm lib/Audio/Nama/IO.pm lib/Audio/Nama/Bunch.pm lib/Audio/Nama/Fade.pm lib/Audio/Nama/CacheTrack.pm lib/Audio/Nama/ChainSetup.pm lib/Audio/Nama/Config.pm lib/Audio/Nama/Insert.pm lib/Audio/Nama/Mark.pm lib/Audio/Nama/Edit.pm lib/Audio/Nama/Object.pm lib/Audio/Nama/EngineRun.pm lib/Audio/Nama/Graph.pm lib/Audio/Nama/Wav.pm lib/Audio/Nama/AnalyseLV2.pm lib/Audio/Nama/EngineCleanup.pm lib/Audio/Nama/EngineSetup.pm lib/Audio/Nama/Custom.pm lib/Audio/Nama/Effect.pm lib/Audio/Nama/Grammar.pm lib/Audio/Nama/EffectChain.pm lib/Audio/Nama/EffectsRegistry.pm lib/Audio/Nama/Git.pm lib/Audio/Nama/Help.pm lib/Audio/Nama/Mix.pm lib/Audio/Nama/Jack.pm lib/Audio/Nama/Modes.pm lib/Audio/Nama/Globals.pm lib/Audio/Nama/Initializations.pm lib/Audio/Nama/Latency.pm lib/Audio/Nama/Graphical.pm lib/Audio/Nama/Log.pm lib/Audio/Nama/Util.pm lib/Audio/Nama/Lat.pm lib/Audio/Nama/Midi.pm lib/Audio/Nama/Project.pm lib/Audio/Nama/Memoize.pm lib/Audio/Nama/Text.pm lib/Audio/Nama/MuteSoloFade.pm lib/Audio/Nama/Options.pm lib/Audio/Nama/Persistence.pm lib/Audio/Nama/Terminal.pm lib/Audio/Nama/Regions.pm lib/Audio/Nama/Track.pm lib/Audio/Nama/Wavinfo.pm lib/Audio/Nama/Engine.pm lib/Audio/Nama/RegionComp.pm lib/Audio/Nama/Sequence.pm lib/Audio/Nama.pm Audio-Nama-1.208/BUILD0000644000175000017500000000322012444122010013242 0ustar jrothjrothBUILD INSTRUCTIONS You may decide to clone the Nama's github repository and from source rather than installing from CPAN. It is easier to browse or hack on Nama this way. Functionality is separated into a number of files, and you will see $::package_var instead of $Audio::Nama::package_var. You can get also updates more quickly and can share patches with other developers. Procedure For typical build and test: cpan Text::Template git-clone git://github.com/bolangi/nama.git cd nama/src ./build ./ui To install the module, do as usual: cd .. perl Makefile.PL make install How it works The build script creates the perl modules for the distribution under the nama/lib directory using *.p, *.pl, *.t and other files in the nama/src directory. build looks into the *.p files for lines that look like: [% somefile.pl %] This notation is analogous to the C-preprocessor #include directive: somefile.pl gets included in the source at that point. Some of these include lines are more complicated: [% qx(./strip_comments ./grammar_body) %] Here the preprocessor runs the script strip_comments on grammar_body, removing text that would choke the parser generator. Build provides a few parameters to the preprocessing script preproc, which uses the Text::Template to perform most of the required substitutions. To see the names of the files and scripts used to build the modules type: ls *.p grep '\[%' * # shows all include directives Audio-Nama-1.208/COPYING0000644000175000017500000010451312444122010013522 0ustar jrothjroth GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. 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. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 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 . 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: Copyright (C) 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 . 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 . Audio-Nama-1.208/t/0000755000175000017500000000000012644673607012757 5ustar jrothjrothAudio-Nama-1.208/t/01_symbols.t0000644000175000017500000000344212644673575015143 0ustar jrothjrothuse Test::More tests => 3; use strict; BEGIN { use_ok(qw(Audio::Nama::Globals) ) }; use Audio::Nama::Globals qw($ui); is($ui, 'bullwinkle', 'global variable import'); package Foo; use Audio::Nama::Globals qw(:all); main::is($ui, 'bullwinkle', 'global variable-all-tag import'); 1; __END__ use Audio::Nama::Assign qw(:all); # `make test'. After `make install' it should work as `perl 1.t' diag ("TESTING $0\n"); my @test_classes = qw( :: main:: main); # SKIP_PREPROC use vars qw( $foo @face $name %dict); my @var_list = qw( $foo @face $name %dict); my $struct2 = { '$foo' => 2, '$name' => 'John', '@face' => [1,5,7,12], '%dict' => {fruit => 'melon'} }; my $struct = { foo => 2, name => 'John', face => [1,5,7,12], dict => {fruit => 'melon'} }; for my $c (@test_classes) { diag ("testing for class $c"); assign (data => $struct, class => $c, vars => \@var_list); #assign($struct, @var_list); #print json_out(\%dict); #print json_out($struct); my $serialized = serialize( class => $c, vars => \@var_list); # store_vars output as string my $expected = < 2, name => undef, face => [], dict => {}, }; diag("scalar array: ",scalar @face, " scalar hash: ", scalar %dict); assign (data => $nulls, class => 'main', vars => \@var_list); is( scalar @face, 0, "Null array assignment"); is( scalar %dict, 0, "Null hash assignment"); 1; __END__Audio-Nama-1.208/t/11_mark.t0000644000175000017500000000114212644673575014401 0ustar jrothjrothuse Test::More tests => 2; use strict; BEGIN { use_ok('Audio::Nama::Mark') ; } $ENV{NAMA_VERBOSE_TEST_OUTPUT} and diag ("TESTING $0\n"); my $mark = Audio::Nama::Mark->new( name => 'thebeginning'); is( ref $mark , 'Audio::Nama::Mark', "Object creation"); 1; __END__ diag("Serializing, storing$ENV{NAMA_VERBOSE_TEST_OUTPUT} recalling data"); is( $foo, 2, "Scalar number assignment"); is( $name, 'John', "Scalar string assignment"); my $sum; map{ $sum += $_ } @face; is ($sum, 25, "Array assignment"); is( $dict{fruit}, 'melon', "Hash assignment"); is ($serialized, $expected, "Serialization round trip");Audio-Nama-1.208/t/06_latency.t0000644000175000017500000000113612644673575015115 0ustar jrothjrothuse Test::More tests => 6; use strict; use Data::Dumper::Concise; use Audio::Nama::Lat; my $lat = Audio::Nama::Lat->new(4,8); my $lat2 = Audio::Nama::Lat->new(16,32); is(ref $lat, 'Audio::Nama::Lat', "Latency object instantiation"); is("$lat","4 8","Stringify object"); is($lat->min, 4, "Min latency accessor"); is_deeply( $lat->add_latency($lat2), Audio::Nama::Lat->new(20,40), "Latency addition"); is_deeply( Audio::Nama::Lat->new(20,40), ($lat + $lat2), "Latency addition, overloading '+' operator"); is(do{ eval {Audio::Nama::Lat->new(1,0)}; defined $@}, 1, "Exception on Max greater than Min"); 1;Audio-Nama-1.208/t/12_nama.t0000644000175000017500000006140312644673575014372 0ustar jrothjrothpackage Audio::Nama; use Audio::Nama; use Test::More tests => 126; use File::Path qw(make_path remove_tree); use File::Slurp; use Cwd; use strict; use warnings; no warnings qw(uninitialized); our ($expected_setup_lines); $ENV{NAMA_VERBOSE_TEST_OUTPUT} and diag ("TESTING $0\n"); $ENV{NAMA_VERBOSE_TEST_OUTPUT} and diag("working directory: ",cwd); our $test_dir = "/tmp/nama-test"; $fx_cache->{fake} = read_file("t/data/fake_effects_cache.json"); cleanup_dirs(); setup_dirs(); sub cleanup_dirs { chdir('..'), remove_tree($test_dir) if -e $test_dir } sub setup_dirs{ make_path("$test_dir/test/.wav", "$test_dir/untitled/.wav") } $ENV{NAMA_VERBOSE_TEST_OUTPUT} and diag( qx(find $test_dir) ); apply_test_args(); $ENV{NAMA_VERBOSE_TEST_OUTPUT} and diag "options: @ARGV"; bootstrap_environment(); $config->{use_git} = 0; $ENV{NAMA_VERBOSE_TEST_OUTPUT} and diag "Check representative variable from default .namarc"; is( $config->{mix_to_disk_format}, "s16_le,N,44100,i", "Read mix_to_disk_format"); # object id => type mappings # my @id_to_type = ( 1 => 'soundcard', Fluidsynth => 'jack_client', "MPlayer [20120]:out_0" => 'jack_client', "drumkit.ports" => 'jack_ports_list', manual => 'jack_manual', jack => 'jack_manual', bus => 'bus', null => 'null', "loop,16" => 'loop', "loop,Master" => 'loop', ); while( my($dest,$type) = splice @id_to_type, 0,2){ is( dest_type($dest), $type, "$dest => $type"); } # SKIP: { # my $cs_got = eval_iam('cs'); # my $cs_want = q(### Chain status (chainsetup 'command-line-setup') ### # Chain "default" [selected] ); # is( $cs_got, $cs_want, "Evaluate Ecasound 'cs' command"); # } my $test_project = 'test'; load_project(name => $test_project, create => 1); $ENV{NAMA_VERBOSE_TEST_OUTPUT} and diag("project project dir: ".project_dir()); $ENV{NAMA_VERBOSE_TEST_OUTPUT} and diag("project project wav dir: ".this_wav_dir()); #diag(map{ $_->dump} values %Audio::Nama::Track::by_index ); is( project_dir(), "$test_dir/$test_project", "establish project directory"); is( ref $bn{Main}, q(Audio::Nama::SubBus), 'Bus initializtion'); force_jack(); ### Unit Tests for Audio::Nama::IO.pm my @io_test_data = split "\n\n", my $yaml = q(--- - class: from_null ecs_string: -i:null - class: to_null ecs_string: -o:null - class: to_wav args: name: sax width: 1 full_path: /foo/.wav/sax_1.wav ecs_string: -f:s16_le,1,44100,i -o:/foo/.wav/sax_1.wav - class: from_wav args: playat_output: playat,5 select_output: select,1,4 modifiers: [] full_path: test_dir/sax_1.wav ecs_string: /-i:playat,5,select,1,4,.+sax_\d+.wav/ - class: from_loop args: endpoint: sax_in ecs_string: -i:loop,sax_in - class: to_loop args: endpoint: sax_out ecs_string: -o:loop,sax_out - class: to_alsa_soundcard_device ecs_string: -o:alsa,default - class: from_alsa_soundcard_device ecs_string: -i:alsa,default - class: from_soundcard args: width: 1 source_id: 2 source_type: soundcard ecs_string: -i:jack_multi,system:capture_2 - class: to_soundcard args: width: 2 send_id: 5 send_type: soundcard ecs_string: -o:jack_multi,system:playback_5,system:playback_6 - class: to_jack_port args: width: 1 port_name: sax ecs_string: -f:f32_le,1,44100 -o:jack,,sax_out - class: from_jack_port args: port_name: sax width: 2 ecs_string: -f:f32_le,2,44100 -i:jack,,sax_in - class: from_jack_client args: source_id: Horgand source_type: jack_client ecs_string: -i:jack,Horgand - class: to_jack_client args: send_id: system send_type: jack_client ecs_string: -o:jack,system - class: to_jack_multi args: width: 2 send_id: system send_type: jack_multi ecs_string: -o:jack_multi,system:playback_1,system:playback_2 - class: from_jack_multi args: width: 2 source_id: Horgand source_type: jack_client ecs_string: -i:jack_multi,Horgand:out_1,Horgand:out_2 ...); my @test = @{yaml_in($yaml)}; my $i; for (@test) { my %t = %$_; $i++; $ENV{NAMA_VERBOSE_TEST_OUTPUT} and diag "IO.pm unit test $i"; my $class = "Audio::Nama::IO::$t{class}"; my $io = $class->new(%{$t{args}}); my @keys = sort grep{ $_ ne 'class'} keys %t; if( $t{ecs_string} =~ m(^/)){ like( $io->ecs_string, $t{ecs_string}, "$t{class} ecs_string"); }else{ is( $io->ecs_string, $t{ecs_string}, "$t{class} ecs_string"); } } force_alsa(); process_command('add sax'); like(ref $this_track, qr/Track/, "track creation"); is( $this_track->name, 'sax', "current track assignment"); my ($vol_id) = $this_track->vol; ok( (defined $vol_id and $Audio::Nama::Effect::by_id{$vol_id}) , "apply volume control"); process_command('add_effect time_reverb3'); like( this_op_o()->code, qr/time_reverb3/, "apply preset"); is (this_op_o()->track_effect_index, 0, "positioned before vol/pan faders"); process_command('add_effect decimator 1 2'); like( this_op_o()->code, qr/decimator/, "apply LADSPA effect"); is( this_op_o()->track_effect_index, 1, "position before faders, after other effects"); process_command('vol -2'); is( $this_track->vol_o->params->[0], -2, "modify effect" ); process_command(join " ", 'position_effect', this_op_o()->id, 'ZZZ'); is( $this_track->ops->[-1], this_op_o()->id, 'position effect at end, using ZZZ pseudo-id'); process_command(join " ", 'position_effect', this_op_o()->id, $vol_id); is( $this_track->ops->[this_op_o()->track_effect_index + 1], $vol_id, "position effect before another effect"); my $op_id = this_op_o()->id; process_command("remove_effect $op_id"); ok( (not grep { $_ eq $op_id } @{$this_track->ops}), 'remove effect'); process_command('source 2'); is( $this_track->source_type, 'soundcard', "set soundcard input"); is( $this_track->source_id, 2, "set input channel"); process_command('send 5'); # track sax, source 2, send 5 is( $this_track->send_type, 'soundcard', 'set soundcard output'); is( $this_track->send_id, 5, 'set soundcard output'); # this is ALSA dependent (i.e. no JACK running) my $io = Audio::Nama::IO->new(track => 'sax'); like( ref $io, qr/IO$/, 'IO base class object'); $io = Audio::Nama::IO::to_alsa_soundcard_device->new(track => 'sax'); is($io->ecs_string, '-o:alsa,default', 'IO to_alsa_soundcard_device 1'); is($io->ecs_extra, ' -chmove:1,5', 'IO to_alsa_soundcard_device 2'); $io = Audio::Nama::IO::to_soundcard->new(track => 'sax'); is($io->ecs_string, '-o:alsa,default', 'IO to_soundcard 1'); is($io->ecs_extra, ' -chmove:1,5', 'IO to_soundcard 2'); force_jack(); $io = Audio::Nama::IO::from_soundcard->new(track => 'sax'); like (ref $io, qr/from_jack_multi/, 'sound system ALSA/JACK detection: input'); is($io->ecs_string, '-i:jack_multi,system:capture_2', 'IO from_soundcard: jack 1'); is($io->ecs_extra, '-chcopy:1,2', 'IO from_soundcard: jack 2'); $io = Audio::Nama::IO::to_soundcard->new(track => 'sax'); like (ref $io, qr/to_jack_multi/, 'sound system ALSA/JACK detection: output'); is($io->ecs_string, '-o:jack_multi,system:playback_5', 'IO to_soundcard: jack 1'); ok(! $io->ecs_extra, 'IO to_soundcard: jack 2'); $io = Audio::Nama::IO::to_null->new(track => 'sax', device_id => 'alsa,default'); is($io->device_id, 'alsa,default', 'value overrides method call'); process_command("sax; source Horgand; gen"); like( Audio::Nama::ChainSetup::ecasound_chain_setup(), qr/Horgand/, 'set JACK client as input'); process_command("sax; source jack; gen"); like( Audio::Nama::ChainSetup::ecasound_chain_setup(), qr/jack,,sax_in/, 'set JACK port for manual input'); process_command("sax; rec; source 2"); force_alsa(); process_command('3; nosend; gen'); $expected_setup_lines = < $playat, region_start => $region_start, region_end => $region_end, edit_play_start => $edit_play_start, edit_play_end => $edit_play_end, setup_length => $length, }; is( Audio::Nama::edit_case($args), $case, "$index: $case $comment"); is( Audio::Nama::new_playat($args), $new_playat, "$index: new_playat: $case"); is( Audio::Nama::new_region_start($args), $new_region_start, "$index: new_region_start: $case"); is( Audio::Nama::new_region_end($args), $new_region_end, "$index: new_region_end: $case"); } } load_project(name => "$test_project-convert51", create => 1); my $script = < "$test_project-sendbus-cooked", create => 1); do_script(' add mic add guitar for 3 4; mon add_submix_cooked ear 7 '); $expected_setup_lines = < "add_submix_raw", create => 1); process_command("add_tracks mic guitar; for 3 4; mon;; 4 source 2; stereo; add_submix_raw raw-user 7"); $expected_setup_lines = < "$test_project-add_insert_post", create => 1); process_command("add sax; mon; gen"); process_command("add_insert post jconvolver; gen"); $expected_setup_lines = < "add_insert_pre", create => 1); process_command("add sax; mon; add_insert pre jconvolver; gen"); $expected_setup_lines = < "add_insert_via_soundcard-postfader", create => 1); process_command("add sax; mon; source 2; add_insert post 5; gen"); $expected_setup_lines = < "add_insert_via_soundcard_pre", create => 1); process_command("add sax; mon; source 2; add_insert pre 5; gen"); $expected_setup_lines = <{opts}->{A} = 1; $config->{opts}->{J} = 0; $jack->{jackd_running} = 0; } sub force_jack{ $config->{opts}->{A} = 0; $config->{opts}->{J} = 1; $jack->{jackd_running} = 1; } sub setup_content { my @lines = split "\n", shift; my %setup; for (@lines){ next unless /^-a:/; s/\s*$//; $setup{$_}++; } \%setup; } sub check_setup { my $test_name = shift; is( json_out(setup_content(Audio::Nama::ChainSetup::ecasound_chain_setup())), json_out(setup_content($expected_setup_lines)), $test_name); } cleanup_dirs(); 1; __END__Audio-Nama-1.208/t/02_assign.t0000644000175000017500000000351212644673575014736 0ustar jrothjrothuse Test::More tests => 18; use strict; BEGIN { use_ok('Audio::Nama::Assign') }; use Audio::Nama::Assign qw(:all); use Audio::Nama::Log; Audio::Nama::Log::initialize_logger(); # `make test'. After `make install' it should work as `perl 1.t' $ENV{NAMA_VERBOSE_TEST_OUTPUT} and diag ("TESTING $0\n"); my @test_classes = qw( :: main:: main); # SKIP_PREPROC use vars qw( $foo @face $name %dict); my @var_list = qw( $foo @face $name %dict); my $struct2 = { '$foo' => 2, '$name' => 'John', '@face' => [1,5,7,12], '%dict' => {fruit => 'melon'} }; my $struct = { foo => 2, name => 'John', face => [1,5,7,12], dict => {fruit => 'melon'} }; $ENV{NAMA_VERBOSE_TEST_OUTPUT} and diag("Serializing, storing$ENV{NAMA_VERBOSE_TEST_OUTPUT} recalling data"); for my $c (@test_classes) { $ENV{NAMA_VERBOSE_TEST_OUTPUT} and diag ("testing for package $c"); assign (data => $struct, class => $c, vars => \@var_list); #assign($struct, @var_list); #print json_out(\%dict); #print json_out($struct); my $serialized = serialize( class => $c, vars => \@var_list); # store_vars output as string my $expected = < 2, name => undef, face => [], dict => {}, }; #diag("scalar array: ",scalar @face, " scalar hash: ", scalar %dict); assign (data => $nulls, class => 'main', vars => \@var_list); is( scalar @face, 0, "Null array assignment"); is( scalar %dict, 0, "Null hash assignment"); 1; __END__Audio-Nama-1.208/t/04_object.t0000644000175000017500000000110012644673575014711 0ustar jrothjrothuse Test::More tests => 4; use strict; BEGIN { use_ok('Audio::Nama::Object') ; } $ENV{NAMA_VERBOSE_TEST_OUTPUT} and diag ("TESTING $0\n"); $ENV{NAMA_VERBOSE_TEST_OUTPUT} and diag "testing trivial class Apple"; package Apple; our @ISA; use Audio::Nama::Object qw(color); package main; my $apple = Apple->new(color => 'green'); is( ref $apple, 'Apple', "instantiation") ; is( $apple->color, 'green', "accessor" ); $apple->set( color => 'red' ); is( $apple->color, 'red', "mutator" ); #$apple->color = 'blue'; #is( $apple->color, 'blue', "lvalue" ); 1; __END__Audio-Nama-1.208/t/13_io.t0000644000175000017500000000070712644673575014066 0ustar jrothjrothpackage Audio::Nama; use Test::More tests => 1; use strict; use warnings; no warnings qw(uninitialized); use Cwd; BEGIN { use_ok('Audio::Nama::IO') }; # `make test'. After `make install' it should work as `perl 1.t' $ENV{NAMA_VERBOSE_TEST_OUTPUT} and diag ("TESTING $0\n"); =comment my $io = Audio::Nama::IO->new( qw[ type raw object loop,mix format s16_le,2,44100 ] ); is( $io->type, 'raw', 'IO object create, access'); =cut 1; __END__Audio-Nama-1.208/t/data/0000755000175000017500000000000012644673607013670 5ustar jrothjrothAudio-Nama-1.208/t/data/fake_effects_cache.json0000644000175000017500000136235012437662263020321 0ustar jrothjroth{ "fx_cache" : { "full_label_to_index" : { "" : 0, "chcopy" : 27, "chmix" : 32, "chmove" : 29, "chmute" : 30, "chorder" : 26, "eS" : 1, "ea" : 2, "eac" : 4, "eadb" : 3, "eal" : 5, "eaw" : 6, "ec" : 7, "eca" : 8, "eemb" : 9, "eemp" : 10, "eemt" : 11, "ef1" : 12, "ef3" : 13, "ef4" : 14, "efa" : 15, "efb" : 16, "efc" : 17, "efh" : 18, "efi" : 19, "efl" : 20, "efr" : 21, "efs" : 22, "ei" : 23, "el:Ambisonics-11-cube-decoder" : 238, "el:Ambisonics-11-hexagon-decoder" : 237, "el:Ambisonics-11-mono-panner" : 233, "el:Ambisonics-11-rotator" : 235, "el:Ambisonics-11-square-decoder" : 236, "el:Ambisonics-11-stereo-panner" : 234, "el:Ambisonics-21-panner" : 142, "el:Ambisonics-21-rotator" : 143, "el:Ambisonics-22-panner" : 144, "el:Ambisonics-22-rotator" : 145, "el:Ambisonics-31-panner" : 178, "el:Ambisonics-31-rotator" : 179, "el:Ambisonics-33-panner" : 180, "el:Ambisonics-33-rotator" : 181, "el:AmpVTS" : 98, "el:AutoFilter" : 107, "el:CEO" : 118, "el:CabinetIV" : 99, "el:ChorusI" : 105, "el:Click" : 117, "el:Compress" : 95, "el:CompressX2" : 96, "el:Eq10" : 109, "el:Eq10X2" : 110, "el:Eq4p" : 111, "el:Fractal" : 116, "el:G2reverb" : 192, "el:Narrower" : 113, "el:NoiseGate" : 94, "el:Parametric1" : 128, "el:PhaserII" : 106, "el:Plate" : 100, "el:PlateX2" : 101, "el:Saturate" : 102, "el:Scape" : 108, "el:Sin" : 114, "el:Spice" : 103, "el:SpiceX2" : 104, "el:ToneStack" : 97, "el:Tricardioid-to-AMB" : 227, "el:UHJ-decoder" : 230, "el:UHJ-encoder" : 229, "el:Virtualmic" : 228, "el:White" : 115, "el:Wider" : 112, "el:alias" : 169, "el:allpass_c" : 222, "el:allpass_l" : 221, "el:allpass_n" : 220, "el:amPitchshift" : 156, "el:amp" : 149, "el:amp_mono" : 59, "el:amp_stereo" : 60, "el:analogueOsc" : 54, "el:artificialLatency" : 135, "el:autoPhaser" : 154, "el:bandpass_a_iir" : 48, "el:bandpass_iir" : 134, "el:bodeShifter" : 74, "el:bodeShifterCV" : 213, "el:butthigh_iir" : 66, "el:buttlow_iir" : 65, "el:bwxover_iir" : 64, "el:chebstortion" : 214, "el:comb" : 209, "el:combSplitter" : 218, "el:comb_c" : 71, "el:comb_l" : 70, "el:comb_n" : 69, "el:const" : 150, "el:crossoverDist" : 232, "el:dcRemove" : 177, "el:decay" : 63, "el:decimator" : 138, "el:declip" : 133, "el:delay_5s" : 146, "el:delay_c" : 88, "el:delay_l" : 87, "el:delay_n" : 86, "el:delayorama" : 68, "el:diode" : 242, "el:divider" : 216, "el:djFlanger" : 166, "el:dj_eq" : 165, "el:dj_eq_mono" : 164, "el:dysonCompress" : 167, "el:fadDelay" : 121, "el:fastLookaheadLimiter" : 90, "el:flanger" : 196, "el:fmOsc" : 83, "el:foldover" : 183, "el:fourByFourPole" : 153, "el:foverdrive" : 67, "el:freqTracker" : 171, "el:gate" : 162, "el:giantFlange" : 141, "el:gong" : 159, "el:gongBeater" : 85, "el:gsm" : 174, "el:gverb" : 170, "el:hardLimiter" : 184, "el:harmonicGen" : 127, "el:hermesFilter" : 73, "el:highpass_iir" : 190, "el:hilbert" : 49, "el:hpf" : 206, "el:imp" : 189, "el:impulse_fc" : 91, "el:inv" : 55, "el:invada_hp_mono_filter_module_0_1" : 51, "el:invada_hp_stereo_filter_module_0_1" : 53, "el:invada_lp_mono_filter_module_0_1" : 50, "el:invada_lp_stereo_filter_module_0_1" : 52, "el:invada_mono_compressor_module_0_1" : 160, "el:invada_mono_reverbER_module_0_1" : 187, "el:invada_mono_tube_module_0_1" : 131, "el:invada_stereo_compressor_module_0_1" : 161, "el:invada_stereo_input_module_0_1" : 148, "el:invada_stereo_tube_module_0_1" : 132, "el:invada_sum_reverbER_module_0_1" : 188, "el:karaoke" : 176, "el:lcrDelay" : 61, "el:lfoPhaser" : 152, "el:lowpass_iir" : 92, "el:lpf" : 205, "el:lsFilter" : 185, "el:matrixMSSt" : 130, "el:matrixSpatialiser" : 186, "el:matrixStMS" : 151, "el:mbeq" : 139, "el:modDelay" : 217, "el:multivoiceChorus" : 82, "el:noise_white" : 241, "el:notch_iir" : 226, "el:pitchScale" : 191, "el:pitchScaleHQ" : 231, "el:plate" : 199, "el:pointerCastDistortion" : 172, "el:rateShifter" : 147, "el:retroFlange" : 126, "el:revdelay" : 175, "el:ringmod_1i1o1l" : 208, "el:ringmod_2i1o" : 207, "el:satanMaximiser" : 136, "el:sc1" : 182, "el:sc2" : 219, "el:sc3" : 72, "el:sc4" : 58, "el:sc4m" : 84, "el:se4" : 155, "el:shaper" : 211, "el:sifter" : 225, "el:sinCos" : 224, "el:sine_faaa" : 75, "el:sine_faac" : 76, "el:sine_fcaa" : 77, "el:sine_fcac" : 78, "el:singlePara" : 137, "el:sinusWavewrapper" : 168, "el:smoothDecimate" : 123, "el:split" : 198, "el:stepMuxer" : 163, "el:surroundEncoder" : 215, "el:svf" : 140, "el:tap_autopan" : 195, "el:tap_chorusflanger" : 124, "el:tap_deesser" : 212, "el:tap_doubler" : 158, "el:tap_dynamics_m" : 201, "el:tap_dynamics_st" : 204, "el:tap_equalizer" : 129, "el:tap_equalizer_bw" : 173, "el:tap_limiter" : 79, "el:tap_pinknoise" : 239, "el:tap_pitch" : 93, "el:tap_reflector" : 240, "el:tap_reverb" : 197, "el:tap_rotspeak" : 80, "el:tap_sigmoid" : 62, "el:tap_stereo_echo" : 122, "el:tap_tremolo" : 56, "el:tap_tubewarmth" : 223, "el:tap_vibrato" : 89, "el:tapeDelay" : 210, "el:transient" : 119, "el:triplePara" : 200, "el:valve" : 57, "el:valveRect" : 157, "el:vynil" : 125, "el:waveTerrain" : 120, "el:xfade" : 202, "el:xfade4" : 203, "el:zita-reverb" : 193, "el:zita-reverb-amb" : 194, "el:zm1" : 81, "elv2:http://gareus.org/oss/lv2/b_overdrive" : 307, "elv2:http://gareus.org/oss/lv2/b_reverb" : 308, "elv2:http://gareus.org/oss/lv2/b_whirl#extended" : 309, "elv2:http://gareus.org/oss/lv2/b_whirl#simple" : 310, "elv2:http://hyperglitch.com/dev/VocProc" : 311, "elv2:http://plugin.org.uk/swh-plugins/alaw" : 312, "elv2:http://plugin.org.uk/swh-plugins/alias" : 313, "elv2:http://plugin.org.uk/swh-plugins/allpass_c" : 314, "elv2:http://plugin.org.uk/swh-plugins/allpass_l" : 315, "elv2:http://plugin.org.uk/swh-plugins/allpass_n" : 316, "elv2:http://plugin.org.uk/swh-plugins/amPitchshift" : 317, "elv2:http://plugin.org.uk/swh-plugins/amp" : 318, "elv2:http://plugin.org.uk/swh-plugins/analogueOsc" : 319, "elv2:http://plugin.org.uk/swh-plugins/artificialLatency" : 320, "elv2:http://plugin.org.uk/swh-plugins/autoPhaser" : 321, "elv2:http://plugin.org.uk/swh-plugins/bandpass_a_iir" : 322, "elv2:http://plugin.org.uk/swh-plugins/bandpass_iir" : 323, "elv2:http://plugin.org.uk/swh-plugins/bodeShifter" : 324, "elv2:http://plugin.org.uk/swh-plugins/bodeShifterCV" : 325, "elv2:http://plugin.org.uk/swh-plugins/butthigh_iir" : 326, "elv2:http://plugin.org.uk/swh-plugins/buttlow_iir" : 327, "elv2:http://plugin.org.uk/swh-plugins/bwxover_iir" : 328, "elv2:http://plugin.org.uk/swh-plugins/chebstortion" : 329, "elv2:http://plugin.org.uk/swh-plugins/comb" : 330, "elv2:http://plugin.org.uk/swh-plugins/combSplitter" : 331, "elv2:http://plugin.org.uk/swh-plugins/comb_c" : 332, "elv2:http://plugin.org.uk/swh-plugins/comb_l" : 333, "elv2:http://plugin.org.uk/swh-plugins/comb_n" : 334, "elv2:http://plugin.org.uk/swh-plugins/const" : 335, "elv2:http://plugin.org.uk/swh-plugins/crossoverDist" : 336, "elv2:http://plugin.org.uk/swh-plugins/dcRemove" : 337, "elv2:http://plugin.org.uk/swh-plugins/decay" : 338, "elv2:http://plugin.org.uk/swh-plugins/decimator" : 339, "elv2:http://plugin.org.uk/swh-plugins/declip" : 340, "elv2:http://plugin.org.uk/swh-plugins/delay_c" : 341, "elv2:http://plugin.org.uk/swh-plugins/delay_l" : 342, "elv2:http://plugin.org.uk/swh-plugins/delay_n" : 343, "elv2:http://plugin.org.uk/swh-plugins/delayorama" : 344, "elv2:http://plugin.org.uk/swh-plugins/diode" : 345, "elv2:http://plugin.org.uk/swh-plugins/divider" : 346, "elv2:http://plugin.org.uk/swh-plugins/djFlanger" : 347, "elv2:http://plugin.org.uk/swh-plugins/dj_eq" : 348, "elv2:http://plugin.org.uk/swh-plugins/dj_eq_mono" : 349, "elv2:http://plugin.org.uk/swh-plugins/dysonCompress" : 350, "elv2:http://plugin.org.uk/swh-plugins/fadDelay" : 351, "elv2:http://plugin.org.uk/swh-plugins/fastLookaheadLimiter" : 352, "elv2:http://plugin.org.uk/swh-plugins/flanger" : 353, "elv2:http://plugin.org.uk/swh-plugins/fmOsc" : 354, "elv2:http://plugin.org.uk/swh-plugins/foldover" : 355, "elv2:http://plugin.org.uk/swh-plugins/fourByFourPole" : 356, "elv2:http://plugin.org.uk/swh-plugins/foverdrive" : 357, "elv2:http://plugin.org.uk/swh-plugins/freqTracker" : 358, "elv2:http://plugin.org.uk/swh-plugins/gate" : 359, "elv2:http://plugin.org.uk/swh-plugins/giantFlange" : 360, "elv2:http://plugin.org.uk/swh-plugins/gong" : 361, "elv2:http://plugin.org.uk/swh-plugins/gongBeater" : 362, "elv2:http://plugin.org.uk/swh-plugins/gverb" : 363, "elv2:http://plugin.org.uk/swh-plugins/hardLimiter" : 364, "elv2:http://plugin.org.uk/swh-plugins/harmonicGen" : 365, "elv2:http://plugin.org.uk/swh-plugins/hermesFilter" : 366, "elv2:http://plugin.org.uk/swh-plugins/highpass_iir" : 367, "elv2:http://plugin.org.uk/swh-plugins/hilbert" : 368, "elv2:http://plugin.org.uk/swh-plugins/impulse_fc" : 369, "elv2:http://plugin.org.uk/swh-plugins/inv" : 370, "elv2:http://plugin.org.uk/swh-plugins/karaoke" : 371, "elv2:http://plugin.org.uk/swh-plugins/lcrDelay" : 372, "elv2:http://plugin.org.uk/swh-plugins/lfoPhaser" : 373, "elv2:http://plugin.org.uk/swh-plugins/lookaheadLimiter" : 374, "elv2:http://plugin.org.uk/swh-plugins/lookaheadLimiterConst" : 375, "elv2:http://plugin.org.uk/swh-plugins/lowpass_iir" : 376, "elv2:http://plugin.org.uk/swh-plugins/lsFilter" : 377, "elv2:http://plugin.org.uk/swh-plugins/matrixMSSt" : 378, "elv2:http://plugin.org.uk/swh-plugins/matrixSpatialiser" : 379, "elv2:http://plugin.org.uk/swh-plugins/matrixStMS" : 380, "elv2:http://plugin.org.uk/swh-plugins/mbeq" : 381, "elv2:http://plugin.org.uk/swh-plugins/modDelay" : 382, "elv2:http://plugin.org.uk/swh-plugins/multivoiceChorus" : 383, "elv2:http://plugin.org.uk/swh-plugins/pitchScaleHQ" : 384, "elv2:http://plugin.org.uk/swh-plugins/plate" : 385, "elv2:http://plugin.org.uk/swh-plugins/pointerCastDistortion" : 386, "elv2:http://plugin.org.uk/swh-plugins/rateShifter" : 387, "elv2:http://plugin.org.uk/swh-plugins/retroFlange" : 388, "elv2:http://plugin.org.uk/swh-plugins/revdelay" : 389, "elv2:http://plugin.org.uk/swh-plugins/ringmod_1i1o1l" : 390, "elv2:http://plugin.org.uk/swh-plugins/ringmod_2i1o" : 391, "elv2:http://plugin.org.uk/swh-plugins/satanMaximiser" : 392, "elv2:http://plugin.org.uk/swh-plugins/sc1" : 393, "elv2:http://plugin.org.uk/swh-plugins/sc2" : 394, "elv2:http://plugin.org.uk/swh-plugins/sc3" : 395, "elv2:http://plugin.org.uk/swh-plugins/sc4" : 396, "elv2:http://plugin.org.uk/swh-plugins/se4" : 397, "elv2:http://plugin.org.uk/swh-plugins/shaper" : 398, "elv2:http://plugin.org.uk/swh-plugins/sifter" : 399, "elv2:http://plugin.org.uk/swh-plugins/sinCos" : 400, "elv2:http://plugin.org.uk/swh-plugins/singlePara" : 401, "elv2:http://plugin.org.uk/swh-plugins/sinusWavewrapper" : 402, "elv2:http://plugin.org.uk/swh-plugins/smoothDecimate" : 403, "elv2:http://plugin.org.uk/swh-plugins/split" : 404, "elv2:http://plugin.org.uk/swh-plugins/surroundEncoder" : 405, "elv2:http://plugin.org.uk/swh-plugins/svf" : 406, "elv2:http://plugin.org.uk/swh-plugins/tapeDelay" : 407, "elv2:http://plugin.org.uk/swh-plugins/transient" : 408, "elv2:http://plugin.org.uk/swh-plugins/triplePara" : 409, "elv2:http://plugin.org.uk/swh-plugins/ulaw" : 410, "elv2:http://plugin.org.uk/swh-plugins/valve" : 411, "elv2:http://plugin.org.uk/swh-plugins/valveRect" : 412, "elv2:http://plugin.org.uk/swh-plugins/vynil" : 413, "elv2:http://plugin.org.uk/swh-plugins/waveTerrain" : 414, "elv2:http://plugin.org.uk/swh-plugins/xfade" : 415, "elv2:http://plugin.org.uk/swh-plugins/xfade4" : 416, "elv2:http://plugin.org.uk/swh-plugins/zm1" : 417, "enm" : 24, "epp" : 25, "erc" : 28, "erm" : 31, "etc" : 33, "etd" : 34, "ete" : 35, "etf" : 36, "etl" : 37, "etm" : 38, "etp" : 39, "etr" : 40, "ev" : 41, "evp" : 42, "ezf" : 43, "ezx" : 44, "gc" : 45, "ge" : 46, "gm" : 47, "kf" : 299, "kl" : 301, "kl2" : 302, "klg" : 303, "km" : 304, "kog" : 300, "kos" : 305, "ksv" : 306, "pn:dyn_compress_brutal" : 243, "pn:dyn_compress_hard" : 244, "pn:dyn_compress_infinite" : 245, "pn:dyn_compress_medium" : 246, "pn:dyn_compress_soft" : 247, "pn:dyn_compress_supersoft" : 248, "pn:eq_template" : 249, "pn:eq_template2" : 250, "pn:f_bandpass" : 251, "pn:f_filtertest" : 252, "pn:f_high_and_low" : 253, "pn:f_highpass" : 254, "pn:f_inverse_comb" : 255, "pn:f_lowp_sine" : 256, "pn:f_lowp_sine2" : 257, "pn:f_lowpass" : 258, "pn:f_rejectband" : 259, "pn:f_res_bandpass" : 260, "pn:f_res_lowpass" : 261, "pn:f_resonator" : 262, "pn:f_two_filters" : 263, "pn:f_two_filters_pareq" : 264, "pn:gate_crop" : 265, "pn:gate_noisegate_1" : 266, "pn:gate_noisegate_delanalog" : 267, "pn:gate_threshold" : 268, "pn:lad_hermes" : 269, "pn:lad_metronome" : 270, "pn:lad_oscillator_stack" : 271, "pn:lad_oscillator_test" : 272, "pn:lad_sc4" : 273, "pn:lad_sc4_rg" : 274, "pn:metronome" : 275, "pn:time_chorus1" : 276, "pn:time_delay1" : 277, "pn:time_delay2" : 278, "pn:time_flanger1" : 279, "pn:time_phaser1" : 280, "pn:time_reverb1" : 281, "pn:time_reverb2" : 282, "pn:time_reverb3" : 283, "pn:time_reverb4" : 284, "pn:time_wicked_dub" : 285, "pn:var_aw" : 286, "pn:var_aw_custom" : 287, "pn:var_aw_ksv" : 288, "pn:var_aw_tri" : 289, "pn:var_aw_tri_custom" : 290, "pn:var_chipmunk" : 291, "pn:var_dali" : 292, "pn:var_molten_tape" : 293, "pn:var_paralmadness" : 294, "pn:var_parchip" : 295, "pn:var_stretched_tape" : 296, "pn:var_sweeping_pan" : 297, "pn:var_switching_pan" : 298 }, "ladspa" : {}, "ladspa_label_to_unique_id" : {}, "ladspa_sorted" : [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 153, 128, 160, 161, 187, 188, 51, 53, 50, 52, 148, 131, 132, 156, 238, 237, 233, 235, 236, 234, 142, 143, 144, 145, 178, 179, 180, 181, 169, 222, 221, 220, 54, 135, 216, 154, 136, 74, 213, 98, 107, 118, 99, 105, 117, 95, 96, 109, 110, 111, 116, 113, 94, 106, 100, 101, 102, 108, 114, 103, 104, 97, 115, 112, 214, 209, 218, 71, 70, 69, 150, 202, 203, 232, 177, 165, 164, 166, 138, 133, 68, 242, 167, 63, 83, 90, 67, 196, 183, 121, 171, 66, 65, 174, 170, 162, 141, 48, 134, 64, 190, 92, 85, 159, 184, 127, 73, 231, 49, 189, 55, 176, 61, 152, 185, 226, 186, 130, 151, 217, 59, 198, 139, 82, 91, 191, 199, 172, 147, 126, 175, 208, 207, 182, 219, 72, 58, 84, 155, 225, 146, 206, 205, 149, 88, 87, 86, 224, 75, 76, 77, 78, 137, 168, 123, 140, 163, 60, 192, 215, 195, 124, 212, 201, 204, 129, 173, 158, 239, 93, 240, 197, 80, 79, 62, 122, 56, 223, 89, 210, 227, 119, 200, 230, 229, 157, 57, 228, 125, 120, 211, 241, 81, 193, 194 ], "lv2_help" : { "elv2:http://gareus.org/oss/lv2/b_overdrive" : "Name: B Organ Overdrive\nURI: http://gareus.org/oss/lv2/b_overdrive\nClass: Distortion\nAuthor: Robin Gareus\nLatency: no\nPorts: \"In\" Input, Audio\n\t\"Out\" Output, Audio\n\t\"Bias\" Input, Control, 0 to 1, default 0.87399\n\t\"Feedback\" Input, Control, 0 to 1, default 0.5821\n\t\"SagToBias\" Input, Control, 0 to 1, default 0.188\n\t\"Postdiff feedback\" Input, Control, 0 to 1, default 1\n\t\"Global feedback\" Input, Control, 0 to 1, default 0.5826\n\t\"Input Gain\" Input, Control, 0 to 1, default 0.3567\n\t\"Output Gain\" Input, Control, 0 to 1, default 0.07873\n\n", "elv2:http://gareus.org/oss/lv2/b_reverb" : "Name: B Organ Reverb\nURI: http://gareus.org/oss/lv2/b_reverb\nClass: Spatial\nAuthor: Robin Gareus\nLatency: no\nPorts: \"In\" Input, Audio\n\t\"Out\" Output, Audio\n\t\"Dry/Wet\" Input, Control, 0 to 1, default 0.3\n\t\"Input Gain\" Input, Control, 0 to 1, default 0.025\n\n", "elv2:http://gareus.org/oss/lv2/b_synth" : "Name: setBfree DSP Tonewheel Organ\nURI: http://gareus.org/oss/lv2/b_synth\nClass: Instrument\nAuthor: Robin Gareus\nLatency: no\nPorts: \"MIDI In\" Input, \n\t\"MIDI Out\" Output, \n\t\"Left output\" Output, Audio\n\t\"Right Output\" Output, Audio\n\n", "elv2:http://gareus.org/oss/lv2/b_whirl#extended" : "Name: B Organ Whirl Speaker Extended Version\nURI: http://gareus.org/oss/lv2/b_whirl#extended\nClass: Simulator\nAuthor: Robin Gareus\nLatency: no\nPorts: \"In\" Input, Audio\n\t\"Left output\" Output, Audio\n\t\"Right output\" Output, Audio\n\t\"Motors (horn, drum speed: off/slow/fast)\" Input, Control, 0 to 8, default 4, 9-way Selector\n\t\"Horn Level [dB]\" Input, Control, -20 to 20, default 0\n\t\"Drum Level [dB]\" Input, Control, -20 to 20, default 0\n\t\"Drum Stereo Width\" Input, Control, 0 to 1, default 1, 2-way Selector\n\t\"Horn Speed Slow [rpm]\" Input, Control, 10 to 200, default 40.32\n\t\"Horn Speed Fast [rpm]\" Input, Control, 100 to 1000, default 423.359985\n\t\"Horn Acceleration [s]\" Input, Control, 0.001 to 10, default 0.161\n\t\"Horn Deceleration [s]\" Input, Control, 0.001 to 10, default 0.321\n\t\"Horn Brake\" Input, Control, 0 to 1, default 0, 2-way Selector\n\t\"Horn Filter-1 Type:\" Input, Control, 0 to 8, default 0, 9-way Selector\n\t\"Horn Filter-1 Frequency [Hz]\" Input, Control, 250 to 8000, default 4500\n\t\"Horn Filter-1 Quality\" Input, Control, 0.01 to 6, default 2.7456\n\t\"Horn Filter-1 Gain (shelf) [dB]\" Input, Control, -48 to 48, default -38.9291\n\t\"Horn Filter-2 Type:\" Input, Control, 0 to 8, default 7, 9-way Selector\n\t\"Horn Filter-2 Frequency [Hz]\" Input, Control, 250 to 8000, default 300\n\t\"Horn Filter-2 Quality\" Input, Control, 0.01 to 6, default 1\n\t\"Horn Filter-2 Gain (shelf) [dB]\" Input, Control, -48 to 48, default -30\n\t\"Drum Speed Slow [rpm]\" Input, Control, 5 to 100, default 36\n\t\"Drum Speed Fast [rpm]\" Input, Control, 60 to 600, default 357.299988\n\t\"Drum Acceleration [s]\" Input, Control, 0.01 to 20, default 4.127\n\t\"Drum Deceleration [s]\" Input, Control, 0.01 to 20, default 1.371\n\t\"Drum Brake Position\" Input, Control, 0 to 1, default 0, 2-way Selector\n\t\"Drum Filter Type:\" Input, Control, 0 to 8, default 8, 9-way Selector\n\t\"Drum Filter Frequency [Hz]\" Input, Control, 50 to 8000, default 811.969482\n\t\"Drum Filter Quality\" Input, Control, 1.6016 to 6, default 1\n\t\"Drum Filter Gain (shelf) [dB]\" Input, Control, -48 to 48, default -38.9291\n\n", "elv2:http://gareus.org/oss/lv2/b_whirl#simple" : "Name: B Organ Whirl Speaker\nURI: http://gareus.org/oss/lv2/b_whirl#simple\nClass: Simulator\nAuthor: Robin Gareus\nLatency: no\nPorts: \"In\" Input, Audio\n\t\"Left output\" Output, Audio\n\t\"Right output\" Output, Audio\n\t\"Motors (horn, drum speed: off/slow/fast)\" Input, Control, 0 to 8, default 4, 9-way Selector\n\t\"Horn Level [dB]\" Input, Control, -20 to 20, default 0\n\t\"Drum Level [dB]\" Input, Control, -20 to 20, default 0\n\t\"Drum Stereo Width\" Input, Control, 0 to 1, default 1, 2-way Selector\n\n", "elv2:http://hyperglitch.com/dev/VocProc" : "Name: VocProc\nURI: http://hyperglitch.com/dev/VocProc\nClass: Pitch Shifter\nAuthor: Igor Brkic\nLatency: no\nPorts: \"Voice input\" Input, Audio\n\t\"Carrier input\" Input, Audio\n\t\"Output\" Output, Audio\n\t\"Pitch Factor\" Input, Control, -12 to 12, default 0\n\t\"Robotize/Whisperize\" Input, Control, 0 to 1, default 0\n\t\"formant correction/vocoder\" Input, Control, 0 to 1, default 0, 2-way Selector\n\t\"0 - formant correction, 1 - vocoder\" Input, Control, 0 to 1, default 0, 2-way Selector\n\t\"Automatic pitch correction\" Input, Control, 0 to 1, default 0, 2-way Selector\n\t\"Threshold\" Input, Control, 0 to 1, default 0\n\t\"Attack\" Input, Control, 0 to 1, default 0\n\t\"Transpose\" Input, Control, -12 to 12, default 0\n\t\"C\" Input, Control, 0 to 1, default 1, 2-way Selector\n\t\"C#\" Input, Control, 0 to 1, default 1, 2-way Selector\n\t\"D\" Input, Control, 0 to 1, default 1, 2-way Selector\n\t\"D#\" Input, Control, 0 to 1, default 1, 2-way Selector\n\t\"E\" Input, Control, 0 to 1, default 1, 2-way Selector\n\t\"F\" Input, Control, 0 to 1, default 1, 2-way Selector\n\t\"F#\" Input, Control, 0 to 1, default 1, 2-way Selector\n\t\"G\" Input, Control, 0 to 1, default 1, 2-way Selector\n\t\"G#\" Input, Control, 0 to 1, default 1, 2-way Selector\n\t\"A\" Input, Control, 0 to 1, default 1, 2-way Selector\n\t\"A#\" Input, Control, 0 to 1, default 1, 2-way Selector\n\t\"B\" Input, Control, 0 to 1, default 1, 2-way Selector\n\t\"Offset from tone\" Output, Control, -100 to 100, default 0\n\n", "elv2:http://plugin.org.uk/swh-plugins/alaw" : "Name: A-Law Compressor\nURI: http://plugin.org.uk/swh-plugins/alaw\nClass: Dynamics\nAuthor: Steve Harris\nLatency: no\nPorts: \"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/alias" : "Name: Aliasing\nURI: http://plugin.org.uk/swh-plugins/alias\nClass: Distortion\nAuthor: Steve Harris\nLatency: no\nPorts: \"Aliasing level\" Input, Control, 0 to 1, default 0\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/allpass_c" : "Name: Allpass delay line, cubic spline interpolation\nURI: http://plugin.org.uk/swh-plugins/allpass_c\nClass: Delay\nAuthor: Steve Harris\nLatency: no\nPorts: \"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\t\"Max Delay (s)\" Input, Control, 0 to 10, default 1\n\t\"Delay Time (s)\" Input, Control, 0 to 10, default 0\n\t\"Decay Time (s)\" Input, Control, 0 to 10, default 0\n\n", "elv2:http://plugin.org.uk/swh-plugins/allpass_l" : "Name: Allpass delay line, linear interpolation\nURI: http://plugin.org.uk/swh-plugins/allpass_l\nClass: Delay\nAuthor: Steve Harris\nLatency: no\nPorts: \"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\t\"Max Delay (s)\" Input, Control, 0 to 10, default 1\n\t\"Delay Time (s)\" Input, Control, 0 to 10, default 0\n\t\"Decay Time (s)\" Input, Control, 0 to 10, default 0\n\n", "elv2:http://plugin.org.uk/swh-plugins/allpass_n" : "Name: Allpass delay line, noninterpolating\nURI: http://plugin.org.uk/swh-plugins/allpass_n\nClass: Delay\nAuthor: Steve Harris\nLatency: no\nPorts: \"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\t\"Max Delay (s)\" Input, Control, 0 to 10, default 1\n\t\"Delay Time (s)\" Input, Control, 0 to 10, default 0\n\t\"Decay Time (s)\" Input, Control, 0 to 10, default 0\n\n", "elv2:http://plugin.org.uk/swh-plugins/amPitchshift" : "Name: AM pitchshifter\nURI: http://plugin.org.uk/swh-plugins/amPitchshift\nClass: Pitch Shifter\nAuthor: Steve Harris\nLatency: yes, reported by port 4\nPorts: \"Pitch shift\" Input, Control, 0.25 to 4, default 1\n\t\"Buffer size\" Input, Control, 1 to 7, default 4\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\t\"latency\" Output, Control\n\n", "elv2:http://plugin.org.uk/swh-plugins/amp" : "Name: Simple amplifier\nURI: http://plugin.org.uk/swh-plugins/amp\nClass: Amplifier\nAuthor: Steve Harris\nLatency: no\nPorts: \"Amps gain (dB)\" Input, Control, -70 to 70, default 0\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/analogueOsc" : "Name: Analogue Oscillator\nURI: http://plugin.org.uk/swh-plugins/analogueOsc\nClass: Oscillator\nAuthor: Steve Harris\nLatency: no\nPorts: \"Waveform (1=sin, 2=tri, 3=squ, 4=saw)\" Input, Control, 1 to 4, default 1\n\t\"Frequency (Hz)\" Input, Control, 0.000001 to 0.499, default 440\n\t\"Warmth\" Input, Control, 0 to 1, default 0\n\t\"Instability\" Input, Control, 0 to 1, default 0\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/artificialLatency" : "Name: Artificial latency\nURI: http://plugin.org.uk/swh-plugins/artificialLatency\nClass: Utility\nAuthor: Steve Harris\nLatency: yes, reported by port 3\nPorts: \"Delay (ms)\" Input, Control, 0 to 10000, default 2500\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\t\"latency\" Output, Control\n\n", "elv2:http://plugin.org.uk/swh-plugins/autoPhaser" : "Name: Auto phaser\nURI: http://plugin.org.uk/swh-plugins/autoPhaser\nClass: Phaser\nAuthor: Steve Harris\nLatency: no\nPorts: \"Attack time (s)\" Input, Control, 0 to 1, default 0.25\n\t\"Decay time (s)\" Input, Control, 0 to 1, default 0.25\n\t\"Modulation depth\" Input, Control, 0 to 1, default 0.25\n\t\"Feedback\" Input, Control, -1 to 1, default 0\n\t\"Spread (octaves)\" Input, Control, 0 to 2, default 1\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/bandpass_a_iir" : "Name: Glame Bandpass Analog Filter\nURI: http://plugin.org.uk/swh-plugins/bandpass_a_iir\nClass: Bandpass\nAuthor: Steve Harris\nLatency: no\nPorts: \"Center Frequency (Hz)\" Input, Control, 0.0001 to 0.45, default 0.112575\n\t\"Bandwidth (Hz)\" Input, Control, 0.0001 to 0.45, default 0.22505\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/bandpass_iir" : "Name: Glame Bandpass Filter\nURI: http://plugin.org.uk/swh-plugins/bandpass_iir\nClass: Bandpass\nAuthor: Steve Harris\nLatency: no\nPorts: \"Center Frequency (Hz)\" Input, Control, 0.0001 to 0.45, default 0.22505\n\t\"Bandwidth (Hz)\" Input, Control, 0.0001 to 0.45, default 0.22505\n\t\"Stages(2 poles per stage)\" Input, Control, 1 to 10, default 1\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/bodeShifter" : "Name: Bode frequency shifter\nURI: http://plugin.org.uk/swh-plugins/bodeShifter\nClass: Spectral\nAuthor: Steve Harris\nLatency: yes, reported by port 4\nPorts: \"Frequency shift\" Input, Control, 0 to 5000, default 0\n\t\"Input\" Input, Audio\n\t\"Down out\" Output, Audio\n\t\"Up out\" Output, Audio\n\t\"latency\" Output, Control\n\n", "elv2:http://plugin.org.uk/swh-plugins/bodeShifterCV" : "Name: Bode frequency shifter (CV)\nURI: http://plugin.org.uk/swh-plugins/bodeShifterCV\nClass: Spectral\nAuthor: Steve Harris\nLatency: yes, reported by port 8\nPorts: \"Base shift\" Input, Control, 0 to 5000, default 0\n\t\"Mix (-1=down, +1=up)\" Input, Control, -1 to 1, default 0\n\t\"Input\" Input, Audio\n\t\"CV Attenuation\" Input, Control, 0 to 1, default 1\n\t\"Shift CV\" Input, Audio\n\t\"Down out\" Output, Audio\n\t\"Up out\" Output, Audio\n\t\"Mix out\" Output, Audio\n\t\"latency\" Output, Control\n\n", "elv2:http://plugin.org.uk/swh-plugins/butthigh_iir" : "Name: GLAME Butterworth Highpass\nURI: http://plugin.org.uk/swh-plugins/butthigh_iir\nClass: Highpass\nAuthor: Steve Harris\nLatency: no\nPorts: \"Cutoff Frequency (Hz)\" Input, Control, 0.0001 to 0.45, default 0.112575\n\t\"Resonance\" Input, Control, 0.1 to 1.41, default 0.755\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/buttlow_iir" : "Name: GLAME Butterworth Lowpass\nURI: http://plugin.org.uk/swh-plugins/buttlow_iir\nClass: Lowpass\nAuthor: Steve Harris\nLatency: no\nPorts: \"Cutoff Frequency (Hz)\" Input, Control, 0.0001 to 0.45, default 0.112575\n\t\"Resonance\" Input, Control, 0.1 to 1.41, default 0.755\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/bwxover_iir" : "Name: Glame Butterworth X-over Filter\nURI: http://plugin.org.uk/swh-plugins/bwxover_iir\nClass: Bandpass\nAuthor: Steve Harris\nLatency: no\nPorts: \"Cutoff Frequency (Hz)\" Input, Control, 0.0001 to 0.45, default 0.112575\n\t\"Resonance\" Input, Control, 0.1 to 1.41, default 0.755\n\t\"Input\" Input, Audio\n\t\"LP-Output\" Output, Audio\n\t\"HP-Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/chebstortion" : "Name: Chebyshev distortion\nURI: http://plugin.org.uk/swh-plugins/chebstortion\nClass: Distortion\nAuthor: Steve Harris\nLatency: no\nPorts: \"Distortion\" Input, Control, 0 to 3, default 0\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/comb" : "Name: Comb Filter\nURI: http://plugin.org.uk/swh-plugins/comb\nClass: Comb\nAuthor: Steve Harris\nLatency: no\nPorts: \"Band separation (Hz)\" Input, Control, 16 to 640, default 172\n\t\"Feedback\" Input, Control, -0.99 to 0.99, default 0\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/combSplitter" : "Name: Comb Splitter\nURI: http://plugin.org.uk/swh-plugins/combSplitter\nClass: Comb\nAuthor: Steve Harris\nLatency: no\nPorts: \"Band separation (Hz)\" Input, Control, 16 to 640, default 172\n\t\"Input\" Input, Audio\n\t\"Output 1\" Output, Audio\n\t\"Output 2\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/comb_c" : "Name: Comb delay line, cubic spline interpolation\nURI: http://plugin.org.uk/swh-plugins/comb_c\nClass: Delay\nAuthor: Steve Harris\nLatency: no\nPorts: \"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\t\"Max Delay (s)\" Input, Control, 0 to 10, default 1\n\t\"Delay Time (s)\" Input, Control, 0 to 10, default 0\n\t\"Decay Time (s)\" Input, Control, 0 to 10, default 0\n\n", "elv2:http://plugin.org.uk/swh-plugins/comb_l" : "Name: Comb delay line, linear interpolation\nURI: http://plugin.org.uk/swh-plugins/comb_l\nClass: Delay\nAuthor: Steve Harris\nLatency: no\nPorts: \"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\t\"Max Delay (s)\" Input, Control, 0 to 10, default 1\n\t\"Delay Time (s)\" Input, Control, 0 to 10, default 0\n\t\"Decay Time (s)\" Input, Control, 0 to 10, default 0\n\n", "elv2:http://plugin.org.uk/swh-plugins/comb_n" : "Name: Comb delay line, noninterpolating\nURI: http://plugin.org.uk/swh-plugins/comb_n\nClass: Delay\nAuthor: Steve Harris\nLatency: no\nPorts: \"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\t\"Max Delay (s)\" Input, Control, 0 to 10, default 1\n\t\"Delay Time (s)\" Input, Control, 0 to 10, default 0\n\t\"Decay Time (s)\" Input, Control, 0 to 10, default 0\n\n", "elv2:http://plugin.org.uk/swh-plugins/const" : "Name: Constant Signal Generator\nURI: http://plugin.org.uk/swh-plugins/const\nClass: Generator\nAuthor: Steve Harris\nLatency: no\nPorts: \"Signal amplitude\" Input, Control, -1 to 1.1, default 0\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/crossoverDist" : "Name: Crossover distortion\nURI: http://plugin.org.uk/swh-plugins/crossoverDist\nClass: Distortion\nAuthor: Steve Harris\nLatency: no\nPorts: \"Crossover amplitude\" Input, Control, 0 to 0.1, default 0\n\t\"Smoothing\" Input, Control, 0 to 1, default 1\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/dcRemove" : "Name: DC Offset Remover\nURI: http://plugin.org.uk/swh-plugins/dcRemove\nClass: Highpass\nAuthor: Steve Harris\nLatency: no\nPorts: \"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/decay" : "Name: Exponential signal decay\nURI: http://plugin.org.uk/swh-plugins/decay\nClass: Utility\nAuthor: Steve Harris\nLatency: no\nPorts: \"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\t\"Decay Time (s)\" Input, Control, 0 to 10, default 1\n\n", "elv2:http://plugin.org.uk/swh-plugins/decimator" : "Name: Decimator\nURI: http://plugin.org.uk/swh-plugins/decimator\nClass: Distortion\nAuthor: Steve Harris\nLatency: no\nPorts: \"Bit depth\" Input, Control, 1 to 24, default 24\n\t\"Sample rate (Hz)\" Input, Control, 0.001 to 1, default 1\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/declip" : "Name: Declipper\nURI: http://plugin.org.uk/swh-plugins/declip\nClass: Waveshaper\nAuthor: Steve Harris\nLatency: no\nPorts: \"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/delay_c" : "Name: Simple delay line, cubic spline interpolation\nURI: http://plugin.org.uk/swh-plugins/delay_c\nClass: Delay\nAuthor: Steve Harris\nLatency: no\nPorts: \"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\t\"Max Delay (s)\" Input, Control, 0 to 10, default 1\n\t\"Delay Time (s)\" Input, Control, 0 to 10, default 0\n\n", "elv2:http://plugin.org.uk/swh-plugins/delay_l" : "Name: Simple delay line, linear interpolation\nURI: http://plugin.org.uk/swh-plugins/delay_l\nClass: Delay\nAuthor: Steve Harris\nLatency: no\nPorts: \"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\t\"Max Delay (s)\" Input, Control, 0 to 10, default 1\n\t\"Delay Time (s)\" Input, Control, 0 to 10, default 0\n\n", "elv2:http://plugin.org.uk/swh-plugins/delay_n" : "Name: Simple delay line, noninterpolating\nURI: http://plugin.org.uk/swh-plugins/delay_n\nClass: Delay\nAuthor: Steve Harris\nLatency: no\nPorts: \"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\t\"Max Delay (s)\" Input, Control, 0 to 10, default 1\n\t\"Delay Time (s)\" Input, Control, 0 to 10, default 0\n\n", "elv2:http://plugin.org.uk/swh-plugins/delayorama" : "Name: Delayorama\nURI: http://plugin.org.uk/swh-plugins/delayorama\nClass: Delay\nAuthor: Steve Harris\nLatency: no\nPorts: \"Random seed\" Input, Control, 0 to 1000, default 0\n\t\"Input gain (dB)\" Input, Control, -96 to 24, default 0\n\t\"Feedback (%)\" Input, Control, 0 to 100, default 0\n\t\"Number of taps\" Input, Control, 2 to 128, default 2\n\t\"First delay (s)\" Input, Control, 0 to 5, default 0\n\t\"Delay range (s)\" Input, Control, 0.0001 to 6, default 6\n\t\"Delay change\" Input, Control, 0.2 to 5, default 1\n\t\"Delay random (%)\" Input, Control, 0 to 100, default 0\n\t\"Amplitude change\" Input, Control, 0.2 to 5, default 1\n\t\"Amplitude random (%)\" Input, Control, 0 to 100, default 0\n\t\"Dry/wet mix\" Input, Control, 0 to 1, default 1\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/diode" : "Name: Diode Processor\nURI: http://plugin.org.uk/swh-plugins/diode\nClass: Distortion\nAuthor: Steve Harris\nLatency: no\nPorts: \"Mode (0 for none, 1 for half wave, 2 for full wave)\" Input, Control, 0 to 3, default 0\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/divider" : "Name: Audio Divider (Suboctave Generator)\nURI: http://plugin.org.uk/swh-plugins/divider\nClass: Generator\nAuthor: Steve Harris\nLatency: no\nPorts: \"Denominator\" Input, Control, 1 to 8, default 1\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/djFlanger" : "Name: DJ flanger\nURI: http://plugin.org.uk/swh-plugins/djFlanger\nClass: Flanger\nAuthor: Steve Harris\nLatency: no\nPorts: \"LFO sync\" Input, Control\n\t\"LFO period (s)\" Input, Control, 0.1 to 32, default 1\n\t\"LFO depth (ms)\" Input, Control, 1 to 5, default 4\n\t\"Feedback (%)\" Input, Control, -100 to 100, default 0\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/dj_eq" : "Name: DJ EQ\nURI: http://plugin.org.uk/swh-plugins/dj_eq\nClass: Equaliser\nAuthor: Steve Harris\nLatency: yes, reported by port 7\nPorts: \"Lo gain (dB)\" Input, Control, -70 to 6, default 0\n\t\"Mid gain (dB)\" Input, Control, -70 to 6, default 0\n\t\"Hi gain (dB)\" Input, Control, -70 to 6, default 0\n\t\"Input L\" Input, Audio\n\t\"Input R\" Input, Audio\n\t\"Output L\" Output, Audio\n\t\"Output R\" Output, Audio\n\t\"latency\" Output, Control\n\n", "elv2:http://plugin.org.uk/swh-plugins/dj_eq_mono" : "Name: DJ EQ (mono)\nURI: http://plugin.org.uk/swh-plugins/dj_eq_mono\nClass: Equaliser\nAuthor: Steve Harris\nLatency: yes, reported by port 5\nPorts: \"Lo gain (dB)\" Input, Control, -70 to 6, default 0\n\t\"Mid gain (dB)\" Input, Control, -70 to 6, default 0\n\t\"Hi gain (dB)\" Input, Control, -70 to 6, default 0\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\t\"latency\" Output, Control\n\n", "elv2:http://plugin.org.uk/swh-plugins/dysonCompress" : "Name: Dyson compressor\nURI: http://plugin.org.uk/swh-plugins/dysonCompress\nClass: Compressor\nAuthor: Steve Harris\nLatency: no\nPorts: \"Peak limit (dB)\" Input, Control, -30 to 0, default 0\n\t\"Release time (s)\" Input, Control, 0 to 1, default 0.25\n\t\"Fast compression ratio\" Input, Control, 0 to 1, default 0.5\n\t\"Compression ratio\" Input, Control, 0 to 1, default 0.5\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/fadDelay" : "Name: Fractionally Addressed Delay Line\nURI: http://plugin.org.uk/swh-plugins/fadDelay\nClass: Delay\nAuthor: Steve Harris\nLatency: no\nPorts: \"Delay (seconds)\" Input, Control, 0.1 to 10, default 1\n\t\"Feedback (dB)\" Input, Control, -70 to 0, default 0\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/fastLookaheadLimiter" : "Name: Fast Lookahead limiter\nURI: http://plugin.org.uk/swh-plugins/fastLookaheadLimiter\nClass: Limiter\nAuthor: Steve Harris\nLatency: yes, reported by port 8\nPorts: \"Input gain (dB)\" Input, Control, -20 to 20, default 0\n\t\"Limit (dB)\" Input, Control, -20 to 0, default 0\n\t\"Release time (s)\" Input, Control, 0.01 to 2, default 0.5075\n\t\"Attenuation (dB)\" Output, Control, 0 to 70\n\t\"Input 1\" Input, Audio\n\t\"Input 2\" Input, Audio\n\t\"Output 1\" Output, Audio\n\t\"Output 2\" Output, Audio\n\t\"latency\" Output, Control\n\n", "elv2:http://plugin.org.uk/swh-plugins/flanger" : "Name: Flanger\nURI: http://plugin.org.uk/swh-plugins/flanger\nClass: Flanger\nAuthor: Steve Harris\nLatency: no\nPorts: \"Delay base (ms)\" Input, Control, 0.1 to 25, default 6.325\n\t\"Max slowdown (ms)\" Input, Control, 0 to 10, default 2.5\n\t\"LFO frequency (Hz)\" Input, Control, 0.05 to 100, default 25.0375\n\t\"Feedback\" Input, Control, -1 to 1, default 0\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/fmOsc" : "Name: FM Oscillator\nURI: http://plugin.org.uk/swh-plugins/fmOsc\nClass: Oscillator\nAuthor: Steve Harris\nLatency: no\nPorts: \"Waveform (1=sin, 2=tri, 3=squ, 4=saw)\" Input, Control, 1 to 4, default 1\n\t\"Frequency (Hz)\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/foldover" : "Name: Foldover distortion\nURI: http://plugin.org.uk/swh-plugins/foldover\nClass: Distortion\nAuthor: Steve Harris\nLatency: no\nPorts: \"Drive\" Input, Control, 0 to 1, default 0\n\t\"Skew\" Input, Control, 0 to 1, default 0\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/fourByFourPole" : "Name: 4 x 4 pole allpass\nURI: http://plugin.org.uk/swh-plugins/fourByFourPole\nClass: Allpass\nAuthor: Steve Harris\nLatency: no\nPorts: \"Frequency 1\" Input, Control, 1 to 20000, default 5000.75\n\t\"Feedback 1\" Input, Control, -1 to 1, default 0\n\t\"Frequency 2\" Input, Control, 1 to 20000, default 10000.5\n\t\"Feedback 2\" Input, Control, -1 to 1, default 0\n\t\"Frequency 3\" Input, Control, 1 to 20000, default 15000.25\n\t\"Feedback 3\" Input, Control, -1 to 1, default 0\n\t\"Frequency 4\" Input, Control, 1 to 20000, default 20000\n\t\"Feedback 4\" Input, Control, -1 to 1, default 0\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/foverdrive" : "Name: Fast overdrive\nURI: http://plugin.org.uk/swh-plugins/foverdrive\nClass: Distortion\nAuthor: Steve Harris\nLatency: no\nPorts: \"Drive level\" Input, Control, 1 to 3, default 1\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/freqTracker" : "Name: Frequency tracker\nURI: http://plugin.org.uk/swh-plugins/freqTracker\nClass: Analyser\nAuthor: Steve Harris\nLatency: no\nPorts: \"Tracking speed\" Input, Control, 0 to 1, default 0.5\n\t\"Input\" Input, Audio\n\t\"Frequency (Hz)\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/gate" : "Name: Gate\nURI: http://plugin.org.uk/swh-plugins/gate\nClass: Gate\nAuthor: Steve Harris\nLatency: no\nPorts: \"LF key filter (Hz)\" Input, Control, 25 to 4000, default 500\n\t\"HF key filter (Hz)\" Input, Control, 250 to 20000, default 2000\n\t\"Threshold (dB)\" Input, Control, -70 to 20, default -40\n\t\"Attack (ms)\" Input, Control, 0.01 to 1000, default 0.1\n\t\"Hold (ms)\" Input, Control, 2 to 2000, default 50\n\t\"Decay (ms)\" Input, Control, 2 to 4000, default 50\n\t\"Range (dB)\" Input, Control, -90 to 0, default -20\n\t\"Output select (-1 = key listen, 0 = gate, 1 = bypass)\" Input, Control, -1 to 1, default 0\n\t\"Key level (dB)\" Output, Control, -90 to 0\n\t\"Gate state\" Output, Control, 0 to 1\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/giantFlange" : "Name: Giant flange\nURI: http://plugin.org.uk/swh-plugins/giantFlange\nClass: Flanger\nAuthor: Steve Harris\nLatency: no\nPorts: \"Double delay\" Input, Control\n\t\"LFO frequency 1 (Hz)\" Input, Control, 0 to 30, default 1\n\t\"Delay 1 range (s)\" Input, Control, 0 to 10.5, default 2.625\n\t\"LFO frequency 2 (Hz)\" Input, Control, 0 to 30, default 1\n\t\"Delay 2 range (s)\" Input, Control, 0 to 10.5, default 0\n\t\"Feedback\" Input, Control, -100 to 100, default 0\n\t\"Dry/Wet level\" Input, Control, 0 to 1, default 0\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/gong" : "Name: Gong model\nURI: http://plugin.org.uk/swh-plugins/gong\nClass: Generator\nAuthor: Steve Harris\nLatency: no\nPorts: \"Inner damping\" Input, Control, 0 to 1, default 0.5\n\t\"Outer damping\" Input, Control, 0 to 1, default 0.5\n\t\"Mic position\" Input, Control, 0 to 1, default 0.25\n\t\"Inner size 1\" Input, Control, 0 to 1, default 0.5\n\t\"Inner stiffness 1 +\" Input, Control, 0 to 1, default 0.5\n\t\"Inner stiffness 1 -\" Input, Control, 0 to 1, default 0.5\n\t\"Inner size 2\" Input, Control, 0 to 1, default 0.5\n\t\"Inner stiffness 2 +\" Input, Control, 0 to 1, default 0.5\n\t\"Inner stiffness 2 -\" Input, Control, 0 to 1, default 0.5\n\t\"Inner size 3\" Input, Control, 0 to 1, default 0.5\n\t\"Inner stiffness 3 +\" Input, Control, 0 to 1, default 0.5\n\t\"Inner stiffness 3 -\" Input, Control, 0 to 1, default 0.5\n\t\"Inner size 4\" Input, Control, 0 to 1, default 0.5\n\t\"Inner stiffness 4 +\" Input, Control, 0 to 1, default 0.5\n\t\"Inner stiffness 4 -\" Input, Control, 0 to 1, default 0.5\n\t\"Outer size 1\" Input, Control, 0 to 1, default 0.5\n\t\"Outer stiffness 1 +\" Input, Control, 0 to 1, default 0.5\n\t\"Outer stiffness 1 -\" Input, Control, 0 to 1, default 0.5\n\t\"Outer size 2\" Input, Control, 0 to 1, default 0.5\n\t\"Outer stiffness 2 +\" Input, Control, 0 to 1, default 0.5\n\t\"Outer stiffness 2 -\" Input, Control, 0 to 1, default 0.5\n\t\"Outer size 3\" Input, Control, 0 to 1, default 0.5\n\t\"Outer stiffness 3 +\" Input, Control, 0 to 1, default 0.5\n\t\"Outer stiffness 3 -\" Input, Control, 0 to 1, default 0.5\n\t\"Outer size 4\" Input, Control, 0 to 1, default 0.5\n\t\"Outer stiffness 4 +\" Input, Control, 0 to 1, default 0.5\n\t\"Outer stiffness 4 -\" Input, Control, 0 to 1, default 0.5\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/gongBeater" : "Name: Gong beater\nURI: http://plugin.org.uk/swh-plugins/gongBeater\nClass: Generator\nAuthor: Steve Harris\nLatency: no\nPorts: \"Impulse gain (dB)\" Input, Control, -70 to 0, default -70\n\t\"Strike gain (dB)\" Input, Control, -70 to 0, default 0\n\t\"Strike duration (s)\" Input, Control, 0.001 to 0.2, default 0.1005\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/gverb" : "Name: GVerb\nURI: http://plugin.org.uk/swh-plugins/gverb\nClass: Reverb\nAuthor: Steve Harris\nLatency: no\nPorts: \"Roomsize (m)\" Input, Control, 1 to 300, default 75.75\n\t\"Reverb time (s)\" Input, Control, 0.1 to 30, default 7.575\n\t\"Damping\" Input, Control, 0 to 1, default 0.5\n\t\"Input bandwidth\" Input, Control, 0 to 1, default 0.75\n\t\"Dry signal level (dB)\" Input, Control, -70 to 0, default -70\n\t\"Early reflection level (dB)\" Input, Control, -70 to 0, default 0\n\t\"Tail level (dB)\" Input, Control, -70 to 0, default -17.5\n\t\"Input\" Input, Audio\n\t\"Left output\" Output, Audio\n\t\"Right output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/hardLimiter" : "Name: Hard Limiter\nURI: http://plugin.org.uk/swh-plugins/hardLimiter\nClass: Distortion\nAuthor: Steve Harris\nLatency: no\nPorts: \"dB limit\" Input, Control, -50 to 0, default 0\n\t\"Wet level\" Input, Control, 0 to 1, default 1\n\t\"Residue level\" Input, Control, 0 to 1, default 0\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/harmonicGen" : "Name: Harmonic generator\nURI: http://plugin.org.uk/swh-plugins/harmonicGen\nClass: Generator\nAuthor: Steve Harris\nLatency: no\nPorts: \"Fundamental magnitude\" Input, Control, -1 to 1, default 1\n\t\"2nd harmonic magnitude\" Input, Control, -1 to 1, default 0\n\t\"3rd harmonic magnitude\" Input, Control, -1 to 1, default 0\n\t\"4th harmonic magnitude\" Input, Control, -1 to 1, default 0\n\t\"5th harmonic magnitude\" Input, Control, -1 to 1, default 0\n\t\"6th harmonic magnitude\" Input, Control, -1 to 1, default 0\n\t\"7th harmonic magnitude\" Input, Control, -1 to 1, default 0\n\t\"8th harmonic magnitude\" Input, Control, -1 to 1, default 0\n\t\"9th harmonic magnitude\" Input, Control, -1 to 1, default 0\n\t\"10th harmonic magnitude\" Input, Control, -1 to 1, default 0\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/hermesFilter" : "Name: Hermes Filter\nURI: http://plugin.org.uk/swh-plugins/hermesFilter\nClass: Filter\nAuthor: Steve Harris\nLatency: no\nPorts: \"LFO1 freq (Hz)\" Input, Control, 0 to 1000, default 250\n\t\"LFO1 wave (0 = sin, 1 = tri, 2 = saw, 3 = squ, 4 = s&h)\" Input, Control, 0 to 4, default 0\n\t\"LFO2 freq (Hz)\" Input, Control, 0 to 1000, default 250\n\t\"LFO2 wave (0 = sin, 1 = tri, 2 = saw, 3 = squ, 4 = s&h)\" Input, Control, 0 to 4, default 0\n\t\"Osc1 freq (Hz)\" Input, Control, 0 to 4000, default 440\n\t\"Osc1 wave (0 = sin, 1 = tri, 2 = saw, 3 = squ, 4 = noise)\" Input, Control, 0 to 4, default 0\n\t\"Osc2 freq (Hz)\" Input, Control, 0 to 4000, default 440\n\t\"Osc2 wave (0 = sin, 1 = tri, 2 = saw, 3 = squ, 4 = noise)\" Input, Control, 0 to 4, default 0\n\t\"Ringmod 1 depth (0=none, 1=AM, 2=RM)\" Input, Control, 0 to 2, default 0\n\t\"Ringmod 2 depth (0=none, 1=AM, 2=RM)\" Input, Control, 0 to 2, default 0\n\t\"Ringmod 3 depth (0=none, 1=AM, 2=RM)\" Input, Control, 0 to 2, default 0\n\t\"Osc1 gain (dB)\" Input, Control, -70 to 20, default -70\n\t\"RM1 gain (dB)\" Input, Control, -70 to 20, default -70\n\t\"Osc2 gain (dB)\" Input, Control, -70 to 20, default -70\n\t\"RM2 gain (dB)\" Input, Control, -70 to 20, default -70\n\t\"Input gain (dB)\" Input, Control, -70 to 20, default 0\n\t\"RM3 gain (dB)\" Input, Control, -70 to 20, default -70\n\t\"Xover lower freq\" Input, Control, 50 to 6000, default 1537.5\n\t\"Xover upper freq\" Input, Control, 1000 to 10000, default 7750\n\t\"Dist1 drive\" Input, Control, 0 to 3, default 0\n\t\"Dist2 drive\" Input, Control, 0 to 3, default 0\n\t\"Dist3 drive\" Input, Control, 0 to 3, default 0\n\t\"Filt1 type (0=none, 1=LP, 2=HP, 3=BP, 4=BR, 5=AP)\" Input, Control, 0 to 5, default 0\n\t\"Filt1 freq\" Input, Control, 0 to 8000, default 440\n\t\"Filt1 q\" Input, Control, 0 to 1, default 0\n\t\"Filt1 resonance\" Input, Control, 0 to 1, default 0\n\t\"Filt1 LFO1 level\" Input, Control, -500 to 500, default 0\n\t\"Filt1 LFO2 level\" Input, Control, -500 to 500, default 0\n\t\"Filt2 type (0=none, 1=LP, 2=HP, 3=BP, 4=BR, 5=AP)\" Input, Control, 0 to 5, default 0\n\t\"Filt2 freq\" Input, Control, 0 to 8000, default 440\n\t\"Filt2 q\" Input, Control, 0 to 1, default 0\n\t\"Filt2 resonance\" Input, Control, 0 to 1, default 0\n\t\"Filt2 LFO1 level\" Input, Control, -500 to 500, default 0\n\t\"Filt2 LFO2 level\" Input, Control, -500 to 500, default 0\n\t\"Filt3 type (0=none, 1=LP, 2=HP, 3=BP, 4=BR, 5=AP)\" Input, Control, 0 to 5, default 0\n\t\"Filt3 freq\" Input, Control, 0 to 8000, default 440\n\t\"Filt3 q\" Input, Control, 0 to 1, default 0\n\t\"Filt3 resonance\" Input, Control, 0 to 1, default 0\n\t\"Filt3 LFO1 level\" Input, Control, -500 to 500, default 0\n\t\"Filt3 LFO2 level\" Input, Control, -500 to 500, default 0\n\t\"Delay1 length (s)\" Input, Control, 0 to 2, default 0\n\t\"Delay1 feedback\" Input, Control, 0 to 1, default 0\n\t\"Delay1 wetness\" Input, Control, 0 to 1, default 0\n\t\"Delay2 length (s)\" Input, Control, 0 to 2, default 0\n\t\"Delay2 feedback\" Input, Control, 0 to 1, default 0\n\t\"Delay2 wetness\" Input, Control, 0 to 1, default 0\n\t\"Delay3 length (s)\" Input, Control, 0 to 2, default 0\n\t\"Delay3 feedback\" Input, Control, 0 to 1, default 0\n\t\"Delay3 wetness\" Input, Control, 0 to 1, default 0\n\t\"Band 1 gain (dB)\" Input, Control, -70 to 20, default 0\n\t\"Band 2 gain (dB)\" Input, Control, -70 to 20, default 0\n\t\"Band 3 gain (dB)\" Input, Control, -70 to 20, default 0\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/highpass_iir" : "Name: Glame Highpass Filter\nURI: http://plugin.org.uk/swh-plugins/highpass_iir\nClass: Highpass\nAuthor: Steve Harris\nLatency: no\nPorts: \"Cutoff Frequency\" Input, Control, 0.0001 to 0.45, default 0.112575\n\t\"Stages(2 poles per stage)\" Input, Control, 1 to 10, default 1\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/hilbert" : "Name: Hilbert transformer\nURI: http://plugin.org.uk/swh-plugins/hilbert\nClass: Analyser\nAuthor: Steve Harris\nLatency: yes, reported by port 3\nPorts: \"Input\" Input, Audio\n\t\"0deg output\" Output, Audio\n\t\"90deg output\" Output, Audio\n\t\"latency\" Output, Control\n\n", "elv2:http://plugin.org.uk/swh-plugins/impulse_fc" : "Name: Non-bandlimited single-sample impulses\nURI: http://plugin.org.uk/swh-plugins/impulse_fc\nClass: Generator\nAuthor: Steve Harris\nLatency: no\nPorts: \"Frequency (Hz)\" Input, Control, 0 to 5000, default 1\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/inv" : "Name: Inverter\nURI: http://plugin.org.uk/swh-plugins/inv\nClass: Utility\nAuthor: Steve Harris\nLatency: no\nPorts: \"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/karaoke" : "Name: Karaoke\nURI: http://plugin.org.uk/swh-plugins/karaoke\nClass: Filter\nAuthor: Steve Harris\nLatency: no\nPorts: \"Vocal volume (dB)\" Input, Control, -70 to 0, default 0\n\t\"Left in\" Input, Audio\n\t\"Right in\" Input, Audio\n\t\"Left out\" Output, Audio\n\t\"Right out\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/lcrDelay" : "Name: L/C/R Delay\nURI: http://plugin.org.uk/swh-plugins/lcrDelay\nClass: Delay\nAuthor: Steve Harris\nLatency: no\nPorts: \"L delay (ms)\" Input, Control, 0 to 2700, default 675\n\t\"L level\" Input, Control, 0 to 50, default 25\n\t\"C delay (ms)\" Input, Control, 0 to 2700, default 675\n\t\"C level\" Input, Control, 0 to 50, default 25\n\t\"R delay (ms)\" Input, Control, 0 to 2700, default 675\n\t\"R level\" Input, Control, 0 to 50, default 25\n\t\"Feedback\" Input, Control, -100 to 100, default 0\n\t\"High damp (%)\" Input, Control, 0 to 100, default 50\n\t\"Low damp (%)\" Input, Control, 0 to 100, default 50\n\t\"Spread\" Input, Control, 0 to 50, default 25\n\t\"Dry/Wet level\" Input, Control, 0 to 1, default 0\n\t\"L input\" Input, Audio\n\t\"R input\" Input, Audio\n\t\"L output\" Output, Audio\n\t\"R output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/lfoPhaser" : "Name: LFO Phaser\nURI: http://plugin.org.uk/swh-plugins/lfoPhaser\nClass: Phaser\nAuthor: Steve Harris\nLatency: no\nPorts: \"LFO rate (Hz)\" Input, Control, 0 to 100, default 25\n\t\"LFO depth\" Input, Control, 0 to 1, default 0.25\n\t\"Feedback\" Input, Control, -1 to 1, default 0\n\t\"Spread (octaves)\" Input, Control, 0 to 2, default 1\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/lookaheadLimiter" : "Name: Lookahead limiter\nURI: http://plugin.org.uk/swh-plugins/lookaheadLimiter\nClass: Limiter\nAuthor: Steve Harris\nLatency: yes, reported by port 7\nPorts: \"Limit (dB)\" Input, Control, -20 to 0, default 0\n\t\"Lookahead delay\" Input, Control, 0.001 to 2, default 1.0005\n\t\"Attenuation (dB)\" Output, Control, 0 to 12\n\t\"Input 1\" Input, Audio\n\t\"Input 2\" Input, Audio\n\t\"Output 1\" Output, Audio\n\t\"Output 2\" Output, Audio\n\t\"latency\" Output, Control\n\n", "elv2:http://plugin.org.uk/swh-plugins/lookaheadLimiterConst" : "Name: Lookahead limiter (fixed latency)\nURI: http://plugin.org.uk/swh-plugins/lookaheadLimiterConst\nClass: Limiter\nAuthor: Steve Harris\nLatency: yes, reported by port 7\nPorts: \"Limit (dB)\" Input, Control, -20 to 0, default 0\n\t\"Lookahead time (s)\" Input, Control, 0.001 to 0.15, default 0.0755\n\t\"Attenuation (dB)\" Output, Control, 0 to 12\n\t\"Input 1\" Input, Audio\n\t\"Input 2\" Input, Audio\n\t\"Output 1\" Output, Audio\n\t\"Output 2\" Output, Audio\n\t\"latency\" Output, Control\n\n", "elv2:http://plugin.org.uk/swh-plugins/lowpass_iir" : "Name: Glame Lowpass Filter\nURI: http://plugin.org.uk/swh-plugins/lowpass_iir\nClass: Lowpass\nAuthor: Steve Harris\nLatency: no\nPorts: \"Cutoff Frequency\" Input, Control, 0.0001 to 0.45, default 0.337525\n\t\"Stages(2 poles per stage)\" Input, Control, 1 to 10, default 1\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/lsFilter" : "Name: LS Filter\nURI: http://plugin.org.uk/swh-plugins/lsFilter\nClass: Filter\nAuthor: Steve Harris\nLatency: no\nPorts: \"Filter type (0=LP, 1=BP, 2=HP)\" Input, Control, 0 to 2, default 0\n\t\"Cutoff frequency (Hz)\" Input, Control, 0.002 to 0.5, default 0.251\n\t\"Resonance\" Input, Control, 0 to 1, default 0\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/matrixMSSt" : "Name: Matrix: MS to Stereo\nURI: http://plugin.org.uk/swh-plugins/matrixMSSt\nClass: Converter\nAuthor: Steve Harris\nLatency: no\nPorts: \"Width\" Input, Control, 0 to 2, default 1\n\t\"Mid\" Input, Audio\n\t\"Side\" Input, Audio\n\t\"Left\" Output, Audio\n\t\"Right\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/matrixSpatialiser" : "Name: Matrix Spatialiser\nURI: http://plugin.org.uk/swh-plugins/matrixSpatialiser\nClass: Utility\nAuthor: Steve Harris\nLatency: no\nPorts: \"Input L\" Input, Audio\n\t\"Input R\" Input, Audio\n\t\"Width\" Input, Control, -512 to 512, default 0\n\t\"Output L\" Output, Audio\n\t\"Output R\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/matrixStMS" : "Name: Matrix: Stereo to MS\nURI: http://plugin.org.uk/swh-plugins/matrixStMS\nClass: Converter\nAuthor: Steve Harris\nLatency: no\nPorts: \"Left\" Input, Audio\n\t\"Right\" Input, Audio\n\t\"Mid\" Output, Audio\n\t\"Side\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/mbeq" : "Name: Multiband EQ\nURI: http://plugin.org.uk/swh-plugins/mbeq\nClass: Multiband\nAuthor: Steve Harris\nLatency: yes, reported by port 17\nPorts: \"50Hz gain (low shelving)\" Input, Control, -70 to 30, default 0\n\t\"100Hz gain\" Input, Control, -70 to 30, default 0\n\t\"156Hz gain\" Input, Control, -70 to 30, default 0\n\t\"220Hz gain\" Input, Control, -70 to 30, default 0\n\t\"311Hz gain\" Input, Control, -70 to 30, default 0\n\t\"440Hz gain\" Input, Control, -70 to 30, default 0\n\t\"622Hz gain\" Input, Control, -70 to 30, default 0\n\t\"880Hz gain\" Input, Control, -70 to 30, default 0\n\t\"1250Hz gain\" Input, Control, -70 to 30, default 0\n\t\"1750Hz gain\" Input, Control, -70 to 30, default 0\n\t\"2500Hz gain\" Input, Control, -70 to 30, default 0\n\t\"3500Hz gain\" Input, Control, -70 to 30, default 0\n\t\"5000Hz gain\" Input, Control, -70 to 30, default 0\n\t\"10000Hz gain\" Input, Control, -70 to 30, default 0\n\t\"20000Hz gain\" Input, Control, -70 to 30, default 0\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\t\"latency\" Output, Control\n\n", "elv2:http://plugin.org.uk/swh-plugins/modDelay" : "Name: Modulatable delay\nURI: http://plugin.org.uk/swh-plugins/modDelay\nClass: Delay\nAuthor: Steve Harris\nLatency: no\nPorts: \"Base delay (s)\" Input, Control, 0 to 1, default 1\n\t\"Delay (s)\" Input, Audio\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/multivoiceChorus" : "Name: Multivoice Chorus\nURI: http://plugin.org.uk/swh-plugins/multivoiceChorus\nClass: Chorus\nAuthor: Steve Harris\nLatency: no\nPorts: \"Number of voices\" Input, Control, 1 to 8, default 1\n\t\"Delay base (ms)\" Input, Control, 10 to 40, default 10\n\t\"Voice separation (ms)\" Input, Control, 0 to 2, default 0.5\n\t\"Detune (%)\" Input, Control, 0 to 5, default 1\n\t\"LFO frequency (Hz)\" Input, Control, 2 to 30, default 9\n\t\"Output attenuation (dB)\" Input, Control, -20 to 0, default 0\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/pitchScaleHQ" : "Name: Higher Quality Pitch Scaler\nURI: http://plugin.org.uk/swh-plugins/pitchScaleHQ\nClass: Pitch Shifter\nAuthor: Steve Harris\nLatency: yes, reported by port 3\nPorts: \"Pitch co-efficient\" Input, Control, 0.5 to 2, default 1\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\t\"latency\" Output, Control\n\n", "elv2:http://plugin.org.uk/swh-plugins/plate" : "Name: Plate reverb\nURI: http://plugin.org.uk/swh-plugins/plate\nClass: Reverb\nAuthor: Steve Harris\nLatency: no\nPorts: \"Reverb time\" Input, Control, 0.01 to 8.5, default 4.255\n\t\"Damping\" Input, Control, 0 to 1, default 0.25\n\t\"Dry/wet mix\" Input, Control, 0 to 1, default 0.25\n\t\"Input\" Input, Audio\n\t\"Left output\" Output, Audio\n\t\"Right output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/pointerCastDistortion" : "Name: Pointer cast distortion\nURI: http://plugin.org.uk/swh-plugins/pointerCastDistortion\nClass: Distortion\nAuthor: Steve Harris\nLatency: no\nPorts: \"Effect cutoff freq (Hz)\" Input, Control, 0.0001 to 0.3, default 0.075075\n\t\"Dry/wet mix\" Input, Control, 0 to 1, default 0\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/rateShifter" : "Name: Rate shifter\nURI: http://plugin.org.uk/swh-plugins/rateShifter\nClass: Pitch Shifter\nAuthor: Steve Harris\nLatency: no\nPorts: \"Rate\" Input, Control, -4 to 4, default 1\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/retroFlange" : "Name: Retro Flanger\nURI: http://plugin.org.uk/swh-plugins/retroFlange\nClass: Flanger\nAuthor: Steve Harris\nLatency: no\nPorts: \"Average stall (ms)\" Input, Control, 0 to 10, default 2.5\n\t\"Flange frequency (Hz)\" Input, Control, 0.5 to 8, default 1\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/revdelay" : "Name: Reverse Delay (5s max)\nURI: http://plugin.org.uk/swh-plugins/revdelay\nClass: Delay\nAuthor: Steve Harris\nLatency: no\nPorts: \"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\t\"Delay Time (s)\" Input, Control, 0 to 5, default 0\n\t\"Dry Level (dB)\" Input, Control, -70 to 0, default 0\n\t\"Wet Level (dB)\" Input, Control, -70 to 0, default 0\n\t\"Feedback\" Input, Control, 0 to 1, default 0\n\t\"Crossfade samples\" Input, Control, 0 to 5000, default 1250\n\n", "elv2:http://plugin.org.uk/swh-plugins/ringmod_1i1o1l" : "Name: Ringmod with LFO\nURI: http://plugin.org.uk/swh-plugins/ringmod_1i1o1l\nClass: Modulator\nAuthor: Steve Harris\nLatency: no\nPorts: \"Modulation depth (0=none, 1=AM, 2=RM)\" Input, Control, 0 to 2, default 0\n\t\"Frequency (Hz)\" Input, Control, 1 to 1000, default 440\n\t\"Sine level\" Input, Control, -1 to 1, default 1\n\t\"Triangle level\" Input, Control, -1 to 1, default 0\n\t\"Sawtooth level\" Input, Control, -1 to 1, default 0\n\t\"Square level\" Input, Control, -1 to 1, default 0\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/ringmod_2i1o" : "Name: Ringmod with two inputs\nURI: http://plugin.org.uk/swh-plugins/ringmod_2i1o\nClass: Modulator\nAuthor: Steve Harris\nLatency: no\nPorts: \"Modulation depth (0=none, 1=AM, 2=RM)\" Input, Control, 0 to 2, default 0\n\t\"Input\" Input, Audio\n\t\"Modulator\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/satanMaximiser" : "Name: Barry's Satan Maximiser\nURI: http://plugin.org.uk/swh-plugins/satanMaximiser\nClass: Distortion\nAuthor: Steve Harris\nLatency: no\nPorts: \"Decay time (samples)\" Input, Control, 2 to 30, default 30\n\t\"Knee point (dB)\" Input, Control, -90 to 0, default 0\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/sc1" : "Name: SC1\nURI: http://plugin.org.uk/swh-plugins/sc1\nClass: Compressor\nAuthor: Steve Harris\nLatency: no\nPorts: \"Attack time (ms)\" Input, Control, 2 to 400, default 101.5\n\t\"Release time (ms)\" Input, Control, 2 to 800, default 401\n\t\"Threshold level (dB)\" Input, Control, -30 to 0, default 0\n\t\"Ratio (1:n)\" Input, Control, 1 to 10, default 1\n\t\"Knee radius (dB)\" Input, Control, 1 to 10, default 3.25\n\t\"Makeup gain (dB)\" Input, Control, 0 to 24, default 0\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/sc2" : "Name: SC2\nURI: http://plugin.org.uk/swh-plugins/sc2\nClass: Compressor\nAuthor: Steve Harris\nLatency: no\nPorts: \"Attack time (ms)\" Input, Control, 2 to 400, default 101.5\n\t\"Release time (ms)\" Input, Control, 2 to 800, default 401\n\t\"Threshold level (dB)\" Input, Control, -30 to 0, default 0\n\t\"Ratio (1:n)\" Input, Control, 1 to 10, default 1\n\t\"Knee radius (dB)\" Input, Control, 1 to 10, default 3.25\n\t\"Makeup gain (dB)\" Input, Control, 0 to 24, default 0\n\t\"Sidechain\" Input, Audio\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/sc3" : "Name: SC3\nURI: http://plugin.org.uk/swh-plugins/sc3\nClass: Compressor\nAuthor: Steve Harris\nLatency: no\nPorts: \"Attack time (ms)\" Input, Control, 2 to 400, default 101.5\n\t\"Release time (ms)\" Input, Control, 2 to 800, default 401\n\t\"Threshold level (dB)\" Input, Control, -30 to 0, default 0\n\t\"Ratio (1:n)\" Input, Control, 1 to 10, default 1\n\t\"Knee radius (dB)\" Input, Control, 1 to 10, default 3.25\n\t\"Makeup gain (dB)\" Input, Control, 0 to 24, default 0\n\t\"Chain balance\" Input, Control, 0 to 1, default 0\n\t\"Sidechain\" Input, Audio\n\t\"Left input\" Input, Audio\n\t\"Right input\" Input, Audio\n\t\"Left output\" Output, Audio\n\t\"Right output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/sc4" : "Name: SC4\nURI: http://plugin.org.uk/swh-plugins/sc4\nClass: Compressor\nAuthor: Steve Harris\nLatency: no\nPorts: \"RMS/peak\" Input, Control, 0 to 1, default 0\n\t\"Attack time (ms)\" Input, Control, 1.5 to 400, default 101.125\n\t\"Release time (ms)\" Input, Control, 2 to 800, default 401\n\t\"Threshold level (dB)\" Input, Control, -30 to 0, default 0\n\t\"Ratio (1:n)\" Input, Control, 1 to 20, default 1\n\t\"Knee radius (dB)\" Input, Control, 1 to 10, default 3.25\n\t\"Makeup gain (dB)\" Input, Control, 0 to 24, default 0\n\t\"Amplitude (dB)\" Output, Control, -40 to 12\n\t\"Gain reduction (dB)\" Output, Control, -24 to 0\n\t\"Left input\" Input, Audio\n\t\"Right input\" Input, Audio\n\t\"Left output\" Output, Audio\n\t\"Right output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/se4" : "Name: SE4\nURI: http://plugin.org.uk/swh-plugins/se4\nClass: Compressor\nAuthor: Steve Harris\nLatency: no\nPorts: \"RMS/peak\" Input, Control, 0 to 1, default 0\n\t\"Attack time (ms)\" Input, Control, 1.5 to 400, default 101.125\n\t\"Release time (ms)\" Input, Control, 2 to 800, default 401\n\t\"Threshold level (dB)\" Input, Control, -30 to 0, default 0\n\t\"Ratio (1:n)\" Input, Control, 1 to 20, default 1\n\t\"Knee radius (dB)\" Input, Control, 1 to 10, default 3.25\n\t\"Attenuation (dB)\" Input, Control, -24 to 0, default 0\n\t\"Amplitude (dB)\" Output, Control, -40 to 12\n\t\"Gain expansion (dB)\" Output, Control, 0 to 24\n\t\"Left input\" Input, Audio\n\t\"Right input\" Input, Audio\n\t\"Left output\" Output, Audio\n\t\"Right output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/shaper" : "Name: Wave shaper\nURI: http://plugin.org.uk/swh-plugins/shaper\nClass: Waveshaper\nAuthor: Steve Harris\nLatency: no\nPorts: \"Waveshape\" Input, Control, -10 to 10, default 0\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/sifter" : "Name: Signal sifter\nURI: http://plugin.org.uk/swh-plugins/sifter\nClass: Distortion\nAuthor: Steve Harris\nLatency: no\nPorts: \"Sift size\" Input, Control, 1 to 1000, default 1\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/sinCos" : "Name: Sine + cosine oscillator\nURI: http://plugin.org.uk/swh-plugins/sinCos\nClass: Oscillator\nAuthor: Steve Harris\nLatency: no\nPorts: \"Base frequency (Hz)\" Input, Control, 0.000001 to 0.5, default 440\n\t\"Pitch offset\" Input, Control, 0 to 8, default 0\n\t\"Sine output\" Output, Audio\n\t\"Cosine output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/singlePara" : "Name: Single band parametric\nURI: http://plugin.org.uk/swh-plugins/singlePara\nClass: Parametric\nAuthor: Steve Harris\nLatency: no\nPorts: \"Gain (dB)\" Input, Control, -70 to 30, default 0\n\t\"Frequency (Hz)\" Input, Control, 0 to 0.4, default 440\n\t\"Bandwidth (octaves)\" Input, Control, 0 to 4, default 1\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/sinusWavewrapper" : "Name: Sinus wavewrapper\nURI: http://plugin.org.uk/swh-plugins/sinusWavewrapper\nClass: Waveshaper\nAuthor: Steve Harris\nLatency: no\nPorts: \"Wrap degree\" Input, Control, 0 to 10, default 0\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/smoothDecimate" : "Name: Smooth Decimator\nURI: http://plugin.org.uk/swh-plugins/smoothDecimate\nClass: Distortion\nAuthor: Steve Harris\nLatency: no\nPorts: \"Resample rate\" Input, Control, 0 to 1, default 1\n\t\"Smoothing\" Input, Control, 0 to 1, default 1\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/split" : "Name: Mono to Stereo splitter\nURI: http://plugin.org.uk/swh-plugins/split\nClass: Converter\nAuthor: Steve Harris\nLatency: no\nPorts: \"Input\" Input, Audio\n\t\"Output 1\" Output, Audio\n\t\"Output 2\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/surroundEncoder" : "Name: Surround matrix encoder\nURI: http://plugin.org.uk/swh-plugins/surroundEncoder\nClass: Converter\nAuthor: Steve Harris\nLatency: no\nPorts: \"L\" Input, Audio\n\t\"R\" Input, Audio\n\t\"C\" Input, Audio\n\t\"S\" Input, Audio\n\t\"Lt\" Output, Audio\n\t\"Rt\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/svf" : "Name: State Variable Filter\nURI: http://plugin.org.uk/swh-plugins/svf\nClass: Filter\nAuthor: Steve Harris\nLatency: no\nPorts: \"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\t\"Filter type (0=none, 1=LP, 2=HP, 3=BP, 4=BR, 5=AP)\" Input, Control, 0 to 5, default 0\n\t\"Filter freq\" Input, Control, 0 to 6000, default 440\n\t\"Filter Q\" Input, Control, 0 to 1, default 0.25\n\t\"Filter resonance\" Input, Control, 0 to 1, default 0\n\n", "elv2:http://plugin.org.uk/swh-plugins/tapeDelay" : "Name: Tape Delay Simulation\nURI: http://plugin.org.uk/swh-plugins/tapeDelay\nClass: Delay\nAuthor: Steve Harris\nLatency: no\nPorts: \"Tape speed (inches/sec, 1=normal)\" Input, Control, 0 to 10, default 1\n\t\"Dry level (dB)\" Input, Control, -90 to 0, default -90\n\t\"Tap 1 distance (inches)\" Input, Control, 0 to 4, default 0\n\t\"Tap 1 level (dB)\" Input, Control, -90 to 0, default 0\n\t\"Tap 2 distance (inches)\" Input, Control, 0 to 4, default 1\n\t\"Tap 2 level (dB)\" Input, Control, -90 to 0, default -90\n\t\"Tap 3 distance (inches)\" Input, Control, 0 to 4, default 2\n\t\"Tap 3 level (dB)\" Input, Control, -90 to 0, default -90\n\t\"Tap 4 distance (inches)\" Input, Control, 0 to 4, default 3\n\t\"Tap 4 level (dB)\" Input, Control, -90 to 0, default -90\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/transient" : "Name: Transient mangler\nURI: http://plugin.org.uk/swh-plugins/transient\nClass: Dynamics\nAuthor: Steve Harris\nLatency: no\nPorts: \"Attack speed\" Input, Control, -1 to 1, default 0\n\t\"Sustain time\" Input, Control, -1 to 1, default 0\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/triplePara" : "Name: Triple band parametric with shelves\nURI: http://plugin.org.uk/swh-plugins/triplePara\nClass: Parametric\nAuthor: Steve Harris\nLatency: no\nPorts: \"Low-shelving gain (dB)\" Input, Control, -70 to 30, default 0\n\t\"Low-shelving frequency (Hz)\" Input, Control, 0.0001 to 0.49, default 0.0001\n\t\"Low-shelving slope\" Input, Control, 0 to 1, default 0.5\n\t\"Band 1 gain (dB)\" Input, Control, -70 to 30, default 0\n\t\"Band 1 frequency (Hz)\" Input, Control, 0.0001 to 0.49, default 0.122575\n\t\"Band 1 bandwidth (octaves)\" Input, Control, 0 to 4, default 1\n\t\"Band 2 gain (dB)\" Input, Control, -70 to 30, default 0\n\t\"Band 2 frequency (Hz)\" Input, Control, 0.0001 to 0.49, default 0.24505\n\t\"Band 2 bandwidth (octaves)\" Input, Control, 0 to 4, default 1\n\t\"Band 3 gain (dB)\" Input, Control, -70 to 30, default 0\n\t\"Band 3 frequency (Hz)\" Input, Control, 0.0001 to 0.49, default 0.367525\n\t\"Band 3 bandwidth (octaves)\" Input, Control, 0 to 4, default 1\n\t\"High-shelving gain (dB)\" Input, Control, -70 to 30, default 0\n\t\"High-shelving frequency (Hz)\" Input, Control, 0.0001 to 0.49, default 0.49\n\t\"High-shelving slope\" Input, Control, 0 to 1, default 0.5\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/ulaw" : "Name: μ-Law Compressor\nURI: http://plugin.org.uk/swh-plugins/ulaw\nClass: Dynamics\nAuthor: Steve Harris\nLatency: no\nPorts: \"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/valve" : "Name: Valve saturation\nURI: http://plugin.org.uk/swh-plugins/valve\nClass: Distortion\nAuthor: Steve Harris\nLatency: no\nPorts: \"Distortion level\" Input, Control, 0 to 1, default 0\n\t\"Distortion character\" Input, Control, 0 to 1, default 0\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/valveRect" : "Name: Valve rectifier\nURI: http://plugin.org.uk/swh-plugins/valveRect\nClass: Distortion\nAuthor: Steve Harris\nLatency: no\nPorts: \"Sag level\" Input, Control, 0 to 1, default 0\n\t\"Distortion\" Input, Control, 0 to 1, default 0\n\t\"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/vynil" : "Name: VyNil (Vinyl Effect)\nURI: http://plugin.org.uk/swh-plugins/vynil\nClass: Distortion\nAuthor: Steve Harris\nLatency: no\nPorts: \"Year\" Input, Control, 1900 to 1990, default 1990\n\t\"RPM\" Input, Control, 33 to 78, default 33\n\t\"Surface warping\" Input, Control, 0 to 1, default 0\n\t\"Crackle\" Input, Control, 0 to 1, default 0\n\t\"Wear\" Input, Control, 0 to 1, default 0\n\t\"Input L\" Input, Audio\n\t\"Input R\" Input, Audio\n\t\"Output L\" Output, Audio\n\t\"Output R\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/waveTerrain" : "Name: Wave Terrain Oscillator\nURI: http://plugin.org.uk/swh-plugins/waveTerrain\nClass: Oscillator\nAuthor: Steve Harris\nLatency: no\nPorts: \"x\" Input, Audio\n\t\"y\" Input, Audio\n\t\"z\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/xfade" : "Name: Crossfade\nURI: http://plugin.org.uk/swh-plugins/xfade\nClass: Mixer\nAuthor: Steve Harris\nLatency: no\nPorts: \"Crossfade\" Input, Control, -1 to 1, default 0\n\t\"Input A left\" Input, Audio\n\t\"Input A right\" Input, Audio\n\t\"Input B left\" Input, Audio\n\t\"Input B right\" Input, Audio\n\t\"Output left\" Output, Audio\n\t\"Output right\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/xfade4" : "Name: Crossfade (4 outs)\nURI: http://plugin.org.uk/swh-plugins/xfade4\nClass: Mixer\nAuthor: Steve Harris\nLatency: no\nPorts: \"Crossfade\" Input, Control, -1 to 1, default 0\n\t\"Input A left\" Input, Audio\n\t\"Input A right\" Input, Audio\n\t\"Input B left\" Input, Audio\n\t\"Input B right\" Input, Audio\n\t\"Output A left\" Output, Audio\n\t\"Output A right\" Output, Audio\n\t\"Output B left\" Output, Audio\n\t\"Output B right\" Output, Audio\n\n", "elv2:http://plugin.org.uk/swh-plugins/zm1" : "Name: z-1\nURI: http://plugin.org.uk/swh-plugins/zm1\nClass: Utility\nAuthor: Steve Harris\nLatency: no\nPorts: \"Input\" Input, Audio\n\t\"Output\" Output, Audio\n\n", "elv2:urn:50m30n3:plugins:SO-404" : "Name: SO-404 Bass Synthesizer\nURI: urn:50m30n3:plugins:SO-404\nClass: Instrument\nLatency: no\nPorts: \"Output\" Output, Audio\n\t\"MIDI Input\" Input, Midi\n\t\"Control Mode\" Input, Control, 2-way Selector\n\t\"Volume\" Input, Control, 0 to 127, default 100\n\t\"Filter Cutoff\" Input, Control, 0 to 127, default 50\n\t\"Filter Resonance\" Input, Control, 0 to 127, default 100\n\t\"Filter Envelope\" Input, Control, 0 to 127, default 80\n\t\"Portamento Time\" Input, Control, 0 to 127, default 64\n\t\"Release Time\" Input, Control, 0 to 127, default 100\n\t\"Midi Channel\" Input, Control, 0 to 16, default 0, 1-way Selector\n\n", "elv2:urn:50m30n3:plugins:SO-666" : "Name: SO-666 Feedback Synthesizer\nURI: urn:50m30n3:plugins:SO-666\nClass: Instrument\nLatency: no\nPorts: \"Output\" Output, Audio\n\t\"MIDI Input\" Input, Midi\n\t\"Control Mode\" Input, Control, 2-way Selector\n\t\"Feedback\" Input, Control, 0 to 1, default 0.25\n\t\"Filter Resonance\" Input, Control, 0 to 1, default 0.5\n\t\"Filter Cutoff\" Input, Control, 0.25 to 0.885, default 0.57\n\t\"Volume\" Input, Control, 0 to 127, default 100\n\t\"Midi Channel\" Input, Control, 0 to 16, default 0, 1-way Selector\n\n", "elv2:urn:50m30n3:plugins:SO-kl5" : "Name: SO-kl5 Piano Synthesizer\nURI: urn:50m30n3:plugins:SO-kl5\nClass: Instrument\nLatency: no\nPorts: \"Output\" Output, Audio\n\t\"MIDI Input\" Input, Midi\n\t\"Control Mode\" Input, Control, 2-way Selector\n\t\"Sustain\" Input, Control, 0 to 1, default 0\n\t\"Filter Resonance\" Input, Control, 0 to 0.907, default 0.625\n\t\"Filter Cutoff\" Input, Control, 0.0125 to 0.3333, default 0.1725\n\t\"Attack\" Input, Control, 0.00625 to 0.165, default 0.01125\n\t\"Volume\" Input, Control, 0 to 127, default 100\n\t\"Midi Channel\" Input, Control, 0 to 16, default 0, 1-way Selector\n\n" }, "partial_label_to_full" : { "chcopy" : "chcopy", "chmix" : "chmix", "chmove" : "chmove", "chmute" : "chmute", "chorder" : "chorder", "eS" : "eS", "ea" : "ea", "eac" : "eac", "eadb" : "eadb", "eal" : "eal", "eaw" : "eaw", "ec" : "ec", "eca" : "eca", "eemb" : "eemb", "eemp" : "eemp", "eemt" : "eemt", "ef1" : "ef1", "ef3" : "ef3", "ef4" : "ef4", "efa" : "efa", "efb" : "efb", "efc" : "efc", "efh" : "efh", "efi" : "efi", "efl" : "efl", "efr" : "efr", "efs" : "efs", "ei" : "ei", "el:Ambisonics-11-cube-decoder" : "el:Ambisonics-11-cube-decoder", "el:Ambisonics-11-hexagon-decoder" : "el:Ambisonics-11-hexagon-decoder", "el:Ambisonics-11-mono-panner" : "el:Ambisonics-11-mono-panner", "el:Ambisonics-11-rotator" : "el:Ambisonics-11-rotator", "el:Ambisonics-11-square-decoder" : "el:Ambisonics-11-square-decoder", "el:Ambisonics-11-stereo-panner" : "el:Ambisonics-11-stereo-panner", "el:Ambisonics-21-panner" : "el:Ambisonics-21-panner", "el:Ambisonics-21-rotator" : "el:Ambisonics-21-rotator", "el:Ambisonics-22-panner" : "el:Ambisonics-22-panner", "el:Ambisonics-22-rotator" : "el:Ambisonics-22-rotator", "el:Ambisonics-31-panner" : "el:Ambisonics-31-panner", "el:Ambisonics-31-rotator" : "el:Ambisonics-31-rotator", "el:Ambisonics-33-panner" : "el:Ambisonics-33-panner", "el:Ambisonics-33-rotator" : "el:Ambisonics-33-rotator", "el:AmpVTS" : "el:AmpVTS", "el:AutoFilter" : "el:AutoFilter", "el:CEO" : "el:CEO", "el:CabinetIV" : "el:CabinetIV", "el:ChorusI" : "el:ChorusI", "el:Click" : "el:Click", "el:Compress" : "el:Compress", "el:CompressX2" : "el:CompressX2", "el:Eq10" : "el:Eq10", "el:Eq10X2" : "el:Eq10X2", "el:Eq4p" : "el:Eq4p", "el:Fractal" : "el:Fractal", "el:G2reverb" : "el:G2reverb", "el:Narrower" : "el:Narrower", "el:NoiseGate" : "el:NoiseGate", "el:Parametric1" : "el:Parametric1", "el:PhaserII" : "el:PhaserII", "el:Plate" : "el:Plate", "el:PlateX2" : "el:PlateX2", "el:Saturate" : "el:Saturate", "el:Scape" : "el:Scape", "el:Sin" : "el:Sin", "el:Spice" : "el:Spice", "el:SpiceX2" : "el:SpiceX2", "el:ToneStack" : "el:ToneStack", "el:Tricardioid-to-AMB" : "el:Tricardioid-to-AMB", "el:UHJ-decoder" : "el:UHJ-decoder", "el:UHJ-encoder" : "el:UHJ-encoder", "el:Virtualmic" : "el:Virtualmic", "el:White" : "el:White", "el:Wider" : "el:Wider", "el:alias" : "el:alias", "el:allpass_c" : "el:allpass_c", "el:allpass_l" : "el:allpass_l", "el:allpass_n" : "el:allpass_n", "el:amPitchshift" : "el:amPitchshift", "el:amp" : "el:amp", "el:amp_mono" : "el:amp_mono", "el:amp_stereo" : "el:amp_stereo", "el:analogueOsc" : "el:analogueOsc", "el:artificialLatency" : "el:artificialLatency", "el:autoPhaser" : "el:autoPhaser", "el:bandpass_a_iir" : "el:bandpass_a_iir", "el:bandpass_iir" : "el:bandpass_iir", "el:bodeShifter" : "el:bodeShifter", "el:bodeShifterCV" : "el:bodeShifterCV", "el:butthigh_iir" : "el:butthigh_iir", "el:buttlow_iir" : "el:buttlow_iir", "el:bwxover_iir" : "el:bwxover_iir", "el:chebstortion" : "el:chebstortion", "el:comb" : "el:comb", "el:combSplitter" : "el:combSplitter", "el:comb_c" : "el:comb_c", "el:comb_l" : "el:comb_l", "el:comb_n" : "el:comb_n", "el:const" : "el:const", "el:crossoverDist" : "el:crossoverDist", "el:dcRemove" : "el:dcRemove", "el:decay" : "el:decay", "el:decimator" : "el:decimator", "el:declip" : "el:declip", "el:delay_5s" : "el:delay_5s", "el:delay_c" : "el:delay_c", "el:delay_l" : "el:delay_l", "el:delay_n" : "el:delay_n", "el:delayorama" : "el:delayorama", "el:diode" : "el:diode", "el:divider" : "el:divider", "el:djFlanger" : "el:djFlanger", "el:dj_eq" : "el:dj_eq", "el:dj_eq_mono" : "el:dj_eq_mono", "el:dysonCompress" : "el:dysonCompress", "el:fadDelay" : "el:fadDelay", "el:fastLookaheadLimiter" : "el:fastLookaheadLimiter", "el:flanger" : "el:flanger", "el:fmOsc" : "el:fmOsc", "el:foldover" : "el:foldover", "el:fourByFourPole" : "el:fourByFourPole", "el:foverdrive" : "el:foverdrive", "el:freqTracker" : "el:freqTracker", "el:gate" : "el:gate", "el:giantFlange" : "el:giantFlange", "el:gong" : "el:gong", "el:gongBeater" : "el:gongBeater", "el:gsm" : "el:gsm", "el:gverb" : "el:gverb", "el:hardLimiter" : "el:hardLimiter", "el:harmonicGen" : "el:harmonicGen", "el:hermesFilter" : "el:hermesFilter", "el:highpass_iir" : "el:highpass_iir", "el:hilbert" : "el:hilbert", "el:hpf" : "el:hpf", "el:imp" : "el:imp", "el:impulse_fc" : "el:impulse_fc", "el:inv" : "el:inv", "el:invada_hp_mono_filter_module_0_1" : "el:invada_hp_mono_filter_module_0_1", "el:invada_hp_stereo_filter_module_0_1" : "el:invada_hp_stereo_filter_module_0_1", "el:invada_lp_mono_filter_module_0_1" : "el:invada_lp_mono_filter_module_0_1", "el:invada_lp_stereo_filter_module_0_1" : "el:invada_lp_stereo_filter_module_0_1", "el:invada_mono_compressor_module_0_1" : "el:invada_mono_compressor_module_0_1", "el:invada_mono_reverbER_module_0_1" : "el:invada_mono_reverbER_module_0_1", "el:invada_mono_tube_module_0_1" : "el:invada_mono_tube_module_0_1", "el:invada_stereo_compressor_module_0_1" : "el:invada_stereo_compressor_module_0_1", "el:invada_stereo_input_module_0_1" : "el:invada_stereo_input_module_0_1", "el:invada_stereo_tube_module_0_1" : "el:invada_stereo_tube_module_0_1", "el:invada_sum_reverbER_module_0_1" : "el:invada_sum_reverbER_module_0_1", "el:karaoke" : "el:karaoke", "el:lcrDelay" : "el:lcrDelay", "el:lfoPhaser" : "el:lfoPhaser", "el:lowpass_iir" : "el:lowpass_iir", "el:lpf" : "el:lpf", "el:lsFilter" : "el:lsFilter", "el:matrixMSSt" : "el:matrixMSSt", "el:matrixSpatialiser" : "el:matrixSpatialiser", "el:matrixStMS" : "el:matrixStMS", "el:mbeq" : "el:mbeq", "el:modDelay" : "el:modDelay", "el:multivoiceChorus" : "el:multivoiceChorus", "el:noise_white" : "el:noise_white", "el:notch_iir" : "el:notch_iir", "el:pitchScale" : "el:pitchScale", "el:pitchScaleHQ" : "el:pitchScaleHQ", "el:plate" : "el:plate", "el:pointerCastDistortion" : "el:pointerCastDistortion", "el:rateShifter" : "el:rateShifter", "el:retroFlange" : "el:retroFlange", "el:revdelay" : "el:revdelay", "el:ringmod_1i1o1l" : "el:ringmod_1i1o1l", "el:ringmod_2i1o" : "el:ringmod_2i1o", "el:satanMaximiser" : "el:satanMaximiser", "el:sc1" : "el:sc1", "el:sc2" : "el:sc2", "el:sc3" : "el:sc3", "el:sc4" : "el:sc4", "el:sc4m" : "el:sc4m", "el:se4" : "el:se4", "el:shaper" : "el:shaper", "el:sifter" : "el:sifter", "el:sinCos" : "el:sinCos", "el:sine_faaa" : "el:sine_faaa", "el:sine_faac" : "el:sine_faac", "el:sine_fcaa" : "el:sine_fcaa", "el:sine_fcac" : "el:sine_fcac", "el:singlePara" : "el:singlePara", "el:sinusWavewrapper" : "el:sinusWavewrapper", "el:smoothDecimate" : "el:smoothDecimate", "el:split" : "el:split", "el:stepMuxer" : "el:stepMuxer", "el:surroundEncoder" : "el:surroundEncoder", "el:svf" : "el:svf", "el:tap_autopan" : "el:tap_autopan", "el:tap_chorusflanger" : "el:tap_chorusflanger", "el:tap_deesser" : "el:tap_deesser", "el:tap_doubler" : "el:tap_doubler", "el:tap_dynamics_m" : "el:tap_dynamics_m", "el:tap_dynamics_st" : "el:tap_dynamics_st", "el:tap_equalizer" : "el:tap_equalizer", "el:tap_equalizer_bw" : "el:tap_equalizer_bw", "el:tap_limiter" : "el:tap_limiter", "el:tap_pinknoise" : "el:tap_pinknoise", "el:tap_pitch" : "el:tap_pitch", "el:tap_reflector" : "el:tap_reflector", "el:tap_reverb" : "el:tap_reverb", "el:tap_rotspeak" : "el:tap_rotspeak", "el:tap_sigmoid" : "el:tap_sigmoid", "el:tap_stereo_echo" : "el:tap_stereo_echo", "el:tap_tremolo" : "el:tap_tremolo", "el:tap_tubewarmth" : "el:tap_tubewarmth", "el:tap_vibrato" : "el:tap_vibrato", "el:tapeDelay" : "el:tapeDelay", "el:transient" : "el:transient", "el:triplePara" : "el:triplePara", "el:valve" : "el:valve", "el:valveRect" : "el:valveRect", "el:vynil" : "el:vynil", "el:waveTerrain" : "el:waveTerrain", "el:xfade" : "el:xfade", "el:xfade4" : "el:xfade4", "el:zita-reverb" : "el:zita-reverb", "el:zita-reverb-amb" : "el:zita-reverb-amb", "el:zm1" : "el:zm1", "elv2:http://gareus.org/oss/lv2/b_overdrive" : "elv2:http://gareus.org/oss/lv2/b_overdrive", "elv2:http://gareus.org/oss/lv2/b_reverb" : "elv2:http://gareus.org/oss/lv2/b_reverb", "elv2:http://gareus.org/oss/lv2/b_whirl#extended" : "elv2:http://gareus.org/oss/lv2/b_whirl#extended", "elv2:http://gareus.org/oss/lv2/b_whirl#simple" : "elv2:http://gareus.org/oss/lv2/b_whirl#simple", "elv2:http://hyperglitch.com/dev/VocProc" : "elv2:http://hyperglitch.com/dev/VocProc", "elv2:http://plugin.org.uk/swh-plugins/alaw" : "elv2:http://plugin.org.uk/swh-plugins/alaw", "elv2:http://plugin.org.uk/swh-plugins/alias" : "elv2:http://plugin.org.uk/swh-plugins/alias", "elv2:http://plugin.org.uk/swh-plugins/allpass_c" : "elv2:http://plugin.org.uk/swh-plugins/allpass_c", "elv2:http://plugin.org.uk/swh-plugins/allpass_l" : "elv2:http://plugin.org.uk/swh-plugins/allpass_l", "elv2:http://plugin.org.uk/swh-plugins/allpass_n" : "elv2:http://plugin.org.uk/swh-plugins/allpass_n", "elv2:http://plugin.org.uk/swh-plugins/amPitchshift" : "elv2:http://plugin.org.uk/swh-plugins/amPitchshift", "elv2:http://plugin.org.uk/swh-plugins/amp" : "elv2:http://plugin.org.uk/swh-plugins/amp", "elv2:http://plugin.org.uk/swh-plugins/analogueOsc" : "elv2:http://plugin.org.uk/swh-plugins/analogueOsc", "elv2:http://plugin.org.uk/swh-plugins/artificialLatency" : "elv2:http://plugin.org.uk/swh-plugins/artificialLatency", "elv2:http://plugin.org.uk/swh-plugins/autoPhaser" : "elv2:http://plugin.org.uk/swh-plugins/autoPhaser", "elv2:http://plugin.org.uk/swh-plugins/bandpass_a_iir" : "elv2:http://plugin.org.uk/swh-plugins/bandpass_a_iir", "elv2:http://plugin.org.uk/swh-plugins/bandpass_iir" : "elv2:http://plugin.org.uk/swh-plugins/bandpass_iir", "elv2:http://plugin.org.uk/swh-plugins/bodeShifter" : "elv2:http://plugin.org.uk/swh-plugins/bodeShifter", "elv2:http://plugin.org.uk/swh-plugins/bodeShifterCV" : "elv2:http://plugin.org.uk/swh-plugins/bodeShifterCV", "elv2:http://plugin.org.uk/swh-plugins/butthigh_iir" : "elv2:http://plugin.org.uk/swh-plugins/butthigh_iir", "elv2:http://plugin.org.uk/swh-plugins/buttlow_iir" : "elv2:http://plugin.org.uk/swh-plugins/buttlow_iir", "elv2:http://plugin.org.uk/swh-plugins/bwxover_iir" : "elv2:http://plugin.org.uk/swh-plugins/bwxover_iir", "elv2:http://plugin.org.uk/swh-plugins/chebstortion" : "elv2:http://plugin.org.uk/swh-plugins/chebstortion", "elv2:http://plugin.org.uk/swh-plugins/comb" : "elv2:http://plugin.org.uk/swh-plugins/comb", "elv2:http://plugin.org.uk/swh-plugins/combSplitter" : "elv2:http://plugin.org.uk/swh-plugins/combSplitter", "elv2:http://plugin.org.uk/swh-plugins/comb_c" : "elv2:http://plugin.org.uk/swh-plugins/comb_c", "elv2:http://plugin.org.uk/swh-plugins/comb_l" : "elv2:http://plugin.org.uk/swh-plugins/comb_l", "elv2:http://plugin.org.uk/swh-plugins/comb_n" : "elv2:http://plugin.org.uk/swh-plugins/comb_n", "elv2:http://plugin.org.uk/swh-plugins/const" : "elv2:http://plugin.org.uk/swh-plugins/const", "elv2:http://plugin.org.uk/swh-plugins/crossoverDist" : "elv2:http://plugin.org.uk/swh-plugins/crossoverDist", "elv2:http://plugin.org.uk/swh-plugins/dcRemove" : "elv2:http://plugin.org.uk/swh-plugins/dcRemove", "elv2:http://plugin.org.uk/swh-plugins/decay" : "elv2:http://plugin.org.uk/swh-plugins/decay", "elv2:http://plugin.org.uk/swh-plugins/decimator" : "elv2:http://plugin.org.uk/swh-plugins/decimator", "elv2:http://plugin.org.uk/swh-plugins/declip" : "elv2:http://plugin.org.uk/swh-plugins/declip", "elv2:http://plugin.org.uk/swh-plugins/delay_c" : "elv2:http://plugin.org.uk/swh-plugins/delay_c", "elv2:http://plugin.org.uk/swh-plugins/delay_l" : "elv2:http://plugin.org.uk/swh-plugins/delay_l", "elv2:http://plugin.org.uk/swh-plugins/delay_n" : "elv2:http://plugin.org.uk/swh-plugins/delay_n", "elv2:http://plugin.org.uk/swh-plugins/delayorama" : "elv2:http://plugin.org.uk/swh-plugins/delayorama", "elv2:http://plugin.org.uk/swh-plugins/diode" : "elv2:http://plugin.org.uk/swh-plugins/diode", "elv2:http://plugin.org.uk/swh-plugins/divider" : "elv2:http://plugin.org.uk/swh-plugins/divider", "elv2:http://plugin.org.uk/swh-plugins/djFlanger" : "elv2:http://plugin.org.uk/swh-plugins/djFlanger", "elv2:http://plugin.org.uk/swh-plugins/dj_eq" : "elv2:http://plugin.org.uk/swh-plugins/dj_eq", "elv2:http://plugin.org.uk/swh-plugins/dj_eq_mono" : "elv2:http://plugin.org.uk/swh-plugins/dj_eq_mono", "elv2:http://plugin.org.uk/swh-plugins/dysonCompress" : "elv2:http://plugin.org.uk/swh-plugins/dysonCompress", "elv2:http://plugin.org.uk/swh-plugins/fadDelay" : "elv2:http://plugin.org.uk/swh-plugins/fadDelay", "elv2:http://plugin.org.uk/swh-plugins/fastLookaheadLimiter" : "elv2:http://plugin.org.uk/swh-plugins/fastLookaheadLimiter", "elv2:http://plugin.org.uk/swh-plugins/flanger" : "elv2:http://plugin.org.uk/swh-plugins/flanger", "elv2:http://plugin.org.uk/swh-plugins/fmOsc" : "elv2:http://plugin.org.uk/swh-plugins/fmOsc", "elv2:http://plugin.org.uk/swh-plugins/foldover" : "elv2:http://plugin.org.uk/swh-plugins/foldover", "elv2:http://plugin.org.uk/swh-plugins/fourByFourPole" : "elv2:http://plugin.org.uk/swh-plugins/fourByFourPole", "elv2:http://plugin.org.uk/swh-plugins/foverdrive" : "elv2:http://plugin.org.uk/swh-plugins/foverdrive", "elv2:http://plugin.org.uk/swh-plugins/freqTracker" : "elv2:http://plugin.org.uk/swh-plugins/freqTracker", "elv2:http://plugin.org.uk/swh-plugins/gate" : "elv2:http://plugin.org.uk/swh-plugins/gate", "elv2:http://plugin.org.uk/swh-plugins/giantFlange" : "elv2:http://plugin.org.uk/swh-plugins/giantFlange", "elv2:http://plugin.org.uk/swh-plugins/gong" : "elv2:http://plugin.org.uk/swh-plugins/gong", "elv2:http://plugin.org.uk/swh-plugins/gongBeater" : "elv2:http://plugin.org.uk/swh-plugins/gongBeater", "elv2:http://plugin.org.uk/swh-plugins/gverb" : "elv2:http://plugin.org.uk/swh-plugins/gverb", "elv2:http://plugin.org.uk/swh-plugins/hardLimiter" : "elv2:http://plugin.org.uk/swh-plugins/hardLimiter", "elv2:http://plugin.org.uk/swh-plugins/harmonicGen" : "elv2:http://plugin.org.uk/swh-plugins/harmonicGen", "elv2:http://plugin.org.uk/swh-plugins/hermesFilter" : "elv2:http://plugin.org.uk/swh-plugins/hermesFilter", "elv2:http://plugin.org.uk/swh-plugins/highpass_iir" : "elv2:http://plugin.org.uk/swh-plugins/highpass_iir", "elv2:http://plugin.org.uk/swh-plugins/hilbert" : "elv2:http://plugin.org.uk/swh-plugins/hilbert", "elv2:http://plugin.org.uk/swh-plugins/impulse_fc" : "elv2:http://plugin.org.uk/swh-plugins/impulse_fc", "elv2:http://plugin.org.uk/swh-plugins/inv" : "elv2:http://plugin.org.uk/swh-plugins/inv", "elv2:http://plugin.org.uk/swh-plugins/karaoke" : "elv2:http://plugin.org.uk/swh-plugins/karaoke", "elv2:http://plugin.org.uk/swh-plugins/lcrDelay" : "elv2:http://plugin.org.uk/swh-plugins/lcrDelay", "elv2:http://plugin.org.uk/swh-plugins/lfoPhaser" : "elv2:http://plugin.org.uk/swh-plugins/lfoPhaser", "elv2:http://plugin.org.uk/swh-plugins/lookaheadLimiter" : "elv2:http://plugin.org.uk/swh-plugins/lookaheadLimiter", "elv2:http://plugin.org.uk/swh-plugins/lookaheadLimiterConst" : "elv2:http://plugin.org.uk/swh-plugins/lookaheadLimiterConst", "elv2:http://plugin.org.uk/swh-plugins/lowpass_iir" : "elv2:http://plugin.org.uk/swh-plugins/lowpass_iir", "elv2:http://plugin.org.uk/swh-plugins/lsFilter" : "elv2:http://plugin.org.uk/swh-plugins/lsFilter", "elv2:http://plugin.org.uk/swh-plugins/matrixMSSt" : "elv2:http://plugin.org.uk/swh-plugins/matrixMSSt", "elv2:http://plugin.org.uk/swh-plugins/matrixSpatialiser" : "elv2:http://plugin.org.uk/swh-plugins/matrixSpatialiser", "elv2:http://plugin.org.uk/swh-plugins/matrixStMS" : "elv2:http://plugin.org.uk/swh-plugins/matrixStMS", "elv2:http://plugin.org.uk/swh-plugins/mbeq" : "elv2:http://plugin.org.uk/swh-plugins/mbeq", "elv2:http://plugin.org.uk/swh-plugins/modDelay" : "elv2:http://plugin.org.uk/swh-plugins/modDelay", "elv2:http://plugin.org.uk/swh-plugins/multivoiceChorus" : "elv2:http://plugin.org.uk/swh-plugins/multivoiceChorus", "elv2:http://plugin.org.uk/swh-plugins/pitchScaleHQ" : "elv2:http://plugin.org.uk/swh-plugins/pitchScaleHQ", "elv2:http://plugin.org.uk/swh-plugins/plate" : "elv2:http://plugin.org.uk/swh-plugins/plate", "elv2:http://plugin.org.uk/swh-plugins/pointerCastDistortion" : "elv2:http://plugin.org.uk/swh-plugins/pointerCastDistortion", "elv2:http://plugin.org.uk/swh-plugins/rateShifter" : "elv2:http://plugin.org.uk/swh-plugins/rateShifter", "elv2:http://plugin.org.uk/swh-plugins/retroFlange" : "elv2:http://plugin.org.uk/swh-plugins/retroFlange", "elv2:http://plugin.org.uk/swh-plugins/revdelay" : "elv2:http://plugin.org.uk/swh-plugins/revdelay", "elv2:http://plugin.org.uk/swh-plugins/ringmod_1i1o1l" : "elv2:http://plugin.org.uk/swh-plugins/ringmod_1i1o1l", "elv2:http://plugin.org.uk/swh-plugins/ringmod_2i1o" : "elv2:http://plugin.org.uk/swh-plugins/ringmod_2i1o", "elv2:http://plugin.org.uk/swh-plugins/satanMaximiser" : "elv2:http://plugin.org.uk/swh-plugins/satanMaximiser", "elv2:http://plugin.org.uk/swh-plugins/sc1" : "elv2:http://plugin.org.uk/swh-plugins/sc1", "elv2:http://plugin.org.uk/swh-plugins/sc2" : "elv2:http://plugin.org.uk/swh-plugins/sc2", "elv2:http://plugin.org.uk/swh-plugins/sc3" : "elv2:http://plugin.org.uk/swh-plugins/sc3", "elv2:http://plugin.org.uk/swh-plugins/sc4" : "elv2:http://plugin.org.uk/swh-plugins/sc4", "elv2:http://plugin.org.uk/swh-plugins/se4" : "elv2:http://plugin.org.uk/swh-plugins/se4", "elv2:http://plugin.org.uk/swh-plugins/shaper" : "elv2:http://plugin.org.uk/swh-plugins/shaper", "elv2:http://plugin.org.uk/swh-plugins/sifter" : "elv2:http://plugin.org.uk/swh-plugins/sifter", "elv2:http://plugin.org.uk/swh-plugins/sinCos" : "elv2:http://plugin.org.uk/swh-plugins/sinCos", "elv2:http://plugin.org.uk/swh-plugins/singlePara" : "elv2:http://plugin.org.uk/swh-plugins/singlePara", "elv2:http://plugin.org.uk/swh-plugins/sinusWavewrapper" : "elv2:http://plugin.org.uk/swh-plugins/sinusWavewrapper", "elv2:http://plugin.org.uk/swh-plugins/smoothDecimate" : "elv2:http://plugin.org.uk/swh-plugins/smoothDecimate", "elv2:http://plugin.org.uk/swh-plugins/split" : "elv2:http://plugin.org.uk/swh-plugins/split", "elv2:http://plugin.org.uk/swh-plugins/surroundEncoder" : "elv2:http://plugin.org.uk/swh-plugins/surroundEncoder", "elv2:http://plugin.org.uk/swh-plugins/svf" : "elv2:http://plugin.org.uk/swh-plugins/svf", "elv2:http://plugin.org.uk/swh-plugins/tapeDelay" : "elv2:http://plugin.org.uk/swh-plugins/tapeDelay", "elv2:http://plugin.org.uk/swh-plugins/transient" : "elv2:http://plugin.org.uk/swh-plugins/transient", "elv2:http://plugin.org.uk/swh-plugins/triplePara" : "elv2:http://plugin.org.uk/swh-plugins/triplePara", "elv2:http://plugin.org.uk/swh-plugins/ulaw" : "elv2:http://plugin.org.uk/swh-plugins/ulaw", "elv2:http://plugin.org.uk/swh-plugins/valve" : "elv2:http://plugin.org.uk/swh-plugins/valve", "elv2:http://plugin.org.uk/swh-plugins/valveRect" : "elv2:http://plugin.org.uk/swh-plugins/valveRect", "elv2:http://plugin.org.uk/swh-plugins/vynil" : "elv2:http://plugin.org.uk/swh-plugins/vynil", "elv2:http://plugin.org.uk/swh-plugins/waveTerrain" : "elv2:http://plugin.org.uk/swh-plugins/waveTerrain", "elv2:http://plugin.org.uk/swh-plugins/xfade" : "elv2:http://plugin.org.uk/swh-plugins/xfade", "elv2:http://plugin.org.uk/swh-plugins/xfade4" : "elv2:http://plugin.org.uk/swh-plugins/xfade4", "elv2:http://plugin.org.uk/swh-plugins/zm1" : "elv2:http://plugin.org.uk/swh-plugins/zm1", "enm" : "enm", "epp" : "epp", "erc" : "erc", "erm" : "erm", "etc" : "etc", "etd" : "etd", "ete" : "ete", "etf" : "etf", "etl" : "etl", "etm" : "etm", "etp" : "etp", "etr" : "etr", "ev" : "ev", "evp" : "evp", "ezf" : "ezf", "ezx" : "ezx", "gc" : "gc", "ge" : "ge", "gm" : "gm", "kf" : "kf", "kl" : "kl", "kl2" : "kl2", "klg" : "klg", "km" : "km", "kog" : "kog", "kos" : "kos", "ksv" : "ksv", "lv2-VocProc" : "elv2:http://hyperglitch.com/dev/VocProc", "lv2-alaw" : "elv2:http://plugin.org.uk/swh-plugins/alaw", "lv2-alias" : "elv2:http://plugin.org.uk/swh-plugins/alias", "lv2-allpass_c" : "elv2:http://plugin.org.uk/swh-plugins/allpass_c", "lv2-allpass_l" : "elv2:http://plugin.org.uk/swh-plugins/allpass_l", "lv2-allpass_n" : "elv2:http://plugin.org.uk/swh-plugins/allpass_n", "lv2-amPitchshift" : "elv2:http://plugin.org.uk/swh-plugins/amPitchshift", "lv2-amp" : "elv2:http://plugin.org.uk/swh-plugins/amp", "lv2-analogueOsc" : "elv2:http://plugin.org.uk/swh-plugins/analogueOsc", "lv2-artificialLatency" : "elv2:http://plugin.org.uk/swh-plugins/artificialLatency", "lv2-autoPhaser" : "elv2:http://plugin.org.uk/swh-plugins/autoPhaser", "lv2-b_overdrive" : "elv2:http://gareus.org/oss/lv2/b_overdrive", "lv2-b_reverb" : "elv2:http://gareus.org/oss/lv2/b_reverb", "lv2-b_whirl#extended" : "elv2:http://gareus.org/oss/lv2/b_whirl#extended", "lv2-b_whirl#simple" : "elv2:http://gareus.org/oss/lv2/b_whirl#simple", "lv2-bandpass_a_iir" : "elv2:http://plugin.org.uk/swh-plugins/bandpass_a_iir", "lv2-bandpass_iir" : "elv2:http://plugin.org.uk/swh-plugins/bandpass_iir", "lv2-bodeShifter" : "elv2:http://plugin.org.uk/swh-plugins/bodeShifter", "lv2-bodeShifterCV" : "elv2:http://plugin.org.uk/swh-plugins/bodeShifterCV", "lv2-butthigh_iir" : "elv2:http://plugin.org.uk/swh-plugins/butthigh_iir", "lv2-buttlow_iir" : "elv2:http://plugin.org.uk/swh-plugins/buttlow_iir", "lv2-bwxover_iir" : "elv2:http://plugin.org.uk/swh-plugins/bwxover_iir", "lv2-chebstortion" : "elv2:http://plugin.org.uk/swh-plugins/chebstortion", "lv2-comb" : "elv2:http://plugin.org.uk/swh-plugins/comb", "lv2-combSplitter" : "elv2:http://plugin.org.uk/swh-plugins/combSplitter", "lv2-comb_c" : "elv2:http://plugin.org.uk/swh-plugins/comb_c", "lv2-comb_l" : "elv2:http://plugin.org.uk/swh-plugins/comb_l", "lv2-comb_n" : "elv2:http://plugin.org.uk/swh-plugins/comb_n", "lv2-const" : "elv2:http://plugin.org.uk/swh-plugins/const", "lv2-crossoverDist" : "elv2:http://plugin.org.uk/swh-plugins/crossoverDist", "lv2-dcRemove" : "elv2:http://plugin.org.uk/swh-plugins/dcRemove", "lv2-decay" : "elv2:http://plugin.org.uk/swh-plugins/decay", "lv2-decimator" : "elv2:http://plugin.org.uk/swh-plugins/decimator", "lv2-declip" : "elv2:http://plugin.org.uk/swh-plugins/declip", "lv2-delay_c" : "elv2:http://plugin.org.uk/swh-plugins/delay_c", "lv2-delay_l" : "elv2:http://plugin.org.uk/swh-plugins/delay_l", "lv2-delay_n" : "elv2:http://plugin.org.uk/swh-plugins/delay_n", "lv2-delayorama" : "elv2:http://plugin.org.uk/swh-plugins/delayorama", "lv2-diode" : "elv2:http://plugin.org.uk/swh-plugins/diode", "lv2-divider" : "elv2:http://plugin.org.uk/swh-plugins/divider", "lv2-djFlanger" : "elv2:http://plugin.org.uk/swh-plugins/djFlanger", "lv2-dj_eq" : "elv2:http://plugin.org.uk/swh-plugins/dj_eq", "lv2-dj_eq_mono" : "elv2:http://plugin.org.uk/swh-plugins/dj_eq_mono", "lv2-dysonCompress" : "elv2:http://plugin.org.uk/swh-plugins/dysonCompress", "lv2-fadDelay" : "elv2:http://plugin.org.uk/swh-plugins/fadDelay", "lv2-fastLookaheadLimiter" : "elv2:http://plugin.org.uk/swh-plugins/fastLookaheadLimiter", "lv2-flanger" : "elv2:http://plugin.org.uk/swh-plugins/flanger", "lv2-fmOsc" : "elv2:http://plugin.org.uk/swh-plugins/fmOsc", "lv2-foldover" : "elv2:http://plugin.org.uk/swh-plugins/foldover", "lv2-fourByFourPole" : "elv2:http://plugin.org.uk/swh-plugins/fourByFourPole", "lv2-foverdrive" : "elv2:http://plugin.org.uk/swh-plugins/foverdrive", "lv2-freqTracker" : "elv2:http://plugin.org.uk/swh-plugins/freqTracker", "lv2-gate" : "elv2:http://plugin.org.uk/swh-plugins/gate", "lv2-giantFlange" : "elv2:http://plugin.org.uk/swh-plugins/giantFlange", "lv2-gong" : "elv2:http://plugin.org.uk/swh-plugins/gong", "lv2-gongBeater" : "elv2:http://plugin.org.uk/swh-plugins/gongBeater", "lv2-gverb" : "elv2:http://plugin.org.uk/swh-plugins/gverb", "lv2-hardLimiter" : "elv2:http://plugin.org.uk/swh-plugins/hardLimiter", "lv2-harmonicGen" : "elv2:http://plugin.org.uk/swh-plugins/harmonicGen", "lv2-hermesFilter" : "elv2:http://plugin.org.uk/swh-plugins/hermesFilter", "lv2-highpass_iir" : "elv2:http://plugin.org.uk/swh-plugins/highpass_iir", "lv2-hilbert" : "elv2:http://plugin.org.uk/swh-plugins/hilbert", "lv2-impulse_fc" : "elv2:http://plugin.org.uk/swh-plugins/impulse_fc", "lv2-inv" : "elv2:http://plugin.org.uk/swh-plugins/inv", "lv2-karaoke" : "elv2:http://plugin.org.uk/swh-plugins/karaoke", "lv2-lcrDelay" : "elv2:http://plugin.org.uk/swh-plugins/lcrDelay", "lv2-lfoPhaser" : "elv2:http://plugin.org.uk/swh-plugins/lfoPhaser", "lv2-lookaheadLimiter" : "elv2:http://plugin.org.uk/swh-plugins/lookaheadLimiter", "lv2-lookaheadLimiterConst" : "elv2:http://plugin.org.uk/swh-plugins/lookaheadLimiterConst", "lv2-lowpass_iir" : "elv2:http://plugin.org.uk/swh-plugins/lowpass_iir", "lv2-lsFilter" : "elv2:http://plugin.org.uk/swh-plugins/lsFilter", "lv2-matrixMSSt" : "elv2:http://plugin.org.uk/swh-plugins/matrixMSSt", "lv2-matrixSpatialiser" : "elv2:http://plugin.org.uk/swh-plugins/matrixSpatialiser", "lv2-matrixStMS" : "elv2:http://plugin.org.uk/swh-plugins/matrixStMS", "lv2-mbeq" : "elv2:http://plugin.org.uk/swh-plugins/mbeq", "lv2-modDelay" : "elv2:http://plugin.org.uk/swh-plugins/modDelay", "lv2-multivoiceChorus" : "elv2:http://plugin.org.uk/swh-plugins/multivoiceChorus", "lv2-pitchScaleHQ" : "elv2:http://plugin.org.uk/swh-plugins/pitchScaleHQ", "lv2-plate" : "elv2:http://plugin.org.uk/swh-plugins/plate", "lv2-pointerCastDistortion" : "elv2:http://plugin.org.uk/swh-plugins/pointerCastDistortion", "lv2-rateShifter" : "elv2:http://plugin.org.uk/swh-plugins/rateShifter", "lv2-retroFlange" : "elv2:http://plugin.org.uk/swh-plugins/retroFlange", "lv2-revdelay" : "elv2:http://plugin.org.uk/swh-plugins/revdelay", "lv2-ringmod_1i1o1l" : "elv2:http://plugin.org.uk/swh-plugins/ringmod_1i1o1l", "lv2-ringmod_2i1o" : "elv2:http://plugin.org.uk/swh-plugins/ringmod_2i1o", "lv2-satanMaximiser" : "elv2:http://plugin.org.uk/swh-plugins/satanMaximiser", "lv2-sc1" : "elv2:http://plugin.org.uk/swh-plugins/sc1", "lv2-sc2" : "elv2:http://plugin.org.uk/swh-plugins/sc2", "lv2-sc3" : "elv2:http://plugin.org.uk/swh-plugins/sc3", "lv2-sc4" : "elv2:http://plugin.org.uk/swh-plugins/sc4", "lv2-se4" : "elv2:http://plugin.org.uk/swh-plugins/se4", "lv2-shaper" : "elv2:http://plugin.org.uk/swh-plugins/shaper", "lv2-sifter" : "elv2:http://plugin.org.uk/swh-plugins/sifter", "lv2-sinCos" : "elv2:http://plugin.org.uk/swh-plugins/sinCos", "lv2-singlePara" : "elv2:http://plugin.org.uk/swh-plugins/singlePara", "lv2-sinusWavewrapper" : "elv2:http://plugin.org.uk/swh-plugins/sinusWavewrapper", "lv2-smoothDecimate" : "elv2:http://plugin.org.uk/swh-plugins/smoothDecimate", "lv2-split" : "elv2:http://plugin.org.uk/swh-plugins/split", "lv2-surroundEncoder" : "elv2:http://plugin.org.uk/swh-plugins/surroundEncoder", "lv2-svf" : "elv2:http://plugin.org.uk/swh-plugins/svf", "lv2-tapeDelay" : "elv2:http://plugin.org.uk/swh-plugins/tapeDelay", "lv2-transient" : "elv2:http://plugin.org.uk/swh-plugins/transient", "lv2-triplePara" : "elv2:http://plugin.org.uk/swh-plugins/triplePara", "lv2-ulaw" : "elv2:http://plugin.org.uk/swh-plugins/ulaw", "lv2-valve" : "elv2:http://plugin.org.uk/swh-plugins/valve", "lv2-valveRect" : "elv2:http://plugin.org.uk/swh-plugins/valveRect", "lv2-vynil" : "elv2:http://plugin.org.uk/swh-plugins/vynil", "lv2-waveTerrain" : "elv2:http://plugin.org.uk/swh-plugins/waveTerrain", "lv2-xfade" : "elv2:http://plugin.org.uk/swh-plugins/xfade", "lv2-xfade4" : "elv2:http://plugin.org.uk/swh-plugins/xfade4", "lv2-zm1" : "elv2:http://plugin.org.uk/swh-plugins/zm1", "pn:dyn_compress_brutal" : "pn:dyn_compress_brutal", "pn:dyn_compress_hard" : "pn:dyn_compress_hard", "pn:dyn_compress_infinite" : "pn:dyn_compress_infinite", "pn:dyn_compress_medium" : "pn:dyn_compress_medium", "pn:dyn_compress_soft" : "pn:dyn_compress_soft", "pn:dyn_compress_supersoft" : "pn:dyn_compress_supersoft", "pn:eq_template" : "pn:eq_template", "pn:eq_template2" : "pn:eq_template2", "pn:f_bandpass" : "pn:f_bandpass", "pn:f_filtertest" : "pn:f_filtertest", "pn:f_high_and_low" : "pn:f_high_and_low", "pn:f_highpass" : "pn:f_highpass", "pn:f_inverse_comb" : "pn:f_inverse_comb", "pn:f_lowp_sine" : "pn:f_lowp_sine", "pn:f_lowp_sine2" : "pn:f_lowp_sine2", "pn:f_lowpass" : "pn:f_lowpass", "pn:f_rejectband" : "pn:f_rejectband", "pn:f_res_bandpass" : "pn:f_res_bandpass", "pn:f_res_lowpass" : "pn:f_res_lowpass", "pn:f_resonator" : "pn:f_resonator", "pn:f_two_filters" : "pn:f_two_filters", "pn:f_two_filters_pareq" : "pn:f_two_filters_pareq", "pn:gate_crop" : "pn:gate_crop", "pn:gate_noisegate_1" : "pn:gate_noisegate_1", "pn:gate_noisegate_delanalog" : "pn:gate_noisegate_delanalog", "pn:gate_threshold" : "pn:gate_threshold", "pn:lad_hermes" : "pn:lad_hermes", "pn:lad_metronome" : "pn:lad_metronome", "pn:lad_oscillator_stack" : "pn:lad_oscillator_stack", "pn:lad_oscillator_test" : "pn:lad_oscillator_test", "pn:lad_sc4" : "pn:lad_sc4", "pn:lad_sc4_rg" : "pn:lad_sc4_rg", "pn:metronome" : "pn:metronome", "pn:time_chorus1" : "pn:time_chorus1", "pn:time_delay1" : "pn:time_delay1", "pn:time_delay2" : "pn:time_delay2", "pn:time_flanger1" : "pn:time_flanger1", "pn:time_phaser1" : "pn:time_phaser1", "pn:time_reverb1" : "pn:time_reverb1", "pn:time_reverb2" : "pn:time_reverb2", "pn:time_reverb3" : "pn:time_reverb3", "pn:time_reverb4" : "pn:time_reverb4", "pn:time_wicked_dub" : "pn:time_wicked_dub", "pn:var_aw" : "pn:var_aw", "pn:var_aw_custom" : "pn:var_aw_custom", "pn:var_aw_ksv" : "pn:var_aw_ksv", "pn:var_aw_tri" : "pn:var_aw_tri", "pn:var_aw_tri_custom" : "pn:var_aw_tri_custom", "pn:var_chipmunk" : "pn:var_chipmunk", "pn:var_dali" : "pn:var_dali", "pn:var_molten_tape" : "pn:var_molten_tape", "pn:var_paralmadness" : "pn:var_paralmadness", "pn:var_parchip" : "pn:var_parchip", "pn:var_stretched_tape" : "pn:var_stretched_tape", "pn:var_sweeping_pan" : "pn:var_sweeping_pan", "pn:var_switching_pan" : "pn:var_switching_pan" }, "registry" : [ {}, { "code" : "eS", "count" : 1, "display" : "field", "name" : "Audio stamp", "number" : "1", "params" : [ { "name" : "stamp-id" } ] }, { "code" : "ea", "count" : "1", "display" : "scale", "name" : "Volume", "params" : [ { "begin" : "0", "default" : "100", "end" : "600", "name" : "Level %", "resolution" : "0" } ] }, { "code" : "eadb", "count" : "1", "display" : "scale", "name" : "Volume", "params" : [ { "begin" : "-40", "default" : "0", "end" : "60", "name" : "Level db", "resolution" : "0.5" } ] }, { "code" : "eac", "count" : 2, "display" : "field", "name" : "Channel amplify", "number" : "4", "params" : [ { "name" : "amp-%" }, { "name" : "channel" } ] }, { "code" : "eal", "count" : "1", "display" : "scale", "name" : "Limiter", "params" : [ { "begin" : "0", "default" : "100", "end" : "100", "name" : "Limit %", "resolution" : "0" } ] }, { "code" : "eaw", "count" : 2, "display" : "field", "name" : "Amplify with clipping control", "number" : "6", "params" : [ { "name" : "amp-%" }, { "name" : "max-clipped-samples" } ] }, { "code" : "ec", "count" : "2", "display" : "scale", "name" : "Compressor", "params" : [ { "begin" : "0", "default" : "1", "end" : "1", "name" : "Compression Rate (Db)", "resolution" : "0" }, { "begin" : "0", "default" : "50", "end" : "100", "name" : "Threshold %", "resolution" : "0" } ] }, { "code" : "eca", "count" : "4", "display" : "scale", "name" : "Advanced Compressor", "params" : [ { "begin" : "0", "default" : "69", "end" : "100", "name" : "Peak Level %", "resolution" : "0" }, { "begin" : "0", "default" : "2", "end" : "5", "name" : "Release Time (Seconds)", "resolution" : "0" }, { "begin" : "0", "default" : "0.5", "end" : "1", "name" : "Fast Compressor Rate", "resolution" : "0" }, { "begin" : "0", "default" : "1", "end" : "1", "name" : "Compressor Rate (Db)", "resolution" : "0" } ] }, { "code" : "eemb", "count" : 2, "display" : "field", "name" : "Pulse gate BPM", "number" : "9", "params" : [ { "name" : "bpm" }, { "name" : "on-time-msec" } ] }, { "code" : "eemp", "count" : 2, "display" : "field", "name" : "Pulse Gate", "number" : "10", "params" : [ { "name" : "freq-Hz" }, { "name" : "on-time-%" } ] }, { "code" : "eemt", "count" : 2, "display" : "field", "name" : "Tremolo", "number" : "11", "params" : [ { "name" : "bpm" }, { "name" : "depth-%" } ] }, { "code" : "ef1", "count" : "2", "display" : "scale", "name" : "Resonant Bandpass Filter", "params" : [ { "begin" : "0", "default" : "0", "end" : "20000", "name" : "Center Frequency (Hz)", "resolution" : "0" }, { "begin" : "0", "default" : "0", "end" : "2000", "name" : "Width (Hz)", "resolution" : "0" } ] }, { "code" : "ef3", "count" : "3", "display" : "scale", "name" : "Resonant Lowpass Filter", "params" : [ { "begin" : "0", "default" : "0", "end" : "5000", "name" : "Cutoff Frequency (Hz)", "resolution" : "0" }, { "begin" : "0", "default" : "0", "end" : "2", "name" : "Resonance", "resolution" : "0" }, { "begin" : "0", "default" : "0", "end" : "1", "name" : "Gain", "resolution" : "0" } ] }, { "code" : "ef4", "count" : 2, "display" : "field", "name" : "RC-lowpass filter", "number" : "14", "params" : [ { "name" : "cutoff-freq" }, { "name" : "resonance" } ] }, { "code" : "efa", "count" : "2", "display" : "scale", "name" : "Allpass Filter", "params" : [ { "begin" : "0", "default" : "0", "end" : "10000", "name" : "Delay Samples", "resolution" : "0" }, { "begin" : "0", "default" : "50", "end" : "100", "name" : "Feedback %", "resolution" : "0" } ] }, { "code" : "efb", "count" : "2", "display" : "scale", "name" : "Bandpass Filter", "params" : [ { "begin" : "0", "default" : "11000", "end" : "11000", "name" : "Center Frequency (Hz)", "resolution" : "0" }, { "begin" : "0", "default" : "22000", "end" : "22000", "name" : "Width (Hz)", "resolution" : "0" } ] }, { "code" : "efc", "count" : 2, "display" : "field", "name" : "Comb filter", "number" : "17", "params" : [ { "name" : "delay-samples" }, { "name" : "radius" } ] }, { "code" : "efh", "count" : "1", "display" : "scale", "name" : "Highpass Filter", "params" : [ { "begin" : "10000", "default" : "10000", "end" : "22000", "name" : "Cutoff Frequency (Hz)", "resolution" : "0" } ] }, { "code" : "efi", "count" : 2, "display" : "field", "name" : "Inverse comb filter", "number" : "19", "params" : [ { "name" : "delay-samples" }, { "name" : "radius" } ] }, { "code" : "efl", "count" : "1", "display" : "scale", "name" : "Lowpass Filter", "params" : [ { "begin" : "0", "default" : "0", "end" : "10000", "name" : "Cutoff Frequency (Hz)", "resolution" : "0" } ] }, { "code" : "efr", "count" : "2", "display" : "scale", "name" : "Bandreject Filter", "params" : [ { "begin" : "0", "default" : "11000", "end" : "11000", "name" : "Center Frequency (Hz)", "resolution" : "0" }, { "begin" : "0", "default" : "22000", "end" : "22000", "name" : "Width (Hz)", "resolution" : "0" } ] }, { "code" : "efs", "count" : "2", "display" : "scale", "name" : "Resonator Filter", "params" : [ { "begin" : "0", "default" : "11000", "end" : "11000", "name" : "Center Frequency (Hz)", "resolution" : "0" }, { "begin" : "0", "default" : "22000", "end" : "22000", "name" : "Width (Hz)", "resolution" : "0" } ] }, { "code" : "ei", "count" : 1, "display" : "field", "name" : "Pitch shifter", "number" : "23", "params" : [ { "name" : "change-%" } ] }, { "code" : "enm", "count" : "5", "display" : "scale", "name" : "Noise Gate", "params" : [ { "begin" : "0", "default" : "100", "end" : "100", "name" : "Threshold Level %", "resolution" : "0" }, { "begin" : "0", "default" : "200", "end" : "2000", "name" : "Pre Hold Time (ms)", "resolution" : "0" }, { "begin" : "0", "default" : "200", "end" : "2000", "name" : "Attack Time (ms)", "resolution" : "0" }, { "begin" : "0", "default" : "200", "end" : "2000", "name" : "Post Hold Time (ms)", "resolution" : "0" }, { "begin" : "0", "default" : "200", "end" : "2000", "name" : "Release Time (ms)", "resolution" : "0" } ] }, { "code" : "epp", "count" : "1", "display" : "scale", "name" : "Pan", "params" : [ { "begin" : "0", "default" : "50", "end" : "100", "name" : "Level %", "resolution" : "0" } ] }, { "code" : "chorder", "count" : 0, "display" : "field", "name" : "Channel select", "number" : "26", "params" : [] }, { "code" : "chcopy", "count" : 2, "display" : "field", "name" : "Channel copy", "number" : "27", "params" : [ { "name" : "from-channel" }, { "name" : "to-channel" } ] }, { "code" : "erc", "count" : 2, "display" : "field", "name" : "Channel copy", "number" : "28", "params" : [ { "name" : "from-channel" }, { "name" : "to-channel" } ] }, { "code" : "chmove", "count" : 2, "display" : "field", "name" : "Channel move", "number" : "29", "params" : [ { "name" : "from-channel" }, { "name" : "to-channel" } ] }, { "code" : "chmute", "count" : 1, "display" : "field", "name" : "Channel mute", "number" : "30", "params" : [ { "name" : "channel" } ] }, { "code" : "erm", "count" : 1, "display" : "field", "name" : "Mix to channel", "number" : "31", "params" : [ { "name" : "to-channel" } ] }, { "code" : "chmix", "count" : 1, "display" : "field", "name" : "Mix to channel", "number" : "32", "params" : [ { "name" : "to-channel" } ] }, { "code" : "etc", "count" : "4", "display" : "scale", "name" : "Chorus", "params" : [ { "begin" : "0", "default" : "200", "end" : "2000", "name" : "Delay Time (ms)", "resolution" : "0" }, { "begin" : "0", "default" : "500", "end" : "10000", "name" : "Variance Time Samples", "resolution" : "0" }, { "begin" : "0", "default" : "50", "end" : "100", "name" : "Feedback %", "resolution" : "0" }, { "begin" : "0", "default" : "50", "end" : "100", "name" : "LFO Frequency (Hz)", "resolution" : "0" } ] }, { "code" : "etd", "count" : "5", "display" : "scale", "name" : "Delay", "params" : [ { "begin" : "0", "default" : "200", "end" : "2000", "name" : "Delay Time (ms)", "resolution" : "0" }, { "begin" : "0", "default" : "0", "end" : "2", "name" : "Surround Mode (Normal, Surround St., Spread)", "resolution" : "1" }, { "begin" : "0", "default" : "50", "end" : "100", "name" : "Number of Delays", "resolution" : "0" }, { "begin" : "0", "default" : "50", "end" : "100", "name" : "Mix %", "resolution" : "0" }, { "begin" : "0", "default" : "0", "end" : "100", "name" : "Feedback %", "resolution" : "0" } ] }, { "code" : "ete", "count" : "3", "display" : "scale", "name" : "Advanced Reverb", "params" : [ { "begin" : "0", "default" : "10", "end" : "100", "name" : "Room Size (Meters)", "resolution" : "0" }, { "begin" : "0", "default" : "50", "end" : "100", "name" : "Feedback %", "resolution" : "0" }, { "begin" : "0", "default" : "50", "end" : "100", "name" : "Wet %", "resolution" : "0" } ] }, { "code" : "etf", "count" : "1", "display" : "scale", "name" : "Fake Stereo", "params" : [ { "begin" : "0", "default" : "40", "end" : "500", "name" : "Delay Time (ms)", "resolution" : "0" } ] }, { "code" : "etl", "count" : "4", "display" : "scale", "name" : "Flanger", "params" : [ { "begin" : "0", "default" : "200", "end" : "1000", "name" : "Delay Time (ms)", "resolution" : "0" }, { "begin" : "0", "default" : "200", "end" : "10000", "name" : "Variance Time Samples", "resolution" : "0" }, { "begin" : "0", "default" : "50", "end" : "100", "name" : "Feedback %", "resolution" : "0" }, { "begin" : "0", "default" : "50", "end" : "100", "name" : "LFO Frequency (Hz)", "resolution" : "0" } ] }, { "code" : "etm", "count" : "3", "display" : "scale", "name" : "Multitap Delay", "params" : [ { "begin" : "0", "default" : "200", "end" : "2000", "name" : "Delay Time (ms)", "resolution" : "0" }, { "begin" : "0", "default" : "20", "end" : "100", "name" : "Number of Delays", "resolution" : "0" }, { "begin" : "0", "default" : "50", "end" : "100", "name" : "Mix %", "resolution" : "0" } ] }, { "code" : "etp", "count" : "4", "display" : "scale", "name" : "Phaser", "params" : [ { "begin" : "0", "default" : "200", "end" : "2000", "name" : "Delay Time (ms)", "resolution" : "0" }, { "begin" : "0", "default" : "100", "end" : "10000", "name" : "Variance Time Samples", "resolution" : "0" }, { "begin" : "0", "default" : "50", "end" : "100", "name" : "Feedback %", "resolution" : "0" }, { "begin" : "0", "default" : "50", "end" : "100", "name" : "LFO Frequency (Hz)", "resolution" : "0" } ] }, { "code" : "etr", "count" : "3", "display" : "scale", "name" : "Reverb", "params" : [ { "begin" : "0", "default" : "200", "end" : "2000", "name" : "Delay Time (ms)", "resolution" : "0" }, { "begin" : "0", "default" : "0", "end" : "1", "name" : "Surround Mode (0=Normal, 1=Surround)", "resolution" : "1" }, { "begin" : "0", "default" : "50", "end" : "100", "name" : "Feedback %", "resolution" : "0" } ] }, { "code" : "ev", "count" : 2, "display" : "field", "name" : "Volume analysis", "number" : "41", "params" : [ { "name" : "cumulative-mode" }, { "name" : "result-max-multiplier" } ] }, { "code" : "evp", "count" : 0, "display" : "field", "name" : "Peak amplitude watcher", "number" : "42", "params" : [] }, { "code" : "ezf", "count" : 0, "display" : "field", "name" : "DC-Find", "number" : "43", "params" : [] }, { "code" : "ezx", "count" : 1, "display" : "field", "name" : "DC-Fix", "number" : "44", "params" : [ { "name" : "channel-count" } ] }, { "code" : "gc", "count" : 2, "display" : "field", "name" : "Time crop gate", "number" : "45", "params" : [ { "name" : "open-at-sec" }, { "name" : "duration-sec" } ] }, { "code" : "ge", "count" : 4, "display" : "field", "name" : "Threshold gate", "number" : "46", "params" : [ { "name" : "threshold-openlevel-%" }, { "name" : "threshold-closelevel-%" }, { "name" : "rms-enabled" }, { "name" : "reopen-count" } ] }, { "code" : "gm", "count" : 1, "display" : "field", "name" : "Manual gate", "number" : "47", "params" : [ { "name" : "state" } ] }, { "code" : "el:bandpass_a_iir", "count" : 2, "display" : "field", "name" : "Glame Bandpass Analog Filter", "number" : "1", "params" : [ { "name" : "Center Frequency (Hz)" }, { "name" : "Bandwidth (Hz)" } ] }, { "code" : "el:hilbert", "count" : 1, "display" : "field", "name" : "Hilbert transformer", "number" : "2", "params" : [ { "name" : "latency" } ] }, { "code" : "el:invada_lp_mono_filter_module_0_1", "count" : 3, "display" : "field", "name" : ":: Invada :: Filter - Low Pass Mono", "number" : "3", "params" : [ { "name" : "Frequency (Hz)" }, { "name" : "Gain (dB)" }, { "name" : "Soft Clip" } ] }, { "code" : "el:invada_hp_mono_filter_module_0_1", "count" : 3, "display" : "field", "name" : ":: Invada :: Filter - High Pass Mono", "number" : "4", "params" : [ { "name" : "Frequency (Hz)" }, { "name" : "Gain (dB)" }, { "name" : "Soft Clip" } ] }, { "code" : "el:invada_lp_stereo_filter_module_0_1", "count" : 3, "display" : "field", "name" : ":: Invada :: Filter - Low Pass Stereo", "number" : "5", "params" : [ { "name" : "Frequency (Hz)" }, { "name" : "Gain (dB)" }, { "name" : "Soft Clip" } ] }, { "code" : "el:invada_hp_stereo_filter_module_0_1", "count" : 3, "display" : "field", "name" : ":: Invada :: Filter - High Pass Stereo", "number" : "6", "params" : [ { "name" : "Frequency (Hz)" }, { "name" : "Gain (dB)" }, { "name" : "Soft Clip" } ] }, { "code" : "el:analogueOsc", "count" : 4, "display" : "field", "name" : "Analogue Oscillator", "number" : "7", "params" : [ { "name" : "Waveform (1=sin, 2=tri, 3=squ, 4=saw)" }, { "name" : "Frequency (Hz)" }, { "name" : "Warmth" }, { "name" : "Instability" } ] }, { "code" : "el:inv", "count" : 0, "display" : "field", "name" : "Inverter", "number" : "8", "params" : [] }, { "code" : "el:tap_tremolo", "count" : 3, "display" : "field", "name" : "TAP Tremolo", "number" : "9", "params" : [ { "name" : "Frequency [Hz]" }, { "name" : "Depth [%]" }, { "name" : "Gain [dB]" } ] }, { "code" : "el:valve", "count" : 2, "display" : "field", "name" : "Valve saturation", "number" : "10", "params" : [ { "name" : "Distortion level" }, { "name" : "Distortion character" } ] }, { "code" : "el:sc4", "count" : 9, "display" : "field", "name" : "SC4", "number" : "11", "params" : [ { "name" : "RMS/peak" }, { "name" : "Attack time (ms)" }, { "name" : "Release time (ms)" }, { "name" : "Threshold level (dB)" }, { "name" : "Ratio (1:n)" }, { "name" : "Knee radius (dB)" }, { "name" : "Makeup gain (dB)" }, { "name" : "Amplitude (dB)" }, { "name" : "Gain reduction (dB)" } ] }, { "code" : "el:amp_mono", "count" : 1, "display" : "field", "name" : "Mono Amplifier", "number" : "12", "params" : [ { "name" : "Gain" } ] }, { "code" : "el:amp_stereo", "count" : 1, "display" : "field", "name" : "Stereo Amplifier", "number" : "13", "params" : [ { "name" : "Gain" } ] }, { "code" : "el:lcrDelay", "count" : 11, "display" : "field", "name" : "L/C/R Delay", "number" : "14", "params" : [ { "name" : "L delay (ms)" }, { "name" : "L level" }, { "name" : "C delay (ms)" }, { "name" : "C level" }, { "name" : "R delay (ms)" }, { "name" : "R level" }, { "name" : "Feedback" }, { "name" : "High damp (%)" }, { "name" : "Low damp (%)" }, { "name" : "Spread" }, { "name" : "Dry/Wet level" } ] }, { "code" : "el:tap_sigmoid", "count" : 2, "display" : "field", "name" : "TAP Sigmoid Booster", "number" : "15", "params" : [ { "name" : "Pre Gain [dB]" }, { "name" : "Post Gain [dB]" } ] }, { "code" : "el:decay", "count" : 1, "display" : "field", "name" : "Exponential signal decay", "number" : "16", "params" : [ { "name" : "Decay Time (s)" } ] }, { "code" : "el:bwxover_iir", "count" : 2, "display" : "field", "name" : "Glame Butterworth X-over Filter", "number" : "17", "params" : [ { "name" : "Cutoff Frequency (Hz)" }, { "name" : "Resonance" } ] }, { "code" : "el:buttlow_iir", "count" : 2, "display" : "field", "name" : "GLAME Butterworth Lowpass", "number" : "18", "params" : [ { "name" : "Cutoff Frequency (Hz)" }, { "name" : "Resonance" } ] }, { "code" : "el:butthigh_iir", "count" : 2, "display" : "field", "name" : "GLAME Butterworth Highpass", "number" : "19", "params" : [ { "name" : "Cutoff Frequency (Hz)" }, { "name" : "Resonance" } ] }, { "code" : "el:foverdrive", "count" : 1, "display" : "field", "name" : "Fast overdrive", "number" : "20", "params" : [ { "name" : "Drive level" } ] }, { "code" : "el:delayorama", "count" : 11, "display" : "field", "name" : "Delayorama", "number" : "21", "params" : [ { "name" : "Random seed" }, { "name" : "Input gain (dB)" }, { "name" : "Feedback (%)" }, { "name" : "Number of taps" }, { "name" : "First delay (s)" }, { "name" : "Delay range (s)" }, { "name" : "Delay change" }, { "name" : "Delay random (%)" }, { "name" : "Amplitude change" }, { "name" : "Amplitude random (%)" }, { "name" : "Dry/wet mix" } ] }, { "code" : "el:comb_n", "count" : 3, "display" : "field", "name" : "Comb delay line, noninterpolating", "number" : "22", "params" : [ { "name" : "Max Delay (s)" }, { "name" : "Delay Time (s)" }, { "name" : "Decay Time (s)" } ] }, { "code" : "el:comb_l", "count" : 3, "display" : "field", "name" : "Comb delay line, linear interpolation", "number" : "23", "params" : [ { "name" : "Max Delay (s)" }, { "name" : "Delay Time (s)" }, { "name" : "Decay Time (s)" } ] }, { "code" : "el:comb_c", "count" : 3, "display" : "field", "name" : "Comb delay line, cubic spline interpolation", "number" : "24", "params" : [ { "name" : "Max Delay (s)" }, { "name" : "Delay Time (s)" }, { "name" : "Decay Time (s)" } ] }, { "code" : "el:sc3", "count" : 7, "display" : "field", "name" : "SC3", "number" : "25", "params" : [ { "name" : "Attack time (ms)" }, { "name" : "Release time (ms)" }, { "name" : "Threshold level (dB)" }, { "name" : "Ratio (1:n)" }, { "name" : "Knee radius (dB)" }, { "name" : "Makeup gain (dB)" }, { "name" : "Chain balance" } ] }, { "code" : "el:hermesFilter", "count" : 52, "display" : "field", "name" : "Hermes Filter", "number" : "26", "params" : [ { "name" : "LFO1 freq (Hz)" }, { "name" : "LFO1 wave (0 = sin, 1 = tri, 2 = saw, 3 = squ, 4 = s&h)" }, { "name" : "LFO2 freq (Hz)" }, { "name" : "LFO2 wave (0 = sin, 1 = tri, 2 = saw, 3 = squ, 4 = s&h)" }, { "name" : "Osc1 freq (Hz)" }, { "name" : "Osc1 wave (0 = sin, 1 = tri, 2 = saw, 3 = squ, 4 = noise)" }, { "name" : "Osc2 freq (Hz)" }, { "name" : "Osc2 wave (0 = sin, 1 = tri, 2 = saw, 3 = squ, 4 = noise)" }, { "name" : "Ringmod 1 depth (0=none, 1=AM, 2=RM)" }, { "name" : "Ringmod 2 depth (0=none, 1=AM, 2=RM)" }, { "name" : "Ringmod 3 depth (0=none, 1=AM, 2=RM)" }, { "name" : "Osc1 gain (dB)" }, { "name" : "RM1 gain (dB)" }, { "name" : "Osc2 gain (dB)" }, { "name" : "RM2 gain (dB)" }, { "name" : "Input gain (dB)" }, { "name" : "RM3 gain (dB)" }, { "name" : "Xover lower freq" }, { "name" : "Xover upper freq" }, { "name" : "Dist1 drive" }, { "name" : "Dist2 drive" }, { "name" : "Dist3 drive" }, { "name" : "Filt1 type (0=none, 1=LP, 2=HP, 3=BP, 4=BR, 5=AP)" }, { "name" : "Filt1 freq" }, { "name" : "Filt1 q" }, { "name" : "Filt1 resonance" }, { "name" : "Filt1 LFO1 level" }, { "name" : "Filt1 LFO2 level" }, { "name" : "Filt2 type (0=none, 1=LP, 2=HP, 3=BP, 4=BR, 5=AP)" }, { "name" : "Filt2 freq" }, { "name" : "Filt2 q" }, { "name" : "Filt2 resonance" }, { "name" : "Filt2 LFO1 level" }, { "name" : "Filt2 LFO2 level" }, { "name" : "Filt3 type (0=none, 1=LP, 2=HP, 3=BP, 4=BR, 5=AP)" }, { "name" : "Filt3 freq" }, { "name" : "Filt3 q" }, { "name" : "Filt3 resonance" }, { "name" : "Filt3 LFO1 level" }, { "name" : "Filt3 LFO2 level" }, { "name" : "Delay1 length (s)" }, { "name" : "Delay1 feedback" }, { "name" : "Delay1 wetness" }, { "name" : "Delay2 length (s)" }, { "name" : "Delay2 feedback" }, { "name" : "Delay2 wetness" }, { "name" : "Delay3 length (s)" }, { "name" : "Delay3 feedback" }, { "name" : "Delay3 wetness" }, { "name" : "Band 1 gain (dB)" }, { "name" : "Band 2 gain (dB)" }, { "name" : "Band 3 gain (dB)" } ] }, { "code" : "el:bodeShifter", "count" : 2, "display" : "field", "name" : "Bode frequency shifter", "number" : "27", "params" : [ { "name" : "Frequency shift" }, { "name" : "latency" } ] }, { "code" : "el:sine_faaa", "count" : 0, "display" : "field", "name" : "Sine Oscillator (Freq:audio, Amp:audio)", "number" : "28", "params" : [] }, { "code" : "el:sine_faac", "count" : 1, "display" : "field", "name" : "Sine Oscillator (Freq:audio, Amp:control)", "number" : "29", "params" : [ { "name" : "Amplitude" } ] }, { "code" : "el:sine_fcaa", "count" : 1, "display" : "field", "name" : "Sine Oscillator (Freq:control, Amp:audio)", "number" : "30", "params" : [ { "name" : "Frequency (Hz)" } ] }, { "code" : "el:sine_fcac", "count" : 2, "display" : "field", "name" : "Sine Oscillator (Freq:control, Amp:control)", "number" : "31", "params" : [ { "name" : "Frequency (Hz)" }, { "name" : "Amplitude" } ] }, { "code" : "el:tap_limiter", "count" : 3, "display" : "field", "name" : "TAP Scaling Limiter", "number" : "32", "params" : [ { "name" : "Limit Level [dB]" }, { "name" : "Output Volume [dB]" }, { "name" : "latency" } ] }, { "code" : "el:tap_rotspeak", "count" : 5, "display" : "field", "name" : "TAP Rotary Speaker", "number" : "33", "params" : [ { "name" : "Rotor Frequency [Hz]" }, { "name" : "Horn Frequency [Hz]" }, { "name" : "Mic Distance [%]" }, { "name" : "Rotor/Horn Mix" }, { "name" : "latency" } ] }, { "code" : "el:zm1", "count" : 0, "display" : "field", "name" : "z-1", "number" : "34", "params" : [] }, { "code" : "el:multivoiceChorus", "count" : 6, "display" : "field", "name" : "Multivoice Chorus", "number" : "35", "params" : [ { "name" : "Number of voices" }, { "name" : "Delay base (ms)" }, { "name" : "Voice separation (ms)" }, { "name" : "Detune (%)" }, { "name" : "LFO frequency (Hz)" }, { "name" : "Output attenuation (dB)" } ] }, { "code" : "el:fmOsc", "count" : 1, "display" : "field", "name" : "FM Oscillator", "number" : "36", "params" : [ { "name" : "Waveform (1=sin, 2=tri, 3=squ, 4=saw)" } ] }, { "code" : "el:sc4m", "count" : 9, "display" : "field", "name" : "SC4 mono", "number" : "37", "params" : [ { "name" : "RMS/peak" }, { "name" : "Attack time (ms)" }, { "name" : "Release time (ms)" }, { "name" : "Threshold level (dB)" }, { "name" : "Ratio (1:n)" }, { "name" : "Knee radius (dB)" }, { "name" : "Makeup gain (dB)" }, { "name" : "Amplitude (dB)" }, { "name" : "Gain reduction (dB)" } ] }, { "code" : "el:gongBeater", "count" : 3, "display" : "field", "name" : "Gong beater", "number" : "38", "params" : [ { "name" : "Impulse gain (dB)" }, { "name" : "Strike gain (dB)" }, { "name" : "Strike duration (s)" } ] }, { "code" : "el:delay_n", "count" : 2, "display" : "field", "name" : "Simple delay line, noninterpolating", "number" : "39", "params" : [ { "name" : "Max Delay (s)" }, { "name" : "Delay Time (s)" } ] }, { "code" : "el:delay_l", "count" : 2, "display" : "field", "name" : "Simple delay line, linear interpolation", "number" : "40", "params" : [ { "name" : "Max Delay (s)" }, { "name" : "Delay Time (s)" } ] }, { "code" : "el:delay_c", "count" : 2, "display" : "field", "name" : "Simple delay line, cubic spline interpolation", "number" : "41", "params" : [ { "name" : "Max Delay (s)" }, { "name" : "Delay Time (s)" } ] }, { "code" : "el:tap_vibrato", "count" : 5, "display" : "field", "name" : "TAP Vibrato", "number" : "42", "params" : [ { "name" : "Frequency [Hz]" }, { "name" : "Depth [%]" }, { "name" : "Dry Level [dB]" }, { "name" : "Wet Level [dB]" }, { "name" : "latency" } ] }, { "code" : "el:fastLookaheadLimiter", "count" : 5, "display" : "field", "name" : "Fast Lookahead limiter", "number" : "43", "params" : [ { "name" : "Input gain (dB)" }, { "name" : "Limit (dB)" }, { "name" : "Release time (s)" }, { "name" : "Attenuation (dB)" }, { "name" : "latency" } ] }, { "code" : "el:impulse_fc", "count" : 1, "display" : "field", "name" : "Nonbandlimited single-sample impulses (Frequency: Control)", "number" : "44", "params" : [ { "name" : "Frequency (Hz)" } ] }, { "code" : "el:lowpass_iir", "count" : 2, "display" : "field", "name" : "Glame Lowpass Filter", "number" : "45", "params" : [ { "name" : "Cutoff Frequency" }, { "name" : "Stages(2 poles per stage)" } ] }, { "code" : "el:tap_pitch", "count" : 5, "display" : "field", "name" : "TAP Pitch Shifter", "number" : "46", "params" : [ { "name" : "Semitone Shift" }, { "name" : "Rate Shift [%]" }, { "name" : "Dry Level [dB]" }, { "name" : "Wet Level [dB]" }, { "name" : "latency" } ] }, { "code" : "el:NoiseGate", "count" : 4, "display" : "field", "name" : "C* NoiseGate - Attenuate hum and noise", "number" : "47", "params" : [ { "name" : "open (dB)" }, { "name" : "attack (ms)" }, { "name" : "close (dB)" }, { "name" : "mains (Hz)" } ] }, { "code" : "el:Compress", "count" : 7, "display" : "field", "name" : "C* Compress - Compressor and saturating limiter", "number" : "48", "params" : [ { "name" : "measure" }, { "name" : "mode" }, { "name" : "threshold" }, { "name" : "strength" }, { "name" : "attack" }, { "name" : "release" }, { "name" : "gain (dB)" } ] }, { "code" : "el:CompressX2", "count" : 7, "display" : "field", "name" : "C* CompressX2 - Stereo compressor and saturating limiter", "number" : "49", "params" : [ { "name" : "measure" }, { "name" : "mode" }, { "name" : "threshold" }, { "name" : "strength" }, { "name" : "attack" }, { "name" : "release" }, { "name" : "gain (dB)" } ] }, { "code" : "el:ToneStack", "count" : 4, "display" : "field", "name" : "C* ToneStack - Classic amplifier tone stack emulation", "number" : "50", "params" : [ { "name" : "model" }, { "name" : "bass" }, { "name" : "mid" }, { "name" : "treble" } ] }, { "code" : "el:AmpVTS", "count" : 11, "display" : "field", "name" : "C* AmpVTS - Idealised guitar amplification", "number" : "51", "params" : [ { "name" : "over" }, { "name" : "gain" }, { "name" : "bright" }, { "name" : "power" }, { "name" : "tonestack" }, { "name" : "bass" }, { "name" : "mid" }, { "name" : "treble" }, { "name" : "attack" }, { "name" : "squash" }, { "name" : "lowcut" } ] }, { "code" : "el:CabinetIV", "count" : 2, "display" : "field", "name" : "C* CabinetIV - Idealised loudspeaker cabinet", "number" : "52", "params" : [ { "name" : "model" }, { "name" : "gain (dB)" } ] }, { "code" : "el:Plate", "count" : 4, "display" : "field", "name" : "C* Plate - Versatile plate reverb", "number" : "53", "params" : [ { "name" : "bandwidth" }, { "name" : "tail" }, { "name" : "damping" }, { "name" : "blend" } ] }, { "code" : "el:PlateX2", "count" : 4, "display" : "field", "name" : "C* PlateX2 - Versatile plate reverb, stereo inputs", "number" : "54", "params" : [ { "name" : "bandwidth" }, { "name" : "tail" }, { "name" : "damping" }, { "name" : "blend" } ] }, { "code" : "el:Saturate", "count" : 3, "display" : "field", "name" : "C* Saturate - Various overdrive models, 8x oversampled", "number" : "55", "params" : [ { "name" : "mode" }, { "name" : "gain (dB)" }, { "name" : "bias" } ] }, { "code" : "el:Spice", "count" : 5, "display" : "field", "name" : "C* Spice - Not an exciter", "number" : "56", "params" : [ { "name" : "lo.f (Hz)" }, { "name" : "lo.compress" }, { "name" : "lo.gain" }, { "name" : "hi.f (Hz)" }, { "name" : "hi.gain" } ] }, { "code" : "el:SpiceX2", "count" : 5, "display" : "field", "name" : "C* SpiceX2 - Not an exciter either", "number" : "57", "params" : [ { "name" : "lo.f (Hz)" }, { "name" : "lo.compress" }, { "name" : "lo.gain" }, { "name" : "hi.f (Hz)" }, { "name" : "hi.gain" } ] }, { "code" : "el:ChorusI", "count" : 6, "display" : "field", "name" : "C* ChorusI - Mono chorus/flanger", "number" : "58", "params" : [ { "name" : "t (ms)" }, { "name" : "width (ms)" }, { "name" : "rate (Hz)" }, { "name" : "blend" }, { "name" : "feedforward" }, { "name" : "feedback" } ] }, { "code" : "el:PhaserII", "count" : 5, "display" : "field", "name" : "C* PhaserII - Mono phaser", "number" : "59", "params" : [ { "name" : "rate" }, { "name" : "lfo" }, { "name" : "depth" }, { "name" : "spread" }, { "name" : "resonance" } ] }, { "code" : "el:AutoFilter", "count" : 9, "display" : "field", "name" : "C* AutoFilter - Modulated filter cascade", "number" : "60", "params" : [ { "name" : "over" }, { "name" : "mode" }, { "name" : "filter" }, { "name" : "gain (dB)" }, { "name" : "f (Hz)" }, { "name" : "Q" }, { "name" : "range" }, { "name" : "lfo/env" }, { "name" : "rate" } ] }, { "code" : "el:Scape", "count" : 6, "display" : "field", "name" : "C* Scape - Stereo delay with chromatic resonances", "number" : "61", "params" : [ { "name" : "bpm" }, { "name" : "divider" }, { "name" : "feedback" }, { "name" : "dry" }, { "name" : "blend" }, { "name" : "tune (Hz)" } ] }, { "code" : "el:Eq10", "count" : 10, "display" : "field", "name" : "C* Eq10 - 10-band equaliser", "number" : "62", "params" : [ { "name" : "31 Hz" }, { "name" : "63 Hz" }, { "name" : "125 Hz" }, { "name" : "250 Hz" }, { "name" : "500 Hz" }, { "name" : "1 kHz" }, { "name" : "2 kHz" }, { "name" : "4 kHz" }, { "name" : "8 kHz" }, { "name" : "16 kHz" } ] }, { "code" : "el:Eq10X2", "count" : 10, "display" : "field", "name" : "C* Eq10X2 - Stereo 10-band equaliser", "number" : "63", "params" : [ { "name" : "31 Hz" }, { "name" : "63 Hz" }, { "name" : "125 Hz" }, { "name" : "250 Hz" }, { "name" : "500 Hz" }, { "name" : "1 kHz" }, { "name" : "2 kHz" }, { "name" : "4 kHz" }, { "name" : "8 kHz" }, { "name" : "16 kHz" } ] }, { "code" : "el:Eq4p", "count" : 16, "display" : "field", "name" : "C* Eq4p - 4-band parametric equaliser", "number" : "64", "params" : [ { "name" : "a.mode" }, { "name" : "a.f (Hz)" }, { "name" : "a.Q" }, { "name" : "a.gain (dB)" }, { "name" : "b.mode" }, { "name" : "b.f (Hz)" }, { "name" : "b.Q" }, { "name" : "b.gain (dB)" }, { "name" : "c.mode" }, { "name" : "c.f (Hz)" }, { "name" : "c.Q" }, { "name" : "c.gain (dB)" }, { "name" : "d.mode" }, { "name" : "d.f (Hz)" }, { "name" : "d.Q" }, { "name" : "d.gain (dB)" } ] }, { "code" : "el:Wider", "count" : 2, "display" : "field", "name" : "C* Wider - Stereo image synthesis", "number" : "65", "params" : [ { "name" : "pan" }, { "name" : "width" } ] }, { "code" : "el:Narrower", "count" : 2, "display" : "field", "name" : "C* Narrower - Stereo image width reduction", "number" : "66", "params" : [ { "name" : "mode" }, { "name" : "strength" } ] }, { "code" : "el:Sin", "count" : 2, "display" : "field", "name" : "C* Sin - Sine wave generator", "number" : "67", "params" : [ { "name" : "f (Hz)" }, { "name" : "volume" } ] }, { "code" : "el:White", "count" : 1, "display" : "field", "name" : "C* White - Noise generator", "number" : "68", "params" : [ { "name" : "volume" } ] }, { "code" : "el:Fractal", "count" : 7, "display" : "field", "name" : "C* Fractal - Audio stream from deterministic chaos", "number" : "69", "params" : [ { "name" : "rate" }, { "name" : "mode" }, { "name" : "x" }, { "name" : "y" }, { "name" : "z" }, { "name" : "hp" }, { "name" : "volume" } ] }, { "code" : "el:Click", "count" : 4, "display" : "field", "name" : "C* Click - Metronome", "number" : "70", "params" : [ { "name" : "model" }, { "name" : "bpm" }, { "name" : "volume" }, { "name" : "damping" } ] }, { "code" : "el:CEO", "count" : 3, "display" : "field", "name" : "C* CEO - Chief Executive Oscillator", "number" : "71", "params" : [ { "name" : "ppm" }, { "name" : "volume" }, { "name" : "damping" } ] }, { "code" : "el:transient", "count" : 2, "display" : "field", "name" : "Transient mangler", "number" : "72", "params" : [ { "name" : "Attack speed" }, { "name" : "Sustain time" } ] }, { "code" : "el:waveTerrain", "count" : 0, "display" : "field", "name" : "Wave Terrain Oscillator", "number" : "73", "params" : [] }, { "code" : "el:fadDelay", "count" : 2, "display" : "field", "name" : "Fractionally Addressed Delay Line", "number" : "74", "params" : [ { "name" : "Delay (seconds)" }, { "name" : "Feedback (dB)" } ] }, { "code" : "el:tap_stereo_echo", "count" : 10, "display" : "field", "name" : "TAP Stereo Echo", "number" : "75", "params" : [ { "name" : "L Delay [ms]" }, { "name" : "L Feedback [%]" }, { "name" : "R/Haas Delay [ms]" }, { "name" : "R/Haas Feedback [%]" }, { "name" : "L Echo Level [dB]" }, { "name" : "R Echo Level [dB]" }, { "name" : "Dry Level [dB]" }, { "name" : "Cross Mode" }, { "name" : "Haas Effect" }, { "name" : "Swap Outputs" } ] }, { "code" : "el:smoothDecimate", "count" : 2, "display" : "field", "name" : "Smooth Decimator", "number" : "76", "params" : [ { "name" : "Resample rate" }, { "name" : "Smoothing" } ] }, { "code" : "el:tap_chorusflanger", "count" : 7, "display" : "field", "name" : "TAP Chorus/Flanger", "number" : "77", "params" : [ { "name" : "Frequency [Hz]" }, { "name" : "L/R Phase Shift [deg]" }, { "name" : "Depth [%]" }, { "name" : "Delay [ms]" }, { "name" : "Contour [Hz]" }, { "name" : "Dry Level [dB]" }, { "name" : "Wet Level [dB]" } ] }, { "code" : "el:vynil", "count" : 5, "display" : "field", "name" : "VyNil (Vinyl Effect)", "number" : "78", "params" : [ { "name" : "Year" }, { "name" : "RPM" }, { "name" : "Surface warping" }, { "name" : "Crackle" }, { "name" : "Wear" } ] }, { "code" : "el:retroFlange", "count" : 2, "display" : "field", "name" : "Retro Flanger", "number" : "79", "params" : [ { "name" : "Average stall (ms)" }, { "name" : "Flange frequency (Hz)" } ] }, { "code" : "el:harmonicGen", "count" : 10, "display" : "field", "name" : "Harmonic generator", "number" : "80", "params" : [ { "name" : "Fundamental magnitude" }, { "name" : "2nd harmonic magnitude" }, { "name" : "3rd harmonic magnitude" }, { "name" : "4th harmonic magnitude" }, { "name" : "5th harmonic magnitude" }, { "name" : "6th harmonic magnitude" }, { "name" : "7th harmonic magnitude" }, { "name" : "8th harmonic magnitude" }, { "name" : "9th harmonic magnitude" }, { "name" : "10th harmonic magnitude" } ] }, { "code" : "el:Parametric1", "count" : 18, "display" : "field", "name" : "4-band parametric filter", "number" : "81", "params" : [ { "name" : "Filter" }, { "name" : "Gain" }, { "name" : "Section 1" }, { "name" : "Frequency 1" }, { "name" : "Bandwidth 1" }, { "name" : "Gain 1" }, { "name" : "Section 2" }, { "name" : "Frequency 2" }, { "name" : "Bandwidth 2" }, { "name" : "Gain 2" }, { "name" : "Section 3" }, { "name" : "Frequency 3" }, { "name" : "Bandwidth 3" }, { "name" : "Gain 3" }, { "name" : "Section 4" }, { "name" : "Frequency 4" }, { "name" : "Bandwidth 4" }, { "name" : "Gain 4" } ] }, { "code" : "el:tap_equalizer", "count" : 16, "display" : "field", "name" : "TAP Equalizer", "number" : "82", "params" : [ { "name" : "Band 1 Gain [dB]" }, { "name" : "Band 2 Gain [dB]" }, { "name" : "Band 3 Gain [dB]" }, { "name" : "Band 4 Gain [dB]" }, { "name" : "Band 5 Gain [dB]" }, { "name" : "Band 6 Gain [dB]" }, { "name" : "Band 7 Gain [dB]" }, { "name" : "Band 8 Gain [dB]" }, { "name" : "Band 1 Freq [Hz]" }, { "name" : "Band 2 Freq [Hz]" }, { "name" : "Band 3 Freq [Hz]" }, { "name" : "Band 4 Freq [Hz]" }, { "name" : "Band 5 Freq [Hz]" }, { "name" : "Band 6 Freq [Hz]" }, { "name" : "Band 7 Freq [Hz]" }, { "name" : "Band 8 Freq [Hz]" } ] }, { "code" : "el:matrixMSSt", "count" : 1, "display" : "field", "name" : "Matrix: MS to Stereo", "number" : "83", "params" : [ { "name" : "Width" } ] }, { "code" : "el:invada_mono_tube_module_0_1", "count" : 4, "display" : "field", "name" : ":: Invada :: Tube - Mono", "number" : "84", "params" : [ { "name" : "Drive (dB)" }, { "name" : "DC Offset" }, { "name" : "Phase" }, { "name" : "Wet/Dry Mix (%)" } ] }, { "code" : "el:invada_stereo_tube_module_0_1", "count" : 4, "display" : "field", "name" : ":: Invada :: Tube - Stereo", "number" : "85", "params" : [ { "name" : "Drive (dB)" }, { "name" : "DC Offset" }, { "name" : "Phase" }, { "name" : "Wet/Dry Mix (%)" } ] }, { "code" : "el:declip", "count" : 0, "display" : "field", "name" : "Declipper", "number" : "86", "params" : [] }, { "code" : "el:bandpass_iir", "count" : 3, "display" : "field", "name" : "Glame Bandpass Filter", "number" : "87", "params" : [ { "name" : "Center Frequency (Hz)" }, { "name" : "Bandwidth (Hz)" }, { "name" : "Stages(2 poles per stage)" } ] }, { "code" : "el:artificialLatency", "count" : 2, "display" : "field", "name" : "Artificial latency", "number" : "88", "params" : [ { "name" : "Delay (ms)" }, { "name" : "latency" } ] }, { "code" : "el:satanMaximiser", "count" : 2, "display" : "field", "name" : "Barry's Satan Maximiser", "number" : "89", "params" : [ { "name" : "Decay time (samples)" }, { "name" : "Knee point (dB)" } ] }, { "code" : "el:singlePara", "count" : 3, "display" : "field", "name" : "Single band parametric", "number" : "90", "params" : [ { "name" : "Gain (dB)" }, { "name" : "Frequency (Hz)" }, { "name" : "Bandwidth (octaves)" } ] }, { "code" : "el:decimator", "count" : 2, "display" : "field", "name" : "Decimator", "number" : "91", "params" : [ { "name" : "Bit depth" }, { "name" : "Sample rate (Hz)" } ] }, { "code" : "el:mbeq", "count" : 16, "display" : "field", "name" : "Multiband EQ", "number" : "92", "params" : [ { "name" : "50Hz gain (low shelving)" }, { "name" : "100Hz gain" }, { "name" : "156Hz gain" }, { "name" : "220Hz gain" }, { "name" : "311Hz gain" }, { "name" : "440Hz gain" }, { "name" : "622Hz gain" }, { "name" : "880Hz gain" }, { "name" : "1250Hz gain" }, { "name" : "1750Hz gain" }, { "name" : "2500Hz gain" }, { "name" : "3500Hz gain" }, { "name" : "5000Hz gain" }, { "name" : "10000Hz gain" }, { "name" : "20000Hz gain" }, { "name" : "latency" } ] }, { "code" : "el:svf", "count" : 4, "display" : "field", "name" : "State Variable Filter", "number" : "93", "params" : [ { "name" : "Filter type (0=none, 1=LP, 2=HP, 3=BP, 4=BR, 5=AP)" }, { "name" : "Filter freq" }, { "name" : "Filter Q" }, { "name" : "Filter resonance" } ] }, { "code" : "el:giantFlange", "count" : 7, "display" : "field", "name" : "Giant flange", "number" : "94", "params" : [ { "name" : "Double delay" }, { "name" : "LFO frequency 1 (Hz)" }, { "name" : "Delay 1 range (s)" }, { "name" : "LFO frequency 2 (Hz)" }, { "name" : "Delay 2 range (s)" }, { "name" : "Feedback" }, { "name" : "Dry/Wet level" } ] }, { "code" : "el:Ambisonics-21-panner", "count" : 2, "display" : "field", "name" : "AMB order 2,1 panner", "number" : "95", "params" : [ { "name" : "Elevation" }, { "name" : "Azimuth" } ] }, { "code" : "el:Ambisonics-21-rotator", "count" : 1, "display" : "field", "name" : "AMB order 2,1 rotator", "number" : "96", "params" : [ { "name" : "Angle" } ] }, { "code" : "el:Ambisonics-22-panner", "count" : 2, "display" : "field", "name" : "AMB order 2,2 panner", "number" : "97", "params" : [ { "name" : "Elevation" }, { "name" : "Azimuth" } ] }, { "code" : "el:Ambisonics-22-rotator", "count" : 1, "display" : "field", "name" : "AMB order 2,2 rotator", "number" : "98", "params" : [ { "name" : "Angle" } ] }, { "code" : "el:delay_5s", "count" : 2, "display" : "field", "name" : "Simple Delay Line", "number" : "99", "params" : [ { "name" : "Delay (Seconds)" }, { "name" : "Dry/Wet Balance" } ] }, { "code" : "el:rateShifter", "count" : 1, "display" : "field", "name" : "Rate shifter", "number" : "100", "params" : [ { "name" : "Rate" } ] }, { "code" : "el:invada_stereo_input_module_0_1", "count" : 6, "display" : "field", "name" : ":: Invada :: Input Module", "number" : "101", "params" : [ { "name" : "Phase Reverse (Left)" }, { "name" : "Phase Reverse (Right)" }, { "name" : "Gain (dB)" }, { "name" : "Pan (L-R)" }, { "name" : "Width (M-S)" }, { "name" : "Soft Clip" } ] }, { "code" : "el:amp", "count" : 1, "display" : "field", "name" : "Simple amplifier", "number" : "102", "params" : [ { "name" : "Amps gain (dB)" } ] }, { "code" : "el:const", "count" : 1, "display" : "field", "name" : "Constant Signal Generator", "number" : "103", "params" : [ { "name" : "Signal amplitude" } ] }, { "code" : "el:matrixStMS", "count" : 0, "display" : "field", "name" : "Matrix: Stereo to MS", "number" : "104", "params" : [] }, { "code" : "el:lfoPhaser", "count" : 4, "display" : "field", "name" : "LFO Phaser", "number" : "105", "params" : [ { "name" : "LFO rate (Hz)" }, { "name" : "LFO depth" }, { "name" : "Feedback" }, { "name" : "Spread (octaves)" } ] }, { "code" : "el:fourByFourPole", "count" : 8, "display" : "field", "name" : "4 x 4 pole allpass", "number" : "106", "params" : [ { "name" : "Frequency 1" }, { "name" : "Feedback 1" }, { "name" : "Frequency 2" }, { "name" : "Feedback 2" }, { "name" : "Frequency 3" }, { "name" : "Feedback 3" }, { "name" : "Frequency 4" }, { "name" : "Feedback 4" } ] }, { "code" : "el:autoPhaser", "count" : 5, "display" : "field", "name" : "Auto phaser", "number" : "107", "params" : [ { "name" : "Attack time (s)" }, { "name" : "Decay time (s)" }, { "name" : "Modulation depth" }, { "name" : "Feedback" }, { "name" : "Spread (octaves)" } ] }, { "code" : "el:se4", "count" : 9, "display" : "field", "name" : "SE4", "number" : "108", "params" : [ { "name" : "RMS/peak" }, { "name" : "Attack time (ms)" }, { "name" : "Release time (ms)" }, { "name" : "Threshold level (dB)" }, { "name" : "Ratio (1:n)" }, { "name" : "Knee radius (dB)" }, { "name" : "Attenuation (dB)" }, { "name" : "Amplitude (dB)" }, { "name" : "Gain expansion (dB)" } ] }, { "code" : "el:amPitchshift", "count" : 3, "display" : "field", "name" : "AM pitchshifter", "number" : "109", "params" : [ { "name" : "Pitch shift" }, { "name" : "Buffer size" }, { "name" : "latency" } ] }, { "code" : "el:valveRect", "count" : 2, "display" : "field", "name" : "Valve rectifier", "number" : "110", "params" : [ { "name" : "Sag level" }, { "name" : "Distortion" } ] }, { "code" : "el:tap_doubler", "count" : 8, "display" : "field", "name" : "TAP Fractal Doubler", "number" : "111", "params" : [ { "name" : "Time Tracking" }, { "name" : "Pitch Tracking" }, { "name" : "Dry Level [dB]" }, { "name" : "Dry Left Position" }, { "name" : "Dry Right Position" }, { "name" : "Wet Level [dB]" }, { "name" : "Wet Left Position" }, { "name" : "Wet Right Position" } ] }, { "code" : "el:gong", "count" : 27, "display" : "field", "name" : "Gong model", "number" : "112", "params" : [ { "name" : "Inner damping" }, { "name" : "Outer damping" }, { "name" : "Mic position" }, { "name" : "Inner size 1" }, { "name" : "Inner stiffness 1 +" }, { "name" : "Inner stiffness 1 -" }, { "name" : "Inner size 2" }, { "name" : "Inner stiffness 2 +" }, { "name" : "Inner stiffness 2 -" }, { "name" : "Inner size 3" }, { "name" : "Inner stiffness 3 +" }, { "name" : "Inner stiffness 3 -" }, { "name" : "Inner size 4" }, { "name" : "Inner stiffness 4 +" }, { "name" : "Inner stiffness 4 -" }, { "name" : "Outer size 1" }, { "name" : "Outer stiffness 1 +" }, { "name" : "Outer stiffness 1 -" }, { "name" : "Outer size 2" }, { "name" : "Outer stiffness 2 +" }, { "name" : "Outer stiffness 2 -" }, { "name" : "Outer size 3" }, { "name" : "Outer stiffness 3 +" }, { "name" : "Outer stiffness 3 -" }, { "name" : "Outer size 4" }, { "name" : "Outer stiffness 4 +" }, { "name" : "Outer stiffness 4 -" } ] }, { "code" : "el:invada_mono_compressor_module_0_1", "count" : 8, "display" : "field", "name" : ":: Invada :: Compressor - Mono", "number" : "113", "params" : [ { "name" : "Tight / Sloppy" }, { "name" : "Attack (ms)" }, { "name" : "Release (ms)" }, { "name" : "Threshold (dB)" }, { "name" : "Ratio" }, { "name" : "Gain (dB)" }, { "name" : "Soft Clip" }, { "name" : "Gain Reduction" } ] }, { "code" : "el:invada_stereo_compressor_module_0_1", "count" : 8, "display" : "field", "name" : ":: Invada :: Compressor - Stereo", "number" : "114", "params" : [ { "name" : "Tight / Sloppy" }, { "name" : "Attack (ms)" }, { "name" : "Release (ms)" }, { "name" : "Threshold (dB)" }, { "name" : "Ratio" }, { "name" : "Gain (dB)" }, { "name" : "Soft Clip" }, { "name" : "Gain Reduction" } ] }, { "code" : "el:gate", "count" : 8, "display" : "field", "name" : "Gate", "number" : "115", "params" : [ { "name" : "LF key filter (Hz)" }, { "name" : "HF key filter (Hz)" }, { "name" : "Threshold (dB)" }, { "name" : "Attack (ms)" }, { "name" : "Hold (ms)" }, { "name" : "Decay (ms)" }, { "name" : "Range (dB)" }, { "name" : "Output select (-1 = key listen, 0 = gate, 1 = bypass)" } ] }, { "code" : "el:stepMuxer", "count" : 1, "display" : "field", "name" : "Step Demuxer", "number" : "116", "params" : [ { "name" : "Crossfade time (in ms)" } ] }, { "code" : "el:dj_eq_mono", "count" : 4, "display" : "field", "name" : "DJ EQ (mono)", "number" : "117", "params" : [ { "name" : "Lo gain (dB)" }, { "name" : "Mid gain (dB)" }, { "name" : "Hi gain (dB)" }, { "name" : "latency" } ] }, { "code" : "el:dj_eq", "count" : 4, "display" : "field", "name" : "DJ EQ", "number" : "118", "params" : [ { "name" : "Lo gain (dB)" }, { "name" : "Mid gain (dB)" }, { "name" : "Hi gain (dB)" }, { "name" : "latency" } ] }, { "code" : "el:djFlanger", "count" : 4, "display" : "field", "name" : "DJ flanger", "number" : "119", "params" : [ { "name" : "LFO sync" }, { "name" : "LFO period (s)" }, { "name" : "LFO depth (ms)" }, { "name" : "Feedback (%)" } ] }, { "code" : "el:dysonCompress", "count" : 4, "display" : "field", "name" : "Dyson compressor", "number" : "120", "params" : [ { "name" : "Peak limit (dB)" }, { "name" : "Release time (s)" }, { "name" : "Fast compression ratio" }, { "name" : "Compression ratio" } ] }, { "code" : "el:sinusWavewrapper", "count" : 1, "display" : "field", "name" : "Sinus wavewrapper", "number" : "121", "params" : [ { "name" : "Wrap degree" } ] }, { "code" : "el:alias", "count" : 1, "display" : "field", "name" : "Aliasing", "number" : "122", "params" : [ { "name" : "Aliasing level" } ] }, { "code" : "el:gverb", "count" : 7, "display" : "field", "name" : "GVerb", "number" : "123", "params" : [ { "name" : "Roomsize (m)" }, { "name" : "Reverb time (s)" }, { "name" : "Damping" }, { "name" : "Input bandwidth" }, { "name" : "Dry signal level (dB)" }, { "name" : "Early reflection level (dB)" }, { "name" : "Tail level (dB)" } ] }, { "code" : "el:freqTracker", "count" : 1, "display" : "field", "name" : "Frequency tracker", "number" : "124", "params" : [ { "name" : "Tracking speed" } ] }, { "code" : "el:pointerCastDistortion", "count" : 2, "display" : "field", "name" : "Pointer cast distortion", "number" : "125", "params" : [ { "name" : "Effect cutoff freq (Hz)" }, { "name" : "Dry/wet mix" } ] }, { "code" : "el:tap_equalizer_bw", "count" : 24, "display" : "field", "name" : "TAP Equalizer/BW", "number" : "126", "params" : [ { "name" : "Band 1 Gain [dB]" }, { "name" : "Band 2 Gain [dB]" }, { "name" : "Band 3 Gain [dB]" }, { "name" : "Band 4 Gain [dB]" }, { "name" : "Band 5 Gain [dB]" }, { "name" : "Band 6 Gain [dB]" }, { "name" : "Band 7 Gain [dB]" }, { "name" : "Band 8 Gain [dB]" }, { "name" : "Band 1 Freq [Hz]" }, { "name" : "Band 2 Freq [Hz]" }, { "name" : "Band 3 Freq [Hz]" }, { "name" : "Band 4 Freq [Hz]" }, { "name" : "Band 5 Freq [Hz]" }, { "name" : "Band 6 Freq [Hz]" }, { "name" : "Band 7 Freq [Hz]" }, { "name" : "Band 8 Freq [Hz]" }, { "name" : "Band 1 Bandwidth [octaves]" }, { "name" : "Band 2 Bandwidth [octaves]" }, { "name" : "Band 3 Bandwidth [octaves]" }, { "name" : "Band 4 Bandwidth [octaves]" }, { "name" : "Band 5 Bandwidth [octaves]" }, { "name" : "Band 6 Bandwidth [octaves]" }, { "name" : "Band 7 Bandwidth [octaves]" }, { "name" : "Band 8 Bandwidth [octaves]" } ] }, { "code" : "el:gsm", "count" : 4, "display" : "field", "name" : "GSM simulator", "number" : "127", "params" : [ { "name" : "Dry/wet mix" }, { "name" : "Number of passes" }, { "name" : "Error rate (bits/block)" }, { "name" : "latency" } ] }, { "code" : "el:revdelay", "count" : 5, "display" : "field", "name" : "Reverse Delay (5s max)", "number" : "128", "params" : [ { "name" : "Delay Time (s)" }, { "name" : "Dry Level (dB)" }, { "name" : "Wet Level (dB)" }, { "name" : "Feedback" }, { "name" : "Crossfade samples" } ] }, { "code" : "el:karaoke", "count" : 1, "display" : "field", "name" : "Karaoke", "number" : "129", "params" : [ { "name" : "Vocal volume (dB)" } ] }, { "code" : "el:dcRemove", "count" : 0, "display" : "field", "name" : "DC Offset Remover", "number" : "130", "params" : [] }, { "code" : "el:Ambisonics-31-panner", "count" : 2, "display" : "field", "name" : "AMB order 3,1 panner", "number" : "131", "params" : [ { "name" : "Elevation" }, { "name" : "Azimuth" } ] }, { "code" : "el:Ambisonics-31-rotator", "count" : 1, "display" : "field", "name" : "AMB order 3,1 rotator", "number" : "132", "params" : [ { "name" : "Angle" } ] }, { "code" : "el:Ambisonics-33-panner", "count" : 2, "display" : "field", "name" : "AMB order 3,3 panner", "number" : "133", "params" : [ { "name" : "Elevation" }, { "name" : "Azimuth" } ] }, { "code" : "el:Ambisonics-33-rotator", "count" : 1, "display" : "field", "name" : "AMB order 3,3 rotator", "number" : "134", "params" : [ { "name" : "Angle" } ] }, { "code" : "el:sc1", "count" : 6, "display" : "field", "name" : "SC1", "number" : "135", "params" : [ { "name" : "Attack time (ms)" }, { "name" : "Release time (ms)" }, { "name" : "Threshold level (dB)" }, { "name" : "Ratio (1:n)" }, { "name" : "Knee radius (dB)" }, { "name" : "Makeup gain (dB)" } ] }, { "code" : "el:foldover", "count" : 2, "display" : "field", "name" : "Foldover distortion", "number" : "136", "params" : [ { "name" : "Drive" }, { "name" : "Skew" } ] }, { "code" : "el:hardLimiter", "count" : 3, "display" : "field", "name" : "Hard Limiter", "number" : "137", "params" : [ { "name" : "dB limit" }, { "name" : "Wet level" }, { "name" : "Residue level" } ] }, { "code" : "el:lsFilter", "count" : 3, "display" : "field", "name" : "LS Filter", "number" : "138", "params" : [ { "name" : "Filter type (0=LP, 1=BP, 2=HP)" }, { "name" : "Cutoff frequency (Hz)" }, { "name" : "Resonance" } ] }, { "code" : "el:matrixSpatialiser", "count" : 1, "display" : "field", "name" : "Matrix Spatialiser", "number" : "139", "params" : [ { "name" : "Width" } ] }, { "code" : "el:invada_mono_reverbER_module_0_1", "count" : 10, "display" : "field", "name" : ":: Invada :: ER Reverb - Mono In", "number" : "140", "params" : [ { "name" : "Room Length" }, { "name" : "Room Width" }, { "name" : "Room Height" }, { "name" : "Source (L/R)" }, { "name" : "Source (F/B)" }, { "name" : "Listener (L/R)" }, { "name" : "Listener (F/B)" }, { "name" : "HPF (Hz)" }, { "name" : "Warmth" }, { "name" : "Diffusion" } ] }, { "code" : "el:invada_sum_reverbER_module_0_1", "count" : 10, "display" : "field", "name" : ":: Invada :: ER Reverb - Sum L+R In", "number" : "141", "params" : [ { "name" : "Room Length" }, { "name" : "Room Width" }, { "name" : "Room Height" }, { "name" : "Source (L/R)" }, { "name" : "Source (F/B)" }, { "name" : "Listener (L/R)" }, { "name" : "Listener (F/B)" }, { "name" : "HPF (Hz)" }, { "name" : "Warmth" }, { "name" : "Diffusion" } ] }, { "code" : "el:imp", "count" : 4, "display" : "field", "name" : "Impulse convolver", "number" : "142", "params" : [ { "name" : "Impulse ID" }, { "name" : "High latency mode" }, { "name" : "Gain (dB)" }, { "name" : "latency" } ] }, { "code" : "el:highpass_iir", "count" : 2, "display" : "field", "name" : "Glame Highpass Filter", "number" : "143", "params" : [ { "name" : "Cutoff Frequency" }, { "name" : "Stages(2 poles per stage)" } ] }, { "code" : "el:pitchScale", "count" : 2, "display" : "field", "name" : "Pitch Scaler", "number" : "144", "params" : [ { "name" : "Pitch co-efficient" }, { "name" : "latency" } ] }, { "code" : "el:G2reverb", "count" : 7, "display" : "field", "name" : "Stereo reverb", "number" : "145", "params" : [ { "name" : "Room size" }, { "name" : "Reverb time" }, { "name" : "Input BW" }, { "name" : "Damping" }, { "name" : "Dry sound" }, { "name" : "Reflections" }, { "name" : "Reverb tail" } ] }, { "code" : "el:zita-reverb", "count" : 10, "display" : "field", "name" : "zita-reverb", "number" : "146", "params" : [ { "name" : "Delay" }, { "name" : "Xover" }, { "name" : "RT-low" }, { "name" : "RT-mid" }, { "name" : "Damping" }, { "name" : "F1-freq" }, { "name" : "F1-gain" }, { "name" : "F2-freq" }, { "name" : "F2-gain" }, { "name" : "Output mix" } ] }, { "code" : "el:zita-reverb-amb", "count" : 10, "display" : "field", "name" : "zita-reverb-amb", "number" : "147", "params" : [ { "name" : "Delay" }, { "name" : "Xover" }, { "name" : "RT-low" }, { "name" : "RT-mid" }, { "name" : "Damping" }, { "name" : "F1-freq" }, { "name" : "F1-gain" }, { "name" : "F2-freq" }, { "name" : "F2-gain" }, { "name" : "XYZ gain" } ] }, { "code" : "el:tap_autopan", "count" : 3, "display" : "field", "name" : "TAP AutoPanner", "number" : "148", "params" : [ { "name" : "Frequency [Hz]" }, { "name" : "Depth [%]" }, { "name" : "Gain [dB]" } ] }, { "code" : "el:flanger", "count" : 4, "display" : "field", "name" : "Flanger", "number" : "149", "params" : [ { "name" : "Delay base (ms)" }, { "name" : "Max slowdown (ms)" }, { "name" : "LFO frequency (Hz)" }, { "name" : "Feedback" } ] }, { "code" : "el:tap_reverb", "count" : 8, "display" : "field", "name" : "TAP Reverberator", "number" : "150", "params" : [ { "name" : "Decay [ms]" }, { "name" : "Dry Level [dB]" }, { "name" : "Wet Level [dB]" }, { "name" : "Comb Filters" }, { "name" : "Allpass Filters" }, { "name" : "Bandpass Filter" }, { "name" : "Enhanced Stereo" }, { "name" : "Reverb Type" } ] }, { "code" : "el:split", "count" : 0, "display" : "field", "name" : "Mono to Stereo splitter", "number" : "151", "params" : [] }, { "code" : "el:plate", "count" : 3, "display" : "field", "name" : "Plate reverb", "number" : "152", "params" : [ { "name" : "Reverb time" }, { "name" : "Damping" }, { "name" : "Dry/wet mix" } ] }, { "code" : "el:triplePara", "count" : 15, "display" : "field", "name" : "Triple band parametric with shelves", "number" : "153", "params" : [ { "name" : "Low-shelving gain (dB)" }, { "name" : "Low-shelving frequency (Hz)" }, { "name" : "Low-shelving slope" }, { "name" : "Band 1 gain (dB)" }, { "name" : "Band 1 frequency (Hz)" }, { "name" : "Band 1 bandwidth (octaves)" }, { "name" : "Band 2 gain (dB)" }, { "name" : "Band 2 frequency (Hz)" }, { "name" : "Band 2 bandwidth (octaves)" }, { "name" : "Band 3 gain (dB)" }, { "name" : "Band 3 frequency (Hz)" }, { "name" : "Band 3 bandwidth (octaves)" }, { "name" : "High-shelving gain (dB)" }, { "name" : "High-shelving frequency (Hz)" }, { "name" : "High-shelving slope" } ] }, { "code" : "el:tap_dynamics_m", "count" : 7, "display" : "field", "name" : "TAP Dynamics (M)", "number" : "154", "params" : [ { "name" : "Attack [ms]" }, { "name" : "Release [ms]" }, { "name" : "Offset Gain [dB]" }, { "name" : "Makeup Gain [dB]" }, { "name" : "Envelope Volume [dB]" }, { "name" : "Gain Adjustment [dB]" }, { "name" : "Function" } ] }, { "code" : "el:xfade", "count" : 1, "display" : "field", "name" : "Crossfade", "number" : "155", "params" : [ { "name" : "Crossfade" } ] }, { "code" : "el:xfade4", "count" : 1, "display" : "field", "name" : "Crossfade (4 outs)", "number" : "156", "params" : [ { "name" : "Crossfade" } ] }, { "code" : "el:tap_dynamics_st", "count" : 10, "display" : "field", "name" : "TAP Dynamics (St)", "number" : "157", "params" : [ { "name" : "Attack [ms]" }, { "name" : "Release [ms]" }, { "name" : "Offset Gain [dB]" }, { "name" : "Makeup Gain [dB]" }, { "name" : "Envelope Volume (L) [dB]" }, { "name" : "Envelope Volume (R) [dB]" }, { "name" : "Gain Adjustment (L) [dB]" }, { "name" : "Gain Adjustment (R) [dB]" }, { "name" : "Stereo Mode" }, { "name" : "Function" } ] }, { "code" : "el:lpf", "count" : 1, "display" : "field", "name" : "Simple Low Pass Filter", "number" : "158", "params" : [ { "name" : "Cutoff Frequency (Hz)" } ] }, { "code" : "el:hpf", "count" : 1, "display" : "field", "name" : "Simple High Pass Filter", "number" : "159", "params" : [ { "name" : "Cutoff Frequency (Hz)" } ] }, { "code" : "el:ringmod_2i1o", "count" : 1, "display" : "field", "name" : "Ringmod with two inputs", "number" : "160", "params" : [ { "name" : "Modulation depth (0=none, 1=AM, 2=RM)" } ] }, { "code" : "el:ringmod_1i1o1l", "count" : 6, "display" : "field", "name" : "Ringmod with LFO", "number" : "161", "params" : [ { "name" : "Modulation depth (0=none, 1=AM, 2=RM)" }, { "name" : "Frequency (Hz)" }, { "name" : "Sine level" }, { "name" : "Triangle level" }, { "name" : "Sawtooth level" }, { "name" : "Square level" } ] }, { "code" : "el:comb", "count" : 2, "display" : "field", "name" : "Comb Filter", "number" : "162", "params" : [ { "name" : "Band separation (Hz)" }, { "name" : "Feedback" } ] }, { "code" : "el:tapeDelay", "count" : 10, "display" : "field", "name" : "Tape Delay Simulation", "number" : "163", "params" : [ { "name" : "Tape speed (inches/sec, 1=normal)" }, { "name" : "Dry level (dB)" }, { "name" : "Tap 1 distance (inches)" }, { "name" : "Tap 1 level (dB)" }, { "name" : "Tap 2 distance (inches)" }, { "name" : "Tap 2 level (dB)" }, { "name" : "Tap 3 distance (inches)" }, { "name" : "Tap 3 level (dB)" }, { "name" : "Tap 4 distance (inches)" }, { "name" : "Tap 4 level (dB)" } ] }, { "code" : "el:shaper", "count" : 1, "display" : "field", "name" : "Wave shaper", "number" : "164", "params" : [ { "name" : "Waveshape" } ] }, { "code" : "el:tap_deesser", "count" : 5, "display" : "field", "name" : "TAP DeEsser", "number" : "165", "params" : [ { "name" : "Threshold Level [dB]" }, { "name" : "Frequency [Hz]" }, { "name" : "Sidechain Filter" }, { "name" : "Monitor" }, { "name" : "Attenuation [dB]" } ] }, { "code" : "el:bodeShifterCV", "count" : 4, "display" : "field", "name" : "Bode frequency shifter (CV)", "number" : "166", "params" : [ { "name" : "Base shift" }, { "name" : "Mix (-1=down, +1=up)" }, { "name" : "CV Attenuation" }, { "name" : "latency" } ] }, { "code" : "el:chebstortion", "count" : 1, "display" : "field", "name" : "Chebyshev distortion", "number" : "167", "params" : [ { "name" : "Distortion" } ] }, { "code" : "el:surroundEncoder", "count" : 0, "display" : "field", "name" : "Surround matrix encoder", "number" : "168", "params" : [] }, { "code" : "el:divider", "count" : 1, "display" : "field", "name" : "Audio Divider (Suboctave Generator)", "number" : "169", "params" : [ { "name" : "Denominator" } ] }, { "code" : "el:modDelay", "count" : 1, "display" : "field", "name" : "Modulatable delay", "number" : "170", "params" : [ { "name" : "Base delay (s)" } ] }, { "code" : "el:combSplitter", "count" : 1, "display" : "field", "name" : "Comb Splitter", "number" : "171", "params" : [ { "name" : "Band separation (Hz)" } ] }, { "code" : "el:sc2", "count" : 6, "display" : "field", "name" : "SC2", "number" : "172", "params" : [ { "name" : "Attack time (ms)" }, { "name" : "Release time (ms)" }, { "name" : "Threshold level (dB)" }, { "name" : "Ratio (1:n)" }, { "name" : "Knee radius (dB)" }, { "name" : "Makeup gain (dB)" } ] }, { "code" : "el:allpass_n", "count" : 3, "display" : "field", "name" : "Allpass delay line, noninterpolating", "number" : "173", "params" : [ { "name" : "Max Delay (s)" }, { "name" : "Delay Time (s)" }, { "name" : "Decay Time (s)" } ] }, { "code" : "el:allpass_l", "count" : 3, "display" : "field", "name" : "Allpass delay line, linear interpolation", "number" : "174", "params" : [ { "name" : "Max Delay (s)" }, { "name" : "Delay Time (s)" }, { "name" : "Decay Time (s)" } ] }, { "code" : "el:allpass_c", "count" : 3, "display" : "field", "name" : "Allpass delay line, cubic spline interpolation", "number" : "175", "params" : [ { "name" : "Max Delay (s)" }, { "name" : "Delay Time (s)" }, { "name" : "Decay Time (s)" } ] }, { "code" : "el:tap_tubewarmth", "count" : 2, "display" : "field", "name" : "TAP TubeWarmth", "number" : "176", "params" : [ { "name" : "Drive" }, { "name" : "Tape--Tube Blend" } ] }, { "code" : "el:sinCos", "count" : 2, "display" : "field", "name" : "Sine + cosine oscillator", "number" : "177", "params" : [ { "name" : "Base frequency (Hz)" }, { "name" : "Pitch offset" } ] }, { "code" : "el:sifter", "count" : 1, "display" : "field", "name" : "Signal sifter", "number" : "178", "params" : [ { "name" : "Sift size" } ] }, { "code" : "el:notch_iir", "count" : 3, "display" : "field", "name" : "Mag's Notch Filter", "number" : "179", "params" : [ { "name" : "Center Frequency (Hz)" }, { "name" : "Bandwidth (Hz)" }, { "name" : "Stages(2 poles per stage)" } ] }, { "code" : "el:Tricardioid-to-AMB", "count" : 0, "display" : "field", "name" : "Three cardioids to AMB matrix", "number" : "180", "params" : [] }, { "code" : "el:Virtualmic", "count" : 4, "display" : "field", "name" : "Virtual stereo microphone", "number" : "181", "params" : [ { "name" : "Elevation" }, { "name" : "Azimuth" }, { "name" : "Angle" }, { "name" : "Polar" } ] }, { "code" : "el:UHJ-encoder", "count" : 0, "display" : "field", "name" : "UHJ Encoder", "number" : "182", "params" : [] }, { "code" : "el:UHJ-decoder", "count" : 0, "display" : "field", "name" : "UHJ Decoder", "number" : "183", "params" : [] }, { "code" : "el:pitchScaleHQ", "count" : 2, "display" : "field", "name" : "Higher Quality Pitch Scaler", "number" : "184", "params" : [ { "name" : "Pitch co-efficient" }, { "name" : "latency" } ] }, { "code" : "el:crossoverDist", "count" : 2, "display" : "field", "name" : "Crossover distortion", "number" : "185", "params" : [ { "name" : "Crossover amplitude" }, { "name" : "Smoothing" } ] }, { "code" : "el:Ambisonics-11-mono-panner", "count" : 2, "display" : "field", "name" : "AMB order 1,1 mono panner", "number" : "186", "params" : [ { "name" : "Elevation" }, { "name" : "Azimuth" } ] }, { "code" : "el:Ambisonics-11-stereo-panner", "count" : 3, "display" : "field", "name" : "AMB order 1,1 stereo panner", "number" : "187", "params" : [ { "name" : "Elevation" }, { "name" : "Width" }, { "name" : "Azimuth" } ] }, { "code" : "el:Ambisonics-11-rotator", "count" : 1, "display" : "field", "name" : "AMB order 1,1 rotator", "number" : "188", "params" : [ { "name" : "Angle" } ] }, { "code" : "el:Ambisonics-11-square-decoder", "count" : 6, "display" : "field", "name" : "AMB order 1,1 square decoder", "number" : "189", "params" : [ { "name" : "Front spkr" }, { "name" : "Shelf filt" }, { "name" : "HF XY gain" }, { "name" : "LF XY gain" }, { "name" : "Shelf freq" }, { "name" : "Distance" } ] }, { "code" : "el:Ambisonics-11-hexagon-decoder", "count" : 6, "display" : "field", "name" : "AMB order 1,1 hexagon decoder", "number" : "190", "params" : [ { "name" : "Front spkr" }, { "name" : "Shelf filt" }, { "name" : "HF XY gain" }, { "name" : "LF XY gain" }, { "name" : "Shelf freq" }, { "name" : "Distance" } ] }, { "code" : "el:Ambisonics-11-cube-decoder", "count" : 5, "display" : "field", "name" : "AMB order 1,1 cube decoder", "number" : "191", "params" : [ { "name" : "Shelf filt" }, { "name" : "HF XYZ gain" }, { "name" : "LF XYZ gain" }, { "name" : "Shelf freq" }, { "name" : "Distance" } ] }, { "code" : "el:tap_pinknoise", "count" : 3, "display" : "field", "name" : "TAP Pink/Fractal Noise", "number" : "192", "params" : [ { "name" : "Fractal Dimension" }, { "name" : "Signal Level [dB]" }, { "name" : "Noise Level [dB]" } ] }, { "code" : "el:tap_reflector", "count" : 3, "display" : "field", "name" : "TAP Reflector", "number" : "193", "params" : [ { "name" : "Fragment Length [ms]" }, { "name" : "Dry Level [dB]" }, { "name" : "Wet Level [dB]" } ] }, { "code" : "el:noise_white", "count" : 1, "display" : "field", "name" : "White Noise Source", "number" : "194", "params" : [ { "name" : "Amplitude" } ] }, { "code" : "el:diode", "count" : 1, "display" : "field", "name" : "Diode Processor", "number" : "195", "params" : [ { "name" : "Mode (0 for none, 1 for half wave, 2 for full wave)" } ] }, { "code" : "pn:dyn_compress_brutal", "count" : 1, "display" : "field", "name" : "dyn_compress_brutal", "number" : "1", "params" : [ { "name" : "gain-%" } ] }, { "code" : "pn:dyn_compress_hard", "count" : 1, "display" : "field", "name" : "dyn_compress_hard", "number" : "2", "params" : [ { "name" : "gain-%" } ] }, { "code" : "pn:dyn_compress_infinite", "count" : 1, "display" : "field", "name" : "dyn_compress_infinite", "number" : "3", "params" : [ { "name" : "gain-%" } ] }, { "code" : "pn:dyn_compress_medium", "count" : 1, "display" : "field", "name" : "dyn_compress_medium", "number" : "4", "params" : [ { "name" : "gain-%" } ] }, { "code" : "pn:dyn_compress_soft", "count" : 1, "display" : "field", "name" : "dyn_compress_soft", "number" : "5", "params" : [ { "name" : "gain-%" } ] }, { "code" : "pn:dyn_compress_supersoft", "count" : 1, "display" : "field", "name" : "dyn_compress_supersoft", "number" : "6", "params" : [ { "name" : "gain-%" } ] }, { "code" : "pn:eq_template", "count" : 10, "display" : "field", "name" : "eq_template", "number" : "7", "params" : [ { "name" : "10hz" }, { "name" : "40hz" }, { "name" : "100hz" }, { "name" : "220hz" }, { "name" : "460hz" }, { "name" : "940hz" }, { "name" : "1900hz" }, { "name" : "3800hz" }, { "name" : "7620hz" }, { "name" : "15300hz" } ] }, { "code" : "pn:eq_template2", "count" : 2, "display" : "field", "name" : "eq_template2", "number" : "8", "params" : [ { "name" : "1000hz" }, { "name" : "4000hz" } ] }, { "code" : "pn:f_bandpass", "count" : 2, "display" : "field", "name" : "f_bandpass", "number" : "9", "params" : [ { "name" : "freq" }, { "name" : "width" } ] }, { "code" : "pn:f_filtertest", "count" : 2, "display" : "field", "name" : "f_filtertest", "number" : "10", "params" : [ { "name" : "freq1" }, { "name" : "freq2" } ] }, { "code" : "pn:f_high_and_low", "count" : 0, "display" : "field", "name" : "f_high_and_low", "number" : "11", "params" : [] }, { "code" : "pn:f_highpass", "count" : 0, "display" : "field", "name" : "f_highpass", "number" : "12", "params" : [] }, { "code" : "pn:f_inverse_comb", "count" : 0, "display" : "field", "name" : "f_inverse_comb", "number" : "13", "params" : [] }, { "code" : "pn:f_lowp_sine", "count" : 0, "display" : "field", "name" : "f_lowp_sine", "number" : "14", "params" : [] }, { "code" : "pn:f_lowp_sine2", "count" : 0, "display" : "field", "name" : "f_lowp_sine2", "number" : "15", "params" : [] }, { "code" : "pn:f_lowpass", "count" : 1, "display" : "field", "name" : "f_lowpass", "number" : "16", "params" : [ { "name" : "freq_hz" } ] }, { "code" : "pn:f_rejectband", "count" : 0, "display" : "field", "name" : "f_rejectband", "number" : "17", "params" : [] }, { "code" : "pn:f_res_bandpass", "count" : 2, "display" : "field", "name" : "f_res_bandpass", "number" : "18", "params" : [ { "name" : "freq" }, { "name" : "width" } ] }, { "code" : "pn:f_res_lowpass", "count" : 1, "display" : "field", "name" : "f_res_lowpass", "number" : "19", "params" : [ { "name" : "arg-1" } ] }, { "code" : "pn:f_resonator", "count" : 0, "display" : "field", "name" : "f_resonator", "number" : "20", "params" : [] }, { "code" : "pn:f_two_filters", "count" : 2, "display" : "field", "name" : "f_two_filters", "number" : "21", "params" : [ { "name" : "lowgain" }, { "name" : "highgain" } ] }, { "code" : "pn:f_two_filters_pareq", "count" : 4, "display" : "field", "name" : "f_two_filters_pareq", "number" : "22", "params" : [ { "name" : "lowfreq" }, { "name" : "lowgain" }, { "name" : "highfreq" }, { "name" : "highgain" } ] }, { "code" : "pn:gate_crop", "count" : 0, "display" : "field", "name" : "gate_crop", "number" : "23", "params" : [] }, { "code" : "pn:gate_noisegate_1", "count" : 0, "display" : "field", "name" : "gate_noisegate_1", "number" : "24", "params" : [] }, { "code" : "pn:gate_noisegate_delanalog", "count" : 0, "display" : "field", "name" : "gate_noisegate_delanalog", "number" : "25", "params" : [] }, { "code" : "pn:gate_threshold", "count" : 0, "display" : "field", "name" : "gate_threshold", "number" : "26", "params" : [] }, { "code" : "pn:lad_hermes", "count" : 4, "display" : "field", "name" : "lad_hermes", "number" : "27", "params" : [ { "name" : "p1" }, { "name" : "p2" }, { "name" : "p3" }, { "name" : "p4" } ] }, { "code" : "pn:lad_metronome", "count" : 1, "display" : "field", "name" : "lad_metronome", "number" : "28", "params" : [ { "name" : "bpm" } ] }, { "code" : "pn:lad_oscillator_stack", "count" : 5, "display" : "field", "name" : "lad_oscillator_stack", "number" : "29", "params" : [ { "name" : "freq" }, { "name" : "osctype1" }, { "name" : "osctype2" }, { "name" : "gain1" }, { "name" : "gain2" } ] }, { "code" : "pn:lad_oscillator_test", "count" : 2, "display" : "field", "name" : "lad_oscillator_test", "number" : "30", "params" : [ { "name" : "freq" }, { "name" : "gain1" } ] }, { "code" : "pn:lad_sc4", "count" : 2, "display" : "field", "name" : "lad_sc4", "number" : "31", "params" : [ { "name" : "output-amplitude-dB" }, { "name" : "output-gain-reduction-dB" } ] }, { "code" : "pn:lad_sc4_rg", "count" : 4, "display" : "field", "name" : "lad_sc4_rg", "number" : "32", "params" : [ { "name" : "ratio" }, { "name" : "gain-dB" }, { "name" : "output-amplitude-dB" }, { "name" : "output-gain-reduction-dB" } ] }, { "code" : "pn:metronome", "count" : "1", "display" : "scale", "name" : "Metronome", "params" : [ { "begin" : "30", "default" : "120", "end" : "300", "name" : "BPM", "resolution" : "1" } ] }, { "code" : "pn:time_chorus1", "count" : 0, "display" : "field", "name" : "time_chorus1", "number" : "34", "params" : [] }, { "code" : "pn:time_delay1", "count" : 0, "display" : "field", "name" : "time_delay1", "number" : "35", "params" : [] }, { "code" : "pn:time_delay2", "count" : 0, "display" : "field", "name" : "time_delay2", "number" : "36", "params" : [] }, { "code" : "pn:time_flanger1", "count" : 0, "display" : "field", "name" : "time_flanger1", "number" : "37", "params" : [] }, { "code" : "pn:time_phaser1", "count" : 0, "display" : "field", "name" : "time_phaser1", "number" : "38", "params" : [] }, { "code" : "pn:time_reverb1", "count" : 0, "display" : "field", "name" : "time_reverb1", "number" : "39", "params" : [] }, { "code" : "pn:time_reverb2", "count" : 0, "display" : "field", "name" : "time_reverb2", "number" : "40", "params" : [] }, { "code" : "pn:time_reverb3", "count" : 0, "display" : "field", "name" : "time_reverb3", "number" : "41", "params" : [] }, { "code" : "pn:time_reverb4", "count" : 0, "display" : "field", "name" : "time_reverb4", "number" : "42", "params" : [] }, { "code" : "pn:time_wicked_dub", "count" : 0, "display" : "field", "name" : "time_wicked_dub", "number" : "43", "params" : [] }, { "code" : "pn:var_aw", "count" : 1, "display" : "field", "name" : "var_aw", "number" : "44", "params" : [ { "name" : "speed" } ] }, { "code" : "pn:var_aw_custom", "count" : 3, "display" : "field", "name" : "var_aw_custom", "number" : "45", "params" : [ { "name" : "low" }, { "name" : "high" }, { "name" : "speed" } ] }, { "code" : "pn:var_aw_ksv", "count" : 0, "display" : "field", "name" : "var_aw_ksv", "number" : "46", "params" : [] }, { "code" : "pn:var_aw_tri", "count" : 1, "display" : "field", "name" : "var_aw_tri", "number" : "47", "params" : [ { "name" : "speed" } ] }, { "code" : "pn:var_aw_tri_custom", "count" : 1, "display" : "field", "name" : "var_aw_tri_custom", "number" : "48", "params" : [ { "name" : "speed" } ] }, { "code" : "pn:var_chipmunk", "count" : 0, "display" : "field", "name" : "var_chipmunk", "number" : "49", "params" : [] }, { "code" : "pn:var_dali", "count" : 0, "display" : "field", "name" : "var_dali", "number" : "50", "params" : [] }, { "code" : "pn:var_molten_tape", "count" : 0, "display" : "field", "name" : "var_molten_tape", "number" : "51", "params" : [] }, { "code" : "pn:var_paralmadness", "count" : 3, "display" : "field", "name" : "var_paralmadness", "number" : "52", "params" : [ { "name" : "freq1" }, { "name" : "freq2" }, { "name" : "freq3" } ] }, { "code" : "pn:var_parchip", "count" : 2, "display" : "field", "name" : "var_parchip", "number" : "53", "params" : [ { "name" : "pitch" }, { "name" : "modfreq" } ] }, { "code" : "pn:var_stretched_tape", "count" : 0, "display" : "field", "name" : "var_stretched_tape", "number" : "54", "params" : [] }, { "code" : "pn:var_sweeping_pan", "count" : 1, "display" : "field", "name" : "var_sweeping_pan", "number" : "55", "params" : [ { "name" : "speed_hz" } ] }, { "code" : "pn:var_switching_pan", "count" : 1, "display" : "field", "name" : "var_switching_pan", "number" : "56", "params" : [ { "name" : "speed_hz" } ] }, { "code" : "kf", "count" : 6, "display" : "field", "name" : "Generic oscillator (preset)", "number" : "1", "params" : [ { "name" : "param-id" }, { "name" : "range-low" }, { "name" : "range-high" }, { "name" : "freq" }, { "name" : "mode" }, { "name" : "preset-number" } ] }, { "code" : "kog", "count" : 8, "display" : "field", "name" : "Generic oscillator", "number" : "2", "params" : [ { "name" : "param-id" }, { "name" : "range-low" }, { "name" : "range-high" }, { "name" : "freq" }, { "name" : "mode" }, { "name" : "pcount" }, { "name" : "start_val" }, { "name" : "end_val" } ] }, { "code" : "kl", "count" : 4, "display" : "field", "name" : "Linear envelope", "number" : "3", "params" : [ { "name" : "param-id" }, { "name" : "range-low" }, { "name" : "range-high" }, { "name" : "length-sec" } ] }, { "code" : "kl2", "count" : 5, "display" : "field", "name" : "Two-stage linear envelope", "number" : "4", "params" : [ { "name" : "param-id" }, { "name" : "range-low" }, { "name" : "range-high" }, { "name" : "1st-stage-sec" }, { "name" : "2nd-stage-sec" } ] }, { "code" : "klg", "count" : 4, "display" : "field", "name" : "Generic linear envelope", "number" : "5", "params" : [ { "name" : "param-id" }, { "name" : "range-low" }, { "name" : "range-high" }, { "name" : "point_count" } ] }, { "code" : "km", "count" : 5, "display" : "field", "name" : "MIDI-Controller", "number" : "6", "params" : [ { "name" : "param-id" }, { "name" : "range-low" }, { "name" : "range-high" }, { "name" : "controller" }, { "name" : "channel" } ] }, { "code" : "kos", "count" : 5, "display" : "field", "name" : "Sine oscillator", "number" : "7", "params" : [ { "name" : "param-id" }, { "name" : "range-low" }, { "name" : "range-high" }, { "name" : "freq" }, { "name" : "phase-offset" } ] }, { "code" : "ksv", "count" : 5, "display" : "field", "name" : "Volume analyze controller", "number" : "8", "params" : [ { "name" : "param-id" }, { "name" : "range-low" }, { "name" : "range-high" }, { "name" : "stamp-id" }, { "name" : "rms-toggle" } ] }, { "code" : "elv2:http://gareus.org/oss/lv2/b_overdrive", "count" : 7, "display" : "field", "name" : "B Organ Overdrive", "number" : "1", "params" : [ { "name" : "Bias" }, { "name" : "Feedback" }, { "name" : "SagToBias" }, { "name" : "Postdiff feedback" }, { "name" : "Global feedback" }, { "name" : "Input Gain" }, { "name" : "Output Gain" } ] }, { "code" : "elv2:http://gareus.org/oss/lv2/b_reverb", "count" : 2, "display" : "field", "name" : "B Organ Reverb", "number" : "2", "params" : [ { "name" : "Dry/Wet" }, { "name" : "Input Gain" } ] }, { "code" : "elv2:http://gareus.org/oss/lv2/b_whirl#extended", "count" : 26, "display" : "field", "name" : "B Organ Whirl Speaker Extended Version", "number" : "3", "params" : [ { "name" : "Motors (horn, drum speed: off/slow/fast)" }, { "name" : "Horn Level [dB]" }, { "name" : "Drum Level [dB]" }, { "name" : "Drum Stereo Width" }, { "name" : "Horn Speed Slow [rpm]" }, { "name" : "Horn Speed Fast [rpm]" }, { "name" : "Horn Acceleration [s]" }, { "name" : "Horn Deceleration [s]" }, { "name" : "Horn Brake" }, { "name" : "Horn Filter-1 Type:" }, { "name" : "Horn Filter-1 Frequency [Hz]" }, { "name" : "Horn Filter-1 Quality" }, { "name" : "Horn Filter-1 Gain (shelf) [dB]" }, { "name" : "Horn Filter-2 Type:" }, { "name" : "Horn Filter-2 Frequency [Hz]" }, { "name" : "Horn Filter-2 Quality" }, { "name" : "Horn Filter-2 Gain (shelf) [dB]" }, { "name" : "Drum Speed Slow [rpm]" }, { "name" : "Drum Speed Fast [rpm]" }, { "name" : "Drum Acceleration [s]" }, { "name" : "Drum Deceleration [s]" }, { "name" : "Drum Brake Position" }, { "name" : "Drum Filter Type:" }, { "name" : "Drum Filter Frequency [Hz]" }, { "name" : "Drum Filter Quality" }, { "name" : "Drum Filter Gain (shelf) [dB]" } ] }, { "code" : "elv2:http://gareus.org/oss/lv2/b_whirl#simple", "count" : 4, "display" : "field", "name" : "B Organ Whirl Speaker", "number" : "4", "params" : [ { "name" : "Motors (horn, drum speed: off/slow/fast)" }, { "name" : "Horn Level [dB]" }, { "name" : "Drum Level [dB]" }, { "name" : "Drum Stereo Width" } ] }, { "code" : "elv2:http://hyperglitch.com/dev/VocProc", "count" : 21, "display" : "field", "name" : "VocProc", "number" : "5", "params" : [ { "name" : "Pitch Factor" }, { "name" : "Robotize/Whisperize" }, { "name" : "formant correction/vocoder" }, { "name" : "0 - formant correction, 1 - vocoder" }, { "name" : "Automatic pitch correction" }, { "name" : "Threshold" }, { "name" : "Attack" }, { "name" : "Transpose" }, { "name" : "C" }, { "name" : "C#" }, { "name" : "D" }, { "name" : "D#" }, { "name" : "E" }, { "name" : "F" }, { "name" : "F#" }, { "name" : "G" }, { "name" : "G#" }, { "name" : "A" }, { "name" : "A#" }, { "name" : "B" }, { "name" : "Offset from tone" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/alaw", "count" : 0, "display" : "field", "name" : "A-Law Compressor", "number" : "6", "params" : [] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/alias", "count" : 1, "display" : "field", "name" : "Aliasing", "number" : "7", "params" : [ { "name" : "Aliasing level" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/allpass_c", "count" : 3, "display" : "field", "name" : "Allpass delay line, cubic spline interpolation", "number" : "8", "params" : [ { "name" : "Max Delay (s)" }, { "name" : "Delay Time (s)" }, { "name" : "Decay Time (s)" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/allpass_l", "count" : 3, "display" : "field", "name" : "Allpass delay line, linear interpolation", "number" : "9", "params" : [ { "name" : "Max Delay (s)" }, { "name" : "Delay Time (s)" }, { "name" : "Decay Time (s)" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/allpass_n", "count" : 3, "display" : "field", "name" : "Allpass delay line, noninterpolating", "number" : "10", "params" : [ { "name" : "Max Delay (s)" }, { "name" : "Delay Time (s)" }, { "name" : "Decay Time (s)" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/amPitchshift", "count" : 3, "display" : "field", "name" : "AM pitchshifter", "number" : "11", "params" : [ { "name" : "Pitch shift" }, { "name" : "Buffer size" }, { "name" : "latency" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/amp", "count" : 1, "display" : "field", "name" : "Simple amplifier", "number" : "12", "params" : [ { "name" : "Amps gain (dB)" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/analogueOsc", "count" : 4, "display" : "field", "name" : "Analogue Oscillator", "number" : "13", "params" : [ { "name" : "Waveform (1=sin, 2=tri, 3=squ, 4=saw)" }, { "name" : "Frequency (Hz)" }, { "name" : "Warmth" }, { "name" : "Instability" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/artificialLatency", "count" : 2, "display" : "field", "name" : "Artificial latency", "number" : "14", "params" : [ { "name" : "Delay (ms)" }, { "name" : "latency" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/autoPhaser", "count" : 5, "display" : "field", "name" : "Auto phaser", "number" : "15", "params" : [ { "name" : "Attack time (s)" }, { "name" : "Decay time (s)" }, { "name" : "Modulation depth" }, { "name" : "Feedback" }, { "name" : "Spread (octaves)" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/bandpass_a_iir", "count" : 2, "display" : "field", "name" : "Glame Bandpass Analog Filter", "number" : "16", "params" : [ { "name" : "Center Frequency (Hz)" }, { "name" : "Bandwidth (Hz)" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/bandpass_iir", "count" : 3, "display" : "field", "name" : "Glame Bandpass Filter", "number" : "17", "params" : [ { "name" : "Center Frequency (Hz)" }, { "name" : "Bandwidth (Hz)" }, { "name" : "Stages(2 poles per stage)" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/bodeShifter", "count" : 2, "display" : "field", "name" : "Bode frequency shifter", "number" : "18", "params" : [ { "name" : "Frequency shift" }, { "name" : "latency" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/bodeShifterCV", "count" : 4, "display" : "field", "name" : "Bode frequency shifter (CV)", "number" : "19", "params" : [ { "name" : "Base shift" }, { "name" : "Mix (-1=down, +1=up)" }, { "name" : "CV Attenuation" }, { "name" : "latency" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/butthigh_iir", "count" : 2, "display" : "field", "name" : "GLAME Butterworth Highpass", "number" : "20", "params" : [ { "name" : "Cutoff Frequency (Hz)" }, { "name" : "Resonance" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/buttlow_iir", "count" : 2, "display" : "field", "name" : "GLAME Butterworth Lowpass", "number" : "21", "params" : [ { "name" : "Cutoff Frequency (Hz)" }, { "name" : "Resonance" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/bwxover_iir", "count" : 2, "display" : "field", "name" : "Glame Butterworth X-over Filter", "number" : "22", "params" : [ { "name" : "Cutoff Frequency (Hz)" }, { "name" : "Resonance" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/chebstortion", "count" : 1, "display" : "field", "name" : "Chebyshev distortion", "number" : "23", "params" : [ { "name" : "Distortion" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/comb", "count" : 2, "display" : "field", "name" : "Comb Filter", "number" : "24", "params" : [ { "name" : "Band separation (Hz)" }, { "name" : "Feedback" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/combSplitter", "count" : 1, "display" : "field", "name" : "Comb Splitter", "number" : "25", "params" : [ { "name" : "Band separation (Hz)" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/comb_c", "count" : 3, "display" : "field", "name" : "Comb delay line, cubic spline interpolation", "number" : "26", "params" : [ { "name" : "Max Delay (s)" }, { "name" : "Delay Time (s)" }, { "name" : "Decay Time (s)" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/comb_l", "count" : 3, "display" : "field", "name" : "Comb delay line, linear interpolation", "number" : "27", "params" : [ { "name" : "Max Delay (s)" }, { "name" : "Delay Time (s)" }, { "name" : "Decay Time (s)" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/comb_n", "count" : 3, "display" : "field", "name" : "Comb delay line, noninterpolating", "number" : "28", "params" : [ { "name" : "Max Delay (s)" }, { "name" : "Delay Time (s)" }, { "name" : "Decay Time (s)" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/const", "count" : 1, "display" : "field", "name" : "Constant Signal Generator", "number" : "29", "params" : [ { "name" : "Signal amplitude" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/crossoverDist", "count" : 2, "display" : "field", "name" : "Crossover distortion", "number" : "30", "params" : [ { "name" : "Crossover amplitude" }, { "name" : "Smoothing" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/dcRemove", "count" : 0, "display" : "field", "name" : "DC Offset Remover", "number" : "31", "params" : [] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/decay", "count" : 1, "display" : "field", "name" : "Exponential signal decay", "number" : "32", "params" : [ { "name" : "Decay Time (s)" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/decimator", "count" : 2, "display" : "field", "name" : "Decimator", "number" : "33", "params" : [ { "name" : "Bit depth" }, { "name" : "Sample rate (Hz)" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/declip", "count" : 0, "display" : "field", "name" : "Declipper", "number" : "34", "params" : [] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/delay_c", "count" : 2, "display" : "field", "name" : "Simple delay line, cubic spline interpolation", "number" : "35", "params" : [ { "name" : "Max Delay (s)" }, { "name" : "Delay Time (s)" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/delay_l", "count" : 2, "display" : "field", "name" : "Simple delay line, linear interpolation", "number" : "36", "params" : [ { "name" : "Max Delay (s)" }, { "name" : "Delay Time (s)" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/delay_n", "count" : 2, "display" : "field", "name" : "Simple delay line, noninterpolating", "number" : "37", "params" : [ { "name" : "Max Delay (s)" }, { "name" : "Delay Time (s)" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/delayorama", "count" : 11, "display" : "field", "name" : "Delayorama", "number" : "38", "params" : [ { "name" : "Random seed" }, { "name" : "Input gain (dB)" }, { "name" : "Feedback (%)" }, { "name" : "Number of taps" }, { "name" : "First delay (s)" }, { "name" : "Delay range (s)" }, { "name" : "Delay change" }, { "name" : "Delay random (%)" }, { "name" : "Amplitude change" }, { "name" : "Amplitude random (%)" }, { "name" : "Dry/wet mix" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/diode", "count" : 1, "display" : "field", "name" : "Diode Processor", "number" : "39", "params" : [ { "name" : "Mode (0 for none, 1 for half wave, 2 for full wave)" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/divider", "count" : 1, "display" : "field", "name" : "Audio Divider (Suboctave Generator)", "number" : "40", "params" : [ { "name" : "Denominator" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/djFlanger", "count" : 4, "display" : "field", "name" : "DJ flanger", "number" : "41", "params" : [ { "name" : "LFO sync" }, { "name" : "LFO period (s)" }, { "name" : "LFO depth (ms)" }, { "name" : "Feedback (%)" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/dj_eq", "count" : 4, "display" : "field", "name" : "DJ EQ", "number" : "42", "params" : [ { "name" : "Lo gain (dB)" }, { "name" : "Mid gain (dB)" }, { "name" : "Hi gain (dB)" }, { "name" : "latency" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/dj_eq_mono", "count" : 4, "display" : "field", "name" : "DJ EQ (mono)", "number" : "43", "params" : [ { "name" : "Lo gain (dB)" }, { "name" : "Mid gain (dB)" }, { "name" : "Hi gain (dB)" }, { "name" : "latency" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/dysonCompress", "count" : 4, "display" : "field", "name" : "Dyson compressor", "number" : "44", "params" : [ { "name" : "Peak limit (dB)" }, { "name" : "Release time (s)" }, { "name" : "Fast compression ratio" }, { "name" : "Compression ratio" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/fadDelay", "count" : 2, "display" : "field", "name" : "Fractionally Addressed Delay Line", "number" : "45", "params" : [ { "name" : "Delay (seconds)" }, { "name" : "Feedback (dB)" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/fastLookaheadLimiter", "count" : 5, "display" : "field", "name" : "Fast Lookahead limiter", "number" : "46", "params" : [ { "name" : "Input gain (dB)" }, { "name" : "Limit (dB)" }, { "name" : "Release time (s)" }, { "name" : "Attenuation (dB)" }, { "name" : "latency" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/flanger", "count" : 4, "display" : "field", "name" : "Flanger", "number" : "47", "params" : [ { "name" : "Delay base (ms)" }, { "name" : "Max slowdown (ms)" }, { "name" : "LFO frequency (Hz)" }, { "name" : "Feedback" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/fmOsc", "count" : 1, "display" : "field", "name" : "FM Oscillator", "number" : "48", "params" : [ { "name" : "Waveform (1=sin, 2=tri, 3=squ, 4=saw)" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/foldover", "count" : 2, "display" : "field", "name" : "Foldover distortion", "number" : "49", "params" : [ { "name" : "Drive" }, { "name" : "Skew" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/fourByFourPole", "count" : 8, "display" : "field", "name" : "4 x 4 pole allpass", "number" : "50", "params" : [ { "name" : "Frequency 1" }, { "name" : "Feedback 1" }, { "name" : "Frequency 2" }, { "name" : "Feedback 2" }, { "name" : "Frequency 3" }, { "name" : "Feedback 3" }, { "name" : "Frequency 4" }, { "name" : "Feedback 4" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/foverdrive", "count" : 1, "display" : "field", "name" : "Fast overdrive", "number" : "51", "params" : [ { "name" : "Drive level" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/freqTracker", "count" : 1, "display" : "field", "name" : "Frequency tracker", "number" : "52", "params" : [ { "name" : "Tracking speed" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/gate", "count" : 10, "display" : "field", "name" : "Gate", "number" : "53", "params" : [ { "name" : "LF key filter (Hz)" }, { "name" : "HF key filter (Hz)" }, { "name" : "Threshold (dB)" }, { "name" : "Attack (ms)" }, { "name" : "Hold (ms)" }, { "name" : "Decay (ms)" }, { "name" : "Range (dB)" }, { "name" : "Output select (-1 = key listen, 0 = gate, 1 = bypass)" }, { "name" : "Key level (dB)" }, { "name" : "Gate state" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/giantFlange", "count" : 7, "display" : "field", "name" : "Giant flange", "number" : "54", "params" : [ { "name" : "Double delay" }, { "name" : "LFO frequency 1 (Hz)" }, { "name" : "Delay 1 range (s)" }, { "name" : "LFO frequency 2 (Hz)" }, { "name" : "Delay 2 range (s)" }, { "name" : "Feedback" }, { "name" : "Dry/Wet level" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/gong", "count" : 27, "display" : "field", "name" : "Gong model", "number" : "55", "params" : [ { "name" : "Inner damping" }, { "name" : "Outer damping" }, { "name" : "Mic position" }, { "name" : "Inner size 1" }, { "name" : "Inner stiffness 1 +" }, { "name" : "Inner stiffness 1 -" }, { "name" : "Inner size 2" }, { "name" : "Inner stiffness 2 +" }, { "name" : "Inner stiffness 2 -" }, { "name" : "Inner size 3" }, { "name" : "Inner stiffness 3 +" }, { "name" : "Inner stiffness 3 -" }, { "name" : "Inner size 4" }, { "name" : "Inner stiffness 4 +" }, { "name" : "Inner stiffness 4 -" }, { "name" : "Outer size 1" }, { "name" : "Outer stiffness 1 +" }, { "name" : "Outer stiffness 1 -" }, { "name" : "Outer size 2" }, { "name" : "Outer stiffness 2 +" }, { "name" : "Outer stiffness 2 -" }, { "name" : "Outer size 3" }, { "name" : "Outer stiffness 3 +" }, { "name" : "Outer stiffness 3 -" }, { "name" : "Outer size 4" }, { "name" : "Outer stiffness 4 +" }, { "name" : "Outer stiffness 4 -" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/gongBeater", "count" : 3, "display" : "field", "name" : "Gong beater", "number" : "56", "params" : [ { "name" : "Impulse gain (dB)" }, { "name" : "Strike gain (dB)" }, { "name" : "Strike duration (s)" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/gverb", "count" : 7, "display" : "field", "name" : "GVerb", "number" : "57", "params" : [ { "name" : "Roomsize (m)" }, { "name" : "Reverb time (s)" }, { "name" : "Damping" }, { "name" : "Input bandwidth" }, { "name" : "Dry signal level (dB)" }, { "name" : "Early reflection level (dB)" }, { "name" : "Tail level (dB)" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/hardLimiter", "count" : 3, "display" : "field", "name" : "Hard Limiter", "number" : "58", "params" : [ { "name" : "dB limit" }, { "name" : "Wet level" }, { "name" : "Residue level" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/harmonicGen", "count" : 10, "display" : "field", "name" : "Harmonic generator", "number" : "59", "params" : [ { "name" : "Fundamental magnitude" }, { "name" : "2nd harmonic magnitude" }, { "name" : "3rd harmonic magnitude" }, { "name" : "4th harmonic magnitude" }, { "name" : "5th harmonic magnitude" }, { "name" : "6th harmonic magnitude" }, { "name" : "7th harmonic magnitude" }, { "name" : "8th harmonic magnitude" }, { "name" : "9th harmonic magnitude" }, { "name" : "10th harmonic magnitude" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/hermesFilter", "count" : 52, "display" : "field", "name" : "Hermes Filter", "number" : "60", "params" : [ { "name" : "LFO1 freq (Hz)" }, { "name" : "LFO1 wave (0 = sin, 1 = tri, 2 = saw, 3 = squ, 4 = s&h)" }, { "name" : "LFO2 freq (Hz)" }, { "name" : "LFO2 wave (0 = sin, 1 = tri, 2 = saw, 3 = squ, 4 = s&h)" }, { "name" : "Osc1 freq (Hz)" }, { "name" : "Osc1 wave (0 = sin, 1 = tri, 2 = saw, 3 = squ, 4 = noise)" }, { "name" : "Osc2 freq (Hz)" }, { "name" : "Osc2 wave (0 = sin, 1 = tri, 2 = saw, 3 = squ, 4 = noise)" }, { "name" : "Ringmod 1 depth (0=none, 1=AM, 2=RM)" }, { "name" : "Ringmod 2 depth (0=none, 1=AM, 2=RM)" }, { "name" : "Ringmod 3 depth (0=none, 1=AM, 2=RM)" }, { "name" : "Osc1 gain (dB)" }, { "name" : "RM1 gain (dB)" }, { "name" : "Osc2 gain (dB)" }, { "name" : "RM2 gain (dB)" }, { "name" : "Input gain (dB)" }, { "name" : "RM3 gain (dB)" }, { "name" : "Xover lower freq" }, { "name" : "Xover upper freq" }, { "name" : "Dist1 drive" }, { "name" : "Dist2 drive" }, { "name" : "Dist3 drive" }, { "name" : "Filt1 type (0=none, 1=LP, 2=HP, 3=BP, 4=BR, 5=AP)" }, { "name" : "Filt1 freq" }, { "name" : "Filt1 q" }, { "name" : "Filt1 resonance" }, { "name" : "Filt1 LFO1 level" }, { "name" : "Filt1 LFO2 level" }, { "name" : "Filt2 type (0=none, 1=LP, 2=HP, 3=BP, 4=BR, 5=AP)" }, { "name" : "Filt2 freq" }, { "name" : "Filt2 q" }, { "name" : "Filt2 resonance" }, { "name" : "Filt2 LFO1 level" }, { "name" : "Filt2 LFO2 level" }, { "name" : "Filt3 type (0=none, 1=LP, 2=HP, 3=BP, 4=BR, 5=AP)" }, { "name" : "Filt3 freq" }, { "name" : "Filt3 q" }, { "name" : "Filt3 resonance" }, { "name" : "Filt3 LFO1 level" }, { "name" : "Filt3 LFO2 level" }, { "name" : "Delay1 length (s)" }, { "name" : "Delay1 feedback" }, { "name" : "Delay1 wetness" }, { "name" : "Delay2 length (s)" }, { "name" : "Delay2 feedback" }, { "name" : "Delay2 wetness" }, { "name" : "Delay3 length (s)" }, { "name" : "Delay3 feedback" }, { "name" : "Delay3 wetness" }, { "name" : "Band 1 gain (dB)" }, { "name" : "Band 2 gain (dB)" }, { "name" : "Band 3 gain (dB)" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/highpass_iir", "count" : 2, "display" : "field", "name" : "Glame Highpass Filter", "number" : "61", "params" : [ { "name" : "Cutoff Frequency" }, { "name" : "Stages(2 poles per stage)" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/hilbert", "count" : 1, "display" : "field", "name" : "Hilbert transformer", "number" : "62", "params" : [ { "name" : "latency" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/impulse_fc", "count" : 1, "display" : "field", "name" : "Non-bandlimited single-sample impulses", "number" : "63", "params" : [ { "name" : "Frequency (Hz)" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/inv", "count" : 0, "display" : "field", "name" : "Inverter", "number" : "64", "params" : [] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/karaoke", "count" : 1, "display" : "field", "name" : "Karaoke", "number" : "65", "params" : [ { "name" : "Vocal volume (dB)" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/lcrDelay", "count" : 11, "display" : "field", "name" : "L/C/R Delay", "number" : "66", "params" : [ { "name" : "L delay (ms)" }, { "name" : "L level" }, { "name" : "C delay (ms)" }, { "name" : "C level" }, { "name" : "R delay (ms)" }, { "name" : "R level" }, { "name" : "Feedback" }, { "name" : "High damp (%)" }, { "name" : "Low damp (%)" }, { "name" : "Spread" }, { "name" : "Dry/Wet level" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/lfoPhaser", "count" : 4, "display" : "field", "name" : "LFO Phaser", "number" : "67", "params" : [ { "name" : "LFO rate (Hz)" }, { "name" : "LFO depth" }, { "name" : "Feedback" }, { "name" : "Spread (octaves)" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/lookaheadLimiter", "count" : 4, "display" : "field", "name" : "Lookahead limiter", "number" : "68", "params" : [ { "name" : "Limit (dB)" }, { "name" : "Lookahead delay" }, { "name" : "Attenuation (dB)" }, { "name" : "latency" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/lookaheadLimiterConst", "count" : 4, "display" : "field", "name" : "Lookahead limiter (fixed latency)", "number" : "69", "params" : [ { "name" : "Limit (dB)" }, { "name" : "Lookahead time (s)" }, { "name" : "Attenuation (dB)" }, { "name" : "latency" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/lowpass_iir", "count" : 2, "display" : "field", "name" : "Glame Lowpass Filter", "number" : "70", "params" : [ { "name" : "Cutoff Frequency" }, { "name" : "Stages(2 poles per stage)" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/lsFilter", "count" : 3, "display" : "field", "name" : "LS Filter", "number" : "71", "params" : [ { "name" : "Filter type (0=LP, 1=BP, 2=HP)" }, { "name" : "Cutoff frequency (Hz)" }, { "name" : "Resonance" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/matrixMSSt", "count" : 1, "display" : "field", "name" : "Matrix: MS to Stereo", "number" : "72", "params" : [ { "name" : "Width" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/matrixSpatialiser", "count" : 1, "display" : "field", "name" : "Matrix Spatialiser", "number" : "73", "params" : [ { "name" : "Width" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/matrixStMS", "count" : 0, "display" : "field", "name" : "Matrix: Stereo to MS", "number" : "74", "params" : [] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/mbeq", "count" : 16, "display" : "field", "name" : "Multiband EQ", "number" : "75", "params" : [ { "name" : "50Hz gain (low shelving)" }, { "name" : "100Hz gain" }, { "name" : "156Hz gain" }, { "name" : "220Hz gain" }, { "name" : "311Hz gain" }, { "name" : "440Hz gain" }, { "name" : "622Hz gain" }, { "name" : "880Hz gain" }, { "name" : "1250Hz gain" }, { "name" : "1750Hz gain" }, { "name" : "2500Hz gain" }, { "name" : "3500Hz gain" }, { "name" : "5000Hz gain" }, { "name" : "10000Hz gain" }, { "name" : "20000Hz gain" }, { "name" : "latency" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/modDelay", "count" : 1, "display" : "field", "name" : "Modulatable delay", "number" : "76", "params" : [ { "name" : "Base delay (s)" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/multivoiceChorus", "count" : 6, "display" : "field", "name" : "Multivoice Chorus", "number" : "77", "params" : [ { "name" : "Number of voices" }, { "name" : "Delay base (ms)" }, { "name" : "Voice separation (ms)" }, { "name" : "Detune (%)" }, { "name" : "LFO frequency (Hz)" }, { "name" : "Output attenuation (dB)" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/pitchScaleHQ", "count" : 2, "display" : "field", "name" : "Higher Quality Pitch Scaler", "number" : "78", "params" : [ { "name" : "Pitch co-efficient" }, { "name" : "latency" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/plate", "count" : 3, "display" : "field", "name" : "Plate reverb", "number" : "79", "params" : [ { "name" : "Reverb time" }, { "name" : "Damping" }, { "name" : "Dry/wet mix" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/pointerCastDistortion", "count" : 2, "display" : "field", "name" : "Pointer cast distortion", "number" : "80", "params" : [ { "name" : "Effect cutoff freq (Hz)" }, { "name" : "Dry/wet mix" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/rateShifter", "count" : 1, "display" : "field", "name" : "Rate shifter", "number" : "81", "params" : [ { "name" : "Rate" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/retroFlange", "count" : 2, "display" : "field", "name" : "Retro Flanger", "number" : "82", "params" : [ { "name" : "Average stall (ms)" }, { "name" : "Flange frequency (Hz)" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/revdelay", "count" : 5, "display" : "field", "name" : "Reverse Delay (5s max)", "number" : "83", "params" : [ { "name" : "Delay Time (s)" }, { "name" : "Dry Level (dB)" }, { "name" : "Wet Level (dB)" }, { "name" : "Feedback" }, { "name" : "Crossfade samples" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/ringmod_1i1o1l", "count" : 6, "display" : "field", "name" : "Ringmod with LFO", "number" : "84", "params" : [ { "name" : "Modulation depth (0=none, 1=AM, 2=RM)" }, { "name" : "Frequency (Hz)" }, { "name" : "Sine level" }, { "name" : "Triangle level" }, { "name" : "Sawtooth level" }, { "name" : "Square level" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/ringmod_2i1o", "count" : 1, "display" : "field", "name" : "Ringmod with two inputs", "number" : "85", "params" : [ { "name" : "Modulation depth (0=none, 1=AM, 2=RM)" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/satanMaximiser", "count" : 2, "display" : "field", "name" : "Barry's Satan Maximiser", "number" : "86", "params" : [ { "name" : "Decay time (samples)" }, { "name" : "Knee point (dB)" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/sc1", "count" : 6, "display" : "field", "name" : "SC1", "number" : "87", "params" : [ { "name" : "Attack time (ms)" }, { "name" : "Release time (ms)" }, { "name" : "Threshold level (dB)" }, { "name" : "Ratio (1:n)" }, { "name" : "Knee radius (dB)" }, { "name" : "Makeup gain (dB)" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/sc2", "count" : 6, "display" : "field", "name" : "SC2", "number" : "88", "params" : [ { "name" : "Attack time (ms)" }, { "name" : "Release time (ms)" }, { "name" : "Threshold level (dB)" }, { "name" : "Ratio (1:n)" }, { "name" : "Knee radius (dB)" }, { "name" : "Makeup gain (dB)" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/sc3", "count" : 7, "display" : "field", "name" : "SC3", "number" : "89", "params" : [ { "name" : "Attack time (ms)" }, { "name" : "Release time (ms)" }, { "name" : "Threshold level (dB)" }, { "name" : "Ratio (1:n)" }, { "name" : "Knee radius (dB)" }, { "name" : "Makeup gain (dB)" }, { "name" : "Chain balance" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/sc4", "count" : 9, "display" : "field", "name" : "SC4", "number" : "90", "params" : [ { "name" : "RMS/peak" }, { "name" : "Attack time (ms)" }, { "name" : "Release time (ms)" }, { "name" : "Threshold level (dB)" }, { "name" : "Ratio (1:n)" }, { "name" : "Knee radius (dB)" }, { "name" : "Makeup gain (dB)" }, { "name" : "Amplitude (dB)" }, { "name" : "Gain reduction (dB)" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/se4", "count" : 9, "display" : "field", "name" : "SE4", "number" : "91", "params" : [ { "name" : "RMS/peak" }, { "name" : "Attack time (ms)" }, { "name" : "Release time (ms)" }, { "name" : "Threshold level (dB)" }, { "name" : "Ratio (1:n)" }, { "name" : "Knee radius (dB)" }, { "name" : "Attenuation (dB)" }, { "name" : "Amplitude (dB)" }, { "name" : "Gain expansion (dB)" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/shaper", "count" : 1, "display" : "field", "name" : "Wave shaper", "number" : "92", "params" : [ { "name" : "Waveshape" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/sifter", "count" : 1, "display" : "field", "name" : "Signal sifter", "number" : "93", "params" : [ { "name" : "Sift size" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/sinCos", "count" : 2, "display" : "field", "name" : "Sine + cosine oscillator", "number" : "94", "params" : [ { "name" : "Base frequency (Hz)" }, { "name" : "Pitch offset" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/singlePara", "count" : 3, "display" : "field", "name" : "Single band parametric", "number" : "95", "params" : [ { "name" : "Gain (dB)" }, { "name" : "Frequency (Hz)" }, { "name" : "Bandwidth (octaves)" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/sinusWavewrapper", "count" : 1, "display" : "field", "name" : "Sinus wavewrapper", "number" : "96", "params" : [ { "name" : "Wrap degree" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/smoothDecimate", "count" : 2, "display" : "field", "name" : "Smooth Decimator", "number" : "97", "params" : [ { "name" : "Resample rate" }, { "name" : "Smoothing" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/split", "count" : 0, "display" : "field", "name" : "Mono to Stereo splitter", "number" : "98", "params" : [] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/surroundEncoder", "count" : 0, "display" : "field", "name" : "Surround matrix encoder", "number" : "99", "params" : [] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/svf", "count" : 4, "display" : "field", "name" : "State Variable Filter", "number" : "100", "params" : [ { "name" : "Filter type (0=none, 1=LP, 2=HP, 3=BP, 4=BR, 5=AP)" }, { "name" : "Filter freq" }, { "name" : "Filter Q" }, { "name" : "Filter resonance" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/tapeDelay", "count" : 10, "display" : "field", "name" : "Tape Delay Simulation", "number" : "101", "params" : [ { "name" : "Tape speed (inches/sec, 1=normal)" }, { "name" : "Dry level (dB)" }, { "name" : "Tap 1 distance (inches)" }, { "name" : "Tap 1 level (dB)" }, { "name" : "Tap 2 distance (inches)" }, { "name" : "Tap 2 level (dB)" }, { "name" : "Tap 3 distance (inches)" }, { "name" : "Tap 3 level (dB)" }, { "name" : "Tap 4 distance (inches)" }, { "name" : "Tap 4 level (dB)" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/transient", "count" : 2, "display" : "field", "name" : "Transient mangler", "number" : "102", "params" : [ { "name" : "Attack speed" }, { "name" : "Sustain time" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/triplePara", "count" : 15, "display" : "field", "name" : "Triple band parametric with shelves", "number" : "103", "params" : [ { "name" : "Low-shelving gain (dB)" }, { "name" : "Low-shelving frequency (Hz)" }, { "name" : "Low-shelving slope" }, { "name" : "Band 1 gain (dB)" }, { "name" : "Band 1 frequency (Hz)" }, { "name" : "Band 1 bandwidth (octaves)" }, { "name" : "Band 2 gain (dB)" }, { "name" : "Band 2 frequency (Hz)" }, { "name" : "Band 2 bandwidth (octaves)" }, { "name" : "Band 3 gain (dB)" }, { "name" : "Band 3 frequency (Hz)" }, { "name" : "Band 3 bandwidth (octaves)" }, { "name" : "High-shelving gain (dB)" }, { "name" : "High-shelving frequency (Hz)" }, { "name" : "High-shelving slope" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/ulaw", "count" : 0, "display" : "field", "name" : "μ-Law Compressor", "number" : "104", "params" : [] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/valve", "count" : 2, "display" : "field", "name" : "Valve saturation", "number" : "105", "params" : [ { "name" : "Distortion level" }, { "name" : "Distortion character" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/valveRect", "count" : 2, "display" : "field", "name" : "Valve rectifier", "number" : "106", "params" : [ { "name" : "Sag level" }, { "name" : "Distortion" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/vynil", "count" : 5, "display" : "field", "name" : "VyNil (Vinyl Effect)", "number" : "107", "params" : [ { "name" : "Year" }, { "name" : "RPM" }, { "name" : "Surface warping" }, { "name" : "Crackle" }, { "name" : "Wear" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/waveTerrain", "count" : 0, "display" : "field", "name" : "Wave Terrain Oscillator", "number" : "108", "params" : [] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/xfade", "count" : 1, "display" : "field", "name" : "Crossfade", "number" : "109", "params" : [ { "name" : "Crossfade" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/xfade4", "count" : 1, "display" : "field", "name" : "Crossfade (4 outs)", "number" : "110", "params" : [ { "name" : "Crossfade" } ] }, { "code" : "elv2:http://plugin.org.uk/swh-plugins/zm1", "count" : 0, "display" : "field", "name" : "z-1", "number" : "111", "params" : [] } ], "split" : { "cop" : { "a" : 1, "z" : 47 }, "ctrl" : { "a" : 299, "z" : 306 }, "ladspa" : { "a" : 48, "b" : 95, "c" : 143, "d" : 191, "z" : 242 }, "lv2" : { "a" : 307, "z" : 417 }, "preset" : { "a" : 243, "b" : 270, "z" : 298 } }, "user_help" : [ "LV2 B Organ Overdrive -elv2:http://gareus.org/oss/lv2/b_overdrive, Bias, Feedback, SagToBias, Postdiff feedback, Global feedback, Input Gain, Output Gain", "LV2 B Organ Reverb -elv2:http://gareus.org/oss/lv2/b_reverb, Dry/Wet, Input Gain", "LV2 B Organ Whirl Speaker Extended Version -elv2:http://gareus.org/oss/lv2/b_whirl#extended, Motors (horn, drum speed: off/slow/fast), Horn Level [dB], Drum Level [dB], Drum Stereo Width, Horn Speed Slow [rpm], Horn Speed Fast [rpm], Horn Acceleration [s], Horn Deceleration [s], Horn Brake, Horn Filter-1 Type:, Horn Filter-1 Frequency [Hz], Horn Filter-1 Quality, Horn Filter-1 Gain (shelf) [dB], Horn Filter-2 Type:, Horn Filter-2 Frequency [Hz], Horn Filter-2 Quality, Horn Filter-2 Gain (shelf) [dB], Drum Speed Slow [rpm], Drum Speed Fast [rpm], Drum Acceleration [s], Drum Deceleration [s], Drum Brake Position, Drum Filter Type:, Drum Filter Frequency [Hz], Drum Filter Quality, Drum Filter Gain (shelf) [dB]", "LV2 B Organ Whirl Speaker -elv2:http://gareus.org/oss/lv2/b_whirl#simple, Motors (horn, drum speed: off/slow/fast), Horn Level [dB], Drum Level [dB], Drum Stereo Width", "LV2 VocProc -elv2:http://hyperglitch.com/dev/VocProc, Pitch Factor, Robotize/Whisperize, formant correction/vocoder, 0 - formant correction, 1 - vocoder, Automatic pitch correction, Threshold, Attack, Transpose, C, C#, D, D#, E, F, F#, G, G#, A, A#, B, Offset from tone", "LV2 A-Law Compressor -elv2:http://plugin.org.uk/swh-plugins/alaw, ", "LV2 Aliasing -elv2:http://plugin.org.uk/swh-plugins/alias, Aliasing level", "LV2 Allpass delay line, cubic spline interpolation -elv2:http://plugin.org.uk/swh-plugins/allpass_c, Max Delay (s), Delay Time (s), Decay Time (s)", "LV2 Allpass delay line, linear interpolation -elv2:http://plugin.org.uk/swh-plugins/allpass_l, Max Delay (s), Delay Time (s), Decay Time (s)", "LV2 Allpass delay line, noninterpolating -elv2:http://plugin.org.uk/swh-plugins/allpass_n, Max Delay (s), Delay Time (s), Decay Time (s)", "LV2 AM pitchshifter -elv2:http://plugin.org.uk/swh-plugins/amPitchshift, Pitch shift, Buffer size, latency", "LV2 Simple amplifier -elv2:http://plugin.org.uk/swh-plugins/amp, Amps gain (dB)", "LV2 Analogue Oscillator -elv2:http://plugin.org.uk/swh-plugins/analogueOsc, Waveform (1=sin, 2=tri, 3=squ, 4=saw), Frequency (Hz), Warmth, Instability", "LV2 Artificial latency -elv2:http://plugin.org.uk/swh-plugins/artificialLatency, Delay (ms), latency", "LV2 Auto phaser -elv2:http://plugin.org.uk/swh-plugins/autoPhaser, Attack time (s), Decay time (s), Modulation depth, Feedback, Spread (octaves)", "LV2 Glame Bandpass Analog Filter -elv2:http://plugin.org.uk/swh-plugins/bandpass_a_iir, Center Frequency (Hz), Bandwidth (Hz)", "LV2 Glame Bandpass Filter -elv2:http://plugin.org.uk/swh-plugins/bandpass_iir, Center Frequency (Hz), Bandwidth (Hz), Stages(2 poles per stage)", "LV2 Bode frequency shifter -elv2:http://plugin.org.uk/swh-plugins/bodeShifter, Frequency shift, latency", "LV2 Bode frequency shifter (CV) -elv2:http://plugin.org.uk/swh-plugins/bodeShifterCV, Base shift, Mix (-1=down, +1=up), CV Attenuation, latency", "LV2 GLAME Butterworth Highpass -elv2:http://plugin.org.uk/swh-plugins/butthigh_iir, Cutoff Frequency (Hz), Resonance", "LV2 GLAME Butterworth Lowpass -elv2:http://plugin.org.uk/swh-plugins/buttlow_iir, Cutoff Frequency (Hz), Resonance", "LV2 Glame Butterworth X-over Filter -elv2:http://plugin.org.uk/swh-plugins/bwxover_iir, Cutoff Frequency (Hz), Resonance", "LV2 Chebyshev distortion -elv2:http://plugin.org.uk/swh-plugins/chebstortion, Distortion", "LV2 Comb Filter -elv2:http://plugin.org.uk/swh-plugins/comb, Band separation (Hz), Feedback", "LV2 Comb Splitter -elv2:http://plugin.org.uk/swh-plugins/combSplitter, Band separation (Hz)", "LV2 Comb delay line, cubic spline interpolation -elv2:http://plugin.org.uk/swh-plugins/comb_c, Max Delay (s), Delay Time (s), Decay Time (s)", "LV2 Comb delay line, linear interpolation -elv2:http://plugin.org.uk/swh-plugins/comb_l, Max Delay (s), Delay Time (s), Decay Time (s)", "LV2 Comb delay line, noninterpolating -elv2:http://plugin.org.uk/swh-plugins/comb_n, Max Delay (s), Delay Time (s), Decay Time (s)", "LV2 Constant Signal Generator -elv2:http://plugin.org.uk/swh-plugins/const, Signal amplitude", "LV2 Crossover distortion -elv2:http://plugin.org.uk/swh-plugins/crossoverDist, Crossover amplitude, Smoothing", "LV2 DC Offset Remover -elv2:http://plugin.org.uk/swh-plugins/dcRemove, ", "LV2 Exponential signal decay -elv2:http://plugin.org.uk/swh-plugins/decay, Decay Time (s)", "LV2 Decimator -elv2:http://plugin.org.uk/swh-plugins/decimator, Bit depth, Sample rate (Hz)", "LV2 Declipper -elv2:http://plugin.org.uk/swh-plugins/declip, ", "LV2 Simple delay line, cubic spline interpolation -elv2:http://plugin.org.uk/swh-plugins/delay_c, Max Delay (s), Delay Time (s)", "LV2 Simple delay line, linear interpolation -elv2:http://plugin.org.uk/swh-plugins/delay_l, Max Delay (s), Delay Time (s)", "LV2 Simple delay line, noninterpolating -elv2:http://plugin.org.uk/swh-plugins/delay_n, Max Delay (s), Delay Time (s)", "LV2 Delayorama -elv2:http://plugin.org.uk/swh-plugins/delayorama, Random seed, Input gain (dB), Feedback (%), Number of taps, First delay (s), Delay range (s), Delay change, Delay random (%), Amplitude change, Amplitude random (%), Dry/wet mix", "LV2 Diode Processor -elv2:http://plugin.org.uk/swh-plugins/diode, Mode (0 for none, 1 for half wave, 2 for full wave)", "LV2 Audio Divider (Suboctave Generator) -elv2:http://plugin.org.uk/swh-plugins/divider, Denominator", "LV2 DJ flanger -elv2:http://plugin.org.uk/swh-plugins/djFlanger, LFO sync, LFO period (s), LFO depth (ms), Feedback (%)", "LV2 DJ EQ -elv2:http://plugin.org.uk/swh-plugins/dj_eq, Lo gain (dB), Mid gain (dB), Hi gain (dB), latency", "LV2 DJ EQ (mono) -elv2:http://plugin.org.uk/swh-plugins/dj_eq_mono, Lo gain (dB), Mid gain (dB), Hi gain (dB), latency", "LV2 Dyson compressor -elv2:http://plugin.org.uk/swh-plugins/dysonCompress, Peak limit (dB), Release time (s), Fast compression ratio, Compression ratio", "LV2 Fractionally Addressed Delay Line -elv2:http://plugin.org.uk/swh-plugins/fadDelay, Delay (seconds), Feedback (dB)", "LV2 Fast Lookahead limiter -elv2:http://plugin.org.uk/swh-plugins/fastLookaheadLimiter, Input gain (dB), Limit (dB), Release time (s), Attenuation (dB), latency", "LV2 Flanger -elv2:http://plugin.org.uk/swh-plugins/flanger, Delay base (ms), Max slowdown (ms), LFO frequency (Hz), Feedback", "LV2 FM Oscillator -elv2:http://plugin.org.uk/swh-plugins/fmOsc, Waveform (1=sin, 2=tri, 3=squ, 4=saw)", "LV2 Foldover distortion -elv2:http://plugin.org.uk/swh-plugins/foldover, Drive, Skew", "LV2 4 x 4 pole allpass -elv2:http://plugin.org.uk/swh-plugins/fourByFourPole, Frequency 1, Feedback 1, Frequency 2, Feedback 2, Frequency 3, Feedback 3, Frequency 4, Feedback 4", "LV2 Fast overdrive -elv2:http://plugin.org.uk/swh-plugins/foverdrive, Drive level", "LV2 Frequency tracker -elv2:http://plugin.org.uk/swh-plugins/freqTracker, Tracking speed", "LV2 Gate -elv2:http://plugin.org.uk/swh-plugins/gate, LF key filter (Hz), HF key filter (Hz), Threshold (dB), Attack (ms), Hold (ms), Decay (ms), Range (dB), Output select (-1 = key listen, 0 = gate, 1 = bypass), Key level (dB), Gate state", "LV2 Giant flange -elv2:http://plugin.org.uk/swh-plugins/giantFlange, Double delay, LFO frequency 1 (Hz), Delay 1 range (s), LFO frequency 2 (Hz), Delay 2 range (s), Feedback, Dry/Wet level", "LV2 Gong model -elv2:http://plugin.org.uk/swh-plugins/gong, Inner damping, Outer damping, Mic position, Inner size 1, Inner stiffness 1 +, Inner stiffness 1 -, Inner size 2, Inner stiffness 2 +, Inner stiffness 2 -, Inner size 3, Inner stiffness 3 +, Inner stiffness 3 -, Inner size 4, Inner stiffness 4 +, Inner stiffness 4 -, Outer size 1, Outer stiffness 1 +, Outer stiffness 1 -, Outer size 2, Outer stiffness 2 +, Outer stiffness 2 -, Outer size 3, Outer stiffness 3 +, Outer stiffness 3 -, Outer size 4, Outer stiffness 4 +, Outer stiffness 4 -", "LV2 Gong beater -elv2:http://plugin.org.uk/swh-plugins/gongBeater, Impulse gain (dB), Strike gain (dB), Strike duration (s)", "LV2 GVerb -elv2:http://plugin.org.uk/swh-plugins/gverb, Roomsize (m), Reverb time (s), Damping, Input bandwidth, Dry signal level (dB), Early reflection level (dB), Tail level (dB)", "LV2 Hard Limiter -elv2:http://plugin.org.uk/swh-plugins/hardLimiter, dB limit, Wet level, Residue level", "LV2 Harmonic generator -elv2:http://plugin.org.uk/swh-plugins/harmonicGen, Fundamental magnitude, 2nd harmonic magnitude, 3rd harmonic magnitude, 4th harmonic magnitude, 5th harmonic magnitude, 6th harmonic magnitude, 7th harmonic magnitude, 8th harmonic magnitude, 9th harmonic magnitude, 10th harmonic magnitude", "LV2 Hermes Filter -elv2:http://plugin.org.uk/swh-plugins/hermesFilter, LFO1 freq (Hz), LFO1 wave (0 = sin, 1 = tri, 2 = saw, 3 = squ, 4 = s&h), LFO2 freq (Hz), LFO2 wave (0 = sin, 1 = tri, 2 = saw, 3 = squ, 4 = s&h), Osc1 freq (Hz), Osc1 wave (0 = sin, 1 = tri, 2 = saw, 3 = squ, 4 = noise), Osc2 freq (Hz), Osc2 wave (0 = sin, 1 = tri, 2 = saw, 3 = squ, 4 = noise), Ringmod 1 depth (0=none, 1=AM, 2=RM), Ringmod 2 depth (0=none, 1=AM, 2=RM), Ringmod 3 depth (0=none, 1=AM, 2=RM), Osc1 gain (dB), RM1 gain (dB), Osc2 gain (dB), RM2 gain (dB), Input gain (dB), RM3 gain (dB), Xover lower freq, Xover upper freq, Dist1 drive, Dist2 drive, Dist3 drive, Filt1 type (0=none, 1=LP, 2=HP, 3=BP, 4=BR, 5=AP), Filt1 freq, Filt1 q, Filt1 resonance, Filt1 LFO1 level, Filt1 LFO2 level, Filt2 type (0=none, 1=LP, 2=HP, 3=BP, 4=BR, 5=AP), Filt2 freq, Filt2 q, Filt2 resonance, Filt2 LFO1 level, Filt2 LFO2 level, Filt3 type (0=none, 1=LP, 2=HP, 3=BP, 4=BR, 5=AP), Filt3 freq, Filt3 q, Filt3 resonance, Filt3 LFO1 level, Filt3 LFO2 level, Delay1 length (s), Delay1 feedback, Delay1 wetness, Delay2 length (s), Delay2 feedback, Delay2 wetness, Delay3 length (s), Delay3 feedback, Delay3 wetness, Band 1 gain (dB), Band 2 gain (dB), Band 3 gain (dB)", "LV2 Glame Highpass Filter -elv2:http://plugin.org.uk/swh-plugins/highpass_iir, Cutoff Frequency, Stages(2 poles per stage)", "LV2 Hilbert transformer -elv2:http://plugin.org.uk/swh-plugins/hilbert, latency", "LV2 Non-bandlimited single-sample impulses -elv2:http://plugin.org.uk/swh-plugins/impulse_fc, Frequency (Hz)", "LV2 Inverter -elv2:http://plugin.org.uk/swh-plugins/inv, ", "LV2 Karaoke -elv2:http://plugin.org.uk/swh-plugins/karaoke, Vocal volume (dB)", "LV2 L/C/R Delay -elv2:http://plugin.org.uk/swh-plugins/lcrDelay, L delay (ms), L level, C delay (ms), C level, R delay (ms), R level, Feedback, High damp (%), Low damp (%), Spread, Dry/Wet level", "LV2 LFO Phaser -elv2:http://plugin.org.uk/swh-plugins/lfoPhaser, LFO rate (Hz), LFO depth, Feedback, Spread (octaves)", "LV2 Lookahead limiter -elv2:http://plugin.org.uk/swh-plugins/lookaheadLimiter, Limit (dB), Lookahead delay, Attenuation (dB), latency", "LV2 Lookahead limiter (fixed latency) -elv2:http://plugin.org.uk/swh-plugins/lookaheadLimiterConst, Limit (dB), Lookahead time (s), Attenuation (dB), latency", "LV2 Glame Lowpass Filter -elv2:http://plugin.org.uk/swh-plugins/lowpass_iir, Cutoff Frequency, Stages(2 poles per stage)", "LV2 LS Filter -elv2:http://plugin.org.uk/swh-plugins/lsFilter, Filter type (0=LP, 1=BP, 2=HP), Cutoff frequency (Hz), Resonance", "LV2 Matrix: MS to Stereo -elv2:http://plugin.org.uk/swh-plugins/matrixMSSt, Width", "LV2 Matrix Spatialiser -elv2:http://plugin.org.uk/swh-plugins/matrixSpatialiser, Width", "LV2 Matrix: Stereo to MS -elv2:http://plugin.org.uk/swh-plugins/matrixStMS, ", "LV2 Multiband EQ -elv2:http://plugin.org.uk/swh-plugins/mbeq, 50Hz gain (low shelving), 100Hz gain, 156Hz gain, 220Hz gain, 311Hz gain, 440Hz gain, 622Hz gain, 880Hz gain, 1250Hz gain, 1750Hz gain, 2500Hz gain, 3500Hz gain, 5000Hz gain, 10000Hz gain, 20000Hz gain, latency", "LV2 Modulatable delay -elv2:http://plugin.org.uk/swh-plugins/modDelay, Base delay (s)", "LV2 Multivoice Chorus -elv2:http://plugin.org.uk/swh-plugins/multivoiceChorus, Number of voices, Delay base (ms), Voice separation (ms), Detune (%), LFO frequency (Hz), Output attenuation (dB)", "LV2 Higher Quality Pitch Scaler -elv2:http://plugin.org.uk/swh-plugins/pitchScaleHQ, Pitch co-efficient, latency", "LV2 Plate reverb -elv2:http://plugin.org.uk/swh-plugins/plate, Reverb time, Damping, Dry/wet mix", "LV2 Pointer cast distortion -elv2:http://plugin.org.uk/swh-plugins/pointerCastDistortion, Effect cutoff freq (Hz), Dry/wet mix", "LV2 Rate shifter -elv2:http://plugin.org.uk/swh-plugins/rateShifter, Rate", "LV2 Retro Flanger -elv2:http://plugin.org.uk/swh-plugins/retroFlange, Average stall (ms), Flange frequency (Hz)", "LV2 Reverse Delay (5s max) -elv2:http://plugin.org.uk/swh-plugins/revdelay, Delay Time (s), Dry Level (dB), Wet Level (dB), Feedback, Crossfade samples", "LV2 Ringmod with LFO -elv2:http://plugin.org.uk/swh-plugins/ringmod_1i1o1l, Modulation depth (0=none, 1=AM, 2=RM), Frequency (Hz), Sine level, Triangle level, Sawtooth level, Square level", "LV2 Ringmod with two inputs -elv2:http://plugin.org.uk/swh-plugins/ringmod_2i1o, Modulation depth (0=none, 1=AM, 2=RM)", "LV2 Barrys Satan Maximiser -elv2:http://plugin.org.uk/swh-plugins/satanMaximiser, Decay time (samples), Knee point (dB)", "LV2 SC1 -elv2:http://plugin.org.uk/swh-plugins/sc1, Attack time (ms), Release time (ms), Threshold level (dB), Ratio (1:n), Knee radius (dB), Makeup gain (dB)", "LV2 SC2 -elv2:http://plugin.org.uk/swh-plugins/sc2, Attack time (ms), Release time (ms), Threshold level (dB), Ratio (1:n), Knee radius (dB), Makeup gain (dB)", "LV2 SC3 -elv2:http://plugin.org.uk/swh-plugins/sc3, Attack time (ms), Release time (ms), Threshold level (dB), Ratio (1:n), Knee radius (dB), Makeup gain (dB), Chain balance", "LV2 SC4 -elv2:http://plugin.org.uk/swh-plugins/sc4, RMS/peak, Attack time (ms), Release time (ms), Threshold level (dB), Ratio (1:n), Knee radius (dB), Makeup gain (dB), Amplitude (dB), Gain reduction (dB)", "LV2 SE4 -elv2:http://plugin.org.uk/swh-plugins/se4, RMS/peak, Attack time (ms), Release time (ms), Threshold level (dB), Ratio (1:n), Knee radius (dB), Attenuation (dB), Amplitude (dB), Gain expansion (dB)", "LV2 Wave shaper -elv2:http://plugin.org.uk/swh-plugins/shaper, Waveshape", "LV2 Signal sifter -elv2:http://plugin.org.uk/swh-plugins/sifter, Sift size", "LV2 Sine + cosine oscillator -elv2:http://plugin.org.uk/swh-plugins/sinCos, Base frequency (Hz), Pitch offset", "LV2 Single band parametric -elv2:http://plugin.org.uk/swh-plugins/singlePara, Gain (dB), Frequency (Hz), Bandwidth (octaves)", "LV2 Sinus wavewrapper -elv2:http://plugin.org.uk/swh-plugins/sinusWavewrapper, Wrap degree", "LV2 Smooth Decimator -elv2:http://plugin.org.uk/swh-plugins/smoothDecimate, Resample rate, Smoothing", "LV2 Mono to Stereo splitter -elv2:http://plugin.org.uk/swh-plugins/split, ", "LV2 Surround matrix encoder -elv2:http://plugin.org.uk/swh-plugins/surroundEncoder, ", "LV2 State Variable Filter -elv2:http://plugin.org.uk/swh-plugins/svf, Filter type (0=none, 1=LP, 2=HP, 3=BP, 4=BR, 5=AP), Filter freq, Filter Q, Filter resonance", "LV2 Tape Delay Simulation -elv2:http://plugin.org.uk/swh-plugins/tapeDelay, Tape speed (inches/sec, 1=normal), Dry level (dB), Tap 1 distance (inches), Tap 1 level (dB), Tap 2 distance (inches), Tap 2 level (dB), Tap 3 distance (inches), Tap 3 level (dB), Tap 4 distance (inches), Tap 4 level (dB)", "LV2 Transient mangler -elv2:http://plugin.org.uk/swh-plugins/transient, Attack speed, Sustain time", "LV2 Triple band parametric with shelves -elv2:http://plugin.org.uk/swh-plugins/triplePara, Low-shelving gain (dB), Low-shelving frequency (Hz), Low-shelving slope, Band 1 gain (dB), Band 1 frequency (Hz), Band 1 bandwidth (octaves), Band 2 gain (dB), Band 2 frequency (Hz), Band 2 bandwidth (octaves), Band 3 gain (dB), Band 3 frequency (Hz), Band 3 bandwidth (octaves), High-shelving gain (dB), High-shelving frequency (Hz), High-shelving slope", "LV2 μ-Law Compressor -elv2:http://plugin.org.uk/swh-plugins/ulaw, ", "LV2 Valve saturation -elv2:http://plugin.org.uk/swh-plugins/valve, Distortion level, Distortion character", "LV2 Valve rectifier -elv2:http://plugin.org.uk/swh-plugins/valveRect, Sag level, Distortion", "LV2 VyNil (Vinyl Effect) -elv2:http://plugin.org.uk/swh-plugins/vynil, Year, RPM, Surface warping, Crackle, Wear", "LV2 Wave Terrain Oscillator -elv2:http://plugin.org.uk/swh-plugins/waveTerrain, ", "LV2 Crossfade -elv2:http://plugin.org.uk/swh-plugins/xfade, Crossfade", "LV2 Crossfade (4 outs) -elv2:http://plugin.org.uk/swh-plugins/xfade4, Crossfade", "LV2 z-1 -elv2:http://plugin.org.uk/swh-plugins/zm1, ", "dyn_compress_brutal, -pn:dyn_compress_brutal:gain-%\n", "dyn_compress_hard, -pn:dyn_compress_hard:gain-%\n", "dyn_compress_infinite, -pn:dyn_compress_infinite:gain-%\n", "dyn_compress_medium, -pn:dyn_compress_medium:gain-%\n", "dyn_compress_soft, -pn:dyn_compress_soft:gain-%\n", "dyn_compress_supersoft, -pn:dyn_compress_supersoft:gain-%\n", "eq_template, -pn:eq_template:10hz, 40hz, 100hz, 220hz, 460hz, 940hz, 1900hz, 3800hz, 7620hz, 15300hz\n", "eq_template2, -pn:eq_template2:1000hz, 4000hz\n", "f_bandpass, -pn:f_bandpass:freq, width\n", "f_filtertest, -pn:f_filtertest:freq1, freq2\n", "f_high_and_low, -pn:f_high_and_low\n", "f_highpass, -pn:f_highpass\n", "f_inverse_comb, -pn:f_inverse_comb\n", "f_lowp_sine, -pn:f_lowp_sine\n", "f_lowp_sine2, -pn:f_lowp_sine2\n", "f_lowpass, -pn:f_lowpass:freq_hz\n", "f_rejectband, -pn:f_rejectband\n", "f_res_bandpass, -pn:f_res_bandpass:freq, width\n", "f_res_lowpass, -pn:f_res_lowpass:arg-1\n", "f_resonator, -pn:f_resonator\n", "f_two_filters, -pn:f_two_filters:lowgain, highgain\n", "f_two_filters_pareq, -pn:f_two_filters_pareq:lowfreq, lowgain, highfreq, highgain\n", "gate_crop, -pn:gate_crop\n", "gate_noisegate_1, -pn:gate_noisegate_1\n", "gate_noisegate_delanalog, -pn:gate_noisegate_delanalog\n", "gate_threshold, -pn:gate_threshold\n", "lad_hermes, -pn:lad_hermes:p1, p2, p3, p4\n", "lad_metronome, -pn:lad_metronome:bpm\n", "lad_oscillator_stack, -pn:lad_oscillator_stack:freq, osctype1, osctype2, gain1, gain2\n", "lad_oscillator_test, -pn:lad_oscillator_test:freq, gain1\n", "lad_sc4, -pn:lad_sc4:output-amplitude-dB, output-gain-reduction-dB\n", "lad_sc4_rg, -pn:lad_sc4_rg:ratio, gain-dB, output-amplitude-dB, output-gain-reduction-dB\n", "metronome, -pn:metronome:bpm\n", "time_chorus1, -pn:time_chorus1\n", "time_delay1, -pn:time_delay1\n", "time_delay2, -pn:time_delay2\n", "time_flanger1, -pn:time_flanger1\n", "time_phaser1, -pn:time_phaser1\n", "time_reverb1, -pn:time_reverb1\n", "time_reverb2, -pn:time_reverb2\n", "time_reverb3, -pn:time_reverb3\n", "time_reverb4, -pn:time_reverb4\n", "time_wicked_dub, -pn:time_wicked_dub\n", "var_aw, -pn:var_aw:speed\n", "var_aw_custom, -pn:var_aw_custom:low, high, speed\n", "var_aw_ksv, -pn:var_aw_ksv\n", "var_aw_tri, -pn:var_aw_tri:speed\n", "var_aw_tri_custom, -pn:var_aw_tri_custom:speed\n", "var_chipmunk, -pn:var_chipmunk\n", "var_dali, -pn:var_dali\n", "var_molten_tape, -pn:var_molten_tape\n", "var_paralmadness, -pn:var_paralmadness:freq1, freq2, freq3\n", "var_parchip, -pn:var_parchip:pitch, modfreq\n", "var_stretched_tape, -pn:var_stretched_tape\n", "var_sweeping_pan, -pn:var_sweeping_pan:speed_hz\n", "var_switching_pan, -pn:var_switching_pan:speed_hz\n", ". Diode Processor -el:diode, Mode (0 for none, 1 for half wave, 2 for full wave)\n", ". White Noise Source -el:noise_white, Amplitude\n", ". TAP Reflector -el:tap_reflector, Fragment Length [ms], Dry Level [dB], Wet Level [dB]\n", ". TAP Pink/Fractal Noise -el:tap_pinknoise, Fractal Dimension, Signal Level [dB], Noise Level [dB]\n", ". AMB order 1, 1 cube decoder -el:Ambisonics-11-cube-decoder, Shelf filt, HF XYZ gain, LF XYZ gain, Shelf freq, Distance\n", ". AMB order 1, 1 hexagon decoder -el:Ambisonics-11-hexagon-decoder, Front spkr, Shelf filt, HF XY gain, LF XY gain, Shelf freq, Distance\n", ". AMB order 1, 1 square decoder -el:Ambisonics-11-square-decoder, Front spkr, Shelf filt, HF XY gain, LF XY gain, Shelf freq, Distance\n", ". AMB order 1, 1 rotator -el:Ambisonics-11-rotator, Angle\n", ". AMB order 1, 1 stereo panner -el:Ambisonics-11-stereo-panner, Elevation, Width, Azimuth\n", ". AMB order 1, 1 mono panner -el:Ambisonics-11-mono-panner, Elevation, Azimuth\n", ". Crossover distortion -el:crossoverDist, Crossover amplitude, Smoothing\n", ". Higher Quality Pitch Scaler -el:pitchScaleHQ, Pitch co-efficient, latency\n", ". UHJ Decoder -el:UHJ-decoder", ". UHJ Encoder -el:UHJ-encoder", ". Virtual stereo microphone -el:Virtualmic, Elevation, Azimuth, Angle, Polar\n", ". Three cardioids to AMB matrix -el:Tricardioid-to-AMB", ". Mag's Notch Filter -el:notch_iir, Center Frequency (Hz), Bandwidth (Hz), Stages(2 poles per stage)\n", ". Signal sifter -el:sifter, Sift size\n", ". Sine + cosine oscillator -el:sinCos, Base frequency (Hz), Pitch offset\n", ". TAP TubeWarmth -el:tap_tubewarmth, Drive, Tape--Tube Blend\n", ". Allpass delay line, cubic spline interpolation -el:allpass_c, Max Delay (s), Delay Time (s), Decay Time (s)\n", ". Allpass delay line, linear interpolation -el:allpass_l, Max Delay (s), Delay Time (s), Decay Time (s)\n", ". Allpass delay line, noninterpolating -el:allpass_n, Max Delay (s), Delay Time (s), Decay Time (s)\n", ". SC2 -el:sc2, Attack time (ms), Release time (ms), Threshold level (dB), Ratio (1:n), Knee radius (dB), Makeup gain (dB)\n", ". Comb Splitter -el:combSplitter, Band separation (Hz)\n", ". Modulatable delay -el:modDelay, Base delay (s)\n", ". Audio Divider (Suboctave Generator) -el:divider, Denominator\n", ". Surround matrix encoder -el:surroundEncoder", ". Chebyshev distortion -el:chebstortion, Distortion\n", ". Bode frequency shifter (CV) -el:bodeShifterCV, Base shift, Mix (-1=down, +1=up), CV Attenuation, latency\n", ". TAP DeEsser -el:tap_deesser, Threshold Level [dB], Frequency [Hz], Sidechain Filter, Monitor, Attenuation [dB]\n", ". Wave shaper -el:shaper, Waveshape\n", ". Tape Delay Simulation -el:tapeDelay, Tape speed (inches/sec, 1=normal), Dry level (dB), Tap 1 distance (inches), Tap 1 level (dB), Tap 2 distance (inches), Tap 2 level (dB), Tap 3 distance (inches), Tap 3 level (dB), Tap 4 distance (inches), Tap 4 level (dB)\n", ". Comb Filter -el:comb, Band separation (Hz), Feedback\n", ". Ringmod with LFO -el:ringmod_1i1o1l, Modulation depth (0=none, 1=AM, 2=RM), Frequency (Hz), Sine level, Triangle level, Sawtooth level, Square level\n", ". Ringmod with two inputs -el:ringmod_2i1o, Modulation depth (0=none, 1=AM, 2=RM)\n", ". Simple High Pass Filter -el:hpf, Cutoff Frequency (Hz)\n", ". Simple Low Pass Filter -el:lpf, Cutoff Frequency (Hz)\n", ". TAP Dynamics (St) -el:tap_dynamics_st, Attack [ms], Release [ms], Offset Gain [dB], Makeup Gain [dB], Envelope Volume (L) [dB], Envelope Volume (R) [dB], Gain Adjustment (L) [dB], Gain Adjustment (R) [dB], Stereo Mode, Function\n", ". Crossfade (4 outs) -el:xfade4, Crossfade\n", ". Crossfade -el:xfade, Crossfade\n", ". TAP Dynamics (M) -el:tap_dynamics_m, Attack [ms], Release [ms], Offset Gain [dB], Makeup Gain [dB], Envelope Volume [dB], Gain Adjustment [dB], Function\n", ". Triple band parametric with shelves -el:triplePara, Low-shelving gain (dB), Low-shelving frequency (Hz), Low-shelving slope, Band 1 gain (dB), Band 1 frequency (Hz), Band 1 bandwidth (octaves), Band 2 gain (dB), Band 2 frequency (Hz), Band 2 bandwidth (octaves), Band 3 gain (dB), Band 3 frequency (Hz), Band 3 bandwidth (octaves), High-shelving gain (dB), High-shelving frequency (Hz), High-shelving slope\n", ". Plate reverb -el:plate, Reverb time, Damping, Dry/wet mix\n", ". Mono to Stereo splitter -el:split", ". TAP Reverberator -el:tap_reverb, Decay [ms], Dry Level [dB], Wet Level [dB], Comb Filters, Allpass Filters, Bandpass Filter, Enhanced Stereo, Reverb Type\n", ". Flanger -el:flanger, Delay base (ms), Max slowdown (ms), LFO frequency (Hz), Feedback\n", ". TAP AutoPanner -el:tap_autopan, Frequency [Hz], Depth [%], Gain [dB]\n", ". zita-reverb-amb -el:zita-reverb-amb, Delay, Xover, RT-low, RT-mid, Damping, F1-freq, F1-gain, F2-freq, F2-gain, XYZ gain\n", ". zita-reverb -el:zita-reverb, Delay, Xover, RT-low, RT-mid, Damping, F1-freq, F1-gain, F2-freq, F2-gain, Output mix\n", ". Stereo reverb -el:G2reverb, Room size, Reverb time, Input BW, Damping, Dry sound, Reflections, Reverb tail\n", ". Pitch Scaler -el:pitchScale, Pitch co-efficient, latency\n", ". Glame Highpass Filter -el:highpass_iir, Cutoff Frequency, Stages(2 poles per stage)\n", ". Impulse convolver -el:imp, Impulse ID, High latency mode, Gain (dB), latency\n", ". :: Invada :: ER Reverb - Sum L+R In -el:invada_sum_reverbER_module_0_1, Room Length, Room Width, Room Height, Source (L/R), Source (F/B), Listener (L/R), Listener (F/B), HPF (Hz), Warmth, Diffusion\n", ". :: Invada :: ER Reverb - Mono In -el:invada_mono_reverbER_module_0_1, Room Length, Room Width, Room Height, Source (L/R), Source (F/B), Listener (L/R), Listener (F/B), HPF (Hz), Warmth, Diffusion\n", ". Matrix Spatialiser -el:matrixSpatialiser, Width\n", ". LS Filter -el:lsFilter, Filter type (0=LP, 1=BP, 2=HP), Cutoff frequency (Hz), Resonance\n", ". Hard Limiter -el:hardLimiter, dB limit, Wet level, Residue level\n", ". Foldover distortion -el:foldover, Drive, Skew\n", ". SC1 -el:sc1, Attack time (ms), Release time (ms), Threshold level (dB), Ratio (1:n), Knee radius (dB), Makeup gain (dB)\n", ". AMB order 3, 3 rotator -el:Ambisonics-33-rotator, Angle\n", ". AMB order 3, 3 panner -el:Ambisonics-33-panner, Elevation, Azimuth\n", ". AMB order 3, 1 rotator -el:Ambisonics-31-rotator, Angle\n", ". AMB order 3, 1 panner -el:Ambisonics-31-panner, Elevation, Azimuth\n", ". DC Offset Remover -el:dcRemove", ". Karaoke -el:karaoke, Vocal volume (dB)\n", ". Reverse Delay (5s max) -el:revdelay, Delay Time (s), Dry Level (dB), Wet Level (dB), Feedback, Crossfade samples\n", ". GSM simulator -el:gsm, Dry/wet mix, Number of passes, Error rate (bits/block), latency\n", ". TAP Equalizer/BW -el:tap_equalizer_bw, Band 1 Gain [dB], Band 2 Gain [dB], Band 3 Gain [dB], Band 4 Gain [dB], Band 5 Gain [dB], Band 6 Gain [dB], Band 7 Gain [dB], Band 8 Gain [dB], Band 1 Freq [Hz], Band 2 Freq [Hz], Band 3 Freq [Hz], Band 4 Freq [Hz], Band 5 Freq [Hz], Band 6 Freq [Hz], Band 7 Freq [Hz], Band 8 Freq [Hz], Band 1 Bandwidth [octaves], Band 2 Bandwidth [octaves], Band 3 Bandwidth [octaves], Band 4 Bandwidth [octaves], Band 5 Bandwidth [octaves], Band 6 Bandwidth [octaves], Band 7 Bandwidth [octaves], Band 8 Bandwidth [octaves]\n", ". Pointer cast distortion -el:pointerCastDistortion, Effect cutoff freq (Hz), Dry/wet mix\n", ". Frequency tracker -el:freqTracker, Tracking speed\n", ". GVerb -el:gverb, Roomsize (m), Reverb time (s), Damping, Input bandwidth, Dry signal level (dB), Early reflection level (dB), Tail level (dB)\n", ". Aliasing -el:alias, Aliasing level\n", ". Sinus wavewrapper -el:sinusWavewrapper, Wrap degree\n", ". Dyson compressor -el:dysonCompress, Peak limit (dB), Release time (s), Fast compression ratio, Compression ratio\n", ". DJ flanger -el:djFlanger, LFO sync, LFO period (s), LFO depth (ms), Feedback (%)\n", ". DJ EQ -el:dj_eq, Lo gain (dB), Mid gain (dB), Hi gain (dB), latency\n", ". DJ EQ (mono) -el:dj_eq_mono, Lo gain (dB), Mid gain (dB), Hi gain (dB), latency\n", ". Step Demuxer -el:stepMuxer, Crossfade time (in ms)\n", ". Gate -el:gate, LF key filter (Hz), HF key filter (Hz), Threshold (dB), Attack (ms), Hold (ms), Decay (ms), Range (dB), Output select (-1 = key listen, 0 = gate, 1 = bypass)\n", ". :: Invada :: Compressor - Stereo -el:invada_stereo_compressor_module_0_1, Tight / Sloppy, Attack (ms), Release (ms), Threshold (dB), Ratio, Gain (dB), Soft Clip, Gain Reduction\n", ". :: Invada :: Compressor - Mono -el:invada_mono_compressor_module_0_1, Tight / Sloppy, Attack (ms), Release (ms), Threshold (dB), Ratio, Gain (dB), Soft Clip, Gain Reduction\n", ". Gong model -el:gong, Inner damping, Outer damping, Mic position, Inner size 1, Inner stiffness 1 +, Inner stiffness 1 -, Inner size 2, Inner stiffness 2 +, Inner stiffness 2 -, Inner size 3, Inner stiffness 3 +, Inner stiffness 3 -, Inner size 4, Inner stiffness 4 +, Inner stiffness 4 -, Outer size 1, Outer stiffness 1 +, Outer stiffness 1 -, Outer size 2, Outer stiffness 2 +, Outer stiffness 2 -, Outer size 3, Outer stiffness 3 +, Outer stiffness 3 -, Outer size 4, Outer stiffness 4 +, Outer stiffness 4 -\n", ". TAP Fractal Doubler -el:tap_doubler, Time Tracking, Pitch Tracking, Dry Level [dB], Dry Left Position, Dry Right Position, Wet Level [dB], Wet Left Position, Wet Right Position\n", ". Valve rectifier -el:valveRect, Sag level, Distortion\n", ". AM pitchshifter -el:amPitchshift, Pitch shift, Buffer size, latency\n", ". SE4 -el:se4, RMS/peak, Attack time (ms), Release time (ms), Threshold level (dB), Ratio (1:n), Knee radius (dB), Attenuation (dB), Amplitude (dB), Gain expansion (dB)\n", ". Auto phaser -el:autoPhaser, Attack time (s), Decay time (s), Modulation depth, Feedback, Spread (octaves)\n", ". 4 x 4 pole allpass -el:fourByFourPole, Frequency 1, Feedback 1, Frequency 2, Feedback 2, Frequency 3, Feedback 3, Frequency 4, Feedback 4\n", ". LFO Phaser -el:lfoPhaser, LFO rate (Hz), LFO depth, Feedback, Spread (octaves)\n", ". Matrix: Stereo to MS -el:matrixStMS", ". Constant Signal Generator -el:const, Signal amplitude\n", ". Simple amplifier -el:amp, Amps gain (dB)\n", ". :: Invada :: Input Module -el:invada_stereo_input_module_0_1, Phase Reverse (Left), Phase Reverse (Right), Gain (dB), Pan (L-R), Width (M-S), Soft Clip\n", ". Rate shifter -el:rateShifter, Rate\n", ". Simple Delay Line -el:delay_5s, Delay (Seconds), Dry/Wet Balance\n", ". AMB order 2, 2 rotator -el:Ambisonics-22-rotator, Angle\n", ". AMB order 2, 2 panner -el:Ambisonics-22-panner, Elevation, Azimuth\n", ". AMB order 2, 1 rotator -el:Ambisonics-21-rotator, Angle\n", ". AMB order 2, 1 panner -el:Ambisonics-21-panner, Elevation, Azimuth\n", ". Giant flange -el:giantFlange, Double delay, LFO frequency 1 (Hz), Delay 1 range (s), LFO frequency 2 (Hz), Delay 2 range (s), Feedback, Dry/Wet level\n", ". State Variable Filter -el:svf, Filter type (0=none, 1=LP, 2=HP, 3=BP, 4=BR, 5=AP), Filter freq, Filter Q, Filter resonance\n", ". Multiband EQ -el:mbeq, 50Hz gain (low shelving), 100Hz gain, 156Hz gain, 220Hz gain, 311Hz gain, 440Hz gain, 622Hz gain, 880Hz gain, 1250Hz gain, 1750Hz gain, 2500Hz gain, 3500Hz gain, 5000Hz gain, 10000Hz gain, 20000Hz gain, latency\n", ". Decimator -el:decimator, Bit depth, Sample rate (Hz)\n", ". Single band parametric -el:singlePara, Gain (dB), Frequency (Hz), Bandwidth (octaves)\n", ". Barry's Satan Maximiser -el:satanMaximiser, Decay time (samples), Knee point (dB)\n", ". Artificial latency -el:artificialLatency, Delay (ms), latency\n", ". Glame Bandpass Filter -el:bandpass_iir, Center Frequency (Hz), Bandwidth (Hz), Stages(2 poles per stage)\n", ". Declipper -el:declip", ". :: Invada :: Tube - Stereo -el:invada_stereo_tube_module_0_1, Drive (dB), DC Offset, Phase, Wet/Dry Mix (%)\n", ". :: Invada :: Tube - Mono -el:invada_mono_tube_module_0_1, Drive (dB), DC Offset, Phase, Wet/Dry Mix (%)\n", ". Matrix: MS to Stereo -el:matrixMSSt, Width\n", ". TAP Equalizer -el:tap_equalizer, Band 1 Gain [dB], Band 2 Gain [dB], Band 3 Gain [dB], Band 4 Gain [dB], Band 5 Gain [dB], Band 6 Gain [dB], Band 7 Gain [dB], Band 8 Gain [dB], Band 1 Freq [Hz], Band 2 Freq [Hz], Band 3 Freq [Hz], Band 4 Freq [Hz], Band 5 Freq [Hz], Band 6 Freq [Hz], Band 7 Freq [Hz], Band 8 Freq [Hz]\n", ". 4-band parametric filter -el:Parametric1, Filter, Gain, Section 1, Frequency 1, Bandwidth 1, Gain 1, Section 2, Frequency 2, Bandwidth 2, Gain 2, Section 3, Frequency 3, Bandwidth 3, Gain 3, Section 4, Frequency 4, Bandwidth 4, Gain 4\n", ". Harmonic generator -el:harmonicGen, Fundamental magnitude, 2nd harmonic magnitude, 3rd harmonic magnitude, 4th harmonic magnitude, 5th harmonic magnitude, 6th harmonic magnitude, 7th harmonic magnitude, 8th harmonic magnitude, 9th harmonic magnitude, 10th harmonic magnitude\n", ". Retro Flanger -el:retroFlange, Average stall (ms), Flange frequency (Hz)\n", ". VyNil (Vinyl Effect) -el:vynil, Year, RPM, Surface warping, Crackle, Wear\n", ". TAP Chorus/Flanger -el:tap_chorusflanger, Frequency [Hz], L/R Phase Shift [deg], Depth [%], Delay [ms], Contour [Hz], Dry Level [dB], Wet Level [dB]\n", ". Smooth Decimator -el:smoothDecimate, Resample rate, Smoothing\n", ". TAP Stereo Echo -el:tap_stereo_echo, L Delay [ms], L Feedback [%], R/Haas Delay [ms], R/Haas Feedback [%], L Echo Level [dB], R Echo Level [dB], Dry Level [dB], Cross Mode, Haas Effect, Swap Outputs\n", ". Fractionally Addressed Delay Line -el:fadDelay, Delay (seconds), Feedback (dB)\n", ". Wave Terrain Oscillator -el:waveTerrain", ". Transient mangler -el:transient, Attack speed, Sustain time\n", ". C* CEO - Chief Executive Oscillator -el:CEO, ppm, volume, damping\n", ". C* Click - Metronome -el:Click, model, bpm, volume, damping\n", ". C* Fractal - Audio stream from deterministic chaos -el:Fractal, rate, mode, x, y, z, hp, volume\n", ". C* White - Noise generator -el:White, volume\n", ". C* Sin - Sine wave generator -el:Sin, f (Hz), volume\n", ". C* Narrower - Stereo image width reduction -el:Narrower, mode, strength\n", ". C* Wider - Stereo image synthesis -el:Wider, pan, width\n", ". C* Eq4p - 4-band parametric equaliser -el:Eq4p, a.mode, a.f (Hz), a.Q, a.gain (dB), b.mode, b.f (Hz), b.Q, b.gain (dB), c.mode, c.f (Hz), c.Q, c.gain (dB), d.mode, d.f (Hz), d.Q, d.gain (dB)\n", ". C* Eq10X2 - Stereo 10-band equaliser -el:Eq10X2, 31 Hz, 63 Hz, 125 Hz, 250 Hz, 500 Hz, 1 kHz, 2 kHz, 4 kHz, 8 kHz, 16 kHz\n", ". C* Eq10 - 10-band equaliser -el:Eq10, 31 Hz, 63 Hz, 125 Hz, 250 Hz, 500 Hz, 1 kHz, 2 kHz, 4 kHz, 8 kHz, 16 kHz\n", ". C* Scape - Stereo delay with chromatic resonances -el:Scape, bpm, divider, feedback, dry, blend, tune (Hz)\n", ". C* AutoFilter - Modulated filter cascade -el:AutoFilter, over, mode, filter, gain (dB), f (Hz), Q, range, lfo/env, rate\n", ". C* PhaserII - Mono phaser -el:PhaserII, rate, lfo, depth, spread, resonance\n", ". C* ChorusI - Mono chorus/flanger -el:ChorusI, t (ms), width (ms), rate (Hz), blend, feedforward, feedback\n", ". C* SpiceX2 - Not an exciter either -el:SpiceX2, lo.f (Hz), lo.compress, lo.gain, hi.f (Hz), hi.gain\n", ". C* Spice - Not an exciter -el:Spice, lo.f (Hz), lo.compress, lo.gain, hi.f (Hz), hi.gain\n", ". C* Saturate - Various overdrive models, 8x oversampled -el:Saturate, mode, gain (dB), bias\n", ". C* PlateX2 - Versatile plate reverb, stereo inputs -el:PlateX2, bandwidth, tail, damping, blend\n", ". C* Plate - Versatile plate reverb -el:Plate, bandwidth, tail, damping, blend\n", ". C* CabinetIV - Idealised loudspeaker cabinet -el:CabinetIV, model, gain (dB)\n", ". C* AmpVTS - Idealised guitar amplification -el:AmpVTS, over, gain, bright, power, tonestack, bass, mid, treble, attack, squash, lowcut\n", ". C* ToneStack - Classic amplifier tone stack emulation -el:ToneStack, model, bass, mid, treble\n", ". C* CompressX2 - Stereo compressor and saturating limiter -el:CompressX2, measure, mode, threshold, strength, attack, release, gain (dB)\n", ". C* Compress - Compressor and saturating limiter -el:Compress, measure, mode, threshold, strength, attack, release, gain (dB)\n", ". C* NoiseGate - Attenuate hum and noise -el:NoiseGate, open (dB), attack (ms), close (dB), mains (Hz)\n", ". TAP Pitch Shifter -el:tap_pitch, Semitone Shift, Rate Shift [%], Dry Level [dB], Wet Level [dB], latency\n", ". Glame Lowpass Filter -el:lowpass_iir, Cutoff Frequency, Stages(2 poles per stage)\n", ". Nonbandlimited single-sample impulses (Frequency: Control) -el:impulse_fc, Frequency (Hz)\n", ". Fast Lookahead limiter -el:fastLookaheadLimiter, Input gain (dB), Limit (dB), Release time (s), Attenuation (dB), latency\n", ". TAP Vibrato -el:tap_vibrato, Frequency [Hz], Depth [%], Dry Level [dB], Wet Level [dB], latency\n", ". Simple delay line, cubic spline interpolation -el:delay_c, Max Delay (s), Delay Time (s)\n", ". Simple delay line, linear interpolation -el:delay_l, Max Delay (s), Delay Time (s)\n", ". Simple delay line, noninterpolating -el:delay_n, Max Delay (s), Delay Time (s)\n", ". Gong beater -el:gongBeater, Impulse gain (dB), Strike gain (dB), Strike duration (s)\n", ". SC4 mono -el:sc4m, RMS/peak, Attack time (ms), Release time (ms), Threshold level (dB), Ratio (1:n), Knee radius (dB), Makeup gain (dB), Amplitude (dB), Gain reduction (dB)\n", ". FM Oscillator -el:fmOsc, Waveform (1=sin, 2=tri, 3=squ, 4=saw)\n", ". Multivoice Chorus -el:multivoiceChorus, Number of voices, Delay base (ms), Voice separation (ms), Detune (%), LFO frequency (Hz), Output attenuation (dB)\n", ". z-1 -el:zm1", ". TAP Rotary Speaker -el:tap_rotspeak, Rotor Frequency [Hz], Horn Frequency [Hz], Mic Distance [%], Rotor/Horn Mix, latency\n", ". TAP Scaling Limiter -el:tap_limiter, Limit Level [dB], Output Volume [dB], latency\n", ". Sine Oscillator (Freq:control, Amp:control) -el:sine_fcac, Frequency (Hz), Amplitude\n", ". Sine Oscillator (Freq:control, Amp:audio) -el:sine_fcaa, Frequency (Hz)\n", ". Sine Oscillator (Freq:audio, Amp:control) -el:sine_faac, Amplitude\n", ". Sine Oscillator (Freq:audio, Amp:audio) -el:sine_faaa", ". Bode frequency shifter -el:bodeShifter, Frequency shift, latency\n", ". Hermes Filter -el:hermesFilter, LFO1 freq (Hz), LFO1 wave (0 = sin, 1 = tri, 2 = saw, 3 = squ, 4 = s&h), LFO2 freq (Hz), LFO2 wave (0 = sin, 1 = tri, 2 = saw, 3 = squ, 4 = s&h), Osc1 freq (Hz), Osc1 wave (0 = sin, 1 = tri, 2 = saw, 3 = squ, 4 = noise), Osc2 freq (Hz), Osc2 wave (0 = sin, 1 = tri, 2 = saw, 3 = squ, 4 = noise), Ringmod 1 depth (0=none, 1=AM, 2=RM), Ringmod 2 depth (0=none, 1=AM, 2=RM), Ringmod 3 depth (0=none, 1=AM, 2=RM), Osc1 gain (dB), RM1 gain (dB), Osc2 gain (dB), RM2 gain (dB), Input gain (dB), RM3 gain (dB), Xover lower freq, Xover upper freq, Dist1 drive, Dist2 drive, Dist3 drive, Filt1 type (0=none, 1=LP, 2=HP, 3=BP, 4=BR, 5=AP), Filt1 freq, Filt1 q, Filt1 resonance, Filt1 LFO1 level, Filt1 LFO2 level, Filt2 type (0=none, 1=LP, 2=HP, 3=BP, 4=BR, 5=AP), Filt2 freq, Filt2 q, Filt2 resonance, Filt2 LFO1 level, Filt2 LFO2 level, Filt3 type (0=none, 1=LP, 2=HP, 3=BP, 4=BR, 5=AP), Filt3 freq, Filt3 q, Filt3 resonance, Filt3 LFO1 level, Filt3 LFO2 level, Delay1 length (s), Delay1 feedback, Delay1 wetness, Delay2 length (s), Delay2 feedback, Delay2 wetness, Delay3 length (s), Delay3 feedback, Delay3 wetness, Band 1 gain (dB), Band 2 gain (dB), Band 3 gain (dB)\n", ". SC3 -el:sc3, Attack time (ms), Release time (ms), Threshold level (dB), Ratio (1:n), Knee radius (dB), Makeup gain (dB), Chain balance\n", ". Comb delay line, cubic spline interpolation -el:comb_c, Max Delay (s), Delay Time (s), Decay Time (s)\n", ". Comb delay line, linear interpolation -el:comb_l, Max Delay (s), Delay Time (s), Decay Time (s)\n", ". Comb delay line, noninterpolating -el:comb_n, Max Delay (s), Delay Time (s), Decay Time (s)\n", ". Delayorama -el:delayorama, Random seed, Input gain (dB), Feedback (%), Number of taps, First delay (s), Delay range (s), Delay change, Delay random (%), Amplitude change, Amplitude random (%), Dry/wet mix\n", ". Fast overdrive -el:foverdrive, Drive level\n", ". GLAME Butterworth Highpass -el:butthigh_iir, Cutoff Frequency (Hz), Resonance\n", ". GLAME Butterworth Lowpass -el:buttlow_iir, Cutoff Frequency (Hz), Resonance\n", ". Glame Butterworth X-over Filter -el:bwxover_iir, Cutoff Frequency (Hz), Resonance\n", ". Exponential signal decay -el:decay, Decay Time (s)\n", ". TAP Sigmoid Booster -el:tap_sigmoid, Pre Gain [dB], Post Gain [dB]\n", ". L/C/R Delay -el:lcrDelay, L delay (ms), L level, C delay (ms), C level, R delay (ms), R level, Feedback, High damp (%), Low damp (%), Spread, Dry/Wet level\n", ". Stereo Amplifier -el:amp_stereo, Gain\n", ". Mono Amplifier -el:amp_mono, Gain\n", ". SC4 -el:sc4, RMS/peak, Attack time (ms), Release time (ms), Threshold level (dB), Ratio (1:n), Knee radius (dB), Makeup gain (dB), Amplitude (dB), Gain reduction (dB)\n", ". Valve saturation -el:valve, Distortion level, Distortion character\n", ". TAP Tremolo -el:tap_tremolo, Frequency [Hz], Depth [%], Gain [dB]\n", ". Inverter -el:inv", ". Analogue Oscillator -el:analogueOsc, Waveform (1=sin, 2=tri, 3=squ, 4=saw), Frequency (Hz), Warmth, Instability\n", ". :: Invada :: Filter - High Pass Stereo -el:invada_hp_stereo_filter_module_0_1, Frequency (Hz), Gain (dB), Soft Clip\n", ". :: Invada :: Filter - Low Pass Stereo -el:invada_lp_stereo_filter_module_0_1, Frequency (Hz), Gain (dB), Soft Clip\n", ". :: Invada :: Filter - High Pass Mono -el:invada_hp_mono_filter_module_0_1, Frequency (Hz), Gain (dB), Soft Clip\n", ". :: Invada :: Filter - Low Pass Mono -el:invada_lp_mono_filter_module_0_1, Frequency (Hz), Gain (dB), Soft Clip\n", ". Hilbert transformer -el:hilbert, latency\n", ". Glame Bandpass Analog Filter -el:bandpass_a_iir, Center Frequency (Hz), Bandwidth (Hz)\n" ] } } Audio-Nama-1.208/inc/0000755000175000017500000000000012644673607013265 5ustar jrothjrothAudio-Nama-1.208/inc/Module/0000755000175000017500000000000012644673607014512 5ustar jrothjrothAudio-Nama-1.208/inc/Module/Install.pm0000644000175000017500000003021712644673575016465 0ustar jrothjroth#line 1 package Module::Install; # For any maintainers: # The load order for Module::Install is a bit magic. # It goes something like this... # # IF ( host has Module::Install installed, creating author mode ) { # 1. Makefile.PL calls "use inc::Module::Install" # 2. $INC{inc/Module/Install.pm} set to installed version of inc::Module::Install # 3. The installed version of inc::Module::Install loads # 4. inc::Module::Install calls "require Module::Install" # 5. The ./inc/ version of Module::Install loads # } ELSE { # 1. Makefile.PL calls "use inc::Module::Install" # 2. $INC{inc/Module/Install.pm} set to ./inc/ version of Module::Install # 3. The ./inc/ version of Module::Install loads # } use 5.006; use strict 'vars'; use Cwd (); use File::Find (); use File::Path (); use vars qw{$VERSION $MAIN}; BEGIN { # All Module::Install core packages now require synchronised versions. # This will be used to ensure we don't accidentally load old or # different versions of modules. # This is not enforced yet, but will be some time in the next few # releases once we can make sure it won't clash with custom # Module::Install extensions. $VERSION = '1.16'; # Storage for the pseudo-singleton $MAIN = undef; *inc::Module::Install::VERSION = *VERSION; @inc::Module::Install::ISA = __PACKAGE__; } sub import { my $class = shift; my $self = $class->new(@_); my $who = $self->_caller; #------------------------------------------------------------- # all of the following checks should be included in import(), # to allow "eval 'require Module::Install; 1' to test # installation of Module::Install. (RT #51267) #------------------------------------------------------------- # Whether or not inc::Module::Install is actually loaded, the # $INC{inc/Module/Install.pm} is what will still get set as long as # the caller loaded module this in the documented manner. # If not set, the caller may NOT have loaded the bundled version, and thus # they may not have a MI version that works with the Makefile.PL. This would # result in false errors or unexpected behaviour. And we don't want that. my $file = join( '/', 'inc', split /::/, __PACKAGE__ ) . '.pm'; unless ( $INC{$file} ) { die <<"END_DIE" } Please invoke ${\__PACKAGE__} with: use inc::${\__PACKAGE__}; not: use ${\__PACKAGE__}; END_DIE # This reportedly fixes a rare Win32 UTC file time issue, but # as this is a non-cross-platform XS module not in the core, # we shouldn't really depend on it. See RT #24194 for detail. # (Also, this module only supports Perl 5.6 and above). eval "use Win32::UTCFileTime" if $^O eq 'MSWin32' && $] >= 5.006; # If the script that is loading Module::Install is from the future, # then make will detect this and cause it to re-run over and over # again. This is bad. Rather than taking action to touch it (which # is unreliable on some platforms and requires write permissions) # for now we should catch this and refuse to run. if ( -f $0 ) { my $s = (stat($0))[9]; # If the modification time is only slightly in the future, # sleep briefly to remove the problem. my $a = $s - time; if ( $a > 0 and $a < 5 ) { sleep 5 } # Too far in the future, throw an error. my $t = time; if ( $s > $t ) { die <<"END_DIE" } Your installer $0 has a modification time in the future ($s > $t). This is known to create infinite loops in make. Please correct this, then run $0 again. END_DIE } # Build.PL was formerly supported, but no longer is due to excessive # difficulty in implementing every single feature twice. if ( $0 =~ /Build.PL$/i ) { die <<"END_DIE" } Module::Install no longer supports Build.PL. It was impossible to maintain duel backends, and has been deprecated. Please remove all Build.PL files and only use the Makefile.PL installer. END_DIE #------------------------------------------------------------- # To save some more typing in Module::Install installers, every... # use inc::Module::Install # ...also acts as an implicit use strict. $^H |= strict::bits(qw(refs subs vars)); #------------------------------------------------------------- unless ( -f $self->{file} ) { foreach my $key (keys %INC) { delete $INC{$key} if $key =~ /Module\/Install/; } local $^W; require "$self->{path}/$self->{dispatch}.pm"; File::Path::mkpath("$self->{prefix}/$self->{author}"); $self->{admin} = "$self->{name}::$self->{dispatch}"->new( _top => $self ); $self->{admin}->init; @_ = ($class, _self => $self); goto &{"$self->{name}::import"}; } local $^W; *{"${who}::AUTOLOAD"} = $self->autoload; $self->preload; # Unregister loader and worker packages so subdirs can use them again delete $INC{'inc/Module/Install.pm'}; delete $INC{'Module/Install.pm'}; # Save to the singleton $MAIN = $self; return 1; } sub autoload { my $self = shift; my $who = $self->_caller; my $cwd = Cwd::getcwd(); my $sym = "${who}::AUTOLOAD"; $sym->{$cwd} = sub { my $pwd = Cwd::getcwd(); if ( my $code = $sym->{$pwd} ) { # Delegate back to parent dirs goto &$code unless $cwd eq $pwd; } unless ($$sym =~ s/([^:]+)$//) { # XXX: it looks like we can't retrieve the missing function # via $$sym (usually $main::AUTOLOAD) in this case. # I'm still wondering if we should slurp Makefile.PL to # get some context or not ... my ($package, $file, $line) = caller; die <<"EOT"; Unknown function is found at $file line $line. Execution of $file aborted due to runtime errors. If you're a contributor to a project, you may need to install some Module::Install extensions from CPAN (or other repository). If you're a user of a module, please contact the author. EOT } my $method = $1; if ( uc($method) eq $method ) { # Do nothing return; } elsif ( $method =~ /^_/ and $self->can($method) ) { # Dispatch to the root M:I class return $self->$method(@_); } # Dispatch to the appropriate plugin unshift @_, ( $self, $1 ); goto &{$self->can('call')}; }; } sub preload { my $self = shift; unless ( $self->{extensions} ) { $self->load_extensions( "$self->{prefix}/$self->{path}", $self ); } my @exts = @{$self->{extensions}}; unless ( @exts ) { @exts = $self->{admin}->load_all_extensions; } my %seen; foreach my $obj ( @exts ) { while (my ($method, $glob) = each %{ref($obj) . '::'}) { next unless $obj->can($method); next if $method =~ /^_/; next if $method eq uc($method); $seen{$method}++; } } my $who = $self->_caller; foreach my $name ( sort keys %seen ) { local $^W; *{"${who}::$name"} = sub { ${"${who}::AUTOLOAD"} = "${who}::$name"; goto &{"${who}::AUTOLOAD"}; }; } } sub new { my ($class, %args) = @_; delete $INC{'FindBin.pm'}; { # to suppress the redefine warning local $SIG{__WARN__} = sub {}; require FindBin; } # ignore the prefix on extension modules built from top level. my $base_path = Cwd::abs_path($FindBin::Bin); unless ( Cwd::abs_path(Cwd::getcwd()) eq $base_path ) { delete $args{prefix}; } return $args{_self} if $args{_self}; $args{dispatch} ||= 'Admin'; $args{prefix} ||= 'inc'; $args{author} ||= ($^O eq 'VMS' ? '_author' : '.author'); $args{bundle} ||= 'inc/BUNDLES'; $args{base} ||= $base_path; $class =~ s/^\Q$args{prefix}\E:://; $args{name} ||= $class; $args{version} ||= $class->VERSION; unless ( $args{path} ) { $args{path} = $args{name}; $args{path} =~ s!::!/!g; } $args{file} ||= "$args{base}/$args{prefix}/$args{path}.pm"; $args{wrote} = 0; bless( \%args, $class ); } sub call { my ($self, $method) = @_; my $obj = $self->load($method) or return; splice(@_, 0, 2, $obj); goto &{$obj->can($method)}; } sub load { my ($self, $method) = @_; $self->load_extensions( "$self->{prefix}/$self->{path}", $self ) unless $self->{extensions}; foreach my $obj (@{$self->{extensions}}) { return $obj if $obj->can($method); } my $admin = $self->{admin} or die <<"END_DIE"; The '$method' method does not exist in the '$self->{prefix}' path! Please remove the '$self->{prefix}' directory and run $0 again to load it. END_DIE my $obj = $admin->load($method, 1); push @{$self->{extensions}}, $obj; $obj; } sub load_extensions { my ($self, $path, $top) = @_; my $should_reload = 0; unless ( grep { ! ref $_ and lc $_ eq lc $self->{prefix} } @INC ) { unshift @INC, $self->{prefix}; $should_reload = 1; } foreach my $rv ( $self->find_extensions($path) ) { my ($file, $pkg) = @{$rv}; next if $self->{pathnames}{$pkg}; local $@; my $new = eval { local $^W; require $file; $pkg->can('new') }; unless ( $new ) { warn $@ if $@; next; } $self->{pathnames}{$pkg} = $should_reload ? delete $INC{$file} : $INC{$file}; push @{$self->{extensions}}, &{$new}($pkg, _top => $top ); } $self->{extensions} ||= []; } sub find_extensions { my ($self, $path) = @_; my @found; File::Find::find( sub { my $file = $File::Find::name; return unless $file =~ m!^\Q$path\E/(.+)\.pm\Z!is; my $subpath = $1; return if lc($subpath) eq lc($self->{dispatch}); $file = "$self->{path}/$subpath.pm"; my $pkg = "$self->{name}::$subpath"; $pkg =~ s!/!::!g; # If we have a mixed-case package name, assume case has been preserved # correctly. Otherwise, root through the file to locate the case-preserved # version of the package name. if ( $subpath eq lc($subpath) || $subpath eq uc($subpath) ) { my $content = Module::Install::_read($subpath . '.pm'); my $in_pod = 0; foreach ( split /\n/, $content ) { $in_pod = 1 if /^=\w/; $in_pod = 0 if /^=cut/; next if ($in_pod || /^=cut/); # skip pod text next if /^\s*#/; # and comments if ( m/^\s*package\s+($pkg)\s*;/i ) { $pkg = $1; last; } } } push @found, [ $file, $pkg ]; }, $path ) if -d $path; @found; } ##################################################################### # Common Utility Functions sub _caller { my $depth = 0; my $call = caller($depth); while ( $call eq __PACKAGE__ ) { $depth++; $call = caller($depth); } return $call; } # Done in evals to avoid confusing Perl::MinimumVersion eval( $] >= 5.006 ? <<'END_NEW' : <<'END_OLD' ); die $@ if $@; sub _read { local *FH; open( FH, '<', $_[0] ) or die "open($_[0]): $!"; binmode FH; my $string = do { local $/; }; close FH or die "close($_[0]): $!"; return $string; } END_NEW sub _read { local *FH; open( FH, "< $_[0]" ) or die "open($_[0]): $!"; binmode FH; my $string = do { local $/; }; close FH or die "close($_[0]): $!"; return $string; } END_OLD sub _readperl { my $string = Module::Install::_read($_[0]); $string =~ s/(?:\015{1,2}\012|\015|\012)/\n/sg; $string =~ s/(\n)\n*__(?:DATA|END)__\b.*\z/$1/s; $string =~ s/\n\n=\w+.+?\n\n=cut\b.+?\n+/\n\n/sg; return $string; } sub _readpod { my $string = Module::Install::_read($_[0]); $string =~ s/(?:\015{1,2}\012|\015|\012)/\n/sg; return $string if $_[0] =~ /\.pod\z/; $string =~ s/(^|\n=cut\b.+?\n+)[^=\s].+?\n(\n=\w+|\z)/$1$2/sg; $string =~ s/\n*=pod\b[^\n]*\n+/\n\n/sg; $string =~ s/\n*=cut\b[^\n]*\n+/\n\n/sg; $string =~ s/^\n+//s; return $string; } # Done in evals to avoid confusing Perl::MinimumVersion eval( $] >= 5.006 ? <<'END_NEW' : <<'END_OLD' ); die $@ if $@; sub _write { local *FH; open( FH, '>', $_[0] ) or die "open($_[0]): $!"; binmode FH; foreach ( 1 .. $#_ ) { print FH $_[$_] or die "print($_[0]): $!"; } close FH or die "close($_[0]): $!"; } END_NEW sub _write { local *FH; open( FH, "> $_[0]" ) or die "open($_[0]): $!"; binmode FH; foreach ( 1 .. $#_ ) { print FH $_[$_] or die "print($_[0]): $!"; } close FH or die "close($_[0]): $!"; } END_OLD # _version is for processing module versions (eg, 1.03_05) not # Perl versions (eg, 5.8.1). sub _version { my $s = shift || 0; my $d =()= $s =~ /(\.)/g; if ( $d >= 2 ) { # Normalise multipart versions $s =~ s/(\.)(\d{1,3})/sprintf("$1%03d",$2)/eg; } $s =~ s/^(\d+)\.?//; my $l = $1 || 0; my @v = map { $_ . '0' x (3 - length $_) } $s =~ /(\d{1,3})\D?/g; $l = $l . '.' . join '', @v if @v; return $l + 0; } sub _cmp { _version($_[1]) <=> _version($_[2]); } # Cloned from Params::Util::_CLASS sub _CLASS { ( defined $_[0] and ! ref $_[0] and $_[0] =~ m/^[^\W\d]\w*(?:::\w+)*\z/s ) ? $_[0] : undef; } 1; # Copyright 2008 - 2012 Adam Kennedy. Audio-Nama-1.208/inc/Module/Install/0000755000175000017500000000000012644673607016120 5ustar jrothjrothAudio-Nama-1.208/inc/Module/Install/Makefile.pm0000644000175000017500000002743712644673575020214 0ustar jrothjroth#line 1 package Module::Install::Makefile; use strict 'vars'; use ExtUtils::MakeMaker (); use Module::Install::Base (); use Fcntl qw/:flock :seek/; use vars qw{$VERSION @ISA $ISCORE}; BEGIN { $VERSION = '1.16'; @ISA = 'Module::Install::Base'; $ISCORE = 1; } sub Makefile { $_[0] } my %seen = (); sub prompt { shift; # Infinite loop protection my @c = caller(); if ( ++$seen{"$c[1]|$c[2]|$_[0]"} > 3 ) { die "Caught an potential prompt infinite loop ($c[1]|$c[2]|$_[0])"; } # In automated testing or non-interactive session, always use defaults if ( ($ENV{AUTOMATED_TESTING} or -! -t STDIN) and ! $ENV{PERL_MM_USE_DEFAULT} ) { local $ENV{PERL_MM_USE_DEFAULT} = 1; goto &ExtUtils::MakeMaker::prompt; } else { goto &ExtUtils::MakeMaker::prompt; } } # Store a cleaned up version of the MakeMaker version, # since we need to behave differently in a variety of # ways based on the MM version. my $makemaker = eval $ExtUtils::MakeMaker::VERSION; # If we are passed a param, do a "newer than" comparison. # Otherwise, just return the MakeMaker version. sub makemaker { ( @_ < 2 or $makemaker >= eval($_[1]) ) ? $makemaker : 0 } # Ripped from ExtUtils::MakeMaker 6.56, and slightly modified # as we only need to know here whether the attribute is an array # or a hash or something else (which may or may not be appendable). my %makemaker_argtype = ( C => 'ARRAY', CONFIG => 'ARRAY', # CONFIGURE => 'CODE', # ignore DIR => 'ARRAY', DL_FUNCS => 'HASH', DL_VARS => 'ARRAY', EXCLUDE_EXT => 'ARRAY', EXE_FILES => 'ARRAY', FUNCLIST => 'ARRAY', H => 'ARRAY', IMPORTS => 'HASH', INCLUDE_EXT => 'ARRAY', LIBS => 'ARRAY', # ignore '' MAN1PODS => 'HASH', MAN3PODS => 'HASH', META_ADD => 'HASH', META_MERGE => 'HASH', PL_FILES => 'HASH', PM => 'HASH', PMLIBDIRS => 'ARRAY', PMLIBPARENTDIRS => 'ARRAY', PREREQ_PM => 'HASH', CONFIGURE_REQUIRES => 'HASH', SKIP => 'ARRAY', TYPEMAPS => 'ARRAY', XS => 'HASH', # VERSION => ['version',''], # ignore # _KEEP_AFTER_FLUSH => '', clean => 'HASH', depend => 'HASH', dist => 'HASH', dynamic_lib=> 'HASH', linkext => 'HASH', macro => 'HASH', postamble => 'HASH', realclean => 'HASH', test => 'HASH', tool_autosplit => 'HASH', # special cases where you can use makemaker_append CCFLAGS => 'APPENDABLE', DEFINE => 'APPENDABLE', INC => 'APPENDABLE', LDDLFLAGS => 'APPENDABLE', LDFROM => 'APPENDABLE', ); sub makemaker_args { my ($self, %new_args) = @_; my $args = ( $self->{makemaker_args} ||= {} ); foreach my $key (keys %new_args) { if ($makemaker_argtype{$key}) { if ($makemaker_argtype{$key} eq 'ARRAY') { $args->{$key} = [] unless defined $args->{$key}; unless (ref $args->{$key} eq 'ARRAY') { $args->{$key} = [$args->{$key}] } push @{$args->{$key}}, ref $new_args{$key} eq 'ARRAY' ? @{$new_args{$key}} : $new_args{$key}; } elsif ($makemaker_argtype{$key} eq 'HASH') { $args->{$key} = {} unless defined $args->{$key}; foreach my $skey (keys %{ $new_args{$key} }) { $args->{$key}{$skey} = $new_args{$key}{$skey}; } } elsif ($makemaker_argtype{$key} eq 'APPENDABLE') { $self->makemaker_append($key => $new_args{$key}); } } else { if (defined $args->{$key}) { warn qq{MakeMaker attribute "$key" is overriden; use "makemaker_append" to append values\n}; } $args->{$key} = $new_args{$key}; } } return $args; } # For mm args that take multiple space-separated args, # append an argument to the current list. sub makemaker_append { my $self = shift; my $name = shift; my $args = $self->makemaker_args; $args->{$name} = defined $args->{$name} ? join( ' ', $args->{$name}, @_ ) : join( ' ', @_ ); } sub build_subdirs { my $self = shift; my $subdirs = $self->makemaker_args->{DIR} ||= []; for my $subdir (@_) { push @$subdirs, $subdir; } } sub clean_files { my $self = shift; my $clean = $self->makemaker_args->{clean} ||= {}; %$clean = ( %$clean, FILES => join ' ', grep { length $_ } ($clean->{FILES} || (), @_), ); } sub realclean_files { my $self = shift; my $realclean = $self->makemaker_args->{realclean} ||= {}; %$realclean = ( %$realclean, FILES => join ' ', grep { length $_ } ($realclean->{FILES} || (), @_), ); } sub libs { my $self = shift; my $libs = ref $_[0] ? shift : [ shift ]; $self->makemaker_args( LIBS => $libs ); } sub inc { my $self = shift; $self->makemaker_args( INC => shift ); } sub _wanted_t { } sub tests_recursive { my $self = shift; my $dir = shift || 't'; unless ( -d $dir ) { die "tests_recursive dir '$dir' does not exist"; } my %tests = map { $_ => 1 } split / /, ($self->tests || ''); require File::Find; File::Find::find( sub { /\.t$/ and -f $_ and $tests{"$File::Find::dir/*.t"} = 1 }, $dir ); $self->tests( join ' ', sort keys %tests ); } sub write { my $self = shift; die "&Makefile->write() takes no arguments\n" if @_; # Check the current Perl version my $perl_version = $self->perl_version; if ( $perl_version ) { eval "use $perl_version; 1" or die "ERROR: perl: Version $] is installed, " . "but we need version >= $perl_version"; } # Make sure we have a new enough MakeMaker require ExtUtils::MakeMaker; if ( $perl_version and $self->_cmp($perl_version, '5.006') >= 0 ) { # This previous attempted to inherit the version of # ExtUtils::MakeMaker in use by the module author, but this # was found to be untenable as some authors build releases # using future dev versions of EU:MM that nobody else has. # Instead, #toolchain suggests we use 6.59 which is the most # stable version on CPAN at time of writing and is, to quote # ribasushi, "not terminally fucked, > and tested enough". # TODO: We will now need to maintain this over time to push # the version up as new versions are released. $self->build_requires( 'ExtUtils::MakeMaker' => 6.59 ); $self->configure_requires( 'ExtUtils::MakeMaker' => 6.59 ); } else { # Allow legacy-compatibility with 5.005 by depending on the # most recent EU:MM that supported 5.005. $self->build_requires( 'ExtUtils::MakeMaker' => 6.36 ); $self->configure_requires( 'ExtUtils::MakeMaker' => 6.36 ); } # Generate the MakeMaker params my $args = $self->makemaker_args; $args->{DISTNAME} = $self->name; $args->{NAME} = $self->module_name || $self->name; $args->{NAME} =~ s/-/::/g; $args->{VERSION} = $self->version or die <<'EOT'; ERROR: Can't determine distribution version. Please specify it explicitly via 'version' in Makefile.PL, or set a valid $VERSION in a module, and provide its file path via 'version_from' (or 'all_from' if you prefer) in Makefile.PL. EOT if ( $self->tests ) { my @tests = split ' ', $self->tests; my %seen; $args->{test} = { TESTS => (join ' ', grep {!$seen{$_}++} @tests), }; } elsif ( $Module::Install::ExtraTests::use_extratests ) { # Module::Install::ExtraTests doesn't set $self->tests and does its own tests via harness. # So, just ignore our xt tests here. } elsif ( -d 'xt' and ($Module::Install::AUTHOR or $ENV{RELEASE_TESTING}) ) { $args->{test} = { TESTS => join( ' ', map { "$_/*.t" } grep { -d $_ } qw{ t xt } ), }; } if ( $] >= 5.005 ) { $args->{ABSTRACT} = $self->abstract; $args->{AUTHOR} = join ', ', @{$self->author || []}; } if ( $self->makemaker(6.10) ) { $args->{NO_META} = 1; #$args->{NO_MYMETA} = 1; } if ( $self->makemaker(6.17) and $self->sign ) { $args->{SIGN} = 1; } unless ( $self->is_admin ) { delete $args->{SIGN}; } if ( $self->makemaker(6.31) and $self->license ) { $args->{LICENSE} = $self->license; } my $prereq = ($args->{PREREQ_PM} ||= {}); %$prereq = ( %$prereq, map { @$_ } # flatten [module => version] map { @$_ } grep $_, ($self->requires) ); # Remove any reference to perl, PREREQ_PM doesn't support it delete $args->{PREREQ_PM}->{perl}; # Merge both kinds of requires into BUILD_REQUIRES my $build_prereq = ($args->{BUILD_REQUIRES} ||= {}); %$build_prereq = ( %$build_prereq, map { @$_ } # flatten [module => version] map { @$_ } grep $_, ($self->configure_requires, $self->build_requires) ); # Remove any reference to perl, BUILD_REQUIRES doesn't support it delete $args->{BUILD_REQUIRES}->{perl}; # Delete bundled dists from prereq_pm, add it to Makefile DIR my $subdirs = ($args->{DIR} || []); if ($self->bundles) { my %processed; foreach my $bundle (@{ $self->bundles }) { my ($mod_name, $dist_dir) = @$bundle; delete $prereq->{$mod_name}; $dist_dir = File::Basename::basename($dist_dir); # dir for building this module if (not exists $processed{$dist_dir}) { if (-d $dist_dir) { # List as sub-directory to be processed by make push @$subdirs, $dist_dir; } # Else do nothing: the module is already present on the system $processed{$dist_dir} = undef; } } } unless ( $self->makemaker('6.55_03') ) { %$prereq = (%$prereq,%$build_prereq); delete $args->{BUILD_REQUIRES}; } if ( my $perl_version = $self->perl_version ) { eval "use $perl_version; 1" or die "ERROR: perl: Version $] is installed, " . "but we need version >= $perl_version"; if ( $self->makemaker(6.48) ) { $args->{MIN_PERL_VERSION} = $perl_version; } } if ($self->installdirs) { warn qq{old INSTALLDIRS (probably set by makemaker_args) is overriden by installdirs\n} if $args->{INSTALLDIRS}; $args->{INSTALLDIRS} = $self->installdirs; } my %args = map { ( $_ => $args->{$_} ) } grep {defined($args->{$_} ) } keys %$args; my $user_preop = delete $args{dist}->{PREOP}; if ( my $preop = $self->admin->preop($user_preop) ) { foreach my $key ( keys %$preop ) { $args{dist}->{$key} = $preop->{$key}; } } my $mm = ExtUtils::MakeMaker::WriteMakefile(%args); $self->fix_up_makefile($mm->{FIRST_MAKEFILE} || 'Makefile'); } sub fix_up_makefile { my $self = shift; my $makefile_name = shift; my $top_class = ref($self->_top) || ''; my $top_version = $self->_top->VERSION || ''; my $preamble = $self->preamble ? "# Preamble by $top_class $top_version\n" . $self->preamble : ''; my $postamble = "# Postamble by $top_class $top_version\n" . ($self->postamble || ''); local *MAKEFILE; open MAKEFILE, "+< $makefile_name" or die "fix_up_makefile: Couldn't open $makefile_name: $!"; eval { flock MAKEFILE, LOCK_EX }; my $makefile = do { local $/; }; $makefile =~ s/\b(test_harness\(\$\(TEST_VERBOSE\), )/$1'inc', /; $makefile =~ s/( -I\$\(INST_ARCHLIB\))/ -Iinc$1/g; $makefile =~ s/( "-I\$\(INST_LIB\)")/ "-Iinc"$1/g; $makefile =~ s/^(FULLPERL = .*)/$1 "-Iinc"/m; $makefile =~ s/^(PERL = .*)/$1 "-Iinc"/m; # Module::Install will never be used to build the Core Perl # Sometimes PERL_LIB and PERL_ARCHLIB get written anyway, which breaks # PREFIX/PERL5LIB, and thus, install_share. Blank them if they exist $makefile =~ s/^PERL_LIB = .+/PERL_LIB =/m; #$makefile =~ s/^PERL_ARCHLIB = .+/PERL_ARCHLIB =/m; # Perl 5.005 mentions PERL_LIB explicitly, so we have to remove that as well. $makefile =~ s/(\"?)-I\$\(PERL_LIB\)\1//g; # XXX - This is currently unused; not sure if it breaks other MM-users # $makefile =~ s/^pm_to_blib\s+:\s+/pm_to_blib :: /mg; seek MAKEFILE, 0, SEEK_SET; truncate MAKEFILE, 0; print MAKEFILE "$preamble$makefile$postamble" or die $!; close MAKEFILE or die $!; 1; } sub preamble { my ($self, $text) = @_; $self->{preamble} = $text . $self->{preamble} if defined $text; $self->{preamble}; } sub postamble { my ($self, $text) = @_; $self->{postamble} ||= $self->admin->postamble; $self->{postamble} .= $text if defined $text; $self->{postamble} } 1; __END__ #line 544 Audio-Nama-1.208/inc/Module/Install/Base.pm0000644000175000017500000000214712644673575017340 0ustar jrothjroth#line 1 package Module::Install::Base; use strict 'vars'; use vars qw{$VERSION}; BEGIN { $VERSION = '1.16'; } # Suspend handler for "redefined" warnings BEGIN { my $w = $SIG{__WARN__}; $SIG{__WARN__} = sub { $w }; } #line 42 sub new { my $class = shift; unless ( defined &{"${class}::call"} ) { *{"${class}::call"} = sub { shift->_top->call(@_) }; } unless ( defined &{"${class}::load"} ) { *{"${class}::load"} = sub { shift->_top->load(@_) }; } bless { @_ }, $class; } #line 61 sub AUTOLOAD { local $@; my $func = eval { shift->_top->autoload } or return; goto &$func; } #line 75 sub _top { $_[0]->{_top}; } #line 90 sub admin { $_[0]->_top->{admin} or Module::Install::Base::FakeAdmin->new; } #line 106 sub is_admin { ! $_[0]->admin->isa('Module::Install::Base::FakeAdmin'); } sub DESTROY {} package Module::Install::Base::FakeAdmin; use vars qw{$VERSION}; BEGIN { $VERSION = $Module::Install::Base::VERSION; } my $fake; sub new { $fake ||= bless(\@_, $_[0]); } sub AUTOLOAD {} sub DESTROY {} # Restore warning handler BEGIN { $SIG{__WARN__} = $SIG{__WARN__}->(); } 1; #line 159 Audio-Nama-1.208/inc/Module/Install/Scripts.pm0000644000175000017500000000101112644673575020102 0ustar jrothjroth#line 1 package Module::Install::Scripts; use strict 'vars'; use Module::Install::Base (); use vars qw{$VERSION @ISA $ISCORE}; BEGIN { $VERSION = '1.16'; @ISA = 'Module::Install::Base'; $ISCORE = 1; } sub install_script { my $self = shift; my $args = $self->makemaker_args; my $exe = $args->{EXE_FILES} ||= []; foreach ( @_ ) { if ( -f $_ ) { push @$exe, $_; } elsif ( -d 'script' and -f "script/$_" ) { push @$exe, "script/$_"; } else { die("Cannot find script '$_'"); } } } 1; Audio-Nama-1.208/inc/Module/Install/Win32.pm0000644000175000017500000000340312644673575017364 0ustar jrothjroth#line 1 package Module::Install::Win32; use strict; use Module::Install::Base (); use vars qw{$VERSION @ISA $ISCORE}; BEGIN { $VERSION = '1.16'; @ISA = 'Module::Install::Base'; $ISCORE = 1; } # determine if the user needs nmake, and download it if needed sub check_nmake { my $self = shift; $self->load('can_run'); $self->load('get_file'); require Config; return unless ( $^O eq 'MSWin32' and $Config::Config{make} and $Config::Config{make} =~ /^nmake\b/i and ! $self->can_run('nmake') ); print "The required 'nmake' executable not found, fetching it...\n"; require File::Basename; my $rv = $self->get_file( url => 'http://download.microsoft.com/download/vc15/Patch/1.52/W95/EN-US/Nmake15.exe', ftp_url => 'ftp://ftp.microsoft.com/Softlib/MSLFILES/Nmake15.exe', local_dir => File::Basename::dirname($^X), size => 51928, run => 'Nmake15.exe /o > nul', check_for => 'Nmake.exe', remove => 1, ); die <<'END_MESSAGE' unless $rv; ------------------------------------------------------------------------------- Since you are using Microsoft Windows, you will need the 'nmake' utility before installation. It's available at: http://download.microsoft.com/download/vc15/Patch/1.52/W95/EN-US/Nmake15.exe or ftp://ftp.microsoft.com/Softlib/MSLFILES/Nmake15.exe Please download the file manually, save it to a directory in %PATH% (e.g. C:\WINDOWS\COMMAND\), then launch the MS-DOS command line shell, "cd" to that directory, and run "Nmake15.exe" from there; that will create the 'nmake.exe' file needed by this module. You may then resume the installation process described in README. ------------------------------------------------------------------------------- END_MESSAGE } 1; Audio-Nama-1.208/inc/Module/Install/Can.pm0000644000175000017500000000615712644673575017174 0ustar jrothjroth#line 1 package Module::Install::Can; use strict; use Config (); use ExtUtils::MakeMaker (); use Module::Install::Base (); use vars qw{$VERSION @ISA $ISCORE}; BEGIN { $VERSION = '1.16'; @ISA = 'Module::Install::Base'; $ISCORE = 1; } # check if we can load some module ### Upgrade this to not have to load the module if possible sub can_use { my ($self, $mod, $ver) = @_; $mod =~ s{::|\\}{/}g; $mod .= '.pm' unless $mod =~ /\.pm$/i; my $pkg = $mod; $pkg =~ s{/}{::}g; $pkg =~ s{\.pm$}{}i; local $@; eval { require $mod; $pkg->VERSION($ver || 0); 1 }; } # Check if we can run some command sub can_run { my ($self, $cmd) = @_; my $_cmd = $cmd; return $_cmd if (-x $_cmd or $_cmd = MM->maybe_command($_cmd)); for my $dir ((split /$Config::Config{path_sep}/, $ENV{PATH}), '.') { next if $dir eq ''; require File::Spec; my $abs = File::Spec->catfile($dir, $cmd); return $abs if (-x $abs or $abs = MM->maybe_command($abs)); } return; } # Can our C compiler environment build XS files sub can_xs { my $self = shift; # Ensure we have the CBuilder module $self->configure_requires( 'ExtUtils::CBuilder' => 0.27 ); # Do we have the configure_requires checker? local $@; eval "require ExtUtils::CBuilder;"; if ( $@ ) { # They don't obey configure_requires, so it is # someone old and delicate. Try to avoid hurting # them by falling back to an older simpler test. return $self->can_cc(); } # Do we have a working C compiler my $builder = ExtUtils::CBuilder->new( quiet => 1, ); unless ( $builder->have_compiler ) { # No working C compiler return 0; } # Write a C file representative of what XS becomes require File::Temp; my ( $FH, $tmpfile ) = File::Temp::tempfile( "compilexs-XXXXX", SUFFIX => '.c', ); binmode $FH; print $FH <<'END_C'; #include "EXTERN.h" #include "perl.h" #include "XSUB.h" int main(int argc, char **argv) { return 0; } int boot_sanexs() { return 1; } END_C close $FH; # Can the C compiler access the same headers XS does my @libs = (); my $object = undef; eval { local $^W = 0; $object = $builder->compile( source => $tmpfile, ); @libs = $builder->link( objects => $object, module_name => 'sanexs', ); }; my $result = $@ ? 0 : 1; # Clean up all the build files foreach ( $tmpfile, $object, @libs ) { next unless defined $_; 1 while unlink; } return $result; } # Can we locate a (the) C compiler sub can_cc { my $self = shift; my @chunks = split(/ /, $Config::Config{cc}) or return; # $Config{cc} may contain args; try to find out the program part while (@chunks) { return $self->can_run("@chunks") || (pop(@chunks), next); } return; } # Fix Cygwin bug on maybe_command(); if ( $^O eq 'cygwin' ) { require ExtUtils::MM_Cygwin; require ExtUtils::MM_Win32; if ( ! defined(&ExtUtils::MM_Cygwin::maybe_command) ) { *ExtUtils::MM_Cygwin::maybe_command = sub { my ($self, $file) = @_; if ($file =~ m{^/cygdrive/}i and ExtUtils::MM_Win32->can('maybe_command')) { ExtUtils::MM_Win32->maybe_command($file); } else { ExtUtils::MM_Unix->maybe_command($file); } } } } 1; __END__ #line 236 Audio-Nama-1.208/inc/Module/Install/Fetch.pm0000644000175000017500000000462712644673575017524 0ustar jrothjroth#line 1 package Module::Install::Fetch; use strict; use Module::Install::Base (); use vars qw{$VERSION @ISA $ISCORE}; BEGIN { $VERSION = '1.16'; @ISA = 'Module::Install::Base'; $ISCORE = 1; } sub get_file { my ($self, %args) = @_; my ($scheme, $host, $path, $file) = $args{url} =~ m|^(\w+)://([^/]+)(.+)/(.+)| or return; if ( $scheme eq 'http' and ! eval { require LWP::Simple; 1 } ) { $args{url} = $args{ftp_url} or (warn("LWP support unavailable!\n"), return); ($scheme, $host, $path, $file) = $args{url} =~ m|^(\w+)://([^/]+)(.+)/(.+)| or return; } $|++; print "Fetching '$file' from $host... "; unless (eval { require Socket; Socket::inet_aton($host) }) { warn "'$host' resolve failed!\n"; return; } return unless $scheme eq 'ftp' or $scheme eq 'http'; require Cwd; my $dir = Cwd::getcwd(); chdir $args{local_dir} or return if exists $args{local_dir}; if (eval { require LWP::Simple; 1 }) { LWP::Simple::mirror($args{url}, $file); } elsif (eval { require Net::FTP; 1 }) { eval { # use Net::FTP to get past firewall my $ftp = Net::FTP->new($host, Passive => 1, Timeout => 600); $ftp->login("anonymous", 'anonymous@example.com'); $ftp->cwd($path); $ftp->binary; $ftp->get($file) or (warn("$!\n"), return); $ftp->quit; } } elsif (my $ftp = $self->can_run('ftp')) { eval { # no Net::FTP, fallback to ftp.exe require FileHandle; my $fh = FileHandle->new; local $SIG{CHLD} = 'IGNORE'; unless ($fh->open("|$ftp -n")) { warn "Couldn't open ftp: $!\n"; chdir $dir; return; } my @dialog = split(/\n/, <<"END_FTP"); open $host user anonymous anonymous\@example.com cd $path binary get $file $file quit END_FTP foreach (@dialog) { $fh->print("$_\n") } $fh->close; } } else { warn "No working 'ftp' program available!\n"; chdir $dir; return; } unless (-f $file) { warn "Fetching failed: $@\n"; chdir $dir; return; } return if exists $args{size} and -s $file != $args{size}; system($args{run}) if exists $args{run}; unlink($file) if $args{remove}; print(((!exists $args{check_for} or -e $args{check_for}) ? "done!" : "failed! ($!)"), "\n"); chdir $dir; return !$?; } 1; Audio-Nama-1.208/inc/Module/Install/WriteAll.pm0000644000175000017500000000237612644673575020215 0ustar jrothjroth#line 1 package Module::Install::WriteAll; use strict; use Module::Install::Base (); use vars qw{$VERSION @ISA $ISCORE}; BEGIN { $VERSION = '1.16'; @ISA = qw{Module::Install::Base}; $ISCORE = 1; } sub WriteAll { my $self = shift; my %args = ( meta => 1, sign => 0, inline => 0, check_nmake => 1, @_, ); $self->sign(1) if $args{sign}; $self->admin->WriteAll(%args) if $self->is_admin; $self->check_nmake if $args{check_nmake}; unless ( $self->makemaker_args->{PL_FILES} ) { # XXX: This still may be a bit over-defensive... unless ($self->makemaker(6.25)) { $self->makemaker_args( PL_FILES => {} ) if -f 'Build.PL'; } } # Until ExtUtils::MakeMaker support MYMETA.yml, make sure # we clean it up properly ourself. $self->realclean_files('MYMETA.yml'); if ( $args{inline} ) { $self->Inline->write; } else { $self->Makefile->write; } # The Makefile write process adds a couple of dependencies, # so write the META.yml files after the Makefile. if ( $args{meta} ) { $self->Meta->write; } # Experimental support for MYMETA if ( $ENV{X_MYMETA} ) { if ( $ENV{X_MYMETA} eq 'JSON' ) { $self->Meta->write_mymeta_json; } else { $self->Meta->write_mymeta_yaml; } } return 1; } 1; Audio-Nama-1.208/inc/Module/Install/Metadata.pm0000644000175000017500000004330212644673575020204 0ustar jrothjroth#line 1 package Module::Install::Metadata; use strict 'vars'; use Module::Install::Base (); use vars qw{$VERSION @ISA $ISCORE}; BEGIN { $VERSION = '1.16'; @ISA = 'Module::Install::Base'; $ISCORE = 1; } my @boolean_keys = qw{ sign }; my @scalar_keys = qw{ name module_name abstract version distribution_type tests installdirs }; my @tuple_keys = qw{ configure_requires build_requires requires recommends bundles resources }; my @resource_keys = qw{ homepage bugtracker repository }; my @array_keys = qw{ keywords author }; *authors = \&author; sub Meta { shift } sub Meta_BooleanKeys { @boolean_keys } sub Meta_ScalarKeys { @scalar_keys } sub Meta_TupleKeys { @tuple_keys } sub Meta_ResourceKeys { @resource_keys } sub Meta_ArrayKeys { @array_keys } foreach my $key ( @boolean_keys ) { *$key = sub { my $self = shift; if ( defined wantarray and not @_ ) { return $self->{values}->{$key}; } $self->{values}->{$key} = ( @_ ? $_[0] : 1 ); return $self; }; } foreach my $key ( @scalar_keys ) { *$key = sub { my $self = shift; return $self->{values}->{$key} if defined wantarray and !@_; $self->{values}->{$key} = shift; return $self; }; } foreach my $key ( @array_keys ) { *$key = sub { my $self = shift; return $self->{values}->{$key} if defined wantarray and !@_; $self->{values}->{$key} ||= []; push @{$self->{values}->{$key}}, @_; return $self; }; } foreach my $key ( @resource_keys ) { *$key = sub { my $self = shift; unless ( @_ ) { return () unless $self->{values}->{resources}; return map { $_->[1] } grep { $_->[0] eq $key } @{ $self->{values}->{resources} }; } return $self->{values}->{resources}->{$key} unless @_; my $uri = shift or die( "Did not provide a value to $key()" ); $self->resources( $key => $uri ); return 1; }; } foreach my $key ( grep { $_ ne "resources" } @tuple_keys) { *$key = sub { my $self = shift; return $self->{values}->{$key} unless @_; my @added; while ( @_ ) { my $module = shift or last; my $version = shift || 0; push @added, [ $module, $version ]; } push @{ $self->{values}->{$key} }, @added; return map {@$_} @added; }; } # Resource handling my %lc_resource = map { $_ => 1 } qw{ homepage license bugtracker repository }; sub resources { my $self = shift; while ( @_ ) { my $name = shift or last; my $value = shift or next; if ( $name eq lc $name and ! $lc_resource{$name} ) { die("Unsupported reserved lowercase resource '$name'"); } $self->{values}->{resources} ||= []; push @{ $self->{values}->{resources} }, [ $name, $value ]; } $self->{values}->{resources}; } # Aliases for build_requires that will have alternative # meanings in some future version of META.yml. sub test_requires { shift->build_requires(@_) } sub install_requires { shift->build_requires(@_) } # Aliases for installdirs options sub install_as_core { $_[0]->installdirs('perl') } sub install_as_cpan { $_[0]->installdirs('site') } sub install_as_site { $_[0]->installdirs('site') } sub install_as_vendor { $_[0]->installdirs('vendor') } sub dynamic_config { my $self = shift; my $value = @_ ? shift : 1; if ( $self->{values}->{dynamic_config} ) { # Once dynamic we never change to static, for safety return 0; } $self->{values}->{dynamic_config} = $value ? 1 : 0; return 1; } # Convenience command sub static_config { shift->dynamic_config(0); } sub perl_version { my $self = shift; return $self->{values}->{perl_version} unless @_; my $version = shift or die( "Did not provide a value to perl_version()" ); # Normalize the version $version = $self->_perl_version($version); # We don't support the really old versions unless ( $version >= 5.005 ) { die "Module::Install only supports 5.005 or newer (use ExtUtils::MakeMaker)\n"; } $self->{values}->{perl_version} = $version; } sub all_from { my ( $self, $file ) = @_; unless ( defined($file) ) { my $name = $self->name or die( "all_from called with no args without setting name() first" ); $file = join('/', 'lib', split(/-/, $name)) . '.pm'; $file =~ s{.*/}{} unless -e $file; unless ( -e $file ) { die("all_from cannot find $file from $name"); } } unless ( -f $file ) { die("The path '$file' does not exist, or is not a file"); } $self->{values}{all_from} = $file; # Some methods pull from POD instead of code. # If there is a matching .pod, use that instead my $pod = $file; $pod =~ s/\.pm$/.pod/i; $pod = $file unless -e $pod; # Pull the different values $self->name_from($file) unless $self->name; $self->version_from($file) unless $self->version; $self->perl_version_from($file) unless $self->perl_version; $self->author_from($pod) unless @{$self->author || []}; $self->license_from($pod) unless $self->license; $self->abstract_from($pod) unless $self->abstract; return 1; } sub provides { my $self = shift; my $provides = ( $self->{values}->{provides} ||= {} ); %$provides = (%$provides, @_) if @_; return $provides; } sub auto_provides { my $self = shift; return $self unless $self->is_admin; unless (-e 'MANIFEST') { warn "Cannot deduce auto_provides without a MANIFEST, skipping\n"; return $self; } # Avoid spurious warnings as we are not checking manifest here. local $SIG{__WARN__} = sub {1}; require ExtUtils::Manifest; local *ExtUtils::Manifest::manicheck = sub { return }; require Module::Build; my $build = Module::Build->new( dist_name => $self->name, dist_version => $self->version, license => $self->license, ); $self->provides( %{ $build->find_dist_packages || {} } ); } sub feature { my $self = shift; my $name = shift; my $features = ( $self->{values}->{features} ||= [] ); my $mods; if ( @_ == 1 and ref( $_[0] ) ) { # The user used ->feature like ->features by passing in the second # argument as a reference. Accomodate for that. $mods = $_[0]; } else { $mods = \@_; } my $count = 0; push @$features, ( $name => [ map { ref($_) ? ( ref($_) eq 'HASH' ) ? %$_ : @$_ : $_ } @$mods ] ); return @$features; } sub features { my $self = shift; while ( my ( $name, $mods ) = splice( @_, 0, 2 ) ) { $self->feature( $name, @$mods ); } return $self->{values}->{features} ? @{ $self->{values}->{features} } : (); } sub no_index { my $self = shift; my $type = shift; push @{ $self->{values}->{no_index}->{$type} }, @_ if $type; return $self->{values}->{no_index}; } sub read { my $self = shift; $self->include_deps( 'YAML::Tiny', 0 ); require YAML::Tiny; my $data = YAML::Tiny::LoadFile('META.yml'); # Call methods explicitly in case user has already set some values. while ( my ( $key, $value ) = each %$data ) { next unless $self->can($key); if ( ref $value eq 'HASH' ) { while ( my ( $module, $version ) = each %$value ) { $self->can($key)->($self, $module => $version ); } } else { $self->can($key)->($self, $value); } } return $self; } sub write { my $self = shift; return $self unless $self->is_admin; $self->admin->write_meta; return $self; } sub version_from { require ExtUtils::MM_Unix; my ( $self, $file ) = @_; $self->version( ExtUtils::MM_Unix->parse_version($file) ); # for version integrity check $self->makemaker_args( VERSION_FROM => $file ); } sub abstract_from { require ExtUtils::MM_Unix; my ( $self, $file ) = @_; $self->abstract( bless( { DISTNAME => $self->name }, 'ExtUtils::MM_Unix' )->parse_abstract($file) ); } # Add both distribution and module name sub name_from { my ($self, $file) = @_; if ( Module::Install::_read($file) =~ m/ ^ \s* package \s* ([\w:]+) [\s|;]* /ixms ) { my ($name, $module_name) = ($1, $1); $name =~ s{::}{-}g; $self->name($name); unless ( $self->module_name ) { $self->module_name($module_name); } } else { die("Cannot determine name from $file\n"); } } sub _extract_perl_version { if ( $_[0] =~ m/ ^\s* (?:use|require) \s* v? ([\d_\.]+) \s* ; /ixms ) { my $perl_version = $1; $perl_version =~ s{_}{}g; return $perl_version; } else { return; } } sub perl_version_from { my $self = shift; my $perl_version=_extract_perl_version(Module::Install::_read($_[0])); if ($perl_version) { $self->perl_version($perl_version); } else { warn "Cannot determine perl version info from $_[0]\n"; return; } } sub author_from { my $self = shift; my $content = Module::Install::_read($_[0]); if ($content =~ m/ =head \d \s+ (?:authors?)\b \s* ([^\n]*) | =head \d \s+ (?:licen[cs]e|licensing|copyright|legal)\b \s* .*? copyright .*? \d\d\d[\d.]+ \s* (?:\bby\b)? \s* ([^\n]*) /ixms) { my $author = $1 || $2; # XXX: ugly but should work anyway... if (eval "require Pod::Escapes; 1") { # Pod::Escapes has a mapping table. # It's in core of perl >= 5.9.3, and should be installed # as one of the Pod::Simple's prereqs, which is a prereq # of Pod::Text 3.x (see also below). $author =~ s{ E<( (\d+) | ([A-Za-z]+) )> } { defined $2 ? chr($2) : defined $Pod::Escapes::Name2character_number{$1} ? chr($Pod::Escapes::Name2character_number{$1}) : do { warn "Unknown escape: E<$1>"; "E<$1>"; }; }gex; } elsif (eval "require Pod::Text; 1" && $Pod::Text::VERSION < 3) { # Pod::Text < 3.0 has yet another mapping table, # though the table name of 2.x and 1.x are different. # (1.x is in core of Perl < 5.6, 2.x is in core of # Perl < 5.9.3) my $mapping = ($Pod::Text::VERSION < 2) ? \%Pod::Text::HTML_Escapes : \%Pod::Text::ESCAPES; $author =~ s{ E<( (\d+) | ([A-Za-z]+) )> } { defined $2 ? chr($2) : defined $mapping->{$1} ? $mapping->{$1} : do { warn "Unknown escape: E<$1>"; "E<$1>"; }; }gex; } else { $author =~ s{E}{<}g; $author =~ s{E}{>}g; } $self->author($author); } else { warn "Cannot determine author info from $_[0]\n"; } } #Stolen from M::B my %license_urls = ( perl => 'http://dev.perl.org/licenses/', apache => 'http://apache.org/licenses/LICENSE-2.0', apache_1_1 => 'http://apache.org/licenses/LICENSE-1.1', artistic => 'http://opensource.org/licenses/artistic-license.php', artistic_2 => 'http://opensource.org/licenses/artistic-license-2.0.php', lgpl => 'http://opensource.org/licenses/lgpl-license.php', lgpl2 => 'http://opensource.org/licenses/lgpl-2.1.php', lgpl3 => 'http://opensource.org/licenses/lgpl-3.0.html', bsd => 'http://opensource.org/licenses/bsd-license.php', gpl => 'http://opensource.org/licenses/gpl-license.php', gpl2 => 'http://opensource.org/licenses/gpl-2.0.php', gpl3 => 'http://opensource.org/licenses/gpl-3.0.html', mit => 'http://opensource.org/licenses/mit-license.php', mozilla => 'http://opensource.org/licenses/mozilla1.1.php', open_source => undef, unrestricted => undef, restrictive => undef, unknown => undef, ); sub license { my $self = shift; return $self->{values}->{license} unless @_; my $license = shift or die( 'Did not provide a value to license()' ); $license = __extract_license($license) || lc $license; $self->{values}->{license} = $license; # Automatically fill in license URLs if ( $license_urls{$license} ) { $self->resources( license => $license_urls{$license} ); } return 1; } sub _extract_license { my $pod = shift; my $matched; return __extract_license( ($matched) = $pod =~ m/ (=head \d \s+ L(?i:ICEN[CS]E|ICENSING)\b.*?) (=head \d.*|=cut.*|)\z /xms ) || __extract_license( ($matched) = $pod =~ m/ (=head \d \s+ (?:C(?i:OPYRIGHTS?)|L(?i:EGAL))\b.*?) (=head \d.*|=cut.*|)\z /xms ); } sub __extract_license { my $license_text = shift or return; my @phrases = ( '(?:under )?the same (?:terms|license) as (?:perl|the perl (?:\d )?programming language)' => 'perl', 1, '(?:under )?the terms of (?:perl|the perl programming language) itself' => 'perl', 1, 'Artistic and GPL' => 'perl', 1, 'GNU general public license' => 'gpl', 1, 'GNU public license' => 'gpl', 1, 'GNU lesser general public license' => 'lgpl', 1, 'GNU lesser public license' => 'lgpl', 1, 'GNU library general public license' => 'lgpl', 1, 'GNU library public license' => 'lgpl', 1, 'GNU Free Documentation license' => 'unrestricted', 1, 'GNU Affero General Public License' => 'open_source', 1, '(?:Free)?BSD license' => 'bsd', 1, 'Artistic license 2\.0' => 'artistic_2', 1, 'Artistic license' => 'artistic', 1, 'Apache (?:Software )?license' => 'apache', 1, 'GPL' => 'gpl', 1, 'LGPL' => 'lgpl', 1, 'BSD' => 'bsd', 1, 'Artistic' => 'artistic', 1, 'MIT' => 'mit', 1, 'Mozilla Public License' => 'mozilla', 1, 'Q Public License' => 'open_source', 1, 'OpenSSL License' => 'unrestricted', 1, 'SSLeay License' => 'unrestricted', 1, 'zlib License' => 'open_source', 1, 'proprietary' => 'proprietary', 0, ); while ( my ($pattern, $license, $osi) = splice(@phrases, 0, 3) ) { $pattern =~ s#\s+#\\s+#gs; if ( $license_text =~ /\b$pattern\b/i ) { return $license; } } return ''; } sub license_from { my $self = shift; if (my $license=_extract_license(Module::Install::_read($_[0]))) { $self->license($license); } else { warn "Cannot determine license info from $_[0]\n"; return 'unknown'; } } sub _extract_bugtracker { my @links = $_[0] =~ m#L<( https?\Q://rt.cpan.org/\E[^>]+| https?\Q://github.com/\E[\w_]+/[\w_]+/issues| https?\Q://code.google.com/p/\E[\w_\-]+/issues/list )>#gx; my %links; @links{@links}=(); @links=keys %links; return @links; } sub bugtracker_from { my $self = shift; my $content = Module::Install::_read($_[0]); my @links = _extract_bugtracker($content); unless ( @links ) { warn "Cannot determine bugtracker info from $_[0]\n"; return 0; } if ( @links > 1 ) { warn "Found more than one bugtracker link in $_[0]\n"; return 0; } # Set the bugtracker bugtracker( $links[0] ); return 1; } sub requires_from { my $self = shift; my $content = Module::Install::_readperl($_[0]); my @requires = $content =~ m/^use\s+([^\W\d]\w*(?:::\w+)*)\s+(v?[\d\.]+)/mg; while ( @requires ) { my $module = shift @requires; my $version = shift @requires; $self->requires( $module => $version ); } } sub test_requires_from { my $self = shift; my $content = Module::Install::_readperl($_[0]); my @requires = $content =~ m/^use\s+([^\W\d]\w*(?:::\w+)*)\s+([\d\.]+)/mg; while ( @requires ) { my $module = shift @requires; my $version = shift @requires; $self->test_requires( $module => $version ); } } # Convert triple-part versions (eg, 5.6.1 or 5.8.9) to # numbers (eg, 5.006001 or 5.008009). # Also, convert double-part versions (eg, 5.8) sub _perl_version { my $v = $_[-1]; $v =~ s/^([1-9])\.([1-9]\d?\d?)$/sprintf("%d.%03d",$1,$2)/e; $v =~ s/^([1-9])\.([1-9]\d?\d?)\.(0|[1-9]\d?\d?)$/sprintf("%d.%03d%03d",$1,$2,$3 || 0)/e; $v =~ s/(\.\d\d\d)000$/$1/; $v =~ s/_.+$//; if ( ref($v) ) { # Numify $v = $v + 0; } return $v; } sub add_metadata { my $self = shift; my %hash = @_; for my $key (keys %hash) { warn "add_metadata: $key is not prefixed with 'x_'.\n" . "Use appopriate function to add non-private metadata.\n" unless $key =~ /^x_/; $self->{values}->{$key} = $hash{$key}; } } ###################################################################### # MYMETA Support sub WriteMyMeta { die "WriteMyMeta has been deprecated"; } sub write_mymeta_yaml { my $self = shift; # We need YAML::Tiny to write the MYMETA.yml file unless ( eval { require YAML::Tiny; 1; } ) { return 1; } # Generate the data my $meta = $self->_write_mymeta_data or return 1; # Save as the MYMETA.yml file print "Writing MYMETA.yml\n"; YAML::Tiny::DumpFile('MYMETA.yml', $meta); } sub write_mymeta_json { my $self = shift; # We need JSON to write the MYMETA.json file unless ( eval { require JSON; 1; } ) { return 1; } # Generate the data my $meta = $self->_write_mymeta_data or return 1; # Save as the MYMETA.yml file print "Writing MYMETA.json\n"; Module::Install::_write( 'MYMETA.json', JSON->new->pretty(1)->canonical->encode($meta), ); } sub _write_mymeta_data { my $self = shift; # If there's no existing META.yml there is nothing we can do return undef unless -f 'META.yml'; # We need Parse::CPAN::Meta to load the file unless ( eval { require Parse::CPAN::Meta; 1; } ) { return undef; } # Merge the perl version into the dependencies my $val = $self->Meta->{values}; my $perl = delete $val->{perl_version}; if ( $perl ) { $val->{requires} ||= []; my $requires = $val->{requires}; # Canonize to three-dot version after Perl 5.6 if ( $perl >= 5.006 ) { $perl =~ s{^(\d+)\.(\d\d\d)(\d*)}{join('.', $1, int($2||0), int($3||0))}e } unshift @$requires, [ perl => $perl ]; } # Load the advisory META.yml file my @yaml = Parse::CPAN::Meta::LoadFile('META.yml'); my $meta = $yaml[0]; # Overwrite the non-configure dependency hashes delete $meta->{requires}; delete $meta->{build_requires}; delete $meta->{recommends}; if ( exists $val->{requires} ) { $meta->{requires} = { map { @$_ } @{ $val->{requires} } }; } if ( exists $val->{build_requires} ) { $meta->{build_requires} = { map { @$_ } @{ $val->{build_requires} } }; } return $meta; } 1; Audio-Nama-1.208/script/0000755000175000017500000000000012644673607014020 5ustar jrothjrothAudio-Nama-1.208/script/nama0000755000175000017500000023645412644673575014704 0ustar jrothjroth#!/usr/bin/env perl require 5.10.1; use Audio::Nama; Audio::Nama::main(); __END__ =head1 NAME B - digital audio workstation =head1 SYNOPSIS B [I] [I] =head1 DESCRIPTION B performs multitrack recording, effects processing, editing, mixing, mastering, live performance and general-purpose audio processing, using the Ecasound realtime audio engine. =head2 Audio Functionality Audio projects may be developed using tracks, buses, effects, sends, inserts, marks, regions, fades, sequences and edits. Each track may contain one or more WAV files, which may be recorded or imported. Effects processing by LADSPA, LV2 and Ecasound plugins may be performed in realtime, or cached (e.g. frozen) to a file. The user may toggle between cached and dynamic processing for a track. Audio regions may be altered, duplicated, time-shifted or replaced. Nama supports MIDI functionality via midish. =head2 Presets and templates To facilitate reuse, a track's plugins and inserts can be stored as an effect chain. Effect profiles and project templates provide templating for groups of tracks and entire projects, respectively. =head2 Audio framework Audio IO is via JACK or ALSA. Soundcard IO is normally routed to JACK with transparent fallback to ALSA. =head2 Persistence Project data parameters related to audio configuration are serialized as JSON and tracked using Git when available. The entire project history is retained and may be managed using branches and tags. Nama supports Ladish Level 1 session handling. =head2 User interfaces Nama has fully featured terminal command prompt, a Tk GUI, and experimental OSC and remote-command modes. The command prompt accepts Nama commands, Ecasound interactive-mode commands, shell commands and perl code. It has command history and autocompletion. The help system provides documentation and keyword search covering Nama commands and effects. The hotkey mode provides a convenient way to select, view, and modify effect parameters. By default, Nama displays a graphic user interface while the command processor runs in a terminal window. =head1 OPTIONS =over 12 =item B<--gui, -g> Start Nama in GUI mode =item B<--text, -t> Start Nama in text mode =item B<--config, -f> Specify configuration file (default: ~/.namarc) =item B<--project-root, -d> Specify project root directory =item B<--create-project, -c> Create project if it doesn't exist =item B<--net-eci, -n> Use Ecasound's Net-ECI interface =item B<--libecasoundc, -l> Use Ecasound's libecasoundc interface =item B<--save-alsa, -a> Save/restore alsa state with project data =item B<--help, -h> This help display =back Debugging options: =over 12 =item B<--no-static-effects-data, -s> Don't load effects data =item B<--no-state, -m> Don't load project state =item B<--no-static-effects-cache, -e> Bypass effects data cache =item B<--regenerate-effects-cache, -r> Regenerate the effects data cache =item B<--no-reconfigure-engine, -R> Don't automatically configure engine =item B<--debugging-output, -D> Emit debugging information =item B<--fake-jack, -J> Simulate JACK environment =item B<--fake-alsa, -A> Simulate ALSA environment =item B<--no-ecasound, -E> Don't spawn Ecasound process =item B<--execute-command, -X> Supply a command to execute =back =head1 CONTROLLING NAMA/ECASOUND The Ecasound audio engine is configured through use of I that specify the signal processing network. Nama serves as an intermediary, taking high-level commands from the user, generating appropriate chain setups for user tasks such as recording, playback, mixing, etc., and running the audio engine. =head2 Configuration Commands Configuration commands affect I runs of the audio engine. For example, B and B determine whether the current track will get its audio stream from an external (e.g. live) source, whether an existing WAV file will be played back, and whether a new WAV file will be recorded. Nama responds to these commands by reconfiguring the engine and displaying the updated track status. See 'man ::ChainSetup' for details on how the chain setup created. =head2 Realtime Commands Once a chain setup is loaded and the engine is launched, commands can be issued to control the realtime behavior of the audio processing engine. These commands include transport C and C, playback repositioning commands such C, C and C. Effects may be added, modified or removed while the engine is running. =head2 Configuration General configuration of sound devices and program options is performed by editing the F<.namarc> file. On Nama's first run, a default version of F<.namarc> is usually placed in the user's home directory. =head1 Tk GRAPHICAL UI Invoked by default if Tk is installed, this interface provides a subset of Nama's functionality on two windows: =head2 Main Window The top section has buttons for creating, loading and saving projects, adding tracks, adding effects to tracks. In short, for setup. Below are buttons for controlling the transport (start, stop and friends) and for setting marks. The GUI project name bar and time display change color to indicate whether the upcoming operation will include live recording (red), mixdown (yellow) or playback (green). =head2 Effects Window The B provides sliders for each effect parameter of each track. Parameter range, defaults, and log/linear scaling hints are automatically detected. Text-entry widgets are used to enter parameters values for plugins without hinted ranges. Any parameter label can be clicked to add a parameter controller. =head2 Terminal Window The command prompt is available in the terminal window during GUI operation. Text commands are used to access Nama's more advanced functions. =head1 TEXT USER INTERFACE Press the I key if necessary to get the command prompt, which will look something like this: =over 12 C> =back In this instance, 'sax' is the current track. When using buses, the bus is indicated before the track: =over 12 C> =back At the prompt, you can enter Nama and Ecasound commands, Perl code preceded by C or shell code preceded by C. Multiple commands on a single line are allowed if delimited by semicolons. Usually the lines are split on semicolons and the parts are executed sequentially, however if the line begins with C or C the entire line (up to double semicolons ';;' if present) will be given to the corresponding interpreter. You can access command history using up-arrow/down-arrow. Type C for general help, C for help with C, C for help with commands containing the string C. C lists all plugins/presets/controller containing both I and I. Tab-completion is provided for Nama commands, Ecasound-iam commands, plugin/preset/controller names, and project names. Many effects have abbreviations, such as 'afx' for 'add_effect'. =head1 TRACKS Each track has a descriptive name (i.e. vocal) and an integer track-number assigned when the track is created. New user tracks initially belong to the Main bus. Track output signals are usually mixed and pass through the Master track on the way to soundcard for monitoring. The following sections describes track attributes and their effects. =head2 Width Specifying 'mono' means the track has one input channel, which will be recorded as a mono WAV file. Mono track signals are automatically duplicated to stereo and a pan effect is provided. Specifying 'stereo' for a track means that two channels of audio input will be recorded as an interleaved stereo WAV file. You can also use a 'stereo' declaration to avoid the automatic channel copy usually applied to single-channel sources. Specifying N channels for a track ('set width N') means N successive input channels will be recorded as an N-channel interleaved WAV file. =head2 REC/PLAY/MON/OFF Each track, including Master and Mixdown, has its own REC/MON/PLAY/OFF setting. The I setting means that the track source is connected to the track input, and the track output is supplied for monitoring by the Main bus and other submixes if any. The I setting prepares the track is ready to record a WAV file. The I setting enqueues an audio file for playback from disk as the track source. I and I settings also create the monitoring routes associated with I status. I setting tells Nama to remove the track from the audio network. I status also results when no audio source is available. A track with no recorded WAV files will show OFF status, even if set to PLAY. =head3 Bus setting Buses can force the status of their member tracks to OFF. Nama provides MON and OFF settings for buses. OFF (set by C) removes all member tracks from the chain setup, MON (set by C restores them. The B command sets the Mixdown track to PLAY and the Main bus to OFF. =head2 Version Numbers Multiple WAV files ("takes") can be recorded for each track. These are distinguished by a version number that increments with each recording run, i.e. F, F, etc. All WAV files recorded in the same run have the same version numbers. The version numbers of files for playback can be selected at the bus or track level. By setting the bus version to 5, you can play back version 5 of several tracks at once. Version 5 could signify the fifth take of a song, or the fifth song of a live recording session. The track version setting, if present, overrides the bus setting. Setting the track version to zero restores control of the version number to the bus. The Main bus version setting does I currently propagate to other buses. =head2 Marks Marks in Nama are similar to those in other audio editing software. One limitation is that mark positions are relative to the beginning of an Ecasound chain setup. If your project involves a single track, and you will be shortening the stream by setting a region to play, set any marks you need I defining the region. =head2 Regions The C command allows you to define endpoints for a portion of an audio file. You can then use the C command to move the region to the desired time position. Each track can have one region definition. To create multiple regions, the C command takes a pair of marks to create a read-only copy of the current track with the specified region definition. You can control this region as you would any other other track, applying effects, adjusting volume, etc. Currently, regions are not clipped out of their host track. This feature may be implemented in future. =head3 Using Tracks from Other Projects The C clones a read-only track from another track, which may belong to a different project. =head2 Effects Each track gets volume and pan effects by default. New effects added using C are applied before pan volume controls. You can position effects anywhere you choose using C or C. =head3 Fades Nama allows you to place fades on any track. Fades are defined by mark position and duration. An additional volume operator, -eadb, is applied to each track to host the envelope controller that implements fades. =head3 Sends and Inserts The C command can route a track's post-fader output to a soundcard channel or JACK client in addition to the normal mixer input. Nama currently allows one aux send per track. The C command configures a pre- or post-fader send-and-return to soundcard channels or JACK clients. Wet and dry signal paths are provided, with a default setting of 100% wet. Each track can have one pre-fader and one post-fader insert. =head2 Bunches A bunch is just a list of track names. Bunch names are used with the keyword C to apply one or more commands to several tracks at once. A bunch can be created with the C command. Any bus name can also be treated as a bunch. Finally, several system defined bunches are available: =over 12 =item B, B, B All tracks with the corresponding I in the current bus =back =head2 Buses =head3 Sub Buses B enable multiple tracks to be routed through a single mix track before feeding the Main mixer bus (or possibly, another bus.) The following commands create a bus and assign three tracks to it. The mix track takes the name of the bus and is stereo by default. # create a bus named Strings with a same-named mix track add_bus Strings # create tracks for the bus add_tracks violin cello bass # move the tracks from the Main bus (default) to the Strings bus for violin cello bass; move_to_bus Strings # use the mix track to control bus output volume Strings vol - 10 =head3 Submixes B are a type of bus used to provide instrument monitors, or to send the outputs from multiple user tracks to an external program such as jconverter. =head1 ROUTING =head2 General Notes While Nama can address tracks by either name and track number, the chain setups use the track number exclusively. The Master track (mixer output control) is always chain 1, the Mixdown track is always chain 2. In single-engine mode, Nama uses Ecasound loop devices where necessary to connect two tracks, or to allow one track to have multiple inputs or outputs. Each loop device adds one buffer, which increases latency. In dual-engine mode, JACK ports are used for interconnections instead of loop devices. =head2 Flow Diagrams The following diagrams apply to Nama's single-engine, mode. (The same topology is used in dual-engine mode.) Let's examine the signal flow from track 3, the first available user track. Assume track 3 is named "sax". We will divide the signal flow into track and mixer sections. Parentheses show the track number/name. The stereo outputs of each user track terminate at Master_in, a loop device at the mixer input. =head3 Track, REC status Sound device --+---(3)----> Master_in /JACK client | +---(R3)---> sax_1.wav REC status indicates that the source of the signal is the soundcard or JACK client. The input signal will be written directly to a file except in the special preview and doodle modes, or if C is issued. =head3 Track, MON status sax_1.wav ------(3)----> Master_in =head3 Mixer, with mixdown enabled In the second part of the flow graph, the mixed signal is delivered to an output device through the Master chain, which can host effects. Usually the Master track provides final control before audio output or mixdown. Master_in --(1)--> Master_out --+--------> Sound device | +-->(2)--> Mixdown_1.wav =head3 Mastering Mode In mastering mode (invoked by C and released C) the following network, receives the Master track signal as input and provides an output to the soundcard or WAV file. +- Low -+ | | Master_in --- Eq --+- Mid -+--- Boost -> soundcard/wav_out | | +- High + The B track hosts an equalizer. The B, B and B tracks each apply a bandpass filter, a compressor and a spatialiser. The B track applies gain and a limiter. These effects and their default parameters are defined in the configuration file F<.namarc>. =head2 Mixdown The C command configures Nama for mixdown. The Mixdown track is set to REC (equivalent to C) and the audio monitoring output is turned off (equivalent to C). Mixdown proceeds after you start the transport. As a convenience, Mixdown_nn.wav will be symlinked to F<_nn.wav> in the project directory. (If git is disabled or not available F<_nn.wav> is used instead.) Corresponding encoded files are created if the "mixdown_encodings" option is set. Acceptable values are a space-separated list. The default is "mixdown_encodings: ogg mp3". =head2 The Preview and Doodle Modes, and the Eager Setting These non-recording modes, invoked by C and C commands tweak the routing rules for special purposes. B disables recording of WAV files to disk. B disables PLAY inputs while excluding any tracks with the same source as a currently routed track. The C command releases both preview and doodle modes. The eager setting causes the engine to start immediately following a reconfiguration. These modes are unnecessary in Nama's dual-engine mode. =head2 Saving Projects The C command is the usual way to preserve your work. When you type C, Settings related to the state of the project are saved in the file F in the current project directory. F is tracked by git. C updates several other data files as well: F, in the current project directory, contains data that is part of the project (such as command history, track comments, and current operating modes) but with no direct effect on the project audio. F, in the project root directory, contains system and user defined effect chains. =head3 Save without Git C will save project state to a file of that name. Similarly C will load the corresponding file. The F<.json> suffix may be omitted if "use_git: 0" is set in F<.namarc>. =head3 Save with Git When git is installed, Nama uses it to store snapshots of every step in the history of your project. While you can continue using the same C and C with snapshots, the underlying version control gives them huge advantages over files: (1) they can sprout branches, (2) they retain their history and (3) they are never overwritten. When you type C, the latest snapshot is tagged with the name "initial-mix", which you can recall later with the command C. You can include a comment with the snapshot: C Nama lets you create new branches, starting at any snapshot. To start a new branch called I starting at a snapshot called I you would say: C If you want to go back to working on the master branch, use C. You can also issue native git commands at the Nama prompt. =head3 Git history example All projects begin on the "master" branch. Because this is the default branch, it is not displayed in the prompt. Otherwise "master" is not special in any way. In the graphs below, the letters indicate named snapshots. create test-project ... save a ... save b ... save c ---a---b---c (master) get a ... save d ... save e ... save f d---e---f (a-branch) / -----a----b---c (master) Now, you want to go back to try something different at "c": get c ... save g d---e---f (a-branch) / ----a----b---c (master) \ g (c-branch CURRENT HEAD) You could also go back to master, and restart from there: get master ... save h ... save i d---e---f (a-branch) / ----a----b---c---h---i (master CURRENT HEAD) \ g (c-branch) While the merging of branches may be possible, the function has not been tested. =head2 Exiting When you type C Nama will automatically save your work to F. If you I want this behavior, use Ctrl-C to exit Nama. =head2 Jack ports list file Use I to ask Nama to connect multiple JACK ports listed in a file F to the input port(s) of that track. If the track is stereo, ports from the list are alternately connected to left and right channels. =head2 Track edits An edit consists of audio clips and data structures associated with a particular track and version. The edit replaces part of the original WAV file, allowing you to fix wrong notes, or substitute one phrase for another. Each track can host multiple edits. Edits are non-destructive; they are achieved by using Ecasound's ability to crossfade and sequence. Select the track to be edited and the correct version. Before creating the edit, you will now need to create three marks: =over 4 =item * play start point =item * rec start point =item * rec end point =back The edit will replace the audio between the rec start and rec end points. There are two ways to set these points. =head3 set_edit_points command Position the playback head a few seconds before the edit. Enter the I command. This will start the engine. Hit the B

key three times to designate the playback start, punch-in and punch-out positions. =head3 Specify points individually Position the playback head at the position you want playback for the edit to start. Enter the I command. Use the same procedure to set the rec start and rec end positions using the I and I commands. =head3 Provide marks as arguments to I (not implemented) Type I.) =head3 Create the edit Enter the I command to create the necessary tracks and data structures. Use I to confirm the edit positions. The engine will run and you will hear the host track with the target region removed. Playback will be restricted to the edit region. You may use I to hear the clip to be removed. Use I to see the edit marks and I to nudge them into perfect position. Once you are satisfied with the mark positions, you are ready to record your edit. Enter I. Playback will begin at first mark. The replacement clip will be recorded from the source specified in the original track. Each I command will record an additional version on the edit track. I will delete (destructively) the most recent audio clip and begin recording anew. You may specify another range for editing and use the editing procedure again as many times as you like. Edits may not overlap. =head3 Merging edits I will recursively merge all edits applied to the current track and version, creating a new version. I recommend that you merge edits when you are satisfied, with the results to protect your edits against an accidental change in mark, region or version settings. I acts on a merged version of the current track, selecting the prior unmerged version with all edits and region definitions in "live" form. You may continue to create new edits. B I will label the edits by index and time. I will restore normal playback mode I Behind the scenes, the host track becomes the mix track to a bus. Sources for the bus are the original audio track, and zero or more edits, each represented by one track object. =head1 REMOTE CONTROL You can send now send commands from a remote process, and also get information back. Understand that this code opens a remote execution hole. In F<.namarc> you need something like: remote_control_port: 57000 Then Nama will set up a listener for remote commands. The usual return value will be a single newline. However, if you send an 'eval' command followed by perl code, the return value will be the result of the perl code executed with a newline appended. If the result is a list, the items will be joined by spaces into a single string. If the result is an object or data structure, it will be returned in a serialized form. For example, if you send this string: eval $this_track->name The return value will be the name of the current track. =head1 TEXT COMMANDS =head2 Help commands =head4 B (h) - Display help on Nama commands. =over 8 help [ | | ] help marks # display the help category marks and all commands containing marks help 6 # display help on the effects category help mfx # display help on modify_effect - shortcut mfx =back =head4 B (hfx he) - Display detailed help on LADSPA or LV2 effects. =over 8 help_effect | help_effect 1970 # display help on Fons Adriaensen's parametric EQ (LADSPA) help_effect etd # prints a short message to consult Ecasound manpage, # where the etd chain operator is documented. hfx lv2-vocProc # display detailed help on the LV2 VocProc effect =back =head4 B (ffx fe) - Display one-line help for effects matching the search string(s). =over 8 find_effect [ ... ] find_effect compressor # List all effects containing "compressor" in their name or parameters fe feedback # List all effects matching "feedback" # (for example a delay with a feedback parameter) =back =head2 General commands =head4 B (quit q) - Exit Nama, saving settings (the current project). =over 8 exit =back =head4 B - Enable WAV directory caching, so Nama won't have to scan the entire project folder for new files after every run. (default) =over 8 memoize =back =head4 B - Disable WAV directory caching. =over 8 unmemoize =back =head2 Transport commands =head4 B (s) - Stop transport. Stop the engine, when recording or playing back. =over 8 stop =back =head4 B (t) - Start the transport rolling =over 8 start rec # prepare the curent track to be recorded. start # Start the engine/transport rolling (play now!) stop # Stop the engine, cleanup, prepare to review =back =head4 B (gp) - Get the current playhead position (in seconds). =over 8 getpos start # Start the engine. gp # Get the current position of the playhead. Where am I? =back =head4 B (sp) - Set current playhead position (in seconds). =over 8 setpos setpos 65.5 =back =head4 B (fw) - Move playback position forwards (in seconds). =over 8 forward fw 23.7 =back =head4 B (rw) - Move playback position backwards (in seconds). =over 8 rewind rewind 6.5 =back =head4 B (beg) - Set the playback head to the start. A synonym for setpos 0. =over 8 to_start =back =head4 B (end) - Set the playback head to end minus 10 seconds. =over 8 to_end =back =head4 B - Ecasound-only start. Nama will not monitor the transport. For diagnostic use. =over 8 ecasound_start =back =head4 B - Ecasound-only stop. Nama will not monitor the transport. For diagnostic use. =over 8 ecasound_stop =back =head4 B - Restart the Ecasound process. May help if Ecasound has crashed or is behaving oddly. =over 8 restart_ecasound =back =head4 B (song) - Enter the preview mode. Configure Nama for playback and passthru of live inputs without recording (for mic test, rehearsal, etc.) =over 8 preview rec # Set the current track to record from its source. preview # Enter the preview mode. start # Playback begins. You can play live, adjust effects, # forward, rewind, etc. stop # Stop the engine/transport. arm # Restore to normal recording/playback mode. =back =head4 B (live) - Enter doodle mode. Passthru of live inputs without recording. No playback. Intended for rehearsing and adjusting effects. =over 8 doodle doodle # Switch into doodle mode. start # start the engine/transport running. (fool around) stop # Stop the engine. arm # Return to normal mode, allowing play and record to disk =back =head2 Mix commands =head4 B (mxd) - Enter mixdown mode for subsequent engine runs. You will record a new mix each time you use the start command until you leave the mixdown mode using "mixoff". =over 8 mixdown mixdown # Enter mixdown mode start # Start the transport. The mix will be recorded by the # Mixdown track. The engine will run until the # longest track ends. (After mixdown Nama places # a symlink to the WAV file and possibly ogg/mp3 # encoded versions in the project directory.) mixoff # Return to the normal mode. =back =head4 B (mxp) - Enter Mixdown play mode, setting user tracks to OFF and only playing the Mixdown track. Use "mixoff" to leave this mode. =over 8 mixplay mixplay # Enter the Mixdown play mode. start # Play the Mixdown track. stop # Stop playback. mixoff # Return to normal mode. =back =head4 B (mxo) - Leave the mixdown or mixplay mode. Sets Mixdown track to OFF, user tracks to MON. =over 8 mixoff =back =head4 B - Normalize track volume levels and fix DC-offsets, then mixdown. =over 8 automix =back =head4 B (mr) - Turn on the mastering mode, adding tracks Eq, Low, Mid, High and Boost, if necessary. The mastering setup allows for one EQ and a three-band multiband compression and a final boosting stage. Using "master_off" to leave the mastering mode. =over 8 master_on mr # Turn on master mode. start # Start the playback. # Now you can adjust the Boost or global EQ. stop # Stop the engine. =back =head4 B (mro) - Leave mastering mode. The mastering network is disabled. =over 8 master_off =back =head2 Track commands =head4 B (add new) - Create a new audio track. =over 8 add_track add_track clarinet # create a mono track called clarinet with input # from soundcard channel 1. =back =head4 B - Create one or more new tracks in one go. =over 8 add_tracks [ ... ] add_tracks violin viola contra_bass =back =head4 B (amt) - Create a new MIDI track. =over 8 add_midi_track =back =head4 B (link) - Create a read-only track, that uses audio files from another track. =over 8 link_track [] link my_song_part1 Mixdown part_1 # Create a read-only track "part_1" in the current project # using files from track "Mixdown" in project "my_song_part_1". # link_track compressed_piano piano # Create a read-only track "compressed_piano" using files from # track "piano". This is one way to provide wet and dry # (processed and unprocessed) versions of same source. # Another way would be to use inserts. =back =head4 B (import) - Import a sound file (wav, ogg, mp3, etc.) to the current track, resampling it if necessary. The imported file is set as current version. =over 8 import_audio [ ] import /home/samples/bells.flac # import the file bells.flac to the current track import /home/music/song.mp3 44100 # import song.mp3, specifying the frequency =back =head4 B - Directly set current track parameters (use with care!). =over 8 set_track =back =head4 B (rec) - Set the current track to record its source. Creates the monitoring route if necessary. Recording to disk will begin on the next engine start. Use the "mon" or "off" commands to disable recording. =over 8 record rec # Set the current track to record. start # A new version (take) will be written to disk, # creating a file such as sax_1.wav. Other tracks # may be recording or playing back as well. stop # Stop the recording/playback, automatically enter playback mode =back =head4 B - Set the current track to playback the currently selected version. Creates the monitoring route if necessary. The selected audio file will play the next time the engine starts. =over 8 play =back =head4 B - Create a monitoring route for the current track at the next opportunity. =over 8 mon =back =head4 B - Remove the monitoring route for the current track and all track I/O at the next opportunity. You can re-include it using "mon", "play" or "rec" commands. =over 8 off =back =head4 B (src r) - Set the current track's input (source), for example to a soundcard channel, or JACK client name =over 8 source | | | | | | 'jack' | 'null' source 3 # Take input from soundcard channel 3 (3/4 if track is stereo) # source null # Track's input is silence. This is useful for when an effect such # as a metronome or signal generator provides a source. # source LinuxSampler # Record input from the JACK client named LinuxSampler. # source synth:output_3 # record from the JACK client synth, using the # port output_3 (see he jackd and jack_lsp manpages # for more information). # source jack # This leaves the track input exposed as JACK ports # such as Nama:sax_in_1 for manual connection. # source kit.ports # The JACK ports listed in the file kit.ports (if it exists) # will be connected to the track input. # # Ports are listed pairwise in the .ports files for stereo tracks. # This is convenient for use with the Hydrogen drumkit, # whose outputs use one JACK port per voice. =back =head4 B (aux) - Set an aux send for the current track. Remove sends with remove_send . =over 8 send | | send 3 # Send the track output to soundcard channel 3. send jconvolver # Send the track output to the jconvolver JACK client. =back =head4 B (nosend noaux) - Remove aux send from the current track. =over 8 remove_send =back =head4 B - Configure the current track to record two channels of audio =over 8 stereo =back =head4 B - Configure the current track to record one channel of audio =over 8 mono =back =head4 B (version ver) - Select a WAV file, by version number, for current track playback (Overrides a bus-level version setting) =over 8 set_version piano # Select the piano track. version 2 # Select the second recorded version sh # Display information about the current track =back =head4 B - Remove the currently selected recording version from the current track after confirming user intent. This DESTRUCTIVE command removes the underlying audio file from your disk. Use with caution. =over 8 destroy_current_wav =back =head4 B (lver) - List WAV versions of the current track. This will print the numbers. =over 8 list_versions list_versions # May print something like: 1 2 5 7 9 # The other versions might have been deleted earlier by you. =back =head4 B (v) - Change or show the current track's volume. =over 8 vol [ [ + | - | / | * ] ] vol * 1.5 # Multiply the current volume by 1.5 vol 75 # Set the current volume to 75 # Depending on your namarc configuration, this means # either 75% of full volume (-ea) or 75 dB (-eadb). vol - 5.7 # Decrease current volume by 5.7 (percent or dB) vol # Display the volume setting of the current track. =back =head4 B (c cut) - Mute the current track by reducing the volume parameter. Use "unmute" to restore the former volume level. =over 8 mute =back =head4 B (nomute C uncut) - Restore previous volume level. It can be used after mute or solo. =over 8 unmute =back =head4 B - Set the current track's volume to unity. This will change the volume to the default value (100% or 0 dB). =over 8 unity vol 55 # Set volume to 55 unity # Set volume to the unity value. vol # Display the current volume (should be 100 or 0, # depending on your settings in namarc.) =back =head4 B (sl) - Mute all tracks but the current track or the tracks or bunches specified. You can reverse this with nosolo. =over 8 solo [ | ] [ ] ... solo # Mute all tracks but the current track. nosolo # Unmute all tracks, restoring prior state. solo piano bass Drums # Mute everything but piano, bass and Drums. =back =head4 B (nsl) - Unmute all tracks which have been muted by a solo command. Tracks that had been muted before the solo command stay muted. =over 8 nosolo =back =head4 B - Unmute all tracks that are currently muted =over 8 all piano # Select track piano mute # Mute the piano track. sax # Select the track sax. solo # Mute other tracks nosolo # Unmute other tracks (piano is still muted) all # all tracks play =back =head4 B (p) - Change or display the current panning position of the current track. Panning is moving the audio in the stereo panorama between right and left. Position is given in percent. 0 is hard left and 100 hard right, 50% is dead centre. =over 8 pan [ ] pan 75 # Pan the track to a position between centre and hard right p 50 # Move the current track to the centre. pan # Show the current position of the track in the stereo panorama. =back =head4 B (pr) - Pan the current track hard right. this is a synonym for pan 100. Can be reversed with pan_back. =over 8 pan_right =back =head4 B (pl) - Pan the current track hard left. This is a synonym for pan 0. Can be reversed with pan_back. =over 8 pan_left =back =head4 B (pc) - Pan the current track to the centre. This is a synonym for pan 50. Can be reversed with pan_back. =over 8 pan_center =back =head4 B (pb) - Restore the current track's pan position prior to pan_left, pan_right or pan_center commands. =over 8 pan_back =back =head4 B (lt show) - Show a list of tracks, including their index number, volume, pan position, recording status and source. =over 8 show_tracks =back =head4 B (sha showa) - Like show_tracks, but includes hidden tracks as well. Useful for debugging. =over 8 show_tracks_all =back =head4 B (ltb showb) - Show a list of tracks in the current bus. =over 8 show_bus_tracks =back =head4 B (sh -fart) - Display full information about the current track: index, recording status, effects and controllers, inserts, the selected WAV version, and signal width (channel count). =over 8 show_track =back =head2 Setup commands =head4 B (shm) - Display the current record/playback mode. this will indicate the mode (doodle, preview, etc.) and possible record/playback settings. =over 8 show_mode =back =head2 Track commands =head4 B (shl) - Display the latency information for the current track. =over 8 show_track_latency =back =head2 Diagnostics commands =head4 B (shla) - Dump all latency data. =over 8 show_latency_all =back =head2 Track commands =head4 B (srg) - Specify a playback region for the current track using marks. Can be reversed with remove_region. =over 8 set_region sax # Select "sax" as the current track. setpos 2.5 # Move the playhead to 2.5 seconds. mark sax_start # Create a mark sp 120.5 # Move playhead to 120.5 seconds. mark sax_end # Create another mark set_region sax_start sax_end # Play only the audio from 2.5 to 120.5 seconds. =back =head4 B - Make a copy of the current track using the supplied a region definition. The original track is untouched. =over 8 add_region | | [ ] sax # Select "sax" as the current track. add_region sax_start 66.7 trimmed_sax # Create "trimmed_sax", a copy of "sax" with a region defined # from mark "sax_start" to 66.7 seconds. =back =head4 B (rrg) - Remove the region definition from the current track. Remove the current track if it is an auxiliary track. =over 8 remove_region =back =head4 B (shift playat pat) - Choose an initial delay before playing a track or region. Can be reversed by unshift_track. =over 8 shift_track | piano # Select "piano" as current track. shift 6.7 # Move the start of track to 6.7 seconds. =back =head4 B (unshift) - Restore the playback start time of a track or region to 0. =over 8 unshift_track =back =head4 B (mods mod) - Add/show modifiers for the current track (man ecasound for details). This provides direct control over Ecasound track modifiers It is not needed for normal work. =over 8 modifiers [ Audio file sequencing parameters ] modifiers select 5 15.2 # Apply Ecasound's select modifier to the current track. # The usual way to accomplish this is with a region definition. =back =head4 B (nomods nomod) - Remove modifiers from the current track. =over 8 nomodifiers =back =head4 B (ecanormalize) - Apply ecanormalize to the current track version. This will raise the gain/volume of the current track as far as possible without clipping and store it that way on disk. Note: this will permanently change the file. =over 8 normalize =back =head4 B (ecafixdc) - Fix the DC-offset of the current track using ecafixdc. Note: This will permanently change the file. =over 8 fixdc =back =head4 B (autofix) - Apply ecafixdc and ecanormalize to all current versions of all tracks, set to playback (MON). =over 8 autofix_tracks =back =head4 B - Remove the current track with its effects, inserts, etc. Audio files are unchanged. =over 8 remove_track =back =head2 Bus commands =head4 B (bmon) - Set the current bus mix_track to monitor (the default behaviour). =over 8 bus_mon =back =head4 B (boff) - Set current bus mixtrack to OFF. Can be reversed with bus_rec or bus_mon. =over 8 bus_off =back =head2 Group commands =head4 B (bver gver) - Set the default monitoring version for tracks in the current bus. =over 8 bus_version =back =head4 B (abn) - =over 8 add_bunch [ | ] ... add_bunch strings violin cello bass # Create a bunch "strings" with tracks violin, cello and bass. for strings; mute # Mute all tracks in the strings bunch. for strings; vol * 0.8 # Lower the volume of all tracks in bunch "strings" by a # a factor of 0.8. =back =head4 B (lbn) - Display a list of all bunches and their tracks. =over 8 list_bunches =back =head4 B (rbn) - Remove the specified bunches. This does not remove the tracks, only the grouping. =over 8 remove_bunch [ ] ... =back =head4 B (atbn) - Add track(s) to an existing bunch. =over 8 add_to_bunch [ ] ... add_to_bunch woodwind oboe sax flute =back =head2 Project commands =head4 B (ci) - Commit Nama's current state =over 8 commit =back =head4 B - Git tag the current branch HEAD commit =over 8 tag [] =back =head4 B (br) - Change to named branch =over 8 branch =back =head4 B (lb lbr) - List branches =over 8 list_branches =back =head4 B (nbr) - Create a new branch =over 8 new_branch [] =back =head4 B (keep save) - Save the project settings as file or git snapshot =over 8 save_state [ [ ] ] =back =head4 B (get recall retrieve) - Retrieve project settings from file or snapshot =over 8 get_state =back =head4 B (lp) - List all projects. This will list all Nama projects, which are stored in the Nama project root directory. =over 8 list_projects =back =head4 B (create) - Create or open a new empty Nama project. =over 8 new_project create jam =back =head4 B (load) - Load an existing project. This will load the project from the default project state file. If you wish to load a project state saved to a user specific file, load the project and then use get_state. =over 8 load_project load my_old_song =back =head4 B (project name) - Display the name of the current project. =over 8 project_name =back =head4 B (npt) - Make a project template based on the current project. This will include tracks and busses. =over 8 new_project_template [ ] new_project_template my_band_setup "tracks and busses for bass, drums and me" =back =head4 B (upt apt) - Use a template to create tracks in a newly created, empty project. =over 8 use_project_template apt my_band_setup # Will add all the tracks for your basic band setup. =back =head4 B (lpt) - List all project templates. =over 8 list_project_templates =back =head4 B - Remove one or more project templates. =over 8 destroy_project_template [ ] ... =back =head2 Setup commands =head4 B (gen) - Generate an Ecasound chain setup for audio processing manually. Mainly useful for diagnostics and debugging. =over 8 generate =back =head4 B - Generate and connect a setup to record or playback. If you are in dodle or preview mode, this will bring you back to normal mode. =over 8 arm =back =head4 B (arms) - Generate and connect the setup and then start. This means, that you can directly record or listen to your tracks. =over 8 arm_start =back =head4 B (con) - Connect the setup, so everything is ready to run. Ifusing JACK, this means, that Nama will connect to all the necessary JACK ports. =over 8 connect =back =head4 B (dcon) - Disconnect the setup. If running with JACK, this will disconnect from all JACK ports. =over 8 disconnect =back =head4 B (chains) - Show the underlying Ecasound chain setup for the current working condition. Mainly useful for diagnostics and debugging. =over 8 show_chain_setup =back =head4 B (l) - Loop the playback between two points. Can be stopped with loop_disable =over 8 loop | | | | loop 1.5 10.0 # Loop between 1.5 and 10.0 seconds. loop 1 5 # Loop between marks with indeices 1 and 5, see list_marks. loop sax_start 12.6 # Loop between mark sax_start and 12.6 seconds. =back =head4 B (nl) - Disable looping. =over 8 noloop =back =head2 Effect commands =head4 B (acl) - Add a controller to an effect (current effect, by default). Controllers can be modified by using mfx and removed using rfx. =over 8 add_controller [ ] [ ] ... add_effect etd 100 2 2 50 50 # Add a stero delay of 100ms. # the delay will get the effect ID E . # Now we want to slowly change the delay to 200ms. acl E klg 1 100 200 2 0 100 15 200 # Change the delay time linearly (klg) =back =head4 B (afx) - Add an effect =over 8 add_effect [ (before | first | last ) ] [ ... ] "before", "first" and "last" can be abbreviated "b", "f" and "l", respectively. We want to add the decimator effect (a LADSPA plugin). help_effect decimator # Print help about its paramters/controls. # We see two input controls: bitrate and samplerate afx decimator 12 22050 # prints "Added GO (Decimator)" # We have added the decimator with 12bits and a sample rate of 22050Hz. # GO is the effect ID, which you will need to modify it. =back =head4 B (afxl) - Same as add-effect last =over 8 add_effect_last [ ... ] =back =head4 B (afxf) - Same as add-effect first =over 8 add_effect_first [ ... ] =back =head4 B (afxb) - Same as add-effect before =over 8 add_effect_before [ ... ] =back =head4 B (mfx) - Modify effect parameter(s). =over 8 modify_effect [ ] [ + | - | * | / ] fx_alias can be: a position, effect ID, nickname or effect code To change the roomsize of our reverb effect to 62 lfx # We see that reverb has unique effect ID AF and roomsize is the # first parameter. mfx AF 1 62 # mfx AF,BG 1 75 # Change the first parameter of both AF and BG to 75. # mfx CE 6,10 -3 # Change parameters 6 and 10 of effect CE to -3 # mfx D 4 + 10 # Increase the fourth parameter of effect D by 10. # mfx A,B,C 3,6 * 5 # Adjust parameters 3 and 6 of effect A, B and C by a factor of 5. =back =head4 B (rfx) - Remove effects. They don't have to be on the current track. =over 8 remove_effect [ ] ... =back =head4 B (pfx) - Position an effect before another effect (use 'ZZZ' for end). =over 8 position_effect position_effect G F # Move effecit with unique ID G before F. =back =head4 B (sfx) - Show information about an effect. Default is to print information on the current effect. =over 8 show_effect [ ] [ ] ... sfx # Print name, unique ID and parameters/controls of the current effect. sfx H # Print out all information about effect with unique ID H. =back =head4 B (dfx) - Dump all data of current effect object =over 8 dump_effect =back =head4 B (lfx) - Print a short list of all effects on the current track, only including unique ID and effect name. =over 8 list_effects =back =head2 General commands =head4 B (hk) - Use this command to set the hotkey mode. (You may also use the hash symbol '#'.) Hit the Escape key to return to command mode. =over 8 hotkeys =back =head4 B (hka) - Activate hotkeys mode after each command. =over 8 hotkeys_always =back =head4 B (hko) - Disable hotkeys always mode =over 8 hotkeys_off =back =head4 B (hkl lhk) - List hotkey bindings =over 8 hotkeys_list =back =head2 Effect commands =head4 B (ain) - Add an external send/return insert to current track. =over 8 add_insert External: ( pre | post ) [ ] Local wet/dry: local add_insert pre jconvolver # Add a prefader insert. The current track signal is sent # to jconvolver and returned to the vol/pan controls. add_insert post jconvolver csound # Send the current track postfader signal (after vol/pan # controls) to jconvolver, getting the return from csound. guitar # Select the guitar track ain local # Create a local insert guitar-1-wet # Select the wet arm afx G2reverb 50 5.0 0.6 0.5 0 -16 -20 # add a reverb afx etc 6 100 45 2.5 # add a chorus effect on the reverbed signal guitar # Change back to the main guitar track wet 25 # Set the balance between wet/dry track to 25% wet, 75% dry. =back =head4 B (wet) - Set wet/dry balance of the insert for the current track. The balance is given in percent, 0 meaning dry and 100 wet signal only. =over 8 set_insert_wetness [ pre | post ] wet pre 50 # Set the prefader insert to be balanced 50/50 wet/dry. wet 100 # Simpler if there's only one insert =back =head4 B (rin) - Remove an insert from the current track. =over 8 remove_insert [ pre | post ] rin # If there is only one insert on the current track, remove it. remove_insert post # Remove the postfader insert from the current track. =back =head4 B (crg) - List all Ecasound controllers. Controllers include linear controllers and oscillators. =over 8 ctrl_register =back =head4 B (prg) - List all Ecasound effect presets. See the Ecasound manpage for more detail on effect_presets. =over 8 preset_register =back =head4 B (lrg) - List all LADSPA plugins, that Ecasound/Nama can find. =over 8 ladspa_register =back =head2 Mark commands =head4 B (lmk lm) - List all marks with index, name and their respective positions in time. =over 8 list_marks =back =head4 B (tmk tom) - Move the playhead to the named mark or mark index. =over 8 to_mark | to_mark sax_start # Jump to the position marked by sax_mark. tmk 2 # Move to the mark with the index 2. =back =head4 B (mark amk k) - Drop a new mark at the current playback position. this will fail, if a mark is already placed on that exact position. =over 8 add_mark [ ] mark start # Create a mark named "start" at the current position. =back =head4 B (rmk) - Remove a mark =over 8 remove_mark [ | ] remove_mark start # remove the mark named start rmk 16 # Remove the mark with the index 16. rmk # Remove the current mark =back =head4 B (nmk) - Move the playhead to the next mark. =over 8 next_mark =back =head4 B (pmk) - Move the playhead to the previous mark. =over 8 previous_mark =back =head4 B - Give a name to the current mark. =over 8 name_mark =back =head4 B (move_mark mmk) - Change the position (time) of the current mark. =over 8 modify_mark [ + | - ] move_mark + 2.3 # Move the current mark 2.3 seconds forward from its mmk 16.8 # Move the current mark to 16.8 seconds, no matter, where it is now. =back =head2 Diagnostics commands =head4 B (egs) - Display the Ecasound audio processing engine status. =over 8 engine_status =back =head4 B (dump) - Dump current track data. =over 8 dump_track =back =head4 B (dumpg) - Dump group settings for user tracks. =over 8 dump_group =back =head4 B (dumpa) - Dump most internal state data. =over 8 dump_all =back =head4 B - Show chain inputs and outputs. =over 8 dump_io =back =head2 Help commands =head4 B (lh) - List the command history. Every project stores its own command history. =over 8 list_history =back =head2 Bus commands =head4 B - Create a submix using all tracks in bus "Main" =over 8 add_submix_cooked add_submix_cooked front_of_house 7 # send a custom mix named "front_of_house" # to soundcard channels 7/8 =back =head4 B (asr) - Add a submix using tracks in Main bus (unprocessed signals, lower latency) =over 8 add_submix_raw asbr Reverb jconv # Add a raw send bus called Reverb, with its output =back =head4 B (abs) - Add a sub bus. This is a bus, as known from other DAWs. The default output goes to a mix track and that is routed to the mixer (the Master track). All busses begin with a capital letter! =over 8 add_bus [ | | ] abs Brass # Add a bus, "Brass", routed to the Main bus (e.g. mixer) abs special csound # Add a bus, "special" routed to JACK client "csound" =back =head4 B (usm) - Include tracks added since the submix was created. =over 8 update_submix update_submix Reverb =back =head4 B - Remove a bus or submix =over 8 remove_bus =back =head4 B (lbs) - List buses and their parameters (TODO). =over 8 list_buses =back =head4 B (sbs) - Set bus parameters. This command is intended for advanced users. =over 8 set_bus =back =head2 Effect commands =head4 B (oec) - Create a new effect chain, overwriting an existing one of the same name. =over 8 overwrite_effect_chain Same as for new_effect_chain =back =head4 B (nec) - Create an effect chain, a named list of effects with all parameter settings. Useful for storing effect setups for particular instruments. =over 8 new_effect_chain [ ... ] new_effect_chain my_piano # Create a new effect chain, "my_piano", storing all # effects and their settings from the current track # except the fader (vol/pan) settings. nec my_guitar A C F G H # Create a new effect chain, "my_guitar", # storing the effects with IDs A, C, F, G, H and # their respective settings. =back =head4 B (dec destroy_effect_chain) - Delete an effect chain definition. Does not affect the project state. This command is not reversible by undo. =over 8 delete_effect_chain =back =head4 B (fec) - Dump effect chains, matching key/value pairs if provided =over 8 find_effect_chains [ ] ... fec # List all effect chains with their effects. =back =head4 B (fuec) - List all *user* created effect chains, matching key/value pairs, if provided. =over 8 find_user_effect_chains [ ] ... =back =head4 B (bypass bfx) - Bypass effects on the current track. With no parameters default to bypassing the current effect. =over 8 bypass_effects [ ... | 'all' ] bypass all # Bypass all effects on the current track, except vol and pan. bypass AF # Only bypass the effect with the unique ID AF. =back =head4 B (restore_effects bbfx) - Restore effects. If no parameter is given, the default is to restore the current effect. =over 8 bring_back_effects [ ... | 'all' ] bbfx # Restore the current effect. restore_effect AF # Restore the effect with the unique ID AF. bring_back_effects all # Restore all effects. =back =head4 B (nep) - Create a new effect profile. An effect profile is a named group of effect chains for multiple tracks. Useful for storing a basic template of standard effects for a group of instruments, like a drum kit. =over 8 new_effect_profile [ ] add_bunch Drums snare toms kick # Create a buch called Drums. nep Drums my_drum_effects # Create an effect profile, call my_drum_effects =back =head4 B (aep) - Apply an effect profile. this will add all the effects in it to the list of tracks stored in the effect profile. Note: You must give the tracks the same names as in the original project, where you created the effect profile. =over 8 apply_effect_profile =back =head4 B - Delete an effect profile. This will delete the effect profile definition from your disk. All projects, which use this effect profile will NOT be affected. =over 8 destroy_effect_profile =back =head4 B (lep) - List all effect profiles. =over 8 list_effect_profiles =back =head4 B (sepr) - List effect profile. =over 8 show_effect_profiles =back =head4 B (fep) - Dump effect profile data structure. =over 8 full_effect_profiles =back =head2 Track commands =head4 B (cache ct bounce freeze) - Cache the current track. Same as freezing or bouncing. This is useful for larger projects or low-power CPUs, since effects do not have to be recomputed for subsequent engine runs. Cache_track stores the effects-processed output of the current track as a new version (WAV file) which becomes the current version. The current effects, inserts and region definition are removed and stored. To go back to the original track state, use the uncache_track command. The show_track display appends a "c" to version numbers created by cache_track (and therefore reversible by uncache) =over 8 cache_track [ ] cache 10 # Cache the curent track and append 10 seconds extra time, =back =head2 Effect commands =head4 B (uncache unc) - Select the uncached track version. This restores effects, but not inserts. =over 8 uncache_track =back =head2 General commands =head4 B (do) - Execute Nama commands from a file in the main project's directory or in the Nama project root directory. A script is a list of Nama commands, just as you would type them on the Nama prompt. =over 8 do_script do prepare_my_drums # Execute the script prepare_my_drums. =back =head4 B - Re-read the project's .wav directory. Mainly useful for troubleshooting. =over 8 scan =back =head2 Effect commands =head4 B (afd fade) - Add a fade-in or fade-out to the current track. =over 8 add_fade ( in | out ) marks/times (see examples) fade in mark1 # Fade in,starting at mark1 and using the # default fade time of 0.5 seconds. fade out mark2 2 # Fade out over 2 seconds, starting at mark2 . fade out 2 mark2 # Fade out over 2 seconds, ending at mark2 . fade in mark1 mark2 # Fade in starting at mark1, ending at mark2 . =back =head4 B (rfd) - Remove a fade from the current track. =over 8 remove_fade [ ] ... list_fade # Print a list of all fades and their tracks. rfd 2 # Remove the fade with the index (n) 2. =back =head4 B (lfd) - List all fades. =over 8 list_fade =back =head2 Track commands =head4 B (comment ac) - Add a comment to the current track (replacing any previous comment). A comment maybe a short discription, notes on instrument settings, etc. =over 8 add_comment ac "Guitar, treble on 50%" =back =head4 B (rc) - Remove a comment from the current track. =over 8 remove_comment =back =head4 B (sc) - Show the comment for the current track. =over 8 show_comment =back =head4 B (sca) - Show all track comments. =over 8 show_comments =back =head4 B (avc) - Add a version comment (replacing any previous user comment). This will add a comment for the current version of the current track. =over 8 add_version_comment avc "The good take with the clear 6/8" =back =head4 B (rvc) - Remove version comment(s) from the current track. =over 8 remove_version_comment =back =head4 B (svc) - Show version comment(s) of the curent track. =over 8 show_version_comment =back =head4 B (svca) - Show all version comments for the current track. =over 8 show_version_comments_all =back =head4 B (ssvc) - Set a system version comment. Useful for testing and diagnostics. =over 8 set_system_version_comment =back =head2 Midi commands =head4 B (m) - Send the command text to the midish MIDI sequencer. Midish must be installed and enabled in namarc. See the midish manpage and fullonline documentation for more. =over 8 midish_command m tracknew my_midi_track =back =head4 B (mmo) - All users commands sent to midish, until =over 8 midish_mode_on =back =head4 B (mmx) - Exit midish mode, restore default Nama command mode, no midish sync =over 8 midish_mode_off =back =head4 B (mmxrp) - Exit midish mode, sync midish start (p) with Ecasound =over 8 midish_mode_off_ready_to_play =back =head4 B (mmxrr) - Exit midish mode, sync midish start (r) with Ecasound =over 8 midish_mode_off_ready_to_record =back =head2 Edit commands =head4 B (ned) - Create an edit for the current track and version. =over 8 new_edit =back =head4 B (sep) - Mark play-start, record-start and record-end positions for the current edit. =over 8 set_edit_points =back =head4 B (led) - List all edits for current track and version. =over 8 list_edits =back =head4 B (sed) - Select an edit to modify or delete. After selection it is the current edit. =over 8 select_edit =back =head4 B (eem) - Switch back to normal playback/record mode. The track will play full length again. Edits are managed via a sub- bus. =over 8 end_edit_mode =back =head4 B - Remove an edit and all associated audio files. If no parameter is given, the default is to destroy the current edit. Note: The data will be lost permanently. Use with care! =over 8 destroy_edit [ ] =back =head4 B (pei) - Play the track region without the edit segment. =over 8 preview_edit_in =back =head4 B (peo) - Play the removed edit segment. =over 8 preview_edit_out =back =head4 B (ped) - Play a completed edit. =over 8 play_edit =back =head4 B (red) - Record an audio file for the current edit. =over 8 record_edit =back =head4 B (et) - Set the edit track as the current track. =over 8 edit_track =back =head4 B (hta) - Set the host track alias as the current track. =over 8 host_track_alias =back =head4 B (ht) - Set the host track (edit sub-bus mix track) as the current track. =over 8 host_track =back =head4 B (vmt) - Set the version mix track as the current track. =over 8 version_mix_track =back =head4 B (psm) - Select (and move to) play start mark of the current edit. =over 8 play_start_mark =back =head4 B (rsm) - Select (and move to) rec start mark of the current edit. =over 8 rec_start_mark =back =head4 B (rem) - Select (and move to) rec end mark of the current edit. =over 8 rec_end_mark =back =head4 B (spsm) - Set play_start_mark to the current playback position. =over 8 set_play_start_mark =back =head4 B (srsm) - Set rec_start_mark to the current playback position. =over 8 set_rec_start_mark =back =head4 B (srem) - Set rec_end_mark to current playback position. =over 8 set_rec_end_mark =back =head4 B (ded) - Turn off the edits for the current track and playback the original. This will exclude the edit sub bus. =over 8 disable_edits =back =head4 B (med) - Mix edits and original into a new host-track. this will write a new audio file to disk and the host track will have a new version for this. =over 8 merge_edits =back =head2 Track commands =head4 B - Make the current track into a sub bus, with one track for each version. =over 8 explode_track =back =head4 B (mtb) - Move the current track to another bus. A new track is always in the Main bus. So to reverse this action use move_to_bus Main . =over 8 move_to_bus asub Drums # Create a new sub bus, called Drums. snare # Make snare the current track. mtb Drums # Move the snare track into the sub bus Drums. =back =head4 B (pvt) - Create a read-only track using the specified version of the current track. =over 8 promote_version_to_track =back =head2 General commands =head4 B (ruc) - Re-read the user customizations file 'custom.pl'. =over 8 read_user_customizations =back =head2 Setup commands =head4 B (lr) - Stop recording after the last audio file finishes playing. Can be turned off with limit_run_time_off. =over 8 limit_run_time [ ] =back =head4 B (lro) - Disable the recording stop timer. =over 8 limit_run_time_off =back =head4 B (ofr) - Record/play from a mark, rather than from the start, i.e. 0.0 seconds. =over 8 offset_run =back =head4 B (ofro) - Turn back to starting from 0. =over 8 offset_run_off =back =head2 General commands =head4 B (wview) - Launch mhwavedit to view/edit waveform of the current track and version. This requires to start Nama on a graphical terminal, like xterm or gterm or from GNOME via alt+F2 . =over 8 view_waveform =back =head4 B (wedit) - Launch audacity to view/edit the waveform of the current track and version. This requires starting Nama on a graphical terminal like xterm or gterm or from GNOME starting Nama using alt+F2 . =over 8 edit_waveform =back =head2 Setup commands =head4 B (rerec) - Record as before. This will set all the tracks to record, which have been recorded just before you listened back. =over 8 rerecord for piano guitar;rec # Set piano and guitar track to record. # do your recording and ilstening. # You want to record another version of both piano and guitar: rerec # Sets piano and guitar to record again. =back =head2 Track commands =head4 B (anl) - Print Ecasound amplitude analysis for current track. This will show highest volume and statistics. =over 8 analyze_level =back =head2 General commands =head4 B - Execute command(s) for several tracks. =over 8 for [ } ... ; for piano guitar; vol - 3; pan 75 # reduce volume and pan right for snare kick toms cymbals; mtb Drums # move tracks to bus Drums =back =head2 Project commands =head4 B - Execute git command in the project directory =over 8 git [arguments] =back =head2 Track commands =head4 B (ersh) - Edit the REC hook script for current track =over 8 edit_rec_setup_hook =back =head4 B (erch) - Edit the REC cleanup hook script for current track =over 8 edit_rec_cleanup_hook =back =head4 B (rffx) - Remove vol pan or fader on current track =over 8 remove_fader_effect vol | pan | fader =back =head4 B - Rename a track and its WAV files =over 8 rename_track =back =head2 Sequence commands =head4 B (nsq) - Define a new sequence =over 8 new_sequence =back =head4 B (slsq) - Select named sequence as current sequence =over 8 select_sequence =back =head4 B (lsq) - List all user sequences =over 8 list_sequences =back =head4 B (ssq) - Display clips making up current sequence =over 8 show_sequence =back =head4 B (asq) - Append items to sequence =over 8 append_to_sequence [,...] asq chorus # append chorus track to current sequence asq # append current track to current sequence =back =head4 B (isq) - Insert items into sequence before index i =over 8 insert_in_sequence [,...] =back =head4 B (rsq) - Remove items from sequence =over 8 remove_from_sequence [,...] =back =head4 B (dsq) - Delete entire sequence =over 8 delete_sequence =back =head4 B (asp) - Add a spacer to the current sequence, in specified position, or appending (if no position is given) =over 8 add_spacer [] =back =head4 B (csq) - Convert the current track to a sequence =over 8 convert_to_sequence =back =head4 B (msq) - Cache and MON the current sequence mix track, disable the sequence =over 8 merge_sequence =back =head4 B - Create a sequence from the current track by removing the region(s) defined by mark pair(s). Not supported if the current track is already a sequence. =over 8 snip [...] snip cut1-start cut1-end cut2-start cut2-end This removes cut1 and cut2 regions from the current track by creating a sequence. =back =head4 B (compose_sequence compose_into_sequence) - Compose a new sequence using the region(s) of the named track defined by mark pair(s). If the sequence of that name exists, append the regions to that sequence (compose_into_sequence). =over 8 compose [...] compose speeches conference-audio speaker1-start speaker1-end speaker2-start speaker2-end This creates a "speeches" sequence with two clips for speaker1 and speaker2. =back =head2 General commands =head4 B - Roll back last commit (use "git log" to see specific commands) Note: redo is not supported yet =over 8 undo =back =head4 B - Restore the last undone commit (TODO) =over 8 redo =back =head4 B (show_head last_command last) - Show the last commit, which undo will roll back. A commit may contain multiple commands. The last_* aliases are meaningful when autosave: undo is set. In that case each commit contains only a single command =over 8 show_head_commit =back =head2 Mode commands =head4 B - Set eager mode =over 8 eager on | off =back =head2 Engine commands =head4 B (neg) - Start a named Ecasound engine, or bind to an existing engine =over 8 new_engine =back =head4 B (seg) - Select an ecasound engine (advanced users only!) =over 8 select_engine =back =head2 Track commands =head4 B (steg) - Set the current track's engine affiliation =over 8 set_track_engine_group =back =head2 Bus commands =head4 B (sbeg) - Set the current bus's engine affiliation =over 8 set_bus_engine_group =back =head4 B (ssm) - Set the target for the trim command =over 8 select_submix =back =head4 B (trim tsm) - Control a submix fader =over 8 trim_submix # reduce vol of current track in in_ear_monitor by 3dB select_submix in_ear_monitor trim vol - 3 =back =head2 Effect commands =head4 B (nfx nick) - Add a nickname to the current effect (and create an alias) =over 8 nickname_effect add_track guitar afx Plate nick reverb # current effect gets name "reverb1" mfx reverb1 1 0.05 # modify first reverb effect on current track mfx reverb 1 2 # works, because current track has one effect named "reverb" afx reverb # add another Plate effect, gets name "reverb2" rfx reverb # Error, multiple reverb effects are present on this # track. Please use a numerical suffix. mfx reverb2 1 3 # modify second reverb effect rfx reverb1 # removes reverb1 ifx reverb2 reverb # insert another reverb effect (reverb3) before reverb2 rfx reverb3 # remove reverb3 rfx reverb # removes reverb2, as it is the sole remain reverb effect =back =head4 B (dnd) - Delete a nickname definition. Previously named effects keep their names. =over 8 delete_nickname_definition afx Plate # add Plate effect nick reverb # name it "reverb", and create a nickname for Plate dnd reverb # removes nickname definition afx reverb # error =back =head4 B (rnick) - Remove the "name" attribute of the current effect =over 8 remove_nickname afx Plate nick reverb mfx reverb 1 3 rnick mfx reverb 1 3 # Error: effect named "reverb" not found on current track =back =head4 B (lnd) - List defined nicknames =over 8 list_nickname_definitions =back =head4 B (sen) - Set a nickname only (don't creating an alias) =over 8 set_effect_name =back =head4 B (ses) - Set an effect surname =over 8 set_effect_surname =back =head4 B (ren) - Remove current effect name =over 8 remove_effect_name =back =head4 B (res) - Remove current effect surname =over 8 remove_effect_surname =back =head2 Track commands =head4 B - Set a particular track as the current, or default track against which track-related commands are executed. =over 8 select_track | =back =head1 REALTIME OPERATION Nama selects realtime or nonrealtime parameters based on the B, B and B fields in F<.namarc>. You can optionally specify the buffersizes as a multiple of the JACK period size. Note that for best realtime operation under JACK you will have to configure jackd appropriately as well. The B and B profiles are useful when using Nama/Ecasound for live fx processing or live monitoring. The B profile sets a small buffersize and other low latency settings whenever a soundcard or JACK client is connected. The B profile uses a bigger buffer, providing extended margins for stable operation. It is suitable for post-processing, or for recording without live monitoring responsibilities. The B profile defaults to nonrealtime settings. It switches to realtime, low-latency settings when a track has a live input. =head1 DIAGNOSTICS On any change in setup, the GUI display updates and C command is executed automatically showing what to expect the next time the engine is started. You can use the C command to verify the Ecasound chain setup. (The Ecasound command C will additionally store all engine data, effects as well as routing.) The C command displays data for the current track. The C command shows all state that would be saved. This is the same output that is written to the F file when you issue the C command. =head1 BUGS AND LIMITATIONS No latency compensation across signal paths is provided at present. This feature is under development. =head1 SECURITY CONCERNS If you are using Nama with the NetECI interface (i.e. if Audio::Ecasound is I installed) you should block TCP port 2868 if your computer is exposed to the Internet. =head1 INSTALLATION The following commands, available on Unixlike systems with Perl installed, will pull in Nama and other Perl libraries required for text mode operation: C -or- C To use the GUI, you will need to install Tk: C You may want to install Audio::Ecasound if you prefer not to run Ecasound in server mode: C You can pull the source code as follows: C Consult the F file for build instructions. =head1 SUPPORT The Nama mailing list is a suitable forum for questions regarding Nama installation, usage, bugs, feature requests, etc. http://www.freelists.org/list/nama For questions and discussion related to Ecasound https://lists.sourceforge.net/lists/listinfo/ecasound-list =head1 PATCHES The modules that make up this application are the preprocessed output from several source files. Patches against these source files are preferred. =head1 AUTHOR Joel Roth, Ejoelz@pobox.comE =head1 CONTRIBUTORS Alex Stone Brett McCoy Dubphil F. Silvain ++ Joy Bausch Julien Claassen ++ Kevin Utter Lars Bjørndal Philippe Schelté Philipp Überbacher Raphaël Mouneyres ++ Rusty Perez S. Massy ++ =head1 COPYRIGHT & LICENSE Copyright (c) 2009-2013 by Joel Roth. This is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, Version 3. Audio-Nama-1.208/lib/0000755000175000017500000000000012644673607013262 5ustar jrothjrothAudio-Nama-1.208/lib/Audio/0000755000175000017500000000000012644673607014323 5ustar jrothjrothAudio-Nama-1.208/lib/Audio/Nama.pm0000644000175000017500000053633212644673574015554 0ustar jrothjrothpackage Audio::Nama; require 5.10.0; use vars qw($VERSION); $VERSION = "1.208"; use Modern::Perl; #use Carp::Always; no warnings qw(uninitialized syntax); ########## External dependencies ########## use Carp qw(carp cluck confess croak); use Cwd; use Data::Section::Simple qw(get_data_section); use File::Find::Rule; use File::Path; use File::Spec; use File::Spec::Link; use File::Temp; use Getopt::Long; use Git::Repository; use Graph; use IO::Socket; use IO::Select; use IPC::Open3; use Log::Log4perl qw(get_logger :levels); use Module::Load::Conditional qw(can_load); use Module::Load; use Parse::RecDescent; use Storable qw(thaw); use Term::ReadLine; use Text::Diff; use Text::Format; use Try::Tiny; # use File::HomeDir;# Assign.pm # use File::Slurp; # several # use List::Util; # Fade.pm # use List::MoreUtils; # Effects.pm # use Time::HiRes; # automatically detected # use Tk; # loaded conditionally # use Event; # loaded conditionally # use AnyEvent; # loaded after Tk or Event # use AnyEvent::Term::TermKey; # --ditto-- # use jacks; # JACK server API # use Protocol::OSC; ########## Nama modules ########### # # Note that :: in the *.p source files is expanded by # SKIP_PREPROC # preprocessing to Audio::Nama in the generated *.pm files. # SKIP_PREPROC # ::Assign becomes Audio::Nama::Assign # SKIP_PREPROC # # These modules import functions and variables # use Audio::Nama::Assign qw(:all); use Audio::Nama::Globals qw(:all); use Audio::Nama::Util qw(:all); # Import the two user-interface classes use Audio::Nama::Text; use Audio::Nama::Graphical; # They are descendents of a base class we define in the root namespace our @ISA; # no ancestors use Audio::Nama::Object qw(mode); # based on Object::Tiny sub hello {"superclass hello"} sub new { my $class = shift; return bless {@_}, $class } # The singleton $ui belongs to either the Audio::Nama::Text or Audio::Nama::Graphical class # depending on command line flags (-t or -g). # This (along with the availability of Tk) # determines whether the GUI comes up. The Text UI # is *always* available in the terminal that launched # Nama. # How is $ui->init_gui interpreted? If $ui belongs to class # Audio::Nama::Text, Nama finds a no-op init_gui() stub in package Audio::Nama::Text # and does nothing. # If $ui belongs to class Audio::Nama::Graphical, Nama looks for # init_gui() in package Audio::Nama::Graphical, finds nothing, so goes to # look in the base class. All graphical methods (found in # Graphical_subs.pl) are defined in the root namespace so they can # call Nama core methods without a package prefix. ######## Nama classes ######## use Audio::Nama::Track; use Audio::Nama::Bus; use Audio::Nama::Sequence; use Audio::Nama::Mark; use Audio::Nama::IO; use Audio::Nama::Wav; use Audio::Nama::Insert; use Audio::Nama::Fade; use Audio::Nama::Edit; use Audio::Nama::EffectChain; use Audio::Nama::Lat; use Audio::Nama::Engine; ####### Nama subroutines ###### # # The following modules serve only to define and segregate subroutines. # They occupy the root namespace (except Audio::Nama::ChainSetup) # and do not execute any code when use'd. use Audio::Nama::AnalyseLV2; use Audio::Nama::Initializations (); use Audio::Nama::Options (); use Audio::Nama::Config (); use Audio::Nama::Custom (); use Audio::Nama::Terminal (); use Audio::Nama::Grammar (); use Audio::Nama::Help (); use Audio::Nama::Project (); use Audio::Nama::Persistence (); use Audio::Nama::Git; use Audio::Nama::ChainSetup (); # separate namespace use Audio::Nama::Graph (); use Audio::Nama::Modes (); use Audio::Nama::Mix (); use Audio::Nama::Memoize (); use Audio::Nama::EngineSetup (); use Audio::Nama::EngineRun (); use Audio::Nama::EngineCleanup (); use Audio::Nama::EffectsRegistry (); use Audio::Nama::Effect q(:all); use Audio::Nama::MuteSoloFade (); use Audio::Nama::Jack (); use Audio::Nama::Regions (); use Audio::Nama::CacheTrack (); use Audio::Nama::Bunch (); use Audio::Nama::Wavinfo (); use Audio::Nama::Midi (); use Audio::Nama::Latency (); use Audio::Nama::Log qw(logit loggit logpkg logsub initialize_logger); sub main { say eval join(get_data_section('banner'), qw(" ")); bootstrap_environment() ; load_project(); process_command($config->{execute_on_project_load}); reconfigure_engine(); process_command($config->{opts}->{X}); $ui->loop(); } sub bootstrap_environment { definitions(); process_command_line_options(); start_logging(); setup_grammar(); setup_hotkey_grammar(); initialize_interfaces(); } sub cleanup_exit { logsub("&cleanup_exit"); remove_riff_header_stubs(); trigger_rec_cleanup_hooks(); # for each process: # - SIGINT (1st time) # - allow time to close down # - SIGINT (2nd time) # - allow time to close down # - SIGKILL delete $project->{events}; close_midish() if $config->{use_midish}; my @engines = values %Audio::Nama::Engine::by_name; for (@engines){ if( @{$_->{pids}}){ map{ my $pid = $_; map{ my $signal = $_; kill $signal, $pid; sleeper(0.2); } (15,9); waitpid $pid, 1; } @{$_->{pids}}; } } $text->{term}->rl_deprep_terminal() if defined $text->{term}; exit; } END { } 1; __DATA__ @@ commands_yml --- help: type: help what: Display help on Nama commands. short: h parameters: [ | | ] example: | help marks # display the help category marks and all commands containing marks help 6 # display help on the effects category help mfx # display help on modify_effect - shortcut mfx help_effect: type: help what: Display detailed help on LADSPA or LV2 effects. short: hfx he parameters: | example: | help_effect 1970 ! display help on Fons Adriaensen's parametric EQ (LADSPA) help_effect etd ! prints a short message to consult Ecasound manpage, ! where the etd chain operator is documented. hfx lv2-vocProc ! display detailed help on the LV2 VocProc effect find_effect: type: help what: Display one-line help for effects matching the search string(s). short: ffx fe parameters: [ ... ] example: | find_effect compressor ! List all effects containing "compressor" in their name or parameters fe feedback ! List all effects matching "feedback" ! (for example a delay with a feedback parameter) exit: type: general what: Exit Nama, saving settings (the current project). short: quit q parameters: none memoize: type: general what: | Enable WAV directory caching, so Nama won't have to scan the entire project folder for new files after every run. (default) parameters: none unmemoize: type: general what: Disable WAV directory caching. parameters: none stop: type: transport what: Stop transport. Stop the engine, when recording or playing back. short: s parameters: none start: type: transport what: Start the transport rolling short: t parameters: none example: | rec # prepare the curent track to be recorded. start # Start the engine/transport rolling (play now!) stop # Stop the engine, cleanup, prepare to review getpos: type: transport what: Get the current playhead position (in seconds). short: gp parameters: none example: | start # Start the engine. gp # Get the current position of the playhead. Where am I? setpos: type: transport what: Set current playhead position (in seconds). short: sp parameters: example: setpos 65.5 # set current position to 65.5 seconds. forward: type: transport what: Move playback position forwards (in seconds). short: fw parameters: example: fw 23.7 # forward 23.7 seconds from the current position. rewind: type: transport what: Move playback position backwards (in seconds). short: rw parameters: example: rewind 6.5 # Move backwards 6.5 seconds from the current position. to_start: type: transport what: Set the playback head to the start. A synonym for setpos 0. short: beg parameters: none to_end: type: transport what: Set the playback head to end minus 10 seconds. short: end parameters: none ecasound_start: type: transport what: | Ecasound-only start. Nama will not monitor the transport. For diagnostic use. parameters: none ecasound_stop: type: transport what: | Ecasound-only stop. Nama will not monitor the transport. For diagnostic use. parameters: none restart_ecasound: type: transport what: | Restart the Ecasound process. May help if Ecasound has crashed or is behaving oddly. parameters: none preview: type: transport what: | Enter the preview mode. Configure Nama for playback and passthru of live inputs without recording (for mic test, rehearsal, etc.) short: song parameters: none example: | rec # Set the current track to record from its source. preview # Enter the preview mode. start # Playback begins. You can play live, adjust effects, ! # forward, rewind, etc. stop # Stop the engine/transport. arm # Restore to normal recording/playback mode. doodle: type: transport short: live what: | Enter doodle mode. Passthru of live inputs without recording. No playback. Intended for rehearsing and adjusting effects. parameters: none example: | doodle # Switch into doodle mode. start # start the engine/transport running. (fool around) stop # Stop the engine. arm # Return to normal mode, allowing play and record to disk mixdown: type: mix what: | Enter mixdown mode for subsequent engine runs. You will record a new mix each time you use the start command until you leave the mixdown mode using "mixoff". short: mxd parameters: none example: | mixdown # Enter mixdown mode start # Start the transport. The mix will be recorded by the ! # Mixdown track. The engine will run until the ! # longest track ends. (After mixdown Nama places ! # a symlink to the WAV file and possibly ogg/mp3 ! # encoded versions in the project directory.) mixoff # Return to the normal mode. mixplay: type: mix what: | Enter Mixdown play mode, setting user tracks to OFF and only playing the Mixdown track. Use "mixoff" to leave this mode. short: mxp parameters: none example: | mixplay # Enter the Mixdown play mode. start # Play the Mixdown track. stop # Stop playback. mixoff # Return to normal mode. mixoff: type: mix what: | Leave the mixdown or mixplay mode. Sets Mixdown track to OFF, user tracks to MON. short: mxo parameters: none automix: type: mix what: Normalize track volume levels and fix DC-offsets, then mixdown. parameters: none master_on: type: mix what: | Turn on the mastering mode, adding tracks Eq, Low, Mid, High and Boost, if necessary. The mastering setup allows for one EQ and a three-band multiband compression and a final boosting stage. Using "master_off" to leave the mastering mode. short: mr parameters: none example: | mr # Turn on master mode. start # Start the playback. ! # Now you can adjust the Boost or global EQ. stop # Stop the engine. master_off: type: mix what: Leave mastering mode. The mastering network is disabled. short: mro parameters: none add_track: type: track what: Create a new audio track. short: add new parameters: example: | add_track clarinet ! create a mono track called clarinet with input ! from soundcard channel 1. add_tracks: type: track what: Create one or more new tracks in one go. parameters: [ ... ] example: add_tracks violin viola contra_bass add_midi_track: type: track what: Create a new MIDI track. short: amt parameters: link_track: type: track what: Create a read-only track, that uses audio files from another track. short: link parameters: [] example: | link my_song_part1 Mixdown part_1 ! Create a read-only track "part_1" in the current project ! using files from track "Mixdown" in project "my_song_part_1". ! link_track compressed_piano piano ! Create a read-only track "compressed_piano" using files from ! track "piano". This is one way to provide wet and dry ! (processed and unprocessed) versions of same source. ! Another way would be to use inserts. import_audio: type: track what: | Import a sound file (wav, ogg, mp3, etc.) to the current track, resampling it if necessary. The imported file is set as current version. short: import parameters: [ ] example: | import /home/samples/bells.flac ! import the file bells.flac to the current track import /home/music/song.mp3 44100 ! import song.mp3, specifying the frequency set_track: type: track what: Directly set current track parameters (use with care!). parameters: record: type: track what: | Set the current track to record its source. Creates the monitoring route if necessary. Recording to disk will begin on the next engine start. Use the "mon" or "off" commands to disable recording. short: rec parameters: none example: | rec ! Set the current track to record. start ! A new version (take) will be written to disk, ! creating a file such as sax_1.wav. Other tracks ! may be recording or playing back as well. stop ! Stop the recording/playback, automatically enter playback mode play: type: track what: | Set the current track to playback the currently selected version. Creates the monitoring route if necessary. The selected audio file will play the next time the engine starts. parameters: none mon: type: track what: | Create a monitoring route for the current track at the next opportunity. parameters: none off: type: track what: | Remove the monitoring route for the current track and all track I/O at the next opportunity. You can re-include it using "mon", "play" or "rec" commands. parameters: none source: type: track what: | Set the current track's input (source), for example to a soundcard channel, or JACK client name short: src r parameters: | | | | | | | 'jack' | 'null' example: | source 3 ! Take input from soundcard channel 3 (3/4 if track is stereo) ! source null ! Track's input is silence. This is useful for when an effect such ! as a metronome or signal generator provides a source. ! source LinuxSampler ! Record input from the JACK client named LinuxSampler. ! source synth:output_3 ! record from the JACK client synth, using the ! port output_3 (see he jackd and jack_lsp manpages ! for more information). ! source jack ! This leaves the track input exposed as JACK ports ! such as Nama:sax_in_1 for manual connection. ! source kit.ports ! The JACK ports listed in the file kit.ports (if it exists) ! will be connected to the track input. ! ! Ports are listed pairwise in the .ports files for stereo tracks. ! This is convenient for use with the Hydrogen drumkit, ! whose outputs use one JACK port per voice. send: type: track what: Set an aux send for the current track. Remove sends with remove_send . short: aux parameters: | | example: | send 3 # Send the track output to soundcard channel 3. send jconvolver # Send the track output to the jconvolver JACK client. remove_send: type: track what: Remove aux send from the current track. short: nosend noaux parameters: none stereo: type: track what: Configure the current track to record two channels of audio parameters: none mono: type: track what: Configure the current track to record one channel of audio parameters: none set_version: type: track what: | Select a WAV file, by version number, for current track playback (Overrides a bus-level version setting) short: version ver parameters: example: | piano # Select the piano track. version 2 # Select the second recorded version sh # Display information about the current track destroy_current_wav: type: track what: | Remove the currently selected recording version from the current track after confirming user intent. This DESTRUCTIVE command removes the underlying audio file from your disk. Use with caution. parameters: none list_versions: type: track what: | List WAV versions of the current track. This will print the numbers. short: lver parameters: none example: | list_versions # May print something like: 1 2 5 7 9 ! # The other versions might have been deleted earlier by you. vol: type: track what: Change or show the current track's volume. short: v parameters: [ [ + | - | / | * ] ] example: | vol * 1.5 # Multiply the current volume by 1.5 vol 75 # Set the current volume to 75 ! # Depending on your namarc configuration, this means ! # either 75% of full volume (-ea) or 75 dB (-eadb). vol - 5.7 # Decrease current volume by 5.7 (percent or dB) vol # Display the volume setting of the current track. mute: type: track what: | Mute the current track by reducing the volume parameter. Use "unmute" to restore the former volume level. short: c cut parameters: none unmute: type: track what: Restore previous volume level. It can be used after mute or solo. short: nomute C uncut parameters: none unity: type: track what: Set the current track's volume to unity. This will change the volume to the default value (100% or 0 dB). parameters: none example: | vol 55 # Set volume to 55 unity # Set volume to the unity value. vol # Display the current volume (should be 100 or 0, ! # depending on your settings in namarc.) solo: type: track what: | Mute all tracks but the current track or the tracks or bunches specified. You can reverse this with nosolo. short: sl parameters: [ | ] [ ] ... example: | solo # Mute all tracks but the current track. nosolo # Unmute all tracks, restoring prior state. solo piano bass Drums # Mute everything but piano, bass and Drums. nosolo: type: track what: | Unmute all tracks which have been muted by a solo command. Tracks that had been muted before the solo command stay muted. short: nsl parameters: none all: type: track what: | Unmute all tracks that are currently muted parameters: none example: | piano # Select track piano mute # Mute the piano track. sax # Select the track sax. solo # Mute other tracks nosolo # Unmute other tracks (piano is still muted) all # all tracks play pan: type: track what: | Change or display the current panning position of the current track. Panning is moving the audio in the stereo panorama between right and left. Position is given in percent. 0 is hard left and 100 hard right, 50% is dead centre. short: p parameters: [ ] example: | pan 75 # Pan the track to a position between centre and hard right p 50 # Move the current track to the centre. pan # Show the current position of the track in the stereo panorama. pan_right: type: track what: | Pan the current track hard right. this is a synonym for pan 100. Can be reversed with pan_back. short: pr parameters: none pan_left: type: track what: | Pan the current track hard left. This is a synonym for pan 0. Can be reversed with pan_back. short: pl parameters: none pan_center: type: track what: | Pan the current track to the centre. This is a synonym for pan 50. Can be reversed with pan_back. short: pc parameters: none pan_back: type: track what: | Restore the current track's pan position prior to pan_left, pan_right or pan_center commands. short: pb parameters: none show_tracks: type: track what: | Show a list of tracks, including their index number, volume, pan position, recording status and source. short: lt show parameters: none show_tracks_all: type: track what: Like show_tracks, but includes hidden tracks as well. Useful for debugging. short: sha showa parameters: none show_bus_tracks: type: track what: Show a list of tracks in the current bus. short: ltb showb parameters: none show_track: type: track what: | Display full information about the current track: index, recording status, effects and controllers, inserts, the selected WAV version, and signal width (channel count). short: sh -fart parameters: none show_mode: type: setup what: | Display the current record/playback mode. this will indicate the mode (doodle, preview, etc.) and possible record/playback settings. short: shm parameters: none show_track_latency: type: track what: display the latency information for the current track. short: shl parameters: none show_latency_all: type: diagnostics what: Dump all latency data. short: shla parameters: none set_region: type: track what: | Specify a playback region for the current track using marks. Can be reversed with remove_region. short: srg parameters: example: | sax # Select "sax" as the current track. setpos 2.5 # Move the playhead to 2.5 seconds. mark sax_start # Create a mark sp 120.5 # Move playhead to 120.5 seconds. mark sax_end # Create another mark set_region sax_start sax_end ! Play only the audio from 2.5 to 120.5 seconds. add_region: type: track what: | Make a copy of the current track using the supplied a region definition. The original track is untouched. parameters: | | [ ] example: | sax # Select "sax" as the current track. add_region sax_start 66.7 trimmed_sax ! Create "trimmed_sax", a copy of "sax" with a region defined ! from mark "sax_start" to 66.7 seconds. remove_region: type: track what: | Remove the region definition from the current track. Remove the current track if it is an auxiliary track. short: rrg parameters: none shift_track: type: track what: | Choose an initial delay before playing a track or region. Can be reversed by unshift_track. short: shift playat pat parameters: | example: | piano # Select "piano" as current track. shift 6.7 # Move the start of track to 6.7 seconds. unshift_track: type: track what: Restore the playback start time of a track or region to 0. short: unshift parameters: none modifiers: type: track what: | Add/show modifiers for the current track (man ecasound for details). This provides direct control over Ecasound track modifiers It is not needed for normal work. short: mods mod parameters: [ Audio file sequencing parameters ] example: | modifiers select 5 15.2 ! Apply Ecasound's select modifier to the current track. ! The usual way to accomplish this is with a region definition. nomodifiers: type: track what: Remove modifiers from the current track. short: nomods nomod parameters: none normalize: type: track what: | Apply ecanormalize to the current track version. This will raise the gain/volume of the current track as far as possible without clipping and store it that way on disk. Note: this will permanently change the file. short: ecanormalize parameters: none fixdc: type: track what: | Fix the DC-offset of the current track using ecafixdc. Note: This will permanently change the file. short: ecafixdc parameters: none autofix_tracks: type: track what: Apply ecafixdc and ecanormalize to all current versions of all tracks, set to playback (MON). short: autofix parameters: none remove_track: type: track what: | Remove the current track with its effects, inserts, etc. Audio files are unchanged. parameters: none bus_mon: type: bus what: Set the current bus mix_track to monitor (the default behaviour). short: bmon parameters: none bus_off: type: bus what: | Set current bus mixtrack to OFF. Can be reversed with bus_rec or bus_mon. short: boff parameters: none bus_version: type: group what: Set the default monitoring version for tracks in the current bus. short: bver gver parameters: none add_bunch: type: group what: short: abn parameters: [ | ] ... example: | add_bunch strings violin cello bass ! Create a bunch "strings" with tracks violin, cello and bass. for strings; mute # Mute all tracks in the strings bunch. for strings; vol * 0.8 ! Lower the volume of all tracks in bunch "strings" by a ! a factor of 0.8. list_bunches: type: group what: Display a list of all bunches and their tracks. short: lbn parameters: none remove_bunch: type: group what: | Remove the specified bunches. This does not remove the tracks, only the grouping. short: rbn parameters: [ ] ... add_to_bunch: type: group what: Add track(s) to an existing bunch. short: atbn parameters: [ ] ... example: | add_to_bunch woodwind oboe sax flute commit: type: project what: commit Nama's current state short: ci parameters: tag: type: project what: git tag the current branch HEAD commit parameters: [] branch: type: project what: change to named branch short: br parameters: list_branches: type: project what: list branches short: lb lbr new_branch: type: project what: create a new branch short: nbr parameters: [] save_state: type: project what: Save the project settings as file or git snapshot short: keep save parameters: [ [ ] ] get_state: type: project what: Retrieve project settings from file or snapshot short: get recall retrieve parameters: list_projects: type: project what: List all projects. This will list all Nama projects, which are stored in the Nama project root directory. short: lp parameters: none new_project: type: project what: Create or open a new empty Nama project. short: create parameters: example: | create jam # creates empty project call "jam". # Now you can start adding your tracks, editing them and mixing them. load_project: type: project what: Load an existing project. This will load the project from the default project state file. If you wish to load a project state saved to a user specific file, load the project and then use get_state. short: load parameters: example: load my_old_song # Will load my_old_song just as you left it. project_name: type: project what: Display the name of the current project. short: project name parameters: none new_project_template: type: project what: Make a project template based on the current project. This will include tracks and busses. short: npt parameters: [ ] example: | new_project_template my_band_setup "tracks and busses for bass, drums and me" use_project_template: type: project what: Use a template to create tracks in a newly created, empty project. short: upt apt parameters: example: | apt my_band_setup # Will add all the tracks for your basic band setup. list_project_templates: type: project what: List all project templates. short: lpt parameters: none destroy_project_template: type: project what: Remove one or more project templates. parameters: [ ] ... generate: type: setup what: Generate an Ecasound chain setup for audio processing manually. Mainly useful for diagnostics and debugging. short: gen parameters: none arm: type: setup what: Generate and connect a setup to record or playback. If you are in dodle or preview mode, this will bring you back to normal mode. parameters: none arm_start: type: setup what: Generate and connect the setup and then start. This means, that you can directly record or listen to your tracks. short: arms parameters: none connect: type: setup what: Connect the setup, so everything is ready to run. Ifusing JACK, this means, that Nama will connect to all the necessary JACK ports. short: con parameters: none disconnect: type: setup what: Disconnect the setup. If running with JACK, this will disconnect from all JACK ports. short: dcon parameters: none show_chain_setup: type: setup what: Show the underlying Ecasound chain setup for the current working condition. Mainly useful for diagnostics and debugging. short: chains parameters: none loop: type: setup what: Loop the playback between two points. Can be stopped with loop_disable short: l parameters: | | | | example: | loop 1.5 10.0 # Loop between 1.5 and 10.0 seconds. loop 1 5 # Loop between marks with indeices 1 and 5, see list_marks. loop sax_start 12.6 # Loop between mark sax_start and 12.6 seconds. noloop: type: setup what: Disable looping. short: nl parameters: none add_controller: type: effect what: Add a controller to an effect (current effect, by default). Controllers can be modified by using mfx and removed using rfx. short: acl parameters: [ ] [ ] ... example: | add_effect etd 100 2 2 50 50 # Add a stero delay of 100ms. ! the delay will get the effect ID E . ! Now we want to slowly change the delay to 200ms. acl E klg 1 100 200 2 0 100 15 200 # Change the delay time linearly (klg) # from 100ms at the start (0 seconds) to 200ms at 15 seconds. See # help for -klg in the Ecasound manpage. add_effect: type: effect what: Add an effect short: afx parameters: | [ (before | first | last ) ] [ ... ] "before", "first" and "last" can be abbreviated "b", "f" and "l", respectively. example: | We want to add the decimator effect (a LADSPA plugin). help_effect decimator # Print help about its paramters/controls. ! # We see two input controls: bitrate and samplerate afx decimator 12 22050 # prints "Added GO (Decimator)" ! We have added the decimator with 12bits and a sample rate of 22050Hz. ! GO is the effect ID, which you will need to modify it. add_effect_last: type: effect what: same as add-effect last short: afxl parameters: [ ... ] add_effect_first: type: effect what: same as add-effect first short: afxf parameters: [ ... ] add_effect_before: type: effect what: same as add-effect before short: afxb parameters: [ ... ] modify_effect: type: effect what: Modify effect parameter(s). short: mfx parameters: | [ ] [ + | - | * | / ] fx_alias can be: a position, effect ID, nickname or effect code example: | To change the roomsize of our reverb effect to 62 lfx ! We see that reverb has unique effect ID AF and roomsize is the ! first parameter. mfx AF 1 62 ! mfx AF,BG 1 75 ! Change the first parameter of both AF and BG to 75. ! mfx CE 6,10 -3 ! Change parameters 6 and 10 of effect CE to -3 ! mfx D 4 + 10 ! Increase the fourth parameter of effect D by 10. ! mfx A,B,C 3,6 * 5 ! Adjust parameters 3 and 6 of effect A, B and C by a factor of 5. remove_effect: type: effect what: Remove effects. They don't have to be on the current track. short: rfx parameters: [ ] ... position_effect: type: effect what: Position an effect before another effect (use 'ZZZ' for end). short: pfx parameters: example: | position_effect G F # Move effecit with unique ID G before F. show_effect: type: effect what: Show information about an effect. Default is to print information on the current effect. short: sfx parameters: [ ] [ ] ... example: | sfx # Print name, unique ID and parameters/controls of the current effect. sfx H # Print out all information about effect with unique ID H. dump_effect: type: effect what: Dump all data of current effect object short: dfx list_effects: type: effect what: Print a short list of all effects on the current track, only including unique ID and effect name. short: lfx parameters: none hotkeys: type: general what: | Use this command to set the hotkey mode. (You may also use the hash symbol '#'.) Hit the Escape key to return to command mode. short: hk parameters: none hotkeys_always: type: general what: Activate hotkeys mode after each command. short: hka parameters: none hotkeys_off: type: general what: disable hotkeys always mode short: hko parameters: none hotkeys_list: type: general what: list hotkey bindings short: hkl lhk parameters: none add_insert: type: effect what: Add an external send/return insert to current track. short: ain parameters: | External: ( pre | post ) [ ] Local wet/dry: local example: | add_insert pre jconvolver ! Add a prefader insert. The current track signal is sent ! to jconvolver and returned to the vol/pan controls. add_insert post jconvolver csound ! Send the current track postfader signal (after vol/pan ! controls) to jconvolver, getting the return from csound. guitar # Select the guitar track ain local # Create a local insert guitar-1-wet # Select the wet arm afx G2reverb 50 5.0 0.6 0.5 0 -16 -20 # add a reverb afx etc 6 100 45 2.5 # add a chorus effect on the reverbed signal guitar # Change back to the main guitar track wet 25 # Set the balance between wet/dry track to 25% wet, 75% dry. set_insert_wetness: type: effect what: Set wet/dry balance of the insert for the current track. The balance is given in percent, 0 meaning dry and 100 wet signal only. short: wet parameters: [ pre | post ] example: | wet pre 50 # Set the prefader insert to be balanced 50/50 wet/dry. wet 100 # Simpler if there's only one insert remove_insert: type: effect what: Remove an insert from the current track. short: rin parameters: [ pre | post ] example: | rin # If there is only one insert on the current track, remove it. remove_insert post # Remove the postfader insert from the current track. ctrl_register: type: effect what: List all Ecasound controllers. Controllers include linear controllers and oscillators. short: crg parameters: none preset_register: type: effect what: List all Ecasound effect presets. See the Ecasound manpage for more detail on effect_presets. short: prg parameters: none ladspa_register: type: effect what: List all LADSPA plugins, that Ecasound/Nama can find. short: lrg parameters: none list_marks: type: mark what: List all marks with index, name and their respective positions in time. short: lmk lm parameters: none to_mark: type: mark what: Move the playhead to the named mark or mark index. short: tmk tom parameters: | example: | to_mark sax_start # Jump to the position marked by sax_mark. tmk 2 # Move to the mark with the index 2. add_mark: type: mark what: Drop a new mark at the current playback position. this will fail, if a mark is already placed on that exact position. short: mark amk k parameters: [ ] example: | mark start # Create a mark named "start" at the current position. remove_mark: type: mark what: Remove a mark short: rmk parameters: [ | ] example: | remove_mark start # remove the mark named start rmk 16 # Remove the mark with the index 16. rmk # Remove the current mark next_mark: type: mark what: Move the playhead to the next mark. short: nmk parameters: none previous_mark: type: mark what: Move the playhead to the previous mark. short: pmk parameters: none name_mark: type: mark what: Give a name to the current mark. parameters: modify_mark: type: mark what: Change the position (time) of the current mark. short: move_mark mmk parameters: [ + | - ] example: | move_mark + 2.3 # Move the current mark 2.3 seconds forward from its # current position. mmk 16.8 # Move the current mark to 16.8 seconds, no matter, where it is now. engine_status: type: diagnostics what: Display the Ecasound audio processing engine status. short: egs parameters: none dump_track: type: diagnostics what: Dump current track data. short: dump parameters: none dump_group: type: diagnostics what: Dump group settings for user tracks. short: dumpg parameters: none dump_all: type: diagnostics what: Dump most internal state data. short: dumpa parameters: none dump_io: type: diagnostics what: Show chain inputs and outputs. parameters: none list_history: type: help what: List the command history. Every project stores its own command history. short: lh parameters: none add_submix_cooked: type: bus what: Create a submix using all tracks in bus "Main" short: parameters: example: | add_submix_cooked front_of_house 7 ! send a custom mix named "front_of_house" ! to soundcard channels 7/8 add_submix_raw: type: bus what: Add a submix using tracks in Main bus (unprocessed signals, lower latency) short: asr parameters: example: | asbr Reverb jconv # Add a raw send bus called Reverb, with its output # going to the JACK client jconv . add_bus: type: bus what: Add a sub bus. This is a bus, as known from other DAWs. The default output goes to a mix track and that is routed to the mixer (the Master track). All busses begin with a capital letter! short: abs parameters: [ | | ] example: | abs Brass # Add a bus, "Brass", routed to the Main bus (e.g. mixer) abs special csound # Add a bus, "special" routed to JACK client "csound" update_submix: type: bus what: Include tracks added since the submix was created. short: usm parameters: example: update_submix Reverb # Include new tracks in the Reverb submix remove_bus: type: bus what: Remove a bus or submix parameters: list_buses: type: bus what: List buses and their parameters (TODO). short: lbs parameters: none set_bus: type: bus what: Set bus parameters. This command is intended for advanced users. short: sbs parameters: overwrite_effect_chain: type: effect what: | Create a new effect chain, overwriting an existing one of the same name. short: oec parameters: Same as for new_effect_chain new_effect_chain: type: effect what: | Create an effect chain, a named list of effects with all parameter settings. Useful for storing effect setups for particular instruments. short: nec parameters: [ ... ] example: | new_effect_chain my_piano ! Create a new effect chain, "my_piano", storing all ! effects and their settings from the current track ! except the fader (vol/pan) settings. nec my_guitar A C F G H ! Create a new effect chain, "my_guitar", ! storing the effects with IDs A, C, F, G, H and ! their respective settings. delete_effect_chain: type: effect what: | Delete an effect chain definition. Does not affect the project state. This command is not reversible by undo. short: dec destroy_effect_chain parameters: find_effect_chains: type: effect what: Dump effect chains, matching key/value pairs if provided short: fec parameters: [ ] ... example: | fec # List all effect chains with their effects. find_user_effect_chains: type: effect what: List all *user* created effect chains, matching key/value pairs, if provided. short: fuec parameters: [ ] ... bypass_effects: type: effect what: Bypass effects on the current track. With no parameters default to bypassing the current effect. short: bypass bfx parameters: [ ... | 'all' ] example: | bypass all # Bypass all effects on the current track, except vol and pan. bypass AF # Only bypass the effect with the unique ID AF. bring_back_effects: type: effect what: Restore effects. If no parameter is given, the default is to restore the current effect. short: restore_effects bbfx parameters: [ ... | 'all' ] example: | bbfx # Restore the current effect. restore_effect AF # Restore the effect with the unique ID AF. bring_back_effects all # Restore all effects. new_effect_profile: type: effect what: Create a new effect profile. An effect profile is a named group of effect chains for multiple tracks. Useful for storing a basic template of standard effects for a group of instruments, like a drum kit. short: nep parameters: [ ] example: | add_bunch Drums snare toms kick # Create a buch called Drums. nep Drums my_drum_effects # Create an effect profile, call my_drum_effects # containing all effects from snare toms and kick. apply_effect_profile: type: effect what: Apply an effect profile. this will add all the effects in it to the list of tracks stored in the effect profile. Note: You must give the tracks the same names as in the original project, where you created the effect profile. short: aep parameters: destroy_effect_profile: type: effect what: Delete an effect profile. This will delete the effect profile definition from your disk. All projects, which use this effect profile will NOT be affected. parameters: list_effect_profiles: type: effect what: List all effect profiles. short: lep parameters: none show_effect_profiles: type: effect what: List effect profile. short: sepr parameters: none full_effect_profiles: type: effect what: Dump effect profile data structure. short: fep parameters: none cache_track: type: track what: | Cache the current track. Same as freezing or bouncing. This is useful for larger projects or low-power CPUs, since effects do not have to be recomputed for subsequent engine runs. Cache_track stores the effects-processed output of the current track as a new version (WAV file) which becomes the current version. The current effects, inserts and region definition are removed and stored. To go back to the original track state, use the uncache_track command. The show_track display appends a "c" to version numbers created by cache_track (and therefore reversible by uncache) short: cache ct bounce freeze parameters: [ ] example: | cache 10 # Cache the curent track and append 10 seconds extra time, # to allow a reverb or delay to fade away without being cut. uncache_track: type: effect what: Select the uncached track version. This restores effects, but not inserts. short: uncache unc parameters: none do_script: type: general what: Execute Nama commands from a file in the main project's directory or in the Nama project root directory. A script is a list of Nama commands, just as you would type them on the Nama prompt. short: do parameters: example: | do prepare_my_drums # Execute the script prepare_my_drums. scan: type: general what: Re-read the project's .wav directory. Mainly useful for troubleshooting. parameters: none add_fade: type: effect what: Add a fade-in or fade-out to the current track. short: afd fade parameters: ( in | out ) marks/times (see examples) example: | fade in mark1 # Fade in,starting at mark1 and using the ! # default fade time of 0.5 seconds. fade out mark2 2 # Fade out over 2 seconds, starting at mark2 . fade out 2 mark2 # Fade out over 2 seconds, ending at mark2 . fade in mark1 mark2 # Fade in starting at mark1, ending at mark2 . remove_fade: type: effect what: Remove a fade from the current track. short: rfd parameters: [ ] ... example: | list_fade # Print a list of all fades and their tracks. rfd 2 # Remove the fade with the index (n) 2. list_fade: type: effect what: List all fades. short: lfd parameters: none add_comment: type: track what: Add a comment to the current track (replacing any previous comment). A comment maybe a short discription, notes on instrument settings, etc. short: comment ac parameters: example: ac "Guitar, treble on 50%" remove_comment: type: track what: Remove a comment from the current track. short: rc parameters: none show_comment: type: track what: Show the comment for the current track. short: sc parameters: none show_comments: type: track what: Show all track comments. short: sca parameters: none add_version_comment: type: track what: Add a version comment (replacing any previous user comment). This will add a comment for the current version of the current track. short: avc parameters: example: avc "The good take with the clear 6/8" remove_version_comment: type: track what: Remove version comment(s) from the current track. short: rvc parameters: none show_version_comment: type: track what: Show version comment(s) of the curent track. short: svc parameters: none show_version_comments_all: type: track what: Show all version comments for the current track. short: svca parameters: none set_system_version_comment: type: track what: Set a system version comment. Useful for testing and diagnostics. short: ssvc parameters: midish_command: type: midi what: Send the command text to the midish MIDI sequencer. Midish must be installed and enabled in namarc. See the midish manpage and fullonline documentation for more. short: m parameters: example: m tracknew my_midi_track # create a new MIDI track in midish. midish_mode_on: type: midi what: all users commands sent to midish, until short: mmo midish_mode_off: what: exit midish mode, restore default Nama command mode, no midish sync type: midi short: mmx midish_mode_off_ready_to_play: what: exit midish mode, sync midish start (p) with Ecasound type: midi short: mmxrp midish_mode_off_ready_to_record: what: exit midish mode, sync midish start (r) with Ecasound type: midi short: mmxrr new_edit: type: edit what: Create an edit for the current track and version. short: ned parameters: none set_edit_points: type: edit what: Mark play-start, record-start and record-end positions for the current edit. short: sep parameters: none list_edits: type: edit what: List all edits for current track and version. short: led parameters: none select_edit: type: edit what: Select an edit to modify or delete. After selection it is the current edit. short: sed parameters: end_edit_mode: type: edit what: Switch back to normal playback/record mode. The track will play full length again. Edits are managed via a sub- bus. short: eem parameters: none destroy_edit: type: edit what: Remove an edit and all associated audio files. If no parameter is given, the default is to destroy the current edit. Note: The data will be lost permanently. Use with care! parameters: [ ] preview_edit_in: type: edit what: Play the track region without the edit segment. short: pei parameters: none preview_edit_out: type: edit what: Play the removed edit segment. short: peo parameters: none play_edit: type: edit what: Play a completed edit. short: ped parameters: none record_edit: type: edit what: Record an audio file for the current edit. short: red parameters: none edit_track: type: edit what: set the edit track as the current track. short: et parameters: none host_track_alias: type: edit what: Set the host track alias as the current track. short: hta parameters: none host_track: type: edit what: Set the host track (edit sub-bus mix track) as the current track. short: ht parameters: none version_mix_track: type: edit what: Set the version mix track as the current track. short: vmt parameters: none play_start_mark: type: edit what: Select (and move to) play start mark of the current edit. short: psm parameters: none rec_start_mark: type: edit what: Select (and move to) rec start mark of the current edit. short: rsm parameters: none rec_end_mark: type: edit what: Select (and move to) rec end mark of the current edit. short: rem parameters: none set_play_start_mark: type: edit what: Set play_start_mark to the current playback position. short: spsm parameters: none set_rec_start_mark: type: edit what: Set rec_start_mark to the current playback position. short: srsm parameters: none set_rec_end_mark: type: edit what: Set rec_end_mark to current playback position. short: srem parameters: none disable_edits: type: edit what: Turn off the edits for the current track and playback the original. This will exclude the edit sub bus. short: ded parameters: none merge_edits: type: edit what: Mix edits and original into a new host-track. this will write a new audio file to disk and the host track will have a new version for this. short: med parameters: none explode_track: type: track what: Make the current track into a sub bus, with one track for each version. parameters: none move_to_bus: type: track what: Move the current track to another bus. A new track is always in the Main bus. So to reverse this action use move_to_bus Main . short: mtb parameters: example: | asub Drums # Create a new sub bus, called Drums. snare # Make snare the current track. mtb Drums # Move the snare track into the sub bus Drums. promote_version_to_track: type: track what: Create a read-only track using the specified version of the current track. short: pvt parameters: read_user_customizations: type: general what: Re-read the user customizations file 'custom.pl'. short: ruc parameters: none limit_run_time: type: setup what: Stop recording after the last audio file finishes playing. Can be turned off with limit_run_time_off. short: lr parameters: [ ] limit_run_time_off: type: setup what: Disable the recording stop timer. short: lro parameters: none offset_run: type: setup what: Record/play from a mark, rather than from the start, i.e. 0.0 seconds. short: ofr parameters: offset_run_off: type: setup what: Turn back to starting from 0. short: ofro parameters: none view_waveform: type: general what: Launch mhwavedit to view/edit waveform of the current track and version. This requires to start Nama on a graphical terminal, like xterm or gterm or from GNOME via alt+F2 . short: wview parameters: none edit_waveform: type: general what: Launch audacity to view/edit the waveform of the current track and version. This requires starting Nama on a graphical terminal like xterm or gterm or from GNOME starting Nama using alt+F2 . short: wedit parameters: none rerecord: type: setup what: Record as before. This will set all the tracks to record, which have been recorded just before you listened back. short: rerec parameters: none example: | for piano guitar;rec # Set piano and guitar track to record. ! do your recording and ilstening. ! You want to record another version of both piano and guitar: rerec # Sets piano and guitar to record again. analyze_level: type: track what: Print Ecasound amplitude analysis for current track. This will show highest volume and statistics. short: anl parameters: none for: type: general what: Execute command(s) for several tracks. parameters: [ } ... ; example: | for piano guitar; vol - 3; pan 75 # reduce volume and pan right for snare kick toms cymbals; mtb Drums # move tracks to bus Drums git: type: project what: execute git command in the project directory parameters: [arguments] edit_rec_setup_hook: type: track what: edit the REC hook script for current track short: ersh parameters: none edit_rec_cleanup_hook: type: track what: edit the REC cleanup hook script for current track short: erch parameters: none remove_fader_effect: type: track short: rffx what: remove vol pan or fader on current track parameters: vol | pan | fader rename_track: type: track what: rename a track and its WAV files parameters: new_sequence: type: sequence short: nsq what: define a new sequence parameters: select_sequence: type: sequence short: slsq what: select named sequence as current sequence parameter: list_sequences: type: sequence short: lsq what: list all user sequences show_sequence: type: sequence short: ssq what: display clips making up current sequence parameters: none append_to_sequence: type: sequence short: asq what: append items to sequence parameters: [,...] example: | asq chorus # append chorus track to current sequence asq # append current track to current sequence insert_in_sequence: type: sequence short: isq what: insert items into sequence before index i parameters: [,...] remove_from_sequence: type: sequence short: rsq what: remove items from sequence parameters: [,...] delete_sequence: type: sequence short: dsq what: delete entire sequence parameters: add_spacer: type: sequence short: asp what: add a spacer to the current sequence, in specified position, or appending (if no position is given) parameters: [] convert_to_sequence: type: sequence short: csq what: convert the current track to a sequence parameters: none merge_sequence: type: sequence short: msq what: cache and MON the current sequence mix track, disable the sequence parameters: none snip: type: sequence what: | create a sequence from the current track by removing the region(s) defined by mark pair(s). Not supported if the current track is already a sequence. example: | snip cut1-start cut1-end cut2-start cut2-end This removes cut1 and cut2 regions from the current track by creating a sequence. parameters: [...] compose: type: sequence short: compose_sequence compose_into_sequence what: | compose a new sequence using the region(s) of the named track defined by mark pair(s). If the sequence of that name exists, append the regions to that sequence (compose_into_sequence). parameters: [...] example: | compose speeches conference-audio speaker1-start speaker1-end speaker2-start speaker2-end This creates a "speeches" sequence with two clips for speaker1 and speaker2. undo: type: general what: | roll back last commit (use "git log" to see specific commands) Note: redo is not supported yet redo: type: general what: restore the last undone commit (TODO) show_head_commit: type: general short: show_head last_command last what: | show the last commit, which undo will roll back. A commit may contain multiple commands. The last_* aliases are meaningful when autosave: undo is set. In that case each commit contains only a single command eager: type: mode what: set eager mode parameters: on | off new_engine: type: engine what: Start a named Ecasound engine, or bind to an existing engine short: neg parameters: select_engine: type: engine what: Select an ecasound engine (advanced users only!) short: seg parameters: set_track_engine_group: type: track what: set the current track's engine affiliation short: steg parameters: set_bus_engine_group: type: bus what: set the current bus's engine affiliation short: sbeg parameters: select_submix: type: bus short: ssm what: Set the target for the trim command parameters: trim_submix: type: bus what: control a submix fader short: trim tsm example: | ! reduce vol of current track in in_ear_monitor by 3dB select_submix in_ear_monitor trim vol - 3 nickname_effect: type: effect short: nfx nick what: Add a nickname to the current effect (and create an alias) parameters: example: | add_track guitar afx Plate nick reverb # current effect gets name "reverb1" # "reverb" becomes an alias for "Plate" mfx reverb1 1 0.05 # modify first reverb effect on current track mfx reverb 1 2 # works, because current track has one effect named "reverb" afx reverb # add another Plate effect, gets name "reverb2" rfx reverb # Error, multiple reverb effects are present on this ! # track. Please use a numerical suffix. mfx reverb2 1 3 # modify second reverb effect rfx reverb1 # removes reverb1 ifx reverb2 reverb # insert another reverb effect (reverb3) before reverb2 rfx reverb3 # remove reverb3 rfx reverb # removes reverb2, as it is the sole remain reverb effect delete_nickname_definition: type: effect short: dnd what: delete a nickname definition. Previously named effects keep their names. example: | afx Plate # add Plate effect nick reverb # name it "reverb", and create a nickname for Plate dnd reverb # removes nickname definition afx reverb # error remove_nickname: type: effect what: remove the "name" attribute of the current effect short: rnick example: | afx Plate nick reverb mfx reverb 1 3 rnick mfx reverb 1 3 # Error: effect named "reverb" not found on current track list_nickname_definitions: type: effect what: list defined nicknames short: lnd parameters: none set_effect_name: type: effect what: set a nickname only (don't creating an alias) short: sen parameters: set_effect_surname: type: effect what: set an effect surname short: ses parameters: remove_effect_name: type: effect what: remove current effect name short: ren remove_effect_surname: type: effect what: remove current effect surname short: res select_track: type: track what: | set a particular track as the current, or default track against which track-related commands are executed. parameters: | ... @@ grammar command: _a_test { print "aaa-test" } _a_test: /something_else\b/ | /a-test\b/ meta: midish_cmd midish_cmd: /[a-z]+/ predicate { return unless $Audio::Nama::midi->{keywords}->{$item[1]}; my $line = "$item[1] $item{predicate}"; Audio::Nama::midish_command($line); 1; } meta: bang shellcode stopper { Audio::Nama::logit(__LINE__,'Audio::Nama::Grammar','debug',"Evaluating shell commands!"); my $shellcode = $item{shellcode}; $shellcode =~ s/\$thiswav/$Audio::Nama::this_track->full_path/e; my $olddir = Audio::Nama::getcwd(); my $prefix = "chdir ". Audio::Nama::project_dir().";"; $shellcode = "$prefix $shellcode" if $shellcode =~ /^\s*git /; Audio::Nama::pager( "executing this shell code: $shellcode" ) if $shellcode ne $item{shellcode}; my $output = qx( $shellcode ); chdir $olddir; Audio::Nama::pager($output) if $output; 1; } meta: eval perlcode stopper { Audio::Nama::logit(__LINE__,'Audio::Nama::Grammar','debug',"Evaluating perl code"); Audio::Nama::eval_perl($item{perlcode}); 1 } meta: for bunch_spec ';' namacode stopper { Audio::Nama::logit(__LINE__,'Grammar','debug',"namacode: $item{namacode}"); my @tracks = Audio::Nama::bunch_tracks($item{bunch_spec}); for my $t(@tracks) { Audio::Nama::user_set_current_track($t); $Audio::Nama::text->{parser}->meta($item{namacode}); } 1; } bunch_spec: text meta: nosemi(s /\s*;\s*/) semicolon(?) nosemi: text { $Audio::Nama::text->{parser}->do_part($item{text}) } text: /[^;]+/ semicolon: ';' do_part: command end do_part: track_spec command end do_part: track_spec end predicate: nonsemi end { $item{nonsemi}} predicate: /$/ iam_cmd: ident { $item{ident} if $Audio::Nama::text->{iam}->{$item{ident}} } track_spec: ident { Audio::Nama::user_set_current_track($item{ident}) } bang: '!' eval: 'eval' for: 'for' stopper: ';;' | /$/ shellcode: somecode perlcode: somecode namacode: somecode somecode: /.+?(?=;;|$)/ nonsemi: /[^;]+/ semistop: /;|$/ command: iam_cmd predicate { my $user_input = "$item{iam_cmd} $item{predicate}"; Audio::Nama::logit(__LINE__,'Audio::Nama::Grammar','debug',"Found Ecasound IAM command: $user_input"); my $result = Audio::Nama::eval_iam($user_input); Audio::Nama::pager( $result ); 1 } command: user_command predicate { Audio::Nama::do_user_command(split " ",$item{predicate}); 1; } command: user_alias predicate { $Audio::Nama::text->{parser}->do_part("$item{user_alias} $item{predicate}"); 1 } user_alias: ident { $Audio::Nama::config->{alias}->{command}->{$item{ident}} } user_command: ident { return $item{ident} if $Audio::Nama::text->{user_command}->{$item{ident}} } key: /\w+/ someval: /[\w.+-]+/ sign: '+' | '-' | '*' | '/' parameter_value: '*' | value value: /[+-]?([\d_]+(\.\d*)?|\.\d+)([eE][+-]?\d+)?/ float: /\d+\.\d+/ op_id: /[A-Z]+/ existing_op_id: op_id { my $FX; $FX = Audio::Nama::fxn($item[-1]) and $FX->id } parameter: /\d+/ dd: /\d+/ shellish: /"(.+)"/ { $1 } shellish: /'(.+)'/ { $1 } shellish: anytag | jack_port: shellish effect: /\w[^, ]+/ project_id: ident slash(?) { $item{ident} } slash: '/' anytag: /\S+/ ident: /[-\w]+/ save_target: /[-:\w.]+/ decimal_seconds: /\d+(\.\d+)?/ marktime: /\d+\.\d+/ markname: /[A-Za-z]\w*/ { Audio::Nama::throw("$item[1]: non-existent mark name. Skipping"), return undef unless $Audio::Nama::Mark::by_name{$item[1]}; $item[1]; } path: shellish modifier: 'audioloop' | 'select' | 'reverse' | 'playat' | value end: /[;\s]*$/ help_effect: _help_effect effect { Audio::Nama::help_effect($item{effect}) ; 1} find_effect: _find_effect anytag(s) { Audio::Nama::find_effect(@{$item{"anytag(s)"}}); 1} help: _help anytag { Audio::Nama::help($item{anytag}) ; 1} help: _help { Audio::Nama::pager( $Audio::Nama::help->{screen} ); 1} project_name: _project_name { Audio::Nama::pager( "project name: ", $Audio::Nama::project->{name}); 1} new_project: _new_project project_id { Audio::Nama::t_create_project $item{project_id} ; 1} list_projects: _list_projects { Audio::Nama::list_projects() ; 1} load_project: _load_project project_id { Audio::Nama::t_load_project $item{project_id} ; 1} new_project_template: _new_project_template key text(?) { Audio::Nama::new_project_template($item{key}, $item{text}); 1; } use_project_template: _use_project_template key { Audio::Nama::use_project_template($item{key}); 1; } list_project_templates: _list_project_templates { Audio::Nama::list_project_templates(); 1; } destroy_project_template: _destroy_project_template key(s) { Audio::Nama::remove_project_template(@{$item{'key(s)'}}); 1; } tag: _tag tagname message(?) { Audio::Nama::git_snapshot(); my @args = ('tag', $item{tagname}); push @args, '-m', "@{$item{'message(?)'}}" if @{$item{'message(?)'}}; Audio::Nama::git(@args); 1; } commit: _commit message(?) { Audio::Nama::git_snapshot(@{$item{'message(?)'}}); 1; } branch: _branch branchname { Audio::Nama::throw("$item{branchname}: branch does not exist. Skipping."), return 1 if ! Audio::Nama::git_branch_exists($item{branchname}); if(Audio::Nama::git_checkout($item{branchname})){ Audio::Nama::load_project(name => $Audio::Nama::project->{name}) } else { } 1; } branch: _branch { Audio::Nama::list_branches(); 1} list_branches: _list_branches end { Audio::Nama::list_branches(); 1} new_branch: _new_branch branchname branchfrom(?) { my $name = $item{branchname}; my $from = "@{$item{'branchfrom(?)'}}"; Audio::Nama::throw("$name: branch already exists. Doing nothing."), return 1 if Audio::Nama::git_branch_exists($name); Audio::Nama::git_create_branch($name, $from); } tagname: ident branchname: ident branchfrom: ident message: /.+/ save_state: _save_state save_target message(?) { my $name = $item{save_target}; my $default_msg = "user save - $name"; my $message = "@{$item{'message(?)'}}" || $default_msg; Audio::Nama::pager("save target name: $name\n"); Audio::Nama::pager("commit message: $message\n") if $message; if( ! $Audio::Nama::config->{use_git} or $name =~ /\.json$/ ) { Audio::Nama::pager("saving as file\n"), Audio::Nama::save_state( $name) } else { Audio::Nama::git_snapshot(); my @args = ('tag', $name); push @args, '-m', $message if $message; Audio::Nama::git(@args); Audio::Nama::pager_newline(qq/tagged HEAD commit as "$name"/, qq/type "get $name" to return to this commit./) } 1 } save_state: _save_state { Audio::Nama::git_snapshot('user save'); 1} get_state: _get_state save_target { Audio::Nama::load_project( name => $Audio::Nama::project->{name}, settings => $item{save_target} ); 1} getpos: _getpos { Audio::Nama::pager( Audio::Nama::d1( Audio::Nama::eval_iam q(getpos) )); 1} setpos: _setpos timevalue { Audio::Nama::set_position($item{timevalue}); 1} forward: _forward timevalue { Audio::Nama::forward( $item{timevalue} ); 1} rewind: _rewind timevalue { Audio::Nama::rewind( $item{timevalue} ); 1} timevalue: min_sec | decimal_seconds seconds: samples seconds: /\d+/ samples: /\d+sa/ { my ($samples) = $item[1] =~ /(\d+)/; $return = $samples/$Audio::Nama::config->{sample_rate} } min_sec: /\d+/ ':' /\d+/ { $item[1] * 60 + $item[3] } to_start: _to_start { Audio::Nama::to_start(); 1 } to_end: _to_end { Audio::Nama::to_end(); 1 } add_track: _add_track new_track_name { Audio::Nama::add_track($item{new_track_name}); 1 } add_midi_track: _add_midi_track new_track_name { Audio::Nama::MidiTrack->new(name => $item{new_track_name}, group => 'Midi'); Audio::Nama::pager_newline(qq(creating MIDI track "$item{new_track_name}")); 1 } arg: anytag add_tracks: _add_tracks track_name(s) { map{ Audio::Nama::add_track($_) } @{$item{'track_name(s)'}}; 1} new_track_name: anytag { my $proposed = $item{anytag}; Audio::Nama::throw( qq(Track name "$proposed" needs to start with a letter)), return undef if $proposed !~ /^[A-Za-z]/; Audio::Nama::throw( qq(Track name "$proposed" cannot contain a colon.)), return undef if $proposed =~ /:/; Audio::Nama::throw( qq(A track named "$proposed" already exists.)), return undef if $Audio::Nama::Track::by_name{$proposed}; Audio::Nama::throw( qq(Track name "$proposed" conflicts with Ecasound command keyword.)), return undef if $Audio::Nama::text->{iam}->{$proposed}; Audio::Nama::throw( qq(Track name "$proposed" conflicts with user command.)), return undef if $Audio::Nama::text->{user_command}->{$proposed}; Audio::Nama::throw( qq(Track name "$proposed" conflicts with Nama command or shortcut.)), return undef if $Audio::Nama::text->{commands}->{$proposed} or $Audio::Nama::text->{command_shortcuts}->{$proposed}; ; $proposed } track_name: ident existing_track_name: track_name { my $track_name = $item{track_name}; if ($Audio::Nama::tn{$track_name}){ $track_name; } else { Audio::Nama::throw("$track_name: track does not exist.\n"); undef } } move_to_bus: _move_to_bus existing_bus_name { $Audio::Nama::this_track->set( group => $item{existing_bus_name}); 1 } set_track: _set_track key someval { $Audio::Nama::this_track->set( $item{key}, $item{someval} ); 1} dump_track: _dump_track { Audio::Nama::pager($Audio::Nama::this_track->dump); 1} dump_group: _dump_group { Audio::Nama::pager($Audio::Nama::bn{Main}->dump); 1} dump_all: _dump_all { Audio::Nama::dump_all(); 1} remove_track: _remove_track quiet end { local $Audio::Nama::quiet = 1; Audio::Nama::remove_track_cmd($Audio::Nama::this_track); 1 } remove_track: _remove_track existing_track_name { Audio::Nama::remove_track_cmd($Audio::Nama::tn{$item{existing_track_name}}); 1 } remove_track: _remove_track end { Audio::Nama::remove_track_cmd($Audio::Nama::this_track) ; 1 } quiet: 'quiet' link_track: _link_track existing_project_name track_name new_track_name end { Audio::Nama::add_track_alias_project( $item{new_track_name}, $item{track_name}, $item{existing_project_name} ); 1 } link_track: _link_track target track_name end { Audio::Nama::add_track_alias($item{track_name}, $item{target}); 1 } target: existing_track_name existing_project_name: ident { $item{ident} if -d Audio::Nama::join_path(Audio::Nama::project_root(),$item{ident}) } project: ident set_region: _set_region beginning ending { Audio::Nama::set_region( @item{ qw( beginning ending ) } ); 1; } set_region: _set_region beginning { Audio::Nama::set_region( $item{beginning}, 'END' ); 1; } remove_region: _remove_region { Audio::Nama::remove_region(); 1; } add_region: _add_region beginning ending track_name(?) { my $name = $item{'track_name(?)'}->[0]; Audio::Nama::new_region(@item{qw(beginning ending)}, $name); 1 } shift_track: _shift_track start_position { my $pos = $item{start_position}; if ( $pos =~ /\d+\.\d+/ ){ Audio::Nama::pager($Audio::Nama::this_track->name, ": Shifting start time to $pos seconds"); $Audio::Nama::this_track->set(playat => $pos); 1; } elsif ( $Audio::Nama::Mark::by_name{$pos} ){ my $time = Audio::Nama::Mark::mark_time( $pos ); Audio::Nama::pager($Audio::Nama::this_track->name, qq(: Shifting start time to mark "$pos", $time seconds)); $Audio::Nama::this_track->set(playat => $pos); 1; } else { Audio::Nama::throw( "Shift value is neither decimal nor mark name. Skipping."); 0; } } start_position: float | samples | mark_name mark_name: ident unshift_track: _unshift_track { $Audio::Nama::this_track->set(playat => undef) } beginning: marktime | markname ending: 'END' | marktime | markname generate: _generate { Audio::Nama::generate_setup(); 1} arm: _arm { Audio::Nama::arm(); 1} arm_start: _arm_start { Audio::Nama::arm(); Audio::Nama::start_transport(); 1 } connect: _connect { Audio::Nama::connect_transport(); 1} disconnect: _disconnect { Audio::Nama::disconnect_transport(); 1} engine_status: _engine_status { Audio::Nama::pager(Audio::Nama::eval_iam q(engine-status)); 1} start: _start { Audio::Nama::start_transport(); 1} stop: _stop { Audio::Nama::stop_transport(); 1} ecasound_start: _ecasound_start { Audio::Nama::eval_iam('start'); 1} ecasound_stop: _ecasound_stop { Audio::Nama::eval_iam('stop'); 1} restart_ecasound: _restart_ecasound { Audio::Nama::restart_ecasound(); 1 } show_tracks: _show_tracks { Audio::Nama::pager( Audio::Nama::show_tracks(Audio::Nama::showlist())); 1; } show_tracks_all: _show_tracks_all { my $list = [undef, undef, sort{$a->n <=> $b->n} Audio::Nama::all_tracks()]; Audio::Nama::pager(Audio::Nama::show_tracks($list)); 1; } show_bus_tracks: _show_bus_tracks { my $bus = $Audio::Nama::bn{$Audio::Nama::this_bus}; my $list = $bus->trackslist; Audio::Nama::pager(Audio::Nama::show_tracks($list)); 1; } modifiers: _modifiers modifier(s) { $Audio::Nama::this_track->set(modifiers => (join q(,), @{$item{"modifier(s)"}}, q() )); 1;} modifiers: _modifiers { Audio::Nama::pager( $Audio::Nama::this_track->modifiers); 1} nomodifiers: _nomodifiers { $Audio::Nama::this_track->set(modifiers => ""); 1} show_chain_setup: _show_chain_setup { Audio::Nama::pager(Audio::Nama::ChainSetup::ecasound_chain_setup); 1} dump_io: _dump_io { Audio::Nama::ChainSetup::show_io(); 1} show_track: _show_track { my $output = $Audio::Nama::text->{format_top}; $output .= Audio::Nama::show_tracks_section($Audio::Nama::this_track); $output .= Audio::Nama::show_track_comment($Audio::Nama::this_track); $output .= Audio::Nama::show_region(); $output .= Audio::Nama::show_versions(); $output .= Audio::Nama::show_version_comment($Audio::Nama::this_track, $Audio::Nama::this_track->version); $output .= Audio::Nama::show_send(); $output .= Audio::Nama::show_bus(); $output .= Audio::Nama::show_modifiers(); $output .= join "", "Signal width: ", Audio::Nama::width($Audio::Nama::this_track->width), "\n"; $output .= Audio::Nama::show_inserts(); $output .= Audio::Nama::show_effects(); Audio::Nama::pager( $output ); 1;} show_track: _show_track track_name { Audio::Nama::pager( Audio::Nama::show_tracks( $Audio::Nama::tn{$item{track_name}} )) if $Audio::Nama::tn{$item{track_name}}; 1;} show_track: _show_track dd { Audio::Nama::pager( Audio::Nama::show_tracks( $Audio::Nama::ti{$item{dd}} )) if $Audio::Nama::ti{$item{dd}}; 1;} show_mode: _show_mode { Audio::Nama::pager( Audio::Nama::show_status()); 1} bus_mon: _bus_mon { my $bus = $Audio::Nama::bn{$Audio::Nama::this_bus}; $bus->set(rw => 'MON'); $Audio::Nama::tn{$bus->send_id}->busify if $bus->send_type eq 'track' and $Audio::Nama::tn{$bus->send_id}; Audio::Nama::pager( "Setting MON mode for $Audio::Nama::this_bus bus."); 1; } bus_off: _bus_off { my $bus = $Audio::Nama::bn{$Audio::Nama::this_bus}; $bus->set(rw => Audio::Nama::OFF); if($bus->send_type eq 'track' and my $mix = $Audio::Nama::tn{$bus->send_id}) { $mix->set(rw => Audio::Nama::OFF) } Audio::Nama::pager( "Setting OFF mode for " , $Audio::Nama::this_bus, " bus. Member tracks disabled."); 1 } bus_version: _bus_version dd { my $n = $item{dd}; Audio::Nama::process_command("for $Audio::Nama::this_bus; version $n"); } mixdown: _mixdown { Audio::Nama::mixdown(); 1} mixplay: _mixplay { Audio::Nama::mixplay(); 1} mixoff: _mixoff { Audio::Nama::mixoff(); 1} automix: _automix { Audio::Nama::automix(); 1 } autofix_tracks: _autofix_tracks { Audio::Nama::process_command("for mon; fixdc; normalize"); 1 } master_on: _master_on { Audio::Nama::master_on(); 1 } master_off: _master_off { Audio::Nama::master_off(); 1 } exit: _exit { Audio::Nama::save_state(); Audio::Nama::cleanup_exit(); CORE::exit; } source: _source ('track'|'t') trackname { $Audio::Nama::this_track->set_source($item{trackname}, 'track'); 1 } trackname: existing_track_name source: _source source_id { $Audio::Nama::this_track->set_source($item{source_id}); 1 } source_id: shellish source: _source { my $status = $Audio::Nama::this_track->rec_status; Audio::Nama::pager_newline($Audio::Nama::this_track->name, ": input set to ", $Audio::Nama::this_track->input_object_text, "\n", "however track status is ", $status) if $status ne Audio::Nama::REC and $status ne Audio::Nama::MON; 1; } send: _send ('track'|'t') trackname { $Audio::Nama::this_track->set_send($item{trackname}, 'track'); 1 } send: _send send_id { $Audio::Nama::this_track->set_send($item{send_id}); 1} send: _send { $Audio::Nama::this_track->set_send(); 1} send_id: shellish remove_send: _remove_send { $Audio::Nama::this_track->set(send_type => undef); $Audio::Nama::this_track->set(send_id => undef); 1 } stereo: _stereo { $Audio::Nama::this_track->set(width => 2); Audio::Nama::pager($Audio::Nama::this_track->name, ": setting to stereo\n"); 1; } mono: _mono { $Audio::Nama::this_track->set(width => 1); Audio::Nama::pager($Audio::Nama::this_track->name, ": setting to mono\n"); 1; } off: 'dummy' record: 'dummy' mon: 'dummy' play: 'dummy' command: mono command: rw rw_setting: 'REC ' | 'rec' | 'PLAY' | 'play' | 'MON' | 'mon' | 'OFF' | 'off' { $return = $item[1] } rw: rw_setting { $Audio::Nama::this_track->is_system_track ? $Audio::Nama::this_track->set(rw => uc $item{rw_setting}) : Audio::Nama::rw_set($Audio::Nama::Bus::by_name{$Audio::Nama::this_bus},$Audio::Nama::this_track,$item{rw_setting}); 1 } set_version: _set_version dd { $Audio::Nama::this_track->set_version($item{dd}); 1} vol: _vol value { $Audio::Nama::this_track->vol or Audio::Nama::throw(( $Audio::Nama::this_track->name . ": no volume control available")), return; Audio::Nama::modify_effect( $Audio::Nama::this_track->vol, 1, undef, $item{value}); 1; } vol: _vol sign(?) value { $Audio::Nama::this_track->vol or Audio::Nama::throw( $Audio::Nama::this_track->name . ": no volume control available"), return; Audio::Nama::modify_effect( $Audio::Nama::this_track->vol, 1, $item{'sign(?)'}->[0], $item{value}); 1; } vol: _vol { Audio::Nama::pager( $Audio::Nama::this_track->vol_level); 1} mute: _mute { $Audio::Nama::this_track->mute; 1} unmute: _unmute { $Audio::Nama::this_track->unmute; 1} solo: _solo ident(s) { Audio::Nama::solo(@{$item{'ident(s)'}}); 1 } solo: _solo { Audio::Nama::solo($Audio::Nama::this_track->name); 1} all: _all { Audio::Nama::all() ; 1} nosolo: _nosolo { Audio::Nama::nosolo() ; 1} unity: _unity { Audio::Nama::unity($Audio::Nama::this_track); 1} pan: _pan panval { Audio::Nama::update_effect( $Audio::Nama::this_track->pan, 0, $item{panval}); 1;} pan: _pan sign panval { Audio::Nama::modify_effect( $Audio::Nama::this_track->pan, 1, $item{sign}, $item{panval} ); 1;} panval: float | dd pan: _pan { Audio::Nama::pager( $Audio::Nama::this_track->pan_level); 1} pan_right: _pan_right { Audio::Nama::pan_check($Audio::Nama::this_track, 100 ); 1} pan_left: _pan_left { Audio::Nama::pan_check($Audio::Nama::this_track, 0 ); 1} pan_center: _pan_center { Audio::Nama::pan_check($Audio::Nama::this_track, 50 ); 1} pan_back: _pan_back { Audio::Nama::pan_back($Audio::Nama::this_track); 1;} remove_mark: _remove_mark dd { my @marks = Audio::Nama::Mark::all(); $marks[$item{dd}]->remove if defined $marks[$item{dd}]; 1;} remove_mark: _remove_mark ident { my $mark = $Audio::Nama::Mark::by_name{$item{ident}}; $mark->remove if defined $mark; 1;} remove_mark: _remove_mark { return unless (ref $Audio::Nama::this_mark) =~ /Mark/; $Audio::Nama::this_mark->remove; 1;} add_mark: _add_mark ident { Audio::Nama::drop_mark $item{ident}; 1} add_mark: _add_mark { Audio::Nama::drop_mark(); 1} next_mark: _next_mark { Audio::Nama::next_mark(); 1} previous_mark: _previous_mark { Audio::Nama::previous_mark(); 1} loop: _loop someval(s) { my @new_endpoints = @{ $item{"someval(s)"}}; $Audio::Nama::mode->{loop_enable} = 1; @{$Audio::Nama::setup->{loop_endpoints}} = (@new_endpoints, @{$Audio::Nama::setup->{loop_endpoints}}); @{$Audio::Nama::setup->{loop_endpoints}} = @{$Audio::Nama::setup->{loop_endpoints}}[0,1]; 1;} noloop: _noloop { $Audio::Nama::mode->{loop_enable} = 0; 1} name_mark: _name_mark ident {$Audio::Nama::this_mark->set_name( $item{ident}); 1} list_marks: _list_marks { my $i = 0; my @lines = map{ ( $_->{time} == $Audio::Nama::this_mark->{time} ? q(*) : q() ,join " ", $i++, sprintf("%.1f", $_->{time}), $_->name, "\n") } @Audio::Nama::Mark::all; my $start = my $end = "undefined"; push @lines, "now at ". sprintf("%.1f", Audio::Nama::eval_iam "getpos"). "\n"; Audio::Nama::pager(@lines); 1;} to_mark: _to_mark dd { my @marks = Audio::Nama::Mark::all(); $marks[$item{dd}]->jump_here; 1;} to_mark: _to_mark ident { my $mark = $Audio::Nama::Mark::by_name{$item{ident}}; $mark->jump_here if defined $mark; 1;} modify_mark: _modify_mark sign value { my $newtime = eval($Audio::Nama::this_mark->{time} . $item{sign} . $item{value}); $Audio::Nama::this_mark->set( time => $newtime ); Audio::Nama::pager($Audio::Nama::this_mark->name, ": set to ", Audio::Nama::d2( $newtime), "\n"); Audio::Nama::pager("adjusted to ",$Audio::Nama::this_mark->time, "\n") if $Audio::Nama::this_mark->time != $newtime; Audio::Nama::set_position($Audio::Nama::this_mark->time); Audio::Nama::request_setup(); 1; } modify_mark: _modify_mark value { $Audio::Nama::this_mark->set( time => $item{value} ); my $newtime = $item{value}; Audio::Nama::pager($Audio::Nama::this_mark->name, ": set to ", Audio::Nama::d2($newtime),"\n"); Audio::Nama::pager("adjusted to ",$Audio::Nama::this_mark->time, "\n") if $Audio::Nama::this_mark->time != $newtime; Audio::Nama::set_position($Audio::Nama::this_mark->time); Audio::Nama::request_setup(); 1; } remove_effect: _remove_effect remove_target(s) { Audio::Nama::mute(); map{ my $id = $_; my ($use) = grep{ $id eq $Audio::Nama::this_track->$_ } qw(vol pan fader); if($use){ Audio::Nama::throw("Effect $id is used as $use by track",$Audio::Nama::this_track->name, ".\nSee 'remove_fader_effect to remove it'\n") } else { my $FX = Audio::Nama::fxn($id); Audio::Nama::pager_newline("removing effect ".$FX->nameline); $FX->_remove_effect(); } } grep { $_ } map{ split ' ', $_} @{ $item{"remove_target(s)"}} ; Audio::Nama::sleeper(0.5); Audio::Nama::unmute(); 1;} add_controller: _add_controller parent effect value(s?) { my $code = $item{effect}; my $parent = $item{parent}; my $parent_o = Audio::Nama::fxn($parent); print "parent: ", $parent_o, " chain: ", $parent_o->chain; my $values = $item{"value(s?)"}; my $id = Audio::Nama::add_effect({ parent => $parent, chain => $parent_o->chain, type => $code, params => $values, }); if($id) { my $iname = Audio::Nama::fxn($id)->fxname; my $pname = Audio::Nama::fxn($parent)->fxname; Audio::Nama::pager("\nAdded $id, $iname to $parent, $pname\n\n"); } 1; } add_controller: _add_controller effect value(s?) { Audio::Nama::throw("current effect is undefined, skipping\n"), return 1 if ! Audio::Nama::this_op(); my $code = $item{effect}; my $parent = Audio::Nama::this_op(); my $values = $item{"value(s?)"}; my $cmd = "add_controller $parent $code @$values"; print "command: $cmd\n"; Audio::Nama::process_command($cmd); 1 } existing_effect_chain: ident { $item{ident} if Audio::Nama::is_effect_chain($item{ident}) } add_target: fx_nick | existing_effect_chain | known_effect_type nickname_effect: _nickname_effect ident { my $ident = $item{ident}; Audio::Nama::this_op_o()->set_name($ident); Audio::Nama::throw("$ident: no such nickname. Skipping."), return unless defined Audio::Nama::this_op_o(); my $type = Audio::Nama::this_op_o()->type; my $fxname = Audio::Nama::this_op_o()->fxname; $Audio::Nama::fx->{alias}->{$ident} = $type; Audio::Nama::pager_newline("$ident: nickname created for $type ($fxname)"); 1 } remove_nickname: _remove_nickname { Audio::Nama::this_op_o()->remove_name() } delete_nickname_definition: _delete_nickname_definition ident { my $was = delete $Audio::Nama::fx->{alias}->{$item{ident}}; $was or Audio::Nama::throw("$item{ident}: no such nickname"), return 0; Audio::Nama::pager_newline("$item{ident}: effect nickname deleted"); } list_nickname_definitions: _list_nickname_definitions { my @lines; while( my($nick,$code) = each %{ $Audio::Nama::fx->{alias} } ) { push @lines, join " ", "$nick:", $Audio::Nama::fx_cache->{registry}->[Audio::Nama::effect_index($code)]->{name}, "($code)\n"; } Audio::Nama::pager(@lines); 1 } known_effect_type: effect { Audio::Nama::full_effect_code($item{effect}) } before: fx_alias fx_name: ident { $Audio::Nama::this_track->effect_id_by_name($item{ident}) } fx_surname: ident { $Audio::Nama::this_track->with_surname($item{ident}) } add_effect: _add_effect add_target parameter_value(s?) before(?) { my ($code, $effect_chain); my $values = $item{'parameter_value(s?)'}; my $args = { track => $Audio::Nama::this_track, params => $values }; if( my $fxc = Audio::Nama::is_effect_chain($item{add_target}) ) { $args->{effect_chain} = $fxc } else{ $args->{type} = $item{add_target} } my $fader = Audio::Nama::fxn($Audio::Nama::this_track->pan) && $Audio::Nama::this_track->pan || Audio::Nama::fxn($Audio::Nama::this_track->vol) && $Audio::Nama::this_track->vol; { no warnings 'uninitialized'; Audio::Nama::logpkg(__FILE__,__LINE__,'debug',$Audio::Nama::this_track->name,": effect insert point is $fader", Audio::Nama::Dumper($args)); } my $predecessor = $item{'before(?)'}->[0] || $fader; $args->{before} = $predecessor if $predecessor; my $added = Audio::Nama::_add_effect($args); for my $FX(@$added) { my $iname = $FX->fxname; my $id = $FX->id; Audio::Nama::pager_newline("Added $id, $iname"); Audio::Nama::set_current_op($id); } } add_effect: _add_effect ('first' | 'f') add_target value(s?) { my $command = join " ", qw(add_effect), $item{add_target}, @{$item{'value(s?)'}}, $Audio::Nama::this_track->{ops}->[0]; Audio::Nama::process_command($command) } add_effect: _add_effect ('last' | 'l') add_target value(s?) { my $command = join " ", qw(add_effect), $item{add_target}, @{$item{'value(s?)'}}, qw(ZZZ); Audio::Nama::process_command($command) } add_effect: _add_effect ('before' | 'b') before add_target value(s?) { my $command = join " ", qw(add_effect), $item{add_target}, @{$item{'value(s?)'}}, $item{before}; Audio::Nama::process_command($command) } add_effect_first: _add_effect_first add_target value(s?) { my $command = join " ", qw(add_effect), "last", $item{add_target}, @{$item{'value(s?)'}}; Audio::Nama::process_command($command) } add_effect_last: _add_effect_last add_target value(s?) { my $command = join " ", qw(add_effect), "last", $item{add_target}, @{$item{'value(s?)'}}; Audio::Nama::process_command($command) } add_effect_before: _add_effect_before before add_target value(s?) { my $command = join " ", qw(add_effect), "before", $item{before}, $item{add_target}, @{$item{'value(s?)'}}; Audio::Nama::process_command($command) } parent: op_id modify_effect: _modify_effect fx_alias(s /,/) parameter(s /,/) value { Audio::Nama::modify_multiple_effects( @item{qw(fx_alias(s) parameter(s) sign value)}); Audio::Nama::pager(Audio::Nama::show_effect(@{ $item{'fx_alias(s)'} })) } modify_effect: _modify_effect fx_alias(s /,/) parameter(s /,/) sign value { Audio::Nama::modify_multiple_effects( @item{qw(fx_alias(s) parameter(s) sign value)}); Audio::Nama::pager(Audio::Nama::show_effect(@{ $item{'fx_alias(s)'} })); } modify_effect: _modify_effect parameter(s /,/) value { Audio::Nama::throw("current effect is undefined, skipping"), return 1 if ! Audio::Nama::this_op(); Audio::Nama::modify_multiple_effects( [Audio::Nama::this_op()], $item{'parameter(s)'}, undef, $item{value}); Audio::Nama::pager( Audio::Nama::show_effect(Audio::Nama::this_op(), "with track affiliation")) } modify_effect: _modify_effect parameter(s /,/) sign value { Audio::Nama::throw("current effect is undefined, skipping"), return 1 if ! Audio::Nama::this_op(); Audio::Nama::modify_multiple_effects( [Audio::Nama::this_op()], @item{qw(parameter(s) sign value)}); Audio::Nama::pager( Audio::Nama::show_effect(Audio::Nama::this_op())); } fx_alias3: ident { join " ", map{ $_->id } grep { $_->surname eq $item{ident} } $Audio::Nama::this_track->fancy_ops_o; } remove_target: existing_op_id | fx_pos | fx_surname | fx_name { $item[-1] or print("no effect object found\n"), return 0} fx_alias: fx_alias2 | fx_alias1 fx_nick: ident { $Audio::Nama::fx->{alias}->{$item{ident}} } fx_alias1: op_id fx_alias1: fx_pos fx_alias1: fx_name fx_alias2: fx_type fx_pos: dd { $Audio::Nama::this_track->{ops}->[$item{dd} - 1] } fx_type: effect { my $FX = $Audio::Nama::this_track->first_effect_of_type($item{effect}); $FX ? $FX->id : undef } position_effect: _position_effect op_to_move new_following_op { my $op = $item{op_to_move}; my $pos = $item{new_following_op}; my $FX = Audio::Nama::fxn($op); $FX->position_effect($pos); Audio::Nama::set_current_op($op); 1; } op_to_move: op_id new_following_op: op_id show_effect: _show_effect fx_alias(s) { my @fx = @{ $item{'fx_alias(s)'}}; @fx = Audio::Nama::Effect::expanded_ops_list(@fx); my @lines = map{ Audio::Nama::show_effect($_, "with track affiliation") } grep{ Audio::Nama::fxn($_) } @fx; Audio::Nama::set_current_op($item{'fx_alias(s)'}->[-1]); Audio::Nama::pager(@lines); 1 } show_effect: _show_effect { Audio::Nama::throw("current effect is undefined, skipping"), return 1 if ! Audio::Nama::this_op(); Audio::Nama::pager( Audio::Nama::show_effect(Audio::Nama::this_op(), "with track affiliation")); 1; } dump_effect: _dump_effect fx_alias { Audio::Nama::pager( Audio::Nama::json_out(Audio::Nama::fxn($item{fx_alias})->as_hash) ); 1} dump_effect: _dump_effect { Audio::Nama::pager( Audio::Nama::json_out(Audio::Nama::this_op_o()->as_hash) ); 1} list_effects: _list_effects { Audio::Nama::pager(Audio::Nama::list_effects()); 1} add_bunch: _add_bunch ident(s) { Audio::Nama::bunch( @{$item{'ident(s)'}}); 1} list_bunches: _list_bunches { Audio::Nama::bunch(); 1} remove_bunch: _remove_bunch ident(s) { map{ delete $Audio::Nama::project->{bunch}->{$_} } @{$item{'ident(s)'}}; 1} add_to_bunch: _add_to_bunch ident(s) { Audio::Nama::add_to_bunch( @{$item{'ident(s)'}});1 } list_versions: _list_versions { Audio::Nama::pager( join " ", @{$Audio::Nama::this_track->versions}); 1} ladspa_register: _ladspa_register { Audio::Nama::pager( Audio::Nama::eval_iam("ladspa-register")); 1} preset_register: _preset_register { Audio::Nama::pager( Audio::Nama::eval_iam("preset-register")); 1} ctrl_register: _ctrl_register { Audio::Nama::pager( Audio::Nama::eval_iam("ctrl-register")); 1} preview: _preview { Audio::Nama::set_preview_mode(); 1} doodle: _doodle { Audio::Nama::set_doodle_mode(); 1 } normalize: _normalize { $Audio::Nama::this_track->normalize; 1} fixdc: _fixdc { $Audio::Nama::this_track->fixdc; 1} destroy_current_wav: _destroy_current_wav { Audio::Nama::destroy_current_wav(); 1 } memoize: _memoize { package Audio::Nama::Wav; $Audio::Nama::config->{memoize} = 1; memoize('candidates'); 1 } unmemoize: _unmemoize { package Audio::Nama::Wav; $Audio::Nama::config->{memoize} = 0; unmemoize('candidates'); 1 } import_audio: _import_audio path frequency { Audio::Nama::import_audio($Audio::Nama::this_track, $item{path}, $item{frequency}); 1; } import_audio: _import_audio path { Audio::Nama::import_audio($Audio::Nama::this_track, $item{path}); 1; } frequency: value list_history: _list_history { my @history = $Audio::Nama::text->{term}->GetHistory; my %seen; Audio::Nama::pager( grep{ ! $seen{$_} and $seen{$_}++ } @history ); } add_submix_cooked: _add_submix_cooked bus_name destination { Audio::Nama::add_submix( $item{bus_name}, $item{destination}, 'cooked' ); 1; } add_submix_raw: _add_submix_raw bus_name destination { Audio::Nama::add_submix( $item{bus_name}, $item{destination}, 'raw' ); 1; } add_bus: _add_bus bus_name { Audio::Nama::add_bus( $item{bus_name}); 1 } existing_bus_name: bus_name { if ( $Audio::Nama::bn{$item{bus_name}} ){ $item{bus_name} } else { Audio::Nama::throw("$item{bus_name}: no such bus"); undef } } bus_name: ident user_bus_name: ident { if($item[1] =~ /^[A-Z]/){ $item[1] } else { Audio::Nama::throw("Bus name must begin with capital letter."); undef} } destination: jack_port remove_bus: _remove_bus existing_bus_name { $Audio::Nama::bn{$item{existing_bus_name}}->remove; 1; } update_submix: _update_submix existing_bus_name { Audio::Nama::update_submix( $item{existing_bus_name} ); 1; } set_bus: _set_bus key someval { $Audio::Nama::bn{$Audio::Nama::this_bus}->set($item{key} => $item{someval}); 1 } list_buses: _list_buses { Audio::Nama::pager(map{ $_->dump } Audio::Nama::Bus::all()) ; 1} add_insert: _add_insert 'local' { Audio::Nama::Insert::add_insert( $Audio::Nama::this_track,'postfader_insert'); 1; } add_insert: _add_insert prepost send_id return_id(?) { my $return_id = $item{'return_id(?)'}->[0]; my $send_id = $item{send_id}; Audio::Nama::Insert::add_insert($Audio::Nama::this_track, "$item{prepost}fader_insert",$send_id, $return_id); 1; } prepost: 'pre' | 'post' send_id: jack_port return_id: jack_port set_insert_wetness: _set_insert_wetness prepost(?) parameter { my $prepost = $item{'prepost(?)'}->[0]; my $p = $item{parameter}; my $id = Audio::Nama::Insert::get_id($Audio::Nama::this_track,$prepost); Audio::Nama::throw($Audio::Nama::this_track->name. ": Missing or ambiguous insert. Skipping"), return 1 unless $id; Audio::Nama::throw("wetness parameter must be an integer between 0 and 100"), return 1 unless ($p <= 100 and $p >= 0); my $i = $Audio::Nama::Insert::by_index{$id}; Audio::Nama::throw("track '",$Audio::Nama::this_track->n, "' has no insert. Skipping."), return 1 unless $i; $i->set_wetness($p); 1; } set_insert_wetness: _set_insert_wetness prepost(?) { my $prepost = $item{'prepost(?)'}->[0]; my $id = Audio::Nama::Insert::get_id($Audio::Nama::this_track,$prepost); $id or Audio::Nama::throw($Audio::Nama::this_track->name. ": Missing or ambiguous insert. Skipping"), return 1 ; my $i = $Audio::Nama::Insert::by_index{$id}; Audio::Nama::pager( "The insert is ", $i->wetness, "% wet, ", (100 - $i->wetness), "% dry."); } remove_insert: _remove_insert prepost(?) { my $prepost = $item{'prepost(?)'}->[0]; my $id = Audio::Nama::Insert::get_id($Audio::Nama::this_track,$prepost); $id or Audio::Nama::throw($Audio::Nama::this_track->name. ": Missing or ambiguous insert. Skipping"), return 1 ; Audio::Nama::pager( $Audio::Nama::this_track->name.": removing ". $prepost ? "$prepost fader insert" : "insert"); $Audio::Nama::Insert::by_index{$id}->remove; 1; } cache_track: _cache_track additional_time(?) { my $time = $item{'additional_time(?)'}->[0]; Audio::Nama::cache_track($Audio::Nama::this_track, $time); 1 } additional_time: float | dd uncache_track: _uncache_track { Audio::Nama::uncache_track($Audio::Nama::this_track); 1 } overwrite_effect_chain: 'dummy' new_effect_chain: (_new_effect_chain | _overwrite_effect_chain ) ident op_id(s?) end { my $name = $item{ident}; my @existing = Audio::Nama::EffectChain::find(user => 1, name => $name); if ( scalar @existing ){ $item[1] eq 'overwrite_effect_chain' ? Audio::Nama::process_command("delete_effect_chain $name") : Audio::Nama::throw(qq/$name: effect chain with this name is already defined. Use a different name, or use "overwrite_effect_chain"/) && return; } my $ops = scalar @{$item{'op_id(s?)'}} ? $item{'op_id(s?)'} : [ $Audio::Nama::this_track->fancy_ops ]; my @options; Audio::Nama::EffectChain->new( user => 1, global => 1, name => $item{ident}, ops_list => $ops, inserts_data => $Audio::Nama::this_track->inserts, @options, ); 1; } delete_effect_chain: _delete_effect_chain ident(s) { map { map{$_->destroy()} Audio::Nama::EffectChain::find( user => 1, name => $_); } @{ $item{'ident(s)'} }; 1; } find_effect_chains: _find_effect_chains ident(s?) { my @args; push @args, @{ $item{'ident(s?)'} } if $item{'ident(s?)'}; Audio::Nama::pager(map{$_->dump} Audio::Nama::EffectChain::find(@args)); } find_user_effect_chains: _find_user_effect_chains ident(s?) { my @args = ('user' , 1); push @args, @{ $item{'ident(s)'} } if $item{'ident(s)'}; (scalar @args) % 2 == 0 or Audio::Nama::throw("odd number of arguments\n@args\n"), return 0; Audio::Nama::pager( map{ $_->summary} Audio::Nama::EffectChain::find(@args) ); 1; } bypass_effects: _bypass_effects op_id(s) { my $arr_ref = $item{'op_id(s)'}; return unless (ref $arr_ref) =~ /ARRAY/ and scalar @{$arr_ref}; my @illegal = grep { ! Audio::Nama::fxn($_) } @$arr_ref; Audio::Nama::throw("@illegal: non-existing effect(s), skipping."), return 0 if @illegal; Audio::Nama::pager( "track ",$Audio::Nama::this_track->name,", bypassing effects:"); Audio::Nama::pager( Audio::Nama::named_effects_list(@$arr_ref)); Audio::Nama::bypass_effects($Audio::Nama::this_track,@$arr_ref); Audio::Nama::set_current_op($arr_ref->[0]) if scalar @$arr_ref == 1; } bypass_effects: _bypass_effects 'all' { Audio::Nama::pager( "track ",$Audio::Nama::this_track->name,", bypassing all effects (except vol/pan)"); Audio::Nama::bypass_effects($Audio::Nama::this_track, $Audio::Nama::this_track->fancy_ops) if $Audio::Nama::this_track->fancy_ops; 1; } bypass_effects: _bypass_effects { Audio::Nama::throw("current effect is undefined, skipping"), return 1 if ! Audio::Nama::this_op(); Audio::Nama::pager( "track ",$Audio::Nama::this_track->name,", bypassing effects:"); Audio::Nama::pager( Audio::Nama::named_effects_list(Audio::Nama::this_op())); Audio::Nama::bypass_effects($Audio::Nama::this_track, Audio::Nama::this_op()); 1; } bring_back_effects: _bring_back_effects end { Audio::Nama::pager("current effect is undefined, skipping"), return 1 if ! Audio::Nama::this_op(); Audio::Nama::pager( "restoring effects:"); Audio::Nama::pager( Audio::Nama::named_effects_list(Audio::Nama::this_op())); Audio::Nama::restore_effects( $Audio::Nama::this_track, Audio::Nama::this_op()); } bring_back_effects: _bring_back_effects op_id(s) { my $arr_ref = $item{'op_id(s)'}; return unless (ref $arr_ref) =~ /ARRAY/ and scalar @{$arr_ref}; my @illegal = grep { ! Audio::Nama::fxn($_) } @$arr_ref; Audio::Nama::throw("@illegal: non-existing effect(s), aborting."), return 0 if @illegal; Audio::Nama::pager( "restoring effects:"); Audio::Nama::pager( Audio::Nama::named_effects_list(@$arr_ref)); Audio::Nama::restore_effects($Audio::Nama::this_track,@$arr_ref); Audio::Nama::set_current_op($arr_ref->[0]) if scalar @$arr_ref == 1; } bring_back_effects: _bring_back_effects 'all' { Audio::Nama::pager( "restoring all effects"); Audio::Nama::restore_effects( $Audio::Nama::this_track, $Audio::Nama::this_track->fancy_ops); } fxc_val: shellish this_track_op_id: op_id(s) { my %ops = map{ $_ => 1 } @{$Audio::Nama::this_track->ops}; my @ids = @{$item{'op_id(s)'}}; my @belonging = grep { $ops{$_} } @ids; my @alien = grep { ! $ops{$_} } @ids; @alien and Audio::Nama::pager("@alien: don't belong to track ",$Audio::Nama::this_track->name, "skipping."); @belonging } bunch_name: ident { Audio::Nama::is_bunch($item{ident}) or Audio::Nama::bunch_tracks($item{ident}) or Audio::Nama::throw("$item{ident}: no such bunch name."), return; $item{ident}; } effect_profile_name: ident existing_effect_profile_name: ident { Audio::Nama::pager("$item{ident}: no such effect profile"), return unless Audio::Nama::EffectChain::find(profile => $item{ident}); $item{ident} } new_effect_profile: _new_effect_profile bunch_name effect_profile_name { Audio::Nama::new_effect_profile($item{bunch_name}, $item{effect_profile_name}); 1 } destroy_effect_profile: _destroy_effect_profile existing_effect_profile_name { Audio::Nama::delete_effect_profile($item{existing_effect_profile_name}); 1 } apply_effect_profile: _apply_effect_profile existing_effect_profile_name { Audio::Nama::apply_effect_profile($item{effect_profile_name}); 1 } list_effect_profiles: _list_effect_profiles { my %profiles; map{ $profiles{$_->profile}++ } Audio::Nama::EffectChain::find(profile => 1); my @output = keys %profiles; if( @output ) { Audio::Nama::pager( join " ","Effect Profiles available:", @output) } else { Audio::Nama::throw("no match") } 1; } show_effect_profiles: _show_effect_profiles ident(?) { my $name; $name = $item{'ident(?)'}->[-1] if $item{'ident(?)'}; $name ||= 1; my %profiles; map{ $profiles{$_->profile}++ } Audio::Nama::EffectChain::find(profile => $name); my @names = keys %profiles; my @output; for $name (@names) { push @output, "\nprofile name: $name\n"; map { push @output, $_->summary } Audio::Nama::EffectChain::find(profile => $name) } if( @output ) { Audio::Nama::pager( @output); } else { Audio::Nama::throw("no match") } 1; } full_effect_profiles: _full_effect_profiles ident(?) { my $name; $name = $item{'ident(?)'}->[-1] if $item{'ident(?)'}; $name ||= 1; my @output = map{ $_->dump } Audio::Nama::EffectChain::find(profile => $name ) ; if( @output ) { Audio::Nama::pager( @output); } else { Audio::Nama::throw("no match") } 1; } do_script: _do_script shellish { Audio::Nama::do_script($item{shellish});1} scan: _scan { Audio::Nama::pager( "scanning ", Audio::Nama::this_wav_dir()); Audio::Nama::restart_wav_memoize() } add_fade: _add_fade in_or_out mark1 duration(?) { Audio::Nama::Fade->new( type => $item{in_or_out}, mark1 => $item{mark1}, duration => $item{'duration(?)'}->[0] || $Audio::Nama::config->{engine_fade_default_length}, relation => 'fade_from_mark', track => $Audio::Nama::this_track->name, ); Audio::Nama::request_setup(); } add_fade: _add_fade in_or_out duration(?) mark1 { Audio::Nama::Fade->new( type => $item{in_or_out}, mark1 => $item{mark1}, duration => $item{'duration(?)'}->[0] || $Audio::Nama::config->{engine_fade_default_length}, track => $Audio::Nama::this_track->name, relation => 'fade_to_mark', ); Audio::Nama::request_setup(); } add_fade: _add_fade in_or_out mark1 mark2 { Audio::Nama::Fade->new( type => $item{in_or_out}, mark1 => $item{mark1}, mark2 => $item{mark2}, track => $Audio::Nama::this_track->name, ); Audio::Nama::request_setup(); } add_fade: _add_fade in_or_out time1 time2 { my $mark1 = Audio::Nama::Mark->new( name => join('_',$Audio::Nama::this_track->name, 'fade', Audio::Nama::Mark::next_id()), time => $item{time1} ); my $mark2 = Audio::Nama::Mark->new( name => join('_',$Audio::Nama::this_track->name, 'fade', Audio::Nama::Mark::next_id()), time => $item{time2} ); Audio::Nama::Fade->new( type => $item{in_or_out}, mark1 => $mark1->name, mark2 => $mark2->name, track => $Audio::Nama::this_track->name, ); Audio::Nama::request_setup(); } time1: value time2: value in_or_out: 'in' | 'out' duration: value mark1: markname mark2: markname remove_fade: _remove_fade fade_index(s) { my @i = @{ $item{'fade_index(s)'} }; Audio::Nama::remove_fade($_) for (@i); Audio::Nama::request_setup(); 1 } fade_index: dd list_fade: _list_fade { Audio::Nama::pager(join "\n", map{ s/^---//; s/...\s$//; $_} map{$_->dump} sort{$a->n <=> $b->n} values %Audio::Nama::Fade::by_index) } add_comment: _add_comment text { Audio::Nama::pager( $Audio::Nama::this_track->name, ": comment: $item{text}"); $Audio::Nama::project->{track_comments}->{$Audio::Nama::this_track->name} = $item{text}; 1; } remove_comment: _remove_comment { Audio::Nama::pager( $Audio::Nama::this_track->name, ": comment removed"); delete $Audio::Nama::project->{track_comments}->{$Audio::Nama::this_track->name}; 1; } show_comment: _show_comment { map{ Audio::Nama::pager( "(",$_->group,") ", $_->name, ": ", $_->comment) } $Audio::Nama::this_track; 1; } show_comments: _show_comments { map{ Audio::Nama::pager( "(",$_->group,") ", $_->name, ": ", $_->comment) } Audio::Nama::all_tracks(); 1; } add_version_comment: _add_version_comment dd(?) text { my $t = $Audio::Nama::this_track; my $v = $item{'dd(?)'}->[0] // $t->monitor_version // return 1; Audio::Nama::pager( $t->add_version_comment($v,$item{text})); } remove_version_comment: _remove_version_comment dd { my $t = $Audio::Nama::this_track; Audio::Nama::pager( $t->remove_version_comment($item{dd})); 1 } show_version_comment: _show_version_comment dd(s?) { my $t = $Audio::Nama::this_track; my @v = @{$item{'dd(s?)'}}; if(!@v){ @v = $t->monitor_version} @v or return 1; $t->show_version_comments(@v); 1; } show_version_comments_all: _show_version_comments_all { my $t = $Audio::Nama::this_track; my @v = @{$t->versions}; $t->show_version_comments(@v); 1; } set_system_version_comment: _set_system_version_comment dd text { Audio::Nama::pager( Audio::Nama::set_system_version_comment($Audio::Nama::this_track,@item{qw(dd text)}));1; } midish_command: _midish_command text { Audio::Nama::midish_command( $item{text} ); 1 } midish_mode_on: _midish_mode_on { Audio::Nama::pager("Setting midish terminal mode!! Return with 'midish_mode_off'."); $Audio::Nama::mode->{midish_terminal}++; } midish_mode_off: _midish_mode_off { Audio::Nama::pager("Releasing midish terminal mode. Sync is not enabled."); undef $Audio::Nama::mode->{midish_terminal}; undef $Audio::Nama::mode->{midish_transport_sync}; 1; } midish_mode_off_ready_to_play: _midish_mode_off_ready_to_play { Audio::Nama::pager("Releasing midish terminal mode. Will sync playback with Ecasound."); undef $Audio::Nama::mode->{midish_terminal} ; $Audio::Nama::mode->{midish_transport_sync} = 'play'; 1; } midish_mode_off_ready_to_record: _midish_mode_off_ready_to_record { Audio::Nama::pager("Releasing midish terminal mode. Will sync record with Ecasound."); undef $Audio::Nama::mode->{midish_terminal} ; $Audio::Nama::mode->{midish_transport_sync} = 'record'; 1; } new_edit: _new_edit { Audio::Nama::new_edit(); 1; } set_edit_points: _set_edit_points { Audio::Nama::set_edit_points(); 1 } list_edits: _list_edits { Audio::Nama::list_edits(); 1} destroy_edit: _destroy_edit { Audio::Nama::destroy_edit(); 1} select_edit: _select_edit dd { Audio::Nama::select_edit($item{dd}); 1} preview_edit_in: _preview_edit_in { Audio::Nama::edit_action($item[0]); 1} preview_edit_out: _preview_edit_out { Audio::Nama::edit_action($item[0]); 1} play_edit: _play_edit { Audio::Nama::edit_action($item[0]); 1} record_edit: _record_edit { Audio::Nama::edit_action($item[0]); 1} edit_track: _edit_track { Audio::Nama::select_edit_track('edit_track'); 1} host_track_alias: _host_track_alias { Audio::Nama::select_edit_track('host_alias_track'); 1} host_track: _host_track { Audio::Nama::select_edit_track('host'); 1} version_mix_track: _version_mix_track { Audio::Nama::select_edit_track('version_mix'); 1} play_start_mark: _play_start_mark { my $mark = $Audio::Nama::this_edit->play_start_mark; $mark->jump_here; 1; } rec_start_mark: _rec_start_mark { $Audio::Nama::this_edit->rec_start_mark->jump_here; 1; } rec_end_mark: _rec_end_mark { $Audio::Nama::this_edit->rec_end_mark->jump_here; 1; } set_play_start_mark: _set_play_start_mark { $Audio::Nama::setup->{edit_points}->[0] = Audio::Nama::eval_iam('getpos'); 1} set_rec_start_mark: _set_rec_start_mark { $Audio::Nama::setup->{edit_points}->[1] = Audio::Nama::eval_iam('getpos'); 1} set_rec_end_mark: _set_rec_end_mark { $Audio::Nama::setup->{edit_points}->[2] = Audio::Nama::eval_iam('getpos'); 1} end_edit_mode: _end_edit_mode { Audio::Nama::end_edit_mode(); 1;} disable_edits: _disable_edits { Audio::Nama::disable_edits();1 } merge_edits: _merge_edits { Audio::Nama::merge_edits(); 1; } explode_track: _explode_track { Audio::Nama::explode_track($Audio::Nama::this_track) } promote_version_to_track: _promote_version_to_track version { my $v = $item{version}; my $t = $Audio::Nama::this_track; $t->versions->[$v] or Audio::Nama::pager($t->name,": version $v does not exist."), return; Audio::Nama::VersionTrack->new( name => $t->name.":$v", version => $v, target => $t->name, rw => Audio::Nama::PLAY, group => $t->group, ); } version: dd read_user_customizations: _read_user_customizations { Audio::Nama::setup_user_customization(); 1 } limit_run_time: _limit_run_time sign(?) dd { my $sign = $item{'sign(?)'}->[-1]; $Audio::Nama::setup->{runtime_limit} = $sign ? eval "$Audio::Nama::setup->{audio_length} $sign $item{dd}" : $item{dd}; Audio::Nama::pager( "Run time limit: ", Audio::Nama::heuristic_time($Audio::Nama::setup->{runtime_limit})); 1; } limit_run_time_off: _limit_run_time_off { Audio::Nama::pager( "Run timer disabled"); Audio::Nama::disable_length_timer(); 1; } offset_run: _offset_run markname { Audio::Nama::set_offset_run_mark( $item{markname} ); 1 } offset_run_off: _offset_run_off { Audio::Nama::pager( "no run offset."); Audio::Nama::disable_offset_run_mode(); } view_waveform: _view_waveform { my $viewer = 'mhwaveedit'; if( `which $viewer` =~ m/\S/){ my $cmd = join " ", $viewer, "--driver", $Audio::Nama::jack->{jackd_running} ? "jack" : "alsa", $Audio::Nama::this_track->full_path, "&"; system($cmd) } else { Audio::Nama::throw("Mhwaveedit not found. No waveform viewer is available.") } } edit_waveform: _edit_waveform { if ( `which audacity` =~ m/\S/ ){ my $cmd = join " ", 'audacity', $Audio::Nama::this_track->full_path, "&"; my $old_pwd = Audio::Nama::getcwd(); chdir Audio::Nama::this_wav_dir(); system($cmd); chdir $old_pwd; } else { Audio::Nama::throw("Audacity not found. No waveform editor available.") } 1; } rerecord: _rerecord { Audio::Nama::pager( scalar @{$Audio::Nama::setup->{_last_rec_tracks}} ? "Toggling previous recording tracks to REC" : "No tracks in REC list. Skipping." ); map{ $_->set(rw => Audio::Nama::REC) } @{$Audio::Nama::setup->{_last_rec_tracks}}; Audio::Nama::restore_preview_mode(); 1; } show_track_latency: _show_track_latency { my $node = $Audio::Nama::setup->{latency}->{track}->{$Audio::Nama::this_track->name}; Audio::Nama::pager( Audio::Nama::json_out($node)) if $node; 1; } show_latency_all: _show_latency_all { Audio::Nama::pager( Audio::Nama::json_out($Audio::Nama::setup->{latency})) if $Audio::Nama::setup->{latency}; 1; } analyze_level: _analyze_level { Audio::Nama::check_level($Audio::Nama::this_track);1 } git: _git shellcode stopper { Audio::Nama::pager(map {$_.="\n"} $Audio::Nama::project->{repo}->run( split " ", $item{shellcode})) } edit_rec_setup_hook: _edit_rec_setup_hook { system("$ENV{EDITOR} ".$Audio::Nama::this_track->rec_setup_script() ); chmod 0755, $Audio::Nama::this_track->rec_setup_script(); 1 } edit_rec_cleanup_hook: _edit_rec_cleanup_hook { system("$ENV{EDITOR} ".$Audio::Nama::this_track->rec_cleanup_script() ); chmod 0755, $Audio::Nama::this_track->rec_cleanup_script(); 1 } remove_fader_effect: _remove_fader_effect fader_role { Audio::Nama::remove_fader_effect($Audio::Nama::this_track, $item{fader_role}); 1 } fader_role: 'vol'|'pan'|'fader' hotkeys: _hotkeys { Audio::Nama::setup_hotkeys()} hotkeys_always: _hotkeys_always { $Audio::Nama::config->{hotkeys_always}++; Audio::Nama::setup_hotkeys(); } hotkeys_off: _hotkeys_off { undef $Audio::Nama::config->{hotkeys_always}; 1 } hotkeys_list: _hotkeys_list { Audio::Nama::list_hotkeys() ; 1 } select_sequence: _select_sequence existing_sequence_name { $Audio::Nama::this_sequence = $Audio::Nama::bn{$item{existing_sequence_name}} } existing_sequence_name: ident { my $buslike = $Audio::Nama::bn{$item{ident}}; $return = $item{ident} if (ref $buslike) =~ /Sequence/ } convert_to_sequence: _convert_to_sequence { my $sequence_name = $Audio::Nama::this_track->name; Audio::Nama::process_command("nsq $sequence_name"); $Audio::Nama::this_sequence->new_clip($Audio::Nama::this_track); 1 } merge_sequence: _merge_sequence { cache_track($Audio::Nama::tn{$Audio::Nama::this_sequence->name}); 1 } new_sequence: _new_sequence new_sequence_name track_identifier(s?) { Audio::Nama::new_sequence( name => $item{new_sequence_name}, tracks => $item{'track_identifier(s?)'} || [] ); 1 } new_sequence_name: ident { $return = $Audio::Nama::bn{$item{ident}} ? do { Audio::Nama::pager("$item{ident}: name already in use\n"), undef} : $item{ident} } track_identifier: tid { my $tid = $Audio::Nama::tn{$item{tid}} || $Audio::Nama::ti{$item{tid}} ; if ($tid) { $tid } else { Audio::Nama::throw("$item{tid}: track name or index not found.\n"); undef } } tid: ident list_sequences: _list_sequences { Audio::Nama::pager( map {Audio::Nama::json_out($_->as_hash)} grep {$_->{class} =~ /Sequence/} Audio::Nama::Bus::all() ); } show_sequence: _show_sequence { Audio::Nama::pager($Audio::Nama::this_sequence->list_output) } append_to_sequence: _append_to_sequence track_identifier(s?) { my $seq = $Audio::Nama::this_sequence; my $items = $item{'track_identifier(s?)'} || [$Audio::Nama::this_track]; map { my $clip = $seq->new_clip($_); $seq->append_item($clip) } @$items; 1; } insert_in_sequence: _insert_in_sequence position track_identifier(s) { my $seq = $Audio::Nama::this_sequence; my $items = $item{'track_identifier(s)'}; my $position = $item{position}; for ( reverse map{ $seq->new_clip($_) } @$items ){ $seq->insert_item($_,$position) } } remove_from_sequence: _remove_from_sequence position(s) { my $seq = $Audio::Nama::this_sequence; my @positions = sort { $a <=> $b } @{ $item{'position(s)'}}; $seq->verify_item($_) ? $seq->delete_item($_) : Audio::Nama::throw("skipping index $_: out of bounds") for reverse @positions } delete_sequence: _delete_sequence existing_sequence_name { $Audio::Nama::bn{$item{existing_sequence_name}}->remove } position: dd { $Audio::Nama::this_sequence->verify_item($item{dd}) and $item{dd} } add_spacer: _add_spacer value position { $Audio::Nama::this_sequence->new_spacer( duration => $item{value}, position => $item{position}, hidden => 1, ); Audio::Nama::request_setup(); 1 } add_spacer: _add_spacer value { $Audio::Nama::this_sequence->new_spacer( duration => $item{value}, hidden => 1, ); Audio::Nama::request_setup(); 1 } snip: _snip track_identifier mark_pair(s) { my $track = $item{track_identifier}; my @pairs = $item{'mark_pair(s)'}; my @list = map{ @$_ } @pairs; @list = (0, @list, $track->length); @pairs = (); while ( scalar @list ){ push @pairs, [splice( @list, 0, 2)] } Audio::Nama::compose_sequence($track->name, $track, \@pairs); } compose: _compose ident track_identifier mark_pair(s) { Audio::Nama::compose_sequence(@item{qw/ident track_identifier mark_pair(s)/}); } mark_pair: mark1 mark2 { my @marks = map{ $Audio::Nama::mn{$_}} @item{qw(mark1 mark2)}; Audio::Nama::throw(join" ",(map{$_->name} @marks), ": pair must be ascending in time"), return undef if not( $marks[0]->time < $marks[1]->time ); \@marks } mark1: ident { $Audio::Nama::mn{$item{ident}} } mark2: mark1 snip: _snip new_sequence_name mark_pair(s) {} rename_track: _rename_track existing_track_name new_track_name { Audio::Nama::rename_track( @item{qw(existing_track_name new_track_name)}, $Audio::Nama::file->git_state_store, Audio::Nama::this_wav_dir() ); } undo: _undo { Audio::Nama::undo() } redo: _redo { Audio::Nama::redo() } show_head_commit: _show_head_commit { Audio::Nama::show_head_commit() } eager: _eager on_or_off { $Audio::Nama::mode->{eager} = $item{on_or_off} =~ /[1n]/ ? 1 : 0 } on_or_off: 'on' | '1' | 'off' | '0' new_engine: _new_engine ident port { Audio::Nama::Engine->new(name => $item{ident}, port => $item{port}) } port: dd select_engine: _select_engine ident { my $new_choice = $Audio::Nama::Engine::by_name{$item{ident}}; $Audio::Nama::this_engine = $new_choice if defined $new_choice; Audio::Nama::pager("Current engine is ".$Audio::Nama::this_engine->name) } set_track_engine_group: _set_track_engine_group ident { $Audio::Nama::this_track->set(engine_group => $item{ident}); Audio::Nama::pager($Audio::Nama::this_track->name. ": engine group set to $item{ident}"); } set_bus_engine_group: _set_bus_engine_group ident { $Audio::Nama::bn{$Audio::Nama::this_bus}->set(engine_group => $item{ident}); Audio::Nama::pager("$Audio::Nama::this_bus: bus engine group set to $item{ident}"); } select_submix: _select_submix existing_bus_name { $Audio::Nama::this_user = $Audio::Nama::bn{$item{existing_bus_name}} } trim_submix: _trim_submix effect parameter sign(?) value { my $real_track = join '_', $Audio::Nama::this_user->name, $Audio::Nama::this_track->name; Audio::Nama::pager("real track: $real_track\n"); my $FX = $Audio::Nama::tn{$real_track}->first_effect_of_type(Audio::Nama::full_effect_code($item{effect})); Audio::Nama::modify_effect($FX->id, $item{parameter}, @{$item{'sign(?)'}}, $item{value}); } set_effect_name: _set_effect_name ident { Audio::Nama::this_op_o->set_name($item{ident}); 1} remove_effect_name: _remove_effect_name { Audio::Nama::this_op_o->set_name(); 1 } set_effect_surname: _set_effect_surname ident { Audio::Nama::this_op_o->set_surname($item{ident}); 1} remove_effect_surname: _remove_effect_surname { Audio::Nama::this_op_o()->set_surname(); 1} select_track: _select_track track_spec command: help command: help_effect command: find_effect command: exit command: memoize command: unmemoize command: stop command: start command: getpos command: setpos command: forward command: rewind command: to_start command: to_end command: ecasound_start command: ecasound_stop command: restart_ecasound command: preview command: doodle command: mixdown command: mixplay command: mixoff command: automix command: master_on command: master_off command: add_track command: add_tracks command: add_midi_track command: link_track command: import_audio command: set_track command: record command: play command: mon command: off command: source command: send command: remove_send command: stereo command: mono command: set_version command: destroy_current_wav command: list_versions command: vol command: mute command: unmute command: unity command: solo command: nosolo command: all command: pan command: pan_right command: pan_left command: pan_center command: pan_back command: show_tracks command: show_tracks_all command: show_bus_tracks command: show_track command: show_mode command: show_track_latency command: show_latency_all command: set_region command: add_region command: remove_region command: shift_track command: unshift_track command: modifiers command: nomodifiers command: normalize command: fixdc command: autofix_tracks command: remove_track command: bus_mon command: bus_off command: bus_version command: add_bunch command: list_bunches command: remove_bunch command: add_to_bunch command: commit command: tag command: branch command: list_branches command: new_branch command: save_state command: get_state command: list_projects command: new_project command: load_project command: project_name command: new_project_template command: use_project_template command: list_project_templates command: destroy_project_template command: generate command: arm command: arm_start command: connect command: disconnect command: show_chain_setup command: loop command: noloop command: add_controller command: add_effect command: add_effect_last command: add_effect_first command: add_effect_before command: modify_effect command: remove_effect command: position_effect command: show_effect command: dump_effect command: list_effects command: hotkeys command: hotkeys_always command: hotkeys_off command: hotkeys_list command: add_insert command: set_insert_wetness command: remove_insert command: ctrl_register command: preset_register command: ladspa_register command: list_marks command: to_mark command: add_mark command: remove_mark command: next_mark command: previous_mark command: name_mark command: modify_mark command: engine_status command: dump_track command: dump_group command: dump_all command: dump_io command: list_history command: add_submix_cooked command: add_submix_raw command: add_bus command: update_submix command: remove_bus command: list_buses command: set_bus command: overwrite_effect_chain command: new_effect_chain command: delete_effect_chain command: find_effect_chains command: find_user_effect_chains command: bypass_effects command: bring_back_effects command: new_effect_profile command: apply_effect_profile command: destroy_effect_profile command: list_effect_profiles command: show_effect_profiles command: full_effect_profiles command: cache_track command: uncache_track command: do_script command: scan command: add_fade command: remove_fade command: list_fade command: add_comment command: remove_comment command: show_comment command: show_comments command: add_version_comment command: remove_version_comment command: show_version_comment command: show_version_comments_all command: set_system_version_comment command: midish_command command: midish_mode_on command: midish_mode_off command: midish_mode_off_ready_to_play command: midish_mode_off_ready_to_record command: new_edit command: set_edit_points command: list_edits command: select_edit command: end_edit_mode command: destroy_edit command: preview_edit_in command: preview_edit_out command: play_edit command: record_edit command: edit_track command: host_track_alias command: host_track command: version_mix_track command: play_start_mark command: rec_start_mark command: rec_end_mark command: set_play_start_mark command: set_rec_start_mark command: set_rec_end_mark command: disable_edits command: merge_edits command: explode_track command: move_to_bus command: promote_version_to_track command: read_user_customizations command: limit_run_time command: limit_run_time_off command: offset_run command: offset_run_off command: view_waveform command: edit_waveform command: rerecord command: analyze_level command: for command: git command: edit_rec_setup_hook command: edit_rec_cleanup_hook command: remove_fader_effect command: rename_track command: new_sequence command: select_sequence command: list_sequences command: show_sequence command: append_to_sequence command: insert_in_sequence command: remove_from_sequence command: delete_sequence command: add_spacer command: convert_to_sequence command: merge_sequence command: snip command: compose command: undo command: redo command: show_head_commit command: eager command: new_engine command: select_engine command: set_track_engine_group command: set_bus_engine_group command: select_submix command: trim_submix command: nickname_effect command: delete_nickname_definition command: remove_nickname command: list_nickname_definitions command: set_effect_name command: set_effect_surname command: remove_effect_name command: remove_effect_surname command: select_track _help: /help\b/ | /h\b/ { "help" } _help_effect: /help_effect\b/ | /hfx\b/ | /he\b/ { "help_effect" } _find_effect: /find_effect\b/ | /ffx\b/ | /fe\b/ { "find_effect" } _exit: /exit\b/ | /quit\b/ | /q\b/ { "exit" } _memoize: /memoize\b/ { "memoize" } _unmemoize: /unmemoize\b/ { "unmemoize" } _stop: /stop\b/ | /s\b/ { "stop" } _start: /start\b/ | /t\b/ { "start" } _getpos: /getpos\b/ | /gp\b/ { "getpos" } _setpos: /setpos\b/ | /sp\b/ { "setpos" } _forward: /forward\b/ | /fw\b/ { "forward" } _rewind: /rewind\b/ | /rw\b/ { "rewind" } _to_start: /to_start\b/ | /beg\b/ { "to_start" } _to_end: /to_end\b/ | /end\b/ { "to_end" } _ecasound_start: /ecasound_start\b/ { "ecasound_start" } _ecasound_stop: /ecasound_stop\b/ { "ecasound_stop" } _restart_ecasound: /restart_ecasound\b/ { "restart_ecasound" } _preview: /preview\b/ | /song\b/ { "preview" } _doodle: /doodle\b/ | /live\b/ { "doodle" } _mixdown: /mixdown\b/ | /mxd\b/ { "mixdown" } _mixplay: /mixplay\b/ | /mxp\b/ { "mixplay" } _mixoff: /mixoff\b/ | /mxo\b/ { "mixoff" } _automix: /automix\b/ { "automix" } _master_on: /master_on\b/ | /mr\b/ { "master_on" } _master_off: /master_off\b/ | /mro\b/ { "master_off" } _add_track: /add_track\b/ | /add\b/ | /new\b/ { "add_track" } _add_tracks: /add_tracks\b/ { "add_tracks" } _add_midi_track: /add_midi_track\b/ | /amt\b/ { "add_midi_track" } _link_track: /link_track\b/ | /link\b/ { "link_track" } _import_audio: /import_audio\b/ | /import\b/ { "import_audio" } _set_track: /set_track\b/ { "set_track" } _record: /record\b/ | /rec\b/ { "record" } _play: /play\b/ { "play" } _mon: /mon\b/ { "mon" } _off: /off\b/ { "off" } _source: /source\b/ | /src\b/ | /r\b/ { "source" } _send: /send\b/ | /aux\b/ { "send" } _remove_send: /remove_send\b/ | /nosend\b/ | /noaux\b/ { "remove_send" } _stereo: /stereo\b/ { "stereo" } _mono: /mono\b/ { "mono" } _set_version: /set_version\b/ | /version\b/ | /ver\b/ { "set_version" } _destroy_current_wav: /destroy_current_wav\b/ { "destroy_current_wav" } _list_versions: /list_versions\b/ | /lver\b/ { "list_versions" } _vol: /vol\b/ | /v\b/ { "vol" } _mute: /mute\b/ | /c\b/ | /cut\b/ { "mute" } _unmute: /unmute\b/ | /nomute\b/ | /C\b/ | /uncut\b/ { "unmute" } _unity: /unity\b/ { "unity" } _solo: /solo\b/ | /sl\b/ { "solo" } _nosolo: /nosolo\b/ | /nsl\b/ { "nosolo" } _all: /all\b/ { "all" } _pan: /pan\b/ | /p\b/ { "pan" } _pan_right: /pan_right\b/ | /pr\b/ { "pan_right" } _pan_left: /pan_left\b/ | /pl\b/ { "pan_left" } _pan_center: /pan_center\b/ | /pc\b/ { "pan_center" } _pan_back: /pan_back\b/ | /pb\b/ { "pan_back" } _show_tracks: /show_tracks\b/ | /lt\b/ | /show\b/ { "show_tracks" } _show_tracks_all: /show_tracks_all\b/ | /sha\b/ | /showa\b/ { "show_tracks_all" } _show_bus_tracks: /show_bus_tracks\b/ | /ltb\b/ | /showb\b/ { "show_bus_tracks" } _show_track: /show_track\b/ | /sh\b/ | /-fart\b/ { "show_track" } _show_mode: /show_mode\b/ | /shm\b/ { "show_mode" } _show_track_latency: /show_track_latency\b/ | /shl\b/ { "show_track_latency" } _show_latency_all: /show_latency_all\b/ | /shla\b/ { "show_latency_all" } _set_region: /set_region\b/ | /srg\b/ { "set_region" } _add_region: /add_region\b/ { "add_region" } _remove_region: /remove_region\b/ | /rrg\b/ { "remove_region" } _shift_track: /shift_track\b/ | /shift\b/ | /playat\b/ | /pat\b/ { "shift_track" } _unshift_track: /unshift_track\b/ | /unshift\b/ { "unshift_track" } _modifiers: /modifiers\b/ | /mods\b/ | /mod\b/ { "modifiers" } _nomodifiers: /nomodifiers\b/ | /nomods\b/ | /nomod\b/ { "nomodifiers" } _normalize: /normalize\b/ | /ecanormalize\b/ { "normalize" } _fixdc: /fixdc\b/ | /ecafixdc\b/ { "fixdc" } _autofix_tracks: /autofix_tracks\b/ | /autofix\b/ { "autofix_tracks" } _remove_track: /remove_track\b/ { "remove_track" } _bus_mon: /bus_mon\b/ | /bmon\b/ { "bus_mon" } _bus_off: /bus_off\b/ | /boff\b/ { "bus_off" } _bus_version: /bus_version\b/ | /bver\b/ | /gver\b/ { "bus_version" } _add_bunch: /add_bunch\b/ | /abn\b/ { "add_bunch" } _list_bunches: /list_bunches\b/ | /lbn\b/ { "list_bunches" } _remove_bunch: /remove_bunch\b/ | /rbn\b/ { "remove_bunch" } _add_to_bunch: /add_to_bunch\b/ | /atbn\b/ { "add_to_bunch" } _commit: /commit\b/ | /ci\b/ { "commit" } _tag: /tag\b/ { "tag" } _branch: /branch\b/ | /br\b/ { "branch" } _list_branches: /list_branches\b/ | /lb\b/ | /lbr\b/ { "list_branches" } _new_branch: /new_branch\b/ | /nbr\b/ { "new_branch" } _save_state: /save_state\b/ | /keep\b/ | /save\b/ { "save_state" } _get_state: /get_state\b/ | /get\b/ | /recall\b/ | /retrieve\b/ { "get_state" } _list_projects: /list_projects\b/ | /lp\b/ { "list_projects" } _new_project: /new_project\b/ | /create\b/ { "new_project" } _load_project: /load_project\b/ | /load\b/ { "load_project" } _project_name: /project_name\b/ | /project\b/ | /name\b/ { "project_name" } _new_project_template: /new_project_template\b/ | /npt\b/ { "new_project_template" } _use_project_template: /use_project_template\b/ | /upt\b/ | /apt\b/ { "use_project_template" } _list_project_templates: /list_project_templates\b/ | /lpt\b/ { "list_project_templates" } _destroy_project_template: /destroy_project_template\b/ { "destroy_project_template" } _generate: /generate\b/ | /gen\b/ { "generate" } _arm: /arm\b/ { "arm" } _arm_start: /arm_start\b/ | /arms\b/ { "arm_start" } _connect: /connect\b/ | /con\b/ { "connect" } _disconnect: /disconnect\b/ | /dcon\b/ { "disconnect" } _show_chain_setup: /show_chain_setup\b/ | /chains\b/ { "show_chain_setup" } _loop: /loop\b/ | /l\b/ { "loop" } _noloop: /noloop\b/ | /nl\b/ { "noloop" } _add_controller: /add_controller\b/ | /acl\b/ { "add_controller" } _add_effect: /add_effect\b/ | /afx\b/ { "add_effect" } _add_effect_last: /add_effect_last\b/ | /afxl\b/ { "add_effect_last" } _add_effect_first: /add_effect_first\b/ | /afxf\b/ { "add_effect_first" } _add_effect_before: /add_effect_before\b/ | /afxb\b/ { "add_effect_before" } _modify_effect: /modify_effect\b/ | /mfx\b/ { "modify_effect" } _remove_effect: /remove_effect\b/ | /rfx\b/ { "remove_effect" } _position_effect: /position_effect\b/ | /pfx\b/ { "position_effect" } _show_effect: /show_effect\b/ | /sfx\b/ { "show_effect" } _dump_effect: /dump_effect\b/ | /dfx\b/ { "dump_effect" } _list_effects: /list_effects\b/ | /lfx\b/ { "list_effects" } _hotkeys: /hotkeys\b/ | /hk\b/ { "hotkeys" } _hotkeys_always: /hotkeys_always\b/ | /hka\b/ { "hotkeys_always" } _hotkeys_off: /hotkeys_off\b/ | /hko\b/ { "hotkeys_off" } _hotkeys_list: /hotkeys_list\b/ | /hkl\b/ | /lhk\b/ { "hotkeys_list" } _add_insert: /add_insert\b/ | /ain\b/ { "add_insert" } _set_insert_wetness: /set_insert_wetness\b/ | /wet\b/ { "set_insert_wetness" } _remove_insert: /remove_insert\b/ | /rin\b/ { "remove_insert" } _ctrl_register: /ctrl_register\b/ | /crg\b/ { "ctrl_register" } _preset_register: /preset_register\b/ | /prg\b/ { "preset_register" } _ladspa_register: /ladspa_register\b/ | /lrg\b/ { "ladspa_register" } _list_marks: /list_marks\b/ | /lmk\b/ | /lm\b/ { "list_marks" } _to_mark: /to_mark\b/ | /tmk\b/ | /tom\b/ { "to_mark" } _add_mark: /add_mark\b/ | /mark\b/ | /amk\b/ | /k\b/ { "add_mark" } _remove_mark: /remove_mark\b/ | /rmk\b/ { "remove_mark" } _next_mark: /next_mark\b/ | /nmk\b/ { "next_mark" } _previous_mark: /previous_mark\b/ | /pmk\b/ { "previous_mark" } _name_mark: /name_mark\b/ { "name_mark" } _modify_mark: /modify_mark\b/ | /move_mark\b/ | /mmk\b/ { "modify_mark" } _engine_status: /engine_status\b/ | /egs\b/ { "engine_status" } _dump_track: /dump_track\b/ | /dump\b/ { "dump_track" } _dump_group: /dump_group\b/ | /dumpg\b/ { "dump_group" } _dump_all: /dump_all\b/ | /dumpa\b/ { "dump_all" } _dump_io: /dump_io\b/ { "dump_io" } _list_history: /list_history\b/ | /lh\b/ { "list_history" } _add_submix_cooked: /add_submix_cooked\b/ { "add_submix_cooked" } _add_submix_raw: /add_submix_raw\b/ | /asr\b/ { "add_submix_raw" } _add_bus: /add_bus\b/ | /abs\b/ { "add_bus" } _update_submix: /update_submix\b/ | /usm\b/ { "update_submix" } _remove_bus: /remove_bus\b/ { "remove_bus" } _list_buses: /list_buses\b/ | /lbs\b/ { "list_buses" } _set_bus: /set_bus\b/ | /sbs\b/ { "set_bus" } _overwrite_effect_chain: /overwrite_effect_chain\b/ | /oec\b/ { "overwrite_effect_chain" } _new_effect_chain: /new_effect_chain\b/ | /nec\b/ { "new_effect_chain" } _delete_effect_chain: /delete_effect_chain\b/ | /dec\b/ | /destroy_effect_chain\b/ { "delete_effect_chain" } _find_effect_chains: /find_effect_chains\b/ | /fec\b/ { "find_effect_chains" } _find_user_effect_chains: /find_user_effect_chains\b/ | /fuec\b/ { "find_user_effect_chains" } _bypass_effects: /bypass_effects\b/ | /bypass\b/ | /bfx\b/ { "bypass_effects" } _bring_back_effects: /bring_back_effects\b/ | /restore_effects\b/ | /bbfx\b/ { "bring_back_effects" } _new_effect_profile: /new_effect_profile\b/ | /nep\b/ { "new_effect_profile" } _apply_effect_profile: /apply_effect_profile\b/ | /aep\b/ { "apply_effect_profile" } _destroy_effect_profile: /destroy_effect_profile\b/ { "destroy_effect_profile" } _list_effect_profiles: /list_effect_profiles\b/ | /lep\b/ { "list_effect_profiles" } _show_effect_profiles: /show_effect_profiles\b/ | /sepr\b/ { "show_effect_profiles" } _full_effect_profiles: /full_effect_profiles\b/ | /fep\b/ { "full_effect_profiles" } _cache_track: /cache_track\b/ | /cache\b/ | /ct\b/ | /bounce\b/ | /freeze\b/ { "cache_track" } _uncache_track: /uncache_track\b/ | /uncache\b/ | /unc\b/ { "uncache_track" } _do_script: /do_script\b/ | /do\b/ { "do_script" } _scan: /scan\b/ { "scan" } _add_fade: /add_fade\b/ | /afd\b/ | /fade\b/ { "add_fade" } _remove_fade: /remove_fade\b/ | /rfd\b/ { "remove_fade" } _list_fade: /list_fade\b/ | /lfd\b/ { "list_fade" } _add_comment: /add_comment\b/ | /comment\b/ | /ac\b/ { "add_comment" } _remove_comment: /remove_comment\b/ | /rc\b/ { "remove_comment" } _show_comment: /show_comment\b/ | /sc\b/ { "show_comment" } _show_comments: /show_comments\b/ | /sca\b/ { "show_comments" } _add_version_comment: /add_version_comment\b/ | /avc\b/ { "add_version_comment" } _remove_version_comment: /remove_version_comment\b/ | /rvc\b/ { "remove_version_comment" } _show_version_comment: /show_version_comment\b/ | /svc\b/ { "show_version_comment" } _show_version_comments_all: /show_version_comments_all\b/ | /svca\b/ { "show_version_comments_all" } _set_system_version_comment: /set_system_version_comment\b/ | /ssvc\b/ { "set_system_version_comment" } _midish_command: /midish_command\b/ | /m\b/ { "midish_command" } _midish_mode_on: /midish_mode_on\b/ | /mmo\b/ { "midish_mode_on" } _midish_mode_off: /midish_mode_off\b/ | /mmx\b/ { "midish_mode_off" } _midish_mode_off_ready_to_play: /midish_mode_off_ready_to_play\b/ | /mmxrp\b/ { "midish_mode_off_ready_to_play" } _midish_mode_off_ready_to_record: /midish_mode_off_ready_to_record\b/ | /mmxrr\b/ { "midish_mode_off_ready_to_record" } _new_edit: /new_edit\b/ | /ned\b/ { "new_edit" } _set_edit_points: /set_edit_points\b/ | /sep\b/ { "set_edit_points" } _list_edits: /list_edits\b/ | /led\b/ { "list_edits" } _select_edit: /select_edit\b/ | /sed\b/ { "select_edit" } _end_edit_mode: /end_edit_mode\b/ | /eem\b/ { "end_edit_mode" } _destroy_edit: /destroy_edit\b/ { "destroy_edit" } _preview_edit_in: /preview_edit_in\b/ | /pei\b/ { "preview_edit_in" } _preview_edit_out: /preview_edit_out\b/ | /peo\b/ { "preview_edit_out" } _play_edit: /play_edit\b/ | /ped\b/ { "play_edit" } _record_edit: /record_edit\b/ | /red\b/ { "record_edit" } _edit_track: /edit_track\b/ | /et\b/ { "edit_track" } _host_track_alias: /host_track_alias\b/ | /hta\b/ { "host_track_alias" } _host_track: /host_track\b/ | /ht\b/ { "host_track" } _version_mix_track: /version_mix_track\b/ | /vmt\b/ { "version_mix_track" } _play_start_mark: /play_start_mark\b/ | /psm\b/ { "play_start_mark" } _rec_start_mark: /rec_start_mark\b/ | /rsm\b/ { "rec_start_mark" } _rec_end_mark: /rec_end_mark\b/ | /rem\b/ { "rec_end_mark" } _set_play_start_mark: /set_play_start_mark\b/ | /spsm\b/ { "set_play_start_mark" } _set_rec_start_mark: /set_rec_start_mark\b/ | /srsm\b/ { "set_rec_start_mark" } _set_rec_end_mark: /set_rec_end_mark\b/ | /srem\b/ { "set_rec_end_mark" } _disable_edits: /disable_edits\b/ | /ded\b/ { "disable_edits" } _merge_edits: /merge_edits\b/ | /med\b/ { "merge_edits" } _explode_track: /explode_track\b/ { "explode_track" } _move_to_bus: /move_to_bus\b/ | /mtb\b/ { "move_to_bus" } _promote_version_to_track: /promote_version_to_track\b/ | /pvt\b/ { "promote_version_to_track" } _read_user_customizations: /read_user_customizations\b/ | /ruc\b/ { "read_user_customizations" } _limit_run_time: /limit_run_time\b/ | /lr\b/ { "limit_run_time" } _limit_run_time_off: /limit_run_time_off\b/ | /lro\b/ { "limit_run_time_off" } _offset_run: /offset_run\b/ | /ofr\b/ { "offset_run" } _offset_run_off: /offset_run_off\b/ | /ofro\b/ { "offset_run_off" } _view_waveform: /view_waveform\b/ | /wview\b/ { "view_waveform" } _edit_waveform: /edit_waveform\b/ | /wedit\b/ { "edit_waveform" } _rerecord: /rerecord\b/ | /rerec\b/ { "rerecord" } _analyze_level: /analyze_level\b/ | /anl\b/ { "analyze_level" } _for: /for\b/ { "for" } _git: /git\b/ { "git" } _edit_rec_setup_hook: /edit_rec_setup_hook\b/ | /ersh\b/ { "edit_rec_setup_hook" } _edit_rec_cleanup_hook: /edit_rec_cleanup_hook\b/ | /erch\b/ { "edit_rec_cleanup_hook" } _remove_fader_effect: /remove_fader_effect\b/ | /rffx\b/ { "remove_fader_effect" } _rename_track: /rename_track\b/ { "rename_track" } _new_sequence: /new_sequence\b/ | /nsq\b/ { "new_sequence" } _select_sequence: /select_sequence\b/ | /slsq\b/ { "select_sequence" } _list_sequences: /list_sequences\b/ | /lsq\b/ { "list_sequences" } _show_sequence: /show_sequence\b/ | /ssq\b/ { "show_sequence" } _append_to_sequence: /append_to_sequence\b/ | /asq\b/ { "append_to_sequence" } _insert_in_sequence: /insert_in_sequence\b/ | /isq\b/ { "insert_in_sequence" } _remove_from_sequence: /remove_from_sequence\b/ | /rsq\b/ { "remove_from_sequence" } _delete_sequence: /delete_sequence\b/ | /dsq\b/ { "delete_sequence" } _add_spacer: /add_spacer\b/ | /asp\b/ { "add_spacer" } _convert_to_sequence: /convert_to_sequence\b/ | /csq\b/ { "convert_to_sequence" } _merge_sequence: /merge_sequence\b/ | /msq\b/ { "merge_sequence" } _snip: /snip\b/ { "snip" } _compose: /compose\b/ | /compose_sequence\b/ | /compose_into_sequence\b/ { "compose" } _undo: /undo\b/ { "undo" } _redo: /redo\b/ { "redo" } _show_head_commit: /show_head_commit\b/ | /show_head\b/ | /last_command\b/ | /last\b/ { "show_head_commit" } _eager: /eager\b/ { "eager" } _new_engine: /new_engine\b/ | /neg\b/ { "new_engine" } _select_engine: /select_engine\b/ | /seg\b/ { "select_engine" } _set_track_engine_group: /set_track_engine_group\b/ | /steg\b/ { "set_track_engine_group" } _set_bus_engine_group: /set_bus_engine_group\b/ | /sbeg\b/ { "set_bus_engine_group" } _select_submix: /select_submix\b/ | /ssm\b/ { "select_submix" } _trim_submix: /trim_submix\b/ | /trim\b/ | /tsm\b/ { "trim_submix" } _nickname_effect: /nickname_effect\b/ | /nfx\b/ | /nick\b/ { "nickname_effect" } _delete_nickname_definition: /delete_nickname_definition\b/ | /dnd\b/ { "delete_nickname_definition" } _remove_nickname: /remove_nickname\b/ | /rnick\b/ { "remove_nickname" } _list_nickname_definitions: /list_nickname_definitions\b/ | /lnd\b/ { "list_nickname_definitions" } _set_effect_name: /set_effect_name\b/ | /sen\b/ { "set_effect_name" } _set_effect_surname: /set_effect_surname\b/ | /ses\b/ { "set_effect_surname" } _remove_effect_name: /remove_effect_name\b/ | /ren\b/ { "remove_effect_name" } _remove_effect_surname: /remove_effect_surname\b/ | /res\b/ { "remove_effect_surname" } _select_track: /select_track\b/ { "select_track" } @@ hotkey_grammar command: set_current_effect command: set_stepsize command: set_jumpsize command: set_parameter command: cancel cancel: /.+Escape/ foo: /./ set_current_effect: 'f' effect_id 'Enter' {Audio::Nama::set_current_op($item{effect_id}) } effect_id: lower_case_effect_id { $return = uc $item{lower_case_effect_id} } lower_case_effect_id: /[a-z]+/ set_stepsize: 'm' digit { Audio::Nama::set_current_stepsize(10**$item{digit})} set_stepsize: 'm-' digit { Audio::Nama::set_current_stepsize(10**-$item{digit})} set_parameter: '=' value 'Enter' {Audio::Nama::set_parameter_value($item{value})} set_jumpsize: 'j' value 'Enter' {$Audio::Nama::text->{hotkey_playback_jumpsize} = $item{value}} digit: /\d/ value: /[+-]?([\d_]+(\.\d*)?|\.\d+)([eE][+-]?\d+)?/ @@ ecasound_chain_operator_hints_yml --- - code: ea count: 1 display: scale name: Volume params: - begin: 0 default: 100 end: 600 name: "Level %" resolution: 0 - code: eadb count: 1 display: scale name: Volume params: - begin: -40 default: 0 end: 60 name: "Level db" resolution: 0.5 - code: epp count: 1 display: scale name: Pan params: - begin: 0 default: 50 end: 100 name: "Level %" resolution: 0 - code: eal count: 1 display: scale name: Limiter params: - begin: 0 default: 100 end: 100 name: "Limit %" resolution: 0 - code: ec count: 2 display: scale name: Compressor params: - begin: 0 default: 1 end: 1 name: "Compression Rate (Db)" resolution: 0 - begin: 0 default: 50 end: 100 name: "Threshold %" resolution: 0 - code: eca count: 4 display: scale name: "Advanced Compressor" params: - begin: 0 default: 69 end: 100 name: "Peak Level %" resolution: 0 - begin: 0 default: 2 end: 5 name: "Release Time (Seconds)" resolution: 0 - begin: 0 default: 0.5 end: 1 name: "Fast Compressor Rate" resolution: 0 - begin: 0 default: 1 end: 1 name: "Compressor Rate (Db)" resolution: 0 - code: enm count: 5 display: scale name: "Noise Gate" params: - begin: 0 default: 100 end: 100 name: "Threshold Level %" resolution: 0 - begin: 0 default: 200 end: 2000 name: "Pre Hold Time (ms)" resolution: 0 - begin: 0 default: 200 end: 2000 name: "Attack Time (ms)" resolution: 0 - begin: 0 default: 200 end: 2000 name: "Post Hold Time (ms)" resolution: 0 - begin: 0 default: 200 end: 2000 name: "Release Time (ms)" resolution: 0 - code: ef1 count: 2 display: scale name: "Resonant Bandpass Filter" params: - begin: 0 default: 0 end: 20000 name: "Center Frequency (Hz)" resolution: 0 - begin: 0 default: 0 end: 2000 name: "Width (Hz)" resolution: 0 - code: ef3 count: 3 display: scale name: "Resonant Lowpass Filter" params: - begin: 0 default: 0 end: 5000 name: "Cutoff Frequency (Hz)" resolution: 0 - begin: 0 default: 0 end: 2 name: Resonance resolution: 0 - begin: 0 default: 0 end: 1 name: Gain resolution: 0 - code: efa count: 2 display: scale name: "Allpass Filter" params: - begin: 0 default: 0 end: 10000 name: "Delay Samples" resolution: 0 - begin: 0 default: 50 end: 100 name: "Feedback %" resolution: 0 - code: efb count: 2 display: scale name: "Bandpass Filter" params: - begin: 0 default: 11000 end: 11000 name: "Center Frequency (Hz)" resolution: 0 - begin: 0 default: 22000 end: 22000 name: "Width (Hz)" resolution: 0 - code: efh count: 1 display: scale name: "Highpass Filter" params: - begin: 10000 default: 10000 end: 22000 name: "Cutoff Frequency (Hz)" resolution: 0 - code: efl count: 1 display: scale name: "Lowpass Filter" params: - begin: 0 default: 0 end: 10000 name: "Cutoff Frequency (Hz)" resolution: 0 - code: efr count: 2 display: scale name: "Bandreject Filter" params: - begin: 0 default: 11000 end: 11000 name: "Center Frequency (Hz)" resolution: 0 - begin: 0 default: 22000 end: 22000 name: "Width (Hz)" resolution: 0 - code: efs count: 2 display: scale name: "Resonator Filter" params: - begin: 0 default: 11000 end: 11000 name: "Center Frequency (Hz)" resolution: 0 - begin: 0 default: 22000 end: 22000 name: "Width (Hz)" resolution: 0 - code: etd count: 5 display: scale name: Delay params: - begin: 0 default: 200 end: 2000 name: "Delay Time (ms)" resolution: 0 - begin: 0 default: 0 end: 2 name: "Surround Mode (Normal, Surround St., Spread)" resolution: 1 - begin: 0 default: 50 end: 100 name: "Number of Delays" resolution: 0 - begin: 0 default: 50 end: 100 name: "Mix %" resolution: 0 - begin: 0 default: 0 end: 100 name: "Feedback %" resolution: 0 - code: etc count: 4 display: scale name: Chorus params: - begin: 0 default: 200 end: 2000 name: "Delay Time (ms)" resolution: 0 - begin: 0 default: 500 end: 10000 name: "Variance Time Samples" resolution: 0 - begin: 0 default: 50 end: 100 name: "Feedback %" resolution: 0 - begin: 0 default: 50 end: 100 name: "LFO Frequency (Hz)" resolution: 0 - code: etr count: 3 display: scale name: Reverb params: - begin: 0 default: 200 end: 2000 name: "Delay Time (ms)" resolution: 0 - begin: 0 default: 0 end: 1 name: "Surround Mode (0=Normal, 1=Surround)" resolution: 1 - begin: 0 default: 50 end: 100 name: "Feedback %" resolution: 0 - code: ete count: 3 display: scale name: "Advanced Reverb" params: - begin: 0 default: 10 end: 100 name: "Room Size (Meters)" resolution: 0 - begin: 0 default: 50 end: 100 name: "Feedback %" resolution: 0 - begin: 0 default: 50 end: 100 name: "Wet %" resolution: 0 - code: etf count: 1 display: scale name: "Fake Stereo" params: - begin: 0 default: 40 end: 500 name: "Delay Time (ms)" resolution: 0 - code: etl count: 4 display: scale name: Flanger params: - begin: 0 default: 200 end: 1000 name: "Delay Time (ms)" resolution: 0 - begin: 0 default: 200 end: 10000 name: "Variance Time Samples" resolution: 0 - begin: 0 default: 50 end: 100 name: "Feedback %" resolution: 0 - begin: 0 default: 50 end: 100 name: "LFO Frequency (Hz)" resolution: 0 - code: etm count: 3 display: scale name: "Multitap Delay" params: - begin: 0 default: 200 end: 2000 name: "Delay Time (ms)" resolution: 0 - begin: 0 default: 20 end: 100 name: "Number of Delays" resolution: 0 - begin: 0 default: 50 end: 100 name: "Mix %" resolution: 0 - code: etp count: 4 display: scale name: Phaser params: - begin: 0 default: 200 end: 2000 name: "Delay Time (ms)" resolution: 0 - begin: 0 default: 100 end: 10000 name: "Variance Time Samples" resolution: 0 - begin: 0 default: 50 end: 100 name: "Feedback %" resolution: 0 - begin: 0 default: 50 end: 100 name: "LFO Frequency (Hz)" resolution: 0 - code: pn:metronome count: 1 display: scale name: Metronome params: - begin: 30 default: 120 end: 300 name: BPM resolution: 1 ... ; @@ default_namarc # # Nama Configuration file # # This file has been auto-generated by Nama # It will not be overwritten, so edit it as you like. # # Notes # # - The format of this file is YAML, preprocessed to allow # comments. # # - A value _must_ be supplied for each 'leaf' field. # For example "mixer_out_format: cd-stereo" # # - A value must _not_ be supplied for nodes, i.e. # 'device:'. The value for 'device' is the entire indented # data structure that follows in subsequent lines. # # - white space *is* significant. Two spaces indent is # required for each sublevel. # # - You may use the tilde symbol '~' to represent a null (undef) value # For example "execute_on_project_load: ~" # # - This file is distinct from .ecasoundrc (which in # general you will not need to run Nama.) # project root directory # all project directories (or their symlinks) will live here project_root: ~ # replaced during first run # define abbreviations abbreviations: 24-mono: s24_le,1,frequency 24-stereo: s24_le,2,frequency,i cd-mono: s16_le,1,44100 cd-stereo: s16_le,2,44100,i frequency: 44100 # define audio devices devices: jack: signal_format: f32_le,N,frequency # do not change this consumer: ecasound_id: alsa,default input_format: cd-stereo output_format: cd-stereo hardware_latency: 0 multi: ecasound_id: alsa,ice1712 input_format: s32_le,12,frequency output_format: s32_le,10,frequency hardware_latency: 0 null: ecasound_id: null output_format: ~ # ALSA soundcard device assignments and formats alsa_capture_device: consumer # for ALSA/OSS alsa_playback_device: consumer # for ALSA/OSS mixer_out_format: cd-stereo # for ALSA/OSS # soundcard_channels: 10 # input/output channel selection range (GUI) # audio file format templates mix_to_disk_format: s16_le,N,frequency,i raw_to_disk_format: s16_le,N,frequency,i cache_to_disk_format: s16_le,N,frequency,i mixdown_encodings: mp3 ogg sample_rate: frequency realtime_profile: nonrealtime # other choices: realtime or auto # The buffer size settings below apply only when JACK is *not* used ecasound_buffersize: realtime: default: 256 nonrealtime: default: 1024 ecasound_globals: common: -z:mixmode,sum -G:jack,Nama,send realtime: -z:db,100000 -z:nointbuf nonrealtime: -z:nodb -z:intbuf # ecasound_tcp_port: 2868 # WAVs recorded at the same time get the same numeric suffix use_group_numbering: 1 # Enable pressing SPACE to start/stop transport (in terminal, cursor in column 1) press_space_to_start_transport: 1 # commands to execute each time a project is loaded execute_on_project_load: ~ volume_control_operator: eadb # must be 'ea' or 'eadb' # beep PC speaker on command error # beep_command: beep -f 350 -l 700 # hotkey_beep: beep -f 250 -l 200 # effects for use in mastering mode eq: Parametric1 1 0 0 40 1 0 0 200 1 0 0 600 1 0 0 3300 1 0 low_pass: lowpass_iir 106 2 mid_pass: bandpass_iir 520 800 2 high_pass: highpass_iir 1030 2 compressor: sc4 0 3 16 0 1 3.25 0 spatialiser: matrixSpatialiser 0 limiter: tap_limiter 0 0 hotkeys: Escape: exit_hotkey_mode Insert: previous_track Delete: next_track Home: previous_effect End: next_effect PageUp: previous_param PageDown: next_param Left: previous_param Right: next_param Up: increment_param Down: decrement_param j: decrement_param k: increment_param h: previous_param l: next_param a: previous_track s: previous_effect d: next_effect f: next_track i: previous_track o: next_track I: previous_effect O: next_effect Space: toggle_transport alias: command: mbs: move_to_bus pcv: promote_current_version djp: disable_jack_polling effect: reverb: gverb # end @@ custom_pl ### customize.pl - user code # test this by typing: # # perl customize.pl # # or, if you are running from your build directory, e.g. # # perl -I ~/build/nama/lib customize.pl use Modern::Perl; use Audio::Nama::Globals qw(:all); my @user_customization = ( prompt => sub { no warnings 'uninitialized'; join ' ', 'nama', git_branch_display(), bus_track_display(), '> ' }, ## user defined commands commands => { # usage: greet greet => sub { my ($name,$adjective) = @_; pager("Hello $name! You look $adjective today!!"); }, disable_jack_polling => sub{ $project->{events}->{poll_jack} = undef }, promote_current_version => sub { my $v = $this_track->monitor_version; promote_version_to_track($this_track, $v); }, }, ); @@ fake_jack_lsp system:capture_1 alsa_pcm:capture_1 properties: output,can-monitor,physical,terminal, system:capture_2 alsa_pcm:capture_2 properties: output,can-monitor,physical,terminal, system:capture_3 alsa_pcm:capture_3 properties: output,can-monitor,physical,terminal, system:capture_4 alsa_pcm:capture_4 properties: output,can-monitor,physical,terminal, system:capture_5 alsa_pcm:capture_5 properties: output,can-monitor,physical,terminal, system:capture_6 alsa_pcm:capture_6 properties: output,can-monitor,physical,terminal, system:capture_7 alsa_pcm:capture_7 properties: output,can-monitor,physical,terminal, system:capture_8 alsa_pcm:capture_8 properties: output,can-monitor,physical,terminal, system:capture_9 alsa_pcm:capture_9 properties: output,can-monitor,physical,terminal, system:capture_10 alsa_pcm:capture_10 properties: output,can-monitor,physical,terminal, system:capture_11 alsa_pcm:capture_11 properties: output,can-monitor,physical,terminal, system:capture_12 alsa_pcm:capture_12 properties: output,can-monitor,physical,terminal, system:playback_1 alsa_pcm:playback_1 properties: input,physical,terminal, system:playback_2 alsa_pcm:playback_2 properties: input,physical,terminal, system:playback_3 alsa_pcm:playback_3 properties: input,physical,terminal, system:playback_4 alsa_pcm:playback_4 properties: input,physical,terminal, system:playback_5 alsa_pcm:playback_5 properties: input,physical,terminal, system:playback_6 alsa_pcm:playback_6 properties: input,physical,terminal, system:playback_7 alsa_pcm:playback_7 properties: input,physical,terminal, system:playback_8 alsa_pcm:playback_8 properties: input,physical,terminal, system:playback_9 alsa_pcm:playback_9 properties: input,physical,terminal, system:playback_10 alsa_pcm:playback_10 properties: input,physical,terminal, Horgand:out_1 properties: output,terminal, Horgand:out_2 properties: output,terminal, fluidsynth:left properties: output, fluidsynth:right properties: output, ecasound:out_1 properties: output, ecasound:out_2 properties: output, jconvolver:out_1 properties: output, jconvolver:out_2 properties: output, jconvolver:in_1 properties: input, jconvolver:in_2 properties: input, LinuxSampler:0 properties: output, LinuxSampler:1 properties: output, beatrix-0:output-0 properties: output, beatrix-0:output-1 properties: output, @@ fake_lv2_register 1. Calf Compressor -elv2:http://calf.sourceforge.net/plugins/Compressor,'Threshold','Ratio',' ... Attack','Release','Makeup Gain','Knee','Detection','Stereo ... Link','A-weighting','Compression','Peak Output','0dB','Bypass' 2. Calf Filter -elv2:http://calf.sourceforge.net/plugins/Filter,'Frequency','Resonance',' ... Mode','Inertia' 3. Calf Filterclavier -elv2:http://calf.sourceforge.net/plugins/Filterclavier,'Transpose','Detun ... e','Max. Resonance','Mode','Portamento time' 4. Calf Flanger -elv2:http://calf.sourceforge.net/plugins/Flanger,'Minimum ... delay','Modulation depth','Modulation rate','Feedback','Stereo ... phase','Reset','Amount','Dry Amount' 5. Calf Monosynth -elv2:http://calf.sourceforge.net/plugins/Monosynth,'Osc1 Wave','Osc2 ... Wave','O1<>2 Detune','Osc 2 transpose','Phase mode','O1<>2 ... Mix','Filter','Cutoff','Resonance','Separation','Env->Cutoff','Env->Res' ... ,'Env->Amp','Attack','Decay','Sustain','Release','Key Follow','Legato ... Mode','Portamento','Vel->Filter','Vel->Amp','Volume','PBend Range' 6. Calf MultiChorus -elv2:http://calf.sourceforge.net/plugins/MultiChorus,'Minimum ... delay','Modulation depth','Modulation rate','Stereo ... phase','Voices','Inter-voice phase','Amount','Dry Amount','Center Frq ... 1','Center Frq 2','Q' 7. Calf Phaser -elv2:http://calf.sourceforge.net/plugins/Phaser,'Center ... Freq','Modulation depth','Modulation rate','Feedback','# ... Stages','Stereo phase','Reset','Amount','Dry Amount' 8. Calf Reverb -elv2:http://calf.sourceforge.net/plugins/Reverb,'Decay time','High Frq ... Damp','Room size','Diffusion','Wet Amount','Dry Amount','Pre ... Delay','Bass Cut','Treble Cut' 9. Calf Rotary Speaker -elv2:http://calf.sourceforge.net/plugins/RotarySpeaker,'Speed Mode','Tap ... Spacing','Tap Offset','Mod Depth','Treble Motor','Bass Motor','Mic ... Distance','Reflection' 10. Calf Vintage Delay -elv2:http://calf.sourceforge.net/plugins/VintageDelay,'Tempo','Subdivide' ... ,'Time L','Time R','Feedback','Amount','Mix mode','Medium','Dry Amount' 11. IR -elv2:http://factorial.hu/plugins/lv2/ir,'Reverse ... IR','Predelay','Attack','Attack ... time','Envelope','Length','Stretch','Stereo width in','Stereo width ... IR','Autogain','Dry','Dry gain','Wet','Wet ... gain','FileHash0','FileHash1','FileHash2','Dry L meter','Dry R ... meter','Wet L meter','Wet R meter','Latency' 12. Aliasing -elv2:http://plugin.org.uk/swh-plugins/alias,'Aliasing level' 13. Allpass delay line, cubic spline interpolation -elv2:http://plugin.org.uk/swh-plugins/allpass_c,'Max Delay (s)','Delay ... Time (s)','Decay Time (s)' 14. Allpass delay line, linear interpolation -elv2:http://plugin.org.uk/swh-plugins/allpass_l,'Max Delay (s)','Delay ... Time (s)','Decay Time (s)' 15. Allpass delay line, noninterpolating -elv2:http://plugin.org.uk/swh-plugins/allpass_n,'Max Delay (s)','Delay ... Time (s)','Decay Time (s)' 16. AM pitchshifter -elv2:http://plugin.org.uk/swh-plugins/amPitchshift,'Pitch shift','Buffer ... size','latency' 17. Simple amplifier -elv2:http://plugin.org.uk/swh-plugins/amp,'Amps gain (dB)' 18. Analogue Oscillator -elv2:http://plugin.org.uk/swh-plugins/analogueOsc,'Waveform (1=sin, ... 2=tri, 3=squ, 4=saw)','Frequency (Hz)','Warmth','Instability' 19. Artificial latency -elv2:http://plugin.org.uk/swh-plugins/artificialLatency,'Delay ... (ms)','latency' 20. Auto phaser -elv2:http://plugin.org.uk/swh-plugins/autoPhaser,'Attack time ... (s)','Decay time (s)','Modulation depth','Feedback','Spread (octaves)' 21. Glame Bandpass Analog Filter -elv2:http://plugin.org.uk/swh-plugins/bandpass_a_iir,'Center Frequency ... (Hz)','Bandwidth (Hz)' 22. Glame Bandpass Filter -elv2:http://plugin.org.uk/swh-plugins/bandpass_iir,'Center Frequency ... (Hz)','Bandwidth (Hz)','Stages(2 poles per stage)' 23. Bode frequency shifter -elv2:http://plugin.org.uk/swh-plugins/bodeShifter,'Frequency ... shift','latency' 24. Bode frequency shifter (CV) -elv2:http://plugin.org.uk/swh-plugins/bodeShifterCV,'Base shift','Mix ... (-1=down, +1=up)','CV Attenuation','latency' 25. GLAME Butterworth Highpass -elv2:http://plugin.org.uk/swh-plugins/butthigh_iir,'Cutoff Frequency ... (Hz)','Resonance' 26. GLAME Butterworth Lowpass -elv2:http://plugin.org.uk/swh-plugins/buttlow_iir,'Cutoff Frequency ... (Hz)','Resonance' 27. Glame Butterworth X-over Filter -elv2:http://plugin.org.uk/swh-plugins/bwxover_iir,'Cutoff Frequency ... (Hz)','Resonance' 28. Chebyshev distortion -elv2:http://plugin.org.uk/swh-plugins/chebstortion,'Distortion' 29. Comb Filter -elv2:http://plugin.org.uk/swh-plugins/comb,'Band separation ... (Hz)','Feedback' 30. Comb Splitter -elv2:http://plugin.org.uk/swh-plugins/combSplitter,'Band separation (Hz)' 31. Comb delay line, cubic spline interpolation -elv2:http://plugin.org.uk/swh-plugins/comb_c,'Max Delay (s)','Delay Time ... (s)','Decay Time (s)' 32. Comb delay line, linear interpolation -elv2:http://plugin.org.uk/swh-plugins/comb_l,'Max Delay (s)','Delay Time ... (s)','Decay Time (s)' 33. Comb delay line, noninterpolating -elv2:http://plugin.org.uk/swh-plugins/comb_n,'Max Delay (s)','Delay Time ... (s)','Decay Time (s)' 34. Constant Signal Generator -elv2:http://plugin.org.uk/swh-plugins/const,'Signal amplitude' 35. Crossover distortion -elv2:http://plugin.org.uk/swh-plugins/crossoverDist,'Crossover ... amplitude','Smoothing' 36. DC Offset Remover -elv2:http://plugin.org.uk/swh-plugins/dcRemove, 37. Exponential signal decay -elv2:http://plugin.org.uk/swh-plugins/decay,'Decay Time (s)' 38. Decimator -elv2:http://plugin.org.uk/swh-plugins/decimator,'Bit depth','Sample rate ... (Hz)' 39. Declipper -elv2:http://plugin.org.uk/swh-plugins/declip, 40. Simple delay line, cubic spline interpolation -elv2:http://plugin.org.uk/swh-plugins/delay_c,'Max Delay (s)','Delay ... Time (s)' 41. Simple delay line, linear interpolation -elv2:http://plugin.org.uk/swh-plugins/delay_l,'Max Delay (s)','Delay ... Time (s)' 42. Simple delay line, noninterpolating -elv2:http://plugin.org.uk/swh-plugins/delay_n,'Max Delay (s)','Delay ... Time (s)' 43. Delayorama -elv2:http://plugin.org.uk/swh-plugins/delayorama,'Random seed','Input ... gain (dB)','Feedback (%)','Number of taps','First delay (s)','Delay ... range (s)','Delay change','Delay random (%)','Amplitude ... change','Amplitude random (%)','Dry/wet mix' 44. Diode Processor -elv2:http://plugin.org.uk/swh-plugins/diode,'Mode (0 for none, 1 for ... half wave, 2 for full wave)' 45. Audio Divider (Suboctave Generator) -elv2:http://plugin.org.uk/swh-plugins/divider,'Denominator' 46. DJ flanger -elv2:http://plugin.org.uk/swh-plugins/djFlanger,'LFO sync','LFO period ... (s)','LFO depth (ms)','Feedback (%)' 47. DJ EQ -elv2:http://plugin.org.uk/swh-plugins/dj_eq,'Lo gain (dB)','Mid gain ... (dB)','Hi gain (dB)','latency' 48. DJ EQ (mono) -elv2:http://plugin.org.uk/swh-plugins/dj_eq_mono,'Lo gain (dB)','Mid ... gain (dB)','Hi gain (dB)','latency' 49. Dyson compressor -elv2:http://plugin.org.uk/swh-plugins/dysonCompress,'Peak limit ... (dB)','Release time (s)','Fast compression ratio','Compression ratio' 50. Fractionally Addressed Delay Line -elv2:http://plugin.org.uk/swh-plugins/fadDelay,'Delay ... (seconds)','Feedback (dB)' 51. Fast Lookahead limiter -elv2:http://plugin.org.uk/swh-plugins/fastLookaheadLimiter,'Input gain ... (dB)','Limit (dB)','Release time (s)','Attenuation (dB)','latency' 52. Flanger -elv2:http://plugin.org.uk/swh-plugins/flanger,'Delay base (ms)','Max ... slowdown (ms)','LFO frequency (Hz)','Feedback' 53. FM Oscillator -elv2:http://plugin.org.uk/swh-plugins/fmOsc,'Waveform (1=sin, 2=tri, ... 3=squ, 4=saw)' 54. Foldover distortion -elv2:http://plugin.org.uk/swh-plugins/foldover,'Drive','Skew' 55. 4 x 4 pole allpass -elv2:http://plugin.org.uk/swh-plugins/fourByFourPole,'Frequency ... 1','Feedback 1','Frequency 2','Feedback 2','Frequency 3','Feedback ... 3','Frequency 4','Feedback 4' 56. Fast overdrive -elv2:http://plugin.org.uk/swh-plugins/foverdrive,'Drive level' 57. Frequency tracker -elv2:http://plugin.org.uk/swh-plugins/freqTracker,'Tracking speed' 58. Gate -elv2:http://plugin.org.uk/swh-plugins/gate,'LF key filter (Hz)','HF key ... filter (Hz)','Threshold (dB)','Attack (ms)','Hold (ms)','Decay ... (ms)','Range (dB)','Output select (-1 = key listen, 0 = gate, 1 = ... bypass)','Key level (dB)','Gate state' 59. Giant flange -elv2:http://plugin.org.uk/swh-plugins/giantFlange,'Double delay','LFO ... frequency 1 (Hz)','Delay 1 range (s)','LFO frequency 2 (Hz)','Delay 2 ... range (s)','Feedback','Dry/Wet level' 60. Gong model -elv2:http://plugin.org.uk/swh-plugins/gong,'Inner damping','Outer ... damping','Mic position','Inner size 1','Inner stiffness 1 +','Inner ... stiffness 1 -','Inner size 2','Inner stiffness 2 +','Inner stiffness 2 ... -','Inner size 3','Inner stiffness 3 +','Inner stiffness 3 -','Inner ... size 4','Inner stiffness 4 +','Inner stiffness 4 -','Outer size ... 1','Outer stiffness 1 +','Outer stiffness 1 -','Outer size 2','Outer ... stiffness 2 +','Outer stiffness 2 -','Outer size 3','Outer stiffness 3 ... +','Outer stiffness 3 -','Outer size 4','Outer stiffness 4 +','Outer ... stiffness 4 -' 61. Gong beater -elv2:http://plugin.org.uk/swh-plugins/gongBeater,'Impulse gain ... (dB)','Strike gain (dB)','Strike duration (s)' 62. GVerb -elv2:http://plugin.org.uk/swh-plugins/gverb,'Roomsize (m)','Reverb time ... (s)','Damping','Input bandwidth','Dry signal level (dB)','Early ... reflection level (dB)','Tail level (dB)' 63. Hard Limiter -elv2:http://plugin.org.uk/swh-plugins/hardLimiter,'dB limit','Wet ... level','Residue level' 64. Harmonic generator -elv2:http://plugin.org.uk/swh-plugins/harmonicGen,'Fundamental ... magnitude','2nd harmonic magnitude','3rd harmonic magnitude','4th ... harmonic magnitude','5th harmonic magnitude','6th harmonic ... magnitude','7th harmonic magnitude','8th harmonic magnitude','9th ... harmonic magnitude','10th harmonic magnitude' 65. Hermes Filter -elv2:http://plugin.org.uk/swh-plugins/hermesFilter,'LFO1 freq ... (Hz)','LFO1 wave (0 = sin, 1 = tri, 2 = saw, 3 = squ, 4 = s&h)','LFO2 ... freq (Hz)','LFO2 wave (0 = sin, 1 = tri, 2 = saw, 3 = squ, 4 = ... s&h)','Osc1 freq (Hz)','Osc1 wave (0 = sin, 1 = tri, 2 = saw, 3 = squ, ... 4 = noise)','Osc2 freq (Hz)','Osc2 wave (0 = sin, 1 = tri, 2 = saw, 3 = ... squ, 4 = noise)','Ringmod 1 depth (0=none, 1=AM, 2=RM)','Ringmod 2 ... depth (0=none, 1=AM, 2=RM)','Ringmod 3 depth (0=none, 1=AM, ... 2=RM)','Osc1 gain (dB)','RM1 gain (dB)','Osc2 gain (dB)','RM2 gain ... (dB)','Input gain (dB)','RM3 gain (dB)','Xover lower freq','Xover upper ... freq','Dist1 drive','Dist2 drive','Dist3 drive','Filt1 type (0=none, ... 1=LP, 2=HP, 3=BP, 4=BR, 5=AP)','Filt1 freq','Filt1 q','Filt1 ... resonance','Filt1 LFO1 level','Filt1 LFO2 level','Filt2 type (0=none, ... 1=LP, 2=HP, 3=BP, 4=BR, 5=AP)','Filt2 freq','Filt2 q','Filt2 ... resonance','Filt2 LFO1 level','Filt2 LFO2 level','Filt3 type (0=none, ... 1=LP, 2=HP, 3=BP, 4=BR, 5=AP)','Filt3 freq','Filt3 q','Filt3 ... resonance','Filt3 LFO1 level','Filt3 LFO2 level','Delay1 length ... (s)','Delay1 feedback','Delay1 wetness','Delay2 length (s)','Delay2 ... feedback','Delay2 wetness','Delay3 length (s)','Delay3 ... feedback','Delay3 wetness','Band 1 gain (dB)','Band 2 gain (dB)','Band ... 3 gain (dB)' 66. Glame Highpass Filter -elv2:http://plugin.org.uk/swh-plugins/highpass_iir,'Cutoff ... Frequency','Stages(2 poles per stage)' 67. Hilbert transformer -elv2:http://plugin.org.uk/swh-plugins/hilbert,'latency' 68. Non-bandlimited single-sample impulses -elv2:http://plugin.org.uk/swh-plugins/impulse_fc,'Frequency (Hz)' 69. Inverter -elv2:http://plugin.org.uk/swh-plugins/inv, 70. Karaoke -elv2:http://plugin.org.uk/swh-plugins/karaoke,'Vocal volume (dB)' 71. L/C/R Delay -elv2:http://plugin.org.uk/swh-plugins/lcrDelay,'L delay (ms)','L ... level','C delay (ms)','C level','R delay (ms)','R ... level','Feedback','High damp (%)','Low damp (%)','Spread','Dry/Wet ... level' 72. LFO Phaser -elv2:http://plugin.org.uk/swh-plugins/lfoPhaser,'LFO rate (Hz)','LFO ... depth','Feedback','Spread (octaves)' 73. Lookahead limiter -elv2:http://plugin.org.uk/swh-plugins/lookaheadLimiter,'Limit ... (dB)','Lookahead delay','Attenuation (dB)','latency' 74. Lookahead limiter (fixed latency) -elv2:http://plugin.org.uk/swh-plugins/lookaheadLimiterConst,'Limit ... (dB)','Lookahead time (s)','Attenuation (dB)','latency' 75. Glame Lowpass Filter -elv2:http://plugin.org.uk/swh-plugins/lowpass_iir,'Cutoff ... Frequency','Stages(2 poles per stage)' 76. LS Filter -elv2:http://plugin.org.uk/swh-plugins/lsFilter,'Filter type (0=LP, 1=BP, ... 2=HP)','Cutoff frequency (Hz)','Resonance' 77. Matrix: MS to Stereo -elv2:http://plugin.org.uk/swh-plugins/matrixMSSt,'Width' 78. Matrix Spatialiser -elv2:http://plugin.org.uk/swh-plugins/matrixSpatialiser,'Width' 79. Matrix: Stereo to MS -elv2:http://plugin.org.uk/swh-plugins/matrixStMS, 80. Multiband EQ -elv2:http://plugin.org.uk/swh-plugins/mbeq,'50Hz gain (low ... shelving)','100Hz gain','156Hz gain','220Hz gain','311Hz gain','440Hz ... gain','622Hz gain','880Hz gain','1250Hz gain','1750Hz gain','2500Hz ... gain','3500Hz gain','5000Hz gain','10000Hz gain','20000Hz ... gain','latency' 81. Modulatable delay -elv2:http://plugin.org.uk/swh-plugins/modDelay,'Base delay (s)' 82. Multivoice Chorus -elv2:http://plugin.org.uk/swh-plugins/multivoiceChorus,'Number of ... voices','Delay base (ms)','Voice separation (ms)','Detune (%)','LFO ... frequency (Hz)','Output attenuation (dB)' 83. Higher Quality Pitch Scaler -elv2:http://plugin.org.uk/swh-plugins/pitchScaleHQ,'Pitch ... co-efficient','latency' 84. Plate reverb -elv2:http://plugin.org.uk/swh-plugins/plate,'Reverb ... time','Damping','Dry/wet mix' 85. Pointer cast distortion -elv2:http://plugin.org.uk/swh-plugins/pointerCastDistortion,'Effect ... cutoff freq (Hz)','Dry/wet mix' 86. Rate shifter -elv2:http://plugin.org.uk/swh-plugins/rateShifter,'Rate' 87. Retro Flanger -elv2:http://plugin.org.uk/swh-plugins/retroFlange,'Average stall ... (ms)','Flange frequency (Hz)' 88. Reverse Delay (5s max) -elv2:http://plugin.org.uk/swh-plugins/revdelay,'Delay Time (s)','Dry ... Level (dB)','Wet Level (dB)','Feedback','Crossfade samples' 89. Ringmod with LFO -elv2:http://plugin.org.uk/swh-plugins/ringmod_1i1o1l,'Modulation depth ... (0=none, 1=AM, 2=RM)','Frequency (Hz)','Sine level','Triangle ... level','Sawtooth level','Square level' 90. Ringmod with two inputs -elv2:http://plugin.org.uk/swh-plugins/ringmod_2i1o,'Modulation depth ... (0=none, 1=AM, 2=RM)' 91. Barry's Satan Maximiser -elv2:http://plugin.org.uk/swh-plugins/satanMaximiser,'Decay time ... (samples)','Knee point (dB)' 92. SC1 -elv2:http://plugin.org.uk/swh-plugins/sc1,'Attack time (ms)','Release ... time (ms)','Threshold level (dB)','Ratio (1:n)','Knee radius ... (dB)','Makeup gain (dB)' 93. SC2 -elv2:http://plugin.org.uk/swh-plugins/sc2,'Attack time (ms)','Release ... time (ms)','Threshold level (dB)','Ratio (1:n)','Knee radius ... (dB)','Makeup gain (dB)' 94. SC3 -elv2:http://plugin.org.uk/swh-plugins/sc3,'Attack time (ms)','Release ... time (ms)','Threshold level (dB)','Ratio (1:n)','Knee radius ... (dB)','Makeup gain (dB)','Chain balance' 95. SC4 -elv2:http://plugin.org.uk/swh-plugins/sc4,'RMS/peak','Attack time ... (ms)','Release time (ms)','Threshold level (dB)','Ratio (1:n)','Knee ... radius (dB)','Makeup gain (dB)','Amplitude (dB)','Gain reduction (dB)' 96. SE4 -elv2:http://plugin.org.uk/swh-plugins/se4,'RMS/peak','Attack time ... (ms)','Release time (ms)','Threshold level (dB)','Ratio (1:n)','Knee ... radius (dB)','Attenuation (dB)','Amplitude (dB)','Gain expansion (dB)' 97. Wave shaper -elv2:http://plugin.org.uk/swh-plugins/shaper,'Waveshape' 98. Signal sifter -elv2:http://plugin.org.uk/swh-plugins/sifter,'Sift size' 99. Sine + cosine oscillator -elv2:http://plugin.org.uk/swh-plugins/sinCos,'Base frequency ... (Hz)','Pitch offset' 100. Single band parametric -elv2:http://plugin.org.uk/swh-plugins/singlePara,'Gain (dB)','Frequency ... (Hz)','Bandwidth (octaves)' 101. Sinus wavewrapper -elv2:http://plugin.org.uk/swh-plugins/sinusWavewrapper,'Wrap degree' 102. Smooth Decimator -elv2:http://plugin.org.uk/swh-plugins/smoothDecimate,'Resample ... rate','Smoothing' 103. Mono to Stereo splitter -elv2:http://plugin.org.uk/swh-plugins/split, 104. Surround matrix encoder -elv2:http://plugin.org.uk/swh-plugins/surroundEncoder, 105. State Variable Filter -elv2:http://plugin.org.uk/swh-plugins/svf,'Filter type (0=none, 1=LP, ... 2=HP, 3=BP, 4=BR, 5=AP)','Filter freq','Filter Q','Filter resonance' 106. Tape Delay Simulation -elv2:http://plugin.org.uk/swh-plugins/tapeDelay,'Tape speed (inches/sec, ... 1=normal)','Dry level (dB)','Tap 1 distance (inches)','Tap 1 level ... (dB)','Tap 2 distance (inches)','Tap 2 level (dB)','Tap 3 distance ... (inches)','Tap 3 level (dB)','Tap 4 distance (inches)','Tap 4 level ... (dB)' 107. Transient mangler -elv2:http://plugin.org.uk/swh-plugins/transient,'Attack speed','Sustain ... time' 108. Triple band parametric with shelves -elv2:http://plugin.org.uk/swh-plugins/triplePara,'Low-shelving gain ... (dB)','Low-shelving frequency (Hz)','Low-shelving slope','Band 1 gain ... (dB)','Band 1 frequency (Hz)','Band 1 bandwidth (octaves)','Band 2 gain ... (dB)','Band 2 frequency (Hz)','Band 2 bandwidth (octaves)','Band 3 gain ... (dB)','Band 3 frequency (Hz)','Band 3 bandwidth ... (octaves)','High-shelving gain (dB)','High-shelving frequency ... (Hz)','High-shelving slope' 109. Valve saturation -elv2:http://plugin.org.uk/swh-plugins/valve,'Distortion ... level','Distortion character' 110. Valve rectifier -elv2:http://plugin.org.uk/swh-plugins/valveRect,'Sag level','Distortion' 111. VyNil (Vinyl Effect) -elv2:http://plugin.org.uk/swh-plugins/vynil,'Year','RPM','Surface ... warping','Crackle','Wear' 112. Wave Terrain Oscillator -elv2:http://plugin.org.uk/swh-plugins/waveTerrain, 113. Crossfade -elv2:http://plugin.org.uk/swh-plugins/xfade,'Crossfade' 114. Crossfade (4 outs) -elv2:http://plugin.org.uk/swh-plugins/xfade4,'Crossfade' 115. z-1 -elv2:http://plugin.org.uk/swh-plugins/zm1, 116. TalentedHack -elv2:urn:jeremy.salwen:plugins:talentedhack,'Mix','Pull To In ... Tune','Smooth Pitch','Formant Correction','Formant Warp','Jump To Midi ... Input','Pitch Correct Midi Out','Quantize LFO','LFO Amplitude','LFO ... Rate (Hz)','LFO Shape','LFO Symmetry','Concert A (Hz)','Detect ... A','Detect A#','Detect B','Detect C','Detect C#','Detect D','Detect ... D#','Detect E','Detect F','Detect F#','Detect G','Detect G#','Output ... A','Output A#','Output B','Output C','Output C#','Output D','Output ... D#','Output E','Output F','Output F#','Output G','Output G#','Latency' @@ fake_jack_latency system:capture_1 port latency = 1024 frames port playback latency = [ 0 0 ] frames port capture latency = [ 1024 1024 ] frames system:capture_2 port latency = 1024 frames port playback latency = [ 0 0 ] frames port capture latency = [ 1024 1024 ] frames system:playback_1 port latency = 2048 frames port playback latency = [ 2048 2048 ] frames port capture latency = [ 0 0 ] frames system:playback_2 port latency = 2048 frames port playback latency = [ 2048 2048 ] frames port capture latency = [ 0 0 ] frames LinuxSampler:capture_1 port latency = 1024 frames port playback latency = [ 256 256 ] frames port capture latency = [ 512 1024 ] frames LinuxSampler:capture_2 port latency = 1024 frames port playback latency = [ 256 256 ] frames port capture latency = [ 256 1024 ] frames LinuxSampler:playback_1 port latency = 2048 frames port playback latency = [ 2048 2048 ] frames port capture latency = [ 512 512 ] frames LinuxSampler:playback_2 port latency = 2048 frames port playback latency = [ 2048 2048 ] frames port capture latency = [ 512 512 ] frames @@ midish_commands tracklist tracknew trackdelete trackrename trackexists trackaddev tracksetcurfilt trackgetcurfilt trackcheck trackcut trackblank trackinsert trackcopy trackquant tracktransp trackmerge tracksetmute trackgetmute trackchanlist trackinfo channew chanset chandelete chanrename chanexists changetch changetdev chanconfev chanunconfev chaninfo chansetcurinput changetcurinput filtnew filtdelete filtrename filtexists filtreset filtinfo filtsetcurchan filtgetcurchan filtchgich filtchgidev filtswapich filtswapidev filtchgoch filtchgodev filtswapoch filtswapodev filtdevdrop filtnodevdrop filtdevmap filtnodevmap filtchandrop filtnochandrop filtchanmap filtnochanmap filtctldrop filtnoctldrop filtctlmap filtnoctlmap filtkeydrop filtnokeydrop filtkeymap filtnokeymap sysexnew sysexdelete sysexrename sysexexists sysexclear sysexsetunit sysexadd sysexinfo songidle songplay songrecord sendraw songsetcurquant songgetcurquant songsetcurpos songgetcurpos songsetcurlen songgetcurlen songsetcurtrack songgetcurtrack songsetcurfilt songgetcurfilt songsetcursysex songgetcursysex songsetcurchan songgetcurchan songsetcurinput changetcurinput songsetunit songgetunit songsetfactor songgetfactor songsettempo songtimeins songtimerm songtimeinfo songinfo songsave songload songreset songexportsmf songimportsmf devlist devattach devdetach devsetmaster devgetmaster devsendrt devticrate devinfo devixctl devoxctl ctlconf ctlconfx ctlconf ctlinfo metroswitch metroconf info print exec debug panic let proc @@ default_palette_json { "gui" : { "_nama_palette" : { "Capture" : "#f22c92f088d3", "ClockBackground" : "#998ca489b438", "ClockForeground" : "#000000000000", "GroupBackground" : "#998ca489b438", "GroupForeground" : "#000000000000", "MarkArmed" : "#d74a811f443f", "Mixdown" : "#bf67c5a1491f", "MonBackground" : "#9420a9aec871", "MonForeground" : "Black", "Mute" : "#a5a183828382", "OffBackground" : "#998ca489b438", "OffForeground" : "Black", "Play" : "#68d7aabf755c", "RecBackground" : "#d9156e866335", "RecForeground" : "Black", "SendBackground" : "#9ba79cbbcc8a", "SendForeground" : "Black", "SourceBackground" : "#f22c92f088d3", "SourceForeground" : "Black" }, "_palette" : { "ew" : { "background" : "#d915cc1bc3cf", "foreground" : "black" }, "mw" : { "activeBackground" : "#4e097822b438", "background" : "#c2c5d0b5e49a", "foreground" : "black" } } } } @@ banner //////////////////////////////////////////////////////////////////// / / / Nama multitrack recorder v. $VERSION (c)2008-2014 Joel Roth / / / / Audio processing by Ecasound, courtesy of Kai Vehmanen / / / //////////////////////////////////////////////////////////////////// Starting...Audio-Nama-1.208/lib/Audio/Nama/0000755000175000017500000000000012644673607015177 5ustar jrothjrothAudio-Nama-1.208/lib/Audio/Nama/Globals.pm0000644000175000017500000000672712644673574017137 0ustar jrothjrothpackage Audio::Nama::Globals; use Modern::Perl; # set aliases for common indices *bn = \%Audio::Nama::Bus::by_name; *tn = \%Audio::Nama::Track::by_name; *ti = \%Audio::Nama::Track::by_index; *mn = \%Audio::Nama::Mark::by_name; *en = \%Audio::Nama::Engine::by_name; *fi = \%Audio::Nama::Effect::by_id; # and the graph *g = \$Audio::Nama::ChainSetup::g; use Exporter; use constant { REC => 'REC', PLAY => 'PLAY', MON => 'MON', OFF => 'OFF', }; our @ISA = 'Exporter'; our @EXPORT_OK = qw( $this_track $this_bus $this_bus_o $this_mark $this_edit $this_sequence $this_engine $this_user $prompt %tn %ti %bn %mn %en %fi $g $debug $debug2 $quiet REC MON PLAY OFF $ui $mode $file $graph $setup $config $jack $fx $fx_cache $text $gui $midi $help $mastering $project @tracks_data @bus_data @groups_data @marks_data @fade_data @edit_data @inserts_data @effects_data @global_effect_chain_vars @global_effect_chain_data @project_effect_chain_data $this_track_name %track_comments %track_version_comments @tracked_vars @persistent_vars ); our %EXPORT_TAGS = ( trackrw => [qw(REC PLAY MON OFF)], singletons => [qw( $ui $mode $file $graph $setup $config $jack $fx $fx_cache $text $gui $midi $help $mastering $project )], var_lists => [qw( @tracked_vars @persistent_vars @global_effect_chain_vars )], pronouns => [qw( $this_track $this_bus $this_bus_o $this_mark $this_edit $this_sequence $this_engine $this_user $prompt %tn %ti %bn %mn %en %fi $g $debug $debug2 $quiet REC MON PLAY OFF )], serialize => [qw( @tracks_data @bus_data @groups_data @marks_data @fade_data @edit_data @inserts_data @effects_data @global_effect_chain_vars @global_effect_chain_data @project_effect_chain_data $this_track_name %track_comments %track_version_comments @tracked_vars @persistent_vars )], ); our $ui = 'bullwinkle'; # for testing { my %seen; push @{$EXPORT_TAGS{all}}, grep {!$seen{$_}++} @{$EXPORT_TAGS{$_}} foreach keys %EXPORT_TAGS; } 1; __END__ =head1 Nama Variables Variables are listed in multiple files in the source. =head2 Exported L exports Nama globals, which it gets by merging the contents of the following files: =over =item F Pronouns (e.g. C<$this_track>) and indices (e.g. C<%tn>, get track by name) =item F Marshalling variables for serializing/deserializing (e.g. C<@tracks_data>) =item F Simple hash structures (such as C<$config>) or objects such as F<$file> that aggregate data. The hashes can be invested with object properties as need be. =back =head2 Other lists =over =item F Maps keys in F<.namarc> (e.g. I) to the corresponding Nama internal scalar (e.g. C<$config-E{mix_to_disk_format}> =item F List of allowed singleton hash keys. Keys of variables appearing in ./var_singletons should be listed in var_keys or in var_config. Undeclared keys will trigger warnings during build. =head2 F Declares lists of variables used in serializing/deserializing. =item C<@global_effect_chain_vars> Mainly user defined and system-wide effect chains, stored in F in the Nama project root directory. =item C<@tracked_vars> These variables are saved to F in the project directory and placed under version control. =item C<@persistent_vars> These Variables saved to F, I under version control. including project-specific effect-chain definitions, and track/version comments. =back =cutAudio-Nama-1.208/lib/Audio/Nama/EngineCleanup.pm0000644000175000017500000001233212644673574020256 0ustar jrothjroth# ----------- Engine cleanup (post-recording) ----------- package Audio::Nama; use Modern::Perl; use Cwd; use Audio::Nama::Globals qw(:all); sub rec_cleanup { logsub("&rec_cleanup"); logpkg(__FILE__,__LINE__,'debug',"transport still running, can't cleanup"),return if transport_running(); if( my (@files) = new_files_were_recorded() ) { if( my @rec_tracks = Audio::Nama::ChainSetup::engine_wav_out_tracks() ) { $project->{playback_position} = 0; $setup->{_last_rec_tracks} = \@rec_tracks; pager(join " ", "Files recorded for these tracks:", map{ $_->name } @rec_tracks); } if( grep /Mixdown/, @files) { mixdown_postprocessing() } else { post_rec_configure() } } } sub mixdown_postprocessing { logsub("&mixdown_postprocessing"); process_command('mixplay'); my ($oldfile) = $tn{Mixdown}->full_path =~ m{([^/]+)$}; $oldfile = join_path('.wav',$oldfile); my $tag_name = join '-', $project->{name}, current_branch(); my $version = $tn{Mixdown}->monitor_version; # simplify the tagname basename # # untitled-master -> untitled # untitled-premix-branch -> untitled-premix $tag_name =~ s/-branch$//; $tag_name =~ s/-master$//; $tag_name .= "_$version"; delete_existing_mixdown_tag_and_convenience_encodings($tag_name); # create symlink in project_dir() my $was_in = getcwd; chdir project_dir() or die "couldn't chdir: $!"; my $newfile = "$tag_name.wav"; logpkg(__FILE__,__LINE__,'debug',"symlinking oldfile: $oldfile, newfile: $newfile"); symlink $oldfile, $newfile or throw("symlink didn't work: $!"); tag_mixdown_commit($tag_name, $newfile, $oldfile) if $config->{use_git}; my $sha = git_sha(); # possibly undef my $encoding = $config->{mixdown_encodings}; my $comment; if ($sha or $encoding){ $comment .= "tagged " if $sha; $comment .= "and " if $sha and $encoding; $comment .= "encoded " if $encoding; $comment .= "as $tag_name "; $comment .= "(commit $sha)" if $sha; } $tn{Mixdown}->add_system_version_comment($version, $comment); pager_newline($comment); encode_mixdown_file($oldfile,$tag_name); chdir $was_in; } sub tag_mixdown_commit { logsub('&tag_mixdown_commit'); my ($name, $newfile, $mixdownfile) = @_; logpkg(__FILE__,__LINE__,'debug',"tag_mixdown_commit: @_"); my ($sym) = $newfile =~ m([^/]+$); my ($mix) = $mixdownfile =~ m([^/]+$); # we want to tag the normal playback state local $quiet = 1; mixoff(); my $msg = "State for $sym ($mix)"; git_snapshot($msg); git('tag', $name, '-m', $mix); # rec_cleanup wants to audition the mixdown mixplay(); } sub delete_existing_mixdown_tag_and_convenience_encodings { logsub('&delete_existing_mixdown_tag_and_convenience_encodings'); my $name = shift; logpkg(__FILE__,__LINE__,'debug',"name: $name"); git('tag', '-d', $name); foreach( qw(mp3 ogg wav) ){ my $file = join_path(project_dir(),"$name.$_"); unlink $file if -e $file; } } sub encode_mixdown_file { state $shell_encode_command = { mp3 => q(lame -h --ta "$artist" --ty $year --tt "$title" $input_file $output_file), ogg => q(oggenc -o $output_file -a "$artist" -t "$title" -d "$date" $input_file) }; my($mixdownfile, $tag_name, @formats) = @_; @formats or @formats = split " ", $config->{mixdown_encodings}; logpkg(__FILE__,__LINE__,'debug',"formats: @formats"); my $artist = $project->{artist} || qx(whoami); my $title = $project->{name}; my $date = qx(date); chomp($date, $artist); my ($year) = $date =~ /(\d{4})$/; my $input_file = $mixdownfile; for my $format( @formats ){ my $output_file = join_path(project_dir(),"$tag_name.$format"); logpkg(__FILE__,__LINE__,'debug',"artist $artist, title $title, date $date, year $year, input file $input_file, output file $output_file"); my $cmd = eval qq(qq($shell_encode_command->{$format})); logpkg(__FILE__,__LINE__,'debug',"Mixdown encoding command:\n$cmd"); system $cmd; } } sub adjust_offset_recordings { for( Audio::Nama::ChainSetup::engine_wav_out_tracks()){ no warnings 'uninitialized'; if (my $mark = $setup->{offset_run}->{mark}){ $_->set(playat => $mark); logpkg(__FILE__,__LINE__,'debug',$_->name, ": offsetting to $mark"); } } } sub post_rec_configure { $ui->global_version_buttons(); # recreate adjust_offset_recordings(); # toggle recorded tracks to PLAY for auditioning map{ $_->set(rw => PLAY) } @{$setup->{_last_rec_tracks}}; undef $mode->{offset_run} if ! defined $this_edit; no warnings 'uninitialized'; $mode->{midish_transport_sync} = 'play' if $mode->{midish_transport_sync} eq 'record'; $ui->refresh(); request_setup(); reconfigure_engine(); } sub new_files_were_recorded { return unless my @files = Audio::Nama::ChainSetup::really_recording(); logpkg(__FILE__,__LINE__,'debug',join $/, "intended recordings:", @files); my @recorded = grep { my ($name, $version) = /([^\/]+)_(\d+).wav$/; if (-e ) { if (-s > 44100) { # 0.5s x 16 bits x 44100/s logpkg(__FILE__,__LINE__,'debug',"File size >44100 bytes: $_"); $tn{$name}->set(version => $version) if $tn{$name}; $ui->update_version_button($tn{$name}->n, $version); 1; } else { unlink $_; 0 } } } @files; if(@recorded){ restart_wav_memoize(); pager(join $/, "recorded:",@recorded); } map{ _get_wav_info($_) } @recorded; @recorded } 1; __END__Audio-Nama-1.208/lib/Audio/Nama/Modes.pm0000644000175000017500000000572312644673574016616 0ustar jrothjroth# ----------- Modes: mastering, preview, doodle --------- package Audio::Nama; use Modern::Perl; { sub set_preview_mode { # set preview mode, releasing doodle mode if necessary logsub("&preview"); # do nothing if already in 'preview' mode return if $mode->preview; $mode->{preview} = "preview"; pager( <<'MSG'); Setting preview mode. Using both REC and PLAY inputs. WAV recording is DISABLED. Type 'arm' to enable recording. MSG } sub set_doodle_mode { logsub("&doodle"); return if engine_running() and Audio::Nama::ChainSetup::really_recording(); $mode->{preview} = "doodle"; $tn{Mixdown}->set(rw => OFF); # reconfigure_engine will generate setup and start transport pager( <<'MSG' ); Setting doodle mode. Using live inputs only, no duplicate inputs Exit using 'preview' or 'arm' commands MSG } sub exit_preview_mode { # exit preview and doodle modes logsub("&exit_preview_mode"); return unless $mode->{preview}; stop_transport() if engine_running(); pager("Exiting preview/doodle mode"); $mode->{preview} = 0; } sub master_on { return if $mode->mastering; # create mastering tracks if needed if ( ! $tn{Eq} ){ local $this_track; add_mastering_tracks(); add_mastering_effects(); } else { unhide_mastering_tracks(); map{ $ui->track_gui($tn{$_}->n) } @{$mastering->{track_names}}; } } sub master_off { return if ! $mode->mastering; hide_mastering_tracks(); map{ $ui->remove_track_gui($tn{$_}->n) } @{$mastering->{track_names}}; $this_track = $tn{Master} if grep{ $this_track->name eq $_} @{$mastering->{track_names}}; ; } sub add_mastering_tracks { map{ my $track = Audio::Nama::MasteringTrack->new( name => $_, rw => MON, group => 'Mastering', ); $ui->track_gui( $track->n ); } grep{ $_ ne 'Boost' } @{$mastering->{track_names}}; my $track = Audio::Nama::BoostTrack->new( name => 'Boost', rw => MON, group => 'Mastering', target => 'Master', ); $ui->track_gui( $track->n ); } sub add_mastering_effects { $this_track = $tn{Eq}; process_command("add_effect $mastering->{fx_eq}"); $this_track = $tn{Low}; process_command("add_effect $mastering->{fx_low_pass}"); process_command("add_effect $mastering->{fx_compressor}"); process_command("add_effect $mastering->{fx_spatialiser}"); $this_track = $tn{Mid}; process_command("add_effect $mastering->{fx_mid_pass}"); process_command("add_effect $mastering->{fx_compressor}"); process_command("add_effect $mastering->{fx_spatialiser}"); $this_track = $tn{High}; process_command("add_effect $mastering->{fx_high_pass}"); process_command("add_effect $mastering->{fx_compressor}"); process_command("add_effect $mastering->{fx_spatialiser}"); $this_track = $tn{Boost}; process_command("add_effect $mastering->{fx_limiter}"); # insert after vol } sub unhide_mastering_tracks { process_command("for Mastering; set_track hide 0 rw MON"); } sub hide_mastering_tracks { process_command("for Mastering; set_track hide 1 rw OFF"); } } 1; __END__Audio-Nama-1.208/lib/Audio/Nama/Fade.pm0000644000175000017500000002115312644673574016401 0ustar jrothjroth# ----------- Fade ------------ package Audio::Nama::Fade; use Modern::Perl; use List::Util qw(min); our $VERSION = 1.0; use Carp; use warnings; no warnings qw(uninitialized); our @ISA; use vars qw($n %by_index); use Audio::Nama::Globals qw(:singletons %tn @fade_data); use Audio::Nama::Log qw(logsub logpkg); use Audio::Nama::Effect qw(remove_effect add_effect update_effect); # we don't import 'type' as it would clobber our $fade->type attribute use Audio::Nama::Object qw( n type mark1 mark2 duration relation track class ); initialize(); sub initialize { %by_index = (); @fade_data = (); # for save/restore } sub next_n { my $n = 1; while( $by_index{$n} ){ $n++} $n } sub new { my $class = shift; my %vals = @_; croak "undeclared field: @_" if grep{ ! $_is_field{$_} } keys %vals; my $object = bless { # class => $class, # not needed yet n => next_n(), relation => 'fade_from_mark', @_ }, $class; $by_index{$object->n} = $object; logpkg(__FILE__,__LINE__,'debug',"object class: $class, object type: ", ref $object); my $id = add_fader($object->track); my $track = $tn{$object->track}; Audio::Nama::request_setup(); # runs apply_fades and reconfigures engine $object } # helper routines sub refresh_fade_controller { my $track = shift; my @pairs = fader_envelope_pairs($track); add_fader($track->name); my $operator = Audio::Nama::fxn($track->fader)->type; my $off_level = $config->{mute_level}->{$operator}; my $on_level = $config->{unity_level}->{$operator}; my @controllers = @{Audio::Nama::fxn($track->fader)->owns}; logpkg(__FILE__,__LINE__,'debug',$track->name, ": existing controllers: @controllers"); for my $controller (@controllers) { logpkg(__FILE__,__LINE__,'debug',"removing fade controller $controller"); remove_effect($controller); } # add controller my $reuseid = pop @controllers; # we expect only one logpkg(__FILE__,__LINE__,'debug',"applying fade controller"); add_effect({ track => $track, id => $reuseid, parent => $track->fader, type => 'klg', # Ecasound controller params => [ 1, # modify first parameter of fader op $off_level, $on_level, @pairs, ] }); # set fader to correct initial value # first fade is type 'in' : 0 # first fade is type 'out' : 100% update_effect($track->fader,0, initial_level($track->name) * 100) } sub all_fades { my $track_name = shift; sort { $Audio::Nama::Mark::by_name{$a->mark1}->{time} <=> $Audio::Nama::Mark::by_name{$b->mark1}->{time} } grep { $_->track eq $track_name } values %by_index } sub fades { # get fades within playable region my $track_name = shift; my $track = $tn{$track_name}; my @fades = all_fades($track_name); return @fades if ! $mode->{offset_run}; # handle offset run mode my @in_bounds; my $play_end = Audio::Nama::play_end_time(); my $play_start_time = Audio::Nama::play_start_time(); my $length = $track->wav_length; for my $fade (@fades){ my $play_end_time = $play_end ? min($play_end, $length) : $length; my $time = $Audio::Nama::Mark::by_name{$fade->mark1}->{time}; push @in_bounds, $fade if $time >= $play_start_time and $time <= $play_end_time; } @in_bounds } # our envelope must include a straight segment from the # beginning of the track (or region) to the fade # start. Similarly, we need a straight segment # from the last fade to the track (or region) end # - If the first fade is a fade-in, the straight # segment will be at zero-percent level # (otherwise 100%) # # - If the last fade is fade-out, the straight # segment will be at zero-percent level # (otherwise 100%) # although we can get the precise start and endpoints, # I'm using 0 and $track->shifted_playat_time + track length sub initial_level { # return 0, 1 or undef # 0: track starts silent # 1: track starts at full volume my $track_name = shift; my @fades = fades($track_name) or return undef; # if we fade in we'll hold level zero from beginning (scalar @fades and $fades[0]->type eq 'in') ? 0 : 1 } sub exit_level { my $track_name = shift; my @fades = fades($track_name) or return undef; # if we fade out we'll hold level zero from end (scalar @fades and $fades[-1]->type eq 'out') ? 0 : 1 } sub initial_pair { # duration: zero to... my $track_name = shift; my $init_level = initial_level($track_name); defined $init_level or return (); (0, $init_level ) } sub final_pair { # duration: .... to length my $track_name = shift; my $exit_level = exit_level($track_name); defined $exit_level or return (); my $track = $tn{$track_name}; ( $track->shifted_playat_time + $track->wav_length, $exit_level ); } sub fader_envelope_pairs { # return number_of_pairs, pos1, val1, pos2, val2,... my $track = shift; my @fades = fades($track->name); my @specs; for my $fade ( @fades ){ # calculate fades my $marktime1 = Audio::Nama::Mark::mark_time($fade->mark1); my $marktime2 = Audio::Nama::Mark::mark_time($fade->mark2); if ($marktime2) {} # nothing to do elsif( $fade->relation eq 'fade_from_mark') { $marktime2 = $marktime1 + $fade->duration } elsif( $fade->relation eq 'fade_to_mark') { $marktime2 = $marktime1; $marktime1 -= $fade->duration } else { $fade->dumpp; die "fade processing failed" } logpkg(__FILE__,__LINE__,'debug',"marktime1: $marktime1, marktime2: $marktime2"); push @specs, [ $marktime1, $marktime2, $fade->type, Audio::Nama::fxn($track->fader)->type, ]; } # sort fades - may not need this @specs = sort{ $a->[0] <=> $b->[0] } @specs; logpkg(__FILE__,__LINE__,'debug',sub{Audio::Nama::json_out( \@specs)}); my @pairs = map{ spec_to_pairs($_) } @specs; # WEIRD message - try to figure this out # XXX results in bug via AUTOLOAD for Edit # @pairs = (initial_pair($track->name), @pairs, final_pair($track->name)); # add flat segments # - from start to first fade # - from last fade to end # prepend number of pairs; unshift @pairs, (scalar @pairs / 2) if @pairs; @pairs; } # each 'spec' is an array reference of the form [ $from, $to, $type, $op ] # # $from: time (in seconds) # $to: time (in seconds) # $type: 'in' or 'out' # $op: 'ea' or 'eadb' sub spec_to_pairs { my ($from, $to, $type, $op) = @{$_[0]}; logpkg(__FILE__,__LINE__,'debug',"from: $from, to: $to, type: $type"); my $cutpos; my @pairs; # op 'eadb' uses two-stage fade if ($op eq 'eadb'){ if ( $type eq 'out' ){ $cutpos = $from + $config->{fade_time1_fraction} * ($to - $from); push @pairs, ($from, 1, $cutpos, $config->{fade_down_fraction}, $to, 0); } elsif( $type eq 'in' ){ $cutpos = $from + $config->{fade_time2_fraction} * ($to - $from); push @pairs, ($from, 0, $cutpos, $config->{fade_down_fraction}, $to, 1); } } # op 'ea' uses one-stage fade elsif ($op eq 'ea'){ if ( $type eq 'out' ){ push @pairs, ($from, 1, $to, 0); } elsif( $type eq 'in' ){ push @pairs, ($from, 0, $to, 1); } } else { die "missing or illegal fader op: $op" } @pairs } # the following routine makes it possible to # remove an edit fade by the name of the edit mark # ???? does it even work? sub remove_by_mark_name { my $mark1 = shift; my ($i) = map{ $_->n} grep{ $_->mark1 eq $mark1 } values %by_index; remove($i) if $i; } sub remove_by_index { my $i = shift; my $fade = $by_index{$i}; $fade->remove; } sub remove { my $fade = shift; my $track = $tn{$fade->track}; my $i = $fade->n; # remove object from index delete $by_index{$i}; # remove fader entirely if this is the last fade on the track my @track_fades = all_fades($fade->track); if ( ! @track_fades ){ remove_effect($track->fader); $tn{$fade->track}->set(fader => undef); } else { refresh_fade_controller($track) } } sub add_fader { # if it is missing my $name = shift; my $track = $tn{$name}; my $id = $track->fader; # create a fader if necessary, place before first effect # if it exists if (! $id or ! Audio::Nama::fxn($id)){ my $first_effect = $track->ops->[0]; $id = add_effect({ before => $first_effect, track => $track, type => $config->{fader_op}, params => [0], # XX hardcoded for -ea chain operator }); $track->set(fader => $id); } $id } package Audio::Nama; sub fade_uses_mark { my $mark_name = shift; grep{ $_->mark1 eq $mark_name or $_->mark2 eq $mark_name } values %Audio::Nama::Fade::by_index; } sub apply_fades { # + data from Fade objects residing in %Audio::Nama::Fade::by_name # + apply to tracks # * that are part of current chain setup # * that have a fade operator (i.e. most user tracks) map{ Audio::Nama::Fade::refresh_fade_controller($_) } grep{$_->{fader} } Audio::Nama::ChainSetup::engine_tracks(); } 1;Audio-Nama-1.208/lib/Audio/Nama/MuteSoloFade.pm0000644000175000017500000000544612644673574020100 0ustar jrothjroth# ------------- Mute and Solo routines ----------- package Audio::Nama; use Modern::Perl; sub mute { return if $config->{opts}->{F}; return if $tn{Master}->rw eq OFF or Audio::Nama::ChainSetup::really_recording(); $tn{Master}->mute; } sub unmute { return if $config->{opts}->{F}; return if $tn{Master}->rw eq OFF or Audio::Nama::ChainSetup::really_recording(); $tn{Master}->unmute; } sub fade_around { my ($coderef, @args) = @_; if( engine_running() ) { mute(); $coderef->(@args); unmute(); } else { $coderef->(@args) } } sub solo { my @args = @_; # get list of already muted tracks if I haven't done so already if ( ! @{$fx->{muted}} ){ @{$fx->{muted}} = map{ $_->name } grep{ defined $_->old_vol_level} user_tracks() } logpkg(__FILE__,__LINE__,'debug', join " ", "already muted:", sub{map{$_->name} @{$fx->{muted}}}); # convert bunches to tracks my @names = map{ bunch_tracks($_) } @args; # use hashes to store our list my %to_mute; my %not_mute; # get dependent tracks my @dependents = map{ $tn{$_}->bus_tree() } @names; # store solo tracks and dependent tracks that we won't mute map{ $not_mute{$_}++ } @names, @dependents; # find all siblings tracks not in depends list # - get buses list corresponding to our non-muting tracks my %buses; $buses{Main}++; # we always want Main map{ $buses{$_}++ } # add to buses list map { $tn{$_}->group } # corresponding bus (group) names keys %not_mute; # tracks we want # - get sibling tracks we want to mute map{ $to_mute{$_}++ } # add to mute list grep{ ! $not_mute{$_} } # those we *don't* want map{ $bn{$_}->tracks } # tracks list keys %buses; # buses list # mute all tracks on our mute list (do we skip already muted tracks?) do_many_tracks( { tracks => [ keys %to_mute ], method => 'mute' } ); # unmute all tracks on our wanted list do_many_tracks( { tracks => [ keys %not_mute ], method => 'unmute' } ); $mode->{soloing} = 1; } sub nosolo { # unmute all except in @{$fx->{muted}} list # unmute all tracks do_many_tracks( { tracks => [ map{$_->name} user_tracks() ], method => 'unmute' } ); # re-mute previously muted tracks if (@{$fx->{muted}}){ do_many_tracks( { tracks => [ @{$fx->{muted}} ], method => 'mute' } ); } # remove listing of muted tracks @{$fx->{muted}} = (); $mode->{soloing} = 0; } sub all { # unmute all tracks do_many_tracks( { tracks => [ Audio::Nama::Track::user() ], method => 'unmute' } ); # remove listing of muted tracks @{$fx->{muted}} = (); $mode->{soloing} = 0; } sub do_many_tracks { # args: { tracks => [ track objects ], method => method_name } my $args = shift; my $method = $args->{method}; my $delay = $args->{delay} || $config->{engine_muting_time}; map{ $tn{$_}->$method('nofade'); sleeper($delay) } @{$args->{tracks}}; } 1; __END__Audio-Nama-1.208/lib/Audio/Nama/Lat.pm0000644000175000017500000000130712644673574016261 0ustar jrothjrothpackage Audio::Nama::Lat; use Modern::Perl; our @ISA; use Data::Dumper::Concise; use overload '+' => \&add_latency, "\"\"" => sub { join ' ',$_[0]->min, $_[0]->max }; sub new { my $class = shift; my ($min, $max) = @_; defined $min and defined $max or die "undefined field: min: $min or max; $max"; die "Lat object has Min ($min) greater than Max ($max)" if $min > $max; my $self = bless [$min, $max], $class; $self; } sub add_latency { my (@latencies) = @_[0,1]; # throw away swap argument my ($min, $max) = (0,0); map{ $min += $_->min; $max += $_->max } @latencies; Audio::Nama::Lat->new($min, $max); } sub min {$_[0]->[0] } sub max {$_[0]->[1] } sub values { $_[0]->min, $_[0]->max } 1; __END__Audio-Nama-1.208/lib/Audio/Nama/ChainSetup.pm0000644000175000017500000004255112644673574017612 0ustar jrothjroth# ---------- ChainSetup----------- package Audio::Nama::ChainSetup; use Audio::Nama::Globals qw($file $config $jack $setup $this_engine %tn %bn $mode :trackrw); use Audio::Nama::Log qw(logsub logpkg); use Modern::Perl; use Data::Dumper::Concise; use Storable qw(dclone); use Audio::Nama::Util qw(signal_format input_node output_node); use Audio::Nama::Assign qw(json_out); no warnings 'uninitialized'; our ( $g, # routing graph object - # based on project data # the routing graph is generated, # then traversed over, and integrated # with track data to generate # Audio::Nama::IO objects. Audio::Nama::IO objects are iterated # over to generate # the Ecasound chain setup text (c.f. chains command) @io, # IO objects corresponding to chain setup %is_ecasound_chain, # chains in final chain seutp # for sorting final result %inputs, %outputs, %post_input, %pre_output, # for final result @input_chains, # list of input chain segments @output_chains, # list of output chain segments @post_input, # post-input chain operators @pre_output, # pre-output chain operators $chain_setup, # final result as string ); sub remove_temporary_tracks { logsub("&remove_temporary_tracks"); map { logpkg(__FILE__,__LINE__,'debug',"removing temporary track ",$_->name); $_->remove } grep{ $_->group eq 'Temp'} Audio::Nama::audio_tracks(); } sub initialize { remove_temporary_tracks(); # we will generate them again $setup->{audio_length} = 0; @io = (); # IO object list Audio::Nama::IO::initialize(); $g = Graph->new(); %inputs = %outputs = %post_input = %pre_output = (); %is_ecasound_chain = (); @input_chains = @output_chains = @post_input = @pre_output = (); undef $chain_setup; Audio::Nama::disable_length_timer(); reset_aux_chain_counter(); unlink $file->chain_setup; $g; } sub ecasound_chain_setup { $chain_setup } sub is_ecasound_chain { $is_ecasound_chain{$_[0]} } sub engine_tracks { # tracks that belong to current chain setup map{$Audio::Nama::ti{$_}} grep{$Audio::Nama::ti{$_}} keys %is_ecasound_chain; } sub is_engine_track { # takes Track object, name or index # returns object if corresponding track belongs to current chain setup my $t = shift; my $n; if( (ref $t) =~ /Track/){ $n = $t->n } if( $t =~ ! /\D/ ) { $n = $t } if( $t =~ /\D/ and $tn{$_} ){ $n = $Audio::Nama::tn{$t}->n} $Audio::Nama::ti{$n} if $is_ecasound_chain{$n} } sub engine_wav_out_tracks { grep{$_->rec_status eq REC} engine_tracks(); } # return file output entries, including Mixdown sub really_recording { my @files = map{ /-o:(.+?\.wav)$/} grep{ /-o:/ and /\.wav$/} split "\n", $chain_setup; wantarray() ? @files : scalar @files; } sub show_io { my $output = json_out( \%inputs ). json_out( \%outputs ); Audio::Nama::pager( $output ); } sub generate_setup_try { logsub("&generate_setup_try"); my $extra_setup_code = shift; # in an ideal CS world, all of the following routing # routines (add_paths_for_*) would be accomplished by # the track or bus itself, rather than handcoded below. # start with bus routing map{ $_->apply($g) } Audio::Nama::Bus::all(); logpkg(__FILE__,__LINE__,'debug',"Graph after bus routing:\n$g"); # now various manual routing add_paths_for_aux_sends(); logpkg(__FILE__,__LINE__,'debug',"Graph after aux sends:\n$g"); add_paths_from_Master(); logpkg(__FILE__,__LINE__,'debug',"Graph with paths from Master:\n$g"); add_paths_for_mixdown_handling(); logpkg(__FILE__,__LINE__,'debug',"Graph with mixdown mods:\n$g"); # run extra setup $extra_setup_code->($g) if $extra_setup_code; prune_graph(); logpkg(__FILE__,__LINE__,'debug',"Graph after pruning unterminated branches:\n$g"); Audio::Nama::Graph::expand_graph($g); logpkg(__FILE__,__LINE__,'debug',"Graph after adding loop devices:\n$g"); # insert handling Audio::Nama::Graph::add_inserts($g); logpkg(__FILE__,__LINE__,'debug',"Graph with inserts:\n$g"); # Mix tracks to mono if Master is mono # (instead of just throwing away right channel) if ($g->has_vertex('Master') and $tn{Master}->width == 1) { $g->set_vertex_attribute('Master', 'ecs_extra' => '-chmix:1') } #logpkg(__FILE__,__LINE__,'info',sub{"Graph object dump:\n",Dumper($g)}); # create IO lists %inputs and %outputs if ( process_routing_graph() ){ write_chains(); 1 } else { Audio::Nama::throw("No tracks to record or play."); 0 } } sub add_paths_for_aux_sends { # currently this routing is track-oriented # we could add this to the Audio::Nama::Bus base class # then suppress it in Mixdown and Master groups logsub("&add_paths_for_aux_sends"); map { Audio::Nama::Graph::add_path_for_aux_send($g, $_ ) } grep { (ref $_) !~ /Slave/ and $_->group !~ /Mixdown|Master/ and $_->send_type and $_->rec_status ne OFF } Audio::Nama::audio_tracks(); } sub add_paths_from_Master { logsub("&add_paths_from_Master"); if ($mode->mastering){ $g->add_path(qw[Master Eq Low Boost]); $g->add_path(qw[Eq Mid Boost]); $g->add_path(qw[Eq High Boost]); } my $final_leg_origin = $mode->mastering ? 'Boost' : 'Master'; $g->add_path($final_leg_origin, output_node($tn{Master}->send_type)) if $tn{Master}->rw ne OFF } sub add_paths_for_mixdown_handling { logsub("&add_paths_for_mixdown_handling"); if ($tn{Mixdown}->rec_status eq REC){ # don't monitor via soundcard $g->delete_edge('Master','soundcard_out'); my @p = (($mode->mastering ? 'Boost' : 'Master'), ,'Mixdown', 'wav_out'); $g->add_path(@p); $g->set_vertex_attributes('Mixdown', { format_template => $config->{mix_to_disk_format}, chain_id => "Mixdown" }, ); # no effects will be applied because effects are on chain 2 # Mixdown handling - playback } elsif ($tn{Mixdown}->rec_status eq PLAY){ my @e = ('wav_in','Mixdown',output_node($tn{Master}->send_type)); $g->add_path(@e); $g->set_vertex_attributes('Mixdown', { send_type => $tn{Master}->send_type, send_id => $tn{Master}->send_id, chain => "Mixdown" }); # no effects will be applied because effects are on chain 2 } } sub prune_graph { logsub("&prune_graph"); Audio::Nama::Graph::simplify_send_routing($g); logpkg(__FILE__,__LINE__,'debug',"Graph after simplify_send_routing:\n$g"); Audio::Nama::Graph::remove_out_of_bounds_tracks($g) if Audio::Nama::edit_mode(); logpkg(__FILE__,__LINE__,'debug',"Graph after remove_out_of_bounds_tracks:\n$g"); Audio::Nama::Graph::recursively_remove_inputless_tracks($g); logpkg(__FILE__,__LINE__,'debug',"Graph after recursively_remove_inputless_tracks:\n$g"); Audio::Nama::Graph::recursively_remove_outputless_tracks($g); logpkg(__FILE__,__LINE__,'debug',"Graph after recursively_remove_outputless_tracks:\n$g"); } # object based dispatch from routing graph sub process_routing_graph { logsub("&process_routing_graph"); # generate a set of IO objects from edges @io = map{ dispatch($_) } $g->edges; logpkg(__FILE__,__LINE__,'debug', sub{ join "\n",map $_->dump, @io }); # sort chain_ids by attached input object # one line will show all with that one input # -a:3,5,6 -i:foo map { $inputs{$_->ecs_string} //= []; push @{$inputs{$_->ecs_string}}, $_->chain_id; # post-input modifiers $post_input{$_->chain_id} = $_->ecs_extra if $_->ecs_extra; } grep { $_->direction eq 'input' } @io; # sort chain_ids by output map { $outputs{$_->ecs_string} //= []; push @{$outputs{$_->ecs_string}}, $_->chain_id; # pre-output modifers $pre_output{$_->chain_id} = $_->ecs_extra if $_->ecs_extra; } grep { $_->direction eq 'output' } @io; no warnings 'numeric'; my @in_keys = values %inputs; my @out_keys = values %outputs; use warnings 'numeric'; %is_ecasound_chain = map{ $_, 1} map{ @$_ } values %inputs; # sort entries into an aesthetic order my %rinputs = reverse %inputs; my %routputs = reverse %outputs; @input_chains = sort map {'-a:'.join(',',sort by_chain @$_)." $rinputs{$_}"} @in_keys; @output_chains = sort map {'-a:'.join(',',sort by_chain @$_)." $routputs{$_}"} @out_keys; @post_input = sort by_index map{ "-a:$_ $post_input{$_}"} keys %post_input; @pre_output = sort by_index map{ "-a:$_ $pre_output{$_}"} keys %pre_output; @input_chains + @output_chains # to sense empty chain setup } { my ($m,$n,$o,$p,$q,$r); sub by_chain { ($m,$n,$o) = $a =~ /(\D*)(\d+)(\D*)/ ; ($p,$q,$r) = $b =~ /(\D*)(\d+)(\D*)/ ; if ($n != $q){ $n <=> $q } elsif ( $m ne $p){ $m cmp $p } else { $o cmp $r } } } sub by_index { my ($i) = $a =~ /(\d+)/; my ($j) = $b =~ /(\d+)/; $i <=> $j } sub non_track_dispatch { # loop -> loop # # assign chain_id to edge based on chain_id of left-side loop's # corresponding track: # # hihat_out -- J7a -> Master_in # # soundcard_in -> wav_out (rec_file) # # currently handled using an anonymous track # # we expect edge attributes # to have been provided for handling this. # loop -> soundcard_out # # track7-soundcard_out as aux_send will have chain id S7 # that will be transferred by expand_graph() to # the new edge, loop-soundcard-out # we will issue two IO objects, one for the chain input # fragment, one for the chain output my $edge = shift; logpkg(__FILE__,__LINE__,'debug',"non-track IO dispatch:",join ' -> ',@$edge); my $eattr = $g->get_edge_attributes(@$edge) // {}; logpkg(__FILE__,__LINE__,'debug',"found edge attributes: ",json_out($eattr)) if $eattr; my $vattr = $g->get_vertex_attributes($edge->[0]) // {}; logpkg(__FILE__,__LINE__,'debug',"found vertex attributes: ",json_out($vattr)) if $vattr; if ( ! $eattr->{chain_id} and ! $vattr->{chain_id} ){ my $n = $eattr->{n} || $vattr->{n}; $eattr->{chain_id} = jumper_count($n); } my @direction = qw(input output); map{ my $direction = shift @direction; my $class = Audio::Nama::IO::get_class($_, $direction); my $attrib = {%$vattr, %$eattr}; $attrib->{endpoint} //= $_ if Audio::Nama::Graph::is_a_loop($_); logpkg(__FILE__,__LINE__,'debug',"non-track: $_, class: $class, chain_id: $attrib->{chain_id},","device_id: $attrib->{device_id}"); my $io = $class->new($attrib ? %$attrib : () ) ; $g->set_edge_attribute(@$edge, $direction, $io); $io; } @$edge; } { ### counter for jumper chains # # sequence: J1 J1a J1b J1c, J2, J3, J4, J4d, J4e my %used; my $counter; my $prefix = 'J'; reset_aux_chain_counter(); sub reset_aux_chain_counter { %used = (); $counter = 'a'; } sub jumper_count { my $track_index = shift; my $try1 = $prefix . $track_index; $used{$try1}++, return $try1 unless $used{$try1}; $try1 . $counter++; } } sub dispatch { # creates an IO object from a graph edge my $edge = shift; return non_track_dispatch($edge) if not grep{ $tn{$_} } @$edge ; logpkg(__FILE__,__LINE__,'debug','dispatch: ',join ' -> ', @$edge); my($name, $endpoint, $direction) = decode_edge($edge); logpkg(__FILE__,__LINE__,'debug',"name: $name, endpoint: $endpoint, direction: $direction"); my $track = $tn{$name}; my $class = Audio::Nama::IO::get_class( $endpoint, $direction ); # we need the $direction because there can be # edges to and from loop,Master_in my @args = (track => $name, endpoint => massaged_endpoint($track, $endpoint, $direction), chain_id => $tn{$name}->n, # default override($name, $edge)); # priority: edge > node #say "dispatch class: $class"; my $io = $class->new(@args); $g->set_edge_attribute(@$edge, $direction => $io ); $io } sub massaged_endpoint { my ($track, $endpoint, $direction) = @_; if ( $endpoint =~ /^(loop_in|loop_out)$/ ){ my $final = ($direction eq 'input' ? $track->source_id : $track->send_id ); $final =~ s/^loop,//; $final } else { $endpoint } } sub decode_edge { # assume track-endpoint or endpoint-track # return track, endpoint my ($a, $b) = @{$_[0]}; #say "a: $a, b: $b"; my ($name, $endpoint) = $tn{$a} ? @{$_[0]} : reverse @{$_[0]} ; my $direction = $tn{$a} ? 'output' : 'input'; ($name, $endpoint, $direction) } sub override { # data from edges has priority over data from vertexes # we specify $name, because it could be left or right # vertex logsub("&override"); my ($name, $edge) = @_; (override_from_vertex($name), override_from_edge($edge)) } sub override_from_vertex { my $name = shift; warn("undefined graph\n"), return () unless (ref $g) =~ /Graph/; my $attr = $g->get_vertex_attributes($name); $attr ? %$attr : (); } sub override_from_edge { my $edge = shift; warn("undefined graph\n"), return () unless (ref $g) =~ /Graph/; my $attr = $g->get_edge_attributes(@$edge); $attr ? %$attr : (); } sub write_chains { logsub("&write_chains"); ## write general options my $globals .= join " ", $config->{engine_globals}->{common}, join(',', '-G:jack',$this_engine->name,$this_engine->jack_transport_mode), "-b",$config->buffersize, $config->globals_realtime; my $format = signal_format($config->{devices}->{jack}->{signal_format},2); $globals .= " -f:$format" if $jack->{jackd_running}; my $ecs_file = join "\n\n", "# ecasound chainsetup file", "# general", $globals, "# audio inputs", join("\n", @input_chains), ""; $ecs_file .= join "\n\n", "# post-input processing", join("\n", @post_input), "" if @post_input; $ecs_file .= join "\n\n", "# pre-output processing", join("\n", @pre_output), "" if @pre_output; $ecs_file .= join "\n\n", "# audio outputs", join("\n", @output_chains), ""; logpkg(__FILE__,__LINE__,'debug',"Chain setup:\n",$ecs_file); open(my $fh, ">", $file->chain_setup) or die("can't open chain setup file ".$file->chain_setup.": $!"); print $fh $ecs_file; close $fh; $chain_setup = $ecs_file; } sub setup_requires_realtime { my $prof = $config->{realtime_profile}; if( $prof eq 'auto'){ grep{ ! $_->is_mix_track and $_->is_user_track and $_->rec_status =~ /REC|MON/ } Audio::Nama::audio_tracks() } elsif ( $prof eq 'realtime') { my @fields = qw(soundcard jack_client jack_manual jack_ports_list); grep { has_vertex("$_\_in") } @fields or grep { has_vertex("$_\_out") } @fields } elsif ( $prof eq 'nonrealtime' or !$prof){} } sub has_vertex { $g->has_vertex($_[0]) } 1; =head1 NAME Audio::Nama::ChainSetup - routines for generating Ecasound chain setup =head2 Overview For the Ecasound engine to run, it must be configured into a signal processing network. This configuration is called a "chain setup". It is a graph comprised of multiple signal processing chains, each of which consists of exactly one input and one output. When user input requires a change of configuration, Nama generates an new chain setup file. These files are guaranteed to be consistent with the rules of Ecasound's routing language. After initializing the data structures, Nama iterates over project tracks and buses to create a first-stage graph. This graph is successively transformed as more routing details are added, then each edge of the graph is processed into a pair of IO objects--one for input and one for output--that together constitute an Ecasound chain. With a bit more processing, the configuration is written out as text in the chain setup file. =head2 The Graph and its Transformations Generating a chain setup starts with each bus iterating over its member tracks, and connecting them to its mix track. (See man Audio::Nama::Bus.) In the case of one track belonging to the Main (default) bus, the initial graph would be: soundcard_in -> sax -> Master -> soundcard_out "soundcard_in" and "soundcard_out" will eventually be mapped to the appropriate JACK or ALSA source, depending on whether jackd is running. The Master track hosts the master fader, connects to the main output, and serves as the mix track for the Main bus. If we've asked to record the input, we automatically get this route: soundcard_in -> sax-rec-file -> wav_out The track 'sax-rec-file' is a temporary clone (slave) of track 'sax' and connects to all the same inputs. A 'send' (for example, a instrument monitor for the sax player) generates this additional route: sax -> soundcard_out Ecasound requires that we insert a loop device where signals fan out or fan in. soundcard_in -> sax -> sax_out -> Master -> soundcard_out sax_out -> soundcard_out Here 'sax_out' is a loop device. (Note that we prohibit track names matching *_out or *_in.) Inserts are incorporated by replacing the edge either before or after a track vertex with a network of auxiliary tracks and loop devices. (See man Audio::Nama::Insert.) Unterminated parts of the network are discarded. Then redundant loop devices are removed from the graph to minimize latency. =head2 Dispatch After routing is complete, Nama iterates over the graph's edges, transforming them into pairs of IO objects that become the inputs and outputs of Ecasound chains. To create an Ecasound chain from Master -> soundcard_out Nama uses 'Master' track attributes to provide data. For example track index (1) serves as the chain_id, and the track's send settings determine the soundcard channel or other destination. Some edges are without a track at either terminal. For example this auxiliary send: sax_out -> soundcard_out In this case, the track, chain_id and other data can be specified as vertex or edge attributes. Edge attributes override vertex attributes, which override track attributes. This allows routing to be edited and annotated to behaviors different from what the track wants. When a temporary track is used for recording, for example sax-rec-file -> wav_out The 'sax-rec-file' vertex is assigned the 'chain_id' attribute 'R3' rather than the track index assigned to 'sax-rec-file'. Audio-Nama-1.208/lib/Audio/Nama/Latency.pm0000644000175000017500000003152612644673574017146 0ustar jrothjroth# ----------- Latency Compensation ----------- package Audio::Nama; use Modern::Perl; no warnings 'uninitialized'; use Audio::Nama::Globals qw(:all); use Storable qw(dclone); use List::Util qw(max); use Carp qw(confess); my $lg; # latency_graph, alias to $jack->{graph} latency_memoize(); sub initialize_jack_graph { # make our own copy of the signal network, and an alias $lg = $jack->{graph} = dclone($g); # remove record-to-disk branches of the graph # which are unrelated to latency compensation remove_connections_to_wav_out($lg); # want to deal with specific ports, # so substitute them into the graph replace_terminals_by_jack_ports($lg); } sub propagate_latency { logsub('&propagate_latency'); initialize_jack_graph(); logpkg(__FILE__,__LINE__,'debug',"jack graph\n","$lg"); parse_port_connections(); start_latency_watcher(); propagate_capture_latency(); #propagate_playback_latency(); } sub propagate_capture_latency { my @sinks = grep{ $lg->is_sink_vertex($_) } $lg->vertices(); logpkg(__FILE__,__LINE__,'debug',"recurse through latency graph starting at sinks: @sinks"); latency_rememoize(); map{ latency_of($lg,'capture',$_) } @sinks; } sub propagate_playback_latency { logsub('&propagate_playback_latency'); logpkg(__FILE__,__LINE__,'debug',"jack graph\n","$lg"); my @sources = grep{ $lg->is_source_vertex($_) } $lg->vertices(); logpkg(__FILE__,__LINE__,'debug',"recurse through latency graph starting at sources: @sources"); latency_rememoize(); map{ latency_of($lg,'playback',$_) } @sources; } sub predecessor_latency { scalar @_ > 2 and die "too many args to predecessor_latency: @_"; my ($g, $v) = @_; my $latency = latency_of($g, 'capture', $g->predecessors($v)); logpkg(__FILE__,__LINE__,'debug',"$v: predecessor latency is $latency"); $latency; } sub successor_latency { scalar @_ > 2 and die "too many args to successor_latency: @_"; my ($g, $v) = @_; my $latency = latency_of($g, 'playback', $g->successors($v)); logpkg(__FILE__,__LINE__,'debug',"$v: successor latency is $latency"); $latency } sub latency_of { my ($g, $direction, @v) = @_; if ($direction eq 'capture' and $g->is_sink_vertex(@v)){ die "too many args: @v" if scalar @v > 1; my $latency = predecessor_latency($g, @v); set_capture_latency($latency->values, jack_port_to_nama(@v)); $latency } elsif($direction eq 'playback' and $g->is_source_vertex(@v)){ die "too many args: @v" if scalar @v > 1; my $latency = successor_latency($g,@v); set_playback_latency($latency->values, jack_port_to_nama(@v)); $latency } elsif(scalar @v == 1){ self_latency($g, $direction, @v) } elsif(scalar @v > 1){ sibling_latency($g, $direction, @v) } } sub track_ops_latency { my $track = shift; my $total = 0;; map { $total += op_latency($_) } $track->fancy_ops; Audio::Nama::Lat->new($total,$total); } sub op_latency { my $op = shift; my $FX = fxn($op); return 0 if $FX->is_controller; # skip controllers my $p = latency_param($op); defined $p and ! $FX->bypassed ? get_live_param($op, $p) : 0 } sub loop_device_latency { Audio::Nama::Lat->new($config->buffersize, $config->buffersize) } sub input_latency { my $port = shift; my $latency = get_capture_latency($port); carp("port $port, asymmetrical latency $latency found\n") if is_asymmetrical($latency); set_capture_latency($latency->values, jack_port_to_nama($port)); $latency } sub is_asymmetrical { my $lat = shift; $lat->min != $lat->max } { my %loop_adjustment; sub sibling_latency { my ($g, $direction, @siblings) = @_; logpkg(__FILE__,__LINE__,'debug',"direction: $direction, Siblings were: @siblings"); if ($direction eq 'capture'){ %loop_adjustment = (); #@siblings = map{ advance_sibling($g, $_) } @siblings; logpkg(__FILE__,__LINE__,'debug',"Siblings are now: @siblings"); my $max = max map {$_->max} map{ self_latency($g, $direction, $_) } @siblings; logpkg(__FILE__,__LINE__,'debug',"$max frames max latency among siblings: @siblings"); for (@siblings) { my $latency = self_latency($g, $direction, $_); my $delay = $max - $latency->max; logpkg(__FILE__,__LINE__,'debug',"$_: self latency: $latency frames"); logpkg(__FILE__,__LINE__,'debug',"$_: delay $delay frames"); compensate_latency($tn{$_},$delay); } Audio::Nama::Lat->new($max,$max); } elsif ($direction eq 'playback'){ my ($final_min, $final_max); for (@siblings){ my $latency = self_latency($g, $direction, $_); my ($min,$max) = $latency->values; $final_min //= $min; $final_min = $min if $min < $final_min; $final_max //= $max; $final_max = $max if $max > $final_max; } $final_min, $final_max } else { die "missing or illegal direction: $direction" } } # not object method sub loop_adjustment { my $trackname = shift; my $delta = $loop_adjustment{$trackname} || 0; Audio::Nama::Lat->new($delta, $delta) } sub self_latency { my ($g, $direction, $node_name) = @_; return input_latency($node_name) if $g->is_source_vertex($node_name); my $latency = my $predecessor_or_successor_latency = $direction eq 'capture' ? predecessor_latency($g, $node_name) : successor_latency($g, $node_name); ref $latency eq 'Audio::Nama::Lat' or die "wrong type for $node_name".Dumper $latency; return( $predecessor_or_successor_latency + track_ops_latency($tn{$node_name}) + loop_adjustment($node_name) + Audio::Nama::Insert::soundcard_delay($node_name) # if we're a wet return track and insert is # a hardware type, i.e. via the soundcard ) if Audio::Nama::Graph::is_a_track($node_name); return( $predecessor_or_successor_latency + loop_device_latency() ) if Audio::Nama::Graph::is_a_loop($node_name); die "shouldn't reach here\nnodename: $node_name, graph:$g"; } } sub remove_connections_to_wav_out { my $g = shift; Audio::Nama::Graph::remove_branch($g,'wav_out'); Audio::Nama::Graph::remove_isolated_vertices($g); } sub replace_terminals_by_jack_ports { my $g = shift; my @sinks = grep{ $g->is_sink_vertex($_) } $g->vertices(); my @sources = grep{ $g->is_source_vertex($_) } $g->vertices(); for my $sink (@sinks) { #logpkg(__FILE__,__LINE__,'debug') logpkg(__FILE__,__LINE__,'debug',"found sink $sink"); my @predecessors = $g->predecessors($sink); logpkg(__FILE__,__LINE__,'debug',"preceeded by: @predecessors"); my @edges = map{ [$_, $sink] } @predecessors; ; logpkg(__FILE__,__LINE__,'debug',"edges: ",json_out(\@edges)); for my $edge ( @edges ) { logpkg(__FILE__,__LINE__,'debug',"edge: @$edge"); my $output = $g->get_edge_attribute(@$edge, "output") || $g->get_vertex_attribute($edge->[0], "output"); logpkg(__FILE__,__LINE__,'debug',Dumper $output); logpkg(__FILE__,__LINE__,'debug', join " ", "JACK client:", $output->client, $output->ports); $g->delete_edge(@$edge); for my $port($output->ports()){ $g->add_edge($edge->[0], $port); #$g->set_edge_attribute($edge->[0], $port, "output", $output); } } } for my $source (@sources) { #logpkg(__FILE__,__LINE__,'debug') logpkg(__FILE__,__LINE__,'debug',"found source $source"); my @successors = $g->successors($source); logpkg(__FILE__,__LINE__,'debug',"succeeded by: @successors"); my @edges = map{ [$source, $_] } @successors; ; logpkg(__FILE__,__LINE__,'debug',"edges: ",json_out(\@edges)); for my $edge ( @edges ) { my $input = $g->get_edge_attribute(@$edge, "input") ; logpkg(__FILE__,__LINE__,'debug',Dumper $edge, Dumper $input); logpkg(__FILE__,__LINE__,'debug', join " ", "JACK client:", $input->client, $input->ports); $g->delete_edge(@$edge); for my $port($input->ports()){ $g->add_edge($port, $edge->[1]); #$g->set_edge_attribute($port, $edge->[1], "input", $input); } } } Audio::Nama::Graph::remove_isolated_vertices($g); } ###### # # remove (or reset) latency operators # generate and connect setup # determine latency # add (or set) operators # (to optimize: add operators only to plural sibling edges, not only edges) sub compensate_latency { my $track = shift; my $delay = shift || 0; my $units = shift; # because of brass_out -> system:playback_1, we # need to advance past brass_out and do # latency compensation on 'brass' instead, # adding in the loop device. my $id = $track->latency_op || add_latency_compensation_op ( $track ); # execute coderef to modify effect, adjusting for units # assume frames by default # but don't convert to frames if $delay is 0 $config->{latency_op_set}->( $id, (! $delay or $units =~ /^s/i) ? $delay : frames_to_secs($delay) ); $id; } sub add_latency_compensation_op { # add the effect, and set the track's latency_op field my $track = shift; my @args = @_; @args or @args = (2,0); my $id = $track->latency_op; # create a delay effect if necessary, place before first effect # if it exists if (! $id){ my $first_effect = $track->ops->[0]; $id = add_effect({ before => $first_effect, track => $track, type => $config->{latency_op}, params => \@args, }); $track->set(latency_op => $id); } $id } sub reset_latency_compensation { map{ compensate_latency($_, 0) } grep{ $_->latency_op } Audio::Nama::audio_tracks(); } { my %reverse = qw(input output output input); sub jack_port_latency { my ($dir, $name) = @_; my $direction; $direction = 'capture' if $dir eq 'input'; $direction = 'playback' if $dir eq 'output'; $direction or confess "$direction: illegal or missing direction"; logpkg(__FILE__,__LINE__,'debug', "name: $name, dir: $dir, direction: $direction"); if ($name !~ /:/) { # we have only the client name, i.e. "system" # pick a port from the ports list logpkg(__FILE__,__LINE__,'debug',"$name is client desriptor, lacks specific port"); # replace with a full port descriptor, i.e. "system:playback_1" # but reverse direction for this: my $node = jack_client($name); $name = $node->{$reverse{$dir}}->[0]; logpkg(__FILE__,__LINE__,'debug', "replacing with $name"); } my ($client, $port) = client_port($name); logpkg(__FILE__,__LINE__,'debug',"name: $name, client: $client, port: $port, dir: $dir, direction: $direction"); my $node = jack_client($client) or Audio::Nama::pager_newline("$name: non existing JACK client"), return; $node->{$port}->{latency}->{$direction}->{min} ne $node->{$port}->{latency}->{$direction}->{max} and Audio::Nama::pager_newline('encountered unmatched latencies', sub{ json_out($node) }); $node->{$port}->{latency}->{$direction}->{min} } } sub latency_param { my $op = shift; my $i = effect_index(type($op)); my $p = 0; for my $param ( @{ $fx_cache->{registry}->[$i]->{params} } ) { $p++; return $p if lc( $param->{name}) eq 'latency' and $param->{dir} eq 'output'; } undef } sub get_live_param { # for effect, not controller # $param is position, starting at one local $config->{category} = 'ECI_FX'; my ($op, $param) = @_; my $FX = fxn($op); my $n = $FX->chain; my $i = $FX->ecasound_effect_index; eval_iam("c-select $n"); eval_iam("cop-select $i"); eval_iam("copp-select $param"); eval_iam("copp-get") } sub frames_to_secs { # One time conversion for delay op my $frames = shift; $frames / $config->{sample_rate}; } sub start_latency_watcher { $jack->{watcher} ||= jacks::JsClient->new("Nama latency manager", undef, $jacks::JackNullOption, 0); } sub get_latency { my ($pname, $direction) = @_; my %io = ( capture => $jacks::JackCaptureLatency, playback => $jacks::JackPlaybackLatency, ); my $port = $jack->{watcher}->getPort($pname); my $dir = $io{$direction}; die "illegal direction $direction" unless defined $dir; # get latency as Jacks objects my $latency = $port->getLatencyRange($dir); # convert to Nama object $latency = Audio::Nama::Lat->new($latency->min, $latency->max); } sub set_latency { my ($pname, $direction, $min, $max) = @_; my %io = ( capture => $jacks::JackCaptureLatency, playback => $jacks::JackPlaybackLatency, ); my $port = $jack->{watcher}->getPort($pname); my $dir = $io{$direction}; die "illegal direction $direction" unless defined $io{$direction}; $port->setLatencyRange($dir, $min, $max); my $latency = get_latency($pname, $direction); my ($gmin,$gmax) = $latency->values; logpkg(__FILE__,__LINE__,'debug',"set port $pname, $direction latency: $min, $max"); logpkg(__FILE__,__LINE__,'debug', ($min != $gmin and $max != $gmax) ? "Bad: got port $pname, $direction latency: $gmin, $gmax" : "Verified!" ); } sub set_multiport_latency { my ($direction, $min, $max, @pnames) = @_; map{ set_latency($_, $direction,$min, $max) } @pnames; } sub set_playback_latency { my ($min, $max, @pnames) = @_; set_multiport_latency('playback',$min, $max, @pnames) } sub set_capture_latency { my ($min, $max, @pnames) = @_; set_multiport_latency('capture',$min, $max, @pnames) } sub get_capture_latency { get_latency($_[0], 'capture' )} sub get_playback_latency { get_latency($_[0], 'playback')} sub recompute_latencies { $jack->{watcher}->recomputeLatencies(); } 1;Audio-Nama-1.208/lib/Audio/Nama/Edit.pm0000644000175000017500000005771012644673574016437 0ustar jrothjroth{ package Audio::Nama::Edit; use Audio::Nama::Globals qw(:singletons :trackrw); # each edit is identified by: # - host track name # - host track version # - edit name (i.e. sax-v1) used as key in %by_name # use Modern::Perl; our $VERSION = 1.0; use Carp; no warnings qw(uninitialized); our @ISA; use vars qw($n %by_index %by_name ); use Audio::Nama::Object qw( n play_start_mark_name rec_start_mark_name rec_end_mark_name host_track host_version fades ); sub initialize { $n = 0; %by_name = (); %by_index = (); @Audio::Nama::edits_data = (); # for save/restore } sub next_n { ++$n } sub new { my $class = shift; my %vals = @_; croak "undeclared field: @_" if grep{ ! $_is_field{$_} } keys %vals; my $self = bless { n => next_n(), fades => [], @_ }, $class; $by_name{ $self->edit_name } = $self; $by_index{ $self->n } = $self; #print "self class: $class, self type: ", ref $self, $/; my $name = $self->host_track; my $host = $Audio::Nama::tn{$name}; confess( Audio::Nama::project_dir().": missing host_track". $Audio::Nama::this_track->dump. $self->dump. Audio::Nama::process_command("dumpa")) if !$host; # Routing: # # sax-v5-original --+ # | # sax-v5-edit1 -----+--- sax-v5 (bus/track) --- sax (bus/track) ----- # prepare top-level bus and mix track $host->busify; # i.e. sax (bus/track) # create the version-level bus and mix track # i.e. sax-v5 (bus/track) # (maybe it already exists) my $version_mix = Audio::Nama::Track->new( name => $self->edit_root_name, # i.e. sax-v5 # rw => REC, # set by ->busify source_type => 'bus', source_id => 'bus', width => 2, # default to stereo group => $self->host_track, # i.e. sax hide => 1, ); $version_mix->busify; # create host track alias if necessary # To ensure that users don't get into trouble, we would like to # restrict this track: # - version number must *not* be allowed to change # - rw setting must be fixed to PLAY # # The easiest way may be to subclass the 'set' routine my $host_track_alias = $Audio::Nama::tn{$self->host_alias} // Audio::Nama::VersionTrack->new( name => $self->host_alias, version => $host->monitor_version, # static target => $host->name, rw => PLAY, # do not REC group => $self->edit_root_name, # i.e. sax-v5 hide => 1, ); # create edit track # - same name as edit # - we expect to record # - source_type and source_id come from host track my $edit_track = Audio::Nama::EditTrack->new( name => $self->edit_name, rw => REC, source_type => $host->source_type, source_id => $host->source_id, group => $self->edit_root_name, # i.e. sax-v5 hide => 1, ); $self } sub edit_root_name { my $self = shift; join '-', $self->host_track, 'v'.$self->host_version; } sub edit_name { my $self = shift; join '-', $self->edit_root_name, 'edit'.$self->n } sub host_alias { my $self = shift; join '-', $self->edit_root_name, 'original' } # default mark names sub play_start_name { my $self = shift; $self->play_start_mark_name || (join '-', $self->edit_name,'play-start') } sub rec_start_name { my $self = shift; $self->rec_start_mark_name || (join '-', $self->edit_name,'rec-start') } sub rec_end_name { my $self = shift; $self->rec_end_mark_name || (join '-', $self->edit_name,'rec-end') } sub play_start_mark { $Audio::Nama::Mark::by_name{$_[0]->play_start_name} } sub rec_start_mark { $Audio::Nama::Mark::by_name{$_[0]->rec_start_name} } sub rec_end_mark { $Audio::Nama::Mark::by_name{$_[0]->rec_end_name} } # the following are unadjusted values sub play_start_time { my $self = shift; $self->marktime('play_start_name') } sub rec_start_time { my $self = shift; $self->marktime('rec_start_name') } sub rec_end_time { my $self = shift; $self->marktime('rec_end_name') } sub play_end_time { my $self = shift; $self->marktime('rec_end_name') + $config->{edit_playback_end_margin} } sub marktime { my ($self,$markfield) = @_; $Audio::Nama::Mark::by_name{$self->$markfield}->{time} } sub store_fades { # replacing previous my $edit = shift; my @fades = @_; my @indices = map{$_->n} @fades; $edit->remove_fades; $edit->set(fades => \@indices) } sub remove_fades { my $edit = shift; map{ $_->remove } map{ $Audio::Nama::Fade::by_index{$_} } @{$edit->fades}; $edit->set(fades => []); } sub destroy { my $edit = shift; # remove object from index hash delete $by_index{$edit->n}; delete $by_name{$edit->edit_name}; # list edit track WAV files my @wavs = values %{$edit->edit_track->targets}; # track removal also takes care of fades # VERIFY # my $fades = $edit->fades; # map{ $Audio::Nama::Fade::by_index{$_}->remove } @$fades; # remove edit track $edit->edit_track->remove; my @sister_edits = grep{ $edit->host_track eq $_->host_track and $edit->host_version == $_->host_version } values %by_index; # if we are the last edit, remove all auxiliary tracks/buses if ( ! @sister_edits ){ $edit->host_alias_track->remove; $edit->version_bus->remove; # note: bus->remove will not delete a mix track with WAV files # The host may have a version symlinked to a WAV file # belonging to the version mix track. So we remove # the track, but not the wav files. $edit->version_mix->remove if defined $edit->version_mix; $edit->host_bus->remove; } # remove edit track WAV files if we've reached here map{ my $path = Audio::Nama::join_path(Audio::Nama::this_wav_dir(), $_); Audio::Nama::pager("removing $path"); #unlink $path; } @wavs; } sub host { $Audio::Nama::tn{$_[0]->host_track} } # top-level mix track, i.e. 'sax' sub host_bus { $Audio::Nama::Bus::by_name{$_[0]->host_track} } # top-level bus sub version_mix { $Audio::Nama::tn{$_[0]->edit_root_name} } # in top-level bus sub version_bus { $Audio::Nama::Bus::by_name{$_[0]->edit_root_name} } # version-level bus sub host_alias_track{ $Audio::Nama::tn{$_[0]->host_alias} } # in version_bus sub edit_track { $Audio::Nama::tn{$_[0]->edit_name} } # in version_bus # utility routines } # -------- Edit routines; Main Namespace ------ { package Audio::Nama; use Modern::Perl; use Carp; no warnings 'uninitialized'; our ( %tn, %ti, %bn, $this_track, $this_edit, ); sub detect_keystroke_p { $project->{events}->{stdin} = AE::io(*STDIN, 0, sub { &{$text->{term_attribs}->{'callback_read_char'}}(); abort_set_edit_points(), return if $text->{term_attribs}->{line_buffer} eq "q" or $text->{term_attribs}->{line_buffer} eq "Q"; if ( $text->{term_attribs}->{line_buffer} eq "p" or $text->{term_attribs}->{line_buffer} eq "P"){ get_edit_mark()} else{ reset_input_line() } }); } sub reset_input_line { $text->{term_attribs}->{line_buffer} = q(); $text->{term_attribs}->{point} = 0; $text->{term_attribs}->{end} = 0; } { my $p; my @_edit_points; my @names = qw(dummy play-start rec-start rec-end); sub initialize_edit_points { $p = 0; @_edit_points = (); } sub abort_set_edit_points { Audio::Nama::throw("...Aborting!"); reset_input_line(); eval_iam('stop'); initialize_edit_points(); detect_spacebar(); } sub get_edit_mark { $p++; if($p <= 3){ # record mark my $pos = eval_iam('getpos'); push @_edit_points, $pos; Audio::Nama::pager(" got $names[$p] position ".d1($pos)); reset_input_line(); if( $p == 3){ complete_edit_points() } else{ $text->{term}->stuff_char(10); &{$text->{term_attribs}->{'callback_read_char'}}(); } } } sub complete_edit_points { @{$setup->{edit_points}} = @_edit_points; # save to global eval_iam('stop'); Audio::Nama::pager("\nEngine is stopped\n"); detect_spacebar(); print prompt(), " "; } } sub set_edit_points { $tn{$this_edit->edit_name}->set(rw => OFF) if defined $this_edit; Audio::Nama::throw("You must use a playback-only mode to setup edit marks. Aborting"), return 1 if Audio::Nama::ChainSetup::really_recording(); Audio::Nama::throw("You need stop the engine first. Aborting"), return 1 if engine_running(); Audio::Nama::pager("Ready to set edit points!"); sleeper(0.2); Audio::Nama::pager(q(Press the "P" key three times to mark positions for: + play-start + record-start + record-end Press "Q" to quit. Engine will start in 2 seconds.)); initialize_edit_points(); $project->{events}->{set_edit_points} = AE::timer(2, 0, sub { reset_input_line(); detect_keystroke_p(); eval_iam('start'); Audio::Nama::pager("\n\nEngine is running\n"); print prompt(); }); } sub transfer_edit_points { Audio::Nama::throw("Use 'set_edit_points' command to specify edit region"), return unless scalar @{$setup->{edit_points}}; my $edit = shift; Audio::Nama::Mark->new( name => $edit->play_start_name, time => $setup->{edit_points}->[0]); Audio::Nama::Mark->new( name => $edit->rec_start_name, time => $setup->{edit_points}->[1]); Audio::Nama::Mark->new( name => $edit->rec_end_name, time => $setup->{edit_points}->[2]); @{$setup->{edit_points}} = (); } sub generate_edit_record_setup { # for current edit # set edit track to REC # set global region start offset # set global region length cutoff # set regenerate_setup flag # insert host track fades # mute edit track # schedule unmuting at rec-start point - fade-in # schedule muting at rec-end point - fade-out } sub new_edit { # abort for many different reasons Audio::Nama::throw("You must use 'set_edit_points' before creating a new edit. Aborting."), return unless @{$setup->{edit_points}}; my $overlap = grep { my $fail; my $rst = $_->rec_start_time; my $ret = $_->rec_end_time; my $nst = $setup->{edit_points}->[1]; my $net = $setup->{edit_points}->[2]; my $rst1 = d1($rst); my $ret1 = d1($ret); my $nst1 = d1($nst); my $net1 = d1($net); Audio::Nama::throw("New rec-start time $nst1 conflicts with Edit ", $_->n, ": $rst1 < $nst1 < $ret1"), $fail++ if $rst < $nst and $nst < $ret; Audio::Nama::throw("New rec-end time $net1 conflicts with Edit ", $_->n, ": $rst1 < $net1 < $ret1"), $fail++ if $rst < $net and $net < $ret; Audio::Nama::throw("New rec interval $nst1 - $net1 conflicts with Edit ", $_->n, ": $rst1 - $ret1"), $fail++ if $nst < $rst and $ret < $net; $fail } grep{ $_->host_track eq $this_track->name} values %Audio::Nama::Edit::by_name; Audio::Nama::throw("Aborting."), return if $overlap; my $name = $this_track->name; my $editre = qr($name-v\d+-edit\d+); Audio::Nama::throw("$name: editing of edits is not currently allowed."), return if $name =~ /-v\d+-edit\d+/; Audio::Nama::throw("$name: must be in PLAY mode. Edits will be applied against current version"), return unless $this_track->rec_status eq PLAY or $this_track->rec_status eq REC and grep{ /$editre/ } keys %Audio::Nama::Track::by_name; # create edit my $v = $this_track->monitor_version; Audio::Nama::pager("$name: creating new edit against version $v"); my $edit = Audio::Nama::Edit->new( host_track => $this_track->name, host_version => $v, ); $this_track->current_edit->{$v} = $edit->n; $this_edit = $edit; transfer_edit_points($edit); #select_edit($this_edit->n); edit_action('preview_edit_in'); } {my %edit_actions = ( record_edit => sub { $this_edit->edit_track->set(rw => REC); $this_edit->store_fades(std_host_fades(), edit_fades()); }, play_edit => sub { $this_edit->edit_track->set(rw => PLAY); $this_edit->store_fades(std_host_fades(), edit_fades()); }, preview_edit_in => sub { $this_edit->edit_track->set(rw => OFF); $this_edit->store_fades(std_host_fades()); }, preview_edit_out => sub { $this_edit->edit_track->set(rw => OFF); $this_edit->store_fades(reverse_host_fades()); }, ); sub edit_action { my $action = shift; defined $this_edit or Audio::Nama::throw("Please select an edit and try again."), return; set_edit_mode(); $this_edit->host_alias_track->set(rw => PLAY); # all $edit_actions{$action}->(); request_setup(); # TODO: looping # my $is_setup = generate_setup(); # return unless $is_setup; # if ($action !~ /record/){ # $mode->{loop_enable}++; # @{$setup->{loop_endpoints}} = (0,$setup->{audio_length} - 0.05); # # and transport_start() # } # connect_transport(); } } sub end_edit_mode { # regenerate fades $mode->{offset_run} = 0; $mode->{loop_enable} = 0; disable_offset_run_mode(); $this_track = $this_edit->host if defined $this_edit; undef $this_edit; request_setup(); } sub destroy_edit { Audio::Nama::throw("no edit selected"), return unless $this_edit; my $reply = $text->{term}->readline('destroy edit "'.$this_edit->edit_name. qq(" and all its WAV files?? [n] )); if ( $reply =~ /y/i ){ Audio::Nama::pager("permanently removing edit"); $this_edit->destroy; } $text->{term}->remove_history($text->{term}->where_history); $this_track = $this_edit->host; end_edit_mode(); } sub set_edit_mode { $mode->{offset_run} = edit_mode_conditions() ? 1 : 0 } sub edit_mode { $mode->{offset_run} and defined $this_edit} sub edit_mode_conditions { defined $this_edit or Audio::Nama::throw('No edit is defined'), return; defined $this_edit->play_start_time or Audio::Nama::throw('No edit points defined'), return; $this_edit->host_alias_track->rec_status eq PLAY or Audio::Nama::throw('host alias track : ',$this_edit->host_alias, " status must be PLAY"), return; # the following conditions should never be triggered $this_edit->host_alias_track->monitor_version == $this_edit->host_version or die('host alias track: ',$this_edit->host_alias, " must be set to version ",$this_edit->host_version), return 1; } sub reverse_host_fades { host_fades('in','out') } sub std_host_fades { host_fades('out','in') } sub host_fades { my ($first,$second) = @_; Audio::Nama::Fade->new( type => $first, mark1 => $this_edit->rec_start_name, duration => $config->{edit_crossfade_time}, relation => 'fade_from_mark', track => $this_edit->host_alias, ), Audio::Nama::Fade->new( type => $second, mark1 => $this_edit->rec_end_name, duration => $config->{edit_crossfade_time}, relation => 'fade_from_mark', track => $this_edit->host_alias, ), } sub edit_fades { Audio::Nama::Fade->new( type => 'in', mark1 => $this_edit->rec_start_name, duration => $config->{edit_crossfade_time}, relation => 'fade_from_mark', track => $this_edit->edit_name, ), Audio::Nama::Fade->new( type => 'out', mark1 => $this_edit->rec_end_name, duration => $config->{edit_crossfade_time}, relation => 'fade_from_mark', track => $this_edit->edit_name, ); } ### edit region computations # pass $args hash with following fields: # ### track values # trackname # playat # region_start # region_end # setup_length # ### edit values # edit_play_start # edit_play_end # ### dispatch tables # playat_dispatch # region_start_dispatch # region_end_dispatch # ### output values # # new_playat # new_region_start # new_region_end sub region_start_dispatch { my ($args, $key) = @_; my %table = ( out_of_bounds_near => "*", out_of_bounds_far => "*", play_start_during_playat_delay => $args->{region_start}, no_region_play_start_during_playat_delay => 0, play_start_within_region => $args->{region_start} + $args->{edit_play_start} - $args->{playat}, no_region_play_start_after_playat_delay => $args->{region_start} + $args->{edit_play_start} - $args->{playat}, ); $table{$key} } sub playat_dispatch { my ($args, $key) = @_; my %table = ( out_of_bounds_near => "*", out_of_bounds_far => "*", play_start_during_playat_delay => $args->{playat} - $args->{edit_play_start}, no_region_play_start_during_playat_delay => $args->{playat} - $args->{edit_play_start}, play_start_within_region => 0, no_region_play_start_after_playat_delay => 0, ); $table{$key} } sub region_end_dispatch { my ($args, $key) = @_; my %table = ( out_of_bounds_near => "*", out_of_bounds_far => "*", play_start_during_playat_delay => $args->{region_start} + $args->{edit_play_end} - $args->{playat}, no_region_play_start_during_playat_delay => $args->{edit_play_end} - $args->{playat}, play_start_within_region => $args->{region_start} + $args->{edit_play_end} - $args->{playat}, no_region_play_start_after_playat_delay => $args->{edit_play_end} - $args->{playat}, ); $table{$key} } sub new_playat { my $args = shift; playat_dispatch($args, edit_case($args)); } sub new_region_start { my $args = shift; region_start_dispatch($args, edit_case($args)); } sub new_region_end { my $args = shift; my $end = region_end_dispatch($args, edit_case($args)); return $end if $end eq '*'; $end < $args->{setup_length} ? $end : $args->{setup_length} }; # the following value will always allow enough time # to record the edit. it may be longer than the # actual WAV file in some cases. (I doubt that # will be a problem.) sub edit_case { my $args = shift; # logic for no-region case if ( ! $args->{region_start} and ! $args->{region_end} ) { if( $args->{edit_play_end} < $args->{playat}) { "out_of_bounds_near" } elsif( $args->{edit_play_start} > $args->{playat} + $args->{setup_length}) { "out_of_bounds_far" } elsif( $args->{edit_play_start} >= $args->{playat}) {"no_region_play_start_after_playat_delay"} elsif( $args->{edit_play_start} < $args->{playat} and $args->{edit_play_end} > $args->{playat} ) { "no_region_play_start_during_playat_delay"} } # logic for region present case elsif ( defined $args->{region_start} and defined $args->{region_end} ) { if ( $args->{edit_play_end} < $args->{playat}) { "out_of_bounds_near" } elsif ( $args->{edit_play_start} > $args->{playat} + $args->{region_end} - $args->{region_start}) { "out_of_bounds_far" } elsif ( $args->{edit_play_start} >= $args->{playat}) { "play_start_within_region"} elsif ( $args->{edit_play_start} < $args->{playat} and $args->{playat} < $args->{edit_play_end}) { "play_start_during_playat_delay"} else {carp "$args->{trackname}: fell through if-then"} } else { carp "$args->{trackname}: improperly defined region" } } sub play_start_time { defined $this_edit ? $this_edit->play_start_time : $setup->{offset_run}->{start_time} # zero unless offset run mode } sub play_end_time { defined $this_edit ? $this_edit->play_end_time : $setup->{offset_run}->{end_time} # undef unless offset run mode } sub edit_vars { my $edit = shift || $this_edit; Audio::Nama::throw("edit is undefined"), return unless $edit; my $track = $Audio::Nama::tn{$edit}->{host_track}; { trackname => $track->name, playat => $track->playat_time, region_start => $track->region_start_time, region_end => $track->region_end_time, edit_play_start => $edit->play_start_time(), edit_play_end => $edit->play_end_time(), setup_length => $track->wav_length(), } } sub list_edits { my @edit_data = map{ s/^---//; s/...\s$//; $_ } map{ $_->dump } sort{$a->n <=> $b->n} values %Audio::Nama::Edit::by_index; Audio::Nama::pager(@edit_data); } sub explode_track { my $track = shift; # quit if I am already a mix track Audio::Nama::throw($track->name,": I am already a mix track. I cannot explode!"),return if $track->is_mix_track; my @versions = @{ $track->versions }; # quit if I have only one version Audio::Nama::throw($track->name,": Only one version. Skipping."), return if scalar @versions == 1; $track->busify; my $host = $track->name; my @names = map{ "$host-v$_"} @versions; my @exists = grep{ $Audio::Nama::tn{$_} } @names; Audio::Nama::throw("@exists: tracks already exist. Aborting."), return if @exists; my $current = cwd; chdir this_wav_dir(); for my $i (@versions){ # make a track my $name = "$host-v$i"; Audio::Nama::Track->new( name => $name, rw => MON, group => $host, ); # symlink the WAV file we want symlink $track->targets->{$i}, "$name.wav"; } chdir $current; } sub select_edit { my $n = shift; my ($edit) = grep{ $_->n == $n } values %Audio::Nama::Edit::by_name; # check that conditions are met Audio::Nama::throw("Edit $n not found. Skipping."),return if ! $edit; Audio::Nama::throw( qq(Edit $n applies to track "), $edit->host_track, qq(" version ), $edit->host_version, ". This does does not match the current monitor version (", $edit->host->monitor_version,"). Set the correct version and try again."), return if $edit->host->monitor_version != $edit->host_version; # select edit $this_edit = $edit; # turn on top-level bus and mix track $edit->host_bus->set(rw => REC); $edit->host->busify; # turn off all version level buses/mix_tracks map{ $tn{$_}->set(rw => OFF); # version mix tracks $bn{$_}->set(rw => OFF); # version buses } $this_edit->host_bus->tracks; # use same name for track/bus # turn on what we want $edit->version_bus->set(rw => REC); $edit->version_mix->busify; $edit->host_alias_track->set(rw => PLAY); $edit->edit_track->set(rw => PLAY); $this_track = $edit->host; } sub disable_edits { Audio::Nama::throw("Please select an edit and try again."), return unless defined $this_edit; my $edit = $this_edit; $edit->host_bus->set( rw => OFF); $edit->version_bus->set( rw => OFF); # reset host track $edit->host->unbusify; } sub merge_edits { my $edit = $this_edit; Audio::Nama::throw("Please select an edit and try again."), return unless defined $edit; Audio::Nama::throw($edit->host_alias, ": track must be PLAY status. Aborting."), return unless $edit->host_alias_track->rec_status eq PLAY; Audio::Nama::throw("Use exit_edit_mode and try again."), return if edit_mode(); # create merge message my $v = $edit->host_version; my %edits = map{ my ($edit) = $tn{$_}->name =~ /edit(\d+)$/; my $ver = $tn{$_}->monitor_version; $edit => $ver } grep{ $tn{$_}->name =~ /edit\d+$/ and $tn{$_}->rec_status eq PLAY} $edit->version_bus->tracks; my $msg = "merges ".$edit->host_track."_$v.wav w/edits ". join " ",map{$_."v$edits{$_}"} sort{$a<=>$b} keys %edits; # merges mic_1.wav w/mic-v1-edits 1_2 2_1 Audio::Nama::pager($msg); # cache at version_mix level my $output_wav = cache_track($edit->version_mix); # promote to host track my $new_version = $edit->host->last + 1; add_system_version_comment($edit->host, $new_version, $msg); add_system_version_comment($edit->version_mix, $edit->version_mix->last, $msg); my $old = cwd(); chdir this_wav_dir(); my $new_host_wav = $edit->host_track . "_" . $new_version . ".wav"; symlink $output_wav, $new_host_wav; $edit->host->set(version => undef); # default to latest $edit->host->{version_comment}{$new_version}{system} = $msg; chdir $old; disable_edits(); $this_track = $edit->host; } # offset recording # Note that although we use ->shifted_* methods, all are # executed outside of edit mode, so we get unadjusted values. sub setup_length { my $setup_length; map{ my $l = $_->shifted_length; $setup_length = $l if $l > $setup_length } grep{ $_-> rec_status eq PLAY } Audio::Nama::ChainSetup::engine_tracks(); $setup_length } sub set_offset_run_mark { Audio::Nama::throw("This function not available in edit mode. Aborting."), return if edit_mode(); my $markname = shift; $setup->{offset_run}->{start_time} = $Audio::Nama::Mark::by_name{$markname}->time; $setup->{offset_run}->{end_time} = setup_length(); $setup->{offset_run}->{mark} = $markname; enable_offset_run_mode(); request_setup(); } sub clear_offset_run_vars { $setup->{offset_run}->{start_time} = 0; $setup->{offset_run}->{end_time} = undef; $setup->{offset_run}->{mark} = undef; } sub enable_offset_run_mode { undef $this_edit; $mode->{offset_run}++ } sub disable_offset_run_mode { undef $mode->{offset_run}; clear_offset_run_vars(); Audio::Nama::request_setup(); } sub is_offset_run_mode { $mode->{offset_run} and ! defined $this_edit } sub select_edit_track { my $track_selector_method = shift; Audio::Nama::throw("You need to select an edit first (list_edits, select_edit)\n"), return unless defined $this_edit; $this_track = $this_edit->$track_selector_method; process_command('show_track'); } } # end package 1; __END__Audio-Nama-1.208/lib/Audio/Nama/Log.pm0000644000175000017500000001105412644673574016262 0ustar jrothjroth# ----------- Logging ------------ package Audio::Nama::Log; use Modern::Perl; use Log::Log4perl qw(get_logger :levels); use Exporter; use Carp qw(carp cluck confess croak); our @ISA = 'Exporter'; our @EXPORT_OK = qw(logit loggit logpkg logsub initialize_logger); our $appender; sub initialize_logger { my $cat_string = shift; my @all_cats = qw( Audio::Nama::AnalyseLV2 Audio::Nama::Assign Audio::Nama::Bunch Audio::Nama::Bus Audio::Nama::CacheTrack Audio::Nama::ChainSetup Audio::Nama::Config Audio::Nama::Custom Audio::Nama::Edit Audio::Nama::EffectChain Audio::Nama::Effect Audio::Nama::EffectsRegistry Audio::Nama::EngineCleanup Audio::Nama::Engine Audio::Nama::EngineRun Audio::Nama::EngineSetup Audio::Nama::Fade Audio::Nama::Git Audio::Nama::Globals Audio::Nama::Grammar Audio::Nama::Graphical Audio::Nama::Graph Audio::Nama::Help Audio::Nama::Initializations Audio::Nama::Insert Audio::Nama::IO Audio::Nama::Jack Audio::Nama::Latency Audio::Nama::Lat Audio::Nama::Log Audio::Nama::Mark Audio::Nama::Memoize Audio::Nama::Midi Audio::Nama::Mix Audio::Nama::Modes Audio::Nama::MuteSoloFade Audio::Nama::Nama Audio::Nama::Object Audio::Nama::Options Audio::Nama::Persistence Audio::Nama::Plug Audio::Nama::Project Audio::Nama::RegionComp Audio::Nama::Regions Audio::Nama::Sequence Audio::Nama::Terminal Audio::Nama::Text Audio::Nama::Track Audio::Nama::Util Audio::Nama::Wavinfo Audio::Nama::Wav ); push @all_cats, 'ECI','SUB'; my %negate; %negate = map{ $_ => 1} map{ s/^#//; $_ } grep{ /^#/ } expand_cats(split q(,), $cat_string) if $cat_string; #say("negate\n",Audio::Nama::json_out(\%negate)); my $layout = "[\%r] %c %m%n"; # backslash to protect from source filter my $logfile = $ENV{NAMA_LOGFILE}; $SIG{ __DIE__ } = sub { Carp::confess( @_ ) } if $cat_string; $appender = $logfile ? 'FILE' : 'STDERR'; $logfile //= "/dev/null"; my @cats; @cats = expand_cats(split ',', $cat_string) if $cat_string; #logpkg(__FILE__,__LINE__,'debug',"initial logging categories: @cats"); #logpkg(__FILE__,__LINE__,'trace',"all cats: @all_cats"); @cats = grep{ ! $negate{$_} } @all_cats if grep {$_ eq 'ALL'} @cats; #logpkg(__FILE__,__LINE__,'debug',"Final logging categories: @cats"); my $conf = qq( #log4perl.rootLogger = DEBUG, $appender #log4perl.category.Audio.Nama = DEBUG, $appender # dummy entry - avoid no logger/no appender warnings log4perl.category.DUMMY = DEBUG, DUMMY log4perl.appender.DUMMY = Log::Log4perl::Appender::Screen log4perl.appender.DUMMY.layout = Log::Log4perl::Layout::NoopLayout # screen appender log4perl.appender.STDERR = Log::Log4perl::Appender::Screen log4perl.appender.STDERR.layout = Log::Log4perl::Layout::PatternLayout log4perl.appender.STDERR.layout.ConversionPattern = $layout # file appender log4perl.appender.FILE = Log::Log4perl::Appender::File log4perl.appender.FILE.filename = $logfile log4perl.appender.FILE.layout = Log::Log4perl::Layout::PatternLayout log4perl.appender.FILE.layout.ConversionPattern = $layout #log4perl.additivity.SUB = 0 # doesn't work... why? ); # add lines for the categories we want to log $conf .= join "\n", "", map{ cat_line($_)} @cats if @cats; #say $conf; Log::Log4perl::init(\$conf); return( { map { $_, 1 } @cats } ) } sub cat_line { "log4perl.category.$_[0] = DEBUG, $appender" } sub expand_cats { # Convert Module -> Audio::Nama::Module -> Audio::Nama::Module # Convert !Module -> !Audio::Nama::Module -> !Audio::Nama::Module no warnings 'uninitialized'; my @cats = @_; map { s/^(#)?::/$1Audio::Nama::/; $_} # SKIP_PREPROC map { s/^(#)?/$1::/ unless /^::/ or /^#?ECI/ or /^#?SUB/ or /^ALL$/; $_ }# SKIP_PREPROC @cats; } { my %is_method = map { $_ => 1 } qw( trace debug info warn error fatal logwarn logdie logcarp logcroak logcluck logconfess); sub logit { my ($line_number, $category, $level, @message) = @_; #say qq($line_number, $category, $level, @message) ; #confess("first call to logit"); my $line_number_output = $line_number ? " (L $line_number) ": ""; cluck "illegal level: $level" unless $is_method{$level}; my $logger = get_logger($category); $logger->$level($line_number_output, @message); } } sub logsub { logit(__LINE__,'SUB','debug',$_[0]) } *loggit = \&logit; # to avoid source filter on logit call below sub logpkg { my( $file, $line_no, $level, @message) = @_; # convert Effects.pm to Audio::Nama::Effects to support logpkg my $pkg = $file; ($pkg) = $file =~ m| ([^/]+)\.pm$ |x; $pkg //= "Dummy::Pkg"; $pkg = "Audio::Nama::$pkg"; # SKIP_PREPROC #say "category: $pkg"; logit ($line_no,$pkg,$level, @message) } 1;Audio-Nama-1.208/lib/Audio/Nama/Wav.pm0000644000175000017500000000346712644673574016307 0ustar jrothjrothpackage Audio::Nama::Wav; our $VERSION = 1.0; use Audio::Nama::Assign qw(:all); use Audio::Nama::Util qw(join_path); use Audio::Nama::Log qw(logsub logpkg); use Memoize qw(memoize unmemoize); # called by code in Audio::Nama::Memoize.pm use warnings; no warnings qw(uninitialized); use Carp; sub get_versions { my %args = @_; $args{sep} //= '_'; $args{ext} //= 'wav'; my ($sep, $ext) = ($args{sep}, $args{ext}); my ($dir, $basename) = ($args{dir}, $args{name}); logpkg(__FILE__,__LINE__,'debug',"getver: dir $dir basename $basename sep $sep ext $ext"); my %versions = (); for my $candidate ( candidates($dir) ) { # logpkg(__FILE__,__LINE__,'debug',"candidate: $candidate"); my( $match, $dummy, $num) = ( $candidate =~ m/^ ( $basename ($sep (\d+))? \.$ext ) $/x ); # regex statement if ( $match ) { $versions{ $num || 'bare' } = $match } } logpkg(__FILE__,__LINE__,'debug',sub{"get_version: " , Audio::Nama::json_out(\%versions)}); %versions; } sub candidates { my $dir = shift; $dir = File::Spec::Link->resolve_all( $dir ); opendir my $wavdir, $dir or die "cannot open $dir: $!"; my @candidates = readdir $wavdir; closedir $wavdir; @candidates = grep{ ! (-s join_path($dir, $_) == 44 ) } @candidates; #logpkg(__FILE__,__LINE__,'debug',join $/, @candidates); @candidates; } sub targets { my %args = @_; # $Audio::Nama::debug2 and print "&targets\n"; my %versions = get_versions(%args); if ($versions{bare}) { $versions{1} = $versions{bare}; delete $versions{bare}; } logpkg(__FILE__,__LINE__,'debug',sub{"\%versions\n================\n", json_out(\%versions)}); \%versions; } sub versions { # $Audio::Nama::debug2 and print "&versions\n"; my %args = @_; [ sort { $a <=> $b } keys %{ targets(%args)} ] } sub last { %args = @_; pop @{ versions(%args) } } 1;Audio-Nama-1.208/lib/Audio/Nama/Engine.pm0000644000175000017500000001102412644673574016743 0ustar jrothjroth{ package Audio::Nama::Engine; our $VERSION = 1.0; use Modern::Perl; use Carp; our @ISA; our %by_name; our @ports = (57000..57050); our %port = ( fof => 57201, bus => 57202, ); use Audio::Nama::Globals qw(:all); use Audio::Nama::Object qw( name port jack_seek_delay jack_transport_mode events socket pids ecasound buffersize on_reconfigure on_exit ); sub new { my $class = shift; my %vals = @_; croak "undeclared field: @_" if grep{ ! $_is_field{$_} } keys %vals; Audio::Nama::pager_newline("$vals{name}: returning existing engine"), return $by_name{$vals{name}} if $by_name{$vals{name}}; my $self = bless { name => 'default', %vals }, $class; #print "object class: $class, object type: ", ref $self, $/; $by_name{ $self->name } = $self; $self->initialize_ecasound(); $this_engine = $self; } sub initialize_ecasound { my $self = shift; my @existing_pids = split " ", qx(pgrep ecasound); $self->launch_ecasound_server; $self->{pids} = [ grep{ my $pid = $_; ! grep{ $pid == $_ } @existing_pids } split " ", qx(pgrep ecasound) ]; } sub launch_ecasound_server {} sub eval_iam {} } { package Audio::Nama::NetEngine; our $VERSION = 1.0; use Modern::Perl; use Audio::Nama::Log qw(logpkg); use Audio::Nama::Globals qw(:all); use Audio::Nama::Log qw(logit); use Carp qw(carp); our @ISA = 'Audio::Nama::Engine'; sub init_ecasound_socket { my $self = shift; my $port = $self->port; Audio::Nama::pager_newline("Creating socket on port $port."); $self->{socket} = new IO::Socket::INET ( PeerAddr => 'localhost', PeerPort => $port, Proto => 'tcp', ); die "Could not create socket: $!\n" unless $self->{socket}; } sub launch_ecasound_server { my $self = shift; my $port = $self->port; # we'll try to communicate with an existing ecasound # process provided: # # started with --server option # --server-tcp-port option matches my $command = "ecasound -K -C --server --server-tcp-port=$port"; my $redirect = ">/dev/null &"; my $ps = qx(ps ax); if ( $ps =~ /ecasound/ and $ps =~ /--server/ and ($ps =~ /tcp-port=$port/) ) { Audio::Nama::pager_newline("Found existing Ecasound server on port $port") } else { Audio::Nama::pager_newline("Starting Ecasound server on port $port"); system("$command $redirect") == 0 or carp("system $command failed: $?\n") } sleep 1; $self->init_ecasound_socket(); } sub eval_iam { my $self = shift; my $cmd = shift; #my $category = Audio::Nama::munge_category(shift()); my $category = "ECI"; logit(__LINE__,$category, 'debug', "Net-ECI sent: $cmd"); $cmd =~ s/\s*$//s; # remove trailing white space $this_engine->{socket}->send("$cmd\r\n"); my $buf; # get socket reply, restart ecasound on error my $result = $this_engine->{socket}->recv($buf, $config->{engine_command_output_buffer_size}); defined $result or Audio::Nama::restart_ecasound(), return; my ($return_value, $setup_length, $type, $reply) = $buf =~ /(\d+)# digits \ # space (\d+)# digits \ # space ([^\r\n]+) # a line of text, probably one character \r\n # newline (.+) # rest of string /sx; # s-flag: . matches newline if( ! $return_value == 256 ){ logit(__LINE__,$category,'error',"Net-ECI bad return value: $return_value (expected 256)"); # restart_ecasound(); # TODO } no warnings 'uninitialized'; $reply =~ s/\s+$//; if( $type eq 'e') { logit(__LINE__,$category,'error',"ECI error! Command: $cmd. Reply: $reply"); #restart_ecasound() if $reply =~ /in engine-status/; } else { logit(__LINE__,$category,'debug',"Net-ECI got: $reply"); $reply } } } # end package { package Audio::Nama::LibEngine; our $VERSION = 1.0; use Modern::Perl; use Audio::Nama::Globals qw(:all); use Audio::Nama::Log qw(logit); our @ISA = 'Audio::Nama::Engine'; sub launch_ecasound_server { my $self = shift; Audio::Nama::pager_newline("Using Ecasound via Audio::Ecasound (libecasoundc)"); $self->{ecasound} = Audio::Ecasound->new(); } sub eval_iam { #logsub("&eval_iam"); my $self = shift; my $cmd = shift; my $category = Audio::Nama::munge_category(shift()); logit(__LINE__,$category,'debug',"ECI sent: $cmd"); my (@result) = $this_engine->{ecasound}->eci($cmd); logit(__LINE__,$category, 'debug',"ECI got: @result") if $result[0] and not $cmd =~ /register/ and not $cmd =~ /int-cmd-list/; my $errmsg = $this_engine->{ecasound}->errmsg(); if( $errmsg ){ Audio::Nama::restart_ecasound() if $errmsg =~ /in engine-status/; $this_engine->{ecasound}->errmsg(''); # Audio::Ecasound already prints error } "@result"; } } 1 __END__Audio-Nama-1.208/lib/Audio/Nama/CacheTrack.pm0000644000175000017500000002226212644673574017534 0ustar jrothjroth# -------- CacheTrack ------ package Audio::Nama; use Modern::Perl; use Storable 'dclone'; use Audio::Nama::Globals qw(:all); # The $args hashref passed among the subroutines in this file # has these fields: # track # additional_time # processing_time # orig_version # complete_caching_ref # output_wav # orig_volume # orig_pan sub cache_track { # launch subparts if conditions are met local $this_track; my $args = {}; # initialize args my $track; ($track, $args->{additional_time}) = @_; $args->{track} = $track; $args->{additional_time} //= 0; pagers($track->name, ": preparing to cache."); # abort if track is a mix track for a bus and the bus is OFF if( my $bus = $bn{$track->name} and $track->rec_status eq REC ){ $bus->rw eq OFF and pagers( $bus->name, ": status is OFF. Aborting."), return; } else { $track->rec_status eq PLAY or pagers( $track->name, ": track caching requires PLAY status. Aborting."), return; } pagers($track->name, ": nothing to cache! Skipping."), return unless $track->fancy_ops or $track->has_insert or $track->is_region or $bn{$track->name}; if ( prepare_to_cache($args) ) { deactivate_vol_pan($args); cache_engine_run($args); reactivate_vol_pan($args); return $args->{output_wav} } else { throw("Empty routing graph. Aborting."); return; } } sub deactivate_vol_pan { my $args = shift; unity($args->{track}, 'save_old_vol'); pan_check($args->{track}, 50); } sub reactivate_vol_pan { my $args = shift; pan_back($args->{track}); vol_back($args->{track}); } sub prepare_to_cache { my $args = shift; my $g = Audio::Nama::ChainSetup::initialize(); $args->{orig_version} = $args->{track}->monitor_version; # We route the signal thusly: # # Target track --> CacheRecTrack --> wav_out # # CacheRecTrack slaves to target target # - same name # - increments track version by one my $cooked = Audio::Nama::CacheRecTrack->new( name => $args->{track}->name . '_cooked', group => 'Temp', target => $args->{track}->name, hide => 1, ); $g->add_path($args->{track}->name, $cooked->name, 'wav_out'); # save the output file name to return later $args->{output_wav} = $cooked->current_wav; # set WAV output format $g->set_vertex_attributes( $cooked->name, { format => signal_format($config->{cache_to_disk_format},$cooked->width), version => (1 + Audio::Nama::Wav::last(name => $args->{track}->name, dir => this_wav_dir()) ) } ); $args->{complete_caching_ref} = \&update_cache_map; # Case 1: Caching a standard track if($args->{track}->rec_status eq PLAY) { # set the input path $g->add_path('wav_in',$args->{track}->name); logpkg(__FILE__,__LINE__,'debug', "The graph after setting input path:\n$g"); } # Case 2: Caching a bus mix track elsif($args->{track}->rec_status eq REC){ # apply all buses (unneeded ones will be pruned) map{ $_->apply($g) } grep{ (ref $_) =~ /Sub/ } Audio::Nama::Bus::all() } logpkg(__FILE__,__LINE__,'debug', "The graph after bus routing:\n$g"); Audio::Nama::ChainSetup::prune_graph(); logpkg(__FILE__,__LINE__,'debug', "The graph after pruning:\n$g"); Audio::Nama::Graph::expand_graph($g); logpkg(__FILE__,__LINE__,'debug', "The graph after adding loop devices:\n$g"); Audio::Nama::Graph::add_inserts($g); logpkg(__FILE__,__LINE__,'debug', "The graph with inserts:\n$g"); my $success = Audio::Nama::ChainSetup::process_routing_graph(); if ($success) { Audio::Nama::ChainSetup::write_chains(); Audio::Nama::ChainSetup::remove_temporary_tracks(); } $success } sub cache_engine_run { my $args = shift; connect_transport() or throw("Couldn't connect engine! Aborting."), return; # remove fades from target track Audio::Nama::Effect::remove_op($args->{track}->fader) if defined $args->{track}->fader; $args->{processing_time} = $setup->{audio_length} + $args->{additional_time}; pagers($args->{track}->name,": processing time: ". d2($args->{processing_time}). " seconds"); pagers("Starting cache operation. Please wait."); revise_prompt(" "); # we try to set processing time this way eval_iam("cs-set-length $args->{processing_time}"); eval_iam("start"); # ensure that engine stops at completion time $setup->{cache_track_args} = $args; $project->{events}->{poll_engine} = AE::timer(1, 0.5, \&poll_cache_progress); # complete_caching() contains the remainder of the caching code. # It is triggered by stop_polling_cache_progress() } sub complete_caching { my $args = shift; my $name = $args->{track}->name; my @files = grep{/$name/} new_files_were_recorded(); if (@files ){ $args->{complete_caching_ref}->($args) if defined $args->{complete_caching_ref}; post_cache_processing($args); } else { throw("track cache operation failed!") } undef $setup->{cache_track_args}; } sub update_cache_map { my $args = shift; logpkg(__FILE__,__LINE__,'debug', "updating track cache_map"); logpkg(__FILE__,__LINE__,'debug', "current track cache entries:", sub { join "\n","cache map", map{($_->dump)} Audio::Nama::EffectChain::find(track_cache => 1) }); my @inserts_list = Audio::Nama::Insert::get_inserts($args->{track}->name); # include all ops, include vol/pan operators # which serve as placeholders, won't overwrite # the track's current vol/pan operators my $track = $args->{track}; my @ops_list = @{$track->ops}; my @ops_remove_list = $track->fancy_ops; if ( @inserts_list or @ops_remove_list or $track->is_region) { my %args = ( track_cache => 1, track_name => $track->name, track_version_original => $args->{orig_version}, project => 1, system => 1, ops_list => \@ops_list, inserts_data => \@inserts_list, ); $args{region} = [ $track->region_start, $track->region_end ] if $track->is_region; $args{track_target_original} = $track->target if $track->target; # late, because this changes after removing target field map{ delete $track->{$_} } qw(target); $args{track_version_result} = $track->last, # update track settings my $ec = Audio::Nama::EffectChain->new( %args ); map{ remove_effect($_) } @ops_remove_list; map{ $_->remove } @inserts_list; map{ delete $track->{$_} } qw( region_start region_end target ); pagers(qq(Saving effects for cached track "), $track->name, '".'); pagers(qq('uncache' will restore effects and set version $args->{orig_version}\n)); } } sub post_cache_processing { my $args = shift; # only set to PLAY tracks that would otherwise remain # in a REC status $args->{track}->set(rw => PLAY) if $args->{track}->rec_status eq 'REC'; $ui->global_version_buttons(); # recreate $ui->refresh(); revise_prompt("default"); } sub poll_cache_progress { my $args = $setup->{cache_track_args}; print "."; my $status = eval_iam('engine-status'); my $here = eval_iam("getpos"); update_clock_display(); logpkg(__FILE__,__LINE__,'debug', "engine time: ". d2($here)); logpkg(__FILE__,__LINE__,'debug', "engine status: $status"); return unless $status =~ /finished|error|stopped/ or $here > $args->{processing_time}; pagers("Done."); logpkg(__FILE__,__LINE__,'debug', engine_status(current_position(),2,1)); #revise_prompt(); stop_polling_cache_progress($args); } sub stop_polling_cache_progress { my $args = shift; $project->{events}->{poll_engine} = undef; $ui->reset_engine_mode_color_display(); complete_caching($args); } sub uncache_track { my $track = shift; local $this_track; $track->rec_status eq PLAY or throw($track->name, ": cannot uncache unless track is set to PLAY"), return; my $version = $track->monitor_version; my ($ec) = is_cached($track, $version); defined $ec or throw($track->name, ": version $version is not cached"), return; $track->fancy_ops and throw($track->name, ": cannot uncache while user effects are present\n", "You must delete them before you can uncache this WAV version."), return; $track->is_region and throw($track->name, ": cannot uncache while region is set for this track\n", "Remove it and try again."), return; # $ec->inserts and $track->inserts and throw($track->name, # ": cannot uncache inserts because an insert is already set for this track\n", # "Remove it and try again."), return; $ec->add($track); # replace track's effect list with ours $track->{ops} = dclone($ec->ops_list); # applying the the effect chain doesn't set the version or target # so we do it here $track->set(version => $ec->track_version_original); $track->set(target => $ec->track_target_original) if $ec->track_target_original; pager($track->name, ": setting uncached version ", $track->version, $/); pager($track->name, ": setting original region bounded by marks ", $track->region_start, " and ", $track->region_end, $/) if $track->is_region; my $bus = $bn{$track->name}; $track->set(rw => REC), pagers($track->name, ": setting mix track to REC") if defined $bus; } sub is_cached { my ($track, $version) = @_; my @results = Audio::Nama::EffectChain::find( project => 1, track_cache => 1, track_name => $track->name, track_version_result => $version, ); scalar @results > 1 and warn ("more than one EffectChain matching query!, found", map{ json_out($_->as_hash) } @results); $results[-1] } 1; __END__Audio-Nama-1.208/lib/Audio/Nama/Mix.pm0000644000175000017500000000633212644673574016301 0ustar jrothjrothpackage Audio::Nama; use Modern::Perl; sub check_level { my $track = shift; my $ev = add_effect( { track => $track, type => 'ev' } ); # disable Master so unused tracks are pruned $tn{Master}->set(rw => OFF); # direct target track to null my $null_routing = sub { my $g = shift; $g->add_path($track->name, output_node('null')) }; generate_setup($null_routing) or throw("check_level: generate_setup failed!"), return; connect_transport(); eval_iam('start'); # don't use heartbeat sleep 2; # time for engine to stabilize while( eval_iam('engine-status') ne 'finished'){ print q(.); sleep 1; update_clock_display()}; print " Done\n"; my $cs = eval_iam('cop-status'); my ($level_output) = $cs =~ /Status info:\s*?\n(.+)\z/s; Audio::Nama::mandatory_pager($level_output); # restore previous state remove_effect($ev); $tn{Master}->set(rw => MON); Audio::Nama::request_setup(); } sub automix { # get working track set my @tracks = grep{ $tn{$_}->rec_status eq PLAY or $bn{$_} and $tn{$_}->rec_status eq REC } $bn{Main}->tracks; pager("tracks: @tracks"); ## we do not allow automix if inserts are present throw("Cannot perform automix if inserts are present. Skipping."), return if grep{$tn{$_}->prefader_insert || $tn{$_}->postfader_insert} @tracks; #use Smart::Comments '###'; # add -ev to summed signal my $ev = add_effect( { chain => $tn{Master}->n, type => 'ev' } ); ### ev id: $ev # turn off audio output my $old_send_type = $tn{Master}->{send_type}; my $old_send_id = $tn{Master}->{send_id}; $tn{Master}->set(send_type => 'null', send_id => 'null'); ### Status before mixdown: process_command('show'); ### reduce track volume levels to 10% ## accommodate ea and eadb volume controls my $vol_operator = fxn($tn{$tracks[0]}->vol)->type; my $reduce_vol_command = $vol_operator eq 'ea' ? 'vol / 10' : 'vol - 10'; my $restore_vol_command = $vol_operator eq 'ea' ? 'vol * 10' : 'vol + 10'; ### reduce vol command: $reduce_vol_command for (@tracks){ process_command("$_ $reduce_vol_command") } process_command('show'); generate_setup('automix') # pass a bit of magic or throw("automix: generate_setup failed!"), return; connect_transport(); # start_transport() does a rec_cleanup() on transport stop eval_iam('start'); # don't use heartbeat sleep 2; # time for engine to stabilize while( eval_iam('engine-status') ne 'finished'){ print q(.); sleep 1; update_clock_display()}; print " Done\n"; # parse cop status my $cs = eval_iam('cop-status'); ### cs: $cs my $cs_re = qr/Chain "1".+?result-max-multiplier ([\.\d]+)/s; my ($multiplier) = $cs =~ /$cs_re/; ### multiplier: $multiplier remove_effect($ev); # deal with all silence case, where multiplier is 0.00000 if ( $multiplier < 0.00001 ){ throw("Signal appears to be silence. Skipping."); for (@tracks){ process_command("$_ $restore_vol_command") } $tn{Master}->set(rw => MON); return; } ### apply multiplier to individual tracks for (@tracks){ process_command( "$_ vol*$multiplier" ) } ### mixdown process_command('mixdown; arm; start'); ### restore audio output $tn{Master}->set( send_type => $old_send_type, send_id => $old_send_id); #no Smart::Comments; } 1 __END__Audio-Nama-1.208/lib/Audio/Nama/Text.pm0000644000175000017500000000306612644673574016471 0ustar jrothjroth# -------- Text Interface ----------- ## The following subroutines/methods belong to the Text interface class ## the grammar of the command processor is defined in # grammar_body.pl with subroutines in Grammar.p package Audio::Nama::Text; use Modern::Perl; use Carp; no warnings 'uninitialized'; use Audio::Nama::Globals qw(:all); use Audio::Nama::Assign qw(:all); our @ISA = 'Audio::Nama'; our $VERSION = 1.071; sub hello {"hello world!";} sub loop { package Audio::Nama; initialize_prompt(); $Event::DIED = sub { my ($event, $errmsg) = @_; throw($errmsg); $text->{term_attribs}->{line_buffer} = q(); if($text->{term}){ $text->{term}->clear_message(); $text->{term}->rl_reset_line_state(); } }; use Data::Dumper::Concise; Event::loop(); } ## NO-OP GRAPHIC METHODS no warnings qw(redefine); sub init_gui {} sub transport_gui {} sub group_gui {} sub track_gui {} sub preview_button {} sub create_master_and_mix_tracks {} sub time_gui {} sub refresh {} sub refresh_group {} sub refresh_track {} sub flash_ready {} sub update_master_version_button {} sub update_version_button {} sub paint_button {} sub project_label_configure{} sub length_display{} sub clock_display {} sub clock_config {} sub manifest {} sub global_version_buttons {} sub destroy_widgets {} sub destroy_marker {} sub restore_time_marks {} sub show_unit {} sub add_effect_gui {} sub remove_effect_gui {} sub marker {} sub init_palette {} sub save_palette {} sub paint_mute_buttons {} sub remove_track_gui {} sub reset_engine_mode_color_display {} sub set_engine_mode_color_display {} 1; __END__Audio-Nama-1.208/lib/Audio/Nama/Object.pm0000644000175000017500000000506312644673574016752 0ustar jrothjrothpackage Audio::Nama::Object; use Modern::Perl; use Carp; use Audio::Nama::Assign qw(json_out); use Storable qw(dclone); use Data::Dumper::Concise; no strict; # Enable during dev and testing BEGIN { require 5.004; $Audio::Nama::Object::VERSION = '1.04'; } sub import { return unless shift eq 'Audio::Nama::Object'; my $pkg = caller; my $child = 0+@{"${pkg}::ISA"}; eval join '', "package $pkg;\n", ' use vars qw(%_is_field); ', ' map{ $_is_field{$_}++ } @_;', ($child ? () : "\@${pkg}::ISA = Audio::Nama::Object;\n"), map { defined and ! ref and /^[^\W\d]\w*$/s or die "Invalid accessor name '$_'"; "sub $_ { \$_[0]->{$_} }" } @_; die "Failed to generate $pkg" if $@; return 1; } sub new { my $class = shift; bless { @_ }, $class; } sub is_legal_key { # The behavior I want here is: # # Example class hierachy: Audio::Nama::Object, Audio::Nama::Wav, Audio::Nama::Track, Audio::Nama::SimpleTrack # By inheriting from Track, SimpleTrack gets all the # attributes of Track and Wav, without having to include # them in the Track class definition my ($class, $key) = @_; $class = ref $class if ref $class; # support objects return 1 if ${"$class\::_is_field"}{$key}; my ($parent_class) = @{"$class\::ISA"}; return unless $parent_class and $parent_class !~ /Object::Tiny/; # this should be: # return unless $parent_class and $parent_class !~ /Object/; is_legal_key($parent_class,$key); } sub set { my $self = shift; my $class = ref $self; #print "class: $class, args: @_\n"; croak "odd number of arguments ",join "\n--\n" ,@_ if @_ % 2; my %new_vals = @_; map{ $self->{$_} = $new_vals{$_} ; my $key = $_; is_legal_key(ref $self, $key) or croak "illegal key: $_ for object of type ", ref $self; } keys %new_vals; } sub dumpp { my $self = shift; print $self->dump } sub dump { my $self = shift; my $output = Dumper($self); return $output; } sub as_hash { my $self = shift; my $class = ref $self; bless $self, 'HASH'; # easy magic my %guts = %{ $self }; bless $self, $class; $guts{class} = $class if is_legal_key(ref $self, 'class'); return \%guts; } 1; __END__ =pod =head1 NAME Audio::Nama::Object - Class builder =head1 SYNOPSIS # Define a class package Foo; use Audio::Nama::Object qw{ bux baz }; 1; # Use the class my $object = Foo->new( bux => 1 ); $object->set( bux => 2); print "bux is " . $object->bux . "\n"; # Define a subclass (automatically inherits parent attributes) package Bar; our @ISA = 'Foo'; my $lonely_bar = Bar->new(); $lonely_bar->set(bux => 3); Audio-Nama-1.208/lib/Audio/Nama/Grammar.pm0000644000175000017500000004141212644673574017130 0ustar jrothjroth# --------------------- Command Grammar ---------------------- package Audio::Nama; use Audio::Nama::Effect qw(:all); use Modern::Perl; sub setup_grammar { ### COMMAND LINE PARSER logsub("&setup_grammar"); $text->{commands_yml} = get_data_section("commands_yml"); $text->{commands_yml} = quote_yaml_scalars($text->{commands_yml}); $text->{commands} = yaml_in( $text->{commands_yml}) ; map { my $full_name = $_; my $shortcuts = $text->{commands}->{$full_name}->{short}; my @shortcuts = (); @shortcuts = split " ", $shortcuts if $shortcuts; map{ $text->{command_shortcuts}->{$_} = $full_name } @shortcuts; } keys %{$text->{commands}}; $Audio::Nama::AUTOSTUB = 1; $Audio::Nama::RD_TRACE = 1; $Audio::Nama::RD_ERRORS = 1; # Make sure the parser dies when it encounters an error $Audio::Nama::RD_WARN = 1; # Enable warnings. This will warn on unused rules &c. $Audio::Nama::RD_HINT = 1; # Give out hints to help fix problems. $text->{grammar} = get_data_section('grammar'); $text->{parser} = Parse::RecDescent->new($text->{grammar}) or croak "Bad grammar!\n"; # Midish command keywords $midi->{keywords} = { map{ $_, 1} split " ", get_data_section("midish_commands") }; } sub process_line { state $total_effects_count; logsub("&process_line"); no warnings 'uninitialized'; my ($user_input) = @_; # convert hyphenated commands to underscore form while( my ($from, $to) = each %{$text->{hyphenated_commands}}) { $user_input =~ s/$from/$to/g } logpkg(__FILE__,__LINE__,'debug',"user input: $user_input"); if (defined $user_input and $user_input !~ /^\s*$/) { $text->{term}->addhistory($user_input) unless $user_input eq $text->{previous_cmd} or ! $text->{term}; $text->{previous_cmd} = $user_input; if ($mode->{midish_terminal}){ $user_input =~ /^\s*(midish_mode_off|mmx)/ ? process_command($user_input) : midish_command($user_input); } else { my $context = context(); my $success = process_command( $user_input ); my $command_stamp = { context => $context, command => $user_input }; push(@{$project->{command_buffer}}, $command_stamp); if ( $config->{autosave} eq 'undo' and $config->{use_git} and $project->{name} and $project->{repo} and ! engine_running() ){ local $quiet = 1; Audio::Nama::ChainSetup::remove_temporary_tracks(); autosave() unless $config->{opts}->{R}; reconfigure_engine(); # quietly, avoiding noisy reconfig below } reconfigure_engine(); } # reset current track to Master if it is # undefined, or the track has been removed # from the index $this_track = $tn{Master} if ! $this_track or (ref $this_track and ! $tn{$this_track->name}); setup_hotkeys() if $config->{hotkeys_always}; } if (! engine_running() ){ my $result = check_fx_consistency(); logpkg(__FILE__,__LINE__,'logcluck',"Inconsistency found in effects data", Dumper ($result)) if $result->{is_error}; } revise_prompt( $mode->{midish_terminal} and "Midish > " ); my $output = delete $text->{output_buffer}; } sub context { my $context = {}; $context->{track} = $this_track->name; $context->{bus} = $this_bus; $context->{op} = $this_track->op; $context } sub process_command { my $input = shift; my $input_was = $input; # parse repeatedly until all input is consumed # return true on complete success # return false if any part of command fails my $was_error = 0; try { while (do { no warnings 'uninitialized'; $input =~ /\S/ }) { logpkg(__FILE__,__LINE__,'debug',"input: $input"); $text->{parser}->meta(\$input) or do { throw("bad command: $input_was\n"); $was_error++; system($config->{beep_command}) if $config->{beep_command}; last; }; } } catch { $was_error++; warn "caught error: $_" }; $ui->refresh; # in case we have a graphic environment set_current_bus(); # select chain operator if appropriate # and there is a current track if ($this_track){ my $FX = fxn($this_track->op); if ($FX and $this_track->n eq $FX->chain){ eval_iam("c-select ".$this_track->n); eval_iam("cop-select ". $FX->ecasound_effect_index); } } ! $was_error } sub do_user_command { my($cmd, @args) = @_; $text->{user_command}->{$cmd}->(@args); } sub do_script { my $name = shift; my $script; if ($name =~ / /){ $script = $name } else { my $filename; # look in project_dir() and project_root() # if filename provided does not contain slash if( $name =~ m!/!){ $filename = $name } else { $filename = join_path(project_dir(),$name); if(-e $filename){} else{ $filename = join_path(project_root(),$name) } } -e $filename or throw("$filename: file not found. Skipping"), return; $script = read_file($filename) } my @lines = split "\n",$script; my $old_opt_r = $config->{opts}->{R}; $config->{opts}->{R} = 1; # turn off auto reconfigure for my $input (@lines) { process_line($input) unless $input =~ /^\s*#/}; $config->{opts}->{R} = $old_opt_r; } sub dump_all { my $tmp = ".dump_all"; my $format = "json"; my $fname = join_path( project_root(), $tmp); save_system_state($fname,$format); file_pager("$fname.$format"); } sub user_set_current_track { my $cmd = shift; if( my $track = $tn{$cmd} || $ti{$cmd} ){ logpkg(__FILE__,__LINE__,'debug',"Selecting track ",$track->name); $this_track = $track; set_current_bus(); ecasound_select_chain( $this_track->n ); 1; } } ### allow commands to abbreviate Audio::Nama::Class as ::Class # SKIP_PREPROC { my @namespace_abbreviations = qw( Assign Track Bus Mark IO Graph Wav Insert Fade Edit Text Effect EffectChain ChainSetup ); my $namespace_root = 'Audio::Nama'; sub eval_perl { my $code = shift; map{ $code =~ s/(^|[^A-Za-z])::$_/$1$namespace_root\::$_/ } @namespace_abbreviations; # SKIP_PREPROC my $err; undef $text->{eval_result}; my @result = eval $code; if ($@){ throw( "Perl command failed: \ncode: $code\nerror: $@"); undef $@; } else { no warnings 'uninitialized'; @result = map{ dumper($_) } @result; $text->{eval_result} = join " ", @result; pager(join "\n", @result) } } } # end namespace abbreviations #### Formatted text output sub show_versions { no warnings 'uninitialized'; if (@{$this_track->versions} ){ "All versions: ". join(" ", map { my $cached = is_cached($this_track, $_) ? 'c' : ''; $cached .= 'C' if $this_track->is_version_comment($_); $_ . $cached } @{$this_track->versions} ). $/ } else {} } sub show_track_comment { my $track = shift; my $text = $track->is_comment; $text and "Track comment: $text\n"; } sub show_version_comment { my ($track, $version) = @_; my $text = $track->is_version_comment($version); $text and "Version comment: $text\n"; } sub show_send { "Send: ". $this_track->send_id. $/ if $this_track->rec_status ne OFF and $this_track->send_id } sub show_bus { "Bus: ". $this_track->group. $/ if $this_track->group ne 'Main' } sub show_effects { Audio::Nama::sync_effect_parameters(); join "", map { show_effect($_) } @{ $this_track->ops }; } sub list_effects { Audio::Nama::sync_effect_parameters(); join "", "Effects on ", $this_track->name,":\n", map{ list_effect($_) } @{ $this_track->ops }; } sub list_effect { my $op_id = shift; my $FX = fxn($op_id); my $line = $FX->nameline; $line .= q(, bypassed) if $FX->bypassed; ($op_id eq $this_track->op ? ' *' : ' ') . $line; } sub show_effect { my $op_id = shift; my $with_track = shift; my $FX = fxn($op_id); return unless $FX; my @lines = $FX->nameline; #EQ: GVerb, gverb, 1216, bypassed, famp5, neap my $i = $FX->registry_index; my @pnames = @{$fx_cache->{registry}->[ $i ]->{params}}; { no warnings 'uninitialized'; map { push @lines, parameter_info_padded($op_id, $_) } (0..scalar @pnames - 1) } map { push @lines, parameter_info_padded($op_id, $_) } (scalar @pnames .. (scalar @{$FX->params} - 1) ) if scalar @{$FX->params} - scalar @pnames - 1; @lines } sub extended_name { no warnings 'uninitialized'; my $op_id = shift; my $FX = fxn($op_id); return unless $FX; my $name = $FX->name; my $ladspa_id = $fx_cache->{ladspa_label_to_unique_id}->{$FX->type}; $name .= " ($ladspa_id)" if $ladspa_id; $name .= " (bypassed)" if $FX->bypassed; $name; } sub parameter_info { no warnings 'uninitialized'; my ($op_id, $parameter) = @_; # zero based my $FX = fxn($op_id); return unless $FX; my $entry = $FX->about->{params}->[$parameter]; my $name = $entry->{name}; $name .= " (read-only)" if $entry->{dir} eq 'output'; ($parameter+1).q(. ) . $name . ": ". $FX->params->[$parameter]; } sub parameter_info_padded { " "x 4 . parameter_info(@_) . "\n"; } sub named_effects_list { my @ops = @_; join("\n", map{ "$_ (" . fxn($_)->name. ")" } @ops), "\n"; } sub show_modifiers { join "", "Modifiers: ",$this_track->modifiers, $/ if $this_track->modifiers; } sub show_region { my $t = $Audio::Nama::this_track; return unless $t->rec_status eq PLAY; my @lines; push @lines,join " ", "Length:",time2($t->shifted_length),"\n"; $t->playat and push @lines,join " ", "Play at:",time2($t->shifted_playat_time), join($t->playat, qw[ ( ) ])."\n"; $t->region_start and push @lines,join " ", "Region start:",time2($t->shifted_region_start_time), join($t->region_start, qw[ ( ) ])."\n"; $t->region_end and push @lines,join " ", "Region end:",time2($t->shifted_region_end_time), join($t->region_end, qw[ ( ) ])."\n"; return(join "", @lines); } sub time2 { package Audio::Nama; my $n = shift; dn($n,3),"/",colonize(int ($n + 0.5)); } sub show_status { package Audio::Nama; my @output; my @modes; push @modes, $mode->{preview} if $mode->{preview}; push @modes, "master" if $mode->mastering; push @modes, "edit" if Audio::Nama::edit_mode(); push @modes, "offset run" if Audio::Nama::is_offset_run_mode(); push @output, "Modes settings: ", join(", ", @modes), $/ if @modes; my @actions; push @actions, "record" if grep{ ! /Mixdown/ } Audio::Nama::ChainSetup::really_recording(); push @actions, "playback" if grep { $_->rec_status eq PLAY } map{ $tn{$_} } $bn{Main}->tracks, q(Mixdown); # We only check Main bus for playback. # buses will route their playback signals through the # Main bus, however it may be that other bus mixdown # tracks are set to REC (with rec-to-file disabled) push @actions, "mixdown" if $tn{Mixdown}->rec_status eq REC; push @output, "Pending actions: ", join(", ", @actions), $/ if @actions; push @output, "Main bus version: ",$bn{Main}->version, $/ if $bn{Main}->version; push @output, "Setup length is: ", Audio::Nama::heuristic_time($setup->{audio_length}), $/; push @output, "Run time limit: ", Audio::Nama::heuristic_time($setup->{runtime_limit}), $/ if $setup->{runtime_limit}; } sub placeholder { my $val = shift; return $val if defined $val and $val !~ /^\s*$/; $config->{use_placeholders} ? q(--) : q() } sub show_inserts { my $output; $output = $Audio::Nama::Insert::by_index{$this_track->prefader_insert}->dump if $this_track->prefader_insert; $output .= $Audio::Nama::Insert::by_index{$this_track->postfader_insert}->dump if $this_track->postfader_insert; "Inserts:\n".join( "\n",map{" "x4 . $_ } split("\n",$output))."\n" if $output; } $text->{format_top} = <{format_divider} = '-' x 77 . "\n"; my $format_picture = <> @<<<<<<<<<<<<<< @>>> @<<<<<< @<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<< @>>> @>>> PICTURE sub show_tracks_section { no warnings; #$^A = $text->{format_top}; my @tracks = grep{ ref $_ } @_; # HACK! undef should not be passed map { formline $format_picture, $_->n, $_->name, $_->rw eq $_->rec_status ? undef : $_->rw, $_->rec_status_display, placeholder($_->source_status), placeholder($_->destination), placeholder($_->vol_level), placeholder($_->pan_level), ($_->is_comment ? 'C' : undef) } @tracks; my $output = $^A; $^A = ""; #$output .= show_tracks_extra_info(); $output; } sub show_tracks { my @array_refs = @_; my @list = $text->{format_top}; for( @array_refs ){ my ($mix,$bus) = splice @$_, 0, 2; push @list, Audio::Nama::Bus::settings_line($mix, $bus), show_tracks_section(@$_), } @list } sub showlist { package Audio::Nama; my @list = grep{ ! $_->hide } Audio::Nama::all_tracks(); my $section = [undef,undef,@list]; my ($screen_lines, $columns); if( $text->{term} ) { ($screen_lines, $columns) = $text->{term}->get_screen_size(); } return $section if scalar @list <= $screen_lines - 5 or ! $screen_lines; my @sections; push @sections, [undef,undef, map $tn{$_},qw(Master Mixdown)]; push @sections, [$tn{Master},$bn{Main},map $tn{$_},$bn{Main}->tracks ]; if( $mode->mastering ){ push @sections, [undef,undef, map $tn{$_},$bn{Mastering}->tracks] } elsif($this_bus ne 'Main'){ push @sections, [$tn{$this_bus},$bn{$this_bus}, map $tn{$_}, $this_bus, $bn{$this_bus}->tracks] } @sections } #### Some Text Commands sub t_load_project { package Audio::Nama; return if engine_running() and Audio::Nama::ChainSetup::really_recording(); my $name = shift; my %args = @_; pager("input name: $name\n"); $name = sanitize($name); throw("Project $name does not exist\n"), return unless -d join_path(project_root(), $name) or $args{create}; stop_transport() if engine_running(); save_state(); load_project( name => $name, %args ); pager("loaded project: $project->{name}\n") unless $args{create}; {no warnings 'uninitialized'; logpkg(__FILE__,__LINE__,'debug',"load hook: $config->{execute_on_project_load}"); } Audio::Nama::process_command($config->{execute_on_project_load}); } sub sanitize { my $name = shift; my $newname = remove_spaces($name); $newname =~ s(/$)(); # remove trailing slash $newname; } sub t_create_project { package Audio::Nama; my $name = shift; t_load_project($name, create => 1); pager("created project: $project->{name}\n"); } sub mixdown { pager_newline("Enabling mixdown to file") if ! $quiet; $tn{Mixdown}->set(rw => REC); } sub mixplay { pager_newline("Setting mixdown playback mode.") if ! $quiet; $tn{Mixdown}->set(rw => PLAY); $tn{Master}->set(rw => OFF); $bn{Main}->set(rw => OFF); } sub mixoff { pager_newline("Leaving mixdown mode.") if ! $quiet; $tn{Mixdown}->set(rw => OFF); $tn{Master}->set(rw => MON); $bn{Main}->set(rw => MON); } sub remove_fade { my $i = shift; my $fade = $Audio::Nama::Fade::by_index{$i} or throw("fade index $i not found. Aborting."), return 1; pager("removing fade $i from track " .$fade->track ."\n"); $fade->remove; } sub import_audio { my ($track, $path, $frequency) = @_; $track->import_audio($path, $frequency); # check that track is audible $track->set(rw => PLAY); } sub destroy_current_wav { carp($this_track->name.": must be set to PLAY."), return unless $this_track->rec_status eq PLAY; $this_track->current_version or throw($this_track->name, ": No current version (track set to OFF?) Skipping."), return; my $wav = $this_track->full_path; my $reply = $text->{term}->readline("delete WAV file $wav? [n] "); #my $reply = chr($text->{term}->read_key()); if ( $reply =~ /y/i ){ # remove version comments, if any delete $this_track->{version_comment}{$this_track->current_version}; pager("Unlinking.\n"); unlink $wav or warn "couldn't unlink $wav: $!\n"; restart_wav_memoize(); } $text->{term}->remove_history($text->{term}->where_history); $this_track->set(version => 0); # reset $this_track->set(version => $this_track->current_version); 1; } sub pan_check { my ($track, $new_position) = @_; my $current = $track->pan_o->params->[0]; $track->set(old_pan_level => $current) unless defined $track->old_pan_level; update_effect( $track->pan, # id 0, # parameter $new_position, # value ); } sub remove_track_cmd { my ($track) = @_; # avoid having ownerless SlaveTracks. Audio::Nama::ChainSetup::remove_temporary_tracks(); $quiet or pager( "Removing track /",$track->name,"/. All WAV files will be kept."); remove_submix_helper_tracks($track->name); $track->remove; $this_track = $tn{Master}; 1 } sub unity { my ($track, $save_level) = @_; if ($save_level){ $track->set(old_vol_level => fxn($track->vol)->params->[0]); } update_effect( $track->vol, 0, $config->{unity_level}->{fxn($track->vol)->type} ); } sub vol_back { my $track = shift; my $old = $track->old_vol_level; if (defined $old){ update_effect( $track->vol, # id 0, # parameter $old, # value ); $track->set(old_vol_level => undef); } } sub pan_back { my $track = shift; my $old = $track->old_pan_level; if (defined $old){ update_effect( $track->pan, # id 0, # parameter $old, # value ); $track->set(old_pan_level => undef); } }Audio-Nama-1.208/lib/Audio/Nama/Jack.pm0000644000175000017500000002433712644673574016421 0ustar jrothjroth# ------- Jack port connect routines ------- package Audio::Nama; use Modern::Perl; use File::Slurp; no warnings 'uninitialized'; # general functions sub poll_jack { jack_update(); # first time # then repeat $project->{events}->{poll_jack} = AE::timer(0,5,\&jack_update) } sub jack_update { #logsub("&jack_update"); # cache current JACK status # skip if Ecasound is busy return if engine_running(); if( $jack->{jackd_running} = process_is_running('jackd') ){ # reset our clients data $jack->{clients} = {}; $jack->{use_jacks} ? jacks_get_port_latency() : parse_port_latency(); parse_ports_list(); my ($bufsize) = qx(jack_bufsize); ($jack->{periodsize}) = $bufsize =~ /(\d+)/; } else { } } sub client_port { my $name = shift; $name =~ /(.+?):([^:]+)$/; =comment $name =~ / (?.+?) # anything, non-greedy : # a colon (?[^:]+$) # non-colon stuff to end /x; @+{qw(client port)} =cut $1, $2 } sub jack_client_array { # returns array of ports if client and direction exist my ($name, $direction) = @_; $jack->{clients}->{$name}{$direction} // [] } sub jacks_get_port_latency { logsub('&jacks_get_port_latency'); delete $jack->{clients}; my $jc; $jc = jacks::JsClient->new("watch latency", undef, $jacks::JackNullOption, 0); my $plist = $jc->getPortNames("."); for (my $i = 0; $i < $plist->length(); $i++) { my $pname = $plist->get($i); my ($client_name,$port_name) = client_port($pname); logpkg(__FILE__,__LINE__,'debug',qq(client: $client_name, port: $port_name)); my $port = $jc->getPort($pname); #my @connections = $jc->getAllConnections($client_name, $port_name); #say for @connections; my $platency = $port->getLatencyRange($jacks::JackPlaybackLatency); my $pmin = $platency->min(); my $pmax = $platency->max(); logpkg(__FILE__,__LINE__,'debug',"$pname: playback Latency [ $pmin $pmax ]"); $jack->{clients}->{$client_name}->{$port_name}->{latency}->{playback}->{min} = $pmin; $jack->{clients}->{$client_name}->{$port_name}->{latency}->{playback}->{max} = $pmax; my $clatency = $port->getLatencyRange($jacks::JackCaptureLatency); my $cmin = $clatency->min(); my $cmax = $clatency->max(); logpkg(__FILE__,__LINE__,'debug',"$pname: capture Latency [ $cmin $cmax ]"); $jack->{clients}->{$client_name}->{$port_name}->{latency}->{capture}->{min} = $cmin; $jack->{clients}->{$client_name}->{$port_name}->{latency}->{capture}->{max} = $cmax; } } sub parse_port_connections { my $j = shift || qx(jack_lsp -c 2> /dev/null); return unless $j; # initialize $jack->{connections} = {}; # convert to single lines $j =~ s/\n\s+/ /sg; my @lines = split "\n",$j; #say for @ports; for (@lines){ my ($port, @connections) = split " ", $_; #say "$port @connections"; $jack->{connections}->{$port} = \@connections; } } sub jack_port_to_nama { my $jack_port = shift; grep{ /Nama/ and $jack->{is_own_port}->{$_} } @{ $jack->{connections}->{$jack_port} }; } sub parse_port_latency { # default to use output of jack_lsp -l my $j = shift || qx(jack_lsp -l 2> /dev/null); logpkg(__FILE__,__LINE__,'debug', "latency input $j"); state $port_latency_re = qr( # ecasound:in_1 (?[^:]+) # non-colon : # colon (?\S+?) # non-space \s+ # port latency = 2048 frames # DEPRECATED \Qport latency = \E \d+ # don't capture \Q frames\E \s+ # port playback latency = [ 0 2048 ] frames \Qport playback latency = [ \E (?\d+) \s+ (?\d+) \Q ] frames\E \s+ # port capture latency = [ 0 2048 ] frames \Qport capture latency = [ \E (?\d+) \s+ (?\d+) \Q ] frames\E )x; # convert to single lines $j =~ s/\n\s+/ /sg; my @ports = split "\n",$j; map { /$port_latency_re/; #logpkg(__FILE__,__LINE__,'debug', Dumper %+); logpkg(__FILE__,__LINE__,'debug', "client: ",$+{client}); logpkg(__FILE__,__LINE__,'debug', "port: ",$+{port}); logpkg(__FILE__,__LINE__,'debug', "capture min: ", $+{capture_min}); logpkg(__FILE__,__LINE__,'debug', "capture max: ",$+{capture_max}); logpkg(__FILE__,__LINE__,'debug', "playback min: ",$+{playback_min}); logpkg(__FILE__,__LINE__,'debug', "playback max: ",$+{playback_max}); $jack->{clients}->{$+{client}}->{$+{port}}->{latency}->{capture}->{min} = $+{capture_min}; $jack->{clients}->{$+{client}}->{$+{port}}->{latency}->{capture}->{max} = $+{capture_max}; $jack->{clients}->{$+{client}}->{$+{port}}->{latency}->{playback}->{min} = $+{playback_min}; $jack->{clients}->{$+{client}}->{$+{port}}->{latency}->{playback}->{max} = $+{playback_max}; } @ports; } sub parse_ports_list { # default to output of jack_lsp -p logsub("&parse_ports_list"); my $j = shift || qx(jack_lsp -p 2> /dev/null); logpkg(__FILE__,__LINE__,'debug', "input: $j"); # convert to single lines $j =~ s/\n\s+/ /sg; # system:capture_1 alsa_pcm:capture_1 properties: output,physical,terminal, #fluidsynth:left properties: output, #fluidsynth:right properties: output, map{ my ($direction) = /properties: (input|output)/; s/properties:.+//; my @port_aliases = / \s* # zero or more spaces ([^:]+:[^:]+?) # non-colon string, colon, non-greedy non-colon string (?=[-+.\w]+:|\s+$) # zero-width port name or spaces to end-of-string /gx; map { s/ $//; # remove trailing space # make entries for 'system' and 'system:capture_1' push @{ $jack->{clients}->{$_}->{$direction} }, $_; my ($client, $port) = /(.+?):(.+)/; push @{ $jack->{clients}->{$client}->{$direction} }, $_; } @port_aliases; } grep{ ! /^jack:/i } # skip spurious jackd diagnostic messages split "\n",$j; } # connect jack ports via jack.plumbing or jack_connect sub jack_plumbing_conf { join_path( $ENV{HOME} , '.jack.plumbing' ) } { my $fh; my $plumbing_tag = q(BEGIN NAMA CONNECTIONS LIST); my $plumbing_header = qq(;### $plumbing_tag ;## The following lines are automatically generated. ;## DO NOT place any connection data below this line!! ; ); sub initialize_jack_plumbing_conf { # remove nama lines return unless -f -r jack_plumbing_conf(); my $user_plumbing = read_file(jack_plumbing_conf()); # keep user data, deleting below tag $user_plumbing =~ s/;[# ]*$plumbing_tag.*//gs; write_file(jack_plumbing_conf(), $user_plumbing); } my $jack_plumbing_code = sub { my ($port1, $port2) = @_; my $debug++; my $config_line = qq{(connect $port1 $port2)}; say $fh $config_line; # $fh in lexical scope logpkg(__FILE__,__LINE__,'debug', $config_line); }; my $jack_connect_code = sub { my ($port1, $port2) = @_; my $debug++; my $cmd = qq(jack_connect $port1 $port2); logpkg(__FILE__,__LINE__,'debug', $cmd); system($cmd) == 0 or die "system $cmd failed: $?"; }; sub connect_jack_ports_list { my @source_tracks = grep{ $_->source_type eq 'jack_ports_list' and $_->rec_status eq REC } Audio::Nama::ChainSetup::engine_tracks(); my @send_tracks = grep{ $_->send_type eq 'jack_ports_list' } Audio::Nama::ChainSetup::engine_tracks(); # we need JACK return if ! $jack->{jackd_running}; # We need tracks to configure return if ! @source_tracks and ! @send_tracks; sleeper(0.3); # extra time for ecasound engine to register JACK ports if( $config->{use_jack_plumbing} ) { # write config file initialize_jack_plumbing_conf(); open($fh, ">>", jack_plumbing_conf()) or die("can't open ".jack_plumbing_conf()." for append: $!"); print $fh $plumbing_header; make_connections($jack_plumbing_code, \@source_tracks, 'in' ); make_connections($jack_plumbing_code, \@send_tracks, 'out'); close $fh; # run jack.plumbing start_jack_plumbing(); sleeper(3); # time for jack.plumbing to launch and poll kill_jack_plumbing(); initialize_jack_plumbing_conf(); } else { make_connections($jack_connect_code, \@source_tracks, 'in' ); make_connections($jack_connect_code, \@send_tracks, 'out'); } } } sub quote { $_[0] =~ /^"/ ? $_[0] : qq("$_[0]")} sub make_connections { my ($code, $tracks, $direction) = @_; my $ports_list = $direction eq 'in' ? 'source_id' : 'send_id'; map{ my $track = $_; my $name = $track->name; my $ecasound_port = "Nama:$name\_$direction\_"; my $file = join_path(project_root(), $track->$ports_list); throw($track->name, ": JACK ports file $file not found. No sources connected."), return if ! -e -r $file; my $line_number = 0; my @lines = read_file($file); for my $external_port (@lines){ # $external_port is the source port name chomp $external_port; logpkg(__FILE__,__LINE__,'debug', "port file $file, line $line_number, port $external_port"); # setup shell command if(! $jack->{clients}->{$external_port}){ throw($track->name, qq(: port "$external_port" not found. Skipping.)); next } # ecasound port index my $index = $track->width == 1 ? 1 : $line_number % $track->width + 1; my @ports = map{quote($_)} $external_port, $ecasound_port.$index; $code->( $direction eq 'in' ? @ports : reverse @ports ); $line_number++; }; } @$tracks } sub kill_jack_plumbing { qx(killall jack.plumbing >/dev/null 2>&1) unless $config->{opts}->{A} or $config->{opts}->{J}; } sub start_jack_plumbing { if ( $config->{use_jack_plumbing} # not disabled in namarc and ! ($config->{opts}->{J} or $config->{opts}->{A}) # we are not testing ){ system('jack.plumbing >/dev/null 2>&1 &') == 0 or die "can't run jack.plumbing: $?" } } sub jack_client : lvalue { my $name = shift; logit(__LINE__,'Audio::Nama::Jack','info',"$name: non-existent JACK client") if not $jack->{clients}->{$name} ; $jack->{clients}->{$name} } sub port_mapping { my $jack_port = shift; my $own_port; #..... $own_port } sub register_other_ports { return unless $jack->{jackd_running}; $jack->{is_other_port} = { map{ chomp; $_ => 1 } qx(jack_lsp) } } sub register_own_ports { # distinct from other Nama instances return unless $jack->{jackd_running}; $jack->{is_own_port} = { map{chomp; $_ => 1} grep{ ! $jack->{is_other_port}->{$_} } grep{ /^Nama/ } qx(jack_lsp) } } 1; __END__ Audio-Nama-1.208/lib/Audio/Nama/Midi.pm0000644000175000017500000000437512644673574016433 0ustar jrothjroth# ------------- MIDI routines ----------- package Audio::Nama; use Modern::Perl; use Carp; { my($error,$answer)=('',''); my ($pid, $sel); my @handles = my ($fh_midish_write, $fh_midish_read, $fh_midish_error) = map{ IO::Handle->new() } 1..3; map{ $_->autoflush(1) } @handles; sub start_midish { my $executable = qx(which midish); chomp $executable; $executable or say("Midish not found!"), return; $pid = open3($fh_midish_write, $fh_midish_read, $fh_midish_error,"$executable -v") or warn "Midish failed to start!"; $sel = IO::Select->new(); $sel->add($fh_midish_read); $sel->add($fh_midish_error); midish_command( qq(print "Midish is ready.") ); } sub start_midish_transport { my $sync = $mode->{midish_transport_sync}; my $start_command; $start_command = 'p' if $sync eq 'play'; $start_command = 'r' if $sync eq 'record'; defined $start_command or die "$mode->{midish_transport_sync}: illegal midish_transport_sync mode"; midish_command($start_command); } sub stop_midish_transport { midish_command('s') } sub midish_command { my $query = shift; print "\n"; #$config->{use_midish} or say( qq($query: cannot execute Midish command #unless you set "midish_enable: 1" in .namarc)), return; #$query eq 'exit' and say("Will exit Midish on closing Nama."), return; #send query to midish print $fh_midish_write "$query\n"; my $length = 2**16; sleeper(0.05); foreach my $h ($sel->can_read) { my $buf = ''; if ($h eq $fh_midish_error) { sysread($fh_midish_error,$buf,$length); if($buf){print "MIDISH ERR-> $buf\n"} } else { sysread($fh_midish_read,$buf,$length); if($buf){map{say} grep{ !/\+ready/ } split "\n", $buf} } } print "\n"; } sub close_midish { my $save_file = join_path(project_dir(), "$project->{name}.msh"); say "saving midish as $save_file"; midish_command("save $save_file"); #my $fh; #$_->close for $fh_midish_read, $fh_midish_write, $fh_midish_error; #sleeper(0.2); #say "exiting midish"; #midish_command("exit"); # isn't necessary, triggers a warning #$_->flush for @handles; # doesn't help warning # sleeper(0.1); # kill 15,$pid; # sleeper(0.1); # kill 9,$pid; # sleeper(0.1); # waitpid($pid, 1); # It is important to waitpid on your child process, # otherwise zombies could be created. } } 1; __END__Audio-Nama-1.208/lib/Audio/Nama/Bunch.pm0000644000175000017500000000411512644673574016600 0ustar jrothjroth# ---------------------- Bunch ----------------- # # operate on a list of tracks package Audio::Nama; use Modern::Perl; sub is_bunch { my $name = shift; $bn{$name} or $project->{bunch}->{$name} } { my %set_stat = ( (map{ $_ => 'rw' } qw(rec play mon off) ), map{ $_ => 'rec_status' } qw(REC PLAY MON OFF ) ); sub bunch { my ($bunchname, @tracks) = @_; if (! $bunchname){ Audio::Nama::pager(json_out( $project->{bunch} )); } elsif (! @tracks){ $project->{bunch}->{$bunchname} and pager("bunch $bunchname: @{$project->{bunch}->{$bunchname}}\n") or throw("bunch $bunchname: does not exist.\n"); } elsif (my @mispelled = grep { ! $tn{$_} and ! $ti{$_}} @tracks){ Audio::Nama::throw("@mispelled: mispelled track(s), skipping.\n"); } else { $project->{bunch}->{$bunchname} = [ @tracks ]; } } sub add_to_bunch {} sub bunch_tracks { my $bunchy = shift; my @tracks; if ( my $bus = $bn{$bunchy}){ @tracks = $bus->tracks; } elsif ( $bunchy eq 'bus' ){ logpkg(__FILE__,__LINE__,'debug', "special bunch: bus"); @tracks = grep{ ! $bn{$_} } $bn{$this_bus}->tracks; } elsif ($bunchy =~ /\s/ # multiple identifiers or $tn{$bunchy} or $bunchy !~ /\D/ and $ti{$bunchy}){ logpkg(__FILE__,__LINE__,'debug', "multiple tracks found"); # verify all tracks are correctly named my @track_ids = split " ", $bunchy; my @illegal = grep{ ! track_from_name_or_index($_) } @track_ids; if ( @illegal ){ throw("Invalid track ids: @illegal. Skipping."); } else { @tracks = map{ $_->name} map{ track_from_name_or_index($_)} @track_ids; } } elsif ( my $method = $set_stat{$bunchy} ){ logpkg(__FILE__,__LINE__,'debug', "special bunch: $bunchy, method: $method"); $bunchy = uc $bunchy; @tracks = grep{$tn{$_}->$method eq $bunchy} $bn{$this_bus}->tracks } elsif ( $project->{bunch}->{$bunchy} and @tracks = @{$project->{bunch}->{$bunchy}} ) { logpkg(__FILE__,__LINE__,'debug', "bunch tracks: @tracks"); } else { throw("$bunchy: no matching bunch identifier found") } @tracks; } } sub track_from_name_or_index { /\D/ ? $tn{$_[0]} : $ti{$_[0]} } 1;Audio-Nama-1.208/lib/Audio/Nama/AnalyseLV2.pm0000644000175000017500000001774012644673574017471 0ustar jrothjroth# ----------------- Analyse LV2 Plugins ------------------ # contributed by S. Massy # package Audio::Nama::AnalyseLV2; use Audio::Nama::Log qw(logpkg); # Initialise our global variables: # Store the plugin info: use strict; my %plugin; my %scalepoints; # Path to utilities my $lv2info; my $lv2ls; # Various internals: my $currentport; my @contents; sub _analyse_lv2 { %plugin = (); # Some variables used here. my ($uri) = @_; my $linecount = my $match; $currentport = -1; unless (acquire_lv2($uri)) { $plugin{error} = "Plugin not found."; return \%plugin; } foreach my $line (@contents) { logpkg(__FILE__,__LINE__,'debug',"Parsing $line"); $linecount++; $plugin{general}{uri} = $line if ($linecount == 1); if ($line =~ /^(\t| )+Name\:(\t| )+(.*+)/ && $currentport == -1) { $plugin{general}{name} = $3; } if (($line =~ /^(\t| )+Class\:(\t| )+(.*+)/) && !($line =~ /(\:\/\/)/) ) { $plugin{general}{class} = $3; } if ($line =~ /^(\t| )+Author\:(\t| )+(.*+)/) { $plugin{general}{author} = $3; } if ($line =~ /^(\t| )+Has latency\:(\t| )+(.*+)/) { $plugin{general}{has_latency} = $3; } # Next we embark on port data collection. # ...fffirst acquire current port. if ($line =~ /^(\t| )+file\:\/\/.*\.ttl$/ && ($currentport == -1) ) { chomp($line); $line =~ s/(\t| )+file\:\/\///; $plugin{'general'}{'datafile'} = $line; logpkg(__FILE__,__LINE__,'debug',"datafile: $plugin{'general'}{'datafile'}\n"); } if ($line =~ /(\t| )+Port (\d+)\:$/) { $currentport = $2; logpkg(__FILE__,__LINE__,'debug',"Acquiring info for $currentport\n"); } # type if ($line =~ /lv2core#(.+)Port$/) { $match = $1; if ($match =~ /Input|Output/) { $plugin{$currentport}{iotype} = $match; logpkg(__FILE__,__LINE__,'debug',"IOTYPE $plugin{$currentport}{iotype}\n"); } else { if (exists($plugin{$currentport}{etype})) { $plugin{$currentport}{etype} .= " "; } $plugin{$currentport}{etype} .= $match; logpkg(__FILE__,__LINE__,'debug',"Acquired ETYPE $1 \n"); } } # A special case for events. if ($line =~ /http.+\#(.+)Event$/ ) { $match = $1; if ( exists($plugin{$currentport}{etype}) ) { $plugin{$currentport}{etype} .= ", "; } $plugin{$currentport}{etype} .= $match; } # Name if ($line =~ /(\t| )+Name\:(\t| )+(.+$)/ && ($currentport != -1)) { $plugin{$currentport}{name} = $3; logpkg(__FILE__,__LINE__,'debug',"Port name is $plugin{$currentport}{name}\n"); } # MINVAL/MAXVAL/DEFVAL if ($line =~ /(\t| )+Minimum\:(\t| )+(.+$)/) { $plugin{$currentport}{minval} = $3; logpkg(__FILE__,__LINE__,'debug',"Acquired minval $plugin{$currentport}{minval}\n"); } if ($line =~ /(\t| )+Maximum\:(\t| )+(.+$)/) { $plugin{$currentport}{maxval} = $3; } if ($line =~ /(\t| )+Default\:(\t| )+(.+$)/) { $plugin{$currentport}{defval} = $3; } # Properties if ($line =~ /extportinfo#(.+$)/) { if (exists($plugin{$currentport}{props})) { $plugin{$currentport}{props} .= ", "; } $plugin{$currentport}{props} .= $1; } if ($currentport != -1 && $line =~ /Scale Points\:/) { $plugin{$currentport}{scalepoints} = 0; } if ($line =~ /(\t+| +)+(-?\d+\.?\d*) = \"(.*)\"$/ && exists($plugin{$currentport}{scalepoints})) { $plugin{$currentport}{scalepoints}++; $scalepoints{$currentport}{$2} = $3; } } $plugin{general}{maxport} = $currentport; $currentport = -1; # We iterate over the ports to add the selector property. for ($currentport = 0; $currentport <= $plugin{general}{maxport}; $currentport++) { if (exists($plugin{$currentport}{scalepoints})) { if (exists($plugin{$currentport}{props})) { $plugin{$currentport}{props} .= ", "; } $plugin{$currentport}{props} .= $plugin{$currentport}{scalepoints} . "-way Selector"; } } # Gather info from datafile proc_datafile($plugin{'general'}{'datafile'}); return (\%plugin, \%scalepoints); } # end of sub crunch sub stripzeros { my ($value) = @_; $value =~ s/\.0+$|0+$//; return $value; } sub generateportinfo { my $portinfo; $portinfo .= "\"$plugin{$currentport}{'name'}"; # For units if (exists($plugin{$currentport}{'units'})) { $portinfo .= " (" . cunits($plugin{$currentport}{'units'}) . ")"; } $portinfo .= "\" "; $portinfo .= "$plugin{$currentport}{iotype}, "; $portinfo .= "$plugin{$currentport}{etype}"; $portinfo .= ", " . &stripzeros($plugin{$currentport}{minval}) if exists($plugin{$currentport}{minval}); $portinfo .= " to " . &stripzeros($plugin{$currentport}{maxval}) if exists($plugin{$currentport}{maxval}); $portinfo .= ", default " . &stripzeros($plugin{$currentport}{defval}) if (exists($plugin{$currentport}{defval}) && $plugin{$currentport}{defval} ne "nan"); $portinfo .= ", " . filterprops($plugin{$currentport}{props}) if (exists($plugin{$currentport}{props}) && filterprops($plugin{$currentport}{props}) ne ""); $portinfo .= "\n"; return $portinfo; } sub filterprops { # Try to limit output my ($props) = @_; # Cut HasStrictBounds is long, uuuuuuseless?, and not in ladspa $props =~ s/, hasStrictBounds|hasStrictBounds, |hasStrictBounds//; # Don't just leave a comma and space $props =~ s/^, $|^ +$//; logpkg(__FILE__,__LINE__,'debug',"props: $props\n"); return $props;; } sub print_lv2 { my @buffer; push @buffer, "Name: $plugin{general}{name}\n" if exists($plugin{general}{name}); push @buffer, "URI: $plugin{general}{uri}"; push @buffer, "Class: $plugin{general}{class}\n" if exists($plugin{general}{class}); push @buffer, "Author: $plugin{general}{author}\n" if exists($plugin{general}{author}); push @buffer, "Latency: $plugin{general}{has_latency}\n" if exists($plugin{general}{has_latency}); for ($currentport = 0; $currentport <= $plugin{general}{maxport}; $currentport++) { if ($currentport == 0) { push @buffer, "Ports: "; } else { push @buffer, "\t"; } push @buffer, generateportinfo(); } push @buffer, "\n"; return @buffer; } sub acquire_lv2 { my ($uri) = @_; @contents = `$lv2info $uri`; logpkg(__FILE__,__LINE__,'debug',"Acquiring contents for $uri\n"); # logpkg(__FILE__,__LINE__,'debug',"$contents[0]\n"; return 0 if ($contents[0] eq ""); return 1; } sub find_utils { my $output; $output = `which lv2info`; chomp($output); if ( $output =~ /^\/.+lv2info$/ ) { $lv2info = $output;; } else { return 0; } $output = `which lv2ls`; chomp($output); if ( $output =~ /^\/.+lv2ls$/ ) { $lv2ls = $output; } else { return 0; } return 1; } sub trymatch { my ($string) = @_; my @lv2lsoutput = `$lv2ls`; my @results; foreach my $uline (@lv2lsoutput) { chomp($uline); push(@results, ($uline)) if ($uline =~ /$string/i); } return @results; } sub print_lv2_scalepoints { my @buffer; if (keys(%scalepoints) > 0) { push @buffer, "Printing full information for ports with scale points in plugin...\n$plugin{general}{name}\n"; foreach my $port (sort {$a <=> $b} (keys(%scalepoints))) { $currentport = $port; push @buffer, "Port $currentport: " . generateportinfo(); foreach my $point ( sort {$a <=> $b} (keys(%{ $scalepoints{$currentport} })) ) { push @buffer, "\t $point \= $scalepoints{$currentport}{$point}\n"; } } } else { push @buffer, "Plugin $plugin{general}{name} does not have any port with scale points.\n\n"; } return @buffer; } sub analyse_lv2 { my ($uri) = @_; if ( find_utils() ) { return _analyse_lv2($uri); } else { $plugin{error} = "Utilities not found."; return \%plugin; } } sub lv2_help { my $uri = shift; find_utils(); analyse_lv2($uri); print_lv2(); } #print lv2_help('http://plugin.org.uk/swh-plugins/zm1'); #print lv2_help('urn:50m30n3:plugins:SO-404'); sub proc_datafile { my ($file) = @_; open(my $fh, "<", $file) || return 0; $currentport = -1; while (my $curline = <$fh>) { if ($curline =~ /lv2\:index +(\d+) *;$/ ) { $currentport = $1; } if ($curline =~ /ue\:unit +ue\:([a-zA-Z0-9_]+) *;$/ && ($currentport != -1)) { $plugin{$currentport}{'units'} = $1; } } close($fh); $currentport = -1; return 1; } sub cunits { (my $units) = @_; $units =~ s/pc/\%/ if $units =~ /pc/; return $units; } 1;Audio-Nama-1.208/lib/Audio/Nama/Mark.pm0000644000175000017500000001565212644673574016443 0ustar jrothjroth # ----------- Mark ------------ package Audio::Nama::Mark; our $VERSION = 1.0; use Carp; use warnings; no warnings qw(uninitialized); our @ISA; use vars qw($n %by_name @all); use Audio::Nama::Log qw(logpkg); use Audio::Nama::Globals qw(:all); use Audio::Nama::Object qw( name time active ); sub initialize { map{ $_->remove} Audio::Nama::Mark::all(); @all = (); %by_name = (); # return ref to Mark by name $by_name{Here} = bless {}, 'Audio::Nama::HereMark'; @Audio::Nama::marks_data = (); # for save/restore } sub next_id { # returns incremented 4-digit $project->{mark_sequence_counter} ||= '0000'; $project->{mark_sequence_counter}++ } sub new { my $class = shift; my %vals = @_; croak "undeclared field: @_" if grep{ ! $_is_field{$_} } keys %vals; # to support set_edit_points, we now allow marks to be overwritten # #croak "name already in use: $vals{name}\n" # if $by_name{$vals{name}}; # null name returns false my $object = bless { ## defaults ## active => 1, name => "", @_ }, $class; #print "object class: $class, object type: ", ref $object, $/; if ($object->name) { $by_name{ $object->name } = $object; } push @all, $object; $Audio::Nama::this_mark = $object; $object; } sub set_name { my $mark = shift; my $name = shift; pager("name: $name\n"); if ( defined $by_name{ $name } ){ carp "you attempted to assign to name already in use\n"; } else { $mark->set(name => $name); $by_name{ $name } = $mark; } } sub jump_here { my $mark = shift; Audio::Nama::set_position($mark->time); $Audio::Nama::this_mark = $mark; } sub shifted_time { # for marks within current edit my $mark = shift; return $mark->time unless $mode->{offset_run}; my $time = $mark->time - Audio::Nama::play_start_time(); $time > 0 ? $time : 0 } sub remove { my $mark = shift; Audio::Nama::throw('Fades depend on this mark. Remove failed.'), return if Audio::Nama::fade_uses_mark($mark->name); if ( $mark->name ) { delete $by_name{$mark->name}; } @all = grep { $_->time != $mark->time } @all; } sub next { my $mark = shift; Audio::Nama::next_mark(); } sub previous { my $mark = shift; Audio::Nama::previous_mark(); } # -- Class Methods sub all { sort { $a->{time} <=> $b->{time} }@all } sub loop_start { my @points = sort { $a <=> $b } grep{ $_ } map{ mark_time($_)} @{$setup->{loop_endpoints}}[0,1]; #print "points @points\n"; $points[0]; } sub loop_end { my @points =sort { $a <=> $b } grep{ $_ } map{ mark_time($_)} @{$setup->{loop_endpoints}}[0,1]; $points[1]; } sub time_from_tag { my $tag = shift; $tag or $tag = ''; #print "tag: $tag\n"; my $mark; if ($tag =~ /\./) { # we assume raw time if decimal #print "mark time: ", $tag, $/; return $tag; } elsif ($tag =~ /^\d+$/){ #print "mark index found\n"; $mark = $Audio::Nama::Mark::all[$tag]; } else { #print "mark name found\n"; $mark = $Audio::Nama::Mark::by_name{$tag}; } return undef if ! defined $mark; #print "mark time: ", $mark->time, $/; return $mark->time; } sub duration_from_tag { my $tag = shift; $tag or $tag = ''; #print "tag: $tag\n"; my $mark; if ($tag =~ /[\d.-]+/) { # we assume time #print "mark time: ", $tag, $/; return $tag; } else { #print "mark name found\n"; $mark = $Audio::Nama::Mark::by_name{$tag}; } return undef if ! defined $mark; #print "mark time: ", $mark->time, $/; return $mark->time; } sub mark_time { my $tag = shift; my $time = time_from_tag($tag); return unless defined $time; $time -= Audio::Nama::play_start_time() if $mode->{offset_run}; $time } # ---------- Mark and jump routines -------- { package Audio::Nama; use Modern::Perl; use Audio::Nama::Globals qw(:all); sub drop_mark { logsub("&drop_mark"); my $name = shift; my $here = eval_iam("getpos"); if( my $mark = $Audio::Nama::Mark::by_name{$name}){ pager("$name: a mark with this name exists already at: ", colonize($mark->time)); return } if( my ($mark) = grep { $_->time == $here} Audio::Nama::Mark::all()){ pager( q(This position is already marked by "),$mark->name,q(") ); return } my $mark = Audio::Nama::Mark->new( time => $here, name => $name); $ui->marker($mark); # for GUI } sub mark { # GUI_CODE logsub("&mark"); my $mark = shift; my $pos = $mark->time; if ($gui->{_markers_armed}){ $ui->destroy_marker($pos); $mark->remove; arm_mark_toggle(); # disarm } else{ set_position($pos); } } sub next_mark { logsub("&next_mark"); my $jumps = shift || 0; $jumps and $jumps--; my $here = eval_iam("cs-get-position"); my @marks = Audio::Nama::Mark::all(); for my $i ( 0..$#marks ){ if ($marks[$i]->time - $here > 0.001 ){ logpkg(__FILE__,__LINE__,'debug', "here: $here, future time: ", $marks[$i]->time); set_position($marks[$i+$jumps]->time); $this_mark = $marks[$i]; return; } } } sub previous_mark { logsub("&previous_mark"); my $jumps = shift || 0; $jumps and $jumps--; my $here = eval_iam("getpos"); my @marks = Audio::Nama::Mark::all(); for my $i ( reverse 0..$#marks ){ if ($marks[$i]->time < $here ){ set_position($marks[$i+$jumps]->time); $this_mark = $marks[$i]; return; } } } ## jump recording head position sub to_start { logsub("&to_start"); return if Audio::Nama::ChainSetup::really_recording(); set_position( 0 ); } sub to_end { logsub("&to_end"); # ten seconds shy of end return if Audio::Nama::ChainSetup::really_recording(); my $end = eval_iam('cs-get-length') - 10 ; set_position( $end); } sub jump { return if Audio::Nama::ChainSetup::really_recording(); my $delta = shift; logsub("&jump"); my $here = eval_iam('getpos'); logpkg(__FILE__,__LINE__,'debug', "delta: $delta, here: $here, unit: $gui->{_seek_unit}"); my $new_pos = $here + $delta * $gui->{_seek_unit}; if ( $setup->{audio_length} ) { $new_pos = $new_pos < $setup->{audio_length} ? $new_pos : $setup->{audio_length} - 10 } set_position( $new_pos ); } sub set_position { fade_around(\&_set_position, @_) } sub _set_position { logsub("&set_position"); return if Audio::Nama::ChainSetup::really_recording(); # don't allow seek while recording my $seconds = shift; my $coderef = sub{ eval_iam("setpos $seconds") }; $jack->{jackd_running} ? Audio::Nama::stop_do_start( $coderef, $jack->{seek_delay} ) : $coderef->(); update_clock_display(); } sub forward { my $delta = shift; my $here = eval_iam('getpos'); my $new = $here + $delta; set_position( $new ); } sub rewind { my $delta = shift; forward( -$delta ); } sub jump_forward { my $multiplier = shift; forward( $multiplier * $text->{hotkey_playback_jumpsize}) } sub jump_backward { jump_forward( - shift()) } } # end package { package Audio::Nama::HereMark; our @ISA = 'Audio::Nama::Mark'; our $last_time; sub name { 'Here' } sub time { Audio::Nama::eval_iam('cs-connected') ? ($last_time = Audio::Nama::eval_iam('getpos')) : $last_time } } { package Audio::Nama::ClipMark; use Modern::Perl; our @ISA = 'Audio::Nama::Mark'; } 1; __END__Audio-Nama-1.208/lib/Audio/Nama/Terminal.pm0000644000175000017500000002250412644673574017316 0ustar jrothjroth# ----------- Terminal related subroutines --------- package Audio::Nama; use Modern::Perl; no warnings 'uninitialized'; use Carp; use Audio::Nama::Globals qw(:singletons $this_bus $this_track); use Audio::Nama::Log qw(logpkg logsub); use Data::Dumper::Concise; use List::MoreUtils qw(first_index); sub initialize_prompt { $text->{term}->stuff_char(10); # necessary to respond to Ctrl-C at first prompt &{$text->{term_attribs}->{'callback_read_char'}}(); set_current_bus(); print prompt(); $text->{term_attribs}->{already_prompted} = 0; } sub initialize_terminal { $text->{term} = new Term::ReadLine("Ecasound/Nama"); $text->{term_attribs} = $text->{term}->Attribs; $text->{term_attribs}->{attempted_completion_function} = \&complete; $text->{term_attribs}->{already_prompted} = 1; ($text->{screen_lines}, $text->{screen_columns}) = $text->{term}->get_screen_size(); logpkg(__FILE__,__LINE__,'debug', "screensize is $text->{screen_lines} lines x $text->{screen_columns} columns"); detect_spacebar(); revise_prompt(); # handle Control-C from terminal #$SIG{INT} = \&cleanup_exit; # responds in a more timely way than abovce $project->{events}->{sigint} = AE::signal('INT', \&cleanup_exit); $SIG{USR1} = sub { git_snapshot() }; } sub setup_hotkeys { say "\nHotkeys on!"; destroy_readline(); setup_termkey(); 1 } sub list_hotkeys { my $hots = dclone($config->{hotkeys}); my %hots = %$hots; $hots{'='} = 'Enter numeric value'; $hots{ 'mN' } = 'Change step size to 10 raised to the Nth power'; $hots{ '#' } = 'Engage hotkey mode (must be typed in column 1)'; pager("Hotkeys\n",Dumper \%hots) } sub setup_termkey { $project->{events}->{termkey} = AnyEvent::TermKey->new( term => \*STDIN, on_key => sub { my $key = shift; my $key_string = $key->termkey->format_key( $key, FORMAT_VIM ); logpkg(__FILE__,__LINE__,'debug',"got key: $key_string"); # remove angle brackets around multi-character # sequences, e.g. -> PageUp $key_string =~ s/[<>]//g if length $key_string > 1; exit_hotkey_mode(), cleanup_exit() if $key->type_is_unicode and $key->utf8 eq "C" and $key->modifiers & KEYMOD_CTRL; # execute callback if we have one keystroke # and it has an "instant" mapping my $suppress_status; $key_string =~ s/ /Space/; # to suit our mapping file if ( my $command = $config->{hotkeys}->{$key_string} and ! length $text->{hotkey_buffer}) { $suppress_status++ if $key_string eq 'Escape' or $key_string eq 'Space'; try { eval "$command()" } catch { throw( qq(cannot execute subroutine "$command" for key "$key_string": $_") ) } } # otherwise assemble keystrokes and check # them against the grammar else { $key_string =~ s/Space/ /; # back to the character $text->{hotkey_buffer} .= $key_string; print $key_string if length $key_string == 1; # push $text->{hotkey_object_buffer}, $key; $text->{hotkey_parser}->command($text->{hotkey_buffer}) and reset_hotkey_buffers(); } print( "\x1b[$text->{screen_lines};0H", # go to screen bottom line, column 0 "\x1b[2K", # erase line hotkey_status_bar(), ) if $text->{hotkey_buffer} eq undef and ! $suppress_status; }, ); } sub hotkey_status_bar { my $name = "[".$this_track->name."]"; return "$name has no selected effect" unless $this_track->op; join " ", $name, "Stepsize: ",$this_track->stepsize, fxn($this_track->op)->fxname, parameter_info($this_track->op, $this_track->param - 1); ; } sub reset_hotkey_buffers { $text->{hotkey_buffer} = ""; $text->{hotkey_object_buffer} = []; } sub exit_hotkey_mode { teardown_hotkeys(); initialize_terminal(); initialize_prompt(); }; sub teardown_hotkeys { $project->{events}->{termkey}->termkey->stop(), delete $project->{events}->{termkey} if $project->{events}->{termkey} } sub destroy_readline { $text->{term}->rl_deprep_terminal() if $text->{term}; delete $text->{term}; delete $project->{events}->{stdin}; } sub setup_hotkey_grammar { $text->{hotkey_grammar} = get_data_section('hotkey_grammar'); $text->{hotkey_parser} = Parse::RecDescent->new($text->{hotkey_grammar}) or croak "Bad grammar!\n"; } sub end_of_list_sound { system( $config->{hotkey_beep} ) } sub previous_track { end_of_list_sound(), return if $this_track->n == 1; do{ $this_track = $ti{$this_track->n - 1} } until ! $this_track->hide; } sub next_track { end_of_list_sound(), return if ! $ti{ $this_track->n + 1 }; do{ $this_track = $ti{$this_track->n + 1} } until ! $this_track->hide; } sub previous_effect { my $op = $this_track->op; my $pos = $this_track->pos; end_of_list_sound(), return if $pos == 0; $pos--; set_current_op($this_track->ops->[$pos]); } sub next_effect { my $op = $this_track->op; my $pos = $this_track->pos; end_of_list_sound(),return if $pos == scalar @{ $this_track->ops } - 1; $pos++; set_current_op($this_track->ops->[$pos]); } sub previous_param { my $param = $this_track->param; $param > 1 ? set_current_param($this_track->param - 1) : end_of_list_sound() } sub next_param { my $param = $this_track->param; $param < scalar @{ fxn($this_track->op)->params } ? $project->{current_param}->{$this_track->op}++ : end_of_list_sound() } {my $override; sub revise_prompt { logsub('&revise_prompt'); # hack to allow suppressing prompt $override = ($_[0] eq "default" ? undef : $_[0]) if defined $_[0]; $text->{term}->callback_handler_install($override//prompt(), \&process_line) if $text->{term} } } sub prompt { logsub('&prompt'); join ' ', 'nama', git_branch_display(), bus_track_display() ," ('h' for help)> " } sub detect_spacebar { # create a STDIN watcher to intervene when space # received in column one $project->{events}->{stdin} = AE::io(*STDIN, 0, sub { &{$text->{term_attribs}->{'callback_read_char'}}(); if ( $config->{press_space_to_start} and $text->{term_attribs}->{line_buffer} eq " " and ! ($mode->song or $mode->live) ) { toggle_transport(); $text->{term_attribs}->{line_buffer} = q(); $text->{term_attribs}->{point} = 0; $text->{term_attribs}->{end} = 0; $text->{term}->stuff_char(10); &{$text->{term_attribs}->{'callback_read_char'}}(); } elsif ( $text->{term_attribs}->{line_buffer} eq "#" ){ setup_hotkeys(); } }); } sub throw { logsub("&throw"); pager_newline(@_) } sub pagers { logsub("&pagers"); my $output = join "", @_; chomp $output; pager($output, $/) } sub pager_newline { my @lines = map { my $s = $_; chomp $s; $s .="\n"; $s } @_; push @{$text->{output_buffer}}, @lines; print @lines; } sub pager { logsub("&pager"); my @output = @_; # this buffer is used to return results of OSC commands # the OSC client clears it after sending $text->{output_buffer} //= []; push @{$text->{output_buffer}}, @output, "\n\n"; my $line_count = 0; map{ $line_count += $_ =~ tr(\n)(\n) } @output; if ( (ref $ui) =~ /Text/ # pager interferes with GUI and $config->{use_pager} and ! $config->{opts}->{T} and $line_count > $text->{screen_lines} - 2 ) { my $fh = File::Temp->new(); my $fname = $fh->filename; print $fh @output; file_pager($fname); } else { print @output; } print "\n\n"; } sub mandatory_pager { logsub("&mandatory_pager"); my @output = @_; if ( (ref $ui) =~ /Text/ # pager interferes with GUI and $config->{use_pager} ) { my $fh = File::Temp->new(); my $fname = $fh->filename; print $fh @output; file_pager($fname); } else { print @output; } print "\n\n"; } sub file_pager { logsub("&file_pager"); my $fname = shift; if (! -e $fname or ! -r $fname ){ carp "file not found or not readable: $fname\n" ; return; } my $pager = $ENV{PAGER} || "/usr/bin/less"; $pager =~ /less/ and $pager .= qq( -M -i -PM"q=quit pager, /=search, PgUp/PgDown=scroll (line %lt/%L)"); my $cmd = qq($pager $fname); system $cmd; } 1; # command line processing routines sub get_ecasound_iam_keywords { my %reserved = map{ $_,1 } qw( forward fw getpos h help rewind quit q rw s setpos start stop t ? ); %{$text->{iam}} = map{$_,1 } grep{ ! $reserved{$_} } split /[\s,]/, eval_iam('int-cmd-list'); } sub load_keywords { my @keywords = keys %{$text->{commands}}; # complete hyphenated forms as well my %hyphenated = map{my $h = $_; $h =~ s/_/-/g; $h => $_ }grep{ /_/ } @keywords; $text->{hyphenated_commands} = \%hyphenated; push @keywords, keys %hyphenated; push @keywords, grep{$_} map{split " ", $text->{commands}->{$_}->{short}} @keywords; push @keywords, keys %{$text->{iam}}; push @keywords, keys %{$fx_cache->{partial_label_to_full}}; push @keywords, keys %{$midi->{keywords}} if $config->{use_midish}; push @keywords, "Audio::Nama::"; @{$text->{keywords}} = @keywords } sub complete { my ($string, $line, $start, $end) = @_; #print join $/, $string, $line, $start, $end, $/; my $term = $text->{term}; return $term->completion_matches($string,\&keyword); }; sub keyword { state $i; my ($string, $state) = @_; return unless $text; if($state) { $i++; } else { # first call $i = 0; } for (; $i<=$#{$text->{keywords}}; $i++) { return $text->{keywords}->[$i] if $text->{keywords}->[$i] =~ /^\Q$string/; }; return undef; }; 1; __END__Audio-Nama-1.208/lib/Audio/Nama/Custom.pm0000644000175000017500000000245312644673575017017 0ustar jrothjroth# ---------------- User Customization --------------- package Audio::Nama; use Modern::Perl; sub setup_user_customization { my $filename = $file->user_customization(); # effect aliases from .namarc for( keys %{$config->{alias}->{effect}} ) { my $longform = $config->{alias}->{effect}->{$_}; if(effect_index($longform)) { $fx_cache->{partial_label_to_full}->{$_} = $fx_cache->{partial_label_to_full}->{$longform} } else { throw("$longform: effect not found, cannot create shortcut") } } return unless -r $filename; say("reading user customization file $filename"); my %custom; unless (%custom = do $filename) { throw("couldn't parse $filename: $@\n") if $@; return; } logpkg(__FILE__,__LINE__,'debug','customization :', sub{Dumper \%custom }); my $prompt; { no warnings 'redefine'; *prompt = $custom{prompt} if $custom{prompt}; } my @commands = keys %{ $custom{commands} }; for my $cmd(@commands){ #my $coderef = gen_coderef($cmd,$custom{commands}{$cmd}) or next; $text->{user_command}->{$cmd} = $custom{commands}{$cmd}; } $config->{alias} = $custom{aliases}; } sub gen_coderef { my ($cmd,$code) = @_; my $coderef = eval "sub{ use feature ':5.10'; no warnings 'uninitialized'; $code }"; throw("couldn't parse command $cmd: $@"), return if $@; $coderef } 1;Audio-Nama-1.208/lib/Audio/Nama/Help.pm0000644000175000017500000005536312644673574016444 0ustar jrothjroth# -------------------- Help ---------------------- package Audio::Nama; use Modern::Perl; { no warnings 'uninitialized'; sub helpline { my $cmd = shift; my $out = "Command: $cmd\n"; $out .= "Shortcuts: $text->{commands}->{$cmd}->{short}\n" if $text->{commands}->{$cmd}->{short}; $out .= "Category: $text->{commands}->{$cmd}->{type}\n"; my $what = munge_help($text->{commands}->{$cmd}->{what}); $out .= "Description: $what\n"; $out .= "Usage: $cmd "; if ( $text->{commands}->{$cmd}->{parameters} && $text->{commands}->{$cmd}->{parameters} ne 'none' ){ $out .= $text->{commands}->{$cmd}->{parameters} } $out .= "\n"; my $example = $text->{commands}->{$cmd}->{example}; $example = munge_help($example); #$example =~ s/!n/\n/g; if ($example){ $out .= "Example: "; if ($example =~ /\n/s){ $example = "\n$example"; # add leading newline $example =~ s(\n)(\n )g; # indent } $out .= $example; $out .= "\n"; } ($/, ucfirst $out, $/); } sub munge_help { my $text = shift; $text =~ s/(^\s*)!(\s*#)/$1 $2/mg; $text =~ s/(^\s*!)/#/mg; $text } } sub helptopic { my $user_input = shift; # we expect topic number or topic name my ($index, $name); if( $user_input =~ /(\D+)/ ){ $name = $1; } else { $index = $user_input; $name = $help->{arr_topic}->[$index]; } #system("man","nama") if $index== 15; format_help_topic($index, $name); } sub format_help_topic { my ($index, $name) = @_; my @output; push @output, "\n-- ", ucfirst $name, " --\n\n"; push @output, $help->{topic}->{$name}, $/; push @output, $help->{usage} if $index == 14; @output } sub help { my $name = shift; $name =~ s/-/_/g; # help indices require underscores chomp $name; #print "seeking help for argument: $name\n"; $text->{iam}->{$name} and pager(<{topic}->{$name}){ @output = helptopic($name); } elsif ($name =~ /^0/){ @output = map{ helptopic $_ } @{$help->{arr_topic}}; } elsif ( $name =~ /^(\d+)$/ and $1 < 20 ){ @output = helptopic($name) } else { my %helped = (); my @help = (); if ( $text->{commands}->{$name} ){ push @help, helpline($name); $helped{$name}++ } map { my $cmd = $_ ; if ($cmd =~ /$name/ ) { push @help, helpline($cmd) unless $helped{$cmd} or $cmd =~ /-/; # skip hyphenated command forms # which lack full help $helped{$cmd}++ ; } no warnings 'uninitialized'; if ( ! $helped{$cmd} and grep{ /$name/ } split " ", $text->{commands}->{$cmd}->{short}) { push @help, helpline($cmd) } } keys %{$text->{commands}}; if ( @help ){ push @output, qq("$name" matches the following commands:\n\n), @help; } } if (@output){ map{ s/_/-/g } @output; Audio::Nama::pager( @output ); } else { throw("$name: no help found.\n"); } } sub help_effect { my ($input, $id, $no_match, @output); $id = $input = shift; push @output, "\n"; # e.g. help tap_reverb # help 2142 # help var_chipmunk # preset # convert digits to LADSPA label if ($id !~ /\D/){ $id = $fx_cache->{ladspa_id_to_label}->{$id} or $no_match++ } # convert ladspa_label to el:ladspa_label # convert preset_name to pn:preset_name if ($fx_cache->{full_label_to_index}->{$id}){} # we are ready elsif ( $fx_cache->{partial_label_to_full}->{$id} ) { $id = $fx_cache->{partial_label_to_full}->{$id} } else { $no_match++ } # one-line help for Ecasound and chain operators, controllers and presets if ($id !~ /^(lv2|el):/) { push @output, grep{ /$id/ } @{$fx_cache->{user_help}}; } # full help for LADSPA/LV2 plugins elsif ( $id =~ /el:/ ) { @output = $fx_cache->{ladspa_help}->{$id} } elsif ( $id =~ /elv2:/) { @output = $fx_cache->{lv2_help}->{$id} } if( $no_match ){ throw("No effects were found matching: $input\n\n"); } else { Audio::Nama::pager(@output) } } sub find_effect { my @keys = @_; #print "keys: @keys\n"; #my @output; my @matches = grep{ my $_help = $_; my $didnt_match; map{ $_help =~ /\Q$_\E/i or $didnt_match++ } @keys; ! $didnt_match; # select if no cases of non-matching } @{$fx_cache->{user_help}}; if ( @matches ){ Audio::Nama::pager( $text->{wrap}->paragraphs(@matches) , "\n" ); } else { throw(join " ", "No effects were found matching:",@keys,"\n\n") } } @{$help->{arr_topic}} = qw( all project track chain_setup transport marks effects group bus mixdown prompt diagnostics fades edits ) ; @{$help->{arr_topic}} = qw( all project track chain_setup transport marks effects group bus mixdown prompt diagnostics edits fades command_line_options ) ; %{$help->{topic}} = ( help => < - show help for help - show help for commands matching // help - invoke analyseplugin for info on a LADSPA id help - list commands under help - list commands under (lower case) HELP project => < get - checkout tag or associated branch and load branch, br - switch to designated branch and load list_branches, lbr - list branches and tags (without arguments) new_branch, nbr - create a new branch starting at the current commit or a specified commit tag - tag current commit with a name and optional message memoize - enable WAV directory cache unmemoize - disable WAV directory cache PROJECT chain_setup => < <